[COMPONENT][Link] Fix some minor issues with empty headed links, typo in event handler's name, and refactor entity to inside component
This commit is contained in:
parent
56d653d980
commit
70ed04a7db
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
// {{{ License
|
// {{{ License
|
||||||
// This file is part of GNU social - https://www.gnu.org/software/social
|
// This file is part of GNU social - https://www.gnu.org/software/social
|
||||||
//
|
//
|
||||||
|
@ -17,7 +19,7 @@
|
||||||
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
|
// along with GNU social. If not, see <http://www.gnu.org/licenses/>.
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
namespace App\Entity;
|
namespace Component\Link\Entity;
|
||||||
|
|
||||||
use App\Core\DB\DB;
|
use App\Core\DB\DB;
|
||||||
use App\Core\Entity;
|
use App\Core\Entity;
|
||||||
|
@ -29,9 +31,8 @@ use App\Util\Common;
|
||||||
use App\Util\Exception\DuplicateFoundException;
|
use App\Util\Exception\DuplicateFoundException;
|
||||||
use App\Util\Exception\NotFoundException;
|
use App\Util\Exception\NotFoundException;
|
||||||
use DateTimeInterface;
|
use DateTimeInterface;
|
||||||
|
use Exception;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use Symfony\Component\HttpClient\Exception\ClientException as HTTPClientException;
|
|
||||||
use Symfony\Component\HttpClient\Exception\TransportException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entity for representing a Link
|
* Entity for representing a Link
|
||||||
|
@ -100,13 +101,13 @@ class Link extends Entity
|
||||||
public function getMimetypeMajor(): ?string
|
public function getMimetypeMajor(): ?string
|
||||||
{
|
{
|
||||||
$mime = $this->getMimetype();
|
$mime = $this->getMimetype();
|
||||||
return is_null($mime) ? $mime : GSFile::mimetypeMajor($mime);
|
return \is_null($mime) ? $mime : GSFile::mimetypeMajor($mime);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getMimetypeMinor(): ?string
|
public function getMimetypeMinor(): ?string
|
||||||
{
|
{
|
||||||
$mime = $this->getMimetype();
|
$mime = $this->getMimetype();
|
||||||
return is_null($mime) ? $mime : GSFile::mimetypeMinor($mime);
|
return \is_null($mime) ? $mime : GSFile::mimetypeMinor($mime);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setModified(DateTimeInterface $modified): self
|
public function setModified(DateTimeInterface $modified): self
|
||||||
|
@ -123,24 +124,21 @@ class Link extends Entity
|
||||||
// @codeCoverageIgnoreEnd
|
// @codeCoverageIgnoreEnd
|
||||||
// }}} Autocode
|
// }}} Autocode
|
||||||
|
|
||||||
const URLHASH_ALGO = 'sha256';
|
public const URLHASH_ALGO = 'sha256';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an attachment for the given URL, fetching the mimetype
|
* Create an attachment for the given URL, fetching the mimetype
|
||||||
*
|
*
|
||||||
* @param string $url
|
|
||||||
*
|
|
||||||
*@throws InvalidArgumentException
|
|
||||||
* @throws DuplicateFoundException
|
* @throws DuplicateFoundException
|
||||||
|
*@throws InvalidArgumentException
|
||||||
*
|
*
|
||||||
* @return Link
|
* @return Link
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static function getOrCreate(string $url): self
|
public static function getOrCreate(string $url): self
|
||||||
{
|
{
|
||||||
if (Common::isValidHttpUrl($url)) {
|
if (Common::isValidHttpUrl($url)) {
|
||||||
// If the URL is a local one, do not create a Link to it
|
// If the URL is a local one, do not create a Link to it
|
||||||
if (parse_url($url, PHP_URL_HOST) === $_ENV['SOCIAL_DOMAIN']) {
|
if (parse_url($url, \PHP_URL_HOST) === $_ENV['SOCIAL_DOMAIN']) {
|
||||||
Log::warning("It was attempted to create a Link to a local location {$url}.");
|
Log::warning("It was attempted to create a Link to a local location {$url}.");
|
||||||
// Forbidden
|
// Forbidden
|
||||||
throw new InvalidArgumentException(message: "A Link can't point to a local location ({$url}), it must be a remote one", code: 400);
|
throw new InvalidArgumentException(message: "A Link can't point to a local location ({$url}), it must be a remote one", code: 400);
|
||||||
|
@ -150,7 +148,7 @@ class Link extends Entity
|
||||||
// This must come before getInfo given that Symfony HTTPClient is lazy (thus forcing curl exec)
|
// This must come before getInfo given that Symfony HTTPClient is lazy (thus forcing curl exec)
|
||||||
$headers = $head->getHeaders();
|
$headers = $head->getHeaders();
|
||||||
// @codeCoverageIgnoreStart
|
// @codeCoverageIgnoreStart
|
||||||
} catch (HTTPClientException | TransportException $e) {
|
} catch (Exception $e) {
|
||||||
throw new InvalidArgumentException(previous: $e);
|
throw new InvalidArgumentException(previous: $e);
|
||||||
// @codeCoverageIgnoreEnd
|
// @codeCoverageIgnoreEnd
|
||||||
}
|
}
|
||||||
|
@ -159,11 +157,11 @@ class Link extends Entity
|
||||||
try {
|
try {
|
||||||
return DB::findOneBy('link', ['url_hash' => $url_hash]);
|
return DB::findOneBy('link', ['url_hash' => $url_hash]);
|
||||||
} catch (NotFoundException) {
|
} catch (NotFoundException) {
|
||||||
$headers = array_change_key_case($headers, CASE_LOWER);
|
$headers = array_change_key_case($headers, \CASE_LOWER);
|
||||||
$link = self::create([
|
$link = self::create([
|
||||||
'url' => $url,
|
'url' => $url,
|
||||||
'url_hash' => $url_hash,
|
'url_hash' => $url_hash,
|
||||||
'mimetype' => $headers['content-type'][0],
|
'mimetype' => $headers['content-type'][0] ?? null,
|
||||||
]);
|
]);
|
||||||
DB::persist($link);
|
DB::persist($link);
|
||||||
Event::handle('LinkStoredNew', [&$link]);
|
Event::handle('LinkStoredNew', [&$link]);
|
|
@ -26,7 +26,6 @@ namespace Component\Link;
|
||||||
use App\Core\DB\DB;
|
use App\Core\DB\DB;
|
||||||
use App\Core\Event;
|
use App\Core\Event;
|
||||||
use App\Core\Modules\Component;
|
use App\Core\Modules\Component;
|
||||||
use App\Entity;
|
|
||||||
use App\Entity\Note;
|
use App\Entity\Note;
|
||||||
use App\Entity\NoteToLink;
|
use App\Entity\NoteToLink;
|
||||||
use App\Util\Common;
|
use App\Util\Common;
|
||||||
|
@ -56,7 +55,7 @@ class Link extends Component
|
||||||
return Event::next;
|
return Event::next;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onRenderPlainTextContent(string &$text): bool
|
public function onRenderPlainTextNoteContent(string &$text): bool
|
||||||
{
|
{
|
||||||
$text = $this->replaceURLs($text);
|
$text = $this->replaceURLs($text);
|
||||||
return Event::next;
|
return Event::next;
|
||||||
|
|
|
@ -42,17 +42,11 @@ use App\Core\DB\DB;
|
||||||
use App\Core\Event;
|
use App\Core\Event;
|
||||||
use App\Core\GSFile;
|
use App\Core\GSFile;
|
||||||
use App\Core\HTTPClient;
|
use App\Core\HTTPClient;
|
||||||
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
|
||||||
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
|
|
||||||
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
|
|
||||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
|
||||||
use function App\Core\I18n\_m;
|
use function App\Core\I18n\_m;
|
||||||
use App\Core\Log;
|
use App\Core\Log;
|
||||||
use App\Core\Modules\Plugin;
|
use App\Core\Modules\Plugin;
|
||||||
use App\Core\Router\RouteLoader;
|
use App\Core\Router\RouteLoader;
|
||||||
use App\Core\Router\Router;
|
use App\Core\Router\Router;
|
||||||
use Component\Attachment\Entity\Attachment;
|
|
||||||
use App\Entity\Link;
|
|
||||||
use App\Entity\Note;
|
use App\Entity\Note;
|
||||||
use App\Util\Common;
|
use App\Util\Common;
|
||||||
use App\Util\Exception\ClientException;
|
use App\Util\Exception\ClientException;
|
||||||
|
@ -61,9 +55,15 @@ use App\Util\Exception\NotFoundException;
|
||||||
use App\Util\Exception\ServerException;
|
use App\Util\Exception\ServerException;
|
||||||
use App\Util\Formatting;
|
use App\Util\Formatting;
|
||||||
use App\Util\TemporaryFile;
|
use App\Util\TemporaryFile;
|
||||||
|
use Component\Attachment\Entity\Attachment;
|
||||||
|
use Component\Link\Entity\Link;
|
||||||
use Embed\Embed as LibEmbed;
|
use Embed\Embed as LibEmbed;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
|
||||||
|
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
|
||||||
|
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
|
||||||
|
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for the Embed plugin that does most of the heavy lifting to get
|
* Base class for the Embed plugin that does most of the heavy lifting to get
|
||||||
|
@ -190,7 +190,7 @@ class Embed extends Plugin
|
||||||
{
|
{
|
||||||
// Only handle text mime
|
// Only handle text mime
|
||||||
$mimetype = $link->getMimetype();
|
$mimetype = $link->getMimetype();
|
||||||
if (!(Formatting::startsWith($mimetype, 'text/html') || Formatting::startsWith($mimetype, 'application/xhtml+xml'))) {
|
if (\is_null($mimetype) || !(Formatting::startsWith($mimetype, 'text/html') || Formatting::startsWith($mimetype, 'application/xhtml+xml'))) {
|
||||||
return Event::next;
|
return Event::next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,9 +291,9 @@ class Embed extends Plugin
|
||||||
$metadata['author_name'] = $info->authorName;
|
$metadata['author_name'] = $info->authorName;
|
||||||
$root_url = parse_url($url);
|
$root_url = parse_url($url);
|
||||||
$root_url = "{$root_url['scheme']}://{$root_url['host']}";
|
$root_url = "{$root_url['scheme']}://{$root_url['host']}";
|
||||||
$metadata['author_url'] = $info->authorUrl ? (string)$info->authorUrl : $root_url;
|
$metadata['author_url'] = $info->authorUrl ? (string) $info->authorUrl : $root_url;
|
||||||
$metadata['provider_name'] = $info->providerName;
|
$metadata['provider_name'] = $info->providerName;
|
||||||
$metadata['provider_url'] = (string)$info->providerUrl ?? $metadata['author_name'];
|
$metadata['provider_url'] = (string) $info->providerUrl ?? $metadata['author_name'];
|
||||||
|
|
||||||
if (!\is_null($info->image)) {
|
if (!\is_null($info->image)) {
|
||||||
$thumbnail_url = (string) $info->image;
|
$thumbnail_url = (string) $info->image;
|
||||||
|
@ -352,7 +352,7 @@ class Embed extends Plugin
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate if the URL really does point to a remote image
|
// Validate if the URL really does point to a remote image
|
||||||
$head = HTTPClient::head($url);
|
$head = HTTPClient::head($url);
|
||||||
try {
|
try {
|
||||||
$headers = $head->getHeaders();
|
$headers = $head->getHeaders();
|
||||||
} catch (ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface $e) {
|
} catch (ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface $e) {
|
||||||
|
@ -368,7 +368,7 @@ class Embed extends Plugin
|
||||||
// Does it respect the file quota?
|
// Does it respect the file quota?
|
||||||
$file_size = $headers['content-length'][0] ?? null;
|
$file_size = $headers['content-length'][0] ?? null;
|
||||||
$max_size = Common::config('attachments', 'file_quota');
|
$max_size = Common::config('attachments', 'file_quota');
|
||||||
if (is_null($file_size) || $file_size > $max_size) {
|
if (\is_null($file_size) || $file_size > $max_size) {
|
||||||
Log::debug("Went to download remote thumbnail of size {$file_size} but the upload limit is {$max_size} so we aborted in Embed->downloadThumbnail.");
|
Log::debug("Went to download remote thumbnail of size {$file_size} but the upload limit is {$max_size} so we aborted in Embed->downloadThumbnail.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,16 +27,16 @@ use App\Core\HTTPClient;
|
||||||
use function App\Core\I18n\_m;
|
use function App\Core\I18n\_m;
|
||||||
use App\Core\Log;
|
use App\Core\Log;
|
||||||
use App\Core\Modules\Plugin;
|
use App\Core\Modules\Plugin;
|
||||||
use Component\Attachment\Entity\AttachmentThumbnail;
|
|
||||||
use Component\Attachment\Entity\AttachmentToLink;
|
|
||||||
use Component\Attachment\Entity\AttachmentToNote;
|
|
||||||
use App\Entity\Link;
|
|
||||||
use App\Entity\Note;
|
use App\Entity\Note;
|
||||||
use App\Util\Common;
|
use App\Util\Common;
|
||||||
use App\Util\Exception\DuplicateFoundException;
|
use App\Util\Exception\DuplicateFoundException;
|
||||||
use App\Util\Exception\ServerException;
|
use App\Util\Exception\ServerException;
|
||||||
use App\Util\Exception\TemporaryFileException;
|
use App\Util\Exception\TemporaryFileException;
|
||||||
use App\Util\TemporaryFile;
|
use App\Util\TemporaryFile;
|
||||||
|
use Component\Attachment\Entity\AttachmentThumbnail;
|
||||||
|
use Component\Attachment\Entity\AttachmentToLink;
|
||||||
|
use Component\Attachment\Entity\AttachmentToNote;
|
||||||
|
use Component\Link\Entity\Link;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The StoreRemoteMedia plugin downloads remotely attached files to local server.
|
* The StoreRemoteMedia plugin downloads remotely attached files to local server.
|
||||||
|
@ -139,7 +139,7 @@ class StoreRemoteMedia extends Plugin
|
||||||
// Retrieve media
|
// Retrieve media
|
||||||
$get_response = HTTPClient::get($link->getUrl());
|
$get_response = HTTPClient::get($link->getUrl());
|
||||||
$media = $get_response->getContent();
|
$media = $get_response->getContent();
|
||||||
$mimetype = $get_response->getHeaders()['content-type'][0];
|
$mimetype = $get_response->getHeaders()['content-type'][0] ?? null;
|
||||||
unset($get_response);
|
unset($get_response);
|
||||||
|
|
||||||
// Ensure we still want to handle it
|
// Ensure we still want to handle it
|
||||||
|
|
|
@ -21,8 +21,8 @@ declare(strict_types = 1);
|
||||||
|
|
||||||
namespace App\Tests\Entity;
|
namespace App\Tests\Entity;
|
||||||
|
|
||||||
use App\Entity\Link;
|
|
||||||
use App\Util\GNUsocialTestCase;
|
use App\Util\GNUsocialTestCase;
|
||||||
|
use Component\Link\Entity\Link;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use Jchook\AssertThrows\AssertThrows;
|
use Jchook\AssertThrows\AssertThrows;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user