function handle_approve(&$event, $param)
 {
     global $ID, $REV;
     if (!$this->can_approve()) {
         return;
     }
     if ($event->data == 'show' && isset($_GET['approve'])) {
         //Add or remove the new line from the end of the page. Silly but needed.
         $content = rawWiki($ID, '');
         if (substr($content, -1) == "\n") {
             $content = substr($content, 0, -1);
         } else {
             $content .= "\n";
         }
         saveWikiText($ID, $content, APPROVED);
         header('Location: ?id=' . $ID);
     }
     /*czytacze wydzą najnowszą zatwierdzaną*/
     $last = $this->find_lastest_approved();
     /*użytkownik może tylko czytać i jednocześnie istnieje jakaś zatwierdzona strona*/
     if (auth_quickaclcheck($ID) <= AUTH_READ && $last != -1) {
         /*najnowsza zatwierdzona nie jest najnowszą*/
         /*i jednocześnie znajdujemy się w stronach nowszych niż aktualna zatwierdzona*/
         if ($last != 0 && ($REV > $last || $REV == 0)) {
             $REV = $last;
         }
     }
 }
Example #2
0
 function handle_start(&$event, $param)
 {
     global $ID;
     global $ACT;
     global $INFO;
     if ($ACT != 'show') {
         return;
     }
     if (!$INFO['exists']) {
         return;
     }
     # don't try to read an article that doesn't exist
     $all = rtrim(rawWiki($ID));
     $inner = substr($all, 2, -2);
     if ($all == '[[' . $inner . ']]' and strpos($inner, '[[') === false and strpos($inner, ']]') === false) {
         if (!strpos($inner, '://') === false) {
             $url = $inner;
             # link is URL already
         } else {
             msg(sprintf('From: <a href="' . wl($ID, 'do=edit') . '">' . hsc($ID) . '</a>'));
             $url = html_wikilink($inner, $name = null, $search = '');
             $url = substr($url, strpos($url, '"') + 1);
             $url = substr($url, 0, strpos($url, '"'));
         }
         idx_addPage($ID);
         # ensure fulltext search indexing of referrer article - to put it on the backlink page of target article
         send_redirect($url);
     }
 }
Example #3
0
 /**
  * renders the xhtml output of an action
  * note that you can define Doku_Action_Postprocessor subclasses to change
  * the global data that is used here, e.g., $ID and $EXAMPLE_TAG,
  */
 public function xhtml()
 {
     global $ID;
     global $EXAMPLE_TAG;
     $text = htmlspecialchars(rawWiki($ID));
     echo '<' . $EXAMPLE_TAG . '>' . $text . '</' . $EXAMPLE_TAG . '>';
 }
 function _hookdo(Doku_Event $event, $param)
 {
     global $ID;
     if ($event->data === 'export_svg' && auth_quickaclcheck($ID) >= AUTH_READ) {
         header('Content-type: image/svg+xml');
         die(rawWiki($ID));
     }
 }
 /**
  * Handle the user input [required]
  *
  * @param helper_plugin_bureaucracy_field[] $fields the list of fields in the form
  * @param string                            $thanks the thank you message as defined in the form
  *                                                  or default one. Might be modified by the action
  *                                                  before returned
  * @param array                             $argv   additional arguments passed to the action
  * @return bool|string false on error, $thanks on success
  */
 public function run($fields, $thanks, $argv)
 {
     global $ID;
     // prepare replacements
     $this->prepareNamespacetemplateReplacements();
     $this->prepareDateTimereplacements();
     $this->prepareLanguagePlaceholder();
     $this->prepareNoincludeReplacement();
     $this->prepareFieldReplacements($fields);
     //handle arguments
     $page_to_modify = array_shift($argv);
     if ($page_to_modify === '_self') {
         # shortcut to modify the same page as the submitter
         $page_to_modify = $ID;
     } else {
         //resolve against page which contains the form
         resolve_pageid(getNS($ID), $page_to_modify, $ignored);
     }
     $template_section_id = cleanID(array_shift($argv));
     if (!page_exists($page_to_modify)) {
         msg(sprintf($this->getLang('e_pagenotexists'), html_wikilink($page_to_modify)), -1);
         return false;
     }
     // check auth
     //
     // This is an important point.  In order to be able to modify a page via this method ALL you need is READ access to the page
     // This is good for admins to be able to only allow people to modify a page via a certain method.  If you want to protect the page
     // from people to WRITE via this method, deny access to the form page.
     $auth = $this->aclcheck($page_to_modify);
     // runas
     if ($auth < AUTH_READ) {
         msg($this->getLang('e_denied'), -1);
         return false;
     }
     // fetch template
     $template = rawWiki($page_to_modify);
     if (empty($template)) {
         msg(sprintf($this->getLang('e_template'), $page_to_modify), -1);
         return false;
     }
     // do the replacements
     $template = $this->updatePage($template, $template_section_id);
     if (!$template) {
         msg(sprintf($this->getLang('e_failedtoparse'), $page_to_modify), -1);
         return false;
     }
     // save page
     saveWikiText($page_to_modify, $template, sprintf($this->getLang('summary'), $ID));
     //thanks message with redirect
     $link = wl($page_to_modify);
     return sprintf($this->getLang('pleasewait'), "<script type='text/javascript' charset='utf-8'>location.replace('{$link}')</script>", html_wikilink($page_to_modify));
 }
 /**
  * Return a raw wiki page
  */
 function rawPage($id, $rev = '')
 {
     if (auth_quickaclcheck($id) < AUTH_READ) {
         return new IXR_Error(1, 'You are not allowed to read this page');
     }
     $text = rawWiki($id, $rev);
     if (!$text) {
         $data = array($id);
         return trigger_event('HTML_PAGE_FROMTEMPLATE', $data, 'pageTemplate', true);
     } else {
         return $text;
     }
 }
Example #7
0
 /**
  * Return a raw wiki page
  * @param string $id wiki page id
  * @param string $rev revision number of the page
  * @return page text.
  */
 function rawPage($id, $rev = '')
 {
     $id = $this->resolvePageId($id);
     if (auth_quickaclcheck($id) < AUTH_READ) {
         throw new RemoteAccessDeniedException('You are not allowed to read this file', 111);
     }
     $text = rawWiki($id, $rev);
     if (!$text) {
         return pageTemplate($id);
     } else {
         return $text;
     }
 }
 public function test_rename()
 {
     /** @var $move helper_plugin_move_op */
     $move = plugin_load('helper', 'move_op');
     if (!$move) {
         return;
     }
     // disable the test when move is not installed
     saveWikiText('editx', 'Page to rename', 'Testcase create');
     saveWikiText('links', '{{section>links#foo}} {{page>editx}} {{page>:eDitX&nofooter}} {{section>editx#test}} {{page>editx&nofooter}}', 'Testcase created');
     idx_addPage('editx');
     idx_addPage('links');
     $this->assertTrue($move->movePage('editx', 'test:edit'));
     $this->assertEquals('{{section>links#foo}} {{page>test:edit}} {{page>test:edit&nofooter}} {{section>test:edit#test}} {{page>test:edit&nofooter}}', rawWiki('links'));
 }
    public function test_rename() {
        global $ID;
        /** @var $pagemove helper_plugin_pagemove */
        $pagemove = plugin_load('helper', 'pagemove');
        if (!$pagemove) return; // disable the test when pagemove is not installed
        saveWikiText('editx', 'Page to rename', 'Testcase create');
        saveWikiText('links', '{{section>links#foo}} {{page>editx}} {{page>:eDitX&nofooter}} {{section>editx#test}} {{page>editx&nofooter}}', 'Testcase created');
        idx_addPage('editx');
        idx_addPage('links');

        $ID = 'editx';
        $opts['ns']      = '';
        $opts['newname'] = 'edit';
        $opts['newns']   = 'test';
        $pagemove->move_page($opts);
        $this->assertEquals('{{section>links#foo}} {{page>test:edit}} {{page>test:edit&nofooter}} {{section>test:edit#test}} {{page>test:edit&nofooter}}', rawWiki('links'));
    }
Example #10
0
 /**
  * Initialize the rendering
  */
 function document_start()
 {
     global $ID;
     $this->id = $ID;
     if (!isset($this->_texit)) {
         if (!$this->configloaded) {
             $this->loadConfig();
         }
         $this->_texit = new texitrender_plugin_texit($this->id);
         $info = array();
         if (preg_match("/<texit info>(.*?)<\\/texit>/", str_replace("\n", '\\n', rawWiki($this->id)), $info, PREG_OFFSET_CAPTURE)) {
             $this->_texit->add_data('info', str_replace('\\n', "\n", $info[0][0]));
         } else {
             echo "error preg_match";
         }
         if ($_REQUEST['texit_type'] == 'zip') {
             $this->_texit->_texit_conf['zipsources'] = true;
         }
         if ($this->_texit->generate('pdf')) {
             $filename = null;
             switch ($_REQUEST['texit_type']) {
                 case 'zip':
                     if (is_readable($this->_texit->zip['file'])) {
                         $filename = $this->_texit->zip['file'];
                         header('Content-Type: application/zip');
                     }
                     break;
                 case 'pdf':
                 default:
                     if (is_readable($this->_texit->pdf['file'])) {
                         $filename = $this->_texit->pdf['file'];
                         header('Content-Type: application/pdf');
                     }
                     break;
             }
             $hdr = "Content-Disposition: attachment;";
             $hdr .= "filename=" . basename($filename) . ";";
             header($hdr);
             header("Content-Transfer-Encoding: binary");
             header("Content-Length: " . filesize($filename));
             readfile("{$filename}");
             die;
         }
     }
 }
 /**
  * @group slow
  */
 public function test_moveSingleMedia_colonstart()
 {
     global $AUTH_ACL;
     $AUTH_ACL[] = "wiki:*\t@ALL\t16";
     $AUTH_ACL[] = "foobar:*\t@ALL\t8";
     $filepath = DOKU_TMP_DATA . 'media/wiki/testimage.png';
     io_makeFileDir($filepath);
     io_saveFile($filepath, '');
     saveWikiText('wiki:movetest', '{{:wiki:testimage.png?200}}', 'Test initialized');
     idx_addPage('wiki:movetest');
     $src = 'wiki:testimage.png';
     $dst = 'foobar:logo_2.png';
     /** @var helper_plugin_move_op $move */
     $move = plugin_load('helper', 'move_op');
     $this->assertTrue($move->moveMedia($src, $dst));
     $this->assertTrue(@file_exists(mediaFn('foobar:logo_2.png')));
     $this->assertEquals('{{:foobar:logo_2.png?200}}', rawWiki('wiki:movetest'));
 }
 /**
  * @dataProvider dataPages
  */
 public function test_PageDeleteSuccessful($id, $new_id, $pages)
 {
     $GLOBALS['INPUT']->server->set('REMOTE_USER', 'testuser');
     foreach ($pages as $page) {
         saveWikiText($page['id'], $page['content'], $page['summary']);
         idx_addPage($page['id']);
     }
     $json = $this->doCall($id, $new_id, 'testuser');
     $this->assertInstanceOf('\\stdClass', $json);
     $this->assertObjectHasAttribute('error', $json);
     $this->assertFalse($json->error);
     //check page deleted
     $this->assertFalse(file_exists(wikiFN($id)));
     //check foreign pages
     foreach ($pages as $page) {
         if ($page['id'] == $id) {
             continue;
             // skip main. it was deleted
         }
         $this->assertEquals(!empty($page['new_content']) ? $page['new_content'] : $page['content'], rawWiki($page['id']));
     }
 }
Example #13
0
    public function test_moveSingleMedia() {
        global $AUTH_ACL;

        $AUTH_ACL[] = "wiki:*\t@ALL\t16";
        $AUTH_ACL[] = "foobar:*\t@ALL\t8";

        saveWikiText('wiki:movetest', '{{wiki:dokuwiki-128.png?200}}', 'Test initialized');
        idx_addPage('wiki:movetest');

        $opts = array();
        $opts['ns'] = 'wiki';
        $opts['name'] = 'dokuwiki-128.png';
        $opts['newns'] = 'foobar';
        $opts['newname'] = 'logo.png';

        /** @var helper_plugin_move $move */
        $move = plugin_load('helper', 'move');
        $this->assertTrue($move->move_media($opts));

        $this->assertTrue(@file_exists(mediaFn('foobar:logo.png')));

        $this->assertEquals('{{foobar:logo.png?200}}', rawWiki('wiki:movetest'));
    }
Example #14
0
 private function _wikiRpcPublish($id)
 {
     # get page contents
     $content = rawWiki($id, '');
     #$meta = p_get_metadata($id);
     //TODO: allow to rewrite, prepend namespace, regexp replace, etc
     $id = $this->getConf('target_ns') . $id;
     # format a XMP-RPC message to update the page
     $req = xmlrpc_encode_request("wiki.putPage", array($id, $content, "pub", false));
     $errors = 0;
     # TODO: loop over mult. servers to update {
     $o = array('doku_host' => $this->getConf('target_host'), 'doku_base' => $this->getConf('target_path'), 'http_port' => $this->getConf('target_port'), 'protocol' => $this->getConf('target_proto'));
     #call "curl ... &" -> fire and forget
     #OR use make request here and inform user about result(s).
     $rv = $this->dokuXmlRpc($req, $o);
     #$this->_debug('parsed RPC reply: '.print_r($rv,true));
     if ($rv != "0") {
         $errors++;
         // TODO queue error message.
         $this->_debug(" !!! XMLRPC error #{$errors}");
     }
     # }
     return true;
 }
Example #15
0
/**
 * Split a page into words
 *
 * Returns an array of word counts, false if an error occurred.
 * Array is keyed on the word length, then the word index.
 *
 * @author Andreas Gohr <*****@*****.**>
 * @author Christopher Smith <*****@*****.**>
 */
