3 <html lang=
"en" class=
"no-js">
7 <meta name=
"viewport" content=
"width=device-width,initial-scale=1">
12 <link rel=
"icon" href=
"../../../assets/default.favicon.ico">
13 <meta name=
"generator" content=
"mkdocs-1.1.2, mkdocs-material-7.1.0">
17 <title>User Notifications - WoltLab Suite Documentation
</title>
21 <link rel=
"stylesheet" href=
"../../../assets/stylesheets/main.33e2939f.min.css">
24 <link rel=
"stylesheet" href=
"../../../assets/stylesheets/palette.ef6f36e2.min.css">
28 <meta name=
"theme-color" content=
"#009485">
38 <link rel=
"stylesheet" href=
"../../../stylesheets/extra.css">
52 <body dir=
"ltr" data-md-color-scheme=
"" data-md-color-primary=
"teal" data-md-color-accent=
"">
55 <script>function __prefix(e){return new URL(
"../../..",location).pathname+
"."+e}function __get(e,t=localStorage){return JSON.parse(t.getItem(__prefix(e)))}
</script>
57 <input class=
"md-toggle" data-md-toggle=
"drawer" type=
"checkbox" id=
"__drawer" autocomplete=
"off">
58 <input class=
"md-toggle" data-md-toggle=
"search" type=
"checkbox" id=
"__search" autocomplete=
"off">
59 <label class=
"md-overlay" for=
"__drawer"></label>
60 <div data-md-component=
"skip">
63 <a href=
"#user-notifications" class=
"md-skip">
68 <div data-md-component=
"announce">
70 <aside class=
"md-announce">
71 <div class=
"md-announce__inner md-grid md-typeset">
73 <a href=
"https://www.woltlab.com">Back to
<strong>woltlab.com
</strong></a>
80 <header class=
"md-header" data-md-component=
"header">
81 <nav class=
"md-header__inner md-grid" aria-label=
"Header">
82 <a href=
"../../.." title=
"WoltLab Suite Documentation" class=
"md-header__button md-logo" aria-label=
"WoltLab Suite Documentation" data-md-component=
"logo">
84 <img src=
"../../../assets/logo.png" alt=
"logo">
87 <label class=
"md-header__button md-icon" for=
"__drawer">
88 <svg xmlns=
"http://www.w3.org/2000/svg" viewBox=
"0 0 24 24"><path d=
"M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2z"/></svg>
90 <div class=
"md-header__title" data-md-component=
"header-title">
91 <div class=
"md-header__ellipsis">
92 <div class=
"md-header__topic">
93 <span class=
"md-ellipsis">
94 WoltLab Suite Documentation
97 <div class=
"md-header__topic" data-md-component=
"header-topic">
98 <span class=
"md-ellipsis">
109 <label class=
"md-header__button md-icon" for=
"__search">
110 <svg xmlns=
"http://www.w3.org/2000/svg" viewBox=
"0 0 24 24"><path d=
"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
113 <div class=
"md-search" data-md-component=
"search" role=
"dialog">
114 <label class=
"md-search__overlay" for=
"__search"></label>
115 <div class=
"md-search__inner" role=
"search">
116 <form class=
"md-search__form" name=
"search">
117 <input type=
"text" class=
"md-search__input" name=
"query" aria-label=
"Search" placeholder=
"Search" autocapitalize=
"off" autocorrect=
"off" autocomplete=
"off" spellcheck=
"false" data-md-component=
"search-query" data-md-state=
"active" required
>
118 <label class=
"md-search__icon md-icon" for=
"__search">
119 <svg xmlns=
"http://www.w3.org/2000/svg" viewBox=
"0 0 24 24"><path d=
"M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
120 <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>
122 <button type=
"reset" class=
"md-search__icon md-icon" aria-label=
"Clear" tabindex=
"-1">
123 <svg xmlns=
"http://www.w3.org/2000/svg" viewBox=
"0 0 24 24"><path d=
"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>
126 <div class=
"md-search__output">
127 <div class=
"md-search__scrollwrap" data-md-scrollfix
>
128 <div class=
"md-search-result" data-md-component=
"search-result">
129 <div class=
"md-search-result__meta">
132 <ol class=
"md-search-result__list"></ol>
140 <div class=
"md-header__source">
142 <a href=
"https://github.com/WoltLab/docs.woltlab.com/" title=
"Go to repository" class=
"md-source" data-md-component=
"source">
143 <div class=
"md-source__icon md-icon">
145 <svg xmlns=
"http://www.w3.org/2000/svg" viewBox=
"0 0 448 512"><path d=
"M439.55 236.05 244 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>
147 <div class=
"md-source__repository">
156 <div class=
"md-container" data-md-component=
"container">
161 <main class=
"md-main" data-md-component=
"main">
162 <div class=
"md-main__inner md-grid">
166 <div class=
"md-sidebar md-sidebar--primary" data-md-component=
"sidebar" data-md-type=
"navigation" >
167 <div class=
"md-sidebar__scrollwrap">
168 <div class=
"md-sidebar__inner">
172 <nav class=
"md-nav md-nav--primary" aria-label=
"Navigation" data-md-level=
"0">
173 <label class=
"md-nav__title" for=
"__drawer">
174 <a href=
"../../.." title=
"WoltLab Suite Documentation" class=
"md-nav__button md-logo" aria-label=
"WoltLab Suite Documentation" data-md-component=
"logo">
176 <img src=
"../../../assets/logo.png" alt=
"logo">
179 WoltLab Suite Documentation
182 <div class=
"md-nav__source">
184 <a href=
"https://github.com/WoltLab/docs.woltlab.com/" title=
"Go to repository" class=
"md-source" data-md-component=
"source">
185 <div class=
"md-source__icon md-icon">
187 <svg xmlns=
"http://www.w3.org/2000/svg" viewBox=
"0 0 448 512"><path d=
"M439.55 236.05 244 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>
189 <div class=
"md-source__repository">
195 <ul class=
"md-nav__list" data-md-scrollfix
>
204 <li class=
"md-nav__item">
205 <a href=
"../../../getting-started/" class=
"md-nav__link">
222 <li class=
"md-nav__item md-nav__item--active md-nav__item--nested">
225 <input class=
"md-nav__toggle md-toggle" data-md-toggle=
"__nav_2" type=
"checkbox" id=
"__nav_2" checked
>
227 <label class=
"md-nav__link" for=
"__nav_2">
229 <span class=
"md-nav__icon md-icon"></span>
231 <nav class=
"md-nav" aria-label=
"PHP API" data-md-level=
"1">
232 <label class=
"md-nav__title" for=
"__nav_2">
233 <span class=
"md-nav__icon md-icon"></span>
236 <ul class=
"md-nav__list" data-md-scrollfix
>
242 <li class=
"md-nav__item">
243 <a href=
"../../pages/" class=
"md-nav__link">
254 <li class=
"md-nav__item">
255 <a href=
"../../database-objects/" class=
"md-nav__link">
266 <li class=
"md-nav__item">
267 <a href=
"../../database-access/" class=
"md-nav__link">
278 <li class=
"md-nav__item">
279 <a href=
"../../exceptions/" class=
"md-nav__link">
293 <li class=
"md-nav__item md-nav__item--active md-nav__item--nested">
296 <input class=
"md-nav__toggle md-toggle" data-md-toggle=
"__nav_2_5" type=
"checkbox" id=
"__nav_2_5" checked
>
298 <label class=
"md-nav__link" for=
"__nav_2_5">
300 <span class=
"md-nav__icon md-icon"></span>
302 <nav class=
"md-nav" aria-label=
"API" data-md-level=
"2">
303 <label class=
"md-nav__title" for=
"__nav_2_5">
304 <span class=
"md-nav__icon md-icon"></span>
307 <ul class=
"md-nav__list" data-md-scrollfix
>
314 <li class=
"md-nav__item md-nav__item--nested">
317 <input class=
"md-nav__toggle md-toggle" data-md-toggle=
"__nav_2_5_1" type=
"checkbox" id=
"__nav_2_5_1" >
319 <label class=
"md-nav__link" for=
"__nav_2_5_1">
321 <span class=
"md-nav__icon md-icon"></span>
323 <nav class=
"md-nav" aria-label=
"Caches" data-md-level=
"3">
324 <label class=
"md-nav__title" for=
"__nav_2_5_1">
325 <span class=
"md-nav__icon md-icon"></span>
328 <ul class=
"md-nav__list" data-md-scrollfix
>
334 <li class=
"md-nav__item">
335 <a href=
"../caches/" class=
"md-nav__link">
346 <li class=
"md-nav__item">
347 <a href=
"../caches_persistent-caches/" class=
"md-nav__link">
358 <li class=
"md-nav__item">
359 <a href=
"../caches_runtime-caches/" class=
"md-nav__link">
376 <li class=
"md-nav__item">
377 <a href=
"../comments/" class=
"md-nav__link">
388 <li class=
"md-nav__item">
389 <a href=
"../cronjobs/" class=
"md-nav__link">
400 <li class=
"md-nav__item">
401 <a href=
"../events/" class=
"md-nav__link">
413 <li class=
"md-nav__item md-nav__item--nested">
416 <input class=
"md-nav__toggle md-toggle" data-md-toggle=
"__nav_2_5_5" type=
"checkbox" id=
"__nav_2_5_5" >
418 <label class=
"md-nav__link" for=
"__nav_2_5_5">
420 <span class=
"md-nav__icon md-icon"></span>
422 <nav class=
"md-nav" aria-label=
"Form Builder" data-md-level=
"3">
423 <label class=
"md-nav__title" for=
"__nav_2_5_5">
424 <span class=
"md-nav__icon md-icon"></span>
427 <ul class=
"md-nav__list" data-md-scrollfix
>
433 <li class=
"md-nav__item">
434 <a href=
"../form_builder/overview/" class=
"md-nav__link">
445 <li class=
"md-nav__item">
446 <a href=
"../form_builder/structure/" class=
"md-nav__link">
457 <li class=
"md-nav__item">
458 <a href=
"../form_builder/form_fields/" class=
"md-nav__link">
469 <li class=
"md-nav__item">
470 <a href=
"../form_builder/validation_data/" class=
"md-nav__link">
481 <li class=
"md-nav__item">
482 <a href=
"../form_builder/dependencies/" class=
"md-nav__link">
499 <li class=
"md-nav__item">
500 <a href=
"../package_installation_plugins/" class=
"md-nav__link">
501 Package Installation Plugins
511 <li class=
"md-nav__item">
512 <a href=
"../user_activity_points/" class=
"md-nav__link">
525 <li class=
"md-nav__item md-nav__item--active">
527 <input class=
"md-nav__toggle md-toggle" data-md-toggle=
"toc" type=
"checkbox" id=
"__toc">
532 <label class=
"md-nav__link md-nav__link--active" for=
"__toc">
534 <span class=
"md-nav__icon md-icon"></span>
537 <a href=
"./" class=
"md-nav__link md-nav__link--active">
542 <nav class=
"md-nav md-nav--secondary" aria-label=
"Table of contents">
548 <label class=
"md-nav__title" for=
"__toc">
549 <span class=
"md-nav__icon md-icon"></span>
552 <ul class=
"md-nav__list" data-md-component=
"toc" data-md-scrollfix
>
554 <li class=
"md-nav__item">
555 <a href=
"#objecttypexml" class=
"md-nav__link">
561 <li class=
"md-nav__item">
562 <a href=
"#usernotificationeventxml" class=
"md-nav__link">
563 userNotificationEvent.xml
568 <li class=
"md-nav__item">
569 <a href=
"#firing-events" class=
"md-nav__link">
575 <li class=
"md-nav__item">
576 <a href=
"#marking-notifications-as-confirmed" class=
"md-nav__link">
577 Marking Notifications as Confirmed
594 <li class=
"md-nav__item">
595 <a href=
"../sitemaps/" class=
"md-nav__link">
612 <li class=
"md-nav__item">
613 <a href=
"../../code-style/" class=
"md-nav__link">
624 <li class=
"md-nav__item">
625 <a href=
"../../apps/" class=
"md-nav__link">
636 <li class=
"md-nav__item">
637 <a href=
"../../gdpr/" class=
"md-nav__link">
658 <li class=
"md-nav__item md-nav__item--nested">
661 <input class=
"md-nav__toggle md-toggle" data-md-toggle=
"__nav_3" type=
"checkbox" id=
"__nav_3" >
663 <label class=
"md-nav__link" for=
"__nav_3">
664 Languages, Templates & CSS
665 <span class=
"md-nav__icon md-icon"></span>
667 <nav class=
"md-nav" aria-label=
"Languages, Templates & CSS" data-md-level=
"1">
668 <label class=
"md-nav__title" for=
"__nav_3">
669 <span class=
"md-nav__icon md-icon"></span>
670 Languages, Templates & CSS
672 <ul class=
"md-nav__list" data-md-scrollfix
>
678 <li class=
"md-nav__item">
679 <a href=
"../../../view/languages/" class=
"md-nav__link">
690 <li class=
"md-nav__item">
691 <a href=
"../../../view/templates/" class=
"md-nav__link">
702 <li class=
"md-nav__item">
703 <a href=
"../../../view/template-plugins/" class=
"md-nav__link">
714 <li class=
"md-nav__item">
715 <a href=
"../../../view/css/" class=
"md-nav__link">
736 <li class=
"md-nav__item md-nav__item--nested">
739 <input class=
"md-nav__toggle md-toggle" data-md-toggle=
"__nav_4" type=
"checkbox" id=
"__nav_4" >
741 <label class=
"md-nav__link" for=
"__nav_4">
742 TypeScript and JavaScript API
743 <span class=
"md-nav__icon md-icon"></span>
745 <nav class=
"md-nav" aria-label=
"TypeScript and JavaScript API" data-md-level=
"1">
746 <label class=
"md-nav__title" for=
"__nav_4">
747 <span class=
"md-nav__icon md-icon"></span>
748 TypeScript and JavaScript API
750 <ul class=
"md-nav__list" data-md-scrollfix
>
756 <li class=
"md-nav__item">
757 <a href=
"../../../javascript/general-usage/" class=
"md-nav__link">
768 <li class=
"md-nav__item">
769 <a href=
"../../../javascript/typescript/" class=
"md-nav__link">
781 <li class=
"md-nav__item md-nav__item--nested">
784 <input class=
"md-nav__toggle md-toggle" data-md-toggle=
"__nav_4_3" type=
"checkbox" id=
"__nav_4_3" >
786 <label class=
"md-nav__link" for=
"__nav_4_3">
788 <span class=
"md-nav__icon md-icon"></span>
790 <nav class=
"md-nav" aria-label=
"New API" data-md-level=
"2">
791 <label class=
"md-nav__title" for=
"__nav_4_3">
792 <span class=
"md-nav__icon md-icon"></span>
795 <ul class=
"md-nav__list" data-md-scrollfix
>
801 <li class=
"md-nav__item">
802 <a href=
"../../../javascript/new-api_writing-a-module/" class=
"md-nav__link">
813 <li class=
"md-nav__item">
814 <a href=
"../../../javascript/new-api_data-structures/" class=
"md-nav__link">
825 <li class=
"md-nav__item">
826 <a href=
"../../../javascript/new-api_core/" class=
"md-nav__link">
837 <li class=
"md-nav__item">
838 <a href=
"../../../javascript/new-api_dom/" class=
"md-nav__link">
849 <li class=
"md-nav__item">
850 <a href=
"../../../javascript/new-api_events/" class=
"md-nav__link">
861 <li class=
"md-nav__item">
862 <a href=
"../../../javascript/new-api_ajax/" class=
"md-nav__link">
873 <li class=
"md-nav__item">
874 <a href=
"../../../javascript/new-api_dialogs/" class=
"md-nav__link">
885 <li class=
"md-nav__item">
886 <a href=
"../../../javascript/new-api_browser/" class=
"md-nav__link">
887 Browser and Screen Sizes
897 <li class=
"md-nav__item">
898 <a href=
"../../../javascript/new-api_ui/" class=
"md-nav__link">
915 <li class=
"md-nav__item">
916 <a href=
"../../../javascript/legacy-api/" class=
"md-nav__link">
927 <li class=
"md-nav__item">
928 <a href=
"../../../javascript/helper-functions/" class=
"md-nav__link">
939 <li class=
"md-nav__item">
940 <a href=
"../../../javascript/code-snippets/" class=
"md-nav__link">
961 <li class=
"md-nav__item md-nav__item--nested">
964 <input class=
"md-nav__toggle md-toggle" data-md-toggle=
"__nav_5" type=
"checkbox" id=
"__nav_5" >
966 <label class=
"md-nav__link" for=
"__nav_5">
968 <span class=
"md-nav__icon md-icon"></span>
970 <nav class=
"md-nav" aria-label=
"Package Components" data-md-level=
"1">
971 <label class=
"md-nav__title" for=
"__nav_5">
972 <span class=
"md-nav__icon md-icon"></span>
975 <ul class=
"md-nav__list" data-md-scrollfix
>
981 <li class=
"md-nav__item">
982 <a href=
"../../../package/package-xml/" class=
"md-nav__link">
994 <li class=
"md-nav__item md-nav__item--nested">
997 <input class=
"md-nav__toggle md-toggle" data-md-toggle=
"__nav_5_2" type=
"checkbox" id=
"__nav_5_2" >
999 <label class=
"md-nav__link" for=
"__nav_5_2">
1001 <span class=
"md-nav__icon md-icon"></span>
1003 <nav class=
"md-nav" aria-label=
"PIPs" data-md-level=
"2">
1004 <label class=
"md-nav__title" for=
"__nav_5_2">
1005 <span class=
"md-nav__icon md-icon"></span>
1008 <ul class=
"md-nav__list" data-md-scrollfix
>
1014 <li class=
"md-nav__item">
1015 <a href=
"../../../package/pip/" class=
"md-nav__link">
1026 <li class=
"md-nav__item">
1027 <a href=
"../../../package/pip/acl-option/" class=
"md-nav__link">
1038 <li class=
"md-nav__item">
1039 <a href=
"../../../package/pip/acp-menu/" class=
"md-nav__link">
1050 <li class=
"md-nav__item">
1051 <a href=
"../../../package/pip/acp-search-provider/" class=
"md-nav__link">
1062 <li class=
"md-nav__item">
1063 <a href=
"../../../package/pip/acp-template/" class=
"md-nav__link">
1074 <li class=
"md-nav__item">
1075 <a href=
"../../../package/pip/bbcode/" class=
"md-nav__link">
1086 <li class=
"md-nav__item">
1087 <a href=
"../../../package/pip/box/" class=
"md-nav__link">
1098 <li class=
"md-nav__item">
1099 <a href=
"../../../package/pip/clipboard-action/" class=
"md-nav__link">
1110 <li class=
"md-nav__item">
1111 <a href=
"../../../package/pip/core-object/" class=
"md-nav__link">
1122 <li class=
"md-nav__item">
1123 <a href=
"../../../package/pip/cronjob/" class=
"md-nav__link">
1134 <li class=
"md-nav__item">
1135 <a href=
"../../../package/pip/database/" class=
"md-nav__link">
1146 <li class=
"md-nav__item">
1147 <a href=
"../../../package/pip/event-listener/" class=
"md-nav__link">
1158 <li class=
"md-nav__item">
1159 <a href=
"../../../package/pip/file/" class=
"md-nav__link">
1170 <li class=
"md-nav__item">
1171 <a href=
"../../../package/pip/language/" class=
"md-nav__link">
1182 <li class=
"md-nav__item">
1183 <a href=
"../../../package/pip/media-provider/" class=
"md-nav__link">
1194 <li class=
"md-nav__item">
1195 <a href=
"../../../package/pip/menu/" class=
"md-nav__link">
1206 <li class=
"md-nav__item">
1207 <a href=
"../../../package/pip/menu-item/" class=
"md-nav__link">
1218 <li class=
"md-nav__item">
1219 <a href=
"../../../package/pip/object-type/" class=
"md-nav__link">
1230 <li class=
"md-nav__item">
1231 <a href=
"../../../package/pip/object-type-definition/" class=
"md-nav__link">
1232 objectTypeDefinition
1242 <li class=
"md-nav__item">
1243 <a href=
"../../../package/pip/option/" class=
"md-nav__link">
1254 <li class=
"md-nav__item">
1255 <a href=
"../../../package/pip/page/" class=
"md-nav__link">
1266 <li class=
"md-nav__item">
1267 <a href=
"../../../package/pip/pip/" class=
"md-nav__link">
1278 <li class=
"md-nav__item">
1279 <a href=
"../../../package/pip/script/" class=
"md-nav__link">
1290 <li class=
"md-nav__item">
1291 <a href=
"../../../package/pip/smiley/" class=
"md-nav__link">
1302 <li class=
"md-nav__item">
1303 <a href=
"../../../package/pip/sql/" class=
"md-nav__link">
1314 <li class=
"md-nav__item">
1315 <a href=
"../../../package/pip/style/" class=
"md-nav__link">
1326 <li class=
"md-nav__item">
1327 <a href=
"../../../package/pip/template/" class=
"md-nav__link">
1338 <li class=
"md-nav__item">
1339 <a href=
"../../../package/pip/template-listener/" class=
"md-nav__link">
1350 <li class=
"md-nav__item">
1351 <a href=
"../../../package/pip/user-group-option/" class=
"md-nav__link">
1362 <li class=
"md-nav__item">
1363 <a href=
"../../../package/pip/user-menu/" class=
"md-nav__link">
1374 <li class=
"md-nav__item">
1375 <a href=
"../../../package/pip/user-notification-event/" class=
"md-nav__link">
1376 userNotificationEvent
1386 <li class=
"md-nav__item">
1387 <a href=
"../../../package/pip/user-option/" class=
"md-nav__link">
1398 <li class=
"md-nav__item">
1399 <a href=
"../../../package/pip/user-profile-menu/" class=
"md-nav__link">
1416 <li class=
"md-nav__item">
1417 <a href=
"../../../package/database-php-api/" class=
"md-nav__link">
1438 <li class=
"md-nav__item md-nav__item--nested">
1441 <input class=
"md-nav__toggle md-toggle" data-md-toggle=
"__nav_6" type=
"checkbox" id=
"__nav_6" >
1443 <label class=
"md-nav__link" for=
"__nav_6">
1445 <span class=
"md-nav__icon md-icon"></span>
1447 <nav class=
"md-nav" aria-label=
"Migration" data-md-level=
"1">
1448 <label class=
"md-nav__title" for=
"__nav_6">
1449 <span class=
"md-nav__icon md-icon"></span>
1452 <ul class=
"md-nav__list" data-md-scrollfix
>
1459 <li class=
"md-nav__item md-nav__item--nested">
1462 <input class=
"md-nav__toggle md-toggle" data-md-toggle=
"__nav_6_1" type=
"checkbox" id=
"__nav_6_1" >
1464 <label class=
"md-nav__link" for=
"__nav_6_1">
1465 Migrating from WSC
5.3
1466 <span class=
"md-nav__icon md-icon"></span>
1468 <nav class=
"md-nav" aria-label=
"Migrating from WSC 5.3" data-md-level=
"2">
1469 <label class=
"md-nav__title" for=
"__nav_6_1">
1470 <span class=
"md-nav__icon md-icon"></span>
1471 Migrating from WSC
5.3
1473 <ul class=
"md-nav__list" data-md-scrollfix
>
1479 <li class=
"md-nav__item">
1480 <a href=
"../../../migration/wsc53/php/" class=
"md-nav__link">
1491 <li class=
"md-nav__item">
1492 <a href=
"../../../migration/wsc53/session/" class=
"md-nav__link">
1493 Session Handling and Authentication
1503 <li class=
"md-nav__item">
1504 <a href=
"../../../migration/wsc53/javascript/" class=
"md-nav__link">
1505 TypeScript and JavaScript
1515 <li class=
"md-nav__item">
1516 <a href=
"../../../migration/wsc53/templates/" class=
"md-nav__link">
1527 <li class=
"md-nav__item">
1528 <a href=
"../../../migration/wsc53/libraries/" class=
"md-nav__link">
1529 Third Party Libraries
1546 <li class=
"md-nav__item md-nav__item--nested">
1549 <input class=
"md-nav__toggle md-toggle" data-md-toggle=
"__nav_6_2" type=
"checkbox" id=
"__nav_6_2" >
1551 <label class=
"md-nav__link" for=
"__nav_6_2">
1552 Migrating from WSC
5.2
1553 <span class=
"md-nav__icon md-icon"></span>
1555 <nav class=
"md-nav" aria-label=
"Migrating from WSC 5.2" data-md-level=
"2">
1556 <label class=
"md-nav__title" for=
"__nav_6_2">
1557 <span class=
"md-nav__icon md-icon"></span>
1558 Migrating from WSC
5.2
1560 <ul class=
"md-nav__list" data-md-scrollfix
>
1566 <li class=
"md-nav__item">
1567 <a href=
"../../../migration/wsc52/php/" class=
"md-nav__link">
1578 <li class=
"md-nav__item">
1579 <a href=
"../../../migration/wsc52/templates/" class=
"md-nav__link">
1580 Templates and Languages
1590 <li class=
"md-nav__item">
1591 <a href=
"../../../migration/wsc52/libraries/" class=
"md-nav__link">
1592 Third Party Libraries
1609 <li class=
"md-nav__item md-nav__item--nested">
1612 <input class=
"md-nav__toggle md-toggle" data-md-toggle=
"__nav_6_3" type=
"checkbox" id=
"__nav_6_3" >
1614 <label class=
"md-nav__link" for=
"__nav_6_3">
1615 Migrating from WSC
3.1
1616 <span class=
"md-nav__icon md-icon"></span>
1618 <nav class=
"md-nav" aria-label=
"Migrating from WSC 3.1" data-md-level=
"2">
1619 <label class=
"md-nav__title" for=
"__nav_6_3">
1620 <span class=
"md-nav__icon md-icon"></span>
1621 Migrating from WSC
3.1
1623 <ul class=
"md-nav__list" data-md-scrollfix
>
1629 <li class=
"md-nav__item">
1630 <a href=
"../../../migration/wsc31/php/" class=
"md-nav__link">
1648 <li class=
"md-nav__item md-nav__item--nested">
1651 <input class=
"md-nav__toggle md-toggle" data-md-toggle=
"__nav_6_4" type=
"checkbox" id=
"__nav_6_4" >
1653 <label class=
"md-nav__link" for=
"__nav_6_4">
1654 Migrating from WSC
3.0
1655 <span class=
"md-nav__icon md-icon"></span>
1657 <nav class=
"md-nav" aria-label=
"Migrating from WSC 3.0" data-md-level=
"2">
1658 <label class=
"md-nav__title" for=
"__nav_6_4">
1659 <span class=
"md-nav__icon md-icon"></span>
1660 Migrating from WSC
3.0
1662 <ul class=
"md-nav__list" data-md-scrollfix
>
1668 <li class=
"md-nav__item">
1669 <a href=
"../../../migration/wsc30/php/" class=
"md-nav__link">
1680 <li class=
"md-nav__item">
1681 <a href=
"../../../migration/wsc30/javascript/" class=
"md-nav__link">
1692 <li class=
"md-nav__item">
1693 <a href=
"../../../migration/wsc30/templates/" class=
"md-nav__link">
1704 <li class=
"md-nav__item">
1705 <a href=
"../../../migration/wsc30/css/" class=
"md-nav__link">
1716 <li class=
"md-nav__item">
1717 <a href=
"../../../migration/wsc30/package/" class=
"md-nav__link">
1735 <li class=
"md-nav__item md-nav__item--nested">
1738 <input class=
"md-nav__toggle md-toggle" data-md-toggle=
"__nav_6_5" type=
"checkbox" id=
"__nav_6_5" >
1740 <label class=
"md-nav__link" for=
"__nav_6_5">
1741 Migrating from WCF
2.1
1742 <span class=
"md-nav__icon md-icon"></span>
1744 <nav class=
"md-nav" aria-label=
"Migrating from WCF 2.1" data-md-level=
"2">
1745 <label class=
"md-nav__title" for=
"__nav_6_5">
1746 <span class=
"md-nav__icon md-icon"></span>
1747 Migrating from WCF
2.1
1749 <ul class=
"md-nav__list" data-md-scrollfix
>
1755 <li class=
"md-nav__item">
1756 <a href=
"../../../migration/wcf21/php/" class=
"md-nav__link">
1767 <li class=
"md-nav__item">
1768 <a href=
"../../../migration/wcf21/templates/" class=
"md-nav__link">
1779 <li class=
"md-nav__item">
1780 <a href=
"../../../migration/wcf21/css/" class=
"md-nav__link">
1791 <li class=
"md-nav__item">
1792 <a href=
"../../../migration/wcf21/package/" class=
"md-nav__link">
1819 <li class=
"md-nav__item md-nav__item--nested">
1822 <input class=
"md-nav__toggle md-toggle" data-md-toggle=
"__nav_7" type=
"checkbox" id=
"__nav_7" >
1824 <label class=
"md-nav__link" for=
"__nav_7">
1826 <span class=
"md-nav__icon md-icon"></span>
1828 <nav class=
"md-nav" aria-label=
"Tutorials" data-md-level=
"1">
1829 <label class=
"md-nav__title" for=
"__nav_7">
1830 <span class=
"md-nav__icon md-icon"></span>
1833 <ul class=
"md-nav__list" data-md-scrollfix
>
1840 <li class=
"md-nav__item md-nav__item--nested">
1843 <input class=
"md-nav__toggle md-toggle" data-md-toggle=
"__nav_7_1" type=
"checkbox" id=
"__nav_7_1" >
1845 <label class=
"md-nav__link" for=
"__nav_7_1">
1847 <span class=
"md-nav__icon md-icon"></span>
1849 <nav class=
"md-nav" aria-label=
"Tutorial Series" data-md-level=
"2">
1850 <label class=
"md-nav__title" for=
"__nav_7_1">
1851 <span class=
"md-nav__icon md-icon"></span>
1854 <ul class=
"md-nav__list" data-md-scrollfix
>
1860 <li class=
"md-nav__item">
1861 <a href=
"../../../tutorial/series/overview/" class=
"md-nav__link">
1872 <li class=
"md-nav__item">
1873 <a href=
"../../../tutorial/series/part_1/" class=
"md-nav__link">
1884 <li class=
"md-nav__item">
1885 <a href=
"../../../tutorial/series/part_2/" class=
"md-nav__link">
1896 <li class=
"md-nav__item">
1897 <a href=
"../../../tutorial/series/part_3/" class=
"md-nav__link">
1924 <div class=
"md-sidebar md-sidebar--secondary" data-md-component=
"sidebar" data-md-type=
"toc" >
1925 <div class=
"md-sidebar__scrollwrap">
1926 <div class=
"md-sidebar__inner">
1928 <nav class=
"md-nav md-nav--secondary" aria-label=
"Table of contents">
1934 <label class=
"md-nav__title" for=
"__toc">
1935 <span class=
"md-nav__icon md-icon"></span>
1938 <ul class=
"md-nav__list" data-md-component=
"toc" data-md-scrollfix
>
1940 <li class=
"md-nav__item">
1941 <a href=
"#objecttypexml" class=
"md-nav__link">
1947 <li class=
"md-nav__item">
1948 <a href=
"#usernotificationeventxml" class=
"md-nav__link">
1949 userNotificationEvent.xml
1954 <li class=
"md-nav__item">
1955 <a href=
"#firing-events" class=
"md-nav__link">
1961 <li class=
"md-nav__item">
1962 <a href=
"#marking-notifications-as-confirmed" class=
"md-nav__link">
1963 Marking Notifications as Confirmed
1976 <div class=
"md-content" data-md-component=
"content">
1977 <article class=
"md-content__inner md-typeset">
1980 <a href=
"https://github.com/WoltLab/docs.woltlab.com/edit/5.4/docs/php/api/user_notifications.md" title=
"Edit this page" class=
"md-content__button md-icon">
1981 <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>
1985 <h1 id=
"user-notifications">User Notifications
<a class=
"headerlink" href=
"#user-notifications" title=
"Permanent link">#
</a></h1>
1986 <p>WoltLab Suite includes a powerful user notification system that supports notifications directly shown on the website and emails sent immediately or on a daily basis.
</p>
1987 <h2 id=
"objecttypexml"><code>objectType.xml
</code><a class=
"headerlink" href=
"#objecttypexml" title=
"Permanent link">#
</a></h2>
1988 <p>For any type of object related to events, you have to define an object type for the object type definition
<code>com.woltlab.wcf.notification.objectType
</code>:
</p>
1989 <div class=
"highlight"><pre><span></span><code><span class=
"cp"><?xml version=
"1.0" encoding=
"UTF-
8"?
></span>
1990 <span class=
"nt"><data
</span> <span class=
"na">xmlns=
</span><span class=
"s">"http://www.woltlab.com
"</span> <span class=
"na">xmlns:xsi=
</span><span class=
"s">"http://www.w3.org/
2001/XMLSchema-instance
"</span> <span class=
"na">xsi:schemaLocation=
</span><span class=
"s">"http://www.woltlab.com http://www.woltlab.com/XSD/
2019/objectType.xsd
"</span><span class=
"nt">></span>
1991 <span class=
"nt"><import
></span>
1992 <span class=
"nt"><type
></span>
1993 <span class=
"nt"><name
></span>com.woltlab.example.foo
<span class=
"nt"></name
></span>
1994 <span class=
"nt"><definitionname
></span>com.woltlab.wcf.notification.objectType
<span class=
"nt"></definitionname
></span>
1995 <span class=
"nt"><classname
></span>example\system\user\notification\object\type\FooUserNotificationObjectType
<span class=
"nt"></classname
></span>
1996 <span class=
"nt"><category
></span>com.woltlab.example
<span class=
"nt"></category
></span>
1997 <span class=
"nt"></type
></span>
1998 <span class=
"nt"></import
></span>
1999 <span class=
"nt"></data
></span>
2001 <p>The referenced class
<code>FooUserNotificationObjectType
</code> has to implement the
<a href=
"https://github.com/WoltLab/WCF/blob/master/wcfsetup/install/files/lib/system/user/notification/object/type/IUserNotificationObjectType.class.php">IUserNotificationObjectType
</a> interface, which should be done by extending
<a href=
"https://github.com/WoltLab/WCF/blob/master/wcfsetup/install/files/lib/system/user/notification/object/type/AbstractUserNotificationObjectType.class.php">AbstractUserNotificationObjectType
</a>.
</p>
2002 <div class=
"highlight"><pre><span></span><code><span class=
"o"><?
</span><span class=
"nx">php
</span>
2003 <span class=
"k">namespace
</span> <span class=
"nx">example\system\user\notification\object\type
</span><span class=
"p">;
</span>
2004 <span class=
"k">use
</span> <span class=
"nx">example\data\foo\Foo
</span><span class=
"p">;
</span>
2005 <span class=
"k">use
</span> <span class=
"nx">example\data\foo\FooList
</span><span class=
"p">;
</span>
2006 <span class=
"k">use
</span> <span class=
"nx">example\system\user\notification\object\FooUserNotificationObject
</span><span class=
"p">;
</span>
2007 <span class=
"k">use
</span> <span class=
"nx">wcf\system\user\notification\object\type\AbstractUserNotificationObjectType
</span><span class=
"p">;
</span>
2009 <span class=
"sd">/**
</span>
2010 <span class=
"sd"> * Represents a foo as a notification object type.
</span>
2011 <span class=
"sd"> *
</span>
2012 <span class=
"sd"> * @author Matthias Schmidt
</span>
2013 <span class=
"sd"> * @copyright
2001-
2017 WoltLab GmbH
</span>
2014 <span class=
"sd"> * @license WoltLab License
<http://www.woltlab.com/license-agreement.html
></span>
2015 <span class=
"sd"> * @package WoltLabSuite\Example\System\User\Notification\Object\Type
</span>
2016 <span class=
"sd"> */
</span>
2017 <span class=
"k">class
</span> <span class=
"nc">FooUserNotificationObjectType
</span> <span class=
"k">extends
</span> <span class=
"nx">AbstractUserNotificationObjectType
</span> <span class=
"p">{
</span>
2018 <span class=
"sd">/**
</span>
2019 <span class=
"sd"> * @inheritDoc
</span>
2020 <span class=
"sd"> */
</span>
2021 <span class=
"k">protected
</span> <span class=
"k">static
</span> <span class=
"nv">$decoratorClassName
</span> <span class=
"o">=
</span> <span class=
"nx">FooUserNotificationObject
</span><span class=
"o">::
</span><span class=
"na">class
</span><span class=
"p">;
</span>
2023 <span class=
"sd">/**
</span>
2024 <span class=
"sd"> * @inheritDoc
</span>
2025 <span class=
"sd"> */
</span>
2026 <span class=
"k">protected
</span> <span class=
"k">static
</span> <span class=
"nv">$objectClassName
</span> <span class=
"o">=
</span> <span class=
"nx">Foo
</span><span class=
"o">::
</span><span class=
"na">class
</span><span class=
"p">;
</span>
2028 <span class=
"sd">/**
</span>
2029 <span class=
"sd"> * @inheritDoc
</span>
2030 <span class=
"sd"> */
</span>
2031 <span class=
"k">protected
</span> <span class=
"k">static
</span> <span class=
"nv">$objectListClassName
</span> <span class=
"o">=
</span> <span class=
"nx">FooList
</span><span class=
"o">::
</span><span class=
"na">class
</span><span class=
"p">;
</span>
2032 <span class=
"p">}
</span>
2034 <p>You have to set the class names of the database object (
<code>$objectClassName
</code>) and the related list (
<code>$objectListClassName
</code>).
2035 Additionally, you have to create a class that implements the
<a href=
"https://github.com/WoltLab/WCF/blob/master/wcfsetup/install/files/lib/system/user/notification/object/IUserNotificationObject.class.php">IUserNotificationObject
</a> whose name you have to set as the value of the
<code>$decoratorClassName
</code> property.
</p>
2036 <div class=
"highlight"><pre><span></span><code><span class=
"o"><?
</span><span class=
"nx">php
</span>
2037 <span class=
"k">namespace
</span> <span class=
"nx">example\system\user\notification\object
</span><span class=
"p">;
</span>
2038 <span class=
"k">use
</span> <span class=
"nx">example\data\foo\Foo
</span><span class=
"p">;
</span>
2039 <span class=
"k">use
</span> <span class=
"nx">wcf\data\DatabaseObjectDecorator
</span><span class=
"p">;
</span>
2040 <span class=
"k">use
</span> <span class=
"nx">wcf\system\user\notification\object\IUserNotificationObject
</span><span class=
"p">;
</span>
2042 <span class=
"sd">/**
</span>
2043 <span class=
"sd"> * Represents a foo as a notification object.
</span>
2044 <span class=
"sd"> *
</span>
2045 <span class=
"sd"> * @author Matthias Schmidt
</span>
2046 <span class=
"sd"> * @copyright
2001-
2017 WoltLab GmbH
</span>
2047 <span class=
"sd"> * @license WoltLab License
<http://www.woltlab.com/license-agreement.html
></span>
2048 <span class=
"sd"> * @package WoltLabSuite\Example\System\User\Notification\Object
</span>
2049 <span class=
"sd"> *
</span>
2050 <span class=
"sd"> * @method Foo getDecoratedObject()
</span>
2051 <span class=
"sd"> * @mixin Foo
</span>
2052 <span class=
"sd"> */
</span>
2053 <span class=
"k">class
</span> <span class=
"nc">FooUserNotificationObject
</span> <span class=
"k">extends
</span> <span class=
"nx">DatabaseObjectDecorator
</span> <span class=
"k">implements
</span> <span class=
"nx">IUserNotificationObject
</span> <span class=
"p">{
</span>
2054 <span class=
"sd">/**
</span>
2055 <span class=
"sd"> * @inheritDoc
</span>
2056 <span class=
"sd"> */
</span>
2057 <span class=
"k">protected
</span> <span class=
"k">static
</span> <span class=
"nv">$baseClass
</span> <span class=
"o">=
</span> <span class=
"nx">Foo
</span><span class=
"o">::
</span><span class=
"na">class
</span><span class=
"p">;
</span>
2059 <span class=
"sd">/**
</span>
2060 <span class=
"sd"> * @inheritDoc
</span>
2061 <span class=
"sd"> */
</span>
2062 <span class=
"k">public
</span> <span class=
"k">function
</span> <span class=
"nf">getTitle
</span><span class=
"p">()
</span> <span class=
"p">{
</span>
2063 <span class=
"k">return
</span> <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getDecoratedObject
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">getTitle
</span><span class=
"p">();
</span>
2064 <span class=
"p">}
</span>
2066 <span class=
"sd">/**
</span>
2067 <span class=
"sd"> * @inheritDoc
</span>
2068 <span class=
"sd"> */
</span>
2069 <span class=
"k">public
</span> <span class=
"k">function
</span> <span class=
"nf">getURL
</span><span class=
"p">()
</span> <span class=
"p">{
</span>
2070 <span class=
"k">return
</span> <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getDecoratedObject
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">getLink
</span><span class=
"p">();
</span>
2071 <span class=
"p">}
</span>
2073 <span class=
"sd">/**
</span>
2074 <span class=
"sd"> * @inheritDoc
</span>
2075 <span class=
"sd"> */
</span>
2076 <span class=
"k">public
</span> <span class=
"k">function
</span> <span class=
"nf">getAuthorID
</span><span class=
"p">()
</span> <span class=
"p">{
</span>
2077 <span class=
"k">return
</span> <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getDecoratedObject
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">userID
</span><span class=
"p">;
</span>
2078 <span class=
"p">}
</span>
2079 <span class=
"p">}
</span>
2082 <li>The
<code>getTitle()
</code> method returns the title of the object.
2083 In this case, we assume that the
<code>Foo
</code> class has implemented the
<a href=
"https://github.com/WoltLab/WCF/blob/master/wcfsetup/install/files/lib/data/ITitledObject.class.php">ITitledObject
</a> interface so that the decorated
<code>Foo
</code> can handle this method call itself.
</li>
2084 <li>The
<code>getURL()
</code> method returns the link to the object.
2085 As for the
<code>getTitle()
</code>, we assume that the
<code>Foo
</code> class has implemented the
<a href=
"https://github.com/WoltLab/WCF/blob/master/wcfsetup/install/files/lib/data/ILinkableObject.class.php">ILinkableObject
</a> interface so that the decorated
<code>Foo
</code> can also handle this method call itself.
</li>
2086 <li>The
<code>getAuthorID()
</code> method returns the id of the user who created the decorated
<code>Foo
</code> object.
2087 We assume that
<code>Foo
</code> objects have a
<code>userID
</code> property that contains this id.
</li>
2089 <h2 id=
"usernotificationeventxml"><code>userNotificationEvent.xml
</code><a class=
"headerlink" href=
"#usernotificationeventxml" title=
"Permanent link">#
</a></h2>
2090 <p>Each event that you fire in your package needs to be registered using the
<a href=
"../../../package/pip/user-notification-event/">user notification event package installation plugin
</a>.
2091 An example file might look like this:
</p>
2092 <div class=
"highlight"><pre><span></span><code><span class=
"cp"><?xml version=
"1.0" encoding=
"UTF-
8"?
></span>
2093 <span class=
"nt"><data
</span> <span class=
"na">xmlns=
</span><span class=
"s">"http://www.woltlab.com
"</span> <span class=
"na">xmlns:xsi=
</span><span class=
"s">"http://www.w3.org/
2001/XMLSchema-instance
"</span> <span class=
"na">xsi:schemaLocation=
</span><span class=
"s">"http://www.woltlab.com http://www.woltlab.com/XSD/
2019/userNotificationEvent.xsd
"</span><span class=
"nt">></span>
2094 <span class=
"nt"><import
></span>
2095 <span class=
"nt"><event
></span>
2096 <span class=
"nt"><name
></span>bar
<span class=
"nt"></name
></span>
2097 <span class=
"nt"><objecttype
></span>com.woltlab.example.foo
<span class=
"nt"></objecttype
></span>
2098 <span class=
"nt"><classname
></span>example\system\user\notification\event\FooUserNotificationEvent
<span class=
"nt"></classname
></span>
2099 <span class=
"nt"><preset
></span>1<span class=
"nt"></preset
></span>
2100 <span class=
"nt"></event
></span>
2101 <span class=
"nt"></import
></span>
2102 <span class=
"nt"></data
></span>
2104 <p>Here, you reference the user notification object type created via
<code>objectType.xml
</code>.
2105 The referenced class in the
<code><classname
></code> element has to implement the
<a href=
"https://github.com/WoltLab/WCF/blob/master/wcfsetup/install/files/lib/system/user/notification/event/IUserNotificationEvent.class.php">IUserNotificationEvent
</a> interface by extending the
<a href=
"https://github.com/WoltLab/WCF/blob/master/wcfsetup/install/files/lib/system/user/notification/event/AbstractUserNotificationEvent.class.php">AbstractUserNotificationEvent
</a> class or the
<a href=
"https://github.com/WoltLab/WCF/blob/master/wcfsetup/install/files/lib/system/user/notification/event/AbstractSharedUserNotificationEvent.class.php">AbstractSharedUserNotificationEvent
</a> class if you want to pre-load additional data before processing notifications.
2106 In
<code>AbstractSharedUserNotificationEvent::prepare()
</code>, you can, for example, tell runtime caches to prepare to load certain objects which then are loaded all at once when the objects are needed.
</p>
2107 <div class=
"highlight"><pre><span></span><code><span class=
"o"><?
</span><span class=
"nx">php
</span>
2108 <span class=
"k">namespace
</span> <span class=
"nx">example\system\user\notification\event
</span><span class=
"p">;
</span>
2109 <span class=
"k">use
</span> <span class=
"nx">example\system\cache\runtime\BazRuntimeCache
</span><span class=
"p">;
</span>
2110 <span class=
"k">use
</span> <span class=
"nx">example\system\user\notification\object\FooUserNotificationObject
</span><span class=
"p">;
</span>
2111 <span class=
"k">use
</span> <span class=
"nx">wcf\system\email\Email
</span><span class=
"p">;
</span>
2112 <span class=
"k">use
</span> <span class=
"nx">wcf\system\request\LinkHandler
</span><span class=
"p">;
</span>
2113 <span class=
"k">use
</span> <span class=
"nx">wcf\system\user\notification\event\AbstractSharedUserNotificationEvent
</span><span class=
"p">;
</span>
2115 <span class=
"sd">/**
</span>
2116 <span class=
"sd"> * Notification event for foos.
</span>
2117 <span class=
"sd"> *
</span>
2118 <span class=
"sd"> * @author Matthias Schmidt
</span>
2119 <span class=
"sd"> * @copyright
2001-
2017 WoltLab GmbH
</span>
2120 <span class=
"sd"> * @license WoltLab License
<http://www.woltlab.com/license-agreement.html
></span>
2121 <span class=
"sd"> * @package WoltLabSuite\Example\System\User\Notification\Event
</span>
2122 <span class=
"sd"> *
</span>
2123 <span class=
"sd"> * @method FooUserNotificationObject getUserNotificationObject()
</span>
2124 <span class=
"sd"> */
</span>
2125 <span class=
"k">class
</span> <span class=
"nc">FooUserNotificationEvent
</span> <span class=
"k">extends
</span> <span class=
"nx">AbstractSharedUserNotificationEvent
</span> <span class=
"p">{
</span>
2126 <span class=
"sd">/**
</span>
2127 <span class=
"sd"> * @inheritDoc
</span>
2128 <span class=
"sd"> */
</span>
2129 <span class=
"k">protected
</span> <span class=
"nv">$stackable
</span> <span class=
"o">=
</span> <span class=
"k">true
</span><span class=
"p">;
</span>
2131 <span class=
"sd">/** @noinspection PhpMissingParentCallCommonInspection */
</span>
2132 <span class=
"sd">/**
</span>
2133 <span class=
"sd"> * @inheritDoc
</span>
2134 <span class=
"sd"> */
</span>
2135 <span class=
"k">public
</span> <span class=
"k">function
</span> <span class=
"nf">checkAccess
</span><span class=
"p">()
</span> <span class=
"p">{
</span>
2136 <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getUserNotificationObject
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">setBaz
</span><span class=
"p">(
</span><span class=
"nx">BazRuntimeCache
</span><span class=
"o">::
</span><span class=
"na">getInstance
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">getObject
</span><span class=
"p">(
</span><span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getUserNotificationObject
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">bazID
</span><span class=
"p">));
</span>
2138 <span class=
"k">if
</span> <span class=
"p">(
</span><span class=
"o">!
</span><span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getUserNotificationObject
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">isAccessible
</span><span class=
"p">())
</span> <span class=
"p">{
</span>
2139 <span class=
"c1">// do some cleanup, if necessary
</span>
2141 <span class=
"k">return
</span> <span class=
"k">false
</span><span class=
"p">;
</span>
2142 <span class=
"p">}
</span>
2144 <span class=
"k">return
</span> <span class=
"k">true
</span><span class=
"p">;
</span>
2145 <span class=
"p">}
</span>
2147 <span class=
"sd">/** @noinspection PhpMissingParentCallCommonInspection */
</span>
2148 <span class=
"sd">/**
</span>
2149 <span class=
"sd"> * @inheritDoc
</span>
2150 <span class=
"sd"> */
</span>
2151 <span class=
"k">public
</span> <span class=
"k">function
</span> <span class=
"nf">getEmailMessage
</span><span class=
"p">(
</span><span class=
"nv">$notificationType
</span> <span class=
"o">=
</span> <span class=
"s1">'instant
'</span><span class=
"p">)
</span> <span class=
"p">{
</span>
2152 <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getUserNotificationObject
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">setBaz
</span><span class=
"p">(
</span><span class=
"nx">BazRuntimeCache
</span><span class=
"o">::
</span><span class=
"na">getInstance
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">getObject
</span><span class=
"p">(
</span><span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getUserNotificationObject
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">bazID
</span><span class=
"p">));
</span>
2154 <span class=
"nv">$messageID
</span> <span class=
"o">=
</span> <span class=
"s1">'<com.woltlab.example.baz/
'</span><span class=
"o">.
</span><span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getUserNotificationObject
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">bazID
</span><span class=
"o">.
</span><span class=
"s1">'@
'</span><span class=
"o">.
</span><span class=
"nx">Email
</span><span class=
"o">::
</span><span class=
"na">getHost
</span><span class=
"p">()
</span><span class=
"o">.
</span><span class=
"s1">'>'</span><span class=
"p">;
</span>
2156 <span class=
"k">return
</span> <span class=
"p">[
</span>
2157 <span class=
"s1">'application
'</span> <span class=
"o">=
></span> <span class=
"s1">'example
'</span><span class=
"p">,
</span>
2158 <span class=
"s1">'in-reply-to
'</span> <span class=
"o">=
></span> <span class=
"p">[
</span><span class=
"nv">$messageID
</span><span class=
"p">],
</span>
2159 <span class=
"s1">'message-id
'</span> <span class=
"o">=
></span> <span class=
"s1">'com.woltlab.example.foo/
'</span><span class=
"o">.
</span><span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getUserNotificationObject
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">fooID
</span><span class=
"p">,
</span>
2160 <span class=
"s1">'references
'</span> <span class=
"o">=
></span> <span class=
"p">[
</span><span class=
"nv">$messageID
</span><span class=
"p">],
</span>
2161 <span class=
"s1">'template
'</span> <span class=
"o">=
></span> <span class=
"s1">'email_notification_foo
'</span>
2162 <span class=
"p">];
</span>
2163 <span class=
"p">}
</span>
2165 <span class=
"sd">/**
</span>
2166 <span class=
"sd"> * @inheritDoc
</span>
2167 <span class=
"sd"> * @since
5.0</span>
2168 <span class=
"sd"> */
</span>
2169 <span class=
"k">public
</span> <span class=
"k">function
</span> <span class=
"nf">getEmailTitle
</span><span class=
"p">()
</span> <span class=
"p">{
</span>
2170 <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getUserNotificationObject
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">setBaz
</span><span class=
"p">(
</span><span class=
"nx">BazRuntimeCache
</span><span class=
"o">::
</span><span class=
"na">getInstance
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">getObject
</span><span class=
"p">(
</span><span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getUserNotificationObject
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">bazID
</span><span class=
"p">));
</span>
2172 <span class=
"k">return
</span> <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getLanguage
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">getDynamicVariable
</span><span class=
"p">(
</span><span class=
"s1">'example.foo.notification.mail.title
'</span><span class=
"p">,
</span> <span class=
"p">[
</span>
2173 <span class=
"s1">'userNotificationObject
'</span> <span class=
"o">=
></span> <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getUserNotificationObject
</span><span class=
"p">()
</span>
2174 <span class=
"p">]);
</span>
2175 <span class=
"p">}
</span>
2177 <span class=
"sd">/** @noinspection PhpMissingParentCallCommonInspection */
</span>
2178 <span class=
"sd">/**
</span>
2179 <span class=
"sd"> * @inheritDoc
</span>
2180 <span class=
"sd"> */
</span>
2181 <span class=
"k">public
</span> <span class=
"k">function
</span> <span class=
"nf">getEventHash
</span><span class=
"p">()
</span> <span class=
"p">{
</span>
2182 <span class=
"k">return
</span> <span class=
"nb">sha1
</span><span class=
"p">(
</span><span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">eventID
</span> <span class=
"o">.
</span> <span class=
"s1">'-
'</span> <span class=
"o">.
</span> <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getUserNotificationObject
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">bazID
</span><span class=
"p">);
</span>
2183 <span class=
"p">}
</span>
2185 <span class=
"sd">/**
</span>
2186 <span class=
"sd"> * @inheritDoc
</span>
2187 <span class=
"sd"> */
</span>
2188 <span class=
"k">public
</span> <span class=
"k">function
</span> <span class=
"nf">getLink
</span><span class=
"p">()
</span> <span class=
"p">{
</span>
2189 <span class=
"k">return
</span> <span class=
"nx">LinkHandler
</span><span class=
"o">::
</span><span class=
"na">getInstance
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">getLink
</span><span class=
"p">(
</span><span class=
"s1">'Foo
'</span><span class=
"p">,
</span> <span class=
"p">[
</span>
2190 <span class=
"s1">'application
'</span> <span class=
"o">=
></span> <span class=
"s1">'example
'</span><span class=
"p">,
</span>
2191 <span class=
"s1">'object
'</span> <span class=
"o">=
></span> <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getUserNotificationObject
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">getDecoratedObject
</span><span class=
"p">()
</span>
2192 <span class=
"p">]);
</span>
2193 <span class=
"p">}
</span>
2195 <span class=
"sd">/**
</span>
2196 <span class=
"sd"> * @inheritDoc
</span>
2197 <span class=
"sd"> */
</span>
2198 <span class=
"k">public
</span> <span class=
"k">function
</span> <span class=
"nf">getMessage
</span><span class=
"p">()
</span> <span class=
"p">{
</span>
2199 <span class=
"nv">$authors
</span> <span class=
"o">=
</span> <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getAuthors
</span><span class=
"p">();
</span>
2200 <span class=
"nv">$count
</span> <span class=
"o">=
</span> <span class=
"nb">count
</span><span class=
"p">(
</span><span class=
"nv">$authors
</span><span class=
"p">);
</span>
2202 <span class=
"k">if
</span> <span class=
"p">(
</span><span class=
"nv">$count
</span> <span class=
"o">></span> <span class=
"mi">1</span><span class=
"p">)
</span> <span class=
"p">{
</span>
2203 <span class=
"k">if
</span> <span class=
"p">(
</span><span class=
"nb">isset
</span><span class=
"p">(
</span><span class=
"nv">$authors
</span><span class=
"p">[
</span><span class=
"mi">0</span><span class=
"p">]))
</span> <span class=
"p">{
</span>
2204 <span class=
"nb">unset
</span><span class=
"p">(
</span><span class=
"nv">$authors
</span><span class=
"p">[
</span><span class=
"mi">0</span><span class=
"p">]);
</span>
2205 <span class=
"p">}
</span>
2206 <span class=
"nv">$count
</span> <span class=
"o">=
</span> <span class=
"nb">count
</span><span class=
"p">(
</span><span class=
"nv">$authors
</span><span class=
"p">);
</span>
2208 <span class=
"k">return
</span> <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getLanguage
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">getDynamicVariable
</span><span class=
"p">(
</span><span class=
"s1">'example.foo.notification.message.stacked
'</span><span class=
"p">,
</span> <span class=
"p">[
</span>
2209 <span class=
"s1">'author
'</span> <span class=
"o">=
></span> <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">author
</span><span class=
"p">,
</span>
2210 <span class=
"s1">'authors
'</span> <span class=
"o">=
></span> <span class=
"nb">array_values
</span><span class=
"p">(
</span><span class=
"nv">$authors
</span><span class=
"p">),
</span>
2211 <span class=
"s1">'count
'</span> <span class=
"o">=
></span> <span class=
"nv">$count
</span><span class=
"p">,
</span>
2212 <span class=
"s1">'guestTimesTriggered
'</span> <span class=
"o">=
></span> <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">notification
</span><span class=
"o">-
></span><span class=
"na">guestTimesTriggered
</span><span class=
"p">,
</span>
2213 <span class=
"s1">'message
'</span> <span class=
"o">=
></span> <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getUserNotificationObject
</span><span class=
"p">(),
</span>
2214 <span class=
"s1">'others
'</span> <span class=
"o">=
></span> <span class=
"nv">$count
</span> <span class=
"o">-
</span> <span class=
"mi">1</span>
2215 <span class=
"p">]);
</span>
2216 <span class=
"p">}
</span>
2218 <span class=
"k">return
</span> <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getLanguage
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">getDynamicVariable
</span><span class=
"p">(
</span><span class=
"s1">'example.foo.notification.message
'</span><span class=
"p">,
</span> <span class=
"p">[
</span>
2219 <span class=
"s1">'author
'</span> <span class=
"o">=
></span> <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">author
</span><span class=
"p">,
</span>
2220 <span class=
"s1">'userNotificationObject
'</span> <span class=
"o">=
></span> <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getUserNotificationObject
</span><span class=
"p">()
</span>
2221 <span class=
"p">]);
</span>
2222 <span class=
"p">}
</span>
2224 <span class=
"sd">/**
</span>
2225 <span class=
"sd"> * @inheritDoc
</span>
2226 <span class=
"sd"> */
</span>
2227 <span class=
"k">public
</span> <span class=
"k">function
</span> <span class=
"nf">getTitle
</span><span class=
"p">()
</span> <span class=
"p">{
</span>
2228 <span class=
"nv">$count
</span> <span class=
"o">=
</span> <span class=
"nb">count
</span><span class=
"p">(
</span><span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getAuthors
</span><span class=
"p">());
</span>
2229 <span class=
"k">if
</span> <span class=
"p">(
</span><span class=
"nv">$count
</span> <span class=
"o">></span> <span class=
"mi">1</span><span class=
"p">)
</span> <span class=
"p">{
</span>
2230 <span class=
"k">return
</span> <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getLanguage
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">getDynamicVariable
</span><span class=
"p">(
</span><span class=
"s1">'example.foo.notification.title.stacked
'</span><span class=
"p">,
</span> <span class=
"p">[
</span>
2231 <span class=
"s1">'count
'</span> <span class=
"o">=
></span> <span class=
"nv">$count
</span><span class=
"p">,
</span>
2232 <span class=
"s1">'timesTriggered
'</span> <span class=
"o">=
></span> <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">notification
</span><span class=
"o">-
></span><span class=
"na">timesTriggered
</span>
2233 <span class=
"p">]);
</span>
2234 <span class=
"p">}
</span>
2236 <span class=
"k">return
</span> <span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getLanguage
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">get
</span><span class=
"p">(
</span><span class=
"s1">'example.foo.notification.title
'</span><span class=
"p">);
</span>
2237 <span class=
"p">}
</span>
2239 <span class=
"sd">/**
</span>
2240 <span class=
"sd"> * @inheritDoc
</span>
2241 <span class=
"sd"> */
</span>
2242 <span class=
"k">protected
</span> <span class=
"k">function
</span> <span class=
"nf">prepare
</span><span class=
"p">()
</span> <span class=
"p">{
</span>
2243 <span class=
"nx">BazRuntimeCache
</span><span class=
"o">::
</span><span class=
"na">getInstance
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">cacheObjectID
</span><span class=
"p">(
</span><span class=
"nv">$this
</span><span class=
"o">-
></span><span class=
"na">getUserNotificationObject
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">bazID
</span><span class=
"p">);
</span>
2244 <span class=
"p">}
</span>
2245 <span class=
"p">}
</span>
2248 <li>The
<code>$stackable
</code> property is
<code>false
</code> by default and has to be explicitly set to
<code>true
</code> if stacking of notifications should be enabled.
2249 Stacking of notification does not create new notifications for the same event for a certain object if the related action as been triggered by different users.
2250 For example, if something is liked by one user and then liked again by another user before the recipient of the notification has confirmed it, the existing notification will be amended to include both users who liked the content.
2251 Stacking can thus be used to avoid cluttering the notification list of users.
</li>
2252 <li>The
<code>checkAccess()
</code> method makes sure that the active user still has access to the object related to the notification.
2253 If that is not the case, the user notification system will automatically deleted the user notification based on the return value of the method.
2254 If you have any cached values related to notifications, you should also reset these values here.
</li>
2255 <li>The
<code>getEmailMessage()
</code> method return data to create the instant email or the daily summary email.
2256 For instant emails (
<code>$notificationType = 'instant'
</code>), you have to return an array like the one shown in the code above with the following components:
</li>
2257 <li><code>application
</code>:
2258 abbreviation of application
</li>
2259 <li><code>in-reply-to
</code> (optional):
2260 message id of the notification for the parent item and used to improve the ordering in threaded email clients
</li>
2261 <li><code>message-id
</code> (optional):
2262 message id of the notification mail and has to be used in
<code>in-reply-to
</code> and
<code>references
</code> for follow up mails
</li>
2263 <li><code>references
</code> (optional):
2264 all of the message ids of parent items (i.e. recursive in-reply-to)
</li>
2265 <li><code>template
</code>:
2266 name of the template used to render the email body, should start with
<code>email_
</code></li>
2267 <li><code>variables
</code> (optional):
2268 template variables passed to the email template where they can be accessed via
<code>$notificationContent[variables]
</code></li>
2270 <p>For daily emails (
<code>$notificationType = 'daily'
</code>), only
<code>application
</code>,
<code>template
</code>, and
<code>variables
</code> are supported.
2271 - The
<code>getEmailTitle()
</code> returns the title of the instant email sent to the user.
2272 By default,
<code>getEmailTitle()
</code> simply calls
<code>getTitle()
</code>.
2273 - The
<code>getEventHash()
</code> method returns a hash by which user notifications are grouped.
2274 Here, we want to group them not by the actual
<code>Foo
</code> object but by its parent
<code>Baz
</code> object and thus overwrite the default implementation provided by
<code>AbstractUserNotificationEvent
</code>.
2275 - The
<code>getLink()
</code> returns the link to the
<code>Foo
</code> object the notification belongs to.
2276 - The
<code>getMessage()
</code> method and the
<code>getTitle()
</code> return the message and the title of the user notification respectively.
2277 By checking the value of
<code>count($this-
>getAuthors())
</code>, we check if the notification is stacked, thus if the event has been triggered for multiple users so that different languages items are used.
2278 If your notification event does not support stacking, this distinction is not necessary.
2279 - The
<code>prepare()
</code> method is called for each user notification before all user notifications are rendered.
2280 This allows to tell runtime caches to prepare to load objects later on (see
<a href=
"../caches_runtime-caches/">Runtime Caches
</a>).
</p>
2281 <h2 id=
"firing-events">Firing Events
<a class=
"headerlink" href=
"#firing-events" title=
"Permanent link">#
</a></h2>
2282 <p>When the action related to a user notification is executed, you can use
<code>UserNotificationHandler::fireEvent()
</code> to create the notifications:
</p>
2283 <div class=
"highlight"><pre><span></span><code><span class=
"nv">$recipientIDs
</span> <span class=
"o">=
</span> <span class=
"p">[];
</span> <span class=
"c1">// fill with user ids of the recipients of the notification
</span>
2284 <span class=
"nx">UserNotificationHandler
</span><span class=
"o">::
</span><span class=
"na">getInstance
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">fireEvent
</span><span class=
"p">(
</span>
2285 <span class=
"s1">'bar
'</span><span class=
"p">,
</span> <span class=
"c1">// event name
</span>
2286 <span class=
"s1">'com.woltlab.example.foo
'</span><span class=
"p">,
</span> <span class=
"c1">// event object type name
</span>
2287 <span class=
"k">new
</span> <span class=
"nx">FooUserNotificationObject
</span><span class=
"p">(
</span><span class=
"k">new
</span> <span class=
"nx">Foo
</span><span class=
"p">(
</span><span class=
"nv">$fooID
</span><span class=
"p">)),
</span> <span class=
"c1">// object related to the event
</span>
2288 <span class=
"nv">$recipientIDs
</span>
2289 <span class=
"p">);
</span>
2291 <h2 id=
"marking-notifications-as-confirmed">Marking Notifications as Confirmed
<a class=
"headerlink" href=
"#marking-notifications-as-confirmed" title=
"Permanent link">#
</a></h2>
2292 <p>In some instances, you might want to manually mark user notifications as confirmed without the user manually confirming them, for example when they visit the page that is related to the user notification.
2293 In this case, you can use
<code>UserNotificationHandler::markAsConfirmed()
</code>:
</p>
2294 <div class=
"highlight"><pre><span></span><code><span class=
"nv">$recipientIDs
</span> <span class=
"o">=
</span> <span class=
"p">[];
</span> <span class=
"c1">// fill with user ids of the recipients of the notification
</span>
2295 <span class=
"nv">$fooIDs
</span> <span class=
"o">=
</span> <span class=
"p">[];
</span> <span class=
"c1">// fill with ids of related foo objects
</span>
2296 <span class=
"nx">UserNotificationHandler
</span><span class=
"o">::
</span><span class=
"na">getInstance
</span><span class=
"p">()
</span><span class=
"o">-
></span><span class=
"na">markAsConfirmed
</span><span class=
"p">(
</span>
2297 <span class=
"s1">'bar
'</span><span class=
"p">,
</span> <span class=
"c1">// event name
</span>
2298 <span class=
"s1">'com.woltlab.example.foo
'</span><span class=
"p">,
</span> <span class=
"c1">// event object type name
</span>
2299 <span class=
"nv">$recipientIDs
</span><span class=
"p">,
</span>
2300 <span class=
"nv">$fooIDs
</span>
2301 <span class=
"p">);
</span>
2308 <div class=
"md-source-date">
2311 Last update:
2021-
01-
08
2330 <footer class=
"md-footer">
2332 <nav class=
"md-footer__inner md-grid" aria-label=
"Footer">
2334 <a href=
"../user_activity_points/" class=
"md-footer__link md-footer__link--prev" rel=
"prev">
2335 <div class=
"md-footer__button md-icon">
2336 <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>
2338 <div class=
"md-footer__title">
2339 <div class=
"md-ellipsis">
2340 <span class=
"md-footer__direction">
2343 User Activity Points
2349 <a href=
"../sitemaps/" class=
"md-footer__link md-footer__link--next" rel=
"next">
2350 <div class=
"md-footer__title">
2351 <div class=
"md-ellipsis">
2352 <span class=
"md-footer__direction">
2358 <div class=
"md-footer__button md-icon">
2359 <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>
2365 <div class=
"md-footer-meta md-typeset">
2366 <div class=
"md-footer-meta__inner md-grid">
2367 <div class=
"md-footer-copyright">
2369 <div class=
"md-footer-copyright__highlight">
2370 Copyright ©
2020 WoltLab GmbH
2374 <a href=
"https://squidfunk.github.io/mkdocs-material/" target=
"_blank" rel=
"noopener">
2379 <div class=
"md-footer-copyright">
2380 <a href=
"https://www.woltlab.com/legal-notice/">Legal Notice
</a>
2381 <a href=
"https://www.woltlab.com/privacy-policy/">Privacy Policy
</a>
2388 <div class=
"md-dialog" data-md-component=
"dialog">
2389 <div class=
"md-dialog__inner md-typeset"></div>
2391 <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.fe42c31b.min.js",
"version": {
"provider":
"mike"}}
</script>
2394 <script src=
"../../../assets/javascripts/bundle.d892486b.min.js"></script>