PluginProbe
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress / 10.11.1
AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress v10.11.1
11.1.1 11.1.0 11.0.5 11.0.4 11.0.3 11.0.2 11.0.1 11.0.0 10.11.1 10.11.0 10.10.2 10.10.1 10.10.0 10.9.1 trunk 10.0.0 10.0.1 10.1.0 10.1.1 10.1.2 10.1.3 10.1.4 10.2.0 10.2.1 10.2.2 All 62 releases
acymailing / back / Helpers / global / file.php

file.php in AcyMailing – An Ultimate Newsletter Plugin and Marketing Automation Solution for WordPress 10.11.1, at back/Helpers/global/file.php

746 lines 22.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 use AcyMailing\Helpers\ImageHelper;
4
5 function acym_bytes(string $val): int
6 {
7 $val = trim($val);
8 if (empty($val)) {
9 return 0;
10 }
11 $last = strtolower($val[strlen($val) - 1]);
12 switch ($last) {
13 case 'g':
14 $val = intval($val) * 1073741824;
15 break;
16 case 'm':
17 $val = intval($val) * 1048576;
18 break;
19 case 'k':
20 $val = intval($val) * 1024;
21 break;
22 }
23
24 return (int)$val;
25 }
26
27 function acym_createDir(string $dir, bool $report = true, bool $secured = false): bool
28 {
29 if (is_dir($dir)) {
30 return true;
31 }
32
33 $indexhtml = '<html><body bgcolor="#FFFFFF"></body></html>';
34
35 try {
36 $status = acym_createFolder($dir);
37 } catch (Exception $e) {
38 $status = false;
39 }
40
41 if (!$status) {
42 if ($report) {
43 acym_display('Could not create the directory '.$dir, 'error');
44 }
45
46 return false;
47 }
48
49 try {
50 $status = acym_writeFile($dir.DS.'index.html', $indexhtml);
51 } catch (Exception $e) {
52 $status = false;
53 }
54
55 if (!$status && $report) {
56 acym_display('Could not create the file '.$dir.DS.'index.html', 'error');
57 }
58
59 if ($secured) {
60 try {
61 $htaccess = 'Order deny,allow'."\r\n".'Deny from all';
62 $status = acym_writeFile($dir.DS.'.htaccess', $htaccess);
63 } catch (Exception $e) {
64 $status = false;
65 }
66
67 if (!$status && $report) {
68 acym_display('Could not create the file '.$dir.DS.'.htaccess', 'error');
69 }
70 }
71
72 return $status;
73 }
74
75 function acym_importFile(array $file, string $uploadPath, bool $onlyPict): ?string
76 {
77 acym_checkToken();
78
79 $config = acym_config();
80 $additionalMsg = '';
81
82 if ($file['error'] > 0) {
83 $file['error'] = intval($file['error']);
84 if ($file['error'] > 8) {
85 $file['error'] = 0;
86 }
87
88 $phpFileUploadErrors = [
89 0 => 'Unknown error',
90 1 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini',
91 2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
92 3 => 'The uploaded file was only partially uploaded',
93 4 => 'No file was uploaded',
94 6 => 'Missing a temporary folder',
95 7 => 'Failed to write file to disk',
96 8 => 'A PHP extension stopped the file upload',
97 ];
98
99 acym_enqueueMessage(acym_translationSprintf('ACYM_ERROR_UPLOADING_FILE_X', $phpFileUploadErrors[$file['error']]), 'error');
100
101 return null;
102 }
103
104 acym_createDir($uploadPath, true);
105
106 if (!is_writable($uploadPath)) {
107 @chmod($uploadPath, '0755');
108 if (!is_writable($uploadPath)) {
109 acym_display(acym_translationSprintf('ACYM_WRITABLE_FOLDER', $uploadPath), 'error');
110
111 return null;
112 }
113 }
114
115 if ($onlyPict) {
116 $allowedExtensions = ['png', 'jpeg', 'jpg', 'gif', 'ico', 'bmp'];
117 } else {
118 $allowedExtensions = explode(',', $config->get('allowed_files'));
119 }
120
121 if (!preg_match('#\.('.implode('|', $allowedExtensions).')$#Ui', $file['name'], $extension)) {
122 $ext = substr($file['name'], strrpos($file['name'], '.') + 1);
123 acym_display(
124 acym_translationSprintf(
125 'ACYM_ACCEPTED_TYPE',
126 acym_escape($ext),
127 implode(', ', $allowedExtensions)
128 ),
129 'error'
130 );
131
132 return null;
133 }
134
135 if (preg_match('#\.(php.?|.?htm.?|pl|py|jsp|asp|sh|cgi)#Ui', $file['name'])) {
136 acym_display(
137 'This extension name is blocked by the system regardless your configuration for security reasons',
138 'error'
139 );
140
141 return null;
142 }
143
144 $file['name'] = str_replace(
145 ['-', '.', ' ', '\''],
146 '_',
147 substr($file['name'], 0, strrpos($file['name'], '.'))
148 ).'.'.$extension[1];
149
150 if ($onlyPict) {
151 $imageSize = @getimagesize($file['tmp_name']);
152 if (empty($imageSize)) {
153 acym_display(acym_translation('ACYM_INVALID_IMAGE'), 'error');
154
155 return null;
156 }
157 }
158
159 if (file_exists($uploadPath.DS.$file['name'])) {
160 $i = 1;
161 $nameFile = preg_replace('/\\.[^.\\s]{3,4}$/', '', $file['name']);
162 $ext = substr($file['name'], strrpos($file['name'], '.') + 1);
163 while (file_exists($uploadPath.DS.$nameFile.'_'.$i.'.'.$ext)) {
164 $i++;
165 }
166
167 $file['name'] = $nameFile.'_'.$i.'.'.$ext;
168 $additionalMsg = '<br />'.acym_translationSprintf('ACYM_FILE_RENAMED', $file['name']);
169 if ($onlyPict) {
170 $additionalMsg .= '<br /><a style="color: blue; cursor: pointer;" onclick="confirmBox(\'rename\', \''.$file['name'].'\', \''.$nameFile.'.'.$ext.'\')">'.acym_translation(
171 'ACYM_RENAME_OR_REPLACE'
172 ).'</a>';
173 }
174 }
175
176 if (!acym_uploadFile($file['tmp_name'], rtrim($uploadPath, DS).DS.$file['name'])) {
177 if (!move_uploaded_file($file['tmp_name'], rtrim($uploadPath, DS).DS.$file['name'])) {
178 acym_display(
179 acym_translationSprintf(
180 'ACYM_FAIL_UPLOAD',
181 '<b><i>'.acym_escape($file['tmp_name']).'</i></b>',
182 '<b><i>'.acym_escape(rtrim($uploadPath, DS).DS.$file['name']).'</i></b>'
183 ),
184 'error'
185 );
186
187 return null;
188 }
189 }
190
191 if ($onlyPict && $imageSize[0] > 1000) {
192 $imageHelper = new ImageHelper();
193 if ($imageHelper->available()) {
194 $imageHelper->maxHeight = 9999;
195 $imageHelper->maxWidth = 700;
196 $message = 'ACYM_IMAGE_RESIZED';
197 $imageHelper->destination = $uploadPath;
198 $thumb = $imageHelper->generateThumbnail(rtrim($uploadPath, DS).DS.$file['name']);
199 if (!empty($thumb)) {
200 acym_moveFile($thumb['file'], $uploadPath.DS.$file['name']);
201 $additionalMsg .= '<br />'.acym_translation($message);
202 }
203 }
204 }
205 acym_enqueueMessage(acym_translation('ACYM_SUCCESS_FILE_UPLOAD').$additionalMsg, 'success');
206
207 return $file['name'];
208 }
209
210 function acym_inputFile(string $name, string $value = '', string $class = '', string $attributes = '', string $downloadUrl = ''): string
211 {
212 $hasValue = !empty($value);
213 $actionStyle = $hasValue ? '' : ' style="display: none;"';
214 $noFileText = acym_translation('ACYM_NO_FILE_CHOSEN');
215 $baseName = substr($name, -2) === '[]' ? substr($name, 0, -2) : $name;
216
217 $downloadAttr = !empty($downloadUrl) ? ' data-download-url="'.acym_escapeUrl($downloadUrl).'"' : '';
218
219 $return = '</label><div class="cell '.acym_escape($class).' grid-x acym__input__file__container">';
220 $return .= '<input type="hidden" name="'.acym_escape($baseName).'" value="'.acym_escape($value).'" class="acym__input__file__clear">';
221 $return .= '<input '.$attributes.' style="display: none" type="file" name="'.acym_escape($name).'">';
222 $return .= '<button type="button" class="acym__button__file button button-secondary cell shrink">'.acym_translation('ACYM_CHOOSE_FILE').'</button>';
223 $return .= '<span class="cell shrink margin-left-2 margin-right-2 acym__input__file__name" data-no-file="'.acym_escape($noFileText).'">';
224 $return .= acym_escape($hasValue ? $value : $noFileText);
225 $return .= '</span>';
226 $return .= '<i class="acym__input__file__download cell shrink acym__color__blue cursor-pointer acymicon-download margin-right-1"'.$actionStyle.$downloadAttr.
227 ' title="'.acym_escape(acym_translation('ACYM_DOWNLOAD')).'" aria-label="'.acym_escape(acym_translation('ACYM_DOWNLOAD')).'"></i>';
228 $return .= '<i class="acymicon-close acym__color__red acym__input__file__delete cursor-pointer cell shrink margin-left-1"'.$actionStyle.
229 ' title="'.acym_escape(acym_translation('ACYM_DELETE')).'" aria-label="'.acym_escape(acym_translation('ACYM_DELETE')).'"></i>';
230 $return .= '</div>';
231
232 return $return;
233 }
234
235 function acym_getFilesFolder(bool $ignoreVariables = false): string
236 {
237 $config = acym_config();
238 $uploadFolder = $config->get('uploadfolder', ACYM_UPLOAD_FOLDER);
239 if ($ignoreVariables) {
240 $uploadFolder = str_replace(['{userid}', '{groupname}', '{year}', '{month}', '{day}'], '', $uploadFolder);
241 }
242 $uploadFolder = trim($uploadFolder, '/');
243
244 $uploadFolder = str_replace('{userid}', acym_currentUserId(), $uploadFolder);
245 $uploadFolder = str_replace('{year}', date('Y'), $uploadFolder);
246 $uploadFolder = str_replace('{month}', date('m'), $uploadFolder);
247 $uploadFolder = str_replace('{day}', date('d'), $uploadFolder);
248
249 return acym_replaceGroupTags($uploadFolder);
250 }
251
252 function acym_generateArborescence(array $folders): array
253 {
254 $folderList = [];
255 foreach ($folders as $folder) {
256 $folderPath = acym_cleanPath(ACYM_ROOT.trim(str_replace('/', DS, trim($folder)), DS));
257 if (!file_exists($folderPath)) {
258 acym_createDir($folderPath);
259 }
260 $subFolders = acym_listFolderTree($folderPath, '', 15);
261 $folderList[$folder] = [];
262 foreach ($subFolders as $oneFolder) {
263 $subFolder = str_replace(ACYM_ROOT, '', $oneFolder['relname']);
264 $subFolder = str_replace(DS, '/', $subFolder);
265 $folderList[$folder][$subFolder] = ltrim($subFolder, '/');
266 }
267 $folderList[$folder] = array_unique($folderList[$folder]);
268 }
269
270 return $folderList;
271 }
272
273 function acym_makeSafeFile(string $file): string
274 {
275 $file = rtrim($file, '.');
276 $regex = ['#(\.){2,}#', '#[^A-Za-z0-9\.\_\- ]#', '#^\.#'];
277
278 return trim(preg_replace($regex, '', $file));
279 }
280
281 function acym_deleteFolder(string $path, bool $report = true): bool
282 {
283 $path = acym_cleanPath($path);
284 if (!is_dir($path)) {
285 if ($report) acym_enqueueMessage(acym_translationSprintf('ACYM_IS_NOT_A_FOLDER', $path), 'error');
286
287 return false;
288 }
289
290 $files = acym_getFiles($path, '.', false, false, [], []);
291 if (!empty($files)) {
292 foreach ($files as $oneFile) {
293 if (!acym_deleteFile($path.DS.$oneFile, $report)) {
294 return false;
295 }
296 }
297 }
298
299 $folders = acym_getFolders($path, '.', false, false, []);
300 if (!empty($folders)) {
301 foreach ($folders as $oneFolder) {
302 if (!acym_deleteFolder($path.DS.$oneFolder, $report)) {
303 return false;
304 }
305 }
306 }
307
308 if (@rmdir($path)) {
309 return true;
310 } else {
311 if ($report) acym_enqueueMessage(acym_translationSprintf('ACYM_COULD_NOT_DELETE_FOLDER', $path), 'error');
312
313 return false;
314 }
315 }
316
317 function acym_createFolder(string $path = '', int $mode = 0755): bool
318 {
319 $path = acym_cleanPath($path);
320 if (file_exists($path)) {
321 return true;
322 }
323
324 $origmask = @umask(0);
325 $ret = @mkdir($path, $mode, true);
326 @umask($origmask);
327
328 return $ret;
329 }
330
331 function acym_getFolders(
332 string $path,
333 string $filter = '.',
334 bool $recurse = false,
335 bool $full = false,
336 array $exclude = ['.svn', 'CVS', '.DS_Store', '__MACOSX'],
337 array $excludefilter = ['^\..*']
338 ): array {
339 $path = acym_cleanPath($path);
340
341 if (!is_dir($path)) {
342 acym_enqueueMessage(acym_translationSprintf('ACYM_IS_NOT_A_FOLDER', $path), 'error');
343
344 return [];
345 }
346
347 if (count($excludefilter)) {
348 $excludefilter_string = '/('.implode('|', $excludefilter).')/';
349 } else {
350 $excludefilter_string = '';
351 }
352
353 $arr = acym_getItems($path, $filter, $recurse, $full, $exclude, $excludefilter_string, false);
354 asort($arr);
355
356 return array_values($arr);
357 }
358
359 function acym_getFiles(
360 string $path,
361 string $filter = '.',
362 bool $recurse = false,
363 bool $full = false,
364 array $exclude = ['.svn', 'CVS', '.DS_Store', '__MACOSX'],
365 array $excludefilter = [
366 '^\..*',
367 '.*~',
368 ],
369 bool $naturalSort = false
370 ): array {
371 $path = acym_cleanPath($path);
372
373 if (!is_dir($path)) {
374 acym_enqueueMessage(acym_translationSprintf('ACYM_IS_NOT_A_FOLDER', $path), 'error');
375
376 return [];
377 }
378
379 if (count($excludefilter)) {
380 $excludefilter_string = '/('.implode('|', $excludefilter).')/';
381 } else {
382 $excludefilter_string = '';
383 }
384
385 $arr = acym_getItems($path, $filter, $recurse, $full, $exclude, $excludefilter_string, true);
386
387 if ($naturalSort) {
388 natsort($arr);
389 } else {
390 asort($arr);
391 }
392
393 return array_values($arr);
394 }
395
396 function acym_getItems(
397 string $path,
398 string $filter,
399 bool $recurse,
400 bool $full,
401 array $exclude,
402 string $excludefilter_string,
403 bool $findfiles
404 ): array {
405 $arr = [];
406
407 if (!($handle = @opendir($path))) {
408 return $arr;
409 }
410
411 while (($file = readdir($handle)) !== false) {
412 if (
413 $file == '.'
414 || $file == '..'
415 || in_array($file, $exclude)
416 || (!empty($excludefilter_string) && preg_match($excludefilter_string, $file))
417 ) {
418 continue;
419 }
420 $fullpath = rtrim($path, '/').'/'.$file;
421
422 $isDir = is_dir($fullpath);
423
424 if (($isDir xor $findfiles) && preg_match("/$filter/", $file)) {
425 if ($full) {
426 $arr[] = $fullpath;
427 } else {
428 $arr[] = $file;
429 }
430 }
431
432 if ($isDir && $recurse) {
433 $arr = array_merge(
434 $arr,
435 acym_getItems(
436 $fullpath,
437 $filter,
438 true,
439 $full,
440 $exclude,
441 $excludefilter_string,
442 $findfiles
443 )
444 );
445 }
446 }
447
448 closedir($handle);
449
450 return $arr;
451 }
452
453 function acym_copyFolder(string $src, string $dest, ?string $path = null, bool $force = false, bool $use_streams = false): bool
454 {
455 if (!empty($path)) {
456 $src = acym_cleanPath($path.'/'.$src);
457 $dest = acym_cleanPath($path.'/'.$dest);
458 }
459
460 $src = rtrim($src, DIRECTORY_SEPARATOR);
461 $dest = rtrim($dest, DIRECTORY_SEPARATOR);
462
463 if (!file_exists($src)) {
464 acym_enqueueMessage(acym_translationSprintf('ACYM_FOLDER_DOES_NOT_EXIST', $src), 'error');
465
466 return false;
467 }
468
469 if (file_exists($dest) && !$force) {
470 acym_enqueueMessage(acym_translationSprintf('ACYM_FOLDER_ALREADY_EXIST', $dest), 'error');
471
472 return true;
473 }
474
475 if (!acym_createFolder($dest)) {
476 acym_enqueueMessage(acym_translation('ACYM_CANNOT_CREATE_DESTINATION_FOLDER'), 'error');
477
478 return false;
479 }
480
481 if (!($dh = @opendir($src))) {
482 acym_enqueueMessage(acym_translation('ACYM_CANNOT_OPEN_SOURCE_FOLDER'), 'error');
483
484 return false;
485 }
486
487 while (($file = readdir($dh)) !== false) {
488 $sfid = $src.'/'.$file;
489 $dfid = $dest.'/'.$file;
490
491 switch (filetype($sfid)) {
492 case 'dir':
493 if ($file != '.' && $file != '..') {
494 $ret = acym_copyFolder($sfid, $dfid, null, $force, $use_streams);
495
496 if ($ret !== true) {
497 return $ret;
498 }
499 }
500 break;
501
502 case 'file':
503 if (!@copy($sfid, $dfid)) {
504 acym_enqueueMessage(acym_translationSprintf('ACYM_COPY_FILE_FAILED_PERMISSION', $sfid), 'error');
505
506 return false;
507 }
508 break;
509 }
510 }
511
512 return true;
513 }
514
515 function acym_listFolderTree(string $path, string $filter, int $maxLevel = 3, int $level = 0, int $parent = 0): array
516 {
517 $dirs = [];
518
519 if ($level === 0) {
520 $GLOBALS['acym_folder_tree_index'] = 0;
521 }
522
523 if ($level < $maxLevel) {
524 $folders = acym_getFolders($path, $filter);
525
526 foreach ($folders as $name) {
527 $id = ++$GLOBALS['acym_folder_tree_index'];
528 $fullName = acym_cleanPath($path.'/'.$name);
529 $dirs[] = [
530 'id' => $id,
531 'parent' => $parent,
532 'name' => $name,
533 'fullname' => $fullName,
534 'relname' => str_replace(ACYM_ROOT, '', $fullName),
535 ];
536 $dirs2 = acym_listFolderTree($fullName, $filter, $maxLevel, $level + 1, $id);
537 $dirs = array_merge($dirs, $dirs2);
538 }
539 }
540
541 return $dirs;
542 }
543
544 function acym_deleteFile(string $file, bool $report = true): bool
545 {
546 $file = acym_cleanPath($file);
547 if (!is_file($file)) {
548 if ($report) acym_enqueueMessage(acym_translationSprintf('ACYM_IS_NOT_A_FILE', $file), 'error');
549
550 return false;
551 }
552
553 @chmod($file, 0777);
554
555 if (!@unlink($file)) {
556 $filename = basename($file);
557 if ($report) acym_enqueueMessage(acym_translationSprintf('ACYM_FAILED_DELETE', $filename), 'error');
558
559 return false;
560 }
561
562 return true;
563 }
564
565 function acym_writeFile(string $file, $buffer, int $flags = 0): bool
566 {
567 if (!file_exists(dirname($file)) && !acym_createFolder(dirname($file))) {
568 return false;
569 }
570
571 $file = acym_cleanPath($file);
572
573 return is_int(file_put_contents($file, $buffer, $flags));
574 }
575
576 function acym_moveFile(string $src, string $dest, string $path = ''): bool
577 {
578 if (!empty($path)) {
579 $src = acym_cleanPath($path.'/'.$src);
580 $dest = acym_cleanPath($path.'/'.$dest);
581 }
582
583 if (!is_readable($src)) {
584 acym_enqueueMessage(acym_translationSprintf('ACYM_COULD_NOT_FIND_FILE_SOURCE_PERMISSION', $src), 'error');
585
586 return false;
587 }
588
589 if (!@rename($src, $dest)) {
590 acym_enqueueMessage(acym_translation('ACYM_COULD_NOT_MOVE_FILE'), 'error');
591
592 return false;
593 }
594
595 return true;
596 }
597
598 function acym_uploadFile(string $src, string $dest): bool
599 {
600 $dest = acym_cleanPath($dest);
601
602 $baseDir = dirname($dest);
603 if (!file_exists($baseDir)) {
604 acym_createFolder($baseDir);
605 }
606
607 if (is_writeable($baseDir) && move_uploaded_file($src, $dest)) {
608 if (@chmod($dest, octdec('0644'))) {
609 return true;
610 } else {
611 acym_enqueueMessage(acym_translation('ACYM_FILE_REJECTED_SAFETY_REASON'), 'error');
612 }
613 } else {
614 acym_enqueueMessage(acym_translationSprintf('ACYM_COULD_NOT_UPLOAD_FILE_PERMISSION', $baseDir), 'error');
615 }
616
617 return false;
618 }
619
620 function acym_copyFile(string $src, string $dest, string $path = ''): bool
621 {
622 if (!empty($path)) {
623 $src = acym_cleanPath($path.DS.$src);
624 $dest = acym_cleanPath($path.DS.$dest);
625 }
626
627 if (!is_readable($src)) {
628 acym_enqueueMessage(acym_translationSprintf('ACYM_COULD_NOT_FIND_FILE_SOURCE_PERMISSION', $src), 'error');
629
630 return false;
631 }
632
633 if (!@copy($src, $dest)) {
634 acym_enqueueMessage(acym_translationSprintf('ACYM_COULD_NOT_COPY_FILE_X_TO_X', $src, $dest), 'error');
635
636 return false;
637 }
638
639 return true;
640 }
641
642 function acym_fileGetExt(string $file): string
643 {
644 $pathInfo = pathinfo($file);
645
646 return empty($pathInfo['extension']) ? '' : strtolower($pathInfo['extension']);
647 }
648
649 function acym_cleanPath(string $path, string $ds = DIRECTORY_SEPARATOR): string
650 {
651 $path = trim($path);
652
653 if (empty($path)) {
654 $path = ACYM_ROOT;
655 } elseif (($ds === '\\') && substr($path, 0, 2) == '\\\\') {
656 $path = "\\".preg_replace('#[/\\\\]+#', $ds, $path);
657 } else {
658 $path = preg_replace('#[/\\\\]+#', $ds, $path);
659 }
660
661 return $path;
662 }
663
664 function acym_createArchive(string $name, array $files): bool
665 {
666 $contents = [];
667 $ctrldir = [];
668
669 $timearray = getdate();
670 $dostime = (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
671 $dtime = dechex($dostime);
672 $hexdtime = chr(hexdec($dtime[6].$dtime[7])).chr(hexdec($dtime[4].$dtime[5])).chr(hexdec($dtime[2].$dtime[3])).chr(
673 hexdec($dtime[0].$dtime[1])
674 );
675
676 foreach ($files as $file) {
677 $data = $file['data'];
678 $filename = str_replace('\\', '/', $file['name']);
679
680 $fr = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00".$hexdtime;
681
682 $unc_len = strlen($data);
683 $crc = crc32($data);
684 $zdata = gzcompress($data);
685 $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2);
686 $c_len = strlen($zdata);
687
688 $fr .= pack('V', $crc).pack('V', $c_len).pack('V', $unc_len).pack('v', strlen($filename)).pack(
689 'v',
690 0
691 ).$filename.$zdata;
692
693 $old_offset = strlen(implode('', $contents));
694 $contents[] = $fr;
695
696 $cdrec = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00".$hexdtime;
697 $cdrec .= pack('V', $crc).pack('V', $c_len).pack('V', $unc_len).pack('v', strlen($filename)).pack('v', 0).pack(
698 'v',
699 0
700 ).pack('v', 0).pack('v', 0).pack('V', 32).pack('V', $old_offset).$filename;
701
702 $ctrldir[] = $cdrec;
703 }
704
705 $data = implode('', $contents);
706 $dir = implode('', $ctrldir);
707 $buffer = $data.$dir."\x50\x4b\x05\x06\x00\x00\x00\x00".pack('v', count($ctrldir)).pack('v', count($ctrldir)).pack(
708 'V',
709 strlen($dir)
710 ).pack('V', strlen($data))."\x00\x00";
711
712 return acym_writeFile($name.'.zip', $buffer);
713 }
714
715 function acym_loaderLogo(bool $wrap = true): string
716 {
717 $loader = '';
718 if ($wrap) {
719 $loader .= '<div class="cell shrink acym_loader_logo">';
720 }
721
722 $loader .= '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="80" height="80" viewBox="0 0 1024 1024">
723 <path class="acym__svg__loader" fill="#a6a9ab" d="M553.074 174.168c-12.201 7.319-26.84 10.573-40.668 10.573s-27.655-3.253-40.668-10.573l-242.376-139.081-229.362 132.575v732.011l254.576 143.963v-430.26l219.602 124.442c11.388 6.507 24.401 9.76 37.415 9.76 0 0 0 0 0 0s0 0 0 0c12.201 0 25.214-3.253 36.6-9.76l221.23-124.442v430.26l254.576-144.775v-732.011l-229.362-131.762-241.563 139.081zM491.261 701.215l-217.164-122.815-61.001-34.161v430.26l-173.243-97.601v-662.063l422.94 245.629c0 0 0 0 0 0 8.947 4.881 17.895 8.135 27.655 10.573v230.178zM983.334 876.086l-173.243 98.416v-431.073l-61.001 34.161-217.164 122.815v-229.362c9.76-2.441 18.707-5.694 27.655-10.573l423.753-246.444v662.063zM539.246 425.493c-17.080 9.76-38.227 9.76-55.307 0 0 0 0 0 0 0l-422.94-245.629 168.362-97.601 222.043 127.696c18.707 10.573 39.853 16.267 61.001 16.267s42.294-5.694 61.001-16.267l222.043-127.696 168.362 97.601-424.566 245.629z"></path>
724 </svg>';
725
726 if ($wrap) {
727 $loader .= '</div>';
728 }
729
730 return $loader;
731 }
732
733 function acym_fileNameValid(string $filename): bool
734 {
735 if (empty($filename)) return false;
736
737 if (strpos($filename, '..') !== false || strpos($filename, '/') !== false || strpos($filename, '\\') !== false) return false;
738
739 return true;
740 }
741
742 function acym_getImageFileExtensions(): array
743 {
744 return ['jpg', 'jpeg', 'png', 'gif', 'ico', 'bmp', 'svg'];
745 }
746