18a638198SSzymon Olewniczak<?php 28a638198SSzymon Olewniczak 38a638198SSzymon Olewniczaknamespace dokuwiki\plugin\bez\mdl; 48a638198SSzymon Olewniczak 58a638198SSzymon Olewniczakuse dokuwiki\plugin\bez\meta\Mailer; 68a638198SSzymon Olewniczakuse dokuwiki\plugin\bez\meta\PermissionDeniedException; 78a638198SSzymon Olewniczakuse dokuwiki\plugin\bez\meta\ValidationException; 88a638198SSzymon Olewniczak 98a638198SSzymon Olewniczakclass Task extends Entity { 108a638198SSzymon Olewniczak 118a638198SSzymon Olewniczak protected $id; 128a638198SSzymon Olewniczak 13e8827d73SSzymon Olewniczak protected $original_poster, $assignee, $closed_by; 148a638198SSzymon Olewniczak 158a638198SSzymon Olewniczak protected $private, $lock; 168a638198SSzymon Olewniczak 178a638198SSzymon Olewniczak protected $state, $type; 188a638198SSzymon Olewniczak 198a638198SSzymon Olewniczak protected $create_date, $last_activity_date, $last_modification_date, $close_date; 208a638198SSzymon Olewniczak 218a638198SSzymon Olewniczak protected $cost, $plan_date, $all_day_event, $start_time, $finish_time; 228a638198SSzymon Olewniczak 238a638198SSzymon Olewniczak protected $content, $content_html; 248a638198SSzymon Olewniczak 258a638198SSzymon Olewniczak protected $thread_id, $thread_comment_id, $task_program_id; 268a638198SSzymon Olewniczak 278a638198SSzymon Olewniczak /** @var \dokuwiki\plugin\bez\mdl\Thread */ 288a638198SSzymon Olewniczak protected $thread; 298a638198SSzymon Olewniczak 308a638198SSzymon Olewniczak /** @var Thread_comment */ 318a638198SSzymon Olewniczak protected $thread_comment; 328a638198SSzymon Olewniczak 338a638198SSzymon Olewniczak //virtual 34ff14b107SSzymon Olewniczak protected $task_program_name, $priority, $coordinator; 358a638198SSzymon Olewniczak 368a638198SSzymon Olewniczak public static function get_columns() { 378a638198SSzymon Olewniczak return array('id', 38e8827d73SSzymon Olewniczak 'original_poster', 'assignee', 'closed_by', 398a638198SSzymon Olewniczak 'private', 'lock', 408a638198SSzymon Olewniczak 'state', 'type', 418a638198SSzymon Olewniczak 'create_date', 'last_activity_date', 'last_modification_date', 'close_date', 428a638198SSzymon Olewniczak 'cost', 'plan_date', 'all_day_event', 'start_time', 'finish_time', 438a638198SSzymon Olewniczak 'content', 'content_html', 448a638198SSzymon Olewniczak 'thread_id', 'thread_comment_id', 'task_program_id'); 458a638198SSzymon Olewniczak } 468a638198SSzymon Olewniczak 47e8827d73SSzymon Olewniczak public static function get_types() { 48e8827d73SSzymon Olewniczak return array('correction', 'corrective', 'preventive', 'program'); 49e8827d73SSzymon Olewniczak } 50e8827d73SSzymon Olewniczak 51e8827d73SSzymon Olewniczak public static function get_states() { 52e8827d73SSzymon Olewniczak return array('opened', 'done'); 53e8827d73SSzymon Olewniczak } 54e8827d73SSzymon Olewniczak 558a638198SSzymon Olewniczak public function __get($property) { 56ff14b107SSzymon Olewniczak if ($property == 'thread') { 57ff14b107SSzymon Olewniczak if ($this->thread_id == null) { 58ff14b107SSzymon Olewniczak return null; 59ff14b107SSzymon Olewniczak } 60ff14b107SSzymon Olewniczak if ($this->thread == null) { 61ff14b107SSzymon Olewniczak $this->thread = $this->model->threadFactory->get_one($this->thread_id); 62ff14b107SSzymon Olewniczak } 63ff14b107SSzymon Olewniczak return $this->thread; 64ff14b107SSzymon Olewniczak 65ff14b107SSzymon Olewniczak } elseif($property == 'thread_comment') { 66ff14b107SSzymon Olewniczak if ($this->thread_comment_id == null) { 67ff14b107SSzymon Olewniczak return null; 68ff14b107SSzymon Olewniczak } 69ff14b107SSzymon Olewniczak if ($this->thread_comment == null) { 7053df74e7SSzymon Olewniczak $this->thread_comment = $this->model->thread_commentFactory->get_one($this->thread_comment_id); 71ff14b107SSzymon Olewniczak } 72ff14b107SSzymon Olewniczak return $this->thread_comment; 73ff14b107SSzymon Olewniczak 74ff14b107SSzymon Olewniczak } elseif($property == 'priority' || $property == 'coordinator' || $property == 'task_program_name') { 758a638198SSzymon Olewniczak return $this->$property; 768a638198SSzymon Olewniczak } 778a638198SSzymon Olewniczak return parent::__get($property); 788a638198SSzymon Olewniczak } 798a638198SSzymon Olewniczak 808a638198SSzymon Olewniczak public function __construct($model, $defaults=array()) { 818a638198SSzymon Olewniczak parent::__construct($model, $defaults); 828a638198SSzymon Olewniczak 83a0cd8c78SSzymon Olewniczak //virutal ACL columns (not in select) 84a0cd8c78SSzymon Olewniczak $this->acl->add_column('participants'); 85a0cd8c78SSzymon Olewniczak 868a638198SSzymon Olewniczak $this->validator->set_rules(array( 878a638198SSzymon Olewniczak 'assignee' => array(array('dw_user'), 'NOT NULL'), 888a638198SSzymon Olewniczak 'cost' => array(array('numeric'), 'NULL'), 898a638198SSzymon Olewniczak 'plan_date' => array(array('iso_date'), 'NOT NULL'), 908a638198SSzymon Olewniczak 'all_day_event' => array(array('select', array('0', '1')), 'NOT NULL'), 918a638198SSzymon Olewniczak 'start_time' => array(array('time'), 'NULL'), 928a638198SSzymon Olewniczak 'finish_time' => array(array('time'), 'NULL'), 938a638198SSzymon Olewniczak 'content' => array(array('length', 10000), 'NOT NULL'), 94e8827d73SSzymon Olewniczak 'thread_comment_id' => array(array('numeric'), 'NULL'), 958a638198SSzymon Olewniczak 'task_program_id' => array(array('numeric'), 'NULL') 968a638198SSzymon Olewniczak )); 978a638198SSzymon Olewniczak 988a638198SSzymon Olewniczak //we've created empty object 998a638198SSzymon Olewniczak if ($this->id === NULL) { 1008a638198SSzymon Olewniczak $this->original_poster = $this->model->user_nick; 1018a638198SSzymon Olewniczak $this->create_date = date('c'); 1028a638198SSzymon Olewniczak $this->last_activity_date = $this->create_date; 1038a638198SSzymon Olewniczak $this->last_modification_date = $this->create_date; 1048a638198SSzymon Olewniczak 1058a638198SSzymon Olewniczak $this->state = 'opened'; 1068a638198SSzymon Olewniczak 1078a638198SSzymon Olewniczak if (isset($defaults['thread'])) { 1088a638198SSzymon Olewniczak $this->thread = $defaults['thread']; 1098a638198SSzymon Olewniczak $this->thread_id = $this->thread->id; 11053df74e7SSzymon Olewniczak $this->coordinator = $this->thread->coordinator; 1118a638198SSzymon Olewniczak $this->type = 'correction'; 1128a638198SSzymon Olewniczak 1138a638198SSzymon Olewniczak if (isset($defaults['thread_comment'])) { 1148a638198SSzymon Olewniczak $this->thread_comment = $defaults['thread_comment']; 1158a638198SSzymon Olewniczak $this->thread_comment_id = $this->thread_comment->id; 116e8827d73SSzymon Olewniczak 117e8827d73SSzymon Olewniczak if ($this->thread_comment->type == 'cause_real') { 1188a638198SSzymon Olewniczak $this->type = 'corrective'; 119e8827d73SSzymon Olewniczak } else { 120e8827d73SSzymon Olewniczak $this->type = 'preventive'; 121e8827d73SSzymon Olewniczak } 1228a638198SSzymon Olewniczak } 123ff14b107SSzymon Olewniczak } else { 124ff14b107SSzymon Olewniczak $this->type = 'program'; 1258a638198SSzymon Olewniczak } 126a0cd8c78SSzymon Olewniczak 127a0cd8c78SSzymon Olewniczak //everyone can report their own program tasks 128a0cd8c78SSzymon Olewniczak if ($this->type == 'program') { 129a0cd8c78SSzymon Olewniczak $this->acl->grant('content', BEZ_PERMISSION_CHANGE); 130a0cd8c78SSzymon Olewniczak $this->acl->grant('plan_date', BEZ_PERMISSION_CHANGE); 131a0cd8c78SSzymon Olewniczak $this->acl->grant('start_time', BEZ_PERMISSION_CHANGE); 132a0cd8c78SSzymon Olewniczak $this->acl->grant('finish_time', BEZ_PERMISSION_CHANGE); 133a0cd8c78SSzymon Olewniczak $this->acl->grant('all_day_event', BEZ_PERMISSION_CHANGE); 134a0cd8c78SSzymon Olewniczak $this->acl->grant('task_program_id', BEZ_PERMISSION_CHANGE); 135a0cd8c78SSzymon Olewniczak $this->acl->grant('cost', BEZ_PERMISSION_CHANGE); 136a0cd8c78SSzymon Olewniczak } 137a0cd8c78SSzymon Olewniczak 138a0cd8c78SSzymon Olewniczak if ($this->type == 'program' && $this->model->get_level() >= BEZ_AUTH_LEADER) { 139a0cd8c78SSzymon Olewniczak $this->acl->grant('assignee', BEZ_PERMISSION_CHANGE); 140a0cd8c78SSzymon Olewniczak $this->acl->grant('participants', BEZ_PERMISSION_CHANGE); 141a0cd8c78SSzymon Olewniczak } 142a0cd8c78SSzymon Olewniczak 143a0cd8c78SSzymon Olewniczak if ($this->type != 'program' && $this->coordinator == $this->model->user_nick) { 144a0cd8c78SSzymon Olewniczak $this->acl->grant('content', BEZ_PERMISSION_CHANGE); 145a0cd8c78SSzymon Olewniczak $this->acl->grant('plan_date', BEZ_PERMISSION_CHANGE); 146a0cd8c78SSzymon Olewniczak $this->acl->grant('start_time', BEZ_PERMISSION_CHANGE); 147a0cd8c78SSzymon Olewniczak $this->acl->grant('finish_time', BEZ_PERMISSION_CHANGE); 148a0cd8c78SSzymon Olewniczak $this->acl->grant('all_day_event', BEZ_PERMISSION_CHANGE); 149a0cd8c78SSzymon Olewniczak $this->acl->grant('task_program_id', BEZ_PERMISSION_CHANGE); 150a0cd8c78SSzymon Olewniczak $this->acl->grant('cost', BEZ_PERMISSION_CHANGE); 151a0cd8c78SSzymon Olewniczak 152a0cd8c78SSzymon Olewniczak $this->acl->grant('assignee', BEZ_PERMISSION_CHANGE); 153a0cd8c78SSzymon Olewniczak $this->acl->grant('participants', BEZ_PERMISSION_CHANGE); 154a0cd8c78SSzymon Olewniczak } 155a0cd8c78SSzymon Olewniczak 156e8827d73SSzymon Olewniczak //we get object form db 157e8827d73SSzymon Olewniczak } else { 158e8827d73SSzymon Olewniczak if (isset($defaults['thread']) && $this->thread_id == $defaults['thread']->id) { 159e8827d73SSzymon Olewniczak $this->thread = $defaults['thread']; 160e8827d73SSzymon Olewniczak } 161e8827d73SSzymon Olewniczak 162e8827d73SSzymon Olewniczak if (isset($defaults['thread_comment']) && $this->thread_comment_id == $defaults['thread_comment']->id) { 163e8827d73SSzymon Olewniczak $this->thread_comment = $defaults['thread_comment']; 164e8827d73SSzymon Olewniczak } 165e8827d73SSzymon Olewniczak 166a0cd8c78SSzymon Olewniczak //user can close their tasks 167a0cd8c78SSzymon Olewniczak if ($this->assignee == $this->model->user_nick || $this->model->get_level() >= BEZ_AUTH_LEADER) { 168a0cd8c78SSzymon Olewniczak $this->acl->grant('state', BEZ_PERMISSION_CHANGE); 169a0cd8c78SSzymon Olewniczak } 170a0cd8c78SSzymon Olewniczak 171a0cd8c78SSzymon Olewniczak if ($this->type == 'program' && $this->original_poster == $this->model->user_nick) { 172a0cd8c78SSzymon Olewniczak $this->acl->grant('content', BEZ_PERMISSION_CHANGE); 173a0cd8c78SSzymon Olewniczak $this->acl->grant('plan_date', BEZ_PERMISSION_CHANGE); 174a0cd8c78SSzymon Olewniczak $this->acl->grant('start_time', BEZ_PERMISSION_CHANGE); 175a0cd8c78SSzymon Olewniczak $this->acl->grant('finish_time', BEZ_PERMISSION_CHANGE); 176a0cd8c78SSzymon Olewniczak $this->acl->grant('all_day_event', BEZ_PERMISSION_CHANGE); 177a0cd8c78SSzymon Olewniczak $this->acl->grant('task_program_id', BEZ_PERMISSION_CHANGE); 178a0cd8c78SSzymon Olewniczak $this->acl->grant('cost', BEZ_PERMISSION_CHANGE); 179a0cd8c78SSzymon Olewniczak } 180a0cd8c78SSzymon Olewniczak 181a0cd8c78SSzymon Olewniczak if (($this->type != 'program' && $this->coordinator == $this->model->user_nick) || 182a0cd8c78SSzymon Olewniczak ($this->model->get_level() >= BEZ_AUTH_LEADER)) { 183a0cd8c78SSzymon Olewniczak $this->acl->grant('content', BEZ_PERMISSION_CHANGE); 184a0cd8c78SSzymon Olewniczak $this->acl->grant('plan_date', BEZ_PERMISSION_CHANGE); 185a0cd8c78SSzymon Olewniczak $this->acl->grant('start_time', BEZ_PERMISSION_CHANGE); 186a0cd8c78SSzymon Olewniczak $this->acl->grant('finish_time', BEZ_PERMISSION_CHANGE); 187a0cd8c78SSzymon Olewniczak $this->acl->grant('all_day_event', BEZ_PERMISSION_CHANGE); 188a0cd8c78SSzymon Olewniczak $this->acl->grant('task_program_id', BEZ_PERMISSION_CHANGE); 189a0cd8c78SSzymon Olewniczak $this->acl->grant('cost', BEZ_PERMISSION_CHANGE); 190a0cd8c78SSzymon Olewniczak 191a0cd8c78SSzymon Olewniczak $this->acl->grant('assignee', BEZ_PERMISSION_CHANGE); 192a0cd8c78SSzymon Olewniczak $this->acl->grant('participants', BEZ_PERMISSION_CHANGE); 193*f7519ef1SSzymon Olewniczak $this->acl->grant('state', BEZ_PERMISSION_CHANGE); 194a0cd8c78SSzymon Olewniczak } 195e8827d73SSzymon Olewniczak } 1968a638198SSzymon Olewniczak 1978a638198SSzymon Olewniczak if ($this->thread_id == '') { 1988a638198SSzymon Olewniczak $this->validator->set_rules(array( 199e8827d73SSzymon Olewniczak 'task_program_id' => array(array('numeric'), 'NOT NULL'), 2008a638198SSzymon Olewniczak )); 201e8827d73SSzymon Olewniczak //this field is unused in program tasks 202e8827d73SSzymon Olewniczak $this->validator->delete_rule('thread_comment_id'); 2038a638198SSzymon Olewniczak } 2048a638198SSzymon Olewniczak } 2058a638198SSzymon Olewniczak 2068a638198SSzymon Olewniczak 2078a638198SSzymon Olewniczak public function set_data($post, $filter=NULL) { 208ff14b107SSzymon Olewniczak //all day event 209ff14b107SSzymon Olewniczak if (!isset($post['all_day_event'])) { 210ff14b107SSzymon Olewniczak $post['all_day_event'] = '0'; 211ff14b107SSzymon Olewniczak } 212ff14b107SSzymon Olewniczak 21353df74e7SSzymon Olewniczak parent::set_data($post); 21453df74e7SSzymon Olewniczak 21553df74e7SSzymon Olewniczak $this->content_html = p_render('xhtml',p_get_instructions($this->content), $ignore); 21653df74e7SSzymon Olewniczak 21753df74e7SSzymon Olewniczak if (!isset($post['assignee'])) { 21853df74e7SSzymon Olewniczak $this->assignee = $this->model->user_nick; 21953df74e7SSzymon Olewniczak } 22053df74e7SSzymon Olewniczak 22153df74e7SSzymon Olewniczak //update dates 22253df74e7SSzymon Olewniczak $this->last_modification_date = date('c'); 22353df74e7SSzymon Olewniczak $this->last_activity_date = $this->last_modification_date; 22453df74e7SSzymon Olewniczak 2258a638198SSzymon Olewniczak return true; 2268a638198SSzymon Olewniczak } 2278a638198SSzymon Olewniczak 228e8827d73SSzymon Olewniczak public function set_state($state) { 229e8827d73SSzymon Olewniczak if ($this->acl_of('state') < BEZ_PERMISSION_CHANGE) { 230e8827d73SSzymon Olewniczak throw new PermissionDeniedException(); 231e8827d73SSzymon Olewniczak } 232e8827d73SSzymon Olewniczak 233e8827d73SSzymon Olewniczak if (!in_array($state, array('opened', 'done'))) { 234e8827d73SSzymon Olewniczak throw new ValidationException('task', array('sholud be opened or done')); 235e8827d73SSzymon Olewniczak } 236e8827d73SSzymon Olewniczak 237e8827d73SSzymon Olewniczak //nothing to do 238e8827d73SSzymon Olewniczak if ($state == $this->state) { 239e8827d73SSzymon Olewniczak return; 240e8827d73SSzymon Olewniczak } 241e8827d73SSzymon Olewniczak 242e8827d73SSzymon Olewniczak if ($state == 'done') { 243e8827d73SSzymon Olewniczak $this->model->sqlite->query("UPDATE {$this->get_table_name()} SET state=?, closed_by=?, close_date=? WHERE id=?", 244e8827d73SSzymon Olewniczak $state, 245e8827d73SSzymon Olewniczak $this->model->user_nick, 246e8827d73SSzymon Olewniczak date('c'), 247e8827d73SSzymon Olewniczak $this->id); 248e8827d73SSzymon Olewniczak //reopen the task 249e8827d73SSzymon Olewniczak } else { 250e8827d73SSzymon Olewniczak $this->model->sqlite->query("UPDATE {$this->get_table_name()} SET state=? WHERE id=?", $state, $this->id); 251e8827d73SSzymon Olewniczak } 252e8827d73SSzymon Olewniczak 253e8827d73SSzymon Olewniczak $this->state = $state; 254e8827d73SSzymon Olewniczak } 255e8827d73SSzymon Olewniczak 256e8827d73SSzymon Olewniczak public function update_last_activity() { 257e8827d73SSzymon Olewniczak $this->last_activity_date = date('c'); 258e8827d73SSzymon Olewniczak $this->model->sqlite->query('UPDATE task SET last_activity_date=? WHERE id=?', 259e8827d73SSzymon Olewniczak $this->last_activity_date, $this->id); 260e8827d73SSzymon Olewniczak } 261e8827d73SSzymon Olewniczak 262*f7519ef1SSzymon Olewniczak public function can_add_comments() { 263*f7519ef1SSzymon Olewniczak if ($this->thread_id != '' && $this->thread->state == 'closed') { 264*f7519ef1SSzymon Olewniczak return false; 265*f7519ef1SSzymon Olewniczak } 266*f7519ef1SSzymon Olewniczak 267*f7519ef1SSzymon Olewniczak if ($this->state == 'opened' || 268*f7519ef1SSzymon Olewniczak ($this->state == 'done' && 269*f7519ef1SSzymon Olewniczak $this->acl_of('state') >= BEZ_PERMISSION_CHANGE)) { 270*f7519ef1SSzymon Olewniczak return true; 271*f7519ef1SSzymon Olewniczak } 272*f7519ef1SSzymon Olewniczak 273*f7519ef1SSzymon Olewniczak return false; 274*f7519ef1SSzymon Olewniczak } 275*f7519ef1SSzymon Olewniczak 276a0cd8c78SSzymon Olewniczak public function can_add_participants() { 277a0cd8c78SSzymon Olewniczak return in_array($this->state, array('opened')); 278a0cd8c78SSzymon Olewniczak } 279a0cd8c78SSzymon Olewniczak 280e8827d73SSzymon Olewniczak public function get_participants($filter='') { 281e8827d73SSzymon Olewniczak if ($this->id === NULL) { 282e8827d73SSzymon Olewniczak return array(); 283e8827d73SSzymon Olewniczak } 284e8827d73SSzymon Olewniczak 285e8827d73SSzymon Olewniczak $sql = 'SELECT * FROM task_participant WHERE'; 286e8827d73SSzymon Olewniczak $possible_flags = array('original_poster', 'assignee', 'commentator', 'subscribent'); 287e8827d73SSzymon Olewniczak if ($filter != '') { 288e8827d73SSzymon Olewniczak if (!in_array($filter, $possible_flags)) { 289e8827d73SSzymon Olewniczak throw new \Exception("unknown flag $filter"); 290e8827d73SSzymon Olewniczak } 291e8827d73SSzymon Olewniczak $sql .= " $filter=1 AND"; 292e8827d73SSzymon Olewniczak } 293e8827d73SSzymon Olewniczak $sql .= ' task_id=? ORDER BY user_id'; 294e8827d73SSzymon Olewniczak 295e8827d73SSzymon Olewniczak $r = $this->model->sqlite->query($sql, $this->id); 296e8827d73SSzymon Olewniczak $pars = $this->model->sqlite->res2arr($r); 297e8827d73SSzymon Olewniczak $participants = array(); 298e8827d73SSzymon Olewniczak foreach ($pars as $par) { 299e8827d73SSzymon Olewniczak $participants[$par['user_id']] = $par; 300e8827d73SSzymon Olewniczak } 301e8827d73SSzymon Olewniczak 302e8827d73SSzymon Olewniczak return $participants; 303e8827d73SSzymon Olewniczak } 304e8827d73SSzymon Olewniczak 305e8827d73SSzymon Olewniczak public function get_participant($user_id) { 306e8827d73SSzymon Olewniczak if ($this->id === NULL) { 307e8827d73SSzymon Olewniczak return array(); 308e8827d73SSzymon Olewniczak } 309e8827d73SSzymon Olewniczak 310e8827d73SSzymon Olewniczak $r = $this->model->sqlite->query('SELECT * FROM task_participant WHERE task_id=? AND user_id=?', $this->id, $user_id); 311e8827d73SSzymon Olewniczak $par = $this->model->sqlite->res2row($r); 312e8827d73SSzymon Olewniczak if (!is_array($par)) { 313e8827d73SSzymon Olewniczak return false; 314e8827d73SSzymon Olewniczak } 315e8827d73SSzymon Olewniczak 316e8827d73SSzymon Olewniczak return $par; 317e8827d73SSzymon Olewniczak } 318e8827d73SSzymon Olewniczak 319e8827d73SSzymon Olewniczak public function is_subscribent($user_id=null) { 320e8827d73SSzymon Olewniczak if ($user_id == null) { 321e8827d73SSzymon Olewniczak $user_id = $this->model->user_nick; 322e8827d73SSzymon Olewniczak } 323e8827d73SSzymon Olewniczak $par = $this->get_participant($user_id); 324e8827d73SSzymon Olewniczak if ($par['subscribent'] == 1) { 325e8827d73SSzymon Olewniczak return true; 326e8827d73SSzymon Olewniczak } 327e8827d73SSzymon Olewniczak return false; 328e8827d73SSzymon Olewniczak } 329e8827d73SSzymon Olewniczak 330e8827d73SSzymon Olewniczak public function remove_participant_flags($user_id, $flags) { 331e8827d73SSzymon Olewniczak //thread not saved yet 332e8827d73SSzymon Olewniczak if ($this->id === NULL) { 333e8827d73SSzymon Olewniczak throw new \Exception('cannot remove flags from not saved thread'); 334e8827d73SSzymon Olewniczak } 335e8827d73SSzymon Olewniczak 336e8827d73SSzymon Olewniczak $possible_flags = array('original_poster', 'assignee', 'commentator', 'subscribent'); 337e8827d73SSzymon Olewniczak if (array_intersect($flags, $possible_flags) != $flags) { 338e8827d73SSzymon Olewniczak throw new \Exception('unknown flags'); 339e8827d73SSzymon Olewniczak } 340e8827d73SSzymon Olewniczak 341e8827d73SSzymon Olewniczak $set = implode(',', array_map(function ($v) { return "$v=0"; }, $flags)); 342e8827d73SSzymon Olewniczak 343e8827d73SSzymon Olewniczak $sql = "UPDATE task_participant SET $set WHERE task_id=? AND user_id=?"; 344e8827d73SSzymon Olewniczak $this->model->sqlite->query($sql, $this->id, $user_id); 345e8827d73SSzymon Olewniczak 346e8827d73SSzymon Olewniczak } 347e8827d73SSzymon Olewniczak 348e8827d73SSzymon Olewniczak public function set_participant_flags($user_id, $flags=array()) { 349e8827d73SSzymon Olewniczak //thread not saved yet 350e8827d73SSzymon Olewniczak if ($this->id === NULL) { 351e8827d73SSzymon Olewniczak throw new \Exception('cannot add flags to not saved thread'); 352e8827d73SSzymon Olewniczak } 353e8827d73SSzymon Olewniczak 354e8827d73SSzymon Olewniczak //validate user 355e8827d73SSzymon Olewniczak if (!$this->model->userFactory->exists($user_id)) { 356e8827d73SSzymon Olewniczak throw new \Exception("$user_id isn't dokuwiki user"); 357e8827d73SSzymon Olewniczak } 358e8827d73SSzymon Olewniczak 359e8827d73SSzymon Olewniczak $possible_flags = array('original_poster', 'assignee', 'commentator', 'subscribent'); 360e8827d73SSzymon Olewniczak if (array_intersect($flags, $possible_flags) != $flags) { 361e8827d73SSzymon Olewniczak throw new \Exception('unknown flags'); 362e8827d73SSzymon Olewniczak } 363e8827d73SSzymon Olewniczak 364e8827d73SSzymon Olewniczak $participant = $this->get_participant($user_id); 365e8827d73SSzymon Olewniczak if ($participant == false) { 366e8827d73SSzymon Olewniczak $participant = array_fill_keys($possible_flags, 0); 367e8827d73SSzymon Olewniczak 368e8827d73SSzymon Olewniczak $participant['task_id'] = $this->id; 369e8827d73SSzymon Olewniczak $participant['user_id'] = $user_id; 370e8827d73SSzymon Olewniczak $participant['added_by'] = $this->model->user_nick; 371e8827d73SSzymon Olewniczak $participant['added_date'] = date('c'); 372e8827d73SSzymon Olewniczak } 373e8827d73SSzymon Olewniczak $values = array_merge($participant, array_fill_keys($flags, 1)); 374e8827d73SSzymon Olewniczak 375e8827d73SSzymon Olewniczak $keys = join(',', array_keys($values)); 376e8827d73SSzymon Olewniczak $vals = join(',', array_fill(0,count($values),'?')); 377e8827d73SSzymon Olewniczak 378e8827d73SSzymon Olewniczak $sql = "REPLACE INTO task_participant ($keys) VALUES ($vals)"; 379e8827d73SSzymon Olewniczak $this->model->sqlite->query($sql, array_values($values)); 380e8827d73SSzymon Olewniczak } 381e8827d73SSzymon Olewniczak 382e8827d73SSzymon Olewniczak public function invite($client) { 383e8827d73SSzymon Olewniczak $this->set_participant_flags($client, array('subscribent')); 384e8827d73SSzymon Olewniczak $this->mail_notify_invite($client); 385e8827d73SSzymon Olewniczak } 386e8827d73SSzymon Olewniczak 387a0cd8c78SSzymon Olewniczak private function mail_notify($replacements=array(), $users=false, $attachedImages=array()) { 3888a638198SSzymon Olewniczak $plain = io_readFile($this->model->action->localFN('task-notification')); 3898a638198SSzymon Olewniczak $html = io_readFile($this->model->action->localFN('task-notification', 'html')); 3908a638198SSzymon Olewniczak 391e8827d73SSzymon Olewniczak $task_link = $this->model->action->url('task', 'tid', $this->id); 3928a638198SSzymon Olewniczak 3938a638198SSzymon Olewniczak $reps = array( 3948a638198SSzymon Olewniczak 'task_id' => $this->id, 3958a638198SSzymon Olewniczak 'task_link' => $task_link, 396e8827d73SSzymon Olewniczak 'who' => $this->original_poster 3978a638198SSzymon Olewniczak ); 3988a638198SSzymon Olewniczak 3998a638198SSzymon Olewniczak //$replacements can override $reps 4008a638198SSzymon Olewniczak $rep = array_merge($reps, $replacements); 4018a638198SSzymon Olewniczak 4028a638198SSzymon Olewniczak if (!isset($rep['who_full_name'])) { 4038a638198SSzymon Olewniczak $rep['who_full_name'] = 404e8827d73SSzymon Olewniczak $this->model->userFactory->get_user_full_name($rep['who']); 4058a638198SSzymon Olewniczak } 4068a638198SSzymon Olewniczak 4078a638198SSzymon Olewniczak //auto title 4088a638198SSzymon Olewniczak if (!isset($rep['subject'])) { 4098a638198SSzymon Olewniczak// if (isset($rep['content'])) { 4108a638198SSzymon Olewniczak// $rep['subject'] = array_shift(explode('.', $rep['content'], 2)); 4118a638198SSzymon Olewniczak// } 412e8827d73SSzymon Olewniczak $rep['subject'] = '#z'.$this->id. ' ' . $this->task_program_name; 4138a638198SSzymon Olewniczak } 4148a638198SSzymon Olewniczak 4158a638198SSzymon Olewniczak //we must do it manually becouse Mailer uses htmlspecialchars() 4168a638198SSzymon Olewniczak $html = str_replace('@TASK_TABLE@', $rep['task_table'], $html); 4178a638198SSzymon Olewniczak 418e8827d73SSzymon Olewniczak $mailer = new Mailer(); 4198a638198SSzymon Olewniczak $mailer->setBody($plain, $rep, $rep, $html, false); 4208a638198SSzymon Olewniczak 4218a638198SSzymon Olewniczak if ($users === FALSE) { 422e8827d73SSzymon Olewniczak $users = $this->get_participants('subscribent'); 4238a638198SSzymon Olewniczak 4248a638198SSzymon Olewniczak //don't notify current user 4258a638198SSzymon Olewniczak unset($users[$this->model->user_nick]); 4268a638198SSzymon Olewniczak } 4278a638198SSzymon Olewniczak 4288a638198SSzymon Olewniczak $emails = array_map(function($user) { 42920e189b9SSzymon Olewniczak if (is_array($user)) { 43020e189b9SSzymon Olewniczak $user = $user['user_id']; 43120e189b9SSzymon Olewniczak } 43220e189b9SSzymon Olewniczak return $this->model->userFactory->get_user_email($user); 4338a638198SSzymon Olewniczak }, $users); 4348a638198SSzymon Olewniczak 4358a638198SSzymon Olewniczak $mailer->to($emails); 4368a638198SSzymon Olewniczak $mailer->subject($rep['subject']); 4378a638198SSzymon Olewniczak 438a0cd8c78SSzymon Olewniczak //add images 439a0cd8c78SSzymon Olewniczak foreach ($attachedImages as $img) { 440a0cd8c78SSzymon Olewniczak $mailer->attachFile($img['path'], $img['mime'], $img['name'], $img['embed']); 441a0cd8c78SSzymon Olewniczak } 442a0cd8c78SSzymon Olewniczak 4438a638198SSzymon Olewniczak $send = $mailer->send(); 4448a638198SSzymon Olewniczak if ($send === false) { 4458a638198SSzymon Olewniczak //this may mean empty $emails 4468a638198SSzymon Olewniczak //throw new Exception("can't send email"); 4478a638198SSzymon Olewniczak } 4488a638198SSzymon Olewniczak } 4498a638198SSzymon Olewniczak 450e8827d73SSzymon Olewniczak protected function bez_html_array_to_style_list($arr) { 451e8827d73SSzymon Olewniczak $output = ''; 452e8827d73SSzymon Olewniczak foreach ($arr as $k => $v) { 453e8827d73SSzymon Olewniczak $output .= $k.': '. $v . ';'; 4548a638198SSzymon Olewniczak } 455e8827d73SSzymon Olewniczak return $output; 456e8827d73SSzymon Olewniczak } 457e8827d73SSzymon Olewniczak 458e8827d73SSzymon Olewniczak protected function bez_html_irrtable($style) { 459e8827d73SSzymon Olewniczak $argv = func_get_args(); 460e8827d73SSzymon Olewniczak $argc = func_num_args(); 461e8827d73SSzymon Olewniczak if (isset($style['table'])) { 462e8827d73SSzymon Olewniczak $output = '<table style="'.self::bez_html_array_to_style_list($style['table']).'">'; 463e8827d73SSzymon Olewniczak } else { 464e8827d73SSzymon Olewniczak $output = '<table>'; 465e8827d73SSzymon Olewniczak } 466e8827d73SSzymon Olewniczak 467e8827d73SSzymon Olewniczak $tr_style = ''; 468e8827d73SSzymon Olewniczak if (isset($style['tr'])) { 469e8827d73SSzymon Olewniczak $tr_style = 'style="'.self::bez_html_array_to_style_list($style['tr']).'"'; 470e8827d73SSzymon Olewniczak } 471e8827d73SSzymon Olewniczak 472e8827d73SSzymon Olewniczak $td_style = ''; 473e8827d73SSzymon Olewniczak if (isset($style['td'])) { 474e8827d73SSzymon Olewniczak $td_style = 'style="'.self::bez_html_array_to_style_list($style['td']).'"'; 475e8827d73SSzymon Olewniczak } 476e8827d73SSzymon Olewniczak 477e8827d73SSzymon Olewniczak $row_max = 0; 478e8827d73SSzymon Olewniczak 479e8827d73SSzymon Olewniczak for ($i = 1; $i < $argc; $i++) { 480e8827d73SSzymon Olewniczak $row = $argv[$i]; 481e8827d73SSzymon Olewniczak $c = count($row); 482e8827d73SSzymon Olewniczak if ($c > $row_max) { 483e8827d73SSzymon Olewniczak $row_max = $c; 484e8827d73SSzymon Olewniczak } 485e8827d73SSzymon Olewniczak } 486e8827d73SSzymon Olewniczak 487e8827d73SSzymon Olewniczak for ($j = 1; $j < $argc; $j++) { 488e8827d73SSzymon Olewniczak $row = $argv[$j]; 489e8827d73SSzymon Olewniczak $output .= '<tr '.$tr_style.'>' . NL; 490e8827d73SSzymon Olewniczak $c = count($row); 491e8827d73SSzymon Olewniczak for ($i = 0; $i < $c; $i++) { 492e8827d73SSzymon Olewniczak //last element 493e8827d73SSzymon Olewniczak if ($i === $c - 1 && $c < $row_max) { 494e8827d73SSzymon Olewniczak $output .= '<td '.$td_style.' colspan="' . ( $row_max - $c + 1 ) . '">' . NL; 495e8827d73SSzymon Olewniczak } else { 496e8827d73SSzymon Olewniczak $output .= '<td '.$td_style.'>' . NL; 497e8827d73SSzymon Olewniczak } 498e8827d73SSzymon Olewniczak $output .= $row[$i] . NL; 499e8827d73SSzymon Olewniczak $output .= '</td>' . NL; 500e8827d73SSzymon Olewniczak } 501e8827d73SSzymon Olewniczak $output .= '</tr>' . NL; 502e8827d73SSzymon Olewniczak } 503e8827d73SSzymon Olewniczak $output .= '</table>' . NL; 504e8827d73SSzymon Olewniczak return $output; 505e8827d73SSzymon Olewniczak } 506e8827d73SSzymon Olewniczak 507e8827d73SSzymon Olewniczak public function mail_notify_task_box($users=false, $replacements=array()) { 5088a638198SSzymon Olewniczak $top_row = array( 5098a638198SSzymon Olewniczak '<strong>'.$this->model->action->getLang('executor').': </strong>' . 510e8827d73SSzymon Olewniczak $this->model->userFactory->get_user_full_name($this->assignee), 5118a638198SSzymon Olewniczak 5128a638198SSzymon Olewniczak '<strong>'.$this->model->action->getLang('reporter').': </strong>' . 513e8827d73SSzymon Olewniczak $this->model->userFactory->get_user_full_name($this->original_poster) 5148a638198SSzymon Olewniczak ); 5158a638198SSzymon Olewniczak 516e8827d73SSzymon Olewniczak if ($this->task_program_name != '') { 5178a638198SSzymon Olewniczak $top_row[] = 5188a638198SSzymon Olewniczak '<strong>'.$this->model->action->getLang('task_type').': </strong>' . 519e8827d73SSzymon Olewniczak $this->task_program_name; 5208a638198SSzymon Olewniczak } 5218a638198SSzymon Olewniczak 5228a638198SSzymon Olewniczak if ($this->cost != '') { 5238a638198SSzymon Olewniczak $top_row[] = 5248a638198SSzymon Olewniczak '<strong>'.$this->model->action->getLang('cost').': </strong>' . 5258a638198SSzymon Olewniczak $this->cost; 5268a638198SSzymon Olewniczak } 5278a638198SSzymon Olewniczak 5288a638198SSzymon Olewniczak //BOTTOM ROW 5298a638198SSzymon Olewniczak $bottom_row = array( 5308a638198SSzymon Olewniczak '<strong>'.$this->model->action->getLang('plan_date').': </strong>' . 5318a638198SSzymon Olewniczak $this->plan_date 5328a638198SSzymon Olewniczak ); 5338a638198SSzymon Olewniczak 5348a638198SSzymon Olewniczak if ($this->all_day_event == '0') { 5358a638198SSzymon Olewniczak $bottom_row[] = 5368a638198SSzymon Olewniczak '<strong>'.$this->model->action->getLang('start_time').': </strong>' . 5378a638198SSzymon Olewniczak $this->start_time; 5388a638198SSzymon Olewniczak $bottom_row[] = 5398a638198SSzymon Olewniczak '<strong>'.$this->model->action->getLang('finish_time').': </strong>' . 5408a638198SSzymon Olewniczak $this->finish_time; 5418a638198SSzymon Olewniczak } 5428a638198SSzymon Olewniczak 543a0cd8c78SSzymon Olewniczak $info = array(); 544a0cd8c78SSzymon Olewniczak $content_html = p_render('bez_xhtmlmail', p_get_instructions($this->content), $info); 545a0cd8c78SSzymon Olewniczak $attachedImages = $info['img']; 546a0cd8c78SSzymon Olewniczak 5478a638198SSzymon Olewniczak $rep = array( 548e8827d73SSzymon Olewniczak 'content' => $this->content, 5498a638198SSzymon Olewniczak 'content_html' => 5508a638198SSzymon Olewniczak '<h2 style="font-size: 1.2em;">'. 551e8827d73SSzymon Olewniczak '<a href="'.$this->model->action->url('task', 'tid', $this->id).'">' . 5528a638198SSzymon Olewniczak '#z'.$this->id . 5538a638198SSzymon Olewniczak '</a> ' . 554e8827d73SSzymon Olewniczak lcfirst($this->model->action->getLang('task_type_' . $this->type)) . ' ' . 5558a638198SSzymon Olewniczak '(' . 556e8827d73SSzymon Olewniczak lcfirst($this->model->action->getLang('task_' . $this->state)) . 5578a638198SSzymon Olewniczak ')' . 5588a638198SSzymon Olewniczak '</h2>' . 559e8827d73SSzymon Olewniczak self::bez_html_irrtable(array( 5608a638198SSzymon Olewniczak 'table' => array( 5618a638198SSzymon Olewniczak 'border-collapse' => 'collapse', 5628a638198SSzymon Olewniczak 'font-size' => '0.8em', 5638a638198SSzymon Olewniczak 'width' => '100%' 5648a638198SSzymon Olewniczak ), 5658a638198SSzymon Olewniczak 'td' => array( 5668a638198SSzymon Olewniczak 'border-top' => '1px solid #8bbcbc', 5678a638198SSzymon Olewniczak 'border-bottom' => '1px solid #8bbcbc', 5688a638198SSzymon Olewniczak 'padding' => '.3em .5em' 5698a638198SSzymon Olewniczak ) 570a0cd8c78SSzymon Olewniczak ), $top_row, $bottom_row) . $content_html, 5718a638198SSzymon Olewniczak 'who' => $this->model->user_nick, 572e8827d73SSzymon Olewniczak 'when' => $this->create_date, 5738a638198SSzymon Olewniczak 'custom_content' => true 5748a638198SSzymon Olewniczak ); 5758a638198SSzymon Olewniczak 5768a638198SSzymon Olewniczak $rep['action_color'] = '#e4f4f4'; 5778a638198SSzymon Olewniczak $rep['action_border_color'] = '#8bbcbc'; 5788a638198SSzymon Olewniczak 5798a638198SSzymon Olewniczak //$replacements can override $reps 5808a638198SSzymon Olewniczak $rep = array_merge($rep, $replacements); 5818a638198SSzymon Olewniczak 582a0cd8c78SSzymon Olewniczak $this->mail_notify($rep, $users, $attachedImages); 5838a638198SSzymon Olewniczak } 5848a638198SSzymon Olewniczak 585e8827d73SSzymon Olewniczak public function mail_notify_subscribents($replacements=array()) { 586e8827d73SSzymon Olewniczak $this->mail_notify_task_box(false, $replacements); 5878a638198SSzymon Olewniczak } 5888a638198SSzymon Olewniczak 589e8827d73SSzymon Olewniczak public function mail_notify_add($users=false, $replacements=array()) { 5908a638198SSzymon Olewniczak $replacements['action'] = $this->model->action->getLang('mail_task_added'); 591e8827d73SSzymon Olewniczak $this->mail_notify_task_box($users, $replacements); 5928a638198SSzymon Olewniczak } 5938a638198SSzymon Olewniczak 5948a638198SSzymon Olewniczak public function mail_notify_remind($users=false) { 5958a638198SSzymon Olewniczak $replacements = array(); 5968a638198SSzymon Olewniczak 5978a638198SSzymon Olewniczak $replacements['action'] = $this->model->action->getLang('mail_task_remind'); 5988a638198SSzymon Olewniczak //we don't want any who 5998a638198SSzymon Olewniczak $replacements['who_full_name'] = ''; 6008a638198SSzymon Olewniczak 6018a638198SSzymon Olewniczak //$users = array($this->executor); 602e8827d73SSzymon Olewniczak $this->mail_notify_task_box($users, $replacements); 6038a638198SSzymon Olewniczak } 6048a638198SSzymon Olewniczak 6058a638198SSzymon Olewniczak public function mail_notify_invite($client) { 6068a638198SSzymon Olewniczak $replacements = array(); 6078a638198SSzymon Olewniczak 6088a638198SSzymon Olewniczak $replacements['action'] = $this->model->action->getLang('mail_task_invite'); 6098a638198SSzymon Olewniczak 6108a638198SSzymon Olewniczak $users = array($client); 611e8827d73SSzymon Olewniczak $this->mail_notify_task_box($users, $replacements); 6128a638198SSzymon Olewniczak } 6138a638198SSzymon Olewniczak} 614