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