function idx_getPageWords($page)
{
    global $conf;
    $swfile = DOKU_INC . 'inc/lang/' . $conf['lang'] . '/stopwords.txt';
    if (@file_exists($swfile)) {
        $stopwords = file($swfile);
    } else {
        $stopwords = array();
    }
    $body = '';
    $data = array($page, $body);
    $evt = new Doku_Event('INDEXER_PAGE_ADD', $data);
    if ($evt->advise_before()) {
        $data[1] .= rawWiki($page);
    }
    $evt->advise_after();
    unset($evt);
    list($page, $body) = $data;
    $body = strtr($body, "\r\n\t", '   ');
    $tokens = explode(' ', $body);
    $tokens = array_count_values($tokens);
    // count the frequency of each token
    // ensure the deaccented or romanised page names of internal links are added to the token array
    // (this is necessary for the backlink function -- there maybe a better way!)
    if ($conf['deaccent']) {
        $links = p_get_metadata($page, 'relation references');
        if (!empty($links)) {
            $tmp = join(' ', array_keys($links));
            // make a single string
            $tmp = strtr($tmp, ':', ' ');
            // replace namespace separator with a space
            $link_tokens = array_unique(explode(' ', $tmp));
            // break into tokens
            foreach ($link_tokens as $link_token) {
                if (isset($tokens[$link_token])) {
                    continue;
                }
                $tokens[$link_token] = 1;
            }
        }
    }
    $words = array();
    foreach ($tokens as $word => $count) {
        $arr = idx_tokenizer($word, $stopwords);
        $arr = array_count_values($arr);
        foreach ($arr as $w => $c) {
            $l = wordlen($w);
            if (isset($words[$l])) {
                $words[$l][$w] = $c * $count + (isset($words[$l][$w]) ? $words[$l][$w] : 0);
            } else {
                $words[$l] = array($w => $c * $count);
            }
        }
    }
    // arrive here with $words = array(wordlen => array(word => frequency))
    $index = array();
    //resulting index
    foreach (array_keys($words) as $wlen) {
        $word_idx = idx_getIndex('w', $wlen);
        foreach ($words[$wlen] as $word => $freq) {
            $wid = array_search("{$word}\n", $word_idx);
            if (!is_int($wid)) {
                $wid = count($word_idx);
                $word_idx[] = "{$word}\n";
            }
            if (!isset($index[$wlen])) {
                $index[$wlen] = array();
            }
            $index[$wlen][$wid] = $freq;
        }
        // save back word index
        if (!idx_saveIndex('w', $wlen, $word_idx)) {
            trigger_error("Failed to write word index", E_USER_ERROR);
            return false;
        }
    }
    return $index;
}
 function _exportPostcontent($exporter)
 {
     global $ID, $INFO, $REV, $conf;
     $exporter->setParameters('Article: ' . $INFO['meta']['title'] . ($REV ? ' (rev ' . $REV . ')' : ''), $this->_getDokuUrl(), $this->_getDokuUrl() . 'doku.php?', 'utf-8', $this->agentlink);
     // create user object
     // $id, $uri, $name, $email, $homepage='', $foaf_uri='', $role=false, $nick='', $sioc_url='', $foaf_url=''
     $dwuserpage_id = cleanID($this->getConf('userns')) . ($conf['useslash'] ? '/' : ':') . $INFO['editor'];
     /*
     if ($INFO['editor'] && $this->getConf('userns'))
         $pageuser = new SIOCUser($INFO['editor'],
                                     normalizeUri(getAbsUrl(exportlink($dwuserpage_id, 'siocxml', array('type'=>'user'), false, '&'))), // user page
                                     $INFO['meta']['contributor'][$INFO['editor']],
                                     getDwUserInfo($dwuserpage_id,$this,'mail'),
                                     '', // no homepage is saved for dokuwiki user
                                     '#'.$INFO['editor'], // local uri
                                     false, // no roles right now
                                     '', // no nick name is saved for dokuwiki user
                                     normalizeUri($exporter->siocURL('user', $dwuserpage_id))
                                 );
     */
     // create wiki page object
     $wikipage = new SIOCDokuWikiArticle($ID, normalizeUri($exporter->siocURL('post', $ID . ($REV ? $exporter->_urlseparator . 'rev' . $exporter->_urlequal . $REV : ''))), $INFO['meta']['title'] . ($REV ? ' (rev ' . $REV . ')' : ''), rawWiki($ID, $REV));
     /* encoded content   */
     $wikipage->addContentEncoded(p_cached_output(wikiFN($ID, $REV), 'xhtml'));
     /* created           */
     if (isset($INFO['meta']['date']['created'])) {
         $wikipage->addCreated(date('c', $INFO['meta']['date']['created']));
     }
     /* or modified       */
     if (isset($INFO['meta']['date']['modified'])) {
         $wikipage->addModified(date('c', $INFO['meta']['date']['modified']));
     }
     /* creator/modifier  */
     if ($INFO['editor'] && $this->getConf('userns')) {
         $wikipage->addCreator(array('foaf:maker' => '#' . $INFO['editor'], 'sioc:modifier' => $dwuserpage_id));
     }
     /* is creator        */
     if (isset($INFO['meta']['date']['created'])) {
         $wikipage->isCreator();
     }
     /* intern wiki links */
     $wikipage->addLinks($INFO['meta']['relation']['references']);
     // contributors - only for last revision b/c of wrong meta data for older revisions
     if (!$REV && $this->getConf('userns') && isset($INFO['meta']['contributor'])) {
         $cont_temp = array();
         $cont_ns = $this->getConf('userns') . ($conf['useslash'] ? '/' : ':');
         foreach ($INFO['meta']['contributor'] as $cont_id => $cont_name) {
             $cont_temp[$cont_ns . $cont_id] = $cont_name;
         }
         $wikipage->addContributors($cont_temp);
     }
     // backlinks - only for last revision
     if (!$REV) {
         require_once DOKU_INC . 'inc/fulltext.php';
         $backlinks = ft_backlinks($ID);
         if (count($backlinks) > 0) {
             $wikipage->addBacklinks($backlinks);
         }
     }
     // TODO: addLinksExtern
     /* previous and next revision */
     $changelog = new PageChangeLog($ID);
     $pagerevs = $changelog->getRevisions(0, $conf['recent'] + 1);
     $prevrev = false;
     $nextrev = false;
     if (!$REV) {
         // latest revision, previous rev is on top in array
         $prevrev = 0;
     } else {
         // other revision
         $currentrev = array_search($REV, $pagerevs);
         if ($currentrev !== false) {
             $prevrev = $currentrev + 1;
             $nextrev = $currentrev - 1;
         }
     }
     if ($prevrev !== false && $prevrev > -1 && page_exists($ID, $pagerevs[$prevrev])) {
         /* previous revision*/
         $wikipage->addVersionPrevious($pagerevs[$prevrev]);
     }
     if ($nextrev !== false && $nextrev > -1 && page_exists($ID, $pagerevs[$nextrev])) {
         /* next revision*/
         $wikipage->addVersionNext($pagerevs[$nextrev]);
     }
     /* latest revision   */
     if ($REV) {
         $wikipage->addVersionLatest();
     }
     // TODO: topics
     /* has_container     */
     if ($INFO['namespace']) {
         $wikipage->addContainer($INFO['namespace']);
     }
     /* has_space         */
     if ($this->getConf('owners')) {
         $wikipage->addSite($this->getConf('owners'));
     }
     // TODO: dc:contributor / has_modifier
     // TODO: attachment (e.g. pictures in that dwns)
     // add wiki page to exporter
     $exporter->addObject($wikipage);
     //if ($INFO['editor'] && $this->getConf('userns')) $exporter->addObject($pageuser);
     return $exporter;
 }
 /**
  * Send the diff for some page change
  *
  * @param string   $subscriber_mail The target mail address
  * @param string   $template        Mail template ('subscr_digest', 'subscr_single', 'mailtext', ...)
  * @param string   $id              Page for which the notification is
  * @param int|null $rev             Old revision if any
  * @param string   $summary         Change summary if any
  * @return bool                     true if successfully sent
  */
 public function send_diff($subscriber_mail, $template, $id, $rev = null, $summary = '')
 {
     global $DIFF_INLINESTYLES;
     // prepare replacements (keys not set in hrep will be taken from trep)
     $trep = array('PAGE' => $id, 'NEWPAGE' => wl($id, '', true, '&'), 'SUMMARY' => $summary, 'SUBSCRIBE' => wl($id, array('do' => 'subscribe'), true, '&'));
     $hrep = array();
     if ($rev) {
         $subject = 'changed';
         $trep['OLDPAGE'] = wl($id, "rev={$rev}", true, '&');
         $old_content = rawWiki($id, $rev);
         $new_content = rawWiki($id);
         $df = new Diff(explode("\n", $old_content), explode("\n", $new_content));
         $dformat = new UnifiedDiffFormatter();
         $tdiff = $dformat->format($df);
         $DIFF_INLINESTYLES = true;
         $df = new Diff(explode("\n", $old_content), explode("\n", $new_content));
         $dformat = new InlineDiffFormatter();
         $hdiff = $dformat->format($df);
         $hdiff = '<table>' . $hdiff . '</table>';
         $DIFF_INLINESTYLES = false;
     } else {
         $subject = 'newpage';
         $trep['OLDPAGE'] = '---';
         $tdiff = rawWiki($id);
         $hdiff = nl2br(hsc($tdiff));
     }
     $trep['DIFF'] = $tdiff;
     $hrep['DIFF'] = $hdiff;
     $headers = array('Message-Id' => $this->getMessageID($id));
     if ($rev) {
         $headers['In-Reply-To'] = $this->getMessageID($id, $rev);
     }
     return $this->send($subscriber_mail, $subject, $id, $template, $trep, $hrep, $headers);
 }
