Skip to content

Commit

Permalink
Add linkback receive support
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianheine committed Jul 22, 2010
1 parent 3f5251f commit dfa32b5
Show file tree
Hide file tree
Showing 8 changed files with 404 additions and 0 deletions.
98 changes: 98 additions & 0 deletions action/linkback.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

/**
* Receive component of the DokuWiki Linkback action plugin.
*
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
* @author Gina Haeussge <osd@foosel.net>
* @link http://wiki.foosel.net/snippets/dokuwiki/linkback
*/

// must be run within Dokuwiki
if (!defined('DOKU_INC'))
die();

if (!defined('DOKU_PLUGIN'))
define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
require_once (DOKU_PLUGIN . 'action.php');

require_once (DOKU_INC . 'inc/common.php');
require_once (DOKU_INC . 'inc/template.php');

if (!defined('NL'))
define('NL', "\n");

class action_plugin_blogtng_linkback extends DokuWiki_Action_Plugin {
private $run = false;

/**
* Register the eventhandlers.
*/
function register(& $controller) {
$controller->register_hook('DOKUWIKI_STARTED', 'BEFORE', $this, 'check', array ());
$controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, 'handle_act_render', array ());
$controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handle_metaheader_output', array ());
$controller->register_hook('ACTION_HEADERS_SEND', 'BEFORE', $this, 'handle_headers_send', array ());
}

function check(&$event, $params) {
// Pingbacks disabled? Quit
if (!$this->getConf('receive_linkbacks'))
return;

$helper = plugin_load('helper', 'blogtng_linkback');
if (!$helper->isPost()) {
return;
}
$this->run = true;
}

/**
* Handler for the TPL_ACT_RENDER event
*/
function handle_act_render(& $event, $params) {
if (!$this->run) return;

// Action not 'show'? Quit
if ($event->data != 'show')
return;

// insert RDF definition of trackback into output
echo '<!--<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"' . NL .
'xmlns:dc="http://purl.org/dc/elements/1.1/"' . NL .
'xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">' . NL .
'<rdf:Description' . NL .
'rdf:about="' . wl($ID, '', true) . '"' . NL .
'dc:identifier="' . wl($ID, '', true) . '"' . NL .
'dc:title="' . tpl_pagetitle($ID, true) . '"' . NL .
'trackback:ping="' . DOKU_URL . 'lib/plugins/blogtng/exe/trackback.php/' . $ID . '" />' . NL .
'</rdf:RDF>-->';
}

/**
* Handler for the TPL_METAHEADER_OUTPUT event
*/
function handle_metaheader_output(& $event, $params) {
if (!$this->run) return;
global $ID;

// Add pingback metaheader
$event->data['link'][] = array (
'rel' => 'pingback',
'href' => DOKU_URL . 'lib/plugins/blogtng/exe/pingback.php/' . $ID
);
return true;
}

/**
* Handler for the ACTION_HEADERS_SEND event
*/
function handle_headers_send(& $event, $params) {
if (!$this->run) return;
global $ID;

// Add pingback header
$event->data[] = 'X-Pingback: ' . DOKU_URL . 'lib/plugins/blogtng/exe/pingback.php/' . $ID;
return true;
}
}
2 changes: 2 additions & 0 deletions conf/default.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@
$conf['comments_xhtml_renderer'] = '';
$conf['editform_set_date'] = 0;
$conf['tags'] = '';
$conf['receive_linkbacks'] = 1;
$conf['send_linkbacks'] = 0;
2 changes: 2 additions & 0 deletions conf/metadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@
);
$meta['editform_set_date'] = array('onoff');
$meta['tags'] = array('string');
$meta['receive_linkbacks'] = array('onoff');
$meta['send_linkbacks'] = array('onoff');
121 changes: 121 additions & 0 deletions exe/pingback.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<?php

/**
* Pingback server for use with the DokuWiki Linkback Plugin.
*
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
* @author Gina Haeussge <osd@foosel.net>
* @link http://wiki.foosel.net/snippets/dokuwiki/linkback
*/

if (!defined('DOKU_INC'))
define('DOKU_INC', realpath(dirname(__FILE__) . '/../../../../') . '/');

