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