LEPTON CMS 7.4.0
feel free to keep it strictly simple...
Loading...
Searching...
No Matches
lepton_core.php
Go to the documentation of this file.
1<?php
2
3declare(strict_types=1);
4
21class LEPTON_core extends LEPTON_securecms
22{
24
25 public static $instance;
26
27 public string $string_secure = 'a-zA-Z0-9\-_\.';
28
29 public string $password_chars = 'a-zA-Z0-9\_\-\!\$\ย\ง\#\*\+';
30
31 public string $email_chars = 'a-zA-Z0-9@\_\-\.';
32
33 public string $username_chars = 'a-zA-Z0-9@ \_\-,\.';
34
35 public string $hex_chars = 'a-fA-F0-9\-';
36
37 public static array $HEADERS = [
38 'frontend' => [
39 'css' => [],
40 'js' => []
41 ],
42 'backend' => [
43 'css' => [],
44 'js' => []
45 ]
46 ];
47
48 public static array $FOOTERS = [
49 'frontend' => [
50 'css' => [],
51 'js' => []
52 ],
53 'backend' => [
54 'css' => [],
55 'js' => []
56 ]
57 ];
58
59 public static bool $bUserGotAdminRights = false;
60
61 public static array $aPageVisibility = ['public', 'private', 'registered', 'hidden', 'none'];
62
66 public function __construct()
67 {
68
69 }
70
79 public function page_is_visible( $page ): bool
80 {
81 // First check if visibility is 'none', 'deleted'
82
83 $show_it = false;
84 switch ($page['visibility'])
85 {
86 case 'hidden':
87 case 'public':
88 $show_it = true;
89 break;
90
91 case 'private':
92 case 'registered':
93 if ($this->is_authenticated() === true)
94 {
95 $show_it = ($this->is_group_match($this->getValue('groups_id', 'string', 'session',','), $page['viewing_groups']) );
96 }
97 break;
98
99 case 'none':
100 case 'deleted':
101 default:
102 $show_it = false;
103 break;
104 }
105
106 return ($show_it);
107 }
108
116 public function section_is_active(int $section_id): bool
117 {
118 $now = time();
119 $sql = "
120 SELECT COUNT(*)
121 FROM `" . TABLE_PREFIX . "sections`
122 WHERE (" . $now . " BETWEEN `publ_start` AND `publ_end`)
123 OR (" . $now . " > `publ_start` AND `publ_end`=0)
124 AND `section_id`=" . $section_id;
125
126 return (LEPTON_database::getInstance()->get_one($sql) > 0);
127 }
128
136 public function page_is_active(array $page ): bool
137 {
138 $now = time();
139 $sql = "
140 SELECT COUNT(*)
141 FROM `".TABLE_PREFIX."sections`
142 WHERE `page_id` = ".$page['page_id']."
143 AND (".$now." BETWEEN `publ_start` AND `publ_end` OR (".$now." > `publ_start` AND `publ_end`= 0))
144 ";
145
146 return (LEPTON_database::getInstance()->get_one($sql) > 0 );
147 }
148
155 public function show_page(array|null $page ): bool
156 {
157 if (!is_array($page))
158 {
159 $page = [];
160 LEPTON_database::getInstance()->execute_query(
161 "SELECT `page_id`, `visibility` FROM `" . TABLE_PREFIX . "pages` WHERE `page_id`=" . (int) $page,
162 true,
163 $page,
164 false
165 );
166
167 if (empty($page))
168 {
169 return false;
170 }
171 }
172 return ($this->page_is_visible($page) && $this->page_is_active($page));
173 }
174
175 // Check if the user is already authenticated or not
176 public function is_authenticated(): bool
177 {
178 return ( (isset( $_SESSION[ 'USER_ID' ] ) ) // gesetzt
179 && ($_SESSION[ 'USER_ID' ] != "") // nicht leer
180 && (is_numeric( $_SESSION[ 'USER_ID' ] ) ) // eine Zahl
181 );
182 }
183
191 public function buildPageLink(string $link): string
192 {
193 // Check for :// in the link (used in URL's) as well as mailto:
194 if (strstr($link, '://') == '' && !str_starts_with($link, 'mailto:'))
195 {
196 return LEPTON_URL . PAGES_DIRECTORY . $link . PAGE_EXTENSION;
197 }
198 else
199 {
200 return $link;
201 }
202 }
203
204
231 public static function getValue(
232 string $lookForName,
233 string $type = "string_clean",
234 string $requestFrom = "post",
235 string $dividerString = "X",
236 string|int|array|null $default = null,
237 string|int|array|null $range = null
238 ): string|int|array|null
239 {
240 // $_SESSION keys are always upper case
241 if ($requestFrom == 'session')
242 {
243 $lookForName = strtoupper($lookForName);
244 }
245
246 LEPTON_request::getInstance()->setStrictLookInside($requestFrom);
247 $aField = [ $lookForName => [
248 'type' => $type,
249 'default' => $default,
250 'range' => $range
251 ]
252 ];
253 $sTested = LEPTON_request::getInstance()->testValues($aField);
254
255 // L*VII.3 if result is NULL or EMPTY and the default value is set, use the default
256 if ((is_null($sTested[$lookForName]) || empty($sTested[$lookForName])) && (!empty($default)))
257 {
258 $sTested[$lookForName] = $default;
259 }
260 // make sure that comma seperated strings are exploded
261 if ($dividerString != 'X')
262 {
263 if (!is_array($sTested[$lookForName]))
264 {
265 $sTested[$lookForName] = explode($dividerString, $sTested[$lookForName] ?? "");
266 } else {
267 foreach ($sTested[$lookForName] as &$item)
268 {
269 $item = explode($dividerString, $item ?? "");
270 }
271 }
272 }
273 return $sTested[$lookForName];
274 }
275
284 public function is_group_match(int|string|array $groups_list1 = '', int|string|array $groups_list2 = ''): bool
285 {
286 if ($groups_list1 == '')
287 {
288 return false;
289 }
290 if ($groups_list2 == '')
291 {
292 return false;
293 }
294 if (!is_array($groups_list1))
295 {
296 $groups_list1 = explode( ',', $groups_list1 );
297 }
298 if (!is_array($groups_list2))
299 {
300 $groups_list2 = explode( ',', $groups_list2 );
301 }
302
303 return (sizeof(array_intersect($groups_list1, $groups_list2)) != 0);
304 }
305
314 public static function addItems(string $for = 'frontend', string $path = LEPTON_PATH, bool $footer = false): void
315 {
316 $trail = explode('/', $path);
317 $subdir = array_pop($trail);
318
319 $mod_headers = [];
320 $mod_footers = [];
321
322 if ($footer)
323 {
324 $add_to = &self::$FOOTERS;
325 $to_load = 'footers.inc.php';
326 }
327 else
328 {
329 $add_to = &self::$HEADERS;
330 $to_load = 'headers.inc.php';
331 }
332
333 require $path.'/'.$to_load;
334
335 if (true === $footer)
336 {
337 $aRefArray = &$mod_footers;
338 }
339 else
340 {
341 $aRefArray = &$mod_headers;
342 }
343
344 if (count($aRefArray))
345 {
346 foreach (['css', 'js'] as $key)
347 {
348 if (!isset($aRefArray[$for][$key]))
349 {
350 continue;
351 }
352 foreach ($aRefArray[$for][$key] as &$item)
353 {
354 // let's see if the path is relative (i.e., does not contain the current subdir)
355 if ((isset($item['file']))
356 && (!preg_match("#/$subdir/#", $item['file']))
357 && (file_exists($path.'/'.$item['file']))
358 )
359 {
360 // treat path as relative, add modules subfolder
361 $item['file'] = str_ireplace(LEPTON_PATH, '', $path).'/'.$item['file'];
362 }
363
364 $is_ok = true;
365 if ($key === "css") {
366 foreach ($add_to[$for][$key] as $temp_ref)
367 {
368 if ($temp_ref['file'] == $item['file'])
369 {
370 $is_ok = false;
371 }
372 }
373 } elseif ($key === "js")
374 {
375 foreach ($add_to[$for][$key] as $temp_ref)
376 {
377 if ($item === $temp_ref)
378 {
379 $is_ok = false;
380 }
381 }
382
383 }
384
385 if (true === $is_ok)
386 {
387 $add_to[$for][$key][] = $item;
388 }
389 }
390 }
391 }
392
393 if ($footer && file_exists($path.$for.'_body.js'))
394 {
395 $add_to[$for]['js'][] = '/modules/'.$subdir.'_body.js';
396 }
397
398 }
399
405 public function getProtectedFunctions(string &$html, object &$oReference): void
406 {
407 $this->addLepToken($html, $oReference);
408 }
409
414 protected function addLepToken(string &$html, object &$oReference): void
415 {
419 if (!LEPTOKEN_LIFETIME)
420 {
421 return;
422 }
423
424 $token = $oReference->createLepToken();
425
426 $token1 = "$1?leptoken=".$token."$3"; // no parameters so far
427 $token2 = "leptoken=".$token; // for replacing placeholder in JS functions
428 $token3 = "$1&leptoken=".$token."$3"; // with existing parameters, produces html-valid code
429 $token4 = "$1?leptoken=".$token."$2"; // for special cases
430 $hiddentoken = "$1\n<span><input type='hidden' name='leptoken' value='".$token."' /></span>\n"; // for GET forms, add a hidden field too
431
432 // finds absolute Links with Parameter:
433 $qs = '~((href|action|window\.location)\s?=\s?[\'"]' . LEPTON_URL . '[\w\-\./]+\.php\?[\w\-\.=&%;/]+)([#[\w]*]?[\'"])~';
434 $html = preg_replace( $qs, $token3, $html, -1 );
435
436 // finds absolute Links without Parameter:
437 $qs = '~((href|action|ajaxfilemanagerurl|window\.location)\s?=\s?[\'"]' . LEPTON_URL . '[\w\-\./]+\.php)([#[\w]*]?[\'"])~';
438 $html = preg_replace( $qs, $token1, $html, -1 );
439
440 // finds relative Links with Parameter:
441 $qs = '~((href|action|window\.location)\s?=\s?[\'"][\w/]+\.php\?[\w\-\.=%&;/]+)([#[\w]*]?[\'"])~';
442 $html = preg_replace( $qs, $token3, $html, -1 );
443
444 // finds relative Links without Parameter:
445 $qs = '~((href|action|window\.location)\s?=\s?[\'"][\w/]+\.php)([#[\w]*]?[\'"])~';
446 $html = preg_replace( $qs, $token1, $html, -1 );
447
448 // finds Start page without Parameter:
449 $qs = '~(href\s?=\s?[\'"]' . LEPTON_URL . ')([\'"])~';
450 $html = preg_replace( $qs, $token4, $html, -1 );
451
452 // finds Testmail in Options:
453 $qs = '~(send_testmail\‍(\'' . ADMIN_URL . '/settings/ajax_testmail\.php)(\'\‍))~';
454 $html = preg_replace( $qs, $token4, $html, -1 );
455
456 // finds forms with method=get and adds a hidden field
457 $qs = '~(<form\s+action=[\'"][\w:\.\?/]+leptoken=\w{32}[\'"]\s+method=[\'"]get[\'"]\s*>)~';
458 $html = preg_replace( $qs, $hiddentoken, $html, -1 );
459
460 // set leptoken in JS functions
461 $qs = '~leptokh=#-!leptoken-!#~';
462 $html = preg_replace( $qs, $token2, $html, -1 );
463 }
464
465
473 static public function make_dir(string $dir_name, string|null $dir_mode = NULL): bool
474 {
475 if ($dir_mode == NULL)
476 {
477 $dir_mode = (int) octdec( STRING_DIR_MODE );
478 }
479
480 if (!is_dir($dir_name))
481 {
482 $umask = umask(); // get current mask
483 $result = mkdir($dir_name, $dir_mode, true);
484 if($result == false)
485 {
486 echo(LEPTON_tools::display('Cannot create directory!', 'pre','ui red message'));
487 return false;
488 }
489 umask($umask);
490 return true;
491 }
492 else
493 {
494 return true;
495 }
496 }
497
506 static public function change_mode(string $name ): bool
507 {
508 if (OPERATING_SYSTEM != 'windows')
509 {
510 $mode = (is_dir($name)) ? (int)octdec(STRING_DIR_MODE) : (int)octdec(STRING_FILE_MODE);
511 if (file_exists($name))
512 {
513 $umask = umask(); // get current
514 chmod($name, $mode);
515 umask($umask);
516 return true;
517 }
518 else
519 {
520 return false;
521 }
522 }
523 else
524 {
525 return true;
526 }
527 }
528
529
537 static public function create_access_file(string $filename, int $page_id): bool
538 {
539 global $admin, $MESSAGE;
540 $pages_path = LEPTON_PATH . PAGES_DIRECTORY;
541 $rel_pages_dir = str_replace($pages_path, '', dirname($filename));
542 $rel_filename = str_replace($pages_path, '', $filename);
543 // root_check prevent system directories and important files from being overwritten if PAGES_DIR = '/'
544 $denied = false;
545 if (PAGES_DIRECTORY == '')
546 {
547 $forbidden = [
548 'account',
549 'admins',
550 'framework',
551 'include',
552 'install',
553 'languages',
554 'media',
555 'modules',
556 'page',
557 'search',
558 'temp',
559 'templates',
560 'index.php',
561 '/config/config.php'
562 ];
563 $search = explode('/', $rel_filename);
564 // we need only the first level
565 $denied = in_array($search[1], $forbidden);
566 }
567 if ((true === is_writable($pages_path)) && (false === $denied))
568 {
569 // First make sure parent folder exists
570 $parent_folders = explode('/', $rel_pages_dir);
571 $parents = '';
572 foreach ($parent_folders as $parent_folder)
573 {
574 if ($parent_folder != '/' && $parent_folder != '')
575 {
576 $parents .= '/' . $parent_folder;
577 if (!file_exists($pages_path . $parents))
578 {
579 LEPTON_core::make_dir( $pages_path . $parents );
580 LEPTON_core::change_mode( $pages_path . $parents );
581 }
582 }
583 }
584 $step_back = str_repeat('../', substr_count($rel_pages_dir, '/') + (PAGES_DIRECTORY == "" ? 0 : 1));
585 $content = '<?php'."\n";
586 $content .= "/**\n * This file is autogenerated by LEPTON - Version: ".LEPTON_VERSION."\n";
587 $content .= " * Do not modify this file!\n */\n";
588 $content .= " ".'$page_id = '.$page_id.';'."\n";
589 $content .= " ".'require_once \''.$step_back.'index.php\';'."\n";
590
595 $fp = fopen($filename, 'w');
596 if ($fp)
597 {
598 fwrite($fp, $content, strlen($content));
599 fclose($fp);
604 LEPTON_core::change_mode($filename);
610 $temp_index_path = dirname($filename)."/index.php";
611 if (!file_exists($temp_index_path))
612 {
613 $origin = ADMIN_PATH."/pages/master_index.php";
614 if (file_exists($origin))
615 {
616 copy($origin, $temp_index_path);
617 }
618 }
619 }
620 else
621 {
622 $admin->print_error($MESSAGE['PAGES_CANNOT_CREATE_ACCESS_FILE']."<br />Problems while trying to open the file!");
623 return false;
624 }
625 return true;
626 }
627 else
628 {
629 $admin->print_error($MESSAGE['PAGES_CANNOT_CREATE_ACCESS_FILE']);
630 return false;
631 }
632 }
633
642 static public function level_count(int $iPageId ): int
643 {
645 // Get page parent
646 $iParent = $database->get_one('SELECT `parent` FROM `'.TABLE_PREFIX.'pages` WHERE `page_id` = '.$iPageId);
647 if ($iParent > 0)
648 {
649 // Get the level of the parent
650 $iLevel = $database->get_one('SELECT `level` FROM `'.TABLE_PREFIX.'pages` WHERE `page_id` = '.$iParent);
651 return $iLevel + 1;
652 }
653 else
654 {
655 return 0;
656 }
657 }
658
659
675 static public function get_subs(int $parent, array &$subs): void
676 {
678
679 // Get id's
680 $all = [];
681 $database->execute_query(
682 "SELECT `page_id` FROM `".TABLE_PREFIX."pages` WHERE `parent` = ".$parent." ORDER BY position",
683 true,
684 $all,
685 true
686 );
687
688 foreach ($all as &$aTempPageRef)
689 {
690 $subs[] = $aTempPageRef['page_id'];
691
692 // Get subs of this sub - recursive call!
693 self::get_subs($aTempPageRef['page_id'], $subs);
694 }
695 }
696
697
706 static public function delete_page(int $page_id): void
707 {
709 $admin = self::getGlobal('admin');
710 $MESSAGE = self::getGlobal('MESSAGE');
711 $section_id = self::getGlobal('section_id');
712
713 LEPTON_handle::register("rm_full_dir");
714
715 // Find out more about the page
716 $page_info = [];
717 $database->execute_query(
718 'SELECT link, parent FROM '.TABLE_PREFIX.'pages WHERE page_id = '.$page_id,
719 true,
720 $page_info,
721 false
722 );
723
724 if (empty($page_info))
725 {
726 $admin->print_error($MESSAGE['PAGES_NOT_FOUND']);
727 }
728
729 // Get the sections that belong to the page
730 $all_sections = [];
731 $database->execute_query(
732 'SELECT section_id, module FROM '.TABLE_PREFIX.'sections WHERE page_id = '.$page_id,
733 true,
734 $all_sections
735 );
736
737 foreach($all_sections as &$section)
738 {
739 // Set section id
740 $section_id = $section['section_id'];
741
742 // Include the modules delete file if it exists
743 if (file_exists(LEPTON_PATH.'/modules/'.$section['module'].'/delete.php'))
744 {
745 include LEPTON_PATH.'/modules/'.$section['module'].'/delete.php';
746 }
747 }
748
749 // Update the pages table
750 $database->simple_query("DELETE FROM ".TABLE_PREFIX."pages WHERE page_id = ".$page_id);
751
752 // Update the sections table
753 $database->simple_query("DELETE FROM ".TABLE_PREFIX."sections WHERE page_id = ".$page_id);
754
755 // Include the ordering class or clean-up ordering
756 $order = LEPTON_order::getInstance(TABLE_PREFIX.'pages', 'position', 'page_id', 'parent');
757 $order->clean($page_info['parent']);
758
759 // Unlink the page access file and directory
760 $directory = LEPTON_PATH . PAGES_DIRECTORY . $page_info['link'];
761 $filename = $directory . PAGE_EXTENSION;
762 $directory .= '/';
763 if (file_exists($filename))
764 {
765 if (!is_writable(LEPTON_PATH . PAGES_DIRECTORY . '/'))
766 {
767 $admin->print_error($MESSAGE['PAGES_CANNOT_DELETE_ACCESS_FILE']);
768 }
769 else
770 {
771 unlink($filename);
772 if (file_exists($directory) && (rtrim($directory, '/') != LEPTON_PATH . PAGES_DIRECTORY) && ($page_info['link'][0] != '.'))
773 {
774 rm_full_dir($directory);
775 }
776 }
777 }
778 }
779
784 static public function getGlobal(string $name): null|int|string|array|object
785 {
786 $returnValue = null;
787 if (isset($GLOBALS[$name]))
788 {
789 $returnValue = &$GLOBALS[$name];
790 }
791 return $returnValue;
792 }
793
799 static function registerBasicFunctions(): void
800 {
801 $functionListToRegister = [
802 "get_page_headers",
803 "get_page_footers",
804 "page_content",
805 "easymultilang_menu"
806 ];
807
808 LEPTON_handle::register($functionListToRegister);
809 }
810
815 static function loadCodeSnippets(): void
816 {
817 $snippets = [];
818 LEPTON_database::getInstance()->execute_query(
819 "SELECT `directory` FROM `".TABLE_PREFIX."addons` WHERE `function` = 'snippet'",
820 true,
821 $snippets,
822 true
823 );
824
825 foreach ($snippets as $snippet)
826 {
827 $tempPath = LEPTON_PATH."/modules/".$snippet['directory']."/include.php";
828 if (file_exists($tempPath))
829 {
830 require $tempPath;
831 }
832 }
833 }
834
841 static public function check_entry(string $value): bool
842 {
843 // get all keepouts
844 $all_entries = [];
845 LEPTON_database::getInstance()->execute_query(
846 "SELECT * FROM ".TABLE_PREFIX."keepout ORDER BY id DESC",
847 true,
848 $all_entries,
849 true
850 );
851
852 if (!empty($all_entries))
853 {
854 foreach ($all_entries as $check)
855 {
856 if (str_contains($check['email'], '*'))
857 {
858 $check_email = str_replace('*','',$check['email']);
859 if (str_contains($value, $check_email))
860 {
861 return true;
862 }
863 }
864
865 if ($value == $check['ip'] || $value == $check['email'])
866 {
867 return true;
868 }
869 }
870 return false;
871 }
872 return false;
873 }
874
880 static public function userHasAdminRights(): bool
881 {
882 if (self::$bUserGotAdminRights == false)
883 {
884 // Current user has admin rights?
885 $aUser = explode(",", ($_SESSION['GROUPS_ID'] ?? ""));
886 self::$bUserGotAdminRights = (in_array(1, $aUser));
887 }
888
889 return self::$bUserGotAdminRights;
890 }
891
897 static public function imageTypesAllowed(): array
898 {
899 $aWhiteList = explode(',', UPLOAD_WHITELIST);
900 $aImageTypes = lib_r_filemanager::allowed_image_types;
901
902 return array_merge(array_intersect($aWhiteList, $aImageTypes), []);
903 }
904
905}
static getInstance(array &$settings=[])
static getInstance(string $table, string $order_field='position', string $id_field='id', string $common_field='')
static display(mixed $something_to_display="", string $tag="pre", string|null $css_class=null, bool|null $useVarDump=null)
$database
Definition constants.php:52
rm_full_dir(string $directory)
trait LEPTON_singleton