Example #18
0
/**
 * Show diff
 * between current page version and provided $text
 * or between the revisions provided via GET or POST
 *
 * @author Andreas Gohr <*****@*****.**>
 * @param  string $text  when non-empty: compare with this text with most current version
 * @param  bool   $intro display the intro text
 * @param  string $type  type of the diff (inline or sidebyside)
 */
function html_diff($text = '', $intro = true, $type = null)
{
    global $ID;
    global $REV;
    global $lang;
    global $INPUT;
    global $INFO;
    $pagelog = new PageChangeLog($ID);
    /*
     * Determine diff type
     */
    if (!$type) {
        $type = $INPUT->str('difftype');
        if (empty($type)) {
            $type = get_doku_pref('difftype', $type);
            if (empty($type) && $INFO['ismobile']) {
                $type = 'inline';
            }
        }
    }
    if ($type != 'inline') {
        $type = 'sidebyside';
    }
    /*
     * Determine requested revision(s)
     */
    // we're trying to be clever here, revisions to compare can be either
    // given as rev and rev2 parameters, with rev2 being optional. Or in an
    // array in rev2.
    $rev1 = $REV;
    $rev2 = $INPUT->ref('rev2');
    if (is_array($rev2)) {
        $rev1 = (int) $rev2[0];
        $rev2 = (int) $rev2[1];
        if (!$rev1) {
            $rev1 = $rev2;
            unset($rev2);
        }
    } else {
        $rev2 = $INPUT->int('rev2');
    }
    /*
     * Determine left and right revision, its texts and the header
     */
    $r_minor = '';
    $l_minor = '';
    if ($text) {
        // compare text to the most current revision
        $l_rev = '';
        $l_text = rawWiki($ID, '');
        $l_head = '<a class="wikilink1" href="' . wl($ID) . '">' . $ID . ' ' . dformat((int) @filemtime(wikiFN($ID))) . '</a> ' . $lang['current'];
        $r_rev = '';
        $r_text = cleanText($text);
        $r_head = $lang['yours'];
    } else {
        if ($rev1 && isset($rev2) && $rev2) {
            // two specific revisions wanted
            // make sure order is correct (older on the left)
            if ($rev1 < $rev2) {
                $l_rev = $rev1;
                $r_rev = $rev2;
            } else {
                $l_rev = $rev2;
                $r_rev = $rev1;
            }
        } elseif ($rev1) {
            // single revision given, compare to current
            $r_rev = '';
            $l_rev = $rev1;
        } else {
            // no revision was given, compare previous to current
            $r_rev = '';
            $revs = $pagelog->getRevisions(0, 1);
            $l_rev = $revs[0];
            $REV = $l_rev;
            // store revision back in $REV
        }
        // when both revisions are empty then the page was created just now
        if (!$l_rev && !$r_rev) {
            $l_text = '';
        } else {
            $l_text = rawWiki($ID, $l_rev);
        }
        $r_text = rawWiki($ID, $r_rev);
        list($l_head, $r_head, $l_minor, $r_minor) = html_diff_head($l_rev, $r_rev, null, false, $type == 'inline');
    }
    /*
     * Build navigation
     */
    $l_nav = '';
    $r_nav = '';
    if (!$text) {
        list($l_nav, $r_nav) = html_diff_navigation($pagelog, $type, $l_rev, $r_rev);
    }
    /*
     * Create diff object and the formatter
     */
    $diff = new Diff(explode("\n", $l_text), explode("\n", $r_text));
    if ($type == 'inline') {
        $diffformatter = new InlineDiffFormatter();
    } else {
        $diffformatter = new TableDiffFormatter();
    }
    /*
     * Display intro
     */
    if ($intro) {
        print p_locale_xhtml('diff');
    }
    /*
     * Display type and exact reference
     */
    if (!$text) {
        ptln('<div class="diffoptions group">');
        $form = new Doku_Form(array('action' => wl()));
        $form->addHidden('id', $ID);
        $form->addHidden('rev2[0]', $l_rev);
        $form->addHidden('rev2[1]', $r_rev);
        $form->addHidden('do', 'diff');
        $form->addElement(form_makeListboxField('difftype', array('sidebyside' => $lang['diff_side'], 'inline' => $lang['diff_inline']), $type, $lang['diff_type'], '', '', array('class' => 'quickselect')));
        $form->addElement(form_makeButton('submit', 'diff', 'Go'));
        $form->printForm();
        ptln('<p>');
        // link to exactly this view FS#2835
        echo html_diff_navigationlink($type, 'difflink', $l_rev, $r_rev ? $r_rev : $INFO['currentrev']);
        ptln('</p>');
        ptln('</div>');
        // .diffoptions
    }
    /*
     * Display diff view table
     */
    ?>
    <div class="table">
    <table class="diff diff_<?php 
    echo $type;
    ?>
">

        <?php 
    //navigation and header
    if ($type == 'inline') {
        if (!$text) {
            ?>
                <tr>
                    <td class="diff-lineheader">-</td>
                    <td class="diffnav"><?php 
            echo $l_nav;
            ?>
</td>
                </tr>
                <tr>
                    <th class="diff-lineheader">-</th>
                    <th <?php 
            echo $l_minor;
            ?>
>
                        <?php 
            echo $l_head;
            ?>
                    </th>
                </tr>
            <?php 
        }
        ?>
            <tr>
                <td class="diff-lineheader">+</td>
                <td class="diffnav"><?php 
        echo $r_nav;
        ?>
</td>
            </tr>
            <tr>
                <th class="diff-lineheader">+</th>
                <th <?php 
        echo $r_minor;
        ?>
>
                    <?php 
        echo $r_head;
        ?>
                </th>
            </tr>
        <?php 
    } else {
        if (!$text) {
            ?>
                <tr>
                    <td colspan="2" class="diffnav"><?php 
            echo $l_nav;
            ?>
</td>
                    <td colspan="2" class="diffnav"><?php 
            echo $r_nav;
            ?>
</td>
                </tr>
            <?php 
        }
        ?>
            <tr>
                <th colspan="2" <?php 
        echo $l_minor;
        ?>
>
                    <?php 
        echo $l_head;
        ?>
                </th>
                <th colspan="2" <?php 
        echo $r_minor;
        ?>
>
                    <?php 
        echo $r_head;
        ?>
                </th>
            </tr>
        <?php 
    }
    //diff view
    echo html_insert_softbreaks($diffformatter->format($diff));
    ?>

    </table>
    </div>
<?php 
}
Example #19
0
 /**
  * Changes the status of a comment
  */
 function _changeStatus($new)
 {
     global $ID;
     // get discussion meta file name
     $file = metaFN($ID, '.comments');
     $data = unserialize(io_readFile($file, false));
     $old = $data['status'];
     if ($old == $new) {
         return true;
     }
     // save the comment metadata file
     $data['status'] = $new;
     io_saveFile($file, serialize($data));
     // look for ~~DISCUSSION~~ command in page file and change it accordingly
     $patterns = array('~~DISCUSSION:off\\2~~', '~~DISCUSSION\\2~~', '~~DISCUSSION:closed\\2~~');
     $replace = $patterns[$new];
     $wiki = preg_replace('/~~DISCUSSION([\\w:]*)(\\|?.*?)~~/', $replace, rawWiki($ID));
     saveWikiText($ID, $wiki, $this->getLang('statuschanged'), true);
     return true;
 }
Example #20
0
/**
 * Sends a notify mail on page change or registration
 *
 * @param string     $id       The changed page
 * @param string     $who      Who to notify (admin|subscribers|register)
 * @param int|string $rev Old page revision
 * @param string     $summary  What changed
 * @param boolean    $minor    Is this a minor edit?
 * @param array      $replace  Additional string substitutions, @KEY@ to be replaced by value
 *
 * @return bool
 * @author Andreas Gohr <*****@*****.**>
 */
function notify($id, $who, $rev = '', $summary = '', $minor = false, $replace = array())
{
    global $lang;
    global $conf;
    global $INFO;
    global $DIFF_INLINESTYLES;
    // decide if there is something to do, eg. whom to mail
    if ($who == 'admin') {
        if (empty($conf['notify'])) {
            return false;
        }
        //notify enabled?
        $text = rawLocale('mailtext');
        $to = $conf['notify'];
        $bcc = '';
    } elseif ($who == 'subscribers') {
        if (!$conf['subscribers']) {
            return false;
        }
        //subscribers enabled?
        if ($conf['useacl'] && $_SERVER['REMOTE_USER'] && $minor) {
            return false;
        }
        //skip minors
        $data = array('id' => $id, 'addresslist' => '', 'self' => false);
        trigger_event('COMMON_NOTIFY_ADDRESSLIST', $data, 'subscription_addresslist');
        $bcc = $data['addresslist'];
        if (empty($bcc)) {
            return false;
        }
        $to = '';
        $text = rawLocale('subscr_single');
    } elseif ($who == 'register') {
        if (empty($conf['registernotify'])) {
            return false;
        }
        $text = rawLocale('registermail');
        $to = $conf['registernotify'];
        $bcc = '';
    } else {
        return false;
        //just to be safe
    }
    // prepare replacements (keys not set in hrep will be taken from trep)
    $trep = array('NEWPAGE' => wl($id, '', true, '&'), 'PAGE' => $id, 'SUMMARY' => $summary);
    $trep = array_merge($trep, $replace);
    $hrep = array();
    // prepare content
    if ($who == 'register') {
        $subject = $lang['mail_new_user'] . ' ' . $summary;
    } elseif ($rev) {
        $subject = $lang['mail_changed'] . ' ' . $id;
        $trep['OLDPAGE'] = wl($id, "rev={$rev}", true, '&');
        $df = new Diff(explode("\n", rawWiki($id, $rev)), explode("\n", rawWiki($id)));
        $dformat = new UnifiedDiffFormatter();
        $tdiff = $dformat->format($df);
        $DIFF_INLINESTYLES = true;
        $dformat = new InlineDiffFormatter();
        $hdiff = $dformat->format($df);
        $hdiff = '<table>' . $hdiff . '</table>';
        $DIFF_INLINESTYLES = false;
    } else {
        $subject = $lang['mail_newpage'] . ' ' . $id;
        $trep['OLDPAGE'] = '---';
        $tdiff = rawWiki($id);
        $hdiff = nl2br(hsc($tdiff));
    }
    $trep['DIFF'] = $tdiff;
    $hrep['DIFF'] = $hdiff;
    // send mail
    $mail = new Mailer();
    $mail->to($to);
    $mail->bcc($bcc);
    $mail->subject($subject);
    $mail->setBody($text, $trep, $hrep);
    if ($who == 'subscribers') {
        $mail->setHeader('List-Unsubscribe', '<' . wl($id, array('do' => 'subscribe'), true, '&') . '>', false);
    }
    return $mail->send();
}
Example #21
0
/**
 * Sends a notify mail on page change
 *
 * @param  string  $id       The changed page
 * @param  string  $who      Who to notify (admin|subscribers)
 * @param  int     $rev      Old page revision
 * @param  string  $summary  What changed
 * @param  boolean $minor    Is this a minor edit?
 * @param  array   $replace  Additional string substitutions, @KEY@ to be replaced by value
 *
 * @author Andreas Gohr <*****@*****.**>
 */
function notify($id, $who, $rev = '', $summary = '', $minor = false, $replace = array())
{
    global $lang;
    global $conf;
    // decide if there is something to do
    if ($who == 'admin') {
        if (empty($conf['notify'])) {
            return;
        }
        //notify enabled?
        $text = rawLocale('mailtext');
        $to = $conf['notify'];
        $bcc = '';
    } elseif ($who == 'subscribers') {
        if (!$conf['subscribers']) {
            return;
        }
        //subscribers enabled?
        if ($conf['useacl'] && $_SERVER['REMOTE_USER'] && $minor) {
            return;
        }
        //skip minors
        $bcc = subscriber_addresslist($id);
        if (empty($bcc)) {
            return;
        }
        $to = '';
        $text = rawLocale('subscribermail');
    } elseif ($who == 'register') {
        if (empty($conf['registernotify'])) {
            return;
        }
        $text = rawLocale('registermail');
        $to = $conf['registernotify'];
        $bcc = '';
    } else {
        return;
        //just to be safe
    }
    $text = str_replace('@DATE@', date($conf['dformat']), $text);
    $text = str_replace('@BROWSER@', $_SERVER['HTTP_USER_AGENT'], $text);
    $text = str_replace('@IPADDRESS@', $_SERVER['REMOTE_ADDR'], $text);
    $text = str_replace('@HOSTNAME@', gethostbyaddr($_SERVER['REMOTE_ADDR']), $text);
    $text = str_replace('@NEWPAGE@', wl($id, '', true), $text);
    $text = str_replace('@PAGE@', $id, $text);
    $text = str_replace('@TITLE@', $conf['title'], $text);
    $text = str_replace('@DOKUWIKIURL@', DOKU_URL, $text);
    $text = str_replace('@SUMMARY@', $summary, $text);
    $text = str_replace('@USER@', $_SERVER['REMOTE_USER'], $text);
    foreach ($replace as $key => $substitution) {
        $text = str_replace('@' . strtoupper($key) . '@', $substitution, $text);
    }
    if ($who == 'register') {
        $subject = $lang['mail_new_user'] . ' ' . $summary;
    } elseif ($rev) {
        $subject = $lang['mail_changed'] . ' ' . $id;
        $text = str_replace('@OLDPAGE@', wl($id, "rev={$rev}", true), $text);
        require_once DOKU_INC . 'inc/DifferenceEngine.php';
        $df = new Diff(split("\n", rawWiki($id, $rev)), split("\n", rawWiki($id)));
        $dformat = new UnifiedDiffFormatter();
        $diff = $dformat->format($df);
    } else {
        $subject = $lang['mail_newpage'] . ' ' . $id;
        $text = str_replace('@OLDPAGE@', 'none', $text);
        $diff = rawWiki($id);
    }
    $text = str_replace('@DIFF@', $diff, $text);
    $subject = '[' . $conf['title'] . '] ' . $subject;
    mail_send($to, $subject, $text, $conf['mailfrom'], '', $bcc);
}
Example #22
0
/**
 * show diff
 *
 * @author Andreas Gohr <*****@*****.**>
 * @param  string $text - compare with this text with most current version
 * @param  bool   $intr - display the intro text
 */
