Completed
Push — master ( fc854e...ca3b34 )
by Peter
15:53
created

Task::executed()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5.3073

Importance

Changes 0
Metric Value
dl 0
loc 20
ccs 10
cts 13
cp 0.7692
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 13
nc 6
nop 0
crap 5.3073
1
<?php
2
/**
3
 * AnimeDb package.
4
 *
5
 * @author    Peter Gribanov <[email protected]>
6
 * @copyright Copyright (c) 2011, Peter Gribanov
7
 * @license   http://opensource.org/licenses/GPL-3.0 GPL v3
8
 */
9
namespace AnimeDb\Bundle\AppBundle\Entity;
10
11
use Doctrine\ORM\Mapping as ORM;
12
use Symfony\Component\Validator\Constraints as Assert;
13
use Symfony\Component\Validator\Context\ExecutionContextInterface;
14
15
/**
16
 * Task for Task Scheduler.
17
 *
18
 * @ORM\Entity
19
 * @ORM\Table(name="task", indexes={
20
 *   @ORM\Index(name="idx_task_next_start", columns={"next_run", "status"})
21
 * })
22
 * @Assert\Callback(methods={"isModifyValid"})
23
 * @ORM\Entity(repositoryClass="AnimeDb\Bundle\AppBundle\Repository\Task")
24
 */
25
class Task
26
{
27
    /**
28
     * @var int
29
     */
30
    const STATUS_ENABLED = 1;
31
32
    /**
33
     * @var int
34
     */
35
    const STATUS_DISABLED = 0;
36
37
    /**
38
     * @ORM\Id
39
     * @ORM\GeneratedValue
40
     * @ORM\Column(type="integer")
41
     *
42
     * @var int
43
     */
44
    protected $id;
45
46
    /**
47
     * @ORM\Column(type="string", length=128)
48
     *
49
     * @var string
50
     */
51
    protected $command = '';
52
53
    /**
54
     * @ORM\Column(type="datetime", nullable=true)
55
     * @Assert\DateTime()
56
     *
57
     * @var \DateTime|null
58
     */
59
    protected $last_run;
60
61
    /**
62
     * @ORM\Column(type="datetime")
63
     * @Assert\DateTime()
64
     *
65
     * @var \DateTime
66
     */
67
    protected $next_run;
68
69
    /**
70
     * A date/time string.
71
     *
72
     * Valid formats are explained in Date and Time Formats.
73
     *
74
     * @link http://www.php.net/manual/en/datetime.formats.php
75
     * @ORM\Column(type="string", length=128, nullable=true)
76
     *
77
     * @var string
78
     */
79
    protected $modify = '';
80
81
    /**
82
     * @ORM\Column(type="integer")
83
     * @Assert\Choice(callback = "getStatuses")
84
     *
85
     * @var int
86
     */
87
    protected $status = self::STATUS_DISABLED;
88
89 27
    public function __construct()
90
    {
91 27
        $this->next_run = new \DateTime();
92 27
    }
93
94
    /**
95
     * @param string $command
96
     *
97
     * @return Task
98
     */
99 1
    public function setCommand($command)
100
    {
101 1
        $this->command = $command;
102
103 1
        return $this;
104
    }
105
106
    /**
107
     * @return string
108
     */
109 1
    public function getCommand()
110
    {
111 1
        return $this->command;
112
    }
113
114
    /**
115
     * @return int
116
     */
117 1
    public function getId()
118
    {
119 1
        return $this->id;
120
    }
121
122
    /**
123
     * @param \DateTime $last_run
124
     *
125
     * @return Task
126
     */
127 4
    public function setLastRun(\DateTime $last_run)
128
    {
129 4
        $this->last_run = clone $last_run;
130
131 4
        return $this;
132
    }
133
134
    /**
135
     * @return \DateTime|null
136
     */
137 4
    public function getLastRun()
138
    {
139 4
        return $this->last_run ? clone $this->last_run : null;
140
    }
141
142
    /**
143
     * @param \DateTime $next_run
144
     *
145
     * @return Task
146
     */
147 2
    public function setNextRun(\DateTime $next_run)
148
    {
149 2
        $this->next_run = clone $next_run;
150
151 2
        return $this;
152
    }
153
154
    /**
155
     * @return \DateTime
156
     */
157 2
    public function getNextRun()
158
    {
159 2
        return clone $this->next_run;
160
    }
161
162
    /**
163
     * @param int $interval
164
     *
165
     * @return Task
166
     */
167 3
    public function setInterval($interval)
168
    {
169 3
        if ($interval > 0) {
170 1
            $this->setModify(sprintf('+%s second', (int) $interval));
171
        }
172
173 3
        return $this;
174
    }
175
176
    /**
177
     * @param string $modify
178
     *
179
     * @return Task
180
     */
181 5
    public function setModify($modify)
182
    {
183 5
        $this->modify = $modify;
184
185 5
        return $this;
186
    }
187
188
    /**
189
     * @return string
190
     */
191 9
    public function getModify()
192
    {
193 9
        return $this->modify;
194
    }
195
196
    /**
197
     * @param int $status
198
     *
199
     * @return Task
200
     */
201 4
    public function setStatus($status)
202
    {
203 4
        $this->status = $status;
204
205 4
        return $this;
206
    }
207
208
    /**
209
     * @return int
210
     */
211 4
    public function getStatus()
212
    {
213 4
        return $this->status;
214
    }
215
216
    /**
217
     * @return int[]
218
     */
219 1
    public static function getStatuses()
220
    {
221
        return [
222 1
            self::STATUS_DISABLED,
223 1
            self::STATUS_ENABLED,
224
        ];
225
    }
226
227
    /**
228
     * @param ExecutionContextInterface $context
229
     */
230 2
    public function isModifyValid(ExecutionContextInterface $context)
231
    {
232 2
        if ($this->getModify() && strtotime($this->getModify()) === false) {
233
            $context
234 1
                ->buildViolation('Wrong date/time format')
235 1
                ->atPath('modify')
236 1
                ->addViolation();
237
        }
238 2
    }
239
240
    /**
241
     * Update task after execution.
242
     */
243 3
    public function executed()
244
    {
245 3
        $this->setLastRun(new \DateTime());
246 3
        if (!$this->getModify()) {
247 2
            $this->setStatus(self::STATUS_DISABLED);
248
        }
249 3
        if ($this->getStatus() == self::STATUS_ENABLED) {
250
            // find near time task launch
251 1
            $next_run = $this->getNextRun();
252
            do {
253
                // failed to compute time of next run
254 1
                if ($next_run->modify($this->getModify()) === false) {
255
                    $this->setModify('');
256
                    $this->setStatus(self::STATUS_DISABLED);
257
                    break;
258
                }
259 1
            } while ($next_run->getTimestamp() <= time());
260 1
            $this->setNextRun($next_run);
261
        }
262 3
    }
263
}
264