aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/inc/File/PageResolver.php
blob: 66a5a024eefdc3f96a001d64f66308e0c6063fd9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<?php

namespace dokuwiki\File;

/**
 * Creates an absolute page ID from a relative one
 */
class PageResolver extends Resolver
{
    /**
     * Resolves a given ID to be absolute
     *
     * This handles all kinds of relative shortcuts, startpages and autoplurals
     * @inheritDoc
     */
    public function resolveId($id, $rev = '', $isDateAt = false)
    {
        global $conf;
        $id = (string) $id;

        // pages may have a hash attached, we separate it on resolving
        if (strpos($id, '#') !== false) {
            [$id, $hash] = sexplode('#', $id, 2);
            $hash = cleanID($hash);
        } else {
            $hash = '';
        }

        if ($id !== '') {
            $id = parent::resolveId($id, $rev, $isDateAt);
            $id = $this->resolveStartPage($id, $rev, $isDateAt);
            if ($conf['autoplural']) {
                $id = $this->resolveAutoPlural($id, $rev, $isDateAt);
            }
        } else {
            $id = $this->contextID;
        }

        $id = cleanID($id); // FIXME always? or support parameter
        // readd hash if any
        if ($hash !== '') $id .= "#$hash";
        return $id;
    }

    /**
     * IDs ending in :
     *
     * @param string $id
     * @param string|int|false $rev
     * @param bool $isDateAt
     * @return string
     */
    protected function resolveStartPage($id, $rev, $isDateAt)
    {
        global $conf;

        if ($id === '' || $id[-1] !== ':') return $id;

        if (page_exists($id . $conf['start'], $rev, true, $isDateAt)) {
            // start page inside namespace
            return $id . $conf['start'];
        } elseif (page_exists($id . noNS(cleanID($id)), $rev, true, $isDateAt)) {
            // page named like the NS inside the NS
            return $id . noNS(cleanID($id));
        } elseif (page_exists(substr($id, 0, -1), $rev, true, $isDateAt)) {
            // page named like the NS outside the NS
            return substr($id, 0, -1);
        }

        // fall back to default start page
        return $id . $conf['start'];
    }

    /**
     * Try alternative plural/singular form
     *
     * @param string $id
     * @param int $rev
     * @param bool $isDateAt
     * @return string
     */
    protected function resolveAutoPlural($id, $rev, $isDateAt)
    {
        if (page_exists($id, $rev, $isDateAt)) return $id;

        if ($id[-1] === 's') {
            $try = substr($id, 0, -1);
        } else {
            $try = $id . 's';
        }

        if (page_exists($try, $rev, true, $isDateAt)) {
            return $try;
        }
        return $id;
    }
}