- Content bestanden met dezelfde naam maar ander type (md/php/html) worden correct geserveerd: URL met extensie opent dat bestand, URL zonder extensie valt terug op md > php > html (resolveContentByType helper) - Admin content editor accepteert bestanden met dezelfde naam (ander type); preview-knop linkt per extensie - Frontend navigatie/directory listing/search tonen elk bestandstype apart - getAllPages() array structuur gewijzigd naar list van ['path','title','type'] met type 'md'/'php'/'html'/'folder' - Verberg-prefix logica: _ is geen verberg-prefix meer, alleen . (en -); admin toont wél alle . bestanden/mappen - ContentAPI getPage()/pageExists() respecteren expliciete extensie - Handleiding content-api.md (NL+EN) herschreven - File-tree unificatie: _file-tree.twig + _editor-styles.twig includes - Versie verhoogd naar 2.6.3
276 lines
7.8 KiB
PHP
276 lines
7.8 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Content API for PHP content files
|
|
*
|
|
* Provides a safe, read-only interface for PHP content files to access
|
|
* CMS data (pages, menu, config, navigation, translations, search).
|
|
* Only instantiated inside parsePHP() — never exposed via URL.
|
|
*/
|
|
class ContentAPI
|
|
{
|
|
private CodePressCMS $cms;
|
|
|
|
public function __construct(CodePressCMS $cms)
|
|
{
|
|
$this->cms = $cms;
|
|
}
|
|
|
|
/**
|
|
* Get all content entries (mappen + bestanden) as a list of entry arrays.
|
|
*
|
|
* @return array List of ['path' => ..., 'title' => ..., 'type' => ...]
|
|
* type is 'md'/'php'/'html' voor bestanden, 'folder' voor mappen.
|
|
*/
|
|
public function getAllPages(): array
|
|
{
|
|
return $this->cms->getAllPageTitles();
|
|
}
|
|
|
|
/**
|
|
* Get a single page by path, including title, content, layout, and metadata
|
|
*
|
|
* De $path mag een extensie bevten (bijv. 'over-ons.php') of niet ('over-ons').
|
|
* Zonder extensie wordt het eerste bestaande bestand gekozen (md > php > html);
|
|
* met extensie wordt dat specifieke bestand gekozen.
|
|
*
|
|
* @param string $path Page path, al dan niet met extensie
|
|
* @return array|null Page data or null if not found
|
|
*/
|
|
public function getPage(string $path): ?array
|
|
{
|
|
$contentDir = $this->cms->config['content_dir'];
|
|
|
|
// Detecteer expliciete extensie en strip hem voor de basis
|
|
$preferredExt = null;
|
|
if (preg_match('/\.(md|php|html)$/i', $path, $m)) {
|
|
$preferredExt = strtolower($m[1]);
|
|
}
|
|
$path = preg_replace('/\.(md|php|html)$/i', '', $path);
|
|
$filePath = $contentDir . '/' . $path;
|
|
|
|
// Probeer de gevraagde extensie eerst, dan de standaard volgorde
|
|
$order = ['md', 'php', 'html'];
|
|
if ($preferredExt !== null) {
|
|
$order = array_unique(array_merge([$preferredExt], $order));
|
|
}
|
|
$actualPath = null;
|
|
foreach ($order as $ext) {
|
|
if (file_exists($filePath . '.' . $ext)) {
|
|
$actualPath = $filePath . '.' . $ext;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!$actualPath || !file_exists($actualPath)) {
|
|
return null;
|
|
}
|
|
|
|
$content = file_get_contents($actualPath);
|
|
$extension = pathinfo($actualPath, PATHINFO_EXTENSION);
|
|
|
|
switch ($extension) {
|
|
case 'md':
|
|
$result = $this->cms->parseMarkdown($content, $actualPath);
|
|
break;
|
|
case 'php':
|
|
$result = $this->cms->parsePHP($actualPath);
|
|
$result['content'] = $this->cms->processContent($result['content']);
|
|
break;
|
|
case 'html':
|
|
$result = $this->cms->parseHTML($content, $actualPath);
|
|
break;
|
|
default:
|
|
return null;
|
|
}
|
|
|
|
return [
|
|
'title' => $result['title'] ?? '',
|
|
'content' => $result['content'] ?? '',
|
|
'path' => $path,
|
|
'layout' => $result['layout'] ?? 'sidebar-content',
|
|
'metadata' => $result['metadata'] ?? [],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Get the navigation menu structure
|
|
*
|
|
* @return array Hierarchical menu array with 'title', 'path', 'children', 'active' keys
|
|
*/
|
|
public function getMenu(): array
|
|
{
|
|
return $this->cms->getMenu();
|
|
}
|
|
|
|
/**
|
|
* Get a config value using dot notation
|
|
*
|
|
* @param string $key Config key, e.g. 'site_title' or 'features.search'
|
|
* @param mixed $default Default value if key is not found
|
|
* @return mixed Config value or default
|
|
*/
|
|
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 the current language code (e.g. 'nl' or 'en')
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getCurrentLanguage(): string
|
|
{
|
|
return $this->cms->currentLanguage;
|
|
}
|
|
|
|
/**
|
|
* Build a URL for a page, optionally with a specific language and extra params
|
|
*
|
|
* @param string $page Page path (default 'index')
|
|
* @param string|null $lang Language code (defaults to current language)
|
|
* @param array $params Additional query parameters
|
|
* @return string URL string starting with '?'
|
|
*/
|
|
public function buildUrl(string $page = 'index', ?string $lang = null, array $params = []): string
|
|
{
|
|
$lang = $lang ?? $this->getCurrentLanguage();
|
|
$query = 'page=' . urlencode($page) . '&lang=' . urlencode($lang);
|
|
if (!empty($params)) {
|
|
$query .= '&' . http_build_query($params);
|
|
}
|
|
return '?' . $query;
|
|
}
|
|
|
|
/**
|
|
* Check if a page exists at the given path
|
|
*
|
|
* @param string $path Page path, al dan niet met extensie
|
|
* @return bool
|
|
*/
|
|
public function pageExists(string $path): bool
|
|
{
|
|
$contentDir = $this->cms->config['content_dir'];
|
|
$basePath = $contentDir . '/' . preg_replace('/\.(md|php|html)$/i', '', $path);
|
|
|
|
return file_exists($basePath . '.md')
|
|
|| file_exists($basePath . '.php')
|
|
|| file_exists($basePath . '.html');
|
|
}
|
|
|
|
/**
|
|
* Get the title of the currently viewed page
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getCurrentPageTitle(): string
|
|
{
|
|
$page = $this->cms->getPage();
|
|
return $page['title'] ?? '';
|
|
}
|
|
|
|
/**
|
|
* Get the path of the currently viewed page
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getCurrentPagePath(): string
|
|
{
|
|
return $_GET['page'] ?? $this->cms->config['default_page'];
|
|
}
|
|
|
|
/**
|
|
* Check if the current page is the homepage
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isHomepage(): bool
|
|
{
|
|
$defaultPage = $this->cms->config['default_page'] ?? 'index';
|
|
$currentPage = $_GET['page'] ?? $defaultPage;
|
|
return $currentPage === $defaultPage;
|
|
}
|
|
|
|
/**
|
|
* Translate a language key using the current language
|
|
*
|
|
* @param string $key Language key
|
|
* @return string Translated text
|
|
*/
|
|
public function t(string $key): string
|
|
{
|
|
return $this->cms->t($key);
|
|
}
|
|
|
|
/**
|
|
* Get the site title from config
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getSiteTitle(): string
|
|
{
|
|
return $this->cms->config['site_title'] ?? 'CodePress';
|
|
}
|
|
|
|
/**
|
|
* Get all available language codes
|
|
*
|
|
* @return array Language codes like ['nl', 'en']
|
|
*/
|
|
public function getAvailableLanguages(): array
|
|
{
|
|
return $this->cms->getAvailableLanguages();
|
|
}
|
|
|
|
/**
|
|
* Get search results for the current search query
|
|
*
|
|
* @return array Search results, or empty array if not searching
|
|
*/
|
|
public function getSearchResults(): array
|
|
{
|
|
if (isset($_GET['search'])) {
|
|
return $this->cms->searchResults;
|
|
}
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
* Check if a search is currently active
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function isSearching(): bool
|
|
{
|
|
return isset($_GET['search']);
|
|
}
|
|
|
|
/**
|
|
* Get the author metadata for the current page.
|
|
* Returns author_name, author_email and created from the page frontmatter.
|
|
*
|
|
* @return array Author metadata with keys: author_name, author_email, created
|
|
*/
|
|
public function getPageAuthor(): array
|
|
{
|
|
$page = $this->cms->getPage();
|
|
$metadata = $page['metadata'] ?? [];
|
|
return [
|
|
'author_name' => $metadata['author_name'] ?? '',
|
|
'author_email' => $metadata['author_email'] ?? '',
|
|
'created' => $metadata['created'] ?? '',
|
|
];
|
|
}
|
|
}
|