18a638198SSzymon Olewniczak<?php 28a638198SSzymon Olewniczak 38a638198SSzymon Olewniczaknamespace dokuwiki\plugin\bez\mdl; 48a638198SSzymon Olewniczak 5a5de966aSSzymon Olewniczakuse dokuwiki\plugin\bez\meta\ConsistencyViolationException; 68a638198SSzymon Olewniczakuse dokuwiki\plugin\bez\meta\Mailer; 78a638198SSzymon Olewniczakuse dokuwiki\plugin\bez\meta\PermissionDeniedException; 88a638198SSzymon Olewniczakuse dokuwiki\plugin\bez\meta\ValidationException; 914a1f0a4SSzymon Olewniczakuse dokuwiki\plugin\struct\types\DateTime; 10*c39bf4d9SSzymon Olewniczakuse LesserPHP\Lessc; 118a638198SSzymon Olewniczak 128a638198SSzymon Olewniczakclass Task extends Entity { 138a638198SSzymon Olewniczak 148a638198SSzymon Olewniczak protected $id; 158a638198SSzymon Olewniczak 16e8827d73SSzymon Olewniczak protected $original_poster, $assignee, $closed_by; 178a638198SSzymon Olewniczak 188a638198SSzymon Olewniczak protected $private, $lock; 198a638198SSzymon Olewniczak 208a638198SSzymon Olewniczak protected $state, $type; 218a638198SSzymon Olewniczak 228a638198SSzymon Olewniczak protected $create_date, $last_activity_date, $last_modification_date, $close_date; 238a638198SSzymon Olewniczak 248a638198SSzymon Olewniczak protected $cost, $plan_date, $all_day_event, $start_time, $finish_time; 258a638198SSzymon Olewniczak 268a638198SSzymon Olewniczak protected $content, $content_html; 278a638198SSzymon Olewniczak 288a638198SSzymon Olewniczak protected $thread_id, $thread_comment_id, $task_program_id; 298a638198SSzymon Olewniczak 308a638198SSzymon Olewniczak /** @var \dokuwiki\plugin\bez\mdl\Thread */ 318a638198SSzymon Olewniczak protected $thread; 328a638198SSzymon Olewniczak 338a638198SSzymon Olewniczak /** @var Thread_comment */ 348a638198SSzymon Olewniczak protected $thread_comment; 358a638198SSzymon Olewniczak 368a638198SSzymon Olewniczak //virtual 37ff14b107SSzymon Olewniczak protected $task_program_name, $priority, $coordinator; 388a638198SSzymon Olewniczak 398a638198SSzymon Olewniczak public static function get_columns() { 408a638198SSzymon Olewniczak return array('id', 41e8827d73SSzymon Olewniczak 'original_poster', 'assignee', 'closed_by', 428a638198SSzymon Olewniczak 'private', 'lock', 438a638198SSzymon Olewniczak 'state', 'type', 448a638198SSzymon Olewniczak 'create_date', 'last_activity_date', 'last_modification_date', 'close_date', 458a638198SSzymon Olewniczak 'cost', 'plan_date', 'all_day_event', 'start_time', 'finish_time', 468a638198SSzymon Olewniczak 'content', 'content_html', 478a638198SSzymon Olewniczak 'thread_id', 'thread_comment_id', 'task_program_id'); 488a638198SSzymon Olewniczak } 498a638198SSzymon Olewniczak 50b331b892SSzymon Olewniczak public static function get_acl_columns() { 51b331b892SSzymon Olewniczak return array_merge(parent::get_acl_columns(), array('participants')); 52b331b892SSzymon Olewniczak } 53b331b892SSzymon Olewniczak 54e8827d73SSzymon Olewniczak public static function get_types() { 55e8827d73SSzymon Olewniczak return array('correction', 'corrective', 'preventive', 'program'); 56e8827d73SSzymon Olewniczak } 57e8827d73SSzymon Olewniczak 58e8827d73SSzymon Olewniczak public static function get_states() { 59e8827d73SSzymon Olewniczak return array('opened', 'done'); 60e8827d73SSzymon Olewniczak } 61e8827d73SSzymon Olewniczak 628a638198SSzymon Olewniczak public function __get($property) { 63ff14b107SSzymon Olewniczak if ($property == 'thread') { 64ff14b107SSzymon Olewniczak if ($this->thread_id == null) { 65ff14b107SSzymon Olewniczak return null; 66ff14b107SSzymon Olewniczak } 679110c699SSzymon Olewniczak if ($this->thread == null || $this->thread_id != $this->thread->id) { 68ff14b107SSzymon Olewniczak $this->thread = $this->model->threadFactory->get_one($this->thread_id); 69ff14b107SSzymon Olewniczak } 70ff14b107SSzymon Olewniczak return $this->thread; 71ff14b107SSzymon Olewniczak 72ff14b107SSzymon Olewniczak } elseif($property == 'thread_comment') { 73ff14b107SSzymon Olewniczak if ($this->thread_comment_id == null) { 74ff14b107SSzymon Olewniczak return null; 75ff14b107SSzymon Olewniczak } 769110c699SSzymon Olewniczak if ($this->thread_comment == null || $this->thread_comment_id != $this->thread_comment->id) { 7753df74e7SSzymon Olewniczak $this->thread_comment = $this->model->thread_commentFactory->get_one($this->thread_comment_id); 78ff14b107SSzymon Olewniczak } 79ff14b107SSzymon Olewniczak return $this->thread_comment; 80ff14b107SSzymon Olewniczak 81ff14b107SSzymon Olewniczak } elseif($property == 'priority' || $property == 'coordinator' || $property == 'task_program_name') { 828a638198SSzymon Olewniczak return $this->$property; 838a638198SSzymon Olewniczak } 848a638198SSzymon Olewniczak return parent::__get($property); 858a638198SSzymon Olewniczak } 868a638198SSzymon Olewniczak 878a638198SSzymon Olewniczak public function __construct($model, $defaults=array()) { 888a638198SSzymon Olewniczak parent::__construct($model, $defaults); 898a638198SSzymon Olewniczak 908a638198SSzymon Olewniczak $this->validator->set_rules(array( 91d5a60e5aSSzymon Olewniczak 'type' => array(array('select', array('corrective', 'preventive')), 'NULL'), // only corrective, preventive can be set this way 928a638198SSzymon Olewniczak 'assignee' => array(array('dw_user'), 'NOT NULL'), 938a638198SSzymon Olewniczak 'cost' => array(array('numeric'), 'NULL'), 948a638198SSzymon Olewniczak 'plan_date' => array(array('iso_date'), 'NOT NULL'), 958a638198SSzymon Olewniczak 'all_day_event' => array(array('select', array('0', '1')), 'NOT NULL'), 968a638198SSzymon Olewniczak 'start_time' => array(array('time'), 'NULL'), 978a638198SSzymon Olewniczak 'finish_time' => array(array('time'), 'NULL'), 988a638198SSzymon Olewniczak 'content' => array(array('length', 10000), 'NOT NULL'), 99e8827d73SSzymon Olewniczak 'thread_comment_id' => array(array('numeric'), 'NULL'), 1008a638198SSzymon Olewniczak 'task_program_id' => array(array('numeric'), 'NULL') 1018a638198SSzymon Olewniczak )); 1028a638198SSzymon Olewniczak 1038a638198SSzymon Olewniczak //we've created empty object 1048a638198SSzymon Olewniczak if ($this->id === NULL) { 1058a638198SSzymon Olewniczak $this->original_poster = $this->model->user_nick; 1068a638198SSzymon Olewniczak $this->create_date = date('c'); 1078a638198SSzymon Olewniczak $this->last_activity_date = $this->create_date; 1088a638198SSzymon Olewniczak $this->last_modification_date = $this->create_date; 1098a638198SSzymon Olewniczak 1108a638198SSzymon Olewniczak $this->state = 'opened'; 1118a638198SSzymon Olewniczak 1128a638198SSzymon Olewniczak if (isset($defaults['thread'])) { 1138a638198SSzymon Olewniczak $this->thread = $defaults['thread']; 1148a638198SSzymon Olewniczak $this->thread_id = $this->thread->id; 11553df74e7SSzymon Olewniczak $this->coordinator = $this->thread->coordinator; 1166f380773SSzymon Olewniczak 1176f380773SSzymon Olewniczak if ($this->thread->private == '1') { 1186f380773SSzymon Olewniczak $this->private = '1'; 1196f380773SSzymon Olewniczak } 1206f380773SSzymon Olewniczak 1218a638198SSzymon Olewniczak $this->type = 'correction'; 1228a638198SSzymon Olewniczak 1238a638198SSzymon Olewniczak if (isset($defaults['thread_comment'])) { 1248a638198SSzymon Olewniczak $this->thread_comment = $defaults['thread_comment']; 1258a638198SSzymon Olewniczak $this->thread_comment_id = $this->thread_comment->id; 126e8827d73SSzymon Olewniczak 1270a76bbd8SSzymon Olewniczak if ($this->thread_comment->type == 'cause') { 1288a638198SSzymon Olewniczak $this->type = 'corrective'; 129e8827d73SSzymon Olewniczak } else { 130e8827d73SSzymon Olewniczak $this->type = 'preventive'; 131e8827d73SSzymon Olewniczak } 1328a638198SSzymon Olewniczak } 133ff14b107SSzymon Olewniczak } else { 134ff14b107SSzymon Olewniczak $this->type = 'program'; 1358a638198SSzymon Olewniczak } 136a0cd8c78SSzymon Olewniczak 1376f380773SSzymon Olewniczak 1386f380773SSzymon Olewniczak if ($this->thread_id == '') { 1396f380773SSzymon Olewniczak $this->validator->set_rules(array( 1406f380773SSzymon Olewniczak 'task_program_id' => array(array('numeric'), 'NOT NULL'), 1416f380773SSzymon Olewniczak )); 1426f380773SSzymon Olewniczak //this field is unused in program tasks 1436f380773SSzymon Olewniczak $this->validator->delete_rule('thread_comment_id'); 1446f380773SSzymon Olewniczak } 1456f380773SSzymon Olewniczak 146a0cd8c78SSzymon Olewniczak //everyone can report their own program tasks 147a0cd8c78SSzymon Olewniczak if ($this->type == 'program') { 148a0cd8c78SSzymon Olewniczak $this->acl->grant('content', BEZ_PERMISSION_CHANGE); 149a0cd8c78SSzymon Olewniczak $this->acl->grant('plan_date', BEZ_PERMISSION_CHANGE); 150a0cd8c78SSzymon Olewniczak $this->acl->grant('start_time', BEZ_PERMISSION_CHANGE); 151a0cd8c78SSzymon Olewniczak $this->acl->grant('finish_time', BEZ_PERMISSION_CHANGE); 152a0cd8c78SSzymon Olewniczak $this->acl->grant('all_day_event', BEZ_PERMISSION_CHANGE); 153a0cd8c78SSzymon Olewniczak $this->acl->grant('task_program_id', BEZ_PERMISSION_CHANGE); 154a0cd8c78SSzymon Olewniczak $this->acl->grant('cost', BEZ_PERMISSION_CHANGE); 155a0cd8c78SSzymon Olewniczak } 156a0cd8c78SSzymon Olewniczak 157a0cd8c78SSzymon Olewniczak if ($this->type == 'program' && $this->model->get_level() >= BEZ_AUTH_LEADER) { 158a0cd8c78SSzymon Olewniczak $this->acl->grant('assignee', BEZ_PERMISSION_CHANGE); 159a0cd8c78SSzymon Olewniczak $this->acl->grant('participants', BEZ_PERMISSION_CHANGE); 160a0cd8c78SSzymon Olewniczak } 161a0cd8c78SSzymon Olewniczak 162a0cd8c78SSzymon Olewniczak if ($this->type != 'program' && $this->coordinator == $this->model->user_nick) { 163a0cd8c78SSzymon Olewniczak $this->acl->grant('content', BEZ_PERMISSION_CHANGE); 164a0cd8c78SSzymon Olewniczak $this->acl->grant('plan_date', BEZ_PERMISSION_CHANGE); 165a0cd8c78SSzymon Olewniczak $this->acl->grant('start_time', BEZ_PERMISSION_CHANGE); 166a0cd8c78SSzymon Olewniczak $this->acl->grant('finish_time', BEZ_PERMISSION_CHANGE); 167a0cd8c78SSzymon Olewniczak $this->acl->grant('all_day_event', BEZ_PERMISSION_CHANGE); 168a0cd8c78SSzymon Olewniczak $this->acl->grant('task_program_id', BEZ_PERMISSION_CHANGE); 169a0cd8c78SSzymon Olewniczak $this->acl->grant('cost', BEZ_PERMISSION_CHANGE); 170a0cd8c78SSzymon Olewniczak 171a0cd8c78SSzymon Olewniczak $this->acl->grant('assignee', BEZ_PERMISSION_CHANGE); 172a0cd8c78SSzymon Olewniczak $this->acl->grant('participants', BEZ_PERMISSION_CHANGE); 173a0cd8c78SSzymon Olewniczak } 174a0cd8c78SSzymon Olewniczak 175e8827d73SSzymon Olewniczak //we get object form db 176e8827d73SSzymon Olewniczak } else { 177e8827d73SSzymon Olewniczak if (isset($defaults['thread']) && $this->thread_id == $defaults['thread']->id) { 178e8827d73SSzymon Olewniczak $this->thread = $defaults['thread']; 179e8827d73SSzymon Olewniczak } 180e8827d73SSzymon Olewniczak 181e8827d73SSzymon Olewniczak if (isset($defaults['thread_comment']) && $this->thread_comment_id == $defaults['thread_comment']->id) { 182e8827d73SSzymon Olewniczak $this->thread_comment = $defaults['thread_comment']; 183e8827d73SSzymon Olewniczak } 184e8827d73SSzymon Olewniczak 1856f380773SSzymon Olewniczak if ($this->thread_id == '') { 1866f380773SSzymon Olewniczak $this->validator->set_rules(array( 1876f380773SSzymon Olewniczak 'task_program_id' => array(array('numeric'), 'NOT NULL'), 1886f380773SSzymon Olewniczak )); 1896f380773SSzymon Olewniczak //this field is unused in program tasks 1906f380773SSzymon Olewniczak $this->validator->delete_rule('thread_comment_id'); 1916f380773SSzymon Olewniczak } 1926f380773SSzymon Olewniczak 1936f380773SSzymon Olewniczak //private tasks 1946f380773SSzymon Olewniczak if ($this->model->level < BEZ_AUTH_ADMIN && $this->private == '1') { 1956f380773SSzymon Olewniczak if ($this->get_participant($this->model->user_nick) === false && 1966f380773SSzymon Olewniczak ($this->thread_id != '' && $this->__get('thread')->get_participant($this->model->user_nick) === false)) { 1976f380773SSzymon Olewniczak $this->acl->revoke(self::get_select_columns(), BEZ_AUTH_LEADER); 1986f380773SSzymon Olewniczak return; 1996f380773SSzymon Olewniczak } 2006f380773SSzymon Olewniczak } 2016f380773SSzymon Olewniczak 202a0cd8c78SSzymon Olewniczak //user can close their tasks 203a0cd8c78SSzymon Olewniczak if ($this->assignee == $this->model->user_nick || $this->model->get_level() >= BEZ_AUTH_LEADER) { 204a0cd8c78SSzymon Olewniczak $this->acl->grant('state', BEZ_PERMISSION_CHANGE); 205a0cd8c78SSzymon Olewniczak } 206a0cd8c78SSzymon Olewniczak 207a0cd8c78SSzymon Olewniczak if ($this->type == 'program' && $this->original_poster == $this->model->user_nick) { 208a0cd8c78SSzymon Olewniczak $this->acl->grant('content', BEZ_PERMISSION_CHANGE); 209a0cd8c78SSzymon Olewniczak $this->acl->grant('plan_date', BEZ_PERMISSION_CHANGE); 210a0cd8c78SSzymon Olewniczak $this->acl->grant('start_time', BEZ_PERMISSION_CHANGE); 211a0cd8c78SSzymon Olewniczak $this->acl->grant('finish_time', BEZ_PERMISSION_CHANGE); 212a0cd8c78SSzymon Olewniczak $this->acl->grant('all_day_event', BEZ_PERMISSION_CHANGE); 213a0cd8c78SSzymon Olewniczak $this->acl->grant('task_program_id', BEZ_PERMISSION_CHANGE); 214a0cd8c78SSzymon Olewniczak $this->acl->grant('cost', BEZ_PERMISSION_CHANGE); 215a0cd8c78SSzymon Olewniczak } 216a0cd8c78SSzymon Olewniczak 217a0cd8c78SSzymon Olewniczak if (($this->type != 'program' && $this->coordinator == $this->model->user_nick) || 218a0cd8c78SSzymon Olewniczak ($this->model->get_level() >= BEZ_AUTH_LEADER)) { 219a0cd8c78SSzymon Olewniczak $this->acl->grant('content', BEZ_PERMISSION_CHANGE); 220a0cd8c78SSzymon Olewniczak $this->acl->grant('plan_date', BEZ_PERMISSION_CHANGE); 221a0cd8c78SSzymon Olewniczak $this->acl->grant('start_time', BEZ_PERMISSION_CHANGE); 222a0cd8c78SSzymon Olewniczak $this->acl->grant('finish_time', BEZ_PERMISSION_CHANGE); 223a0cd8c78SSzymon Olewniczak $this->acl->grant('all_day_event', BEZ_PERMISSION_CHANGE); 224a0cd8c78SSzymon Olewniczak $this->acl->grant('task_program_id', BEZ_PERMISSION_CHANGE); 225a0cd8c78SSzymon Olewniczak $this->acl->grant('cost', BEZ_PERMISSION_CHANGE); 226a0cd8c78SSzymon Olewniczak 227a0cd8c78SSzymon Olewniczak $this->acl->grant('assignee', BEZ_PERMISSION_CHANGE); 228a0cd8c78SSzymon Olewniczak $this->acl->grant('participants', BEZ_PERMISSION_CHANGE); 229f7519ef1SSzymon Olewniczak $this->acl->grant('state', BEZ_PERMISSION_CHANGE); 230a0cd8c78SSzymon Olewniczak } 231e8827d73SSzymon Olewniczak } 2328a638198SSzymon Olewniczak } 2338a638198SSzymon Olewniczak 23414a1f0a4SSzymon Olewniczak public function update_virutal() { 23514a1f0a4SSzymon Olewniczak if ($this->state == 'done') { 23614a1f0a4SSzymon Olewniczak $this->priority = ''; 23714a1f0a4SSzymon Olewniczak } else { 23814a1f0a4SSzymon Olewniczak $now = date('Y-m-d'); 23914a1f0a4SSzymon Olewniczak $plus_1_month = date('Y-m-d', strtotime('+1 month')); 24014a1f0a4SSzymon Olewniczak 24114a1f0a4SSzymon Olewniczak if ($this->plan_date >= $plus_1_month) { 24214a1f0a4SSzymon Olewniczak $this->priority = '0'; 24314a1f0a4SSzymon Olewniczak } elseif ($this->plan_date >= $now) { 24414a1f0a4SSzymon Olewniczak $this->priority = '1'; 24514a1f0a4SSzymon Olewniczak } else { 24614a1f0a4SSzymon Olewniczak $this->priority = '2'; 24714a1f0a4SSzymon Olewniczak } 24814a1f0a4SSzymon Olewniczak } 24914a1f0a4SSzymon Olewniczak } 2508a638198SSzymon Olewniczak 2518a638198SSzymon Olewniczak public function set_data($post, $filter=NULL) { 252ff14b107SSzymon Olewniczak //all day event 253ff14b107SSzymon Olewniczak if (!isset($post['all_day_event'])) { 254ff14b107SSzymon Olewniczak $post['all_day_event'] = '0'; 255ff14b107SSzymon Olewniczak } 256ff14b107SSzymon Olewniczak 25753df74e7SSzymon Olewniczak parent::set_data($post); 25853df74e7SSzymon Olewniczak 2592448d85aSSzymon Olewniczak $this->purge(); 26053df74e7SSzymon Olewniczak 2619110c699SSzymon Olewniczak if ($this->thread_id == '') { 2629110c699SSzymon Olewniczak $this->type = 'program'; 2639110c699SSzymon Olewniczak } elseif ($this->thread_comment_id == '') { 2649110c699SSzymon Olewniczak $this->type = 'correction'; 2659110c699SSzymon Olewniczak } 2669110c699SSzymon Olewniczak 26753df74e7SSzymon Olewniczak if (!isset($post['assignee'])) { 26853df74e7SSzymon Olewniczak $this->assignee = $this->model->user_nick; 26953df74e7SSzymon Olewniczak } 27053df74e7SSzymon Olewniczak 27153df74e7SSzymon Olewniczak //update dates 27253df74e7SSzymon Olewniczak $this->last_modification_date = date('c'); 27353df74e7SSzymon Olewniczak $this->last_activity_date = $this->last_modification_date; 27453df74e7SSzymon Olewniczak 27514a1f0a4SSzymon Olewniczak //update virtual 27614a1f0a4SSzymon Olewniczak $this->update_virutal(); 27714a1f0a4SSzymon Olewniczak 2788a638198SSzymon Olewniczak return true; 2798a638198SSzymon Olewniczak } 2808a638198SSzymon Olewniczak 281e8827d73SSzymon Olewniczak public function set_state($state) { 282e8827d73SSzymon Olewniczak if ($this->acl_of('state') < BEZ_PERMISSION_CHANGE) { 283e8827d73SSzymon Olewniczak throw new PermissionDeniedException(); 284e8827d73SSzymon Olewniczak } 285e8827d73SSzymon Olewniczak 286e8827d73SSzymon Olewniczak if (!in_array($state, array('opened', 'done'))) { 287e8827d73SSzymon Olewniczak throw new ValidationException('task', array('sholud be opened or done')); 288e8827d73SSzymon Olewniczak } 289e8827d73SSzymon Olewniczak 290e8827d73SSzymon Olewniczak //nothing to do 291e8827d73SSzymon Olewniczak if ($state == $this->state) { 292e8827d73SSzymon Olewniczak return; 293e8827d73SSzymon Olewniczak } 294e8827d73SSzymon Olewniczak 295e8827d73SSzymon Olewniczak if ($state == 'done') { 296c8bd19cbSSzymon Olewniczak $this->state = $state; 297c8bd19cbSSzymon Olewniczak $this->closed_by = $this->model->user_nick; 298c8bd19cbSSzymon Olewniczak $this->close_date = date('c'); 299c8bd19cbSSzymon Olewniczak 300e8827d73SSzymon Olewniczak $this->model->sqlite->query("UPDATE {$this->get_table_name()} SET state=?, closed_by=?, close_date=? WHERE id=?", 301c8bd19cbSSzymon Olewniczak $this->state, 302c8bd19cbSSzymon Olewniczak $this->closed_by, 303c8bd19cbSSzymon Olewniczak $this->close_date, 304e8827d73SSzymon Olewniczak $this->id); 305e8827d73SSzymon Olewniczak //reopen the task 306e8827d73SSzymon Olewniczak } else { 307e8827d73SSzymon Olewniczak $this->model->sqlite->query("UPDATE {$this->get_table_name()} SET state=? WHERE id=?", $state, $this->id); 308e8827d73SSzymon Olewniczak } 309e8827d73SSzymon Olewniczak 310e8827d73SSzymon Olewniczak $this->state = $state; 311e8827d73SSzymon Olewniczak } 312e8827d73SSzymon Olewniczak 313f6c28761SSzymon Olewniczak public function set_task_program($taks_program_id) { 314f6c28761SSzymon Olewniczak $this->task_program_id = $taks_program_id; 315f6c28761SSzymon Olewniczak } 316f6c28761SSzymon Olewniczak 317e8827d73SSzymon Olewniczak public function update_last_activity() { 318e8827d73SSzymon Olewniczak $this->last_activity_date = date('c'); 319e8827d73SSzymon Olewniczak $this->model->sqlite->query('UPDATE task SET last_activity_date=? WHERE id=?', 320e8827d73SSzymon Olewniczak $this->last_activity_date, $this->id); 321e8827d73SSzymon Olewniczak } 322e8827d73SSzymon Olewniczak 323f7519ef1SSzymon Olewniczak public function can_add_comments() { 324d5a60e5aSSzymon Olewniczak if ($this->thread_id != '' && $this->type != 'preventive' && $this->thread->state == 'closed') { 325f7519ef1SSzymon Olewniczak return false; 326f7519ef1SSzymon Olewniczak } 327f7519ef1SSzymon Olewniczak 328f7519ef1SSzymon Olewniczak if ($this->state == 'opened' || 329f7519ef1SSzymon Olewniczak ($this->state == 'done' && 330f7519ef1SSzymon Olewniczak $this->acl_of('state') >= BEZ_PERMISSION_CHANGE)) { 331f7519ef1SSzymon Olewniczak return true; 332f7519ef1SSzymon Olewniczak } 333f7519ef1SSzymon Olewniczak 334f7519ef1SSzymon Olewniczak return false; 335f7519ef1SSzymon Olewniczak } 336f7519ef1SSzymon Olewniczak 337a0cd8c78SSzymon Olewniczak public function can_add_participants() { 338a0cd8c78SSzymon Olewniczak return in_array($this->state, array('opened')); 339a0cd8c78SSzymon Olewniczak } 340a0cd8c78SSzymon Olewniczak 341e8827d73SSzymon Olewniczak public function get_participants($filter='') { 342e8827d73SSzymon Olewniczak if ($this->id === NULL) { 343e8827d73SSzymon Olewniczak return array(); 344e8827d73SSzymon Olewniczak } 345e8827d73SSzymon Olewniczak 346e8827d73SSzymon Olewniczak $sql = 'SELECT * FROM task_participant WHERE'; 347e8827d73SSzymon Olewniczak $possible_flags = array('original_poster', 'assignee', 'commentator', 'subscribent'); 348e8827d73SSzymon Olewniczak if ($filter != '') { 349e8827d73SSzymon Olewniczak if (!in_array($filter, $possible_flags)) { 350e8827d73SSzymon Olewniczak throw new \Exception("unknown flag $filter"); 351e8827d73SSzymon Olewniczak } 352e8827d73SSzymon Olewniczak $sql .= " $filter=1 AND"; 353e8827d73SSzymon Olewniczak } 354b331b892SSzymon Olewniczak $sql .= ' task_id=? AND removed=0 ORDER BY user_id'; 355e8827d73SSzymon Olewniczak 356e8827d73SSzymon Olewniczak $r = $this->model->sqlite->query($sql, $this->id); 357e8827d73SSzymon Olewniczak $pars = $this->model->sqlite->res2arr($r); 358e8827d73SSzymon Olewniczak $participants = array(); 359e8827d73SSzymon Olewniczak foreach ($pars as $par) { 360e8827d73SSzymon Olewniczak $participants[$par['user_id']] = $par; 361e8827d73SSzymon Olewniczak } 362e8827d73SSzymon Olewniczak 363e8827d73SSzymon Olewniczak return $participants; 364e8827d73SSzymon Olewniczak } 365e8827d73SSzymon Olewniczak 366b331b892SSzymon Olewniczak public function get_participant($user_id, $can_be_removed=false) { 367e8827d73SSzymon Olewniczak if ($this->id === NULL) { 368e8827d73SSzymon Olewniczak return array(); 369e8827d73SSzymon Olewniczak } 370e8827d73SSzymon Olewniczak 371b331b892SSzymon Olewniczak $q = 'SELECT * FROM task_participant WHERE task_id=? AND user_id=?'; 372b331b892SSzymon Olewniczak if (!$can_be_removed) { 373b331b892SSzymon Olewniczak $q .= ' AND removed=0'; 374b331b892SSzymon Olewniczak } 375b331b892SSzymon Olewniczak $r = $this->model->sqlite->query($q, $this->id, $user_id); 376e8827d73SSzymon Olewniczak $par = $this->model->sqlite->res2row($r); 377e8827d73SSzymon Olewniczak if (!is_array($par)) { 378e8827d73SSzymon Olewniczak return false; 379e8827d73SSzymon Olewniczak } 380e8827d73SSzymon Olewniczak 381e8827d73SSzymon Olewniczak return $par; 382e8827d73SSzymon Olewniczak } 383e8827d73SSzymon Olewniczak 384e8827d73SSzymon Olewniczak public function is_subscribent($user_id=null) { 385e8827d73SSzymon Olewniczak if ($user_id == null) { 386e8827d73SSzymon Olewniczak $user_id = $this->model->user_nick; 387e8827d73SSzymon Olewniczak } 388e8827d73SSzymon Olewniczak $par = $this->get_participant($user_id); 389e8827d73SSzymon Olewniczak if ($par['subscribent'] == 1) { 390e8827d73SSzymon Olewniczak return true; 391e8827d73SSzymon Olewniczak } 392e8827d73SSzymon Olewniczak return false; 393e8827d73SSzymon Olewniczak } 394e8827d73SSzymon Olewniczak 395e8827d73SSzymon Olewniczak public function remove_participant_flags($user_id, $flags) { 396e8827d73SSzymon Olewniczak //thread not saved yet 397e8827d73SSzymon Olewniczak if ($this->id === NULL) { 398e8827d73SSzymon Olewniczak throw new \Exception('cannot remove flags from not saved thread'); 399e8827d73SSzymon Olewniczak } 400e8827d73SSzymon Olewniczak 401b331b892SSzymon Olewniczak $participant = $this->get_participant($user_id, true); 402b331b892SSzymon Olewniczak if ($participant === false) { 403b331b892SSzymon Olewniczak throw new ConsistencyViolationException("$user_id isn't participant"); 404b331b892SSzymon Olewniczak } 405b331b892SSzymon Olewniczak 406e8827d73SSzymon Olewniczak $possible_flags = array('original_poster', 'assignee', 'commentator', 'subscribent'); 407e8827d73SSzymon Olewniczak if (array_intersect($flags, $possible_flags) != $flags) { 408e8827d73SSzymon Olewniczak throw new \Exception('unknown flags'); 409e8827d73SSzymon Olewniczak } 410e8827d73SSzymon Olewniczak 411e8827d73SSzymon Olewniczak $set = implode(',', array_map(function ($v) { return "$v=0"; }, $flags)); 412e8827d73SSzymon Olewniczak 413e8827d73SSzymon Olewniczak $sql = "UPDATE task_participant SET $set WHERE task_id=? AND user_id=?"; 414e8827d73SSzymon Olewniczak $this->model->sqlite->query($sql, $this->id, $user_id); 415e8827d73SSzymon Olewniczak 416e8827d73SSzymon Olewniczak } 417e8827d73SSzymon Olewniczak 418e8827d73SSzymon Olewniczak public function set_participant_flags($user_id, $flags=array()) { 419e8827d73SSzymon Olewniczak //thread not saved yet 420e8827d73SSzymon Olewniczak if ($this->id === NULL) { 421e8827d73SSzymon Olewniczak throw new \Exception('cannot add flags to not saved thread'); 422e8827d73SSzymon Olewniczak } 423e8827d73SSzymon Olewniczak 424e8827d73SSzymon Olewniczak //validate user 425e8827d73SSzymon Olewniczak if (!$this->model->userFactory->exists($user_id)) { 426e8827d73SSzymon Olewniczak throw new \Exception("$user_id isn't dokuwiki user"); 427e8827d73SSzymon Olewniczak } 428e8827d73SSzymon Olewniczak 429e8827d73SSzymon Olewniczak $possible_flags = array('original_poster', 'assignee', 'commentator', 'subscribent'); 430e8827d73SSzymon Olewniczak if (array_intersect($flags, $possible_flags) != $flags) { 431e8827d73SSzymon Olewniczak throw new \Exception('unknown flags'); 432e8827d73SSzymon Olewniczak } 433e8827d73SSzymon Olewniczak 434b331b892SSzymon Olewniczak $participant = $this->get_participant($user_id, true); 435e8827d73SSzymon Olewniczak if ($participant == false) { 436e8827d73SSzymon Olewniczak $participant = array_fill_keys($possible_flags, 0); 437e8827d73SSzymon Olewniczak 438e8827d73SSzymon Olewniczak $participant['task_id'] = $this->id; 439e8827d73SSzymon Olewniczak $participant['user_id'] = $user_id; 440e8827d73SSzymon Olewniczak $participant['added_by'] = $this->model->user_nick; 441e8827d73SSzymon Olewniczak $participant['added_date'] = date('c'); 442b331b892SSzymon Olewniczak 443e8827d73SSzymon Olewniczak $values = array_merge($participant, array_fill_keys($flags, 1)); 444b331b892SSzymon Olewniczak $this->model->sqlite->storeEntry('task_participant', $values); 445b331b892SSzymon Olewniczak } else { 446b331b892SSzymon Olewniczak $set = implode(',', array_map(function($flag) { return "$flag=1"; }, $flags)); 447e8827d73SSzymon Olewniczak 448b331b892SSzymon Olewniczak if ($participant['removed'] == '1') { 449b331b892SSzymon Olewniczak $set .= ',removed=0'; 450b331b892SSzymon Olewniczak } 451e8827d73SSzymon Olewniczak 452b331b892SSzymon Olewniczak $q = "UPDATE task_participant SET $set WHERE task_id=? AND user_id=?"; 453b331b892SSzymon Olewniczak $this->model->sqlite->query($q, $this->id, $user_id); 454b331b892SSzymon Olewniczak } 455b331b892SSzymon Olewniczak } 456b331b892SSzymon Olewniczak 457b331b892SSzymon Olewniczak public function remove_participant($user_id) { 458b331b892SSzymon Olewniczak //thread not saved yet 459b331b892SSzymon Olewniczak if ($this->id === NULL) { 460b331b892SSzymon Olewniczak throw new \Exception('cannot remove flags from not saved thread'); 461b331b892SSzymon Olewniczak } 462b331b892SSzymon Olewniczak 463b331b892SSzymon Olewniczak $participant = $this->get_participant($user_id); 464b331b892SSzymon Olewniczak if ($participant === false) { 465b331b892SSzymon Olewniczak throw new ConsistencyViolationException("$user_id isn't participant"); 466b331b892SSzymon Olewniczak } 467b331b892SSzymon Olewniczak 468b331b892SSzymon Olewniczak if ($participant['assignee'] == '1') { 469b331b892SSzymon Olewniczak throw new ConsistencyViolationException("cannot remove assignee"); 470b331b892SSzymon Olewniczak } 471b331b892SSzymon Olewniczak 472b331b892SSzymon Olewniczak $q = "UPDATE task_participant SET removed=1 WHERE task_id=? AND user_id=?"; 473b331b892SSzymon Olewniczak $this->model->sqlite->query($q, $this->id, $user_id); 474b331b892SSzymon Olewniczak 475e8827d73SSzymon Olewniczak } 476e8827d73SSzymon Olewniczak 477a5de966aSSzymon Olewniczak public function pin($thread_id) { 478a5de966aSSzymon Olewniczak if ($this->acl_of('thread_id') < BEZ_PERMISSION_CHANGE) { 479a5de966aSSzymon Olewniczak throw new PermissionDeniedException(); 480a5de966aSSzymon Olewniczak } 481a5de966aSSzymon Olewniczak if ($this->thread_id != '') { 482a5de966aSSzymon Olewniczak throw new ConsistencyViolationException('task already pinned to thread'); 483a5de966aSSzymon Olewniczak } 484a5de966aSSzymon Olewniczak 485a5de966aSSzymon Olewniczak //check if thread exists and isn't closed 486ef211518SSzymon Olewniczak $q = "SELECT id, private FROM thread_view WHERE id = ? AND state IN ('opened', 'done')"; 487a5de966aSSzymon Olewniczak $r = $this->model->sqlite->query($q, $thread_id); 488ef211518SSzymon Olewniczak $thread = $this->model->sqlite->res_fetch_assoc($r); 489ef211518SSzymon Olewniczak if (!$thread) { 490a5de966aSSzymon Olewniczak throw new ValidationException("task", array('thread_id' => 'pin_task')); 491a5de966aSSzymon Olewniczak } 492ef211518SSzymon Olewniczak 493ef211518SSzymon Olewniczak //if thread was private task is also private 494ef211518SSzymon Olewniczak $q = "UPDATE task SET type='correction', thread_id=?"; 495ef211518SSzymon Olewniczak if ($thread['private']) { 496ef211518SSzymon Olewniczak $q .= ", private=1"; 497ef211518SSzymon Olewniczak } 498ef211518SSzymon Olewniczak $q .= " WHERE id=?"; 499a5de966aSSzymon Olewniczak $this->model->sqlite->query($q, $thread_id, $this->id); 500a5de966aSSzymon Olewniczak } 501a5de966aSSzymon Olewniczak 502a5de966aSSzymon Olewniczak public function unpin() { 503a5de966aSSzymon Olewniczak if ($this->acl_of('thread_id') < BEZ_PERMISSION_CHANGE) { 504a5de966aSSzymon Olewniczak throw new PermissionDeniedException(); 505a5de966aSSzymon Olewniczak } 506a5de966aSSzymon Olewniczak 5075a4034efSSzymon Olewniczak $q = "UPDATE task SET type='program', thread_id='', thread_comment_id='', private=0 WHERE id=?"; 508a5de966aSSzymon Olewniczak $this->model->sqlite->query($q, $this->id); 509a5de966aSSzymon Olewniczak } 510a5de966aSSzymon Olewniczak 511e8827d73SSzymon Olewniczak public function invite($client) { 512e8827d73SSzymon Olewniczak $this->set_participant_flags($client, array('subscribent')); 513e8827d73SSzymon Olewniczak $this->mail_notify_invite($client); 514e8827d73SSzymon Olewniczak } 5155b88664dSSzymon Olewniczak 5165b88664dSSzymon Olewniczak protected function html_link_url() { 5175b88664dSSzymon Olewniczak $tpl = $this->model->action->get_tpl(); 5185b88664dSSzymon Olewniczak return $tpl->url('task', 'tid', $this->id); 5195b88664dSSzymon Olewniczak } 5205b88664dSSzymon Olewniczak 5215b88664dSSzymon Olewniczak protected function html_link_content() { 5225b88664dSSzymon Olewniczak $ret = ''; 5235b88664dSSzymon Olewniczak if ($this->thread_id != '') { 5245b88664dSSzymon Olewniczak $ret .= '#'.$this->thread_id . ' '; 5255b88664dSSzymon Olewniczak } 5265b88664dSSzymon Olewniczak return $ret . '#z' . $this->id; 5275b88664dSSzymon Olewniczak } 528e8827d73SSzymon Olewniczak 52967fdb426SSzymon Olewniczak protected function getMailSubject() 53067fdb426SSzymon Olewniczak { 53167fdb426SSzymon Olewniczak return parent::getMailSubject() . ' #z'.$this->id. ' ' . $this->task_program_name; // TODO: Change the autogenerated stub 5328a638198SSzymon Olewniczak } 5338a638198SSzymon Olewniczak 53414a1f0a4SSzymon Olewniczak public function mail_task_box(&$attachedImages) { 53514a1f0a4SSzymon Olewniczak $tpl = $this->model->action->get_tpl(); 53614a1f0a4SSzymon Olewniczak 53714a1f0a4SSzymon Olewniczak //render style 538*c39bf4d9SSzymon Olewniczak $less = new Lessc(); 53914a1f0a4SSzymon Olewniczak $less->addImportDir(DOKU_PLUGIN . 'bez/style/'); 54014a1f0a4SSzymon Olewniczak $style = $less->compileFile(DOKU_PLUGIN . 'bez/style/task.less'); 54114a1f0a4SSzymon Olewniczak 54214a1f0a4SSzymon Olewniczak //render content for mail 54314a1f0a4SSzymon Olewniczak $old_content_html = $this->content_html; 54414a1f0a4SSzymon Olewniczak $this->content_html = p_render('bez_xhtmlmail', p_get_instructions($this->content), $info); 54514a1f0a4SSzymon Olewniczak $attachedImages = array_merge($attachedImages, $info['img']); 54614a1f0a4SSzymon Olewniczak 54714a1f0a4SSzymon Olewniczak $tpl->set('task', $this); 54814a1f0a4SSzymon Olewniczak $tpl->set('style', $style); 54914a1f0a4SSzymon Olewniczak $tpl->set('no_actions', true); 55014a1f0a4SSzymon Olewniczak $task_box = $this->model->action->bez_tpl_include('task_box', true); 55114a1f0a4SSzymon Olewniczak 55214a1f0a4SSzymon Olewniczak $this->content_html = $old_content_html; 55314a1f0a4SSzymon Olewniczak 55414a1f0a4SSzymon Olewniczak return $task_box; 555e8827d73SSzymon Olewniczak } 556e8827d73SSzymon Olewniczak 55714a1f0a4SSzymon Olewniczak public function mail_task(&$attachedImages) { 55814a1f0a4SSzymon Olewniczak $tpl = $this->model->action->get_tpl(); 55914a1f0a4SSzymon Olewniczak 56014a1f0a4SSzymon Olewniczak $task_box = $this->mail_task_box($attachedImages); 56114a1f0a4SSzymon Olewniczak $tpl->set('content', $task_box); 56214a1f0a4SSzymon Olewniczak $content = $this->model->action->bez_tpl_include('mail/task', true); 56314a1f0a4SSzymon Olewniczak 56414a1f0a4SSzymon Olewniczak return $content; 565e8827d73SSzymon Olewniczak } 566e8827d73SSzymon Olewniczak 56714a1f0a4SSzymon Olewniczak public function mail_notify_assignee() { 56814a1f0a4SSzymon Olewniczak $tpl = $this->model->action->get_tpl(); 569e8827d73SSzymon Olewniczak 57014a1f0a4SSzymon Olewniczak //we don't want who 57114a1f0a4SSzymon Olewniczak $tpl->set('who', $this->model->user_nick); 57214a1f0a4SSzymon Olewniczak $tpl->set('action', 'mail_task_assignee'); 57314a1f0a4SSzymon Olewniczak $attachedImages = array(); 57414a1f0a4SSzymon Olewniczak $content = $this->mail_task($attachedImages); 57514a1f0a4SSzymon Olewniczak $this->mail_notify($content, array($this->assignee), $attachedImages); 5768a638198SSzymon Olewniczak } 5778a638198SSzymon Olewniczak 578d571026cSSzymon Olewniczak public function mail_notify_remind($users=false, $days=1) { 57914a1f0a4SSzymon Olewniczak $tpl = $this->model->action->get_tpl(); 5808a638198SSzymon Olewniczak 58114a1f0a4SSzymon Olewniczak //we don't want who 58214a1f0a4SSzymon Olewniczak $tpl->set('who', ''); 58314a1f0a4SSzymon Olewniczak $tpl->set('action', 'mail_task_remind'); 584d571026cSSzymon Olewniczak $tpl->set('action_replacements', array($days)); 58514a1f0a4SSzymon Olewniczak $attachedImages = array(); 58614a1f0a4SSzymon Olewniczak $content = $this->mail_task($attachedImages); 58714a1f0a4SSzymon Olewniczak $this->mail_notify($content, $users, $attachedImages); 5888a638198SSzymon Olewniczak } 5898a638198SSzymon Olewniczak 5908a638198SSzymon Olewniczak public function mail_notify_invite($client) { 5918a638198SSzymon Olewniczak $users = array($client); 59214a1f0a4SSzymon Olewniczak $tpl = $this->model->action->get_tpl(); 59314a1f0a4SSzymon Olewniczak 59414a1f0a4SSzymon Olewniczak //we don't want who 59514a1f0a4SSzymon Olewniczak $tpl->set('who', $this->model->user_nick); 59614a1f0a4SSzymon Olewniczak $tpl->set('action', 'mail_task_invite'); 59714a1f0a4SSzymon Olewniczak $attachedImages = array(); 59814a1f0a4SSzymon Olewniczak $content = $this->mail_task($attachedImages); 59914a1f0a4SSzymon Olewniczak $this->mail_notify($content, $users, $attachedImages); 6008a638198SSzymon Olewniczak } 60114a1f0a4SSzymon Olewniczak 60214a1f0a4SSzymon Olewniczak public function mail_notify_change_state($action='') { 60314a1f0a4SSzymon Olewniczak $tpl = $this->model->action->get_tpl(); 60414a1f0a4SSzymon Olewniczak 60514a1f0a4SSzymon Olewniczak $tpl->set('who', $this->model->user_nick); 60614a1f0a4SSzymon Olewniczak $tpl->set('action', $action); 60714a1f0a4SSzymon Olewniczak $attachedImages = array(); 60814a1f0a4SSzymon Olewniczak $content = $this->mail_task($attachedImages); 60914a1f0a4SSzymon Olewniczak $this->mail_notify($content, false, $attachedImages); 61014a1f0a4SSzymon Olewniczak } 61114a1f0a4SSzymon Olewniczak 6128a638198SSzymon Olewniczak} 613