xref: /plugin/aclinfo/syntax.php (revision ef67e929675a5055a440496af227b50903f73f69)
1a2f0e577SAndreas Gohr<?php
28769b165SAndreas Gohr
38769b165SAndreas Gohruse dokuwiki\Extension\SyntaxPlugin;
48769b165SAndreas Gohr
5a2f0e577SAndreas Gohr/**
6a2f0e577SAndreas Gohr * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
7a2f0e577SAndreas Gohr * @author     Andreas Gohr <andi@splitbrain.org>
8a2f0e577SAndreas Gohr */
98769b165SAndreas Gohrclass syntax_plugin_aclinfo extends SyntaxPlugin
108769b165SAndreas Gohr{
118769b165SAndreas Gohr    /** @inheritdoc */
128769b165SAndreas Gohr    public function getType()
138769b165SAndreas Gohr    {
14a2f0e577SAndreas Gohr        return 'substition';
15a2f0e577SAndreas Gohr    }
16a2f0e577SAndreas Gohr
178769b165SAndreas Gohr    /** @inheritdoc */
188769b165SAndreas Gohr    public function getPType()
198769b165SAndreas Gohr    {
20a2f0e577SAndreas Gohr        return 'block';
21a2f0e577SAndreas Gohr    }
22a2f0e577SAndreas Gohr
238769b165SAndreas Gohr    /** @inheritdoc */
248769b165SAndreas Gohr    public function getSort()
258769b165SAndreas Gohr    {
26a2f0e577SAndreas Gohr        return 155;
27a2f0e577SAndreas Gohr    }
28a2f0e577SAndreas Gohr
298769b165SAndreas Gohr    /** @inheritdoc */
308769b165SAndreas Gohr    public function connectTo($mode)
318769b165SAndreas Gohr    {
3216f7e10fSAndreas Gohr        $this->Lexer->addSpecialPattern('~~ACLINFO!?[^~]*?~~', $mode, 'plugin_aclinfo');
33a2f0e577SAndreas Gohr    }
34a2f0e577SAndreas Gohr
358769b165SAndreas Gohr    /** @inheritdoc */
368769b165SAndreas Gohr    public function handle($match, $state, $pos, Doku_Handler $handler)
378769b165SAndreas Gohr    {
3816f7e10fSAndreas Gohr        $match = substr($match, 10, -2);
398769b165SAndreas Gohr        return [$match];
40a2f0e577SAndreas Gohr    }
41a2f0e577SAndreas Gohr
428769b165SAndreas Gohr    /** @inheritdoc */
438769b165SAndreas Gohr    public function render($format, Doku_Renderer $R, $data)
448769b165SAndreas Gohr    {
45a2f0e577SAndreas Gohr        global $INFO;
46a2f0e577SAndreas Gohr        if ($format != 'xhtml') return false;
47a2f0e577SAndreas Gohr
4816f7e10fSAndreas Gohr        if (!$data[0]) {
4916f7e10fSAndreas Gohr            $page = $INFO['id'];
5016f7e10fSAndreas Gohr        } else {
5116f7e10fSAndreas Gohr            $page = $data[0];
5216f7e10fSAndreas Gohr        }
5316f7e10fSAndreas Gohr
548769b165SAndreas Gohr        $perms = $this->aclCheck($page);
55*f5f66cd5SAndreas Gohr        $R->doc .= '<div class="plugin_aclinfo">';
56a2f0e577SAndreas Gohr        $R->listu_open();
5763d6b4f1SAndreas Gohr        foreach ($perms as $who => $p) {
58a2f0e577SAndreas Gohr            $R->listitem_open(1);
59a2f0e577SAndreas Gohr            $R->listcontent_open();
60a2f0e577SAndreas Gohr            $R->cdata(sprintf($this->getLang('perm' . $p), urldecode($who)));
61a2f0e577SAndreas Gohr            $R->listcontent_close();
62a2f0e577SAndreas Gohr            $R->listitem_close();
63a2f0e577SAndreas Gohr        }
64a2f0e577SAndreas Gohr        $R->listu_close();
65*f5f66cd5SAndreas Gohr        $R->doc .= '</div>';
66a2f0e577SAndreas Gohr        return true;
67a2f0e577SAndreas Gohr    }
68a2f0e577SAndreas Gohr
698769b165SAndreas Gohr    /**
708769b165SAndreas Gohr     * Parse the ACL setup and return the permissions for the given page ID.
718769b165SAndreas Gohr     *
728769b165SAndreas Gohr     * @param string $id The page ID to check
738769b165SAndreas Gohr     * @return array
748769b165SAndreas Gohr     */
758769b165SAndreas Gohr    protected function aclCheck($id)
768769b165SAndreas Gohr    {
77a2f0e577SAndreas Gohr        global $AUTH_ACL;
78a2f0e577SAndreas Gohr
7916f7e10fSAndreas Gohr        $id    = cleanID($id);
80a2f0e577SAndreas Gohr        $ns    = getNS($id);
818769b165SAndreas Gohr        $perms = [];
82a2f0e577SAndreas Gohr
83a2f0e577SAndreas Gohr        //check exact match first
84a2f0e577SAndreas Gohr        $matches = preg_grep('/^' . preg_quote($id, '/') . '\s+/', $AUTH_ACL);
8563d6b4f1SAndreas Gohr        $perms = array_merge($perms, $this->processAclMatches($matches));
86a2f0e577SAndreas Gohr
87a2f0e577SAndreas Gohr        //still here? do the namespace checks
88a2f0e577SAndreas Gohr        if ($ns) {
89a2f0e577SAndreas Gohr            $path = $ns . ':\*';
90a2f0e577SAndreas Gohr        } else {
91a2f0e577SAndreas Gohr            $path = '\*'; //root document
92a2f0e577SAndreas Gohr        }
93a2f0e577SAndreas Gohr
94a2f0e577SAndreas Gohr        do {
95a2f0e577SAndreas Gohr            $matches = preg_grep('/^' . $path . '\s+/', $AUTH_ACL);
9663d6b4f1SAndreas Gohr            $perms = array_merge($perms, $this->processAclMatches($matches));
97a2f0e577SAndreas Gohr
98a2f0e577SAndreas Gohr            //get next higher namespace
99a2f0e577SAndreas Gohr            $ns   = getNS($ns);
100a2f0e577SAndreas Gohr
101a2f0e577SAndreas Gohr            if ($path != '\*') {
102a2f0e577SAndreas Gohr                $path = $ns . ':\*';
103a2f0e577SAndreas Gohr                if ($path == ':\*') $path = '\*';
104a2f0e577SAndreas Gohr            } else {
105a2f0e577SAndreas Gohr                //we did this already
106a2f0e577SAndreas Gohr                //break here
107a2f0e577SAndreas Gohr                break;
108a2f0e577SAndreas Gohr            }
109a2f0e577SAndreas Gohr        } while (1); //this should never loop endless
110a2f0e577SAndreas Gohr
111a2f0e577SAndreas Gohr        return $perms;
112a2f0e577SAndreas Gohr    }
11363d6b4f1SAndreas Gohr
11463d6b4f1SAndreas Gohr    /**
11563d6b4f1SAndreas Gohr     * Process ACL matches and return parsed permissions.
11663d6b4f1SAndreas Gohr     *
11763d6b4f1SAndreas Gohr     * @param array $matches Array of ACL lines to process
11863d6b4f1SAndreas Gohr     * @return array Parsed permissions array
11963d6b4f1SAndreas Gohr     */
12063d6b4f1SAndreas Gohr    protected function processAclMatches(array $matches)
12163d6b4f1SAndreas Gohr    {
12263d6b4f1SAndreas Gohr        $perms = [];
12363d6b4f1SAndreas Gohr        foreach ($matches as $match) {
12463d6b4f1SAndreas Gohr            $match = preg_replace('/#.*$/', '', $match); //ignore comments
12563d6b4f1SAndreas Gohr            $acl   = preg_split('/\s+/', $match);
12663d6b4f1SAndreas Gohr            if ($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL!
12763d6b4f1SAndreas Gohr            if (!isset($perms[$acl[1]])) $perms[$acl[1]] = $acl[2];
12863d6b4f1SAndreas Gohr        }
12963d6b4f1SAndreas Gohr        return $perms;
13063d6b4f1SAndreas Gohr    }
131a2f0e577SAndreas Gohr}
132