1<?php 2 3use \dokuwiki\plugin\bez; 4 5if(!defined('DOKU_INC')) die(); 6 7define('BEZ_NOTIFICATIONS_COOKIE_NAME', 'bez_notifications'); 8 9class action_plugin_bez_default extends action_plugin_bez_base { 10 11 protected $action = ''; 12 protected $params = array(); 13 14 protected $notifications = array(); 15 16 protected $errors = array(); 17 18 public function get_action() { 19 return $this->action; 20 } 21 22 public function get_param($id, $default='') { 23 return (isset($this->params[$id]) ? $this->params[$id] : $default); 24 } 25 26 private function add_notification($value, $header=NULL) { 27 if (isset($_COOKIE[BEZ_NOTIFICATIONS_COOKIE_NAME])) { 28 $notifs = unserialize($_COOKIE[BEZ_NOTIFICATIONS_COOKIE_NAME]); 29 } else { 30 $notifs = array(); 31 } 32 $notifs[] = array('value' => $value, 'header' => $header); 33 setcookie(BEZ_NOTIFICATIONS_COOKIE_NAME, serialize($notifs)); 34 } 35 36 private function flush_notifications() { 37 if (!isset($_COOKIE[BEZ_NOTIFICATIONS_COOKIE_NAME])) { 38 return array(); 39 } 40 $this->notifications = unserialize($_COOKIE[BEZ_NOTIFICATIONS_COOKIE_NAME]); 41 42 //remove cookie 43 setcookie(BEZ_NOTIFICATIONS_COOKIE_NAME, serialize(array())); 44 } 45 46 private function add_error($value, $header=NULL) { 47 $this->errors[] = array('value' => $value, 'header' => $header); 48 } 49 50 /** 51 * Register its handlers with the DokuWiki's event controller 52 */ 53 public function register(Doku_Event_Handler $controller) 54 { 55 $controller->register_hook('DOKUWIKI_STARTED', 'BEFORE', $this, 'setup_id'); 56 $controller->register_hook('DOKUWIKI_STARTED', 'AFTER', $this, 'setup_enviroment'); 57 $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'action_act_preprocess'); 58 $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, 'tpl_act_render'); 59 $controller->register_hook('TEMPLATE_PAGETOOLS_DISPLAY', 'BEFORE', $this, 'tpl_pagetools_display'); 60 $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'include_dependencies', array()); 61 $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this,'_ajax_call'); 62 63 $controller->register_hook('PLUGIN_NOTIFICATION_REGISTER_SOURCE', 'AFTER', $this, 'add_notifications_source'); 64 $controller->register_hook('PLUGIN_NOTIFICATION_GATHER', 'AFTER', $this, 'add_notifications'); 65 $controller->register_hook('PLUGIN_NOTIFICATION_CACHE_DEPENDENCIES', 'AFTER', $this, 'add_notification_cache_dependencies'); 66 } 67 68 public function include_dependencies(Doku_Event $event) { 69 // Adding a stylesheet 70 $event->data["link"][] = array ( 71 "type" => "text/css", 72 "rel" => "stylesheet", 73 "href" => DOKU_BASE. 74 "lib/plugins/bez/lib/jquery.timepicker-1.11.9-0/jquery.timepicker.css", 75 ); 76 77 // Adding a JavaScript File 78 $event->data["script"][] = array ( 79 "type" => "text/javascript", 80 "src" => DOKU_BASE. 81 "lib/plugins/bez/lib/jquery.timepicker-1.11.9-0/jquery.timepicker.min.js", 82 "defer" => "defer", 83 "_data" => "", 84 ); 85 86 // Adding a JavaScript File 87 $event->data["script"][] = array ( 88 "type" => "text/javascript", 89 "src" => DOKU_BASE. 90 "lib/plugins/bez/lib/jquery.datepair/datepair.js", 91 "defer" => "defer", 92 "_data" => "", 93 ); 94 95 // Adding a JavaScript File 96 $event->data["script"][] = array ( 97 "type" => "text/javascript", 98 "src" => DOKU_BASE. 99 "lib/plugins/bez/lib/jquery.datepair/jquery.datepair.js", 100 "defer" => "defer", 101 "_data" => "", 102 ); 103 104 $event->data["link"][] = array ( 105 "type" => "text/css", 106 "rel" => "stylesheet", 107 "href" => DOKU_BASE. 108 "lib/plugins/bez/lib/jquery.form-validator/theme-default.min.css", 109 ); 110 111 112 $event->data["script"][] = array ( 113 "type" => "text/javascript", 114 "src" => DOKU_BASE. 115 "lib/plugins/bez/lib/jquery.form-validator/jquery.form-validator.min.js", 116 "defer" => "defer", 117 "_data" => "", 118 ); 119 } 120 121 public function setup_id(Doku_Event $event, $param) { 122 global $INFO, $ID; 123 124 $id = $_GET['id']; 125 $ex = explode(':', $id); 126 127 //check if we process BEZ 128 if ($ex[0] !== 'bez' && $ex[1] !== 'bez') { 129 return; 130 } 131 132 $INFO['id'] = $id; 133 $ID = $id; 134 } 135 136 public function setup_enviroment(Doku_Event $event, $param) { 137 global $ACT, $conf, $ID; 138 139 if ($ACT !== 'show') { 140 return; 141 } 142 143 $ex = explode(':', $ID); 144 145 //check if we process BEZ 146 if ($ex[0] !== 'bez' && $ex[1] !== 'bez') { 147 return; 148 } 149 150 if ($ex[1] === 'bez') { 151 //pl is default language 152 if ($ex[0] == 'pl') { 153 //throw out "pl" and "bez" 154 array_shift($ex); 155 array_shift($ex); 156 157 $url = call_user_func_array(array($this, 'url'), $ex); 158 header("Location: $url"); 159 } 160 $conf['lang'] = array_shift($ex); 161 162 $this->localised = false; 163 } 164 //throw out "bez" 165 array_shift($ex); 166 167 $this->action = array_shift($ex); 168 169 if (count($ex) % 2 !== 0) { 170 throw new Exception('invalid params'); 171 } 172 173 for ($i = 0; $i < count($ex); $i += 2) { 174 $this->params[$ex[$i]] = $ex[$i+1]; 175 } 176 177 $this->setupLocale(); 178 $this->createObjects(); 179 180// if (empty($conf['baseurl'])) { 181// msg($this->getLang('info set baseurl')); 182// } 183 } 184 185 /** 186 * handle ajax requests 187 */ 188 public function _ajax_call(Doku_Event $event, $param) { 189 global $auth; 190 if ($event->data !== 'plugin_bez') { 191 return; 192 } 193 //no other ajax call handlers needed 194 $event->stopPropagation(); 195 $event->preventDefault(); 196 197 } 198 199 public function tpl_pagetools_display(Doku_Event $event, $param) { 200 if ($this->action !== '') { 201 $event->preventDefault(); 202 } 203 } 204 205 protected $prevent_rendering = false; 206 207 public function action_act_preprocess(Doku_Event $event, $param) 208 { 209 global $conf; 210 211 if ($this->action === '') { 212 return; 213 } 214 215 $event->preventDefault(); 216 try { 217 $this->flush_notifications(); 218 219 $ctl = DOKU_PLUGIN."bez/ctl/".str_replace('/', '', $this->action).".php"; 220 221 if (file_exists($ctl)) { 222 include $ctl; 223 } 224 } catch(bez\meta\ValidationException $e) { 225 foreach ($e->get_errors() as $field => $error_code) { 226 $lang = $this->getLang($field); 227 if ($lang != '') { 228 $field = $lang; 229 } 230 $this->add_error( 231 $this->getLang('validate_' . $error_code), 232 $field); 233 } 234 235 $this->tpl->set_values($_POST); 236 237 } catch(bez\meta\PermissionDeniedException $e) { 238 dbglog('plugin_bez', $e); 239 header('Location: ' . DOKU_URL . 'doku.php?id=' . $_GET['id'] . '&do=login'); 240// } catch (\PHPMailer\PHPMailer\Exception $e) { 241// msg($e->getMessage(), -1); 242 } catch(Exception $e) { 243 dbglog('plugin_bez', $e); 244 if ($conf['allowdebug']) { 245 dbg($e); 246 } else { 247 msg($e->getMessage(), -1); 248 } 249 $this->prevent_rendering = true; 250 } 251 } 252 253 public function tpl_act_render($event, $param) 254 { 255 global $conf; 256 257 if ($this->action === '') { 258 return false; 259 } 260 $event->preventDefault(); 261 262 if ($this->prevent_rendering) return; 263 264 try { 265 266 foreach ($this->errors as $error) { 267 echo '<div class="error">'; 268 if ($error['header'] === NULL) { 269 echo $error['value']; 270 } else { 271 echo '<strong>'.$error['header'].'</strong>: '.$error['value']; 272 } 273 echo '</div>'; 274 } 275 276 foreach ($this->notifications as $note) { 277 echo '<div class="info">'; 278 if ($note['header'] === NULL) { 279 echo $note['value']; 280 } else { 281 echo $note['header'].': <strong>'.$note['value'].'</strong>'; 282 } 283 echo '</div>'; 284 } 285 286 $this->bez_tpl_include(str_replace('/', '', $this->get_action())); 287 288 } catch(bez\meta\PermissionDeniedException $e) { 289 dbglog('plugin_bez', $e); 290 } catch(Exception $e) { 291 /*exception*/ 292 dbglog('plugin_bez', $e); 293 if ($conf['allowdebug']) { 294 dbg($e); 295 } 296 } 297 } 298 299 public function add_notifications_source(Doku_Event $event) 300 { 301 $event->data[] = 'bez:problems_without_tasks'; 302 $event->data[] = 'bez:problems_coming'; 303 $event->data[] = 'bez:problems_outdated'; 304 $event->data[] = 'bez:tasks_coming'; 305 $event->data[] = 'bez:tasks_outdated'; 306 } 307 308 public function add_notification_cache_dependencies(Doku_Event $event) 309 { 310 if (!preg_grep('/^bez:.*/', $event->data['plugins'])) return; 311 312 /** @var \helper_plugin_bez_db $db_helper */ 313 $db_helper = plugin_load('helper', 'bez_db'); 314 $event->data['dependencies'][] = $db_helper->getDB()->getAdapter()->getDbFile(); 315 } 316 317 public function add_notifications(Doku_Event $event) 318 { 319 if (!preg_grep('/^bez:.*/', $event->data['plugins'])) return; 320 321 $user = $event->data['user']; 322 $this->createObjects(true); 323 324 if (in_array('bez:problems_without_tasks', $event->data['plugins'])) { 325 $threads = $this->get_model()->factory('thread')->get_all(array( 326 'type' => 'issue', 327 'task_count' => '0', 328 'state' => 'opened', 329 'coordinator' => $user 330 )); 331 $now = new DateTime('now', new DateTimeZone('Europe/Warsaw')); 332 $tomorrow = $now->add(new DateInterval('P1D')); 333 334 /** @var bez\mdl\Thread $thread */ 335 foreach ($threads as $thread) { 336 $givenDate = new DateTime($thread->last_activity_date); 337 338 if ($givenDate >= $tomorrow) { // prevent cold start problem 339 $link = '<a href="' . $this->url('thread', 'id', $thread->id) . '">'; 340 $link .= '#' . $thread->id; 341 $link .= '</a>'; 342 343 $full = sprintf($this->getLang('notification problems_without_tasks'), $link); 344 $event->data['notifications'][] = [ 345 'plugin' => 'bez:problems_without_tasks', 346 'id' => 'thread:' . $thread->id . ':without_tasks:' . $thread->last_activity_date, 347 'full' => $full, 348 'brief' => $link, 349 'timestamp' => strtotime($thread->last_activity_date) 350 ]; 351 } 352 } 353 } 354 355 if (in_array('bez:problems_coming', $event->data['plugins'])) { 356 $threads = $this->get_model()->factory('thread')->get_all(array( 357 'type' => 'issue', 358 'priority' => '1', 359 'coordinator' => $user 360 )); 361 /** @var bez\mdl\Thread $thread */ 362 foreach ($threads as $thread) { 363 $link = '<a href="' . $this->url('thread', 'id', $thread->id) . '">'; 364 $link .= '#' . $thread->id; 365 $link .= '</a>'; 366 367 $full = sprintf($this->getLang('notification problems_coming'), $link); 368 $event->data['notifications'][] = [ 369 'plugin' => 'bez:problems_coming', 370 'id' => 'thread:' . $thread->id . ':coming:' . $thread->last_activity_date, 371 'full' => $full, 372 'brief' => $link, 373 'timestamp' => strtotime($thread->last_activity_date) 374 ]; 375 } 376 } 377 378 if (in_array('bez:problems_outdated', $event->data['plugins'])) { 379 $threads = $this->get_model()->threadFactory->get_all(array( 380 'type' => 'issue', 381 'priority' => '2', 382 'coordinator' => $user 383 )); 384 /** @var bez\mdl\Thread $thread */ 385 foreach ($threads as $thread) { 386 $link = '<a href="' . $this->url('thread', 'id', $thread->id) . '">'; 387 $link .= '#' . $thread->id; 388 $link .= '</a>'; 389 390 $full = sprintf($this->getLang('notification problems_outdated'), $link); 391 $event->data['notifications'][] = [ 392 'plugin' => 'bez:problems_outdated', 393 'id' => 'thread:' . $thread->id . ':outdated:' . $thread->last_activity_date, 394 'full' => $full, 395 'brief' => $link, 396 'timestamp' => strtotime($thread->last_activity_date) 397 ]; 398 } 399 } 400 401 if (in_array('bez:tasks_coming', $event->data['plugins'])) { 402 $tasks = $this->get_model()->factory('task')->get_all(array( 403 'priority' => '1', 404 'assignee' => $user 405 )); 406 /** @var bez\mdl\Thread $thread */ 407 foreach ($tasks as $task) { 408 $link = '<a href="' . $this->url('task', 'tid', $task->id) . '">'; 409 $link .= '#z' . $task->id; 410 $link .= '</a>'; 411 412 $full = sprintf($this->getLang('notification tasks_coming'), $link); 413 $event->data['notifications'][] = [ 414 'plugin' => 'bez:tasks_coming', 415 'id' => 'task:' . $task->id. ':coming:' . $task->plan_date, 416 'full' => $full, 417 'brief' => $link, 418 'timestamp' => strtotime($task->plan_date) 419 ]; 420 } 421 } 422 423 if (in_array('bez:tasks_outdated', $event->data['plugins'])) { 424 $tasks = $this->get_model()->factory('task')->get_all(array( 425 'priority' => '2', 426 'assignee' => $user 427 )); 428 /** @var bez\mdl\Thread $thread */ 429 foreach ($tasks as $task) { 430 $link = '<a href="' . $this->url('task', 'tid', $task->id) . '">'; 431 $link .= '#z' . $task->id; 432 $link .= '</a>'; 433 434 $full = sprintf($this->getLang('notification tasks_outdated'), $link); 435 $event->data['notifications'][] = [ 436 'plugin' => 'bez:tasks_outdated', 437 'id' => 'task:' . $task->id . ':outdated:' . $task->plan_date, 438 'full' => $full, 439 'brief' => $link, 440 'timestamp' => strtotime($task->plan_date) 441 ]; 442 } 443 } 444 } 445} 446