*/ class admin_plugin_linkback extends DokuWiki_Admin_Plugin { function getMenuSort(){ return 201; } function forAdminOnly(){ return false; } function handle(){ global $lang; $lid = $_REQUEST['lid']; if (is_array($lid)) $lid = array_keys($lid); /** @var action_plugin_linkback_display $action */ $action = plugin_load('action', 'linkback_display'); if (!$action) return; // couldn't load action plugin component switch ($_REQUEST['linkback']){ case $lang['btn_delete']: $action->_deleteLinkbacks($lid); break; case $this->getLang('btn_show'): $action->_changeLinkbackVisibilities($lid, true); break; case $this->getLang('btn_hide'): $action->_changeLinkbackVisibilities($lid, false); break; case $this->getLang('btn_ham'): $action->_markLinkbacks($lid, false); break; case $this->getLang('btn_spam'): $action->_markLinkbacks($lid, true); break; case $this->getLang('btn_change'): $this->_changeStatus($_REQUEST['status']); break; } } function html(){ global $conf; $first = $_REQUEST['first']; if (!is_numeric($first)) $first = 0; $num = $conf['recent']; ptln('

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

'); $targets = $this->_getTargets(); // slice the needed chunk of linkback targets $more = count($targets) > ($first + $num); $targets = array_slice($targets, $first, $num); foreach ($targets as $target){ $linkbacks = $this->_getLinkbacks($target); $this->_targetHead($target); if ($linkbacks === false){ ptln('', 6); // class="level2" continue; } ptln('
', 8); ptln('
', 10); ptln('', 10); ptln('', 10); echo html_buildlist($linkbacks, 'admin_linkback', array($this, '_linkbackItem'), array($this, '_li_linkback')); $this->_actionButtons($target['id']); } $this->_browseLinkbackLinks($more, $first, $num); if(count($targets) === 0) { echo 'No linkback targets'; } } /** * Returns an array of targets with linkback features, sorted by recent linkbacks */ function _getTargets(){ global $conf; // returns the list of pages in the given namespace and it's subspaces $items = array(); search($items, $conf['datadir'], 'search_allpages', array()); // add pages with comments to result $result = array(); foreach ($items as $item){ $id = $item['id']; // some checks $file = metaFN($id, '.linkbacks'); if (!@file_exists($file)) continue; // skip if no comments file $date = filemtime($file); $result[] = array( 'id' => $id, 'file' => $file, 'date' => $date, ); } // finally sort by time of last comment usort($result, array('admin_plugin_linkback', '_targetCmp')); return $result; } /** * Callback for comparison of target data. * * Used for sorting targets in descending order by date of last linkback. * If this date happens to be equal for the compared targest, page id * is used as second comparison attribute. */ function _targetCmp($a, $b) { if ($a['date'] == $b['date']) { return strcmp($a['id'], $b['id']); } return ($a['date'] < $b['date']) ? 1 : -1; } /** * Outputs header, page ID and status of linkbacks */ function _targetHead($target){ $id = $target['id']; $labels = array( 'send' => $this->getLang('send'), 'receive' => $this->getLang('receive'), 'display' => $this->getLang('display') ); $title = p_get_metadata($id, 'title'); if (!$title) $title = $id; ptln('

'.hsc($title).'

', 6); ptln('', 6); ptln('
', 8); ptln('', 10); ptln('', 10); ptln($this->getLang('status').': ', 10); foreach ($labels as $key => $label){ $selected = (($target[$key]) ? ' checked="checked"' : ''); ptln('   ', 12); } ptln('', 10); ptln('
', 8); ptln('', 6); ptln('
', 6); ptln(''.$id.' ', 8); return true; } /** * Returns the full comments data for a given wiki page */ function _getLinkbacks(&$target){ $id = $target['id']; if (!$target['file']) $target['file'] = metaFN($id, '.linkbacks'); if (!@file_exists($target['file'])) return false; // no discussion thread at all $data = unserialize(io_readFile($target['file'], false)); $target['send'] = $data['send']; $target['receive'] = $data['receive']; $target['display'] = $data['display']; $target['number'] = $data['number']; if (!$data['display']) return false; // comments are turned off if (!$data['receivedpings']) return false; // no comments $result = array(); foreach($data['receivedpings'] as $lid => $linkback) { $linkback['level'] = 1; $result[$lid] = $linkback; } if (empty($result)) return false; else return $result; } /** * Checkbox and info about a linkback item */ function _linkbackItem($linkback){ global $conf; // prepare variables $title = $linkback['title']; $url = $linkback['url']; $date = $linkback['received']; $excerpt = $linkback['excerpt']; $type = $linkback['type']; if (utf8_strlen($excerpt) > 160) $excerpt = utf8_substr($excerpt, 0, 160).'...'; return ' '. $this->external_link($url, $title).', '.strftime($conf['dformat'], $date).', ' . $this->getLang('linkback_type_' . $type) . ': '. ''.$excerpt.''; } /** * list item tag */ function _li_linkback($linkback){ if (!$linkback['show']) return '
  • '; } /** * Show buttons to bulk remove, hide or show comments */ function _actionButtons($id){ ptln('
    ', 12); ptln('', 14); ptln('', 14); ptln('', 14); ptln('', 14); ptln('', 14); ptln('
    ', 12); // class="comment_buttons" ptln('
  • ', 10); // class="no" ptln('', 8); ptln('
    ', 6); // class="level2" return true; } /** * Displays links to older newer discussions */ function _browseLinkbackLinks($more, $first, $num){ global $ID; if (($first == 0) && (!$more)) return true; $params = array('do' => 'admin', 'page' => 'linkback'); $last = $first+$num; ptln('
    ', 8); if ($first > 0){ $first -= $num; if ($first < 0) $first = 0; $params['first'] = $first; ptln('

    ', 8); $ret = '<< '.$this->getLang('newer').''; if ($more){ $ret .= ' | '; } else { ptln($ret, 10); ptln('

    ', 8); } } else if ($more){ ptln('

    ', 8); } if ($more){ $params['first'] = $last; $ret .= ''.$this->getLang('older').' >>'; ptln($ret, 10); ptln('

    ', 8); } ptln('
    ', 6); // class="level1" return true; } /** * Changes the status of a comment */ function _changeStatus($new){ global $ID; // get discussion meta file name $file = metaFN($ID, '.linkbacks'); $data = unserialize(io_readFile($file, false)); $updated = false; $updateText = false; foreach (array('send', 'receive', 'display') as $key) { if (!isset($new[$key])) $new[$key] = false; if ($new[$key] == $data[$key]) continue; $data[$key] = $new[$key]; $updated = true; if (in_array($key, array('send', 'receive'))) $updateText = true; } if (!$updated) return false; // save the comment metadata file io_saveFile($file, serialize($data)); if (!$updateText) return true; // look for ~~LINKBACK~~ command in page file and change it accordingly if ($data['receive'] && $data['display']) $replace = '~~LINKBACK~~'; else if (!$data['receive']) $replace = '~~LINKBACK:closed~~'; else $replace = '~~LINKBACK:off~~'; $wiki = preg_replace('/~~LINKBACK([\w:]*)~~/', $replace, rawWiki($ID)); saveWikiText($ID, $wiki, $this->getLang('statuschanged'), true); return true; } } //Setup VIM: ex: et ts=4 enc=utf-8 :