public function test_numeric_twice_meta()
 {
     $indexer = idx_get_indexer();
     $indexer->addMetaKeys('testpage', 'onezero', array('1010'));
     $indexer->addMetaKeys('notfound', 'onezero', array('1010'));
     $query = '1010';
     $this->assertEquals(array('notfound', 'testpage'), $indexer->lookupKey('onezero', $query));
 }
Example #2
0
 function setUp()
 {
     parent::setUp();
     $this->indexer = idx_get_indexer();
     $this->indexer->clear();
     saveWikiText($this->old_id, 'Old test content', 'Created old test page for indexer rename test');
     idx_addPage($this->old_id);
 }
Example #3
0
    public function test_media_in_footnotes() {
        saveWikiText('test:media_footnotes', '(({{footnote.png?20x50}} [[foonote|{{:footlink.png}}]]))', 'Test initialization');
        idx_addPage('test:media_footnotes');

        $query = array('test:footnote.png', 'footlink.png');
        $this->assertEquals(array(
            'test:footnote.png' => array('test:media_footnotes'),
            'footlink.png' => array('test:media_footnotes')
        ), idx_get_indexer()->lookupKey('relation_media', $query));
    }
 function test_minlength()
 {
     $indexer = idx_get_indexer();
     $indexer->addMetaKeys('histo1', 'testkey', array('foo', 'bar', 'foobar'));
     $indexer->addMetaKeys('histo2', 'testkey', array('bar', 'testing'));
     $indexer->addMetaKeys('histo3', 'testkey', array('foo', 'foobar'));
     $histogram4 = $indexer->histogram(1, 0, 4, 'testkey');
     $this->assertEquals(array('foobar' => 2, 'testing' => 1), $histogram4);
     $histogram2 = $indexer->histogram(1, 0, 2, 'testkey');
     $this->assertEquals(array('foobar' => 2, 'testing' => 1, 'foo' => 2, 'bar' => 2), $histogram2);
 }
Example #5
0
 function test_pid()
 {
     $indexer = idx_get_indexer();
     $syntaxPID = $indexer->getPID('wiki:syntax');
     $this->assertEquals('wiki:syntax', $indexer->getPageFromPID($syntaxPID), 'getPageFromPID(getPID(\'wiki:syntax\')) != \'wiki:syntax\'');
     $dokuwikiPID = $indexer->getPID('wiki:dokuwiki');
     $this->assertEquals('wiki:syntax', $indexer->getPageFromPID($syntaxPID), 'getPageFromPID(getPID(\'wiki:syntax\')) != \'wiki:syntax\' after getting the PID for wiki:dokuwiki');
     $this->assertEquals($syntaxPID, $indexer->getPID('wiki:syntax'), 'getPID(\'wiki:syntax\') didn\'t returned different PIDs when called twice');
     $this->assertNotEquals($syntaxPID, $dokuwikiPID, 'Same PID returned for different pages');
     $this->assertTrue(is_numeric($syntaxPID) && is_numeric($dokuwikiPID), 'PIDs are not numeric');
 }
Example #6
0
function _update()
{
    global $conf;
    global $INDEXER;
    $INDEXER = idx_get_indexer();
    $data = array();
    _quietecho("Searching pages... ");
    search($data, $conf['datadir'], 'search_allpages', array('skipacl' => true));
    _quietecho(count($data) . " pages found.\n");
    foreach ($data as $val) {
        _index($val['id']);
    }
}
Example #7
0
 /**
  * Builds a Google Sitemap of all public pages known to the indexer
  *
  * The map is placed in the cache directory named sitemap.xml.gz - This
  * file needs to be writable!
  *
  * @author Michael Hamann
  * @author Andreas Gohr
  * @link   https://www.google.com/webmasters/sitemaps/docs/en/about.html
  * @link   http://www.sitemaps.org/
  */
 public function generate()
 {
     global $conf;
     if ($conf['sitemap'] < 1 || !is_numeric($conf['sitemap'])) {
         return false;
     }
     $sitemap = Sitemapper::getFilePath();
     if (@file_exists($sitemap)) {
         if (!is_writable($sitemap)) {
             return false;
         }
     } else {
         if (!is_writable(dirname($sitemap))) {
             return false;
         }
     }
     if (@filesize($sitemap) && @filemtime($sitemap) > time() - $conf['sitemap'] * 86400) {
         // 60*60*24=86400
         dbglog('Sitemapper::generate(): Sitemap up to date');
         // FIXME: only in debug mode
         return false;
     }
     dbglog("Sitemapper::generate(): using {$sitemap}");
     // FIXME: Only in debug mode
     $pages = idx_get_indexer()->getPages();
     dbglog('Sitemapper::generate(): creating sitemap using ' . count($pages) . ' pages');
     $items = array();
     // build the sitemap items
     foreach ($pages as $id) {
         //skip hidden, non existing and restricted files
         if (isHiddenPage($id)) {
             continue;
         }
         if (auth_aclcheck($id, '', '') < AUTH_READ) {
             continue;
         }
         $item = SitemapItem::createFromID($id);
         if ($item !== NULL) {
             $items[] = $item;
         }
     }
     $eventData = array('items' => &$items, 'sitemap' => &$sitemap);
     $event = new Doku_Event('SITEMAP_GENERATE', $eventData);
     if ($event->advise_before(true)) {
         //save the new sitemap
         $result = io_saveFile($sitemap, Sitemapper::getXML($items));
     }
     $event->advise_after();
     return $result;
 }
Example #8
0
 /**
  * Setup the data directory
  *
  * This is ran before each test class
  */
 public static function setUpBeforeClass()
 {
     // just to be safe not to delete something undefined later
     if (!defined('TMP_DIR')) {
         die('no temporary directory');
     }
     if (!defined('DOKU_TMP_DATA')) {
         die('no temporary data directory');
     }
     // remove any leftovers from the last run
     if (is_dir(DOKU_TMP_DATA)) {
         // clear indexer data and cache
         idx_get_indexer()->clear();
         TestUtils::rdelete(DOKU_TMP_DATA);
     }
     // populate default dirs
     TestUtils::rcopy(TMP_DIR, dirname(__FILE__) . '/../data/');
 }
Example #9
0
 /**
  * Tag index lookup
  *
  * @param array $tags the tags to filter
  * @return array the matching page ids
  */
 function _tagIndexLookup($tags)
 {
     $result = array();
     // array of page ids
     $clean_tags = array();
     foreach ($tags as $i => $tag) {
         if ($tag[0] == '+' || $tag[0] == '-') {
             $clean_tags[$i] = substr($tag, 1);
         } else {
             $clean_tags[$i] = $tag;
         }
     }
     $indexer = idx_get_indexer();
     $pages = $indexer->lookupKey('subject', $clean_tags, array($this, '_tagCompare'));
     // use all pages as basis if the first tag isn't an "or"-tag or if there are no tags given
     if (empty($tags) || $clean_tags[0] != $tags[0]) {
         $result = $indexer->getPages();
     }
     foreach ($tags as $i => $tag) {
         $t = $clean_tags[$i];
         if (!is_array($pages[$t])) {
             $pages[$t] = array();
         }
         if ($tag[0] == '+') {
             // AND: add only if in both arrays
             $result = array_intersect($result, $pages[$t]);
         } elseif ($tag[0] == '-') {
             // NOT: remove array from docs
             $result = array_diff($result, $pages[$t]);
         } else {
             // OR: add array to docs
             $result = array_unique(array_merge($result, $pages[$t]));
         }
     }
     return $result;
 }
Example #10
0
function _ft_pageLookup(&$data)
{
    // split out original parameters
    $id = $data['id'];
    if (preg_match('/(?:^| )@(\\w+)/', $id, $matches)) {
        $ns = cleanID($matches[1]) . ':';
        $id = str_replace($matches[0], '', $id);
    }
    $in_ns = $data['in_ns'];
    $in_title = $data['in_title'];
    $cleaned = cleanID($id);
    $Indexer = idx_get_indexer();
    $page_idx = $Indexer->getPages();
    $pages = array();
    if ($id !== '' && $cleaned !== '') {
        foreach ($page_idx as $p_id) {
            if (strpos($in_ns ? $p_id : noNSorNS($p_id), $cleaned) !== false) {
                if (!isset($pages[$p_id])) {
                    $pages[$p_id] = p_get_first_heading($p_id, METADATA_DONT_RENDER);
                }
            }
        }
        if ($in_title) {
            foreach ($Indexer->lookupKey('title', $id, '_ft_pageLookupTitleCompare') as $p_id) {
                if (!isset($pages[$p_id])) {
                    $pages[$p_id] = p_get_first_heading($p_id, METADATA_DONT_RENDER);
                }
            }
        }
    }
    if (isset($ns)) {
        foreach (array_keys($pages) as $p_id) {
            if (strpos($p_id, $ns) !== 0) {
                unset($pages[$p_id]);
            }
        }
    }
    // discard hidden pages
    // discard nonexistent pages
    // check ACL permissions
    foreach (array_keys($pages) as $idx) {
        if (!isVisiblePage($idx) || !page_exists($idx) || auth_quickaclcheck($idx) < AUTH_READ) {
            unset($pages[$idx]);
        }
    }
    uksort($pages, 'ft_pagesorter');
    return $pages;
}
Example #11
0
 /**
  * List all pages - we use the indexer list here
  */
 function listPages()
 {
     $list = array();
     $pages = idx_get_indexer()->getPages();
     $pages = array_filter(array_filter($pages, 'isVisiblePage'), 'page_exists');
     foreach (array_keys($pages) as $idx) {
         $perm = auth_quickaclcheck($pages[$idx]);
         if ($perm < AUTH_READ) {
             continue;
         }
         $page = array();
         $page['id'] = trim($pages[$idx]);
         $page['perms'] = $perm;
         $page['size'] = @filesize(wikiFN($pages[$idx]));
         $page['lastModified'] = $this->api->toDate(@filemtime(wikiFN($pages[$idx])));
         $list[] = $page;
     }
     return $list;
 }
Example #12
0
/**
 * Split a string into tokens
 *
 */
function idx_tokenizer($string, $wc = false)
{
    $Indexer = idx_get_indexer();
    return $Indexer->tokenizer($string, $wc);
}
Example #13
0
 /**
  * Clear all index files
  */
 function clearindex() {
     $this->quietecho("Clearing index... ");
     idx_get_indexer()->clear();
     $this->quietecho("done.\n");
 }
Example #14
0
 /**
  * A heavily customised version of _ft_pageLookup in inc/fulltext.php
  * no sorting!
  */
 function page_lookup($query, $fullregex, $incl_ns, $excl_ns)
 {
     global $conf;
     $query = trim($query);
     $pages = idx_get_indexer()->getPages();
     if (!$fullregex) {
         // first deal with excluded namespaces, then included, order matters!
         $pages = $this->_filter_ns($pages, $excl_ns, true);
         $pages = $this->_filter_ns($pages, $incl_ns, false);
     }
     $cnt = count($pages);
     for ($i = 0; $i < $cnt; $i++) {
         $page = $pages[$i];
         if (!page_exists($page) || isHiddenPage($page)) {
             unset($pages[$i]);
             continue;
         }
         if (!$fullregex) {
             $page = noNS($page);
         }
         /*
          * This is the actual "search" expression.
          * Note: preg_grep cannot be used because we need to
          *  allow for beginning of string "^" regex on normal page search
          *  and the page-exists check above
          * The @ prevents problems with invalid queries!
          */
         $matched = @preg_match('/' . $query . '/iS', $page);
         if ($matched === false) {
             return false;
         } elseif ($matched == 0) {
             unset($pages[$i]);
         }
     }
     if (count($pages) > 0) {
         return $pages;
     } else {
         // we always return an array type
         return array();
     }
 }
Example #15
0
 /**
  * Execute a media file move/rename
  *
  * @param string $src original ID
  * @param string $dst new ID
  * @return bool true if the move was successfully executed
  */
 public function moveMedia($src, $dst)
 {
     if (!$this->checkMedia($src, $dst)) {
         return false;
     }
     // get all pages using this media
     $affected_pages = idx_get_indexer()->lookupKey('relation_media', $src);
     $src_ns = getNS($src);
     $src_name = noNS($src);
     $dst_ns = getNS($dst);
     $dst_name = noNS($dst);
     // pass this info on to other plugins
     $eventdata = array('opts' => array('ns' => $src_ns, 'name' => $src_name, 'newns' => $dst_ns, 'newname' => $dst_name), 'affected_pages' => &$affected_pages, 'src_id' => $src, 'dst_id' => $dst);
     // give plugins the option to add their own meta files to the list of files that need to be moved
     // to the oldfiles/newfiles array or to adjust their own metadata, database, ...
     // and to add other pages to the affected pages
     $event = new Doku_Event('PLUGIN_MOVE_MEDIA_RENAME', $eventdata);
     if ($event->advise_before()) {
         /** @var helper_plugin_move_file $FileMover */
         $FileMover = plugin_load('helper', 'move_file');
         /** @var helper_plugin_move_rewrite $Rewriter */
         $Rewriter = plugin_load('helper', 'move_rewrite');
         // Move the Subscriptions & Indexes (new feature since Spring 2013 release)
         $Indexer = idx_get_indexer();
         if (($idx_msg = $Indexer->renameMetaValue('relation_media', $src, $dst)) !== true) {
             msg(sprintf($this->getLang('indexerror'), $idx_msg), -1);
             return false;
         }
         if (!$FileMover->moveMediaMeta($src_ns, $src_name, $dst_ns, $dst_name)) {
             msg(sprintf($this->getLang('mediametamoveerror'), $src), -1);
             return false;
         }
         // prepare directory
         io_createNamespace($dst, 'media');
         // move it FIXME this does not create a changelog entry!
         if (!io_rename(mediaFN($src), mediaFN($dst))) {
             msg(sprintf($this->getLang('mediamoveerror'), $src), -1);
             return false;
         }
         // clean up old ns
         io_sweepNS($src, 'mediadir');
         // Move the old revisions
         if (!$FileMover->moveMediaAttic($src_ns, $src_name, $dst_ns, $dst_name)) {
             // it's too late to stop the move, so just display a message.
             msg(sprintf($this->getLang('mediaatticmoveerror'), $src), -1);
         }
         // Add meta data to all affected pages, so links get updated later
         foreach ($affected_pages as $id) {
             $Rewriter->setMoveMeta($id, $src, $dst, 'media');
         }
     }
     $event->advise_after();
     // store this for later use
     $this->affectedPages = $affected_pages;
     return true;
 }
