1<?php 2 3use dokuwiki\Extension\Plugin; 4use dokuwiki\Extension\Event; 5 6/** 7 * DokuWiki Plugin notification (Helper Component) 8 * 9 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 10 */ 11class helper_plugin_notification_cron extends Plugin 12{ 13 /** @var helper_plugin_sqlite */ 14 protected $sqlite; 15 16 public function __construct() 17 { 18 /** @var \helper_plugin_notification_db $db_helper */ 19 $db_helper = plugin_load('helper', 'notification_db'); 20 $this->sqlite = $db_helper->getDB(); 21 } 22 23 public function addUsersToCron() 24 { 25 /** @var DokuWiki_Auth_Plugin $auth */ 26 global $auth; 27 28 $res = $this->sqlite->query('SELECT user from cron_check'); 29 $ourUsers = $this->sqlite->res2arr($res); 30 31 $ourUsers = array_map(function ($item) { 32 return $item['user']; 33 }, $ourUsers); 34 35 $allUsers = array_keys($auth->retrieveUsers()); 36 37 $newUsers = array_diff($allUsers, $ourUsers); 38 39 if (!is_array($newUsers) || $newUsers === []) return; 40 41 foreach ($newUsers as $user) { 42 $this->sqlite->storeEntry( 43 'cron_check', 44 ['user' => $user, 'timestamp' => date('c', 0)] 45 ); 46 } 47 } 48 49 /** 50 * Gather notification data from plugins 51 * 52 * @param string $user 53 * @return array 54 */ 55 public function getNotificationData($user) 56 { 57 $plugins = []; 58 $event = new Event('PLUGIN_NOTIFICATION_REGISTER_SOURCE', $plugins); 59 $event->trigger(); 60 61 $notifications_data = [ 62 'plugins' => $plugins, 63 'user' => $user, 64 'notifications' => [] 65 ]; 66 $event = new Event('PLUGIN_NOTIFICATION_GATHER', $notifications_data); 67 $event->trigger(); 68 69 if (!empty($notifications_data['notifications'])) { 70 $notifications = $notifications_data['notifications']; 71 72 // get only notifications that have ids 73 $notifications_data['notifications'] = array_filter($notifications, function ($notification) { 74 return array_key_exists('id', $notification); 75 }); 76 } 77 78 return $notifications_data; 79 } 80 81 /** 82 * Prune old (already sent) notifications and return only new ones 83 * 84 * @param string $user 85 * @param array $notification_data 86 * @return array 87 */ 88 public function getNewNotifications($user, $notification_data) 89 { 90 /** @var \helper_plugin_notification_db $db_helper */ 91 $db_helper = plugin_load('helper', 'notification_db'); 92 $sqlite = $db_helper->getDB(); 93 94 $notifications = $notification_data['notifications']; 95 $plugins = $notification_data['plugins']; 96 97 //get the notifications that have been sent already 98 $res = $sqlite->query('SELECT plugin, notification_id FROM notification WHERE user=?', $user); 99 $sent_notifications = $sqlite->res2arr($res); 100 $sent_notifications_by_plugin = []; 101 foreach ($plugins as $plugin) { 102 $sent_notifications_by_plugin[$plugin] = []; 103 } 104 foreach ($sent_notifications as $sent_notification) { 105 $plugin = $sent_notification['plugin']; 106 $id = $sent_notification['notification_id']; 107 $sent_notifications_by_plugin[$plugin][$id] = true; 108 } 109 110 // keep only notifications not yet sent 111 $new_notifications = []; 112 foreach ($notifications as $notification) { 113 $plugin = $notification['plugin']; 114 $id = $notification['id']; 115 if (!isset($sent_notifications_by_plugin[$plugin][$id])) { 116 $new_notifications[] = $notification; 117 } 118 } 119 120 return $new_notifications; 121 } 122 123 /** 124 * Create text and HTML components of email message 125 * 126 * @param array $new_notifications 127 * @return string[] 128 */ 129 public function composeEmail($new_notifications) 130 { 131 $html = '<p>' . $this->getLang('mail content') . '</p>'; 132 $html .= '<ul>'; 133 $text = $this->getLang('mail content') . "\n\n"; 134 135 usort($new_notifications, function ($a, $b) { 136 if ($a['timestamp'] == $b['timestamp']) { 137 return 0; 138 } 139 return ($a['timestamp'] > $b['timestamp']) ? -1 : 1; 140 }); 141 142 foreach ($new_notifications as $notification) { 143 $content = $notification['full']; 144 $timestamp = $notification['timestamp']; 145 146 $date = strftime('%d.%m %H:%M', $timestamp); 147 148 $html .= "<li class=\"level1\"><div class=\"li\">$date $content</div></li>"; 149 $text .= $date . ' ' . strip_tags($content) . "\n"; 150 } 151 $html .= '</ul>'; 152 153 return [$text, $html]; 154 } 155 156 /** 157 * Send notification email to the given user 158 * 159 * @param string $user 160 * @param string $text 161 * @param string $html 162 * @return bool true if email was sent successfully 163 */ 164 public function sendMail($user, $text, $html) 165 { 166 /** @var DokuWiki_Auth_Plugin $auth */ 167 global $auth; 168 169 $mail = new Mailer(); 170 $userinfo = $auth->getUserData($user, false); 171 $mail->to($userinfo['name'] . ' <' . $userinfo['mail'] . '>'); 172 $mail->subject($this->getLang('mail subject')); 173 $mail->setBody($text, null, null, $html); 174 return $mail->send(); 175 } 176 177 /** 178 * Store info about sent notifications 179 * 180 * @param string $user 181 * @param array $notifications 182 */ 183 public function storeSentNotifications($user, $notifications) 184 { 185 /** @var \helper_plugin_notification_db $db_helper */ 186 $db_helper = plugin_load('helper', 'notification_db'); 187 $sqlite = $db_helper->getDB(); 188 189 foreach ($notifications as $notification) { 190 $plugin = $notification['plugin']; 191 $id = $notification['id']; 192 $sqlite->storeEntry( 193 'notification', 194 ['plugin' => $plugin, 'notification_id' => $id, 'user' => $user, 'sent' => date('c')] 195 ); 196 } 197 } 198} 199