1<?php 2 3/** 4 * DokuWiki Plugin notification (Action Component) 5 * 6 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 7 * @author Szymon Olewniczak <it@rid.pl> 8 */ 9 10// must be run within Dokuwiki 11if (!defined('DOKU_INC')) { 12 die(); 13} 14 15class action_plugin_notification_cron extends DokuWiki_Action_Plugin 16{ 17 18 /** 19 * Registers a callback function for a given event 20 * 21 * @param Doku_Event_Handler $controller DokuWiki's event controller object 22 * 23 * @return void 24 */ 25 public function register(Doku_Event_Handler $controller) 26 { 27 $controller->register_hook('INDEXER_TASKS_RUN', 'AFTER', $this, 'handle_indexer_tasks_run'); 28 } 29 30 /** 31 * 32 * @param Doku_Event $event event object by reference 33 * @param mixed $param [the parameters passed as fifth argument to register_hook() when this 34 * handler was registered] 35 * 36 * @return void 37 */ 38 public function handle_indexer_tasks_run(Doku_Event $event, $param) 39 { 40 /** @var DokuWiki_Auth_Plugin $auth */ 41 global $auth; 42 43 /** @var \helper_plugin_notification_db $db_helper */ 44 $db_helper = plugin_load('helper', 'notification_db'); 45 $sqlite = $db_helper->getDB(); 46 47 // insert new users first 48 /** @var \helper_plugin_notification_cron $cron_helper */ 49 $cron_helper = plugin_load('helper', 'notification_cron'); 50 $cron_helper->addUsersToCron(); 51 52 53 //get the oldest check 54 $res = $sqlite->query('SELECT user, MIN(timestamp) FROM cron_check'); 55 $user = $sqlite->res2single($res); 56 //no user to sent notifications 57 if (!$user) return; 58 59 //update user last check 60 $sqlite->query('UPDATE cron_check SET timestamp=? WHERE user=?', date('c'), $user); 61 62 $plugins = []; 63 trigger_event('PLUGIN_NOTIFICATION_REGISTER_SOURCE', $plugins); 64 $notifications_data = [ 65 'plugins' => $plugins, 66 'user' => $user, 67 'notifications' => [] 68 ]; 69 trigger_event('PLUGIN_NOTIFICATION_GATHER', $notifications_data); 70 71 $notifications = $notifications_data['notifications']; 72 //no notifications - nothing to sent 73 if (!$notifications) return; 74 75 //get only notifications that has id 76 $notifications = array_filter($notifications, function ($notification) { 77 return array_key_exists('id', $notification); 78 }); 79 //no notifications - nothing to sent 80 if (!$notifications) return; 81 82 //get the notifications that has been sent already 83 $res = $sqlite->query('SELECT plugin, notification_id FROM notification WHERE user=?', $user); 84 $sent_notifications = $sqlite->res2arr($res); 85 $sent_notifications_by_plugin = []; 86 foreach ($plugins as $plugin) { 87 $sent_notifications_by_plugin[$plugin] = []; 88 } 89 foreach ($sent_notifications as $sent_notification) { 90 $plugin = $sent_notification['plugin']; 91 $id = $sent_notification['notification_id']; 92 $sent_notifications_by_plugin[$plugin][$id] = true; 93 } 94 95 $new_notifications = []; 96 foreach ($notifications as $notification) { 97 $plugin = $notification['plugin']; 98 $id = $notification['id']; 99 if (!isset($sent_notifications_by_plugin[$plugin][$id])) { 100 $new_notifications[] = $notification; 101 } 102 } 103 104 //no notifications - nothing to sent 105 if (!$new_notifications) return; 106 107 $html = '<p>' . $this->getLang('mail content'); 108 $html .= '<ul>'; 109 $text = $this->getLang('mail content') . "\n\n"; 110 111 usort($new_notifications, function($a, $b) { 112 if ($a['timestamp'] == $b['timestamp']) { 113 return 0; 114 } 115 return ($a['timestamp'] > $b['timestamp']) ? -1 : 1; 116 }); 117 118 foreach ($new_notifications as $notification) { 119 $content = $notification['full']; 120 $timestamp = $notification['timestamp']; 121 122 $date = strftime('%d.%m %H:%M', $timestamp); 123 124 $html .= "<li class=\"level1\"><div class=\"li\">$date $content</div></li>"; 125 $text .= $date . ' ' . strip_tags($content). "\n"; 126 } 127 $html .= '</ul></p>'; 128 129 $mail = new Mailer(); 130 $userinfo = $auth->getUserData($user, $requireGroups = false); 131 $mail->to($userinfo['name'].' <'.$userinfo['mail'].'>'); 132 $mail->subject($this->getLang('mail subject')); 133 $mail->setBody($text, null, null, $html); 134 $mail->send(); 135 136 //mark notifications as sent 137 foreach ($new_notifications as $notification) { 138 $plugin = $notification['plugin']; 139 $id = $notification['id']; 140 $sqlite->storeEntry('notification', 141 ['plugin' => $plugin, 'notification_id' => $id, 'user' => $user, 'sent' => date('c')]); 142 } 143 144 $event->stopPropagation(); 145 $event->preventDefault(); 146 } 147} 148