LEPTON CMS 7.2.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
64 public function __construct()
65 {
66
67 }
68
77 public function page_is_visible( $page ): bool
78 {
79 // First check if visibility is 'none', 'deleted'
80
81 $show_it = false;
82 switch ($page['visibility'])
83 {
84 case 'hidden':
85 case 'public':
86 $show_it = true;
87 break;
88
89 case 'private':
90 case 'registered':
91 if ($this->is_authenticated() === true)
92 {
93 $show_it = ($this->is_group_match($this->getValue('groups_id', 'string', 'session',','), $page['viewing_groups']) );
94 }
95 break;
96
97 case 'none':
98 case 'deleted':
99 default:
100 $show_it = false;
101 break;
102 }
103
104 return ($show_it);
105 }
106
114 public function section_is_active(int $section_id): bool
115 {
116 $now = time();
117 $sql = "
118 SELECT COUNT(*)
119 FROM `" . TABLE_PREFIX . "sections`
120 WHERE (" . $now . " BETWEEN `publ_start` AND `publ_end`)
121 OR (" . $now . " > `publ_start` AND `publ_end`=0)
122 AND `section_id`=" . $section_id;
123
124 return (LEPTON_database::getInstance()->get_one($sql) > 0);
125 }
126
134 public function page_is_active(array $page ): bool
135 {
136 $now = time();
137 $sql = "
138 SELECT COUNT(*)
139 FROM `".TABLE_PREFIX."sections`
140 WHERE `page_id` = ".$page['page_id']."
141 AND (".$now." BETWEEN `publ_start` AND `publ_end` OR (".$now." > `publ_start` AND `publ_end`= 0))
142 ";
143
144 return (LEPTON_database::getInstance()->get_one($sql) > 0 );
145 }
146
153 public function show_page(array|null $page ): bool
154 {
155 if (!is_array($page))
156 {
157 $page = [];
158 LEPTON_database::getInstance()->execute_query(
159 "SELECT `page_id`, `visibility` FROM `" . TABLE_PREFIX . "pages` WHERE `page_id`=" . (int) $page,
160 true,
161 $page,
162 false
163 );
164
165 if (empty($page))
166 {
167 return false;
168 }
169 }
170 return ($this->page_is_visible($page) && $this->page_is_active($page));
171 }
172
173 // Check if the user is already authenticated or not
174 public function is_authenticated(): bool
175 {
176 return ( (isset( $_SESSION[ 'USER_ID' ] ) ) // gesetzt
177 && ($_SESSION[ 'USER_ID' ] != "") // nicht leer
178 && (is_numeric( $_SESSION[ 'USER_ID' ] ) ) // eine Zahl
179 );
180 }
181
189 public function buildPageLink(string $link): string
190 {
191 // Check for :// in the link (used in URL's) as well as mailto:
192 if (strstr($link, '://') == '' && !str_starts_with($link, 'mailto:'))
193 {
194 return LEPTON_URL . PAGES_DIRECTORY . $link . PAGE_EXTENSION;
195 }
196 else
197 {
198 return $link;
199 }
200 }
201
202 // @ADD_method 20230907: for use instead of old marked deprecated methods
220 public static function getValue(
221 string $lookForName,
222 string $type = "string_clean",
223 string $requestFrom = "post",
224 string $dividerString = "X"
225 ): string|int|array|null
226 {
227 // $_SESSION keys are always upper case
228 if ($requestFrom == 'session')
229 {
230 $lookForName = strtoupper($lookForName);
231 }
232
233 LEPTON_request::getInstance()->setStrictLookInside($requestFrom);
234 $aField = [ $lookForName => ['type' => $type, 'default' => null] ];
235 $sTested = LEPTON_request::getInstance()->testValues($aField);
236
237 // make sure, that array that are comma seperated strings are exploded
238 if ($dividerString != 'X')
239 {
240 if (!is_array($sTested[$lookForName]))
241 {
242 $sTested[$lookForName] = explode($dividerString, $sTested[$lookForName] ?? "");
243 } else {
244 foreach ($sTested[$lookForName] as &$item)
245 {
246 $item = explode($dividerString, $item ?? "");
247 }
248 }
249 }
250 return $sTested[$lookForName];
251 }
252
261 public function is_group_match(int|string|array $groups_list1 = '', int|string|array $groups_list2 = ''): bool
262 {
263 if ($groups_list1 == '')
264 {
265 return false;
266 }
267 if ($groups_list2 == '')
268 {
269 return false;
270 }
271 if (!is_array($groups_list1))
272 {
273 $groups_list1 = explode( ',', $groups_list1 );
274 }
275 if (!is_array($groups_list2))
276 {
277 $groups_list2 = explode( ',', $groups_list2 );
278 }
279
280 return (sizeof(array_intersect($groups_list1, $groups_list2)) != 0);
281 }
282
291 public static function addItems(string $for = 'frontend', string $path = LEPTON_PATH, bool $footer = false): void
292 {
293 $trail = explode('/', $path);
294 $subdir = array_pop($trail);
295
296 $mod_headers = [];
297 $mod_footers = [];
298
299 if ($footer)
300 {
301 $add_to = &self::$FOOTERS;
302 $to_load = 'footers.inc.php';
303 }
304 else
305 {
306 $add_to = &self::$HEADERS;
307 $to_load = 'headers.inc.php';
308 }
309
310 require $path.'/'.$to_load;
311
312 if (true === $footer)
313 {
314 $aRefArray = &$mod_footers;
315 }
316 else
317 {
318 $aRefArray = &$mod_headers;
319 }
320
321 if (count($aRefArray))
322 {
323 foreach (['css', 'js'] as $key)
324 {
325 if (!isset($aRefArray[$for][$key]))
326 {
327 continue;
328 }
329 foreach ($aRefArray[$for][$key] as &$item)
330 {
331 // let's see if the path is relative (i.e., does not contain the current subdir)
332 if ((isset($item['file']))
333 && (!preg_match("#/$subdir/#", $item['file']))
334 && (file_exists($path.'/'.$item['file']))
335 )
336 {
337 // treat path as relative, add modules subfolder
338 $item['file'] = str_ireplace(LEPTON_PATH, '', $path).'/'.$item['file'];
339 }
340
341 $is_ok = true;
342 if ($key === "css") {
343 foreach ($add_to[$for][$key] as $temp_ref)
344 {
345 if ($temp_ref['file'] == $item['file'])
346 {
347 $is_ok = false;
348 }
349 }
350 } elseif ($key === "js")
351 {
352 foreach ($add_to[$for][$key] as $temp_ref)
353 {
354 if ($item === $temp_ref)
355 {
356 $is_ok = false;
357 }
358 }
359
360 }
361
362 if (true === $is_ok)
363 {
364 $add_to[$for][$key][] = $item;
365 }
366 }
367 }
368 }
369
370 if ($footer && file_exists($path.$for.'_body.js'))
371 {
372 $add_to[$for]['js'][] = '/modules/'.$subdir.'_body.js';
373 }
374
375 }
376
382 public function getProtectedFunctions(string &$html, object &$oReference): void
383 {
384 $this->addLepToken($html, $oReference);
385 }
386
391 protected function addLepToken(string &$html, object &$oReference): void
392 {
396 if (!LEPTOKEN_LIFETIME)
397 {
398 return;
399 }
400
401 $token = $oReference->createLepToken();
402
403 $token1 = "$1?leptoken=".$token."$3"; // no parameters so far
404 $token2 = "leptoken=".$token; // for replacing placeholder in JS functions
405 $token3 = "$1&leptoken=".$token."$3"; // with existing parameters, produces html-valid code
406 $token4 = "$1?leptoken=".$token."$2"; // for special cases
407 $hiddentoken = "$1\n<span><input type='hidden' name='leptoken' value='".$token."' /></span>\n"; // for GET forms, add a hidden field too
408
409 // finds absolute Links with Parameter:
410 $qs = '~((href|action|window\.location)\s?=\s?[\'"]' . LEPTON_URL . '[\w\-\./]+\.php\?[\w\-\.=&%;/]+)([#[\w]*]?[\'"])~';
411 $html = preg_replace( $qs, $token3, $html, -1 );
412
413 // finds absolute Links without Parameter:
414 $qs = '~((href|action|ajaxfilemanagerurl|window\.location)\s?=\s?[\'"]' . LEPTON_URL . '[\w\-\./]+\.php)([#[\w]*]?[\'"])~';
415 $html = preg_replace( $qs, $token1, $html, -1 );
416
417 // finds relative Links with Parameter:
418 $qs = '~((href|action|window\.location)\s?=\s?[\'"][\w/]+\.php\?[\w\-\.=%&;/]+)([#[\w]*]?[\'"])~';
419 $html = preg_replace( $qs, $token3, $html, -1 );
420
421 // finds relative Links without Parameter:
422 $qs = '~((href|action|window\.location)\s?=\s?[\'"][\w/]+\.php)([#[\w]*]?[\'"])~';
423 $html = preg_replace( $qs, $token1, $html, -1 );
424
425 // finds Start page without Parameter:
426 $qs = '~(href\s?=\s?[\'"]' . LEPTON_URL . ')([\'"])~';
427 $html = preg_replace( $qs, $token4, $html, -1 );
428
429 // finds Testmail in Options:
430 $qs = '~(send_testmail\‍(\'' . ADMIN_URL . '/settings/ajax_testmail\.php)(\'\‍))~';
431 $html = preg_replace( $qs, $token4, $html, -1 );
432
433 // finds forms with method=get and adds a hidden field
434 $qs = '~(<form\s+action=[\'"][\w:\.\?/]+leptoken=\w{32}[\'"]\s+method=[\'"]get[\'"]\s*>)~';
435 $html = preg_replace( $qs, $hiddentoken, $html, -1 );
436
437 // set leptoken in JS functions
438 $qs = '~leptokh=#-!leptoken-!#~';
439 $html = preg_replace( $qs, $token2, $html, -1 );
440 }
441
442
450 static public function make_dir(string $dir_name, string $dir_mode = NULL): bool
451 {
452 if ($dir_mode == NULL)
453 {
454 $dir_mode = (int) octdec( STRING_DIR_MODE );
455 }
456
457 if (!is_dir($dir_name))
458 {
459 $umask = umask(); // get current mask
460 mkdir($dir_name, $dir_mode, true);
461 umask($umask);
462 return true;
463 }
464 return false;
465 }
466
475 static public function change_mode(string $name ): bool
476 {
477 if (OPERATING_SYSTEM != 'windows')
478 {
479 $mode = (is_dir($name)) ? (int)octdec(STRING_DIR_MODE) : (int)octdec(STRING_FILE_MODE);
480 if (file_exists($name))
481 {
482 $umask = umask(); // get current
483 chmod($name, $mode);
484 umask($umask);
485 return true;
486 }
487 else
488 {
489 return false;
490 }
491 }
492 else
493 {
494 return true;
495 }
496 }
497
498
506 static public function create_access_file(string $filename, int $page_id): bool
507 {
508 global $admin, $MESSAGE;
509 $pages_path = LEPTON_PATH . PAGES_DIRECTORY;
510 $rel_pages_dir = str_replace($pages_path, '', dirname($filename));
511 $rel_filename = str_replace($pages_path, '', $filename);
512 // root_check prevent system directories and important files from being overwritten if PAGES_DIR = '/'
513 $denied = false;
514 if (PAGES_DIRECTORY == '')
515 {
516 $forbidden = [
517 'account',
518 'admins',
519 'framework',
520 'include',
521 'install',
522 'languages',
523 'media',
524 'modules',
525 'page',
526 'search',
527 'temp',
528 'templates',
529 'index.php',
530 '/config/config.php'
531 ];
532 $search = explode('/', $rel_filename);
533 // we need only the first level
534 $denied = in_array($search[1], $forbidden);
535 }
536 if ((true === is_writable($pages_path)) && (false === $denied))
537 {
538 // First make sure parent folder exists
539 $parent_folders = explode('/', $rel_pages_dir);
540 $parents = '';
541 foreach ($parent_folders as $parent_folder)
542 {
543 if ($parent_folder != '/' && $parent_folder != '')
544 {
545 $parents .= '/' . $parent_folder;
546 if (!file_exists($pages_path . $parents))
547 {
548 LEPTON_core::make_dir( $pages_path . $parents );
549 LEPTON_core::change_mode( $pages_path . $parents );
550 }
551 }
552 }
553 $step_back = str_repeat('../', substr_count($rel_pages_dir, '/') + (PAGES_DIRECTORY == "" ? 0 : 1));
554 $content = '<?php' . "\n";
555 $content .= "/**\n *\tThis file is autogenerated by LEPTON - Version: ".LEPTON_VERSION."\n";
556 $content .= " *\tDo not modify this file!\n */\n";
557 $content .= "\t" . '$page_id = ' . $page_id . ';' . "\n";
558 $content .= "\t" . 'require_once(\'' . $step_back . 'index.php\');' . "\n";
559
564 $fp = fopen($filename, 'w');
565 if ($fp)
566 {
567 fwrite($fp, $content, strlen($content));
568 fclose($fp);
573 LEPTON_core::change_mode($filename);
579 $temp_index_path = dirname($filename)."/index.php";
580 if (!file_exists($temp_index_path))
581 {
582 $origin = ADMIN_PATH."/pages/master_index.php";
583 if (file_exists($origin))
584 {
585 copy($origin, $temp_index_path);
586 }
587 }
588 }
589 else
590 {
591 $admin->print_error($MESSAGE['PAGES_CANNOT_CREATE_ACCESS_FILE']."<br />Problems while trying to open the file!");
592 return false;
593 }
594 return true;
595 }
596 else
597 {
598 $admin->print_error($MESSAGE['PAGES_CANNOT_CREATE_ACCESS_FILE']);
599 return false;
600 }
601 }
602
611 static public function level_count(int $iPageId ): int
612 {
614 // Get page parent
615 $iParent = $database->get_one('SELECT `parent` FROM `'.TABLE_PREFIX.'pages` WHERE `page_id` = '.$iPageId);
616 if ($iParent > 0)
617 {
618 // Get the level of the parent
619 $iLevel = $database->get_one('SELECT `level` FROM `'.TABLE_PREFIX.'pages` WHERE `page_id` = '.$iParent);
620 return $iLevel + 1;
621 }
622 else
623 {
624 return 0;
625 }
626 }
627
628
644 static public function get_subs(int $parent, array &$subs): void
645 {
647
648 // Get id's
649 $all = [];
650 $database->execute_query(
651 "SELECT page_id FROM ".TABLE_PREFIX."pages WHERE parent = ".$parent." ORDER BY position",
652 true,
653 $all,
654 true
655 );
656
657 foreach ($all as &$fetch)
658 {
659 $subs[] = $fetch['page_id'];
660
661 // Get subs of this sub - recursive call!
662 self::get_subs($fetch['page_id'], $subs);
663 }
664 }
665
666
675 static public function delete_page(int $page_id): void
676 {
678 $admin = self::getGlobal('admin');
679 $MESSAGE = self::getGlobal('MESSAGE');
680 $section_id = self::getGlobal('section_id');
681
682 LEPTON_handle::register("rm_full_dir");
683
684 // Find out more about the page
685 $page_info = [];
686 $database->execute_query(
687 'SELECT link, parent FROM '.TABLE_PREFIX.'pages WHERE page_id = '.$page_id,
688 true,
689 $page_info,
690 false
691 );
692
693 if (empty($page_info))
694 {
695 $admin->print_error($MESSAGE['PAGES_NOT_FOUND']);
696 }
697
698 // Get the sections that belong to the page
699 $all_sections = [];
700 $database->execute_query(
701 'SELECT section_id, module FROM '.TABLE_PREFIX.'sections WHERE page_id = '.$page_id,
702 true,
703 $all_sections
704 );
705
706 foreach($all_sections as &$section)
707 {
708 // Set section id
709 $section_id = $section['section_id'];
710
711 // Include the modules delete file if it exists
712 if (file_exists(LEPTON_PATH.'/modules/'.$section['module'].'/delete.php'))
713 {
714 include LEPTON_PATH.'/modules/'.$section['module'].'/delete.php';
715 }
716 }
717
718 // Update the pages table
719 $database->simple_query("DELETE FROM ".TABLE_PREFIX."pages WHERE page_id = ".$page_id);
720
721 // Update the sections table
722 $database->simple_query("DELETE FROM ".TABLE_PREFIX."sections WHERE page_id = ".$page_id);
723
724 // Include the ordering class or clean-up ordering
725 $order = LEPTON_order::getInstance(TABLE_PREFIX.'pages', 'position', 'page_id', 'parent');
726 $order->clean($page_info['parent']);
727
728 // Unlink the page access file and directory
729 $directory = LEPTON_PATH . PAGES_DIRECTORY . $page_info['link'];
730 $filename = $directory . PAGE_EXTENSION;
731 $directory .= '/';
732 if (file_exists($filename))
733 {
734 if (!is_writable(LEPTON_PATH . PAGES_DIRECTORY . '/'))
735 {
736 $admin->print_error($MESSAGE['PAGES_CANNOT_DELETE_ACCESS_FILE']);
737 }
738 else
739 {
740 unlink($filename);
741 if (file_exists($directory) && (rtrim($directory, '/') != LEPTON_PATH . PAGES_DIRECTORY) && ($page_info['link'][0] != '.'))
742 {
743 rm_full_dir($directory);
744 }
745 }
746 }
747 }
748
753 static public function getGlobal(string $name): null|int|string|array|object
754 {
755 $returnValue = null;
756 if (isset($GLOBALS[$name]))
757 {
758 $returnValue = &$GLOBALS[$name];
759 }
760 return $returnValue;
761 }
762
768 static function registerBasicFunctions(): void
769 {
770 $functionListToRegister = [
771 "get_page_headers",
772 "get_page_footers",
773 "page_content",
774 "easymultilang_menu"
775 ];
776
777 LEPTON_handle::register($functionListToRegister);
778 }
779
784 static function loadCodeSnippets(): void
785 {
786 $snippets = [];
787 LEPTON_database::getInstance()->execute_query(
788 "SELECT `directory` FROM `".TABLE_PREFIX."addons` WHERE `function` = 'snippet'",
789 true,
790 $snippets,
791 true
792 );
793
794 foreach ($snippets as $snippet)
795 {
796 $tempPath = LEPTON_PATH."/modules/".$snippet['directory']."/include.php";
797 if (file_exists($tempPath))
798 {
799 require $tempPath;
800 }
801 }
802 }
803
810 static public function check_entry(string $value): bool
811 {
812 // get all keepouts
813 $all_entries = [];
814 LEPTON_database::getInstance()->execute_query(
815 "SELECT * FROM ".TABLE_PREFIX."keepout ORDER BY id DESC",
816 true,
817 $all_entries,
818 true
819 );
820
821 if (!empty($all_entries))
822 {
823 foreach ($all_entries as $check)
824 {
825 if (str_contains($check['email'], '*'))
826 {
827 $check_email = str_replace('*','',$check['email']);
828 if (str_contains($value, $check_email))
829 {
830 return true;
831 }
832 }
833
834 if ($value == $check['ip'] || $value == $check['email'])
835 {
836 return true;
837 }
838 }
839 return false;
840 }
841 return false;
842 }
843
849 static public function userHasAdminRights(): bool
850 {
851 if (self::$bUserGotAdminRights == false)
852 {
853 // Current user has admin rights?
854 $aUser = explode(",", ($_SESSION['GROUPS_ID'] ?? ""));
855 self::$bUserGotAdminRights = (in_array(1, $aUser));
856 }
857
858 return self::$bUserGotAdminRights;
859 }
860
866 static public function imageTypesAllowed(): array
867 {
868 $aWhiteList = explode(',', UPLOAD_WHITELIST);
869 $aImageTypes = lib_r_filemanager::allowed_image_types;
870
871 return array_merge(array_intersect($aWhiteList, $aImageTypes), []);
872 }
873
874}
static getInstance(array &$settings=[])
static getInstance(string $table, string $order_field='position', string $id_field='id', string $common_field='')
$database
Definition constants.php:52
rm_full_dir(string $directory)
trait LEPTON_singleton