[core] Deduplicate ImageAdditionEvent & ImageInfoSetEvent
Rather than ImageAddition triggering TagsSet/SourceSet/LockSet etc in one way, and ImageInfoSet triggering TagsSet/SourceSet/LockSet in a different way, why not have ImageAddition *just* deal with image addition, and then send a separate ImageInfoSet to deal with all of the metadata setting?
This commit is contained in:
parent
50fe355046
commit
db0e788a67
26 changed files with 136 additions and 178 deletions
|
@ -341,7 +341,8 @@ abstract class DataHandlerExtension extends Extension
|
|||
// we can just send a TagSetEvent - in the future we might
|
||||
// want a dedicated MergeEvent?
|
||||
if(!empty($event->metadata['tags'])) {
|
||||
send_event(new TagSetEvent($existing, array_merge($existing->get_tag_array(), $event->metadata['tags'])));
|
||||
$tags = Tag::explode($existing->get_tag_list() . " " . $event->metadata['tags']);
|
||||
send_event(new TagSetEvent($existing, $tags));
|
||||
}
|
||||
$event->images[] = $existing;
|
||||
return;
|
||||
|
@ -357,11 +358,9 @@ abstract class DataHandlerExtension extends Extension
|
|||
$image->tmp_file = $filename;
|
||||
$image->filesize = \Safe\filesize($filename);
|
||||
$image->hash = \Safe\md5_file($filename);
|
||||
$image->filename = (($pos = strpos($event->metadata['filename'], '?')) !== false) ? substr($event->metadata['filename'], 0, $pos) : $event->metadata['filename'];
|
||||
$image->set_mime(MimeType::get_for_file($filename, get_file_ext($event->metadata["filename"]) ?? null));
|
||||
if (empty($image->get_mime())) {
|
||||
throw new UploadException("Unable to determine MIME for $filename");
|
||||
}
|
||||
// DB limits to 255 char filenames
|
||||
$image->filename = substr($event->filename, -250);
|
||||
$image->set_mime($event->mime);
|
||||
try {
|
||||
send_event(new MediaCheckPropertiesEvent($image));
|
||||
} catch (MediaException $e) {
|
||||
|
@ -369,8 +368,8 @@ abstract class DataHandlerExtension extends Extension
|
|||
}
|
||||
$image->save_to_db(); // Ensure the image has a DB-assigned ID
|
||||
|
||||
// Let everybody else know, so that TagEdit can set tags, Ratings can set ratings, etc
|
||||
$iae = send_event(new ImageAdditionEvent($image, $event->metadata));
|
||||
$iae = send_event(new ImageAdditionEvent($image));
|
||||
send_event(new ImageInfoSetEvent($image, $event->slot, $event->metadata));
|
||||
|
||||
// If everything is OK, then move the file to the archive
|
||||
$filename = warehouse_path(Image::IMAGE_DIR, $event->hash);
|
||||
|
|
|
@ -10,14 +10,12 @@ namespace Shimmie2;
|
|||
class ImageAdditionEvent extends Event
|
||||
{
|
||||
/**
|
||||
* Inserts a new image into the database with its associated
|
||||
* information.
|
||||
*
|
||||
* @param mixed[] $metadata
|
||||
* A new image is being added to the database - just the image,
|
||||
* metadata will come later with ImageInfoSetEvent (and if that
|
||||
* fails, then the image addition transaction will be rolled back)
|
||||
*/
|
||||
public function __construct(
|
||||
public Image $image,
|
||||
public array $metadata,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
|
|
@ -27,10 +27,9 @@ function add_dir(string $base, array $extra_tags = []): array
|
|||
$tags = array_merge(path_to_tags($short_path), $extra_tags);
|
||||
try {
|
||||
$more_results = $database->with_savepoint(function () use ($full_path, $filename, $tags) {
|
||||
$dae = send_event(new DataUploadEvent($full_path, [
|
||||
$dae = send_event(new DataUploadEvent($full_path, basename($full_path), 0, [
|
||||
'filename' => pathinfo($filename, PATHINFO_BASENAME),
|
||||
'tags' => $tags,
|
||||
'source' => null,
|
||||
'tags' => Tag::implode($tags),
|
||||
]));
|
||||
$results = [];
|
||||
foreach($dae->images as $image) {
|
||||
|
|
|
@ -257,10 +257,9 @@ if(class_exists("\\PHPUnit\\Framework\\TestCase")) {
|
|||
// post things
|
||||
protected function post_image(string $filename, string $tags): int
|
||||
{
|
||||
$dae = send_event(new DataUploadEvent($filename, [
|
||||
$dae = send_event(new DataUploadEvent($filename, basename($filename), 0, [
|
||||
"filename" => $filename,
|
||||
"tags" => Tag::explode($tags),
|
||||
"source" => null,
|
||||
"tags" => $tags,
|
||||
]));
|
||||
if(count($dae->images) == 0) {
|
||||
throw new \Exception("Upload failed :(");
|
||||
|
|
|
@ -208,6 +208,22 @@ function format_text(string $string): string
|
|||
return $event->formatted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a map of string to string-or-array, return only the string-to-string subset
|
||||
*
|
||||
* @param array<string, string|string[]> $map
|
||||
* @return array<string, string>
|
||||
*/
|
||||
function only_strings(array $map): array
|
||||
{
|
||||
$out = [];
|
||||
foreach ($map as $k => $v) {
|
||||
if (is_string($v)) {
|
||||
$out[$k] = $v;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
/**
|
||||
* Generates the path to a file under the data folder based on the file's hash.
|
||||
* This process creates subfolders based on octet pairs from the file's hash.
|
||||
|
|
|
@ -38,8 +38,9 @@ class Artists extends Extension
|
|||
public function onImageInfoSet(ImageInfoSetEvent $event): void
|
||||
{
|
||||
global $user;
|
||||
if ($user->can(Permissions::EDIT_IMAGE_ARTIST) && isset($event->params["author"])) {
|
||||
send_event(new AuthorSetEvent($event->image, $user, $event->params["author"]));
|
||||
$author = $event->get_param("author");
|
||||
if ($user->can(Permissions::EDIT_IMAGE_ARTIST) && $author) {
|
||||
send_event(new AuthorSetEvent($event->image, $user, $author));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,9 +56,8 @@ class BulkAddCSV extends Extension
|
|||
{
|
||||
global $database;
|
||||
$database->with_savepoint(function () use ($tmpname, $filename, $tags, $source, $rating, $thumbfile) {
|
||||
$event = send_event(new DataUploadEvent($tmpname, [
|
||||
'filename' => pathinfo($filename, PATHINFO_BASENAME),
|
||||
'tags' => $tags,
|
||||
$event = send_event(new DataUploadEvent($tmpname, basename($filename), 0, [
|
||||
'tags' => Tag::implode($tags),
|
||||
'source' => $source,
|
||||
'rating' => $rating,
|
||||
]));
|
||||
|
|
|
@ -49,10 +49,8 @@ class BulkImportExport extends DataHandlerExtension
|
|||
file_put_contents($tmpfile, $stream);
|
||||
|
||||
$database->with_savepoint(function () use ($item, $tmpfile, $event) {
|
||||
$images = send_event(new DataUploadEvent($tmpfile, [
|
||||
'filename' => pathinfo($item->filename, PATHINFO_BASENAME),
|
||||
$images = send_event(new DataUploadEvent($tmpfile, basename($item->filename), 0, [
|
||||
'tags' => $item->new_tags,
|
||||
'source' => null,
|
||||
]))->images;
|
||||
|
||||
if (count($images) == 0) {
|
||||
|
|
|
@ -455,10 +455,8 @@ class CronUploader extends Extension
|
|||
*/
|
||||
private function add_image(string $tmpname, string $filename, array $tags): DataUploadEvent
|
||||
{
|
||||
$event = send_event(new DataUploadEvent($tmpname, [
|
||||
'filename' => pathinfo($filename, PATHINFO_BASENAME),
|
||||
'tags' => $tags,
|
||||
'source' => null,
|
||||
$event = send_event(new DataUploadEvent($tmpname, basename($filename), 0, [
|
||||
'tags' => Tag::implode($tags),
|
||||
]));
|
||||
|
||||
// Generate info message
|
||||
|
|
|
@ -362,8 +362,7 @@ class DanbooruApi extends Extension
|
|||
try {
|
||||
$newimg = $database->with_savepoint(function () use ($file, $filename, $posttags, $source) {
|
||||
// Fire off an event which should process the new file and add it to the db
|
||||
$dae = send_event(new DataUploadEvent($file, [
|
||||
'filename' => pathinfo($filename, PATHINFO_BASENAME),
|
||||
$dae = send_event(new DataUploadEvent($file, basename($filename), 0, [
|
||||
'tags' => $posttags,
|
||||
'source' => $source,
|
||||
]));
|
||||
|
|
|
@ -93,12 +93,13 @@ class Favorites extends Extension
|
|||
public function onImageInfoSet(ImageInfoSetEvent $event): void
|
||||
{
|
||||
global $user;
|
||||
$action = $event->get_param("favorite_action");
|
||||
if (
|
||||
$user->can(Permissions::EDIT_FAVOURITES) &&
|
||||
in_array('favorite_action', $event->params) &&
|
||||
(($event->params['favorite_action'] == "set") || ($event->params['favorite_action'] == "unset"))
|
||||
!is_null($action) &&
|
||||
($action == "set" || $action == "unset")
|
||||
) {
|
||||
send_event(new FavoriteSetEvent($event->image->id, $user, ($event->params['favorite_action'] == "set")));
|
||||
send_event(new FavoriteSetEvent($event->image->id, $user, $action == "set"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ class MetadataInput
|
|||
global $user;
|
||||
$image = Image::by_id_ex($post_id);
|
||||
if (!$image->is_locked() || $user->can(Permissions::EDIT_IMAGE_LOCK)) {
|
||||
send_event(new ImageInfoSetEvent($image, [
|
||||
send_event(new ImageInfoSetEvent($image, 0, [
|
||||
'tags' => $metadata->tags,
|
||||
'source' => $metadata->source,
|
||||
]));
|
||||
|
@ -176,9 +176,8 @@ class GraphQL extends Extension
|
|||
if (!empty($_POST["source$n"])) {
|
||||
$source = $_POST["source$n"];
|
||||
}
|
||||
$event = $database->with_savepoint(function () use ($tmpname, $filename, $tags, $source) {
|
||||
return send_event(new DataUploadEvent($tmpname, [
|
||||
'filename' => $filename,
|
||||
$event = $database->with_savepoint(function () use ($tmpname, $filename, $n, $tags, $source) {
|
||||
return send_event(new DataUploadEvent($tmpname, $filename, $n, [
|
||||
'tags' => Tag::explode($tags),
|
||||
'source' => $source,
|
||||
]));
|
||||
|
|
|
@ -35,7 +35,7 @@ class ArchiveFileHandler extends DataHandlerExtension
|
|||
exec($cmd);
|
||||
if (file_exists($tmpdir)) {
|
||||
try {
|
||||
$results = add_dir($tmpdir, $event->metadata['tags']);
|
||||
$results = add_dir($tmpdir, Tag::explode($event->metadata['tags']));
|
||||
foreach ($results as $r) {
|
||||
if(is_a($r, UploadError::class)) {
|
||||
$page->flash($r->name." failed: ".$r->error);
|
||||
|
|
|
@ -338,7 +338,7 @@ class OuroborosAPI extends Extension
|
|||
}
|
||||
}
|
||||
$meta = [];
|
||||
$meta['tags'] = Tag::explode($post->tags);
|
||||
$meta['tags'] = $post->tags;
|
||||
$meta['source'] = $post->source;
|
||||
if (Extension::is_enabled(RatingsInfo::KEY) !== false) {
|
||||
$meta['rating'] = $post->rating;
|
||||
|
@ -358,12 +358,12 @@ class OuroborosAPI extends Extension
|
|||
$this->sendResponse(500, "Transloading failed: $e");
|
||||
return;
|
||||
}
|
||||
$meta['hash'] = md5_file($meta['file']);
|
||||
$meta['hash'] = \Safe\md5_file($meta['file']);
|
||||
} else {
|
||||
// Use file
|
||||
$meta['file'] = $post->file['tmp_name'];
|
||||
$meta['filename'] = $post->file['name'];
|
||||
$meta['hash'] = md5_file($meta['file']);
|
||||
$meta['hash'] = \Safe\md5_file($meta['file']);
|
||||
}
|
||||
if (!empty($md5) && $md5 !== $meta['hash']) {
|
||||
$this->sendResponse(420, self::ERROR_POST_CREATE_MD5);
|
||||
|
@ -390,10 +390,9 @@ class OuroborosAPI extends Extension
|
|||
}
|
||||
}
|
||||
}
|
||||
$meta['extension'] = pathinfo($meta['filename'], PATHINFO_EXTENSION);
|
||||
try {
|
||||
$image = $database->with_savepoint(function () use ($meta) {
|
||||
$dae = send_event(new DataUploadEvent($meta['file'], $meta));
|
||||
$dae = send_event(new DataUploadEvent($meta['file'], basename($meta['file']), 0, $meta));
|
||||
return $dae->images[0];
|
||||
});
|
||||
$this->sendResponse(200, make_link('post/view/' . $image->id), true);
|
||||
|
|
|
@ -22,13 +22,6 @@ class PostLock extends Extension
|
|||
/** @var PostLockTheme */
|
||||
protected Themelet $theme;
|
||||
|
||||
public function onImageAddition(ImageAdditionEvent $event): void
|
||||
{
|
||||
if (!empty($event->metadata['locked'])) {
|
||||
send_event(new LockSetEvent($event->image, $event->metadata['locked']));
|
||||
}
|
||||
}
|
||||
|
||||
public function onImageInfoSet(ImageInfoSetEvent $event): void
|
||||
{
|
||||
global $page, $user;
|
||||
|
@ -36,7 +29,7 @@ class PostLock extends Extension
|
|||
throw new PermissionDenied("Error: This image is locked and cannot be edited.");
|
||||
}
|
||||
if ($user->can(Permissions::EDIT_IMAGE_LOCK)) {
|
||||
$locked = isset($event->params['locked']) && $event->params['locked'] == "on";
|
||||
$locked = $event->get_param('locked') == "on";
|
||||
send_event(new LockSetEvent($event->image, $locked));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,24 +14,24 @@ class PostLockTest extends ShimmiePHPUnitTestCase
|
|||
|
||||
// admin can lock
|
||||
$this->log_in_as_admin();
|
||||
send_event(new ImageInfoSetEvent(Image::by_id_ex($image_id), ["locked" => "on"]));
|
||||
send_event(new ImageInfoSetEvent(Image::by_id_ex($image_id), 0, ["locked" => "on"]));
|
||||
|
||||
// user can't edit locked post
|
||||
$this->log_in_as_user();
|
||||
$this->assertException(PermissionDenied::class, function () use ($image_id) {
|
||||
send_event(new ImageInfoSetEvent(Image::by_id_ex($image_id), ["source" => "http://example.com"]));
|
||||
send_event(new ImageInfoSetEvent(Image::by_id_ex($image_id), 0, ["source" => "http://example.com"]));
|
||||
});
|
||||
|
||||
// admin can edit locked post
|
||||
$this->log_in_as_admin();
|
||||
send_event(new ImageInfoSetEvent(Image::by_id_ex($image_id), ["source" => "http://example.com"]));
|
||||
send_event(new ImageInfoSetEvent(Image::by_id_ex($image_id), 0, ["source" => "http://example.com"]));
|
||||
|
||||
// admin can unlock
|
||||
$this->log_in_as_admin();
|
||||
send_event(new ImageInfoSetEvent(Image::by_id_ex($image_id), [])); // "locked" is not set
|
||||
send_event(new ImageInfoSetEvent(Image::by_id_ex($image_id), 0, [])); // "locked" is not set
|
||||
|
||||
// user can edit un-locked post
|
||||
$this->log_in_as_user();
|
||||
send_event(new ImageInfoSetEvent(Image::by_id_ex($image_id), ["source" => "http://example.com"]));
|
||||
send_event(new ImageInfoSetEvent(Image::by_id_ex($image_id), 0, ["source" => "http://example.com"]));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,18 +22,14 @@ class PostOwner extends Extension
|
|||
/** @var PostOwnerTheme */
|
||||
protected Themelet $theme;
|
||||
|
||||
public function onImageAddition(ImageAdditionEvent $event): void
|
||||
{
|
||||
// FIXME: send an event instead of implicit default owner?
|
||||
}
|
||||
|
||||
public function onImageInfoSet(ImageInfoSetEvent $event): void
|
||||
{
|
||||
global $page, $user;
|
||||
if ($user->can(Permissions::EDIT_IMAGE_OWNER) && isset($event->params['owner'])) {
|
||||
$owner = User::by_name($event->params['owner']);
|
||||
if ($owner instanceof User) {
|
||||
send_event(new OwnerSetEvent($event->image, $owner));
|
||||
$owner = $event->get_param('owner');
|
||||
if ($user->can(Permissions::EDIT_IMAGE_OWNER) && !is_null($owner)) {
|
||||
$owner_ob = User::by_name($owner);
|
||||
if (!is_null($owner_ob)) {
|
||||
send_event(new OwnerSetEvent($event->image, $owner_ob));
|
||||
} else {
|
||||
throw new UserNotFound("Error: No user with that name was found.");
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ class PostOwnerTest extends ShimmiePHPUnitTestCase
|
|||
$image = Image::by_id_ex($image_id);
|
||||
|
||||
$this->log_in_as_admin();
|
||||
send_event(new ImageInfoSetEvent($image, ["owner" => self::$admin_name]));
|
||||
send_event(new ImageInfoSetEvent($image, 0, ["owner" => self::$admin_name]));
|
||||
|
||||
$this->log_in_as_user();
|
||||
$this->get_page("post/view/$image_id");
|
||||
|
|
|
@ -32,19 +32,16 @@ class PostSource extends Extension
|
|||
}
|
||||
}
|
||||
|
||||
public function onImageAddition(ImageAdditionEvent $event): void
|
||||
{
|
||||
if(!empty($event->metadata['source'])) {
|
||||
send_event(new SourceSetEvent($event->image, $event->metadata['source']));
|
||||
}
|
||||
}
|
||||
|
||||
public function onImageInfoSet(ImageInfoSetEvent $event): void
|
||||
{
|
||||
global $page, $user;
|
||||
if ($user->can(Permissions::EDIT_IMAGE_SOURCE) && isset($event->params['source'])) {
|
||||
global $config, $page, $user;
|
||||
$source = $event->get_param('source');
|
||||
if(is_null($source) && $config->get_bool(UploadConfig::TLSOURCE)) {
|
||||
$source = $event->get_param('url');
|
||||
}
|
||||
if ($user->can(Permissions::EDIT_IMAGE_SOURCE) && !is_null($source)) {
|
||||
if (isset($event->params['tags']) ? !preg_match('/source[=|:]/', $event->params["tags"]) : true) {
|
||||
send_event(new SourceSetEvent($event->image, $event->params['source']));
|
||||
send_event(new SourceSetEvent($event->image, $source));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,8 +12,8 @@ class PostSourceTest extends ShimmiePHPUnitTestCase
|
|||
$image_id = $this->post_image("tests/pbx_screenshot.jpg", "pbx");
|
||||
$image = Image::by_id_ex($image_id);
|
||||
|
||||
send_event(new ImageInfoSetEvent($image, ["source" => "example.com"]));
|
||||
send_event(new ImageInfoSetEvent($image, ["source" => "http://example.com"]));
|
||||
send_event(new ImageInfoSetEvent($image, 0, ["source" => "example.com"]));
|
||||
send_event(new ImageInfoSetEvent($image, 0, ["source" => "http://example.com"]));
|
||||
|
||||
$this->get_page("post/view/$image_id");
|
||||
$this->assert_text("example.com");
|
||||
|
|
|
@ -121,19 +121,20 @@ class PostTags extends Extension
|
|||
});
|
||||
}
|
||||
|
||||
public function onImageAddition(ImageAdditionEvent $event): void
|
||||
{
|
||||
if(!empty($event->metadata['tags'])) {
|
||||
send_event(new TagSetEvent($event->image, $event->metadata['tags']));
|
||||
}
|
||||
}
|
||||
|
||||
public function onImageInfoSet(ImageInfoSetEvent $event): void
|
||||
{
|
||||
global $page, $user;
|
||||
if ($user->can(Permissions::EDIT_IMAGE_TAG) && isset($event->params['tags'])) {
|
||||
if (
|
||||
$user->can(Permissions::EDIT_IMAGE_TAG) && (
|
||||
isset($event->params['tags'])
|
||||
|| isset($event->params["tags{$event->slot}"])
|
||||
)
|
||||
) {
|
||||
$common_tags = $event->params['tags'] ?? "";
|
||||
$my_tags = $event->params["tags{$event->slot}"] ?? "";
|
||||
$tags = Tag::explode("$common_tags $my_tags");
|
||||
try {
|
||||
send_event(new TagSetEvent($event->image, Tag::explode($event->params['tags'])));
|
||||
send_event(new TagSetEvent($event->image, $tags));
|
||||
} catch (TagSetException $e) {
|
||||
if ($e->redirect) {
|
||||
$page->flash("{$e->getMessage()}, please see {$e->redirect}");
|
||||
|
|
|
@ -55,9 +55,9 @@ class PostTitles extends Extension
|
|||
public function onImageInfoSet(ImageInfoSetEvent $event): void
|
||||
{
|
||||
global $user;
|
||||
|
||||
if ($user->can(Permissions::EDIT_IMAGE_TITLE) && isset($event->params["title"])) {
|
||||
send_event(new PostTitleSetEvent($event->image, $event->params["title"]));
|
||||
$title = $event->get_param('title');
|
||||
if ($user->can(Permissions::EDIT_IMAGE_TITLE) && !is_null($title)) {
|
||||
send_event(new PostTitleSetEvent($event->image, $title));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -158,13 +158,6 @@ class Ratings extends Extension
|
|||
$sb->end_table();
|
||||
}
|
||||
|
||||
public function onImageAddition(ImageAdditionEvent $event): void
|
||||
{
|
||||
if(!empty($event->metadata['rating'])) {
|
||||
send_event(new RatingSetEvent($event->image, $event->metadata['rating']));
|
||||
}
|
||||
}
|
||||
|
||||
public function onDisplayingImage(DisplayingImageEvent $event): void
|
||||
{
|
||||
global $page;
|
||||
|
@ -216,8 +209,8 @@ class Ratings extends Extension
|
|||
public function onImageInfoSet(ImageInfoSetEvent $event): void
|
||||
{
|
||||
global $user;
|
||||
if ($user->can(Permissions::EDIT_IMAGE_RATING) && isset($event->params["rating"])) {
|
||||
$rating = $event->params["rating"];
|
||||
$rating = $event->get_param('rating');
|
||||
if ($user->can(Permissions::EDIT_IMAGE_RATING) && !is_null($rating)) {
|
||||
if (Ratings::rating_is_valid($rating)) {
|
||||
send_event(new RatingSetEvent($event->image, $rating));
|
||||
}
|
||||
|
|
|
@ -24,21 +24,22 @@ class DataUploadEvent extends Event
|
|||
* Some data is being uploaded.
|
||||
* This should be caught by a file handler.
|
||||
*
|
||||
* @param array<string, mixed> $metadata
|
||||
* @param string $tmpname The name of a physical file on the local hard drive.
|
||||
* @param string $filename The name of the file as it was uploaded.
|
||||
* @param int $slot The slot number of the upload.
|
||||
* @param array<string, string> $metadata Key-value pairs of metadata, the
|
||||
* upload form can contain both common and slot-specific fields such as
|
||||
* "source" and "source12", in which case the slot-specific field will
|
||||
* override the common one.
|
||||
*/
|
||||
public function __construct(
|
||||
public string $tmpname,
|
||||
public string $filename,
|
||||
public int $slot,
|
||||
public array $metadata,
|
||||
) {
|
||||
parent::__construct();
|
||||
|
||||
$this->set_tmpname($tmpname);
|
||||
assert(is_string($metadata["filename"]));
|
||||
assert(is_array($metadata["tags"]));
|
||||
assert(is_string($metadata["source"]) || is_null($metadata["source"]));
|
||||
|
||||
// DB limits to 255 char filenames
|
||||
$metadata['filename'] = substr($metadata['filename'], 0, 255);
|
||||
}
|
||||
|
||||
public function set_tmpname(string $tmpname, ?string $mime = null): void
|
||||
|
@ -47,7 +48,7 @@ class DataUploadEvent extends Event
|
|||
$this->tmpname = $tmpname;
|
||||
$this->hash = \Safe\md5_file($tmpname);
|
||||
$this->size = \Safe\filesize($tmpname);
|
||||
$mime = $mime ?? MimeType::get_for_file($tmpname, get_file_ext($this->metadata["filename"]) ?? null);
|
||||
$mime = $mime ?? MimeType::get_for_file($tmpname, get_file_ext($this->filename));
|
||||
if (empty($mime)) {
|
||||
throw new UploadException("Could not determine mime type");
|
||||
}
|
||||
|
@ -235,9 +236,7 @@ class Upload extends Extension
|
|||
});
|
||||
foreach ($files as $name => $file) {
|
||||
$slot = int_escape(substr($name, 4));
|
||||
$tags = $this->tags_for_upload_slot($event->POST, $slot);
|
||||
$source = $this->source_for_upload_slot($event->POST, $slot);
|
||||
$results = array_merge($results, $this->try_upload($file, $tags, $source));
|
||||
$results = array_merge($results, $this->try_upload($file, $slot, only_strings($event->POST)));
|
||||
}
|
||||
|
||||
$urls = array_filter($event->POST, function ($value, $key) {
|
||||
|
@ -245,48 +244,13 @@ class Upload extends Extension
|
|||
}, ARRAY_FILTER_USE_BOTH);
|
||||
foreach ($urls as $name => $value) {
|
||||
$slot = int_escape(substr($name, 3));
|
||||
$tags = $this->tags_for_upload_slot($event->POST, $slot);
|
||||
$source = $this->source_for_upload_slot($event->POST, $slot);
|
||||
$results = array_merge($results, $this->try_transload($value, $tags, $source));
|
||||
$results = array_merge($results, $this->try_transload($value, $slot, only_strings($event->POST)));
|
||||
}
|
||||
|
||||
$this->theme->display_upload_status($page, $results);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $params
|
||||
* @return string[]
|
||||
*/
|
||||
private function tags_for_upload_slot(array $params, int $id): array
|
||||
{
|
||||
# merge then explode, not explode then merge - else
|
||||
# one of the merges may create a surplus "tagme"
|
||||
return Tag::explode(
|
||||
($params["tags"] ?? "") .
|
||||
" " .
|
||||
($params["tags$id"] ?? "")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $params
|
||||
*/
|
||||
private function source_for_upload_slot(array $params, int $id): ?string
|
||||
{
|
||||
global $config;
|
||||
if(!empty($params["source$id"])) {
|
||||
return $params["source$id"];
|
||||
}
|
||||
if(!empty($params['source'])) {
|
||||
return $params['source'];
|
||||
}
|
||||
if($config->get_bool(UploadConfig::TLSOURCE) && !empty($params["url$id"])) {
|
||||
return $params["url$id"];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a descriptive error message for the specified PHP error code.
|
||||
*
|
||||
|
@ -320,10 +284,10 @@ class Upload extends Extension
|
|||
/**
|
||||
* Handle an upload.
|
||||
* @param mixed[] $file
|
||||
* @param string[] $tags
|
||||
* @param array<string, string> $metadata
|
||||
* @return UploadResult[]
|
||||
*/
|
||||
private function try_upload(array $file, array $tags, ?string $source = null): array
|
||||
private function try_upload(array $file, int $slot, array $metadata): array
|
||||
{
|
||||
global $page, $config, $database;
|
||||
|
||||
|
@ -332,10 +296,6 @@ class Upload extends Extension
|
|||
return [];
|
||||
}
|
||||
|
||||
if (empty($source)) {
|
||||
$source = null;
|
||||
}
|
||||
|
||||
$results = [];
|
||||
|
||||
for ($i = 0; $i < count($file['name']); $i++) {
|
||||
|
@ -352,12 +312,8 @@ class Upload extends Extension
|
|||
throw new UploadException($this->upload_error_message($error));
|
||||
}
|
||||
|
||||
$new_images = $database->with_savepoint(function () use ($tmp_name, $name, $tags, $source) {
|
||||
$event = send_event(new DataUploadEvent($tmp_name, [
|
||||
'filename' => pathinfo($name, PATHINFO_BASENAME),
|
||||
'tags' => $tags,
|
||||
'source' => $source,
|
||||
]));
|
||||
$new_images = $database->with_savepoint(function () use ($tmp_name, $name, $slot, $metadata) {
|
||||
$event = send_event(new DataUploadEvent($tmp_name, basename($name), $slot, $metadata));
|
||||
if (count($event->images) == 0) {
|
||||
throw new UploadException("MIME type not supported: " . $event->mime);
|
||||
}
|
||||
|
@ -375,10 +331,10 @@ class Upload extends Extension
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string[] $tags
|
||||
* @param array<string, string> $metadata
|
||||
* @return UploadResult[]
|
||||
*/
|
||||
private function try_transload(string $url, array $tags, string $source = null): array
|
||||
private function try_transload(string $url, int $slot, array $metadata): array
|
||||
{
|
||||
global $page, $config, $user, $database;
|
||||
|
||||
|
@ -398,13 +354,8 @@ class Upload extends Extension
|
|||
$h_filename = ($s_filename ? preg_replace('/^.*filename="([^ ]+)"/i', '$1', $s_filename) : null);
|
||||
$filename = $h_filename ?: basename($url);
|
||||
|
||||
$metadata = [];
|
||||
$metadata['filename'] = $filename;
|
||||
$metadata['tags'] = $tags;
|
||||
$metadata['source'] = $source;
|
||||
|
||||
$new_images = $database->with_savepoint(function () use ($tmp_filename, $metadata) {
|
||||
$event = send_event(new DataUploadEvent($tmp_filename, $metadata));
|
||||
$new_images = $database->with_savepoint(function () use ($tmp_filename, $filename, $slot, $metadata) {
|
||||
$event = send_event(new DataUploadEvent($tmp_filename, $filename, $slot, $metadata));
|
||||
if (count($event->images) == 0) {
|
||||
throw new UploadException("File type not supported: " . $event->mime);
|
||||
}
|
||||
|
|
|
@ -7,16 +7,43 @@ namespace Shimmie2;
|
|||
class ImageInfoSetEvent extends Event
|
||||
{
|
||||
public Image $image;
|
||||
public int $slot;
|
||||
/** @var array<string, string> */
|
||||
public array $params;
|
||||
|
||||
/**
|
||||
* currently all post metadata is string => string - in the future
|
||||
* we might want to have a more complex type system, but for now
|
||||
* we just filter out non-string keys (eg, `only_strings($_POST)`)
|
||||
*
|
||||
* @param array<string, string> $params
|
||||
*/
|
||||
public function __construct(Image $image, array $params)
|
||||
public function __construct(Image $image, int $slot, array $params)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->image = $image;
|
||||
$this->slot = $slot;
|
||||
$this->params = $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a slot-specific value, or a common value, or null. This allows
|
||||
* a user to POST an update to multiple images at once, setting eg
|
||||
* "source" to be a common default source and "source12" to be a
|
||||
* specific source for image 12.
|
||||
*
|
||||
* Specifically we check for "empty" rather than "isset" because
|
||||
* the upload form might have a "source" field that is empty, and
|
||||
* we want to allow non-empty values to override empty ones.
|
||||
*/
|
||||
public function get_param(string $name): ?string
|
||||
{
|
||||
if(!empty($this->params["$name{$this->slot}"])) {
|
||||
return $this->params["$name{$this->slot}"];
|
||||
}
|
||||
if(!empty($this->params[$name])) {
|
||||
return $this->params[$name];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,12 +66,7 @@ class ViewPost extends Extension
|
|||
$image_id = int_escape($event->req_POST('image_id'));
|
||||
$image = Image::by_id_ex($image_id);
|
||||
if (!$image->is_locked() || $user->can(Permissions::EDIT_IMAGE_LOCK)) {
|
||||
// currently all post metadata is string => string - in the future
|
||||
// we might want to have a more complex type system, but for now
|
||||
// we just filter out non-string keys
|
||||
/** @var array<string, string> */
|
||||
$kvs = array_filter($event->POST, 'is_string', ARRAY_FILTER_USE_KEY);
|
||||
send_event(new ImageInfoSetEvent($image, $kvs));
|
||||
send_event(new ImageInfoSetEvent($image, 0, only_strings($event->POST)));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
|
||||
if ($event->get_GET('search')) {
|
||||
|
|
Reference in a new issue