Correct Aphlict websocket URI construction after PHP8 compatibility changes
[phabricator.git] / src / docs / user / userguide / events.diviner
blobe18578288ba5906cf7334773c5aa33be73b82f3f
1 @title Events User Guide: Installing Event Listeners
2 @group userguide
4 Using Phabricator event listeners to customize behavior.
6 = Overview =
8 (WARNING) The event system is an artifact of a bygone era. Use of the event
9 system is strongly discouraged. We have been removing events since 2013 and
10 will continue to remove events in the future.
12 Phabricator and Arcanist allow you to install custom runtime event listeners
13 which can react to certain things happening (like a Maniphest Task being edited
14 or a user creating a new Differential Revision) and run custom code to perform
15 logging, synchronize with other systems, or modify workflows.
17 These listeners are PHP classes which you install beside Phabricator or
18 Arcanist, and which Phabricator loads at runtime and runs in-process. They
19 require somewhat more effort upfront than simple configuration switches, but are
20 the most direct and powerful way to respond to events.
22 = Installing Event Listeners (Phabricator) =
24 To install event listeners in Phabricator, follow these steps:
26   - Write a listener class which extends @{class@arcanist:PhutilEventListener}.
27   - Add it to a libphutil library, or create a new library (for instructions,
28     see @{article@phabcontrib:Adding New Classes}.
29   - Configure Phabricator to load the library by adding it to `load-libraries`
30     in the Phabricator config.
31   - Configure Phabricator to install the event listener by adding the class
32     name to `events.listeners` in the Phabricator config.
34 You can verify your listener is registered in the "Events" tab of DarkConsole.
35 It should appear at the top under "Registered Event Listeners". You can also
36 see any events the page emitted there. For details on DarkConsole, see
37 @{article:Using DarkConsole}.
39 = Installing Event Listeners (Arcanist) =
41 To install event listeners in Arcanist, follow these steps:
43   - Write a listener class which extends @{class@arcanist:PhutilEventListener}.
44   - Add it to a libphutil library, or create a new library (for instructions,
45     see @{article@phabcontrib:Adding New Classes}.
46   - Configure Phabricator 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.
51 You 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
53 event listener.
55 = Example Listener =
57 Phabricator includes an example event listener,
58 @{class:PhabricatorExampleEventListener}, which may be useful as a starting
59 point in developing your own listeners. This listener listens for a test
60 event that is emitted by the script `scripts/util/emit_test_event.php`.
62 If you run this script normally, it should output something like this:
64   $ ./scripts/util/emit_test_event.php
65   Emitting event...
66   Done.
68 This is because there are no listeners for the event, so nothing reacts to it
69 when it is emitted. You can add the example listener by either adding it to
70 your `events.listeners` configuration or with the `--listen` command-line flag:
72   $ ./scripts/util/emit_test_event.php --listen PhabricatorExampleEventListener
73   Installing 'PhabricatorExampleEventListener'...
74   Emitting event...
75   PhabricatorExampleEventListener got test event at 1341344566
76   Done.
78 This time, the listener was installed and had its callback invoked when the
79 test event was emitted.
81 = Available Events =
83 You can find a list of all Phabricator events in @{class:PhabricatorEventType}.
85 == All Events ==
87 The special constant `PhutilEventType::TYPE_ALL` will let you listen for all
88 events. Normally, you want to listen only to specific events, but if you're
89 writing a generic handler you can listen to all events with this constant
90 rather than by enumerating each event.
92 == Arcanist Events ==
94 Arcanist event constants are listed in @{class@arcanist:ArcanistEventType}.
96 All Arcanist events have this data available:
98   - `workflow` The active @{class@arcanist:ArcanistWorkflow}.
100 == Arcanist: Commit: Will Commit SVN ==
102 The constant for this event is `ArcanistEventType::TYPE_COMMIT_WILLCOMMITSVN`.
104 This event is dispatched before an `svn commit` occurs and allows you to
105 modify the commit message. Data available on this event:
107   - `message` The text of the message.
109 == Arcanist: Diff: Will Build Message ==
111 The constant for this event is `ArcanistEventType::TYPE_DIFF_WILLBUILDMESSAGE`.
113 This event is dispatched before an editable message is presented to the user,
114 and allows you to, e.g., fill in default values for fields. Data available
115 on this event:
117   - `fields` A map of field values to be compiled into a message.
119 == Arcanist: Diff: Was Created ==
121 The constant for this event is `ArcanistEventType::TYPE_DIFF_WASCREATED`.
123 This event is dispatched after a diff is created. It is currently only useful
124 for collecting timing information. No data is available on this event.
126 == Arcanist: Revision: Will Create Revision ==
128 The constant for this event is
129 `ArcanistEventType::TYPE_REVISION_WILLCREATEREVISION`.
131 This event is dispatched before a revision is created. It allows you to modify
132 fields to, e.g., edit revision titles. Data available on this event:
134   - `specification` Parameters that will be used to invoke the
135     `differential.createrevision` Conduit call.
137 == Differential: Will Mark Generated ==
139 The constant for this event is
140 `PhabricatorEventType::TYPE_DIFFERENTIAL_WILLMARKGENERATED`.
142 This event is dispatched before Differential decides if a file is generated (and
143 doesn't need to be reviewed) or not. Data available on this event:
145   - `corpus` Body of the file.
146   - `is_generated` Boolean indicating if this file should be treated as
147     generated.
149 == Diffusion: Did Discover Commit ==
151 The constant for this event is
152 `PhabricatorEventType::TYPE_DIFFUSION_DIDDISCOVERCOMMIT`.
154 This event is dispatched when the daemons discover a commit for the first time.
155 This event happens very early in the pipeline, and not all commit information
156 will be available yet. Data available on this event:
158   - `commit` The @{class:PhabricatorRepositoryCommit} that was discovered.
159   - `repository` The @{class:PhabricatorRepository} the commit was discovered
160     in.
162 == Test: Did Run Test ==
164 The constant for this event is
165 `PhabricatorEventType::TYPE_TEST_DIDRUNTEST`.
167 This is a test event for testing event listeners. See above for details.
169 == UI: Did Render Actions ==
171 The constant for this event is
172 `PhabricatorEventType::TYPE_UI_DIDRENDERACTIONS`.
174 This event is dispatched after a @{class:PhabricatorActionListView} is built by
175 the UI. It allows you to add new actions that your application may provide, like
176 "Fax this Object". Data available on this event:
178   - `object` The object which actions are being rendered for.
179   - `actions` The current list of available actions.
181 NOTE: This event is unstable and subject to change.
183 = Debugging Listeners =
185 If you're having problems with your listener, try these steps:
187   - If you're getting an error about Phabricator being unable to find the
188     listener class, make sure you've added it to a libphutil library and
189     configured Phabricator 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.
213 = Next Steps =
215 Continue by:
217   - taking a look at @{class:PhabricatorExampleEventListener}; or
218   - building a library with @{article:libphutil Libraries User Guide}.