diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 0704b84f..7380d7b5 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -6,6 +6,7 @@ use Exception; use Illuminate\Validation\ValidationException; use Illuminate\Session\TokenMismatchException; use Illuminate\Auth\Access\AuthorizationException; +use Symfony\Component\Debug\Exception\FlattenException; use Illuminate\Database\Eloquent\ModelNotFoundException; use Symfony\Component\HttpKernel\Exception\HttpException; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; @@ -78,10 +79,11 @@ class Handler extends ExceptionHandler }); $whoops->pushHandler($handler); + $flattened = FlattenException::create($exc); return new \Illuminate\Http\Response( $whoops->handleException($exc), - $exc->getStatusCode(), - $exc->getHeaders() + $flattened->getStatusCode(), + $flattened->getHeaders() ); } } diff --git a/app/Http/Controllers/NotesAdminController.php b/app/Http/Controllers/NotesAdminController.php index 6fd48096..ca4c3741 100644 --- a/app/Http/Controllers/NotesAdminController.php +++ b/app/Http/Controllers/NotesAdminController.php @@ -9,6 +9,12 @@ use App\Services\NoteService; class NotesAdminController extends Controller { + protected $noteService; + + public function __construct(NoteService $noteService = null) + { + $this->noteService = $noteService ?? new NoteService(); + } /** * Show the form to make a new note. * diff --git a/app/Http/Controllers/WebMentionsController.php b/app/Http/Controllers/WebMentionsController.php index ccffd451..fc254058 100644 --- a/app/Http/Controllers/WebMentionsController.php +++ b/app/Http/Controllers/WebMentionsController.php @@ -5,7 +5,6 @@ namespace App\Http\Controllers; use App\Note; use Illuminate\Http\Request; use Illuminate\Http\Response; -use App\Jobs\SendWebMentions; use App\Jobs\ProcessWebMention; use Jonnybarnes\IndieWeb\Numbers; use Illuminate\Database\Eloquent\ModelNotFoundException; @@ -64,37 +63,4 @@ class WebMentionsController extends Controller break; } } - - /** - * Send a webmention. - * - * @param \App\Note $note - * @return array An array of successful then failed URLs - */ - public function send(Note $note) - { - //grab the URLs - $urlsInReplyTo = explode(' ', $note->in_reply_to); - $urlsNote = $this->getLinks($note->note); - $urls = array_filter(array_merge($urlsInReplyTo, $urlsNote)); //filter out none URLs - foreach ($urls as $url) { - $this->dispatch(new SendWebMentions($url, $note->longurl)); - } - } - - /** - * Get the URLs from a note. - */ - private function getLinks($html) - { - $urls = []; - $dom = new \DOMDocument(); - $dom->loadHTML($html); - $anchors = $dom->getElementsByTagName('a'); - foreach ($anchors as $anchor) { - $urls[] = ($anchor->hasAttribute('href')) ? $anchor->getAttribute('href') : false; - } - - return $urls; - } } diff --git a/app/Jobs/SendWebMentions.php b/app/Jobs/SendWebMentions.php index 796fc97c..3052247a 100644 --- a/app/Jobs/SendWebMentions.php +++ b/app/Jobs/SendWebMentions.php @@ -2,6 +2,7 @@ namespace App\Jobs; +use App\Note; use GuzzleHttp\Client; use Illuminate\Queue\SerializesModels; use Illuminate\Queue\InteractsWithQueue; @@ -11,18 +12,20 @@ class SendWebMentions extends Job implements ShouldQueue { use InteractsWithQueue, SerializesModels; - protected $url; - protected $source; + protected $note; + protected $guzzle; /** - * Create a new job instance. + * Create the job instance, inject dependencies. * + * @param User $user + * @param Note $note * @return void */ - public function __construct($url, $source) + public function __construct(Note $note, Client $guzzle = null) { - $this->url = $url; - $this->source = $source; + $this->note = $note; + $this->guzzle = $guzzle ?? new Client(); } /** @@ -30,16 +33,22 @@ class SendWebMentions extends Job implements ShouldQueue * * @return void */ - public function handle(Client $client) + public function handle(Note $note) { - $endpoint = $this->discoverWebmentionEndpoint($this->url, $client); - if ($endpoint) { - $client->post($endpoint, [ - 'form_params' => [ - 'source' => $this->source, - 'target' => $this->url, - ], - ]); + //grab the URLs + $urlsInReplyTo = explode(' ', $this->note->in_reply_to); + $urlsNote = $this->getLinks($this->note->note); + $urls = array_filter(array_merge($urlsInReplyTo, $urlsNote)); //filter out none URLs + foreach ($urls as $url) { + $endpoint = $this->discoverWebmentionEndpoint($url); + if ($endpoint) { + $this->guzzle->post($endpoint, [ + 'form_params' => [ + 'source' => $this->note->longurl, + 'target' => $url + ] + ]); + } } } @@ -50,11 +59,16 @@ class SendWebMentions extends Job implements ShouldQueue * @param \GuzzleHttp\Client $client * @return string The webmention endpoint URL */ - private function discoverWebmentionEndpoint($url, $client) + private function discoverWebmentionEndpoint($url) { + //let’s not send webmentions to myself + if (parse_url($url, PHP_URL_HOST) == env('LONG_URL', 'localhost')) { + return false; + } + $endpoint = null; - $response = $client->get($url); + $response = $this->guzzle->get($url); //check HTTP Headers for webmention endpoint $links = \GuzzleHttp\Psr7\parse_header($response->getHeader('Link')); foreach ($links as $link) { @@ -83,4 +97,20 @@ class SendWebMentions extends Job implements ShouldQueue return false; } + + /** + * Get the URLs from a note. + */ + private function getLinks($html) + { + $urls = []; + $dom = new \DOMDocument(); + $dom->loadHTML($html); + $anchors = $dom->getElementsByTagName('a'); + foreach ($anchors as $anchor) { + $urls[] = ($anchor->hasAttribute('href')) ? $anchor->getAttribute('href') : false; + } + + return $urls; + } } diff --git a/app/Services/NoteService.php b/app/Services/NoteService.php index 0b680090..a1c36905 100644 --- a/app/Services/NoteService.php +++ b/app/Services/NoteService.php @@ -5,6 +5,7 @@ namespace App\Services; use App\Note; use App\Place; use Illuminate\Http\Request; +use App\Jobs\SendWebMentions; use App\Jobs\SyndicateToTwitter; use Illuminate\Foundation\Bus\DispatchesJobs; use App\Http\Controllers\WebMentionsController; @@ -45,10 +46,7 @@ class NoteService } } - if ($request->input('webmentions')) { - $wmc = new WebMentionsController(); - $wmc->send($note); - } + $this->dispatch(new SendWebMentions($note)); if (//micropub request, syndication sent as array (is_array($request->input('mp-syndicate-to')) diff --git a/changelog.md b/changelog.md index 9f3a71c0..fd1aef94 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,7 @@ # Changelog ## Version {next} + - Automatically send webmentions ## Version 0.0.4 (2016-06-21) - Move bower components into their own subdir diff --git a/resources/views/templates/new-note-form.blade.php b/resources/views/templates/new-note-form.blade.php index e0c55ca2..310159ee 100644 --- a/resources/views/templates/new-note-form.blade.php +++ b/resources/views/templates/new-note-form.blade.php @@ -4,7 +4,6 @@ New Note -
@if ($micropub === true) @if($syndication)@endif Refresh Syndication Targets
diff --git a/tests/MicropubTest.php b/tests/MicropubTest.php index 1cac5657..1854f3fb 100644 --- a/tests/MicropubTest.php +++ b/tests/MicropubTest.php @@ -38,7 +38,7 @@ class MicropubTest extends TestCase public function testMicropubRequestWithValidToken() { $this->call('GET', $this->appurl . '/api/post', [], [], [], ['HTTP_Authorization' => 'Bearer ' . $this->getToken()]); - $this->see('me=https%3A%2F%2Fjbl5.dev'); + $this->see('me=https%3A%2F%2Fjonnybarnes.localhost'); } public function testMicropubRequestForSyndication() @@ -79,8 +79,6 @@ class MicropubTest extends TestCase public function testMicropubRequestCreateNewPlace() { - $faker = \Faker\Factory::create(); - $note = $faker->text; $this->call( 'POST', $this->appurl . '/api/post', @@ -101,7 +99,7 @@ class MicropubTest extends TestCase $signer = new Sha256(); $token = (new Builder()) ->set('client_id', 'https://quill.p3k.io') - ->set('me', 'https://jbl5.dev') + ->set('me', 'https://jonnybarnes.localhost') ->set('scope', 'post') ->set('issued_at', time()) ->sign($signer, env('APP_KEY')) diff --git a/tests/NotesAdminTest.php b/tests/NotesAdminTest.php new file mode 100644 index 00000000..06da88ce --- /dev/null +++ b/tests/NotesAdminTest.php @@ -0,0 +1,33 @@ +appurl = config('app.url'); + $this->notesAdminController = new \App\Http\Controllers\NotesAdminController(); + } + + public function testCreatedNoteDispatchesSendWebmentionsJob() + { + $this->expectsJobs(\App\Jobs\SendWebMentions::class); + + $this->withSession(['loggedin' => true]) + ->visit($this->appurl . '/admin/note/new') + ->type('Mentioning', 'content') + ->press('Submit'); + } +}