function html_diff($text = '', $intro = true, $type = null)
{
    global $ID;
    global $REV;
    global $lang;
    global $conf;
    if (!$type) {
        $type = $_REQUEST['difftype'];
    }
    if ($type != 'inline') {
        $type = 'sidebyside';
    }
    // we're trying to be clever here, revisions to compare can be either
    // given as rev and rev2 parameters, with rev2 being optional. Or in an
    // array in rev2.
    $rev1 = $REV;
    if (is_array($_REQUEST['rev2'])) {
        $rev1 = (int) $_REQUEST['rev2'][0];
        $rev2 = (int) $_REQUEST['rev2'][1];
        if (!$rev1) {
            $rev1 = $rev2;
            unset($rev2);
        }
    } else {
        $rev2 = (int) $_REQUEST['rev2'];
    }
    $r_minor = '';
    $l_minor = '';
    if ($text) {
        // compare text to the most current revision
        $l_rev = '';
        $l_text = rawWiki($ID, '');
        $l_head = '<a class="wikilink1" href="' . wl($ID) . '">' . $ID . ' ' . dformat((int) @filemtime(wikiFN($ID))) . '</a> ' . $lang['current'];
        $r_rev = '';
        $r_text = cleanText($text);
        $r_head = $lang['yours'];
    } else {
        if ($rev1 && $rev2) {
            // two specific revisions wanted
            // make sure order is correct (older on the left)
            if ($rev1 < $rev2) {
                $l_rev = $rev1;
                $r_rev = $rev2;
            } else {
                $l_rev = $rev2;
                $r_rev = $rev1;
            }
        } elseif ($rev1) {
            // single revision given, compare to current
            $r_rev = '';
            $l_rev = $rev1;
        } else {
            // no revision was given, compare previous to current
            $r_rev = '';
            $revs = getRevisions($ID, 0, 1);
            $l_rev = $revs[0];
            $REV = $l_rev;
            // store revision back in $REV
        }
        // when both revisions are empty then the page was created just now
        if (!$l_rev && !$r_rev) {
            $l_text = '';
        } else {
            $l_text = rawWiki($ID, $l_rev);
        }
        $r_text = rawWiki($ID, $r_rev);
        list($l_head, $r_head, $l_minor, $r_minor) = html_diff_head($l_rev, $r_rev);
    }
    $df = new Diff(explode("\n", htmlspecialchars($l_text)), explode("\n", htmlspecialchars($r_text)));
    if ($type == 'inline') {
        $tdf = new InlineDiffFormatter();
    } else {
        $tdf = new TableDiffFormatter();
    }
    if ($intro) {
        print p_locale_xhtml('diff');
    }
    if (!$text) {
        ptln('<div class="diffoptions">');
        $form = new Doku_Form(array('action' => wl()));
        $form->addHidden('id', $ID);
        $form->addHidden('rev2[0]', $l_rev);
        $form->addHidden('rev2[1]', $r_rev);
        $form->addHidden('do', 'diff');
        $form->addElement(form_makeListboxField('difftype', array('sidebyside' => $lang['diff_side'], 'inline' => $lang['diff_inline']), $type, $lang['diff_type'], '', '', array('class' => 'quickselect')));
        $form->addElement(form_makeButton('submit', 'diff', 'Go'));
        $form->printForm();
        $diffurl = wl($ID, array('do' => 'diff', 'rev2[0]' => $l_rev, 'rev2[1]' => $r_rev, 'difftype' => $type));
        ptln('<p><a class="wikilink1" href="' . $diffurl . '">' . $lang['difflink'] . '</a></p>');
        ptln('</div>');
    }
    ?>
    <table class="diff diff_<?php 
    echo $type;
    ?>
">
    <tr>
    <th colspan="2" <?php 
    echo $l_minor;
    ?>
>
    <?php 
    echo $l_head;
    ?>
    </th>
    <th colspan="2" <?php 
    echo $r_minor;
    ?>
>
    <?php 
    echo $r_head;
    ?>
    </th>
    </tr>
    <?php 
    echo $tdf->format($df);
    ?>
    </table>
    <?php 
}
Example #23
0
/**
 * Creates a snippet extract
 *
 * @author Andreas Gohr <*****@*****.**>
 * @triggers FULLTEXT_SNIPPET_CREATE
 */
function ft_snippet($id, $highlight)
{
    $text = rawWiki($id);
    $text = str_replace("­", '', $text);
    // remove soft-hyphens
    $evdata = array('id' => $id, 'text' => &$text, 'highlight' => &$highlight, 'snippet' => '');
    $evt = new Doku_Event('FULLTEXT_SNIPPET_CREATE', $evdata);
    if ($evt->advise_before()) {
        $match = array();
        $snippets = array();
        $utf8_offset = $offset = $end = 0;
        $len = utf8_strlen($text);
        // build a regexp from the phrases to highlight
        $re1 = '(' . join('|', array_map('ft_snippet_re_preprocess', array_map('preg_quote_cb', array_filter((array) $highlight)))) . ')';
        $re2 = "{$re1}.{0,75}(?!\\1){$re1}";
        $re3 = "{$re1}.{0,45}(?!\\1){$re1}.{0,45}(?!\\1)(?!\\2){$re1}";
        for ($cnt = 4; $cnt--;) {
            if (0) {
            } else {
                if (preg_match('/' . $re3 . '/iu', $text, $match, PREG_OFFSET_CAPTURE, $offset)) {
                } else {
                    if (preg_match('/' . $re2 . '/iu', $text, $match, PREG_OFFSET_CAPTURE, $offset)) {
                    } else {
                        if (preg_match('/' . $re1 . '/iu', $text, $match, PREG_OFFSET_CAPTURE, $offset)) {
                        } else {
                            break;
                        }
                    }
                }
            }
            list($str, $idx) = $match[0];
            // convert $idx (a byte offset) into a utf8 character offset
            $utf8_idx = utf8_strlen(substr($text, 0, $idx));
            $utf8_len = utf8_strlen($str);
            // establish context, 100 bytes surrounding the match string
            // first look to see if we can go 100 either side,
            // then drop to 50 adding any excess if the other side can't go to 50,
            $pre = min($utf8_idx - $utf8_offset, 100);
            $post = min($len - $utf8_idx - $utf8_len, 100);
            if ($pre > 50 && $post > 50) {
                $pre = $post = 50;
            } else {
                if ($pre > 50) {
                    $pre = min($pre, 100 - $post);
                } else {
                    if ($post > 50) {
                        $post = min($post, 100 - $pre);
                    } else {
                        // both are less than 50, means the context is the whole string
                        // make it so and break out of this loop - there is no need for the
                        // complex snippet calculations
                        $snippets = array($text);
                        break;
                    }
                }
            }
            // establish context start and end points, try to append to previous
            // context if possible
            $start = $utf8_idx - $pre;
            $append = $start < $end ? $end : false;
            // still the end of the previous context snippet
            $end = $utf8_idx + $utf8_len + $post;
            // now set it to the end of this context
            if ($append) {
                $snippets[count($snippets) - 1] .= utf8_substr($text, $append, $end - $append);
            } else {
                $snippets[] = utf8_substr($text, $start, $end - $start);
            }
            // set $offset for next match attempt
            //   substract strlen to avoid splitting a potential search success,
            //   this is an approximation as the search pattern may match strings
            //   of varying length and it will fail if the context snippet
            //   boundary breaks a matching string longer than the current match
            $utf8_offset = $utf8_idx + $post;
            $offset = $idx + strlen(utf8_substr($text, $utf8_idx, $post));
            $offset = utf8_correctIdx($text, $offset);
        }
        $m = "";
        $snippets = preg_replace('/' . $re1 . '/iu', $m . '$1' . $m, $snippets);
        $snippet = preg_replace('/' . $m . '([^' . $m . ']*?)' . $m . '/iu', '<strong class="search_hit">$1</strong>', hsc(join('... ', $snippets)));
        $evdata['snippet'] = $snippet;
    }
    $evt->advise_after();
    unset($evt);
    return $evdata['snippet'];
}
Example #24
0
 private function _load_existing_frames()
 {
     global $ID;
     //load source
     $source = preg_replace('/(?:[\\r\\n]*)(\\{\\{[^\\}]*\\}\\})(?:[\\r\\n]*)/', '<!-- Frame -->$1<!-- Image -->', rawWiki($ID));
     $source = trim($source . '');
     $source = preg_replace('/(?:[\\r\\n]+)(\\/\\/[^\\/]*\\/\\/)/', '<!-- Reference -->$1', $source);
     list($source, $reference) = explode('<!-- Reference -->', $source);
     $frames = explode('<!-- Frame -->', $source);
     unset($source);
     //set data
     $this->title = preg_replace('/^(?:\\s*======\\s*)?(.*?)(?:\\s*======\\s*)?$/', '$1', array_shift($frames));
     $this->reference = preg_replace('/^(?:\\s*\\/\\/\\s*)?(.*?)(?:\\s*\\/\\/\\s*)?$/', '$1', $reference);
     unset($reference);
     $frame_keys = array();
     for ($i = 1; $i <= count($frames); $i++) {
         array_push($frame_keys, str_pad($i, 2, '0', STR_PAD_LEFT));
     }
     unset($i);
     $this->frames = array_combine($frame_keys, $frames);
     unset($frames, $frame_keys);
 }
