jonnybarnes.uk/app/Jobs/ProcessWebMention.php

142 lines
4.4 KiB
PHP
Raw Normal View History

2016-05-19 15:01:28 +01:00
<?php
namespace App\Jobs;
use Mf2;
2016-05-19 15:01:28 +01:00
use GuzzleHttp\Client;
2017-06-21 21:34:33 +01:00
use App\{Note, WebMention};
2016-09-20 13:13:05 +01:00
use Illuminate\Bus\Queueable;
2016-05-19 15:01:28 +01:00
use Jonnybarnes\WebmentionsParser\Parser;
use GuzzleHttp\Exception\RequestException;
2016-05-19 15:01:28 +01:00
use Illuminate\Contracts\Queue\ShouldQueue;
2016-08-03 16:08:30 +01:00
use App\Exceptions\RemoteContentNotFoundException;
2017-06-21 21:34:33 +01:00
use Illuminate\Queue\{InteractsWithQueue, SerializesModels};
2016-05-19 15:01:28 +01:00
2016-09-20 13:13:05 +01:00
class ProcessWebMention implements ShouldQueue
2016-05-19 15:01:28 +01:00
{
2016-09-20 13:13:05 +01:00
use InteractsWithQueue, Queueable, SerializesModels;
2016-05-19 15:01:28 +01:00
protected $note;
protected $source;
/**
* Create a new job instance.
*
* @param \App\Note $note
* @param string $source
* @return void
*/
public function __construct(Note $note, $source)
2016-05-19 15:01:28 +01:00
{
$this->note = $note;
$this->source = $source;
}
/**
* Execute the job.
*
* @param \Jonnybarnes\WebmentionsParser\Parser $parser
* @param \GuzzleHttp\Client $guzzle
2016-05-19 15:01:28 +01:00
* @return void
*/
public function handle(Parser $parser, Client $guzzle)
2016-05-19 15:01:28 +01:00
{
$remoteContent = $this->getRemoteContent($this->source, $guzzle);
if ($remoteContent === null) {
2016-08-03 16:08:30 +01:00
throw new RemoteContentNotFoundException;
}
$microformats = Mf2\parse($remoteContent, $this->source);
2016-08-03 16:08:30 +01:00
$webmentions = WebMention::where('source', $this->source)->get();
foreach ($webmentions as $webmention) {
//check webmention still references target
//we try each type of mention (reply/like/repost)
if ($webmention->type == 'in-reply-to') {
if ($parser->checkInReplyTo($microformats, $this->note->longurl) == false) {
//it doesn't so delete
$webmention->delete();
return;
}
//webmenion is still a reply, so update content
2016-09-20 13:13:05 +01:00
dispatch(new SaveProfileImage($microformats));
2016-08-03 16:08:30 +01:00
$webmention->mf2 = json_encode($microformats);
$webmention->save();
return;
}
if ($webmention->type == 'like-of') {
if ($parser->checkLikeOf($microformats, $note->longurl) == false) {
//it doesn't so delete
$webmention->delete();
return;
} //note we don't need to do anything if it still is a like
}
if ($webmention->type == 'repost-of') {
if ($parser->checkRepostOf($microformats, $note->longurl) == false) {
//it doesn't so delete
$webmention->delete();
return;
} //again, we don't need to do anything if it still is a repost
}
}//foreach
2016-05-19 15:01:28 +01:00
//no wemention in db so create new one
$webmention = new WebMention();
2016-08-03 16:08:30 +01:00
$type = $parser->getMentionType($microformats); //throw error here?
2016-09-20 13:13:05 +01:00
dispatch(new SaveProfileImage($microformats));
2016-08-03 16:08:30 +01:00
$webmention->source = $this->source;
$webmention->target = $this->note->longurl;
$webmention->commentable_id = $this->note->id;
$webmention->commentable_type = 'App\Note';
$webmention->type = $type;
$webmention->mf2 = json_encode($microformats);
$webmention->save();
2016-05-19 15:01:28 +01:00
}
/**
* Retreive the remote content from a URL, and caches the result.
*
* @param string $url
* @param GuzzleHttp\client $guzzle
* @return string|null
2016-05-19 15:01:28 +01:00
*/
private function getRemoteContent($url, Client $guzzle)
2016-05-19 15:01:28 +01:00
{
try {
$response = $guzzle->request('GET', $url);
2016-07-29 10:48:05 +01:00
} catch (RequestException $e) {
return;
}
2016-05-19 15:01:28 +01:00
$html = (string) $response->getBody();
$path = storage_path() . '/HTML/' . $this->createFilenameFromURL($url);
2016-08-03 16:08:30 +01:00
$parts = explode('/', $path);
$name = array_pop($parts);
$dir = implode('/', $parts);
if (! is_dir($dir)) {
mkdir($dir, 0755, true);
}
file_put_contents("$dir/$name", $html);
2016-05-19 15:01:28 +01:00
return $html;
}
/**
* Create a file path from a URL. This is used when caching the HTML
* response.
*
* @param string The URL
* @return string The path name
*/
private function createFilenameFromURL($url)
{
$url = str_replace(['https://', 'http://'], ['https/', 'http/'], $url);
2016-05-19 15:01:28 +01:00
if (substr($url, -1) == '/') {
$url = $url . 'index.html';
}
return $url;
}
}