if (!defined('NL'))
define('NL', "\n");

require_once (DOKU_INC . 'inc/init.php');
require_once (DOKU_INC . 'inc/common.php');
require_once (DOKU_INC . 'inc/events.php');
require_once (DOKU_INC . 'inc/HTTPClient.php');
require_once (DOKU_INC . 'inc/IXR_Library.php');
require_once (DOKU_INC . 'inc/pluginutils.php');

// Pingback Faultcodes
define('PINGBACK_ERROR_GENERIC', 0);
define('PINGBACK_ERROR_SOURCEURI_DOES_NOT_EXIST', 16);
define('PINGBACK_ERROR_SOURCEURI_DOES_NOT_CONTAIN_LINK', 17);
define('PINGBACK_ERROR_TARGETURI_DOES_NOT_EXIST', 32);
define('PINGBACK_ERROR_TARGETURI_CANNOT_BE_USED', 33);
define('PINGBACK_ERROR_PINGBACK_ALREADY_MADE', 48);
define('PINGBACK_ERROR_ACCESS_DENIED', 49);
define('PINGBACK_ERROR_NO_UPSTREAM', 50);

class PingbackServer extends IXR_Server {

/**
* Register service and construct helper
*/
function PingbackServer() {
$this->tools =& plugin_load('helper', 'blogtng_linkback');
parent::__construct(array('pingback.ping' => 'this:ping'));
}

function ping($sourceUri, $targetUri) {
// Plugin not enabled? Quit
if (plugin_isdisabled('blogtng'))
return new IXR_Error(PINGBACK_ERROR_TARGETURI_CANNOT_BE_USED, '');

// pingback disabled? Quit
if (!$this->tools->getConf('receive_linkbacks'))
return new IXR_Error(PINGBACK_ERROR_TARGETURI_CANNOT_BE_USED, '');

// Given URLs are no urls? Quit
if (!preg_match("#^([a-z0-9\-\.+]+?)://.*#i", $sourceUri))
return new IXR_Error(PINGBACK_ERROR_GENERIC, '');
if (!preg_match("#^([a-z0-9\-\.+]+?)://.*#i", $targetUri))
return new IXR_Error(PINGBACK_ERROR_GENERIC, '');

// Source URL does not exist? Quit
$http = new DokuHTTPClient;
$page = $http->get($sourceUri);
if ($page === false)
return new IXR_Error(PINGBACK_ERROR_SOURCEURI_DOES_NOT_EXIST, '');

// Target URL does not match with request? Quit
$ID = substr($_SERVER['PATH_INFO'], 1);
if ($targetUri != wl($ID, '', true))
return new IXR_Error(PINGBACK_ERROR_GENERIC, '');

if (!$this->tools->isPost()) {
return new IXR_Error(PINGBACK_ERROR_TARGETURI_CANNOT_BE_USED, '');
}

// Retrieve data from source
$linkback = $this->_getTrackbackData($sourceUri, $targetUri, $page);

// Source URL does not contain link to target? Quit
if (!$linkback)
return new IXR_Error(PINGBACK_ERROR_SOURCEURI_DOES_NOT_CONTAIN_LINK, '');

if (!$this->tools->saveLinkback('pingback', $linkback['title'],
$sourceUri, $linkback['excerpt'], $ID)) {
return new IXR_Error(PINGBACK_ERROR_PINGBACK_ALREADY_MADE, '');
}
}

/**
* Constructs linkback data and checks if source contains a link to target and a title.
*/
function _getTrackbackData($sourceUri, $targetUri, $page) {
$linkback = array ();

$searchurl = preg_quote($targetUri, '!');
$regex = '!<a[^>]+?href="' . $searchurl . '"[^>]*?>(.*?)</a>!is';
$regex2 = '!\s(' . $searchurl . ')\s!is';
if (!preg_match($regex, $page, $match) && !preg_match($regex2, $page, $match)) {
// FIXME internal pings
if ((strstr($targetUri, DOKU_URL) == $targetUri)) {
$ID = substr($_SERVER['PATH_INFO'], 1);
$searchurl = preg_quote(wl($ID, '', false), '!');

$regex = '!<a[^>]+?href="' . $searchurl . '"[^>]*?>(.*?)</a>!is';
$regex2 = '!\s(' . $searchurl . ')\s!is';
if (!preg_match($regex, $page, $match) && !preg_match($regex2, $page, $match))
return false;
} else {
return false;
}
}
$linkback['excerpt'] = '[…] ' . strip_tags($match[1]) . ' […]';

$regex = '!<title.*?>(.*?)</title>!is';
if (!preg_match($regex, $page, $match))
return false;
$linkback['title'] = strip_tags($match[1]);

return $linkback;
}
}

$server = new PingbackServer();
112 changes: 112 additions & 0 deletions exe/trackback.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php

/**
* Trackback server for use with the DokuWiki Linkback Plugin.
*
* @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
* @author Gina Haeussge <osd@foosel.net>
* @link http://wiki.foosel.net/snippets/dokuwiki/linkback
*/

if (!defined('DOKU_INC'))
define('DOKU_INC', realpath(dirname(__FILE__) . '/../../../../') . '/');

if (!defined('NL'))
define('NL', "\n");

require_once (DOKU_INC . 'inc/init.php');
require_once (DOKU_INC . 'inc/common.php');
require_once (DOKU_INC . 'inc/events.php');
require_once (DOKU_INC . 'inc/pluginutils.php');
require_once (DOKU_INC . 'inc/HTTPClient.php');

class TrackbackServer {

/**
* Construct helper and process request.
*/
function TrackbackServer() {
$this->tools =& plugin_load('helper', 'blogtng_linkback');
$this->_process();
}

/**
* Process trackback request.
*/
function _process() {

// Plugin not enabled? Quit
if (plugin_isdisabled('blogtng')) {
$this->_printTrackbackError('Trackbacks disabled.');
return;
}

// Trackbacks not enabled? Quit
if (!$this->tools->getConf('receive_linkbacks')) {
$this->_printTrackbackError('Trackbacks disabled.');
return;
}

// No POST request? Quit
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
$this->_printTrackbackError('Trackback was not received via HTTP POST.');
return;
}

// get ID
$ID = substr($_SERVER['PATH_INFO'], 1);

// FIXME is blog?
// target is not trackback-enabled? Quit
if (!$this->tools->isPost()) {
$this->_printTrackbackError('Trackbacks not enabled for this resource.');
return;
}

$sourceUri = $_REQUEST['url'];

// Given URL is not an url? Quit
if (!preg_match("#^([a-z0-9\-\.+]+?)://.*#i", $sourceUri)) {
$this->_printTrackbackError('Given trackback URL is not an URL.');
return;
}

// Source does not exist? Quit
$http = new DokuHTTPClient;
$page = $http->get($sourceUri);
if ($page === false) {
$this->_printTrackbackError('Linked page cannot be reached');
return;
}

if (!$this->tools->saveLinkback('trackback', strip_tags($_REQUEST['title']),
$sourceUri, strip_tags($_REQUEST['excerpt']), $ID)) {
$this->_printTrackbackError('Trackback already received.');
return;
}
$this->_printTrackbackSuccess();
}

/**
* Print trackback success xml.
*/
function _printTrackbackSuccess() {
echo '<?xml version="1.0" encoding="iso-8859-1"?>' . NL .
'<response>' . NL .
'<error>0</error>' . NL .
'</response>';
}

/**
* Print trackback error xml.
*/
function _printTrackbackError($reason = '') {
echo '<?xml version="1.0" encoding="iso-8859-1"?>' . NL .
'<response>' . NL .
'<error>1</error>' . NL .
'<message>' . $reason . '</message>' . NL .
'</response>';
}
}

$server = new TrackbackServer();
6 changes: 6 additions & 0 deletions helper/comments.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ function save($comment) {
}

// Doing an insert
$entry = plugin_load('helper', 'blogtng_entry');
$entry->load_by_pid($comment['pid']);
if ($entry->entry['commentstatus'] !== 'enabled') {
return;
}

$query = 'INSERT OR IGNORE INTO comments (';
$query .= 'pid, source, name, mail, web, avatar, created, text, status, ip) VALUES (';
$query .= '?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
Expand Down

0 comments on commit dfa32b5

Please sign in to comment.