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