Subversion Repositories oidplus

Rev

Rev 555 | Rev 625 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
511 daniel-mar 5
 * Copyright 2019 - 2021 Daniel Marschall, ViaThinkSoft
2 daniel-mar 6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
 
20
function insertWhitespace($str, $index) {
21
        return substr($str, 0, $index) . ' ' . substr($str, $index);
22
}
23
 
24
function js_escape($data) {
25
        // TODO.... json_encode??
289 daniel-mar 26
        $data = str_replace('\\', '\\\\', $data);
27
        $data = str_replace('\'', '\\\'', $data);
28
        return "'" . $data . "'";
2 daniel-mar 29
}
30
 
11 daniel-mar 31
function trim_br($html) {
386 daniel-mar 32
        $count = 0;
11 daniel-mar 33
        do { $html = preg_replace('@^\s*<\s*br\s*/{0,1}\s*>@isU', '', $html, -1, $count); } while ($count > 0); // left trim
34
        do { $html = preg_replace('@<\s*br\s*/{0,1}\s*>\s*$@isU', '', $html, -1, $count); } while ($count > 0); // right trim
35
        return $html;
36
}
74 daniel-mar 37
 
453 daniel-mar 38
function generateRandomString($length) {
39
        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
40
        $charactersLength = strlen($characters);
41
        $randomString = '';
42
        for ($i = 0; $i < $length; $i++) {
43
                $randomString .= $characters[rand(0, $charactersLength - 1)];
44
        }
45
        return $randomString;
46
}
47
 
74 daniel-mar 48
function verify_private_public_key($privKey, $pubKey) {
49
        try {
50
                if (empty($privKey)) return false;
51
                if (empty($pubKey)) return false;
453 daniel-mar 52
                $data = generateRandomString(25);
386 daniel-mar 53
                $encrypted = '';
54
                $decrypted = '';
74 daniel-mar 55
                if (!@openssl_public_encrypt($data, $encrypted, $pubKey)) return false;
56
                if (!@openssl_private_decrypt($encrypted, $decrypted, $privKey)) return false;
57
                return $decrypted == $data;
58
        } catch (Exception $e) {
59
                return false;
60
        }
61
}
62
 
63
function smallhash($data) { // get 31 bits from SHA1. Values 0..2147483647
250 daniel-mar 64
        return (hexdec(substr(sha1($data),-4*2)) & 0x7FFFFFFF);
74 daniel-mar 65
}
180 daniel-mar 66
 
182 daniel-mar 67
function split_firstname_lastname($name) {
68
        $ary = explode(' ', $name);
69
        $last_name = array_pop($ary);
70
        $first_name = implode(' ', $ary);
71
        return array($first_name, $last_name);
72
}
73
 
180 daniel-mar 74
function originHeaders() {
75
        // CORS
76
        // Author: Till Wehowski
426 daniel-mar 77
        // TODO: add to class OIDplus
182 daniel-mar 78
 
180 daniel-mar 79
        header("Access-Control-Allow-Credentials: true");
80
        header("Access-Control-Allow-Origin: ".strip_tags(((isset($_SERVER['HTTP_ORIGIN'])) ? $_SERVER['HTTP_ORIGIN'] : "*")));
81
 
82
        header("Access-Control-Allow-Headers: If-None-Match, X-Requested-With, Origin, X-Frdlweb-Bugs, Etag, X-Forgery-Protection-Token, X-CSRF-Token");
83
 
84
        if (isset($_SERVER['HTTP_ORIGIN'])) {
85
                header('X-Frame-Options: ALLOW-FROM '.$_SERVER['HTTP_ORIGIN']);
86
        } else {
87
                header_remove("X-Frame-Options");
88
        }
89
 
90
        $expose = array('Etag', 'X-CSRF-Token');
91
        foreach (headers_list() as $num => $header) {
92
                $h = explode(':', $header);
93
                $expose[] = trim($h[0]);
94
        }
95
        header("Access-Control-Expose-Headers: ".implode(',',$expose));
96
 
97
        header("Vary: Origin");
98
}
236 daniel-mar 99
 
