*/ // must be run within Dokuwiki if(!defined('DOKU_INC')) die(); class admin_plugin_linkfix extends DokuWiki_Admin_Plugin { protected $searchin = ''; protected $changefrom = ''; protected $changeto = ''; protected $qchangefrom = ''; protected $dryrun = false; protected $type = 'links'; protected $isextern = false; public function getMenuSort() { return 3000; } public function handle() { global $INPUT; $this->searchin = cleanID($INPUT->str('searchin')); $this->changefrom = $INPUT->str('changefrom'); $this->changeto = $INPUT->str('changeto'); $this->type = $INPUT->valid('type', array('links', 'media'), 'links'); $this->dryrun = $INPUT->bool('dryrun'); $this->isextern = preg_match('/^(\w+:\/\/|\\\\)/i', $this->changefrom); } public function html() { global $ID; global $INPUT; if($INPUT->has('go') && checkSecurityToken()) { echo '

' . $this->getLang('processing') . '

'; tpl_flush(); ignore_user_abort(true); set_time_limit(0); if($this->execute()) { echo '

'.$this->getLang('processingdone').'

'; if($this->dryrun) { echo ''.$this->getLang('rerunhot').''; } tpl_flush(); } } else { echo $this->locale_xhtml('intro'); $form = new Doku_Form(array('action' => wl(), 'class' => 'plugin_linkfix')); $form->addHidden('go', 'go'); $form->addHidden('page', 'linkfix'); $form->addHidden('id', $ID); $form->startFieldset($this->getLang('menu')); $form->addElement(form_makeTextField('searchin', '', $this->getLang('searchin'), '', 'block')); $form->addElement(form_makeTextField('changefrom', '', $this->getLang('changefrom'), '', 'block')); $form->addElement(form_makeTextField('changeto', '', $this->getLang('changeto'), '', 'block')); $form->addElement(form_makeRadioField('type', 'links', $this->getLang('links'), '', 'block tick', array('checked' => 'checked'))); $form->addElement(form_makeRadioField('type', 'media', $this->getLang('media'), '', 'block tick')); $form->addElement(form_makeCheckboxField('dryrun', '1', $this->getLang('dryrun'), '', 'block tick', array('checked' => 'checked'))); $form->addElement(form_makeButton('submit', 'admin', $this->getLang('submit'))); $form->printForm(); } } /** * Search for all pages in the set namespace and update them * * @returns bool false if no correct namespace was given */ protected function execute() { global $conf; // make sure the given search namespace exists $searchin = str_replace(':', '/', $this->searchin); if(!is_dir($conf['datadir'] . '/' . $searchin)) { msg(sprintf($this->getLang('badnamespace'), hsc($this->searchin)), -1); return false; } // use indexer to find all possibly affected pages if($this->isextern) { $null = ''; $data = ft_pageSearch('"' . $this->changefrom . '"*', $null); $data = array_keys($data); } elseif($this->type == 'media') { $query = $this->changefrom . '*'; $data = idx_get_indexer()->lookupKey('relation_media', $query); } else { $query = $this->changefrom . '*'; $data = idx_get_indexer()->lookupKey('relation_references', $query); } $data = array_unique($data); $len = strlen($this->searchin); foreach($data as $id) { // skip everything that's not in the wanted namespace if($len && substr($id, 0, $len + 1) != $this->searchin . ':') continue; // skip non existing pages if(!page_exists($id)) continue; $this->prnt(''); } return true; } /** * Rewrite all links and media items in the given page * * @param string $currentpage the page to rewrite */ protected function updatepage($currentpage) { $currentns = getNS($currentpage); $text = rawWiki($currentpage); $crc = md5($text); $instructions = p_get_instructions($text); $instructions = array_reverse($instructions); $this->prnt('
  • '); $this->prnt($this->getLang('checking') . ' ' . hsc($currentpage) . "
    "); tpl_flush(); $this->prnt(''); if($crc == md5($text)) { $this->prnt('✗ '.$this->getLang('fail').'
    '); } else { if($this->dryrun) { $this->prnt('✓ '.$this->getLang('successdry').'
    '); } else { saveWikiText($currentpage, $text, $this->getLang('summary'), true); $this->prnt('✓ '.$this->getLang('success').'
    '); } } $this->prnt('
  • '); tpl_flush(); } /** * Wrapper around echo, for better testability * * @param $string */ protected function prnt($string) { echo $string; } /** * Rewrite the given link according to the given settings * * @param string $link the current link as found in the page source * @param string $full the full, resolved version of the above link * @param string $currentNS the namespace of the page the link was found in * @return string the corrected link */ protected function changeLink($link, $full, $currentNS) { // make sure the prefix matches (caseinsensitive) if($this->changefrom){ if(!$this->qchangefrom) { $this->qchangefrom = preg_quote($this->qchangefrom, '/'); } if(!preg_match('/^'.$this->qchangefrom.'/ui', $full)) return $link; } // strip prefix $new = substr($full, strlen($this->changefrom)); // add prefix $new = $this->changeto . $new; if(!$this->isextern) { // strip left over colons $new = ltrim($new, ':'); // make absolute if needed if($currentNS && strpos($new, ':') === false) $new = ":$new"; } return $new; } } // vim:ts=4:sw=4:et: