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)) { 115*c0d6a71fSSzymon Olewniczak $message_with_replacements = $this->replacePlaceholders($message, $values); 116*c0d6a71fSSzymon Olewniczak $message_with_replacements_html = p_render('xhtml', 117*c0d6a71fSSzymon Olewniczak p_get_instructions($message_with_replacements), $info); 118922aade7SSzymon Olewniczak $event->data['notifications'][] = [ 119922aade7SSzymon Olewniczak 'plugin' => 'structnotification', 120922aade7SSzymon Olewniczak 'id' => $predicate['id'] . ':'. $schema . ':' . $pid . ':' . $rawDate, 121*c0d6a71fSSzymon Olewniczak 'full' => $message_with_replacements_html, 122*c0d6a71fSSzymon Olewniczak 'brief' => $message_with_replacements_html, 123922aade7SSzymon Olewniczak 'timestamp' => (int) strtotime($rawDate) 124922aade7SSzymon Olewniczak ]; 125922aade7SSzymon Olewniczak } 126922aade7SSzymon Olewniczak } 127922aade7SSzymon Olewniczak } catch (Exception $e) { 128922aade7SSzymon Olewniczak msg($e->getMessage(), -1); 129922aade7SSzymon Olewniczak return; 130922aade7SSzymon Olewniczak } 131922aade7SSzymon Olewniczak } 132a1f4c7baSSzymon Olewniczak } 133a1f4c7baSSzymon Olewniczak 134a1f4c7baSSzymon Olewniczak /** 135922aade7SSzymon Olewniczak * @return array 136a1f4c7baSSzymon Olewniczak */ 1372c65b673SSzymon Olewniczak protected function users_set($user_and_groups, $values) { 138922aade7SSzymon Olewniczak /** @var DokuWiki_Auth_Plugin $auth */ 139922aade7SSzymon Olewniczak global $auth; 140922aade7SSzymon Olewniczak 1412c65b673SSzymon Olewniczak //make substitutions 1422c65b673SSzymon Olewniczak $user_and_groups = preg_replace_callback( 1432c65b673SSzymon Olewniczak '/@@(.*?)@@/', 1442c65b673SSzymon Olewniczak function ($matches) use ($values) { 1452c65b673SSzymon Olewniczak list($schema, $field) = explode('.', trim($matches[1])); 1462c65b673SSzymon Olewniczak if (!$field) return ''; 1472c65b673SSzymon Olewniczak /* @var Value $value */ 1482c65b673SSzymon Olewniczak foreach ($values as $value) { 14986ba6958SSzymon Olewniczak $column = $value->getColumn(); 15086ba6958SSzymon Olewniczak $colLabel = $column->getLabel(); 15186ba6958SSzymon Olewniczak $type = $column->getType(); 1522c65b673SSzymon Olewniczak if ($colLabel == $field) { 1532c65b673SSzymon Olewniczak if (class_exists('\dokuwiki\plugin\structgroup\types\Group') && 1542c65b673SSzymon Olewniczak $type instanceof \dokuwiki\plugin\structgroup\types\Group) { 15586ba6958SSzymon Olewniczak if ($column->isMulti()) { 15686ba6958SSzymon Olewniczak return implode(',', array_map(function ($rawValue) { 15786ba6958SSzymon Olewniczak return '@' . $rawValue; 15886ba6958SSzymon Olewniczak }, $value->getRawValue())); 15986ba6958SSzymon Olewniczak } else { 1602c65b673SSzymon Olewniczak return '@' . $value->getRawValue(); 1612c65b673SSzymon Olewniczak } 16286ba6958SSzymon Olewniczak } 16386ba6958SSzymon Olewniczak if ($column->isMulti()) { 16486ba6958SSzymon Olewniczak return implode(',', $value->getRawValue()); 16586ba6958SSzymon Olewniczak } else { 1662c65b673SSzymon Olewniczak return $value->getRawValue(); 1672c65b673SSzymon Olewniczak } 1682c65b673SSzymon Olewniczak } 16986ba6958SSzymon Olewniczak } 1702c65b673SSzymon Olewniczak return ''; 1712c65b673SSzymon Olewniczak }, 1722c65b673SSzymon Olewniczak $user_and_groups 1732c65b673SSzymon Olewniczak ); 1742c65b673SSzymon Olewniczak 175922aade7SSzymon Olewniczak $user_and_groups_set = array_map('trim', explode(',', $user_and_groups)); 176922aade7SSzymon Olewniczak $users = []; 177922aade7SSzymon Olewniczak $groups = []; 178922aade7SSzymon Olewniczak foreach ($user_and_groups_set as $user_or_group) { 179922aade7SSzymon Olewniczak if ($user_or_group[0] == '@') { 180922aade7SSzymon Olewniczak $groups[] = substr($user_or_group, 1); 181922aade7SSzymon Olewniczak } else { 182922aade7SSzymon Olewniczak $users[] = $user_or_group; 183a1f4c7baSSzymon Olewniczak } 184a1f4c7baSSzymon Olewniczak } 185922aade7SSzymon Olewniczak $set = []; 186922aade7SSzymon Olewniczak 187922aade7SSzymon Olewniczak $all_users = $auth->retrieveUsers(); 188922aade7SSzymon Olewniczak foreach ($all_users as $user => $info) { 189922aade7SSzymon Olewniczak if (in_array($user, $users)) { 190922aade7SSzymon Olewniczak $set[$user] = $info; 191922aade7SSzymon Olewniczak } elseif (array_intersect($groups, $info['grps'])) { 192922aade7SSzymon Olewniczak $set[$user] = $info; 193922aade7SSzymon Olewniczak } 194922aade7SSzymon Olewniczak } 195922aade7SSzymon Olewniczak 196922aade7SSzymon Olewniczak return $set; 197922aade7SSzymon Olewniczak } 198922aade7SSzymon Olewniczak 199922aade7SSzymon Olewniczak protected function predicateTrue($date, $operator, $days) { 200922aade7SSzymon Olewniczak $date = date('Y-m-d', strtotime($date)); 201922aade7SSzymon Olewniczak 202922aade7SSzymon Olewniczak switch ($operator) { 203922aade7SSzymon Olewniczak case 'before': 204922aade7SSzymon Olewniczak $days = date('Y-m-d', strtotime("+$days days")); 205922aade7SSzymon Olewniczak return $days >= $date; 206922aade7SSzymon Olewniczak case 'after': 207922aade7SSzymon Olewniczak $days = date('Y-m-d', strtotime("-$days days")); 208922aade7SSzymon Olewniczak return $date <= $days; 209922aade7SSzymon Olewniczak default: 210922aade7SSzymon Olewniczak return false; 211922aade7SSzymon Olewniczak } 212a1f4c7baSSzymon Olewniczak } 213a1f4c7baSSzymon Olewniczak 214ac63f65fSSzymon Olewniczak protected function replacePlaceholders($message, $values) { 215ac63f65fSSzymon Olewniczak $patterns = []; 216ac63f65fSSzymon Olewniczak $replacements = []; 217ac63f65fSSzymon Olewniczak /* @var Value $value */ 218ac63f65fSSzymon Olewniczak foreach ($values as $value) { 219ac63f65fSSzymon Olewniczak $schema = $value->getColumn()->getTable(); 220ac63f65fSSzymon Olewniczak $label = $value->getColumn()->getLabel(); 221ac63f65fSSzymon Olewniczak $patterns[] = "/@@$schema.$label@@/"; 222ac63f65fSSzymon Olewniczak $replacements[] = $value->getDisplayValue(); 223ac63f65fSSzymon Olewniczak } 224ac63f65fSSzymon Olewniczak 225ac63f65fSSzymon Olewniczak return preg_replace($patterns, $replacements, $message); 226ac63f65fSSzymon Olewniczak } 227ac63f65fSSzymon Olewniczak 228a1f4c7baSSzymon Olewniczak} 229a1f4c7baSSzymon Olewniczak 230