xref: /plugin/sqlite/Functions.php (revision 14fe8e279910db76dc1446ba0e4f688190343c1a)
1<?php
2
3/**
4 * @noinspection PhpUndefinedMethodInspection
5 * @noinspection PhpComposerExtensionStubsInspection
6 */
7
8namespace dokuwiki\plugin\sqlite;
9
10/**
11 * SQLite registered functions
12 */
13class Functions
14{
15    /**
16     * Register all standard functions
17     *
18     * @param \PDO $pdo
19     */
20    public static function register($pdo)
21    {
22        $pdo->sqliteCreateAggregate(
23            'GROUP_CONCAT_DISTINCT',
24            [Functions::class, 'GroupConcatStep'],
25            [Functions::class, 'GroupConcatFinalize']
26        );
27
28        $pdo->sqliteCreateFunction('GETACCESSLEVEL', [Functions::class, 'getAccessLevel'], 1);
29        $pdo->sqliteCreateFunction('PAGEEXISTS', [Functions::class, 'pageExists'], 1);
30        $pdo->sqliteCreateFunction('REGEXP', [Functions::class, 'regExp'], 2);
31        $pdo->sqliteCreateFunction('CLEANID', 'cleanID', 1);
32        $pdo->sqliteCreateFunction('RESOLVEPAGE', [Functions::class, 'resolvePage'], 1);
33    }
34
35    /**
36     * Aggregation function for SQLite via PDO
37     *
38     * @link http://devzone.zend.com/article/863-SQLite-Lean-Mean-DB-Machine
39     *
40     * @param null|array &$context (reference) argument where processed data can be stored
41     * @param int $rownumber current row number
42     * @param string $string column value
43     * @param string $separator separator added between values
44     */
45    // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
46    public static function GroupConcatStep(&$context, $rownumber, $string, $separator = ',')
47    {
48        if (is_null($context)) {
49            $context = [
50                'sep' => $separator,
51                'data' => []
52            ];
53        }
54
55        $context['data'][] = $string;
56        return $context;
57    }
58
59    /**
60     * Aggregation function for SQLite via PDO
61     *
62     * @link http://devzone.zend.com/article/863-SQLite-Lean-Mean-DB-Machine
63     *
64     * @param null|array &$context (reference) data as collected in step callback
65     * @param int $rownumber number of rows over which the aggregate was performed.
66     * @return null|string
67     */
68    // phpcs:ignore PSR1.Methods.CamelCapsMethodName.NotCamelCaps
69    public static function GroupConcatFinalize(&$context, $rownumber)
70    {
71        if (!is_array($context)) {
72            return null;
73        }
74        $context['data'] = array_unique($context['data']);
75        if (empty($context['data'][0])) {
76            return null;
77        }
78        return implode($context['sep'], $context['data']);
79    }
80
81
82    /**
83     * Callback checks the permissions for the current user
84     *
85     * This function is registered as a SQL function named GETACCESSLEVEL
86     *
87     * @param string $pageid page ID (needs to be resolved and cleaned)
88     * @return int permission level
89     */
90    public static function getAccessLevel($pageid)
91    {
92        global $auth;
93        if (!$auth) return AUTH_DELETE;
94
95        static $aclcache = [];
96
97        if (isset($aclcache[$pageid])) {
98            return $aclcache[$pageid];
99        }
100
101        if (isHiddenPage($pageid)) {
102            $acl = AUTH_NONE;
103        } else {
104            $acl = auth_quickaclcheck($pageid);
105        }
106        $aclcache[$pageid] = $acl;
107        return $acl;
108    }
109
110    /**
111     * Wrapper around page_exists() with static caching
112     *
113     * This function is registered as a SQL function named PAGEEXISTS
114     *
115     * @param string $pageid
116     * @return int 0|1
117     */
118    public static function pageExists($pageid)
119    {
120        static $cache = [];
121        if (!isset($cache[$pageid])) {
122            $cache[$pageid] = page_exists($pageid);
123        }
124        return (int)$cache[$pageid];
125    }
126
127    /**
128     * Match a regular expression against a value
129     *
130     * This function is registered as a SQL function named REGEXP
131     *
132     * @param string $regexp
133     * @param string $value
134     * @return bool
135     */
136    public static function regExp($regexp, $value)
137    {
138        $regexp = addcslashes($regexp, '/');
139        return (bool)preg_match('/' . $regexp . '/u', $value);
140    }
141
142    /**
143     * Resolves a page ID (relative namespaces, plurals etc)
144     *
145     * This function is registered as a SQL function named RESOLVEPAGE
146     *
147     * @param string $page The page ID to resolve
148     * @param string $context The page ID (not namespace!) to resolve the page with
149     * @return null|string
150     */
151    public static function resolvePage($page, $context)
152    {
153        if (is_null($page)) return null;
154        if (is_null($context)) return cleanID($page);
155
156        $ns = getNS($context);
157        resolve_pageid($ns, $page, $exists);
158        return $page;
159    }
160}
161