xref: /plugin/bez/mdl/Task.php (revision a0cd8c785f18b483f73582b411767428d04a78f6)
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
83*a0cd8c78SSzymon Olewniczak		//virutal ACL columns (not in select)
84*a0cd8c78SSzymon Olewniczak		$this->acl->add_column('participants');
85*a0cd8c78SSzymon 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            }
126*a0cd8c78SSzymon Olewniczak
127*a0cd8c78SSzymon Olewniczak            //everyone can report their own program tasks
128*a0cd8c78SSzymon Olewniczak            if ($this->type == 'program') {
129*a0cd8c78SSzymon Olewniczak                $this->acl->grant('content', BEZ_PERMISSION_CHANGE);
130*a0cd8c78SSzymon Olewniczak                $this->acl->grant('plan_date', BEZ_PERMISSION_CHANGE);
131*a0cd8c78SSzymon Olewniczak                $this->acl->grant('start_time', BEZ_PERMISSION_CHANGE);
132*a0cd8c78SSzymon Olewniczak                $this->acl->grant('finish_time', BEZ_PERMISSION_CHANGE);
133*a0cd8c78SSzymon Olewniczak                $this->acl->grant('all_day_event', BEZ_PERMISSION_CHANGE);
134*a0cd8c78SSzymon Olewniczak                $this->acl->grant('task_program_id', BEZ_PERMISSION_CHANGE);
135*a0cd8c78SSzymon Olewniczak                $this->acl->grant('cost', BEZ_PERMISSION_CHANGE);
136*a0cd8c78SSzymon Olewniczak            }
137*a0cd8c78SSzymon Olewniczak
138*a0cd8c78SSzymon Olewniczak            if ($this->type == 'program' && $this->model->get_level() >= BEZ_AUTH_LEADER) {
139*a0cd8c78SSzymon Olewniczak                $this->acl->grant('assignee', BEZ_PERMISSION_CHANGE);
140*a0cd8c78SSzymon Olewniczak                $this->acl->grant('participants', BEZ_PERMISSION_CHANGE);
141*a0cd8c78SSzymon Olewniczak            }
142*a0cd8c78SSzymon Olewniczak
143*a0cd8c78SSzymon Olewniczak            if ($this->type != 'program' && $this->coordinator == $this->model->user_nick) {
144*a0cd8c78SSzymon Olewniczak                $this->acl->grant('content', BEZ_PERMISSION_CHANGE);
145*a0cd8c78SSzymon Olewniczak                $this->acl->grant('plan_date', BEZ_PERMISSION_CHANGE);
146*a0cd8c78SSzymon Olewniczak                $this->acl->grant('start_time', BEZ_PERMISSION_CHANGE);
147*a0cd8c78SSzymon Olewniczak                $this->acl->grant('finish_time', BEZ_PERMISSION_CHANGE);
148*a0cd8c78SSzymon Olewniczak                $this->acl->grant('all_day_event', BEZ_PERMISSION_CHANGE);
149*a0cd8c78SSzymon Olewniczak                $this->acl->grant('task_program_id', BEZ_PERMISSION_CHANGE);
150*a0cd8c78SSzymon Olewniczak                $this->acl->grant('cost', BEZ_PERMISSION_CHANGE);
151*a0cd8c78SSzymon Olewniczak
152*a0cd8c78SSzymon Olewniczak                $this->acl->grant('assignee', BEZ_PERMISSION_CHANGE);
153*a0cd8c78SSzymon Olewniczak                $this->acl->grant('participants', BEZ_PERMISSION_CHANGE);
154*a0cd8c78SSzymon Olewniczak            }
155*a0cd8c78SSzymon 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
166*a0cd8c78SSzymon Olewniczak            //user can close their tasks
167*a0cd8c78SSzymon Olewniczak            if ($this->assignee == $this->model->user_nick || $this->model->get_level() >= BEZ_AUTH_LEADER) {
168*a0cd8c78SSzymon Olewniczak                $this->acl->grant('state', BEZ_PERMISSION_CHANGE);
169*a0cd8c78SSzymon Olewniczak            }
170*a0cd8c78SSzymon Olewniczak
171*a0cd8c78SSzymon Olewniczak            if ($this->type == 'program' && $this->original_poster == $this->model->user_nick) {
172*a0cd8c78SSzymon Olewniczak                $this->acl->grant('content', BEZ_PERMISSION_CHANGE);
173*a0cd8c78SSzymon Olewniczak                $this->acl->grant('plan_date', BEZ_PERMISSION_CHANGE);
174*a0cd8c78SSzymon Olewniczak                $this->acl->grant('start_time', BEZ_PERMISSION_CHANGE);
175*a0cd8c78SSzymon Olewniczak                $this->acl->grant('finish_time', BEZ_PERMISSION_CHANGE);
176*a0cd8c78SSzymon Olewniczak                $this->acl->grant('all_day_event', BEZ_PERMISSION_CHANGE);
177*a0cd8c78SSzymon Olewniczak                $this->acl->grant('task_program_id', BEZ_PERMISSION_CHANGE);
178*a0cd8c78SSzymon Olewniczak                $this->acl->grant('cost', BEZ_PERMISSION_CHANGE);
179*a0cd8c78SSzymon Olewniczak            }
180*a0cd8c78SSzymon Olewniczak
181*a0cd8c78SSzymon Olewniczak            if (($this->type != 'program' && $this->coordinator == $this->model->user_nick) ||
182*a0cd8c78SSzymon Olewniczak                ($this->model->get_level() >= BEZ_AUTH_LEADER)) {
183*a0cd8c78SSzymon Olewniczak                $this->acl->grant('content', BEZ_PERMISSION_CHANGE);
184*a0cd8c78SSzymon Olewniczak                $this->acl->grant('plan_date', BEZ_PERMISSION_CHANGE);
185*a0cd8c78SSzymon Olewniczak                $this->acl->grant('start_time', BEZ_PERMISSION_CHANGE);
186*a0cd8c78SSzymon Olewniczak                $this->acl->grant('finish_time', BEZ_PERMISSION_CHANGE);
187*a0cd8c78SSzymon Olewniczak                $this->acl->grant('all_day_event', BEZ_PERMISSION_CHANGE);
188*a0cd8c78SSzymon Olewniczak                $this->acl->grant('task_program_id', BEZ_PERMISSION_CHANGE);
189*a0cd8c78SSzymon Olewniczak                $this->acl->grant('cost', BEZ_PERMISSION_CHANGE);
190*a0cd8c78SSzymon Olewniczak
191*a0cd8c78SSzymon Olewniczak                $this->acl->grant('assignee', BEZ_PERMISSION_CHANGE);
192*a0cd8c78SSzymon Olewniczak                $this->acl->grant('participants', BEZ_PERMISSION_CHANGE);
193*a0cd8c78SSzymon Olewniczak            }
194e8827d73SSzymon Olewniczak        }
1958a638198SSzymon Olewniczak
1968a638198SSzymon Olewniczak		if ($this->thread_id == '') {
1978a638198SSzymon Olewniczak			$this->validator->set_rules(array(
198e8827d73SSzymon Olewniczak				'task_program_id' => array(array('numeric'), 'NOT NULL'),
1998a638198SSzymon Olewniczak			));
200e8827d73SSzymon Olewniczak		    //this field is unused in program tasks
201e8827d73SSzymon Olewniczak            $this->validator->delete_rule('thread_comment_id');
2028a638198SSzymon Olewniczak        }
2038a638198SSzymon Olewniczak    }
2048a638198SSzymon Olewniczak
2058a638198SSzymon Olewniczak
2068a638198SSzymon Olewniczak	public function set_data($post, $filter=NULL) {
207ff14b107SSzymon Olewniczak        //all day event
208ff14b107SSzymon Olewniczak        if (!isset($post['all_day_event'])) {
209ff14b107SSzymon Olewniczak            $post['all_day_event'] = '0';
210ff14b107SSzymon Olewniczak        }
211ff14b107SSzymon Olewniczak
21253df74e7SSzymon Olewniczak        parent::set_data($post);
21353df74e7SSzymon Olewniczak
21453df74e7SSzymon Olewniczak        $this->content_html = p_render('xhtml',p_get_instructions($this->content), $ignore);
21553df74e7SSzymon Olewniczak
21653df74e7SSzymon Olewniczak        if (!isset($post['assignee'])) {
21753df74e7SSzymon Olewniczak            $this->assignee = $this->model->user_nick;
21853df74e7SSzymon Olewniczak        }
21953df74e7SSzymon Olewniczak
22053df74e7SSzymon Olewniczak        //update dates
22153df74e7SSzymon Olewniczak        $this->last_modification_date = date('c');
22253df74e7SSzymon Olewniczak        $this->last_activity_date = $this->last_modification_date;
22353df74e7SSzymon Olewniczak
2248a638198SSzymon Olewniczak		return true;
2258a638198SSzymon Olewniczak	}
2268a638198SSzymon Olewniczak
227e8827d73SSzymon Olewniczak    public function set_state($state) {
228e8827d73SSzymon Olewniczak	    if ($this->acl_of('state') < BEZ_PERMISSION_CHANGE) {
229e8827d73SSzymon Olewniczak	        throw new PermissionDeniedException();
230e8827d73SSzymon Olewniczak        }
231e8827d73SSzymon Olewniczak
232e8827d73SSzymon Olewniczak        if (!in_array($state, array('opened', 'done'))) {
233e8827d73SSzymon Olewniczak	        throw new ValidationException('task', array('sholud be opened or done'));
234e8827d73SSzymon Olewniczak        }
235e8827d73SSzymon Olewniczak
236e8827d73SSzymon Olewniczak        //nothing to do
237e8827d73SSzymon Olewniczak        if ($state == $this->state) {
238e8827d73SSzymon Olewniczak	        return;
239e8827d73SSzymon Olewniczak        }
240e8827d73SSzymon Olewniczak
241e8827d73SSzymon Olewniczak        if ($state == 'done') {
242e8827d73SSzymon Olewniczak            $this->model->sqlite->query("UPDATE {$this->get_table_name()} SET state=?, closed_by=?, close_date=? WHERE id=?",
243e8827d73SSzymon Olewniczak                $state,
244e8827d73SSzymon Olewniczak                $this->model->user_nick,
245e8827d73SSzymon Olewniczak                date('c'),
246e8827d73SSzymon Olewniczak                $this->id);
247e8827d73SSzymon Olewniczak        //reopen the task
248e8827d73SSzymon Olewniczak        } else {
249e8827d73SSzymon Olewniczak            $this->model->sqlite->query("UPDATE {$this->get_table_name()} SET state=? WHERE id=?", $state, $this->id);
250e8827d73SSzymon Olewniczak        }
251e8827d73SSzymon Olewniczak
252e8827d73SSzymon Olewniczak        $this->state = $state;
253e8827d73SSzymon Olewniczak    }
254e8827d73SSzymon Olewniczak
255e8827d73SSzymon Olewniczak    public function update_last_activity() {
256e8827d73SSzymon Olewniczak        $this->last_activity_date = date('c');
257e8827d73SSzymon Olewniczak        $this->model->sqlite->query('UPDATE task SET last_activity_date=? WHERE id=?',
258e8827d73SSzymon Olewniczak                                    $this->last_activity_date, $this->id);
259e8827d73SSzymon Olewniczak    }
260e8827d73SSzymon Olewniczak
261*a0cd8c78SSzymon Olewniczak    public function can_add_participants() {
262*a0cd8c78SSzymon Olewniczak        return in_array($this->state, array('opened'));
263*a0cd8c78SSzymon Olewniczak    }
264*a0cd8c78SSzymon Olewniczak
265e8827d73SSzymon Olewniczak    public function get_participants($filter='') {
266e8827d73SSzymon Olewniczak        if ($this->id === NULL) {
267e8827d73SSzymon Olewniczak            return array();
268e8827d73SSzymon Olewniczak        }
269e8827d73SSzymon Olewniczak
270e8827d73SSzymon Olewniczak        $sql = 'SELECT * FROM task_participant WHERE';
271e8827d73SSzymon Olewniczak        $possible_flags = array('original_poster', 'assignee', 'commentator', 'subscribent');
272e8827d73SSzymon Olewniczak        if ($filter != '') {
273e8827d73SSzymon Olewniczak            if (!in_array($filter, $possible_flags)) {
274e8827d73SSzymon Olewniczak                throw new \Exception("unknown flag $filter");
275e8827d73SSzymon Olewniczak            }
276e8827d73SSzymon Olewniczak            $sql .= " $filter=1 AND";
277e8827d73SSzymon Olewniczak        }
278e8827d73SSzymon Olewniczak        $sql .= ' task_id=? ORDER BY user_id';
279e8827d73SSzymon Olewniczak
280e8827d73SSzymon Olewniczak        $r = $this->model->sqlite->query($sql, $this->id);
281e8827d73SSzymon Olewniczak        $pars = $this->model->sqlite->res2arr($r);
282e8827d73SSzymon Olewniczak        $participants = array();
283e8827d73SSzymon Olewniczak        foreach ($pars as $par) {
284e8827d73SSzymon Olewniczak            $participants[$par['user_id']] = $par;
285e8827d73SSzymon Olewniczak        }
286e8827d73SSzymon Olewniczak
287e8827d73SSzymon Olewniczak        return $participants;
288e8827d73SSzymon Olewniczak    }
289e8827d73SSzymon Olewniczak
290e8827d73SSzymon Olewniczak    public function get_participant($user_id) {
291e8827d73SSzymon Olewniczak        if ($this->id === NULL) {
292e8827d73SSzymon Olewniczak            return array();
293e8827d73SSzymon Olewniczak        }
294e8827d73SSzymon Olewniczak
295e8827d73SSzymon Olewniczak        $r = $this->model->sqlite->query('SELECT * FROM task_participant WHERE task_id=? AND user_id=?', $this->id, $user_id);
296e8827d73SSzymon Olewniczak        $par = $this->model->sqlite->res2row($r);
297e8827d73SSzymon Olewniczak        if (!is_array($par)) {
298e8827d73SSzymon Olewniczak            return false;
299e8827d73SSzymon Olewniczak        }
300e8827d73SSzymon Olewniczak
301e8827d73SSzymon Olewniczak        return $par;
302e8827d73SSzymon Olewniczak    }
303e8827d73SSzymon Olewniczak
304e8827d73SSzymon Olewniczak    public function is_subscribent($user_id=null) {
305e8827d73SSzymon Olewniczak        if ($user_id == null) {
306e8827d73SSzymon Olewniczak            $user_id = $this->model->user_nick;
307e8827d73SSzymon Olewniczak        }
308e8827d73SSzymon Olewniczak        $par = $this->get_participant($user_id);
309e8827d73SSzymon Olewniczak        if ($par['subscribent'] == 1) {
310e8827d73SSzymon Olewniczak            return true;
311e8827d73SSzymon Olewniczak        }
312e8827d73SSzymon Olewniczak        return false;
313e8827d73SSzymon Olewniczak    }
314e8827d73SSzymon Olewniczak
315e8827d73SSzymon Olewniczak    public function remove_participant_flags($user_id, $flags) {
316e8827d73SSzymon Olewniczak        //thread not saved yet
317e8827d73SSzymon Olewniczak        if ($this->id === NULL) {
318e8827d73SSzymon Olewniczak            throw new \Exception('cannot remove flags from not saved thread');
319e8827d73SSzymon Olewniczak        }
320e8827d73SSzymon Olewniczak
321e8827d73SSzymon Olewniczak        $possible_flags = array('original_poster', 'assignee', 'commentator', 'subscribent');
322e8827d73SSzymon Olewniczak        if (array_intersect($flags, $possible_flags) != $flags) {
323e8827d73SSzymon Olewniczak            throw new \Exception('unknown flags');
324e8827d73SSzymon Olewniczak        }
325e8827d73SSzymon Olewniczak
326e8827d73SSzymon Olewniczak        $set = implode(',', array_map(function ($v) { return "$v=0"; }, $flags));
327e8827d73SSzymon Olewniczak
328e8827d73SSzymon Olewniczak        $sql = "UPDATE task_participant SET $set WHERE task_id=? AND user_id=?";
329e8827d73SSzymon Olewniczak        $this->model->sqlite->query($sql, $this->id, $user_id);
330e8827d73SSzymon Olewniczak
331e8827d73SSzymon Olewniczak    }
332e8827d73SSzymon Olewniczak
333e8827d73SSzymon Olewniczak    public function set_participant_flags($user_id, $flags=array()) {
334e8827d73SSzymon Olewniczak        //thread not saved yet
335e8827d73SSzymon Olewniczak        if ($this->id === NULL) {
336e8827d73SSzymon Olewniczak            throw new \Exception('cannot add flags to not saved thread');
337e8827d73SSzymon Olewniczak        }
338e8827d73SSzymon Olewniczak
339e8827d73SSzymon Olewniczak        //validate user
340e8827d73SSzymon Olewniczak        if (!$this->model->userFactory->exists($user_id)) {
341e8827d73SSzymon Olewniczak            throw new \Exception("$user_id isn't dokuwiki user");
342e8827d73SSzymon Olewniczak        }
343e8827d73SSzymon Olewniczak
344e8827d73SSzymon Olewniczak        $possible_flags = array('original_poster', 'assignee', 'commentator', 'subscribent');
345e8827d73SSzymon Olewniczak        if (array_intersect($flags, $possible_flags) != $flags) {
346e8827d73SSzymon Olewniczak            throw new \Exception('unknown flags');
347e8827d73SSzymon Olewniczak        }
348e8827d73SSzymon Olewniczak
349e8827d73SSzymon Olewniczak        $participant = $this->get_participant($user_id);
350e8827d73SSzymon Olewniczak        if ($participant == false) {
351e8827d73SSzymon Olewniczak            $participant = array_fill_keys($possible_flags, 0);
352e8827d73SSzymon Olewniczak
353e8827d73SSzymon Olewniczak            $participant['task_id'] = $this->id;
354e8827d73SSzymon Olewniczak            $participant['user_id'] = $user_id;
355e8827d73SSzymon Olewniczak            $participant['added_by'] = $this->model->user_nick;
356e8827d73SSzymon Olewniczak            $participant['added_date'] = date('c');
357e8827d73SSzymon Olewniczak        }
358e8827d73SSzymon Olewniczak        $values = array_merge($participant, array_fill_keys($flags, 1));
359e8827d73SSzymon Olewniczak
360e8827d73SSzymon Olewniczak        $keys = join(',', array_keys($values));
361e8827d73SSzymon Olewniczak        $vals = join(',', array_fill(0,count($values),'?'));
362e8827d73SSzymon Olewniczak
363e8827d73SSzymon Olewniczak        $sql = "REPLACE INTO task_participant ($keys) VALUES ($vals)";
364e8827d73SSzymon Olewniczak        $this->model->sqlite->query($sql, array_values($values));
365e8827d73SSzymon Olewniczak    }
366e8827d73SSzymon Olewniczak
367e8827d73SSzymon Olewniczak    public function invite($client) {
368e8827d73SSzymon Olewniczak        $this->set_participant_flags($client, array('subscribent'));
369e8827d73SSzymon Olewniczak        $this->mail_notify_invite($client);
370e8827d73SSzymon Olewniczak    }
371e8827d73SSzymon Olewniczak
372*a0cd8c78SSzymon Olewniczak    private function mail_notify($replacements=array(), $users=false, $attachedImages=array()) {
3738a638198SSzymon Olewniczak        $plain = io_readFile($this->model->action->localFN('task-notification'));
3748a638198SSzymon Olewniczak        $html = io_readFile($this->model->action->localFN('task-notification', 'html'));
3758a638198SSzymon Olewniczak
376e8827d73SSzymon Olewniczak        $task_link = $this->model->action->url('task', 'tid', $this->id);
3778a638198SSzymon Olewniczak
3788a638198SSzymon Olewniczak        $reps = array(
3798a638198SSzymon Olewniczak                        'task_id' => $this->id,
3808a638198SSzymon Olewniczak                        'task_link' => $task_link,
381e8827d73SSzymon Olewniczak                        'who' => $this->original_poster
3828a638198SSzymon Olewniczak                     );
3838a638198SSzymon Olewniczak
3848a638198SSzymon Olewniczak        //$replacements can override $reps
3858a638198SSzymon Olewniczak        $rep = array_merge($reps, $replacements);
3868a638198SSzymon Olewniczak
3878a638198SSzymon Olewniczak        if (!isset($rep['who_full_name'])) {
3888a638198SSzymon Olewniczak            $rep['who_full_name'] =
389e8827d73SSzymon Olewniczak                $this->model->userFactory->get_user_full_name($rep['who']);
3908a638198SSzymon Olewniczak        }
3918a638198SSzymon Olewniczak
3928a638198SSzymon Olewniczak        //auto title
3938a638198SSzymon Olewniczak        if (!isset($rep['subject'])) {
3948a638198SSzymon Olewniczak//            if (isset($rep['content'])) {
3958a638198SSzymon Olewniczak//                $rep['subject'] =  array_shift(explode('.', $rep['content'], 2));
3968a638198SSzymon Olewniczak//            }
397e8827d73SSzymon Olewniczak            $rep['subject'] = '#z'.$this->id. ' ' . $this->task_program_name;
3988a638198SSzymon Olewniczak        }
3998a638198SSzymon Olewniczak
4008a638198SSzymon Olewniczak        //we must do it manually becouse Mailer uses htmlspecialchars()
4018a638198SSzymon Olewniczak        $html = str_replace('@TASK_TABLE@', $rep['task_table'], $html);
4028a638198SSzymon Olewniczak
403e8827d73SSzymon Olewniczak        $mailer = new Mailer();
4048a638198SSzymon Olewniczak        $mailer->setBody($plain, $rep, $rep, $html, false);
4058a638198SSzymon Olewniczak
4068a638198SSzymon Olewniczak        if ($users === FALSE) {
407e8827d73SSzymon Olewniczak            $users = $this->get_participants('subscribent');
4088a638198SSzymon Olewniczak
4098a638198SSzymon Olewniczak            //don't notify current user
4108a638198SSzymon Olewniczak            unset($users[$this->model->user_nick]);
4118a638198SSzymon Olewniczak        }
4128a638198SSzymon Olewniczak
4138a638198SSzymon Olewniczak        $emails = array_map(function($user) {
41420e189b9SSzymon Olewniczak            if (is_array($user)) {
41520e189b9SSzymon Olewniczak                $user = $user['user_id'];
41620e189b9SSzymon Olewniczak            }
41720e189b9SSzymon Olewniczak            return $this->model->userFactory->get_user_email($user);
4188a638198SSzymon Olewniczak        }, $users);
4198a638198SSzymon Olewniczak
4208a638198SSzymon Olewniczak        $mailer->to($emails);
4218a638198SSzymon Olewniczak        $mailer->subject($rep['subject']);
4228a638198SSzymon Olewniczak
423*a0cd8c78SSzymon Olewniczak        //add images
424*a0cd8c78SSzymon Olewniczak        foreach ($attachedImages as $img) {
425*a0cd8c78SSzymon Olewniczak            $mailer->attachFile($img['path'], $img['mime'], $img['name'], $img['embed']);
426*a0cd8c78SSzymon Olewniczak        }
427*a0cd8c78SSzymon Olewniczak
4288a638198SSzymon Olewniczak        $send = $mailer->send();
4298a638198SSzymon Olewniczak        if ($send === false) {
4308a638198SSzymon Olewniczak            //this may mean empty $emails
4318a638198SSzymon Olewniczak            //throw new Exception("can't send email");
4328a638198SSzymon Olewniczak        }
4338a638198SSzymon Olewniczak    }
4348a638198SSzymon Olewniczak
435e8827d73SSzymon Olewniczak    protected function bez_html_array_to_style_list($arr) {
436e8827d73SSzymon Olewniczak        $output = '';
437e8827d73SSzymon Olewniczak        foreach ($arr as $k => $v) {
438e8827d73SSzymon Olewniczak            $output .= $k.': '. $v . ';';
4398a638198SSzymon Olewniczak        }
440e8827d73SSzymon Olewniczak        return $output;
441e8827d73SSzymon Olewniczak    }
442e8827d73SSzymon Olewniczak
443e8827d73SSzymon Olewniczak    protected function bez_html_irrtable($style) {
444e8827d73SSzymon Olewniczak        $argv = func_get_args();
445e8827d73SSzymon Olewniczak        $argc = func_num_args();
446e8827d73SSzymon Olewniczak        if (isset($style['table'])) {
447e8827d73SSzymon Olewniczak            $output = '<table style="'.self::bez_html_array_to_style_list($style['table']).'">';
448e8827d73SSzymon Olewniczak        } else {
449e8827d73SSzymon Olewniczak            $output = '<table>';
450e8827d73SSzymon Olewniczak        }
451e8827d73SSzymon Olewniczak
452e8827d73SSzymon Olewniczak        $tr_style  = '';
453e8827d73SSzymon Olewniczak        if (isset($style['tr'])) {
454e8827d73SSzymon Olewniczak            $tr_style = 'style="'.self::bez_html_array_to_style_list($style['tr']).'"';
455e8827d73SSzymon Olewniczak        }
456e8827d73SSzymon Olewniczak
457e8827d73SSzymon Olewniczak        $td_style  = '';
458e8827d73SSzymon Olewniczak        if (isset($style['td'])) {
459e8827d73SSzymon Olewniczak            $td_style = 'style="'.self::bez_html_array_to_style_list($style['td']).'"';
460e8827d73SSzymon Olewniczak        }
461e8827d73SSzymon Olewniczak
462e8827d73SSzymon Olewniczak        $row_max = 0;
463e8827d73SSzymon Olewniczak
464e8827d73SSzymon Olewniczak        for ($i = 1; $i < $argc; $i++) {
465e8827d73SSzymon Olewniczak            $row = $argv[$i];
466e8827d73SSzymon Olewniczak            $c = count($row);
467e8827d73SSzymon Olewniczak            if ($c > $row_max) {
468e8827d73SSzymon Olewniczak                $row_max = $c;
469e8827d73SSzymon Olewniczak            }
470e8827d73SSzymon Olewniczak        }
471e8827d73SSzymon Olewniczak
472e8827d73SSzymon Olewniczak        for ($j = 1; $j < $argc; $j++) {
473e8827d73SSzymon Olewniczak            $row = $argv[$j];
474e8827d73SSzymon Olewniczak            $output .= '<tr '.$tr_style.'>' . NL;
475e8827d73SSzymon Olewniczak            $c = count($row);
476e8827d73SSzymon Olewniczak            for ($i = 0; $i < $c; $i++) {
477e8827d73SSzymon Olewniczak                //last element
478e8827d73SSzymon Olewniczak                if ($i === $c - 1 && $c < $row_max) {
479e8827d73SSzymon Olewniczak                    $output .= '<td '.$td_style.' colspan="' . ( $row_max - $c + 1 ) . '">' . NL;
480e8827d73SSzymon Olewniczak                } else {
481e8827d73SSzymon Olewniczak                    $output .= '<td '.$td_style.'>' . NL;
482e8827d73SSzymon Olewniczak                }
483e8827d73SSzymon Olewniczak                $output .= $row[$i] . NL;
484e8827d73SSzymon Olewniczak                $output .= '</td>' . NL;
485e8827d73SSzymon Olewniczak            }
486e8827d73SSzymon Olewniczak            $output .= '</tr>' . NL;
487e8827d73SSzymon Olewniczak        }
488e8827d73SSzymon Olewniczak        $output .= '</table>' . NL;
489e8827d73SSzymon Olewniczak        return $output;
490e8827d73SSzymon Olewniczak    }
491e8827d73SSzymon Olewniczak
492e8827d73SSzymon Olewniczak    public function mail_notify_task_box($users=false, $replacements=array()) {
4938a638198SSzymon Olewniczak       $top_row = array(
4948a638198SSzymon Olewniczak            '<strong>'.$this->model->action->getLang('executor').': </strong>' .
495e8827d73SSzymon Olewniczak            $this->model->userFactory->get_user_full_name($this->assignee),
4968a638198SSzymon Olewniczak
4978a638198SSzymon Olewniczak            '<strong>'.$this->model->action->getLang('reporter').': </strong>' .
498e8827d73SSzymon Olewniczak            $this->model->userFactory->get_user_full_name($this->original_poster)
4998a638198SSzymon Olewniczak        );
5008a638198SSzymon Olewniczak
501e8827d73SSzymon Olewniczak        if ($this->task_program_name != '') {
5028a638198SSzymon Olewniczak            $top_row[] =
5038a638198SSzymon Olewniczak                '<strong>'.$this->model->action->getLang('task_type').': </strong>' .
504e8827d73SSzymon Olewniczak                $this->task_program_name;
5058a638198SSzymon Olewniczak        }
5068a638198SSzymon Olewniczak
5078a638198SSzymon Olewniczak        if ($this->cost != '') {
5088a638198SSzymon Olewniczak            $top_row[] =
5098a638198SSzymon Olewniczak                '<strong>'.$this->model->action->getLang('cost').': </strong>' .
5108a638198SSzymon Olewniczak                $this->cost;
5118a638198SSzymon Olewniczak        }
5128a638198SSzymon Olewniczak
5138a638198SSzymon Olewniczak        //BOTTOM ROW
5148a638198SSzymon Olewniczak        $bottom_row = array(
5158a638198SSzymon Olewniczak            '<strong>'.$this->model->action->getLang('plan_date').': </strong>' .
5168a638198SSzymon Olewniczak            $this->plan_date
5178a638198SSzymon Olewniczak        );
5188a638198SSzymon Olewniczak
5198a638198SSzymon Olewniczak        if ($this->all_day_event == '0') {
5208a638198SSzymon Olewniczak            $bottom_row[] =
5218a638198SSzymon Olewniczak                '<strong>'.$this->model->action->getLang('start_time').': </strong>' .
5228a638198SSzymon Olewniczak                $this->start_time;
5238a638198SSzymon Olewniczak            $bottom_row[] =
5248a638198SSzymon Olewniczak                '<strong>'.$this->model->action->getLang('finish_time').': </strong>' .
5258a638198SSzymon Olewniczak                $this->finish_time;
5268a638198SSzymon Olewniczak        }
5278a638198SSzymon Olewniczak
528*a0cd8c78SSzymon Olewniczak        $info = array();
529*a0cd8c78SSzymon Olewniczak        $content_html = p_render('bez_xhtmlmail', p_get_instructions($this->content), $info);
530*a0cd8c78SSzymon Olewniczak        $attachedImages = $info['img'];
531*a0cd8c78SSzymon Olewniczak
5328a638198SSzymon Olewniczak        $rep = array(
533e8827d73SSzymon Olewniczak            'content' => $this->content,
5348a638198SSzymon Olewniczak            'content_html' =>
5358a638198SSzymon Olewniczak                '<h2 style="font-size: 1.2em;">'.
536e8827d73SSzymon Olewniczak	               '<a href="'.$this->model->action->url('task', 'tid', $this->id).'">' .
5378a638198SSzymon Olewniczak		              '#z'.$this->id .
5388a638198SSzymon Olewniczak	               '</a> ' .
539e8827d73SSzymon Olewniczak	lcfirst($this->model->action->getLang('task_type_' . $this->type)) . ' ' .
5408a638198SSzymon Olewniczak    '(' .
541e8827d73SSzymon Olewniczak        lcfirst($this->model->action->getLang('task_' . $this->state)) .
5428a638198SSzymon Olewniczak    ')' .
5438a638198SSzymon Olewniczak                '</h2>' .
544e8827d73SSzymon Olewniczak                self::bez_html_irrtable(array(
5458a638198SSzymon Olewniczak                    'table' => array(
5468a638198SSzymon Olewniczak                        'border-collapse' => 'collapse',
5478a638198SSzymon Olewniczak                        'font-size' => '0.8em',
5488a638198SSzymon Olewniczak                        'width' => '100%'
5498a638198SSzymon Olewniczak                    ),
5508a638198SSzymon Olewniczak                    'td' => array(
5518a638198SSzymon Olewniczak                        'border-top' => '1px solid #8bbcbc',
5528a638198SSzymon Olewniczak                        'border-bottom' => '1px solid #8bbcbc',
5538a638198SSzymon Olewniczak                        'padding' => '.3em .5em'
5548a638198SSzymon Olewniczak                    )
555*a0cd8c78SSzymon Olewniczak                ), $top_row, $bottom_row) . $content_html,
5568a638198SSzymon Olewniczak            'who' => $this->model->user_nick,
557e8827d73SSzymon Olewniczak            'when' => $this->create_date,
5588a638198SSzymon Olewniczak            'custom_content' => true
5598a638198SSzymon Olewniczak        );
5608a638198SSzymon Olewniczak
5618a638198SSzymon Olewniczak        $rep['action_color'] = '#e4f4f4';
5628a638198SSzymon Olewniczak        $rep['action_border_color'] = '#8bbcbc';
5638a638198SSzymon Olewniczak
5648a638198SSzymon Olewniczak        //$replacements can override $reps
5658a638198SSzymon Olewniczak        $rep = array_merge($rep, $replacements);
5668a638198SSzymon Olewniczak
567*a0cd8c78SSzymon Olewniczak        $this->mail_notify($rep, $users, $attachedImages);
5688a638198SSzymon Olewniczak    }
5698a638198SSzymon Olewniczak
570e8827d73SSzymon Olewniczak    public function mail_notify_subscribents($replacements=array()) {
571e8827d73SSzymon Olewniczak        $this->mail_notify_task_box(false, $replacements);
5728a638198SSzymon Olewniczak    }
5738a638198SSzymon Olewniczak
574e8827d73SSzymon Olewniczak    public function mail_notify_add($users=false, $replacements=array()) {
5758a638198SSzymon Olewniczak        $replacements['action'] = $this->model->action->getLang('mail_task_added');
576e8827d73SSzymon Olewniczak        $this->mail_notify_task_box($users, $replacements);
5778a638198SSzymon Olewniczak    }
5788a638198SSzymon Olewniczak
5798a638198SSzymon Olewniczak    public function mail_notify_remind($users=false) {
5808a638198SSzymon Olewniczak        $replacements = array();
5818a638198SSzymon Olewniczak
5828a638198SSzymon Olewniczak        $replacements['action'] = $this->model->action->getLang('mail_task_remind');
5838a638198SSzymon Olewniczak        //we don't want any who
5848a638198SSzymon Olewniczak        $replacements['who_full_name'] = '';
5858a638198SSzymon Olewniczak
5868a638198SSzymon Olewniczak        //$users = array($this->executor);
587e8827d73SSzymon Olewniczak        $this->mail_notify_task_box($users, $replacements);
5888a638198SSzymon Olewniczak    }
5898a638198SSzymon Olewniczak
5908a638198SSzymon Olewniczak    public function mail_notify_invite($client) {
5918a638198SSzymon Olewniczak        $replacements = array();
5928a638198SSzymon Olewniczak
5938a638198SSzymon Olewniczak        $replacements['action'] = $this->model->action->getLang('mail_task_invite');
5948a638198SSzymon Olewniczak
5958a638198SSzymon Olewniczak        $users = array($client);
596e8827d73SSzymon Olewniczak        $this->mail_notify_task_box($users, $replacements);
5978a638198SSzymon Olewniczak    }
5988a638198SSzymon Olewniczak}
599