5188c73c9362b1ac5a3fce94c5ec467ce020c576
[GitHub/WoltLab/woltlab.github.io.git] / latest / php / api / events / index.html
1
2 <!doctype html>
3 <html lang="en" class="no-js">
4 <head>
5
6 <meta charset="utf-8">
7 <meta name="viewport" content="width=device-width,initial-scale=1">
8
9
10
11
12 <link rel="shortcut icon" href="../../../assets/default.favicon.ico">
13 <meta name="generator" content="mkdocs-1.1.2, mkdocs-material-7.0.5">
14
15
16
17 <title>Events - WoltLab Suite Documentation</title>
18
19
20
21 <link rel="stylesheet" href="../../../assets/stylesheets/main.77f3fd56.min.css">
22
23
24 <link rel="stylesheet" href="../../../assets/stylesheets/palette.7fa14f5b.min.css">
25
26
27
28 <meta name="theme-color" content="#009485">
29
30
31
32
33
34
35
36
37
38 <link rel="stylesheet" href="../../../stylesheets/extra.css">
39
40
41
42
43
44 </head>
45
46
47
48
49
50
51
52 <body dir="ltr" data-md-color-scheme="" data-md-color-primary="teal" data-md-color-accent="">
53
54
55
56 <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
57 <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
58 <label class="md-overlay" for="__drawer"></label>
59 <div data-md-component="skip">
60
61
62 <a href="#events" class="md-skip">
63 Skip to content
64 </a>
65
66 </div>
67 <div data-md-component="announce">
68
69 <aside class="md-announce">
70 <div class="md-announce__inner md-grid md-typeset">
71
72 <a href="https://www.woltlab.com">Back to <strong>woltlab.com</strong></a>
73
74 </div>
75 </aside>
76
77 </div>
78
79
80
81 <header class="md-header" data-md-component="header">
82 <nav class="md-header__inner md-grid" aria-label="Header">
83 <a href="../../.." title="WoltLab Suite Documentation" class="md-header__button md-logo" aria-label="WoltLab Suite Documentation">
84
85 <img src="../../../assets/logo.png" alt="logo">
86
87 </a>
88 <label class="md-header__button md-icon" for="__drawer">
89 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2z"/></svg>
90 </label>
91 <div class="md-header__title" data-md-component="header-title">
92 <div class="md-header__ellipsis">
93 <div class="md-header__topic">
94 <span class="md-ellipsis">
95 WoltLab Suite Documentation
96 </span>
97 </div>
98 <div class="md-header__topic" data-md-component="header-topic">
99 <span class="md-ellipsis">
100
101 Events
102
103 </span>
104 </div>
105 </div>
106 </div>
107 <div class="md-header__options">
108
109 </div>
110
111
112 <div class="md-header__source">
113
114 <a href="https://github.com/WoltLab/docs.woltlab.com/" title="Go to repository" class="md-source" data-md-component="source">
115 <div class="md-source__icon md-icon">
116
117 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05L244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
118 </div>
119 <div class="md-source__repository">
120 GitHub
121 </div>
122 </a>
123 </div>
124
125 </nav>
126 </header>
127
128 <div class="md-container" data-md-component="container">
129
130
131
132
133 <main class="md-main" data-md-component="main">
134 <div class="md-main__inner md-grid">
135
136
137
138 <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
139 <div class="md-sidebar__scrollwrap">
140 <div class="md-sidebar__inner">
141
142
143
144
145
146 <nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
147 <label class="md-nav__title" for="__drawer">
148 <a href="../../.." title="WoltLab Suite Documentation" class="md-nav__button md-logo" aria-label="WoltLab Suite Documentation">
149
150 <img src="../../../assets/logo.png" alt="logo">
151
152 </a>
153 WoltLab Suite Documentation
154 </label>
155
156 <div class="md-nav__source">
157
158 <a href="https://github.com/WoltLab/docs.woltlab.com/" title="Go to repository" class="md-source" data-md-component="source">
159 <div class="md-source__icon md-icon">
160
161 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M439.55 236.05L244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z"/></svg>
162 </div>
163 <div class="md-source__repository">
164 GitHub
165 </div>
166 </a>
167 </div>
168
169 <ul class="md-nav__list" data-md-scrollfix>
170
171
172
173
174
175
176
177
178 <li class="md-nav__item">
179 <a href="../../../getting-started/" class="md-nav__link">
180 Getting Started
181 </a>
182 </li>
183
184
185
186
187
188
189
190
191
192
193
194
195
196 <li class="md-nav__item md-nav__item--active md-nav__item--nested">
197
198
199 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_2" type="checkbox" id="__nav_2" checked>
200
201 <label class="md-nav__link" for="__nav_2">
202 PHP API
203 <span class="md-nav__icon md-icon"></span>
204 </label>
205 <nav class="md-nav" aria-label="PHP API" data-md-level="1">
206 <label class="md-nav__title" for="__nav_2">
207 <span class="md-nav__icon md-icon"></span>
208 PHP API
209 </label>
210 <ul class="md-nav__list" data-md-scrollfix>
211
212
213
214
215
216 <li class="md-nav__item">
217 <a href="../../pages/" class="md-nav__link">
218 Pages
219 </a>
220 </li>
221
222
223
224
225
226
227
228 <li class="md-nav__item">
229 <a href="../../database-objects/" class="md-nav__link">
230 Database Objects
231 </a>
232 </li>
233
234
235
236
237
238
239
240 <li class="md-nav__item">
241 <a href="../../database-access/" class="md-nav__link">
242 Database Access
243 </a>
244 </li>
245
246
247
248
249
250
251
252 <li class="md-nav__item">
253 <a href="../../exceptions/" class="md-nav__link">
254 Exceptions
255 </a>
256 </li>
257
258
259
260
261
262
263
264
265
266
267 <li class="md-nav__item md-nav__item--active md-nav__item--nested">
268
269
270 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_2_5" type="checkbox" id="__nav_2_5" checked>
271
272 <label class="md-nav__link" for="__nav_2_5">
273 API
274 <span class="md-nav__icon md-icon"></span>
275 </label>
276 <nav class="md-nav" aria-label="API" data-md-level="2">
277 <label class="md-nav__title" for="__nav_2_5">
278 <span class="md-nav__icon md-icon"></span>
279 API
280 </label>
281 <ul class="md-nav__list" data-md-scrollfix>
282
283
284
285
286
287 <li class="md-nav__item">
288 <a href="../caches/" class="md-nav__link">
289 Caches
290 </a>
291 </li>
292
293
294
295
296
297
298
299 <li class="md-nav__item">
300 <a href="../comments/" class="md-nav__link">
301 Comments
302 </a>
303 </li>
304
305
306
307
308
309
310
311 <li class="md-nav__item">
312 <a href="../cronjobs/" class="md-nav__link">
313 Cronjobs
314 </a>
315 </li>
316
317
318
319
320
321
322
323
324
325 <li class="md-nav__item md-nav__item--active">
326
327 <input class="md-nav__toggle md-toggle" data-md-toggle="toc" type="checkbox" id="__toc">
328
329
330
331
332 <label class="md-nav__link md-nav__link--active" for="__toc">
333 Events
334 <span class="md-nav__icon md-icon"></span>
335 </label>
336
337 <a href="./" class="md-nav__link md-nav__link--active">
338 Events
339 </a>
340
341
342 <nav class="md-nav md-nav--secondary" aria-label="Table of contents">
343
344
345
346
347
348 <label class="md-nav__title" for="__toc">
349 <span class="md-nav__icon md-icon"></span>
350 Table of contents
351 </label>
352 <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
353
354 <li class="md-nav__item">
355 <a href="#introductory-example" class="md-nav__link">
356 Introductory Example
357 </a>
358
359 </li>
360
361 <li class="md-nav__item">
362 <a href="#listening-to-events" class="md-nav__link">
363 Listening to Events
364 </a>
365
366 </li>
367
368 <li class="md-nav__item">
369 <a href="#firing-events" class="md-nav__link">
370 Firing Events
371 </a>
372
373 <nav class="md-nav" aria-label="Firing Events">
374 <ul class="md-nav__list">
375
376 <li class="md-nav__item">
377 <a href="#example-using-parameters-argument" class="md-nav__link">
378 Example: Using $parameters argument
379 </a>
380
381 </li>
382
383 </ul>
384 </nav>
385
386 </li>
387
388 <li class="md-nav__item">
389 <a href="#advanced-example-additional-form-field" class="md-nav__link">
390 Advanced Example: Additional Form Field
391 </a>
392
393 </li>
394
395 </ul>
396
397 </nav>
398
399 </li>
400
401
402
403
404
405
406
407
408 <li class="md-nav__item md-nav__item--nested">
409
410
411 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_2_5_5" type="checkbox" id="__nav_2_5_5" >
412
413 <label class="md-nav__link" for="__nav_2_5_5">
414 Form Builder
415 <span class="md-nav__icon md-icon"></span>
416 </label>
417 <nav class="md-nav" aria-label="Form Builder" data-md-level="3">
418 <label class="md-nav__title" for="__nav_2_5_5">
419 <span class="md-nav__icon md-icon"></span>
420 Form Builder
421 </label>
422 <ul class="md-nav__list" data-md-scrollfix>
423
424
425
426
427
428 <li class="md-nav__item">
429 <a href="../form_builder/overview/" class="md-nav__link">
430 Overview
431 </a>
432 </li>
433
434
435
436
437
438
439
440 <li class="md-nav__item">
441 <a href="../form_builder/structure/" class="md-nav__link">
442 Structure
443 </a>
444 </li>
445
446
447
448
449
450
451
452 <li class="md-nav__item">
453 <a href="../form_builder/form_fields/" class="md-nav__link">
454 Fields
455 </a>
456 </li>
457
458
459
460
461
462
463
464 <li class="md-nav__item">
465 <a href="../form_builder/validation_data/" class="md-nav__link">
466 Validation and Data
467 </a>
468 </li>
469
470
471
472
473
474
475
476 <li class="md-nav__item">
477 <a href="../form_builder/dependencies/" class="md-nav__link">
478 Dependencies
479 </a>
480 </li>
481
482
483
484 </ul>
485 </nav>
486 </li>
487
488
489
490
491
492
493
494 <li class="md-nav__item">
495 <a href="../package_installation_plugins/" class="md-nav__link">
496 Package Installation Plugins
497 </a>
498 </li>
499
500
501
502
503
504
505
506 <li class="md-nav__item">
507 <a href="../user_activity_points/" class="md-nav__link">
508 User Activity Points
509 </a>
510 </li>
511
512
513
514
515
516
517
518 <li class="md-nav__item">
519 <a href="../user_notifications/" class="md-nav__link">
520 User Notifications
521 </a>
522 </li>
523
524
525
526
527
528
529
530 <li class="md-nav__item">
531 <a href="../sitemaps/" class="md-nav__link">
532 Sitemaps
533 </a>
534 </li>
535
536
537
538 </ul>
539 </nav>
540 </li>
541
542
543
544
545
546
547
548 <li class="md-nav__item">
549 <a href="../../code-style/" class="md-nav__link">
550 Code Style
551 </a>
552 </li>
553
554
555
556
557
558
559
560 <li class="md-nav__item">
561 <a href="../../apps/" class="md-nav__link">
562 Apps
563 </a>
564 </li>
565
566
567
568
569
570
571
572 <li class="md-nav__item">
573 <a href="../../gdpr/" class="md-nav__link">
574 GDPR
575 </a>
576 </li>
577
578
579
580 </ul>
581 </nav>
582 </li>
583
584
585
586
587
588
589
590
591
592
593
594 <li class="md-nav__item md-nav__item--nested">
595
596
597 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_3" type="checkbox" id="__nav_3" >
598
599 <label class="md-nav__link" for="__nav_3">
600 Languages, Templates & CSS
601 <span class="md-nav__icon md-icon"></span>
602 </label>
603 <nav class="md-nav" aria-label="Languages, Templates & CSS" data-md-level="1">
604 <label class="md-nav__title" for="__nav_3">
605 <span class="md-nav__icon md-icon"></span>
606 Languages, Templates & CSS
607 </label>
608 <ul class="md-nav__list" data-md-scrollfix>
609
610
611
612
613
614 <li class="md-nav__item">
615 <a href="../../../view/languages/" class="md-nav__link">
616 Languages
617 </a>
618 </li>
619
620
621
622
623
624
625
626 <li class="md-nav__item">
627 <a href="../../../view/templates/" class="md-nav__link">
628 Templates
629 </a>
630 </li>
631
632
633
634
635
636
637
638 <li class="md-nav__item">
639 <a href="../../../view/css/" class="md-nav__link">
640 CSS
641 </a>
642 </li>
643
644
645
646 </ul>
647 </nav>
648 </li>
649
650
651
652
653
654
655
656
657
658
659
660 <li class="md-nav__item md-nav__item--nested">
661
662
663 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_4" type="checkbox" id="__nav_4" >
664
665 <label class="md-nav__link" for="__nav_4">
666 JavaScript API
667 <span class="md-nav__icon md-icon"></span>
668 </label>
669 <nav class="md-nav" aria-label="JavaScript API" data-md-level="1">
670 <label class="md-nav__title" for="__nav_4">
671 <span class="md-nav__icon md-icon"></span>
672 JavaScript API
673 </label>
674 <ul class="md-nav__list" data-md-scrollfix>
675
676
677
678
679
680 <li class="md-nav__item">
681 <a href="../../../javascript/general-usage/" class="md-nav__link">
682 General Usage
683 </a>
684 </li>
685
686
687
688
689
690
691
692
693 <li class="md-nav__item md-nav__item--nested">
694
695
696 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_4_2" type="checkbox" id="__nav_4_2" >
697
698 <label class="md-nav__link" for="__nav_4_2">
699 New API
700 <span class="md-nav__icon md-icon"></span>
701 </label>
702 <nav class="md-nav" aria-label="New API" data-md-level="2">
703 <label class="md-nav__title" for="__nav_4_2">
704 <span class="md-nav__icon md-icon"></span>
705 New API
706 </label>
707 <ul class="md-nav__list" data-md-scrollfix>
708
709
710
711
712
713 <li class="md-nav__item">
714 <a href="../../../javascript/new-api_writing-a-module/" class="md-nav__link">
715 Writing a module
716 </a>
717 </li>
718
719
720
721
722
723
724
725 <li class="md-nav__item">
726 <a href="../../../javascript/new-api_data-structures/" class="md-nav__link">
727 Data Structures
728 </a>
729 </li>
730
731
732
733
734
735
736
737 <li class="md-nav__item">
738 <a href="../../../javascript/new-api_core/" class="md-nav__link">
739 Core Functions
740 </a>
741 </li>
742
743
744
745
746
747
748
749 <li class="md-nav__item">
750 <a href="../../../javascript/new-api_dom/" class="md-nav__link">
751 DOM
752 </a>
753 </li>
754
755
756
757
758
759
760
761 <li class="md-nav__item">
762 <a href="../../../javascript/new-api_events/" class="md-nav__link">
763 Event Handling
764 </a>
765 </li>
766
767
768
769
770
771
772
773 <li class="md-nav__item">
774 <a href="../../../javascript/new-api_ajax/" class="md-nav__link">
775 Ajax
776 </a>
777 </li>
778
779
780
781
782
783
784
785 <li class="md-nav__item">
786 <a href="../../../javascript/new-api_dialogs/" class="md-nav__link">
787 Dialogs
788 </a>
789 </li>
790
791
792
793
794
795
796
797 <li class="md-nav__item">
798 <a href="../../../javascript/new-api_browser/" class="md-nav__link">
799 Browser and Screen Sizes
800 </a>
801 </li>
802
803
804
805
806
807
808
809 <li class="md-nav__item">
810 <a href="../../../javascript/new-api_ui/" class="md-nav__link">
811 User Interface
812 </a>
813 </li>
814
815
816
817 </ul>
818 </nav>
819 </li>
820
821
822
823
824
825
826
827 <li class="md-nav__item">
828 <a href="../../../javascript/legacy-api/" class="md-nav__link">
829 Legacy API
830 </a>
831 </li>
832
833
834
835
836
837
838
839 <li class="md-nav__item">
840 <a href="../../../javascript/helper-functions/" class="md-nav__link">
841 Helper Functions
842 </a>
843 </li>
844
845
846
847
848
849
850
851 <li class="md-nav__item">
852 <a href="../../../javascript/code-snippets/" class="md-nav__link">
853 Code Snippets
854 </a>
855 </li>
856
857
858
859 </ul>
860 </nav>
861 </li>
862
863
864
865
866
867
868
869
870
871
872
873 <li class="md-nav__item md-nav__item--nested">
874
875
876 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_5" type="checkbox" id="__nav_5" >
877
878 <label class="md-nav__link" for="__nav_5">
879 Package Components
880 <span class="md-nav__icon md-icon"></span>
881 </label>
882 <nav class="md-nav" aria-label="Package Components" data-md-level="1">
883 <label class="md-nav__title" for="__nav_5">
884 <span class="md-nav__icon md-icon"></span>
885 Package Components
886 </label>
887 <ul class="md-nav__list" data-md-scrollfix>
888
889
890
891
892
893 <li class="md-nav__item">
894 <a href="../../../package/package-xml/" class="md-nav__link">
895 package.xml
896 </a>
897 </li>
898
899
900
901
902
903
904
905
906 <li class="md-nav__item md-nav__item--nested">
907
908
909 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_5_2" type="checkbox" id="__nav_5_2" >
910
911 <label class="md-nav__link" for="__nav_5_2">
912 PIPs
913 <span class="md-nav__icon md-icon"></span>
914 </label>
915 <nav class="md-nav" aria-label="PIPs" data-md-level="2">
916 <label class="md-nav__title" for="__nav_5_2">
917 <span class="md-nav__icon md-icon"></span>
918 PIPs
919 </label>
920 <ul class="md-nav__list" data-md-scrollfix>
921
922
923
924
925
926 <li class="md-nav__item">
927 <a href="../../../package/pip/" class="md-nav__link">
928 Overview
929 </a>
930 </li>
931
932
933
934
935
936
937
938 <li class="md-nav__item">
939 <a href="../../../package/pip/acl-option/" class="md-nav__link">
940 aclOption
941 </a>
942 </li>
943
944
945
946
947
948
949
950 <li class="md-nav__item">
951 <a href="../../../package/pip/acp-menu/" class="md-nav__link">
952 acpMenu
953 </a>
954 </li>
955
956
957
958
959
960
961
962 <li class="md-nav__item">
963 <a href="../../../package/pip/acp-search-provider/" class="md-nav__link">
964 acpSearchProvider
965 </a>
966 </li>
967
968
969
970
971
972
973
974 <li class="md-nav__item">
975 <a href="../../../package/pip/acp-template/" class="md-nav__link">
976 acpTemplate
977 </a>
978 </li>
979
980
981
982
983
984
985
986 <li class="md-nav__item">
987 <a href="../../../package/pip/bbcode/" class="md-nav__link">
988 bbcode
989 </a>
990 </li>
991
992
993
994
995
996
997
998 <li class="md-nav__item">
999 <a href="../../../package/pip/box/" class="md-nav__link">
1000 box
1001 </a>
1002 </li>
1003
1004
1005
1006
1007
1008
1009
1010 <li class="md-nav__item">
1011 <a href="../../../package/pip/clipboard-action/" class="md-nav__link">
1012 clipboardAction
1013 </a>
1014 </li>
1015
1016
1017
1018
1019
1020
1021
1022 <li class="md-nav__item">
1023 <a href="../../../package/pip/core-object/" class="md-nav__link">
1024 coreObject
1025 </a>
1026 </li>
1027
1028
1029
1030
1031
1032
1033
1034 <li class="md-nav__item">
1035 <a href="../../../package/pip/cronjob/" class="md-nav__link">
1036 cronjob
1037 </a>
1038 </li>
1039
1040
1041
1042
1043
1044
1045
1046 <li class="md-nav__item">
1047 <a href="../../../package/pip/event-listener/" class="md-nav__link">
1048 eventListener
1049 </a>
1050 </li>
1051
1052
1053
1054
1055
1056
1057
1058 <li class="md-nav__item">
1059 <a href="../../../package/pip/file/" class="md-nav__link">
1060 file
1061 </a>
1062 </li>
1063
1064
1065
1066
1067
1068
1069
1070 <li class="md-nav__item">
1071 <a href="../../../package/pip/language/" class="md-nav__link">
1072 language
1073 </a>
1074 </li>
1075
1076
1077
1078
1079
1080
1081
1082 <li class="md-nav__item">
1083 <a href="../../../package/pip/media-provider/" class="md-nav__link">
1084 mediaProvider
1085 </a>
1086 </li>
1087
1088
1089
1090
1091
1092
1093
1094 <li class="md-nav__item">
1095 <a href="../../../package/pip/menu/" class="md-nav__link">
1096 menu
1097 </a>
1098 </li>
1099
1100
1101
1102
1103
1104
1105
1106 <li class="md-nav__item">
1107 <a href="../../../package/pip/menu-item/" class="md-nav__link">
1108 menuItem
1109 </a>
1110 </li>
1111
1112
1113
1114
1115
1116
1117
1118 <li class="md-nav__item">
1119 <a href="../../../package/pip/object-type/" class="md-nav__link">
1120 objectType
1121 </a>
1122 </li>
1123
1124
1125
1126
1127
1128
1129
1130 <li class="md-nav__item">
1131 <a href="../../../package/pip/object-type-definition/" class="md-nav__link">
1132 objectTypeDefinition
1133 </a>
1134 </li>
1135
1136
1137
1138
1139
1140
1141
1142 <li class="md-nav__item">
1143 <a href="../../../package/pip/option/" class="md-nav__link">
1144 option
1145 </a>
1146 </li>
1147
1148
1149
1150
1151
1152
1153
1154 <li class="md-nav__item">
1155 <a href="../../../package/pip/page/" class="md-nav__link">
1156 page
1157 </a>
1158 </li>
1159
1160
1161
1162
1163
1164
1165
1166 <li class="md-nav__item">
1167 <a href="../../../package/pip/pip/" class="md-nav__link">
1168 pip
1169 </a>
1170 </li>
1171
1172
1173
1174
1175
1176
1177
1178 <li class="md-nav__item">
1179 <a href="../../../package/pip/script/" class="md-nav__link">
1180 script
1181 </a>
1182 </li>
1183
1184
1185
1186
1187
1188
1189
1190 <li class="md-nav__item">
1191 <a href="../../../package/pip/smiley/" class="md-nav__link">
1192 smiley
1193 </a>
1194 </li>
1195
1196
1197
1198
1199
1200
1201
1202 <li class="md-nav__item">
1203 <a href="../../../package/pip/sql/" class="md-nav__link">
1204 sql
1205 </a>
1206 </li>
1207
1208
1209
1210
1211
1212
1213
1214 <li class="md-nav__item">
1215 <a href="../../../package/pip/style/" class="md-nav__link">
1216 style
1217 </a>
1218 </li>
1219
1220
1221
1222
1223
1224
1225
1226 <li class="md-nav__item">
1227 <a href="../../../package/pip/template/" class="md-nav__link">
1228 template
1229 </a>
1230 </li>
1231
1232
1233
1234
1235
1236
1237
1238 <li class="md-nav__item">
1239 <a href="../../../package/pip/template-listener/" class="md-nav__link">
1240 templateListener
1241 </a>
1242 </li>
1243
1244
1245
1246
1247
1248
1249
1250 <li class="md-nav__item">
1251 <a href="../../../package/pip/user-group-option/" class="md-nav__link">
1252 userGroupOption
1253 </a>
1254 </li>
1255
1256
1257
1258
1259
1260
1261
1262 <li class="md-nav__item">
1263 <a href="../../../package/pip/user-menu/" class="md-nav__link">
1264 userMenu
1265 </a>
1266 </li>
1267
1268
1269
1270
1271
1272
1273
1274 <li class="md-nav__item">
1275 <a href="../../../package/pip/user-notification-event/" class="md-nav__link">
1276 userNotificationEvent
1277 </a>
1278 </li>
1279
1280
1281
1282
1283
1284
1285
1286 <li class="md-nav__item">
1287 <a href="../../../package/pip/user-option/" class="md-nav__link">
1288 userOption
1289 </a>
1290 </li>
1291
1292
1293
1294
1295
1296
1297
1298 <li class="md-nav__item">
1299 <a href="../../../package/pip/user-profile-menu/" class="md-nav__link">
1300 userProfileMenu
1301 </a>
1302 </li>
1303
1304
1305
1306 </ul>
1307 </nav>
1308 </li>
1309
1310
1311
1312
1313
1314
1315
1316 <li class="md-nav__item">
1317 <a href="../../../package/database-php-api/" class="md-nav__link">
1318 Database PHP API
1319 </a>
1320 </li>
1321
1322
1323
1324 </ul>
1325 </nav>
1326 </li>
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338 <li class="md-nav__item md-nav__item--nested">
1339
1340
1341 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_6" type="checkbox" id="__nav_6" >
1342
1343 <label class="md-nav__link" for="__nav_6">
1344 Migration
1345 <span class="md-nav__icon md-icon"></span>
1346 </label>
1347 <nav class="md-nav" aria-label="Migration" data-md-level="1">
1348 <label class="md-nav__title" for="__nav_6">
1349 <span class="md-nav__icon md-icon"></span>
1350 Migration
1351 </label>
1352 <ul class="md-nav__list" data-md-scrollfix>
1353
1354
1355
1356
1357
1358
1359 <li class="md-nav__item md-nav__item--nested">
1360
1361
1362 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_6_1" type="checkbox" id="__nav_6_1" >
1363
1364 <label class="md-nav__link" for="__nav_6_1">
1365 Migrating from WSC 5.3
1366 <span class="md-nav__icon md-icon"></span>
1367 </label>
1368 <nav class="md-nav" aria-label="Migrating from WSC 5.3" data-md-level="2">
1369 <label class="md-nav__title" for="__nav_6_1">
1370 <span class="md-nav__icon md-icon"></span>
1371 Migrating from WSC 5.3
1372 </label>
1373 <ul class="md-nav__list" data-md-scrollfix>
1374
1375
1376
1377
1378
1379 <li class="md-nav__item">
1380 <a href="../../../migration/wsc53/php/" class="md-nav__link">
1381 PHP API
1382 </a>
1383 </li>
1384
1385
1386
1387
1388
1389
1390
1391 <li class="md-nav__item">
1392 <a href="../../../migration/wsc53/session/" class="md-nav__link">
1393 Session Handling and Authentication
1394 </a>
1395 </li>
1396
1397
1398
1399
1400
1401
1402
1403 <li class="md-nav__item">
1404 <a href="../../../migration/wsc53/javascript/" class="md-nav__link">
1405 JavaScript
1406 </a>
1407 </li>
1408
1409
1410
1411
1412
1413
1414
1415 <li class="md-nav__item">
1416 <a href="../../../migration/wsc53/templates/" class="md-nav__link">
1417 Templates
1418 </a>
1419 </li>
1420
1421
1422
1423
1424
1425
1426
1427 <li class="md-nav__item">
1428 <a href="../../../migration/wsc53/libraries/" class="md-nav__link">
1429 Third Party Libraries
1430 </a>
1431 </li>
1432
1433
1434
1435 </ul>
1436 </nav>
1437 </li>
1438
1439
1440
1441
1442
1443
1444
1445
1446 <li class="md-nav__item md-nav__item--nested">
1447
1448
1449 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_6_2" type="checkbox" id="__nav_6_2" >
1450
1451 <label class="md-nav__link" for="__nav_6_2">
1452 Migrating from WSC 5.2
1453 <span class="md-nav__icon md-icon"></span>
1454 </label>
1455 <nav class="md-nav" aria-label="Migrating from WSC 5.2" data-md-level="2">
1456 <label class="md-nav__title" for="__nav_6_2">
1457 <span class="md-nav__icon md-icon"></span>
1458 Migrating from WSC 5.2
1459 </label>
1460 <ul class="md-nav__list" data-md-scrollfix>
1461
1462
1463
1464
1465
1466 <li class="md-nav__item">
1467 <a href="../../../migration/wsc52/php/" class="md-nav__link">
1468 PHP API
1469 </a>
1470 </li>
1471
1472
1473
1474
1475
1476
1477
1478 <li class="md-nav__item">
1479 <a href="../../../migration/wsc52/templates/" class="md-nav__link">
1480 Templates and Languages
1481 </a>
1482 </li>
1483
1484
1485
1486
1487
1488
1489
1490 <li class="md-nav__item">
1491 <a href="../../../migration/wsc52/libraries/" class="md-nav__link">
1492 Third Party Libraries
1493 </a>
1494 </li>
1495
1496
1497
1498 </ul>
1499 </nav>
1500 </li>
1501
1502
1503
1504
1505
1506
1507
1508
1509 <li class="md-nav__item md-nav__item--nested">
1510
1511
1512 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_6_3" type="checkbox" id="__nav_6_3" >
1513
1514 <label class="md-nav__link" for="__nav_6_3">
1515 Migrating from WSC 3.1
1516 <span class="md-nav__icon md-icon"></span>
1517 </label>
1518 <nav class="md-nav" aria-label="Migrating from WSC 3.1" data-md-level="2">
1519 <label class="md-nav__title" for="__nav_6_3">
1520 <span class="md-nav__icon md-icon"></span>
1521 Migrating from WSC 3.1
1522 </label>
1523 <ul class="md-nav__list" data-md-scrollfix>
1524
1525
1526
1527
1528
1529 <li class="md-nav__item">
1530 <a href="../../../migration/wsc31/php/" class="md-nav__link">
1531 PHP API
1532 </a>
1533 </li>
1534
1535
1536
1537 </ul>
1538 </nav>
1539 </li>
1540
1541
1542
1543
1544
1545
1546
1547
1548 <li class="md-nav__item md-nav__item--nested">
1549
1550
1551 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_6_4" type="checkbox" id="__nav_6_4" >
1552
1553 <label class="md-nav__link" for="__nav_6_4">
1554 Migrating from WSC 3.0
1555 <span class="md-nav__icon md-icon"></span>
1556 </label>
1557 <nav class="md-nav" aria-label="Migrating from WSC 3.0" data-md-level="2">
1558 <label class="md-nav__title" for="__nav_6_4">
1559 <span class="md-nav__icon md-icon"></span>
1560 Migrating from WSC 3.0
1561 </label>
1562 <ul class="md-nav__list" data-md-scrollfix>
1563
1564
1565
1566
1567
1568 <li class="md-nav__item">
1569 <a href="../../../migration/wsc30/php/" class="md-nav__link">
1570 PHP API
1571 </a>
1572 </li>
1573
1574
1575
1576
1577
1578
1579
1580 <li class="md-nav__item">
1581 <a href="../../../migration/wsc30/javascript/" class="md-nav__link">
1582 JavaScript API
1583 </a>
1584 </li>
1585
1586
1587
1588
1589
1590
1591
1592 <li class="md-nav__item">
1593 <a href="../../../migration/wsc30/templates/" class="md-nav__link">
1594 Templates
1595 </a>
1596 </li>
1597
1598
1599
1600
1601
1602
1603
1604 <li class="md-nav__item">
1605 <a href="../../../migration/wsc30/css/" class="md-nav__link">
1606 CSS
1607 </a>
1608 </li>
1609
1610
1611
1612
1613
1614
1615
1616 <li class="md-nav__item">
1617 <a href="../../../migration/wsc30/package/" class="md-nav__link">
1618 Package Components
1619 </a>
1620 </li>
1621
1622
1623
1624 </ul>
1625 </nav>
1626 </li>
1627
1628
1629
1630
1631
1632
1633
1634
1635 <li class="md-nav__item md-nav__item--nested">
1636
1637
1638 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_6_5" type="checkbox" id="__nav_6_5" >
1639
1640 <label class="md-nav__link" for="__nav_6_5">
1641 Migrating from WCF 2.1
1642 <span class="md-nav__icon md-icon"></span>
1643 </label>
1644 <nav class="md-nav" aria-label="Migrating from WCF 2.1" data-md-level="2">
1645 <label class="md-nav__title" for="__nav_6_5">
1646 <span class="md-nav__icon md-icon"></span>
1647 Migrating from WCF 2.1
1648 </label>
1649 <ul class="md-nav__list" data-md-scrollfix>
1650
1651
1652
1653
1654
1655 <li class="md-nav__item">
1656 <a href="../../../migration/wcf21/php/" class="md-nav__link">
1657 PHP API
1658 </a>
1659 </li>
1660
1661
1662
1663
1664
1665
1666
1667 <li class="md-nav__item">
1668 <a href="../../../migration/wcf21/templates/" class="md-nav__link">
1669 Templates
1670 </a>
1671 </li>
1672
1673
1674
1675
1676
1677
1678
1679 <li class="md-nav__item">
1680 <a href="../../../migration/wcf21/css/" class="md-nav__link">
1681 CSS
1682 </a>
1683 </li>
1684
1685
1686
1687
1688
1689
1690
1691 <li class="md-nav__item">
1692 <a href="../../../migration/wcf21/package/" class="md-nav__link">
1693 Package Components
1694 </a>
1695 </li>
1696
1697
1698
1699 </ul>
1700 </nav>
1701 </li>
1702
1703
1704
1705 </ul>
1706 </nav>
1707 </li>
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719 <li class="md-nav__item md-nav__item--nested">
1720
1721
1722 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_7" type="checkbox" id="__nav_7" >
1723
1724 <label class="md-nav__link" for="__nav_7">
1725 Tutorials
1726 <span class="md-nav__icon md-icon"></span>
1727 </label>
1728 <nav class="md-nav" aria-label="Tutorials" data-md-level="1">
1729 <label class="md-nav__title" for="__nav_7">
1730 <span class="md-nav__icon md-icon"></span>
1731 Tutorials
1732 </label>
1733 <ul class="md-nav__list" data-md-scrollfix>
1734
1735
1736
1737
1738
1739
1740 <li class="md-nav__item md-nav__item--nested">
1741
1742
1743 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_7_1" type="checkbox" id="__nav_7_1" >
1744
1745 <label class="md-nav__link" for="__nav_7_1">
1746 Tutorial Series
1747 <span class="md-nav__icon md-icon"></span>
1748 </label>
1749 <nav class="md-nav" aria-label="Tutorial Series" data-md-level="2">
1750 <label class="md-nav__title" for="__nav_7_1">
1751 <span class="md-nav__icon md-icon"></span>
1752 Tutorial Series
1753 </label>
1754 <ul class="md-nav__list" data-md-scrollfix>
1755
1756
1757
1758
1759
1760 <li class="md-nav__item">
1761 <a href="../../../tutorial/series/overview/" class="md-nav__link">
1762 Overview
1763 </a>
1764 </li>
1765
1766
1767
1768
1769
1770
1771
1772 <li class="md-nav__item">
1773 <a href="../../../tutorial/series/part_1/" class="md-nav__link">
1774 Part 1
1775 </a>
1776 </li>
1777
1778
1779
1780
1781
1782
1783
1784 <li class="md-nav__item">
1785 <a href="../../../tutorial/series/part_2/" class="md-nav__link">
1786 Part 2
1787 </a>
1788 </li>
1789
1790
1791
1792
1793
1794
1795
1796 <li class="md-nav__item">
1797 <a href="../../../tutorial/series/part_3/" class="md-nav__link">
1798 Part 3
1799 </a>
1800 </li>
1801
1802
1803
1804 </ul>
1805 </nav>
1806 </li>
1807
1808
1809
1810 </ul>
1811 </nav>
1812 </li>
1813
1814
1815
1816 </ul>
1817 </nav>
1818 </div>
1819 </div>
1820 </div>
1821
1822
1823
1824 <div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
1825 <div class="md-sidebar__scrollwrap">
1826 <div class="md-sidebar__inner">
1827
1828 <nav class="md-nav md-nav--secondary" aria-label="Table of contents">
1829
1830
1831
1832
1833
1834 <label class="md-nav__title" for="__toc">
1835 <span class="md-nav__icon md-icon"></span>
1836 Table of contents
1837 </label>
1838 <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
1839
1840 <li class="md-nav__item">
1841 <a href="#introductory-example" class="md-nav__link">
1842 Introductory Example
1843 </a>
1844
1845 </li>
1846
1847 <li class="md-nav__item">
1848 <a href="#listening-to-events" class="md-nav__link">
1849 Listening to Events
1850 </a>
1851
1852 </li>
1853
1854 <li class="md-nav__item">
1855 <a href="#firing-events" class="md-nav__link">
1856 Firing Events
1857 </a>
1858
1859 <nav class="md-nav" aria-label="Firing Events">
1860 <ul class="md-nav__list">
1861
1862 <li class="md-nav__item">
1863 <a href="#example-using-parameters-argument" class="md-nav__link">
1864 Example: Using $parameters argument
1865 </a>
1866
1867 </li>
1868
1869 </ul>
1870 </nav>
1871
1872 </li>
1873
1874 <li class="md-nav__item">
1875 <a href="#advanced-example-additional-form-field" class="md-nav__link">
1876 Advanced Example: Additional Form Field
1877 </a>
1878
1879 </li>
1880
1881 </ul>
1882
1883 </nav>
1884 </div>
1885 </div>
1886 </div>
1887
1888
1889 <div class="md-content" data-md-component="content">
1890 <article class="md-content__inner md-typeset">
1891
1892
1893 <a href="https://github.com/WoltLab/docs.woltlab.com/edit/5.4/docs/php/api/events.md" title="Edit this page" class="md-content__button md-icon">
1894 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z"/></svg>
1895 </a>
1896
1897
1898 <h1 id="events">Events<a class="headerlink" href="#events" title="Permanent link">#</a></h1>
1899 <p>WoltLab Suite's event system allows manipulation of program flows and data without having to change any of the original source code.
1900 At many locations throughout the PHP code of WoltLab Suite Core and mainly through inheritance also in the applications and plugins, so called <em>events</em> are fired which trigger registered <em>event listeners</em> that get access to the object firing the event (or at least the class name if the event has been fired in a static method).</p>
1901 <p>This page focuses on the technical aspects of events and event listeners, <a href="../../../package/pip/event-listener/">the eventListener package installation plugin page</a> covers how you can actually register an event listener.
1902 A comprehensive list of all available events is provided <a href="../event_list/">here</a>.</p>
1903 <h2 id="introductory-example">Introductory Example<a class="headerlink" href="#introductory-example" title="Permanent link">#</a></h2>
1904 <p>Let's start with a simple example to illustrate how the event system works.
1905 Consider this pre-existing class:</p>
1906 <div class="highlight"><pre><span></span><code><span class="o">&lt;?</span><span class="nx">php</span>
1907 <span class="k">namespace</span> <span class="nx">wcf\system\example</span><span class="p">;</span>
1908 <span class="k">use</span> <span class="nx">wcf\system\event\EventHandler</span><span class="p">;</span>
1909
1910 <span class="k">class</span> <span class="nc">ExampleComponent</span> <span class="p">{</span>
1911 <span class="k">public</span> <span class="nv">$var</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
1912
1913 <span class="k">public</span> <span class="k">function</span> <span class="nf">getVar</span><span class="p">()</span> <span class="p">{</span>
1914 <span class="nx">EventHandler</span><span class="o">::</span><span class="na">getInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">fireAction</span><span class="p">(</span><span class="nv">$this</span><span class="p">,</span> <span class="s1">&#39;getVar&#39;</span><span class="p">);</span>
1915
1916 <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">var</span><span class="p">;</span>
1917 <span class="p">}</span>
1918 <span class="p">}</span>
1919 </code></pre></div>
1920 <p>where an event with event name <code>getVar</code> is fired in the <code>getVar()</code> method.</p>
1921 <p>If you create an object of this class and call the <code>getVar()</code> method, the return value will be <code>1</code>, of course:</p>
1922 <div class="highlight"><pre><span></span><code><span class="o">&lt;?</span><span class="nx">php</span>
1923
1924 <span class="nv">$example</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">wcf\system\example\ExampleComponent</span><span class="p">();</span>
1925 <span class="k">if</span> <span class="p">(</span><span class="nv">$example</span><span class="o">-&gt;</span><span class="na">getVar</span><span class="p">()</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
1926 <span class="k">echo</span> <span class="s2">&quot;var is 1!&quot;</span><span class="p">;</span>
1927 <span class="p">}</span>
1928 <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nv">$example</span><span class="o">-&gt;</span><span class="na">getVar</span><span class="p">()</span> <span class="o">==</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
1929 <span class="k">echo</span> <span class="s2">&quot;var is 2!&quot;</span><span class="p">;</span>
1930 <span class="p">}</span>
1931 <span class="k">else</span> <span class="p">{</span>
1932 <span class="k">echo</span> <span class="s2">&quot;No, var is neither 1 nor 2.&quot;</span><span class="p">;</span>
1933 <span class="p">}</span>
1934
1935 <span class="c1">// output: var is 1!</span>
1936 </code></pre></div>
1937 <p>Now, consider that we have registered the following event listener to this event:</p>
1938 <div class="highlight"><pre><span></span><code><span class="o">&lt;?</span><span class="nx">php</span>
1939 <span class="k">namespace</span> <span class="nx">wcf\system\event\listener</span><span class="p">;</span>
1940
1941 <span class="k">class</span> <span class="nc">ExampleEventListener</span> <span class="k">implements</span> <span class="nx">IParameterizedEventListener</span> <span class="p">{</span>
1942 <span class="k">public</span> <span class="k">function</span> <span class="nf">execute</span><span class="p">(</span><span class="nv">$eventObj</span><span class="p">,</span> <span class="nv">$className</span><span class="p">,</span> <span class="nv">$eventName</span><span class="p">,</span> <span class="k">array</span> <span class="o">&amp;</span><span class="nv">$parameters</span><span class="p">)</span> <span class="p">{</span>
1943 <span class="nv">$eventObj</span><span class="o">-&gt;</span><span class="na">var</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
1944 <span class="p">}</span>
1945 <span class="p">}</span>
1946 </code></pre></div>
1947 <p>Whenever the event in the <code>getVar()</code> method is called, this method (of the same event listener object) is called.
1948 In this case, the value of the method's first parameter is the <code>ExampleComponent</code> object passed as the first argument of the <code>EventHandler::fireAction()</code> call in <code>ExampleComponent::getVar()</code>.
1949 As <code>ExampleComponent::$var</code> is a public property, the event listener code can change it and set it to <code>2</code>.</p>
1950 <p>If you now execute the example code from above again, the output will change from <code>var is 1!</code> to <code>var is 2!</code> because prior to returning the value, the event listener code changes the value from <code>1</code> to <code>2</code>.</p>
1951 <p>This introductory example illustrates how event listeners can change data in a non-intrusive way.
1952 Program flow can be changed, for example, by throwing a <code>wcf\system\exception\PermissionDeniedException</code> if some additional constraint to access a page is not fulfilled.</p>
1953 <h2 id="listening-to-events">Listening to Events<a class="headerlink" href="#listening-to-events" title="Permanent link">#</a></h2>
1954 <p>In order to listen to events, you need to register the event listener and the event listener itself needs to implement the interface <code>wcf\system\event\listener\IParameterizedEventListener</code> which only contains the <code>execute</code> method (see example above).</p>
1955 <p>The first parameter <code>$eventObj</code> of the method contains the passed object where the event is fired or the name of the class in which the event is fired if it is fired from a static method.
1956 The second parameter <code>$className</code> always contains the name of the class where the event has been fired.
1957 The third parameter <code>$eventName</code> provides the name of the event within a class to uniquely identify the exact location in the class where the event has been fired.
1958 The last parameter <code>$parameters</code> is a reference to the array which contains additional data passed by the method firing the event.
1959 If no additional data is passed, <code>$parameters</code> is empty.</p>
1960 <h2 id="firing-events">Firing Events<a class="headerlink" href="#firing-events" title="Permanent link">#</a></h2>
1961 <p>If you write code and want plugins to have access at certain points, you can fire an event on your own.
1962 The only thing to do is to call the <code>wcf\system\event\EventHandler::fireAction($eventObj, $eventName, array &amp;$parameters = [])</code> method and pass the following parameters:</p>
1963 <ol>
1964 <li><code>$eventObj</code> should be <code>$this</code> if you fire from an object context, otherwise pass the class name <code>static::class</code>.</li>
1965 <li><code>$eventName</code> identifies the event within the class and generally has the same name as the method.
1966 In cases, were you might fire more than one event in a method, for example before and after a certain piece of code, you can use the prefixes <code>before*</code> and <code>after*</code> in your event names.</li>
1967 <li><code>$parameters</code> is an optional array which allows you to pass additional data to the event listeners without having to make this data accessible via a property explicitly only created for this purpose.
1968 This additional data can either be just additional information for the event listeners about the context of the method call or allow the event listener to manipulate local data if the code, where the event has been fired, uses the passed data afterwards. </li>
1969 </ol>
1970 <h3 id="example-using-parameters-argument">Example: Using <code>$parameters</code> argument<a class="headerlink" href="#example-using-parameters-argument" title="Permanent link">#</a></h3>
1971 <p>Consider the following method which gets some text that the methods parses.</p>
1972 <div class="highlight"><pre><span></span><code><span class="o">&lt;?</span><span class="nx">php</span>
1973 <span class="k">namespace</span> <span class="nx">wcf\system\example</span><span class="p">;</span>
1974 <span class="k">use</span> <span class="nx">wcf\system\event\EventHandler</span><span class="p">;</span>
1975
1976 <span class="k">class</span> <span class="nc">ExampleParser</span> <span class="p">{</span>
1977 <span class="k">public</span> <span class="k">function</span> <span class="nf">parse</span><span class="p">(</span><span class="nv">$text</span><span class="p">)</span> <span class="p">{</span>
1978 <span class="c1">// [some parsing done by default]</span>
1979
1980 <span class="nv">$parameters</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;text&#39;</span> <span class="o">=&gt;</span> <span class="nv">$text</span><span class="p">];</span>
1981 <span class="nx">EventHandler</span><span class="o">::</span><span class="na">getInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">fireAction</span><span class="p">(</span><span class="nv">$this</span><span class="p">,</span> <span class="s1">&#39;parse&#39;</span><span class="p">,</span> <span class="nv">$parameters</span><span class="p">);</span>
1982
1983 <span class="k">return</span> <span class="nv">$parameters</span><span class="p">[</span><span class="s1">&#39;text&#39;</span><span class="p">];</span>
1984 <span class="p">}</span>
1985 <span class="p">}</span>
1986 </code></pre></div>
1987 <p>After the default parsing by the method itself, the author wants to enable plugins to do additional parsing and thus fires an event and passes the parsed text as an additional parameter.
1988 Then, a plugin can deliver the following event listener</p>
1989 <div class="highlight"><pre><span></span><code><span class="o">&lt;?</span><span class="nx">php</span>
1990 <span class="k">namespace</span> <span class="nx">wcf\system\event\listener</span><span class="p">;</span>
1991
1992 <span class="k">class</span> <span class="nc">ExampleParserEventListener</span> <span class="k">implements</span> <span class="nx">IParameterizedEventListener</span> <span class="p">{</span>
1993 <span class="k">public</span> <span class="k">function</span> <span class="nf">execute</span><span class="p">(</span><span class="nv">$eventObj</span><span class="p">,</span> <span class="nv">$className</span><span class="p">,</span> <span class="nv">$eventName</span><span class="p">,</span> <span class="k">array</span> <span class="o">&amp;</span><span class="nv">$parameters</span><span class="p">)</span> <span class="p">{</span>
1994 <span class="nv">$text</span> <span class="o">=</span> <span class="nv">$parameters</span><span class="p">[</span><span class="s1">&#39;text&#39;</span><span class="p">];</span>
1995
1996 <span class="c1">// [some additional parsing which changes $text]</span>
1997
1998 <span class="nv">$parameters</span><span class="p">[</span><span class="s1">&#39;text&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$text</span><span class="p">;</span>
1999 <span class="p">}</span>
2000 <span class="p">}</span>
2001 </code></pre></div>
2002 <p>which can access the text via <code>$parameters['text']</code>.</p>
2003 <p>This example can also be perfectly used to illustrate how to name multiple events in the same method.
2004 Let's assume that the author wants to enable plugins to change the text before and after the method does its own parsing and thus fires two events:</p>
2005 <div class="highlight"><pre><span></span><code><span class="o">&lt;?</span><span class="nx">php</span>
2006 <span class="k">namespace</span> <span class="nx">wcf\system\example</span><span class="p">;</span>
2007 <span class="k">use</span> <span class="nx">wcf\system\event\EventHandler</span><span class="p">;</span>
2008
2009 <span class="k">class</span> <span class="nc">ExampleParser</span> <span class="p">{</span>
2010 <span class="k">public</span> <span class="k">function</span> <span class="nf">parse</span><span class="p">(</span><span class="nv">$text</span><span class="p">)</span> <span class="p">{</span>
2011 <span class="nv">$parameters</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;text&#39;</span> <span class="o">=&gt;</span> <span class="nv">$text</span><span class="p">];</span>
2012 <span class="nx">EventHandler</span><span class="o">::</span><span class="na">getInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">fireAction</span><span class="p">(</span><span class="nv">$this</span><span class="p">,</span> <span class="s1">&#39;beforeParsing&#39;</span><span class="p">,</span> <span class="nv">$parameters</span><span class="p">);</span>
2013 <span class="nv">$text</span> <span class="o">=</span> <span class="nv">$parameters</span><span class="p">[</span><span class="s1">&#39;text&#39;</span><span class="p">];</span>
2014
2015 <span class="c1">// [some parsing done by default]</span>
2016
2017 <span class="nv">$parameters</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;text&#39;</span> <span class="o">=&gt;</span> <span class="nv">$text</span><span class="p">];</span>
2018 <span class="nx">EventHandler</span><span class="o">::</span><span class="na">getInstance</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">fireAction</span><span class="p">(</span><span class="nv">$this</span><span class="p">,</span> <span class="s1">&#39;afterParsing&#39;</span><span class="p">,</span> <span class="nv">$parameters</span><span class="p">);</span>
2019
2020 <span class="k">return</span> <span class="nv">$parameters</span><span class="p">[</span><span class="s1">&#39;text&#39;</span><span class="p">];</span>
2021 <span class="p">}</span>
2022 <span class="p">}</span>
2023 </code></pre></div>
2024 <h2 id="advanced-example-additional-form-field">Advanced Example: Additional Form Field<a class="headerlink" href="#advanced-example-additional-form-field" title="Permanent link">#</a></h2>
2025 <p>One common reason to use event listeners is to add an additional field to a pre-existing form (in combination with template listeners, which we will not cover here).
2026 We will assume that users are able to do both, create and edit the objects via this form.
2027 The points in the program flow of <a href="../../pages/#abstractform">AbstractForm</a> that are relevant here are:</p>
2028 <ul>
2029 <li>adding object (after the form has been submitted):</li>
2030 <li>reading the value of the field</li>
2031 <li>validating the read value</li>
2032 <li>
2033 <p>saving the additional value after successful validation and resetting locally stored value or assigning the current value of the field to the template after unsuccessful validation</p>
2034 </li>
2035 <li>
2036 <p>editing object:</p>
2037 </li>
2038 <li>on initial form request:<ol>
2039 <li>reading the pre-existing value of the edited object</li>
2040 <li>assigning the field value to the template</li>
2041 </ol>
2042 </li>
2043 <li>after the form has been submitted:<ol>
2044 <li>reading the value of the field</li>
2045 <li>validating the read value</li>
2046 <li>saving the additional value after successful validation</li>
2047 <li>assigning the current value of the field to the template</li>
2048 </ol>
2049 </li>
2050 </ul>
2051 <p>All of these cases can be covered the by following code in which we assume that <code>wcf\form\ExampleAddForm</code> is the form to create example objects and that <code>wcf\form\ExampleEditForm</code> extends <code>wcf\form\ExampleAddForm</code> and is used for editing existing example objects.</p>
2052 <div class="highlight"><pre><span></span><code><span class="o">&lt;?</span><span class="nx">php</span>
2053 <span class="k">namespace</span> <span class="nx">wcf\system\event\listener</span><span class="p">;</span>
2054 <span class="k">use</span> <span class="nx">wcf\form\ExampleAddForm</span><span class="p">;</span>
2055 <span class="k">use</span> <span class="nx">wcf\form\ExampleEditForm</span><span class="p">;</span>
2056 <span class="k">use</span> <span class="nx">wcf\system\exception\UserInputException</span><span class="p">;</span>
2057 <span class="k">use</span> <span class="nx">wcf\system\WCF</span><span class="p">;</span>
2058
2059 <span class="k">class</span> <span class="nc">ExampleAddFormListener</span> <span class="k">implements</span> <span class="nx">IParameterizedEventListener</span> <span class="p">{</span>
2060 <span class="k">protected</span> <span class="nv">$var</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
2061
2062 <span class="k">public</span> <span class="k">function</span> <span class="nf">execute</span><span class="p">(</span><span class="nv">$eventObj</span><span class="p">,</span> <span class="nv">$className</span><span class="p">,</span> <span class="nv">$eventName</span><span class="p">,</span> <span class="k">array</span> <span class="o">&amp;</span><span class="nv">$parameters</span><span class="p">)</span> <span class="p">{</span>
2063 <span class="nv">$this</span><span class="o">-&gt;</span><span class="nv">$eventName</span><span class="p">(</span><span class="nv">$eventObj</span><span class="p">);</span>
2064 <span class="p">}</span>
2065
2066 <span class="k">protected</span> <span class="k">function</span> <span class="nf">assignVariables</span><span class="p">()</span> <span class="p">{</span>
2067 <span class="nx">WCF</span><span class="o">::</span><span class="na">getTPL</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">assign</span><span class="p">(</span><span class="s1">&#39;var&#39;</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">var</span><span class="p">);</span>
2068 <span class="p">}</span>
2069
2070 <span class="k">protected</span> <span class="k">function</span> <span class="nf">readData</span><span class="p">(</span><span class="nx">ExampleEditForm</span> <span class="nv">$eventObj</span><span class="p">)</span> <span class="p">{</span>
2071 <span class="k">if</span> <span class="p">(</span><span class="k">empty</span><span class="p">(</span><span class="nv">$_POST</span><span class="p">))</span> <span class="p">{</span>
2072 <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">var</span> <span class="o">=</span> <span class="nv">$eventObj</span><span class="o">-&gt;</span><span class="na">example</span><span class="o">-&gt;</span><span class="na">var</span><span class="p">;</span>
2073 <span class="p">}</span>
2074 <span class="p">}</span>
2075
2076 <span class="k">protected</span> <span class="k">function</span> <span class="nf">readFormParameters</span><span class="p">()</span> <span class="p">{</span>
2077 <span class="k">if</span> <span class="p">(</span><span class="nb">isset</span><span class="p">(</span><span class="nv">$_POST</span><span class="p">[</span><span class="s1">&#39;var&#39;</span><span class="p">]))</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">var</span> <span class="o">=</span> <span class="nb">intval</span><span class="p">(</span><span class="nv">$_POST</span><span class="p">[</span><span class="s1">&#39;var&#39;</span><span class="p">]);</span>
2078 <span class="p">}</span>
2079
2080 <span class="k">protected</span> <span class="k">function</span> <span class="nf">save</span><span class="p">(</span><span class="nx">ExampleAddForm</span> <span class="nv">$eventObj</span><span class="p">)</span> <span class="p">{</span>
2081 <span class="nv">$eventObj</span><span class="o">-&gt;</span><span class="na">additionalFields</span> <span class="o">=</span> <span class="nb">array_merge</span><span class="p">(</span><span class="nv">$eventObj</span><span class="o">-&gt;</span><span class="na">additionalFields</span><span class="p">,</span> <span class="p">[</span><span class="s1">&#39;var&#39;</span> <span class="o">=&gt;</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">var</span><span class="p">]);</span>
2082 <span class="p">}</span>
2083
2084 <span class="k">protected</span> <span class="k">function</span> <span class="nf">saved</span><span class="p">()</span> <span class="p">{</span>
2085 <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">var</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
2086 <span class="p">}</span>
2087
2088 <span class="k">protected</span> <span class="k">function</span> <span class="nf">validate</span><span class="p">()</span> <span class="p">{</span>
2089 <span class="k">if</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">var</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
2090 <span class="k">throw</span> <span class="k">new</span> <span class="nx">UserInputException</span><span class="p">(</span><span class="s1">&#39;var&#39;</span><span class="p">,</span> <span class="s1">&#39;isNegative&#39;</span><span class="p">);</span>
2091 <span class="p">}</span>
2092 <span class="p">}</span>
2093 <span class="p">}</span>
2094 </code></pre></div>
2095 <p>The <code>execute</code> method in this example just delegates the call to a method with the same name as the event so that this class mimics the structure of a form class itself.
2096 The form object is passed to the methods but is only given in the method signatures as a parameter here whenever the form object is actually used.
2097 Furthermore, the type-hinting of the parameter illustrates in which contexts the method is actually called which will become clear in the following discussion of the individual methods:</p>
2098 <ul>
2099 <li><code>assignVariables()</code> is called for the add and the edit form and simply assigns the current value of the variable to the template.</li>
2100 <li><code>readData()</code> reads the pre-existing value of <code>$var</code> if the form has not been submitted and thus is only relevant when editing objects which is illustrated by the explicit type-hint of <code>ExampleEditForm</code>.</li>
2101 <li><code>readFormParameters()</code> reads the value for both, the add and the edit form.</li>
2102 <li><code>save()</code> is, of course, also relevant in both cases but requires the form object to store the additional value in the <code>wcf\form\AbstractForm::$additionalFields</code> array which can be used if a <code>var</code> column has been added to the database table in which the example objects are stored.</li>
2103 <li><code>saved()</code> is only called for the add form as it clears the internal value so that in the <code>assignVariables()</code> call, the default value will be assigned to the template to create an "empty" form.
2104 During edits, this current value is the actual value that should be shown.</li>
2105 <li><code>validate()</code> also needs to be called in both cases as the input data always has to be validated.</li>
2106 </ul>
2107 <p>Lastly, the following XML file has to be used to register the event listeners (you can find more information about how to register event listeners on <a href="../../../package/pip/event-listener/">the eventListener package installation plugin page</a>):</p>
2108 <div class="highlight"><pre><span></span><code><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
2109 <span class="nt">&lt;data</span> <span class="na">xmlns=</span><span class="s">&quot;http://www.woltlab.com&quot;</span> <span class="na">xmlns:xsi=</span><span class="s">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span> <span class="na">xsi:schemaLocation=</span><span class="s">&quot;http://www.woltlab.com http://www.woltlab.com/XSD/2019/eventListener.xsd&quot;</span><span class="nt">&gt;</span>
2110 <span class="nt">&lt;import&gt;</span>
2111 <span class="nt">&lt;eventlistener</span> <span class="na">name=</span><span class="s">&quot;exampleAddInherited&quot;</span><span class="nt">&gt;</span>
2112 <span class="nt">&lt;eventclassname&gt;</span>wcf\form\ExampleAddForm<span class="nt">&lt;/eventclassname&gt;</span>
2113 <span class="nt">&lt;eventname&gt;</span>assignVariables,readFormParameters,save,validate<span class="nt">&lt;/eventname&gt;</span>
2114 <span class="nt">&lt;listenerclassname&gt;</span>wcf\system\event\listener\ExampleAddFormListener<span class="nt">&lt;/listenerclassname&gt;</span>
2115 <span class="nt">&lt;inherit&gt;</span>1<span class="nt">&lt;/inherit&gt;</span>
2116 <span class="nt">&lt;/eventlistener&gt;</span>
2117
2118 <span class="nt">&lt;eventlistener</span> <span class="na">name=</span><span class="s">&quot;exampleAdd&quot;</span><span class="nt">&gt;</span>
2119 <span class="nt">&lt;eventclassname&gt;</span>wcf\form\ExampleAddForm<span class="nt">&lt;/eventclassname&gt;</span>
2120 <span class="nt">&lt;eventname&gt;</span>saved<span class="nt">&lt;/eventname&gt;</span>
2121 <span class="nt">&lt;listenerclassname&gt;</span>wcf\system\event\listener\ExampleAddFormListener<span class="nt">&lt;/listenerclassname&gt;</span>
2122 <span class="nt">&lt;/eventlistener&gt;</span>
2123
2124 <span class="nt">&lt;eventlistener</span> <span class="na">name=</span><span class="s">&quot;exampleEdit&quot;</span><span class="nt">&gt;</span>
2125 <span class="nt">&lt;eventclassname&gt;</span>wcf\form\ExampleEditForm<span class="nt">&lt;/eventclassname&gt;</span>
2126 <span class="nt">&lt;eventname&gt;</span>readData<span class="nt">&lt;/eventname&gt;</span>
2127 <span class="nt">&lt;listenerclassname&gt;</span>wcf\system\event\listener\ExampleAddFormListener<span class="nt">&lt;/listenerclassname&gt;</span>
2128 <span class="nt">&lt;/eventlistener&gt;</span>
2129 <span class="nt">&lt;/import&gt;</span>
2130 <span class="nt">&lt;/data&gt;</span>
2131 </code></pre></div>
2132
2133
2134
2135
2136 <hr>
2137 <div class="md-source-date">
2138 <small>
2139
2140 Last update: 2021-01-08
2141
2142 </small>
2143 </div>
2144
2145
2146
2147
2148
2149
2150
2151
2152 </article>
2153 </div>
2154 </div>
2155 </main>
2156
2157
2158 <footer class="md-footer">
2159
2160 <nav class="md-footer__inner md-grid" aria-label="Footer">
2161
2162 <a href="../cronjobs/" class="md-footer__link md-footer__link--prev" rel="prev">
2163 <div class="md-footer__button md-icon">
2164 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
2165 </div>
2166 <div class="md-footer__title">
2167 <div class="md-ellipsis">
2168 <span class="md-footer__direction">
2169 Previous
2170 </span>
2171 Cronjobs
2172 </div>
2173 </div>
2174 </a>
2175
2176
2177 <a href="../form_builder/overview/" class="md-footer__link md-footer__link--next" rel="next">
2178 <div class="md-footer__title">
2179 <div class="md-ellipsis">
2180 <span class="md-footer__direction">
2181 Next
2182 </span>
2183 Overview
2184 </div>
2185 </div>
2186 <div class="md-footer__button md-icon">
2187 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11H4z"/></svg>
2188 </div>
2189 </a>
2190
2191 </nav>
2192
2193 <div class="md-footer-meta md-typeset">
2194 <div class="md-footer-meta__inner md-grid">
2195 <div class="md-footer-copyright">
2196
2197 <div class="md-footer-copyright__highlight">
2198 Copyright © 2020 WoltLab GmbH
2199 </div>
2200
2201 Made with
2202 <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
2203 Material for MkDocs
2204 </a>
2205
2206 </div>
2207 <div class="md-footer-copyright">
2208 <a href="https://www.woltlab.com/legal-notice/">Legal Notice</a>
2209 <a href="https://www.woltlab.com/privacy-policy/">Privacy Policy</a>
2210 </div>
2211 </div>
2212 </div>
2213 </footer>
2214
2215 </div>
2216 <div class="md-dialog" data-md-component="dialog">
2217 <div class="md-dialog__inner md-typeset"></div>
2218 </div>
2219 <script id="__config" type="application/json">{"base": "../../..", "features": [], "translations": {"clipboard.copy": "Copy to clipboard", "clipboard.copied": "Copied to clipboard", "search.config.lang": "en", "search.config.pipeline": "trimmer, stopWordFilter", "search.config.separator": "[\\s\\-]+", "search.placeholder": "Search", "search.result.placeholder": "Type to start searching", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.term.missing": "Missing"}, "search": "../../../assets/javascripts/workers/search.fb4a9340.min.js", "version": {"provider": "mike"}}</script>
2220
2221
2222 <script src="../../../assets/javascripts/bundle.5cf3e710.min.js"></script>
2223
2224
2225 </body>
2226 </html>