1: <?php
2:
3: /**
4: * Initial setup
5: * @package framework
6: * @subpackage setup
7: */
8:
9: const VERSION = .1;
10:
11: /* load the framework */
12: require APP_PATH.'lib/repository.php';
13: require APP_PATH.'lib/searchable.php';
14: require APP_PATH.'lib/module.php';
15: require APP_PATH.'lib/modules.php';
16: require APP_PATH.'lib/modules_exec.php';
17: require APP_PATH.'lib/config.php';
18: require APP_PATH.'lib/auth.php';
19: require APP_PATH.'lib/oauth2.php';
20: require APP_PATH.'lib/session_base.php';
21: require APP_PATH.'lib/session_php.php';
22: require APP_PATH.'lib/session_db.php';
23: require APP_PATH.'lib/session_memcached.php';
24: require APP_PATH.'lib/session_redis.php';
25: require APP_PATH.'lib/format.php';
26: require APP_PATH.'lib/dispatch.php';
27: require APP_PATH.'lib/request.php';
28: require APP_PATH.'lib/cache.php';
29: require APP_PATH.'lib/output.php';
30: require APP_PATH.'lib/crypt.php';
31: require APP_PATH.'lib/crypt_sodium.php';
32: require APP_PATH.'lib/sodium_compat.php';
33: require APP_PATH.'lib/scram.php';
34: require APP_PATH.'lib/environment.php';
35: require APP_PATH.'lib/db.php';
36: require APP_PATH.'lib/servers.php';
37: require APP_PATH.'lib/api.php';
38: require APP_PATH.'lib/webdav_formats.php';
39: require APP_PATH.'lib/js_libs.php';
40:
41: require_once APP_PATH.'modules/core/functions.php';
42:
43: /* check for and load the correct libsodium interface */
44: if (!defined('LIBSODIUM')) {
45: if (extension_loaded('libsodium') && function_exists('\Sodium\crypto_pwhash_str_verify')) {
46: define('LIBSODIUM', true);
47: class Hm_Sodium_Compat extends Hm_Sodium_PECL {}
48: } elseif (extension_loaded('sodium') && function_exists('sodium_crypto_pwhash_str_verify')) {
49: define('LIBSODIUM', true);
50: class Hm_Sodium_Compat extends Hm_Sodium_PHP {}
51: } else {
52: define('LIBSODIUM', false);
53: }
54: }
55:
56: if (!class_exists('Hm_Functions')) {
57: /**
58: * Used to override built in functions that break unit tests
59: * @package framework
60: * @subpackage setup
61: */
62: class Hm_Functions {
63:
64: /**
65: * @param string $name
66: * @param string $value
67: * @return boolean
68: */
69: public static function setcookie($name, $value, $lifetime = 0, $path = '', $domain = '', $secure = false, $html_only = false, $same_site = 'Strict') {
70: $prefix = ($lifetime != 0 && $lifetime < time()) ? 'Deleting' : 'Setting';
71: Hm_Debug::add(sprintf('%s cookie: name: %s, lifetime: %s, path: %s, domain: %s, secure: %s, html_only %s',$prefix, $name, $lifetime, $path, $domain, $secure, $html_only), 'info');
72: return setcookie($name, $value, [
73: 'expires' => $lifetime,
74: 'path' => $path,
75: 'domain' => $domain,
76: 'secure' => $secure,
77: 'httponly' => $html_only,
78: 'samesite' => $same_site
79: ]);
80: }
81:
82: /**
83: * @param string $header
84: * @return void
85: */
86: public static function header($header) {
87: header($header);
88: }
89:
90: /**
91: * @param string $msg
92: * @return null
93: */
94: public static function cease($msg = '') {
95: die($msg);
96: }
97:
98: /**
99: * @return boolean
100: */
101: public static function session_destroy() {
102: if (session_status() === PHP_SESSION_ACTIVE) {
103: return session_destroy();
104: }
105: return false;
106: }
107:
108: /**
109: * @return boolean
110: */
111: public static function session_start() {
112: return session_start();
113: }
114:
115: /**
116: * @return boolean
117: */
118: public static function error_log($str) {
119: return error_log($str);
120: }
121:
122: /**
123: * @param resource|false $handle
124: * @param integer $name
125: */
126: public static function c_setopt($handle, $name, $value) {
127: if ($handle !== false) {
128: curl_setopt($handle, $name, $value);
129: }
130: }
131:
132: /**
133: * @return resource|false
134: */
135: public static function c_init() {
136: if (extension_loaded('curl')) {
137: return curl_init();
138: } else {
139: Hm_Msgs::add('Please enable the cURL extension.', 'warning');
140: return false;
141: }
142: }
143:
144: /**
145: * @param resource $handle
146: */
147: public static function c_exec($handle) {
148: $response = curl_exec($handle);
149: if ($response === false) {
150: $error = curl_error($handle);
151: Hm_Msgs::add('cURL error: '.$error, 'danger');
152: }
153: return $response;
154: }
155:
156: /**
157: * @param resource $handle
158: */
159: public static function c_status($ch) {
160: return curl_getinfo($ch, CURLINFO_HTTP_CODE);
161: }
162:
163: /**
164: * @param string $func
165: */
166: public static function function_exists($func) {
167: return function_exists($func);
168: }
169:
170: /**
171: * @param string $class
172: */
173: public static function class_exists($class) {
174: return class_exists($class, false);
175: }
176:
177: /**
178: * @param integer $size
179: */
180: public static function random_bytes($size) {
181: return random_bytes($size);
182: }
183:
184: /**
185: * @return Memcached
186: */
187: public static function memcached() {
188: return new Memcached();
189: }
190:
191: /**
192: * @return Redis
193: */
194: public static function redis() {
195: return new Redis();
196: }
197:
198: /**
199: * @param integer $type input type
200: * @param array $filters filter list
201: * @return array filtered list
202: */
203: public static function filter_input_array($type, $filters) {
204: /*
205: In FastCGI, filter_input_array does not work as intended with INPUT_SERVER because its stored copy of data doesn't get modified during the request.
206: So we need to explicitly access the $_SERVER.
207: */
208: if ($type === INPUT_SERVER) {
209: $value = array();
210: foreach ($filters as $var => $flag) {
211: if (isset($_SERVER[$var])) {
212: $value[$var] = filter_var($_SERVER[$var], $flag);
213: } else {
214: $value[$var] = null;
215: }
216: }
217: return $value;
218: }
219: return filter_input_array($type, $filters, false);
220: }
221:
222: /**
223: * @param string $server host to connect to
224: * @param integer $port port to connect to
225: * @param integer $errno error number
226: * @param string $errstr error string
227: * @param integer $mode connection mode
228: * @param resource $ctx context
229: */
230: public static function stream_socket_client($server, $port, &$errno, &$errstr, $timeout, $mode, $ctx) {
231: return @stream_socket_client($server.':'.$port, $errno, $errstr, $timeout, $mode, $ctx);
232: }
233:
234: /**
235: * @param resource $resource socket connection
236: * @return boolean
237: */
238: public static function stream_ended($resource) {
239: if (!is_resource($resource) || feof($resource)) {
240: return true;
241: }
242: return false;
243: }
244: /**
245: * @param resource $socket socket connection to flip to TLS
246: * @return boolean
247: */
248: public static function stream_socket_enable_crypto($socket, $type) {
249: return stream_socket_enable_crypto($socket, true, $type);
250: }
251: }
252: }
253:
254: /**
255: * See if a function already exists
256: * @param string $name function name to check
257: * @return boolean
258: */
259: function hm_exists($name) {
260: $bt = debug_backtrace();
261: $caller = array_shift($bt);
262: $module = hm_get_module_from_path($caller['file']);
263: if (function_exists($name)) {
264: Hm_Debug::add(sprintf('Function in %s replaced: %s', $module, $name), 'warning');
265: return true;
266: }
267: return false;
268: }
269:
270: /**
271: * Return the module set name from a file path
272: * @param string $path file path
273: * @return string
274: */
275: function hm_get_module_from_path($path) {
276: $data = pathinfo($path);
277: if (!is_array($data) || !array_key_exists('dirname', $data)) {
278: return 'unknown';
279: }
280: $parts = array_reverse(explode(DIRECTORY_SEPARATOR, $data['dirname']));
281: foreach ($parts as $i => $v) {
282: if ($v == 'modules') {
283: return $parts[($i - 1)];
284: }
285: }
286: return 'unknown';
287: }
288: