]> git.mxchange.org Git - friendica.git/commitdiff
Create event for photo upload hooks
authorArt4 <art4@wlabs.de>
Thu, 10 Apr 2025 14:17:20 +0000 (14:17 +0000)
committerArt4 <art4@wlabs.de>
Thu, 10 Apr 2025 14:17:20 +0000 (14:17 +0000)
src/Core/Hooks/HookEventBridge.php
src/Event/ArrayFilterEvent.php
src/Module/Profile/Photos.php
tests/Unit/Core/Hooks/HookEventBridgeTest.php
tests/Unit/Event/ArrayFilterEventTest.php

index 03f8ced58ca36314c8e0babeeb182499104248b3..df2a17322e0e2a0478112ac62c289f335c138cbd 100644 (file)
@@ -54,6 +54,9 @@ final class HookEventBridge
                ArrayFilterEvent::PREPARE_POST                    => 'prepare_body',
                ArrayFilterEvent::PREPARE_POST_END                => 'prepare_body_final',
                ArrayFilterEvent::PHOTO_UPLOAD_FORM               => 'photo_upload_form',
+               ArrayFilterEvent::PHOTO_UPLOAD_START              => 'photo_post_init',
+               ArrayFilterEvent::PHOTO_UPLOAD                    => 'photo_post_file',
+               ArrayFilterEvent::PHOTO_UPLOAD_END                => 'photo_post_end',
                ArrayFilterEvent::NETWORK_TO_NAME                 => 'network_to_name',
                ArrayFilterEvent::NETWORK_CONTENT_START           => 'network_content_init',
                ArrayFilterEvent::NETWORK_CONTENT_TABS            => 'network_tabs',
@@ -139,6 +142,9 @@ final class HookEventBridge
                        ArrayFilterEvent::PREPARE_POST                    => 'onArrayFilterEvent',
                        ArrayFilterEvent::PREPARE_POST_END                => 'onArrayFilterEvent',
                        ArrayFilterEvent::PHOTO_UPLOAD_FORM               => 'onArrayFilterEvent',
+                       ArrayFilterEvent::PHOTO_UPLOAD_START              => 'onPhotoUploadStartEvent',
+                       ArrayFilterEvent::PHOTO_UPLOAD                    => 'onArrayFilterEvent',
+                       ArrayFilterEvent::PHOTO_UPLOAD_END                => 'onPhotoUploadEndEvent',
                        ArrayFilterEvent::NETWORK_TO_NAME                 => 'onArrayFilterEvent',
                        ArrayFilterEvent::NETWORK_CONTENT_START           => 'onArrayFilterEvent',
                        ArrayFilterEvent::NETWORK_CONTENT_TABS            => 'onArrayFilterEvent',
@@ -273,6 +279,33 @@ final class HookEventBridge
                $event->setArray($data);
        }
 
+       /**
+        * Map the PHOTO_UPLOAD_START event to `photo_post_init` hook
+        */
+       public static function onPhotoUploadStartEvent(ArrayFilterEvent $event): void
+       {
+               $data = $event->getArray();
+
+               $request = (array) $data['request'] ?? [];
+
+               $data['request'] = static::callHook($event->getName(), $request);
+
+               $event->setArray($data);
+       }
+
+       /**
+        * Map the PHOTO_UPLOAD_END event to `photo_post_end` hook
+        */
+       public static function onPhotoUploadEndEvent(ArrayFilterEvent $event): void
+       {
+               $data = $event->getArray();
+
+               $id = (int) $data['id'] ?? 0;
+
+               // one-way-event: we don't care about the returned value
+               static::callHook($event->getName(), $id);
+       }
+
        /**
         * Map the PROFILE_SIDEBAR_ENTRY event to `profile_sidebar_enter` hook
         */
index f1ba9887d9d0ebb19e9ad34c2ef2f5513e9f44a1..7c772f4132799bae1a0522c837809f663e32af4f 100644 (file)
@@ -58,6 +58,12 @@ final class ArrayFilterEvent extends Event
 
        public const PHOTO_UPLOAD_FORM = 'friendica.data.photo_upload_form';
 
+       public const PHOTO_UPLOAD_START = 'friendica.data.photo_upload_start';
+
+       public const PHOTO_UPLOAD = 'friendica.data.photo_upload';
+
+       public const PHOTO_UPLOAD_END = 'friendica.data.photo_upload_end';
+
        public const NETWORK_TO_NAME = 'friendica.data.network_to_name';
 
        public const NETWORK_CONTENT_START = 'friendica.data.network_content_start';
