1<?php
2/**
3 * Matomo - free/libre analytics platform
4 *
5 * @link https://matomo.org
6 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
7 */
8
9namespace Piwik\Scheduler;
10
11use Exception;
12use Piwik\Scheduler\Schedule\Schedule;
13
14/**
15 * Describes a task that should be executed on a given time.
16 *
17 * See the {@link TaskScheduler} docs to learn more about scheduled tasks.
18 *
19 * @api
20 */
21class Task
22{
23    const LOWEST_PRIORITY = 12;
24    const LOW_PRIORITY = 9;
25    const NORMAL_PRIORITY = 6;
26    const HIGH_PRIORITY = 3;
27    const HIGHEST_PRIORITY = 0;
28
29    /**
30     * Object instance on which the method will be executed by the task scheduler
31     * @var string
32     */
33    private $objectInstance;
34
35    /**
36     * Class name where the specified method is located
37     * @var string
38     */
39    private $className;
40
41    /**
42     * Class method to run when task is scheduled
43     * @var string
44     */
45    private $methodName;
46
47    /**
48     * Parameter to pass to the executed method
49     * @var string
50     */
51    private $methodParameter;
52
53    /**
54     * The scheduled time policy
55     * @var Schedule
56     */
57    private $scheduledTime;
58
59    /**
60     * The priority of a task. Affects the order in which this task will be run.
61     * @var int
62     */
63    private $priority;
64
65    /**
66     * @param mixed $objectInstance The object or class that contains the method to execute regularly.
67     *                              Usually this will be a {@link Plugin} instance.
68     * @param string $methodName The name of the method that will be regularly executed.
69     * @param mixed|null $methodParameter An optional parameter to pass to the method when executed.
70     *                                    Must be convertible to string.
71     * @param Schedule|null $scheduledTime A {@link Schedule} instance that describes when the method
72     *                                          should be executed and how long before the next execution.
73     * @param int $priority The priority of the task. Tasks with a higher priority will be executed first.
74     *                      Tasks with low priority will be executed last.
75     * @throws Exception
76     */
77    public function __construct($objectInstance, $methodName, $methodParameter, $scheduledTime,
78                                $priority = self::NORMAL_PRIORITY)
79    {
80        $this->className = $this->getClassNameFromInstance($objectInstance);
81
82        if ($priority < self::HIGHEST_PRIORITY || $priority > self::LOWEST_PRIORITY) {
83            throw new Exception("Invalid priority for ScheduledTask '$this->className.$methodName': $priority");
84        }
85
86        $this->objectInstance = $objectInstance;
87        $this->methodName = $methodName;
88        $this->scheduledTime = $scheduledTime;
89        $this->methodParameter = $methodParameter;
90        $this->priority = $priority;
91    }
92
93    protected function getClassNameFromInstance($_objectInstance)
94    {
95        if (is_string($_objectInstance)) {
96            return $_objectInstance;
97        }
98
99        $namespaced = get_class($_objectInstance);
100
101        return $namespaced;
102    }
103
104    /**
105     * Returns the object instance that contains the method to execute. Returns a class
106     * name if the method is static.
107     *
108     * @return mixed
109     */
110    public function getObjectInstance()
111    {
112        return $this->objectInstance;
113    }
114
115    /**
116     * Returns the name of the class that contains the method to execute.
117     *
118     * @return string
119     */
120    public function getClassName()
121    {
122        return $this->className;
123    }
124
125    /**
126     * Returns the name of the method that will be executed.
127     *
128     * @return string
129     */
130    public function getMethodName()
131    {
132        return $this->methodName;
133    }
134
135    /**
136     * Returns the value that will be passed to the method when executed, or `null` if
137     * no value will be supplied.
138     *
139     * @return string|null
140     */
141    public function getMethodParameter()
142    {
143        return $this->methodParameter;
144    }
145
146    /**
147     * Returns a {@link Schedule} instance that describes when the method should be executed
148     * and how long before the next execution.
149     *
150     * @return \Piwik\Scheduler\Schedule\Schedule
151     */
152    public function getScheduledTime()
153    {
154        return $this->scheduledTime;
155    }
156
157    /**
158     * Returns the time in milliseconds when this task will be executed next.
159     *
160     * @return int
161     */
162    public function getRescheduledTime()
163    {
164        return $this->getScheduledTime()->getRescheduledTime();
165    }
166
167    /**
168     * Returns the task priority. The priority will be an integer whose value is
169     * between {@link HIGH_PRIORITY} and {@link LOW_PRIORITY}.
170     *
171     * @return int
172     */
173    public function getPriority()
174    {
175        return $this->priority;
176    }
177
178    /**
179     * Returns a unique name for this scheduled task. The name is stored in the DB and is used
180     * to store a task's previous execution time. The name is created using:
181     *
182     * - the name of the class that contains the method to execute,
183     * - the name of the method to regularly execute,
184     * - and the value that is passed to the executed task.
185     *
186     * @return string
187     */
188    public function getName()
189    {
190        return self::getTaskName($this->getClassName(), $this->getMethodName(), $this->getMethodParameter());
191    }
192
193    /**
194     * @ignore
195     */
196    public static function getTaskName($className, $methodName, $methodParameter = null)
197    {
198        return $className . '.' . $methodName . ($methodParameter == null ? '' : '_' . $methodParameter);
199    }
200}
201