PageRenderTime 41ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/sys/autoload-core/common.php

https://gitlab.com/VxMxPx/mysli
PHP | 281 lines | 220 code | 31 blank | 30 comment | 15 complexity | b140aa5a2d498ed5dbd9651384c8c985 MD5 | raw file
  1. <?php
  2. # correct directory separators
  3. function ds(...$path): string
  4. {
  5. $path = array_filter($path, 'strlen');
  6. $path = implode(DIRECTORY_SEPARATOR, $path);
  7. return $path
  8. ? preg_replace('/(?<![:\/])[\/\\\\]+/', DIRECTORY_SEPARATOR, $path) : '';
  9. }
  10. function urlseperator(...$path): string
  11. {
  12. $path = array_filter($path, 'strlen');
  13. $path = implode('/', $path);
  14. return $path
  15. ? preg_replace('/(?<![:\/])[\/\\\\]+/', '/', $path) : '';
  16. }
  17. # get various system paths
  18. function pkgpath(...$p): string
  19. {
  20. return (array_key_exists(0, $p) && $p[0] === 'dat')
  21. ? datpath(...array_slice($p, 1))
  22. : ds(MYSLI_PKGPATH, ...$p);
  23. }
  24. function datpath(...$p): string { return ds(MYSLI_DATPATH, ...$p); }
  25. function pubpath(...$p): string { return ds(MYSLI_PUBPATH, ...$p); }
  26. function tmppath(...$p): string { return ds(MYSLI_DATPATH, 'tmp', ...$p); }
  27. # return or insert data dummy package info
  28. function datpkg(array &$packages=null): \sys\package
  29. {
  30. $pkg = new \sys\package([
  31. 'id' => 'dat',
  32. 'version' => '1.0.0',
  33. 'date' => '2017-06-10',
  34. 'updated_on' => '2017-06-10',
  35. 'require' => [],
  36. 'enabled' => true
  37. ]);
  38. if ($packages) {
  39. if (array_key_exists(0, $packages)) {
  40. $packages[] = $pkg;
  41. }
  42. else {
  43. $packages[$pkg->id] = $pkg;
  44. }
  45. }
  46. return $pkg;
  47. }
  48. # convert filepath to class:
  49. # sys.cli.output => \sys\cli\output
  50. # sys/cli/output.php => ^
  51. function filetoclass(string $path): string
  52. {
  53. if (substr($path, -4) === '.php') { $path = substr($path, 0, -4); }
  54. return '\\'.str_replace(['.', '/'], '\\', $path);
  55. }
  56. # determine if script is running in command line
  57. function is_cli()
  58. {
  59. return php_sapi_name() === 'cli' || defined('STDIN');
  60. }
  61. # output a variable as: <pre>print_r($variable)</pre> (this is only for debugging)
  62. # this will die after dumping variables on screen
  63. function dump()
  64. {
  65. die(call_user_func_array('dump_r', func_get_args()));
  66. }
  67. # dump, but don't die - echo results instead
  68. function dump_e()
  69. {
  70. echo call_user_func_array('dump_r', func_get_args());
  71. }
  72. # dump, but don't die - fwrite STDOUT results
  73. function dump_s()
  74. {
  75. if (!defined('STDOUT')) {
  76. trigger_error("Cannot use `dump_s` when not running in CLI!", E_USER_ERROR);
  77. }
  78. fwrite(STDOUT, call_user_func_array('dump_r', func_get_args()));
  79. fwrite(STDOUT, PHP_EOL);
  80. flush();
  81. }
  82. # dump, but don't die - return results instead
  83. function dump_r()
  84. {
  85. $arguments = func_get_args();
  86. $result = '';
  87. foreach ($arguments as $variable)
  88. {
  89. if (is_bool($variable)) {
  90. $bool = $variable ? 'true' : 'false';
  91. } else {
  92. $bool = false;
  93. }
  94. $result .= (!is_cli()) ? "\n<pre>\n" : "\n";
  95. $result .= '' . gettype($variable);
  96. $result .= (is_string($variable) ? '['.strlen($variable).']' : '');
  97. $result .= ': ' . (is_bool($variable) ? $bool : print_r($variable, true));
  98. $result .= (!is_cli()) ? "\n</pre>\n" : "\n";
  99. }
  100. return $result;
  101. }
  102. # query array element by a string path. my.key.value
  103. function arr_path($arr, $path, $default=null)
  104. {
  105. $path = trim($path, '.');
  106. $path = explode('.', $path);
  107. $get = $arr;
  108. foreach ($path as $w)
  109. {
  110. if (is_array($get) && array_key_exists($w, $get)) $get = $get[$w];
  111. else return $default;
  112. }
  113. return $get;
  114. }
  115. # create a designated scope, example:
  116. # $sum = using(12, 40, function($a, $b) { return $a + $b; });
  117. # return callback's results
  118. function using(...$args)
  119. {
  120. $f = array_pop($args);
  121. return call_user_func_array($f, $args);
  122. }
  123. # format generic exception message when parsing string
  124. # if $lines are array `err_lines` will be called, otherwise `err_char`
  125. function f_error($lines, int $current, string $message, string $file=null): string
  126. {
  127. return $message . "\n" .
  128. (is_array($lines)
  129. ? err_lines($lines, $current, 3)
  130. : err_char($lines, $current)).
  131. ($file ? "File: `{$file}`\n" : "\n");
  132. }
  133. # return -$padding, $current, +$padding lines for exceptions, for example:
  134. # 11. ::if true
  135. # >>12. {username|non_existant_function}
  136. # 13. ::/if
  137. # $current use negative to get lines from end of the list
  138. function err_lines(array $lines, int $current, int $padding=3): string
  139. {
  140. if ($current < 0) $current = count($lines)+$current;
  141. $start = $current - $padding;
  142. $end = $current + $padding;
  143. $result = '';
  144. for ($position = $start; $position <= $end; $position++)
  145. {
  146. if (isset($lines[$position])) {
  147. $result .= $position === $current ? '>>' : ' ';
  148. $result .= ($position+1).". {$lines[$position]}\n";
  149. }
  150. }
  151. return $result;
  152. }
  153. # mark particular character in line
  154. # example:
  155. # There's an error I require dot.
  156. # ----------------^--------------
  157. # $line full line
  158. # $at which character error occurred
  159. function err_char(string $line, string $at): string
  160. {
  161. $output = $line."\n";
  162. $output .= str_repeat(' ', $at);
  163. $output .= '^';
  164. return $output;
  165. }
  166. # output logs as an HTML
  167. function log_as_html(array $logs): string
  168. {
  169. $css_output = "width:100%;";
  170. $css_message = "width:100%; background:#234; color:#eee;";
  171. $output = <<<STYLE
  172. <style type="text/css">
  173. section.logs
  174. {
  175. width: 100%;
  176. }
  177. section.logs div.log-message
  178. {
  179. display: block;
  180. background: #0F181A;
  181. color: #999;
  182. border-bottom: 1px solid #444;
  183. padding: 10px;
  184. font-family: sans;
  185. font-size: 12px;
  186. }
  187. section.logs div.log-message span.message
  188. {
  189. font-family: monospace;
  190. font-size: 16px;
  191. display: block;
  192. margin-bottom: 10px;
  193. }
  194. section.logs div.log-message.type-debug span.message
  195. {
  196. color: #6e973d;
  197. }
  198. section.logs div.log-message.type-info span.message
  199. {
  200. color: #aee87b;
  201. }
  202. section.logs div.log-message.type-notice span.message
  203. {
  204. color: #ddb691;
  205. }
  206. section.logs div.log-message.type-warning span.message
  207. {
  208. color: #ed683b;
  209. }
  210. section.logs div.log-message.type-error span.message
  211. {
  212. color: #f23d3d;
  213. }
  214. section.logs div.log-message.type-panic span.message
  215. {
  216. color: #fcc;
  217. background: #893434;
  218. padding: 5px;
  219. border-radius: 4px;
  220. }
  221. section.logs div.log-message.type-panic span.message:before
  222. {
  223. content: "PANIC!!";
  224. font-weight: bold;
  225. font-size: 18px;
  226. display: block;
  227. }
  228. section.logs div.log-message span.type
  229. {
  230. display: none;
  231. }
  232. section.logs div.log-message span.from
  233. {
  234. padding-right: 10px;
  235. }
  236. </style>
  237. STYLE;
  238. $output .= '<section class="logs" />';
  239. foreach ($logs as $k => $log)
  240. {
  241. $output .= '<div class="log-message type-'.$log['type'].'">';
  242. $output .= '<span class="type">'.$log['type'].'</span>';
  243. $output .= '<span class="message">'.$log['message'].'</span>';
  244. $output .= '<span class="from">'.$log['from'].'</span>';
  245. $output .= '<span class="time">'.$log['timestamp'].'</span>';
  246. $output .= '</div>';
  247. }
  248. $output .= '</section>';
  249. return $output;
  250. }