100
function get_calling_function() {
101
        $ex = new Exception();
102
        $trace = $ex->getTrace();
360 daniel-mar 103
        if (!isset($trace[2])) return _L('(main)');
236 daniel-mar 104
        $final_call = $trace[2];
105
        return $final_call['file'].':'.$final_call['line'].'/'.$final_call['function'].'()';
106
}
346 daniel-mar 107
 
108
if (!function_exists('mb_wordwrap')) {
109
        function mb_wordwrap($str, $width = 75, $break = "\n", $cut = false) {
110
                // https://stackoverflow.com/a/4988494/488539
111
                $lines = explode($break, $str);
112
                foreach ($lines as &$line) {
113
                        $line = rtrim($line);
114
                        if (mb_strlen($line) <= $width) {
115
                                continue;
116
                        }
117
                        $words = explode(' ', $line);
118
                        $line = '';
119
                        $actual = '';
120
                        foreach ($words as $word) {
121
                                if (mb_strlen($actual.$word) <= $width) {
122
                                        $actual .= $word.' ';
123
                                } else {
124
                                        if ($actual != '') {
125
                                                $line .= rtrim($actual).$break;
126
                                        }
127
                                        $actual = $word;
128
                                        if ($cut) {
129
                                                while (mb_strlen($actual) > $width) {
130
                                                        $line .= mb_substr($actual, 0, $width).$break;
131
                                                        $actual = mb_substr($actual, $width);
132
                                                }
133
                                        }
134
                                        $actual .= ' ';
135
                                }
136
                        }
137
                        $line .= trim($actual);
138
                }
139
                return implode($break, $lines);
140
        }
141
}
355 daniel-mar 142
 
379 daniel-mar 143
function httpOutWithETag($out, $contentType, $filename='') {
144
        $etag = md5($out);
145
        header("Etag: $etag");
146
        header("Content-MD5: $etag"); // RFC 2616 clause 14.15
147
        if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && (trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag)) {
148
                header("HTTP/1.1 304 Not Modified");
149
        } else {
150
                header("Content-Type: $contentType");
151
                if (!empty($filename)) {
152
                        header('Content-Disposition:inline; filename="'.$filename.'"');
153
                }
154
                echo $out;
155
        }
156
        die();
157
}
158
 
360 daniel-mar 159
function my_vsprintf($str, $args) {
160
        $n = 1;
161
        foreach ($args as $val) {
162
                $str = str_replace("%$n", $val, $str);
163
                $n++;
164
        }
370 daniel-mar 165
        $str = str_replace("%%", "%", $str);
360 daniel-mar 166
        return $str;
167
}
168
 
355 daniel-mar 169
function _L($str, ...$sprintfArgs) {
401 daniel-mar 170
        static $translation_array = array();
171
        static $translation_loaded = null;
172
 
506 daniel-mar 173
        $str = trim($str);
174
 
438 daniel-mar 175
        if (!class_exists('OIDplus')) {
176
                return my_vsprintf($str, $sprintfArgs);
177
        }
178
 
360 daniel-mar 179
        $lang = OIDplus::getCurrentLang();
468 daniel-mar 180
        $ta = OIDplus::getTranslationArray($lang);
181
        $res = (isset($ta[$lang]) && isset($ta[$lang][$str])) ? $ta[$lang][$str] : $str;
360 daniel-mar 182
 
183
        $res = str_replace('###', OIDplus::baseConfig()->getValue('TABLENAME_PREFIX', ''), $res);
184
 
185
        $res = my_vsprintf($res, $sprintfArgs);
186
 
187
        return $res;
370 daniel-mar 188
}
386 daniel-mar 189
 
552 daniel-mar 190
function _CheckParamExists($params, $key) {
191
        if (!isset($params[$key])) throw new OIDplusException(_L('Parameter %1 is missing', $key));
192
}
193
 
386 daniel-mar 194
function extractHtmlContents($cont) {
195
        // make sure the program works even if the user provided HTML is not UTF-8
196
        $cont = iconv(mb_detect_encoding($cont, mb_detect_order(), true), 'UTF-8//IGNORE', $cont);
197
        $bom = pack('H*','EFBBBF');
198
        $cont = preg_replace("/^$bom/", '', $cont);
199
 
200
        $out_js = '';
201
        $m = array();
202
        preg_match_all('@<script[^>]*>(.+)</script>@ismU', $cont, $m);
203
        foreach ($m[1] as $x) {
204
                $out_js = $x . "\n\n";
205
        }
206
 
207
        $out_css = '';
208
        $m = array();
209
        preg_match_all('@<style[^>]*>(.+)</style>@ismU', $cont, $m);
210
        foreach ($m[1] as $x) {
211
                $out_css = $x . "\n\n";
212
        }
213
 
214
        $out_html = $cont;
215
        $out_html = preg_replace('@^(.+)<body[^>]*>@isU', '', $out_html);
216
        $out_html = preg_replace('@</body>.+$@isU', '', $out_html);
217
        $out_html = preg_replace('@<title>.+</title>@isU', '', $out_html);
218
        $out_html = preg_replace('@<h1>.+</h1>@isU', '', $out_html, 1);
219
        $out_html = preg_replace('@<script[^>]*>(.+)</script>@ismU', '', $out_html);
220
        $out_html = preg_replace('@<style[^>]*>(.+)</style>@ismU', '', $out_html);
221
 
222
        return array($out_html, $out_js, $out_css);
392 daniel-mar 223
}
224
 
400 daniel-mar 225
function sha3_512($password, $raw_output=false) {
392 daniel-mar 226
        if (version_compare(PHP_VERSION, '7.1.0') >= 0) {
400 daniel-mar 227
                return hash('sha3-512', $password, $raw_output);
392 daniel-mar 228
        } else {
400 daniel-mar 229
                return bb\Sha3\Sha3::hash($password, 512, $raw_output);
392 daniel-mar 230
        }
231
}
486 daniel-mar 232
 
233
function get_svn_revision($dir='') {
234
        if (!empty($dir)) $dir .= '/';
235
 
236
        // Try to get the version via SQLite3
237
        if (class_exists('SQLite3')) {
238
                try {
239
                        $db = new SQLite3($dir.'.svn/wc.db');
240
                        $results = $db->query('SELECT MIN(revision) AS rev FROM NODES_BASE');
241
                        while ($row = $results->fetchArray()) {
491 daniel-mar 242
                                return ($cachedVersion = $row['rev']);
486 daniel-mar 243
                        }
244
                        $db->close();
245
                        $db = null;
246
                } catch (Exception $e) {
247
                }
248
        }
249
        if (class_exists('PDO')) {
250
                try {
251
                        $pdo = new PDO('sqlite:'.$dir.'.svn/wc.db');
252
                        $res = $pdo->query('SELECT MIN(revision) AS rev FROM NODES_BASE');
253
                        $row = $res->fetch();
254
                        if ($row !== false) {
491 daniel-mar 255
                                return ($cachedVersion = $row['rev']);
486 daniel-mar 256
                        }
257
                        $pdo = null;
258
                } catch (Exception $e) {
259
                }
260
        }
261
 
262
        // Try to find out the SVN version using the shell
263
        // We don't prioritize this method, because a failed shell access will flood the apache error log with STDERR messages
264
        $output = @shell_exec('svnversion '.escapeshellarg($dir));
265
        $match = array();
266
        if (preg_match('/\d+/', $output, $match)) {
491 daniel-mar 267
                return ($cachedVersion = $match[0]);
486 daniel-mar 268
        }
269
 
270
        $output = @shell_exec('svn info '.escapeshellarg($dir));
271
        if (preg_match('/Revision:\s*(\d+)/m', $output, $match)) { // do not translate
491 daniel-mar 272
                return ($cachedVersion = $match[1]);
486 daniel-mar 273
        }
491 daniel-mar 274
 
275
        return false;
486 daniel-mar 276
}
277
 
278
function get_gitsvn_revision($dir='') {
279
        $ec = -1;
280
        $out = array();
281
        if (!empty($dir)) {
282
                @exec('cd '.escapeshellarg($dir).' && git log', $out, $ec);
283
        } else {
284
                @exec('git log', $out, $ec);
285
        }
286
        if ($ec == 0) {
287
                $out = implode("\n", $out);
288
                $m = array();
289
                if (preg_match('%git-svn-id: (.+)@(\\d+) %ismU', $out, $m)) {
290
                        return $m[2];
291
                }
292
        }
293
        return false;
294
}