xref: /plugin/newpagefill/action.php (revision 9a36670832b754c53fa81850c7b00d5bb57a3705)
1<?php
2if (!defined('DOKU_INC')) die();
3
4class action_plugin_newpagefill extends DokuWiki_Action_Plugin
5{
6    public function register(Doku_Event_Handler $controller)
7    {
8        $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'injectJsInfo');
9        $controller->register_hook('COMMON_PAGETPL_LOAD', 'BEFORE', $this, 'handlePageTemplate');
10    }
11
12    public function injectJsInfo(Doku_Event $event, $param): void
13    {
14        global $JSINFO;
15        global $conf;
16
17        if (!isset($JSINFO['plugins']) || !is_array($JSINFO['plugins'])) {
18            $JSINFO['plugins'] = [];
19        }
20        if (!isset($JSINFO['plugins']['newpagefill']) || !is_array($JSINFO['plugins']['newpagefill'])) {
21            $JSINFO['plugins']['newpagefill'] = [];
22        }
23
24        $JSINFO['plugins']['newpagefill']['start'] = (string)$conf['start'];
25        $JSINFO['plugins']['newpagefill']['default_start_mode'] = (string)$this->getConf('default_start_mode');
26        $JSINFO['plugins']['newpagefill']['sepchar'] = (string)$conf['sepchar'];
27        $JSINFO['plugins']['newpagefill']['userewrite'] = (int)$conf['userewrite'];
28    }
29
30    public function handlePageTemplate(Doku_Event $event, $param): void
31    {
32        if (empty($event->data) || !is_array($event->data)) return;
33
34        $id = cleanID((string)($event->data['id'] ?? ''));
35        if ($id === '') return;
36        if (page_exists($id)) return;
37        if (!empty($event->data['tpl'])) {
38            $event->data['tpl'] = $this->applyTitlePlaceholder((string)$event->data['tpl'], $id);
39            return;
40        }
41
42        $templatePath = $this->findNativePageTemplatePath($id);
43        if ($templatePath !== '') {
44            $event->data['tplfile'] = $templatePath;
45            $event->data['tpl'] = $this->applyTitlePlaceholder((string)io_readFile($templatePath), $id);
46            return;
47        }
48
49        if (!empty($event->data['tplfile'])) {
50            $event->data['tpl'] = $this->applyTitlePlaceholder((string)io_readFile((string)$event->data['tplfile']), $id);
51            return;
52        }
53
54        $template = trim((string)$this->getConf('template'));
55        if ($template === '') return;
56
57        $event->data['tpl'] = $this->applyTitlePlaceholder($template, $id);
58    }
59
60    protected function applyTitlePlaceholder(string $template, string $id): string
61    {
62        global $INPUT;
63
64        $title = trim((string)$INPUT->str('title'));
65        if ($title === '') {
66            $title = $this->extractTitleFromRequestUri($id);
67        }
68
69        if ($title === '') {
70            $title = $this->buildFallbackTitleFromId($id);
71        }
72
73        return str_replace('@TITLE@', $title, $template);
74    }
75
76    protected function extractTitleFromRequestUri(string $id): string
77    {
78        global $conf;
79
80        $requestUri = (string)($_SERVER['REQUEST_URI'] ?? '');
81        if ($requestUri === '') return '';
82
83        $path = parse_url($requestUri, PHP_URL_PATH);
84        if (!is_string($path) || $path === '') return '';
85
86        $segments = array_values(array_filter(explode('/', trim($path, '/')), 'strlen'));
87        if (!$segments) return '';
88
89        $candidate = rawurldecode((string)end($segments));
90        if ($candidate === $conf['start']) {
91            array_pop($segments);
92            if (!$segments) return '';
93            $candidate = rawurldecode((string)end($segments));
94        }
95
96        $candidate = str_replace($conf['sepchar'], ' ', $candidate);
97        $candidate = str_replace('_', ' ', $candidate);
98        return ucfirst($candidate);
99    }
100
101    protected function buildFallbackTitleFromId(string $id): string
102    {
103        global $conf;
104
105        $file = noNS($id);
106        $titleSource = $file;
107        if ($file === $conf['start']) {
108            $namespace = getNS($id);
109            if ($namespace !== '') {
110                $titleSource = noNS($namespace);
111            }
112        }
113
114        $title = str_replace($conf['sepchar'], ' ', $titleSource);
115        $title = str_replace('_', ' ', $title);
116        return ucfirst($title);
117    }
118
119    protected function findNativePageTemplatePath(string $id): string
120    {
121        global $conf;
122
123        $path = dirname(wikiFN($id));
124        if (file_exists($path . '/_template.txt')) {
125            return $path . '/_template.txt';
126        }
127
128        $root = strlen(rtrim($conf['datadir'], '/'));
129        while (strlen($path) >= $root) {
130            if (file_exists($path . '/__template.txt')) {
131                return $path . '/__template.txt';
132            }
133
134            $next = strrpos($path, '/');
135            if ($next === false) break;
136            $path = substr($path, 0, $next);
137        }
138
139        return '';
140    }
141}
142