1<?php 2 3use dokuwiki\Extension\AuthPlugin; 4use dokuwiki\plugin\structpublish\meta\Assignments; 5use dokuwiki\plugin\structpublish\meta\Constants; 6use dokuwiki\plugin\structpublish\meta\Revision; 7 8/** 9 * Notification helper 10 */ 11class helper_plugin_structpublish_notify extends DokuWiki_Plugin 12{ 13 /** @var helper_plugin_structpublish_db */ 14 protected $dbHelper; 15 16 public function __construct() 17 { 18 $this->dbHelper = plugin_load('helper', 'structpublish_db'); 19 } 20 21 /** 22 * If activated, send emails on configured status changes. 23 * 24 * @param string $action 25 * @param Revision $newRevision 26 * @return void 27 * @throws Exception 28 */ 29 public function sendEmails($action, $newRevision) 30 { 31 32 if (!$this->triggerNotification($action)) { 33 return; 34 } 35 36 // get assignees from DB 37 $assignments = Assignments::getInstance(); 38 $assignees = $assignments->getPageAssignments($newRevision->getId(), false); 39 40 // get recipients for the next workflow step 41 $nextAction = Constants::workflowSteps($action)['nextAction']; 42 if (is_null($nextAction)) { 43 return; 44 } 45 46 if (empty($assignees[$nextAction])) { 47 msg($this->getLang('email_error_norecipients'), -1); 48 return; 49 } 50 51 // flatten the array and split into single user or group items 52 $assignees = implode(',', array_values($assignees[$nextAction])); 53 $assignees = explode(',', $assignees); 54 55 // get recipient emails 56 $recipients = $this->resolveRecipients($assignees); 57 58 // prepare mail text 59 $mailText = $this->prepareMailText($newRevision->getStatus()); 60 61 $this->sendMail(implode(',', $recipients), $mailText); 62 } 63 64 /** 65 * @param string $recipients Comma separated list of emails 66 * @param string $mailText 67 * @return void 68 */ 69 public function sendMail($recipients, $mailText) 70 { 71 $mailer = new Mailer(); 72 $mailer->bcc($recipients); 73 74 $subject = $this->getLang('email_subject'); 75 $mailer->subject($subject); 76 77 $mailer->setBody($mailText); 78 $mailer->send(); 79 } 80 81 /** 82 * Processes an array of (comma separated) recipients 83 * and returns an array of emails 84 * with user groups resolved to individual users 85 * 86 * @param array $recipients 87 * @return array 88 * @throws Exception 89 */ 90 public function resolveRecipients($recipients) 91 { 92 $resolved = []; 93 94 $recipients = array_unique($recipients); 95 96 foreach ($recipients as $recipient) { 97 $recipient = trim($recipient); 98 99 if ($recipient[0] === '@') { 100 $this->resolveGroup($resolved, $recipient); 101 } elseif (strpos($recipient, '@') === false) { 102 $this->resolveUser($resolved, $recipient); 103 } else { 104 $resolved[] = $recipient; 105 } 106 } 107 return $resolved; 108 } 109 110 /** 111 * @param array $resolved 112 * @param string $recipient 113 * @return void 114 * @throws Exception 115 */ 116 protected function resolveGroup(&$resolved, $recipient) 117 { 118 /** @var AuthPlugin $auth */ 119 global $auth; 120 if (!$auth->canDo('getUsers')) { 121 throw new \Exception('Auth cannot fetch users by group.'); 122 } 123 124 $users = $auth->retrieveUsers(0, 0, ['grps' => substr($recipient, 1)]); 125 foreach ($users as $user) { 126 $resolved[] = $user['mail']; 127 } 128 } 129 130 /** 131 * @param array $resolved 132 * @param string $recipient 133 * @return void 134 */ 135 protected function resolveUser(&$resolved, $recipient) 136 { 137 /** @var AuthPlugin $auth */ 138 global $auth; 139 $user = $auth->getUserData($recipient); 140 if ($user) { 141 $resolved[] = $user['mail']; 142 } 143 } 144 145 /** 146 * Check configuration to see if a notification should be triggered. 147 * 148 * @return bool 149 */ 150 private function triggerNotification($action) 151 { 152 if (!$this->getConf('email_enable')) { 153 return false; 154 } 155 156 $actions = array_map('trim', explode(',', $this->getConf('email_status'))); 157 return in_array($action, $actions); 158 } 159 160 /** 161 * @return string 162 */ 163 protected function prepareMailText($status) 164 { 165 global $ID; 166 167 $mailtext = file_get_contents($this->localFN('mail')); 168 169 $vars = [ 170 'PAGE' => $ID, 171 'URL' => wl($ID, '', true), 172 'STATUS_CURRENT' => $status, 173 ]; 174 175 foreach ($vars as $var => $val) { 176 $mailtext = str_replace('@' . $var . '@', $val, $mailtext); 177 } 178 179 return $mailtext; 180 } 181} 182