- Fix path traversal with realpath() validation in getPage() and executePhpFile() - Remove insecure JWT secret fallback, require JWT_SECRET env var - Fix IP spoofing by only trusting proxy headers from configured proxies - Add Secure/HttpOnly/SameSite flags to all cookies - Use env var for debug mode instead of hardcoded true - Fix operator precedence bug in MQTTTracker track_user_flows check - Remove dead code: duplicate is_dir() block, unused scanForPageNames() - Remove htmlspecialchars() from filesystem path operations - Remove duplicate require_once calls and redundant autoloader includes - Fix unclosed </div> in getDirectoryListing() - Escape breadcrumb titles and add lang param to search result URLs - Make language prefixes dynamic from config instead of hardcoded nl|en - Make HTML lang attribute dynamic, add go_to translation key - Add aria-label/aria-expanded to sidebar toggle for accessibility - Fix event listener leak in app.js using event delegation - Remove console.log from production code - Update guides (NL/EN) with sidebar toggle documentation - Add TODO.md documenting all identified improvements
223 lines
5.1 KiB
PHP
223 lines
5.1 KiB
PHP
<?php
|
|
|
|
class CMSAPI
|
|
{
|
|
private CodePressCMS $cms;
|
|
|
|
public function __construct(CodePressCMS $cms)
|
|
{
|
|
$this->cms = $cms;
|
|
}
|
|
|
|
/**
|
|
* Get current page information
|
|
*/
|
|
public function getCurrentPage(): array
|
|
{
|
|
return $this->cms->getPage();
|
|
}
|
|
|
|
/**
|
|
* Get current page title
|
|
*/
|
|
public function getCurrentPageTitle(): string
|
|
{
|
|
$page = $this->cms->getPage();
|
|
return $page['title'] ?? '';
|
|
}
|
|
|
|
/**
|
|
* Get current page content
|
|
*/
|
|
public function getCurrentPageContent(): string
|
|
{
|
|
$page = $this->cms->getPage();
|
|
return $page['content'] ?? '';
|
|
}
|
|
|
|
/**
|
|
* Get current page URL
|
|
*/
|
|
public function getCurrentPageUrl(): string
|
|
{
|
|
$page = $_GET['page'] ?? $this->cms->config['default_page'];
|
|
$lang = $_GET['lang'] ?? $this->cms->config['language']['default'] ?? 'nl';
|
|
return "?page={$page}&lang={$lang}";
|
|
}
|
|
|
|
/**
|
|
* Get menu structure
|
|
*/
|
|
public function getMenu(): array
|
|
{
|
|
return $this->cms->getMenu();
|
|
}
|
|
|
|
/**
|
|
* Get configuration value
|
|
*/
|
|
public function getConfig(string $key, $default = null)
|
|
{
|
|
$keys = explode('.', $key);
|
|
$value = $this->cms->config;
|
|
|
|
foreach ($keys as $k) {
|
|
if (!isset($value[$k])) {
|
|
return $default;
|
|
}
|
|
$value = $value[$k];
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
/**
|
|
* Get translation
|
|
*/
|
|
public function translate(string $key): string
|
|
{
|
|
return $this->cms->t($key);
|
|
}
|
|
|
|
/**
|
|
* Get current language
|
|
*/
|
|
public function getCurrentLanguage(): string
|
|
{
|
|
return $this->cms->currentLanguage;
|
|
}
|
|
|
|
/**
|
|
* Check if user is on homepage
|
|
*/
|
|
public function isHomepage(): bool
|
|
{
|
|
$defaultPage = $this->cms->config['default_page'] ?? 'index';
|
|
$currentPage = $_GET['page'] ?? $defaultPage;
|
|
return $currentPage === $defaultPage;
|
|
}
|
|
|
|
/**
|
|
* Get file info for current page
|
|
*/
|
|
public function getCurrentPageFileInfo(): ?array
|
|
{
|
|
$page = $this->cms->getPage();
|
|
return $page['file_info'] ?? null;
|
|
}
|
|
|
|
/**
|
|
* Get breadcrumb data
|
|
*/
|
|
public function getBreadcrumb(): string
|
|
{
|
|
return $this->cms->generateBreadcrumb();
|
|
}
|
|
|
|
/**
|
|
* Check if content directory has content
|
|
*/
|
|
public function hasContent(): bool
|
|
{
|
|
return !$this->cms->isContentDirEmpty();
|
|
}
|
|
|
|
/**
|
|
* Get search results if searching
|
|
*/
|
|
public function getSearchResults(): array
|
|
{
|
|
if (isset($_GET['search'])) {
|
|
return $this->cms->searchResults;
|
|
}
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Check if currently searching
|
|
*/
|
|
public function isSearching(): bool
|
|
{
|
|
return isset($_GET['search']);
|
|
}
|
|
|
|
/**
|
|
* Get available languages
|
|
*/
|
|
public function getAvailableLanguages(): array
|
|
{
|
|
return $this->cms->getAvailableLanguages();
|
|
}
|
|
|
|
/**
|
|
* Create URL for page
|
|
*/
|
|
public function createUrl(string $page, ?string $lang = null): string
|
|
{
|
|
$lang = $lang ?? $this->getCurrentLanguage();
|
|
return "?page={$page}&lang={$lang}";
|
|
}
|
|
|
|
/**
|
|
* Execute PHP file and capture output
|
|
*/
|
|
public function executePhpFile(string $filePath): string
|
|
{
|
|
if (!file_exists($filePath)) {
|
|
return '';
|
|
}
|
|
|
|
// Validate file is within the CMS directory to prevent arbitrary file inclusion
|
|
$realPath = realpath($filePath);
|
|
$cmsRoot = realpath(__DIR__ . '/../../../');
|
|
if (!$realPath || !$cmsRoot || strpos($realPath, $cmsRoot) !== 0) {
|
|
return '';
|
|
}
|
|
|
|
ob_start();
|
|
include $filePath;
|
|
return ob_get_clean();
|
|
}
|
|
|
|
/**
|
|
* Get content from PHP/HTML/Markdown file
|
|
*/
|
|
public function getFileContent(string $filePath): string
|
|
{
|
|
if (!file_exists($filePath)) {
|
|
return '';
|
|
}
|
|
|
|
$extension = pathinfo($filePath, PATHINFO_EXTENSION);
|
|
|
|
switch ($extension) {
|
|
case 'php':
|
|
return $this->executePhpFile($filePath);
|
|
case 'md':
|
|
$content = file_get_contents($filePath);
|
|
$result = $this->cms->parseMarkdown($content, $filePath);
|
|
return $result['content'] ?? '';
|
|
case 'html':
|
|
return file_get_contents($filePath);
|
|
default:
|
|
return file_get_contents($filePath);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if file exists in content directory
|
|
*/
|
|
public function contentFileExists(string $filename): bool
|
|
{
|
|
$contentDir = $this->cms->config['content_dir'];
|
|
return file_exists($contentDir . '/' . $filename);
|
|
}
|
|
|
|
/**
|
|
* Get all pages with their metadata
|
|
*/
|
|
public function getAllPages(): array
|
|
{
|
|
return $this->cms->getAllPageTitles();
|
|
}
|
|
} |