@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
at upstream/main 218 lines 8.7 kB view raw
1@title Events User Guide: Installing Event Listeners 2@group userguide 3 4Using Phorge event listeners to customize behavior. 5 6= Overview = 7 8(WARNING) The event system is an artifact of a bygone era. Use of the event 9system is strongly discouraged. We have been removing events since 2013 and 10will continue to remove events in the future. 11 12Phorge and Arcanist allow you to install custom runtime event listeners 13which can react to certain things happening (like a Maniphest Task being edited 14or a user creating a new Differential Revision) and run custom code to perform 15logging, synchronize with other systems, or modify workflows. 16 17These listeners are PHP classes which you install beside Phorge or 18Arcanist, and which Phorge loads at runtime and runs in-process. They 19require somewhat more effort upfront than simple configuration switches, but are 20the most direct and powerful way to respond to events. 21 22= Installing Event Listeners (Phorge) = 23 24To install event listeners in Phorge, follow these steps: 25 26 - Write a listener class which extends @{class@arcanist:PhutilEventListener}. 27 - Add it to a library, or create a new library (for instructions, 28 see @{article@contrib:Adding New Classes}. 29 - Configure Phorge to load the library by adding it to `load-libraries` 30 in the Phorge config. 31 - Configure Phorge to install the event listener by adding the class 32 name to `events.listeners` in the Phorge config. 33 34You can verify your listener is registered in the "Events" tab of DarkConsole. 35It should appear at the top under "Registered Event Listeners". You can also 36see any events the page emitted there. For details on DarkConsole, see 37@{article:Using DarkConsole}. 38 39= Installing Event Listeners (Arcanist) = 40 41To install event listeners in Arcanist, follow these steps: 42 43 - Write a listener class which extends @{class@arcanist:PhutilEventListener}. 44 - Add it to a library, or create a new library (for instructions, 45 see @{article@contrib:Adding New Classes}. 46 - Configure Phorge to load the library by adding it to `load` 47 in the Arcanist config (e.g., `.arcconfig`, or user/global config). 48 - Configure Arcanist to install the event listener by adding the class 49 name to `events.listeners` in the Arcanist config. 50 51You can verify your listener is registered by running any `arc` command with 52`--trace`. You should see output indicating your class was registered as an 53event listener. 54 55= Example Listener = 56 57Phorge includes an example event listener, 58@{class:PhabricatorExampleEventListener}, which may be useful as a starting 59point in developing your own listeners. This listener listens for a test 60event that is emitted by the script `scripts/util/emit_test_event.php`. 61 62If you run this script normally, it should output something like this: 63 64 $ ./scripts/util/emit_test_event.php 65 Emitting event... 66 Done. 67 68This is because there are no listeners for the event, so nothing reacts to it 69when it is emitted. You can add the example listener by either adding it to 70your `events.listeners` configuration or with the `--listen` command-line flag: 71 72 $ ./scripts/util/emit_test_event.php --listen PhabricatorExampleEventListener 73 Installing 'PhabricatorExampleEventListener'... 74 Emitting event... 75 PhabricatorExampleEventListener got test event at 1341344566 76 Done. 77 78This time, the listener was installed and had its callback invoked when the 79test event was emitted. 80 81= Available Events = 82 83You can find a list of all Phorge events in @{class:PhabricatorEventType}. 84 85== All Events == 86 87The special constant `PhutilEventType::TYPE_ALL` will let you listen for all 88events. Normally, you want to listen only to specific events, but if you're 89writing a generic handler you can listen to all events with this constant 90rather than by enumerating each event. 91 92== Arcanist Events == 93 94Arcanist event constants are listed in @{class@arcanist:ArcanistEventType}. 95 96All Arcanist events have this data available: 97 98 - `workflow` The active @{class@arcanist:ArcanistWorkflow}. 99 100== Arcanist: Commit: Will Commit SVN == 101 102The constant for this event is `ArcanistEventType::TYPE_COMMIT_WILLCOMMITSVN`. 103 104This event is dispatched before an `svn commit` occurs and allows you to 105modify the commit message. Data available on this event: 106 107 - `message` The text of the message. 108 109== Arcanist: Diff: Will Build Message == 110 111The constant for this event is `ArcanistEventType::TYPE_DIFF_WILLBUILDMESSAGE`. 112 113This event is dispatched before an editable message is presented to the user, 114and allows you to, e.g., fill in default values for fields. Data available 115on this event: 116 117 - `fields` A map of field values to be compiled into a message. 118 119== Arcanist: Diff: Was Created == 120 121The constant for this event is `ArcanistEventType::TYPE_DIFF_WASCREATED`. 122 123This event is dispatched after a diff is created. It is currently only useful 124for collecting timing information. No data is available on this event. 125 126== Arcanist: Revision: Will Create Revision == 127 128The constant for this event is 129`ArcanistEventType::TYPE_REVISION_WILLCREATEREVISION`. 130 131This event is dispatched before a revision is created. It allows you to modify 132fields to, e.g., edit revision titles. Data available on this event: 133 134 - `specification` Parameters that will be used to invoke the 135 `differential.createrevision` Conduit call. 136 137== Differential: Will Mark Generated == 138 139The constant for this event is 140`PhabricatorEventType::TYPE_DIFFERENTIAL_WILLMARKGENERATED`. 141 142This event is dispatched before Differential decides if a file is generated (and 143doesn't need to be reviewed) or not. Data available on this event: 144 145 - `corpus` Body of the file. 146 - `is_generated` Boolean indicating if this file should be treated as 147 generated. 148 149== Diffusion: Did Discover Commit == 150 151The constant for this event is 152`PhabricatorEventType::TYPE_DIFFUSION_DIDDISCOVERCOMMIT`. 153 154This event is dispatched when the daemons discover a commit for the first time. 155This event happens very early in the pipeline, and not all commit information 156will be available yet. Data available on this event: 157 158 - `commit` The @{class:PhabricatorRepositoryCommit} that was discovered. 159 - `repository` The @{class:PhabricatorRepository} the commit was discovered 160 in. 161 162== Test: Did Run Test == 163 164The constant for this event is 165`PhabricatorEventType::TYPE_TEST_DIDRUNTEST`. 166 167This is a test event for testing event listeners. See above for details. 168 169== UI: Did Render Actions == 170 171The constant for this event is 172`PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS`. 173 174This event is dispatched after a @{class:PhabricatorActionListView} is built by 175the UI. It allows you to add new actions that your application may provide, like 176"Fax this Object". Data available on this event: 177 178 - `object` The object which actions are being rendered for. 179 - `actions` The current list of available actions. 180 181NOTE: This event is unstable and subject to change. 182 183= Debugging Listeners = 184 185If you're having problems with your listener, try these steps: 186 187 - If you're getting an error about Phorge being unable to find the 188 listener class, make sure you've added it to a library and configured 189 Phorge to load the library with `load-libraries`. 190 - Make sure the listener is registered. It should appear in the "Events" tab 191 of DarkConsole. If it's not there, you may have forgotten to add it to 192 `events.listeners`. 193 - Make sure it calls `listen()` on the right events in its `register()` 194 method. If you don't listen for the events you're interested in, you 195 won't get a callback. 196 - Make sure the events you're listening for are actually happening. If they 197 occur on a normal page they should appear in the "Events" tab of 198 DarkConsole. If they occur on a POST, you could add a `phlog()` 199 to the source code near the event and check your error log to make sure the 200 code ran. 201 - You can check if your callback is getting invoked by adding `phlog()` with 202 a message and checking the error log. 203 - You can try listening to `PhutilEventType::TYPE_ALL` instead of a specific 204 event type to get all events, to narrow down whether problems are caused 205 by the types of events you're listening to. 206 - You can edit the `emit_test_event.php` script to emit other types of 207 events instead, to test that your listener reacts to them properly. You 208 might have to use fake data, but this gives you an easy way to test the 209 at least the basics. 210 - For scripts, you can run under `--trace` to see which events are emitted 211 and how many handlers are listening to each event. 212 213= Next Steps = 214 215Continue by: 216 217 - taking a look at @{class:PhabricatorExampleEventListener}; or 218 - building a library with @{article@contrib:Adding New Classes}.