@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Make it much easier to add one-off event listeners

Summary:
Ref T4657. Right now, you have to muck with `events.listeners` to install listeners. Instead, automatically install all subclasses of AutoEventListener.

Primarily, this makes it easier to resolve requests with "drop this file in `src/extensions/`, no warranty", which seems to have worked well so far in resolving things like custom remarkup rules, etc.

Test Plan:
- Added such a listener, had it autoregister.
- Clicked around and saw the effects of normal listeners.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T4657

Differential Revision: https://secure.phabricator.com/D9262

+48 -15
+2
src/__phutil_library_map__.php
··· 1288 1288 'PhabricatorAuthUnlinkController' => 'applications/auth/controller/PhabricatorAuthUnlinkController.php', 1289 1289 'PhabricatorAuthValidateController' => 'applications/auth/controller/PhabricatorAuthValidateController.php', 1290 1290 'PhabricatorAuthenticationConfigOptions' => 'applications/config/option/PhabricatorAuthenticationConfigOptions.php', 1291 + 'PhabricatorAutoEventListener' => 'infrastructure/events/PhabricatorAutoEventListener.php', 1291 1292 'PhabricatorBarePageExample' => 'applications/uiexample/examples/PhabricatorBarePageExample.php', 1292 1293 'PhabricatorBarePageView' => 'view/page/PhabricatorBarePageView.php', 1293 1294 'PhabricatorBaseEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorBaseEnglishTranslation.php', ··· 4062 4063 'PhabricatorAuthUnlinkController' => 'PhabricatorAuthController', 4063 4064 'PhabricatorAuthValidateController' => 'PhabricatorAuthController', 4064 4065 'PhabricatorAuthenticationConfigOptions' => 'PhabricatorApplicationConfigOptions', 4066 + 'PhabricatorAutoEventListener' => 'PhabricatorEventListener', 4065 4067 'PhabricatorBarePageExample' => 'PhabricatorUIExample', 4066 4068 'PhabricatorBarePageView' => 'AphrontPageView', 4067 4069 'PhabricatorBaseEnglishTranslation' => 'PhabricatorTranslation',
+17
src/infrastructure/events/PhabricatorAutoEventListener.php
··· 1 + <?php 2 + 3 + /** 4 + * Event listener which is registered automatically, without requiring 5 + * configuration. 6 + * 7 + * Normally, event listeners must be registered via applications. This is 8 + * appropriate for structured listeners in libraries, but it adds a lot of 9 + * overhead and is cumbersome for one-off listeners. 10 + * 11 + * All concrete subclasses of this class are automatically registered at 12 + * startup. This allows it to be used with custom one-offs that can be dropped 13 + * into `phabricator/src/extensions/`. 14 + */ 15 + abstract class PhabricatorAutoEventListener extends PhabricatorEventListener { 16 + 17 + }
+29 -15
src/infrastructure/events/PhabricatorEventEngine.php
··· 1 1 <?php 2 2 3 - /** 4 - * @group events 5 - */ 6 3 final class PhabricatorEventEngine { 7 4 8 5 public static function initialize() { 9 - $listeners = PhabricatorEnv::getEnvConfig('events.listeners'); 10 - foreach ($listeners as $listener) { 6 + // NOTE: If any of this fails, we just log it and move on. It's important 7 + // to try to make it through here because users may have difficulty fixing 8 + // fix the errors if we don't: for example, if we fatal here a user may not 9 + // be able to run `bin/config` in order to remove an invalid listener. 10 + 11 + // Load automatic listeners. 12 + $listeners = id(new PhutilSymbolLoader()) 13 + ->setAncestorClass('PhabricatorAutoEventListener') 14 + ->loadObjects(); 15 + 16 + // Load configured listeners. 17 + $config_listeners = PhabricatorEnv::getEnvConfig('events.listeners'); 18 + foreach ($config_listeners as $listener_class) { 11 19 try { 12 - id(new $listener())->register(); 20 + $listeners[] = newv($listener_class, array()); 13 21 } catch (Exception $ex) { 14 - // If the listener does not exist, or throws when registering, just 15 - // log it and continue. In particular, this is important to let you 16 - // run `bin/config` in order to remove an invalid listener. 17 22 phlog($ex); 18 23 } 19 24 } 20 25 21 - // Register the DarkConosole event logger. 22 - id(new DarkConsoleEventPluginAPI())->register(); 23 - id(new ManiphestEdgeEventListener())->register(); 26 + // Add builtin listeners. 27 + $listeners[] = new DarkConsoleEventPluginAPI(); 28 + $listeners[] = new ManiphestEdgeEventListener(); 24 29 30 + // Add application listeners. 25 31 $applications = PhabricatorApplication::getAllInstalledApplications(); 26 32 foreach ($applications as $application) { 27 - $listeners = $application->getEventListeners(); 28 - foreach ($listeners as $listener) { 33 + $app_listeners = $application->getEventListeners(); 34 + foreach ($app_listeners as $listener) { 29 35 $listener->setApplication($application); 36 + $listeners[] = $listener; 37 + } 38 + } 39 + 40 + // Now, register all of the listeners. 41 + foreach ($listeners as $listener) { 42 + try { 30 43 $listener->register(); 44 + } catch (Exception $ex) { 45 + phlog($ex); 31 46 } 32 47 } 33 - 34 48 } 35 49 36 50 }