2024-01-16 19:24:40 +01:00
|
|
|
<?php
|
2024-02-05 21:21:04 +01:00
|
|
|
require_once "lib/dynamic_style.php";
|
|
|
|
require_once "lib/script_data.php";
|
2024-04-28 22:37:23 +02:00
|
|
|
/**
|
|
|
|
* Loads and returns the result of a PHP file.
|
|
|
|
* This function is typically used to process dynamic content of a page.
|
|
|
|
* It simply scopes an external file into a function to prevent variable conflicts.
|
|
|
|
*
|
|
|
|
* @param string $page_file The file path to the dynamic page.
|
|
|
|
* @return array Returns the array of data generated by including the PHP file.
|
|
|
|
*/
|
|
|
|
function renderDynamicPage(string $page_file): array
|
2024-01-16 20:43:57 +01:00
|
|
|
{
|
2024-02-04 09:01:28 +01:00
|
|
|
return require $page_file;
|
2024-01-16 20:43:57 +01:00
|
|
|
}
|
|
|
|
|
2024-04-28 22:37:23 +02:00
|
|
|
/**
|
|
|
|
* Removes all HTML comments from the provided content string.
|
|
|
|
*
|
|
|
|
* @param string $content The HTML content from which to remove comments.
|
|
|
|
* @return string The content without any HTML comments.
|
|
|
|
*/
|
|
|
|
function removeHtmlComments(string $content = '') :string {
|
2024-02-29 09:47:03 +01:00
|
|
|
return preg_replace('/<!--(.|\s)*?-->/', '', $content);
|
|
|
|
}
|
2024-04-28 22:37:23 +02:00
|
|
|
/**
|
|
|
|
* Parses custom `<page>` tags from the given input string and extracts parameters.
|
|
|
|
* Returns the input string with `<page>` tags removed and a list of parameters.
|
|
|
|
*
|
|
|
|
* @param string $input The input HTML or text containing `<page>` tags.
|
|
|
|
* @return array Returns an associative array with 'parameters' (parsed from the tag)
|
|
|
|
* and 'output' (the modified input string with `<page>` tags removed).
|
|
|
|
*/
|
|
|
|
function parsePageTag(string $input): array
|
2024-01-31 23:07:12 +01:00
|
|
|
{
|
|
|
|
// Define the pattern for the tag
|
|
|
|
$pattern = '/<page\s+([^>]+)><\/page>/i';
|
|
|
|
|
|
|
|
// Check if the pattern matches the input
|
|
|
|
if (preg_match($pattern, $input, $matches)) {
|
|
|
|
// Extract parameters
|
|
|
|
$parameters = [];
|
|
|
|
if (preg_match_all('/(\w+)="([^"]+)"/', $matches[1], $paramMatches, PREG_SET_ORDER)) {
|
|
|
|
foreach ($paramMatches as $paramMatch) {
|
|
|
|
$parameters[$paramMatch[1]] = $paramMatch[2];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove the tag from the input
|
|
|
|
$output = preg_replace($pattern, '', $input, 1);
|
|
|
|
|
|
|
|
return ['parameters' => $parameters, 'output' => $output];
|
|
|
|
}
|
|
|
|
|
|
|
|
// If no match is found, return the original input
|
|
|
|
return ['parameters' => [], 'output' => $input];
|
|
|
|
}
|
2024-04-28 22:37:23 +02:00
|
|
|
/**
|
|
|
|
* Renders a page based on specified page and site names, handling dynamic and static content,
|
|
|
|
* permissions, and error pages.
|
|
|
|
*
|
|
|
|
* @param string|null $page_name The name of the page to render. If null, uses default from request.
|
|
|
|
* @param string|null $site_name The name of the site to render. If null, uses default from request.
|
|
|
|
* @return array Returns an associative array containing the rendered page content, page name, site name, and page title.
|
|
|
|
*/
|
|
|
|
function renderPage(string $page_name = null, string $site_name = null): array
|
2024-01-31 22:05:23 +01:00
|
|
|
{
|
2024-01-16 20:43:57 +01:00
|
|
|
global $routerConfig;
|
|
|
|
global $routerRequest;
|
2024-01-16 19:39:54 +01:00
|
|
|
|
2024-02-05 21:21:04 +01:00
|
|
|
if(!$site_name) {
|
2024-02-06 16:24:57 +01:00
|
|
|
$site_name = $routerRequest["site_name"];
|
2024-02-05 21:21:04 +01:00
|
|
|
}
|
|
|
|
|
2024-02-24 09:23:09 +01:00
|
|
|
$site_title = str_replace("_", " ", $site_name);
|
|
|
|
|
|
|
|
$site_title = ucfirst($site_title);
|
|
|
|
|
2024-01-16 20:43:57 +01:00
|
|
|
if(!$page_name){
|
|
|
|
$page_name = $routerRequest["page_name"];
|
2024-01-16 19:39:54 +01:00
|
|
|
}
|
2024-01-16 19:24:40 +01:00
|
|
|
|
2024-02-05 21:21:04 +01:00
|
|
|
$dynamic_page_file = $routerConfig["page_dir"] . $site_name . "/" . $page_name . ".php";
|
|
|
|
$page_file = $routerConfig["page_dir"] . $site_name . "/" . $page_name . ".html";
|
2024-01-16 19:24:40 +01:00
|
|
|
|
2024-02-02 12:38:18 +01:00
|
|
|
if (file_exists($dynamic_page_file)){
|
2024-02-01 09:10:55 +01:00
|
|
|
$pageMetadata = renderDynamicPage($dynamic_page_file);
|
|
|
|
|
|
|
|
$page = $pageMetadata["output"];
|
2024-01-16 19:24:40 +01:00
|
|
|
}
|
|
|
|
elseif (file_exists($page_file)){
|
2024-02-01 09:24:58 +01:00
|
|
|
$page_tmp = file_get_contents($page_file);
|
2024-02-01 09:10:55 +01:00
|
|
|
|
2024-02-01 09:24:58 +01:00
|
|
|
$pageMetadata = parsePageTag($page_tmp);
|
2024-02-01 09:10:55 +01:00
|
|
|
$page = $pageMetadata["output"];
|
2024-01-16 19:24:40 +01:00
|
|
|
}
|
|
|
|
else{
|
2024-02-01 09:38:16 +01:00
|
|
|
$page_tmp = file_get_contents($routerConfig["template_dir"] . "404.html");
|
|
|
|
$pageMetadata = parsePageTag($page_tmp);
|
|
|
|
$page = $pageMetadata["output"];
|
|
|
|
http_response_code(404);
|
2024-01-16 19:38:42 +01:00
|
|
|
}
|
2024-01-31 23:07:12 +01:00
|
|
|
|
|
|
|
if(!empty($pageMetadata["parameters"]["minimal_permission_level"])){
|
|
|
|
$page_required_permission = intval($pageMetadata["parameters"]["minimal_permission_level"]);
|
|
|
|
}
|
|
|
|
else{
|
2024-02-06 16:24:57 +01:00
|
|
|
$page_required_permission = $routerConfig["page"]["default_permissions"];
|
2024-01-31 23:07:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if(!empty($pageMetadata["parameters"]["secret"])){
|
2024-02-01 10:06:50 +01:00
|
|
|
$origSecret = $pageMetadata["parameters"]["secret"];
|
|
|
|
if ($origSecret == "yes"){
|
|
|
|
$is_secret_page = 1;
|
|
|
|
}
|
|
|
|
elseif ($origSecret == "no"){
|
|
|
|
$is_secret_page = 0;
|
|
|
|
}
|
|
|
|
else{
|
2024-02-06 16:24:57 +01:00
|
|
|
$is_secret_page = $routerConfig["page"]["default_secret"];
|
2024-02-01 10:06:50 +01:00
|
|
|
}
|
2024-01-31 23:07:12 +01:00
|
|
|
}
|
|
|
|
else{
|
2024-02-06 16:24:57 +01:00
|
|
|
$is_secret_page = $routerConfig["page"]["default_secret"];
|
2024-01-31 23:07:12 +01:00
|
|
|
}
|
|
|
|
|
2024-02-01 10:19:28 +01:00
|
|
|
|
2024-02-03 16:08:26 +01:00
|
|
|
if($page_required_permission > $_SESSION["privilege_level"]){
|
2024-01-31 23:07:12 +01:00
|
|
|
if($is_secret_page == 1) {
|
2024-02-01 09:38:16 +01:00
|
|
|
$page_tmp = file_get_contents($routerConfig["template_dir"] . "404.html");
|
|
|
|
$pageMetadata = parsePageTag($page_tmp);
|
|
|
|
$page = $pageMetadata["output"];
|
2024-02-01 09:10:55 +01:00
|
|
|
http_response_code(404);
|
2024-01-31 23:07:12 +01:00
|
|
|
}
|
|
|
|
else{
|
2024-02-01 09:38:16 +01:00
|
|
|
$page_tmp = file_get_contents($routerConfig["template_dir"] . "403.html");
|
|
|
|
$pageMetadata = parsePageTag($page_tmp);
|
2024-02-06 20:52:27 +01:00
|
|
|
$page = $pageMetadata["output"];
|
2024-02-01 09:10:55 +01:00
|
|
|
http_response_code(403);
|
2024-01-31 23:07:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-06 20:52:27 +01:00
|
|
|
$page = str_replace("__DEFAULT_LINK__", "/" . $routerConfig["default_site"] . "/" . $routerConfig["default_page"], $page);
|
2024-02-03 16:54:50 +01:00
|
|
|
if(!is_string($page)){
|
|
|
|
$page = "";
|
|
|
|
}
|
|
|
|
|
2024-02-24 09:16:21 +01:00
|
|
|
if(!empty($pageMetadata["parameters"]["page_title"])){
|
2024-02-24 10:04:16 +01:00
|
|
|
$page_title = $pageMetadata["parameters"]["page_title"];
|
2024-02-24 09:16:21 +01:00
|
|
|
}
|
|
|
|
else{
|
|
|
|
$page_title = $page_name;
|
|
|
|
}
|
|
|
|
|
2024-02-24 10:04:16 +01:00
|
|
|
$page_title = $routerConfig['site_prefix'] . " " . $site_title . " " . $page_title;
|
|
|
|
|
2024-02-29 09:32:59 +01:00
|
|
|
$page = str_replace("__TEMPLATE_PAGE_TITLE__", $page_title, $page);
|
|
|
|
|
2024-02-29 09:47:03 +01:00
|
|
|
$page = removeHtmlComments($page);
|
|
|
|
|
2024-02-05 21:37:42 +01:00
|
|
|
return [
|
|
|
|
"PageContent" => $page,
|
|
|
|
"PageName" => $page_name,
|
|
|
|
"SiteName" => $site_name,
|
2024-02-24 09:16:21 +01:00
|
|
|
"PageTitle" => $page_title,
|
2024-02-05 21:37:42 +01:00
|
|
|
];
|
|
|
|
|
|
|
|
}
|
2024-04-28 22:37:23 +02:00
|
|
|
/**
|
|
|
|
* Compiles a complete web page by injecting dynamic elements into a template skeleton,
|
|
|
|
* including headers, footers, and SEO tags.
|
|
|
|
* It is used when not going to a page by AJAX to initialize everything.
|
|
|
|
*
|
|
|
|
* @param string|null $site_name_in The site name to be used; defaults from global configuration if null.
|
|
|
|
* @param string|null $page_name_in The page name to be used; defaults from global configuration if null.
|
|
|
|
* @return string The complete HTML content of the web page ready for display.
|
|
|
|
*/
|
|
|
|
function getPage(string $site_name_in = null, string $page_name_in = null): string
|
2024-02-05 21:37:42 +01:00
|
|
|
{
|
|
|
|
$page_tmp = renderPage($page_name_in, $site_name_in);
|
|
|
|
|
|
|
|
$page = $page_tmp["PageContent"];
|
|
|
|
$page_name = $page_tmp["PageName"];
|
|
|
|
$site_name = $page_tmp["SiteName"];
|
|
|
|
global $routerConfig;
|
|
|
|
|
|
|
|
$skeleton = file_get_contents($routerConfig["template_dir"] . "skeleton.html");
|
2024-02-05 22:26:02 +01:00
|
|
|
|
2024-02-06 17:09:28 +01:00
|
|
|
$footer = file_get_contents($routerConfig["template_dir"] . "footer.html");
|
|
|
|
|
2024-02-24 09:16:21 +01:00
|
|
|
$page_title = $page_tmp["PageTitle"];
|
2024-02-05 21:21:04 +01:00
|
|
|
$dynamic_style = doDynamicStyling();
|
2024-02-06 20:46:31 +01:00
|
|
|
$dynamic_script_data = [
|
2024-02-05 21:21:04 +01:00
|
|
|
"currentPage" => $page_name,
|
|
|
|
"currentSite" => $site_name,
|
|
|
|
"currentTitle" => $page_title,
|
|
|
|
"defaultPage" => $routerConfig["default_page"],
|
2024-02-06 20:02:29 +01:00
|
|
|
"defaultSite" => $routerConfig["default_site"],
|
2024-02-24 09:01:13 +01:00
|
|
|
"UserInfo_Privileges" => $_SESSION["privilege_level"],
|
2024-02-06 20:46:31 +01:00
|
|
|
];
|
|
|
|
if(isLoggedIn()){
|
|
|
|
$dynamic_script_data += [
|
2024-02-06 20:55:33 +01:00
|
|
|
"UserInfo_FirstName" => $_SESSION["first_name"],
|
|
|
|
"UserInfo_LastName" => $_SESSION["last_name"],
|
|
|
|
"UserInfo_Nickname" => $_SESSION["nickname"],
|
|
|
|
"UserInfo_Email" => $_SESSION["email"],
|
2024-02-06 20:46:31 +01:00
|
|
|
];
|
|
|
|
}
|
|
|
|
$dynamic_script = generateScriptData($dynamic_script_data);
|
2024-01-16 19:38:42 +01:00
|
|
|
|
2024-02-06 16:24:57 +01:00
|
|
|
$navigation = generateNavigation();
|
2024-01-16 19:38:42 +01:00
|
|
|
|
2024-02-15 10:09:01 +01:00
|
|
|
$seo = array();
|
|
|
|
|
|
|
|
|
|
|
|
if(!empty($pageMetadata["parameters"]["author"])){
|
|
|
|
$seo["author"] = htmlspecialchars($pageMetadata["parameters"]["author"]);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
$seo["author"] = $routerConfig["seo"]["author"];
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!empty($pageMetadata["parameters"]["description"])){
|
|
|
|
$seo["description"] = htmlspecialchars($pageMetadata["parameters"]["description"]);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
$seo["description"] = $routerConfig["seo"]["description"];
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!empty($pageMetadata["parameters"]["keywords"])){
|
|
|
|
$seo["keywords"] = $routerConfig["seo"]["keywords"] . ", " . htmlspecialchars($pageMetadata["parameters"]["keywords"]);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
$seo["keywords"] = $routerConfig["seo"]["keywords"];
|
|
|
|
}
|
|
|
|
|
|
|
|
$seo["generator"] = $routerConfig["seo"]["generator"];
|
|
|
|
|
|
|
|
$seo["robots"] = $routerConfig["seo"]["robots"];
|
|
|
|
|
|
|
|
$seo_stuff = "";
|
|
|
|
|
|
|
|
foreach ($seo as $key => $value){
|
|
|
|
$seo_stuff .= "<meta name='$key' content='$value'>\n";
|
|
|
|
}
|
|
|
|
|
2024-01-16 19:38:42 +01:00
|
|
|
$out = $skeleton;
|
2024-02-06 16:24:57 +01:00
|
|
|
$out = str_replace("__TEMPLATE__NAV__", $navigation, $out);
|
2024-01-16 19:38:42 +01:00
|
|
|
$out = str_replace("__TEMPLATE__PAGE__", $page, $out);
|
2024-02-06 17:09:28 +01:00
|
|
|
$out = str_replace("__TEMPLATE__FOOTER__", $footer, $out);
|
2024-02-06 16:24:57 +01:00
|
|
|
$out = str_replace("__TEMPLATE__DYNAMIC__SCRIPT__", $dynamic_script, $out);
|
|
|
|
$out = str_replace("__TEMPLATE__DYNAMIC__STYLE__", $dynamic_style, $out);
|
2024-02-15 10:09:01 +01:00
|
|
|
$out = str_replace("__TEMPLATE_SEO_STUFF__", $seo_stuff, $out);
|
2024-02-06 16:24:57 +01:00
|
|
|
if($routerConfig["inlining"]) {
|
|
|
|
require_once "lib/inliner.php";
|
|
|
|
$out = inlineLocalStylesFromHref($out);
|
|
|
|
$out = inlineScriptFromSrc($out);
|
|
|
|
}
|
2024-02-29 09:37:30 +01:00
|
|
|
return str_replace("__TEMPLATE_PAGE_TITLE__", $page_title, $out);
|
2024-02-05 21:21:04 +01:00
|
|
|
}
|
2024-04-28 22:37:23 +02:00
|
|
|
/**
|
|
|
|
* Provides an API interface to get page details including content and meta-information for routing purposes.
|
|
|
|
* This is what enables the page to never refresh.
|
|
|
|
*
|
|
|
|
* @param string $page_name The name of the page.
|
|
|
|
* @param string $site_name The name of the site.
|
|
|
|
* @return array Returns an array with status, page content, location URL, and title for the requested page.
|
|
|
|
*/
|
|
|
|
function getPageEndpoint(string $page_name, string $site_name) :array
|
2024-02-05 21:21:04 +01:00
|
|
|
{
|
2024-02-06 16:24:57 +01:00
|
|
|
$page_location = "/" . $site_name . "/" . $page_name;
|
2024-02-05 21:37:42 +01:00
|
|
|
$page_tmp = renderPage($page_name, $site_name);
|
2024-02-05 21:21:04 +01:00
|
|
|
return [
|
|
|
|
"Status" => "Success",
|
2024-02-05 21:37:42 +01:00
|
|
|
"Page" => $page_tmp["PageContent"],
|
2024-02-05 21:21:04 +01:00
|
|
|
"PageLocation" => $page_location,
|
2024-02-24 09:17:49 +01:00
|
|
|
"PageTitle" => $page_tmp["PageTitle"],
|
2024-02-05 21:21:04 +01:00
|
|
|
];
|
2024-01-18 11:49:38 +01:00
|
|
|
}
|