1<?php
2
3namespace dokuwiki\File;
4
5/**
6 * Creates an absolute page ID from a relative one
7 */
8class PageResolver extends Resolver
9{
10
11    /**
12     * Resolves a given ID to be absolute
13     *
14     * This handles all kinds of relative shortcuts, startpages and autoplurals
15     * @inheritDoc
16     */
17    public function resolveId($id, $rev = '', $isDateAt = false)
18    {
19        global $conf;
20        $id = (string) $id;
21
22        // pages may have a hash attached, we separate it on resolving
23        if (strpos($id, '#') !== false) {
24            list($id, $hash) = sexplode('#', $id, 2);
25            $hash = cleanID($hash);
26        } else {
27            $hash = '';
28        }
29
30        if ($id !== '') {
31            $id = parent::resolveId($id, $rev, $isDateAt);
32            $id = $this->resolveStartPage($id, $rev, $isDateAt);
33            if ($conf['autoplural']) {
34                $id = $this->resolveAutoPlural($id, $rev, $isDateAt);
35            }
36        } else {
37            $id = $this->contextID;
38        }
39
40        $id = cleanID($id); // FIXME always? or support parameter
41        // readd hash if any
42        if ($hash !== '') $id .= "#$hash";
43        return $id;
44    }
45
46    /**
47     * IDs ending in :
48     *
49     * @param string $id
50     * @param string|int|false $rev
51     * @param bool $isDateAt
52     * @return string
53     */
54    protected function resolveStartPage($id, $rev, $isDateAt)
55    {
56        global $conf;
57
58        if ($id[-1] !== ':') return $id;
59
60        if (page_exists($id . $conf['start'], $rev, true, $isDateAt)) {
61            // start page inside namespace
62            return $id . $conf['start'];
63        } elseif (page_exists($id . noNS(cleanID($id)), $rev, true, $isDateAt)) {
64            // page named like the NS inside the NS
65            return $id . noNS(cleanID($id));
66        } elseif (page_exists(substr($id, 0, -1), $rev, true, $isDateAt)) {
67            // page named like the NS outside the NS
68            return substr($id, 0, -1);
69        }
70
71        // fall back to default start page
72        return $id . $conf['start'];
73    }
74
75    /**
76     * Try alternative plural/singular form
77     *
78     * @param string $id
79     * @param int $rev
80     * @param bool $isDateAt
81     * @return string
82     */
83    protected function resolveAutoPlural($id, $rev, $isDateAt)
84    {
85        if (page_exists($id, $rev, $isDateAt)) return $id;
86
87        if ($id[-1] === 's') {
88            $try = substr($id, 0, -1);
89        } else {
90            $try = $id . 's';
91        }
92
93        if (page_exists($try, $rev, true, $isDateAt)) {
94            return $try;
95        }
96        return $id;
97    }
98
99}
100