diff --git a/README.markdown b/README.markdown index bd71aa06..23dec0ee 100644 --- a/README.markdown +++ b/README.markdown @@ -99,21 +99,21 @@ For example, one can override the default anonymous "allow nothing" permissions like so: ```php -new UserClass("anonymous", "base", array( +new UserClass("anonymous", "base", [ "create_comment" => True, "edit_image_tag" => True, "edit_image_source" => True, "create_image_report" => True, -)); +]); ``` For a moderator class, being a regular user who can delete images and comments: ```php -new UserClass("moderator", "user", array( +new UserClass("moderator", "user", [ "delete_image" => True, "delete_comment" => True, -)); +]); ``` For a list of permissions, see `core/userclass.php` diff --git a/core/_install.php b/core/_install.php index dcc622be..a695c237 100644 --- a/core/_install.php +++ b/core/_install.php @@ -110,7 +110,7 @@ function do_install() { // {{{ if (file_exists("data/config/auto_install.conf.php")) { require_once "data/config/auto_install.conf.php"; - } elseif (@$_POST["database_type"] == "sqlite") { + } elseif (@$_POST["database_type"] == DatabaseDriver::SQLITE) { $id = bin2hex(random_bytes(5)); define('DATABASE_DSN', "sqlite:data/shimmie.{$id}.sqlite"); } elseif (isset($_POST['database_type']) && isset($_POST['database_host']) && isset($_POST['database_user']) && isset($_POST['database_name'])) { @@ -153,9 +153,9 @@ function ask_questions() $drivers = PDO::getAvailableDrivers(); if ( - !in_array("mysql", $drivers) && - !in_array("pgsql", $drivers) && - !in_array("sqlite", $drivers) + !in_array(DatabaseDriver::MYSQL, $drivers) && + !in_array(DatabaseDriver::PGSQL, $drivers) && + !in_array(DatabaseDriver::SQLITE, $drivers) ) { $errors[] = " No database connection library could be found; shimmie needs @@ -163,9 +163,9 @@ function ask_questions() "; } - $db_m = in_array("mysql", $drivers) ? '' : ""; - $db_p = in_array("pgsql", $drivers) ? '' : ""; - $db_s = in_array("sqlite", $drivers) ? '' : ""; + $db_m = in_array(DatabaseDriver::MYSQL, $drivers) ? '' : ""; + $db_p = in_array(DatabaseDriver::PGSQL, $drivers) ? '' : ""; + $db_s = in_array(DatabaseDriver::SQLITE, $drivers) ? '' : ""; $warn_msg = $warnings ? "

Warnings

".implode("\n

", $warnings) : ""; $err_msg = $errors ? "

Errors

".implode("\n

", $errors) : ""; diff --git a/core/config.php b/core/config.php index 695fa8f1..c9fb225b 100644 --- a/core/config.php +++ b/core/config.php @@ -144,6 +144,13 @@ abstract class BaseConfig implements Config } } + public function set_default_float(string $name, float $value): void + { + if (is_null($this->get($name))) { + $this->values[$name] = $value; + } + } + public function set_default_string(string $name, string $value): void { if (is_null($this->get($name))) { @@ -170,6 +177,11 @@ abstract class BaseConfig implements Config return (int)($this->get($name, $default)); } + public function get_float(string $name, ?float $default=null): ?float + { + return (float)($this->get($name, $default)); + } + public function get_string(string $name, ?string $default=null): ?string { return $this->get($name, $default); diff --git a/core/database.php b/core/database.php index c6135878..65405211 100644 --- a/core/database.php +++ b/core/database.php @@ -1,9 +1,17 @@ get_driver_name() == "sqlite") { + if (version_compare(PHP_VERSION, "6.9.9") == 1 && $this->get_driver_name() == DatabaseDriver::SQLITE) { $ka = false; } @@ -96,11 +104,11 @@ class Database throw new SCoreException("Can't figure out database engine"); } - if ($db_proto === "mysql") { + if ($db_proto === DatabaseDriver::MYSQL) { $this->engine = new MySQL(); - } elseif ($db_proto === "pgsql") { + } elseif ($db_proto === DatabaseDriver::PGSQL) { $this->engine = new PostgreSQL(); - } elseif ($db_proto === "sqlite") { + } elseif ($db_proto === DatabaseDriver::SQLITE) { $this->engine = new SQLite(); } else { die('Unknown PDO driver: '.$db_proto); @@ -296,7 +304,7 @@ class Database */ public function get_last_insert_id(string $seq): int { - if ($this->engine->name == "pgsql") { + if ($this->engine->name == DatabaseDriver::PGSQL) { return $this->db->lastInsertId($seq); } else { return $this->db->lastInsertId(); @@ -326,15 +334,15 @@ class Database $this->connect_db(); } - if ($this->engine->name === "mysql") { + if ($this->engine->name === DatabaseDriver::MYSQL) { return count( $this->get_all("SHOW TABLES") ); - } elseif ($this->engine->name === "pgsql") { + } elseif ($this->engine->name === DatabaseDriver::PGSQL) { return count( $this->get_all("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'") ); - } elseif ($this->engine->name === "sqlite") { + } elseif ($this->engine->name === DatabaseDriver::SQLITE) { return count( $this->get_all("SELECT name FROM sqlite_master WHERE type = 'table'") ); diff --git a/core/dbengine.php b/core/dbengine.php index bb7c674b..404adad9 100644 --- a/core/dbengine.php +++ b/core/dbengine.php @@ -22,7 +22,7 @@ class DBEngine class MySQL extends DBEngine { /** @var string */ - public $name = "mysql"; + public $name = DatabaseDriver::MYSQL; public function init(PDO $db) { @@ -54,7 +54,7 @@ class MySQL extends DBEngine class PostgreSQL extends DBEngine { /** @var string */ - public $name = "pgsql"; + public $name = DatabaseDriver::PGSQL; public function init(PDO $db) { @@ -136,7 +136,7 @@ function _ln($n) class SQLite extends DBEngine { /** @var string */ - public $name = "sqlite"; + public $name = DatabaseDriver::SQLITE; public function init(PDO $db) { diff --git a/core/extension.php b/core/extension.php index b7472583..5c8c61fa 100644 --- a/core/extension.php +++ b/core/extension.php @@ -182,7 +182,7 @@ abstract class DataHandlerExtension extends Extension // even more hax.. $event->metadata['tags'] = $existing->get_tag_list(); - $image = $this->create_image_from_data(warehouse_path("images", $event->metadata['hash']), $event->metadata); + $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 image object from data"); @@ -192,13 +192,14 @@ abstract class DataHandlerExtension extends Extension send_event($ire); $event->image_id = $image_id; } else { - $image = $this->create_image_from_data(warehouse_path("images", $event->hash), $event->metadata); + $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 image object from data"); } $iae = new ImageAdditionEvent($image); send_event($iae); $event->image_id = $iae->image->id; + $event->merged = $iae->merged; // Rating Stuff. if (!empty($event->metadata['rating'])) { @@ -222,13 +223,13 @@ abstract class DataHandlerExtension extends Extension $result = false; if ($this->supported_ext($event->type)) { if ($event->force) { - $result = $this->create_thumb($event->hash); + $result = $this->create_thumb($event->hash, $event->type); } else { - $outname = warehouse_path("thumbs", $event->hash); + $outname = warehouse_path(Image::THUMBNAIL_DIR, $event->hash); if (file_exists($outname)) { return; } - $result = $this->create_thumb($event->hash); + $result = $this->create_thumb($event->hash, $event->type); } } if ($result) { @@ -256,5 +257,5 @@ abstract class DataHandlerExtension extends Extension abstract protected function supported_ext(string $ext): bool; abstract protected function check_contents(string $tmpname): bool; abstract protected function create_image_from_data(string $filename, array $metadata); - abstract protected function create_thumb(string $hash): bool; + abstract protected function create_thumb(string $hash, string $type): bool; } diff --git a/core/imageboard/event.php b/core/imageboard/event.php index 2fc40fef..ec663d6b 100644 --- a/core/imageboard/event.php +++ b/core/imageboard/event.php @@ -11,6 +11,8 @@ class ImageAdditionEvent extends Event /** @var Image */ public $image; + public $merged = false; + /** * Inserts a new image into the database with its associated * information. Also calls TagSetEvent to set the tags for diff --git a/core/imageboard/image.php b/core/imageboard/image.php index cc2999dc..2f224c8b 100644 --- a/core/imageboard/image.php +++ b/core/imageboard/image.php @@ -10,6 +10,10 @@ */ class Image { + public const DATA_DIR = "data"; + public const IMAGE_DIR = "images"; + public const THUMBNAIL_DIR = "thumbs"; + private static $tag_n = 0; // temp hack public static $order_sql = null; // this feels ugly @@ -552,7 +556,7 @@ class Image */ public function get_image_filename(): string { - return warehouse_path("images", $this->hash); + return warehouse_path(self::IMAGE_DIR, $this->hash); } /** @@ -560,7 +564,7 @@ class Image */ public function get_thumb_filename(): string { - return warehouse_path("thumbs", $this->hash); + return warehouse_path(self::THUMBNAIL_DIR, $this->hash); } /** @@ -640,7 +644,7 @@ class Image public function delete_tags_from_image(): void { global $database; - if ($database->get_driver_name() == "mysql") { + if ($database->get_driver_name() == DatabaseDriver::MYSQL) { //mysql < 5.6 has terrible subquery optimization, using EXISTS / JOIN fixes this $database->execute( " @@ -917,7 +921,7 @@ class Image // more than one positive tag, or more than zero negative tags else { - if ($database->get_driver_name() === "mysql") { + if ($database->get_driver_name() === DatabaseDriver::MYSQL) { $query = Image::build_ugly_search_querylet($tag_conditions); } else { $query = Image::build_accurate_search_querylet($tag_conditions); diff --git a/core/imageboard/misc.php b/core/imageboard/misc.php index dbdf25f5..d08daf2b 100644 --- a/core/imageboard/misc.php +++ b/core/imageboard/misc.php @@ -7,11 +7,12 @@ * Move a file from PHP's temporary area into shimmie's image storage * hierarchy, or throw an exception trying. * + * @param DataUploadEvent $event * @throws UploadException */ function move_upload_to_archive(DataUploadEvent $event): void { - $target = warehouse_path("images", $event->hash); + $target = warehouse_path(Image::IMAGE_DIR, $event->hash); if (!@copy($event->tmpname, $target)) { $errors = error_get_last(); throw new UploadException( @@ -24,7 +25,8 @@ function move_upload_to_archive(DataUploadEvent $event): void /** * Add a directory full of images * - * #return string[] + * @param string $base + * @return array */ function add_dir(string $base): array { @@ -48,6 +50,14 @@ function add_dir(string $base): array return $results; } +/** + * Sends a DataUploadEvent for a file. + * + * @param string $tmpname + * @param string $filename + * @param string $tags + * @throws UploadException + */ function add_image(string $tmpname, string $filename, string $tags): void { assert(file_exists($tmpname)); @@ -65,10 +75,15 @@ function add_image(string $tmpname, string $filename, string $tags): void send_event($event); } - -function get_extension_from_mime(String $file_path): ?String +/** + * Gets an the extension defined in MIME_TYPE_MAP for a file. + * + * @param String $file_path + * @return String The extension that was found. + * @throws UploadException if the mimetype could not be determined, or if an extension for hte mimetype could not be found. + */ +function get_extension_from_mime(String $file_path): String { - global $config; $mime = mime_content_type($file_path); if (!empty($mime)) { $ext = get_extension($mime); @@ -83,11 +98,15 @@ function get_extension_from_mime(String $file_path): ?String /** * Given a full size pair of dimensions, return a pair scaled down to fit - * into the configured thumbnail square, with ratio intact + * into the configured thumbnail square, with ratio intact. + * Optionally uses the High-DPI scaling setting to adjust the final resolution. * - * #return int[] + * @param int $orig_width + * @param int $orig_height + * @param bool $use_dpi_scaling Enables the High-DPI scaling. + * @return array */ -function get_thumbnail_size(int $orig_width, int $orig_height): array +function get_thumbnail_size(int $orig_width, int $orig_height, bool $use_dpi_scaling = false): array { global $config; @@ -105,8 +124,15 @@ function get_thumbnail_size(int $orig_width, int $orig_height): array $orig_height = $orig_width * 5; } - $max_width = $config->get_int('thumb_width'); - $max_height = $config->get_int('thumb_height'); + + if($use_dpi_scaling) { + $max_size = get_thumbnail_max_size_scaled(); + $max_width = $max_size[0]; + $max_height = $max_size[1]; + } else { + $max_width = $config->get_int('thumb_width'); + $max_height = $config->get_int('thumb_height'); + } $xscale = ($max_height / $orig_height); $yscale = ($max_width / $orig_width); @@ -120,44 +146,10 @@ function get_thumbnail_size(int $orig_width, int $orig_height): array } /** - * Given a full size pair of dimensions, return a pair scaled down to fit - * into the configured thumbnail square, with ratio intact, using thumb_scaling + * Fetches the thumbnails height and width settings and applies the High-DPI scaling setting before returning the dimensions. * - * #return int[] + * @return array [width, height] */ -function get_thumbnail_size_scaled(int $orig_width, int $orig_height): array -{ - global $config; - - if ($orig_width === 0) { - $orig_width = 192; - } - if ($orig_height === 0) { - $orig_height = 192; - } - - if ($orig_width > $orig_height * 5) { - $orig_width = $orig_height * 5; - } - if ($orig_height > $orig_width * 5) { - $orig_height = $orig_width * 5; - } - - $max_size = get_thumbnail_max_size_scaled(); - $max_width = $max_size[0]; - $max_height = $max_size[1]; - - $xscale = ($max_height / $orig_height); - $yscale = ($max_width / $orig_width); - $scale = ($xscale < $yscale) ? $xscale : $yscale; - - if ($scale > 1 && $config->get_bool('thumb_upscale')) { - return [(int)$orig_width, (int)$orig_height]; - } else { - return [(int)($orig_width*$scale), (int)($orig_height*$scale)]; - } -} - function get_thumbnail_max_size_scaled(): array { global $config; @@ -168,12 +160,19 @@ function get_thumbnail_max_size_scaled(): array return [$max_width, $max_height]; } -function create_thumbnail_convert($hash): bool +/** + * Creates a thumbnail file using ImageMagick's convert command. + * + * @param $hash + * @param string $input_type Optional, allows specifying the input format. Usually not necessary. + * @return bool true is successful, false if not. + */ +function create_thumbnail_convert($hash, $input_type = ""): bool { global $config; - $inname = warehouse_path("images", $hash); - $outname = warehouse_path("thumbs", $hash); + $inname = warehouse_path(Image::IMAGE_DIR, $hash); + $outname = warehouse_path(Image::THUMBNAIL_DIR, $hash); $q = $config->get_int("thumb_quality"); $convert = $config->get_string("thumb_convert_path"); @@ -187,9 +186,7 @@ function create_thumbnail_convert($hash): bool //$cmd = sprintf($format, $convert, $inname); //$size = shell_exec($cmd); //$size = explode(" ", trim($size)); - $tsize = get_thumbnail_max_size_scaled(); - $w = $tsize[0]; - $h = $tsize[1]; + list($w, $h) = get_thumbnail_max_size_scaled(); // running the call with cmd.exe requires quoting for our paths @@ -204,13 +201,18 @@ function create_thumbnail_convert($hash): bool if ($type=="webp") { $bg = "none"; } - $format = '"%s" -flatten -strip -thumbnail %ux%u%s -quality %u -background %s "%s[0]" %s:"%s"'; - - $cmd = sprintf($format, $convert, $w, $h, $options, $q, $bg, $inname, $type, $outname); + if(!empty($input_type)) { + $input_type = $input_type.":"; + } + $format = '"%s" -flatten -strip -thumbnail %ux%u%s -quality %u -background %s %s"%s[0]" %s:"%s" 2>&1'; + $cmd = sprintf($format, $convert, $w, $h, $options, $q, $bg,$input_type, $inname, $type, $outname); $cmd = str_replace("\"convert\"", "convert", $cmd); // quotes are only needed if the path to convert contains a space; some other times, quotes break things, see github bug #27 exec($cmd, $output, $ret); - - log_debug('handle_pixel', "Generating thumbnail with command `$cmd`, returns $ret"); + if ($ret!=0) { + log_warning('imageboard/misc', "Generating thumbnail with command `$cmd`, returns $ret, outputting ".implode("\r\n",$output)); + } else { + log_debug('imageboard/misc', "Generating thumbnail with command `$cmd`, returns $ret"); + } if ($config->get_bool("thumb_optim", false)) { exec("jpegoptim $outname", $output, $ret); @@ -219,6 +221,12 @@ function create_thumbnail_convert($hash): bool return true; } +/** + * Creates a thumbnail using ffmpeg. + * + * @param $hash + * @return bool true if successful, false if not. + */ function create_thumbnail_ffmpeg($hash): bool { global $config; @@ -228,11 +236,11 @@ function create_thumbnail_ffmpeg($hash): bool return false; } - $inname = warehouse_path("images", $hash); - $outname = warehouse_path("thumbs", $hash); + $inname = warehouse_path(Image::IMAGE_DIR, $hash); + $outname = warehouse_path(Image::THUMBNAIL_DIR, $hash); $orig_size = video_size($inname); - $scaled_size = get_thumbnail_size_scaled($orig_size[0], $orig_size[1]); + $scaled_size = get_thumbnail_size($orig_size[0], $orig_size[1], true); $codec = "mjpeg"; $quality = $config->get_int("thumb_quality"); @@ -270,6 +278,12 @@ function create_thumbnail_ffmpeg($hash): bool } } +/** + * Determines the dimensions of a video file using ffmpeg. + * + * @param string $filename + * @return array [width, height] + */ function video_size(string $filename): array { global $config; @@ -307,6 +321,9 @@ function video_size(string $filename): array * * The factor of 2.5 is simply a rough guideline. * http://stackoverflow.com/questions/527532/reasonable-php-memory-limit-for-image-resize + * + * @param array $info The output of getimagesize() for the source file in question. + * @return int The number of bytes an image resize operation is estimated to use. */ function calc_memory_use(array $info): int { @@ -320,12 +337,25 @@ function calc_memory_use(array $info): int return (int)$memory_use; } +/** + * Performs a resize operation on an image file using GD. + * + * @param String $image_filename The source file to be resized. + * @param array $info The output of getimagesize() for the source file. + * @param int $new_width + * @param int $new_height + * @param string $output_filename + * @param string|null $output_type If set to null, the output file type will be automatically determined via the $info parameter. Otherwise an exception will be thrown. + * @param int $output_quality Defaults to 80. + * @throws ImageResizeException + * @throws InsufficientMemoryException if the estimated memory usage exceeds the memory limit. + */ function image_resize_gd( String $image_filename, array $info, int $new_width, int $new_height, - string $output_filename=null, + string $output_filename, string $output_type=null, int $output_quality = 80 ) { @@ -423,7 +453,7 @@ function image_resize_gd( throw new ImageResizeException("Unable to copy resized image data to new image"); } - $result = false; + switch ($output_type) { case "bmp": $result = imagebmp($image_resized, $output_filename, true); @@ -453,15 +483,20 @@ function image_resize_gd( } } -function is_animated_gif(String $image_filename) -{ - $isanigif = 0; +/** + * Determines if a file is an animated gif. + * + * @param String $image_filename The path of the file to check. + * @return bool true if the file is an animated gif, false if it is not. + */ +function is_animated_gif(String $image_filename) { + $is_anim_gif = 0; if (($fh = @fopen($image_filename, 'rb'))) { //check if gif is animated (via http://www.php.net/manual/en/function.imagecreatefromgif.php#104473) - while (!feof($fh) && $isanigif < 2) { + while (!feof($fh) && $is_anim_gif < 2) { $chunk = fread($fh, 1024 * 100); - $isanigif += preg_match_all('#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s', $chunk, $matches); + $is_anim_gif += preg_match_all('#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s', $chunk, $matches); } } - return ($isanigif == 0); -} + return ($is_anim_gif == 0); +} \ No newline at end of file diff --git a/core/page.php b/core/page.php index e9b3384b..998adc7d 100644 --- a/core/page.php +++ b/core/page.php @@ -26,6 +26,11 @@ * Various other common functions are available as part of the Themelet class. */ +abstract class PageMode { + const REDIRECT = 'redirect'; + const DATA = 'data'; + const PAGE = 'page'; +} /** * Class Page @@ -40,7 +45,7 @@ class Page /** @name Overall */ //@{ /** @var string */ - public $mode = "page"; + public $mode = PageMode::PAGE; /** @var string */ public $type = "text/html; charset=utf-8"; @@ -261,7 +266,7 @@ class Page } switch ($this->mode) { - case "page": + case PageMode::PAGE: if (CACHE_HTTP) { header("Vary: Cookie, Accept-Encoding"); if ($user->is_anonymous() && $_SERVER["REQUEST_METHOD"] == "GET") { @@ -285,14 +290,14 @@ class Page $layout = new Layout(); $layout->display_page($page); break; - case "data": + case PageMode::DATA: header("Content-Length: ".strlen($this->data)); if (!is_null($this->filename)) { header('Content-Disposition: attachment; filename='.$this->filename); } print $this->data; break; - case "redirect": + case PageMode::REDIRECT: header('Location: '.$this->redirect); print 'You should be redirected to '.$this->redirect.''; break; diff --git a/core/user.php b/core/user.php index 098c7723..05f6e7f7 100644 --- a/core/user.php +++ b/core/user.php @@ -69,7 +69,7 @@ class User global $config, $database; $row = $database->cache->get("user-session:$name-$session"); if (!$row) { - if ($database->get_driver_name() === "mysql") { + if ($database->get_driver_name() === DatabaseDriver::MYSQL) { $query = "SELECT * FROM users WHERE name = :name AND md5(concat(pass, :ip)) = :sess"; } else { $query = "SELECT * FROM users WHERE name = :name AND md5(pass || :ip) = :sess"; diff --git a/core/util.php b/core/util.php index 566474df..ca50a728 100644 --- a/core/util.php +++ b/core/util.php @@ -163,10 +163,13 @@ function warehouse_path(string $base, string $hash, bool $create=true): string { $ab = substr($hash, 0, 2); $cd = substr($hash, 2, 2); + + $pa = Image::DATA_DIR.'/'.$base.'/'; + if (WH_SPLITS == 2) { - $pa = 'data/'.$base.'/'.$ab.'/'.$cd.'/'.$hash; + $pa .= $ab.'/'.$cd.'/'.$hash; } else { - $pa = 'data/'.$base.'/'.$ab.'/'.$hash; + $pa .= $ab.'/'.$hash; } if ($create && !file_exists(dirname($pa))) { mkdir(dirname($pa), 0755, true); diff --git a/ext/admin/main.php b/ext/admin/main.php index 212b07fb..c6c7f33f 100644 --- a/ext/admin/main.php +++ b/ext/admin/main.php @@ -70,7 +70,7 @@ class AdminPage extends Extension } if ($aae->redirect) { - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("admin")); } } @@ -149,7 +149,7 @@ class AdminPage extends Extension send_event(new ImageDeletionEvent($image)); } - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/list")); return false; } @@ -201,14 +201,14 @@ class AdminPage extends Extension $database = $matches['dbname']; switch ($software) { - case 'mysql': + case DatabaseDriver::MYSQL: $cmd = "mysqldump -h$hostname -u$username -p$password $database"; break; - case 'pgsql': + case DatabaseDriver::PGSQL: putenv("PGPASSWORD=$password"); $cmd = "pg_dump -h $hostname -U $username $database"; break; - case 'sqlite': + case DatabaseDriver::SQLITE: $cmd = "sqlite3 $database .dump"; break; default: @@ -218,7 +218,7 @@ class AdminPage extends Extension //FIXME: .SQL dump is empty if cmd doesn't exist if ($cmd) { - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->set_type("application/x-unknown"); $page->set_filename('shimmie-'.date('Ymd').'.sql'); $page->set_data(shell_exec($cmd)); @@ -237,13 +237,13 @@ class AdminPage extends Extension $zip = new ZipArchive; if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE) === true) { foreach ($images as $img) { - $img_loc = warehouse_path("images", $img["hash"], false); + $img_loc = warehouse_path(Image::IMAGE_DIR, $img["hash"], false); $zip->addFile($img_loc, $img["hash"].".".$img["ext"]); } $zip->close(); } - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link($filename)); //TODO: Delete file after downloaded? return false; // we do want a redirect, but a manual one @@ -257,7 +257,7 @@ class AdminPage extends Extension //TODO: Update score_log (Having an optional ID column for score_log would be nice..) preg_match("#^(?P\w+)\:(?:user=(?P\w+)(?:;|$)|password=(?P\w*)(?:;|$)|host=(?P[\w\.\-]+)(?:;|$)|dbname=(?P[\w_]+)(?:;|$))+#", DATABASE_DSN, $matches); - if ($matches['proto'] == "mysql") { + if ($matches['proto'] == DatabaseDriver::MYSQL) { $tables = $database->get_col("SELECT TABLE_NAME FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = :db @@ -280,9 +280,9 @@ class AdminPage extends Extension $i++; } $database->execute("ALTER TABLE images AUTO_INCREMENT=".(count($ids) + 1)); - } elseif ($matches['proto'] == "pgsql") { + } elseif ($matches['proto'] == DatabaseDriver::PGSQL) { //TODO: Make this work with PostgreSQL - } elseif ($matches['proto'] == "sqlite") { + } elseif ($matches['proto'] == DatabaseDriver::SQLITE) { //TODO: Make this work with SQLite } return true; diff --git a/ext/admin/theme.php b/ext/admin/theme.php index 3e60d224..64191067 100644 --- a/ext/admin/theme.php +++ b/ext/admin/theme.php @@ -45,7 +45,7 @@ class AdminPageTheme extends Themelet $html .= $this->button("Download all images", "download_all_images", false); } $html .= $this->button("Download database contents", "database_dump", false); - if ($database->get_driver_name() == "mysql") { + if ($database->get_driver_name() == DatabaseDriver::MYSQL) { $html .= $this->button("Reset image IDs", "reset_image_ids", true); } $page->add_block(new Block("Misc Admin Tools", $html)); diff --git a/ext/alias_editor/main.php b/ext/alias_editor/main.php index 9e7139cf..07f9f289 100644 --- a/ext/alias_editor/main.php +++ b/ext/alias_editor/main.php @@ -41,7 +41,7 @@ class AliasEditor extends Extension try { $aae = new AddAliasEvent($_POST['oldtag'], $_POST['newtag']); send_event($aae); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("alias/list")); } catch (AddAliasException $ex) { $this->theme->display_error(500, "Error adding alias", $ex->getMessage()); @@ -54,7 +54,7 @@ class AliasEditor extends Extension $database->execute("DELETE FROM aliases WHERE oldtag=:oldtag", ["oldtag" => $_POST['oldtag']]); log_info("alias_editor", "Deleted alias for ".$_POST['oldtag'], "Deleted alias"); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("alias/list")); } } @@ -80,7 +80,7 @@ class AliasEditor extends Extension $this->theme->display_aliases($alias, $page_number + 1, $total_pages); } elseif ($event->get_arg(0) == "export") { - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->set_type("text/csv"); $page->set_filename("aliases.csv"); $page->set_data($this->get_alias_csv($database)); @@ -91,7 +91,7 @@ class AliasEditor extends Extension $contents = file_get_contents($tmp); $this->add_alias_csv($database, $contents); log_info("alias_editor", "Imported aliases from file", "Imported aliases"); # FIXME: how many? - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("alias/list")); } else { $this->theme->display_error(400, "No File Specified", "You have to upload a file"); diff --git a/ext/artists/main.php b/ext/artists/main.php index 7a3f3377..568933de 100644 --- a/ext/artists/main.php +++ b/ext/artists/main.php @@ -172,7 +172,7 @@ class Artists extends Extension } case "new_artist": { - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("artist/new")); break; } @@ -183,7 +183,7 @@ class Artists extends Extension if ($newArtistID == -1) { $this->theme->display_error(400, "Error", "Error when entering artist data."); } else { - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("artist/view/".$newArtistID)); } } else { @@ -238,7 +238,7 @@ class Artists extends Extension case "edit_artist": { $artistID = $_POST['artist_id']; - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("artist/edit/".$artistID)); break; } @@ -246,14 +246,14 @@ class Artists extends Extension { $artistID = int_escape($_POST['id']); $this->update_artist(); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("artist/view/".$artistID)); break; } case "nuke_artist": { $artistID = $_POST['artist_id']; - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("artist/nuke/".$artistID)); break; } @@ -261,7 +261,7 @@ class Artists extends Extension { $artistID = $event->get_arg(1); $this->delete_artist($artistID); // this will delete the artist, its alias, its urls and its members - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("artist/list")); break; } @@ -291,7 +291,7 @@ class Artists extends Extension { $artistID = $_POST['artistID']; $this->add_alias(); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("artist/view/".$artistID)); break; } @@ -300,7 +300,7 @@ class Artists extends Extension $aliasID = $event->get_arg(2); $artistID = $this->get_artistID_by_aliasID($aliasID); $this->delete_alias($aliasID); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("artist/view/".$artistID)); break; } @@ -316,7 +316,7 @@ class Artists extends Extension $this->update_alias(); $aliasID = int_escape($_POST['aliasID']); $artistID = $this->get_artistID_by_aliasID($aliasID); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("artist/view/".$artistID)); break; } @@ -332,7 +332,7 @@ class Artists extends Extension { $artistID = $_POST['artistID']; $this->add_urls(); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("artist/view/".$artistID)); break; } @@ -341,7 +341,7 @@ class Artists extends Extension $urlID = $event->get_arg(2); $artistID = $this->get_artistID_by_urlID($urlID); $this->delete_url($urlID); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("artist/view/".$artistID)); break; } @@ -357,7 +357,7 @@ class Artists extends Extension $this->update_url(); $urlID = int_escape($_POST['urlID']); $artistID = $this->get_artistID_by_urlID($urlID); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("artist/view/".$artistID)); break; } @@ -372,7 +372,7 @@ class Artists extends Extension { $artistID = $_POST['artistID']; $this->add_members(); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("artist/view/".$artistID)); break; } @@ -381,7 +381,7 @@ class Artists extends Extension $memberID = int_escape($event->get_arg(2)); $artistID = $this->get_artistID_by_memberID($memberID); $this->delete_member($memberID); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("artist/view/".$artistID)); break; } @@ -397,7 +397,7 @@ class Artists extends Extension $this->update_member(); $memberID = int_escape($_POST['memberID']); $artistID = $this->get_artistID_by_memberID($memberID); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("artist/view/".$artistID)); break; } diff --git a/ext/autocomplete/main.php b/ext/autocomplete/main.php index eb71227b..a7c85050 100644 --- a/ext/autocomplete/main.php +++ b/ext/autocomplete/main.php @@ -21,7 +21,7 @@ class AutoComplete extends Extension return; } - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->set_type("application/json"); $s = strtolower($_GET["s"]); diff --git a/ext/blocks/main.php b/ext/blocks/main.php index 86e0a1c5..cb9c375c 100644 --- a/ext/blocks/main.php +++ b/ext/blocks/main.php @@ -61,7 +61,7 @@ class Blocks extends Extension ", [$_POST['pages'], $_POST['title'], $_POST['area'], (int)$_POST['priority'], $_POST['content']]); log_info("blocks", "Added Block #".($database->get_last_insert_id('blocks_id_seq'))." (".$_POST['title'].")"); $database->cache->delete("blocks"); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("blocks/list")); } } @@ -81,7 +81,7 @@ class Blocks extends Extension log_info("blocks", "Updated Block #".$_POST['id']." (".$_POST['title'].")"); } $database->cache->delete("blocks"); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("blocks/list")); } } elseif ($event->get_arg(0) == "list") { diff --git a/ext/blotter/main.php b/ext/blotter/main.php index 8f54576e..cb88490b 100644 --- a/ext/blotter/main.php +++ b/ext/blotter/main.php @@ -102,7 +102,7 @@ class Blotter extends Extension [$entry_text, $important] ); log_info("blotter", "Added Message: $entry_text"); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("blotter/editor")); } break; @@ -119,7 +119,7 @@ class Blotter extends Extension } $database->Execute("DELETE FROM blotter WHERE id=:id", ["id"=>$id]); log_info("blotter", "Removed Entry #$id"); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("blotter/editor")); } break; diff --git a/ext/browser_search/main.php b/ext/browser_search/main.php index 10950000..7c1fcc82 100644 --- a/ext/browser_search/main.php +++ b/ext/browser_search/main.php @@ -54,7 +54,7 @@ class BrowserSearch extends Extension "; // And now to send it to the browser - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->set_type("text/xml"); $page->set_data($xml); } elseif ( @@ -85,7 +85,7 @@ class BrowserSearch extends Extension // And now for the final output $json_string = "[\"$tag_search\",[\"$json_tag_list\"],[],[]]"; - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->set_data($json_string); } } diff --git a/ext/bulk_actions/main.php b/ext/bulk_actions/main.php index 2c93de4e..073a85f1 100644 --- a/ext/bulk_actions/main.php +++ b/ext/bulk_actions/main.php @@ -171,7 +171,7 @@ class BulkActions extends Extension } - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); if (!isset($_SERVER['HTTP_REFERER'])) { $_SERVER['HTTP_REFERER'] = make_link(); } diff --git a/ext/bulk_add_csv/main.php b/ext/bulk_add_csv/main.php index 14db3591..d1648a7d 100644 --- a/ext/bulk_add_csv/main.php +++ b/ext/bulk_add_csv/main.php @@ -81,7 +81,7 @@ class BulkAddCSV extends Extension send_event($ratingevent); } if (file_exists($thumbfile)) { - copy($thumbfile, warehouse_path("thumbs", $event->hash)); + copy($thumbfile, warehouse_path(Image::THUMBNAIL_DIR, $event->hash)); } } } diff --git a/ext/comment/main.php b/ext/comment/main.php index 85a9672b..1dfdc03b 100644 --- a/ext/comment/main.php +++ b/ext/comment/main.php @@ -178,7 +178,7 @@ class CommentList extends Extension $i_iid = int_escape($_POST['image_id']); $cpe = new CommentPostingEvent($_POST['image_id'], $user, $_POST['comment']); send_event($cpe); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/$i_iid#comment_on_$i_iid")); } catch (CommentPostingException $ex) { $this->theme->display_error(403, "Comment Blocked", $ex->getMessage()); @@ -194,7 +194,7 @@ class CommentList extends Extension if ($event->count_args() === 3) { send_event(new CommentDeletionEvent($event->get_arg(1))); flash_message("Deleted comment"); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); if (!empty($_SERVER['HTTP_REFERER'])) { $page->set_redirect($_SERVER['HTTP_REFERER']); } else { @@ -224,7 +224,7 @@ class CommentList extends Extension } flash_message("Deleted $num comments"); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("admin")); } else { $this->theme->display_permission_denied(); @@ -480,14 +480,14 @@ class CommentList extends Extension global $config, $database; // sqlite fails at intervals - if ($database->get_driver_name() === "sqlite") { + if ($database->get_driver_name() === DatabaseDriver::SQLITE) { return false; } $window = int_escape($config->get_int('comment_window')); $max = int_escape($config->get_int('comment_limit')); - if ($database->get_driver_name() == "mysql") { + if ($database->get_driver_name() == DatabaseDriver::MYSQL) { $window_sql = "interval $window minute"; } else { $window_sql = "interval '$window minute'"; diff --git a/ext/cron_uploader/main.php b/ext/cron_uploader/main.php index f4bd3c51..560a15a3 100644 --- a/ext/cron_uploader/main.php +++ b/ext/cron_uploader/main.php @@ -1,42 +1,52 @@ + * Authors: YaoiFox , Matthew Barbour * Link: http://www.yaoifox.com/ * License: GPLv2 * Description: Uploads images automatically using Cron Jobs * Documentation: Installation guide: activate this extension and navigate to www.yoursite.com/cron_upload */ + class CronUploader extends Extension { // TODO: Checkbox option to only allow localhost + a list of additional IP adresses that can be set in /cron_upload // TODO: Change logging to MySQL + display log at /cron_upload // TODO: Move stuff to theme.php - + + const QUEUE_DIR = "queue"; + const UPLOADED_DIR = "uploaded"; + const FAILED_DIR = "failed_to_upload"; + + const CONFIG_KEY = "cron_uploader_key"; + const CONFIG_COUNT = "cron_uploader_count"; + const CONFIG_DIR = "cron_uploader_dir"; + /** * Lists all log events this session * @var string */ private $upload_info = ""; - + /** * Lists all files & info required to upload. * @var array */ private $image_queue = []; - + /** * Cron Uploader root directory * @var string */ private $root_dir = ""; - + /** * Key used to identify uploader * @var string */ private $upload_key = ""; - + /** * Checks if the cron upload page has been accessed * and initializes the upload. @@ -44,39 +54,50 @@ class CronUploader extends Extension public function onPageRequest(PageRequestEvent $event) { global $config, $user; - + if ($event->page_matches("cron_upload")) { - $this->upload_key = $config->get_string("cron_uploader_key", ""); - + $this->upload_key = $config->get_string(self::CONFIG_KEY, ""); + // If the key is in the url, upload if ($this->upload_key != "" && $event->get_arg(0) == $this->upload_key) { // log in as admin - $this->process_upload(); // Start upload + $this->set_dir(); + + $lockfile = fopen($this->root_dir . "/.lock", "w"); + if (!flock($lockfile, LOCK_EX | LOCK_NB)) { + throw new Exception("Cron upload process is already running"); + } + try { + $this->process_upload(); // Start upload + } finally { + flock($lockfile, LOCK_UN); + fclose($lockfile); + } } elseif ($user->is_admin()) { $this->set_dir(); $this->display_documentation(); } } } - + private function display_documentation() { global $page; $this->set_dir(); // Determines path to cron_uploader_dir - - - $queue_dir = $this->root_dir . "/queue"; - $uploaded_dir = $this->root_dir . "/uploaded"; - $failed_dir = $this->root_dir . "/failed_to_upload"; - + + + $queue_dir = $this->root_dir . "/" . self::QUEUE_DIR; + $uploaded_dir = $this->root_dir . "/" . self::UPLOADED_DIR; + $failed_dir = $this->root_dir . "/" . self::FAILED_DIR; + $queue_dirinfo = $this->scan_dir($queue_dir); $uploaded_dirinfo = $this->scan_dir($uploaded_dir); $failed_dirinfo = $this->scan_dir($failed_dir); - + $cron_url = make_http(make_link("/cron_upload/" . $this->upload_key)); $cron_cmd = "curl --silent $cron_url"; $log_path = $this->root_dir . "/uploads.log"; - + $info_html = "Information
@@ -105,7 +126,7 @@ class CronUploader extends Extension
Cron Command:
Create a cron job with the command above.
Read the documentation if you're not sure what to do.
"; - + $install_html = " This cron uploader is fairly easy to use but has to be configured first.
1. Install & activate this plugin. @@ -130,8 +151,10 @@ class CronUploader extends Extension
So when you want to manually upload an image, all you have to do is open the link once.
This link can be found under 'Cron Command' in the board config, just remove the 'wget ' part and only the url remains.
($cron_url)"; - - + + $page->set_title("Cron Uploader"); + $page->set_heading("Cron Uploader"); + $block = new Block("Cron Uploader", $info_html, "main", 10); $block_install = new Block("Installation Guide", $install_html, "main", 20); $page->add_block($block); @@ -142,36 +165,37 @@ class CronUploader extends Extension { global $config; // Set default values - $this->upload_key = $config->get_string("cron_uploader_key", ""); - if (strlen($this->upload_key)<=0) { + $config->set_default_int(self::CONFIG_COUNT, 1); + $this->set_dir(); + + $this->upload_key = $config->get_string(self::CONFIG_KEY, ""); + if (empty($this->upload_key)) { $this->upload_key = $this->generate_key(); - - $config->set_default_int('cron_uploader_count', 1); - $config->set_default_string('cron_uploader_key', $this->upload_key); - $this->set_dir(); + + $config->set_string(self::CONFIG_KEY, $this->upload_key); } } - + public function onSetupBuilding(SetupBuildingEvent $event) { $this->set_dir(); - + $cron_url = make_http(make_link("/cron_upload/" . $this->upload_key)); $cron_cmd = "curl --silent $cron_url"; $documentation_link = make_http(make_link("cron_upload")); - + $sb = new SetupBlock("Cron Uploader"); $sb->add_label("Settings
"); - $sb->add_int_option("cron_uploader_count", "How many to upload each time"); - $sb->add_text_option("cron_uploader_dir", "
Set Cron Uploader root directory
"); - - $sb->add_label("
Cron Command:
+ $sb->add_int_option(self::CONFIG_COUNT, "How many to upload each time"); + $sb->add_text_option(self::CONFIG_DIR, "
Set Cron Uploader root directory
"); + + $sb->add_label("
Cron Command:
Create a cron job with the command above.
Read the documentation if you're not sure what to do."); $event->panel->add_block($sb); } - + /* * Generates a unique key for the website to prevent unauthorized access. */ @@ -180,14 +204,14 @@ class CronUploader extends Extension $length = 20; $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $randomString = ''; - - for ($i = 0; $i < $length; $i ++) { + + for ($i = 0; $i < $length; $i++) { $randomString .= $characters [rand(0, strlen($characters) - 1)]; } - + return $randomString; } - + /* * Set the directory for the image queue. If no directory was given, set it to the default directory. */ @@ -195,50 +219,50 @@ class CronUploader extends Extension { global $config; // Determine directory (none = default) - - $dir = $config->get_string("cron_uploader_dir", ""); - + + $dir = $config->get_string(self::CONFIG_DIR, ""); + // Sets new default dir if not in config yet/anymore if ($dir == "") { $dir = data_path("cron_uploader"); - $config->set_string('cron_uploader_dir', $dir); + $config->set_string(self::CONFIG_DIR, $dir); } - + // Make the directory if it doesn't exist yet - if (!is_dir($dir . "/queue/")) { - mkdir($dir . "/queue/", 0775, true); + if (!is_dir($dir . "/" . self::QUEUE_DIR . "/")) { + mkdir($dir . "/" . self::QUEUE_DIR . "/", 0775, true); } - if (!is_dir($dir . "/uploaded/")) { - mkdir($dir . "/uploaded/", 0775, true); + if (!is_dir($dir . "/" . self::UPLOADED_DIR . "/")) { + mkdir($dir . "/" . self::UPLOADED_DIR . "/", 0775, true); } - if (!is_dir($dir . "/failed_to_upload/")) { - mkdir($dir . "/failed_to_upload/", 0775, true); + if (!is_dir($dir . "/" . self::FAILED_DIR . "/")) { + mkdir($dir . "/" . self::FAILED_DIR . "/", 0775, true); } - + $this->root_dir = $dir; return $dir; } - + /** * Returns amount of files & total size of dir. */ public function scan_dir(string $path): array { - $bytestotal=0; - $nbfiles=0; + $bytestotal = 0; + $nbfiles = 0; - $ite=new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS); - foreach (new RecursiveIteratorIterator($ite) as $filename=>$cur) { + $ite = new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS); + foreach (new RecursiveIteratorIterator($ite) as $filename => $cur) { $filesize = $cur->getSize(); $bytestotal += $filesize; $nbfiles++; } - + $size_mb = $bytestotal / 1048576; // to mb $size_mb = number_format($size_mb, 2, '.', ''); - return ['total_files'=>$nbfiles,'total_mb'=>$size_mb]; + return ['total_files' => $nbfiles, 'total_mb' => $size_mb]; } - + /** * Uploads the image & handles everything */ @@ -246,24 +270,24 @@ class CronUploader extends Extension { global $config, $database; - set_time_limit(0); + //set_time_limit(0); - $output_subdir = date('Ymd-His', time())."/"; - $this->set_dir(); + + $output_subdir = date('Ymd-His', time()) . "/"; $this->generate_image_queue(); - + // Gets amount of imgs to upload if ($upload_count == 0) { - $upload_count = $config->get_int("cron_uploader_count", 1); + $upload_count = $config->get_int(self::CONFIG_COUNT, 1); } - + // Throw exception if there's nothing in the queue if (count($this->image_queue) == 0) { $this->add_upload_info("Your queue is empty so nothing could be uploaded."); $this->handle_log(); return false; } - + // Randomize Images //shuffle($this->image_queue); @@ -271,18 +295,17 @@ class CronUploader extends Extension $added = 0; $failed = 0; - $failedItems = []; - // Upload the file(s) - for ($i = 0; $i < $upload_count && sizeof($this->image_queue)>0; $i++) { + for ($i = 0; $i < $upload_count && sizeof($this->image_queue) > 0; $i++) { $img = array_pop($this->image_queue); - + try { $database->beginTransaction(); + $this->add_upload_info("Adding file: {$img[1]} - tags: {$img[2]}"); $result = $this->add_image($img[0], $img[1], $img[2]); $database->commit(); $this->move_uploaded($img[0], $img[1], $output_subdir, false); - if ($result==null) { + if ($result->merged) { $merged++; } else { $added++; @@ -290,13 +313,9 @@ class CronUploader extends Extension } catch (Exception $e) { $failed++; $this->move_uploaded($img[0], $img[1], $output_subdir, true); - $msgNumber = $this->add_upload_info("(".gettype($e).") ".$e->getMessage()); + $msgNumber = $this->add_upload_info("(" . gettype($e) . ") " . $e->getMessage()); $msgNumber = $this->add_upload_info($e->getTraceAsString()); - if (strpos($e->getMessage(), 'SQLSTATE') !== false) { - // Postgres invalidates the transaction if there is an SQL error, - // so all subsequence transactions will fail. - break; - } + try { $database->rollback(); } catch (Exception $e) { @@ -310,85 +329,95 @@ class CronUploader extends Extension $msgNumber = $this->add_upload_info("Items failed: $failed"); - // Display & save upload log $this->handle_log(); - + return true; + } - + private function move_uploaded($path, $filename, $output_subdir, $corrupt = false) { global $config; - + // Create $newDir = $this->root_dir; - + $relativeDir = dirname(substr($path, strlen($this->root_dir) + 7)); // Determine which dir to move to if ($corrupt) { // Move to corrupt dir - $newDir .= "/failed_to_upload/".$output_subdir.$relativeDir; + $newDir .= "/" . self::FAILED_DIR . "/" . $output_subdir . $relativeDir; $info = "ERROR: Image was not uploaded."; } else { - $newDir .= "/uploaded/".$output_subdir.$relativeDir; + $newDir .= "/" . self::UPLOADED_DIR . "/" . $output_subdir . $relativeDir; $info = "Image successfully uploaded. "; } - $newDir = str_replace("//", "/", $newDir."/"); + $newDir = str_replace("//", "/", $newDir . "/"); if (!is_dir($newDir)) { mkdir($newDir, 0775, true); } // move file to correct dir - rename($path, $newDir.$filename); - + rename($path, $newDir . $filename); + $this->add_upload_info($info . "Image \"$filename\" moved from queue to \"$newDir\"."); } /** * Generate the necessary DataUploadEvent for a given image and tags. */ - private function add_image(string $tmpname, string $filename, string $tags) + 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'] = Tag::explode($tags); + $metadata ['tags'] = $tagArray; // doesn't work when not logged in here, handled below $metadata ['source'] = null; $event = new DataUploadEvent($tmpname, $metadata); send_event($event); - + // Generate info message $infomsg = ""; // Will contain info message if ($event->image_id == -1) { throw new Exception("File type not recognised. Filename: {$filename}"); - } elseif ($event->image_id == null) { - $infomsg = "Image merged. Filename: {$filename}"; + } elseif ($event->merged === true) { + $infomsg = "Image merged. ID: {$event->image_id} Filename: {$filename}"; } else { $infomsg = "Image uploaded. ID: {$event->image_id} - Filename: {$filename}"; } $msgNumber = $this->add_upload_info($infomsg); - return $event->image_id; + + // Set tags + $img = Image::by_id($event->image_id); + $img->set_tags(array_merge($tagArray, $img->get_tag_array())); + + return $event; } - + private function generate_image_queue(): void { - $base = $this->root_dir . "/queue"; - - if (! is_dir($base)) { + $base = $this->root_dir . "/" . self::QUEUE_DIR; + + if (!is_dir($base)) { $this->add_upload_info("Image Queue Directory could not be found at \"$base\"."); return; } - - $ite=new RecursiveDirectoryIterator($base, FilesystemIterator::SKIP_DOTS); - foreach (new RecursiveIteratorIterator($ite) as $fullpath=>$cur) { + + $ite = new RecursiveDirectoryIterator($base, FilesystemIterator::SKIP_DOTS); + foreach (new RecursiveIteratorIterator($ite) as $fullpath => $cur) { if (!is_link($fullpath) && !is_dir($fullpath)) { $pathinfo = pathinfo($fullpath); @@ -396,62 +425,62 @@ class CronUploader extends Extension $tags = path_to_tags($relativePath); $img = [ - 0 => $fullpath, - 1 => $pathinfo ["basename"], - 2 => $tags + 0 => $fullpath, + 1 => $pathinfo ["basename"], + 2 => $tags ]; array_push($this->image_queue, $img); } } } - + /** * Adds a message to the info being published at the end */ private function add_upload_info(string $text, int $addon = 0): int { $info = $this->upload_info; - $time = "[" .date('Y-m-d H:i:s'). "]"; - + $time = "[" . date('Y-m-d H:i:s') . "]"; + // If addon function is not used if ($addon == 0) { - $this->upload_info .= "$time $text\r\n"; - + $this->upload_info .= "$time $text\r\n"; + // Returns the number of the current line - $currentLine = substr_count($this->upload_info, "\n") -1; + $currentLine = substr_count($this->upload_info, "\n") - 1; return $currentLine; } - + // else if addon function is used, select the line & modify it $lines = substr($info, "\n"); // Seperate the string to array in lines $lines[$addon] = "$lines[$addon] $text"; // Add the content to the line $this->upload_info = implode("\n", $lines); // Put string back together & update - + return $addon; // Return line number } - + /** * This is run at the end to display & save the log. */ private function handle_log() { global $page; - + // Display message - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->set_type("text/plain"); $page->set_data($this->upload_info); - + // Save log $log_path = $this->root_dir . "/uploads.log"; - + if (file_exists($log_path)) { $prev_content = file_get_contents($log_path); } else { $prev_content = ""; } - - $content = $prev_content ."\r\n".$this->upload_info; + + $content = $prev_content . "\r\n" . $this->upload_info; file_put_contents($log_path, $content); } } diff --git a/ext/danbooru_api/main.php b/ext/danbooru_api/main.php index a831f366..ce13295b 100644 --- a/ext/danbooru_api/main.php +++ b/ext/danbooru_api/main.php @@ -60,7 +60,7 @@ class DanbooruApi extends Extension private function api_danbooru(PageRequestEvent $event) { global $page; - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); if (($event->get_arg(1) == 'add_post') || (($event->get_arg(1) == 'post') && ($event->get_arg(2) == 'create.xml'))) { // No XML data is returned from this function @@ -80,7 +80,7 @@ class DanbooruApi extends Extension // This redirects that to http://shimmie/post/view/123 elseif (($event->get_arg(1) == 'post') && ($event->get_arg(2) == 'show')) { $fixedlocation = make_link("post/view/" . $event->get_arg(3)); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect($fixedlocation); } } diff --git a/ext/downtime/theme.php b/ext/downtime/theme.php index feb7e4ea..caedcfda 100644 --- a/ext/downtime/theme.php +++ b/ext/downtime/theme.php @@ -26,7 +26,7 @@ class DowntimeTheme extends Themelet $login_link = make_link("user_admin/login"); $auth = $user->get_auth_html(); - $page->set_mode('data'); + $page->set_mode(PageMode::DATA); $page->set_code(503); $page->set_data( <<set_mode("data"); + $page->set_mode(PageMode::DATA); $page->set_data($html); } } diff --git a/ext/ext_manager/main.php b/ext/ext_manager/main.php index f9ef6bba..b41b53dd 100644 --- a/ext/ext_manager/main.php +++ b/ext/ext_manager/main.php @@ -22,8 +22,7 @@ class ExtensionInfo public $ext_name; public $name; public $link; - public $author; - public $email; + public $authors; public $description; public $documentation; public $version; @@ -39,8 +38,9 @@ class ExtensionInfo $this->ext_name = $matches[1]; $this->name = $this->ext_name; $this->enabled = $this->is_enabled($this->ext_name); + $this->authors = []; - for ($i=0; $i<$number_of_lines; $i++) { + for ($i = 0; $i < $number_of_lines; $i++) { $line = $lines[$i]; if (preg_match("/Name: (.*)/", $line, $matches)) { $this->name = $matches[1]; @@ -53,25 +53,31 @@ class ExtensionInfo } } elseif (preg_match("/Version: (.*)/", $line, $matches)) { $this->version = $matches[1]; - } elseif (preg_match("/Author: (.*) [<\(](.*@.*)[>\)]/", $line, $matches)) { - $this->author = $matches[1]; - $this->email = $matches[2]; - } elseif (preg_match("/Author: (.*)/", $line, $matches)) { - $this->author = $matches[1]; + } elseif (preg_match("/Authors?: (.*)/", $line, $matches)) { + $author_list = explode(',', $matches[1]); + foreach ($author_list as $author) { + if (preg_match("/(.*) [<\(](.*@.*)[>\)]/", $author, $matches)) { + $this->authors[] = new ExtensionAuthor($matches[1], $matches[2]); + } else { + $this->authors[] = new ExtensionAuthor($author, null); + } + } + + } elseif (preg_match("/(.*)Description: ?(.*)/", $line, $matches)) { $this->description = $matches[2]; - $start = $matches[1]." "; + $start = $matches[1] . " "; $start_len = strlen($start); - while (substr($lines[$i+1], 0, $start_len) == $start) { - $this->description .= " ".substr($lines[$i+1], $start_len); + while (substr($lines[$i + 1], 0, $start_len) == $start) { + $this->description .= " " . substr($lines[$i + 1], $start_len); $i++; } } elseif (preg_match("/(.*)Documentation: ?(.*)/", $line, $matches)) { $this->documentation = $matches[2]; - $start = $matches[1]." "; + $start = $matches[1] . " "; $start_len = strlen($start); - while (substr($lines[$i+1], 0, $start_len) == $start) { - $this->documentation .= " ".substr($lines[$i+1], $start_len); + while (substr($lines[$i + 1], 0, $start_len) == $start) { + $this->documentation .= " " . substr($lines[$i + 1], $start_len); $i++; } $this->documentation = str_replace('$site', make_http(get_base_href()), $this->documentation); @@ -96,6 +102,18 @@ class ExtensionInfo } } +class ExtensionAuthor +{ + public $name; + public $email; + + public function __construct(string $name, ?string $email) + { + $this->name = $name; + $this->email = $email; + } +} + class ExtManager extends Extension { public function onPageRequest(PageRequestEvent $event) @@ -107,7 +125,7 @@ class ExtManager extends Extension if (is_writable("data/config")) { $this->set_things($_POST); log_warning("ext_manager", "Active extensions changed", "Active extensions changed"); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("ext_manager")); } else { $this->theme->display_error( @@ -166,7 +184,7 @@ class ExtManager extends Extension if ($all) { $exts = zglob("ext/*/main.php"); } else { - $exts = zglob("ext/{".ENABLED_EXTS."}/main.php"); + $exts = zglob("ext/{" . ENABLED_EXTS . "}/main.php"); } foreach ($exts as $main) { $extensions[] = new ExtensionInfo($main); @@ -200,9 +218,9 @@ class ExtManager extends Extension { file_put_contents( "data/config/extensions.conf.php", - '<'.'?php'."\n". - 'define("EXTRA_EXTS", "'.implode(",", $extras).'");'."\n". - '?'.">" + '<' . '?php' . "\n" . + 'define("EXTRA_EXTS", "' . implode(",", $extras) . '");' . "\n" . + '?' . ">" ); // when the list of active extensions changes, we can be diff --git a/ext/ext_manager/theme.php b/ext/ext_manager/theme.php index 3cc6d871..58bd79ab 100644 --- a/ext/ext_manager/theme.php +++ b/ext/ext_manager/theme.php @@ -9,7 +9,7 @@ class ExtManagerTheme extends Themelet { $h_en = $editable ? "" : ""; $html = " - ".make_form(make_link("ext_manager/set"))." + " . make_form(make_link("ext_manager/set")) . "
Enabled
@@ -26,17 +26,17 @@ class ExtManagerTheme extends Themelet continue; } - $h_name = html_escape(empty($extension->name) ? $extension->ext_name : $extension->name); + $h_name = html_escape(empty($extension->name) ? $extension->ext_name : $extension->name); $h_description = html_escape($extension->description); - $h_link = make_link("ext_doc/".url_escape($extension->ext_name)); - $h_enabled = ($extension->enabled === true ? " checked='checked'" : ($extension->enabled === false ? "" : " disabled checked='checked'")); - $h_enabled_box = $editable ? "" : ""; - $h_docs = ($extension->documentation ? "â– " : ""); //TODO: A proper "docs" symbol would be preferred here. + $h_link = make_link("ext_doc/" . url_escape($extension->ext_name)); + $h_enabled = ($extension->enabled === true ? " checked='checked'" : ($extension->enabled === false ? "" : " disabled checked='checked'")); + $h_enabled_box = $editable ? "" : ""; + $h_docs = ($extension->documentation ? "â– " : ""); //TODO: A proper "docs" symbol would be preferred here. $html .= " {$h_enabled_box} - + "; @@ -116,15 +116,24 @@ class ExtManagerTheme extends Themelet public function display_doc(Page $page, ExtensionInfo $info) { $author = ""; - if ($info->author) { - if ($info->email) { - $author = "
Author:email)."\">".html_escape($info->author).""; - } else { - $author = "
Author: ".html_escape($info->author); + if (count($info->authors) > 0) { + $author = "
Author"; + if (count($info->authors) > 1) { + $author .= "s"; } + $author .= ":"; + foreach ($info->authors as $auth) { + if (!empty($auth->email)) { + $author .= "email) . "\">" . html_escape($auth->name) . ""; + } else { + $author .= html_escape($auth->name); + } + } + } - $version = ($info->version) ? "
Version: ".html_escape($info->version) : ""; - $link = ($info->link) ? "
Home Page:link)."\">Link" : ""; + + $version = ($info->version) ? "
Version: " . html_escape($info->version) : ""; + $link = ($info->link) ? "
Home Page:link) . "\">Link" : ""; $doc = $info->documentation; $html = "
@@ -133,10 +142,10 @@ class ExtManagerTheme extends Themelet $link

