1<?php 2 3//if(!defined('DOKU_INC')) die(); 4 5//require_once 'entity.php'; 6 7namespace dokuwiki\plugin\bez\mdl; 8 9use dokuwiki\plugin\bez\meta\PermissionDeniedException; 10use dokuwiki\plugin\bez\meta\ValidationException; 11 12class Thread extends Entity { 13 14 protected $id; 15 16 protected $original_poster, $coordinator; 17 18 protected $private, $lock; 19 20 protected $type, $state; 21 22 protected $create_date, $last_activity_date, $last_modification_date, $close_date; 23 24 protected $title, $content, $content_html; 25 26 protected $task_count, $task_count_open, $task_sum_cost; 27 28 /*new labels to add when object saved*/ 29 //protected $new_label_ids; 30 protected $labels; 31 32 public static function get_columns() { 33 return array('id', 34 'original_poster', 'coordinator', 35 'private', 'lock', 36 'type', 'state', 37 'create_date', 'last_activity_date', 'last_modification_date', 'close_date', 38 'title', 'content', 'content_html', 39 'task_count', 'task_count_open', 'task_sum_cost'); 40 } 41 42 public static function get_select_columns() { 43 $cols = parent::get_select_columns(); 44 array_push($cols, 'label_id', 'label_name'); 45 return $cols; 46 } 47 48 public static function get_states() { 49 return array('proposal', 'opened', 'done', 'closed', 'rejected'); 50 } 51 52 53// private function state_string() { 54// if ($this->state === '2') { 55// return 'state_rejected'; 56// } else if ($this->coordinator === '-proposal') { 57// return 'state_proposal'; 58// } else if ( $this->state === '0' && 59// (int)$this->assigned_tasks_count > 0 && 60// (int)$this->opened_tasks_count === 0) { 61// return 'state_done'; 62// } else if ($this->state === '0') { 63// return 'state_opened'; 64// } else if ($this->state === '1') { 65// return 'state_closed'; 66// } 67// } 68// 69// private function type_string() { 70// if ($this->type === '') { 71// return ''; 72// } 73// $issuetype = $this->model->issuetypes->get_one($this->type)->get_assoc(); 74// return $issuetype[$this->model->conf['lang']]; 75// } 76// 77// private function priority() { 78// if ($this->state === '2') { 79// return '3'; 80// } 81// $min_pr = $this->model->tasks->min_priority(array('issue' => $this->id)); 82// if ($min_pr === NULL) { 83// return 'None'; 84// } 85// return $min_pr; 86// } 87 88 public function user_is_coordinator() { 89 if ($this->coordinator === $this->model->user_nick || 90 $this->model->acl->get_level() >= BEZ_AUTH_ADMIN) { 91 return true; 92 } 93 } 94 95 public function __construct($model, $defaults=array()) { 96 parent::__construct($model); 97 98 $this->validator->set_rules(array( 99 'coordinator' => array(array('dw_user'), 'NULL'), 100 'title' => array(array('length', 200), 'NOT NULL'), 101 'content' => array(array('length', 10000), 'NOT NULL') 102 )); 103 104// $this->validator->set_rules(array( 105// 'title' => array(array('length', 200), 'NOT NULL'), 106// 'description' => array(array('length', 10000), 'NOT NULL'), 107// 'state' => array(array('select', array('0', '1', '2')), 'NULL'), 108// 'opinion' => array(array('length', 10000), 'NOT NULL'), 109// 'type' => array(array('numeric'), 'NULL'), 110// 'coordinator' => array(array('dw_user'), 'NOT NULL'), 111// 'reporter' => array(array('dw_user'), 'NOT NULL'), 112// 'date' => array(array('unix_timestamp'), 'NOT NULL'), 113// 'last_mod' => array(array('unix_timestamp'), 'NULL'), 114// 'last_activity' => array(array('sqlite_datetime'), 'NOT NULL') 115// )); 116 117// $this->validator->set_rules(array( 118 //'coordinator' => array(array('dw_user'), 'NULL'), 119// 'original_poster' => array(array('dw_user'), 'NOT NULL'), 120// 'title' => array(array('length', 200), 'NOT NULL'), 121// 'content' => array(array('length', 10000), 'NOT NULL'), 122// 'state' => array(array('select', array('0', '1', '2')), 'NULL'), 123// 'opinion' => array(array('length', 10000), 'NOT NULL'), 124// 'type' => array(array('select'), 'NULL'), 125 126// 'create_date' => array(array('sqlite_datetime'), 'NOT NULL'), 127// 'last_mod' => array(array('sqlite_datetime'), 'NULL'), 128// 'last_activity' => array(array('sqlite_datetime'), 'NOT NULL') 129// )); 130 131 //we've created empty object (new record) 132 if ($this->id === NULL) { 133 $this->original_poster = $this->model->user_nick; 134 $this->create_date = date('c'); 135 $this->last_activity_date = $this->create_date; 136 $this->last_modification_date = $this->create_date; 137 138 $this->state = 'proposal'; 139 140// $this->close_date = ''; 141 142// $this->lock = '0'; 143// $this->private = '0'; 144// $this->type = '1';//type 1 - issue 145// $this->state = '0';//state 0 - proposal 146 147 //$this->update_last_activity(); 148 149 //$this->state = '0'; 150 151 if ($this->model->acl->get_level() >= BEZ_AUTH_LEADER) { 152// $this->validator->add_rule('cooridnator', array(array('dw_user'), 'NOT NULL')); 153 //throws ValidationException 154// $this->coordinator = $this->validator->validate_field('coordinator', $defaults['coordinator']); 155 if (!$this->model->userFactory->exists($defaults['coordinator'])) { 156 throw new ValidationException('thread', array('coordinator' => 'is_null')); 157 } 158 $this->coordinator = $defaults['coordinator']; 159 $this->state = 'opened'; 160 } 161// } else { 162// $this->coordinator = '-proposal'; 163// } 164 165 166// $this->add_participant($this->reporter); 167// $this->add_subscribent($this->reporter); 168// if ($this->coordinator !== '-proposal') { 169// $this->add_participant($this->coordinator); 170// $this->add_subscribent($this->coordinator); 171// } 172 173 } 174 //close_date required 175// if ($this->state !== 'state_proposal' && $this->state !== 'state_opened') { 176// $this->validator->set_rules(array( 177// 'close_date' => array(array('unix_timestamp'), 'NOT NULL') 178// )); 179// } 180 181 182// if ($this->participants !== NULL) { 183// $exp_part = explode(',', $this->participants); 184// foreach ($exp_part as $participant) { 185// $this->participants_array[$participant] = $participant; 186// } 187// } 188// 189// if ($this->subscribents !== NULL) { 190// $exp_part = explode(',', $this->subscribents); 191// foreach ($exp_part as $subscribent) { 192// $this->subscribents_array[$subscribent] = $subscribent; 193// } 194// } 195 } 196 197 public function set_data($data, $filter=NULL) { 198 $input = array('title', 'content', 'coordinator'); 199 $val_data = $this->validator->validate($data, $input); 200 201 if ($val_data === false) { 202 throw new ValidationException('thread', $this->validator->get_errors()); 203 } 204 205 206 //change coordinator at the end(!) 207 if (isset($val_data['coordinator'])) { 208 $val_coordinator = $val_data['coordinator']; 209 unset($val_data['coordinator']); 210 } 211 212 $this->set_property_array($val_data); 213 214 if (isset($val_coordinator)) { 215 $this->set_property('coordinator', $val_coordinator); 216 } 217 218 //!!! don't update activity on issue update 219 $this->content_html = p_render('xhtml',p_get_instructions($this->content), $ignore); 220// $this->opinion_cache = $this->helper->wiki_parse($this->opinion); 221 222 //update virtuals 223 //$this->update_virtual_columns(); 224 } 225 226// public function set_labels($labels_ids = array()) { 227// 228// } 229 230// public function get_meta_fields() { 231// return array('reporter', 'date', 'last_mod', 'last_activity'); 232// } 233// 234// public function set_meta($post) { 235// 236// if (isset($post['date'])) { 237// $unix = strtotime($post['date']); 238// //if $unix === false validator will catch it 239// if ($unix !== false) { 240// $post['date'] = (string)$unix; 241// } 242// } 243// 244// if (isset($post['last_mod'])) { 245// $unix = strtotime($post['last_mod']); 246// //if $unix === false validator will catch it 247// if ($unix !== false) { 248// $post['last_mod'] = (string)$unix; 249// } 250// } 251// 252// parent::set_data($post, $this->get_meta_fields()); 253// } 254 255// public function update_cache() { 256// if ($this->model->acl->get_level() < BEZ_AUTH_ADMIN) { 257// return false; 258// } 259// $this->description_cache = $this->helper->wiki_parse($this->description); 260// $this->opinion_cache = $this->helper->wiki_parse($this->opinion); 261// } 262// 263// public function set_state($data) { 264// 265// $input = array('state', 'opinion'); 266// $val_data = $this->validator->validate($data, $input); 267// 268// if ($val_data === false) { 269// throw new ValidationException('issues', $this->validator->get_errors()); 270// } 271// 272// $this->set_property_array($val_data); 273// 274// if (count($this->validator->get_errors()) > 0) { 275// throw new ValidationException('issues', $this->validator->get_errors()); 276// } 277// 278// //update activity on state update 279// $this->last_mod = time(); 280// $this->update_last_activity(); 281// $this->opinion_cache = $this->helper->wiki_parse($this->opinion); 282// 283// //update virtuals 284// //$this->update_virtual_columns(); 285// } 286 287// public function update_last_activity() { 288// $this->last_activity = $this->sqlite_date(); 289// } 290 291 //private $participants; 292 public function get_participants($filter='') { 293 if ($this->acl_of('participants') < BEZ_PERMISSION_VIEW) { 294 throw new PermissionDeniedException(); 295 } 296 if ($this->id === NULL) { 297 return array(); 298 } 299 300 $sql = 'SELECT * FROM thread_participant WHERE thread_id=? ORDER BY user_id'; 301 $possible_flags = array('original_poster', 'coordinator', 'commentator', 'task_assignee', 'subscribent'); 302 if ($filter != '') { 303 if (!in_array($filter, $possible_flags)) { 304 throw new \Exception("unknown flag $filter"); 305 } 306 $sql .= " WHERE $filter=1"; 307 } 308 309 $r = $this->model->sqlite->query($sql, $this->id); 310 $pars = $this->model->sqlite->res2arr($r); 311 $participants = array(); 312 foreach ($pars as $par) { 313 $participants[$par['user_id']] = $par; 314 } 315 316 return $participants; 317 } 318 319 public function get_participant($user_id) { 320 if ($this->acl_of('participants') < BEZ_PERMISSION_VIEW) { 321 throw new PermissionDeniedException(); 322 } 323 if ($this->id === NULL) { 324 return array(); 325 } 326 327 $r = $this->model->sqlite->query('SELECT * FROM thread_participant WHERE thread_id=? AND user_id=?', $this->id, $user_id); 328 $par = $this->model->sqlite->res2row($r); 329 if (!is_array($par)) { 330 return false; 331 } 332 333 return $par; 334 } 335 336 public function is_subscribent($user_id=null) { 337 if ($user_id == null) { 338 $user_id = $this->model->user_nick; 339 } 340 $par = $this->get_participant($user_id); 341 if ($par['subscribent'] == 1) { 342 return true; 343 } 344 return false; 345 } 346 347 public function remove_participant_flags($user_id, $flags) { 348 if ($this->acl_of('participants') < BEZ_PERMISSION_CHANGE) { 349 throw new PermissionDeniedException(); 350 } 351 352 //thread not saved yet 353 if ($this->id === NULL) { 354 throw new \Exception('cannot remove flags from not saved thread'); 355 } 356 357 $possible_flags = array('original_poster', 'coordinator', 'commentator', 'task_assignee', 'subscribent'); 358 if (array_intersect($flags, $possible_flags) != $flags) { 359 throw new \Exception('unknown flags'); 360 } 361 362 $set = implode(',', array_map(function ($v) { return "$v=0"; }, $flags)); 363 364 $sql = "UPDATE thread_participant SET $set WHERE thread_id=? AND user_id=?"; 365 $this->model->sqlite->query($sql, $this->id, $user_id); 366 367 } 368 369 public function set_participant_flags($user_id, $flags=array()) { 370 if ($this->acl_of('participants') < BEZ_PERMISSION_CHANGE) { 371 throw new PermissionDeniedException(); 372 } 373 374 //thread not saved yet 375 if ($this->id === NULL) { 376 throw new \Exception('cannot add flags to not saved thread'); 377 } 378 379 $possible_flags = array('original_poster', 'coordinator', 'commentator', 'task_assignee', 'subscribent'); 380 if (array_intersect($flags, $possible_flags) != $flags) { 381 throw new \Exception('unknown flags'); 382 } 383 384 $participant = $this->get_participant($user_id); 385 if ($participant == false) { 386 $participant = array_fill_keys($possible_flags, 0); 387 388 $participant['thread_id'] = $this->id; 389 $participant['user_id'] = $user_id; 390 $participant['added_by'] = $this->model->user_nick; 391 $participant['added_date'] = date('c'); 392 } 393 $values = array_merge($participant, array_fill_keys($flags, 1)); 394 395 $keys = join(',', array_keys($values)); 396 $vals = join(',', array_fill(0,count($values),'?')); 397 398 $sql = "REPLACE INTO thread_participant ($keys) VALUES ($vals)"; 399 $this->model->sqlite->query($sql, array_values($values)); 400 401 402 403// if (! ( $this->user_is_coordinator() || 404// $participant === $this->model->user_nick || 405// $participant === $this->coordinator) //dodajemy nowego koordynatora 406// ) { 407// throw new PermissionDeniedException(); 408// } 409// if ($this->model->users->exists($participant)) { 410// $this->participants_array[$participant] = $participant; 411// $this->participants = implode(',', $this->participants_array); 412// } 413 } 414 415 public function get_labels() { 416 if ($this->acl_of('labels') < BEZ_PERMISSION_VIEW) { 417 throw new PermissionDeniedException(); 418 } 419 420 //record not saved 421 if ($this->id === NULL) { 422 return array(); 423 } 424 425 $labels = array(); 426 $r = $this->model->sqlite->query('SELECT * FROM label JOIN thread_label ON label.id = thread_label.label_id 427 WHERE thread_label.thread_id=?', $this->id); 428 $arr = $this->model->sqlite->res2arr($r); 429 foreach ($arr as $label) { 430 $labels[$label['id']] = $label; 431 } 432 433 return $labels; 434 } 435 436// public function get_label_id($name) { 437// $labels = $this->get_labels(); 438// 439// foreach ($labels as $label) { 440// if ($label['name'] == $name) { 441// return $label['label_id']; 442// } 443// } 444// return false; 445// } 446 447 public function add_label($label_id) { 448 if ($this->acl_of('labels') < BEZ_PERMISSION_CHANGE) { 449 throw new PermissionDeniedException(); 450 } 451 452 453 //issue not saved yet 454 if ($this->id === NULL) { 455 throw new \Exception('cannot add labels to not saved thread. use initial_save() instead'); 456 } 457 458 //label already assigned, nothing to do 459// if ($this->get_label_id($name)) return; 460 461 $r = $this->model->sqlite->query('SELECT id FROM label WHERE id=?', $label_id); 462 $label_id = $this->model->sqlite->res2single($r); 463 if (!$label_id) { 464 throw new \Exception("label($label_id) doesn't exist"); 465 } 466 467 468 $this->model->sqlite->storeEntry('thread_label', 469 array('thread_id' => $this->id, 470 'label_id' => $label_id)); 471 472 } 473 474 public function remove_label($label_id) { 475 if ($this->acl_of('labels') < BEZ_PERMISSION_CHANGE) { 476 throw new PermissionDeniedException(); 477 } 478 479 //issue not saved yet 480 if ($this->id === NULL) { 481 throw new \Exception('cannot remove labels from not saved thread. use initial_save() instead'); 482 } 483 484 /** @var \PDOStatement $r */ 485 $r = $this->model->sqlite->query('DELETE FROM thread_label WHERE thread_id=? AND label_id=?',$this->id, $label_id); 486 if ($r->rowCount() != 1) { 487 throw new \Exception('label was not assigned to this thread'); 488 } 489 490 } 491 492 public function causes_without_tasks_count() { 493 return 0; 494 } 495 496// public function remove_label($name) { 497// if ($this->acl_of('labels') < BEZ_PERMISSION_CHANGE) { 498// throw new PermissionDeniedException(); 499// } 500// //label not assigned 501// $label_id = $this->get_label($name); 502// 503// if ($label_id === false) { 504// throw new \Exception('label don not exists'); 505// } 506// 507// $this->model->sqlite->query('DELETE FROM thread_label WHERE thread_id=?, label_id=?', $this->id, $label_id); 508// } 509 510// public function add_subscribent($subscribent) { 511// if (! ( $this->user_is_coordinator() || 512// $subscribent === $this->model->user_nick || 513// $subscribent === $this->coordinator) //dodajemy nowego koordynatora) 514// ) { 515// throw new PermissionDeniedException(); 516// } 517// 518// if ($this->model->users->exists($subscribent) && 519// !in_array($subscribent, $this->subscribents_array)) { 520// $this->subscribents_array[$subscribent] = $subscribent; 521// $this->subscribents = implode(',', $this->subscribents_array); 522// return true; 523// } 524// return false; 525// } 526// 527// public function remove_subscribent($subscribent) { 528// if (! ( $this->user_is_coordinator() || 529// $subscribent === $this->model->user_nick) 530// ) { 531// throw new PermissionDeniedException(); 532// } 533// unset($this->subscribents_array[$subscribent]); 534// $this->subscribents = implode(',', $this->subscribents_array); 535// } 536// 537// public function get_subscribents() { 538// return $this->subscribents_array; 539// } 540 541// public function get_participants() { 542// $full_names = []; 543// 544// $involved = array_merge($this->subscribents_array, $this->participants_array); 545// foreach ($involved as $par) { 546// $name = $this->model->users->get_user_full_name($par); 547// if ($name == '') { 548// $full_names[$par] = $par; 549// } else { 550// $full_names[$par] = $name; 551// } 552// } 553// //coordinator on top 554// uksort($full_names, function ($a, $b) use($full_names) { 555// if ($a === $this->coordinator) { 556// return -1; 557// } else if ($b === $this->coordinator) { 558// return 1; 559// } 560// return $full_names[$a] > $full_names[$b]; 561// }); 562// 563// return $full_names; 564// } 565 566// public function is_subscribent($user=NULL) { 567// if ($user === NULL) { 568// $user = $this->model->user_nick; 569// } 570// if (in_array($user, $this->subscribents_array)) { 571// return true; 572// } 573// return false; 574// } 575// 576// public function is_task_executor($user=NULL) { 577// if ($user === NULL) { 578// $user = $this->model->user_nick; 579// } 580// $sth = $this->model->db->prepare('SELECT COUNT(*) FROM tasks 581// WHERE issue=:issue AND executor=:executor'); 582// $sth->execute(array(':issue' => $this->id, ':executor' => $user)); 583// $fetch = $sth->fetch(); 584// if ($fetch[0] === '0') { 585// return false; 586// } else { 587// return true; 588// } 589// } 590// 591// public function is_commentator($user=NULL) { 592// if ($user === NULL) { 593// $user = $this->model->user_nick; 594// } 595// $sth = $this->model->db->prepare('SELECT COUNT(*) FROM commcauses 596// WHERE issue=:issue AND reporter=:reporter'); 597// $sth->execute(array(':issue' => $this->id, ':reporter' => $user)); 598// $fetch = $sth->fetch(); 599// if ($fetch[0] === '0') { 600// return false; 601// } else { 602// return true; 603// } 604// } 605// 606// private $causes_without_tasks = -1; 607// public function causes_without_tasks_count() { 608// if ($this->causes_without_tasks === -1) { 609// $sth = $this->model->db->prepare('SELECT COUNT(*) FROM 610// (SELECT tasks.id 611// FROM commcauses LEFT JOIN tasks ON commcauses.id = tasks.cause 612// WHERE commcauses.type > 0 AND commcauses.issue = ? 613// GROUP BY commcauses.id) 614// WHERE id IS NULL'); 615// $sth->execute(array($this->id)); 616// $count = $sth->fetchColumn(); 617// 618// $this->causes_without_tasks = (int)$count; 619// } 620// return $this->causes_without_tasks; 621// } 622 623 //http://data.agaric.com/capture-all-sent-mail-locally-postfix 624 //https://askubuntu.com/questions/192572/how-do-i-read-local-email-in-thunderbird 625 public function mail_notify($replacements=array(), $users=false) { 626 $plain = io_readFile($this->model->action->localFN('issue-notification')); 627 $html = io_readFile($this->model->action->localFN('issue-notification', 'html')); 628 629 $issue_link = DOKU_URL . 'doku.php?id='.$this->model->action->id('issue', 'id', $this->id); 630 $issue_unsubscribe = DOKU_URL . 'doku.php?id='.$this->model->action->id('issue', 'id', $this->id, 'action', 'unsubscribe'); 631 632 $issue_reps = array( 633 'issue_id' => $this->id, 634 'issue_link' => $issue_link, 635 'issue_unsubscribe' => $issue_unsubscribe, 636 'custom_content' => false, 637 'action_border_color' => 'transparent', 638 'action_color' => 'transparent', 639 ); 640 641 //$replacements can override $issue_reps 642 $rep = array_merge($issue_reps, $replacements); 643 //auto title 644 if (!isset($rep['subject'])) { 645 $rep['subject'] = '#'.$this->id. ' ' .$this->title; 646 } 647 if (!isset($rep['content_html'])) { 648 $rep['content_html'] = $rep['content']; 649 } 650 if (!isset($rep['who_full_name'])) { 651 $rep['who_full_name'] = 652 $this->model->users->get_user_full_name($rep['who']); 653 } 654 655 //format when 656 $rep['when'] = $this->date_format($rep['when']); 657 658 if ($rep['custom_content'] === false) { 659 $html = str_replace('@CONTENT_HTML@', ' 660 <div style="margin: 5px 0;"> 661 <strong>@WHO_FULL_NAME@</strong> <br> 662 <span style="color: #888">@WHEN@</span> 663 </div> 664 @CONTENT_HTML@ 665 ', $html); 666 } 667 668 //we must do it manually becouse Mailer uses htmlspecialchars() 669 $html = str_replace('@CONTENT_HTML@', $rep['content_html'], $html); 670 671 $mailer = new BEZ_Mailer(); 672 $mailer->setBody($plain, $rep, $rep, $html, false); 673 674 if ($users === FALSE) { 675 $users = $this->subscribents_array; 676 unset($users[$this->model->user_nick]); 677 } 678 679 $emails = array_map(function($user) { 680 return $this->model->users->get_user_email($user); 681 }, $users); 682 683 684 $mailer->to($emails); 685 $mailer->subject($rep['subject']); 686 687 $send = $mailer->send(); 688 if ($send === false) { 689 //this may mean empty $emails 690 //throw new Exception("can't send email"); 691 } 692 } 693 694 protected function mail_issue_box_reps($replacements=array()) { 695 $replacements['custom_content'] = true; 696 697 $html = '<h2 style="font-size: 1.2em;">'; 698 $html .= '<a style="font-size:115%" href="@ISSUE_LINK@">#@ISSUE_ID@</a> '; 699 700 if ( ! empty($this->type_string)) { 701 $html .= $this->type_string; 702 } else { 703 $html .= '<i style="color: #777"> '. 704 $this->model->action->getLang('issue_type_no_specified'). 705 '</i>'; 706 } 707 708 $html .= ' ('.$this->state_string.') '; 709 710 $html .= '<span style="color: #777; font-weight: normal; font-size: 90%;">'; 711 $html .= $this->model->action->getLang('coordinator') . ': '; 712 $html .= '<span style="font-weight: bold;">'; 713 714 if ($this->coordinator === '-proposal') { 715 $html .= '<i style="font-weight: normal;">' . 716 $this->model->action->getLang('proposal') . 717 '</i>'; 718 } else { 719 $html .= $this->model->users->get_user_full_name($this->coordinator); 720 } 721 $html .= '</span></span></h2>'; 722 723 $html .= '<h2 style="font-size: 1.2em;border-bottom: 1px solid @ACTION_BORDER_COLOR@">' . $this->title . '</h2>'; 724 725 $html .= $this->description_cache; 726 727 if ($this->state !== '0') { 728 $html .= '<h3 style="font-size:100%; border-bottom: 1px dotted #bbb">'; 729 if ($this->state === '1') { 730 $html .= $this->model->action->getLang('opinion'); 731 } else { 732 $html .= $this->model->action->getLang('reason'); 733 } 734 $html .= '</h3>'; 735 $html .= $this->opinion_cache; 736 } 737 738 $replacements['content_html'] = $html; 739 740 741 switch ($this->priority) { 742 case '0': 743 $replacements['action_color'] = '#F8E8E8'; 744 $replacements['action_border_color'] = '#F0AFAD'; 745 break; 746 case '1': 747 $replacements['action_color'] = '#ffd'; 748 $replacements['action_border_color'] = '#dd9'; 749 break; 750 case '2': 751 $replacements['action_color'] = '#EEF6F0'; 752 $replacements['action_border_color'] = '#B0D2B6'; 753 break; 754 case 'None': 755 $replacements['action_color'] = '#e7f1ff'; 756 $replacements['action_border_color'] = '#a3c8ff'; 757 break; 758 default: 759 $replacements['action_color'] = '#fff'; 760 $replacements['action_border_color'] = '#bbb'; 761 break; 762 } 763 764 return $replacements; 765 } 766 767 public function mail_notify_change_state() { 768 $this->mail_notify($this->mail_issue_box_reps(array( 769 'who' => $this->model->user_nick, 770 'action' => $this->model->action->getLang('mail_mail_notify_change_state_action'), 771 //'subject' => $this->model->action->getLang('mail_mail_notify_change_state_subject') . ' #'.$this->id 772 ))); 773 } 774 775 public function mail_notify_invite($client) { 776 $this->mail_notify($this->mail_issue_box_reps(array( 777 'who' => $this->model->user_nick, 778 'action' => $this->model->action->getLang('mail_mail_notify_invite_action'), 779 //'subject' => $this->model->action->getLang('mail_mail_notify_invite_subject') . ' #'.$this->id 780 )), array($client)); 781 } 782 783 public function mail_inform_coordinator() { 784 $this->mail_notify($this->mail_issue_box_reps(array( 785 'who' => $this->model->user_nick, 786 'action' => $this->model->action->getLang('mail_mail_inform_coordinator_action'), 787 //'subject' => $this->model->action->getLang('mail_mail_inform_coordinator_subject') . ' #'.$this->id 788 )), array($this->coordinator)); 789 } 790 791 public function mail_notify_issue_inactive($users=false) { 792 $this->mail_notify($this->mail_issue_box_reps(array( 793 'who' => '', 794 'action' => $this->model->action->getLang('mail_mail_notify_issue_inactive'), 795 )), $users); 796 } 797} 798