Example #25
0
/**
 * Just lists all documents
 *
 * $opts['depth']   recursion level, 0 for all
 * $opts['hash']    do md5 sum of content?
 * $opts['skipacl'] list everything regardless of ACL
 *
 * @author  Andreas Gohr <*****@*****.**>
 */
function search_allpages(&$data, $base, $file, $type, $lvl, $opts)
{
    //we do nothing with directories
    if ($type == 'd') {
        if (!$opts['depth']) {
            return true;
        }
        // recurse forever
        $parts = explode('/', ltrim($file, '/'));
        if (count($parts) == $opts['depth']) {
            return false;
        }
        // depth reached
        return true;
    }
    //only search txt files
    if (substr($file, -4) != '.txt') {
        return true;
    }
    $item['id'] = pathID($file);
    if (!$opts['skipacl'] && auth_quickaclcheck($item['id']) < AUTH_READ) {
        return false;
    }
    $item['rev'] = filemtime($base . '/' . $file);
    $item['mtime'] = $item['rev'];
    $item['size'] = filesize($base . '/' . $file);
    if ($opts['hash']) {
        $item['hash'] = md5(trim(rawWiki($item['id'])));
    }
    $data[] = $item;
    return true;
}
Example #26
0
/**
 * Send a digest mail
 *
 * Sends a digest mail showing a bunch of changes.
 *
 * @param string $subscriber_mail The target mail address
 * @param array  $id              The ID
 * @param int    $lastupdate      Time of the last notification
 *
 * @author Adrian Lang <*****@*****.**>
 */
function subscription_send_digest($subscriber_mail, $id, $lastupdate)
{
    $n = 0;
    do {
        $rev = getRevisions($id, $n++, 1);
        $rev = count($rev) > 0 ? $rev[0] : null;
    } while (!is_null($rev) && $rev > $lastupdate);
    $replaces = array('NEWPAGE' => wl($id, '', true, '&'), 'SUBSCRIBE' => wl($id, array('do' => 'subscribe'), true, '&'));
    if (!is_null($rev)) {
        $subject = 'changed';
        $replaces['OLDPAGE'] = wl($id, "rev={$rev}", true, '&');
        $df = new Diff(explode("\n", rawWiki($id, $rev)), explode("\n", rawWiki($id)));
        $dformat = new UnifiedDiffFormatter();
        $replaces['DIFF'] = $dformat->format($df);
    } else {
        $subject = 'newpage';
        $replaces['OLDPAGE'] = 'none';
        $replaces['DIFF'] = rawWiki($id);
    }
    subscription_send($subscriber_mail, $replaces, $subject, $id, 'subscr_digest');
}
 function p_render_latex($id, &$info)
 {
     $info['current_id'] = $id;
     $filename = wikiFN($id);
     if (!file_exists($filename)) {
         msg("{$filename}: Not exists", -1);
     }
     if (!is_readable($filename)) {
         msg("{$filename}: Can't read", -1);
     }
     $text = rawWiki($id);
     $parsed = $this->p_render_latex_text($text, $info);
     return $parsed;
 }
Example #28
0
/**
 * moves the current version to the attic and returns its
 * revision date
 *
 * @author Andreas Gohr <*****@*****.**>
 *
 * @param string $id page id
 * @return int|string revision timestamp
 */
function saveOldRevision($id)
{
    $oldf = wikiFN($id);
    if (!file_exists($oldf)) {
        return '';
    }
    $date = filemtime($oldf);
    $newf = wikiFN($id, $date);
    io_writeWikiPage($newf, rawWiki($id), $id, $date);
    return $date;
}
/**
 * Adds/updates the search index for the given page
 *
 * Locking is handled internally.
 *
 * @param string        $page   name of the page to index
 * @param boolean       $verbose    print status messages
 * @param boolean       $force  force reindexing even when the index is up to date
 * @return boolean              the function completed successfully
 * @author Tom N Harris <*****@*****.**>
 */
