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('*'); 102*115044e5SSzymon Olewniczak // add special columns 103*115044e5SSzymon Olewniczak $special_columns = ['%pageid%', '%title%', '%lastupdate%', '%lasteditor%', '%lastsummary%', '%rowid%']; 104*115044e5SSzymon Olewniczak foreach ($special_columns as $special_column) { 105*115044e5SSzymon Olewniczak $search->addColumn($special_column); 106*115044e5SSzymon Olewniczak } 107922aade7SSzymon Olewniczak $result = $search->execute(); 108922aade7SSzymon Olewniczak $result_pids = $search->getPids(); 109922aade7SSzymon Olewniczak 110922aade7SSzymon Olewniczak /* @var Value[] $row */ 111922aade7SSzymon Olewniczak for ($i=0; $i<count($result); $i++) { 112922aade7SSzymon Olewniczak $values = $result[$i]; 113922aade7SSzymon Olewniczak $pid = $result_pids[$i]; 1142c65b673SSzymon Olewniczak 1152c65b673SSzymon Olewniczak $users_set = $this->users_set($users_and_groups, $values); 1162c65b673SSzymon Olewniczak if (!isset($users_set[$user])) continue; 1172c65b673SSzymon Olewniczak 118922aade7SSzymon Olewniczak $rawDate = $this->getValueByLabel($values, $field); 119922aade7SSzymon Olewniczak if ($this->predicateTrue($rawDate, $operator, $days)) { 120c0d6a71fSSzymon Olewniczak $message_with_replacements = $this->replacePlaceholders($message, $values); 121c0d6a71fSSzymon Olewniczak $message_with_replacements_html = p_render('xhtml', 122c0d6a71fSSzymon Olewniczak p_get_instructions($message_with_replacements), $info); 123922aade7SSzymon Olewniczak $event->data['notifications'][] = [ 124922aade7SSzymon Olewniczak 'plugin' => 'structnotification', 125922aade7SSzymon Olewniczak 'id' => $predicate['id'] . ':'. $schema . ':' . $pid . ':' . $rawDate, 126c0d6a71fSSzymon Olewniczak 'full' => $message_with_replacements_html, 127c0d6a71fSSzymon Olewniczak 'brief' => $message_with_replacements_html, 128922aade7SSzymon Olewniczak 'timestamp' => (int) strtotime($rawDate) 129922aade7SSzymon Olewniczak ]; 130922aade7SSzymon Olewniczak } 131922aade7SSzymon Olewniczak } 132922aade7SSzymon Olewniczak } catch (Exception $e) { 133922aade7SSzymon Olewniczak msg($e->getMessage(), -1); 134922aade7SSzymon Olewniczak return; 135922aade7SSzymon Olewniczak } 136922aade7SSzymon Olewniczak } 137a1f4c7baSSzymon Olewniczak } 138a1f4c7baSSzymon Olewniczak 139a1f4c7baSSzymon Olewniczak /** 140922aade7SSzymon Olewniczak * @return array 141a1f4c7baSSzymon Olewniczak */ 1422c65b673SSzymon Olewniczak protected function users_set($user_and_groups, $values) { 143922aade7SSzymon Olewniczak /** @var DokuWiki_Auth_Plugin $auth */ 144922aade7SSzymon Olewniczak global $auth; 145922aade7SSzymon Olewniczak 1462c65b673SSzymon Olewniczak //make substitutions 1472c65b673SSzymon Olewniczak $user_and_groups = preg_replace_callback( 1482c65b673SSzymon Olewniczak '/@@(.*?)@@/', 1492c65b673SSzymon Olewniczak function ($matches) use ($values) { 1502c65b673SSzymon Olewniczak list($schema, $field) = explode('.', trim($matches[1])); 1512c65b673SSzymon Olewniczak if (!$field) return ''; 1522c65b673SSzymon Olewniczak /* @var Value $value */ 1532c65b673SSzymon Olewniczak foreach ($values as $value) { 15486ba6958SSzymon Olewniczak $column = $value->getColumn(); 15586ba6958SSzymon Olewniczak $colLabel = $column->getLabel(); 15686ba6958SSzymon Olewniczak $type = $column->getType(); 1572c65b673SSzymon Olewniczak if ($colLabel == $field) { 1582c65b673SSzymon Olewniczak if (class_exists('\dokuwiki\plugin\structgroup\types\Group') && 1592c65b673SSzymon Olewniczak $type instanceof \dokuwiki\plugin\structgroup\types\Group) { 16086ba6958SSzymon Olewniczak if ($column->isMulti()) { 16186ba6958SSzymon Olewniczak return implode(',', array_map(function ($rawValue) { 16286ba6958SSzymon Olewniczak return '@' . $rawValue; 16386ba6958SSzymon Olewniczak }, $value->getRawValue())); 16486ba6958SSzymon Olewniczak } else { 1652c65b673SSzymon Olewniczak return '@' . $value->getRawValue(); 1662c65b673SSzymon Olewniczak } 16786ba6958SSzymon Olewniczak } 16886ba6958SSzymon Olewniczak if ($column->isMulti()) { 16986ba6958SSzymon Olewniczak return implode(',', $value->getRawValue()); 17086ba6958SSzymon Olewniczak } else { 1712c65b673SSzymon Olewniczak return $value->getRawValue(); 1722c65b673SSzymon Olewniczak } 1732c65b673SSzymon Olewniczak } 17486ba6958SSzymon Olewniczak } 1752c65b673SSzymon Olewniczak return ''; 1762c65b673SSzymon Olewniczak }, 1772c65b673SSzymon Olewniczak $user_and_groups 1782c65b673SSzymon Olewniczak ); 1792c65b673SSzymon Olewniczak 180922aade7SSzymon Olewniczak $user_and_groups_set = array_map('trim', explode(',', $user_and_groups)); 181922aade7SSzymon Olewniczak $users = []; 182922aade7SSzymon Olewniczak $groups = []; 183922aade7SSzymon Olewniczak foreach ($user_and_groups_set as $user_or_group) { 184922aade7SSzymon Olewniczak if ($user_or_group[0] == '@') { 185922aade7SSzymon Olewniczak $groups[] = substr($user_or_group, 1); 186922aade7SSzymon Olewniczak } else { 187922aade7SSzymon Olewniczak $users[] = $user_or_group; 188a1f4c7baSSzymon Olewniczak } 189a1f4c7baSSzymon Olewniczak } 190922aade7SSzymon Olewniczak $set = []; 191922aade7SSzymon Olewniczak 192922aade7SSzymon Olewniczak $all_users = $auth->retrieveUsers(); 193922aade7SSzymon Olewniczak foreach ($all_users as $user => $info) { 194922aade7SSzymon Olewniczak if (in_array($user, $users)) { 195922aade7SSzymon Olewniczak $set[$user] = $info; 196922aade7SSzymon Olewniczak } elseif (array_intersect($groups, $info['grps'])) { 197922aade7SSzymon Olewniczak $set[$user] = $info; 198922aade7SSzymon Olewniczak } 199922aade7SSzymon Olewniczak } 200922aade7SSzymon Olewniczak 201922aade7SSzymon Olewniczak return $set; 202922aade7SSzymon Olewniczak } 203922aade7SSzymon Olewniczak 204922aade7SSzymon Olewniczak protected function predicateTrue($date, $operator, $days) { 205922aade7SSzymon Olewniczak $date = date('Y-m-d', strtotime($date)); 206922aade7SSzymon Olewniczak 207922aade7SSzymon Olewniczak switch ($operator) { 208922aade7SSzymon Olewniczak case 'before': 209922aade7SSzymon Olewniczak $days = date('Y-m-d', strtotime("+$days days")); 210922aade7SSzymon Olewniczak return $days >= $date; 211922aade7SSzymon Olewniczak case 'after': 212922aade7SSzymon Olewniczak $days = date('Y-m-d', strtotime("-$days days")); 213922aade7SSzymon Olewniczak return $date <= $days; 214922aade7SSzymon Olewniczak default: 215922aade7SSzymon Olewniczak return false; 216922aade7SSzymon Olewniczak } 217a1f4c7baSSzymon Olewniczak } 218a1f4c7baSSzymon Olewniczak 219ac63f65fSSzymon Olewniczak protected function replacePlaceholders($message, $values) { 220ac63f65fSSzymon Olewniczak $patterns = []; 221ac63f65fSSzymon Olewniczak $replacements = []; 222ac63f65fSSzymon Olewniczak /* @var Value $value */ 223ac63f65fSSzymon Olewniczak foreach ($values as $value) { 224ac63f65fSSzymon Olewniczak $schema = $value->getColumn()->getTable(); 225ac63f65fSSzymon Olewniczak $label = $value->getColumn()->getLabel(); 226ac63f65fSSzymon Olewniczak $patterns[] = "/@@$schema.$label@@/"; 227ac63f65fSSzymon Olewniczak $replacements[] = $value->getDisplayValue(); 228ac63f65fSSzymon Olewniczak } 229ac63f65fSSzymon Olewniczak 230ac63f65fSSzymon Olewniczak return preg_replace($patterns, $replacements, $message); 231ac63f65fSSzymon Olewniczak } 232ac63f65fSSzymon Olewniczak 233a1f4c7baSSzymon Olewniczak} 234a1f4c7baSSzymon Olewniczak 235