index a377cd6dc31da5ea2ea75068727dcf8cb11b6e56..29ece42ef93c61f289891dece9dde349b63e5aae 100644 (file)
@@ -14,12 +14,12 @@ use Friendica\AppHelper;
 use Friendica\Content\Feature;
 use Friendica\Content\Pager;
 use Friendica\Core\Config\Capability\IManageConfigValues;
-use Friendica\Core\Hook;
 use Friendica\Core\L10n;
 use Friendica\Core\Renderer;
 use Friendica\Core\Session\Capability\IHandleUserSessions;
 use Friendica\Core\System;
 use Friendica\Database\Database;
+use Friendica\Event\ArrayFilterEvent;
 use Friendica\Model\Contact;
 use Friendica\Model\Item;
 use Friendica\Model\Photo;
@@ -34,6 +34,7 @@ use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Images;
 use Friendica\Util\Profiler;
 use Friendica\Util\Strings;
+use Psr\EventDispatcher\EventDispatcherInterface;
 use Psr\Log\LoggerInterface;
 
 class Photos extends \Friendica\Module\BaseProfile
@@ -52,11 +53,28 @@ class Photos extends \Friendica\Module\BaseProfile
        private $systemMessages;
        /** @var ACLFormatter */
        private $aclFormatter;
+       private EventDispatcherInterface $eventDispatcher;
        /** @var array owner-view record */
        private $owner;
 
