2023-01-06 04:01:00 +00:00
|
|
|
<?php
|
2023-01-06 08:49:49 +00:00
|
|
|
|
2023-01-06 04:17:07 +00:00
|
|
|
namespace AntCMS;
|
2023-01-06 08:49:49 +00:00
|
|
|
|
2023-01-06 04:17:07 +00:00
|
|
|
use AntCMS\AntMarkdown;
|
2023-01-07 01:09:55 +00:00
|
|
|
use AntCMS\AntPages;
|
2023-01-07 01:47:03 +00:00
|
|
|
use AntCMS\AntConfig;
|
2023-01-06 04:01:00 +00:00
|
|
|
|
2023-01-06 08:49:49 +00:00
|
|
|
class AntCMS
|
|
|
|
{
|
2023-01-11 02:20:24 +00:00
|
|
|
/**
|
|
|
|
* Renders a page based on the provided page name.
|
|
|
|
*
|
|
|
|
* @param string $page The name of the page to be rendered
|
|
|
|
* @return string The rendered HTML of the page
|
|
|
|
*/
|
|
|
|
public function renderPage(string $page)
|
2023-01-06 08:49:49 +00:00
|
|
|
{
|
2023-01-06 07:43:31 +00:00
|
|
|
$start_time = microtime(true);
|
2023-01-06 04:01:00 +00:00
|
|
|
$content = $this->getPage($page);
|
2023-01-06 07:43:31 +00:00
|
|
|
|
2023-01-06 08:49:49 +00:00
|
|
|
if (!$content || !is_array($content)) {
|
2023-01-06 04:01:00 +00:00
|
|
|
$this->renderException("404");
|
|
|
|
}
|
2023-01-06 07:43:31 +00:00
|
|
|
|
2023-01-13 03:08:35 +00:00
|
|
|
$pageTemplate = $this->getPageLayout(null, $page);
|
2023-01-06 07:43:31 +00:00
|
|
|
|
2023-01-09 20:50:11 +00:00
|
|
|
$params = array(
|
|
|
|
'AntCMSTitle' => $content['title'],
|
|
|
|
'AntCMSDescription' => $content['description'],
|
|
|
|
'AntCMSAuthor' => $content['author'],
|
|
|
|
'AntCMSKeywords' => $content['keywords'],
|
2023-01-26 05:32:38 +00:00
|
|
|
'AntCMSBody' => AntMarkdown::renderMarkdown($content['content']),
|
2023-01-09 20:50:11 +00:00
|
|
|
);
|
2023-01-19 23:07:15 +00:00
|
|
|
$pageTemplate = AntTwig::renderWithTiwg($pageTemplate, $params);
|
2023-01-07 01:47:03 +00:00
|
|
|
|
2023-01-06 07:43:31 +00:00
|
|
|
$end_time = microtime(true);
|
|
|
|
$elapsed_time = round($end_time - $start_time, 4);
|
2023-01-07 09:28:04 +00:00
|
|
|
|
2023-01-11 01:24:30 +00:00
|
|
|
if (AntConfig::currentConfig('debug')) {
|
2023-01-07 09:28:04 +00:00
|
|
|
$pageTemplate = str_replace('<!--AntCMS-Debug-->', '<p>Took ' . $elapsed_time . ' seconds to render the page. </p>', $pageTemplate);
|
|
|
|
}
|
2023-01-06 07:43:31 +00:00
|
|
|
|
2023-01-09 18:47:55 +00:00
|
|
|
return $pageTemplate;
|
2023-01-06 04:01:00 +00:00
|
|
|
}
|
|
|
|
|
2023-01-11 02:20:24 +00:00
|
|
|
/**
|
|
|
|
* Returns the default layout of the active theme unless otherwise specified.
|
|
|
|
*
|
|
|
|
* @param string|null $theme optional - the theme to get the page layout for.
|
2023-01-13 03:08:35 +00:00
|
|
|
* @param string $currentPage optional - What page is the active page.
|
2023-01-11 02:20:24 +00:00
|
|
|
* @return string the default page layout
|
|
|
|
*/
|
2023-01-26 02:45:36 +00:00
|
|
|
public static function getPageLayout(string $theme = null, string $currentPage = '')
|
2023-01-06 08:49:49 +00:00
|
|
|
{
|
2023-01-07 14:41:17 +00:00
|
|
|
$siteInfo = AntCMS::getSiteInfo();
|
|
|
|
|
2023-01-26 02:45:36 +00:00
|
|
|
$pageTemplate = self::getThemeTemplate('default_layout', $theme);
|
|
|
|
$pageTemplate = str_replace('<!--AntCMS-Navigation-->', AntPages::generateNavigation(self::getThemeTemplate('nav_layout', $theme), $currentPage), $pageTemplate);
|
2023-01-07 14:41:17 +00:00
|
|
|
|
|
|
|
$pageTemplate = str_replace('<!--AntCMS-SiteTitle-->', $siteInfo['siteTitle'], $pageTemplate);
|
|
|
|
|
2023-01-15 04:44:27 +00:00
|
|
|
return str_replace('<!--AntCMS-SiteLink-->', '//' . AntConfig::currentConfig('baseURL'), $pageTemplate);
|
2023-01-07 14:41:17 +00:00
|
|
|
}
|
|
|
|
|
2023-01-11 02:20:24 +00:00
|
|
|
/**
|
|
|
|
* Render an exception page with the provided exception code.
|
|
|
|
*
|
|
|
|
* @param string $exceptionCode The exception code to be displayed on the error page
|
2023-01-26 02:45:36 +00:00
|
|
|
* @param int $httpCode The HTTP response code to return, 404 by default.
|
|
|
|
* @param string $exceptionString An optional parameter to define a custom string to be displayed along side the exception.
|
2023-01-11 02:20:24 +00:00
|
|
|
* @return never
|
|
|
|
*/
|
2023-01-26 02:45:36 +00:00
|
|
|
public static function renderException(string $exceptionCode, int $httpCode = 404, string $exceptionString = 'That request caused an exception to be thrown.')
|
2023-01-07 20:15:29 +00:00
|
|
|
{
|
2023-01-26 06:08:19 +00:00
|
|
|
$exceptionString .= " (Code {$exceptionCode})";
|
2023-01-26 02:45:36 +00:00
|
|
|
$pageTemplate = self::getPageLayout();
|
2023-01-07 20:15:29 +00:00
|
|
|
|
2023-01-26 05:32:38 +00:00
|
|
|
$pageTemplate = str_replace('{{ AntCMSTitle }}', 'An error ocurred', $pageTemplate);
|
|
|
|
$pageTemplate = str_replace('{{ AntCMSBody | raw }} ', '<h1>An error ocurred</h1><p>' . $exceptionString . '</p>', $pageTemplate);
|
2023-01-07 14:41:17 +00:00
|
|
|
|
2023-01-26 02:45:36 +00:00
|
|
|
http_response_code($httpCode);
|
2023-01-07 14:41:17 +00:00
|
|
|
echo $pageTemplate;
|
2023-01-06 23:17:31 +00:00
|
|
|
exit;
|
2023-01-06 04:01:00 +00:00
|
|
|
}
|
|
|
|
|
2023-01-26 06:08:19 +00:00
|
|
|
/**
|
2023-01-11 02:20:24 +00:00
|
|
|
* @return array<mixed>|false
|
|
|
|
*/
|
|
|
|
public function getPage(string $page)
|
2023-01-06 08:49:49 +00:00
|
|
|
{
|
2023-01-06 04:01:00 +00:00
|
|
|
$page = strtolower($page);
|
2023-01-25 01:48:12 +00:00
|
|
|
$pagePath = AntTools::convertFunctionaltoFullpath($page);
|
2023-01-06 23:17:31 +00:00
|
|
|
|
2023-01-06 08:49:49 +00:00
|
|
|
if (file_exists($pagePath)) {
|
2023-01-06 04:01:00 +00:00
|
|
|
try {
|
2023-01-06 08:49:49 +00:00
|
|
|
$pageContent = file_get_contents($pagePath);
|
2023-01-07 00:16:11 +00:00
|
|
|
$pageHeaders = AntCMS::getPageHeaders($pageContent);
|
2023-01-06 10:46:38 +00:00
|
|
|
// Remove the AntCMS section from the content
|
2023-01-13 09:18:43 +00:00
|
|
|
$pageContent = preg_replace('/\A--AntCMS--.*?--AntCMS--/sm', '', $pageContent);
|
2023-01-15 04:44:27 +00:00
|
|
|
return ['content' => $pageContent, 'title' => $pageHeaders['title'], 'author' => $pageHeaders['author'], 'description' => $pageHeaders['description'], 'keywords' => $pageHeaders['keywords']];
|
2023-01-12 08:20:13 +00:00
|
|
|
} catch (\Exception) {
|
2023-01-06 04:01:00 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2023-01-06 07:43:31 +00:00
|
|
|
|
2023-01-26 06:08:19 +00:00
|
|
|
/**
|
2023-01-11 02:20:24 +00:00
|
|
|
* @param string|null $theme
|
|
|
|
* @return string
|
|
|
|
*/
|
2023-01-26 02:45:36 +00:00
|
|
|
public static function getThemeTemplate(string $layout = 'default_layout', string $theme = null)
|
2023-01-06 08:49:49 +00:00
|
|
|
{
|
2023-01-11 01:24:30 +00:00
|
|
|
$theme = $theme ?? AntConfig::currentConfig('activeTheme');
|
2023-01-08 23:47:23 +00:00
|
|
|
|
|
|
|
if (!is_dir(antThemePath . '/' . $theme)) {
|
|
|
|
$theme = 'Default';
|
|
|
|
}
|
|
|
|
|
2023-01-09 00:53:58 +00:00
|
|
|
$templatePath = AntTools::repairFilePath(antThemePath . '/' . $theme . '/' . 'Templates');
|
|
|
|
$defaultTemplates = AntTools::repairFilePath(antThemePath . '/Default/Templates');
|
2023-01-07 21:35:14 +00:00
|
|
|
|
2023-01-10 14:32:51 +00:00
|
|
|
$templates = AntTools::getFileList($templatePath, 'twig');
|
2023-01-07 21:35:14 +00:00
|
|
|
|
2023-01-09 18:47:55 +00:00
|
|
|
try {
|
2023-01-10 08:07:20 +00:00
|
|
|
if (in_array($layout . '.html.twig', $templates)) {
|
|
|
|
$template = file_get_contents(AntTools::repairFilePath($templatePath . '/' . $layout . '.html.twig'));
|
2023-01-09 18:47:55 +00:00
|
|
|
} else {
|
2023-01-10 08:07:20 +00:00
|
|
|
$template = file_get_contents(AntTools::repairFilePath($defaultTemplates . '/' . $layout . '.html.twig'));
|
2023-01-09 18:47:55 +00:00
|
|
|
}
|
2023-01-12 08:20:13 +00:00
|
|
|
} catch (\Exception) {
|
2023-01-07 10:20:02 +00:00
|
|
|
}
|
2023-01-06 07:43:31 +00:00
|
|
|
|
2023-01-09 18:47:55 +00:00
|
|
|
if (empty($template)) {
|
|
|
|
if ($layout == 'default_layout') {
|
|
|
|
$template = '
|
|
|
|
<!DOCTYPE html>
|
|
|
|
<html>
|
|
|
|
<head>
|
2023-01-10 08:26:05 +00:00
|
|
|
<title>{{ AntCMSTitle }}</title>
|
|
|
|
<meta name="description" content="{{ AntCMSDescription }}">
|
|
|
|
<meta name="author" content="{{ AntCMSAuthor }}">
|
|
|
|
<meta name="keywords" content="{{ AntCMSKeywords }}">
|
2023-01-09 18:47:55 +00:00
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<p>AntCMS had an error when fetching the page template, please contact the site administrator.</p>
|
2023-01-26 05:32:38 +00:00
|
|
|
{{ AntCMSBody | raw }}
|
2023-01-09 18:47:55 +00:00
|
|
|
</body>
|
|
|
|
</html>';
|
|
|
|
} else {
|
|
|
|
$template = '
|
|
|
|
<h1>There was an error</h1>
|
|
|
|
<p>AntCMS had an error when fetching the page template, please contact the site administrator.</p>';
|
|
|
|
}
|
2023-01-06 07:43:31 +00:00
|
|
|
}
|
|
|
|
|
2023-01-07 21:35:14 +00:00
|
|
|
return $template;
|
2023-01-06 07:43:31 +00:00
|
|
|
}
|
2023-01-07 00:16:11 +00:00
|
|
|
|
2023-01-26 06:08:19 +00:00
|
|
|
/**
|
2023-01-11 02:20:24 +00:00
|
|
|
* @return array<mixed>
|
|
|
|
*/
|
|
|
|
public static function getPageHeaders(string $pageContent)
|
2023-01-07 00:16:11 +00:00
|
|
|
{
|
2023-01-13 09:18:43 +00:00
|
|
|
$pageHeaders = [
|
|
|
|
'title' => 'AntCMS',
|
|
|
|
'author' => 'AntCMS',
|
|
|
|
'description' => 'AntCMS',
|
2023-01-20 02:01:03 +00:00
|
|
|
'keywords' => '',
|
2023-01-13 09:18:43 +00:00
|
|
|
];
|
2023-01-07 00:16:11 +00:00
|
|
|
|
2023-01-07 21:35:14 +00:00
|
|
|
// First get the AntCMS header and store it in the matches varible
|
2023-01-13 09:18:43 +00:00
|
|
|
preg_match('/\A--AntCMS--.*?--AntCMS--/sm', $pageContent, $matches);
|
2023-01-07 21:35:14 +00:00
|
|
|
|
2023-01-13 09:18:43 +00:00
|
|
|
if (isset($matches[0])) {
|
2023-01-07 00:16:11 +00:00
|
|
|
$header = $matches[0];
|
2023-01-13 09:18:43 +00:00
|
|
|
// Then remove it from the page content so it doesn't cause issues if we try to generate the keywords
|
|
|
|
$pageContent = str_replace($header, '', $pageContent);
|
2023-01-07 00:16:11 +00:00
|
|
|
|
|
|
|
preg_match('/Title: (.*)/', $header, $matches);
|
|
|
|
$pageHeaders['title'] = trim($matches[1] ?? 'AntCMS');
|
|
|
|
|
|
|
|
preg_match('/Author: (.*)/', $header, $matches);
|
|
|
|
$pageHeaders['author'] = trim($matches[1] ?? 'AntCMS');
|
|
|
|
|
|
|
|
preg_match('/Description: (.*)/', $header, $matches);
|
2023-01-07 02:25:28 +00:00
|
|
|
$pageHeaders['description'] = trim($matches[1] ?? 'AntCMS');
|
2023-01-07 00:16:11 +00:00
|
|
|
|
|
|
|
preg_match('/Keywords: (.*)/', $header, $matches);
|
2023-01-20 02:01:03 +00:00
|
|
|
$pageHeaders['keywords'] = trim($matches[1] ?? '');
|
2023-01-07 00:16:11 +00:00
|
|
|
}
|
2023-01-13 09:18:43 +00:00
|
|
|
|
2023-01-07 00:16:11 +00:00
|
|
|
return $pageHeaders;
|
|
|
|
}
|
2023-01-07 01:47:03 +00:00
|
|
|
|
2023-01-11 02:20:24 +00:00
|
|
|
/**
|
|
|
|
* @return mixed
|
|
|
|
*/
|
2023-01-07 10:20:02 +00:00
|
|
|
public static function getSiteInfo()
|
|
|
|
{
|
2023-01-12 03:30:34 +00:00
|
|
|
return AntConfig::currentConfig('siteInfo');
|
2023-01-07 01:47:03 +00:00
|
|
|
}
|
2023-01-08 01:44:16 +00:00
|
|
|
|
2023-01-26 06:08:19 +00:00
|
|
|
/**
|
2023-01-11 02:20:24 +00:00
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function serveContent(string $path)
|
2023-01-08 01:44:16 +00:00
|
|
|
{
|
|
|
|
if (!file_exists($path)) {
|
|
|
|
$this->renderException('404');
|
|
|
|
} else {
|
|
|
|
$asset_mime_type = mime_content_type($path);
|
|
|
|
header('Content-Type: ' . $asset_mime_type);
|
|
|
|
readfile($path);
|
|
|
|
}
|
|
|
|
}
|
2023-01-07 20:15:29 +00:00
|
|
|
}
|