helpers.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. <?php
  2. use Psr\Http\Message\ResponseInterface as Response;
  3. use Psr\Http\Message\ServerRequestInterface as Request;
  4. use Slim\Factory\ServerRequestCreatorFactory;
  5. if (!defined('HUMAN_RANDOM_CHARS')) {
  6. define('HUMAN_RANDOM_CHARS', 'bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZaeiouAEIOU');
  7. }
  8. if (!function_exists('humanFileSize')) {
  9. /**
  10. * Generate a human readable file size.
  11. *
  12. * @param $size
  13. * @param int $precision
  14. *
  15. * @param bool $iniMode
  16. * @return string
  17. */
  18. function humanFileSize($size, $precision = 2, $iniMode = false): string
  19. {
  20. for ($i = 0; ($size / 1024) > 0.9; $i++, $size /= 1024) {
  21. }
  22. if ($iniMode) {
  23. return round($size, $precision).['B', 'K', 'M', 'G', 'T'][$i];
  24. }
  25. return round($size, $precision).' '.['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'][$i];
  26. }
  27. }
  28. if (!function_exists('humanRandomString')) {
  29. /**
  30. * @param int $length
  31. *
  32. * @return string
  33. */
  34. function humanRandomString(int $length = 10): string
  35. {
  36. $result = '';
  37. $numberOffset = round($length * 0.2);
  38. for ($x = 0; $x < $length - $numberOffset; $x++) {
  39. $result .= ($x % 2) ? HUMAN_RANDOM_CHARS[rand(42, 51)] : HUMAN_RANDOM_CHARS[rand(0, 41)];
  40. }
  41. for ($x = 0; $x < $numberOffset; $x++) {
  42. $result .= rand(0, 9);
  43. }
  44. return $result;
  45. }
  46. }
  47. if (!function_exists('isDisplayableImage')) {
  48. /**
  49. * @param string $mime
  50. *
  51. * @return bool
  52. */
  53. function isDisplayableImage(string $mime): bool
  54. {
  55. return in_array($mime, [
  56. 'image/apng',
  57. 'image/bmp',
  58. 'image/gif',
  59. 'image/x-icon',
  60. 'image/jpeg',
  61. 'image/png',
  62. 'image/svg',
  63. 'image/svg+xml',
  64. 'image/tiff',
  65. 'image/webp',
  66. ]);
  67. }
  68. }
  69. if (!function_exists('stringToBytes')) {
  70. /**
  71. * @param $str
  72. *
  73. * @return float
  74. */
  75. function stringToBytes(string $str): float
  76. {
  77. $val = trim($str);
  78. if (is_numeric($val)) {
  79. return (float) $val;
  80. }
  81. $last = strtolower($val[strlen($val) - 1]);
  82. $val = substr($val, 0, -1);
  83. $val = (float) $val;
  84. switch ($last) {
  85. case 't':
  86. $val *= 1024;
  87. case 'g':
  88. $val *= 1024;
  89. case 'm':
  90. $val *= 1024;
  91. case 'k':
  92. $val *= 1024;
  93. }
  94. return $val;
  95. }
  96. }
  97. if (!function_exists('removeDirectory')) {
  98. /**
  99. * Remove a directory and it's content.
  100. *
  101. * @param $path
  102. */
  103. function removeDirectory($path)
  104. {
  105. $files = glob($path.'/*');
  106. foreach ($files as $file) {
  107. is_dir($file) ? removeDirectory($file) : unlink($file);
  108. }
  109. rmdir($path);
  110. }
  111. }
  112. if (!function_exists('cleanDirectory')) {
  113. /**
  114. * Removes all directory contents.
  115. *
  116. * @param $path
  117. */
  118. function cleanDirectory($path)
  119. {
  120. $directoryIterator = new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS);
  121. $iteratorIterator = new RecursiveIteratorIterator($directoryIterator, RecursiveIteratorIterator::CHILD_FIRST);
  122. foreach ($iteratorIterator as $file) {
  123. if ($file->getFilename() !== '.gitkeep') {
  124. $file->isDir() ? rmdir($file) : unlink($file);
  125. }
  126. }
  127. }
  128. }
  129. if (!function_exists('resolve')) {
  130. /**
  131. * Resolve a service from de DI container.
  132. *
  133. * @param string $service
  134. *
  135. * @return mixed
  136. */
  137. function resolve(string $service)
  138. {
  139. global $app;
  140. return $app->getContainer()->get($service);
  141. }
  142. }
  143. if (!function_exists('make')) {
  144. /**
  145. * Resolve a service from de DI container.
  146. *
  147. * @param string $class
  148. * @param array $params
  149. * @return mixed
  150. */
  151. function make(string $class, array $params = [])
  152. {
  153. global $app;
  154. return $app->getContainer()->make($class, $params);
  155. }
  156. }
  157. if (!function_exists('view')) {
  158. /**
  159. * Render a view to the response body.
  160. *
  161. * @return \App\Web\View
  162. */
  163. function view()
  164. {
  165. return resolve('view');
  166. }
  167. }
  168. if (!function_exists('redirect')) {
  169. /**
  170. * Set the redirect response.
  171. *
  172. * @param Response $response
  173. * @param string $url
  174. * @param int $status
  175. *
  176. * @return Response
  177. */
  178. function redirect(Response $response, string $url, $status = 302)
  179. {
  180. return $response
  181. ->withHeader('Location', $url)
  182. ->withStatus($status);
  183. }
  184. }
  185. if (!function_exists('asset')) {
  186. /**
  187. * Get the asset link with timestamp.
  188. *
  189. * @param string $path
  190. *
  191. * @return string
  192. */
  193. function asset(string $path): string
  194. {
  195. return urlFor($path, '?'.filemtime(realpath(BASE_DIR.$path)));
  196. }
  197. }
  198. if (!function_exists('urlFor')) {
  199. /**
  200. * Generate the app url given a path.
  201. *
  202. * @param string $path
  203. * @param string $append
  204. *
  205. * @return string
  206. */
  207. function urlFor(string $path = '', string $append = ''): string
  208. {
  209. $baseUrl = resolve('config')['base_url'];
  210. return $baseUrl.$path.$append;
  211. }
  212. }
  213. if (!function_exists('route')) {
  214. /**
  215. * Generate the app url given a path.
  216. *
  217. * @param string $path
  218. * @param array $args
  219. * @param string $append
  220. *
  221. * @return string
  222. */
  223. function route(string $path, array $args = [], string $append = ''): string
  224. {
  225. global $app;
  226. $uri = $app->getRouteCollector()->getRouteParser()->relativeUrlFor($path, $args);
  227. return urlFor($uri, $append);
  228. }
  229. }
  230. if (!function_exists('param')) {
  231. /**
  232. * Get a parameter from the request.
  233. *
  234. * @param Request $request
  235. * @param string $name
  236. * @param null $default
  237. *
  238. * @return string
  239. */
  240. function param(Request $request, string $name, $default = null)
  241. {
  242. if ($request->getMethod() === 'GET') {
  243. $params = $request->getQueryParams();
  244. } else {
  245. $params = $request->getParsedBody();
  246. }
  247. if (isset($params[$name])) {
  248. return $params[$name];
  249. }
  250. return $default;
  251. }
  252. }
  253. if (!function_exists('json')) {
  254. /**
  255. * Return a json response.
  256. *
  257. * @param Response $response
  258. * @param $data
  259. * @param int $status
  260. * @param int $options
  261. *
  262. * @return Response
  263. */
  264. function json(Response $response, $data, int $status = 200, $options = 0): Response
  265. {
  266. $response->getBody()->write(json_encode($data, $options));
  267. return $response
  268. ->withStatus($status)
  269. ->withHeader('Content-Type', 'application/json');
  270. }
  271. }
  272. if (!function_exists('lang')) {
  273. /**
  274. * @param string $key
  275. * @param array $args
  276. *
  277. * @return string
  278. */
  279. function lang(string $key, $args = []): string
  280. {
  281. return resolve('lang')->get($key, $args);
  282. }
  283. }
  284. if (!function_exists('isBot')) {
  285. /**
  286. * @param string $userAgent
  287. *
  288. * @return bool
  289. */
  290. function isBot(string $userAgent)
  291. {
  292. $bots = [
  293. 'TelegramBot',
  294. 'facebookexternalhit/',
  295. 'Discordbot/',
  296. 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:38.0) Gecko/20100101 Firefox/38.0', // The discord service bot?
  297. 'Facebot',
  298. 'curl/',
  299. 'wget/',
  300. ];
  301. foreach ($bots as $bot) {
  302. if (stripos($userAgent, $bot) !== false) {
  303. return true;
  304. }
  305. }
  306. return false;
  307. }
  308. }
  309. if (!function_exists('mime2font')) {
  310. /**
  311. * Convert get the icon from the file mimetype.
  312. *
  313. * @param $mime
  314. *
  315. * @return mixed|string
  316. */
  317. function mime2font($mime)
  318. {
  319. $classes = [
  320. 'image' => 'fa-file-image',
  321. 'audio' => 'fa-file-audio',
  322. 'video' => 'fa-file-video',
  323. 'application/pdf' => 'fa-file-pdf',
  324. 'application/msword' => 'fa-file-word',
  325. 'application/vnd.ms-word' => 'fa-file-word',
  326. 'application/vnd.oasis.opendocument.text' => 'fa-file-word',
  327. 'application/vnd.openxmlformats-officedocument.wordprocessingml' => 'fa-file-word',
  328. 'application/vnd.ms-excel' => 'fa-file-excel',
  329. 'application/vnd.openxmlformats-officedocument.spreadsheetml' => 'fa-file-excel',
  330. 'application/vnd.oasis.opendocument.spreadsheet' => 'fa-file-excel',
  331. 'application/vnd.ms-powerpoint' => 'fa-file-powerpoint',
  332. 'application/vnd.openxmlformats-officedocument.presentationml' => 'fa-file-powerpoint',
  333. 'application/vnd.oasis.opendocument.presentation' => 'fa-file-powerpoint',
  334. 'text/plain' => 'fa-file-alt',
  335. 'text/html' => 'fa-file-code',
  336. 'text/x-php' => 'fa-file-code',
  337. 'application/json' => 'fa-file-code',
  338. 'application/gzip' => 'fa-file-archive',
  339. 'application/zip' => 'fa-file-archive',
  340. 'application/octet-stream' => 'fa-file-alt',
  341. ];
  342. foreach ($classes as $fullMime => $class) {
  343. if (strpos($mime, $fullMime) === 0) {
  344. return $class;
  345. }
  346. }
  347. return 'fa-file';
  348. }
  349. }
  350. if (!function_exists('dd')) {
  351. /**
  352. * Dumps all the given vars and halt the execution.
  353. */
  354. function dd()
  355. {
  356. array_map(function ($x) {
  357. echo '<pre>';
  358. print_r($x);
  359. echo '</pre>';
  360. }, func_get_args());
  361. die();
  362. }
  363. }
  364. if (!function_exists('queryParams')) {
  365. /**
  366. * Get the query parameters of the current request.
  367. *
  368. * @param array $replace
  369. *
  370. * @return string
  371. */
  372. function queryParams(array $replace = [])
  373. {
  374. $request = ServerRequestCreatorFactory::determineServerRequestCreator()->createServerRequestFromGlobals();
  375. $params = array_replace_recursive($request->getQueryParams(), $replace);
  376. return !empty($params) ? '?'.http_build_query($params) : '';
  377. }
  378. }
  379. if (!function_exists('inPath')) {
  380. /**
  381. * Check if uri start with a path.
  382. *
  383. * @param string $uri
  384. * @param string $path
  385. *
  386. * @return bool
  387. */
  388. function inPath(string $uri, string $path): bool
  389. {
  390. $path = parse_url(urlFor($path), PHP_URL_PATH);
  391. return substr($uri, 0, strlen($path)) === $path;
  392. }
  393. }
  394. if (!function_exists('glob_recursive')) {
  395. /**
  396. * Does not support flag GLOB_BRACE.
  397. *
  398. * @param $pattern
  399. * @param int $flags
  400. *
  401. * @return array|false
  402. */
  403. function glob_recursive($pattern, $flags = 0)
  404. {
  405. $files = glob($pattern, $flags);
  406. foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) {
  407. $files = array_merge($files, glob_recursive($dir.'/'.basename($pattern), $flags));
  408. }
  409. return $files;
  410. }
  411. }
  412. if (!function_exists('dsnFromConfig')) {
  413. /**
  414. * Return the database DSN from config.
  415. *
  416. * @param array $config
  417. *
  418. * @param string $baseDir
  419. * @return string
  420. */
  421. function dsnFromConfig(array $config, $baseDir = BASE_DIR): string
  422. {
  423. $dsn = $config['db']['connection'] === 'sqlite' ? $baseDir.$config['db']['dsn'] : $config['db']['dsn'];
  424. return $config['db']['connection'].':'.$dsn;
  425. }
  426. }
  427. if (!function_exists('platform_mail')) {
  428. /**
  429. * Return the system no-reply mail.
  430. *
  431. * @param string $mailbox
  432. * @return string
  433. */
  434. function platform_mail($mailbox = 'no-reply'): string
  435. {
  436. return $mailbox.'@'.str_ireplace('www.', '', parse_url(resolve('config')['base_url'], PHP_URL_HOST));
  437. }
  438. }