15511bd5bSAndreas Gohr<?php 25511bd5bSAndreas Gohr 3ba766201SAndreas Gohrnamespace dokuwiki\plugin\struct\meta; 45511bd5bSAndreas Gohr 55511bd5bSAndreas Gohr/** 65511bd5bSAndreas Gohr * Class SearchConfig 75511bd5bSAndreas Gohr * 85511bd5bSAndreas Gohr * The same as @see Search but can be initialized by a configuration array 95511bd5bSAndreas Gohr * 10ba766201SAndreas Gohr * @package dokuwiki\plugin\struct\meta 115511bd5bSAndreas Gohr */ 12*d6d97f60SAnna Dabrowskaclass SearchConfig extends Search 13*d6d97f60SAnna Dabrowska{ 145511bd5bSAndreas Gohr 1516b7d914SAndreas Gohr /** @var int default aggregation caching (depends on last struct save) */ 16*d6d97f60SAnna Dabrowska public static $CACHE_DEFAULT = 1; 1716b7d914SAndreas Gohr /** @var int caching depends on current user */ 18*d6d97f60SAnna Dabrowska public static $CACHE_USER = 2; 1916b7d914SAndreas Gohr /** @var int caching depends on current date */ 20*d6d97f60SAnna Dabrowska public static $CACHE_DATE = 4; 2116b7d914SAndreas Gohr 22668e4f8eSAndreas Gohr /** 23668e4f8eSAndreas Gohr * @var array hold the configuration as parsed and extended by dynamic params 24668e4f8eSAndreas Gohr */ 251a07b696SMichael Große protected $config; 261a07b696SMichael Große 27668e4f8eSAndreas Gohr /** 28668e4f8eSAndreas Gohr * @var SearchConfigParameters manages dynamic parameters 29668e4f8eSAndreas Gohr */ 3000f6af48SAndreas Gohr protected $dynamicParameters; 3100f6af48SAndreas Gohr 325511bd5bSAndreas Gohr /** 3316b7d914SAndreas Gohr * @var int the cache flag to use (binary flags) 3416b7d914SAndreas Gohr */ 3516b7d914SAndreas Gohr protected $cacheFlag; 3616b7d914SAndreas Gohr 3716b7d914SAndreas Gohr /** 385511bd5bSAndreas Gohr * SearchConfig constructor. 3900f6af48SAndreas Gohr * @param array $config The parsed configuration for this search 405511bd5bSAndreas Gohr */ 41*d6d97f60SAnna Dabrowska public function __construct($config) 42*d6d97f60SAnna Dabrowska { 435511bd5bSAndreas Gohr parent::__construct(); 445511bd5bSAndreas Gohr 453ad292a8SAndreas Gohr // setup schemas and columns 460215a637SAndreas Gohr if (!empty($config['schemas'])) foreach ($config['schemas'] as $schema) { 473ad292a8SAndreas Gohr $this->addSchema($schema[0], $schema[1]); 483ad292a8SAndreas Gohr } 490215a637SAndreas Gohr if (!empty($config['cols'])) foreach ($config['cols'] as $col) { 503ad292a8SAndreas Gohr $this->addColumn($col); 513ad292a8SAndreas Gohr } 523ad292a8SAndreas Gohr 5316b7d914SAndreas Gohr // cache flag setting 5416b7d914SAndreas Gohr $this->cacheFlag = self::$CACHE_DEFAULT; 5516b7d914SAndreas Gohr if (!empty($config['filters'])) $this->cacheFlag = $this->determineCacheFlag($config['filters']); 5616b7d914SAndreas Gohr 5700f6af48SAndreas Gohr // apply dynamic paramters 5800f6af48SAndreas Gohr $this->dynamicParameters = new SearchConfigParameters($this); 59668e4f8eSAndreas Gohr $config = $this->dynamicParameters->updateConfig($config); 6000f6af48SAndreas Gohr 6100f6af48SAndreas Gohr // configure search from configuration 6200f6af48SAndreas Gohr if (!empty($config['filter'])) foreach ($config['filter'] as $filter) { 635625b985SAndreas Gohr $this->addFilter($filter[0], $this->applyFilterVars($filter[2]), $filter[1], $filter[3]); 645511bd5bSAndreas Gohr } 6500f6af48SAndreas Gohr 6600f6af48SAndreas Gohr if (!empty($config['sort'])) foreach ($config['sort'] as $sort) { 67aa124708SAndreas Gohr $this->addSort($sort[0], $sort[1]); 681a07b696SMichael Große } 691a07b696SMichael Große 701a07b696SMichael Große if (!empty($config['limit'])) { 711a07b696SMichael Große $this->setLimit($config['limit']); 721a07b696SMichael Große } 7300f6af48SAndreas Gohr 7400f6af48SAndreas Gohr if (!empty($config['offset'])) { 75d2a8ce05SPaweł Czochański $this->setOffset($config['offset']); 7600f6af48SAndreas Gohr } 77668e4f8eSAndreas Gohr 78668e4f8eSAndreas Gohr $this->config = $config; 791a07b696SMichael Große } 805511bd5bSAndreas Gohr 8100f6af48SAndreas Gohr /** 8216b7d914SAndreas Gohr * Set the cache flag accordingly to the set filter placeholders 8316b7d914SAndreas Gohr * 8416b7d914SAndreas Gohr * @param array $filters 8516b7d914SAndreas Gohr * @return int 8616b7d914SAndreas Gohr */ 87*d6d97f60SAnna Dabrowska protected function determineCacheFlag($filters) 88*d6d97f60SAnna Dabrowska { 8916b7d914SAndreas Gohr $flags = self::$CACHE_DEFAULT; 9016b7d914SAndreas Gohr 9116b7d914SAndreas Gohr foreach ($filters as $filter) { 9216b7d914SAndreas Gohr if (is_array($filter)) $filter = $filter[2]; // this is the format we get fro the config parser 9316b7d914SAndreas Gohr 9416b7d914SAndreas Gohr if (strpos($filter, '$USER$') !== false) { 9516b7d914SAndreas Gohr $flags |= self::$CACHE_USER; 9616b7d914SAndreas Gohr } elseif (strpos($filter, '$TODAY$') !== false) { 9716b7d914SAndreas Gohr $flags |= self::$CACHE_DATE; 9816b7d914SAndreas Gohr } 9916b7d914SAndreas Gohr } 10016b7d914SAndreas Gohr 10116b7d914SAndreas Gohr return $flags; 10216b7d914SAndreas Gohr } 10316b7d914SAndreas Gohr 10416b7d914SAndreas Gohr /** 1055625b985SAndreas Gohr * Replaces placeholders in the given filter value by the proper value 1065625b985SAndreas Gohr * 1075625b985SAndreas Gohr * @param string $filter 10853528ecfSAndreas Gohr * @return string|string[] Result may be an array when a multi column placeholder is used 1095625b985SAndreas Gohr */ 110*d6d97f60SAnna Dabrowska protected function applyFilterVars($filter) 111*d6d97f60SAnna Dabrowska { 11206fee43aSMichael Grosse global $INFO; 1135625b985SAndreas Gohr 1145625b985SAndreas Gohr // apply inexpensive filters first 1155625b985SAndreas Gohr $filter = str_replace( 1165625b985SAndreas Gohr array( 1175625b985SAndreas Gohr '$ID$', 1185625b985SAndreas Gohr '$NS$', 1195625b985SAndreas Gohr '$PAGE$', 1205625b985SAndreas Gohr '$USER$', 1215625b985SAndreas Gohr '$TODAY$' 1225625b985SAndreas Gohr ), 1235625b985SAndreas Gohr array( 12406fee43aSMichael Grosse $INFO['id'], 12506fee43aSMichael Grosse getNS($INFO['id']), 12606fee43aSMichael Grosse noNS($INFO['id']), 1275625b985SAndreas Gohr isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'] : '', 1285625b985SAndreas Gohr date('Y-m-d') 1295625b985SAndreas Gohr ), 1305625b985SAndreas Gohr $filter 1315625b985SAndreas Gohr ); 1325625b985SAndreas Gohr 13353528ecfSAndreas Gohr // apply struct column placeholder (we support only one!) 13453528ecfSAndreas Gohr if (preg_match('/^(.*?)(?:\$STRUCT\.(.*?)\$)(.*?)$/', $filter, $match)) { 135e983bcdaSSzymon Olewniczak $filter = $this->applyFilterVarsStruct($match); 136e983bcdaSSzymon Olewniczak } elseif (preg_match('/^(.*?)(?:\$USER\.(.*?)\$)(.*?)$/', $filter, $match)) { 137e983bcdaSSzymon Olewniczak $filter = $this->applyFilterVarsUser($match); 138e983bcdaSSzymon Olewniczak } 139e983bcdaSSzymon Olewniczak 140e983bcdaSSzymon Olewniczak return $filter; 141e983bcdaSSzymon Olewniczak } 142e983bcdaSSzymon Olewniczak 143e983bcdaSSzymon Olewniczak /** 144e983bcdaSSzymon Olewniczak * Replaces struct placeholders in the given filter value by the proper value 145e983bcdaSSzymon Olewniczak * 146e983bcdaSSzymon Olewniczak * @param string $match 147e983bcdaSSzymon Olewniczak * @return string|string[] Result may be an array when a multi column placeholder is used 148e983bcdaSSzymon Olewniczak */ 149*d6d97f60SAnna Dabrowska protected function applyFilterVarsStruct($match) 150*d6d97f60SAnna Dabrowska { 151e983bcdaSSzymon Olewniczak global $INFO; 152e983bcdaSSzymon Olewniczak 15353528ecfSAndreas Gohr $key = $match[2]; 154d19ba4b1SAndreas Gohr 155aec9051bSAndreas Gohr // we try to resolve the key via current schema aliases first, otherwise take it literally 156aec9051bSAndreas Gohr $column = $this->findColumn($key); 1575625b985SAndreas Gohr if ($column) { 1585625b985SAndreas Gohr $label = $column->getLabel(); 1595625b985SAndreas Gohr $table = $column->getTable(); 160aec9051bSAndreas Gohr } else { 161aec9051bSAndreas Gohr list($table, $label) = explode('.', $key); 162aec9051bSAndreas Gohr } 163aec9051bSAndreas Gohr 164aec9051bSAndreas Gohr // get the data from the current page 165aec9051bSAndreas Gohr if ($table && $label) { 166387ee210SAnna Dabrowska $schemaData = AccessTable::byTableName($table, $INFO['id'], time()); 1677717c082SMichael Große $data = $schemaData->getData(); 16834db2096SMichael Große if (!isset($data[$label])) { 169e87d1e74SMichael Große throw new StructException("column not in table", $label, $table); 17034db2096SMichael Große } 1717717c082SMichael Große $value = $data[$label]->getCompareValue(); 172c75f25cfSAndreas Gohr 173c75f25cfSAndreas Gohr if (is_array($value) && !count($value)) { 174c75f25cfSAndreas Gohr $value = ''; 175c75f25cfSAndreas Gohr } 1765625b985SAndreas Gohr } else { 1775625b985SAndreas Gohr $value = ''; 1785625b985SAndreas Gohr } 1798b8243b2SAndreas Gohr 18053528ecfSAndreas Gohr // apply any pre and postfixes, even when multi value 18153528ecfSAndreas Gohr if (is_array($value)) { 18253528ecfSAndreas Gohr $filter = array(); 18353528ecfSAndreas Gohr foreach ($value as $item) { 18453528ecfSAndreas Gohr $filter[] = $match[1] . $item . $match[3]; 18553528ecfSAndreas Gohr } 18653528ecfSAndreas Gohr } else { 18753528ecfSAndreas Gohr $filter = $match[1] . $value . $match[3]; 18853528ecfSAndreas Gohr } 189e983bcdaSSzymon Olewniczak 190e983bcdaSSzymon Olewniczak return $filter; 191e983bcdaSSzymon Olewniczak } 192e983bcdaSSzymon Olewniczak 193e983bcdaSSzymon Olewniczak /** 194e983bcdaSSzymon Olewniczak * Replaces user placeholders in the given filter value by the proper value 195e983bcdaSSzymon Olewniczak * 196e983bcdaSSzymon Olewniczak * @param string $match 197e983bcdaSSzymon Olewniczak * @return string|string[] String for name and mail, array for grps 198e983bcdaSSzymon Olewniczak */ 199*d6d97f60SAnna Dabrowska protected function applyFilterVarsUser($match) 200*d6d97f60SAnna Dabrowska { 201e983bcdaSSzymon Olewniczak global $INFO; 202e983bcdaSSzymon Olewniczak 203daa4b09dSSzymon Olewniczak $key = strtolower($match[2]); 204daa4b09dSSzymon Olewniczak 205daa4b09dSSzymon Olewniczak if (!in_array($key, array('name', 'mail', 'grps'))) { 206daa4b09dSSzymon Olewniczak throw new StructException('"%s" is not a valid USER key', $key); 207daa4b09dSSzymon Olewniczak } 208daa4b09dSSzymon Olewniczak 209daa4b09dSSzymon Olewniczak if (empty($INFO['userinfo'])) { 210daa4b09dSSzymon Olewniczak $filter = ''; 211daa4b09dSSzymon Olewniczak } else { 212daa4b09dSSzymon Olewniczak $filter = $INFO['userinfo'][$key]; 213daa4b09dSSzymon Olewniczak } 2145625b985SAndreas Gohr 2155625b985SAndreas Gohr return $filter; 2165625b985SAndreas Gohr } 2175625b985SAndreas Gohr 2185625b985SAndreas Gohr /** 21916b7d914SAndreas Gohr * @return int cacheflag for this search 22016b7d914SAndreas Gohr */ 221*d6d97f60SAnna Dabrowska public function getCacheFlag() 222*d6d97f60SAnna Dabrowska { 22316b7d914SAndreas Gohr return $this->cacheFlag; 22416b7d914SAndreas Gohr } 22516b7d914SAndreas Gohr 22616b7d914SAndreas Gohr /** 22700f6af48SAndreas Gohr * Access the dynamic paramters of this search 22800f6af48SAndreas Gohr * 229668e4f8eSAndreas Gohr * Note: This call returns a clone of the parameters as they were initialized 23000f6af48SAndreas Gohr * 23100f6af48SAndreas Gohr * @return SearchConfigParameters 23200f6af48SAndreas Gohr */ 233*d6d97f60SAnna Dabrowska public function getDynamicParameters() 234*d6d97f60SAnna Dabrowska { 23500f6af48SAndreas Gohr return clone $this->dynamicParameters; 2365511bd5bSAndreas Gohr } 2375511bd5bSAndreas Gohr 23800f6af48SAndreas Gohr /** 23907993756SAndreas Gohr * @return array the current config 24000f6af48SAndreas Gohr */ 241*d6d97f60SAnna Dabrowska public function getConf() 242*d6d97f60SAnna Dabrowska { 2431a07b696SMichael Große return $this->config; 2441a07b696SMichael Große } 2455511bd5bSAndreas Gohr} 246