-       public function __construct(ACLFormatter $aclFormatter, SystemMessages $systemMessages, Database $database, AppHelper $appHelper, IManageConfigValues $config, Page $page, IHandleUserSessions $session, L10n $l10n, BaseURL $baseUrl, Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
-       {
+       public function __construct(
+               ACLFormatter $aclFormatter,
+               SystemMessages $systemMessages,
+               Database $database,
+               AppHelper $appHelper,
+               IManageConfigValues $config,
+               Page $page,
+               IHandleUserSessions $session,
+               EventDispatcherInterface $eventDispatcher,
+               L10n $l10n,
+               BaseURL $baseUrl,
+               Arguments $args,
+               LoggerInterface $logger,
+               Profiler $profiler,
+               Response $response,
+               array $server,
+               array $parameters = [],
+       ) {
                parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
 
                $this->session        = $session;
@@ -66,6 +84,7 @@ class Photos extends \Friendica\Module\BaseProfile
                $this->database       = $database;
                $this->systemMessages = $systemMessages;
                $this->aclFormatter   = $aclFormatter;
+               $this->eventDispatcher = $eventDispatcher;
 
                $owner = Profile::load($this->appHelper, $this->parameters['nickname'] ?? '', false);
                if (!$owner || $owner['account_removed'] || $owner['account_expired']) {
@@ -97,8 +116,16 @@ class Photos extends \Friendica\Module\BaseProfile
                        $str_contact_allow .= $this->aclFormatter->toString(Contact::getPublicIdByUserId($this->owner['uid']));
                }
 
+               $hook_data = [
+                       'request' => $request,
+               ];
+
                // default post action - upload a photo
-               Hook::callAll('photo_post_init', $request);
+               $hook_data = $this->eventDispatcher->dispatch(
+                       new ArrayFilterEvent(ArrayFilterEvent::PHOTO_UPLOAD_START, $hook_data),
+               )->getArray();
+
+               $request = $hook_data['request'] ?? $request;
 
                // Determine the album to use
                $album    = trim($request['album'] ?? '');
@@ -127,19 +154,27 @@ class Photos extends \Friendica\Module\BaseProfile
                        $visible = 0;
                }
 
-               $ret      = ['src' => '', 'filename' => '', 'filesize' => 0, 'type' => ''];
+               $hook_data = [
+                       'src' => '',
+                       'filename' => '',
+                       'filesize' => 0,
+                       'type' => '',
+               ];
+
+               $hook_data = $this->eventDispatcher->dispatch(
+                       new ArrayFilterEvent(ArrayFilterEvent::PHOTO_UPLOAD, $hook_data),
+               )->getArray();
+
                $src      = null;
                $filename = '';
                $filesize = 0;
                $type     = '';
 
-               Hook::callAll('photo_post_file', $ret);
-
-               if (!empty($ret['src']) && !empty($ret['filesize'])) {
-                       $src      = $ret['src'];
-                       $filename = $ret['filename'];
-                       $filesize = $ret['filesize'];
-                       $type     = $ret['type'];
+               if (!empty($hook_data['src']) && !empty($hook_data['filesize'])) {
+                       $src      = $hook_data['src'];
+                       $filename = $hook_data['filename'];
+                       $filesize = $hook_data['filesize'];
+                       $type     = $hook_data['type'];
                        $error    = UPLOAD_ERR_OK;
                } elseif (!empty($_FILES['userfile'])) {
                        $src      = $_FILES['userfile']['tmp_name'];
@@ -176,8 +211,10 @@ class Photos extends \Friendica\Module\BaseProfile
                                @unlink($src);
                        }
 
-                       $foo = 0;
-                       Hook::callAll('photo_post_end', $foo);
+                       $this->eventDispatcher->dispatch(
+                               new ArrayFilterEvent(ArrayFilterEvent::PHOTO_UPLOAD_END, ['id' => 0]),
+                       );
+
                        return;
                }
 
@@ -188,16 +225,22 @@ class Photos extends \Friendica\Module\BaseProfile
                if ($maximagesize && ($filesize > $maximagesize)) {
                        $this->systemMessages->addNotice($this->t('Image exceeds size limit of %s', Strings::formatBytes($maximagesize)));
                        @unlink($src);
-                       $foo = 0;
-                       Hook::callAll('photo_post_end', $foo);
+
+                       $this->eventDispatcher->dispatch(
+                               new ArrayFilterEvent(ArrayFilterEvent::PHOTO_UPLOAD_END, ['id' => 0]),
+                       );
+
                        return;
                }
 
                if (!$filesize) {
                        $this->systemMessages->addNotice($this->t('Image file is empty.'));
                        @unlink($src);
-                       $foo = 0;
-                       Hook::callAll('photo_post_end', $foo);
+
+                       $this->eventDispatcher->dispatch(
+                               new ArrayFilterEvent(ArrayFilterEvent::PHOTO_UPLOAD_END, ['id' => 0]),
+                       );
+
                        return;
                }
 
@@ -211,8 +254,11 @@ class Photos extends \Friendica\Module\BaseProfile
                        $this->logger->notice('unable to process image');
                        $this->systemMessages->addNotice($this->t('Unable to process image.'));
                        @unlink($src);
-                       $foo = 0;
-                       Hook::callAll('photo_post_end',$foo);
+
+                       $this->eventDispatcher->dispatch(
+                               new ArrayFilterEvent(ArrayFilterEvent::PHOTO_UPLOAD_END, ['id' => 0]),
+                       );
+
                        return;
                }
 
@@ -274,10 +320,11 @@ class Photos extends \Friendica\Module\BaseProfile
                // Update the photo albums cache
                Photo::clearAlbumCache($this->owner['uid']);
 
-               Hook::callAll('photo_post_end', $item_id);
-
-               // addon uploaders should call "exit()" within the photo_post_end hook
+               // addon uploaders should call "exit()" within the PHOTO_UPLOAD_END event
                // if they do not wish to be redirected
+               $this->eventDispatcher->dispatch(
+                       new ArrayFilterEvent(ArrayFilterEvent::PHOTO_UPLOAD_END, ['id' => $item_id]),
+               );
 
                $this->baseUrl->redirect($this->session->get('photo_return') ?? 'profile/' . $this->owner['nickname'] . '/photos');
        }
index a07907e42752dc91a6f2a97fc1f21c832cbbb391..f30a1c2fef42a6bb36d0f4266da4c1be0b12a000 100644 (file)
@@ -43,6 +43,9 @@ class HookEventBridgeTest extends TestCase
                        ArrayFilterEvent::PREPARE_POST                    => 'onArrayFilterEvent',
                        ArrayFilterEvent::PREPARE_POST_END                => 'onArrayFilterEvent',
                        ArrayFilterEvent::PHOTO_UPLOAD_FORM               => 'onArrayFilterEvent',
