secions to protect // from broke
 tags and leave well known 
        // behaviour (i.e. type all text inside AS IS w/o
        // any interpretation)
        $preparsed = [];

        preg_match_all("/(<[Pp][Rr][Ee]>)(.*?)(<\/[Pp][Rr][Ee]>)/s", $data, $preparse);
        $idx = 0;

        foreach (array_unique($preparse[2]) as $pp) {
            $key = md5($this->genPass());

            $aux['key'] = $key;
            $aux['data'] = $pp;
            $preparsed[] = $aux;
            $data = str_replace($preparse[1][$idx] . $pp . $preparse[3][$idx], $key, $data);
            $idx = $idx + 1;
        }

        $parts = explode($prefs['wiki_page_separator'], $data);
        return count($parts);
    }

    public function get_page($data, $i)
    {
        // Get slides
        global $prefs;
        $parts = explode($prefs['wiki_page_separator'], $data);
        $ret = $parts[$i - 1];

        if (substr($parts[$i - 1], 1, 5) == '
') { $ret = substr($parts[$i - 1], 6); } if (substr($parts[$i - 1], 1, 6) == '
') { $ret = substr($parts[$i - 1], 7); } return $ret; } public function get_page_by_slug($slug) { $pages = TikiDb::get()->table('tiki_pages'); $found = $pages->fetchOne('pageName', ['pageSlug' => $slug]); if ($found) { return $found; } if (function_exists('utf8_encode')) { $slug_utf8 = utf8_encode($slug); if ($slug != $slug_utf8) { $found = $pages->fetchOne('pageName', ['pageSlug' => $slug_utf8]); if ($found) { return $found; } } } return $slug; } /** * Return a Slug, if set, or the page name supplied as result * * @param string $page * @return string */ public function get_slug_by_page($page) { $pages = TikiDb::get()->table('tiki_pages'); $slug = $pages->fetchOne('pageSlug', ['pageName' => $page]); if ($slug) { return $slug; } return $page; } public function get_creator($name) { return $this->getOne('select `creator` from `tiki_pages` where `pageName`=?', [$name]); } /** * Get the contributors for page * the returned array does not contain the user $last (usually the current or last user) */ public function get_contributors($page, $last = '') { static $cache_page_contributors; if (! empty($cache_page_contributors['page']) && $cache_page_contributors['page'] == $page) { if (empty($last)) { return $cache_page_contributors['contributors']; } $ret = []; if (is_array($cache_page_contributors['contributors'])) { foreach ($cache_page_contributors['contributors'] as $res) { if (isset($res['user']) && $res['user'] != $last) { $ret[] = $res; } } } return $ret; } $query = 'select `user`, MAX(`version`) as `vsn` from `tiki_history` where `pageName`=? group by `user` order by `vsn` desc'; // jb fixed 110115 - please check intended behaviour remains // was: $query = "select `user` from `tiki_history` where `pageName`=? group by `user` order by MAX(`version`) desc"; $result = $this->query($query, [$page]); $cache_page_contributors = []; $cache_page_contributors['contributors'] = []; $ret = []; while ($res = $result->fetchRow()) { if ($res['user'] != $last) { $ret[] = $res['user']; } $cache_page_contributors['contributors'][] = $res['user']; } $cache_page_contributors['page'] = $page; return $ret; } // Returns all pages that links from here or to here, without distinction // This is used by wiki mindmap, to make the graph public function wiki_get_neighbours($page) { $neighbours = []; $already = []; $query = "select `toPage` from `tiki_links` where `fromPage`=? and `fromPage` not like 'objectlink:%'"; $result = $this->query($query, [$page]); while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC)) { $neighbour = $row['toPage']; $neighbours[] = $neighbour; $already[$neighbour] = 1; } $query = "select `fromPage` from `tiki_links` where `toPage`=? and `fromPage` not like 'objectlink:%'"; $result = $this->query($query, [$page]); while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC)) { $neighbour = $row['fromPage']; if (! isset($already[$neighbour])) { $neighbours[] = $neighbour; } } return $neighbours; } // Returns a string containing all characters considered bad in page names public function get_badchars() { return "/?#[]@$&+;=<>"; } // Returns a boolean indicating whether the given page name contains "bad characters" // See http://dev.tiki.org/Bad+characters public function contains_badchars($name) { if (preg_match('/^tiki\-(\w+)\-(\w+)$/', $name)) { return true; } $badchars = $this->get_badchars(); $badchars = preg_quote($badchars, '/'); return preg_match("/[$badchars]/", $name); } public function remove_badchars($page) { if ($this->contains_badchars($page)) { $badChars = $this->get_badchars(); // Replace bad characters with a '_' $iStrlenBadChars = strlen($badChars); for ($j = 0; $j < $iStrlenBadChars; $j++) { $char = $badChars[$j]; $page = str_replace($char, "_", $page); } } return $page; } /** * Duplicate an existing page * * @param string $name * @param string $copyName * @return bool */ public function wiki_duplicate_page($name, $copyName = null, $dupCateg = true, $dupTags = true, $copyData = null) { global $user; global $prefs; $tikilib = TikiLib::lib('tiki'); $userlib = TikiLib::lib('user'); $globalperms = Perms::get(); $info = $tikilib->get_page_info($name); $ip = $tikilib->get_ip_address(); $version = $info['version']; $comment = tr("Initial content copied from version %0 of page %1", $version, $name); if (! $info) { return false; } if (! $copyName) { $copyName = $name . ' (' . $tikilib->now . ')'; } $copyPage = $tikilib->create_page( $copyName, 0, $copyData ?? $info['data'], $tikilib->now, $comment, $user, $ip, $info['description'], $info['lang'], $info['is_html'] ); if ($copyPage) { $warnings = []; if ($dupCateg && $prefs['feature_categories'] === 'y') { if ($globalperms->modify_object_categories) { $categlib = TikiLib::lib('categ'); $categories = $categlib->get_object_categories('wiki page', $name); Perms::bulk([ 'type' => 'category' ], 'object', $categories); foreach ($categories as $catId) { $perms = Perms::get([ 'type' => 'category', 'object' => $catId]); if ($perms->add_object) { $categlib->categorizePage($copyName, $catId); } else { $warnings[] = tr("You don't have permission to use category '%0'.", $categlib->get_category_name($catId)); } } } else { $warnings[] = tr("You don't have permission to edit categories."); } } if ($dupTags && $prefs['feature_freetags'] === 'y') { if ($globalperms->freetags_tag) { $freetaglib = TikiLib::lib('freetag'); $freetags = $freetaglib->get_tags_on_object($name, 'wiki page'); foreach ($freetags['data'] as $tag) { $freetaglib->tag_object($user, $copyName, 'wiki page', $tag['tag']); } } else { $warnings[] = tr("You don't have permission to edit tags."); } } if (count($warnings) > 0) { Feedback::warning(['mes' => $warnings]); } } return $copyPage; } // This method renames a wiki page // If you think this is easy you are very very wrong public function wiki_rename_page($oldName, $newName, $renameHomes = true, $user = '') { global $prefs; $tikilib = TikiLib::lib('tiki'); // if page already exists, stop here $newName = trim($newName); if ($this->get_page_info($newName, false, true)) { // if it is a case change of same page: allow it, else stop here if (strcasecmp(trim($oldName), $newName) <> 0) { throw new Exception("Page already exists", 2); } } if ($this->contains_badchars($newName) && $prefs['wiki_badchar_prevent'] == 'y') { throw new Exception("Bad characters", 1); } // The pre- and post-tags are eating away the max usable page name length // Use ~ instead of Tmp. Shorter // $tmpName = "TmP".$newName."TmP"; $tmpName = "~" . $newName . "~"; // 1st rename the page in tiki_pages, using a tmpname inbetween for // rename pages like ThisTestpage to ThisTestPage $query = 'update `tiki_pages` set `pageName`=?, `pageSlug`=NULL where `pageName`=?'; $this->query($query, [ $tmpName, $oldName ]); $slug = TikiLib::lib('slugmanager')->generate($prefs['wiki_url_scheme'], $newName, $prefs['url_only_ascii'] === 'y'); $query = 'update `tiki_pages` set `pageName`=?, `pageSlug`=? where `pageName`=?'; $this->query($query, [ $newName, $slug, $tmpName ]); // correct pageName in tiki_history, using a tmpname inbetween for // rename pages like ThisTestpage to ThisTestPage $query = 'update `tiki_history` set `pageName`=? where `pageName`=?'; $this->query($query, [ $tmpName, $oldName ]); $query = 'update `tiki_history` set `pageName`=? where `pageName`=?'; $this->query($query, [ $newName, $tmpName ]); // get pages linking to the old page $query = 'select `fromPage` from `tiki_links` where `toPage`=?'; $result = $this->query($query, [ $oldName ]); $linksToOld = []; while ($res = $result->fetchRow()) { $linkOrigin = $res['fromPage']; $linksToOld[] = $linkOrigin; $is_wiki_page = substr($linkOrigin, 0, 11) != 'objectlink:'; if (! $is_wiki_page) { $objectlinkparts = explode(':', $linkOrigin); $type = $objectlinkparts[1]; // $objectId can contain :, so consider the remaining string $objectId = substr($linkOrigin, strlen($type) + 12); } $parserlib = TikiLib::lib('parser'); if ($is_wiki_page) { $info = $this->get_page_info($linkOrigin); //$data=addslashes(str_replace($oldName,$newName,$info['data'])); $data = $parserlib->replace_links($info['data'], $oldName, $newName); $query = "update `tiki_pages` set `data`=?,`page_size`=? where `pageName`=?"; $this->query($query, [ $data,(int) strlen($data), $linkOrigin]); $this->invalidate_cache($linkOrigin); } elseif ($type == 'forum post' || substr($type, -7) == 'comment') { $comment_info = TikiLib::lib('comments')->get_comment($objectId); $data = $parserlib->replace_links($comment_info['data'], $oldName, $newName); $query = "update `tiki_comments` set `data`=? where `threadId`=?"; $this->query($query, [ $data, $objectId]); } elseif ($type == 'article') { $info = TikiLib::lib('art')->get_article($objectId); $heading = $parserlib->replace_links($info['heading'], $oldName, $newName); $body = $parserlib->replace_links($info['body'], $oldName, $newName); $query = "update `tiki_articles` set `heading`=?, `body`=? where `articleId`=?"; $this->query($query, [ $heading, $body, $objectId]); } elseif ($type == 'post') { $info = TikiLib::lib('blog')->get_post($objectId); $data = $parserlib->replace_links($info['data'], $oldName, $newName); $query = "update `tiki_blog_posts` set `data`=? where `postId`=?"; $this->query($query, [ $data, $objectId]); } elseif ($type == 'tracker') { $tracker_info = TikiLib::lib('trk')->get_tracker($objectId); $data = $parserlib->replace_links($tracker_info['description'], $oldName, $newName); $query = "update `tiki_trackers` set `description`=? where `trackerId`=?"; $this->query($query, [ $data, $objectId]); } elseif ($type == 'trackerfield') { $field_info = TikiLib::lib('trk')->get_field_info($objectId); $data = $parserlib->replace_links($field_info['description'], $oldName, $newName); $query = "update `tiki_tracker_fields` set `description`=? where `fieldId`=?"; $this->query($query, [ $data, $objectId]); } elseif ($type == 'trackeritemfield') { list($itemId, $fieldId) = explode(":", $objectId); $data = TikiLib::lib('trk')->get_item_value(null, (int)$itemId, (int)$fieldId); $data = $parserlib->replace_links($data, $oldName, $newName); $query = "update `tiki_tracker_item_fields` set `value`=? where `itemId`=? and `fieldId`=?"; $this->query($query, [ $data, $itemId, $fieldId]); } elseif ($type == 'calendar event') { $event_info = TikiLib::lib('calendar')->get_item($objectId); $data = $parserlib->replace_links($event_info['description'], $oldName, $newName); $query = "update `tiki_calendar_items` set `description`=? where `calitemId`=?"; $this->query($query, [ $data, $objectId ]); } } // correct toPage and fromPage in tiki_links // before update, manage to avoid duplicating index(es) when B is renamed to C while page(s) points to both C (not created yet) and B $query = 'select `fromPage` from `tiki_links` where `toPage`=?'; $result = $this->query($query, [ $newName ]); $linksToNew = []; while ($res = $result->fetchRow()) { $linksToNew[] = $res['fromPage']; } if ($extra = array_intersect($linksToOld, $linksToNew)) { $query = 'delete from `tiki_links` where `fromPage` in (' . implode(',', array_fill(0, count($extra), '?')) . ') and `toPage`=?'; $this->query($query, array_merge($extra, [$oldName])); } $query = 'update `tiki_links` set `fromPage`=? where `fromPage`=?'; $this->query($query, [ $newName, $oldName]); $query = 'update `tiki_links` set `toPage`=? where `toPage`=?'; $this->query($query, [ $newName, $oldName]); // Modify pages including the old page with Include plugin, // so that they include the new name $relationlib = TikiLib::lib('relation'); $relations = $relationlib->get_relations_to('wiki page', $oldName, 'tiki.wiki.include'); foreach ($relations as $relation) { $type = $relation['type']; if ($type == 'wiki page') { $page = $relation['itemId']; $info = $this->get_page_info($page); $data = [ $info['data'] ]; } elseif ($type == 'forum post' || substr($type, -7) == 'comment') { $objectId = (int)$relation['itemId']; $comment_info = TikiLib::lib('comments')->get_comment($objectId); $data = [ $comment_info['data'] ]; } elseif ($type == 'article') { $objectId = (int)$relation['itemId']; $info = TikiLib::lib('art')->get_article($objectId); $data = [ $info['heading'], $info['body'] ]; } elseif ($type == 'post') { $objectId = (int)$relation['itemId']; $info = TikiLib::lib('blog')->get_post($objectId); $data = [ $info['data'] ]; } elseif ($type == 'tracker') { $objectId = (int)$relation['itemId']; $tracker_info = TikiLib::lib('trk')->get_tracker($objectId); $data = [ $tracker_info['description'] ]; } elseif ($type == 'trackerfield') { $objectId = (int)$relation['itemId']; $field_info = TikiLib::lib('trk')->get_field_info($objectId); $data = [ $field_info['description'] ]; } elseif ($type == 'trackeritemfield') { $objectId = explode(":", $relation['itemId']); $data = [ TikiLib::lib('trk')->get_item_value(null, $objectId[0], $objectId[1]) ]; } elseif ($type == 'calendar event') { $objectId = (int)$relation['itemId']; $data = [ TikiLib::lib('calendar')->get_item($objectId)['description'] ]; } else { continue; } $modified = false; $matches = []; for ($i = 0; $i < sizeof($data); $i++) { $matches[] = WikiParser_PluginMatcher::match($data[$i]); $argParser = new WikiParser_PluginArgumentParser(); foreach ($matches[$i] as $match) { if ($match->getName() == 'include') { $arguments = $argParser->parse($match->getArguments()); if ($arguments['page'] == $oldName) { $arguments['page'] = $newName; $match->replaceWithPlugin($match->getName(), $arguments, $match->getBody()); $modified = true; } } } } if ($modified) { if ($type == 'article') { $heading = $matches[0]->getText(); $body = $matches[1]->getText(); $query = "update `tiki_articles` set `heading`=?, `body`=? where `articleId`=?"; $this->query($query, [ $heading, $body, $objectId]); continue; } else { $data = $matches[0]->getText(); } if ($type == 'wiki page') { $query = "update `tiki_pages` set `data`=?,`page_size`=? where `pageName`=?"; $this->query($query, [ $data,(int) strlen($data), $page]); $this->invalidate_cache($page); } elseif ($type == 'forum post' || substr($type, -7) == 'comment') { $query = "update `tiki_comments` set `data`=? where `threadId`=?"; $this->query($query, [ $data, $objectId]); } elseif ($type == 'post') { $query = "update `tiki_blog_posts` set `data`=? where `postId`=?"; $this->query($query, [ $data, $objectId]); } elseif ($type == 'tracker') { $query = "update `tiki_trackers` set `description`=? where `trackerId`=?"; $this->query($query, [ $data, $objectId]); } elseif ($type == 'trackerfield') { $query = "update `tiki_tracker_fields` set `description`=? where `fieldId`=?"; $this->query($query, [ $data, $objectId]); } elseif ($type == 'trackeritemfield') { $query = "update `tiki_tracker_item_fields` set `value`=? where `itemId`=? and `fieldId`=?"; $this->query($query, [ $data, $objectId[0], $objectId[1]]); } elseif ($type == 'calendar event') { $query = "update `tiki_calendar_items` set `description`=? where `calitemId`=?"; $this->query($query, [ $data, $objectId ]); } } } // tiki_footnotes change pageName $query = 'update `tiki_page_footnotes` set `pageName`=? where `pageName`=?'; $this->query($query, [ $newName, $oldName ]); // in tiki_categorized_objects update objId $newcathref = 'tiki-index.php?page=' . urlencode($newName); $query = 'update `tiki_objects` set `itemId`=?,`name`=?,`href`=? where `itemId`=? and `type`=?'; $this->query($query, [ $newName, $newName, $newcathref, $oldName, 'wiki page']); $this->rename_object('wiki page', $oldName, $newName, $user); // update categories if new name has a category default $categlib = TikiLib::lib('categ'); $categories = $categlib->get_object_categories('wiki page', $newName); $info = $this->get_page_info($newName); $categlib->update_object_categories($categories, $newName, 'wiki page', $info['description'], $newName, $newcathref); $query = 'update `tiki_wiki_attachments` set `page`=? where `page`=?'; $this->query($query, [ $newName, $oldName ]); // group home page if ($renameHomes) { $query = 'update `users_groups` set `groupHome`=? where `groupHome`=?'; $this->query($query, [ $newName, $oldName ]); } // copyright $query = 'update tiki_copyrights set `page`=? where `page`=?'; $this->query($query, [ $newName, $oldName ]); //breadcrumb if (isset($_SESSION['breadCrumb']) && in_array($oldName, $_SESSION['breadCrumb'])) { $pos = array_search($oldName, $_SESSION["breadCrumb"]); $_SESSION['breadCrumb'][$pos] = $newName; } global $prefs; global $user; $tikilib = TikiLib::lib('tiki'); $smarty = TikiLib::lib('smarty'); if ($prefs['feature_use_fgal_for_wiki_attachments'] == 'y') { $query = 'update `tiki_file_galleries` set `name`=? where `name`=?'; $this->query($query, [ $newName, $oldName ]); } // first get all watches for this page ... if ($prefs['feature_user_watches'] == 'y') { $nots = $tikilib->get_event_watches('wiki_page_changed', $oldName); } // ... then update the watches table // user watches $query = "update `tiki_user_watches` set `object`=?, `title`=?, `url`=? where `object`=? and `type` = 'wiki page'"; $this->query($query, [ $newName, $newName, 'tiki-index.php?page=' . $newName, $oldName ]); $query = "update `tiki_group_watches` set `object`=?, `title`=?, `url`=? where `object`=? and `type` = 'wiki page'"; $this->query($query, [ $newName, $newName, 'tiki-index.php?page=' . $newName, $oldName ]); // now send notification email to all on the watchlist: if ($prefs['feature_user_watches'] == 'y') { if (! isset($_SERVER["SERVER_NAME"])) { $_SERVER['SERVER_NAME'] = $_SERVER['HTTP_HOST']; } if (count($nots)) { include_once('lib/notifications/notificationemaillib.php'); $smarty->assign('mail_site', $_SERVER['SERVER_NAME']); $smarty->assign('mail_oldname', $oldName); $smarty->assign('mail_newname', $newName); $smarty->assign('mail_user', $user); sendEmailNotification($nots, 'watch', 'user_watch_wiki_page_renamed_subject.tpl', $_SERVER['SERVER_NAME'], 'user_watch_wiki_page_renamed.tpl'); } } require_once('lib/search/refresh-functions.php'); refresh_index('pages', $oldName, false); refresh_index('pages', $newName); if ($renameHomes && $prefs['wikiHomePage'] == $oldName) { $tikilib->set_preference('wikiHomePage', $newName); } if ($prefs['feature_trackers'] == 'y') { $trklib = TikiLib::lib('trk'); $trklib->rename_page($oldName, $newName); } // Clear cache $cachelib = TikiLib::lib('cache'); $cachelib->empty_type_cache('menu'); $cachelib->empty_type_cache('structure'); return true; } /** * Gets a wiki content that has just been saved, parses it and stores relations * with wiki pages that will created from this content. * * If content is optionally wiki parsed, this function must be called even if content is not * to be parsed in this case, so that relations can be cleared. * * @param string $data wiki parsed content * @param string $objectType * @param string/int $itemId * @param boolean $wikiParsed Indicates if content is wiki parsed. */ public function update_wikicontent_relations($data, $objectType, $itemId, $wikiParsed = true) { $parserlib = TikiLib::lib('parser'); $relationlib = TikiLib::lib('relation'); $relationlib->remove_relations_from($objectType, $itemId, 'tiki.wiki.include'); if (! $wikiParsed) { return; } // Now create Plugin Include relations $includes = $parserlib->find_plugins($data, 'include'); foreach ($includes as $include) { $page = $include['arguments']['page']; if (isset($page)) { $relationlib->add_relation('tiki.wiki.include', $objectType, $itemId, 'wiki page', $page); } } } /** * Very similar to update_wikicontent_relations, but for links. * Both should be merged. The only reason they are not is because * wiki pages have their own way of updating content links. * * @param string $data wiki parsed content * @param string $objectType * @param string/int $itemId * @param boolean $wikiParsed Indicates if content is wiki parsed. */ public function update_wikicontent_links($data, $objectType, $itemId, $wikiParsed = true) { $parserlib = TikiLib::lib('parser'); $tikilib = TikiLib::lib('tiki'); // First get identifier for tiki_links table if ($objectType == 'wiki page') { $linkhandle = $itemId; } else { $linkhandle = "objectlink:$objectType:$itemId"; } $tikilib->clear_links($linkhandle); if (! $wikiParsed) { return; } // Create tiki_links entries $pages = $parserlib->get_pages($data); foreach ($pages as $a_page) { $tikilib->replace_link($linkhandle, $a_page); } } /** * Checks all pages that include $page and parses its contents to * get a list of all Plugin Include calls. * * @param string $page * @return array list of associative arrays with (page, arguments, body) keys */ public function get_external_includes($page) { $relationlib = TikiLib::lib('relation'); $relations = $relationlib->get_relations_to('wiki page', $page, 'tiki.wiki.include'); $objectlib = TikiLib::lib('object'); $result = []; foreach ($relations as $relation) { $data = $objectlib->get_wiki_content($relation['type'], $relation['itemId']); $matches = WikiParser_PluginMatcher::match($data); $argParser = new WikiParser_PluginArgumentParser(); $objectlib = TikiLib::lib('object'); foreach ($matches as $match) { $arguments = $argParser->parse($match->getArguments()); if ($match->getName() == 'include') { $result[$relation['type'] . ':' . $relation['itemId']] = [ 'type' => $relation['type'], 'itemId' => $relation['itemId'], 'start' => $arguments['start'], 'end' => $arguments['end'] ]; } } } return array_values($result); } public function set_page_cache($page, $cache) { $query = 'update `tiki_pages` set `wiki_cache`=? where `pageName`=?'; $this->query($query, [ $cache, $page]); } // TODO: huho why that function is empty ? public function save_notepad($user, $title, $data) { } // Methods to cache and handle the cached version of wiki pages // to prevent parsing large pages. public function get_cache_info($page) { $query = 'select `cache`,`cache_timestamp` from `tiki_pages` where `pageName`=?'; $result = $this->query($query, [ $page ]); $res = $result->fetchRow(); return $res; } public function get_page_wiki_syntax($info) { global $prefs; if ($prefs['markdown_enabled'] !== 'y') { return 'tiki'; } if ($info['wiki_syntax']) { return $info['wiki_syntax']; } return $prefs['markdown_default']; } public function get_parse($page, &$canBeRefreshed = false, $suppress_icons = false) { global $prefs, $user; $tikilib = TikiLib::lib('tiki'); $headerlib = TikiLib::lib('header'); $content = ''; $canBeRefreshed = false; $info = $this->get_page_info($page); if (empty($info)) { return ''; } $parse_options = [ 'is_html' => $info['is_html'], 'is_markdown' => $this->get_page_wiki_syntax($info) === 'markdown', 'language' => $info['lang'], 'namespace' => $info['namespace'], ]; if ($prefs['wiki_auto_toc'] === 'y' && $this->get_page_auto_toc($page) >= 0) { $parse_options['autotoc'] = true; } if ($suppress_icons || (! empty($info['lockedby']) && $info['lockedby'] != $user)) { $parse_options['suppress_icons'] = true; } if ($prefs['wysiwyg_inline_editing'] === 'y' && getCookie('wysiwyg_inline_edit', "preview", false)) { $parse_options['ck_editor'] = true; $parse_options['suppress_icons'] = true; } $wiki_cache = ($prefs['feature_wiki_icache'] == 'y' && ! is_null($info['wiki_cache'])) ? $info['wiki_cache'] : $prefs['wiki_cache']; if ($wiki_cache > 0 && empty($_REQUEST['offset']) && empty($_REQUEST['itemId']) && (empty($user) || $prefs['wiki_cache'] == 0)) { $cache_info = $this->get_cache_info($page); if (! empty($cache_info['cache_timestamp']) && $cache_info['cache_timestamp'] + $wiki_cache >= $this->now) { $content = $cache_info['cache']; // get any cached JS and add to headerlib JS $jsFiles = $headerlib->getJsFromHTML($content, false, true); foreach ($jsFiles as $jsFile) { $headerlib->add_jsfile($jsFile); } $headerlib->add_js(implode("\n", $headerlib->getJsFromHTML($content))); // now remove all the js from the source $content = $headerlib->removeJsFromHtml($content); $canBeRefreshed = true; } else { $jsFile1 = $headerlib->getJsFilesWithScriptTags(); $js1 = $headerlib->getJs(); $info['outputType'] = $tikilib->getOne("SELECT `outputType` FROM `tiki_output` WHERE `entityId` = ? AND `objectType` = ? AND `version` = ?", [$info['pageName'], 'wikiPage', $info['version']]); $content = (new WikiLibOutput($info, $info['data'], $parse_options))->parsedValue; // get any JS added to headerlib during parse_data and add to the bottom of the data to cache $jsFile2 = $headerlib->getJsFilesWithScriptTags(); $js2 = $headerlib->getJs(); $jsFile = array_diff($jsFile2, $jsFile1); $js = array_diff($js2, $js1); $jsFile = implode("\n", $jsFile); $js = $headerlib->wrap_js(implode("\n", $js)); $this->update_cache($page, $content . $jsFile . $js); } } else { $content = (new WikiLibOutput($info, $info['data'], $parse_options, $info['version']))->parsedValue; } return $content; } public function update_cache($page, $data) { $query = 'update `tiki_pages` set `cache`=?, `cache_timestamp`=? where `pageName`=?'; $result = $this->query($query, [ $data, $this->now, $page ]); return true; } public function get_attachment_owner($attId) { return $this->getOne("select `user` from `tiki_wiki_attachments` where `attId`=$attId"); } public function remove_wiki_attachment($attId) { global $prefs; $path = $this->getOne("select `path` from `tiki_wiki_attachments` where `attId`=?", [$attId]); /* carefull a same file can be attached in different page */ if ($path && $this->getOne("select count(*) from `tiki_wiki_attachments` where `path`=?", [$path]) <= 1) { @unlink($prefs['w_use_dir'] . $path); } $query = "delete from `tiki_wiki_attachments` where `attId`=?"; $result = $this->query($query, [$attId]); if ($prefs['feature_actionlog'] == 'y') { $logslib = TikiLib::lib('logs'); $logslib->add_action('Removed', $attId, 'wiki page attachment'); } } public function wiki_attach_file($page, $name, $type, $size, $data, $comment, $user, $fhash, $date = '') { $comment = strip_tags($comment); $now = empty($date) ? $this->now : $date; $attId = $this->table('tiki_wiki_attachments')->insert([ 'page' => $page, 'filename' => $name, 'filesize' => (int) $size, 'filetype' => $type, 'data' => $data, 'created' => (int) $now, 'hits' => 0, 'user' => $user, 'comment' => $comment, 'path' => $fhash, ]); global $prefs; TikiLib::events()->trigger( 'tiki.wiki.attachfile', [ 'type' => 'file', 'object' => $attId, 'wiki' => $page, 'user' => $user, ] ); if ($prefs['feature_user_watches'] = 'y') { include_once(__DIR__ . '/../notifications/notificationemaillib.php'); sendWikiEmailNotification('wiki_file_attached', $page, $user, $comment, '', $name, '', '', false, '', 0, $attId); } if ($prefs['feature_actionlog'] == 'y') { $logslib = TikiLib::lib('logs'); $logslib->add_action('Created', $attId, 'wiki page attachment', '', $user); } return $attId; } public function get_wiki_attach_file($page, $name, $type, $size) { $query = 'select * from `tiki_wiki_attachments` where `page`=? and `filename`=? and `filetype`=? and `filesize`=?'; $result = $this->query($query, [$page, $name, $type, $size]); $res = $result->fetchRow(); return $res; } public function list_wiki_attachments($page, $offset = 0, $maxRecords = -1, $sort_mode = 'created_desc', $find = '') { if ($find) { $mid = ' where `page`=? and (`filename` like ?)'; // why braces? $bindvars = [$page,'%' . $find . '%']; } else { $mid = ' where `page`=? '; $bindvars = [$page]; } if ($sort_mode !== 'created_desc') { $pos = strrpos($sort_mode, '_'); // check the sort order is valid for attachments if ($pos !== false && $pos > 0) { $shortsort = substr($sort_mode, 0, $pos); } else { $shortsort = $sort_mode; } if (! in_array(['user','attId','page','filename','filesize','filetype','hits','created','comment'], $shortsort)) { $sort_mode = 'created_desc'; } } $query = 'select `user`,`attId`,`page`,`filename`,`filesize`,`filetype`,`hits`,`created`,`comment`' . ' from `tiki_wiki_attachments` ' . $mid . ' order by ' . $this->convertSortMode($sort_mode); $query_cant = "select count(*) from `tiki_wiki_attachments` $mid"; $result = $this->query($query, $bindvars, $maxRecords, $offset); $cant = $this->getOne($query_cant, $bindvars); $ret = []; while ($res = $result->fetchRow()) { $ret[] = $res; } $retval = []; $retval['data'] = $ret; $retval['cant'] = $cant; return $retval; } public function list_all_attachments($offset = 0, $maxRecords = -1, $sort_mode = 'created_desc', $find = '') { if ($find) { $findesc = '%' . $find . '%'; $mid = ' where `filename` like ?'; $bindvars = [$findesc]; } else { $mid = ''; $bindvars = []; } $query = 'select `user`,`attId`,`page`,`filename`,`filesize`,`filetype`,`hits`,`created`,`comment`,`path` '; $query .= ' from `tiki_wiki_attachments` ' . $mid . ' order by ' . $this->convertSortMode($sort_mode); $query_cant = "select count(*) from `tiki_wiki_attachments` $mid"; $result = $this->query($query, $bindvars, $maxRecords, $offset); $cant = $this->getOne($query_cant, $bindvars); $ret = []; while ($res = $result->fetchRow()) { $ret[] = $res; } $retval = []; $retval['data'] = $ret; $retval['cant'] = $cant; return $retval; } public function file_to_db($path, $attId) { if (is_file($path)) { $fp = fopen($path, 'rb'); $data = ''; while (! feof($fp)) { $data .= fread($fp, 8192 * 16); } fclose($fp); $query = 'update `tiki_wiki_attachments` set `data`=?,`path`=? where `attId`=?'; if ($this->query($query, [$data,'',(int) $attId])) { unlink($path); } } } public function db_to_file($filename, $attId) { global $prefs; $file_name = md5($filename . date('U') . rand()); $fw = fopen($prefs['w_use_dir'] . $file_name, 'wb'); $data = $this->getOne('select `data` from `tiki_wiki_attachments` where `attId`=?', [(int) $attId]); if ($data) { fwrite($fw, $data); } fclose($fw); if (is_file($prefs['w_use_dir'] . $file_name)) { $query = 'update `tiki_wiki_attachments` set `data`=?,`path`=? where `attId`=?'; $this->query($query, ['',$file_name,(int) $attId]); } } public function get_item_attachment($attId) { $query = 'select * from `tiki_wiki_attachments` where `attId`=?'; $result = $this->query($query, [(int) $attId]); if (! $result->numRows()) { return false; } $res = $result->fetchRow(); return $res; } public function get_item_attachement_data($att_info) { if ($att_info['path']) { return file_get_contents($att_info['filename']); } else { return $att_info['data']; } } // Functions for wiki page footnotes public function get_footnote($user, $page) { $count = $this->getOne('select count(*) from `tiki_page_footnotes` where `user`=? and `pageName`=?', [$user,$page]); if (! $count) { return ''; } else { return $this->getOne('select `data` from `tiki_page_footnotes` where `user`=? and `pageName`=?', [$user,$page]); } } public function replace_footnote($user, $page, $data) { $querydel = 'delete from `tiki_page_footnotes` where `user`=? and `pageName`=?'; $this->query($querydel, [$user, $page], -1, -1, false); $query = 'insert into `tiki_page_footnotes`(`user`,`pageName`,`data`) values(?,?,?)'; $this->query($query, [$user,$page,$data]); } public function remove_footnote($user, $page) { if (empty($user)) { $query = 'delete from `tiki_page_footnotes` where `pageName`=?'; $this->query($query, [$page]); } else { $query = 'delete from `tiki_page_footnotes` where `user`=? and `pageName`=?'; $this->query($query, [$user,$page]); } } public function wiki_link_structure() { $query = 'select `pageName` from `tiki_pages` order by ' . $this->convertSortMode('pageName_asc'); $result = $this->query($query); while ($res = $result->fetchRow()) { print ($res['pageName'] . ' '); $page = $res['pageName']; $query2 = 'select `toPage` from `tiki_links` where `fromPage`=?'; $result2 = $this->query($query2, [ $page ]); $pages = []; while ($res2 = $result2->fetchRow()) { if (($res2['toPage'] <> $res['pageName']) && (! in_array($res2['toPage'], $pages))) { $pages[] = $res2['toPage']; print ($res2['toPage'] . ' '); } } print ("\n"); } } // Removes last version of the page (from pages) if theres some // version in the tiki_history then the last version becomes the actual version public function remove_last_version($page, $comment = '') { global $prefs; $this->invalidate_cache($page); $query = 'select * from `tiki_history` where `pageName`=? order by ' . $this->convertSortMode('lastModif_desc'); $result = $this->query($query, [ $page ]); if ($result->numRows()) { // We have a version $res = $result->fetchRow(); $histlib = TikiLib::lib('hist'); if ($prefs['feature_contribution'] == 'y') { $contributionlib = TikiLib::lib('contribution'); $tikilib = TikiLib::lib('tiki'); $info = $tikilib->get_page_info($res['pageName']); $contributionlib->change_assigned_contributions( $res['historyId'], 'history', $res['pageName'], 'wiki page', $info['description'], $res['pageName'], 'tiki-index.php?page' . urlencode($res['pageName']) ); } $ret = $histlib->remove_version($res['pageName'], $res['version']); $ret2 = $histlib->restore_page_from_history($res['pageName']); } else { $ret = $this->remove_all_versions($page); } if ($ret) { $logslib = TikiLib::lib('logs'); $logslib->add_action('Removed last version', $page, 'wiki page', $comment); //get_strings tra("Removed last version"); } return $ret; } /** * Return the page names for a page alias, if any. * * Unfortunately there is no mechanism to prevent two * different pages from sharing the same alias and that is * why this method return an array of page names instead of a * page name string. * * @param string $alias * @return array page names */ public function get_pages_by_alias($alias) { global $prefs; $semanticlib = TikiLib::lib('semantic'); $pages = []; if ($prefs['feature_wiki_pagealias'] == 'n' && empty($prefs["wiki_prefixalias_tokens"])) { return $pages; } $toPage = $alias; $tokens = explode(',', $prefs['wiki_pagealias_tokens']); $prefixes = explode(',', $prefs["wiki_prefixalias_tokens"]); foreach ($prefixes as $p) { $p = trim($p); if (strlen($p) > 0 && TikiLib::strtolower(substr($alias, 0, strlen($p))) == TikiLib::strtolower($p)) { $toPage = $p; $tokens = 'prefixalias'; } } $links = $semanticlib->getLinksUsing($tokens, [ 'toPage' => $toPage ]); if (empty($links)) { // if no linked pages found then the alias may be sefurl "slug" encoded, so try the un-slugged version global $prefs; $toPage = TikiLib::lib('slugmanager')->degenerate($prefs['wiki_url_scheme'], $toPage); $links = $semanticlib->getLinksUsing($tokens, [ 'toPage' => $toPage ]); } if (count($links) > 0) { foreach ($links as $row) { $pages[] = $row['fromPage']; } } return $pages; } /** * Get wiki pages by ID * @param array$pageIds * @param array $columns The fields to * @return array|bool */ public function getPagesByIds($pageIds, $columns = []) { return $this->table('tiki_pages')->fetchAll($columns, [ 'page_id' => $this->table('tiki_pages')->in($pageIds) ]); } // Like pages are pages that share a word in common with the current page public function get_like_pages($page) { global $user, $prefs; $semanticlib = TikiLib::lib('semantic'); $tikilib = TikiLib::lib('tiki'); preg_match_all("/([A-Z])([a-z]+)/", $page, $words); // Add support to ((x)) in either strict or full modes preg_match_all("/(([A-Za-z]|[\x80-\xFF])+)/", $page, $words2); $words = array_unique(array_merge($words[0], $words2[0])); $exps = []; $bindvars = []; foreach ($words as $word) { $exps[] = ' `pageName` like ?'; $bindvars[] = "%$word%"; } $exp = implode(' or ', $exps); if ($exp) { $query = "select `pageName`, `lang` from `tiki_pages` where ($exp)"; if ($prefs['feature_multilingual'] == 'y') { $query .= ' ORDER BY CASE WHEN `lang` = ? THEN 0 WHEN `lang` IS NULL OR `lang` = \'\' THEN 1 ELSE 2 END'; $bindvars[] = $prefs['language']; } $result = $this->query($query, $bindvars); $ret = []; while ($res = $result->fetchRow()) { if ($prefs['wiki_likepages_samelang_only'] == 'y' && ! empty($res['lang']) && $res['lang'] != $prefs['language']) { continue; } if ($tikilib->user_has_perm_on_object($user, $res['pageName'], 'wiki page', 'tiki_p_view')) { $ret[] = $res['pageName']; } } asort($ret); return $ret; } else { return []; } } /** * Tests removing 1 or 2 of the last characters from the URL to see * if it gets an existing page * * @param array $page the page name * @param string $type 'wikiPage'|'tpl' * @param string $path the path where to look for the template in the case $type = 'tpl' * @param string $prefix * * @return '' | redirect to the new url if page name retrieves an existing page */ public function clean_url_suffix_and_redirect($page, $type = '', $path = '', $prefix = '') { if (! $page && $prefs['feature_url_suffix_cleaner'] != 'y') { return; } global $prefs, $url_scheme, $url_host, $base_uri; $tikilib = TikiLib::lib('tiki'); $access = TikiLib::lib('access'); $request_uri = ($prefs['feature_sefurl'] == 'y' && ! $_SERVER['QUERY_STRING']) ? ($request_uri = basename(debug_backtrace()[0]['file']).'?page='.$page) : $base_uri; $pathInfo = parse_url($request_uri); $queryString = $pathInfo['query']; parse_str($queryString, $queryArray); // search for a matching page $possiblePages = array($page, substr($page,0,-1) , substr($page,0,-2)); $newPage = ''; foreach ( $possiblePages as $p ) { if ($type == '' || $type == 'wikiPage') { if ($tikilib->page_exists($p)) { $newPage = $p; break; } } elseif ($type == "tpl" && $path) { if (file_exists($path . $prefix . $p . ".tpl")) { $newPage = $p; break; } } } // construct new url if ($newPage) { $queryArray['page'] = $newPage; $newQueryStr = http_build_query($queryArray, '', '&'); $new_url = $url_scheme . "://" . $url_host . $pathInfo['path'] . "?" .$newQueryStr; // if feature_sefurl is enabled, create a sefurl if ($prefs['feature_sefurl'] == 'y' && ! $_SERVER['QUERY_STRING']) { TikiLib::lib('smarty')->loadPlugin('smarty_modifier_sefurl'); $new_url = smarty_modifier_sefurl($newPage, '', $newQueryStr); } // redirect to the new url $access->redirect($new_url); } return ''; } public function is_locked($page, $info = null) { if (! $info) { $query = "select `flag`, `user` from `tiki_pages` where `pageName`=?"; $result = $this->query($query, [ $page ]); $info = $result->fetchRow(); } return ($info['flag'] == 'L') ? $info['user'] : null; } public function get_locked() { $locked = []; $query = "select `pageName`, 'lockedby', 'lastModif' from `tiki_pages` where `flag`='L'"; return $this->fetchAll($query); } public function is_editable($page, $user, $info = null) { global $prefs; $perms = Perms::get([ 'type' => 'wiki page', 'object' => $page ]); if ($perms->admin_wiki) { return true; } if ($prefs['wiki_creator_admin'] == 'y' && ! empty($user) && $info['creator'] == $user) { return true; } if ( $prefs['feature_wiki_userpage'] == 'y' && ! empty($user) && strcasecmp($prefs['feature_wiki_userpage_prefix'], substr($page, 0, strlen($prefs['feature_wiki_userpage_prefix']))) == 0 ) { if (strcasecmp($page, $prefs['feature_wiki_userpage_prefix'] . $user) == 0) { return true; } } if ( $prefs['feature_wiki_userpage'] == 'y' && strcasecmp(substr($page, 0, strlen($prefs['feature_wiki_userpage_prefix'])), $prefs['feature_wiki_userpage_prefix']) == 0 and strcasecmp($page, $prefs['feature_wiki_userpage_prefix'] . $user) != 0 ) { return false; } if (! $perms->edit) { return false; } return ($this->is_locked($page, $info) == null || $user == $this->is_locked($page, $info)) ? true : false; } /** * Lock a wiki page * * @param $page * * @return TikiDb_Pdo_Result|TikiDb_Adodb_Result */ public function lock_page($page) { global $user, $tikilib; $query = 'update `tiki_pages` set `flag`=?, `lockedby`=? where `pageName`=?'; $result = $this->query($query, [ 'L', $user, $page ]); if (! empty($user)) { $info = $tikilib->get_page_info($page); $query = 'update `tiki_pages` set `user`=?, `comment`=?, `version`=? where `pageName`=?'; $this->query($query, [$user, tra('Page locked'), $info['version'] + 1, $page]); $query = 'insert into `tiki_history`(`pageName`, `version`, `lastModif`, `user`, `ip`, `comment`, `data`, `description`)' . ' values(?,?,?,?,?,?,?,?)'; $this->query( $query, [ $page, (int) $info['version'] + 1, (int) $info['lastModif'], $user, $info['ip'], tra('Page locked'), $info['data'], $info['description'] ] ); } return $result; } public function unlock_page($page) { global $user; $tikilib = TikiLib::lib('tiki'); $query = "update `tiki_pages` set `flag`='' where `pageName`=?"; $result = $this->query($query, [$page]); if (isset($user)) { $info = $tikilib->get_page_info($page); $query = "update `tiki_pages` set `user`=?, `comment`=?, `version`=? where `pageName`=?"; $result = $this->query($query, [$user, tra('Page unlocked'), $info['version'] + 1, $page]); $query = "insert into `tiki_history`(`pageName`, `version`, `lastModif`, `user`, `ip`, `comment`, `data`, `description`) values(?,?,?,?,?,?,?,?)"; $result = $this->query( $query, [ $page, (int) $info['version'] + 1, (int) $info['lastModif'], $user, $info['ip'], tra('Page unlocked'), $info['data'], $info['description'] ] ); } return true; } // Returns backlinks for a given page public function get_backlinks($page) { global $prefs; // First lastModif values of $page's backlinks for sorting purposes $wikilib = TikiLib::lib('wiki'); $wikilib->getBacklinkLastModif($page); // Then return them for display purposes $query = "select `fromPage` from `tiki_links` where `toPage` = ? order by lastmodif desc"; $result = $this->query($query, [ $page ]); $ret = []; while ($res = $result->fetchRow()) { $is_wiki_page = substr($res['fromPage'], 0, 11) != 'objectlink:'; if ($is_wiki_page) { $type = 'wiki page'; $objectId = $res['fromPage']; } else { $objectlinkparts = explode(':', $res['fromPage']); $type = $objectlinkparts[1]; $objectId = substr($res['fromPage'], strlen($type) + 12); if ($type == 'trackeritemfield') { $feature = 'wiki_backlinks_show_trackeritem'; } elseif (substr($type, -7) == 'comment') { $feature = 'wiki_backlinks_show_comment'; } else { $feature = 'wiki_backlinks_show_' . str_replace(" ", "_", $type); } if ($prefs[$feature] !== 'y') { continue; } } if ($type == 'trackeritemfield') { list($itemId, $fieldId) = explode(':', $objectId); $itemObject = Tracker_Item::fromId($itemId); if (! $itemObject->canView() || ! $itemObject->canViewField($fieldId)) { continue; } } else { $objectperms = Perms::get(['type' => $type, 'object' => $objectId]); if (! $objectperms->view) { continue; } } $aux["type"] = $type; $aux["objectId"] = $objectId; $ret[] = $aux; } return $ret; } //Set the last modified item (wiki page or tracker item) public function getBacklinkLastModif($page) { $trackerlib = self::lib('trk'); $tikilib = self::lib('tiki'); $lastModif = 'lastModif'; $query = "select `fromPage` from `tiki_links` where `toPage` = ?"; $result = $tikilib->query($query, [ $page ]); //Query to update 'tiki_links' with lastModif $updateQuery = "UPDATE `tiki_links` SET `lastModif` =? WHERE `frompage` =? AND `topage` =?"; while ($res = $result->fetchRow()) { $frompage = $res['fromPage']; if (substr($frompage, 0, 11) != 'objectlink:') { $wikiLastModif = (int) $tikilib->get_page_info($frompage)[$lastModif]; $tikilib->query($updateQuery, [ $wikiLastModif, $frompage, $page ]); } else { // Get the item id from object link $objectLinkInfo = explode(':', $frompage); $itemId = (int) $objectLinkInfo[2]; $trackerItemLastModif = (int) $trackerlib->get_tracker_item($itemId)[$lastModif]; $tikilib->query($updateQuery, [ $trackerItemLastModif , $frompage, $page ]); } } } public function get_parent_pages($child_page) { $parent_pages = []; $backlinks_info = $this->get_backlinks($child_page); foreach ($backlinks_info as $index => $backlink) { $parent_pages[] = $backlink['fromPage']; } return $parent_pages; } public function list_plugins($with_help = false, $area_id = 'editwiki', $onlyEnabled = true) { $parserlib = TikiLib::lib('parser'); if ($with_help) { global $prefs; $cachelib = TikiLib::lib('cache'); $commonKey = '{{{area-id}}}'; $cachetag = 'plugindesc' . $this->get_language() . '_js=' . $prefs['javascript_enabled']; if (! $plugins = $cachelib->getSerialized($cachetag, '', strtotime('1 week ago'))) { $list = $parserlib->plugin_get_list(); $plugins = []; foreach ($list as $name) { $pinfo = [ 'help' => $parserlib->get_plugin_description($name, $enabled, $commonKey), 'name' => TikiLib::strtoupper($name), ]; if (! $onlyEnabled || $enabled) { $info = $parserlib->plugin_info($name); $pinfo['title'] = $info['name']; unset($info['name']); $pinfo = array_merge($pinfo, $info); $plugins[] = $pinfo; } } usort( $plugins, function ($ar1, $ar2) { return strcasecmp($ar1['title'], $ar2['title']); // sort by translated name } ); $cachelib->cacheItem($cachetag, serialize($plugins)); } array_walk_recursive( $plugins, function (&$item) use ($commonKey, $area_id) { $item = str_replace($commonKey, $area_id, $item); } ); return $plugins; } else { // Only used by WikiPluginPluginManager $files = []; if (is_dir(PLUGINS_DIR)) { if ($dh = opendir(PLUGINS_DIR)) { while (($file = readdir($dh)) !== false) { if (preg_match("/^wikiplugin_.*\.php$/", $file)) { array_push($files, $file); } } closedir($dh); } } sort($files); return $files; } } // get all modified pages for a user (if actionlog is not clean) public function get_user_all_pages($user, $sort_mode) { $query = "select p.`pageName`, p.`user` as lastEditor, p.`creator`, max(a.`lastModif`) as date" . " from `tiki_actionlog` as a, `tiki_pages` as p" . " where a.`object`= p.`pageName` and a.`user`= ? and (a.`action`=? or a.`action`=?)" . " group by p.`pageName`, p.`user`, p.`creator` order by " . $this->convertSortMode($sort_mode); $result = $this->query($query, [$user, 'Updated', 'Created']); $ret = []; while ($res = $result->fetchRow()) { if ($this->user_has_perm_on_object($user, $res['pageName'], 'wiki page', 'tiki_p_view')) { $ret[] = $res; } } return $ret; } public function get_default_wiki_page() { global $user, $prefs; if ($prefs['useGroupHome'] == 'y') { $userlib = TikiLib::lib('user'); if ($groupHome = $userlib->get_user_default_homepage($user)) { return $groupHome; } else { return $prefs['wikiHomePage']; } } return $prefs['wikiHomePage']; } public function sefurl($page, $with_next = '', $all_langs = '') { global $prefs, $info; $smarty = TikiLib::lib('smarty'); $script_name = 'tiki-index.php'; if ($prefs['feature_multilingual_one_page'] == 'y') { // if ( basename($_SERVER['PHP_SELF']) == 'tiki-all_languages.php' ) { // return 'tiki-all_languages.php?page='.urlencode($page); // } if ($all_langs == 'y') { $script_name = 'tiki-all_languages.php'; } } $pages = TikiDb::get()->table('tiki_pages'); $page = $pages->fetchOne('pageSlug', ['pageName' => $page]) ?: $page; $href = "$script_name?page=" . $page; if (isset($prefs['feature_wiki_use_date_links']) && $prefs['feature_wiki_use_date_links'] == 'y') { if (isset($_REQUEST['date'])) { $href .= '&date=' . urlencode($_REQUEST['date']); } elseif (isset($_REQUEST['version'])) { $href .= '&date=' . urlencode($info['lastModif']); } } if ($with_next) { $href .= '&'; } if ($prefs['feature_sefurl'] == 'y') { // escape colon chars so the url doesn't appear to be protocol:address - occurs with user pages and namespaces $href = str_replace(':', '%3A', $href); include_once(__DIR__ . '/../../tiki-sefurl.php'); return filter_out_sefurl($href, 'wiki'); } else { return $href; } } public function url_for_operation_on_a_page($script_name, $page, $with_next) { $href = "$script_name?page=" . urlencode($page); if ($with_next) { $href .= '&'; } return $href; } public function editpage_url($page, $with_next) { return $this->url_for_operation_on_a_page('tiki-editpage.php', $page, $with_next); } public function move_attachments($old, $new) { $query = 'update `tiki_wiki_attachments` set `page`=? where `page`=?'; $this->query($query, [$new, $old]); } public function duplicate_page($old, $new) { $query = 'insert into `tiki_pages`' . ' (`pageName`,`hits`,`data`,`lastModif`,`comment`,`version`,`user`,`ip`,`description`,' . ' `creator`,`page_size`,`is_html`,`created`, `flag`,`points`,`votes`,`pageRank`,`lang`,' . ' `lockedby`) select ?,`hits`,`data`,`lastModif`,`comment`,`version`,`user`,`ip`,' . ' `description`,`creator`,`page_size`,`is_html`,`created`, `flag`,`points`,`votes`' . ',`pageRank`,`lang`,`lockedby` from `tiki_pages` where `pageName`=?'; $this->query($query, [$new, $old]); } public function get_pages_contains($searchtext, $offset = 0, $maxRecords = -1, $sort_mode = 'pageName_asc', $categFilter = []) { $jail_bind = []; $jail_join = ''; $jail_where = ''; if ($categFilter) { $categlib = TikiLib::lib('categ'); $categlib->getSqlJoin($categFilter, 'wiki page', '`tiki_pages`.`pageName`', $jail_join, $jail_where, $jail_bind); } $query = "select * from `tiki_pages` $jail_join where `tiki_pages`.`data` like ? $jail_where order by " . $this->convertSortMode($sort_mode); $bindvars = ['%' . $searchtext . '%']; $bindvars = array_merge($bindvars, $jail_bind); $results = $this->fetchAll($query, $bindvars, $maxRecords, $offset); $ret['data'] = $results; $query_cant = "select count(*) from (select count(*) from `tiki_pages` $jail_join where `data` like ? $jail_where group by `page_id`) as `temp`"; $ret['cant'] = $this->getOne($query_cant, $bindvars); return $ret; } /* * get_page_auto_toc * Get the auto generated TOC setting for the page * @return * +1 page_auto_toc is explicitly set to true * 0 page_auto_toc is not set for page. Use global setting * -1 page_auto_toc is explicitly set to false */ public function get_page_auto_toc($pageName) { $attributes = TikiLib::lib('attribute')->get_attributes('wiki page', $pageName); $value = (int) ($attributes['tiki.wiki.autotoc'] ?? 0); return $value === 0 ? 0 : ($value > 0 ? 1 : -1); } public function set_page_auto_toc($pageName, $isAutoToc) { TikiLib::lib('attribute')->set_attribute('wiki page', $pageName, 'tiki.wiki.autotoc', $isAutoToc); } /* * get_page_hide_title * Enable the page title to not be displayed, on a per-page basis. * @return * +1 page_hide_title is explicitly set to true * 0 page_hide_title is not set for page. Use global setting * -1 page_hide_title is explicitly set to false */ public function get_page_hide_title($pageName) { $attributes = TikiLib::lib('attribute')->get_attributes('wiki page', $pageName); $rc = 0; if (! isset($attributes['tiki.wiki.page_hide_title'])) { return 0; } $value = (int)$attributes['tiki.wiki.page_hide_title']; if ($value > 0) { return 1; } else { return -1; } } public function set_page_hide_title($pageName, $isHideTitle) { TikiLib::lib('attribute')->set_attribute('wiki page', $pageName, 'tiki.wiki.page_hide_title', $isHideTitle); } public function get_without_namespace($pageName) { global $prefs; if ((isset($prefs['namespace_enabled']) && $prefs['namespace_enabled'] == 'y') && $prefs['namespace_separator']) { $pos = strrpos($pageName, $prefs['namespace_separator']); if (false !== $pos) { return substr($pageName, $pos + strlen($prefs['namespace_separator'])); } else { return $pageName; } } else { return $pageName; } } public function get_explicit_namespace($pageName) { $attributes = TikiLib::lib('attribute')->get_attributes('wiki page', $pageName); return isset($attributes['tiki.wiki.namespace']) ? $attributes['tiki.wiki.namespace'] : ''; } public function set_explicit_namespace($pageName, $namespace) { TikiLib::lib('attribute')->set_attribute('wiki page', $pageName, 'tiki.wiki.namespace', $namespace); } public function get_namespace($pageName) { global $prefs; if ( $pageName && $prefs['namespace_enabled'] == 'y' && $prefs['namespace_separator'] ) { $explicit = $this->get_explicit_namespace($pageName); if ($explicit) { return $explicit; } $pos = strrpos($pageName, $prefs['namespace_separator']); if (false !== $pos) { return substr($pageName, 0, $pos); } } return false; } public function get_readable($pageName) { global $prefs; if ( $pageName && $prefs['namespace_enabled'] == 'y' && $prefs['namespace_separator'] ) { return str_replace($prefs['namespace_separator'], ' / ', $pageName); } return $pageName; } public function include_default_namespace($pageName) { global $prefs; if ($prefs['namespace_enabled'] == 'y' && ! empty($prefs['namespace_default'])) { return $prefs['namespace_default'] . $prefs['namespace_separator'] . $pageName; } else { return $pageName; } } public function include_namespace($pageName, $namespace) { global $prefs; if ($prefs['namespace_enabled'] == 'y' && $namespace) { return $namespace . $prefs['namespace_separator'] . $pageName; } else { return $pageName; } } public function get_namespace_parts($pageName) { global $prefs; if ($namespace = $this->get_namespace($pageName)) { return explode($prefs['namespace_separator'], $namespace); } return []; } // Page display options ////////////////////////// public function processPageDisplayOptions() { global $prefs; $headerlib = TikiLib::lib('header'); $currPage = isset($_REQUEST['page']) ? $_REQUEST['page'] : ''; if ( ! empty($currPage) && (strstr($_SERVER["SCRIPT_NAME"], "tiki-editpage.php") === false) && (strstr($_SERVER["SCRIPT_NAME"], 'tiki-pagehistory.php') === false) ) { // Determine the auto TOC setting if ($prefs['wiki_auto_toc'] === 'y') { $isAutoTocActive = $this->get_page_auto_toc($currPage); // Use page specific setting? if ($isAutoTocActive > 0) { $isAutoTocActive = true; } elseif ($isAutoTocActive < 0) { $isAutoTocActive = false; } else { $isAutoTocActive = $prefs['wiki_toc_default'] === 'on'; } // Add Auto TOC if enabled if ($isAutoTocActive) { // Enable Auto TOC $headerlib->add_jsfile('lib/jquery_tiki/autoToc.js'); //Get autoToc offset $tocOffset = ! empty($prefs['wiki_toc_offset']) ? $prefs['wiki_toc_offset'] : 10; // Show/Hide the static inline TOC $isAddInlineToc = isset($prefs['wiki_inline_auto_toc']) ? $prefs['wiki_inline_auto_toc'] === 'y' : false; if ($isAddInlineToc) { // Enable static, inline TOC //$headerlib->add_css('#autotoc {display: block;}'); //Add top margin $headerlib->add_css('#autotoc {margin-top:' . $tocOffset . 'px;}'); // Postion inline TOC top/left/right $tocPos = ! empty($prefs['wiki_toc_pos']) ? $prefs['wiki_toc_pos'] : 'right'; switch (strtolower($tocPos)) { case 'top': $headerlib->add_css('#autotoc {border: 0px;}'); break; case 'left': $headerlib->add_css('#autotoc {float: left;margin-right:15px;}'); break; case 'right': default: $headerlib->add_css('#autotoc {float: right;margin-left:15px;}'); break; } } else {//Not inline TOC //$headerlib->add_css('#autotoc {display: none;}'); //Adds the offset for the affix $headerlib->add_css('.affix {top:' . $tocOffset . 'px;}'); } } } // Hide title per page $isHideTitlePerPage = isset($prefs['wiki_page_hide_title']) ? $prefs['wiki_page_hide_title'] === 'y' : false; if ($isHideTitlePerPage) { $isHideTitle = false; if (! empty($currPage)) { $isPageHideTitle = $this->get_page_hide_title($currPage); if ($isPageHideTitle != 0) { // Use page specific setting $isHideTitle = $isPageHideTitle < 0 ? true : false; } } if ($isHideTitle) { TikiLib::lib('smarty')->assign('hide_page_header', true); $headerlib->add_css('.pagetitle {display: none;}'); $headerlib->add_css('.titletop {display: none;}'); } } } } } class convertToTiki9 { public $parserlib; public $argumentParser; public function __construct() { $this->parserlib = TikiLib::lib('parser'); $this->argumentParser = new WikiParser_PluginArgumentParser(); } // // // //end conversion of objects--> // // } class WikiLibOutput { public $info; public $originalValue; public $parsedValue; public $options; public function __construct($info, $originalValue, $options = []) { //TODO: info may have an override, we need to build it in using MYSQL $this->info = $info; $this->originalValue = $originalValue; $this->options = $options; $this->parsedValue = TikiLib::lib('parser')->parse_data($this->originalValue, $this->options = $options); } }