Merge pull request #5989 from WoltLab/wsc-rpc-api-const
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / form / NotificationSettingsForm.class.php
CommitLineData
320f4a6d 1<?php
a9229942 2
320f4a6d 3namespace wcf\form;
a9229942 4
320f4a6d
MW
5use wcf\data\object\type\ObjectTypeCache;
6use wcf\system\exception\UserInputException;
7use wcf\system\menu\user\UserMenu;
7a23a706 8use wcf\system\user\notification\event\IUserNotificationEvent;
320f4a6d
MW
9use wcf\system\user\notification\UserNotificationHandler;
10use wcf\system\WCF;
11
12/**
13 * Shows the notification settings form.
a9229942
TD
14 *
15 * @author Alexander Ebert
16 * @copyright 2001-2019 WoltLab GmbH
17 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
320f4a6d 18 */
a9229942
TD
19class NotificationSettingsForm extends AbstractForm
20{
21 /**
22 * @inheritDoc
23 */
24 public $loginRequired = true;
25
26 /**
27 * list of notification events
28 * @var IUserNotificationEvent[][]
29 */
30 public $events;
31
32 /**
33 * list of settings by event
34 * @var mixed[][]
35 */
36 public $settings = [];
37
38 /**
39 * list of valid options for the mail notification type.
40 * @var string[]
41 */
42 protected static $validMailNotificationTypes = ['none', 'instant', 'daily'];
43
44 /**
45 * @inheritDoc
46 */
47 public function readParameters()
48 {
49 parent::readParameters();
50
51 $this->events = UserNotificationHandler::getInstance()->getAvailableEvents();
52
53 // filter events
54 foreach ($this->events as $objectTypeID => $events) {
55 foreach ($events as $eventName => $event) {
56 if (!$event->isVisible()) {
57 unset($this->events[$objectTypeID][$eventName]);
58 }
59 }
60
61 if (empty($this->events[$objectTypeID])) {
62 unset($this->events[$objectTypeID]);
63 }
64 }
65 }
66
67 /**
68 * @inheritDoc
69 */
70 public function readFormParameters()
71 {
72 parent::readFormParameters();
73
74 if (isset($_POST['settings'])) {
75 $this->settings = $_POST['settings'];
76 }
77 }
78
79 /**
80 * @inheritDoc
81 */
82 public function validate()
83 {
84 parent::validate();
85
86 // valid event ids
87 $validEventIDs = [];
88 foreach ($this->events as $events) {
89 foreach ($events as $event) {
90 $validEventIDs[] = $event->eventID;
91
92 if (!isset($this->settings[$event->eventID]['enabled'])) {
93 $this->settings[$event->eventID]['enabled'] = 0;
94 }
95 }
96 }
97
98 foreach ($this->settings as $eventID => &$settings) {
99 // validate event id
100 if (!\in_array($eventID, $validEventIDs)) {
101 throw new UserInputException();
102 }
103
104 // ensure 'enabled' exists
105 if (!isset($settings['enabled'])) {
106 $settings['enabled'] = 0;
107 }
108
109 // ensure 'mailNotificationType' exists
110 if (
111 !isset($settings['mailNotificationType'])
112 || !\in_array($settings['mailNotificationType'], self::$validMailNotificationTypes)
113 ) {
114 $settings['mailNotificationType'] = 'none';
115 }
116 }
117 unset($settings);
118 }
119
120 /**
121 * @inheritDoc
122 */
123 public function readData()
124 {
125 parent::readData();
126
127 // default values
128 if (empty($_POST)) {
129 // get user settings
130 foreach ($this->events as $events) {
131 foreach ($events as $event) {
132 $this->settings[$event->eventID] = [
133 'enabled' => false,
134 'mailNotificationType' => 'none',
135 ];
136 }
137 }
138
139 // get activation state
140 $sql = "SELECT eventID, mailNotificationType
141 FROM wcf" . WCF_N . "_user_notification_event_to_user
142 WHERE userID = ?";
143 $statement = WCF::getDB()->prepareStatement($sql);
144 $statement->execute([WCF::getUser()->userID]);
145 while ($row = $statement->fetchArray()) {
146 $this->settings[$row['eventID']]['enabled'] = true;
147 $this->settings[$row['eventID']]['mailNotificationType'] = $row['mailNotificationType'];
148 }
149 }
150 }
151
152 /**
153 * @inheritDoc
154 */
155 public function assignVariables()
156 {
157 parent::assignVariables();
158
159 $groupedEvents = [];
160 foreach ($this->events as $objectType => $events) {
161 $objectTypeObj = ObjectTypeCache::getInstance()
162 ->getObjectTypeByName('com.woltlab.wcf.notification.objectType', $objectType);
163 $category = ($objectTypeObj->category ?: $objectType);
164
165 if (!isset($groupedEvents[$category])) {
166 $groupedEvents[$category] = [];
167 }
168
169 foreach ($events as $event) {
170 $groupedEvents[$category][] = $event;
171 }
172 }
173
174 \ksort($groupedEvents);
175
176 WCF::getTPL()->assign([
177 'events' => $groupedEvents,
178 'settings' => $this->settings,
179 ]);
180 }
181
182 /**
183 * @inheritDoc
184 */
185 public function show()
186 {
187 // set active tab
188 UserMenu::getInstance()->setActiveMenuItem('wcf.user.menu.settings.notification');
189
190 parent::show();
191 }
192
193 /**
194 * @inheritDoc
195 */
196 public function save()
197 {
198 parent::save();
199
200 $this->updateActivationStates();
201 $this->saved();
202
203 // show success message
204 WCF::getTPL()->assign('success', true);
205 }
206
207 /**
208 * Updates preferences for notification events.
209 */
210 protected function updateActivationStates()
211 {
212 $sql = "DELETE FROM wcf" . WCF_N . "_user_notification_event_to_user
213 WHERE eventID = ?
214 AND userID = ?";
215 $statement = WCF::getDB()->prepareStatement($sql);
216 WCF::getDB()->beginTransaction();
217 $newSettings = [];
218 foreach ($this->settings as $eventID => $setting) {
219 $statement->execute([
220 $eventID,
221 WCF::getUser()->userID,
222 ]);
223
224 if ($setting['enabled']) {
225 $newSettings[] = [
226 'eventID' => $eventID,
227 'mailNotificationType' => $setting['mailNotificationType'],
228 ];
229 }
230 }
231
232 if (!empty($newSettings)) {
233 $sql = "INSERT INTO wcf" . WCF_N . "_user_notification_event_to_user
234 (eventID, userID, mailNotificationType)
235 VALUES (?, ?, ?)";
236 $statement = WCF::getDB()->prepareStatement($sql);
237 foreach ($newSettings as $newSetting) {
238 $statement->execute([
239 $newSetting['eventID'],
240 WCF::getUser()->userID,
241 $newSetting['mailNotificationType'],
242 ]);
243 }
244 }
245 WCF::getDB()->commitTransaction();
246 }
320f4a6d 247}