+                       ArrayFilterEvent::PHOTO_UPLOAD_START              => 'onPhotoUploadStartEvent',
+                       ArrayFilterEvent::PHOTO_UPLOAD                    => 'onArrayFilterEvent',
+                       ArrayFilterEvent::PHOTO_UPLOAD_END                => 'onPhotoUploadEndEvent',
                        ArrayFilterEvent::NETWORK_TO_NAME                 => 'onArrayFilterEvent',
                        ArrayFilterEvent::NETWORK_CONTENT_START           => 'onArrayFilterEvent',
                        ArrayFilterEvent::NETWORK_CONTENT_TABS            => 'onArrayFilterEvent',
@@ -298,6 +301,45 @@ class HookEventBridgeTest extends TestCase
                );
        }
 
+       public function testOnPhotoUploadStartEventCallsHookWithCorrectValue(): void
+       {
+               $event = new ArrayFilterEvent(ArrayFilterEvent::PHOTO_UPLOAD_START, ['request' => ['album' => -1]]);
+
+               $reflectionProperty = new \ReflectionProperty(HookEventBridge::class, 'mockedCallHook');
+               $reflectionProperty->setAccessible(true);
+
+               $reflectionProperty->setValue(null, function (string $name, array $data): array {
+                       $this->assertSame('photo_post_init', $name);
+                       $this->assertSame(['album' => -1], $data);
+
+                       return ['album' => 123];
+               });
+
+               HookEventBridge::onPhotoUploadStartEvent($event);
+
+               $this->assertSame(
+                       ['request' => ['album' => 123]],
+                       $event->getArray(),
+               );
+       }
+
+       public function testOnPhotoUploadEndEventCallsHookWithCorrectValue(): void
+       {
+               $event = new ArrayFilterEvent(ArrayFilterEvent::PHOTO_UPLOAD_END, ['id' => -1]);
+
+               $reflectionProperty = new \ReflectionProperty(HookEventBridge::class, 'mockedCallHook');
+               $reflectionProperty->setAccessible(true);
+
+               $reflectionProperty->setValue(null, function (string $name, int $data): int {
+                       $this->assertSame('photo_post_end', $name);
+                       $this->assertSame(-1, $data);
+
+                       return 123;
+               });
+
+               HookEventBridge::onPhotoUploadEndEvent($event);
+       }
+
        public function testOnProfileSidebarEntryEventCallsHookWithCorrectValue(): void
        {
                $event = new ArrayFilterEvent(ArrayFilterEvent::PROFILE_SIDEBAR_ENTRY, ['profile' => ['uid' => 0, 'name' => 'original']]);
@@ -491,6 +533,7 @@ class HookEventBridgeTest extends TestCase
                        [ArrayFilterEvent::PREPARE_POST, 'prepare_body'],
                        [ArrayFilterEvent::PREPARE_POST_END, 'prepare_body_final'],
                        [ArrayFilterEvent::PHOTO_UPLOAD_FORM, 'photo_upload_form'],
+                       [ArrayFilterEvent::PHOTO_UPLOAD, 'photo_post_file'],
                        [ArrayFilterEvent::NETWORK_TO_NAME, 'network_to_name'],
                        [ArrayFilterEvent::NETWORK_CONTENT_START, 'network_content_init'],
                        [ArrayFilterEvent::NETWORK_CONTENT_TABS, 'network_tabs'],
index 69a8d6829d5fefacfa08fead4010909256c2c8dd..9ecdb6feeeed308c26718c8d2c6a869f427d547f 100644 (file)
@@ -40,6 +40,9 @@ class ArrayFilterEventTest extends TestCase
                        [ArrayFilterEvent::PREPARE_POST, 'friendica.data.prepare_post'],
                        [ArrayFilterEvent::PREPARE_POST_END, 'friendica.data.prepare_post_end'],
                        [ArrayFilterEvent::PHOTO_UPLOAD_FORM, 'friendica.data.photo_upload_form'],
+                       [ArrayFilterEvent::PHOTO_UPLOAD_START, 'friendica.data.photo_upload_start'],
+                       [ArrayFilterEvent::PHOTO_UPLOAD, 'friendica.data.photo_upload'],
+                       [ArrayFilterEvent::PHOTO_UPLOAD_END, 'friendica.data.photo_upload_end'],
                        [ArrayFilterEvent::NETWORK_TO_NAME, 'friendica.data.network_to_name'],
                        [ArrayFilterEvent::NETWORK_CONTENT_START, 'friendica.data.network_content_start'],
                        [ArrayFilterEvent::NETWORK_CONTENT_TABS, 'friendica.data.network_content_tabs'],