LEPTON CMS 7.5.0
feel free to keep it strictly simple...
Loading...
Searching...
No Matches
lepton_admin.php
Go to the documentation of this file.
1<?php
2
3declare(strict_types=1);
4
19
20
27class LEPTON_admin extends LEPTON_core
28{
29
36 private LEPTON_database $database;
37
44 public array $header_storage = [
45 'css' => [],
46 'js' => [],
47 'html' => [],
48 'modules' => []
49 ];
50
57 private string $html_output_storage = "";
58
65 private bool $droplets_ok = false;
66
67 private array $adminTools = [];
68
69 protected string $section_name = "";
70 protected string $section_permission = "";
71
77 public ?lib_twig_box $oTWIG = null;
78
83 public static $instance;
84
95
96 #[\Override]
97 public static function getInstance(): object
98 {
99 if (null === static::$instance)
100 {
101 $section_name = "Pages";
102 $section_permission = "start";
103 $auto_header = true;
104 $auto_auth = true;
105
106 switch( func_num_args() )
107 {
108 case 1:
109 $section_name = func_get_arg(0);
110 break;
111 case 2:
112 $section_name = func_get_arg(0);
113 $section_permission = func_get_arg(1);
114 break;
115 case 3:
116 $section_name = func_get_arg(0);
117 $section_permission = func_get_arg(1);
118 $auto_header = func_get_arg(2);
119 break;
120 case 4:
121 $section_name = func_get_arg(0);
122 $section_permission = func_get_arg(1);
123 $auto_header = func_get_arg(2);
124 $auto_auth = func_get_arg(3);
125 break;
126 default:
127 // nothing
128 break;
129 }
130 static::$instance = new static($section_name, $section_permission, $auto_header, $auto_auth);
131 }
132 return static::$instance;
133 }
134
146 public function __construct(
147 string $section_name = "Pages",
148 string $section_permission = 'start',
149 bool $auto_header = true,
150 bool $auto_auth = true
151 )
152 {
153 global $database, $MESSAGE, $section_id, $page_id;
154
155 parent::__construct();
156
157 static::$instance = $this;
158
159 $section_id = (isset ($_POST['section_id']) ? intval($_POST['section_id']) : 0);
160 if ($section_id == 0 )
161 {
162 $section_id = (isset ($_GET['section_id'])? intval($_GET['section_id']): 0);
163 }
164
165 $page_id = (isset ($_POST['page_id']) ? intval($_POST['page_id']) : 0);
166 if ($page_id == 0 )
167 {
168 $page_id = (isset ($_GET['page_id']) ? intval($_GET['page_id']) : 0);
169 }
170
174 if (is_null($this->oTWIG))
175 {
176 $this->oTWIG = lib_twig_box::getInstance();
177 $this->oTWIG->loader->prependPath( THEME_PATH."/templates/", "theme" );
178 }
179
184 if (true === $auto_auth)
185 {
186 ob_start();
187 }
188
189 $this->database = LEPTON_database::getInstance();
190
191 // Specify the current applications name
192 $this->section_name = $section_name;
193 $this->section_permission = $section_permission;
194 // Authenticate the user for this application
195 if ($auto_auth === true)
196 {
197 // [a1] First check if the user is logged-in
198 if ($this->is_authenticated() === false)
199 {
200 header('Location:' . ADMIN_URL . '/login/index.php');
201 exit();
202 }
203
204 // [a2] Now check whether he has a valid token
205 if (!$this->checkLepToken())
206 {
207 $pin_set = $this->database->get_one("SELECT `pin_set` FROM `".TABLE_PREFIX."users` WHERE `user_id` = '".$_SESSION['USER_ID']."' ");
208 if ($pin_set == 2)
209 {
210 $this->database->simple_query("UPDATE `" . TABLE_PREFIX . "users` SET `pin_set` = 1 WHERE user_id = '" . $_SESSION['USER_ID'] . "' ");
211 }
212 unset($_SESSION['USER_ID']);
213 header('Location:' . ADMIN_URL . '/login/index.php');
214 exit();
215 }
216
217 // [a3] Now check if they are allowed in this section
218 if ($this->get_permission($section_permission) === false)
219 {
220 if ($section_permission === "admintools")
221 {
222 if (false == $this->userHasAdminToolPermission())
223 {
224 die($MESSAGE['ADMIN_INSUFFICIENT_PRIVILEGES']." [007-002]");
225 }
226
227 } else {
228 die($MESSAGE['ADMIN_INSUFFICIENT_PRIVILEGES']." [007-001]");
229 }
230 }
231 }
232
233 // Check if the backend language is also the selected language. If not, send headers again.
234 $user_language = [];
235 $this->database->execute_query(
236 "SELECT `language` FROM `" . TABLE_PREFIX . "users` WHERE `user_id` = '" . (int) $this->getValue('user_id', 'integer', 'session') . "'",
237 true,
238 $user_language,
239 false
240 );
241 // prevent infinite loop if language file is not XX.php (e.g. DE_de.php)
242 $user_language = (!isset($user_language['language']))
243 ? ""
244 : substr($user_language['language'], 0,2)
245 ;
246
247 // obtain the admin folder (e.g. /admin)
248 $admin_folder = str_replace(LEPTON_PATH, '', ADMIN_PATH);
249 if ((LANGUAGE != $user_language) && file_exists(LEPTON_PATH . '/languages/' . $user_language . '.php') && strpos($_SERVER['SCRIPT_NAME'], $admin_folder . '/') !== false)
250 {
251 // check if page_id is set
252 $page_id_url = (isset($_GET['page_id'])) ? '&page_id=' . (int) $_GET['page_id'] : '';
253 $section_id_url = (isset($_GET['section_id'])) ? '&section_id=' . (int) $_GET['section_id'] : '';
254 if (isset($_SERVER['QUERY_STRING']) && $_SERVER['QUERY_STRING'] != '') // check if there is an query-string
255 {
256 header('Location: ' . $_SERVER['SCRIPT_NAME'] . '?lang=' . $user_language . $page_id_url . $section_id_url . '&' . $_SERVER['QUERY_STRING']);
257 }
258 else
259 {
260 header('Location: ' . $_SERVER['SCRIPT_NAME'] . '?lang=' . $user_language . $page_id_url . $section_id_url);
261 }
262 exit();
263 }
264
265 // [a2.1] Auto header code
266 if ($auto_header === true)
267 {
268 $this->print_header();
269 }
270
271 // include cronjob file for external call
272 // @DEPRECATED_TEMP 20251010: this class will be removed in L* > 7.5.0, use external cronjobs instead
273 if(CRONJOB == 2 || CRONJOB == 3)
274 {
275 $_POST['ikey'] = LEPTON_cronjob::getInstance()->cj_key;
276 LEPTON_handle::include_files("/modules/cronjob.php");
277 }
278 }
279
287 public function get_permission(string $name, string $type = 'system'): bool
288 {
289 // [p.1] Append to permission type
290 $type .= '_permissions';
291 // [p.2] Check if we have a section to check for
292 if ($name === 'start')
293 {
294 return true;
295 }
296 else
297 {
298 if (true === self::userHasAdminRights())
299 {
300 return true;
301 }
302
303 $aTemp = match (strtolower($type))
304 {
305 "system_permissions" => ($this->getValue('system_permissions', 'string', 'session') ?? []),
306 "module_permissions" => ($this->getValue('module_permissions', 'string', 'session') ?? []),
307 default => []
308 };
309 return in_array($name, $aTemp);
310 }
311 }
312
319 public static function get_user_details(int $user_id): array
320 {
321 $user = [];
322 LEPTON_database::getInstance()->execute_query(
323 "SELECT `username`,`display_name` FROM `".TABLE_PREFIX."users` WHERE `user_id` = ".$user_id,
324 true,
325 $user,
326 false
327 );
328
329 if (empty($user))
330 {
331 $user['display_name'] = 'Unknown';
332 $user['username'] = 'unknown';
333 }
334 return $user;
335 }
336
344 public function get_page_details(int $page_id): array
345 {
346 $aResults = [];
347 $this->database->execute_query(
348 "SELECT * from ".TABLE_PREFIX."pages WHERE page_id = ".$page_id,
349 true,
350 $aResults,
351 false
352 );
353
354 if (empty($aResults))
355 {
356 $this->print_header();
357 $this->print_error($GLOBALS['MESSAGE']['PAGES_NOT_FOUND']);
358 }
359 return $aResults;
360 }
361
372 public function get_page_permission(int $page_id, string $action = 'admin'): bool
373 {
374 $action_groups = $action.'_groups';
375
376 $sGroups = $this->database->get_one("SELECT ".$action_groups." FROM ".TABLE_PREFIX."pages WHERE page_id = ".$page_id);
377
378 $aGroups = explode(',',$sGroups);
379
380 $aUserPermissions = $this->getValue('groups_id', 'string', 'session',',');
381
382 $in_group = !empty(array_intersect($aGroups,$aUserPermissions));
383
384 return $in_group;
385 }
386
395 public function get_link_permission(string $title): bool
396 {
397 if (true === self::userHasAdminRights())
398 {
399 return true;
400 }
401
402 $titleLower = strtolower(str_replace('_blank', '', $title));
403
404 // Set system permissions var
405 $system_permissions = $this->getValue('system_permissions', 'string_clean', 'session');
406
407 // Return true if system perm = 1
408 return (is_numeric(array_search($titleLower, $system_permissions)));
409 }
410
416 public function getGroupsPermissions(string $what): bool
417 {
418 if (self::userHasAdminRights())
419 {
420 return true;
421 }
422
423 $lookFor = strtolower($what);
424
425 switch ($lookFor)
426 {
427 case '*':
428 $terms = ["groups", "groups_view", "groups_add", "groups_modify", "groups_delete"];
429 break;
430
431 case 'view':
432 case 'add':
433 case 'modify':
434 case 'delete':
435 $terms = ["groups_".$lookFor];
436 break;
437
438 default:
439 echo LEPTON_tools::display_dev("[1023] No valid group key!", "pre", "ui message red");
440 $terms = [];
441 break;
442 }
443 return !empty(array_intersect($terms, $_SESSION['SYSTEM_PERMISSIONS']));
444 }
445
453 public function getUsersPermissions(string $what): bool
454 {
455 if (self::userHasAdminRights())
456 {
457 return true;
458 }
459
460 $lookFor = strtolower($what);
461
462 switch ($lookFor)
463 {
464 case '*':
465 $terms = ["users", "users_view", "users_add", "users_modify", "users_delete"];
466 break;
467
468 case 'view':
469 case 'add':
470 case 'modify':
471 case 'delete':
472 $terms = ["users_".$lookFor];
473 break;
474
475 default:
476 echo LEPTON_tools::display_dev("[1024] No valid users key!", "pre", "ui message red");
477 $terms = [];
478 break;
479 }
480 return !empty(array_intersect($terms, $_SESSION['SYSTEM_PERMISSIONS']));
481 }
482
490 public function getPagesPermissions(string $what): bool
491 {
492 if (self::userHasAdminRights())
493 {
494 return true;
495 }
496
497 $lookFor = strtolower($what);
498
499 switch ($lookFor)
500 {
501 case '*':
502 $terms = ["pages", "pages_settings", "pages_view", "pages_add", "pages_modify", "pages_delete"];
503 break;
504
505 case 'view':
506 case 'add':
507 case 'modify':
508 case 'settings':
509 case 'delete':
510 $terms = ["pages_".$lookFor];
511 break;
512
513 default:
514 echo LEPTON_tools::display_dev("[1025] No valid pages key!", "pre", "ui message red");
515 $terms = [];
516 break;
517 }
518 return !empty(array_intersect($terms, $_SESSION['SYSTEM_PERMISSIONS']));
519 }
520
525 public function print_header(): void
526 {
527 LEPTON_handle::register("get_page_headers");
528 // Get vars from the language file
529 global $MENU;
530 global $MESSAGE;
531 global $TEXT;
532
533 // Get website title
534 $title = $this->database->get_one("SELECT `value` FROM `".TABLE_PREFIX."settings` WHERE `name`='website_title'");
535
536 $charset = (true === defined('DEFAULT_CHARSET')) ? DEFAULT_CHARSET : 'utf-8';
537
538 // Work out the URL for the 'View menu' link in the WB backend
539 // if the page_id is set, show this page otherwise show the root directory of WB
540 $view_url = LEPTON_URL;
541 if (isset($_GET['page_id']))
542 {
543 // Extract page link from the database
544 $result = $this->database->get_one("SELECT `link` FROM `" . TABLE_PREFIX . "pages` WHERE `page_id`= '" . (int) addslashes($_GET['page_id']) . "'");
545 if (!is_null($result))
546 {
547 $view_url .= PAGES_DIRECTORY.$result.PAGE_EXTENSION;
548 }
549 }
550
555 $backend_theme_version = "";
556 if (defined('DEFAULT_THEME'))
557 {
558 $backend_theme_version = $this->database->get_one("SELECT `version` from `" . TABLE_PREFIX . "addons` where `directory`='" . DEFAULT_THEME . "'");
559 }
560
561 $header_vars = [
562 'SECTION_NAME' => $MENU[strtoupper($this->section_name)],
563 'WEBSITE_TITLE' => $title,
564 'BACKEND_TITLE' => BACKEND_TITLE,
565 'TEXT_ADMINISTRATION' => $TEXT['ADMINISTRATION'],
566 'CURRENT_USER' => $MESSAGE['START_CURRENT_USER'],
567 'DISPLAY_NAME' => $this->getValue('display_name', 'string', 'session'),
568 'CHARSET' => $charset,
569 'LANGUAGE' => strtolower(LANGUAGE),
570 'LEPTON_VERSION' => LEPTON_VERSION,
571 'SUBVERSION' => SUBVERSION,
572 'LEPTON_URL' => LEPTON_URL,
573 'ADMIN_URL' => ADMIN_URL,
574 'THEME_URL' => THEME_URL,
575 'TITLE_START' => $MENU['START'],
576 'TITLE_VIEW' => $MENU['VIEW'],
577 'TITLE_HELP' => $MENU['HELP'],
578 'TITLE_LOGOUT' => $MENU['LOGOUT'],
579// additional marker links/text in semantic BE-header
580 //'PAGES' => $MENU['PAGES'],
581 //'MEDIA' => $MENU['MEDIA'],
582 //'ADDONS' => $MENU['ADDONS'],
583 //'PREFERENCES' => $MENU['PREFERENCES'],
584 //'SETTINGS' => $MENU['SETTINGS'],
585 //'ADMINTOOLS' => $MENU['ADMINTOOLS'],
586 //'ACCESS' => $MENU['ACCESS'],
587// end additional marks
588 'URL_VIEW' => $view_url,
589 'URL_HELP' => ' https://lepton-cms.org/',
590 'GET_PAGE_HEADERS' => get_page_headers('backend', false),
591 'THEME_VERSION' => $backend_theme_version,
592 'THEME_NAME' => DEFAULT_THEME,
593 // permissions
594 'p_pages' => $this->get_link_permission('pages'),
595 'p_pages_settings' => $this->getUserPermission('pages_settings'), // 1
596 'p_pages_add' => $this->getUserPermission('pages_add'), // 2
597
598 'p_media' => $this->get_link_permission('media'),
599 'p_addons' => $this->get_link_permission('addons'),
600 'p_preferences' => $this->getUserPermission('preferences'), // 1
601 'p_settings' => $this->get_link_permission('settings'),
602 'p_admintools' => $this->userHasAdminToolPermission(), // $this->get_link_permission('admintools'),
603 'p_access' => $this->get_link_permission('access'),
604 // -- [groups]
605 'p_groups' => $this->getGroupsPermissions("*"),
606 'p_groups_view' => $this->getGroupsPermissions("view"),
607 'p_groups_add' => $this->getGroupsPermissions("add"),
608 'p_groups_moddify' => $this->getGroupsPermissions("modify"),
609 'p_groups_delete' => $this->getGroupsPermissions("delete"),
610 // -- [users]
611 'p_users' => $this->getUsersPermissions("*"),
612 'p_users_view' => $this->getUsersPermissions("view"),
613 'p_users_add' => $this->getUsersPermissions("add"),
614 'p_users_moddify' => $this->getUsersPermissions("modify"),
615 'p_users_delete' => $this->getUsersPermissions("delete")
616 ];
617
618 echo $this->oTWIG->render(
619 '@theme/header.lte',
620 $header_vars
621 );
622 }
623
630 public function print_footer(): void
631 {
632 LEPTON_handle::register("get_page_footers");
633 $footer_vars = [
634 'GET_PAGE_FOOTERS' => get_page_footers('backend'),
635// 'LEPTON_URL' => LEPTON_URL,
636// 'LEPTON_PATH' => LEPTON_PATH,
637// 'ADMIN_URL' => ADMIN_URL,
638// 'THEME_URL' => THEME_URL
639 ];
640
641 echo $this->oTWIG->render(
642 "@theme/footer.lte",
643 $footer_vars
644 );
645
654 $this->html_output_storage = ob_get_clean();
655 if (true === $this->droplets_ok)
656 {
657 evalDroplets($this->html_output_storage);
658 }
659
660 // CSRF protection - add tokens to internal links
661 if ($this->is_authenticated() )
662 {
663 LEPTON_core::getInstance()->getProtectedFunctions($this->html_output_storage, $this);
664 }
665
666 echo $this->html_output_storage;
667 }
668
677 public function print_success(string|array $message, string $redirect = 'index.php', bool $auto_footer = true): void
678 {
679 global $TEXT;
680 global $section_id;
681
683
684 if (true === is_array($message))
685 {
686 $message = implode("<br />", $message);
687 }
688
689 // add template variables
690 $page_vars = [
691 'NEXT' => $TEXT['NEXT'],
692 'BACK' => $TEXT['BACK'],
693 'MESSAGE' => $message,
694 'THEME_URL' => THEME_URL,
695 'REDIRECT' => $redirect,
696 'REDIRECT_TIMER' => REDIRECT_TIMER
697 ];
698
699 echo $this->oTWIG->render(
700 '@theme/success.lte',
701 $page_vars
702 );
703
704 if (true === $auto_footer)
705 {
706 $this->print_footer();
707 }
708 exit();
709 }
710
719 public function print_error(string|array $message, string $link = 'index.php', bool $auto_footer = true): void
720 {
721 global $TEXT;
722
724
725 if (true === is_array($message))
726 {
727 $message = implode("<br />", $message);
728 }
729
730 $page_vars = [
731 'MESSAGE' => $message,
732 'LINK' => $link,
733 'BACK' => $TEXT['BACK'],
734 'THEME_URL' => THEME_URL
735 ];
736
737 echo $this->oTWIG->render(
738 '@theme/error.lte',
739 $page_vars
740 );
741
742 if (true === $auto_footer && method_exists($this, "print_footer"))
743 {
744 $this->print_footer();
745 }
746 exit();
747 }
748
756 static public function getUserPermission(string $sPermissionName = "" ): bool
757 {
758 if (self::userHasAdminRights())
759 {
760 return true;
761 }
762
763 if (!isset($_SESSION['SYSTEM_PERMISSIONS']))
764 {
765 return false;
766 }
767
768 return (in_array($sPermissionName, $_SESSION['SYSTEM_PERMISSIONS']));
769 }
770
774 public function getHeaderStorage(): array
775 {
777 }
778
779 public function resetObject()
780 {
781 static::$instance = null;
782 return self::getInstance();
783 }
784
789 public function userHasAdminToolPermission(): bool
790 {
791 if (LEPTON_core::userHasAdminRights() == true)
792 {
793 return true;
794 }
795
796 if (empty($this->adminTools))
797 {
798 $aAllAdminToolsStorage = [];
799 $this->database->execute_query(
800 "SELECT `directory` FROM `".TABLE_PREFIX."addons` WHERE `function` = 'tool'",
801 true,
802 $aAllAdminToolsStorage,
803 true
804 );
805
806 foreach ($aAllAdminToolsStorage as $tempTool)
807 {
808 $this->adminTools[] = $tempTool['directory'];
809 }
810 }
811 // Keep in mind that module_permissions is an array!
812 $aUserModules = LEPTON_core::getValue("module_permissions", "array", "session");
813
814 return !empty(array_intersect($aUserModules, $this->adminTools));
815 }
816
837 public static function displayMessage(
838 string $sType ="success",
839 array|string $aMessage = [],
840 string $sRedirect = "",
841 int $iRedirectTime = -1,
842 string $sTemplateName = "message.lte",
843 bool $bDirectOutput = true
844 ): string
845 {
846 $oTwig = lib_twig_box::getInstance();
847
848 if (!is_array($aMessage))
849 {
850 $aMessage = [$aMessage];
851 }
852
853 if (empty($sRedirect))
854 {
855 die(LEPTON_tools::display('Please set $sRedirect! ', 'pre','ui red message'));
856 }
857
858 if(stripos('leptoken=',$sRedirect) == 0)
859 {
860 $sRedirect.='&leptoken='.get_leptoken();
861 }
862
863 // [1] Is there a lte file inside the THEME dir?
864 if (file_exists(LEPTON_PATH."/templates/".DEFAULT_THEME."/backend/backend/message.lte"))
865 {
866 // [1.1] File is inside the fTHEME - so we are using this path.
867 $oTwig->registerPath(LEPTON_PATH."/templates/".DEFAULT_THEME."/backend/backend/", "backend");
868 }
869
870 $data = [
871 'type' => $sType,
872 'message' => $aMessage,
873 'redirect' => $sRedirect,
874 'redirect_time' => $iRedirectTime
875 ];
876
877 $sHTML_rendered = $oTwig->render(
878 "@backend/".$sTemplateName,
879 $data
880 );
881
882 if ($bDirectOutput == true)
883 {
884 echo $sHTML_rendered;
885 return "";
886 }
887
888 return $sHTML_rendered;
889 }
890}
static saveLastEditSection(int $iSectionID=0)
get_permission(string $name, string $type='system')
get_page_permission(int $page_id, string $action='admin')
array $header_storage
__construct(string $section_name="Pages", string $section_permission='start', bool $auto_header=true, bool $auto_auth=true)
string $section_permission
print_error(string|array $message, string $link='index.php', bool $auto_footer=true)
getPagesPermissions(string $what)
static getUserPermission(string $sPermissionName="")
get_link_permission(string $title)
static get_user_details(int $user_id)
getUsersPermissions(string $what)
print_success(string|array $message, string $redirect='index.php', bool $auto_footer=true)
getGroupsPermissions(string $what)
string $section_name
static getInstance()
lib_twig_box $oTWIG
get_page_details(int $page_id)
static getInstance(array &$settings=[])
static include_files(array|string $file_names=[], bool $interrupt=true)
static display(mixed $something_to_display="", string $tag="pre", string|null $css_class=null, bool|null $useVarDump=null)
static display_dev(mixed $something_to_display="", string $tag="pre", string|null $css_class=null, bool|null $useVarDump=null)
const THEME_PATH
get_page_footers(string $for='frontend')
get_page_headers(string $for='frontend', bool $print_output=true, bool $individual=false)