Merge pull request #663 from sanmadjack/bugfixes
Bugfixes and small changes
This commit is contained in:
commit
42a502953b
88 changed files with 693 additions and 570 deletions
|
@ -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`
|
||||
|
|
|
@ -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) ? '<option value="mysql">MySQL</option>' : "";
|
||||
$db_p = in_array("pgsql", $drivers) ? '<option value="pgsql">PostgreSQL</option>' : "";
|
||||
$db_s = in_array("sqlite", $drivers) ? '<option value="sqlite">SQLite</option>' : "";
|
||||
$db_m = in_array(DatabaseDriver::MYSQL, $drivers) ? '<option value="'. DatabaseDriver::MYSQL .'">MySQL</option>' : "";
|
||||
$db_p = in_array(DatabaseDriver::PGSQL, $drivers) ? '<option value="'. DatabaseDriver::PGSQL .'">PostgreSQL</option>' : "";
|
||||
$db_s = in_array(DatabaseDriver::SQLITE, $drivers) ? '<option value="'. DatabaseDriver::SQLITE .'">SQLite</option>' : "";
|
||||
|
||||
$warn_msg = $warnings ? "<h3>Warnings</h3>".implode("\n<p>", $warnings) : "";
|
||||
$err_msg = $errors ? "<h3>Errors</h3>".implode("\n<p>", $errors) : "";
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,9 +1,17 @@
|
|||
<?php
|
||||
abstract class DatabaseDriver
|
||||
{
|
||||
public const MYSQL = "mysql";
|
||||
public const PGSQL = "pgsql";
|
||||
public const SQLITE = "sqlite";
|
||||
}
|
||||
|
||||
/**
|
||||
* A class for controlled database access
|
||||
*/
|
||||
class Database
|
||||
{
|
||||
|
||||
/**
|
||||
* The PDO database connection object, for anyone who wants direct access.
|
||||
* @var null|PDO
|
||||
|
@ -72,7 +80,7 @@ class Database
|
|||
|
||||
// https://bugs.php.net/bug.php?id=70221
|
||||
$ka = DATABASE_KA;
|
||||
if (version_compare(PHP_VERSION, "6.9.9") == 1 && $this->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'")
|
||||
);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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 <a href="'.$this->redirect.'">'.$this->redirect.'</a>';
|
||||
break;
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<proto>\w+)\:(?:user=(?P<user>\w+)(?:;|$)|password=(?P<password>\w*)(?:;|$)|host=(?P<host>[\w\.\-]+)(?:;|$)|dbname=(?P<dbname>[\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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"]);
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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'";
|
||||
|
|
|
@ -1,42 +1,52 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* Name: Cron Uploader
|
||||
* Author: YaoiFox <admin@yaoifox.com>
|
||||
* Authors: YaoiFox <admin@yaoifox.com>, Matthew Barbour <matthew@darkholme.net>
|
||||
* 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 = "<b>Information</b>
|
||||
<br>
|
||||
<table style='width:470px;'>
|
||||
|
@ -105,7 +126,7 @@ class CronUploader extends Extension
|
|||
<br>Cron Command: <input type='text' size='60' value='$cron_cmd'><br>
|
||||
Create a cron job with the command above.<br/>
|
||||
Read the documentation if you're not sure what to do.<br>";
|
||||
|
||||
|
||||
$install_html = "
|
||||
This cron uploader is fairly easy to use but has to be configured first.
|
||||
<br />1. Install & activate this plugin.
|
||||
|
@ -130,8 +151,10 @@ class CronUploader extends Extension
|
|||
<br />So when you want to manually upload an image, all you have to do is open the link once.
|
||||
<br />This link can be found under 'Cron Command' in the board config, just remove the 'wget ' part and only the url remains.
|
||||
<br />(<b>$cron_url</b>)";
|
||||
|
||||
|
||||
|
||||
$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("<b>Settings</b><br>");
|
||||
$sb->add_int_option("cron_uploader_count", "How many to upload each time");
|
||||
$sb->add_text_option("cron_uploader_dir", "<br>Set Cron Uploader root directory<br>");
|
||||
|
||||
$sb->add_label("<br>Cron Command: <input type='text' size='60' value='$cron_cmd'><br>
|
||||
$sb->add_int_option(self::CONFIG_COUNT, "How many to upload each time");
|
||||
$sb->add_text_option(self::CONFIG_DIR, "<br>Set Cron Uploader root directory<br>");
|
||||
|
||||
$sb->add_label("<br>Cron Command: <input type='text' size='60' readonly='readonly' value='" . html_escape($cron_cmd) . "'><br>
|
||||
Create a cron job with the command above.<br/>
|
||||
<a href='$documentation_link'>Read the documentation</a> 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
<<<EOD
|
||||
|
|
|
@ -18,7 +18,7 @@ class EmoticonListTheme extends Themelet
|
|||
}
|
||||
$html .= "</tr></table>";
|
||||
$html .= "</body></html>";
|
||||
$page->set_mode("data");
|
||||
$page->set_mode(PageMode::DATA);
|
||||
$page->set_data($html);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -9,7 +9,7 @@ class ExtManagerTheme extends Themelet
|
|||
{
|
||||
$h_en = $editable ? "<th>Enabled</th>" : "";
|
||||
$html = "
|
||||
".make_form(make_link("ext_manager/set"))."
|
||||
" . make_form(make_link("ext_manager/set")) . "
|
||||
<table id='extensions' class='zebra sortable'>
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -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 ? "<td><input type='checkbox' name='ext_".html_escape($extension->ext_name)."' id='ext_".html_escape($extension->ext_name)."'$h_enabled></td>" : "";
|
||||
$h_docs = ($extension->documentation ? "<a href='$h_link'>■</a>" : ""); //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 ? "<td><input type='checkbox' name='ext_" . html_escape($extension->ext_name) . "' id='ext_" . html_escape($extension->ext_name) . "'$h_enabled></td>" : "";
|
||||
$h_docs = ($extension->documentation ? "<a href='$h_link'>■</a>" : ""); //TODO: A proper "docs" symbol would be preferred here.
|
||||
|
||||
$html .= "
|
||||
<tr data-ext='{$extension->ext_name}'>
|
||||
{$h_enabled_box}
|
||||
<td><label for='ext_".html_escape($extension->ext_name)."'>{$h_name}</label></td>
|
||||
<td><label for='ext_" . html_escape($extension->ext_name) . "'>{$h_name}</label></td>
|
||||
<td>{$h_docs}</td>
|
||||
<td style='text-align: left;'>{$h_description}</td>
|
||||
</tr>";
|
||||
|
@ -116,15 +116,24 @@ class ExtManagerTheme extends Themelet
|
|||
public function display_doc(Page $page, ExtensionInfo $info)
|
||||
{
|
||||
$author = "";
|
||||
if ($info->author) {
|
||||
if ($info->email) {
|
||||
$author = "<br><b>Author:</b> <a href=\"mailto:".html_escape($info->email)."\">".html_escape($info->author)."</a>";
|
||||
} else {
|
||||
$author = "<br><b>Author:</b> ".html_escape($info->author);
|
||||
if (count($info->authors) > 0) {
|
||||
$author = "<br /><b>Author";
|
||||
if (count($info->authors) > 1) {
|
||||
$author .= "s";
|
||||
}
|
||||
$author .= ":</b>";
|
||||
foreach ($info->authors as $auth) {
|
||||
if (!empty($auth->email)) {
|
||||
$author .= "<a href=\"mailto:" . html_escape($auth->email) . "\">" . html_escape($auth->name) . "</a>";
|
||||
} else {
|
||||
$author .= html_escape($auth->name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
$version = ($info->version) ? "<br><b>Version:</b> ".html_escape($info->version) : "";
|
||||
$link = ($info->link) ? "<br><b>Home Page:</b> <a href=\"".html_escape($info->link)."\">Link</a>" : "";
|
||||
|
||||
$version = ($info->version) ? "<br><b>Version:</b> " . html_escape($info->version) : "";
|
||||
$link = ($info->link) ? "<br><b>Home Page:</b> <a href=\"" . html_escape($info->link) . "\">Link</a>" : "";
|
||||
$doc = $info->documentation;
|
||||
$html = "
|
||||
<div style='margin: auto; text-align: left; width: 512px;'>
|
||||
|
@ -133,10 +142,10 @@ class ExtManagerTheme extends Themelet
|
|||
$link
|
||||
<p>$doc
|
||||
<hr>
|
||||
<p><a href='".make_link("ext_manager")."'>Back to the list</a>
|
||||
<p><a href='" . make_link("ext_manager") . "'>Back to the list</a>
|
||||
</div>";
|
||||
|
||||
$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));
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 <a href='".make_link("post/view/{$existing->id}")."'>{$existing->id}</a> ".
|
||||
"already has hash {$image->hash}:<p>".$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)) {
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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 .= "
|
||||
|
|
|
@ -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"];
|
||||
|
|
|
@ -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:<br>";
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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")) {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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)");
|
||||
}
|
||||
|
|
|
@ -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)");
|
||||
}
|
||||
|
|
|
@ -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("
|
||||
|
|
|
@ -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 = "";
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 .= "
|
||||
<tr>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ class TaggerXML extends Extension
|
|||
$tags.
|
||||
"</tags>";
|
||||
|
||||
$page->set_mode("data");
|
||||
$page->set_mode(PageMode::DATA);
|
||||
$page->set_type("text/xml");
|
||||
$page->set_data($xml);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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("<i>PHP Limit = ".ini_get('max_file_uploads')."</i>");
|
||||
$sb->add_label("<i>PHP Limit = " . ini_get('max_file_uploads') . "</i>");
|
||||
$sb->add_shorthand_int_option("upload_size", "<br/>Max size per file: ");
|
||||
$sb->add_label("<i>PHP Limit = ".ini_get('upload_max_filesize')."</i>");
|
||||
$sb->add_label("<i>PHP Limit = " . ini_get('upload_max_filesize') . "</i>");
|
||||
$sb->add_choice_option("transload_engine", $tes, "<br/>Transload: ");
|
||||
$sb->add_bool_option("upload_tlsource", "<br/>Use transloaded URL as source if none is provided: ");
|
||||
$sb->add_bool_option("upload_use_mime", "<br/>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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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'])));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
Reference in a new issue