diff --git a/lib/Telegraph/Webmention.php b/lib/Telegraph/Webmention.php index 60fee6e..ed0a432 100644 --- a/lib/Telegraph/Webmention.php +++ b/lib/Telegraph/Webmention.php @@ -5,9 +5,11 @@ use IndieWeb\MentionClient; class Webmention { - private static function saveStatus($webmentionID, $http_code, $code, $raw=null) { + private static $http = false; + + private static function updateStatus($webmention, $http_code, $code, $raw=null) { $status = ORM::for_table('webmention_status')->create(); - $status->webmention_id = $webmentionID; + $status->webmention_id = $webmention->id; $status->created_at = date('Y-m-d H:i:s'); if($http_code) $status->http_code = $http_code; @@ -15,9 +17,18 @@ class Webmention { if($raw) $status->raw_response = $raw; $status->save(); + + // Post to the callback URL if one is set + if($webmention->callback) { + return self::$http->post($webmention->callback, [ + 'source' => $webmention->source, + 'target' => $webmention->target, + 'status' => $code + ]); + } } - public static function send($id, $client=false) { + public static function send($id, $client=false, $http=false) { $webmention = ORM::for_table('webmentions')->where('id', $id)->find_one(); if(!$webmention) { echo 'Webmention '.$id.' was not found'."\n"; @@ -27,6 +38,11 @@ class Webmention { if(!$client) $client = new MentionClient(); + if(!$http) + $http = new Telegraph\HTTP(); + + self::$http = $http; + // Discover the webmention or pingback endpoint $endpoint = $client->discoverWebmentionEndpoint($webmention->target); @@ -36,16 +52,14 @@ class Webmention { // If no pingback endpoint was found, we can't do anything else if(!$pingbackEndpoint) { - self::saveStatus($id, null, 'not_supported'); - return; + return self::updateStatus($webmention, null, 'not_supported'); } $webmention->pingback_endpoint = $pingbackEndpoint; $webmention->save(); $success = $client->sendPingbackToEndpoint($pingbackEndpoint, $webmention->source, $webmention->target); - self::saveStatus($id, null, ($success ? 'pingback_accepted' : 'pingback_error')); - return; + return self::updateStatus($webmention, null, ($success ? 'pingback_accepted' : 'pingback_error')); } // There is a webmention endpoint, send the webmention now @@ -68,7 +82,7 @@ class Webmention { $status = 'webmention_error'; } - self::saveStatus($webmention->id, $response['code'], $status, $response['body']); + return self::updateStatus($webmention, $response['code'], $status, $response['body']); } } diff --git a/tests/ProcessTest.php b/tests/ProcessTest.php index aba31d8..3f2dce8 100644 --- a/tests/ProcessTest.php +++ b/tests/ProcessTest.php @@ -4,11 +4,13 @@ use Symfony\Component\HttpFoundation\Response; class ProcessTest extends PHPUnit_Framework_TestCase { - private $client; + private $http; + private $api; public function setUp() { - $this->client = new API(); - $this->client->http = new Telegraph\HTTPTest(); + $this->http = new Telegraph\HTTPTest(); + $this->api = new API(); + $this->api->http = $this->http; ORM::for_table('users')->raw_query('TRUNCATE users')->delete_many(); ORM::for_table('roles')->raw_query('TRUNCATE roles')->delete_many(); ORM::for_table('sites')->raw_query('TRUNCATE sites')->delete_many(); @@ -37,15 +39,15 @@ class ProcessTest extends PHPUnit_Framework_TestCase { private function webmention($params) { $request = new Request($params); $response = new Response(); - $response = $this->client->webmention($request, $response); + $response = $this->api->webmention($request, $response); $webmention = ORM::for_table('webmentions')->where(['source' => $params['source'], 'target' => $params['target']])->find_one(); $client = new IndieWeb\MentionClientTest(); $client::$dataDir = dirname(__FILE__) . '/data/'; if(!is_object($webmention)) { throw new Exception("No webmention was queued for this test"); } - Telegraph\Webmention::send($webmention->id, $client); - return $webmention; + $callback = Telegraph\Webmention::send($webmention->id, $client, $this->http); + return [$webmention, $callback]; } private static function webmentionStatus($id) { @@ -54,7 +56,7 @@ class ProcessTest extends PHPUnit_Framework_TestCase { public function testNoEndpoint() { $this->_createExampleAccount(); - $webmention = $this->webmention([ + list($webmention, $callback) = $this->webmention([ 'token' => 'a', 'source' => 'http://source.example.com/no-endpoint', 'target' => 'http://target.example.com/no-endpoint' @@ -65,7 +67,7 @@ class ProcessTest extends PHPUnit_Framework_TestCase { public function testPingbackSuccess() { $this->_createExampleAccount(); - $webmention = $this->webmention([ + list($webmention, $callback) = $this->webmention([ 'token' => 'a', 'source' => 'http://source.example.com/pingback-success', 'target' => 'http://target.example.com/pingback-success' @@ -78,7 +80,7 @@ class ProcessTest extends PHPUnit_Framework_TestCase { public function testPingbackFailed() { $this->_createExampleAccount(); - $webmention = $this->webmention([ + list($webmention, $callback) = $this->webmention([ 'token' => 'a', 'source' => 'http://source.example.com/pingback-failed', 'target' => 'http://target.example.com/pingback-failed' @@ -89,7 +91,7 @@ class ProcessTest extends PHPUnit_Framework_TestCase { public function testWebmentionTakesPriorityOverPingback() { $this->_createExampleAccount(); - $webmention = $this->webmention([ + list($webmention, $callback) = $this->webmention([ 'token' => 'a', 'source' => 'http://source.example.com/webmention-and-pingback', 'target' => 'http://target.example.com/webmention-success' @@ -100,7 +102,7 @@ class ProcessTest extends PHPUnit_Framework_TestCase { public function testWebmentionSucceeds() { $this->_createExampleAccount(); - $webmention = $this->webmention([ + list($webmention, $callback) = $this->webmention([ 'token' => 'a', 'source' => 'http://source.example.com/webmention-success', 'target' => 'http://target.example.com/webmention-success' @@ -113,7 +115,7 @@ class ProcessTest extends PHPUnit_Framework_TestCase { public function testSavesWebmentionStatusURL() { $this->_createExampleAccount(); - $webmention = $this->webmention([ + list($webmention, $callback) = $this->webmention([ 'token' => 'a', 'source' => 'http://source.example.com/webmention-status-url', 'target' => 'http://target.example.com/webmention-status-url' @@ -128,7 +130,7 @@ class ProcessTest extends PHPUnit_Framework_TestCase { public function testWebmentionFailed() { $this->_createExampleAccount(); - $webmention = $this->webmention([ + list($webmention, $callback) = $this->webmention([ 'token' => 'a', 'source' => 'http://source.example.com/webmention-failed', 'target' => 'http://target.example.com/webmention-failed' @@ -139,4 +141,19 @@ class ProcessTest extends PHPUnit_Framework_TestCase { $this->assertEquals('http://webmention.example.com/error', $webmention->webmention_endpoint); } + public function testWebmentionStatusCallback() { + $this->_createExampleAccount(); + list($webmention, $callback) = $this->webmention([ + 'token' => 'a', + 'source' => 'http://source.example.com/webmention-success', + 'target' => 'http://target.example.com/webmention-success', + 'callback' => 'http://source.example.com/callback' + ]); + $status = $this->webmentionStatus($webmention->id); + $this->assertEquals($status->status, 'webmention_accepted'); + $webmention = ORM::for_table('webmentions')->where('id',$webmention->id)->find_one(); + $this->assertEquals('http://webmention.example.com/success', $webmention->webmention_endpoint); + $this->assertEquals('Callback was successful', trim($callback['body'])); + } + } diff --git a/tests/data/source.example.com/callback b/tests/data/source.example.com/callback new file mode 100644 index 0000000..2e207b6 --- /dev/null +++ b/tests/data/source.example.com/callback @@ -0,0 +1,7 @@ +HTTP/1.1 200 OK +Server: Apache +Date: Wed, 09 Dec 2015 03:29:14 GMT +Content-Type: text/html; charset=utf-8 +Connection: keep-alive + +Callback was successful