From 834b6d8f91ce9ebc47ad34e3e9b42475fb1333a6 Mon Sep 17 00:00:00 2001 From: Saophalkun Ponlu Date: Wed, 23 Jun 2010 05:50:02 +0000 Subject: [PATCH] ENHANCEMENT: Allow notifying multiple trackback urls per blog entry APICHANGE: TrackBackDecorator::trackbackNotify() allow one parameter APICHANGE: remove TrackBackDecorator::ShouldTrackbackNotify() --- code/TrackBackDecorator.php | 67 ++++++++++++++++++---------------- code/TrackBackURL.php | 54 +++++++++++++++++++++++++++ tests/BlogTrackbackTest.php | 73 +++++++++++++++++++++++-------------- tests/BlogTrackbackTest.yml | 38 +++++++++++++++++++ 4 files changed, 173 insertions(+), 59 deletions(-) create mode 100644 code/TrackBackURL.php create mode 100644 tests/BlogTrackbackTest.yml diff --git a/code/TrackBackDecorator.php b/code/TrackBackDecorator.php index 8bc2dec..5356fd9 100644 --- a/code/TrackBackDecorator.php +++ b/code/TrackBackDecorator.php @@ -1,6 +1,6 @@ array( - 'TrackbackURL' => 'Varchar(2048)', - 'PungTrackbackURL' => 'Varchar(2048)' - ), 'has_many' => array( + 'TrackBackURLs' => 'TrackBackURL', 'TrackBacks' => 'TrackBackPing' ) ); @@ -21,63 +18,67 @@ class TrackBackDecorator extends DataObjectDecorator { function updateCMSFields($fields) { // Trackback URL field if($this->owner->TrackBacksEnabled()) { - $fields->addFieldToTab("Root.Content.Main", new TextField("TrackbackURL", _t("BlogEntry.TRACKBACKURL", "Trackback URL")), "Content"); + $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("TrackbackURLReadOnly", _t("BlogEntry.TRACKBACKURL", "Trackback URL"), _t("BlogEntry.TRACKBACKURL_DISABLED", "To use this feature, please check 'Enable TrackBacks' check box on the blog holder.")), "Content"); + $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() { - $owner = $this->owner; - - if(!empty($owner->TrackbackURL) && $owner->TrackBacksEnabled() && $owner->ShouldTrackbackNotify()) { - - if($this->trackbackNotify()) { - $owner->PungTrackbackURL = $owner->TrackbackURL; - $owner->write(); + 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() { - $owner = $this->owner; - + function trackbackNotify($url) { $content = new HTMLText('Content'); - $content->setValue($owner->Content); + $content->setValue($this->owner->Content); $excerpt = $content->FirstParagraph(); - - if($owner->Parent() && $owner->ParentID > 0) { - $blogName = $owner->Parent()->Title; + + if($this->owner->Parent() && $this->owner->ParentID > 0) { + $blogName = $this->owner->Parent()->Title; } else { $blogName = ""; } - + $postData = array( - 'url' => $owner->AbsoluteLink(), - 'title' => $owner->Title, + 'url' => $this->owner->AbsoluteLink(), + 'title' => $this->owner->Title, 'excerpt' => $excerpt, 'blog_name' => $blogName ); - + $controller = Object::create(self::$trackback_server_class); - $response = $controller->request($owner->TrackbackURL, $postData); + $response = $controller->request($url, $postData); if($response->getStatusCode() == '200' && stripos($response->getBody(), "0") !== false) { return true; } return false; - - } - - function ShouldTrackbackNotify() { - return (trim($this->owner->TrackbackURL) != '' && $this->owner->TrackbackURL != $this->owner->PungTrackbackURL); } function updateMetaTags(&$tags) { @@ -136,6 +137,8 @@ class TrackbackHTTPServer { */ 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); diff --git a/code/TrackBackURL.php b/code/TrackBackURL.php new file mode 100644 index 0000000..c2b112c --- /dev/null +++ b/code/TrackBackURL.php @@ -0,0 +1,54 @@ + 'Varchar(2048)', + 'Pung' => 'Boolean(0)' + ); + + static $has_one = array( + 'BlogEntry' => 'BlogEntry' + ); + + function getCMSFields_forPopup() { + return new FieldSet( + 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 IS TRUE"; + + if(DataObject::get_one($this->ClassName, $where)) { + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/tests/BlogTrackbackTest.php b/tests/BlogTrackbackTest.php index 7fa6745..cf9550e 100644 --- a/tests/BlogTrackbackTest.php +++ b/tests/BlogTrackbackTest.php @@ -4,7 +4,7 @@ * @subpackage tests */ class BlogTrackbackTest extends SapphireTest { - static $fixture_file = 'blog/tests/BlogTest.yml'; + static $fixture_file = 'blog/tests/BlogTrackbackTest.yml'; function testTrackback() { $blog = $this->objFromFixture('BlogHolder', 'mainblog'); @@ -33,47 +33,66 @@ class BlogTrackbackTest extends SapphireTest { unset($_POST); } - function testShouldTrackbackNotify() { - $blog = $this->objFromFixture('BlogHolder', 'mainblog'); - $blog->TrackBacksEnabled = true; - - $entry = $this->objFromFixture('BlogEntry', 'testpost'); - $this->assertFalse($entry->ShouldTrackbackNotify()); - - $entry = $this->objFromFixture('BlogEntry', 'testpost'); - $entry->TrackbackURL = ' '; - $this->assertFalse($entry->ShouldTrackbackNotify()); - - $entry = $this->objFromFixture('BlogEntry', 'testpost'); - $entry->TrackbackURL = 'someurl'; - $this->assertTrue($entry->ShouldTrackbackNotify()); - } - 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'); - $entry->TrackbackURL = 'testGoodTrackbackURL'; - $this->assertTrue($entry->trackbackNotify()); - - $entry->TrackbackURL = 'testBadTrackbackURL'; - $this->assertFalse($entry->trackbackNotify()); - - $entry->TrackbackURL = 'testNonExistingTrackbackURL'; - $this->assertFalse($entry->trackbackNotify()); + $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')); + + $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')); + + 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($url == 'testGoodTrackbackURL') { + if(in_array($url, array('testGoodTrackbackURL', 'testGoodTrackbackURL2', 'testGoodTrackbackURL3'))) { $response = $this->goodTrackback(); $statusCode = '200'; } diff --git a/tests/BlogTrackbackTest.yml b/tests/BlogTrackbackTest.yml new file mode 100644 index 0000000..586b7b1 --- /dev/null +++ b/tests/BlogTrackbackTest.yml @@ -0,0 +1,38 @@ +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 + + + + + + +