knownTokens)) { return; } $tikilib = TikiLib::lib('tiki'); $this->knownTokens = []; $result = $tikilib->query("SELECT token, label, invert_token FROM tiki_semantic_tokens"); while ($row = $result->fetchRow()) { $token = $row['token']; $this->knownTokens[$token] = $row; } ksort($this->knownTokens); } private function loadNewTokens() { if (is_array($this->newTokens)) { return; } $db = TikiDb::get(); $result = $db->fetchAll("SELECT DISTINCT relation FROM tiki_object_relations WHERE relation LIKE 'tiki.link.%'"); $tokens = []; foreach ($result as $row) { $tokens[] = substr($row['relation'], strlen('tiki.link.')); } $this->loadKnownTokens(); $existing = array_keys($this->knownTokens); $this->newTokens = array_diff($tokens, $existing); } public function getToken($name, $field = null) { $this->loadKnownTokens(); if (array_key_exists($name, $this->knownTokens)) { $data = $this->knownTokens[$name]; if (is_null($field)) { return $data; } if (array_key_exists($field, $data)) { return $data[$field]; } } return false; } public function getInvert($name, $field = null) { if (false !== $invert = $this->getToken($name, 'invert_token')) { if (empty($invert)) { $invert = $name; } return $this->getToken($invert, $field); } return false; } public function getTokens() { $this->loadKnownTokens(); return $this->knownTokens; } public function getNewTokens() { $this->loadNewTokens(); return $this->newTokens; } public function getAllTokens() { $this->loadKnownTokens(); $this->loadNewTokens(); return array_merge(array_keys($this->knownTokens), $this->newTokens); } public function getLinksUsing($token, $conditions = []) { $db = TikiDb::get(); $token = (array) $token; $bindvars = []; // Multiple tokens can be fetched at the same time $values = []; foreach ($token as $name) { $values[] = "tiki.link.$name"; } $mid = [ $db->in('relation', $values, $bindvars) ]; // Filter on source and destination foreach ($conditions as $field => $value) { if ($field == 'fromPage') { $field = 'source_itemId'; } elseif ($field == 'toPage') { $field = 'target_itemId'; } else { continue; } $mid[] = "`$field` = ?"; $bindvars[] = $value; } $mid = implode(' AND ', $mid); $result = $db->query( $q = "SELECT `source_itemId` `fromPage`, `target_itemId` `toPage`, GROUP_CONCAT(SUBSTR(`relation` FROM 11) SEPARATOR ',') `reltype` FROM tiki_object_relations WHERE $mid AND `source_type` = 'wiki page' AND `target_type` = 'wiki page' AND `relation` LIKE 'tiki.link.%' GROUP BY `fromPage`, `toPage` ORDER BY `fromPage`, `toPage`", $bindvars ); $links = []; while ($row = $result->fetchRow()) { $row['reltype'] = explode(',', $row['reltype']); $links[] = $row; } return $links; } public function replaceToken($oldName, $newName, $label, $invert = null) { $exists = ( false !== $this->getToken($oldName) ); if ($oldName != $newName && false !== $this->getToken($newName)) { return tra('Semantic token already exists') . ": $newName"; } if (! $this->isValid($oldName)) { return tra('Invalid semantic token name') . ": $oldName"; } if (! $this->isValid($newName)) { return tra('Invalid semantic token name') . ": $newName"; } if (false === $this->getToken($invert) || $invert == $newName) { $invert = null; } $tikilib = TikiLib::lib('tiki'); if ($exists) { $tikilib->query("DELETE FROM tiki_semantic_tokens WHERE token = ?", [ $oldName ]); } if (is_null($invert)) { $tikilib->query("INSERT INTO tiki_semantic_tokens (token, label) VALUES(?,?)", [ $newName, $label ]); } else { $tikilib->query("INSERT INTO tiki_semantic_tokens (token, label, invert_token) VALUES(?,?,?)", [ $newName, $label, $invert ]); } if ($oldName != '' && $newName != $oldName) { $tikilib->query("UPDATE tiki_semantic_tokens SET invert_token = ? WHERE invert_token = ?", [ $newName, $oldName ]); $this->replaceReferences($oldName, $newName); } unset($this->knownTokens[$oldName]); $this->knownTokens[$newName] = [ 'token' => $newName, 'label' => $label, 'invert_token' => $invert, ]; ksort($this->knownTokens); return true; } private function replaceReferences($oldName, $newName = null) { $tikilib = TikiLib::lib('tiki'); if (! $this->isValid($oldName)) { return tra('Invalid semantic token name') . ": $oldName"; } if (! is_null($newName) && ! $this->isValid($newName)) { return tra('Invalid semantic token name') . ": $newName"; } $links = $this->getLinksUsing($oldName); $pagesDone = []; foreach ($links as $link) { // Page body only needs to be replaced once if (! array_key_exists($link['fromPage'], $pagesDone)) { $info = $tikilib->get_page_info($link['fromPage']); $data = $info['data']; $data = str_replace("($oldName(", "($newName(", $data); $query = "update `tiki_pages` set `data`=?,`page_size`=? where `pageName`=?"; $tikilib->query($query, [ $data,(int) strlen($data), $link['fromPage']]); $pagesDone[ $link['fromPage'] ] = true; } } if ($newName) { $tikilib->query('UPDATE tiki_object_relations SET relation = ? WHERE relation = ? AND source_type = "wiki page" AND target_type = "wiki page"', [ "tiki.link.$newName", "tiki.link.$oldName" ]); } else { $tikilib->query('DELETE FROM tiki_object_relations WHERE relation = ? AND source_type = "wiki page" AND target_type = "wiki page"', [ "tiki.link.$oldName" ]); } return true; } public function cleanToken($token) { $this->replaceReferences($token); $this->newTokens = array_diff($this->newTokens, [ $token ]); } public function removeToken($token, $removeReferences = false) { $tikilib = TikiLib::lib('tiki'); if (false === $this->getToken($token)) { return tra("Semantic token not found") . ": $token"; } $tikilib->query("DELETE FROM tiki_semantic_tokens WHERE token = ?", [ $token ]); unset($this->knownTokens[$token]); if ($removeReferences) { $this->replaceReferences($token, ''); } elseif ($this->newTokens !== false) { $this->newTokens[] = $token; } return true; } public function renameToken($oldName, $newName) { $this->replaceReferences($oldName, $newName); $this->newTokens = array_diff($this->newTokens, [ $oldName ]); if (false === $this->getToken($newName)) { $this->newTokens[] = $newName; } } public function isValid($token) { return preg_match("/^[a-z0-9-]{1,15}\\z/", $token); } public function getRelationList($page) { $wikilib = TikiLib::lib('wiki'); $tikilib = TikiLib::lib('tiki'); $relations = []; $result = $tikilib->fetchAll("SELECT `target_itemId` `toPage`, SUBSTR(`relation` FROM 11) `reltype` FROM tiki_object_relations WHERE `source_itemId` = ? AND `source_type` = 'wiki page' AND `target_type` = 'wiki page' AND `relation` LIKE 'tiki.link.%'", [$page]); foreach ($result as $row) { if (false === $label = $this->getToken($row['reltype'], 'label')) { continue; } $label = tra($label); if (! array_key_exists($label, $relations)) { $relations[$label] = []; } if (! array_key_exists($row['toPage'], $relations[$label])) { $relations[$label][ $row['toPage'] ] = $wikilib->sefurl($row['toPage']); } } $result = $tikilib->fetchAll("SELECT `source_itemId` `fromPage`, SUBSTR(`relation` FROM 11) `reltype` FROM tiki_object_relations WHERE `target_itemId` = ? AND `source_type` = 'wiki page' AND `target_type` = 'wiki page' AND `relation` LIKE 'tiki.link.%'", [$page]); foreach ($result as $row) { if (false === $label = $this->getInvert($row['reltype'], 'label')) { continue; } $label = tra($label); if (! array_key_exists($label, $relations)) { $relations[$label] = []; } if (! array_key_exists($row['fromPage'], $relations[$label])) { $relations[$label][ $row['fromPage'] ] = $wikilib->sefurl($row['fromPage']); } } ksort($relations); foreach ($relations as &$set) { ksort($set); } return $relations; } public function getAliasContaining($query, $exact_match = false, $in_lang = null) { global $prefs; $tikilib = TikiLib::lib('tiki'); $orig_query = $query; if (! $exact_match) { $query = "%$query%"; } $mid = "((`target_type` = 'wiki page' AND `target_itemId` LIKE ?)"; $bindvars = [$query]; $prefixes = explode(',', $prefs["wiki_prefixalias_tokens"]); $haveprefixes = false; foreach ($prefixes as $p) { $p = trim($p); if (strlen($p) > 0 && TikiLib::strtolower(substr($query, 0, strlen($p))) == TikiLib::strtolower($p)) { $mid .= " OR ( `target_type` = 'wiki page' AND `target_itemId` LIKE ?)"; $bindvars[] = "$p%"; $haveprefixes = true; } } $mid .= ") AND ( `relation` = 'tiki.link.alias' "; if ($haveprefixes) { $mid .= " OR `relation` = 'tiki.link.prefixalias' "; } $mid .= ")"; $querystring = "SELECT `source_itemId` `fromPage`, `target_itemId` `toPage` FROM `tiki_object_relations` WHERE $mid"; $aliases = $tikilib->fetchAll($querystring, $bindvars); $aliases = $this->onlyKeepAliasesFromPageInLanguage($in_lang, $aliases); return $aliases; } public function onlyKeepAliasesFromPageInLanguage($language, $aliases) { $multilinguallib = TikiLib::lib('multilingual'); if (! $language) { return $aliases; } $aliasesInCorrectLanguage = []; foreach ($aliases as $index => $aliasInfo) { $aliasLang = $multilinguallib->getLangOfPage($aliasInfo['fromPage']); if ($aliasLang === $language) { $aliasesInCorrectLanguage[] = $aliasInfo; } } // echo "
-- onlyKeepAliasesFromPageInLanguage: exiting
\n"; return $aliasesInCorrectLanguage; } public function getItemsFromTracker($page, $suffix) { $t_links = $this->getLinksUsing('trackerid', [ 'fromPage' => $page ]); $f_links = $this->getLinksUsing('titlefieldid', [ 'fromPage' => $page ]); $ret = []; if (count($t_links) && count($f_links) && ctype_digit($t_links[0]['toPage']) && ctype_digit($f_links[0]['toPage'])) { $trklib = TikiLib::lib('trk'); $items = $trklib->list_items($t_links[0]['toPage'], 0, -1, '', '', $f_links[0]['toPage'], '', '', '', $suffix); foreach ($items["data"] as $i) { $ret[] = $i["itemId"]; } } return $ret; } }