$doc


-

Back to the list +

Back to the list

"; - $page->set_title("Documentation for ".html_escape($info->name)); + $page->set_title("Documentation for " . html_escape($info->name)); $page->set_heading(html_escape($info->name)); $page->add_block(new NavBlock()); $page->add_block(new Block("Documentation", $html)); diff --git a/ext/favorites/main.php b/ext/favorites/main.php index 1ccf2031..e8b7f6fe 100644 --- a/ext/favorites/main.php +++ b/ext/favorites/main.php @@ -81,7 +81,7 @@ class Favorites extends Extension log_debug("favourite", "Favourite removed for $image_id", "Favourite removed"); } } - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/$image_id")); } } diff --git a/ext/featured/main.php b/ext/featured/main.php index c58be8b4..4b713424 100644 --- a/ext/featured/main.php +++ b/ext/featured/main.php @@ -37,7 +37,7 @@ class Featured extends Extension if ($id > 0) { $config->set_int("featured_id", $id); log_info("featured", "Featured image set to $id", "Featured image set"); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/$id")); } } @@ -45,7 +45,7 @@ class Featured extends Extension if ($event->get_arg(0) == "download") { $image = Image::by_id($config->get_int("featured_id")); if (!is_null($image)) { - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->set_type($image->get_mime_type()); $page->set_data(file_get_contents($image->get_image_filename())); } diff --git a/ext/forum/main.php b/ext/forum/main.php index 95d79908..db2ff1a8 100644 --- a/ext/forum/main.php +++ b/ext/forum/main.php @@ -139,7 +139,7 @@ class Forum extends Extension $redirectTo = "forum/view/".$newThreadID."/1"; } - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link($redirectTo)); break; @@ -151,7 +151,7 @@ class Forum extends Extension $this->delete_post($postID); } - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("forum/view/".$threadID)); break; case "nuke": @@ -161,7 +161,7 @@ class Forum extends Extension $this->delete_thread($threadID); } - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("forum/index")); break; case "answer": @@ -176,11 +176,11 @@ class Forum extends Extension } $this->save_new_post($threadID, $user); } - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("forum/view/".$threadID."/".$total_pages)); break; default: - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("forum/index")); //$this->theme->display_error(400, "Invalid action", "You should check forum/index."); break; diff --git a/ext/handle_404/main.php b/ext/handle_404/main.php index 4bc31dfd..a45ea7fb 100644 --- a/ext/handle_404/main.php +++ b/ext/handle_404/main.php @@ -14,7 +14,7 @@ class Handle404 extends Extension { global $config, $page; // hax. - if ($page->mode == "page" && (!isset($page->blocks) || $this->count_main($page->blocks) == 0)) { + if ($page->mode == PageMode::PAGE && (!isset($page->blocks) || $this->count_main($page->blocks) == 0)) { $h_pagename = html_escape(implode('/', $event->args)); log_debug("handle_404", "Hit 404: $h_pagename"); $page->set_code(404); diff --git a/ext/handle_flash/main.php b/ext/handle_flash/main.php index 8da00583..e47b193b 100644 --- a/ext/handle_flash/main.php +++ b/ext/handle_flash/main.php @@ -8,12 +8,12 @@ class FlashFileHandler extends DataHandlerExtension { - protected function create_thumb(string $hash): bool + protected function create_thumb(string $hash, string $type): bool { global $config; if (!create_thumbnail_ffmpeg($hash)) { - copy("ext/handle_flash/thumb.jpg", warehouse_path("thumbs", $hash)); + copy("ext/handle_flash/thumb.jpg", warehouse_path(Image::THUMBNAIL_DIR, $hash)); } return true; } diff --git a/ext/handle_ico/main.php b/ext/handle_ico/main.php index 56e3f373..ab005c96 100644 --- a/ext/handle_ico/main.php +++ b/ext/handle_ico/main.php @@ -5,65 +5,45 @@ * Description: Handle windows icons */ -class IcoFileHandler extends Extension +class IcoFileHandler extends DataHandlerExtension { - public function onDataUpload(DataUploadEvent $event) + const SUPPORTED_EXTENSIONS = ["ico", "ani", "cur"]; + + + protected function supported_ext(string $ext): bool { - if ($this->supported_ext($event->type) && $this->check_contents($event->tmpname)) { - $hash = $event->hash; - $ha = substr($hash, 0, 2); - move_upload_to_archive($event); - send_event(new ThumbnailGenerationEvent($event->hash, $event->type)); - $image = $this->create_image_from_data("images/$ha/$hash", $event->metadata); - if (is_null($image)) { - throw new UploadException("Icon handler failed to create image object from data"); - } - $iae = new ImageAdditionEvent($image); - send_event($iae); - $event->image_id = $iae->image->id; - } + return in_array(strtolower($ext), self::SUPPORTED_EXTENSIONS); } - public function onDisplayingImage(DisplayingImageEvent $event) - { - global $page; - if ($this->supported_ext($event->image->ext)) { - $this->theme->display_image($page, $event->image); - } - } - - private function supported_ext(string $ext): bool - { - $exts = ["ico", "ani", "cur"]; - return in_array(strtolower($ext), $exts); - } - - private function create_image_from_data(string $filename, array $metadata) + protected function create_image_from_data(string $filename, array $metadata) { $image = new Image(); - $fp = fopen($filename, "r"); - $header = unpack("Snull/Stype/Scount", fread($fp, 6)); - $subheader = unpack("Cwidth/Cheight/Ccolours/Cnull/Splanes/Sbpp/Lsize/loffset", fread($fp, 16)); - fclose($fp); + $fp = fopen($filename, "r"); + try { + unpack("Snull/Stype/Scount", fread($fp, 6)); + $subheader = unpack("Cwidth/Cheight/Ccolours/Cnull/Splanes/Sbpp/Lsize/loffset", fread($fp, 16)); + } finally { + fclose($fp); + } $width = $subheader['width']; $height = $subheader['height']; $image->width = $width == 0 ? 256 : $width; $image->height = $height == 0 ? 256 : $height; - $image->filesize = $metadata['size']; - $image->hash = $metadata['hash']; - $image->filename = $metadata['filename']; - $image->ext = $metadata['extension']; + $image->filesize = $metadata['size']; + $image->hash = $metadata['hash']; + $image->filename = $metadata['filename']; + $image->ext = $metadata['extension']; $image->tag_array = is_array($metadata['tags']) ? $metadata['tags'] : Tag::explode($metadata['tags']); - $image->source = $metadata['source']; + $image->source = $metadata['source']; return $image; } - private function check_contents(string $file): bool + protected function check_contents(string $file): bool { if (!file_exists($file)) { return false; @@ -74,27 +54,8 @@ class IcoFileHandler extends Extension return ($header['null'] == 0 && ($header['type'] == 0 || $header['type'] == 1)); } - private function create_thumb(string $hash): bool + protected function create_thumb(string $hash, string $type): bool { - global $config; - - $inname = warehouse_path("images", $hash); - $outname = warehouse_path("thumbs", $hash); - - $tsize = get_thumbnail_size_scaled($width, $height); - $w = $tsize[0]; - $h = $tsise[1]; - - $q = $config->get_int("thumb_quality"); - $mem = $config->get_int("thumb_mem_limit") / 1024 / 1024; // IM takes memory in MB - - if ($config->get_bool("ico_convert")) { - // "-limit memory $mem" broken? - exec("convert {$inname}[0] -geometry {$w}x{$h} -quality {$q} jpg:$outname"); - } else { - copy($inname, $outname); - } - - return true; + return create_thumbnail_convert($hash, $type); } } diff --git a/ext/handle_mp3/main.php b/ext/handle_mp3/main.php index a3e3dc9c..e0fcd5a7 100644 --- a/ext/handle_mp3/main.php +++ b/ext/handle_mp3/main.php @@ -7,9 +7,9 @@ class MP3FileHandler extends DataHandlerExtension { - protected function create_thumb(string $hash): bool + protected function create_thumb(string $hash, string $type): bool { - copy("ext/handle_mp3/thumb.jpg", warehouse_path("thumbs", $hash)); + copy("ext/handle_mp3/thumb.jpg", warehouse_path(Image::THUMBNAIL_DIR, $hash)); return true; } diff --git a/ext/handle_pixel/main.php b/ext/handle_pixel/main.php index e10d8f75..ac72bcc1 100644 --- a/ext/handle_pixel/main.php +++ b/ext/handle_pixel/main.php @@ -8,11 +8,12 @@ class PixelFileHandler extends DataHandlerExtension { + const SUPPORTED_EXTENSIONS = ["jpg", "jpeg", "gif", "png", "webp"]; + protected function supported_ext(string $ext): bool { - $exts = ["jpg", "jpeg", "gif", "png", "webp"]; $ext = (($pos = strpos($ext, '?')) !== false) ? substr($ext, 0, $pos) : $ext; - return in_array(strtolower($ext), $exts); + return in_array(strtolower($ext), self::SUPPORTED_EXTENSIONS); } protected function create_image_from_data(string $filename, array $metadata) @@ -53,12 +54,12 @@ class PixelFileHandler extends DataHandlerExtension return false; } - protected function create_thumb(string $hash): bool + protected function create_thumb(string $hash, string $type): bool { global $config; - $inname = warehouse_path("images", $hash); - $outname = warehouse_path("thumbs", $hash); + $inname = warehouse_path(Image::IMAGE_DIR, $hash); + $outname = warehouse_path(Image::THUMBNAIL_DIR, $hash); $ok = false; @@ -96,7 +97,7 @@ class PixelFileHandler extends DataHandlerExtension try { $info = getimagesize($inname); - $tsize = get_thumbnail_size_scaled($info[0], $info[1]); + $tsize = get_thumbnail_size($info[0], $info[1], true); $image = image_resize_gd( $inname, $info, diff --git a/ext/handle_static/main.php b/ext/handle_static/main.php index e2dd7de1..fb20dd59 100644 --- a/ext/handle_static/main.php +++ b/ext/handle_static/main.php @@ -14,7 +14,7 @@ class HandleStatic extends Extension { global $config, $page; // hax. - if ($page->mode == "page" && (!isset($page->blocks) || $this->count_main($page->blocks) == 0)) { + if ($page->mode == PageMode::PAGE && (!isset($page->blocks) || $this->count_main($page->blocks) == 0)) { $h_pagename = html_escape(implode('/', $event->args)); $f_pagename = preg_replace("/[^a-z_\-\.]+/", "_", $h_pagename); $theme_name = $config->get_string("theme", "default"); @@ -27,7 +27,7 @@ class HandleStatic extends Extension $page->add_http_header("Cache-control: public, max-age=600"); $page->add_http_header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 600) . ' GMT'); - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->set_data(file_get_contents($filename)); if (endsWith($filename, ".ico")) { $page->set_type("image/x-icon"); diff --git a/ext/handle_svg/main.php b/ext/handle_svg/main.php index 5676d24f..9998a245 100644 --- a/ext/handle_svg/main.php +++ b/ext/handle_svg/main.php @@ -19,23 +19,24 @@ class SVGFileHandler extends DataHandlerExtension $sanitizer->removeRemoteReferences(true); $dirtySVG = file_get_contents($event->tmpname); $cleanSVG = $sanitizer->sanitize($dirtySVG); - file_put_contents(warehouse_path("images", $hash), $cleanSVG); + file_put_contents(warehouse_path(Image::IMAGE_DIR, $hash), $cleanSVG); send_event(new ThumbnailGenerationEvent($event->hash, $event->type)); - $image = $this->create_image_from_data(warehouse_path("images", $hash), $event->metadata); + $image = $this->create_image_from_data(warehouse_path(Image::IMAGE_DIR, $hash), $event->metadata); if (is_null($image)) { throw new UploadException("SVG handler failed to create image object from data"); } $iae = new ImageAdditionEvent($image); send_event($iae); $event->image_id = $iae->image->id; + $event->merged = $iae->merged; } } - protected function create_thumb(string $hash): bool + protected function create_thumb(string $hash, string $type): bool { if (!create_thumbnail_convert($hash)) { - copy("ext/handle_svg/thumb.jpg", warehouse_path("thumbs", $hash)); + copy("ext/handle_svg/thumb.jpg", warehouse_path(Image::THUMBNAIL_DIR, $hash)); } return true; } @@ -57,11 +58,11 @@ class SVGFileHandler extends DataHandlerExtension $hash = $image->hash; $page->set_type("image/svg+xml"); - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $sanitizer = new Sanitizer(); $sanitizer->removeRemoteReferences(true); - $dirtySVG = file_get_contents(warehouse_path("images", $hash)); + $dirtySVG = file_get_contents(warehouse_path(Image::IMAGE_DIR, $hash)); $cleanSVG = $sanitizer->sanitize($dirtySVG); $page->set_data($cleanSVG); } diff --git a/ext/handle_video/main.php b/ext/handle_video/main.php index 316139c8..f4f50320 100644 --- a/ext/handle_video/main.php +++ b/ext/handle_video/main.php @@ -53,7 +53,7 @@ class VideoFileHandler extends DataHandlerExtension /** * Generate the Thumbnail image for particular file. */ - protected function create_thumb(string $hash): bool + protected function create_thumb(string $hash, string $type): bool { return create_thumbnail_ffmpeg($hash); } diff --git a/ext/home/theme.php b/ext/home/theme.php index e8f4086d..8dfc666d 100644 --- a/ext/home/theme.php +++ b/ext/home/theme.php @@ -4,7 +4,7 @@ class HomeTheme extends Themelet { public function display_page(Page $page, $sitename, $base_href, $theme_name, $body) { - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->add_auto_html_headers(); $hh = $page->get_all_html_headers(); $page->set_data( diff --git a/ext/image/main.php b/ext/image/main.php index b2fe5722..3fc63325 100644 --- a/ext/image/main.php +++ b/ext/image/main.php @@ -43,7 +43,7 @@ class ImageIO extends Extension $image = Image::by_id($_POST['image_id']); if ($image) { send_event(new ImageDeletionEvent($image)); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); if (isset($_SERVER['HTTP_REFERER']) && !strstr($_SERVER['HTTP_REFERER'], 'post/view')) { $page->set_redirect($_SERVER['HTTP_REFERER']); } else { @@ -56,7 +56,7 @@ class ImageIO extends Extension if ($user->can("replace_image") && isset($_POST['image_id']) && $user->check_auth_token()) { $image = Image::by_id($_POST['image_id']); if ($image) { - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link('upload/replace/'.$image->id)); } else { /* Invalid image ID */ @@ -88,7 +88,7 @@ class ImageIO extends Extension public function onImageAddition(ImageAdditionEvent $event) { try { - $this->add_image($event->image); + $this->add_image($event); } catch (ImageAdditionException $e) { throw new UploadException($e->error); } @@ -141,7 +141,7 @@ class ImageIO extends Extension $thumb_types = []; $thumb_types['JPEG'] = "jpg"; - $thumb_types['WEBP'] = "webp"; + $thumb_types['WEBP (Not IE/Safari compatible)'] = "webp"; $sb = new SetupBlock("Thumbnailing"); @@ -175,10 +175,12 @@ class ImageIO extends Extension // add image {{{ - private function add_image(Image $image) + private function add_image(ImageAdditionEvent $event) { global $user, $database, $config; + $image = $event->image; + /* * Validate things */ @@ -201,7 +203,9 @@ class ImageIO extends Extension if (isset($_GET['source']) && isset($_GET['update'])) { send_event(new SourceSetEvent($existing, $_GET['source'])); } - return null; + $event->merged = true; + $event->image = Image::by_id($existing->id); + return; } else { $error = "Image {$existing->id} ". "already has hash {$image->hash}:

".$this->theme->build_thumb_html($existing); @@ -251,7 +255,7 @@ class ImageIO extends Extension global $page; if (!is_null($image)) { - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); if ($type == "thumb") { $ext = $config->get_string("thumb_type"); if (array_key_exists($ext, MIME_TYPE_MAP)) { diff --git a/ext/image_hash_ban/main.php b/ext/image_hash_ban/main.php index 6589ee16..c2e3ec3a 100644 --- a/ext/image_hash_ban/main.php +++ b/ext/image_hash_ban/main.php @@ -79,7 +79,7 @@ class ImageBan extends Extension flash_message("Image deleted"); } - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect($_SERVER['HTTP_REFERER']); } } elseif ($event->get_arg(0) == "remove") { @@ -87,7 +87,7 @@ class ImageBan extends Extension send_event(new RemoveImageHashBanEvent($_POST['hash'])); flash_message("Image ban removed"); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect($_SERVER['HTTP_REFERER']); } } elseif ($event->get_arg(0) == "list") { diff --git a/ext/index/main.php b/ext/index/main.php index f8d77843..7e37f7ea 100644 --- a/ext/index/main.php +++ b/ext/index/main.php @@ -239,10 +239,10 @@ class Index extends Extension // implode(explode()) to resolve aliases and sanitise $search = url_escape(Tag::implode(Tag::explode($_GET['search'], false))); if (empty($search)) { - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/list/1")); } else { - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link('post/list/'.$search.'/1')); } return; @@ -278,7 +278,7 @@ class Index extends Extension $this->theme->display_intro($page); send_event(new PostListBuildingEvent($search_terms)); } elseif ($count_search_terms > 0 && $count_images === 1 && $page_number === 1) { - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link('post/view/'.$images[0]->id)); } else { $plbe = new PostListBuildingEvent($search_terms); diff --git a/ext/index/test.php b/ext/index/test.php index e9debe74..5d54fd42 100644 --- a/ext/index/test.php +++ b/ext/index/test.php @@ -157,7 +157,7 @@ class IndexTest extends ShimmiePHPUnitTestCase global $database; $db = $database->get_driver_name(); - if ($db == "pgsql" || $db == "sqlite") { + if ($db == DatabaseDriver::PGSQL || $db == DatabaseDriver::SQLITE) { $this->markTestIncomplete(); } diff --git a/ext/ipban/main.php b/ext/ipban/main.php index 659246f9..d6feb092 100644 --- a/ext/ipban/main.php +++ b/ext/ipban/main.php @@ -77,7 +77,7 @@ class IPBan extends Extension send_event(new AddIPBanEvent($_POST['ip'], $_POST['reason'], $end)); flash_message("Ban for {$_POST['ip']} added"); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("ip_ban/list")); } } elseif ($event->get_arg(0) == "remove" && $user->check_auth_token()) { @@ -85,7 +85,7 @@ class IPBan extends Extension send_event(new RemoveIPBanEvent($_POST['id'])); flash_message("Ban removed"); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("ip_ban/list")); } } elseif ($event->get_arg(0) == "list") { @@ -235,7 +235,7 @@ class IPBan extends Extension { global $config, $database; - $prefix = ($database->get_driver_name() == "sqlite" ? "bans." : ""); + $prefix = ($database->get_driver_name() == DatabaseDriver::SQLITE ? "bans." : ""); $bans = $this->get_active_bans(); diff --git a/ext/ipban/theme.php b/ext/ipban/theme.php index 6529c51f..0373c94d 100644 --- a/ext/ipban/theme.php +++ b/ext/ipban/theme.php @@ -16,7 +16,7 @@ class IPBanTheme extends Themelet { global $database, $user; $h_bans = ""; - $prefix = ($database->get_driver_name() == "sqlite" ? "bans." : ""); + $prefix = ($database->get_driver_name() == DatabaseDriver::SQLITE ? "bans." : ""); foreach ($bans as $ban) { $end_human = date('Y-m-d', $ban[$prefix.'end_timestamp']); $h_bans .= " diff --git a/ext/log_db/main.php b/ext/log_db/main.php index b185c783..2f1d761a 100644 --- a/ext/log_db/main.php +++ b/ext/log_db/main.php @@ -68,7 +68,7 @@ class LogDatabase extends Extension $args["module"] = $_GET["module"]; } if (!empty($_GET["user"])) { - if ($database->get_driver_name() == "pgsql") { + if ($database->get_driver_name() == DatabaseDriver::PGSQL) { if (preg_match("#\d+\.\d+\.\d+\.\d+(/\d+)?#", $_GET["user"])) { $wheres[] = "(username = :user1 OR text(address) = :user2)"; $args["user1"] = $_GET["user"]; diff --git a/ext/mail/main.php b/ext/mail/main.php index 3e51bcb4..35fb2061 100644 --- a/ext/mail/main.php +++ b/ext/mail/main.php @@ -35,7 +35,7 @@ class MailTest extends Extension { if ($event->page_matches("mail/test")) { global $page; - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); echo "Alert: uncomment this page's code on /ext/mail/main.php starting on line 33, and change the email address. Make sure you're using a server with a domain, not localhost."; /* echo "Preparing to send message:
"; diff --git a/ext/mass_tagger/main.php b/ext/mass_tagger/main.php index 648d7b79..fe91b366 100644 --- a/ext/mass_tagger/main.php +++ b/ext/mass_tagger/main.php @@ -64,7 +64,7 @@ class MassTagger extends Extension } } - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); if (!isset($_SERVER['HTTP_REFERER'])) { $_SERVER['HTTP_REFERER'] = make_link(); } diff --git a/ext/not_a_tag/main.php b/ext/not_a_tag/main.php index c03b0e81..18486e9c 100644 --- a/ext/not_a_tag/main.php +++ b/ext/not_a_tag/main.php @@ -81,14 +81,14 @@ class NotATag extends Extension [$tag, $redirect] ); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect($_SERVER['HTTP_REFERER']); } elseif ($event->get_arg(0) == "remove") { if (isset($_POST['tag'])) { $database->Execute("DELETE FROM untags WHERE tag = ?", [$_POST['tag']]); flash_message("Image ban removed"); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect($_SERVER['HTTP_REFERER']); } } elseif ($event->get_arg(0) == "list") { diff --git a/ext/notes/main.php b/ext/notes/main.php index 14285df2..aafa928f 100644 --- a/ext/notes/main.php +++ b/ext/notes/main.php @@ -100,7 +100,7 @@ class Notes extends Extension $this->revert_history($noteID, $reviewID); } - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("note/updated")); break; case "add_note": @@ -108,7 +108,7 @@ class Notes extends Extension $this->add_new_note(); } - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/".$_POST["image_id"])); break; case "add_request": @@ -116,7 +116,7 @@ class Notes extends Extension $this->add_note_request(); } - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/".$_POST["image_id"])); break; case "nuke_notes": @@ -124,7 +124,7 @@ class Notes extends Extension $this->nuke_notes(); } - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/".$_POST["image_id"])); break; case "nuke_requests": @@ -132,25 +132,25 @@ class Notes extends Extension $this->nuke_requests(); } - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/".$_POST["image_id"])); break; case "edit_note": if (!$user->is_anonymous()) { $this->update_note(); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/" . $_POST["image_id"])); } break; case "delete_note": if ($user->is_admin()) { $this->delete_note(); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/".$_POST["image_id"])); } break; default: - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("note/list")); break; } diff --git a/ext/numeric_score/main.php b/ext/numeric_score/main.php index f15a9d37..5275dfa7 100644 --- a/ext/numeric_score/main.php +++ b/ext/numeric_score/main.php @@ -94,7 +94,7 @@ class NumericScore extends Extension if (!is_null($score) && $image_id>0) { send_event(new NumericScoreSetEvent($image_id, $user, $score)); } - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/$image_id")); } } elseif ($event->page_matches("numeric_score/remove_votes_on") && $user->check_auth_token()) { @@ -108,13 +108,13 @@ class NumericScore extends Extension "UPDATE images SET numeric_score=0 WHERE id=?", [$image_id] ); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/$image_id")); } } elseif ($event->page_matches("numeric_score/remove_votes_by") && $user->check_auth_token()) { if ($user->can("edit_other_vote")) { $this->delete_votes_by(int_escape($_POST['user_id'])); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link()); } } elseif ($event->page_matches("popular_by_day") || $event->page_matches("popular_by_month") || $event->page_matches("popular_by_year")) { diff --git a/ext/oekaki/main.php b/ext/oekaki/main.php index f18383e9..1da9cc90 100644 --- a/ext/oekaki/main.php +++ b/ext/oekaki/main.php @@ -41,7 +41,7 @@ class Oekaki extends Extension throw new UploadException("File type not recognised"); } else { unlink($tmpname); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/".$duev->image_id)); } } diff --git a/ext/ouroboros_api/main.php b/ext/ouroboros_api/main.php index 9434f6aa..91fd85ef 100644 --- a/ext/ouroboros_api/main.php +++ b/ext/ouroboros_api/main.php @@ -404,7 +404,7 @@ class OuroborosAPI extends Extension } elseif ($this->type == 'xml') { $page->set_type('text/xml; charset=utf-8'); } - $page->set_mode('data'); + $page->set_mode(PageMode::DATA); $this->tryAuth(); if ($event->page_matches('post')) { @@ -464,7 +464,7 @@ class OuroborosAPI extends Extension } } } elseif ($event->page_matches('post/show')) { - $page->set_mode('redirect'); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link(str_replace('post/show', 'post/view', implode('/', $event->args)))); $page->display(); die(); diff --git a/ext/pm/main.php b/ext/pm/main.php index 2cf8d0a7..123d6368 100644 --- a/ext/pm/main.php +++ b/ext/pm/main.php @@ -149,7 +149,7 @@ class PrivMsg extends Extension $database->execute("DELETE FROM private_message WHERE id = :id", ["id" => $pm_id]); $database->cache->delete("pm-count-{$user->id}"); log_info("pm", "Deleted PM #$pm_id", "PM deleted"); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect($_SERVER["HTTP_REFERER"]); } } @@ -162,7 +162,7 @@ class PrivMsg extends Extension $message = $_POST["message"]; send_event(new SendPMEvent(new PM($from_id, $_SERVER["REMOTE_ADDR"], $to_id, $subject, $message))); flash_message("PM sent"); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect($_SERVER["HTTP_REFERER"]); } break; diff --git a/ext/pools/main.php b/ext/pools/main.php index 6fd35b9e..bdf8ce87 100644 --- a/ext/pools/main.php +++ b/ext/pools/main.php @@ -130,7 +130,7 @@ class Pools extends Extension case "create": // ADD _POST try { $newPoolID = $this->add_pool(); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("pool/view/".$newPoolID)); } catch (PoolCreationException $e) { $this->theme->display_error(400, "Error", $e->error); @@ -150,7 +150,7 @@ class Pools extends Extension if (!$user->is_anonymous()) { $historyID = int_escape($event->get_arg(1)); $this->revert_history($historyID); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("pool/updated")); } break; @@ -159,7 +159,7 @@ class Pools extends Extension if ($this->have_permission($user, $pool)) { $this->theme->edit_pool($page, $this->get_pool($pool_id), $this->edit_posts($pool_id)); } else { - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("pool/view/".$pool_id)); } break; @@ -169,13 +169,13 @@ class Pools extends Extension if ($this->have_permission($user, $pool)) { $this->theme->edit_order($page, $this->get_pool($pool_id), $this->edit_order($pool_id)); } else { - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("pool/view/".$pool_id)); } } else { if ($this->have_permission($user, $pool)) { $this->order_posts(); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("pool/view/".$pool_id)); } else { $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); @@ -194,7 +194,7 @@ class Pools extends Extension case "add_posts": if ($this->have_permission($user, $pool)) { $this->add_posts(); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("pool/view/".$pool_id)); } else { $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); @@ -204,7 +204,7 @@ class Pools extends Extension case "remove_posts": if ($this->have_permission($user, $pool)) { $this->remove_posts(); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("pool/view/".$pool_id)); } else { $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); @@ -215,7 +215,7 @@ class Pools extends Extension case "edit_description": if ($this->have_permission($user, $pool)) { $this->edit_description(); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("pool/view/".$pool_id)); } else { $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); @@ -228,7 +228,7 @@ class Pools extends Extension // -> Only admins and owners may do this if ($user->is_admin() || $user->id == $pool['user_id']) { $this->nuke_pool($pool_id); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("pool/list")); } else { $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); @@ -236,7 +236,7 @@ class Pools extends Extension break; default: - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("pool/list")); break; } diff --git a/ext/random_image/main.php b/ext/random_image/main.php index 6630b8cb..fc0424f7 100644 --- a/ext/random_image/main.php +++ b/ext/random_image/main.php @@ -40,7 +40,7 @@ class RandomImage extends Extension if ($action === "download") { if (!is_null($image)) { - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->set_type($image->get_mime_type()); $page->set_data(file_get_contents($image->get_image_filename())); } @@ -50,7 +50,7 @@ class RandomImage extends Extension } } elseif ($action === "widget") { if (!is_null($image)) { - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->set_type("text/html"); $page->set_data($this->theme->build_thumb_html($image)); } diff --git a/ext/random_list/main.php b/ext/random_list/main.php index a4da5604..7333905d 100644 --- a/ext/random_list/main.php +++ b/ext/random_list/main.php @@ -21,10 +21,10 @@ class RandomList extends Extension // implode(explode()) to resolve aliases and sanitise $search = url_escape(Tag::implode(Tag::explode($_GET['search'], false))); if (empty($search)) { - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("random")); } else { - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link('random/'.$search)); } return; diff --git a/ext/rating/main.php b/ext/rating/main.php index 18b40823..a5e173a1 100644 --- a/ext/rating/main.php +++ b/ext/rating/main.php @@ -37,7 +37,7 @@ class RatingSetEvent extends Event class Ratings extends Extension { - protected $db_support = ['mysql','pgsql']; // ? + protected $db_support = [DatabaseDriver::MYSQL, DatabaseDriver::PGSQL]; public function get_priority(): int { @@ -91,7 +91,7 @@ class Ratings extends Extension $user_view_level = Ratings::get_user_privs($user); $user_view_level = preg_split('//', $user_view_level, -1); if (!in_array($event->image->rating, $user_view_level)) { - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/list")); } } @@ -170,7 +170,7 @@ class Ratings extends Extension global $user; if ($user->is_admin()) { - $event->add_action("bulk_rate", "Set Rating", "", $this->theme->get_selection_rater_html("bulk_rating")); + $event->add_action("bulk_rate","Set Rating","",$this->theme->get_selection_rater_html("u","bulk_rating")); } } @@ -191,7 +191,7 @@ class Ratings extends Extension if ($image==null) { continue; } - + send_event(new RatingSetEvent($image, $rating)); $total++; } @@ -228,7 +228,7 @@ class Ratings extends Extension # select image_id from image_tags join tags # on image_tags.tag_id = tags.id where tags.tag = ?); # ", array($_POST["rating"], $_POST["tag"])); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/list")); } } @@ -331,10 +331,10 @@ class Ratings extends Extension if ($config->get_int("ext_ratings2_version") < 3) { $database->Execute("UPDATE images SET rating = 'u' WHERE rating is null"); switch ($database->get_driver_name()) { - case "mysql": + case DatabaseDriver::MYSQL: $database->Execute("ALTER TABLE images CHANGE rating rating CHAR(1) NOT NULL DEFAULT 'u'"); break; - case "pgsql": + case DatabaseDriver::PGSQL: $database->Execute("ALTER TABLE images ALTER COLUMN rating SET DEFAULT 'u'"); $database->Execute("ALTER TABLE images ALTER COLUMN rating SET NOT NULL"); break; diff --git a/ext/regen_thumb/main.php b/ext/regen_thumb/main.php index c7115b34..b402281f 100644 --- a/ext/regen_thumb/main.php +++ b/ext/regen_thumb/main.php @@ -43,7 +43,7 @@ class RegenThumb extends Extension $this->regenerate_thumbnail($image); } - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/list")); } } @@ -133,7 +133,7 @@ class RegenThumb extends Extension $i = 0; foreach ($images as $image) { if (!$force) { - $path = warehouse_path("thumbs", $image["hash"], false); + $path = warehouse_path(Image::THUMBNAIL_DIR, $image["hash"], false); if (file_exists($path)) { continue; } @@ -157,7 +157,7 @@ class RegenThumb extends Extension $i = 0; foreach ($images as $image) { - $outname = warehouse_path("thumbs", $image["hash"]); + $outname = warehouse_path(Image::THUMBNAIL_DIR, $image["hash"]); if (file_exists($outname)) { unlink($outname); $i++; diff --git a/ext/relatationships/main.php b/ext/relatationships/main.php index 28e785d1..5304e3a5 100644 --- a/ext/relatationships/main.php +++ b/ext/relatationships/main.php @@ -8,7 +8,7 @@ class Relationships extends Extension { - protected $db_support = ['mysql', 'pgsql']; + protected $db_support = [DatabaseDriver::MYSQL, DatabaseDriver::PGSQL]; public function onInitExt(InitExtEvent $event) { diff --git a/ext/report_image/main.php b/ext/report_image/main.php index 0e716fec..d3ee2c81 100644 --- a/ext/report_image/main.php +++ b/ext/report_image/main.php @@ -67,7 +67,7 @@ class ReportImage extends Extension if (!empty($_POST['image_id']) && !empty($_POST['reason'])) { $image_id = int_escape($_POST['image_id']); send_event(new AddReportedImageEvent(new ImageReport($image_id, $user->id, $_POST['reason']))); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/$image_id")); } else { $this->theme->display_error(500, "Missing input", "Missing image ID or report reason"); @@ -76,7 +76,7 @@ class ReportImage extends Extension if (!empty($_POST['id'])) { if ($user->can("view_image_report")) { send_event(new RemoveReportedImageEvent($_POST['id'])); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("image_report/list")); } } else { @@ -85,7 +85,7 @@ class ReportImage extends Extension } elseif ($event->get_arg(0) == "remove_reports_by" && $user->check_auth_token()) { if ($user->can("view_image_report")) { $this->delete_reports_by(int_escape($_POST['user_id'])); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link()); } } elseif ($event->get_arg(0) == "list") { diff --git a/ext/resize/main.php b/ext/resize/main.php index 41eabde0..a998814e 100644 --- a/ext/resize/main.php +++ b/ext/resize/main.php @@ -16,6 +16,8 @@ */ class ResizeImage extends Extension { + const SUPPORTED_EXT = ["jpg","jpeg","png","gif","webp"]; + /** * Needs to be after the data processing extensions */ @@ -37,7 +39,8 @@ class ResizeImage extends Extension public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event) { global $user, $config; - if ($user->is_admin() && $config->get_bool("resize_enabled")) { + if ($user->is_admin() && $config->get_bool("resize_enabled") + && in_array($event->image->ext, self::SUPPORTED_EXT)) { /* Add a link to resize the image */ $event->add_part($this->theme->get_resize_html($event->image)); } @@ -64,7 +67,8 @@ class ResizeImage extends Extension $image_obj = Image::by_id($event->image_id); - if ($config->get_bool("resize_upload") == true && ($image_obj->ext == "jpg" || $image_obj->ext == "png" || $image_obj->ext == "gif" || $image_obj->ext == "webp")) { + if ($config->get_bool("resize_upload") == true + && in_array($event->type, self::SUPPORTED_EXT)) { $width = $height = 0; if ($config->get_int("resize_default_width") !== 0) { @@ -75,7 +79,7 @@ class ResizeImage extends Extension } $isanigif = 0; if ($image_obj->ext == "gif") { - $image_filename = warehouse_path("images", $image_obj->hash); + $image_filename = warehouse_path(Image::IMAGE_DIR, $image_obj->hash); if (($fh = @fopen($image_filename, 'rb'))) { //check if gif is animated (via http://www.php.net/manual/en/function.imagecreatefromgif.php#104473) while (!feof($fh) && $isanigif < 2) { @@ -141,7 +145,7 @@ class ResizeImage extends Extension //$this->theme->display_resize_page($page, $image_id); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/".$image_id)); } catch (ImageResizeException $e) { $this->theme->display_resize_error($page, "Error Resizing", $e->error); @@ -163,7 +167,7 @@ class ResizeImage extends Extension } $hash = $image_obj->hash; - $image_filename = warehouse_path("images", $hash); + $image_filename = warehouse_path(Image::IMAGE_DIR, $hash); $info = getimagesize($image_filename); if (($image_obj->width != $info[0]) || ($image_obj->height != $info[1])) { @@ -189,7 +193,7 @@ class ResizeImage extends Extension $new_image->ext = $image_obj->ext; /* Move the new image into the main storage location */ - $target = warehouse_path("images", $new_image->hash); + $target = warehouse_path(Image::IMAGE_DIR, $new_image->hash); if (!@copy($tmp_filename, $target)) { throw new ImageResizeException("Failed to copy new image file from temporary location ({$tmp_filename}) to archive ($target)"); } diff --git a/ext/rotate/main.php b/ext/rotate/main.php index 397639a3..65194bbc 100644 --- a/ext/rotate/main.php +++ b/ext/rotate/main.php @@ -31,6 +31,8 @@ class ImageRotateException extends SCoreException */ class RotateImage extends Extension { + const SUPPORTED_EXT = ["jpg","jpeg","png","gif","webp"]; + public function onInitExt(InitExtEvent $event) { global $config; @@ -41,7 +43,8 @@ class RotateImage extends Extension public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event) { global $user, $config; - if ($user->is_admin() && $config->get_bool("rotate_enabled")) { + if ($user->is_admin() && $config->get_bool("rotate_enabled") + && in_array($event->image->ext, self::SUPPORTED_EXT)) { /* Add a link to rotate the image */ $event->add_part($this->theme->get_rotate_html($event->image->id)); } @@ -93,7 +96,7 @@ class RotateImage extends Extension //$this->theme->display_rotate_page($page, $image_id); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/".$image_id)); } catch (ImageRotateException $e) { $this->theme->display_rotate_error($page, "Error Rotating", $e->error); @@ -120,7 +123,7 @@ class RotateImage extends Extension throw new ImageRotateException("Image does not have a hash associated with it."); } - $image_filename = warehouse_path("images", $hash); + $image_filename = warehouse_path(Image::IMAGE_DIR, $hash); if (file_exists($image_filename)==false) { throw new ImageRotateException("$image_filename does not exist."); } @@ -212,7 +215,7 @@ class RotateImage extends Extension $new_image->ext = $image_obj->ext; /* Move the new image into the main storage location */ - $target = warehouse_path("images", $new_image->hash); + $target = warehouse_path(Image::IMAGE_DIR, $new_image->hash); if (!@copy($tmp_filename, $target)) { throw new ImageRotateException("Failed to copy new image file from temporary location ({$tmp_filename}) to archive ($target)"); } diff --git a/ext/rss_comments/main.php b/ext/rss_comments/main.php index 4f3b5ed5..b00f92aa 100644 --- a/ext/rss_comments/main.php +++ b/ext/rss_comments/main.php @@ -9,7 +9,7 @@ class RSS_Comments extends Extension { - protected $db_support = ['mysql', 'sqlite']; // pgsql has no UNIX_TIMESTAMP + protected $db_support = [DatabaseDriver::MYSQL, DatabaseDriver::SQLITE]; // pgsql has no UNIX_TIMESTAMP public function onPostListBuilding(PostListBuildingEvent $event) { @@ -24,7 +24,7 @@ class RSS_Comments extends Extension { global $config, $database, $page; if ($event->page_matches("rss/comments")) { - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->set_type("application/rss+xml"); $comments = $database->get_all(" diff --git a/ext/rss_images/main.php b/ext/rss_images/main.php index 292ecf05..b11fad92 100644 --- a/ext/rss_images/main.php +++ b/ext/rss_images/main.php @@ -39,7 +39,7 @@ class RSS_Images extends Extension { global $page; global $config; - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->set_type("application/rss+xml"); $data = ""; diff --git a/ext/rule34/main.php b/ext/rule34/main.php index a39b6949..529e6201 100644 --- a/ext/rule34/main.php +++ b/ext/rule34/main.php @@ -19,7 +19,7 @@ if ( // kill these glitched requests immediately class Rule34 extends Extension { - protected $db_support = ['pgsql']; # Only PG has the NOTIFY pubsub system + protected $db_support = [DatabaseDriver::PGSQL]; # Only PG has the NOTIFY pubsub system public function onImageDeletion(ImageDeletionEvent $event) { @@ -90,14 +90,14 @@ class Rule34 extends Extension 'UPDATE users SET comic_admin=? WHERE id=?', [$input['is_admin'] ? 't' : 'f', $input['user_id']] ); - $page->set_mode('redirect'); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(@$_SERVER['HTTP_REFERER']); } } if ($event->page_matches("tnc_agreed")) { setcookie("ui-tnc-agreed", "true", 0, "/"); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(@$_SERVER['HTTP_REFERER'] ?? "/"); } @@ -116,14 +116,14 @@ class Rule34 extends Extension continue; } log_info("admin", "Cleaning {$hash}"); - @unlink(warehouse_path('images', $hash)); - @unlink(warehouse_path('thumbs', $hash)); + @unlink(warehouse_path(Image::IMAGE_DIR, $hash)); + @unlink(warehouse_path(Image::THUMBNAIL_DIR, $hash)); $database->execute("NOTIFY shm_image_bans, '{$hash}';"); } } } - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("admin")); } } diff --git a/ext/rule34/theme.php b/ext/rule34/theme.php index 09712b3d..f71d8c15 100644 --- a/ext/rule34/theme.php +++ b/ext/rule34/theme.php @@ -19,7 +19,7 @@ class Rule34Theme extends Themelet { global $database, $user; $h_bans = ""; - $prefix = ($database->get_driver_name() == "sqlite" ? "bans." : ""); + $prefix = ($database->get_driver_name() == DatabaseDriver::SQLITE ? "bans." : ""); foreach ($bans as $ban) { $h_bans .= "

