API Remove Trackback support

It was disabled since migrating the module to SS3,
and the whole concept has become less relevant since spammers discovered trackbacks
(ref http://en.wikipedia.org/wiki/Trackback#Spam).

Since we don't have the resources to make a spam-proof trackback system,
its prudent to remove it instead.
This commit is contained in:
Ingo Schommer 2013-04-11 01:01:09 +02:00
parent 7f019444cb
commit d351d33621
11 changed files with 9 additions and 466 deletions

View File

@ -37,10 +37,6 @@ class BlogEntry extends Page {
'ShowInMenus' => false
);
private static $extensions = array(
'TrackBackDecorator'
);
/**
* Is WYSIWYG editing allowed?
* @var boolean
@ -174,21 +170,6 @@ class BlogEntry extends Page {
return ($this->getParent()) ? $this->getParent()->Link('post') . '/' . $this->ID . '/' : false;
}
/**
* Check to see if trackbacks are enabled.
*/
function TrackBacksEnabled() {
return ($this->getParent()) ? $this->getParent()->TrackBacksEnabled : false;
}
function trackbackping() {
if($this->TrackBacksEnabled() && $this->hasExtension('TrackBackDecorator')) {
return $this->decoratedTrackbackping();
} else {
Controller::curr()->redirect($this->Link());
}
}
function IsOwner() {
if(method_exists($this->Parent(), 'IsOwner')) {
return $this->Parent()->IsOwner();
@ -251,7 +232,6 @@ class BlogEntry_Controller extends Page_Controller {
private static $allowed_actions = array(
'index',
'trackbackping',
'unpublishPost',
'PageComments',
'SearchForm'

View File

@ -14,15 +14,14 @@
class BlogHolder extends BlogTree implements PermissionProvider {
private static $icon = "blog/images/blogholder-file.png";
private static $description = "Displays listings of blog entries";
private static $singular_name = 'Blog Holder Page';
private static $plural_name = 'Blog Holder Pages';
private static $db = array(
'TrackBacksEnabled' => 'Boolean',
'AllowCustomAuthors' => 'Boolean',
'ShowFullEntry' => 'Boolean',
);
@ -42,13 +41,13 @@ class BlogHolder extends BlogTree implements PermissionProvider {
$fields = parent::getCMSFields();
SiteTree::enableCMSFieldsExtensions();
//sets the ID and Name Map for Blog Ownership
$owners = new DropdownField('OwnerID', 'Blog owner', $blogOwners->map('ID', 'Name')->toArray());
$owners->setEmptyString('(None)');
$owners->setHasEmptyDefault(true);
$fields->addFieldToTab('Root.Main', new CheckboxField('TrackBacksEnabled', 'Enable TrackBacks'), "Content");
$fields->addFieldToTab('Root.Main', $owners, "Content");
$fields->addFieldToTab(
'Root.Main',
DropdownField::create('OwnerID', 'Blog owner', $blogOwners->map('ID', 'Name')->toArray())
->setEmptyString('(None)')
->setHasEmptyDefault(true),
"Content"
);
$fields->addFieldToTab('Root.Main', new CheckboxField('AllowCustomAuthors', 'Allow non-admins to have a custom author field'), "Content");
$fields->addFieldToTab("Root.Main", new CheckboxField("ShowFullEntry", "Show Full Entry"), "Content");

View File

@ -1,161 +0,0 @@
<?php
/**
* Add trackback (receive and send) feature blog entry
*/
class TrackBackDecorator extends DataExtension {
static $trackback_server_class = 'TrackbackHTTPServer';
// function extraStatics() {
// return array(
// 'has_many' => array(
// 'TrackBackURLs' => 'TrackBackURL',
// 'TrackBacks' => 'TrackBackPing'
// )
// );
// }
private static $has_many = array(
'TrackBackURLs' => 'TrackBackURL',
'TrackBacks' => 'TrackBackPing'
);
// function updateCMSFields($fields) {
// // Trackback URL field
// if($this->owner->TrackBacksEnabled()) {
// $trackbackURLTable = new ComplexTableField(
// $this,
// 'TrackBackURLs',
// 'TrackBackURL',
// array(
// 'URL' => 'URL',
// 'IsPung' => 'Pung?'
// ),
// 'getCMSFields_forPopup',
// '',
// 'ID'
// );
// $fields->addFieldToTab("Root.Content.Main", $trackbackURLTable);
// }
// else {
// $fields->addFieldToTab("Root.Content.Main", new ReadonlyField("TrackBackURLsReadOnly", _t("BlogEntry.TrackbackURLs", "Trackback URLs"), _t("BlogEntry.TrackbackURLs_DISABLED", "To use this feature, please check 'Enable TrackBacks' check box on the blog holder.")));
// }
// }
function onBeforePublish() {
if(!$this->owner->TrackBacksEnabled() && !$this->owner->TrackBackURLs()) return;
foreach($this->owner->TrackBackURLs() as $trackBackURL) {
if(!$trackBackURL->Pung && $this->trackbackNotify($trackBackURL->URL)) {
$trackBackURL->Pung = true;
$trackBackURL->write();
}
}
}
/**
* Trackback notify the specified trackback url
* @param boolean | true on success, otherwise false
*/
function trackbackNotify($url) {
$content = new HTMLText('Content');
$content->setValue($this->owner->Content);
$excerpt = $content->FirstParagraph();
if($this->owner->Parent() && $this->owner->ParentID > 0) {
$blogName = $this->owner->Parent()->Title;
}
else {
$blogName = "";
}
$postData = array(
'url' => $this->owner->AbsoluteLink(),
'title' => $this->owner->Title,
'excerpt' => $excerpt,
'blog_name' => $blogName
);
$controller = Object::create(self::$trackback_server_class);
$response = $controller->request($url, $postData);
if($response->getStatusCode() == '200' && stripos($response->getBody(), "<error>0</error>") !== false) {
return true;
}
return false;
}
function updateMetaTags(&$tags) {
$tags .= $this->owner->renderWith('TrackBackRdf');
}
function TrackBackPingLink() {
return $this->owner->AbsoluteLink() . 'trackbackping';
}
function decoratedTrackbackping() {
$error = 0;
$message = '';
if(!(isset($_POST['url']) && $_POST['url'])) {
$error = 1;
$message = 'Missing required POST parameter \'url\'.';
} else {
$trackbackping = new TrackBackPing();
$trackbackping->Url = $_POST['url'];
if(isset($_POST['title']) && $_POST['title']) {
$trackbackping->Title = $_POST['title'];
}
if(isset($_POST['excerpt']) && $_POST['excerpt']) {
$trackbackping->Excerpt = $_POST['excerpt'];
}
if(isset($_POST['blog_name']) && $_POST['blog_name']) {
$trackbackping->BlogName = $_POST['blog_name'];
}
$trackbackping->PageID = $this->owner->ID;
$trackbackping->write();
}
$returnData = new ArrayData(array(
'Error' => $error,
'Message' => $message
));
return $returnData->renderWith('TrackBackPingReturn');
}
}
/**
* Example:
* $controller = Object::create('TrackbackHTTPClient');
* $response = $controller->request(new SS_HTTPRequest('POST', $url, null, $postData));
*/
class TrackbackHTTPServer {
function __construct() {}
/**
* @param string
* @param array
* @return SS_HTTPResponse
*/
function request($url, $data) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return new SS_HTTPResponse($response, $statusCode);
}
}
?>

View File

@ -1,24 +0,0 @@
<?php
class TrackBackPing extends DataObject {
private static $db = array(
'Title' => 'Varchar',
'Excerpt' => 'Text',
// 2083 is URL-length limit for IE, AFAIK.
// see: http://www.boutell.com/newfaq/misc/urllength.html
'Url' => 'Varchar(2048)',
'BlogName' => 'Varchar'
);
private static $has_one = array(
'Page' => 'Page'
);
private static $has_many = array();
private static $many_many = array();
private static $belongs_many_many = array();
}
?>

View File

@ -1,55 +0,0 @@
<?php
class TrackBackURL extends DataObject {
private static $db = array(
'URL' => 'Varchar(2048)',
'Pung' => 'Boolean(0)'
);
private static $has_one = array(
'BlogEntry' => 'BlogEntry'
);
function getCMSFields_forPopup() {
return new FieldList(
new TextField('URL'),
new ReadonlyField('Pung', 'Pung?')
);
}
/**
* Return a human-reable string indicate whether the url has been pung or not
* Also update the url if it's duplicate
* @return string - 'Yes' or 'No'
*/
function IsPung() {
if($this->Pung) return _t('TrackBackULR.YES', 'Yes');
if($this->isDuplicate(true)) {
$this->Pung = true;
$this->write();
return _t('TrackBackULR.YES', 'Yes');
}
return _t('TrackBackULR.NO', 'No');
}
/**
* Check if there is a duplication, based on the associcated blog entry and the url.
* If onPung is set, it returns true only when the duplicated record that has Pung = true
* @param boolean
* @return boolean
*/
function isDuplicate($onPung = false) {
$where = "\"BlogEntryID\" = {$this->BlogEntryID} AND \"URL\" = '{$this->URL}' AND \"TrackBackURL\".\"ID\" <> {$this->ID}";
if($onPung) $where .= " AND \"Pung\" = 1";
if(DataObject::get_one($this->ClassName, $where)) {
return true;
}
return false;
}
}

View File

@ -1,20 +0,0 @@
<div id="TrackBacks_holder" class="typography">
<h4>TrackBacks</h4>
<% if TrackBacks %>
<ul id="TrackBacks">
<% loop TrackBacks %>
<li>
<a href="$Url"><% if Title %>$Title<% else %>$Url<% end_if %></a> <span class="date">on $Created.Nice</span>
<% if Excerpt %><p class="excerpt">$Excerpt</p><% end_if %>
</li>
<% end_loop %>
</ul>
<% else %>
<p>No TrackBacks have been submitted for this page.</p>
<% end_if %>
<a href="$TrackBackPingLink">Trackback URL for this page.</a>
</div>

View File

@ -18,8 +18,5 @@
<% if IsOwner %><p class="edit-post"><a href="$EditURL" id="editpost" title="<% _t('EDITTHIS', 'Edit this post') %>"><% _t('EDITTHIS', 'Edit this post') %></a> | <a href="$Link(unpublishPost)" id="unpublishpost"><% _t('UNPUBLISHTHIS', 'Unpublish this post') %></a></p><% end_if %>
<% if TrackBacksEnabled %>
<% include TrackBacks %>
<% end_if %>
$PageComments
</div>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<response>
<error>$Error</error>
<% if Message %><message>$Message</message><% end_if %>
</response>

View File

@ -1,3 +0,0 @@
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:dc="http://purl.org/dc/elements/1.1/" >
<rdf:Description rdf:about="$AbsoluteLink" trackback:ping="$TrackBackPingLink" dc:identifier="$AbsoluteLink" dc:title="$Title" />
</rdf:RDF>

View File

@ -1,127 +0,0 @@
<?php
/**
* @package blog
* @subpackage tests
*/
class BlogTrackbackTest extends SapphireTest {
static $fixture_file = 'blog/tests/BlogTrackbackTest.yml';
function testTrackback() {
$blog = $this->objFromFixture('BlogHolder', 'mainblog');
$blog->TrackBacksEnabled = true;
$blog->write();
$entry = $this->objFromFixture('BlogEntry', 'testpost');
$response = $entry->trackbackping();
$this->assertContains("<error>1</error>", $response);
$_POST['url'] = 'test trackback post url';
$_POST['title'] = 'test trackback post title';
$_POST['excerpt'] = 'test trackback post excerpt';
$_POST['blog_name'] = 'test trackback blog name';
$response = $entry->trackbackping();
$this->assertContains("<error>0</error>", $response);
$trackback = DataObject::get_one('TrackBackPing');
$this->assertEquals('test trackback post url', $trackback->Url);
$this->assertEquals('test trackback post title', $trackback->Title);
$this->assertEquals('test trackback post excerpt', $trackback->Excerpt);
$this->assertEquals('test trackback blog name', $trackback->BlogName);
unset($_POST);
}
function testTrackbackNotify() {
$tmpServerClass = TrackBackDecorator::$trackback_server_class;
TrackBackDecorator::$trackback_server_class = "TestTrackbackHTTPServer";
$blog = $this->objFromFixture('BlogHolder', 'mainblog');
$blog->TrackBacksEnabled = true;
$blog->write();
$entry = $this->objFromFixture('BlogEntry', 'testpost');
$this->assertTrue($entry->trackbackNotify('testGoodTrackbackURL'));
$this->assertFalse($entry->trackbackNotify('testBadTrackbackURL'));
$this->assertFalse($entry->trackbackNotify('testNonExistingTrackbackURL'));
TrackBackDecorator::$trackback_server_class = $tmpServerClass;
}
function testOnBeforePublish() {
$tmpServerClass = TrackBackDecorator::$trackback_server_class;
TrackBackDecorator::$trackback_server_class = "TestTrackbackHTTPServer";
$blog = $this->objFromFixture('BlogHolder', 'mainblog');
$blog->TrackBacksEnabled = true;
$blog->write();
$entry1 = $this->objFromFixture('BlogEntry', 'testpost');
$entry1->doPublish();
$this->assertEquals(2, $entry1->TrackBackURLs()->Count());
$this->assertEquals(array('testGoodTrackbackURL' => 1), $entry1->TrackBackURLs()->map('URL', 'Pung')->toArray());
$entry2 = $this->objFromFixture('BlogEntry', 'testpost2');
$entry2->doPublish();
$this->assertEquals(4, $entry2->TrackBackURLs()->Count());
$this->assertEquals(array('testBadTrackbackURL' => 0, 'testGoodTrackbackURL2' => 1, 'noneExistingURL' => 0, 'testGoodTrackbackURL3' => 1), $entry2->TrackBackURLs()->map('URL', 'Pung')->toArray());
TrackBackDecorator::$trackback_server_class = $tmpServerClass;
}
function testDuplicateIsTrackBackURL() {
$url1 = $this->objFromFixture('TrackBackURL', 'goodTrackBackURL1');
$urlDup = $this->objFromFixture('TrackBackURL', 'dupTrackBackURL');
$url2 = $this->objFromFixture('TrackBackURL', 'goodTrackBackURL2');
$this->assertFalse($url2->isDuplicate());
$this->assertFalse($url2->isDuplicate(true));
$this->assertTrue($urlDup->isDuplicate());
$this->assertFalse($urlDup->isDuplicate(true));
$url1->Pung = true;
$url1->write();
$this->assertTrue($urlDup->isDuplicate(true));
}
}
class TestTrackbackHTTPServer extends TrackbackHTTPServer implements TestOnly {
function request($url, $data) {
if(in_array($url, array('testGoodTrackbackURL', 'testGoodTrackbackURL2', 'testGoodTrackbackURL3'))) {
$response = $this->goodTrackback();
$statusCode = '200';
}
else if($url == 'testBadTrackbackURL') {
$response = $this->badTrackback();
$statusCode = '200';
}
else {
$response = $this->badTrackback();
$statusCode = '404';
}
return new SS_HTTPResponse($response, $statusCode);
}
private function goodTrackback() {
return "<?xml version=\"1.0\" encoding=\"utf-8\"?>
<response>
<error>0</error>
<message></message>
</response>";
}
private function badTrackback() {
return "<?xml version=\"1.0\" encoding=\"utf-8\"?>
<response>
<error>1</error>
<message>Some error text</message>
</response>";
}
}

View File

@ -1,38 +0,0 @@
TrackBackURL:
goodTrackBackURL1:
URL: testGoodTrackbackURL
goodTrackBackURL2:
URL: testGoodTrackbackURL2
goodTrackBackURL3:
URL: testGoodTrackbackURL3
badTrackBackURL:
URL: testBadTrackbackURL
noneTrackBackURL:
URL: noneExistingURL
dupTrackBackURL:
URL: testGoodTrackbackURL
BlogHolder:
mainblog:
Title: Main Blog
BlogEntry:
testpost:
Title: Test Post
URLSegment: test-post
Date: 2007-02-17 18:45:00
Parent: =>BlogHolder.mainblog
Tags: tag1,tag2
TrackBackURLs: =>TrackBackURL.goodTrackBackURL1, =>TrackBackURL.dupTrackBackURL
testpost2:
Title: Test Post 2
URLSegment: test-post-2
Parent: =>BlogHolder.mainblog
TrackBackURLs: =>TrackBackURL.badTrackBackURL,=>TrackBackURL.goodTrackBackURL2,=>TrackBackURL.noneTrackBackURL,=>TrackBackURL.goodTrackBackURL3