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('PAGEISHIDDEN', [Functions::class, 'pageIsHidden'], 1); 30 $pdo->sqliteCreateFunction('PAGEEXISTS', [Functions::class, 'pageExists'], 1); 31 $pdo->sqliteCreateFunction('REGEXP', [Functions::class, 'regExp'], 2); 32 $pdo->sqliteCreateFunction('CLEANID', 'cleanID', 1); 33 $pdo->sqliteCreateFunction('RESOLVEPAGE', [Functions::class, 'resolvePage'], 1); 34 } 35 36 /** 37 * Aggregation function for SQLite via PDO 38 * 39 * @link http://devzone.zend.com/article/863-SQLite-Lean-Mean-DB-Machine 40 * 41 * @param null|array &$context (reference) argument where processed data can be stored 42 * @param int $rownumber current row number 43 * @param string $string column value 44 * @param string $separator separator added between values 45 */ 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 public static function groupConcatFinalize(&$context, $rownumber) 69 { 70 if (!is_array($context)) { 71 return null; 72 } 73 $context['data'] = array_unique($context['data']); 74 if (empty($context['data'][0])) { 75 return null; 76 } 77 return implode($context['sep'], $context['data']); 78 } 79 80 81 /** 82 * Callback checks the permissions for the current user 83 * 84 * This function is registered as a SQL function named GETACCESSLEVEL 85 * 86 * @param string $pageid page ID (needs to be resolved and cleaned) 87 * @return int permission level 88 */ 89 public static function getAccessLevel($pageid) 90 { 91 global $auth; 92 if (!$auth) return AUTH_DELETE; 93 94 static $aclcache = []; 95 96 if (isset($aclcache[$pageid])) { 97 return $aclcache[$pageid]; 98 } 99 100 $acl = auth_quickaclcheck($pageid); 101 $aclcache[$pageid] = $acl; 102 return $acl; 103 } 104 105 /** 106 * Check if a page is hidden 107 * 108 * @param string $pageid 109 * @return int 1 if the page is hidden 110 */ 111 public static function pageIsHidden($pageid) 112 { 113 static $hiddenCache = []; 114 if (isset($hiddenCache[$pageid])) { 115 return $hiddenCache[$pageid]; 116 } 117 118 119 $ishidden = (int) isHiddenPage($pageid); 120 $hiddenCache[$pageid] = $ishidden; 121 return $ishidden; 122 } 123 124 /** 125 * Wrapper around page_exists() with static caching 126 * 127 * This function is registered as a SQL function named PAGEEXISTS 128 * 129 * @param string $pageid 130 * @return int 0|1 131 */ 132 public static function pageExists($pageid) 133 { 134 static $cache = []; 135 if (!isset($cache[$pageid])) { 136 $cache[$pageid] = page_exists($pageid); 137 } 138 return (int)$cache[$pageid]; 139 } 140 141 /** 142 * Match a regular expression against a value 143 * 144 * This function is registered as a SQL function named REGEXP 145 * 146 * @param string $regexp 147 * @param string $value 148 * @return bool 149 */ 150 public static function regExp($regexp, $value) 151 { 152 $regexp = addcslashes($regexp, '/'); 153 return (bool)preg_match('/' . $regexp . '/u', $value); 154 } 155 156 /** 157 * Resolves a page ID (relative namespaces, plurals etc) 158 * 159 * This function is registered as a SQL function named RESOLVEPAGE 160 * 161 * @param string $page The page ID to resolve 162 * @param string $context The page ID (not namespace!) to resolve the page with 163 * @return null|string 164 */ 165 public static function resolvePage($page, $context) 166 { 167 if (is_null($page)) return null; 168 if (is_null($context)) return cleanID($page); 169 170 $ns = getNS($context); 171 resolve_pageid($ns, $page, $exists); 172 return $page; 173 } 174} 175