diff --git a/ext/setup/main.php b/ext/setup/main.php index b316c975..23999102 100644 --- a/ext/setup/main.php +++ b/ext/setup/main.php @@ -203,7 +203,7 @@ class Setup extends Extension global $config, $page, $user; if ($event->page_matches("nicetest")) { - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->set_data("ok"); } @@ -216,7 +216,7 @@ class Setup extends Extension $config->save(); flash_message("Config saved"); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("setup")); } elseif ($event->get_arg(0) == "advanced") { $this->theme->display_advanced($page, $config->values); diff --git a/ext/shimmie_api/main.php b/ext/shimmie_api/main.php index ed5a3e1c..130c4971 100644 --- a/ext/shimmie_api/main.php +++ b/ext/shimmie_api/main.php @@ -53,7 +53,7 @@ class ShimmieApi extends Extension global $page, $user; if ($event->page_matches("api/shimmie")) { - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->set_type("text/plain"); if ($event->page_matches("api/shimmie/get_tags")) { @@ -100,7 +100,7 @@ class ShimmieApi extends Extension $all = $this->api_get_user($type, $query); $page->set_data(json_encode($all)); } else { - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("ext_doc/shimmie_api")); } } diff --git a/ext/sitemap/main.php b/ext/sitemap/main.php index d7a17217..4ff80f88 100644 --- a/ext/sitemap/main.php +++ b/ext/sitemap/main.php @@ -152,7 +152,7 @@ class XMLSitemap extends Extension // Generate new sitemap file_put_contents($this->sitemap_filepath, $xml); - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->set_type("application/xml"); $page->set_data($xml); } @@ -188,7 +188,7 @@ class XMLSitemap extends Extension $xml = file_get_contents($this->sitemap_filepath); - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->set_type("application/xml"); $page->set_data($xml); } diff --git a/ext/source_history/main.php b/ext/source_history/main.php index d8de6b55..591fd217 100644 --- a/ext/source_history/main.php +++ b/ext/source_history/main.php @@ -132,7 +132,7 @@ class Source_History extends Extension // check for the nothing case if ($revert_id < 1) { - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link()); return; } @@ -165,7 +165,7 @@ class Source_History extends Extension send_event(new SourceSetEvent($image, $stored_source)); // all should be done now so redirect the user back to the image - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link('post/view/'.$stored_image_id)); } diff --git a/ext/tag_edit/main.php b/ext/tag_edit/main.php index 19f0dfa0..aa443797 100644 --- a/ext/tag_edit/main.php +++ b/ext/tag_edit/main.php @@ -165,14 +165,14 @@ class TagEdit extends Extension $search = $_POST['search']; $replace = $_POST['replace']; $this->mass_tag_edit($search, $replace); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("admin")); } } if ($event->get_arg(0) == "mass_source_set") { if ($user->can("mass_tag_edit") && isset($_POST['tags']) && isset($_POST['source'])) { $this->mass_source_edit($_POST['tags'], $_POST['source']); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/list")); } } diff --git a/ext/tag_history/main.php b/ext/tag_history/main.php index 125c36c7..618bd85a 100644 --- a/ext/tag_history/main.php +++ b/ext/tag_history/main.php @@ -132,7 +132,7 @@ class Tag_History extends Extension // check for the nothing case if ($revert_id < 1) { - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link()); return; } @@ -162,7 +162,7 @@ class Tag_History extends Extension send_event(new TagSetEvent($image, Tag::explode($stored_tags))); // all should be done now so redirect the user back to the image - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link('post/view/'.$stored_image_id)); } diff --git a/ext/tag_list/main.php b/ext/tag_list/main.php index c546794e..a415d153 100644 --- a/ext/tag_list/main.php +++ b/ext/tag_list/main.php @@ -75,7 +75,7 @@ class TagList extends Extension $database->cache->set($cache_key, $res, 600); } - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->set_type("text/plain"); $page->set_data(implode("\n", $res)); } diff --git a/ext/tagger/main.php b/ext/tagger/main.php index e7a9148e..631da7b4 100644 --- a/ext/tagger/main.php +++ b/ext/tagger/main.php @@ -59,7 +59,7 @@ class TaggerXML extends Extension $tags. ""; - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->set_type("text/xml"); $page->set_data($xml); } diff --git a/ext/tips/main.php b/ext/tips/main.php index f4f7d619..7e5610a6 100644 --- a/ext/tips/main.php +++ b/ext/tips/main.php @@ -10,7 +10,7 @@ class Tips extends Extension { - protected $db_support = ['mysql', 'sqlite']; // rand() ? + protected $db_support = [DatabaseDriver::MYSQL, DatabaseDriver::SQLITE]; // rand() ? public function onInitExt(InitExtEvent $event) { @@ -51,7 +51,7 @@ class Tips extends Extension case "save": if ($user->check_auth_token()) { $this->saveTip(); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("tips/list")); } break; @@ -59,14 +59,14 @@ class Tips extends Extension // FIXME: HTTP GET CSRF $tipID = int_escape($event->get_arg(1)); $this->setStatus($tipID); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("tips/list")); break; case "delete": // FIXME: HTTP GET CSRF $tipID = int_escape($event->get_arg(1)); $this->deleteTip($tipID); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("tips/list")); break; } diff --git a/ext/transcode/main.php b/ext/transcode/main.php index 85c554d8..94520ba0 100644 --- a/ext/transcode/main.php +++ b/ext/transcode/main.php @@ -43,6 +43,7 @@ class TranscodeImage extends Extension "psd", "tiff", "webp", + "ico", ] ]; @@ -68,6 +69,7 @@ class TranscodeImage extends Extension const INPUT_FORMATS = [ "BMP" => "bmp", "GIF" => "gif", + "ICO" => "ico", "JPG" => "jpg", "PNG" => "png", "PSD" => "psd", @@ -197,7 +199,7 @@ class TranscodeImage extends Extension if (isset($_POST['transcode_format'])) { try { $this->transcode_and_replace_image($image_obj, $_POST['transcode_format']); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/".$image_id)); } catch (ImageTranscodeException $e) { $this->theme->display_transcode_error($page, "Error Transcoding", $e->getMessage()); @@ -306,7 +308,7 @@ class TranscodeImage extends Extension private function transcode_and_replace_image(Image $image_obj, String $target_format) { $target_format = $this->clean_format($target_format); - $original_file = warehouse_path("images", $image_obj->hash); + $original_file = warehouse_path(Image::IMAGE_DIR, $image_obj->hash); $tmp_filename = $this->transcode_image($original_file, $image_obj->ext, $target_format); @@ -319,7 +321,7 @@ class TranscodeImage extends Extension $new_image->ext = $this->determine_ext($target_format); /* Move the new image into the main storage location */ - $target = warehouse_path("images", $new_image->hash); + $target = warehouse_path(Image::IMAGE_DIR, $new_image->hash); if (!@copy($tmp_filename, $target)) { throw new ImageTranscodeException("Failed to copy new image file from temporary location ({$tmp_filename}) to archive ($target)"); } @@ -440,15 +442,21 @@ class TranscodeImage extends Extension } $tmp_name = tempnam("/tmp", "shimmie_transcode"); - $format = '"%s" %s -quality %u -background %s "%s" %s:"%s"'; - $cmd = sprintf($format, $convert, $args, $q, $bg, $source_name, $ext, $tmp_name); + $source_type = ""; + switch ($source_format) { + case "ico": + $source_type = "ico:"; + } + + $format = '"%s" %s -quality %u -background %s %s"%s" %s:"%s" 2>&1'; + $cmd = sprintf($format, $convert, $args, $q, $bg, $source_type, $source_name, $ext, $tmp_name); $cmd = str_replace("\"convert\"", "convert", $cmd); // quotes are only needed if the path to convert contains a space; some other times, quotes break things, see github bug #27 exec($cmd, $output, $ret); log_debug('transcode', "Transcoding with command `$cmd`, returns $ret"); if ($ret!==0) { - throw new ImageTranscodeException("Transcoding failed with command ".$cmd); + throw new ImageTranscodeException("Transcoding failed with command ".$cmd.", returning ".implode("\r\n", $output)); } return $tmp_name; diff --git a/ext/update/main.php b/ext/update/main.php index cf995c10..00762620 100644 --- a/ext/update/main.php +++ b/ext/update/main.php @@ -38,7 +38,7 @@ class Update extends Extension if ($event->page_matches("update/download")) { $ok = $this->download_shimmie(); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); if ($ok) { $page->set_redirect(make_link("update/update", "sha=".$_GET['sha'])); } else { @@ -47,7 +47,7 @@ class Update extends Extension } elseif ($event->page_matches("update/update")) { $ok = $this->update_shimmie(); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); if ($ok) { $page->set_redirect(make_link("admin")); } //TODO: Show success? diff --git a/ext/upgrade/main.php b/ext/upgrade/main.php index 3321b409..160422b5 100644 --- a/ext/upgrade/main.php +++ b/ext/upgrade/main.php @@ -44,7 +44,7 @@ class Upgrade extends Extension $config->set_bool("in_upgrade", true); $config->set_int("db_version", 9); - if ($database->get_driver_name() == 'mysql') { + if ($database->get_driver_name() == DatabaseDriver::MYSQL) { $tables = $database->get_col("SHOW TABLES"); foreach ($tables as $table) { log_info("upgrade", "converting $table to innodb"); @@ -84,7 +84,7 @@ class Upgrade extends Extension $config->set_bool("in_upgrade", true); $config->set_int("db_version", 12); - if ($database->get_driver_name() == 'pgsql') { + if ($database->get_driver_name() == DatabaseDriver::PGSQL) { log_info("upgrade", "Changing ext column to VARCHAR"); $database->execute("ALTER TABLE images ALTER COLUMN ext SET DATA TYPE VARCHAR(4)"); } @@ -101,9 +101,9 @@ class Upgrade extends Extension $config->set_int("db_version", 13); log_info("upgrade", "Changing password column to VARCHAR(250)"); - if ($database->get_driver_name() == 'pgsql') { + if ($database->get_driver_name() == DatabaseDriver::PGSQL) { $database->execute("ALTER TABLE users ALTER COLUMN pass SET DATA TYPE VARCHAR(250)"); - } elseif ($database->get_driver_name() == 'mysql') { + } elseif ($database->get_driver_name() == DatabaseDriver::MYSQL) { $database->execute("ALTER TABLE users CHANGE pass pass VARCHAR(250)"); } @@ -116,11 +116,11 @@ class Upgrade extends Extension $config->set_int("db_version", 14); log_info("upgrade", "Changing tag column to VARCHAR(255)"); - if ($database->get_driver_name() == 'pgsql') { + if ($database->get_driver_name() == DatabaseDriver::PGSQL) { $database->execute('ALTER TABLE tags ALTER COLUMN tag SET DATA TYPE VARCHAR(255)'); $database->execute('ALTER TABLE aliases ALTER COLUMN oldtag SET DATA TYPE VARCHAR(255)'); $database->execute('ALTER TABLE aliases ALTER COLUMN newtag SET DATA TYPE VARCHAR(255)'); - } elseif ($database->get_driver_name() == 'mysql') { + } elseif ($database->get_driver_name() == DatabaseDriver::MYSQL) { $database->execute('ALTER TABLE tags MODIFY COLUMN tag VARCHAR(255) NOT NULL'); $database->execute('ALTER TABLE aliases MODIFY COLUMN oldtag VARCHAR(255) NOT NULL'); $database->execute('ALTER TABLE aliases MODIFY COLUMN newtag VARCHAR(255) NOT NULL'); @@ -129,6 +129,20 @@ class Upgrade extends Extension log_info("upgrade", "Database at version 14"); $config->set_bool("in_upgrade", false); } + + if ($config->get_int("db_version") < 15) { + $config->set_bool("in_upgrade", true); + $config->set_int("db_version", 15); + + log_info("upgrade", "Adding lower indexes for postgresql use"); + if ($database->get_driver_name() == DatabaseDriver::PGSQL) { + $database->execute('CREATE INDEX tags_lower_tag_idx ON tags ((lower(tag)))'); + $database->execute('CREATE INDEX users_lower_name_idx ON users ((lower(name)))'); + } + + log_info("upgrade", "Database at version 15"); + $config->set_bool("in_upgrade", false); + } } public function get_priority(): int diff --git a/ext/upload/main.php b/ext/upload/main.php index f42f1360..e0274346 100644 --- a/ext/upload/main.php +++ b/ext/upload/main.php @@ -27,7 +27,6 @@ class DataUploadEvent extends Event public $merged = false; - /** * Some data is being uploaded. * This should be caught by a file handler. @@ -49,10 +48,10 @@ class DataUploadEvent extends Event if ($config->get_bool("upload_use_mime")) { $this->set_type(get_extension_from_mime($tmpname)); } else { - if (array_key_exists('extension', $metadata)&&!empty($metadata['extension'])) { + if (array_key_exists('extension', $metadata) && !empty($metadata['extension'])) { $this->type = strtolower($metadata['extension']); } else { - throw new UploadException("Could not determine extension for file ".$metadata["filename"]); + throw new UploadException("Could not determine extension for file " . $metadata["filename"]); } } } @@ -130,9 +129,9 @@ class Upload extends Extension $sb->position = 10; // Output the limits from PHP so the user has an idea of what they can set. $sb->add_int_option("upload_count", "Max uploads: "); - $sb->add_label("PHP Limit = ".ini_get('max_file_uploads').""); + $sb->add_label("PHP Limit = " . ini_get('max_file_uploads') . ""); $sb->add_shorthand_int_option("upload_size", "
Max size per file: "); - $sb->add_label("PHP Limit = ".ini_get('upload_max_filesize').""); + $sb->add_label("PHP Limit = " . ini_get('upload_max_filesize') . ""); $sb->add_choice_option("transload_engine", $tes, "
Transload: "); $sb->add_bool_option("upload_tlsource", "
Use transloaded URL as source if none is provided: "); $sb->add_bool_option("upload_use_mime", "
Use mime type to determine file types: "); @@ -190,10 +189,10 @@ class Upload extends Extension if (count($_FILES) > 1) { throw new UploadException("Can not upload more than one image for replacing."); } - + $source = isset($_POST['source']) ? $_POST['source'] : null; $tags = []; // Tags aren't changed when replacing. Set to empty to stop PHP warnings. - + $ok = false; if (count($_FILES)) { foreach ($_FILES as $file) { @@ -249,7 +248,7 @@ class Upload extends Extension if (!empty($_GET['tags']) && $_GET['tags'] != "null") { $tags = Tag::explode($_GET['tags']); } - + $ok = $this->try_transload($url, $tags, $source); $this->theme->display_upload_status($page, $ok); } else { @@ -314,7 +313,7 @@ class Upload extends Extension * #param string[] $file * #param string[] $tags */ - private function try_upload(array $file, array $tags, ?string $source=null, int $replace=-1): bool + private function try_upload(array $file, array $tags, ?string $source = null, int $replace = -1): bool { global $page; @@ -331,7 +330,7 @@ class Upload extends Extension if ($file['error'] !== UPLOAD_ERR_OK) { throw new UploadException($this->upload_error_message($file['error'])); } - + $pathinfo = pathinfo($file['name']); $metadata = []; $metadata['filename'] = $pathinfo['basename']; @@ -340,19 +339,22 @@ class Upload extends Extension } $metadata['tags'] = $tags; $metadata['source'] = $source; - + /* check if we have been given an image ID to replace */ if ($replace >= 0) { $metadata['replace'] = $replace; } - + $event = new DataUploadEvent($file['tmp_name'], $metadata); send_event($event); - $page->add_http_header("X-Shimmie-Image-ID: ".int_escape($event->image_id)); + if ($event->image_id == -1) { + throw new UploadException("File type not supported: " . $metadata['extension']); + } + $page->add_http_header("X-Shimmie-Image-ID: " . int_escape($event->image_id)); } catch (UploadException $ex) { $this->theme->display_upload_error( $page, - "Error with ".html_escape($file['name']), + "Error with " . html_escape($file['name']), $ex->getMessage() ); $ok = false; @@ -362,7 +364,7 @@ class Upload extends Extension return $ok; } - private function try_transload(string $url, array $tags, string $source=null, int $replace=-1): bool + private function try_transload(string $url, array $tags, string $source = null, int $replace = -1): bool { global $page, $config, $user; @@ -372,7 +374,7 @@ class Upload extends Extension if ($user->can("edit_image_lock") && !empty($_GET['locked'])) { $locked = bool_escape($_GET['locked']); } - + // Checks if url contains rating, also checks if the rating extension is enabled. if ($config->get_string("transload_engine", "none") != "none" && ext_is_live("Ratings") && !empty($_GET['rating'])) { // Rating event will validate that this is s/q/e/u @@ -386,7 +388,7 @@ class Upload extends Extension // transload() returns Array or Bool, depending on the transload_engine. $headers = transload($url, $tmp_filename); - + $s_filename = is_array($headers) ? findHeader($headers, 'Content-Disposition') : null; $h_filename = ($s_filename ? preg_replace('/^.*filename="([^ ]+)"/i', '$1', $s_filename) : null); $filename = $h_filename ?: basename($url); @@ -394,8 +396,8 @@ class Upload extends Extension if (!$headers) { $this->theme->display_upload_error( $page, - "Error with ".html_escape($filename), - "Error reading from ".html_escape($url) + "Error with " . html_escape($filename), + "Error reading from " . html_escape($url) ); return false; } @@ -403,7 +405,7 @@ class Upload extends Extension if (filesize($tmp_filename) == 0) { $this->theme->display_upload_error( $page, - "Error with ".html_escape($filename), + "Error with " . html_escape($filename), "No data found -- perhaps the site has hotlink protection?" ); $ok = false; @@ -413,7 +415,7 @@ class Upload extends Extension $metadata['filename'] = $filename; $metadata['tags'] = $tags; $metadata['source'] = (($url == $source) && !$config->get_bool('upload_tlsource') ? "" : $source); - + $ext = false; if (is_array($headers)) { $ext = get_extension(findHeader($headers, 'Content-Type')); @@ -422,7 +424,7 @@ class Upload extends Extension $ext = $pathinfo['extension']; } $metadata['extension'] = $ext; - + /* check for locked > adds to metadata if it has */ if (!empty($locked)) { $metadata['locked'] = $locked ? "on" : ""; @@ -432,19 +434,22 @@ class Upload extends Extension if (!empty($rating)) { $metadata['rating'] = $rating; } - + /* check if we have been given an image ID to replace */ if ($replace >= 0) { $metadata['replace'] = $replace; } - + try { $event = new DataUploadEvent($tmp_filename, $metadata); send_event($event); + if ($event->image_id == -1) { + throw new UploadException("File type not supported: " . $metadata['extension']); + } } catch (UploadException $ex) { $this->theme->display_upload_error( $page, - "Error with ".html_escape($url), + "Error with " . html_escape($url), $ex->getMessage() ); $ok = false; diff --git a/ext/upload/theme.php b/ext/upload/theme.php index 71041030..6b3b503a 100644 --- a/ext/upload/theme.php +++ b/ext/upload/theme.php @@ -300,7 +300,7 @@ class UploadTheme extends Themelet public function display_upload_status(Page $page, bool $ok) { if ($ok) { - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link()); } else { $page->set_title("Upload Status"); diff --git a/ext/user/main.php b/ext/user/main.php index f9ecc54c..58c6ce38 100644 --- a/ext/user/main.php +++ b/ext/user/main.php @@ -372,7 +372,7 @@ class UserPage extends Extension if (!is_null($duser)) { $user = $duser; $this->set_login_cookie($duser->name, $pass); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); // Try returning to previous page if ($config->get_int("user_loginshowprofile", 0) == 0 && @@ -397,7 +397,7 @@ class UserPage extends Extension $page->add_cookie("user", "", time() + 60 * 60 * 24 * $config->get_int('login_memory'), "/"); } log_info("user", "Logged out"); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); // Try forwarding to same page on logout unless user comes from registration page if ($config->get_int("user_loginshowprofile", 0) == 0 && @@ -440,7 +440,7 @@ class UserPage extends Extension $uce = new UserCreationEvent($_POST['name'], $_POST['pass1'], $_POST['email']); send_event($uce); $this->set_login_cookie($uce->username, $uce->password); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("user")); } catch (UserCreationException $ex) { $this->theme->display_error(400, "User Creation Error", $ex->getMessage()); @@ -532,10 +532,10 @@ class UserPage extends Extension global $page, $user; if ($user->id == $duser->id) { - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("user")); } else { - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("user/{$duser->name}")); } } @@ -698,7 +698,7 @@ class UserPage extends Extension ["id" => $_POST['id']] ); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/list")); } } diff --git a/ext/view/main.php b/ext/view/main.php index bfbe2fba..bb2ee8c6 100644 --- a/ext/view/main.php +++ b/ext/view/main.php @@ -123,7 +123,7 @@ class ViewImage extends Extension return; } - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/{$image->id}", $query)); } elseif ($event->page_matches("post/view")) { if (!is_numeric($event->get_arg(0))) { @@ -157,7 +157,7 @@ class ViewImage extends Extension send_event(new ImageInfoSetEvent(Image::by_id($image_id))); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("post/view/$image_id", url_escape(@$_POST['query']))); } } diff --git a/ext/wiki/main.php b/ext/wiki/main.php index 360c686a..7279b630 100644 --- a/ext/wiki/main.php +++ b/ext/wiki/main.php @@ -137,7 +137,7 @@ class Wiki extends Extension send_event(new WikiUpdateEvent($user, $wikipage)); $u_title = url_escape($title); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("wiki/$u_title")); } catch (WikiUpdateException $e) { $original = $this->get_page($title); @@ -159,7 +159,7 @@ class Wiki extends Extension ["title"=>$_POST["title"], "rev"=>$_POST["revision"]] ); $u_title = url_escape($_POST["title"]); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("wiki/$u_title")); } } elseif ($event->page_matches("wiki_admin/delete_all")) { @@ -170,7 +170,7 @@ class Wiki extends Extension ["title"=>$_POST["title"]] ); $u_title = url_escape($_POST["title"]); - $page->set_mode("redirect"); + $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("wiki/$u_title")); } } @@ -213,7 +213,7 @@ class Wiki extends Extension return false; } - private function get_page(string $title): WikiPage + private function get_page(string $title, int $revision=-1): WikiPage { global $database; // first try and get the actual page @@ -222,21 +222,17 @@ class Wiki extends Extension SELECT * FROM wiki_pages WHERE SCORE_STRNORM(title) LIKE SCORE_STRNORM(:title) - ORDER BY revision DESC - LIMIT 1 - "), + ORDER BY revision DESC"), ["title"=>$title] ); // fall back to wiki:default if (empty($row)) { $row = $database->get_row(" - SELECT * - FROM wiki_pages - WHERE title LIKE :title - ORDER BY revision DESC - LIMIT 1 - ", ["title"=>"wiki:default"]); + SELECT * + FROM wiki_pages + WHERE title LIKE :title + ORDER BY revision DESC", ["title"=>"wiki:default"]); // fall further back to manual if (empty($row)) { diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 28539364..e2bcb800 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -52,7 +52,7 @@ abstract class ShimmiePHPUnitTestCase extends \PHPUnit\Framework\TestCase $_POST = []; $page = class_exists("CustomPage") ? new CustomPage() : new Page(); send_event(new PageRequestEvent($page_name)); - if ($page->mode == "redirect") { + if ($page->mode == PageMode::REDIRECT) { $page->code = 302; } } @@ -68,7 +68,7 @@ abstract class ShimmiePHPUnitTestCase extends \PHPUnit\Framework\TestCase $_POST = $args; $page = class_exists("CustomPage") ? new CustomPage() : new Page(); send_event(new PageRequestEvent($page_name)); - if ($page->mode == "redirect") { + if ($page->mode == PageMode::REDIRECT) { $page->code = 302; } } diff --git a/themes/material/home.theme.php b/themes/material/home.theme.php index 68b700e1..ada70b17 100644 --- a/themes/material/home.theme.php +++ b/themes/material/home.theme.php @@ -4,7 +4,7 @@ class CustomHomeTheme extends HomeTheme { public function display_page(Page $page, $sitename, $base_href, $theme_name, $body) { - $page->set_mode("data"); + $page->set_mode(PageMode::DATA); $page->add_auto_html_headers(); $hh = $page->get_all_html_headers(); $page->set_data(
{$h_docs} {$h_description}