PluginProbe
UpStream: a Project Management Plugin for WordPress / 1.39.1
UpStream: a Project Management Plugin for WordPress v1.39.1
trunk 1.39.0 1.39.1 1.39.2 1.39.3 2.0.7 2.1.0
upstream / includes / model / UpStream_Model_Task.php

UpStream_Model_Task.php in UpStream: a Project Management Plugin for WordPress 1.39.1, at includes/model/UpStream_Model_Task.php

334 lines 10.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3
4 // Exit if accessed directly
5 if ( ! defined('ABSPATH')) {
6 exit;
7 }
8
9 class UpStream_Model_Task extends UpStream_Model_Meta_Object
10 {
11 protected $statusCode = null;
12
13 protected $progress = 0;
14
15 protected $milestoneId = 0;
16
17 protected $startDate = null;
18
19 protected $endDate = null;
20
21 protected $notes = '';
22
23 protected $reminders = [];
24
25 protected $timeRecords = [];
26
27 protected $metadataKey = '_upstream_project_tasks';
28
29 protected $type = UPSTREAM_ITEM_TYPE_TASK;
30
31 /**
32 * UpStream_Model_Task constructor.
33 */
34 public function __construct($parent, $item_metadata)
35 {
36 parent::__construct($parent, $item_metadata);
37 }
38
39 protected function loadFromArray($item_metadata)
40 {
41 parent::loadFromArray($item_metadata);
42
43 $this->statusCode = !empty($item_metadata['status']) ? $item_metadata['status'] : null;
44 $this->progress = !empty($item_metadata['progress']) ? $item_metadata['progress'] : 0;
45 $this->startDate = UpStream_Model_Object::loadDate($item_metadata, 'start_date');
46 $this->endDate = UpStream_Model_Object::loadDate($item_metadata, 'end_date');
47 $this->milestoneId = !empty($item_metadata['milestone']) ? $item_metadata['milestone'] : null;
48 $this->notes = !empty($item_metadata['notes']) ? $item_metadata['notes'] : '';
49
50 if (!empty($item_metadata['reminders'])) {
51 foreach ($item_metadata['reminders'] as $reminder_data) {
52
53 try {
54 $d = json_decode($reminder_data, true);
55 $reminder = new UpStream_Model_Reminder($d);
56 $this->reminders[] = $reminder;
57 } catch (\Exception $e) {
58 // don't add anything else
59 }
60
61 }
62 }
63
64 if (!empty($item_metadata['records'])) {
65 foreach ($item_metadata['records'] as $tr_data) {
66
67 try {
68 $d = json_decode($tr_data, true);
69 $timeRecord = new UpStream_Model_TimeRecord($d);
70 $this->timeRecords[] = $timeRecord;
71 } catch (\Exception $e) {
72 // don't add anything else
73 }
74
75 }
76 }
77
78 }
79
80 public function storeToArray(&$item_metadata)
81 {
82 parent::storeToArray($item_metadata);
83
84 if ($this->statusCode != null) $item_metadata['status'] = $this->statusCode;
85 if ($this->progress >= 0) $item_metadata['progress'] = $this->progress;
86 if ($this->startDate != null) $item_metadata['start_date'] = UpStream_Model_Object::ymdToTimestamp($this->startDate);
87 if ($this->endDate != null) $item_metadata['end_date'] = UpStream_Model_Object::ymdToTimestamp($this->endDate);
88 if ($this->startDate != null) $item_metadata['start_date.YMD'] = $this->startDate;
89 if ($this->endDate != null) $item_metadata['end_date.YMD'] = $this->endDate;
90 if ($this->notes != null) $item_metadata['notes'] = $this->notes;
91 if ($this->milestoneId > 0) $item_metadata['milestone'] = $this->milestoneId;
92
93 $item_metadata['reminders'] = [];
94
95 foreach ($this->reminders as $reminder) {
96 $r = [];
97 $reminder->storeToArray($r);
98 $item_metadata['reminders'][] = json_encode($r);
99 }
100
101 $item_metadata['time_records'] = [];
102
103 foreach ($this->timeRecords as $tr) {
104 $r = [];
105 $tr->storeToArray($r);
106 $item_metadata['records'][] = json_encode($r);
107 }
108 }
109
110 public function calculateElapsedTime()
111 {
112 $total = 0;
113
114 foreach ($this->timeRecords as $tr) {
115 $total += $tr->elapsedTime;
116 }
117
118 return $total;
119 }
120
121 public function calculateBudgeted()
122 {
123 $total = 0;
124
125 foreach ($this->timeRecords as $tr) {
126 $total += $tr->budgeted;
127 }
128
129 return $total;
130 }
131
132 public function calculateSpent()
133 {
134 $total = 0;
135
136 foreach ($this->timeRecords as $tr) {
137 $total += $tr->spent;
138 }
139
140 return $total;
141 }
142
143 public function getMilestone()
144 {
145 if ($this->milestoneId) {
146 try {
147 return \UpStream_Model_Manager::get_instance()->getByID(UPSTREAM_ITEM_TYPE_MILESTONE,
148 $this->milestoneId, UPSTREAM_ITEM_TYPE_PROJECT, $this->parent->id);
149 } catch (\Exception $e) {
150
151 }
152 }
153
154 return null;
155 }
156
157 public function setMilestone($milestone)
158 {
159 $this->milestoneId = $milestone->id;
160 }
161
162 public function __get($property)
163 {
164 switch ($property) {
165
166 case 'milestone':
167 return $this->getMilestone();
168
169 case 'status':
170 $s = $this->getStatuses();
171
172 foreach ($s as $sKey => $sValue) {
173 if ($this->statusCode === $sKey)
174 return $sValue;
175 }
176 return '';
177
178 case 'elapsedTime':
179 return $this->calculateElapsedTime();
180 case 'budgeted':
181 return $this->calculateBudgeted();
182 case 'spent':
183 return $this->calculateSpent();
184
185 case 'statusCode':
186 case 'notes':
187 case 'milestoneId':
188 case 'progress':
189 case 'timeRecords':
190 case 'startDate':
191 case 'endDate':
192 return $this->{$property};
193
194 default:
195 return parent::__get($property);
196 }
197 }
198
199 public function __set($property, $value)
200 {
201 switch ($property) {
202
203 case 'milestone':
204 if (!$value instanceof UpStream_Model_Milestone)
205 throw new UpStream_Model_ArgumentException(__('Argument must be of type milestone.', 'upstream'));
206 elseif ($value->id == 0)
207 throw new UpStream_Model_ArgumentException(__('Milestone must be stored before setting.', 'upstream'));
208
209 return $this->setMilestone($value);
210
211 case 'status':
212 $s = $this->getStatuses();
213 $sc = null;
214
215 foreach ($s as $sKey => $sValue) {
216 if ($value === $sValue) {
217 $sc = $sKey;
218 break;
219 }
220 }
221
222 if ($sc == null)
223 throw new UpStream_Model_ArgumentException(sprintf(__('Status %s is invalid.', 'upstream'), $value));
224
225 $this->statusCode = $sc;
226
227 break;
228
229 case 'statusCode':
230 $s = $this->getStatuses();
231 $sc = null;
232
233 foreach ($s as $sKey => $sValue) {
234 if ($value === $sKey) {
235 $sc = $sKey;
236 break;
237 }
238 }
239
240 if ($sc == null)
241 throw new UpStream_Model_ArgumentException(sprintf(__('Status code %s is invalid.', 'upstream'), $value));
242
243 $this->statusCode = $sc;
244
245 break;
246
247 case 'notes':
248 $this->notes = wp_kses_post($value);
249 break;
250
251 case 'milestoneId':
252 $milestone = UpStream_Model_Manager::get_instance()->getByID(UPSTREAM_ITEM_TYPE_MILESTONE, $value, UPSTREAM_ITEM_TYPE_PROJECT, $this->parent->id);
253 $this->milestoneId = $milestone->id;
254 break;
255
256 case 'progress':
257 if (!filter_var($value, FILTER_VALIDATE_INT) || (int)$value < 0 || (int)$value > 100 || ((int)$value) % 5 != 0)
258 throw new UpStream_Model_ArgumentException(__('Argument must be a multiple of 5 between 0 and 100.', 'upstream'));
259
260 $this->{$property} = $value;
261 break;
262
263 case 'startDate':
264 case 'endDate':
265 if (!self::isValidDate($value))
266 throw new UpStream_Model_ArgumentException(__('Argument is not a valid date of the form YYYY-MM-DD.', 'upstream'));
267
268 $this->{$property} = $value;
269 break;
270
271 case 'timeRecords':
272 if (!is_array($value))
273 throw new UpStream_Model_ArgumentException(__('Argument must be an array of UpStream_Model_TimeRecord objects.', 'upstream'));
274
275 foreach ($value as $item) {
276 if (!$item instanceof UpStream_Model_TimeRecord)
277 throw new UpStream_Model_ArgumentException(__('Argument must be an array of UpStream_Model_TimeRecord objects.', 'upstream'));
278 }
279
280 $this->{$property} = $value;
281 break;
282
283 default:
284 parent::__set($property, $value);
285 break;
286 }
287 }
288
289
290 public static function fields()
291 {
292 $fields = parent::fields();
293
294 $fields['notes'] = [ 'type' => 'text', 'title' => __('Notes'), 'search' => true, 'display' => true ];
295 $fields['startDate'] = [ 'type' => 'date', 'title' => __('Start Date'), 'search' => true, 'display' => true ];
296 $fields['endDate'] = [ 'type' => 'date', 'title' => __('End Date'), 'search' => true, 'display' => true ];
297 $fields['statusCode'] = [ 'type' => 'select', 'title' => __('Status'), 'search' => true, 'display' => true, 'options_cb' => 'UpStream_Model_Task::getStatuses' ];
298 $fields['progress'] = [ 'type' => 'number', 'title' => __('Progress (%)'), 'search' => true, 'display' => true ];
299
300 unset($fields['description']);
301
302 $fields = self::customFields($fields, UPSTREAM_ITEM_TYPE_TASK);
303
304 return $fields;
305 }
306
307
308 public static function getStatuses()
309 {
310 $option = get_option('upstream_tasks');
311 $statuses = isset($option['statuses']) ? $option['statuses'] : '';
312 $array = [];
313 if ($statuses) {
314 foreach ($statuses as $status) {
315 $array[$status['id']] = $status['name'];
316 }
317 }
318
319 return $array;
320 }
321
322 public static function create($parent, $title, $createdBy)
323 {
324 if (get_userdata($createdBy) === false)
325 throw new UpStream_Model_ArgumentException(__('User ID does not exist.', 'upstream'));
326
327 $item_metadata =
328 ['title' => sanitize_text_field($title),
329 'created_by' => $createdBy];
330
331 return new self($parent, $item_metadata);
332 }
333
334 }