From 0fc0b8e723cc90d86d8a8d98d7e551167824ddec Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Thu, 8 Oct 2020 16:58:57 -0500 Subject: [PATCH 1/6] Added get_pairs_iterable to database object --- core/database.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/core/database.php b/core/database.php index ea3ac36f..f9effb9a 100644 --- a/core/database.php +++ b/core/database.php @@ -258,6 +258,20 @@ class Database return $res; } + + /** + * Execute an SQL query and return the the first column => the second column as an iterable object. + */ + public function get_pairs_iterable(string $query, array $args = []): Generator + { + $_start = microtime(true); + $stmt = $this->execute($query, $args); + $this->count_time("get_pairs_iterable", $_start, $query, $args); + foreach ($stmt as $row) { + yield $row[0] => $row[1]; + } + } + /** * Execute an SQL query and return a single value, or null. */ From 79a2fe23b3ae13990d3b75edf8b2b176bda437ae Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Thu, 8 Oct 2020 17:00:51 -0500 Subject: [PATCH 2/6] Added support for specifying conflicting extensions --- core/extension.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/core/extension.php b/core/extension.php index c65418c4..b544acf0 100644 --- a/core/extension.php +++ b/core/extension.php @@ -61,7 +61,7 @@ abstract class Extension return 50; } - public static function determine_enabled_extensions() + public static function determine_enabled_extensions(): void { self::$enabled_extensions = []; foreach (array_merge( @@ -138,6 +138,7 @@ abstract class ExtensionInfo public $license; public $version; public $dependencies = []; + public $conflicts = []; public $visibility; public $description; public $documentation; @@ -193,6 +194,13 @@ abstract class ExtensionInfo if (!empty($this->db_support) && !in_array($database->get_driver_name(), $this->db_support)) { $this->support_info .= "Database not supported. "; } + if (!empty($this->conflicts)) { + $intersects = array_intersect($this->conflicts, Extension::get_enabled_extensions()); + if (!empty($intersects)) { + $this->support_info .= "Conflicts with other extension(s): " . join(", ", $intersects); + } + } + // Additional checks here as needed $this->supported = empty($this->support_info); From 6bc8b791d26627b3b226a79e1d9456c2de29320f Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Thu, 8 Oct 2020 17:07:33 -0500 Subject: [PATCH 3/6] Added option to go to next image when an image is deleted --- core/imageboard/misc.php | 24 ++++++++++++++++++++++++ ext/image/config.php | 4 ++++ ext/image/main.php | 16 ++++++++++++++-- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/core/imageboard/misc.php b/core/imageboard/misc.php index 6e13527d..8bef7bec 100644 --- a/core/imageboard/misc.php +++ b/core/imageboard/misc.php @@ -187,3 +187,27 @@ function create_scaled_image(string $inname, string $outname, array $tsize, stri true )); } + +function redirect_to_next_image(Image $image): void +{ + global $page; + + if (isset($_GET['search'])) { + $search_terms = Tag::explode(Tag::decaret($_GET['search'])); + $query = "search=" . url_escape($_GET['search']); + } else { + $search_terms = []; + $query = null; + } + + $target_image = $image->get_next($search_terms); + + if ($target_image == null) { + $redirect_target = referer_or(make_link("post/list"), ['post/view']); + } else { + $redirect_target = make_link("post/view/{$target_image->id}", null, $query); + } + + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect($redirect_target); +} diff --git a/ext/image/config.php b/ext/image/config.php index e622bef6..80666f24 100644 --- a/ext/image/config.php +++ b/ext/image/config.php @@ -23,4 +23,8 @@ abstract class ImageConfig const COLLISION_MERGE = 'merge'; const COLLISION_ERROR = 'error'; + + const ON_DELETE = 'image_on_delete'; + const ON_DELETE_NEXT = 'next'; + const ON_DELETE_LIST = 'list'; } diff --git a/ext/image/main.php b/ext/image/main.php index b3ffa092..d6dbffcb 100644 --- a/ext/image/main.php +++ b/ext/image/main.php @@ -15,6 +15,11 @@ class ImageIO extends Extension 'Merge'=>ImageConfig::COLLISION_MERGE ]; + const ON_DELETE_OPTIONS = [ + 'Return to post list'=>ImageConfig::ON_DELETE_LIST, + 'Go to next image'=>ImageConfig::ON_DELETE_NEXT + ]; + const EXIF_READ_FUNCTION = "exif_read_data"; const THUMBNAIL_ENGINES = [ @@ -70,14 +75,20 @@ class ImageIO extends Extension public function onPageRequest(PageRequestEvent $event) { + global $config; if ($event->page_matches("image/delete")) { global $page, $user; if ($user->can(Permissions::DELETE_IMAGE) && isset($_POST['image_id']) && $user->check_auth_token()) { $image = Image::by_id(int_escape($_POST['image_id'])); if ($image) { send_event(new ImageDeletionEvent($image)); - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(referer_or(make_link("post/list"), ['post/view'])); + + if ($config->get_string(ImageConfig::ON_DELETE)===ImageConfig::ON_DELETE_NEXT) { + redirect_to_next_image($image); + } else { + $page->set_mode(PageMode::REDIRECT); + $page->set_redirect(referer_or(make_link("post/list"), ['post/view'])); + } } } } elseif ($event->page_matches("image/replace")) { @@ -254,6 +265,7 @@ class ImageIO extends Extension $sb->add_text_option(ImageConfig::TIP, "Image tooltip", true); $sb->add_text_option(ImageConfig::INFO, "Image info", true); $sb->add_choice_option(ImageConfig::UPLOAD_COLLISION_HANDLER, self::COLLISION_OPTIONS, "Upload collision handler", true); + $sb->add_choice_option(ImageConfig::ON_DELETE, self::ON_DELETE_OPTIONS, "On Delete", true); if (function_exists(self::EXIF_READ_FUNCTION)) { $sb->add_bool_option(ImageConfig::SHOW_META, "Show metadata", true); } From 59bb8a31a2854ed18d6190c6b57338655352df74 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Thu, 8 Oct 2020 17:07:53 -0500 Subject: [PATCH 4/6] Relaxed filename search to allow for non alpha-numeric filenames --- ext/index/main.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/index/main.php b/ext/index/main.php index 09ba2ac5..50cdd235 100644 --- a/ext/index/main.php +++ b/ext/index/main.php @@ -208,7 +208,7 @@ class Index extends Extension } elseif (preg_match("/^(phash)[=|:]([0-9a-fA-F]*)$/i", $event->term, $matches)) { $phash = strtolower($matches[2]); $event->add_querylet(new Querylet('images.phash = :phash', ["phash" => $phash])); - } elseif (preg_match("/^(filename|name)[=|:]([a-zA-Z0-9]*)$/i", $event->term, $matches)) { + } elseif (preg_match("/^(filename|name)[=|:](.+)$/i", $event->term, $matches)) { $filename = strtolower($matches[2]); $event->add_querylet(new Querylet("lower(images.filename) LIKE :filename{$this->stpen}", ["filename{$this->stpen}"=>"%$filename%"])); } elseif (preg_match("/^(source)[=|:](.*)$/i", $event->term, $matches)) { From 49a3277cca34960b959df44d83fbf62f88b72441 Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Thu, 8 Oct 2020 17:08:22 -0500 Subject: [PATCH 5/6] Fixed imagemagick thumbnailing issue with metadata-rotated images --- ext/media/main.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/media/main.php b/ext/media/main.php index 74d7f0a7..ec644952 100644 --- a/ext/media/main.php +++ b/ext/media/main.php @@ -581,7 +581,7 @@ class Media extends Extension $resize_suffix .= "\!"; } - $args = ""; + $args = " -auto-orient "; $resize_arg = "-resize"; if ($minimize) { $args .= "-strip "; @@ -611,8 +611,8 @@ class Media extends Extension case Media::RESIZE_TYPE_FIT_BLUR: $blur_size = max(ceil(max($new_width, $new_height) / 25), 5); $args .= "${file_arg} ". - "\( -clone 0 -resize ${new_width}x${new_height}\^ -background ${bg} -flatten -gravity center -fill black -colorize 50% -extent ${new_width}x${new_height} -blur 0x${blur_size} \) ". - "\( -clone 0 -resize ${new_width}x${new_height} \) ". + "\( -clone 0 -auto-orient -resize ${new_width}x${new_height}\^ -background ${bg} -flatten -gravity center -fill black -colorize 50% -extent ${new_width}x${new_height} -blur 0x${blur_size} \) ". + "\( -clone 0 -auto-orient -resize ${new_width}x${new_height} \) ". "-delete 0 -gravity center -compose over -composite"; break; } From 45511cbcdad407835c8ac3da5e50273e19c5b51a Mon Sep 17 00:00:00 2001 From: Matthew Barbour Date: Thu, 8 Oct 2020 17:08:42 -0500 Subject: [PATCH 6/6] Fixed issue with detecting animated GIFs --- ext/mime/mime_type.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ext/mime/mime_type.php b/ext/mime/mime_type.php index cd925c39..eec112c9 100644 --- a/ext/mime/mime_type.php +++ b/ext/mime/mime_type.php @@ -131,15 +131,17 @@ class MimeType if (($fh = @fopen($image_filename, 'rb'))) { try { //check if gif is animated (via https://www.php.net/manual/en/function.imagecreatefromgif.php#104473) + $chunk = false; + while (!feof($fh) && $is_anim_gif < 2) { - $chunk = fread($fh, 1024 * 100); - $is_anim_gif += preg_match_all('#\x00\x21\xF9\x04.{4}\x00[\x2C\x21]#s', $chunk, $matches); + $chunk = ($chunk ? substr($chunk, -20) : "") . fread($fh, 1024 * 100); //read 100kb at a time + $is_anim_gif += preg_match_all('#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s', $chunk, $matches); } } finally { @fclose($fh); } } - return ($is_anim_gif == 0); + return ($is_anim_gif >=2); }