1<?php 2 3/* 4 * Task coordinator is taken from tasktypes 5 */ 6//require_once 'entity.php'; 7// 8//class BEZ_mdl_Dummy_Task extends BEZ_mdl_Entity { 9// protected $coordinator; 10// 11// function __construct($model, $defaults=array()) { 12// parent::__construct($model); 13// 14// if (isset($defaults['issue'])) { 15// $issue = $this->model->issues->get_one($defaults['issue']); 16// $this->coordinator = $issue->coordinator; 17// } else { 18// $this->coordinator = ''; 19// } 20// } 21// 22// public function __get($property) { 23// if ($property === 'coordinator') { 24// return $this->coordinator; 25// } 26// parent::__get($property); 27// } 28//} 29 30namespace dokuwiki\plugin\bez\mdl; 31 32use dokuwiki\plugin\bez\meta\Mailer; 33use dokuwiki\plugin\bez\meta\PermissionDeniedException; 34use dokuwiki\plugin\bez\meta\ValidationException; 35 36class Task extends Entity { 37 38 protected $id; 39 40 protected $original_poster, $assignee, $closed_by; 41 42 protected $private, $lock; 43 44 protected $state, $type; 45 46 protected $create_date, $last_activity_date, $last_modification_date, $close_date; 47 48 protected $cost, $plan_date, $all_day_event, $start_time, $finish_time; 49 50 protected $content, $content_html; 51 52 protected $thread_id, $thread_comment_id, $task_program_id; 53 54 /** @var \dokuwiki\plugin\bez\mdl\Thread */ 55 protected $thread; 56 57 /** @var Thread_comment */ 58 protected $thread_comment; 59 60 //virtual 61 protected $task_program_name, $priority, $coordinator; 62 63 public static function get_columns() { 64 return array('id', 65 'original_poster', 'assignee', 'closed_by', 66 'private', 'lock', 67 'state', 'type', 68 'create_date', 'last_activity_date', 'last_modification_date', 'close_date', 69 'cost', 'plan_date', 'all_day_event', 'start_time', 'finish_time', 70 'content', 'content_html', 71 'thread_id', 'thread_comment_id', 'task_program_id'); 72 } 73 74 public static function get_types() { 75 return array('correction', 'corrective', 'preventive', 'program'); 76 } 77 78 public static function get_states() { 79 return array('opened', 'done'); 80 } 81 82 public function __get($property) { 83 if ($property == 'thread') { 84 if ($this->thread_id == null) { 85 return null; 86 } 87 if ($this->thread == null) { 88 $this->thread = $this->model->threadFactory->get_one($this->thread_id); 89 } 90 return $this->thread; 91 92 } elseif($property == 'thread_comment') { 93 if ($this->thread_comment_id == null) { 94 return null; 95 } 96 if ($this->thread_comment == null) { 97 $this->thread = $this->model->thread_commentFactory->get_one($this->thread_comment_id); 98 } 99 return $this->thread_comment; 100 101 } elseif($property == 'priority' || $property == 'coordinator' || $property == 'task_program_name') { 102 return $this->$property; 103 } 104 return parent::__get($property); 105 } 106 107 108// private function state_string() { 109// switch($this->state) { 110// case '0': return 'task_opened'; 111// case '-outdated': return 'task_outdated'; 112// case '1': return 'task_done'; 113// case '2': return 'task_rejected'; 114// } 115// } 116// 117// private function action_string() { 118// switch($this->action) { 119// case '0': return 'correction'; 120// case '1': return 'corrective_action'; 121// case '2': return 'preventive_action'; 122// case '3': return 'programme'; 123// } 124// } 125// 126// public function cost_localized() { 127// if ($this->cost === '') { 128// return ''; 129// } 130// 131// return sprintf('%.2f', (float)$this->cost); 132// } 133// 134// private function update_virtual_columns() { 135// $this->state_string = $this->model->action->getLang($this->state_string()); 136// $this->action_string = $this->model->action->getLang($this->action_string()); 137// $this->tasktype_string = $this->model->tasktypes->get_one($this->tasktype)->type; 138// } 139// 140// public function user_is_executor() { 141// if ($this->executor === $this->model->user_nick || 142// $this->model->acl->get_level() >= BEZ_AUTH_ADMIN) { 143// return true; 144// } 145// } 146 147 //by defaults you can set: cause, tasktype and issue 148 //tasktype is required 149 public function __construct($model, $defaults=array()) { 150 parent::__construct($model, $defaults); 151 152 153 //array(filter, NULL) 154 $this->validator->set_rules(array( 155// 'reporter' => array(array('dw_user'), 'NOT NULL'), 156// 'date' => array(array('unix_timestamp'), 'NOT NULL'), 157// 'close_date' => array(array('unix_timestamp'), 'NULL'), 158// 'cause' => array(array('numeric'), 'NULL'), 159 160// 'executor' => array(array('dw_user'), 'NOT NULL'), 161 162// 'issue' => array(array('numeric'), 'NULL'), 163 164 'assignee' => array(array('dw_user'), 'NOT NULL'), 165 'cost' => array(array('numeric'), 'NULL'), 166 'plan_date' => array(array('iso_date'), 'NOT NULL'), 167 'all_day_event' => array(array('select', array('0', '1')), 'NOT NULL'), 168 'start_time' => array(array('time'), 'NULL'), 169 'finish_time' => array(array('time'), 'NULL'), 170 'content' => array(array('length', 10000), 'NOT NULL'), 171 'thread_comment_id' => array(array('numeric'), 'NULL'), 172 'task_program_id' => array(array('numeric'), 'NULL') 173 174// 'state' => array(array('select', array('0', '1', '2')), 'NULL'), 175// 'reason' => array(array('length', 10000), 'NULL'), 176 177// 'coordinator' => array(array('dw_user', array('-none')), 'NOT NULL'), 178 )); 179 180 //we've created empty object 181 if ($this->id === NULL) { 182 $this->original_poster = $this->model->user_nick; 183 $this->create_date = date('c'); 184 $this->last_activity_date = $this->create_date; 185 $this->last_modification_date = $this->create_date; 186 187 $this->state = 'opened'; 188 189 if (isset($defaults['thread'])) { 190 $this->thread = $defaults['thread']; 191 $this->thread_id = $this->thread->id; 192 $this->type = 'correction'; 193 194 if (isset($defaults['thread_comment'])) { 195 $this->thread_comment = $defaults['thread_comment']; 196 $this->thread_comment_id = $this->thread_comment->id; 197 198 if ($this->thread_comment->type == 'cause_real') { 199 $this->type = 'corrective'; 200 } else { 201 $this->type = 'preventive'; 202 } 203 } 204 } else { 205 $this->type = 'program'; 206 } 207 208// //meta 209// $this->reporter = $this->model->user_nick; 210// $this->date = time(); 211// 212// $this->state = '0'; 213// $this->all_day_event = '1'; 214// 215// //throws ValidationException 216// $this->issue = $this->validator->validate_field('issue', $defaults['issue']); 217// 218// if ($this->issue !== '') { 219// $issue = $this->model->issues->get_one($defaults['issue']); 220// $this->coordinator = $issue->coordinator; 221// } else { 222// $this->coordinator = ''; 223// } 224// 225// //throws ValidationException 226// $this->validator->validate_field('cause', $defaults['cause']); 227// $this->cause = $defaults['cause']; 228// 229// //by default reporter is a executor 230// $this->executor = $this->reporter; 231 232 233 //we get object form db 234 } else { 235 236 if (isset($defaults['thread']) && $this->thread_id == $defaults['thread']->id) { 237 $this->thread = $defaults['thread']; 238 } 239 240 if (isset($defaults['thread_comment']) && $this->thread_comment_id == $defaults['thread_comment']->id) { 241 $this->thread_comment = $defaults['thread_comment']; 242 } 243 244 } 245 246 if ($this->thread_id == '') { 247 $this->validator->set_rules(array( 248 'task_program_id' => array(array('numeric'), 'NOT NULL'), 249 )); 250 //this field is unused in program tasks 251 $this->validator->delete_rule('thread_comment_id'); 252 } 253 254 255// //close_date required 256// if ($this->state !== '0') { 257// $this->validator->set_rules(array( 258// 'close_date' => array(array('unix_timestamp'), 'NOT NULL') 259// )); 260// } 261 262 //explode subscribents 263// if ($this->subscribents !== NULL) { 264// $exp_part = explode(',', $this->subscribents); 265// foreach ($exp_part as $subscribent) { 266// $this->subscribents_array[$subscribent] = $subscribent; 267// } 268// } 269// 270// //we've created empty object 271// if ($this->id === NULL) { 272// //throws ValidationException 273// $this->validator->validate_field('tasktype', $defaults['tasktype']); 274// $this->tasktype = $defaults['tasktype']; 275// } 276 } 277 278 279 public function set_data($post, $filter=NULL) { 280 parent::set_data($post); 281 282 $this->content_html = p_render('xhtml',p_get_instructions($this->content), $ignore); 283 284 //update dates 285 $this->last_modification_date = date('c'); 286 $this->last_activity_date = $this->last_modification_date; 287 288 //all day event 289 if (!isset($post['all_day_event'])) { 290 $post['all_day_event'] = '0'; 291 } 292 293 //specjalne reguły 294// if ($this->issue === '') { 295// $this->cause = ''; 296// } 297 298 //set parsed 299// $this->task_cache = $this->helper->wiki_parse($this->task); 300// $this->reason_cache = $this->helper->wiki_parse($this->reason); 301 302 //update virtuals 303 //$this->update_virtual_columns(); 304 305 return true; 306 } 307 308 public function set_state($state) { 309 if ($this->acl_of('state') < BEZ_PERMISSION_CHANGE) { 310 throw new PermissionDeniedException(); 311 } 312 313 if (!in_array($state, array('opened', 'done'))) { 314 throw new ValidationException('task', array('sholud be opened or done')); 315 } 316 317 //nothing to do 318 if ($state == $this->state) { 319 return; 320 } 321 322 if ($state == 'done') { 323 $this->model->sqlite->query("UPDATE {$this->get_table_name()} SET state=?, closed_by=?, close_date=? WHERE id=?", 324 $state, 325 $this->model->user_nick, 326 date('c'), 327 $this->id); 328 //reopen the task 329 } else { 330 $this->model->sqlite->query("UPDATE {$this->get_table_name()} SET state=? WHERE id=?", $state, $this->id); 331 } 332 333 $this->state = $state; 334 } 335 336 public function update_last_activity() { 337 $this->last_activity_date = date('c'); 338 $this->model->sqlite->query('UPDATE task SET last_activity_date=? WHERE id=?', 339 $this->last_activity_date, $this->id); 340 } 341 342// public function update_cache() { 343// if ($this->model->acl->get_level() < BEZ_AUTH_ADMIN) { 344// return false; 345// } 346// $this->task_cache = $this->helper->wiki_parse($this->task); 347// $this->reason_cache = $this->helper->wiki_parse($this->reason); 348// } 349// 350// public function set_state($data) { 351// //reason is required while changing state 352// if ($data['state'] === '2') { 353// $this->validator->set_rules(array( 354// 'reason' => array(array('length', 10000), 'NOT NULL') 355// )); 356// } 357// 358// $val_data = $this->validator->validate($data, array('state', 'reason')); 359// if ($val_data === false) { 360// throw new ValidationException('tasks', $this->validator->get_errors()); 361// } 362// 363// //if state is changed 364// if ($this->state != $data['state']) { 365// $this->close_date = time(); 366// } 367// 368// $this->set_property_array($val_data); 369// $this->reason_cache = $this->helper->wiki_parse($this->reason); 370// 371// //update virtuals 372// $this->update_virtual_columns(); 373// 374// return true; 375// } 376// 377// public function get_meta_fields() { 378// return array('reporter', 'date', 'close_date'); 379// } 380// 381// public function set_meta($post) { 382// 383// if (isset($post['date'])) { 384// $unix = strtotime($post['date']); 385// //if $unix === false validator will catch it 386// if ($unix !== false) { 387// $post['date'] = (string)$unix; 388// } 389// } 390// 391// if (isset($post['close_date'])) { 392// $unix = strtotime($post['close_date']); 393// //if $unix === false validator will catch it 394// if ($unix !== false) { 395// $post['close_date'] = (string)$unix; 396// } 397// } 398// 399// parent::set_data($post, $this->get_meta_fields()); 400// } 401// 402// public function is_subscribent($user=NULL) { 403// if ($user === NULL) { 404// $user = $this->model->user_nick; 405// } 406// if (in_array($user, $this->subscribents_array)) { 407// return true; 408// } 409// return false; 410// } 411// 412// public function get_subscribents() { 413// return $this->subscribents_array; 414// } 415// 416// public function get_participants() { 417// $subscribents = array_merge(array($this->reporter, $this->executor), 418// $this->subscribents_array); 419// $full_names = array(); 420// foreach ($subscribents as $par) { 421// $name = $this->model->users->get_user_full_name($par); 422// if ($name == '') { 423// $full_names[$par] = $par; 424// } else { 425// $full_names[$par] = $name; 426// } 427// } 428// ksort($full_names); 429// return $full_names; 430// } 431// 432// public function remove_subscribent($subscribent) { 433// if ($subscribent !== $this->model->user_nick && 434// $this->acl_of('subscribents') < BEZ_PERMISSION_CHANGE) { 435// throw new PermissionDeniedException(); 436// } 437// 438// if ($this->issue != '') { 439// throw new ConsistencyViolationException('cannot modify subscribents from issue related tasks'); 440// } 441// 442// if (!isset($this->subscribents_array[$subscribent])) { 443// throw new ConsistencyViolationException('user '.$subscribent.' wasn\'t subscriber so cannot be removed'); 444// } 445// 446// unset($this->subscribents_array[$subscribent]); 447// $this->subscribents = implode(',', $this->subscribents_array); 448// } 449// 450// public function add_subscribent($subscribent) { 451// if ($subscribent !== $this->model->user_nick && 452// $this->acl_of('subscribents') < BEZ_PERMISSION_CHANGE) { 453// throw new PermissionDeniedException(); 454// } 455// 456// if ($this->issue != '') { 457// throw new ConsistencyViolationException('cannot add subscribents to issue related tasks'); 458// } 459// 460// if ($this->model->users->exists($subscribent) && 461// !in_array($subscribent, $this->subscribents_array)) { 462// $this->subscribents_array[$subscribent] = $subscribent; 463// $this->subscribents = implode(',', $this->subscribents_array); 464// 465// return true; 466// } 467// 468// return false; 469// } 470 471 public function get_participants($filter='') { 472 if ($this->acl_of('participants') < BEZ_PERMISSION_VIEW) { 473 throw new PermissionDeniedException(); 474 } 475 if ($this->id === NULL) { 476 return array(); 477 } 478 479 $sql = 'SELECT * FROM task_participant WHERE'; 480 $possible_flags = array('original_poster', 'assignee', 'commentator', 'subscribent'); 481 if ($filter != '') { 482 if (!in_array($filter, $possible_flags)) { 483 throw new \Exception("unknown flag $filter"); 484 } 485 $sql .= " $filter=1 AND"; 486 } 487 $sql .= ' task_id=? ORDER BY user_id'; 488 489 $r = $this->model->sqlite->query($sql, $this->id); 490 $pars = $this->model->sqlite->res2arr($r); 491 $participants = array(); 492 foreach ($pars as $par) { 493 $participants[$par['user_id']] = $par; 494 } 495 496 return $participants; 497 } 498 499 public function get_participant($user_id) { 500 if ($this->acl_of('participants') < BEZ_PERMISSION_VIEW) { 501 throw new PermissionDeniedException(); 502 } 503 if ($this->id === NULL) { 504 return array(); 505 } 506 507 $r = $this->model->sqlite->query('SELECT * FROM task_participant WHERE task_id=? AND user_id=?', $this->id, $user_id); 508 $par = $this->model->sqlite->res2row($r); 509 if (!is_array($par)) { 510 return false; 511 } 512 513 return $par; 514 } 515 516 public function is_subscribent($user_id=null) { 517 if ($user_id == null) { 518 $user_id = $this->model->user_nick; 519 } 520 $par = $this->get_participant($user_id); 521 if ($par['subscribent'] == 1) { 522 return true; 523 } 524 return false; 525 } 526 527 public function remove_participant_flags($user_id, $flags) { 528 if ($this->acl_of('participants') < BEZ_PERMISSION_CHANGE) { 529 throw new PermissionDeniedException(); 530 } 531 532 //thread not saved yet 533 if ($this->id === NULL) { 534 throw new \Exception('cannot remove flags from not saved thread'); 535 } 536 537 $possible_flags = array('original_poster', 'assignee', 'commentator', 'subscribent'); 538 if (array_intersect($flags, $possible_flags) != $flags) { 539 throw new \Exception('unknown flags'); 540 } 541 542 $set = implode(',', array_map(function ($v) { return "$v=0"; }, $flags)); 543 544 $sql = "UPDATE task_participant SET $set WHERE task_id=? AND user_id=?"; 545 $this->model->sqlite->query($sql, $this->id, $user_id); 546 547 } 548 549 public function set_participant_flags($user_id, $flags=array()) { 550 if ($this->acl_of('participants') < BEZ_PERMISSION_CHANGE) { 551 throw new PermissionDeniedException(); 552 } 553 554 //thread not saved yet 555 if ($this->id === NULL) { 556 throw new \Exception('cannot add flags to not saved thread'); 557 } 558 559 //validate user 560 if (!$this->model->userFactory->exists($user_id)) { 561 throw new \Exception("$user_id isn't dokuwiki user"); 562 } 563 564 $possible_flags = array('original_poster', 'assignee', 'commentator', 'subscribent'); 565 if (array_intersect($flags, $possible_flags) != $flags) { 566 throw new \Exception('unknown flags'); 567 } 568 569 $participant = $this->get_participant($user_id); 570 if ($participant == false) { 571 $participant = array_fill_keys($possible_flags, 0); 572 573 $participant['task_id'] = $this->id; 574 $participant['user_id'] = $user_id; 575 $participant['added_by'] = $this->model->user_nick; 576 $participant['added_date'] = date('c'); 577 } 578 $values = array_merge($participant, array_fill_keys($flags, 1)); 579 580 $keys = join(',', array_keys($values)); 581 $vals = join(',', array_fill(0,count($values),'?')); 582 583 $sql = "REPLACE INTO task_participant ($keys) VALUES ($vals)"; 584 $this->model->sqlite->query($sql, array_values($values)); 585 586 587 588// if (! ( $this->user_is_coordinator() || 589// $participant === $this->model->user_nick || 590// $participant === $this->coordinator) //dodajemy nowego koordynatora 591// ) { 592// throw new PermissionDeniedException(); 593// } 594// if ($this->model->users->exists($participant)) { 595// $this->participants_array[$participant] = $participant; 596// $this->participants = implode(',', $this->participants_array); 597// } 598 } 599 600 public function invite($client) { 601 $this->set_participant_flags($client, array('subscribent')); 602 $this->mail_notify_invite($client); 603 } 604 605 private function mail_notify($replacements=array(), $users=false) { 606 $plain = io_readFile($this->model->action->localFN('task-notification')); 607 $html = io_readFile($this->model->action->localFN('task-notification', 'html')); 608 609 $task_link = $this->model->action->url('task', 'tid', $this->id); 610 611 $reps = array( 612 'task_id' => $this->id, 613 'task_link' => $task_link, 614 'who' => $this->original_poster 615 ); 616 617 //$replacements can override $reps 618 $rep = array_merge($reps, $replacements); 619 620 if (!isset($rep['who_full_name'])) { 621 $rep['who_full_name'] = 622 $this->model->userFactory->get_user_full_name($rep['who']); 623 } 624 625 //auto title 626 if (!isset($rep['subject'])) { 627// if (isset($rep['content'])) { 628// $rep['subject'] = array_shift(explode('.', $rep['content'], 2)); 629// } 630 $rep['subject'] = '#z'.$this->id. ' ' . $this->task_program_name; 631 } 632 633 //we must do it manually becouse Mailer uses htmlspecialchars() 634 $html = str_replace('@TASK_TABLE@', $rep['task_table'], $html); 635 636 $mailer = new Mailer(); 637 $mailer->setBody($plain, $rep, $rep, $html, false); 638 639 if ($users === FALSE) { 640 $users = $this->get_participants('subscribent'); 641 642 //don't notify current user 643 unset($users[$this->model->user_nick]); 644 } 645 646 $emails = array_map(function($user) { 647 return $this->model->userFactory->get_user_email($user); 648 }, $users); 649 650 $mailer->to($emails); 651 $mailer->subject($rep['subject']); 652 653 $send = $mailer->send(); 654 if ($send === false) { 655 //this may mean empty $emails 656 //throw new Exception("can't send email"); 657 } 658 } 659 660 protected function bez_html_array_to_style_list($arr) { 661 $output = ''; 662 foreach ($arr as $k => $v) { 663 $output .= $k.': '. $v . ';'; 664 } 665 return $output; 666 } 667 668 protected function bez_html_irrtable($style) { 669 $argv = func_get_args(); 670 $argc = func_num_args(); 671 if (isset($style['table'])) { 672 $output = '<table style="'.self::bez_html_array_to_style_list($style['table']).'">'; 673 } else { 674 $output = '<table>'; 675 } 676 677 $tr_style = ''; 678 if (isset($style['tr'])) { 679 $tr_style = 'style="'.self::bez_html_array_to_style_list($style['tr']).'"'; 680 } 681 682 $td_style = ''; 683 if (isset($style['td'])) { 684 $td_style = 'style="'.self::bez_html_array_to_style_list($style['td']).'"'; 685 } 686 687 $row_max = 0; 688 689 for ($i = 1; $i < $argc; $i++) { 690 $row = $argv[$i]; 691 $c = count($row); 692 if ($c > $row_max) { 693 $row_max = $c; 694 } 695 } 696 697 for ($j = 1; $j < $argc; $j++) { 698 $row = $argv[$j]; 699 $output .= '<tr '.$tr_style.'>' . NL; 700 $c = count($row); 701 for ($i = 0; $i < $c; $i++) { 702 //last element 703 if ($i === $c - 1 && $c < $row_max) { 704 $output .= '<td '.$td_style.' colspan="' . ( $row_max - $c + 1 ) . '">' . NL; 705 } else { 706 $output .= '<td '.$td_style.'>' . NL; 707 } 708 $output .= $row[$i] . NL; 709 $output .= '</td>' . NL; 710 } 711 $output .= '</tr>' . NL; 712 } 713 $output .= '</table>' . NL; 714 return $output; 715 } 716 717 public function mail_notify_task_box($users=false, $replacements=array()) { 718// if ($issue_obj !== NULL && $issue_obj->id !== $this->issue) { 719// throw new Exception('issue object id and task->issue does not match'); 720// } 721 722 $top_row = array( 723 '<strong>'.$this->model->action->getLang('executor').': </strong>' . 724 $this->model->userFactory->get_user_full_name($this->assignee), 725 726 '<strong>'.$this->model->action->getLang('reporter').': </strong>' . 727 $this->model->userFactory->get_user_full_name($this->original_poster) 728 ); 729 730 if ($this->task_program_name != '') { 731 $top_row[] = 732 '<strong>'.$this->model->action->getLang('task_type').': </strong>' . 733 $this->task_program_name; 734 } 735 736 if ($this->cost != '') { 737 $top_row[] = 738 '<strong>'.$this->model->action->getLang('cost').': </strong>' . 739 $this->cost; 740 } 741 742 //BOTTOM ROW 743 $bottom_row = array( 744 '<strong>'.$this->model->action->getLang('plan_date').': </strong>' . 745 $this->plan_date 746 ); 747 748 if ($this->all_day_event == '0') { 749 $bottom_row[] = 750 '<strong>'.$this->model->action->getLang('start_time').': </strong>' . 751 $this->start_time; 752 $bottom_row[] = 753 '<strong>'.$this->model->action->getLang('finish_time').': </strong>' . 754 $this->finish_time; 755 } 756 757 $rep = array( 758 'content' => $this->content, 759 'content_html' => 760 '<h2 style="font-size: 1.2em;">'. 761 '<a href="'.$this->model->action->url('task', 'tid', $this->id).'">' . 762 '#z'.$this->id . 763 '</a> ' . 764 lcfirst($this->model->action->getLang('task_type_' . $this->type)) . ' ' . 765 '(' . 766 lcfirst($this->model->action->getLang('task_' . $this->state)) . 767 ')' . 768 '</h2>' . 769 self::bez_html_irrtable(array( 770 'table' => array( 771 'border-collapse' => 'collapse', 772 'font-size' => '0.8em', 773 'width' => '100%' 774 ), 775 'td' => array( 776 'border-top' => '1px solid #8bbcbc', 777 'border-bottom' => '1px solid #8bbcbc', 778 'padding' => '.3em .5em' 779 ) 780 ), $top_row, $bottom_row) . $this->content_html, 781 'who' => $this->model->user_nick, 782 'when' => $this->create_date, 783 'custom_content' => true 784 ); 785 786 $rep['action_color'] = '#e4f4f4'; 787 $rep['action_border_color'] = '#8bbcbc'; 788 789 //$replacements can override $reps 790 $rep = array_merge($rep, $replacements); 791 792// if ($this->thread == NULL) { 793// $this->mail_notify($rep, $users); 794// } else { 795// $this->thread->mail_notify($rep); 796// } 797 $this->mail_notify($rep, $users); 798 } 799 800 public function mail_notify_subscribents($replacements=array()) { 801 $this->mail_notify_task_box(false, $replacements); 802 } 803 804 public function mail_notify_add($users=false, $replacements=array()) { 805 $replacements['action'] = $this->model->action->getLang('mail_task_added'); 806 $this->mail_notify_task_box($users, $replacements); 807 } 808 809 public function mail_notify_remind($users=false) { 810 $replacements = array(); 811 812 $replacements['action'] = $this->model->action->getLang('mail_task_remind'); 813 //we don't want any who 814 $replacements['who_full_name'] = ''; 815 816 //$users = array($this->executor); 817 $this->mail_notify_task_box($users, $replacements); 818 } 819 820 public function mail_notify_invite($client) { 821 $replacements = array(); 822 823 $replacements['action'] = $this->model->action->getLang('mail_task_invite'); 824 825 $users = array($client); 826 $this->mail_notify_task_box($users, $replacements); 827 } 828} 829