forked from GNUsocial/gnu-social
[Posting] Extract and store URLs from note content. Introduce 'AttachmentStoreNew' event
This commit is contained in:
parent
cc47cda3d1
commit
c1db9bd0a3
@ -41,6 +41,13 @@ use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
|||||||
|
|
||||||
class Posting extends Component
|
class Posting extends Component
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* "Perfect URL Regex", courtesy of https://urlregex.com/
|
||||||
|
*/
|
||||||
|
const URL_REGEX = <<<END
|
||||||
|
%(?:(?:https?|ftp)://)(?:\\S+(?::\\S*)?@|\\d{1,3}(?:\\.\\d{1,3}){3}|(?:(?:[a-z\\d\\x{00a1}-\\x{ffff}]+-?)*[a-z\\d\\x{00a1}-\\x{ffff}]+)(?:\\.(?:[a-z\\d\\x{00a1}-\\x{ffff}]+-?)*[a-z\\d\\x{00a1}-\\x{ffff}]+)*(?:\\.[a-z\\x{00a1}-\\x{ffff}]{2,6}))(?::\\d+)?(?:[^\\s]*)?%iu
|
||||||
|
END;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HTML render event handler responsible for adding and handling
|
* HTML render event handler responsible for adding and handling
|
||||||
* the result of adding the note submission form, only if a user is logged in
|
* the result of adding the note submission form, only if a user is logged in
|
||||||
@ -96,24 +103,32 @@ class Posting extends Component
|
|||||||
*/
|
*/
|
||||||
public static function storeNote(int $actor_id, ?string $content, array $attachments, bool $is_local, ?int $reply_to = null, ?int $repeat_of = null)
|
public static function storeNote(int $actor_id, ?string $content, array $attachments, bool $is_local, ?int $reply_to = null, ?int $repeat_of = null)
|
||||||
{
|
{
|
||||||
|
$content = Security::sanitize($content);
|
||||||
$note = Note::create([
|
$note = Note::create([
|
||||||
'gsactor_id' => $actor_id,
|
'gsactor_id' => $actor_id,
|
||||||
'content' => Security::sanitize($content),
|
'content' => $content,
|
||||||
'is_local' => $is_local,
|
'is_local' => $is_local,
|
||||||
'reply_to' => $reply_to,
|
'reply_to' => $reply_to,
|
||||||
'repeat_of' => $repeat_of,
|
'repeat_of' => $repeat_of,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$processed_attachments = [];
|
$processed_attachments = [];
|
||||||
foreach ($attachments as $f) {
|
foreach ($attachments as $f) {
|
||||||
$na = GSFile::validateAndStoreAttachment(
|
$processed_attachments[] = GSFile::validateAndStoreAttachment(
|
||||||
$f, Common::config('attachments', 'dir'),
|
$f, Common::config('attachments', 'dir'),
|
||||||
Security::sanitize($title = $f->getClientOriginalName()),
|
Security::sanitize($f->getClientOriginalName()),
|
||||||
$is_local = true, $actor_id
|
is_local: true, actor_id: $actor_id
|
||||||
);
|
);
|
||||||
$processed_attachments[] = $na;
|
|
||||||
DB::persist($na);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$matched_urls = [];
|
||||||
|
preg_match_all(self::URL_REGEX, $content, $matched_urls, PREG_SET_ORDER);
|
||||||
|
foreach ($matched_urls as $match) {
|
||||||
|
$processed_attachments[] = GSFile::validateAndStoreURL($url);
|
||||||
|
}
|
||||||
|
|
||||||
DB::persist($note);
|
DB::persist($note);
|
||||||
|
|
||||||
// Need file and note ids for the next step
|
// Need file and note ids for the next step
|
||||||
DB::flush();
|
DB::flush();
|
||||||
if ($processed_attachments != []) {
|
if ($processed_attachments != []) {
|
||||||
|
@ -57,20 +57,33 @@ class GSFile
|
|||||||
'is_local' => $is_local,
|
'is_local' => $is_local,
|
||||||
]);
|
]);
|
||||||
$sfile->move($dest_dir, $hash);
|
$sfile->move($dest_dir, $hash);
|
||||||
|
DB::persist($attachment);
|
||||||
|
Event::handle('AttachmentStoreNew', [&$attachment]);
|
||||||
return $attachment;
|
return $attachment;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform file validation (checks and normalization) and store the given file
|
* Create an attachment for the given URL, fetching the mimetype
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public static function validateAndStoreAttachmentThumbnail(SymfonyFile $sfile,
|
public static function validateAndStoreURL(string $url): Attachment
|
||||||
string $dest_dir,
|
|
||||||
?string $title = null,
|
|
||||||
bool $is_local = true,
|
|
||||||
int $actor_id = null): Attachment//Thumbnail
|
|
||||||
{
|
{
|
||||||
$attachment = self::validateAndStoreAttachment($sfile,$dest_dir,$title,$is_local,$actor_id);
|
if (Common::isValidHttpUrl($url)) {
|
||||||
|
HTTPClient::head($url);
|
||||||
|
$headers = $head->getHeaders();
|
||||||
|
$headers = array_change_key_case($headers, CASE_LOWER);
|
||||||
|
$attachment = Attachment::create([
|
||||||
|
'remote_url' => $match[0],
|
||||||
|
'remote_url_hash' => hash('sha256', $match[0]),
|
||||||
|
'mimetype' => $headers['content-type'],
|
||||||
|
]);
|
||||||
|
DB::persist($attachment);
|
||||||
|
Event::handle('AttachmentStoreNew', [&$at]);
|
||||||
return $attachment;
|
return $attachment;
|
||||||
|
} else {
|
||||||
|
throw new \InvalidArgumentException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -159,7 +172,7 @@ class GSFile
|
|||||||
*/
|
*/
|
||||||
public static function mimetypeMajor(string $mime)
|
public static function mimetypeMajor(string $mime)
|
||||||
{
|
{
|
||||||
return explode('/', self::mimeBare($mime))[0];
|
return explode('/', self::mimetypeBare($mime))[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -167,13 +180,13 @@ class GSFile
|
|||||||
*/
|
*/
|
||||||
public static function mimetypeMinor(string $mime)
|
public static function mimetypeMinor(string $mime)
|
||||||
{
|
{
|
||||||
return explode('/', self::mimeBare($mime))[1];
|
return explode('/', self::mimetypeBare($mime))[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get only the mimetype and not additional info (separated from bare mime with semi-colon)
|
* Get only the mimetype and not additional info (separated from bare mime with semi-colon)
|
||||||
*/
|
*/
|
||||||
public static function mimeBare(string $mimetype)
|
public static function mimetypeBare(string $mimetype)
|
||||||
{
|
{
|
||||||
$mimetype = mb_strtolower($mimetype);
|
$mimetype = mb_strtolower($mimetype);
|
||||||
if (($semicolon = mb_strpos($mimetype, ';')) !== false) {
|
if (($semicolon = mb_strpos($mimetype, ';')) !== false) {
|
||||||
|
Loading…
Reference in New Issue
Block a user