payload()); } public function update(UpdateNotificationSettingsRequest $request) { $data = $request->toSettingsData(); $added = Config::addOption(NotificationSettings::OPTION_NAME->value, $data); if (!$added) { Config::updateOption(NotificationSettings::OPTION_NAME->value, $data); } // Dispatch resolves every recipient through the cached option, so a // notification raised later in this same request would otherwise be // decided by the settings as they were before this save. NotificationPreferences::flushSettings(); // Switching the forum back on has to put the jobs back: deactivation // clears them, and an admin who disabled notifications and re-enabled // them would otherwise have a forum that writes rows and never mails // them. CronProvider::schedule(); return Response::success($this->payload()); } /** * Sends the signed-in admin one message, using the settings as saved. * * The one control that turns "is mail working on this site?" from a support * thread into a click. Deliberately sent to the admin's own address rather * than an arbitrary one — this is a diagnostic, not a way to mail strangers * from someone else's forum. */ public function sendTest(SendTestNotificationEmailRequest $_request) // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable { $user = wp_get_current_user(); if (!$user || !is_email($user->user_email)) { return Response::error([], 422) ->message(__('Your account has no email address to send to.', 'bit-connect')); } $sent = NotificationMailer::sendTest((int) $user->ID); if (!$sent) { return Response::error([], 500)->message( __( 'WordPress could not send the message. Check this site\'s email configuration or SMTP plugin.', 'bit-connect' ) ); } return Response::success( [ 'sentTo' => $user->user_email, ] ); } /** * Settings plus everything the screen needs to render them. * * @return array */ private function payload(): array { $stored = Config::getOption(NotificationSettings::OPTION_NAME->value, []); $catalog = []; // Not cases(): a type nothing on this forum raises is not a default an // admin has any use for setting. See ExtensionPoints::notifiableTypes(). foreach (ExtensionPoints::notifiableTypes() as $type) { $catalog[] = [ 'type' => $type->value, 'label' => NotificationTypes::translatedLabel($type), 'description' => NotificationTypes::translatedDescription($type), // The screen greys the member-override column for these: a // moderator-only type is never on an ordinary member's screen // to be overridden in the first place. 'moderatorOnly' => NotificationTypes::isModeratorOnly($type), // And locks the in-app column for these, because the forum // sends them whatever anybody says. 'mandatoryInApp' => NotificationTypes::isMandatoryInApp($type), ]; } return [ 'settings' => NotificationSettings::normalize($stored), 'catalog' => $catalog, 'frequencies' => NotificationSettings::frequencies(), // What an admin may write in the template fields, described by the // code rather than by prose on the screen that would drift from it. 'placeholders' => NotificationSettings::mailPlaceholders(), // So the screen can say where mail will appear to come from without // reimplementing the fallback chain. 'effectiveSender' => [ 'name' => NotificationSettings::fromName($stored), 'email' => NotificationSettings::fromEmail($stored), ], ]; } }