page: .private to restrict access to subdirectories
[minimedit.git] / page.php
1 <?php
2 error_reporting(E_ALL);
3 ini_set('display_errors', TRUE);
4
5 function getoutput($blocks = [])
6 {
7         $rep = [];
8         foreach ($blocks as $name => $html) {
9                 $rep["[[$name]]"] = sprintf('<!--BLOCK:%s-->%s<!--/-->',
10                         is_numeric($name) ? '' : "[[$name]]",
11                         preg_replace('{<!--[^-]*-->}', '', $html)
12                 );
13         }
14         return str_replace(array_keys($rep), array_values($rep), ob_get_clean());
15 }
16
17 function fail($error)
18 {
19         http_response_code(500);
20         include_once 'page.inc.php';
21         ob_start();
22         require_once './500.html';
23         print getoutput(['debug' => $error]);
24 }
25 set_exception_handler('fail');
26 register_shutdown_function(function () {
27         # display failure page for fatal exceptions
28         $error = error_get_last();
29         if (!($error['type'] & (E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR))) return;
30         fail("Fatal: $error[message] in $error[file]:$error[line]");
31 });
32
33 include_once 'auth.inc.php';
34 $Edit = isset($_GET['edit']);
35
36 # distinguish subpage Args from topmost Page script
37
38 $Args = '';
39 $Page = preg_replace('/\?.*/', '', $_SERVER['REQUEST_URI']);
40 $Page = urldecode(trim($Page, '/')) ?: 'index';
41 while (TRUE) {
42         if (file_exists("$Page/.private")) {
43                 # access restriction
44                 if (!isset($User)) {
45                         http_response_code(403);
46                         include_once 'page.inc.php';
47                         ob_start();
48                         require_once './403.html';
49                         exit;
50                 }
51         }
52
53         if (file_exists("$Page.php")) {
54                 break;
55         }
56
57         $up = strrpos($Page, '/');
58         $Args = substr($Page, $up) . $Args;
59         $Page = substr($Page, 0, $up);
60         if ($up === FALSE) {
61                 break;
62         }
63 }
64
65 # load static contents
66
67 ob_start(); # page body
68 ob_start(); # inner html
69 print '<div class="static">'."\n\n";
70
71 $found = FALSE;
72 if (file_exists("$Page$Args/index.html")) {
73         $found = include "./$Page$Args/index.html";
74 }
75 elseif (file_exists("$Page$Args.html")) {
76         $found = include "./$Page$Args.html";
77 }
78 elseif (isset($User) and $User['admin']) {
79         $found = require (file_exists("$Page/template.html") ? "$Page/template.html" : './template.html');
80 }
81
82 print "</div>\n\n";
83
84 # execute dynamic code
85
86 if ($Page) {
87         $found |= require "./$Page.php";
88 }
89
90 # global html
91
92 include_once 'page.inc.php';
93
94 if (!$found) {
95         # no resulting output
96         http_response_code(404);
97         ob_start();
98         require "./404.html";
99         print getoutput([ 'url' => htmlspecialchars($_SERVER['REQUEST_URI']) ]);
100 }
101