Example #16
0
    /**
     * Move media file
     *
     * @author  Michael Hamann <*****@*****.**>
     *
     * @param array $opts
     * @param bool  $checkonly Only execute the checks if the media file can be moved
     * @return bool If the move was executed
     */
    public function move_media(&$opts, $checkonly = false) {
        $opts['id'] = cleanID($opts['ns'].':'.$opts['name']);
        $opts['path'] = mediaFN($opts['id']);

        // Check we have rights to move this document
        if ( !file_exists(mediaFN($opts['id']))) {
            msg(sprintf($this->getLang('medianotexist'), hsc($opts['id'])), -1);
            return false;
        }

        if ( auth_quickaclcheck($opts['ns'].':*') < AUTH_DELETE ) {
            msg(sprintf($this->getLang('nomediarights'), hsc($opts['id'])), -1);
            return false;
        }

        // Assemble media name and path
        $opts['new_id'] = cleanID($opts['newns'].':'.$opts['newname']);
        $opts['new_path'] = mediaFN($opts['new_id']);

        // Has the document name and/or namespace changed?
        if ( $opts['newns'] == $opts['ns'] && $opts['newname'] == $opts['name'] ) {
            msg($this->getLang('nomediachange'), -1);
            return false;
        }
        // Check the page does not already exist
        if ( @file_exists($opts['new_path']) ) {
            msg(sprintf($this->getLang('mediaexisting'), $opts['newname'], ($opts['newns'] == '' ? $this->getLang('root') : $opts['newns'])), -1);
            return false;
        }

        // Check if the current user can create the new page
        if (auth_quickaclcheck($opts['new_ns'].':*') < AUTH_UPLOAD) {
            msg(sprintf($this->getLang('nomediatargetperms'), $opts['new_id']), -1);
            return false;
        }

        if ($checkonly) return true;

        /**
         * End of init (checks)
         */

        $affected_pages = idx_get_indexer()->lookupKey('relation_media', $opts['id']);

        $data = array('opts' => &$opts, 'affected_pages' => &$affected_pages);
        // give plugins the option to add their own meta files to the list of files that need to be moved
        // to the oldfiles/newfiles array or to adjust their own metadata, database, ...
        // and to add other pages to the affected pages
        $event = new Doku_Event('PLUGIN_MOVE_MEDIA_RENAME', $data);
        if ($event->advise_before()) {
            // Move the Subscriptions & Indexes
            if (method_exists('Doku_Indexer', 'renamePage')) { // new feature since Spring 2013 release
                $Indexer = idx_get_indexer();
            } else {
                $Indexer = new helper_plugin_move_indexer(); // copy of the new code
            }
            if (($idx_msg = $Indexer->renameMetaValue('relation_media', $opts['id'], $opts['new_id'])) !== true) {
                msg('Error while updating the search index '.$idx_msg, -1);
                return false;
            }
            if (!$this->movemediameta($opts)) {
                msg('The meta files of the media file '.$opts['id'].' couldn\'t be moved', -1);
                return false;
            }

            // prepare directory
            io_createNamespace($opts['new_id'], 'media');

            if (!io_rename($opts['path'], $opts['new_path'])) {
                msg('Moving the media file '.$opts['id'].' failed', -1);
                return false;
            }

            io_sweepNS($opts['id'], 'mediadir');

            // Move the old revisions
            if (!$this->movemediaattic($opts)) {
                // it's too late to stop the move, so just display a message.
                msg('The attic files of media file '.$opts['id'].' couldn\'t be moved. Please move them manually.', -1);
            }

            foreach ($affected_pages as $id) {
                if (!page_exists($id, '', false)) continue;
                $meta = $this->getMoveMeta($id);
                if (!$meta) $meta = array('media_moves' => array());
                if (!isset($meta['media_moves'])) $meta['media_moves'] = array();
                $meta['media_moves'] = $this->resolve_moves($meta['media_moves'], '__');
                $meta['media_moves'][$opts['id']] = $opts['new_id'];
                //if (empty($meta['moves'])) unset($meta['moves']);
                p_set_metadata($id, array('plugin_move' => $meta), false, true);
            }
        }

        $event->advise_after();
        return true;
    }
    function setUp()
    {
        parent::setUpBeforeClass();
        $this->pluginsEnabled[] = 'move';
        global $ID;
        global $INFO;
        global $conf;
        $ID = $this->movedId;
        $text = <<<EOT
[[start|start]]
[[parallel_page|parallel_page]]
[[.:|.:]]
[[..current_ns:|..current_ns:]]
[[..:current_ns:|..:current_ns:]]
[[..parallel_ns:|..parallel_ns:]]
[[..:parallel_ns:|..:parallel_ns:]]
[[..:..:|..:..:]]
[[..:..:parent_ns:|..:..:parent_ns:]]
[[parent_ns:new_page|parent_ns:new_page]]
[[parent_ns/new_page|parent_ns/new_page]]
[[/start|/start]]
EOT;
        $summary = 'Test';
        saveWikiText($this->movedId, $text, $summary);
        $INFO = pageinfo();
        $references = array_keys(p_get_metadata($this->movedId, 'relation references', METADATA_RENDER_UNLIMITED));
        idx_get_indexer()->addMetaKeys($this->movedId, 'relation_references', $references);
        $text = <<<EOT
[[{$this->movedId}|{$this->movedId}]]
[[:{$this->movedId}|:{$this->movedId}]]
[[.current_ns:test_page|.current_ns:test_page]]
[[.:current_ns:test_page|.:current_ns:test_page]]
[[..parent_ns:current_ns:test_page|..parent_ns:current_ns:test_page]]
[[test_page|test_page]]
[[new_page|new_page]]
[[ftp://somewhere.com|ftp://somewhere.com]]
[[http://somewhere.com|http://somewhere.com]]

[[start|start]]
[[parallel_page|parallel_page]]
[[.:|.:]]
[[..current_ns:|..current_ns:]]
[[..:current_ns:|..:current_ns:]]
[[..parallel_ns:|..parallel_ns:]]
[[..:parallel_ns:|..:parallel_ns:]]
[[..:..:|..:..:]]
[[..:..:parent_ns:|..:..:parent_ns:]]
[[parent_ns:new_page|parent_ns:new_page]]
[[parent_ns/new_page|parent_ns/new_page]]
[[/start|/start]]
EOT;
        saveWikiText($this->parentBacklinkingId, $text, $summary);
        $references = array_keys(p_get_metadata($this->parentBacklinkingId, 'relation references', METADATA_RENDER_UNLIMITED));
        idx_get_indexer()->addMetaKeys($this->parentBacklinkingId, 'relation_references', $references);
        $text = <<<EOT
[[{$this->movedId}|{$this->movedId}]]
[[:{$this->movedId}|:{$this->movedId}]]
[[..current_ns:test_page|..current_ns:test_page]]
[[..:current_ns:test_page|..:current_ns:test_page]]
[[test_page|test_page]]
[[.test_page|.test_page]]
[[.:test_page|.:test_page]]
[[..test_page|..test_page]]
[[..:test_page|..:test_page]]
[[.:..:test_page|.:..:test_page]]
[[new_page|new_page]]
[[ftp://somewhere.com|ftp://somewhere.com]]
[[http://somewhere.com|http://somewhere.com]]

[[start|start]]
[[parallel_page|parallel_page]]
[[.:|.:]]
[[..current_ns:|..current_ns:]]
[[..:current_ns:|..:current_ns:]]
[[..parallel_ns:|..parallel_ns:]]
[[..:parallel_ns:|..:parallel_ns:]]
[[..:..:|..:..:]]
[[..:..:parent_ns:|..:..:parent_ns:]]
[[parent_ns:new_page|parent_ns:new_page]]
[[parent_ns/new_page|parent_ns/new_page]]
[[/start|/start]]
EOT;
        saveWikiText($this->currentNsBacklinkingId, $text, $summary);
        $references = array_keys(p_get_metadata($this->currentNsBacklinkingId, 'relation references', METADATA_RENDER_UNLIMITED));
        idx_get_indexer()->addMetaKeys($this->currentNsBacklinkingId, 'relation_references', $references);
        $text = <<<EOT
[[{$this->movedId}|{$this->movedId}]]
[[:{$this->movedId}|:{$this->movedId}]]
[[.current_ns:test_page|.current_ns:test_page]]
[[.:current_ns:test_page|.:current_ns:test_page]]
[[test_page|test_page]]
[[new_page|new_page]]
[[ftp://somewhere.com|ftp://somewhere.com]]
[[http://somewhere.com|http://somewhere.com]]

[[start|start]]
[[parallel_page|parallel_page]]
[[.:|.:]]
[[..current_ns:|..current_ns:]]
[[..:current_ns:|..:current_ns:]]
[[..parallel_ns:|..parallel_ns:]]
[[..:parallel_ns:|..:parallel_ns:]]
[[..:..:|..:..:]]
[[..:..:parent_ns:|..:..:parent_ns:]]
[[parent_ns:new_page|parent_ns:new_page]]
[[parent_ns/new_page|parent_ns/new_page]]
[[/start|/start]]
EOT;
        saveWikiText($this->otherBacklinkingId, $text, $summary);
        $references = array_keys(p_get_metadata($this->otherBacklinkingId, 'relation references', METADATA_RENDER_UNLIMITED));
        idx_get_indexer()->addMetaKeys($this->otherBacklinkingId, 'relation_references', $references);
        $text = <<<EOT
[[{$this->movedId}|{$this->movedId}]]
[[:{$this->movedId}|:{$this->movedId}]]
[[..:..current_ns:test_page|..:..current_ns:test_page]]
[[..:..:current_ns:test_page|..:..:current_ns:test_page]]
[[test_page|test_page]]
[[..:test_page|..:test_page]]
[[..:test_page|..:test_page]]
[[.:..:test_page|.:..:test_page]]
[[new_page|new_page]]
[[..:new_page|..:new_page]]
[[ftp://somewhere.com|ftp://somewhere.com]]
[[http://somewhere.com|http://somewhere.com]]

[[start|start]]
[[parallel_page|parallel_page]]
[[.:|.:]]
[[..current_ns:|..current_ns:]]
[[..:current_ns:|..:current_ns:]]
[[..parallel_ns:|..parallel_ns:]]
[[..:parallel_ns:|..:parallel_ns:]]
[[..:..:|..:..:]]
[[..:..:parent_ns:|..:..:parent_ns:]]
[[parent_ns:new_page|parent_ns:new_page]]
[[parent_ns/new_page|parent_ns/new_page]]
[[/start|/start]]
EOT;
        saveWikiText($this->subNsPage, $text, $summary);
        $references = array_keys(p_get_metadata($this->subNsPage, 'relation references', METADATA_RENDER_UNLIMITED));
        idx_get_indexer()->addMetaKeys($this->subNsPage, 'relation_references', $references);
        parent::setUp();
        // we test under useslash conditions
        $conf['useslash'] = 1;
    }
Example #18
0
/**
 * Clear all index files
 */
function _clearindex()
{
    _quietecho("Clearing index... ");
    idx_get_indexer()->clear();
    _quietecho("done.\n");
}
 /**
  * Gets highlight candidates from HTTP_REFERER info
  * (A compensation for "remove_url_params" option)
  */
 function getCandidatesFromReferer()
 {
     global $HIGH;
     global $ACT;
     if ($ACT !== 'show' || !empty($HIGH) || !isset($_SERVER['HTTP_REFERER']) || in_array($this->disable_highlight, array('all', 'auto'))) {
         return;
     }
     $referer = (string) $_SERVER['HTTP_REFERER'];
     if (strpos($referer, DOKU_URL) === 0 && preg_match('/[?&]do=search&id=([^&]+)/', $referer, $matches)) {
         // users seem to have jumped from search result link in this wiki
         require_once DOKU_INC . 'inc/fulltext.php';
         $query = urldecode($matches[1]);
         // set highlight candidates
         // (ft_queryParser has been modified since DokuWiki Rincewind)
         if (function_exists('idx_get_indexer')) {
             $Indexer = idx_get_indexer();
             $parsed_query = ft_queryParser($Indexer, $query);
         } else {
             $parsed_query = ft_queryParser($query);
         }
         $HIGH = $parsed_query['highlight'];
     }
 }
Example #20
0
 function search_queries(&$event, $param)
 {
     global $ACT;
     if (is_array($ACT) || $this->is_edit_user) {
         return;
     }
     if ($ACT != 'show' && $ACT != 'search') {
         return;
     }
     //login,admin,profile, revisions,logout
     if (empty($_SERVER['QUERY_STRING']) || $this->is_excluded($this->ipaddr)) {
         return;
     }
     $queries = unserialize(io_readFile($this->qs_file, false));
     if (!$queries) {
         $queries = array('words' => array(), 'ns' => array(), 'extern' => array());
     }
     $elems = explode('&', html_entity_decode($_SERVER['QUERY_STRING']));
     $data_found = false;
     if (count($elems > 1)) {
         $words = array();
         $temp = array();
         foreach ($elems as $el) {
             if (isset($el) && $el) {
                 list($name, $value) = explode('=', $el);
                 $temp[$name] = $value;
             }
         }
         if (isset($temp['do']) && $temp['do'] == 'search') {
             $data_found = true;
             if (function_exists('idx_get_indexer')) {
                 $ar = ft_queryParser(idx_get_indexer(), urldecode($temp['id']));
             } else {
                 $ar = ft_queryParser(urldecode($temp['id']));
             }
             if (!empty($ar['phrases']) && !empty($ar['not'])) {
                 $words = array_diff($ar['words'], $ar['not']);
             } else {
                 $words = $ar['words'];
             }
             if (!empty($words)) {
                 foreach ($words as $word) {
                     $this->set_queries($queries, $word, 'words');
                 }
             }
             if (!empty($ar['ns'])) {
                 foreach ($ar['ns'] as $ns) {
                     $this->set_queries($queries, $ns, 'ns');
                 }
             }
         } else {
             foreach ($this->dw_tokens as $t) {
                 if (isset($temp[$t])) {
                     unset($temp[$t]);
                 }
             }
             if (count($temp)) {
                 $keys = array_keys($temp);
                 foreach ($keys as $k) {
                     if (preg_match('/rev\\d*\\[\\d*\\]/', $k)) {
                         unset($temp[$k]);
                     }
                 }
                 if (count($temp)) {
                     $data_found = true;
                 }
             }
             foreach ($temp as $name => $val) {
                 $this->set_queries($queries['extern'], urldecode($name), 'name');
                 if (!$val) {
                     $val = '_empty_';
                 }
                 $this->set_queries($queries['extern'], urldecode($val), 'val');
                 $this->set_named_values($queries['extern']['name'][urldecode($name)], urldecode($val));
             }
         }
         if ($data_found) {
             io_saveFile($this->qs_file, serialize($queries));
         }
     }
 }
Example #21
0
 /**
  * Looks up pages that will be affected by a move of $src
  *
  * Calls addToAffectedPagesList() directly to store the result
  *
  * @param string $src source namespace
  * @param string $dst destination namespace
  * @param int    $class
  * @param int    $type
  */
 protected function findAffectedPages($src, $dst, $class, $type)
 {
     $idx = idx_get_indexer();
     if ($class == self::CLASS_NS) {
         $src_ = "{$src}:*";
         // use wildcard lookup for namespaces
     } else {
         $src_ = $src;
     }
     $pages = array();
     if ($type == self::TYPE_PAGES) {
         $pages = $idx->lookupKey('relation_references', $src_);
         $len = strlen($src);
         foreach ($pages as &$page) {
             if (substr($page, 0, $len + 1) === "{$src}:") {
                 $page = $dst . substr($page, $len + 1);
             }
         }
         unset($page);
     } else {
         if ($type == self::TYPE_MEDIA) {
             $pages = $idx->lookupKey('relation_media', $src_);
         }
     }
     $this->addToAffectedPagesList($pages);
 }
Example #22
0
 /**
  * Builds the sorting array: array of arrays (0 = id, 1 = name, 2 = abstract, 3 = ... , etc)
  *
  * @param array     $ids    array of page ids to be sorted
  * @param array     $opt    all user options/settings
  *
  * @return array    $sort_array     array of array(one value for each key to be sorted)
  *                  $sort_opts      sorting options for the msort function
  *                  $group_opts     grouping options for the mgroup function
  */
 function build_sorting_array($ids, $opt)
 {
     global $conf;
     $sort_array = array();
     $sort_opts = array();
     $group_opts = array();
     $dformat = array();
     $wformat = array();
     $cnt = 0;
     // look for 'abc' by title instead of name ('abc' by page-id makes little sense)
     // title takes precedence over name (should you try to sort by both...why?)
     $from_title = isset($opt['sort']['title']) ? true : false;
     // is it necessary to cache the abstract column?
     $get_abstract = $opt['snippet']['type'] != 'none';
     // add any extra columns needed for filtering!
     $extrakeys = array_diff_key($opt['filter'], $opt['sort']);
     $col_keys = array_merge($opt['sort'], $extrakeys);
     // it is more efficient to get all the back-links at once from the indexer metadata
     if (isset($col_keys['backlinks'])) {
         $backlinks = idx_get_indexer()->lookupKey('relation_references', $ids);
     }
     foreach ($ids as $id) {
         // getting metadata is very time-consuming, hence ONCE per displayed row
         $meta = p_get_metadata($id, '', METADATA_DONT_RENDER);
         if (!isset($meta['date']['created'])) {
             $meta['date']['created'] = 0;
         }
         if (!isset($meta['date']['modified'])) {
             $meta['date']['modified'] = $meta['date']['created'];
         }
         // establish page name (without namespace)
         $name = noNS($id);
         // ref to current row, used through out function
         $row =& $sort_array[$cnt];
         // first column is the basic page id
         $row['id'] = $id;
         // second column is the display 'name' (used when sorting by 'name')
         // this also avoids rebuilding the display name when building links later (DRY)
         $row['name'] = $name;
         // third column: cache the display name; taken from metadata => 1st heading
         // used when sorting by 'title'
         $title = isset($meta['title']) && !empty($meta['title']) ? $meta['title'] : $name;
         $row['title'] = $title;
         // needed later in the a, ab ,abc clauses
         $abc = $from_title ? $title : $name;
         // fourth column: cache the page abstract if needed; this saves a lot of time later
         // and avoids repeated slow metadata retrievals (v. slow!)
         $abstract = $get_abstract ? $meta['description']['abstract'] : '';
         $row['abstract'] = $abstract;
         // fifth column is the displayed text for links; set below
         $row['display'] = '';
         // reset cache of full date for this row
         $real_date = 0;
         // ...optional columns
         foreach ($col_keys as $key => $void) {
             $value = '';
             switch ($key) {
                 case 'a':
                 case 'ab':
                 case 'abc':
                     $value = $this->_first($abc, strlen($key));
                     break;
                 case 'name':
                 case 'title':
                     // name/title columns already exists by default (col 1,2)
                     // save a few microseconds by just moving on to the next key
                     continue 2;
                 case 'id':
                     $value = $id;
                     break;
                 case 'ns':
                     $value = getNS($id);
                     if (empty($value)) {
                         $value = '[' . $conf['start'] . ']';
                     }
                     break;
                 case 'creator':
                     $value = $meta['creator'];
                     break;
                 case 'contributor':
                     $value = implode(' ', $meta['contributor']);
                     break;
                 case 'mdate':
                     $value = $meta['date']['modified'];
                     break;
                 case 'cdate':
                     $value = $meta['date']['created'];
                     break;
                 case 'links':
                     $value = $this->_join_keys_if(' ', $meta['relation']['references']);
                     break;
                 case 'backlinks':
                     $value = implode(' ', current($backlinks));
                     next($backlinks);
                     break;
                 default:
                     // date sorting types (groupable)
                     $dtype = $key[0];
                     if ($dtype == 'c' || $dtype == 'm') {
                         // we only set real date once per id (needed for grouping)
                         // not per sort column--the date should remain same across all columns
                         // this is always the last column!
                         if ($real_date == 0) {
                             $real_date = $dtype == 'c' ? $meta['date']['created'] : $meta['date']['modified'];
                             $row[self::MGROUP_REALDATE] = $real_date;
                         }
                         // only set date formats once per sort column/key (not per id!), i.e. on first row
                         if ($cnt == 0) {
                             $dformat[$key] = $this->_date_format($key);
                             // collect date in word format for potential use in grouping
                             $wformat[$key] = $opt['spelldate'] ? $this->_date_format_words($dformat[$key]) : '';
                         }
                         // create a string date used for sorting only
                         // (we cannot just use the real date otherwise it would not group correctly)
                         $value = strftime($dformat[$key], $real_date);
                     }
             }
             // set the optional column
             $row[$key] = $value;
         }
         /* provide custom display formatting via string templating {...} */
         $matches = array();
         $display = $opt['display'];
         $matched = preg_match_all('/\\{(.+?)\\}/', $display, $matches, PREG_SET_ORDER);
         // first try to use the custom column names as entered by user
         if ($matched > 0) {
             foreach ($matches as $match) {
                 $key = $match[1];
                 $value = null;
                 if (isset($row[$key])) {
                     $value = $row[$key];
                 } elseif (isset($meta[$key])) {
                     $value = $meta[$key];
                     // allow for nested meta keys (e.g. date:created)
                 } elseif (strpos($key, ':') !== false) {
                     $keys = explode(':', $key);
                     if (isset($meta[$keys[0]][$keys[1]])) {
                         $value = $meta[$keys[0]][$keys[1]];
                     }
                 } elseif ($key == 'mdate') {
                     $value = $meta['date']['modified'];
                 } elseif ($key == 'cdate') {
                     $value = $meta['date']['created'];
                 }
                 if (!is_null($value)) {
                     if (strpos($key, 'date') !== false) {
                         $value = utf8_encode(strftime($opt['dformat'], $value));
                     }
                     $display = str_replace($match[0], $value, $display);
                 }
             }
             // try to match any metadata field; to allow for plain single word display settings
             // e.g. display=title or display=name
         } elseif (isset($row[$display])) {
             $display = $row[$display];
             // if all else fails then use the page name (always available)
         } else {
             $display = $row['name'];
         }
         $row['display'] = $display;
         $cnt++;
     }
     $idx = 0;
     foreach ($opt['sort'] as $key => $value) {
         $sort_opts['key'][] = $key;
         // now the sort direction
         switch ($value) {
             case 'a':
             case 'asc':
                 $dir = self::MSORT_ASC;
                 break;
             case 'd':
             case 'desc':
                 $dir = self::MSORT_DESC;
                 break;
             default:
                 switch ($key) {
                     // sort dates descending by default; text ascending
                     case 'a':
                     case 'ab':
                     case 'abc':
                     case 'name':
                     case 'title':
                     case 'id':
                     case 'ns':
                     case 'creator':
                     case 'contributor':
                         $dir = self::MSORT_ASC;
                         break;
                     default:
                         $dir = self::MSORT_DESC;
                         break;
                 }
         }
         $sort_opts['dir'][] = $dir;
         // set the sort array's data type
         switch ($key) {
             case 'mdate':
             case 'cdate':
                 $type = self::MSORT_NUMERIC;
                 break;
             default:
                 if ($opt['casesort']) {
                     // case sensitive: a-z then A-Z
                     $type = $opt['natsort'] ? self::MSORT_NAT : self::MSORT_STRING;
                 } else {
                     // case-insensitive
                     $type = $opt['natsort'] ? self::MSORT_NAT_CASE : self::MSORT_STRING_CASE;
                 }
         }
         $sort_opts['type'][] = $type;
         // now establish grouping options
         switch ($key) {
             // name strings and full dates cannot be meaningfully grouped (no duplicates!)
             case 'mdate':
             case 'cdate':
             case 'name':
             case 'title':
             case 'id':
                 $group_by = self::MGROUP_NONE;
                 break;
             case 'ns':
                 $group_by = self::MGROUP_NAMESPACE;
                 break;
             default:
                 $group_by = self::MGROUP_HEADING;
         }
         if ($group_by != self::MGROUP_NONE) {
             $group_opts['key'][$idx] = $key;
             $group_opts['type'][$idx] = $group_by;
             $group_opts['dformat'][$idx] = $wformat[$key];
             $idx++;
         }
     }
     return array($sort_array, $sort_opts, $group_opts);
 }
Example #23
0
/**
 * Use this tool to reindex your wiki
 *
 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
 * @author  Abilio Marques <https://github.com/abiliojr>
 */
if (!defined('DOKU_ROOT')) {
    define('DOKU_ROOT', realpath(dirname(__FILE__) . '/../../../') . '/');
}
define('NOSESSION', 1);
require_once DOKU_ROOT . 'inc/init.php';
global $conf;
$sphinx = new SphinxSearch();
// clear the index
idx_get_indexer()->clear();
// must complete the basic indexing first
search($data, $conf['datadir'], 'search_allpages', array('skipacl' => true));
foreach ($data as $val) {
    idx_addPage($val['id'], false, true);
}
// only now the backlinks counters in the dokuwiki index are valid
// so lets update sphinxsearch to reflect them
$pages = idx_get_indexer()->getPages();
foreach ($pages as $page) {
    $namespace = getNS($page);
    if (!$namespace) {
        $namespace = 'root';
    }
    $title = str_replace($conf['sepchar'], ' ', noNS($page));
    $sphinx->updateReferences($namespace, $title, count(ft_backlinks($page, true)));
}