Rev 83 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 83 | Rev 84 | ||
---|---|---|---|
1 | <?php |
1 | <?php |
2 | 2 | ||
3 | /* |
3 | /* |
4 | * PHP svn functions |
4 | * PHP svn functions |
5 | * Copyright 2021 - 2023 Daniel Marschall, ViaThinkSoft |
5 | * Copyright 2021 - 2023 Daniel Marschall, ViaThinkSoft |
6 | * Revision 2023-04-21 |
6 | * Revision 2023-04-21 |
7 | * |
7 | * |
8 | * Licensed under the Apache License, Version 2.0 (the "License"); |
8 | * Licensed under the Apache License, Version 2.0 (the "License"); |
9 | * you may not use this file except in compliance with the License. |
9 | * you may not use this file except in compliance with the License. |
10 | * You may obtain a copy of the License at |
10 | * You may obtain a copy of the License at |
11 | * |
11 | * |
12 | * http://www.apache.org/licenses/LICENSE-2.0 |
12 | * http://www.apache.org/licenses/LICENSE-2.0 |
13 | * |
13 | * |
14 | * Unless required by applicable law or agreed to in writing, software |
14 | * Unless required by applicable law or agreed to in writing, software |
15 | * distributed under the License is distributed on an "AS IS" BASIS, |
15 | * distributed under the License is distributed on an "AS IS" BASIS, |
16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
17 | * See the License for the specific language governing permissions and |
17 | * See the License for the specific language governing permissions and |
18 | * limitations under the License. |
18 | * limitations under the License. |
19 | */ |
19 | */ |
20 | 20 | ||
21 | function get_svn_revision($dir='') { |
21 | function get_svn_revision($dir='') { |
22 | if (!empty($dir)) $dir .= '/'; |
22 | if (!empty($dir)) $dir .= '/'; |
23 | if (!is_dir($dir)) return false; |
23 | if (!is_dir($dir)) return false; |
- | 24 | if (is_dir($dir.'/.svn')) $dir .= '/.svn/'; |
|
24 | 25 | ||
25 | // Try to find out the SVN version using the shell |
26 | // Try to find out the SVN version using the shell |
26 | $output = @shell_exec('svnversion '.escapeshellarg($dir).' 2>&1'); |
27 | $output = @shell_exec('svnversion '.escapeshellarg($dir).' 2>&1'); |
27 | $match = array(); |
28 | $match = array(); |
28 | if (preg_match('/\d+/', $output, $match)) { |
29 | if (preg_match('/\d+/', $output, $match)) { |
29 | return ($cachedVersion = $match[0]); |
30 | return ($cachedVersion = $match[0]); |
30 | } |
31 | } |
31 | 32 | ||
32 | $output = @shell_exec('svn info '.escapeshellarg($dir).' 2>&1'); |
33 | $output = @shell_exec('svn info '.escapeshellarg($dir).' 2>&1'); |
33 | if (preg_match('/Revision:\s*(\d+)/m', $output, $match)) { // do not translate |
34 | if (preg_match('/Revision:\s*(\d+)/m', $output, $match)) { // do not translate |
34 | return ($cachedVersion = $match[1]); |
35 | return ($cachedVersion = $match[1]); |
35 | } |
36 | } |
36 | 37 | ||
37 | // If that failed, try to get the version via access of the database files |
38 | // If that failed, try to get the version via access of the database files |
38 | if (class_exists('SQLite3')) { |
39 | if (class_exists('SQLite3')) { |
39 | try { |
40 | try { |
40 | $db = new SQLite3($dir.'.svn/wc.db'); |
41 | $db = new SQLite3($dir.'.svn/wc.db'); |
41 | $results = $db->query('SELECT MIN(revision) AS rev FROM NODES_BASE'); |
42 | $results = $db->query('SELECT MIN(revision) AS rev FROM NODES_BASE'); |
42 | while ($row = $results->fetchArray()) { |
43 | while ($row = $results->fetchArray()) { |
43 | return ($cachedVersion = $row['rev']); |
44 | return ($cachedVersion = $row['rev']); |
44 | } |
45 | } |
45 | $db->close(); |
46 | $db->close(); |
46 | $db = null; |
47 | $db = null; |
47 | } catch (Exception $e) { |
48 | } catch (Exception $e) { |
48 | } |
49 | } |
49 | } |
50 | } |
50 | if (class_exists('PDO')) { |
51 | if (class_exists('PDO')) { |
51 | try { |
52 | try { |
52 | $pdo = new PDO('sqlite:'.$dir.'.svn/wc.db'); |
53 | $pdo = new PDO('sqlite:'.$dir.'.svn/wc.db'); |
53 | $res = $pdo->query('SELECT MIN(revision) AS rev FROM NODES_BASE'); |
54 | $res = $pdo->query('SELECT MIN(revision) AS rev FROM NODES_BASE'); |
54 | $row = $res->fetch(); |
55 | $row = $res->fetch(); |
55 | if ($row !== false) { |
56 | if ($row !== false) { |
56 | return ($cachedVersion = $row['rev']); |
57 | return ($cachedVersion = $row['rev']); |
57 | } |
58 | } |
58 | $pdo = null; |
59 | $pdo = null; |
59 | } catch (Exception $e) { |
60 | } catch (Exception $e) { |
60 | } |
61 | } |
61 | } |
62 | } |
62 | 63 | ||
63 | // We couldn't get the revision info |
64 | // We couldn't get the revision info |
64 | // Try parsing the binary file. It is a bit risky though... |
65 | // Try parsing the binary file. It is a bit risky though... |
65 | return get_svn_revision_without_sqlite3($dir); |
66 | return get_svn_revision_without_sqlite3($dir); |
66 | } |
67 | } |
67 | 68 | ||
68 | function get_svn_revision_without_sqlite3($svn_path, $base='trunk') { |
69 | function get_svn_revision_without_sqlite3($svn_path, $base='trunk') { |
- | 70 | if (!empty($svn_path)) $svn_path .= '/'; |
|
- | 71 | if (!is_dir($svn_path)) return false; |
|
- | 72 | if (!is_dir($svn_path.'/.svn')) $svn_path .= '/../'; |
|
- | 73 | ||
69 | $fil = file_get_contents($svn_path.'/.svn/wc.db'); |
74 | $fil = file_get_contents($svn_path.'/.svn/wc.db'); |
70 | preg_match_all('@('.preg_quote($base,'@').'/[a-z0-9!"#$%&\'()*+,.\/:;<=>?\@\[\] ^_`{|}~-]+)(..)normal(file|dir)@', $fil, $m, PREG_SET_ORDER); |
75 | preg_match_all('@('.preg_quote($base,'@').'/[a-z0-9!"#$%&\'()*+,.\/:;<=>?\@\[\] ^_`{|}~-]+)(..)normal(file|dir)@', $fil, $m, PREG_SET_ORDER); |
71 | 76 | ||
72 | $files = array(); |
77 | $files = array(); |
73 | foreach ($m as list($dummy, $fil, $revision)) { |
78 | foreach ($m as list($dummy, $fil, $revision)) { |
74 | $val = hexdec(bin2hex($revision)); |
79 | $val = hexdec(bin2hex($revision)); |
75 | 80 | ||
76 | $tmp = explode("$base/", $fil); |
81 | $tmp = explode("$base/", $fil); |
77 | $fil = end($tmp); |
82 | $fil = end($tmp); |
78 | 83 | ||
79 | if (!file_exists($svn_path."/$base/$fil")) continue; // deleted files (deleted rows?!) might be still in the binary |
84 | if (!file_exists($svn_path."/$base/$fil")) continue; // deleted files (deleted rows?!) might be still in the binary |
80 | 85 | ||
81 | if (!isset($files[$fil])) $files[$fil] = -1; |
86 | if (!isset($files[$fil])) $files[$fil] = -1; |
82 | if ($files[$fil] < $val) $files[$fil] = $val; |
87 | if ($files[$fil] < $val) $files[$fil] = $val; |
83 | } |
88 | } |
84 | 89 | ||
85 | $arr = array_values($files); |
90 | $arr = array_values($files); |
86 | 91 | ||
87 | /* |
92 | /* |
88 | foreach ($files as $name => $val) { |
93 | foreach ($files as $name => $val) { |
89 | if ($val != 1228) echo "DEBUG Unexpected: $val / $fil\n"; |
94 | if ($val != 1228) echo "DEBUG Unexpected: $val / $fil\n"; |
90 | } |
95 | } |
91 | */ |
96 | */ |
92 | 97 | ||
93 | $num = count($arr); |
98 | $num = count($arr); |
94 | $middleVal = floor(($num - 1) / 2); |
99 | $middleVal = floor(($num - 1) / 2); |
95 | if($num % 2) { |
100 | if($num % 2) { |
96 | $median = $arr[$middleVal]; |
101 | $median = $arr[$middleVal]; |
97 | } else { |
102 | } else { |
98 | $lowMid = $arr[$middleVal]; |
103 | $lowMid = $arr[$middleVal]; |
99 | $highMid = $arr[$middleVal + 1]; |
104 | $highMid = $arr[$middleVal + 1]; |
100 | $median = (($lowMid + $highMid) / 2); |
105 | $median = (($lowMid + $highMid) / 2); |
101 | } |
106 | } |
102 | 107 | ||
103 | return $median; |
108 | return $median; |
104 | } |
109 | } |
105 | 110 |