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