page.php

main 91 lines · 2.9 KB Raw
Alex Alex Commit Initial commit 01/10/2026 09:20
1<?php
2/**
3 * Front controller for pages a theme adds.
4 *
5 * Any .php file dropped in layouts/<theme>/pages/ is live at
6 * page.php?p=<filename> - nothing to register anywhere.
7 *
8 * The name is checked against the files that actually exist in the theme, so
9 * ?p= can never reach anything outside pages/.
10 *
11 * Pretty URLs are a rewrite away, if you want them:
12 * RewriteRule ^([a-z0-9_-]+)\.html$ page.php?p=$1 [L,QSA]
13 */
14
15require_once 'engine/init.php';
16
17$requested = theme_sanitize((string)($_GET['p'] ?? ''));
18
19// A plugin page: page.php?plugin=shop_coupons&p=redeem
20// Checked first, and only for an enabled plugin - a disabled one is invisible.
21$pluginName = znote_plugin_sanitize((string)($_GET['plugin'] ?? ''));
22$file = ($pluginName !== '')
23 ? znote_plugin_page($pluginName, $requested)
24 : (($requested !== '') ? theme_file('pages/' . $requested . '.php') : null);
25
26if ($file === null) {
27 if ($pluginName === '' && $requested !== '' && function_exists('znote_table_exists') && znote_table_exists('znote_pages')) {
28 $dbPage = db()->fetchOne("
29 SELECT `slug`, `title`, `body`, `access`
30 FROM `znote_pages`
31 WHERE `slug` = ?
32 AND `active` = 1
33 LIMIT 1;
34 ", [$requested]);
35
36 if (is_array($dbPage)) {
37 if ((int)$dbPage['access'] > 0) {
38 protect_page();
39 }
40 $page_filename = 'page_' . $requested;
41 theme_open();
42 echo '<h1>' . htmlspecialchars((string)$dbPage['title'], ENT_QUOTES, 'UTF-8') . '</h1>';
43 echo znote_bbcode_raw((string)$dbPage['body']);
44 theme_close();
45 exit;
46 }
47 }
48
49 http_response_code(404);
50 $page_filename = 'page_not_found';
51 theme_open();
52 echo '<h1>'. t('page.not_found') .'</h1>';
53 if ($pluginName !== '') {
54 echo '<p>The <strong>' . htmlspecialchars($pluginName, ENT_QUOTES, 'UTF-8')
55 . '</strong> plugin has no page called <code>' . htmlspecialchars($requested, ENT_QUOTES, 'UTF-8')
56 . '</code>, or the plugin is disabled.</p>';
57 } else {
58 echo '<p>'. t('page.no_such_page') .' <code>pages/' . htmlspecialchars($requested, ENT_QUOTES, 'UTF-8')
59 . '.php</code> in the <strong>' . htmlspecialchars(theme_active(), ENT_QUOTES, 'UTF-8')
60 . '</strong> theme.</p>';
61 }
62 theme_close();
63 exit;
64}
65
66// Lets a theme style one of its own pages from CSS alone: body.page_wiki
67$page_filename = 'page_' . ($pluginName !== '' ? $pluginName . '_' : '') . $requested;
68
69$page_title = ucwords(str_replace(array('-', '_'), ' ', $requested !== '' ? $requested : 'index'));
70if (function_exists('znote_hook_filter')) {
71 $page_title = (string) znote_hook_filter('page.title', $page_title, array(
72 'plugin' => $pluginName,
73 'page' => $requested,
74 'filename' => $page_filename,
75 ));
76}
77$GLOBALS['page_title'] = $page_title;
78
79theme_open();
80if ($pluginName !== '') {
81 ob_start();
82 include $file;
83 $pluginContent = ob_get_clean();
84 echo function_exists('theme_wrap_plugin_page')
85 ? theme_wrap_plugin_page($pluginContent, $page_title, $pluginName, $requested)
86 : $pluginContent;
87} else {
88 include $file;
89}
90theme_close();
91
Top