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; } } }
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); } }
/** * 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; } }
/** * 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')); }
/** * 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'])); } }
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')); }
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; }
/** * 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); }
/** * 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 }
/** * 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; }
/** * 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(); }
/** * 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); }
/** * 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 }
/** * 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']; }
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); }
/** * 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; }
/** * 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; }
/** * 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; }
/** * 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(); }