@@ -9,12 +9,68 @@ Phabricator allows you to install custom runtime event listeners which can react
9
9
to certain things happening (like a Maniphest Task being edited) and run custom
10
10
code to perform logging, synchronize with other systems, or modify workflows.
11
11
12
- NOTE: This feature is new and experimental, so few events are available and
13
- things might not be completely stable.
12
+ These listeners are PHP classes which you install beside Phabricator, and which
13
+ Phabricator loads at runtime and runs in-process. They are the most direct and
14
+ powerful way to respond to events.
15
+
16
+ = Installing Event Listeners =
17
+
18
+ To install event listeners, follow these steps:
19
+
20
+ - Write a listener class which extends @{class:PhutilEventListener}.
21
+ - Add it to a libphutil library, or create a new library (for instructions,
22
+ see @{article:libphutil Libraries User Guide}.
23
+ - Configure Phabricator to load the library by adding it to `load-libraries`
24
+ in the Phabricator config.
25
+ - Configure Phabricator to install the event listener by adding the class
26
+ name to `events.listeners` in the Phabricator config.
27
+
28
+ You can verify your listener is registered in the "Events" tab of DarkConsole.
29
+ It should appear at the top under "Registered Event Listeners". You can also
30
+ see any events the page emitted there. For details on DarkConsole, see
31
+ @{article:Using DarkConsole}.
32
+
33
+ = Example Listener =
34
+
35
+ Phabricator includes an example event listener,
36
+ @{class:PhabricatorExampleEventListener}, which may be useful as a starting
37
+ point in developing your own listeners. This listener listens for a test
38
+ event that is emitted by the script `scripts/util/emit_test_event.php`.
39
+
40
+ If you run this script normally, it should output something like this:
41
+
42
+ $ ./scripts/util/emit_test_event.php
43
+ Emitting event...
44
+ Done.
45
+
46
+ This is because there are no listeners for the event, so nothing reacts to it
47
+ when it is emitted. You can add the example listener by either adding it to
48
+ your `events.listeners` configuration or with the `--listen` command-line flag:
49
+
50
+ $ ./scripts/util/emit_test_event.php --listen PhabricatorExampleEventListener
51
+ Installing 'PhabricatorExampleEventListener'...
52
+ Emitting event...
53
+ PhabricatorExampleEventListener got test event at 1341344566
54
+ Done.
55
+
56
+ This time, the listener was installed and had its callback invoked when the
57
+ test event was emitted.
14
58
15
59
= Available Events =
16
60
17
- == PhabricatorEventType::TYPE_MANIPHEST_WILLEDITTASK ==
61
+ You can find a list of all Phabricator events in @{class:PhabricatorEventType}.
62
+
63
+ == All Events ==
64
+
65
+ The special constant `PhutilEventType::TYPE_ALL` will let you listen for all
66
+ events. Normally, you want to listen only to specific events, but if you're
67
+ writing a generic handler you can listen to all events with this constant
68
+ rather than by enumerating each event.
69
+
70
+ == Maniphest: Will Edit Task ==
71
+
72
+ The constant for this event is
73
+ `PhabricatorEventType::TYPE_MANIPHEST_WILLEDITTASK`.
18
74
19
75
This event is dispatched before a task is edited, and allows you to respond to
20
76
or alter the edit. Data available on this event:
@@ -26,18 +82,134 @@ or alter the edit. Data available on this event:
26
82
- ##mail## If this edit originates from email, the
27
83
@{class:PhabricatorMetaMTAReceivedMail} object.
28
84
29
- == PhabricatorEventType::TYPE_DIFFERENTIAL_WILLSENDMAIL ==
85
+ This is similar to the next event (did edit task) but occurs before the edit
86
+ begins.
87
+
88
+ == Maniphest: Did Edit Task ==
89
+
90
+ The constant for this event is
91
+ `PhabricatorEventType::TYPE_MANIPHEST_DIDEDITTASK`.
92
+
93
+ This event is dispatched after a task is edited, and allows you to react to the
94
+ edit. Data available on this event:
95
+
96
+ - ##task## The @{class:ManiphestTask} that was edited.
97
+ - ##transactions## The list of edits (objects of class
98
+ @{class:ManiphestTransaction}) that were applied.
99
+ - ##new## A boolean indicating if this task was newly created.
100
+ - ##mail## If this edit originates from email, the
101
+ @{class:PhabricatorMetaMTAReceivedMail} object.
102
+
103
+ This is similar to the previous event (will edit task) but occurs after the
104
+ edit completes.
105
+
106
+ == Differential: Will Send Mail ==
107
+
108
+ The constant for this event is
109
+ `PhabricatorEventType::TYPE_DIFFERENTIAL_WILLSENDMAIL`
30
110
31
111
This event is dispatched before Differential sends an email, and allows you to
32
112
edit the message that will be sent. Data available on this event:
33
113
34
114
- ##mail## The @{class:PhabricatorMetaMTAMail} being edited.
35
115
36
- == PhabricatorEventType::TYPE_DIFFERENTIAL_WILLMARKGENERATED ==
116
+ == Differential: Will Mark Generated ==
117
+
118
+ The constant for this event is
119
+ `PhabricatorEventType::TYPE_DIFFERENTIAL_WILLMARKGENERATED`.
37
120
38
121
This event is dispatched before Differential decides if a file is generated (and
39
122
doesn't need to be reviewed) or not. Data available on this event:
40
123
41
124
- ##corpus## Body of the file.
42
125
- ##is_generated## Boolean indicating if this file should be treated as
43
126
generated.
127
+
128
+ == Diffusion: Did Discover Commit ==
129
+
130
+ The constant for this event is
131
+ `PhabricatorEventType::TYPE_DIFFUSION_DIDDISCOVERCOMMIT`.
132
+
133
+ This event is dispatched when the daemons discover a commit for the first time.
134
+ This event happens very early in the pipeline, and not all commit information
135
+ will be available yet. Data available on this event:
136
+
137
+ - `commit` The @{class:PhabricatorRepositoryCommit} that was discovered.
138
+ - `repository` The @{class:PhabricatorRepository} the commit was discovered
139
+ in.
140
+
141
+ == Edge: Will Edit Edges ==
142
+
143
+ NOTE: Edge events are low-level events deep in the core. It is more difficult to
144
+ correct implement listeners for these events than for higher-level events.
145
+
146
+ The constant for this event is
147
+ `PhabricatorEventType::TYPE_EDGE_WILLEDITEDGES`.
148
+
149
+ This event is dispatched before @{class:PhabricatorEdgeEditor} makes an edge
150
+ edit.
151
+
152
+ - `id` An identifier for this edit operation.
153
+ - `add` A list of dictionaries, each representing a new edge.
154
+ - `rem` A list of dictionaries, each representing a removed edge.
155
+
156
+ This is similar to the next event (did edit edges) but occurs before the
157
+ edit begins.
158
+
159
+ == Edge: Did Edit Edges ==
160
+
161
+ The constant for this event is
162
+ `PhabricatorEventType::TYPE_EDGE_DIDEDITEDGES`.
163
+
164
+ This event is dispatched after @{class:PhabricatorEdgeEditor} makes an edge
165
+ edit, but before it commits the transactions. Data available on this event:
166
+
167
+ - `id` An identifier for this edit operation. This is the same ID as
168
+ the one included in the corresponding "will edit edges" event.
169
+ - `add` A list of dictionaries, each representing a new edge.
170
+ - `rem` A list of dictionaries, each representing a removed edge.
171
+
172
+ This is similar to the previous event (will edit edges) but occurs after the
173
+ edit completes.
174
+
175
+ == Test: Did Run Test ==
176
+
177
+ The constant for this event is
178
+ `PhabricatorEventType::TYPE_TEST_DIDRUNTEST`.
179
+
180
+ This is a test event for testing event listeners. See above for details.
181
+
182
+ = Debugging Listeners =
183
+
184
+ If you're having problems with your listener, try these steps:
185
+
186
+ - If you're getting an error about Phabricator being unable to find the
187
+ listener class, make sure you've added it to a libphutil library and
188
+ configured Phabricator to load the library with `load-libraries`.
189
+ - Make sure the listener is registered. It should appear in the "Events" tab
190
+ of DarkConsole. If it's not there, you may have forgotten to add it to
191
+ `events.listeners`.
192
+ - Make sure it calls `listen()` on the right events in its `register()`
193
+ method. If you don't listen for the events you're interested in, you
194
+ won't get a callback.
195
+ - Make sure the events you're listening for are actually happening. If they
196
+ occur on a normal page they should appear in the "Events" tab of
197
+ DarkConsole. If they occur on a POST, you could add a `phlog()`
198
+ to the source code near the event and check your error log to make sure the
199
+ code ran.
200
+ - You can check if your callback is getting invoked by adding `phlog()` with
201
+ a message and checking the error log.
202
+ - You can try listening to `PhutilEventType::TYPE_ALL` instead of a specific
203
+ event type to get all events, to narrow down whether problems are caused
204
+ by the types of events you're listening to.
205
+ - You can edit the `emit_test_event.php` script to emit other types of
206
+ events instead, to test that your listener reacts to them properly. You
207
+ might have to use fake data, but this gives you an easy way to test the
208
+ at least the basics.
209
+
210
+ = Next Steps =
211
+
212
+ Continue by:
213
+
214
+ - taking a look at @{class:PhabricatorExampleEventListener}; or
215
+ - building a library with @{article:@{article:libphutil Libraries User Guide}.
0 commit comments