summaryrefslogtreecommitdiff
path: root/app/Model/TaskRecurrenceModel.php
blob: ffe43f8c283e50f96b9826ea4014d03957941711 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<?php

namespace Kanboard\Model;

use DateInterval;
use DateTime;

/**
 * Task Recurrence
 *
 * @package  Kanboard\Model
 * @author   Frederic Guillot
 */
class TaskRecurrenceModel extends TaskDuplicationModel
{
    /**
     * Return the list user selectable recurrence status
     *
     * @access public
     * @return array
     */
    public function getRecurrenceStatusList()
    {
        return array(
            TaskModel::RECURRING_STATUS_NONE    => t('No'),
            TaskModel::RECURRING_STATUS_PENDING => t('Yes'),
        );
    }

    /**
     * Return the list recurrence triggers
     *
     * @access public
     * @return array
     */
    public function getRecurrenceTriggerList()
    {
        return array(
            TaskModel::RECURRING_TRIGGER_FIRST_COLUMN => t('When task is moved from first column'),
            TaskModel::RECURRING_TRIGGER_LAST_COLUMN  => t('When task is moved to last column'),
            TaskModel::RECURRING_TRIGGER_CLOSE        => t('When task is closed'),
        );
    }

    /**
     * Return the list options to calculate recurrence due date
     *
     * @access public
     * @return array
     */
    public function getRecurrenceBasedateList()
    {
        return array(
            TaskModel::RECURRING_BASEDATE_DUEDATE     => t('Existing due date'),
            TaskModel::RECURRING_BASEDATE_TRIGGERDATE => t('Action date'),
        );
    }

    /**
     * Return the list recurrence timeframes
     *
     * @access public
     * @return array
     */
    public function getRecurrenceTimeframeList()
    {
        return array(
            TaskModel::RECURRING_TIMEFRAME_DAYS   => t('Day(s)'),
            TaskModel::RECURRING_TIMEFRAME_MONTHS => t('Month(s)'),
            TaskModel::RECURRING_TIMEFRAME_YEARS  => t('Year(s)'),
        );
    }

    /**
     * Duplicate recurring task
     *
     * @access public
     * @param  integer             $task_id      Task id
     * @return boolean|integer                   Recurrence task id
     */
    public function duplicateRecurringTask($task_id)
    {
        $values = $this->copyFields($task_id);

        if ($values['recurrence_status'] == TaskModel::RECURRING_STATUS_PENDING) {
            $values['recurrence_parent'] = $task_id;
            $values['column_id'] = $this->columnModel->getFirstColumnId($values['project_id']);
            $this->calculateRecurringTaskDueDate($values);

            $recurring_task_id = $this->save($task_id, $values);

            if ($recurring_task_id !== false) {
                $this->tagDuplicationModel->duplicateTaskTags($task_id, $recurring_task_id);

                $parent_update = $this->db
                    ->table(TaskModel::TABLE)
                    ->eq('id', $task_id)
                    ->update(array(
                        'recurrence_status' => TaskModel::RECURRING_STATUS_PROCESSED,
                        'recurrence_child' => $recurring_task_id,
                    ));

                if ($parent_update) {
                    return $recurring_task_id;
                }
            }
        }

        return false;
    }

    /**
     * Calculate new due date for new recurrence task
     *
     * @access public
     * @param  array   $values   Task fields
     */
    public function calculateRecurringTaskDueDate(array &$values)
    {
        if (! empty($values['date_due']) && $values['recurrence_factor'] != 0) {
            if ($values['recurrence_basedate'] == TaskModel::RECURRING_BASEDATE_TRIGGERDATE) {
                $values['date_due'] = time();
            }

            $factor = abs($values['recurrence_factor']);
            $subtract = $values['recurrence_factor'] < 0;

            switch ($values['recurrence_timeframe']) {
                case TaskModel::RECURRING_TIMEFRAME_MONTHS:
                    $interval = 'P' . $factor . 'M';
                    break;
                case TaskModel::RECURRING_TIMEFRAME_YEARS:
                    $interval = 'P' . $factor . 'Y';
                    break;
                default:
                    $interval = 'P' . $factor . 'D';
            }

            $date_due = new DateTime();
            $date_due->setTimestamp($values['date_due']);

            $subtract ? $date_due->sub(new DateInterval($interval)) : $date_due->add(new DateInterval($interval));

            $values['date_due'] = $date_due->getTimestamp();
        }
    }
}