function enhanced_idx_addPage($page, $verbose = false, $force = false)
{
    $idxtag = metaFN($page, '.indexed');
    // check if page was deleted but is still in the index
    if (!page_exists($page)) {
        if (!@file_exists($idxtag)) {
            if ($verbose) {
                print "Indexer: {$page} does not exist, ignoring" . DOKU_LF;
            }
            return false;
        }
        $Indexer = enhanced_idx_get_indexer();
        $result = $Indexer->deletePage($page);
        if ($result === "locked") {
            if ($verbose) {
                print "Indexer: locked" . DOKU_LF;
            }
            return false;
        }
        @unlink($idxtag);
        return $result;
    }
    // check if indexing needed
    if (!$force && @file_exists($idxtag)) {
        if (trim(io_readFile($idxtag)) == idx_get_version()) {
            $last = @filemtime($idxtag);
            if ($last > @filemtime(wikiFN($page))) {
                if ($verbose) {
                    print "Indexer: index for {$page} up to date" . DOKU_LF;
                }
                return false;
            }
        }
    }
    $indexenabled = p_get_metadata($page, 'internal index', METADATA_RENDER_UNLIMITED);
    if ($indexenabled === false) {
        $result = false;
        if (@file_exists($idxtag)) {
            $Indexer = enhanced_idx_get_indexer();
            $result = $Indexer->deletePage($page);
            if ($result === "locked") {
                if ($verbose) {
                    print "Indexer: locked" . DOKU_LF;
                }
                return false;
            }
            @unlink($idxtag);
        }
        if ($verbose) {
            print "Indexer: index disabled for {$page}" . DOKU_LF;
        }
        return $result;
    }
    $Indexer = enhanced_idx_get_indexer();
    $pid = $Indexer->getPID($page);
    if ($pid === false) {
        if ($verbose) {
            print "Indexer: getting the PID failed for {$page}" . DOKU_LF;
        }
        return false;
    }
    $body = '';
    $metadata = array();
    $metadata['title'] = p_get_metadata($page, 'title', METADATA_RENDER_UNLIMITED);
    if (($references = p_get_metadata($page, 'relation references', METADATA_RENDER_UNLIMITED)) !== null) {
        $metadata['relation_references'] = array_keys($references);
    } else {
        $metadata['relation_references'] = array();
    }
    if (($media = p_get_metadata($page, 'relation media', METADATA_RENDER_UNLIMITED)) !== null) {
        $metadata['relation_media'] = array_keys($media);
    } else {
        $metadata['relation_media'] = array();
    }
    $data = compact('page', 'body', 'metadata', 'pid');
    $evt = new Doku_Event('INDEXER_PAGE_ADD', $data);
    if ($evt->advise_before()) {
        $data['body'] = $data['body'] . " " . rawWiki($page);
    }
    $evt->advise_after();
    unset($evt);
    extract($data);
    $result = $Indexer->addPageWords($page, $body);
    if ($result === "locked") {
        if ($verbose) {
            print "Indexer: locked" . DOKU_LF;
        }
        return false;
    }
    if ($result) {
        $result = $Indexer->addMetaKeys($page, $metadata);
        if ($result === "locked") {
            if ($verbose) {
                print "Indexer: locked" . DOKU_LF;
            }
            return false;
        }
    }
    if ($result) {
        io_saveFile(metaFN($page, '.indexed'), idx_get_version());
    }
    if ($verbose) {
        print "Indexer: finished" . DOKU_LF;
        return true;
    }
    return $result;
}
Example #30
0
/**
 * Add recent changed pages to a feed object
 *
 * @author Andreas Gohr <*****@*****.**>
 * @param  object $rss - the FeedCreator Object
 * @param  array $data - the items to add
 * @param  array $opt  - the feed options
 */
function rss_buildItems(&$rss, &$data, $opt)
{
    global $conf;
    global $lang;
    global $auth;
    $eventData = array('rss' => &$rss, 'data' => &$data, 'opt' => &$opt);
    $event = new Doku_Event('FEED_DATA_PROCESS', $eventData);
    if ($event->advise_before(false)) {
        foreach ($data as $ditem) {
            if (!is_array($ditem)) {
                // not an array? then only a list of IDs was given
                $ditem = array('id' => $ditem);
            }
            $item = new FeedItem();
            $id = $ditem['id'];
            $meta = p_get_metadata($id);
            // add date
            if ($ditem['date']) {
                $date = $ditem['date'];
            } elseif ($meta['date']['modified']) {
                $date = $meta['date']['modified'];
            } else {
                $date = @filemtime(wikiFN($id));
            }
            if ($date) {
                $item->date = date('r', $date);
            }
            // add title
            if ($conf['useheading'] && $meta['title']) {
                $item->title = $meta['title'];
            } else {
                $item->title = $ditem['id'];
            }
            if ($conf['rss_show_summary'] && !empty($ditem['sum'])) {
                $item->title .= ' - ' . strip_tags($ditem['sum']);
            }
            // add item link
            switch ($opt['link_to']) {
                case 'page':
                    $item->link = wl($id, 'rev=' . $date, true, '&');
                    break;
                case 'rev':
                    $item->link = wl($id, 'do=revisions&rev=' . $date, true, '&');
                    break;
                case 'current':
                    $item->link = wl($id, '', true, '&');
                    break;
                case 'diff':
                default:
                    $item->link = wl($id, 'rev=' . $date . '&do=diff', true, '&');
            }
            // add item content
            switch ($opt['item_content']) {
                case 'diff':
                case 'htmldiff':
                    require_once DOKU_INC . 'inc/DifferenceEngine.php';
                    $revs = getRevisions($id, 0, 1);
                    $rev = $revs[0];
                    if ($rev) {
                        $df = new Diff(explode("\n", htmlspecialchars(rawWiki($id, $rev))), explode("\n", htmlspecialchars(rawWiki($id, ''))));
                    } else {
                        $df = new Diff(array(''), explode("\n", htmlspecialchars(rawWiki($id, ''))));
                    }
                    if ($opt['item_content'] == 'htmldiff') {
                        $tdf = new TableDiffFormatter();
                        $content = '<table>';
                        $content .= '<tr><th colspan="2" width="50%">' . $rev . '</th>';
                        $content .= '<th colspan="2" width="50%">' . $lang['current'] . '</th></tr>';
                        $content .= $tdf->format($df);
                        $content .= '</table>';
                    } else {
                        $udf = new UnifiedDiffFormatter();
                        $content = "<pre>\n" . $udf->format($df) . "\n</pre>";
                    }
                    break;
                case 'html':
                    $content = p_wiki_xhtml($id, $date, false);
                    // no TOC in feeds
                    $content = preg_replace('/(<!-- TOC START -->).*(<!-- TOC END -->)/s', '', $content);
                    // make URLs work when canonical is not set, regexp instead of rerendering!
                    if (!$conf['canonical']) {
                        $base = preg_quote(DOKU_REL, '/');
                        $content = preg_replace('/(<a href|<img src)="(' . $base . ')/s', '$1="' . DOKU_URL, $content);
                    }
                    break;
                case 'abstract':
                default:
                    $content = $meta['description']['abstract'];
            }
            $item->description = $content;
            //FIXME a plugin hook here could be senseful
            // add user
            # FIXME should the user be pulled from metadata as well?
            $user = null;
            $user = @$ditem['user'];
            // the @ spares time repeating lookup
            $item->author = '';
            if ($user && $conf['useacl'] && $auth) {
                $userInfo = $auth->getUserData($user);
                $item->author = $userInfo['name'];
                if ($userInfo && !$opt['guardmail']) {
                    $item->authorEmail = $userInfo['mail'];
                } else {
                    //cannot obfuscate because some RSS readers may check validity
                    $item->authorEmail = $user . '@' . $ditem['ip'];
                }
            } elseif ($user) {
                // this happens when no ACL but some Apache auth is used
                $item->author = $user;
                $item->authorEmail = $user . '@' . $ditem['ip'];
            } else {
                $item->authorEmail = 'anonymous@' . $ditem['ip'];
            }
            // add category
            if ($meta['subject']) {
                $item->category = $meta['subject'];
            } else {
                $cat = getNS($id);
                if ($cat) {
                    $item->category = $cat;
                }
            }
            // finally add the item to the feed object, after handing it to registered plugins
            $evdata = array('item' => &$item, 'opt' => &$opt, 'ditem' => &$ditem, 'rss' => &$rss);
            $evt = new Doku_Event('FEED_ITEM_ADD', $evdata);
            if ($evt->advise_before()) {
                $rss->addItem($item);
            }
            $evt->advise_after();
            // for completeness
        }
    }
    $event->advise_after();
}