1a1f4c7baSSzymon Olewniczak<?php 2a1f4c7baSSzymon Olewniczak/** 3a1f4c7baSSzymon Olewniczak * DokuWiki Plugin structnotification (Action Component) 4a1f4c7baSSzymon Olewniczak * 5a1f4c7baSSzymon Olewniczak * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6a1f4c7baSSzymon Olewniczak * @author Szymon Olewniczak <it@rid.pl> 7a1f4c7baSSzymon Olewniczak */ 8a1f4c7baSSzymon Olewniczak 9a1f4c7baSSzymon Olewniczak// must be run within Dokuwiki 10922aade7SSzymon Olewniczakuse dokuwiki\plugin\struct\meta\Search; 11922aade7SSzymon Olewniczakuse dokuwiki\plugin\struct\meta\Value; 12922aade7SSzymon Olewniczak 13a1f4c7baSSzymon Olewniczakif (!defined('DOKU_INC')) { 14a1f4c7baSSzymon Olewniczak die(); 15a1f4c7baSSzymon Olewniczak} 16a1f4c7baSSzymon Olewniczak 17a1f4c7baSSzymon Olewniczakclass action_plugin_structnotification_notification extends DokuWiki_Action_Plugin 18a1f4c7baSSzymon Olewniczak{ 19a1f4c7baSSzymon Olewniczak 20a1f4c7baSSzymon Olewniczak /** 21a1f4c7baSSzymon Olewniczak * Registers a callback function for a given event 22a1f4c7baSSzymon Olewniczak * 23a1f4c7baSSzymon Olewniczak * @param Doku_Event_Handler $controller DokuWiki's event controller object 24a1f4c7baSSzymon Olewniczak * 25a1f4c7baSSzymon Olewniczak * @return void 26a1f4c7baSSzymon Olewniczak */ 27a1f4c7baSSzymon Olewniczak public function register(Doku_Event_Handler $controller) 28a1f4c7baSSzymon Olewniczak { 29922aade7SSzymon Olewniczak $controller->register_hook('PLUGIN_NOTIFICATION_REGISTER_SOURCE', 'AFTER', $this, 'add_notifications_source'); 30922aade7SSzymon Olewniczak $controller->register_hook('PLUGIN_NOTIFICATION_GATHER', 'AFTER', $this, 'add_notifications'); 31922aade7SSzymon Olewniczak $controller->register_hook('PLUGIN_NOTIFICATION_CACHE_DEPENDENCIES', 'AFTER', $this, 'add_notification_cache_dependencies'); 32a1f4c7baSSzymon Olewniczak 33922aade7SSzymon Olewniczak 34922aade7SSzymon Olewniczak } 35922aade7SSzymon Olewniczak 36922aade7SSzymon Olewniczak public function add_notifications_source(Doku_Event $event) 37922aade7SSzymon Olewniczak { 38922aade7SSzymon Olewniczak $event->data[] = 'structnotification'; 39922aade7SSzymon Olewniczak } 40922aade7SSzymon Olewniczak 41922aade7SSzymon Olewniczak public function add_notification_cache_dependencies(Doku_Event $event) 42922aade7SSzymon Olewniczak { 43922aade7SSzymon Olewniczak if (!in_array('structnotification', $event->data['plugins'])) return; 44922aade7SSzymon Olewniczak 45922aade7SSzymon Olewniczak try { 46922aade7SSzymon Olewniczak /** @var \helper_plugin_structnotification_db $db_helper */ 47922aade7SSzymon Olewniczak $db_helper = plugin_load('helper', 'structnotification_db'); 48922aade7SSzymon Olewniczak $sqlite = $db_helper->getDB(); 49922aade7SSzymon Olewniczak $event->data['dependencies'][] = $sqlite->getAdapter()->getDbFile(); 50922aade7SSzymon Olewniczak } catch (Exception $e) { 51922aade7SSzymon Olewniczak msg($e->getMessage(), -1); 52922aade7SSzymon Olewniczak return; 53922aade7SSzymon Olewniczak } 54922aade7SSzymon Olewniczak } 55922aade7SSzymon Olewniczak 56922aade7SSzymon Olewniczak protected function getValueByLabel($values, $label) 57922aade7SSzymon Olewniczak { 58922aade7SSzymon Olewniczak /* @var Value $value */ 59922aade7SSzymon Olewniczak foreach ($values as $value) { 60922aade7SSzymon Olewniczak $colLabel = $value->getColumn()->getLabel(); 61922aade7SSzymon Olewniczak if ($colLabel == $label) { 62922aade7SSzymon Olewniczak return $value->getRawValue(); 63922aade7SSzymon Olewniczak } 64922aade7SSzymon Olewniczak } 65922aade7SSzymon Olewniczak //nothing found 66922aade7SSzymon Olewniczak throw new Exception("column: $label not found in values"); 67922aade7SSzymon Olewniczak } 68922aade7SSzymon Olewniczak 69922aade7SSzymon Olewniczak 70922aade7SSzymon Olewniczak public function add_notifications(Doku_Event $event) 71922aade7SSzymon Olewniczak { 72922aade7SSzymon Olewniczak if (!in_array('structnotification', $event->data['plugins'])) return; 73922aade7SSzymon Olewniczak 74922aade7SSzymon Olewniczak try { 75922aade7SSzymon Olewniczak /** @var \helper_plugin_structnotification_db$db_helper */ 76922aade7SSzymon Olewniczak $db_helper = plugin_load('helper', 'structnotification_db'); 77922aade7SSzymon Olewniczak $sqlite = $db_helper->getDB(); 78922aade7SSzymon Olewniczak } catch (Exception $e) { 79922aade7SSzymon Olewniczak msg($e->getMessage(), -1); 80922aade7SSzymon Olewniczak return; 81922aade7SSzymon Olewniczak } 82922aade7SSzymon Olewniczak 83922aade7SSzymon Olewniczak $user = $event->data['user']; 84922aade7SSzymon Olewniczak 85922aade7SSzymon Olewniczak $q = 'SELECT * FROM predicate'; 86922aade7SSzymon Olewniczak $res = $sqlite->query($q); 87922aade7SSzymon Olewniczak 88922aade7SSzymon Olewniczak $predicates = $sqlite->res2arr($res); 89922aade7SSzymon Olewniczak 90922aade7SSzymon Olewniczak foreach ($predicates as $predicate) { 91922aade7SSzymon Olewniczak $schema = $predicate['schema']; 92922aade7SSzymon Olewniczak $field = $predicate['field']; 93922aade7SSzymon Olewniczak $operator = $predicate['operator']; 94922aade7SSzymon Olewniczak $days = $predicate['days']; 95922aade7SSzymon Olewniczak $users_and_groups = $predicate['users_and_groups']; 96922aade7SSzymon Olewniczak $message = $predicate['message']; 97922aade7SSzymon Olewniczak 98922aade7SSzymon Olewniczak try { 99922aade7SSzymon Olewniczak $search = new Search(); 100922aade7SSzymon Olewniczak $search->addSchema($schema); 101922aade7SSzymon Olewniczak $search->addColumn('*'); 102922aade7SSzymon Olewniczak $result = $search->execute(); 103922aade7SSzymon Olewniczak $result_pids = $search->getPids(); 104922aade7SSzymon Olewniczak 105922aade7SSzymon Olewniczak /* @var Value[] $row */ 106922aade7SSzymon Olewniczak for ($i=0; $i<count($result); $i++) { 107922aade7SSzymon Olewniczak $values = $result[$i]; 108922aade7SSzymon Olewniczak $pid = $result_pids[$i]; 1092c65b673SSzymon Olewniczak 1102c65b673SSzymon Olewniczak $users_set = $this->users_set($users_and_groups, $values); 1112c65b673SSzymon Olewniczak if (!isset($users_set[$user])) continue; 1122c65b673SSzymon Olewniczak 113922aade7SSzymon Olewniczak $rawDate = $this->getValueByLabel($values, $field); 114922aade7SSzymon Olewniczak if ($this->predicateTrue($rawDate, $operator, $days)) { 115ac63f65fSSzymon Olewniczak $message = $this->replacePlaceholders($message, $values); 116922aade7SSzymon Olewniczak $message_html = p_render('xhtml',p_get_instructions($message), $info); 117922aade7SSzymon Olewniczak $event->data['notifications'][] = [ 118922aade7SSzymon Olewniczak 'plugin' => 'structnotification', 119922aade7SSzymon Olewniczak 'id' => $predicate['id'] . ':'. $schema . ':' . $pid . ':' . $rawDate, 120922aade7SSzymon Olewniczak 'full' => $message_html, 121922aade7SSzymon Olewniczak 'brief' => $message_html, 122922aade7SSzymon Olewniczak 'timestamp' => (int) strtotime($rawDate) 123922aade7SSzymon Olewniczak ]; 124922aade7SSzymon Olewniczak } 125922aade7SSzymon Olewniczak } 126922aade7SSzymon Olewniczak } catch (Exception $e) { 127922aade7SSzymon Olewniczak msg($e->getMessage(), -1); 128922aade7SSzymon Olewniczak return; 129922aade7SSzymon Olewniczak } 130922aade7SSzymon Olewniczak } 131a1f4c7baSSzymon Olewniczak } 132a1f4c7baSSzymon Olewniczak 133a1f4c7baSSzymon Olewniczak /** 134922aade7SSzymon Olewniczak * @return array 135a1f4c7baSSzymon Olewniczak */ 1362c65b673SSzymon Olewniczak protected function users_set($user_and_groups, $values) { 137922aade7SSzymon Olewniczak /** @var DokuWiki_Auth_Plugin $auth */ 138922aade7SSzymon Olewniczak global $auth; 139922aade7SSzymon Olewniczak 1402c65b673SSzymon Olewniczak //make substitutions 1412c65b673SSzymon Olewniczak $user_and_groups = preg_replace_callback( 1422c65b673SSzymon Olewniczak '/@@(.*?)@@/', 1432c65b673SSzymon Olewniczak function ($matches) use ($values) { 1442c65b673SSzymon Olewniczak list($schema, $field) = explode('.', trim($matches[1])); 1452c65b673SSzymon Olewniczak if (!$field) return ''; 1462c65b673SSzymon Olewniczak /* @var Value $value */ 1472c65b673SSzymon Olewniczak foreach ($values as $value) { 148*86ba6958SSzymon Olewniczak $column = $value->getColumn(); 149*86ba6958SSzymon Olewniczak $colLabel = $column->getLabel(); 150*86ba6958SSzymon Olewniczak $type = $column->getType(); 1512c65b673SSzymon Olewniczak if ($colLabel == $field) { 1522c65b673SSzymon Olewniczak if (class_exists('\dokuwiki\plugin\structgroup\types\Group') && 1532c65b673SSzymon Olewniczak $type instanceof \dokuwiki\plugin\structgroup\types\Group) { 154*86ba6958SSzymon Olewniczak if ($column->isMulti()) { 155*86ba6958SSzymon Olewniczak return implode(',', array_map(function ($rawValue) { 156*86ba6958SSzymon Olewniczak return '@' . $rawValue; 157*86ba6958SSzymon Olewniczak }, $value->getRawValue())); 158*86ba6958SSzymon Olewniczak } else { 1592c65b673SSzymon Olewniczak return '@' . $value->getRawValue(); 1602c65b673SSzymon Olewniczak } 161*86ba6958SSzymon Olewniczak } 162*86ba6958SSzymon Olewniczak if ($column->isMulti()) { 163*86ba6958SSzymon Olewniczak return implode(',', $value->getRawValue()); 164*86ba6958SSzymon Olewniczak } else { 1652c65b673SSzymon Olewniczak return $value->getRawValue(); 1662c65b673SSzymon Olewniczak } 1672c65b673SSzymon Olewniczak } 168*86ba6958SSzymon Olewniczak } 1692c65b673SSzymon Olewniczak return ''; 1702c65b673SSzymon Olewniczak }, 1712c65b673SSzymon Olewniczak $user_and_groups 1722c65b673SSzymon Olewniczak ); 1732c65b673SSzymon Olewniczak 174922aade7SSzymon Olewniczak $user_and_groups_set = array_map('trim', explode(',', $user_and_groups)); 175922aade7SSzymon Olewniczak $users = []; 176922aade7SSzymon Olewniczak $groups = []; 177922aade7SSzymon Olewniczak foreach ($user_and_groups_set as $user_or_group) { 178922aade7SSzymon Olewniczak if ($user_or_group[0] == '@') { 179922aade7SSzymon Olewniczak $groups[] = substr($user_or_group, 1); 180922aade7SSzymon Olewniczak } else { 181922aade7SSzymon Olewniczak $users[] = $user_or_group; 182a1f4c7baSSzymon Olewniczak } 183a1f4c7baSSzymon Olewniczak } 184922aade7SSzymon Olewniczak $set = []; 185922aade7SSzymon Olewniczak 186922aade7SSzymon Olewniczak $all_users = $auth->retrieveUsers(); 187922aade7SSzymon Olewniczak foreach ($all_users as $user => $info) { 188922aade7SSzymon Olewniczak if (in_array($user, $users)) { 189922aade7SSzymon Olewniczak $set[$user] = $info; 190922aade7SSzymon Olewniczak } elseif (array_intersect($groups, $info['grps'])) { 191922aade7SSzymon Olewniczak $set[$user] = $info; 192922aade7SSzymon Olewniczak } 193922aade7SSzymon Olewniczak } 194922aade7SSzymon Olewniczak 195922aade7SSzymon Olewniczak return $set; 196922aade7SSzymon Olewniczak } 197922aade7SSzymon Olewniczak 198922aade7SSzymon Olewniczak protected function predicateTrue($date, $operator, $days) { 199922aade7SSzymon Olewniczak $date = date('Y-m-d', strtotime($date)); 200922aade7SSzymon Olewniczak 201922aade7SSzymon Olewniczak switch ($operator) { 202922aade7SSzymon Olewniczak case 'before': 203922aade7SSzymon Olewniczak $days = date('Y-m-d', strtotime("+$days days")); 204922aade7SSzymon Olewniczak return $days >= $date; 205922aade7SSzymon Olewniczak case 'after': 206922aade7SSzymon Olewniczak $days = date('Y-m-d', strtotime("-$days days")); 207922aade7SSzymon Olewniczak return $date <= $days; 208922aade7SSzymon Olewniczak default: 209922aade7SSzymon Olewniczak return false; 210922aade7SSzymon Olewniczak } 211a1f4c7baSSzymon Olewniczak } 212a1f4c7baSSzymon Olewniczak 213ac63f65fSSzymon Olewniczak protected function replacePlaceholders($message, $values) { 214ac63f65fSSzymon Olewniczak $patterns = []; 215ac63f65fSSzymon Olewniczak $replacements = []; 216ac63f65fSSzymon Olewniczak /* @var Value $value */ 217ac63f65fSSzymon Olewniczak foreach ($values as $value) { 218ac63f65fSSzymon Olewniczak $schema = $value->getColumn()->getTable(); 219ac63f65fSSzymon Olewniczak $label = $value->getColumn()->getLabel(); 220ac63f65fSSzymon Olewniczak $patterns[] = "/@@$schema.$label@@/"; 221ac63f65fSSzymon Olewniczak $replacements[] = $value->getDisplayValue(); 222ac63f65fSSzymon Olewniczak } 223ac63f65fSSzymon Olewniczak 224ac63f65fSSzymon Olewniczak return preg_replace($patterns, $replacements, $message); 225ac63f65fSSzymon Olewniczak } 226ac63f65fSSzymon Olewniczak 227a1f4c7baSSzymon Olewniczak} 228a1f4c7baSSzymon Olewniczak 229