diff --git a/core/extension.php b/core/extension.php index 3822d9d1..7ef28fb2 100644 --- a/core/extension.php +++ b/core/extension.php @@ -313,43 +313,20 @@ abstract class DataHandlerExtension extends Extension if (is_null($existing)) { throw new UploadException("Post to replace does not exist!"); } - if ($existing->hash === $event->metadata['hash']) { + if ($existing->hash === $event->hash) { throw new UploadException("The uploaded post is the same as the one to replace."); } // even more hax.. $event->metadata['tags'] = $existing->get_tag_list(); - $image = $this->create_image_from_data(warehouse_path(Image::IMAGE_DIR, $event->metadata['hash']), $event->metadata); - if (is_null($image)) { - throw new UploadException("Data handler failed to create post object from data"); - } - if (empty($image->get_mime())) { - throw new UploadException("Unable to determine MIME for ". $event->tmpname); - } - try { - send_event(new MediaCheckPropertiesEvent($image)); - } catch (MediaException $e) { - throw new UploadException("Unable to scan media properties: ".$e->getMessage()); - } + $image = $this->create_image_from_data(warehouse_path(Image::IMAGE_DIR, $event->hash), $event->metadata); send_event(new ImageReplaceEvent($event->replace_id, $image)); $_id = $event->replace_id; assert(!is_null($_id)); $event->image_id = $_id; } else { $image = $this->create_image_from_data(warehouse_path(Image::IMAGE_DIR, $event->hash), $event->metadata); - if (is_null($image)) { - throw new UploadException("Data handler failed to create post object from data"); - } - if (empty($image->get_mime())) { - throw new UploadException("Unable to determine MIME for ". $event->tmpname); - } - try { - send_event(new MediaCheckPropertiesEvent($image)); - } catch (MediaException $e) { - throw new UploadException("Unable to scan media properties: ".$e->getMessage()); - } - $iae = send_event(new ImageAdditionEvent($image)); $event->image_id = $iae->image->id; $event->merged = $iae->merged; @@ -402,7 +379,7 @@ abstract class DataHandlerExtension extends Extension public function onMediaCheckProperties(MediaCheckPropertiesEvent $event) { - if ($this->supported_mime($event->mime)) { + if ($this->supported_mime($event->image->get_mime())) { $this->media_check_properties($event); } } @@ -411,19 +388,23 @@ abstract class DataHandlerExtension extends Extension { $image = new Image(); - $image->filesize = $metadata['size']; - $image->hash = $metadata['hash']; + assert(is_readable($filename)); + $image->filesize = filesize($filename); + $image->hash = md5_file($filename); $image->filename = (($pos = strpos($metadata['filename'], '?')) !== false) ? substr($metadata['filename'], 0, $pos) : $metadata['filename']; - - if (array_key_exists("extension", $metadata)) { - $image->set_mime(MimeType::get_for_file($filename, $metadata["extension"])); - } else { - $image->set_mime(MimeType::get_for_file($filename)); - } - + $image->set_mime(MimeType::get_for_file($filename, get_file_ext($metadata["filename"]) ?? null)); $image->tag_array = is_array($metadata['tags']) ? $metadata['tags'] : Tag::explode($metadata['tags']); $image->source = $metadata['source']; + if (empty($image->get_mime())) { + throw new UploadException("Unable to determine MIME for $filename"); + } + try { + send_event(new MediaCheckPropertiesEvent($image)); + } catch (MediaException $e) { + throw new UploadException("Unable to scan media properties $filename / $image->filename / $image->hash: ".$e->getMessage()); + } + return $image; } diff --git a/core/imageboard/misc.php b/core/imageboard/misc.php index b65938ab..e9944606 100644 --- a/core/imageboard/misc.php +++ b/core/imageboard/misc.php @@ -39,22 +39,18 @@ function add_dir(string $base): array /** * Sends a DataUploadEvent for a file. */ -function add_image(string $tmpname, string $filename, string $tags): int +function add_image(string $tmpname, string $filename, string $tags, ?string $source=null): DataUploadEvent { - assert(file_exists($tmpname)); + return send_event(new DataUploadEvent($tmpname, [ + 'filename' => pathinfo($filename, PATHINFO_BASENAME), + 'tags' => Tag::explode($tags), + 'source' => $source, + ])); +} - $pathinfo = pathinfo($filename); - $metadata = []; - $metadata['filename'] = $pathinfo['basename']; - if (array_key_exists('extension', $pathinfo)) { - $metadata['extension'] = $pathinfo['extension']; - } - - $metadata['tags'] = Tag::explode($tags); - $metadata['source'] = null; - - $due = send_event(new DataUploadEvent($tmpname, $metadata)); - return $due->image_id; +function get_file_ext(string $filename): ?string +{ + return pathinfo($filename)['extension'] ?? null; } /** diff --git a/ext/bulk_add_csv/main.php b/ext/bulk_add_csv/main.php index 5bdb9252..6dfcb488 100644 --- a/ext/bulk_add_csv/main.php +++ b/ext/bulk_add_csv/main.php @@ -50,17 +50,7 @@ class BulkAddCSV extends Extension */ private function add_image(string $tmpname, string $filename, string $tags, string $source, string $rating, string $thumbfile) { - assert(file_exists($tmpname)); - - $pathinfo = pathinfo($filename); - $metadata = []; - $metadata['filename'] = $pathinfo['basename']; - if (array_key_exists('extension', $pathinfo)) { - $metadata['extension'] = $pathinfo['extension']; - } - $metadata['tags'] = Tag::explode($tags); - $metadata['source'] = $source; - $event = send_event(new DataUploadEvent($tmpname, $metadata)); + $event = add_image($tmpname, $filename, $tags, $source); if ($event->image_id == -1) { throw new UploadException("File type not recognised"); } else { @@ -105,12 +95,11 @@ class BulkAddCSV extends Extension $source = $csvdata[2]; $rating = $csvdata[3]; $thumbfile = $csvdata[4]; - $pathinfo = pathinfo($fullpath); - $shortpath = $pathinfo["basename"]; + $shortpath = pathinfo($fullpath, PATHINFO_BASENAME); $list .= "
".html_escape("$shortpath (".str_replace(" ", ", ", $tags).")... "); if (file_exists($csvdata[0]) && is_file($csvdata[0])) { try { - $this->add_image($fullpath, $pathinfo["basename"], $tags, $source, $rating, $thumbfile); + $this->add_image($fullpath, $shortpath, $tags, $source, $rating, $thumbfile); $list .= "ok\n"; } catch (\Exception $ex) { $list .= "failed:
". $ex->getMessage(); diff --git a/ext/bulk_import_export/main.php b/ext/bulk_import_export/main.php index 03982ae2..5f635784 100644 --- a/ext/bulk_import_export/main.php +++ b/ext/bulk_import_export/main.php @@ -52,7 +52,7 @@ class BulkImportExport extends DataHandlerExtension file_put_contents($tmpfile, $stream); - $id = add_image($tmpfile, $item->filename, Tag::implode($item->tags)); + $id = add_image($tmpfile, $item->filename, Tag::implode($item->tags))->image_id; if ($id==-1) { throw new SCoreException("Unable to import file $item->hash"); diff --git a/ext/cron_uploader/main.php b/ext/cron_uploader/main.php index 5e49a03d..8da3c467 100644 --- a/ext/cron_uploader/main.php +++ b/ext/cron_uploader/main.php @@ -466,29 +466,11 @@ class CronUploader extends Extension */ private function add_image(string $tmpname, string $filename, string $tags): DataUploadEvent { - assert(file_exists($tmpname)); - - $tagArray = Tag::explode($tags); - if (count($tagArray) == 0) { - $tagArray[] = "tagme"; - } - - $pathinfo = pathinfo($filename); - $metadata = []; - $metadata ['filename'] = $pathinfo ['basename']; - if (array_key_exists('extension', $pathinfo)) { - $metadata ['extension'] = $pathinfo ['extension']; - } - $metadata ['tags'] = $tagArray; - $metadata ['source'] = null; - $event = send_event(new DataUploadEvent($tmpname, $metadata)); + $event = add_image($tmpname, $filename, $tags, null); // Generate info message if ($event->image_id == -1) { - if (array_key_exists("mime", $event->metadata)) { - throw new UploadException("File type not recognised (".$event->metadata["mime"]."). Filename: {$filename}"); - } - throw new UploadException("File type not recognised. Filename: {$filename}"); + throw new UploadException("File type not recognised (".$event->mime."). Filename: {$filename}"); } elseif ($event->merged === true) { $infomsg = "Post merged. ID: {$event->image_id} - Filename: {$filename}"; } else { @@ -529,14 +511,12 @@ class CronUploader extends Extension $ite = new \RecursiveDirectoryIterator($base, \FilesystemIterator::SKIP_DOTS); foreach (new \RecursiveIteratorIterator($ite) as $fullpath => $cur) { if (!is_link($fullpath) && !is_dir($fullpath) && !$this->is_skippable_file($fullpath)) { - $pathinfo = pathinfo($fullpath); - $relativePath = substr($fullpath, strlen($base)); $tags = path_to_tags($relativePath); yield [ 0 => $fullpath, - 1 => $pathinfo ["basename"], + 1 => pathinfo($fullpath, PATHINFO_BASENAME), 2 => $tags ]; } diff --git a/ext/danbooru_api/main.php b/ext/danbooru_api/main.php index 9f0a84f8..6b46ef20 100644 --- a/ext/danbooru_api/main.php +++ b/ext/danbooru_api/main.php @@ -336,22 +336,13 @@ class DanbooruApi extends Extension return; } - // Fire off an event which should process the new file and add it to the db - $fileinfo = pathinfo($filename); - $metadata = []; - $metadata['filename'] = $fileinfo['basename']; - if (array_key_exists('extension', $fileinfo)) { - $metadata['extension'] = $fileinfo['extension']; - } - $metadata['tags'] = $posttags; - $metadata['source'] = $source; //log_debug("danbooru_api","========== NEW($filename) ========="); //log_debug("danbooru_api", "upload($filename): fileinfo(".var_export($fileinfo,TRUE)."), metadata(".var_export($metadata,TRUE).")..."); try { - $nevent = new DataUploadEvent($file, $metadata); + // Fire off an event which should process the new file and add it to the db + $nevent = add_image($file, $filename, $posttags, $source); //log_debug("danbooru_api", "send_event(".var_export($nevent,TRUE).")"); - send_event($nevent); // If it went ok, grab the id for the newly uploaded image and pass it in the header $newimg = Image::by_hash($hash); // FIXME: Unsupported file doesn't throw an error? $newid = make_link("post/view/" . $newimg->id); diff --git a/ext/emoticons_list/theme.php b/ext/emoticons_list/theme.php index d545e03e..1f01a34b 100644 --- a/ext/emoticons_list/theme.php +++ b/ext/emoticons_list/theme.php @@ -14,8 +14,7 @@ class EmoticonListTheme extends Themelet $html .= ""; $n = 1; foreach ($list as $item) { - $pathinfo = pathinfo($item); - $name = $pathinfo["filename"]; + $name = pathinfo($item, PATHINFO_FILENAME); $html .= ""; if ($n++ % 3 == 0) { $html .= ""; diff --git a/ext/handle_cbz/main.php b/ext/handle_cbz/main.php index 2a6ac9c0..1ff44636 100644 --- a/ext/handle_cbz/main.php +++ b/ext/handle_cbz/main.php @@ -15,7 +15,7 @@ class CBZFileHandler extends DataHandlerExtension $event->image->audio = false; $event->image->image = false; - $tmp = $this->get_representative_image($event->file_name); + $tmp = $this->get_representative_image($event->image->get_image_filename()); $info = getimagesize($tmp); if ($info) { $event->image->width = $info[0]; diff --git a/ext/handle_flash/main.php b/ext/handle_flash/main.php index d0ab7127..8670ef65 100644 --- a/ext/handle_flash/main.php +++ b/ext/handle_flash/main.php @@ -14,7 +14,7 @@ class FlashFileHandler extends DataHandlerExtension $event->image->video = true; $event->image->image = false; - $info = getimagesize($event->file_name); + $info = getimagesize($event->image->get_image_filename()); if ($info) { $event->image->width = $info[0]; $event->image->height = $info[1]; diff --git a/ext/handle_ico/main.php b/ext/handle_ico/main.php index a6c50b09..2b03096d 100644 --- a/ext/handle_ico/main.php +++ b/ext/handle_ico/main.php @@ -13,9 +13,9 @@ class IcoFileHandler extends DataHandlerExtension $event->image->lossless = true; $event->image->video = false; $event->image->audio = false; - $event->image->image = ($event->mime!= MimeType::ANI); + $event->image->image = ($event->image->get_mime() != MimeType::ANI); - $fp = fopen($event->file_name, "r"); + $fp = fopen($event->image->get_image_filename(), "r"); try { unpack("Snull/Stype/Scount", fread($fp, 6)); $subheader = unpack("Cwidth/Cheight/Ccolours/Cnull/Splanes/Sbpp/Lsize/loffset", fread($fp, 16)); diff --git a/ext/handle_pixel/main.php b/ext/handle_pixel/main.php index cc758b8e..eab2bfc7 100644 --- a/ext/handle_pixel/main.php +++ b/ext/handle_pixel/main.php @@ -10,14 +10,17 @@ class PixelFileHandler extends DataHandlerExtension protected function media_check_properties(MediaCheckPropertiesEvent $event): void { - $event->image->lossless = Media::is_lossless($event->file_name, $event->mime); + $filename = $event->image->get_image_filename(); + $mime = $event->image->get_mime(); + + $event->image->lossless = Media::is_lossless($filename, $mime); $event->image->audio = false; - switch ($event->mime) { + switch ($mime) { case MimeType::GIF: - $event->image->video = MimeType::is_animated_gif($event->file_name); + $event->image->video = MimeType::is_animated_gif($filename); break; case MimeType::WEBP: - $event->image->video = MimeType::is_animated_webp($event->file_name); + $event->image->video = MimeType::is_animated_webp($filename); break; default: $event->image->video = false; @@ -25,7 +28,7 @@ class PixelFileHandler extends DataHandlerExtension } $event->image->image = !$event->image->video; - $info = getimagesize($event->file_name); + $info = getimagesize($event->image->get_image_filename()); if ($info) { $event->image->width = $info[0]; $event->image->height = $info[1]; diff --git a/ext/handle_svg/main.php b/ext/handle_svg/main.php index 848c95a7..e4b214a4 100644 --- a/ext/handle_svg/main.php +++ b/ext/handle_svg/main.php @@ -39,7 +39,7 @@ class SVGFileHandler extends DataHandlerExtension $event->image->audio = false; $event->image->image = true; - $msp = new MiniSVGParser($event->file_name); + $msp = new MiniSVGParser($event->image->get_image_filename()); $event->image->width = $msp->width; $event->image->height = $msp->height; } @@ -50,6 +50,7 @@ class SVGFileHandler extends DataHandlerExtension $sanitizer->removeRemoteReferences(true); $dirtySVG = file_get_contents($event->tmpname); $cleanSVG = $sanitizer->sanitize($dirtySVG); + $event->hash = md5($cleanSVG); file_put_contents(warehouse_path(Image::IMAGE_DIR, $event->hash), $cleanSVG); } diff --git a/ext/handle_svg/test.php b/ext/handle_svg/test.php index 7a2660e8..60652ffe 100644 --- a/ext/handle_svg/test.php +++ b/ext/handle_svg/test.php @@ -18,7 +18,7 @@ class SVGFileHandlerTest extends ShimmiePHPUnitTestCase # FIXME: test that it gets displayed properly } - public function testAbuiveSVG() + public function testAbusiveSVG() { $this->log_in_as_user(); $image_id = $this->post_image("tests/alert.svg", "something"); diff --git a/ext/handle_video/main.php b/ext/handle_video/main.php index 49e73160..2ae4f627 100644 --- a/ext/handle_video/main.php +++ b/ext/handle_video/main.php @@ -64,7 +64,7 @@ class VideoFileHandler extends DataHandlerExtension $event->image->video = true; $event->image->image = false; try { - $data = Media::get_ffprobe_data($event->file_name); + $data = Media::get_ffprobe_data($event->image->get_image_filename()); if (is_array($data)) { if (array_key_exists("streams", $data)) { diff --git a/ext/media/events.php b/ext/media/events.php index 0ea62c3b..a7bce3f4 100644 --- a/ext/media/events.php +++ b/ext/media/events.php @@ -55,15 +55,8 @@ class MediaResizeEvent extends Event class MediaCheckPropertiesEvent extends Event { - public Image $image; - public string $file_name; - public string $mime; - - public function __construct(Image $image) + public function __construct(public Image $image) { parent::__construct(); - $this->image = $image; - $this->file_name = warehouse_path(Image::IMAGE_DIR, $image->hash); - $this->mime = strtolower($image->get_mime()); } } diff --git a/ext/transcode/main.php b/ext/transcode/main.php index 9125c013..e284e81e 100644 --- a/ext/transcode/main.php +++ b/ext/transcode/main.php @@ -168,20 +168,18 @@ class TranscodeImage extends Extension global $config; if ($config->get_bool(TranscodeConfig::UPLOAD) == true) { - $mime = strtolower($event->mime); - if ($mime===MimeType::GIF&&MimeType::is_animated_gif($event->tmpname)) { + if ($event->mime === MimeType::GIF&&MimeType::is_animated_gif($event->tmpname)) { return; } - if (in_array($mime, array_values(self::INPUT_MIMES))) { - $target_mime = self::get_mapping($mime); + if (in_array($event->mime, array_values(self::INPUT_MIMES))) { + $target_mime = self::get_mapping($event->mime); if (empty($target_mime)) { return; } try { - $new_image = $this->transcode_image($event->tmpname, $mime, $target_mime); - $event->set_mime($target_mime); - $event->set_tmpname($new_image); + $new_image = $this->transcode_image($event->tmpname, $event->mime, $target_mime); + $event->set_tmpname($new_image, $target_mime); } catch (\Exception $e) { log_error("transcode", "Error while performing upload transcode: ".$e->getMessage()); // We don't want to interfere with the upload process, diff --git a/ext/transcode_video/main.php b/ext/transcode_video/main.php index e431d090..9a778f8a 100644 --- a/ext/transcode_video/main.php +++ b/ext/transcode_video/main.php @@ -85,8 +85,7 @@ class TranscodeVideo extends Extension // } // try { // $new_image = $this->transcode_image($event->tmpname, $ext, $target_format); -// $event->set_mime(Media::determine_ext($target_format)); -// $event->set_tmpname($new_image); +// $event->set_tmpname($new_image, Media::determine_ext($target_format)); // } catch (Exception $e) { // log_error("transcode_video", "Error while performing upload transcode: ".$e->getMessage()); // // We don't want to interfere with the upload process, diff --git a/ext/upload/main.php b/ext/upload/main.php index 205dfa31..8ebc2f2d 100644 --- a/ext/upload/main.php +++ b/ext/upload/main.php @@ -11,63 +11,46 @@ require_once "config.php"; */ class DataUploadEvent extends Event { - public string $tmpname; - public array $metadata; public string $hash; - public string $mime = ""; + public string $mime; + public int $size; + public int $image_id = -1; - public ?int $replace_id = null; public bool $handled = false; public bool $merged = false; /** * Some data is being uploaded. * This should be caught by a file handler. - * $metadata should contain at least "filename", "extension", "tags" and "source". */ - public function __construct(string $tmpname, array $metadata, ?int $replace_id = null) - { + public function __construct( + public string $tmpname, + public array $metadata, + public ?int $replace_id = null + ) { parent::__construct(); - assert(file_exists($tmpname)); + $this->set_tmpname($tmpname); assert(is_string($metadata["filename"])); assert(is_array($metadata["tags"])); assert(is_string($metadata["source"]) || is_null($metadata["source"])); // DB limits to 255 char filenames $metadata['filename'] = substr($metadata['filename'], 0, 255); - - $this->metadata = $metadata; - $this->replace_id = $replace_id; - - $this->set_tmpname($tmpname); - - if (array_key_exists("extension", $metadata)) { - $mime = MimeType::get_for_file($tmpname, $metadata["extension"]); - } else { - $mime = MimeType::get_for_file($tmpname); - } - - if (empty($mime)) { - throw new UploadException("Could not determine mime type for file " . $metadata["filename"]); - } - - $this->set_mime($mime); } - public function set_mime(String $mime) - { - $this->mime = strtolower($mime); - $this->metadata["mime"] = $this->mime; - } - - public function set_tmpname(String $tmpname) + public function set_tmpname(string $tmpname, ?string $mime=null) { + assert(is_readable($tmpname)); $this->tmpname = $tmpname; - $this->metadata['hash'] = md5_file($tmpname); - $this->metadata['size'] = filesize($tmpname); - // useful for most file handlers, so pull directly into fields - $this->hash = $this->metadata['hash']; + $this->hash = md5_file($tmpname); + $this->size = filesize($tmpname); + $mime = $mime ?? MimeType::get_for_file($tmpname, get_file_ext($this->metadata["filename"]) ?? null); + if (empty($mime)) { + throw new UploadException("Could not determine mime type"); + } + + $this->mime = strtolower($mime); } } @@ -162,8 +145,8 @@ class Upload extends Extension if ($this->is_full) { throw new UploadException("Upload failed; disk nearly full"); } - if (filesize($event->tmpname) > $config->get_int(UploadConfig::SIZE)) { - $size = to_shorthand_int(filesize($event->tmpname)); + if ($event->size > $config->get_int(UploadConfig::SIZE)) { + $size = to_shorthand_int($event->size); $limit = to_shorthand_int($config->get_int(UploadConfig::SIZE)); throw new UploadException("File too large ($size > $limit)"); } @@ -343,22 +326,15 @@ class Upload extends Extension throw new UploadException($this->upload_error_message($file['error'][$i])); } - $pathinfo = pathinfo($file['name'][$i]); $metadata = []; - $metadata['filename'] = $pathinfo['basename']; - $metadata['extension'] = $pathinfo['extension'] ?? ""; - $metadata['mime'] = MimeType::get_for_file($file['tmp_name'][$i], $metadata['extension']); - if (empty($metadata['mime'])) { - throw new UploadException("Unable to determine MIME for file " . $metadata['filename']); - } - + $metadata['filename'] = pathinfo($file['name'][$i], PATHINFO_BASENAME); $metadata['tags'] = $tags; $metadata['source'] = $source; $event = new DataUploadEvent($file['tmp_name'][$i], $metadata, $replace_id); send_event($event); if ($event->image_id == -1) { - throw new UploadException("MIME type not supported: " . $metadata['mime']); + throw new UploadException("MIME type not supported: " . $event->mime); } $image_ids[] = $event->image_id; $page->add_http_header("X-Shimmie-Post-ID: " . $event->image_id); @@ -404,12 +380,10 @@ class Upload extends Extension $h_filename = ($s_filename ? preg_replace('/^.*filename="([^ ]+)"/i', '$1', $s_filename) : null); $filename = $h_filename ?: basename($url); - $pathinfo = pathinfo($url); $metadata = []; $metadata['filename'] = $filename; $metadata['tags'] = $tags; $metadata['source'] = (($url == $source) && !$config->get_bool(UploadConfig::TLSOURCE) ? "" : $source); - $metadata['extension'] = $pathinfo['extension'] ?? ""; if ($user->can(Permissions::EDIT_IMAGE_LOCK) && !empty($_GET['locked'])) { $metadata['locked'] = bool_escape($_GET['locked']) ? "on" : ""; } @@ -422,7 +396,7 @@ class Upload extends Extension $event = new DataUploadEvent($tmp_filename, $metadata, $replace_id); send_event($event); if ($event->image_id == -1) { - throw new UploadException("File type not supported: " . $metadata['extension']); + throw new UploadException("File type not supported: " . $event->mime); } $image_ids[] = $event->image_id; } catch (UploadException $ex) { diff --git a/tests/bootstrap.php b/tests/bootstrap.php index e6d8b72b..8203ee96 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -250,7 +250,6 @@ abstract class ShimmiePHPUnitTestCase extends TestCase { $dae = send_event(new DataUploadEvent($filename, [ "filename" => $filename, - "extension" => pathinfo($filename, PATHINFO_EXTENSION), "tags" => Tag::explode($tags), "source" => null, ]));
$name :$name: