PluginProbe
UpStream: a Project Management Plugin for WordPress / 1.39.2
UpStream: a Project Management Plugin for WordPress v1.39.2
trunk 1.39.0 1.39.1 1.39.2 1.39.3 2.0.7 2.1.0
upstream / includes / class-up-import.php

class-up-import.php in UpStream: a Project Management Plugin for WordPress 1.39.2, at includes/class-up-import.php

400 lines 11.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Setup message asking for review.
4 *
5 * @author UpStream
6 * @category Admin
7 * @package UpStream/Admin
8 * @version 1.0.0
9 */
10
11 // Exit if accessed directly or already defined.
12 if ( ! defined('ABSPATH') || class_exists('UpStream_Import')) {
13 return;
14 }
15
16 class UpStream_Import_Exception extends Exception {}
17
18 /**
19 * Class UpStream_Import
20 */
21 class UpStream_Import
22 {
23 protected $option_created_by = 1;
24
25 protected $columns = [];
26
27 protected $model_manager;
28
29 /**
30 * UpStream_Admin_Import constructor.
31 */
32 public function __construct()
33 {
34 $this->option_created_by = wp_get_current_user()->ID;
35
36 $this->model_manager = \UpStream_Model_Manager::get_instance();
37 $this->model_manager->loadAll();
38 }
39
40 /**
41 * @param int $project_column
42 */
43 public function setProjectColumn($project_column)
44 {
45 $this->project_column = $project_column;
46 }
47
48 /**
49 * @param $file
50 * @return string|null
51 */
52 public static function importFile($file, $line_start)
53 {
54
55 if (true) {
56
57 $error = '';
58 $importer = new UpStream_Import();
59
60 ini_set('auto_detect_line_endings',TRUE);
61 $handle = fopen($file,'r');
62
63 try {
64 $lineNo = 0;
65 while (($data = fgetcsv($handle)) !== FALSE) {
66
67 if ($lineNo == 0 || $lineNo >= $line_start) {
68 $importer->importTableLine($data, $lineNo);
69 }
70 $lineNo++;
71 if ($lineNo >= $line_start + 100) {
72 break;
73 }
74 }
75 } catch (\Exception $e) {
76 $error = __('Error loading file: line ', 'upstream') . ($lineNo + 1) . ' ' . $e->getMessage();
77 }
78
79 fclose($handle);
80 ini_set('auto_detect_line_endings',FALSE);
81
82 return $error;
83 }
84 }
85
86 public static function prepareFile($file)
87 {
88
89 if (true) {
90
91 $message = '';
92 $importer = new UpStream_Import();
93
94 ini_set('auto_detect_line_endings',TRUE);
95 $handle = fopen($file,'r');
96
97 try {
98 $lineNo = 0;
99 while (($data = fgetcsv($handle)) !== FALSE) {
100 $lineNo++;
101 }
102 } catch (\Exception $e) {
103 $message = __('Error loading file: line ', 'upstream') . ($lineNo + 1) . ' ' . $e->getMessage();
104 }
105
106 fclose($handle);
107 ini_set('auto_detect_line_endings',FALSE);
108
109 return ['message' => $message, 'lines' => $lineNo];
110 }
111 }
112
113 /**
114 * @param $line
115 * @return array
116 */
117 protected function cleanLine(&$line)
118 {
119 $newline = [];
120
121 foreach ($line as $l) {
122 $newline[] = trim($l);
123 }
124
125 return $newline;
126 }
127
128 /**
129 * @param $arr
130 * @param $lineNo
131 * @throws UpStream_Import_Exception
132 */
133 protected function importTableLine(&$arr, $lineNo)
134 {
135 if ($lineNo == 0) {
136 $this->loadHeader($arr);
137 } else {
138 $line = $this->cleanLine($arr);
139
140 // load project
141 $projectId = $this->findItemField(UPSTREAM_ITEM_TYPE_PROJECT, 'id', $line);
142 if (!$projectId) {
143 $title = $this->findItemField(UPSTREAM_ITEM_TYPE_PROJECT, 'title', $line);
144 if ($title) {
145 $projectId = $this->findOrCreateItemByTitle(UPSTREAM_ITEM_TYPE_PROJECT, $title);
146 }
147 }
148
149 $project = null;
150 if ($projectId) {
151 try {
152 $project = $this->model_manager->getByID(UPSTREAM_ITEM_TYPE_PROJECT, $projectId);
153 } catch (\UpStream_Model_ArgumentException $e) {
154 throw new UpStream_Import_Exception(sprintf(__('Project with ID %s does not exist.', 'upstream'), $projectId));
155 }
156 }
157
158 if ($project) {
159 $this->setFields($line, $project);
160 }
161
162 // load milestone
163 $milestoneId = $this->findItemField(UPSTREAM_ITEM_TYPE_MILESTONE, 'id', $line);
164 if (!$milestoneId) {
165 $title = $this->findItemField(UPSTREAM_ITEM_TYPE_MILESTONE, 'title', $line);
166 if ($title) {
167 $milestoneId = $this->findOrCreateItemByTitle(UPSTREAM_ITEM_TYPE_MILESTONE, $title, $project);
168 }
169 }
170
171 $milestone = null;
172 if ($milestoneId) {
173 try {
174 $milestone = $this->model_manager->getByID(UPSTREAM_ITEM_TYPE_MILESTONE, $milestoneId);
175 } catch (\UpStream_Model_ArgumentException $e) {
176 throw new UpStream_Import_Exception(sprintf(__('Milestone with ID %s does not exist.', 'upstream'), $milestoneId));
177 }
178 }
179
180
181 if ($milestone) {
182 $this->setFields($line, $milestone);
183 }
184
185 $this->importChildrenOfType(UPSTREAM_ITEM_TYPE_TASK, $project, $milestone, $line);
186 $this->importChildrenOfType(UPSTREAM_ITEM_TYPE_FILE, $project, $milestone, $line);
187 $this->importChildrenOfType(UPSTREAM_ITEM_TYPE_BUG, $project, $milestone, $line);
188
189
190 }
191 }
192
193 /**
194 * @param $type
195 * @param $project
196 * @param $itemId
197 * @return mixed
198 */
199 protected function findChildItem($type, &$project, $itemId)
200 {
201 if ($project) {
202 $pid = $project->id;
203
204 return $this->model_manager->getByID($type, $itemId, UPSTREAM_ITEM_TYPE_PROJECT, $project->id);
205
206 } else {
207 // TODO: what to do when there's no preoject
208 }
209 }
210
211
212 /**
213 * @param $type
214 * @param $project
215 * @param $milestone
216 * @param $line
217 * @throws UpStream_Import_Exception
218 */
219 protected function importChildrenOfType($type, &$project, &$milestone, &$line)
220 {
221 // look for tasks
222 $itemId = $this->findItemField($type, 'id', $line);
223 if (!$itemId) {
224 $title = $this->findItemField($type, 'title', $line);
225 if ($title) {
226 $itemId = $this->findOrCreateItemByTitle($type, $title, $project, $milestone);
227 }
228 }
229
230 if ($itemId) {
231 try {
232 $item = $this->findChildItem($type, $project, $itemId);
233 } catch (\UpStream_Model_ArgumentException $e) {
234 throw new UpStream_Import_Exception(sprintf(__('Item %s with ID %s does not exist.', 'upstream'), $type, $itemId));
235 }
236
237 $this->setFields($line, $item);
238 }
239
240 }
241
242 /**
243 * @param $type
244 * @param $title
245 * @param null $project
246 * @param null $milestone
247 * @return |null
248 */
249 protected function findOrCreateItemByTitle($type, $title, $project = null, $milestone = null)
250 {
251
252 if ($type === UPSTREAM_ITEM_TYPE_PROJECT) {
253
254 $matches = $this->model_manager->findAllByCallback(function($item) use ($title) {
255 return $item->type === UPSTREAM_ITEM_TYPE_PROJECT && $item->title == $title;
256 });
257
258 $obj = null;
259
260 if (count($matches) > 0) {
261 $obj = $matches[0];
262 } else {
263 $obj = $this->model_manager->createObject($type, $title, $this->option_created_by);
264 $obj->store();
265 }
266
267 return $obj->id;
268 }
269
270 if (!$project) {
271 return null;
272 }
273
274 $matches = $this->model_manager->findAllByCallback(function($item) use ($title, $type, $project) {
275 return $item->type === $type && $item->parentId == $project->id && $item->title == $title;
276 });
277
278 if (count($matches) > 0) {
279 $obj = $matches[0];
280 } else {
281 $obj = $this->model_manager->createObject($type, $title, $this->option_created_by, $project->id);
282 }
283
284 if ($type === UPSTREAM_ITEM_TYPE_TASK && $milestone) {
285 $obj->milestone = $milestone;
286 }
287
288 $obj->store();
289
290 return $obj->id;
291 }
292
293 /**
294 * @param $type
295 * @param $field
296 * @param $line
297 * @return mixed|null
298 */
299 protected function findItemField($type, $field, &$line)
300 {
301 for ($i = 0; $i < count($this->columns); $i++) {
302
303 if ($this->columns[$i]->itemType === $type && $this->columns[$i]->fieldName === $field) {
304 return $line[$i];
305 }
306
307 }
308
309 return null;
310 }
311
312
313 /**
314 * Sets the fields of the object based on the fields in the table
315 * @param $line
316 * @param $item
317 * @throws UpStream_Import_Exception
318 */
319 protected function setFields(&$line, &$item)
320 {
321 $changed = false;
322
323 if (!$item) {
324 return;
325 }
326
327 for ($i = 0; $i < count($line); $i++) {
328
329 if (!$this->columns[$i]) {
330 continue;
331 }
332
333 if ($this->columns[$i]->itemType === $item->type) {
334 $val = null;
335 try {
336 $val = $item->{$this->columns[$i]->fieldName};
337 } catch (\UpStream_Model_ArgumentException $e) {
338 // ignore this
339 }
340
341 if ($line[$i] && $val != $line[$i]) {
342 try {
343 $item->{$this->columns[$i]->fieldName} = htmlentities(iconv("cp1252", "utf-8", trim($line[$i])), ENT_IGNORE, "UTF-8");
344 $changed = true;
345 } catch (\UpStream_Model_ArgumentException $e) {
346 throw new UpStream_Import_Exception(sprintf(__('(column %s, field %s)', 'upstream'), $i+1, $this->columns[$i]->fieldName) . ' ' . $e->getMessage());
347 }
348 }
349 }
350
351 }
352
353 if ($changed) {
354 $item->store();
355 }
356
357 return $changed;
358 }
359
360
361 /**
362 * @param $header
363 * @throws UpStream_Import_Exception
364 */
365 protected function loadHeader(&$header)
366 {
367 for ($i = 0; $i < count($header); $i++) {
368
369 $header[$i] = trim($header[$i]);
370 $header[$i] = trim($header[$i], chr(239).chr(187).chr(191));
371 $s = null;
372
373 if ($header[$i]) {
374 $parts = explode('.', $header[$i]);
375
376 if (count($parts) < 2) {
377 throw new UpStream_Import_Exception(sprintf(__('Header column %s must be of the form item.field (example: project.title).', 'upstream'), $header[$i]));
378 }
379
380 $itemType = $parts[0];
381 $fieldName = $parts[1];
382
383 if (!in_array($itemType, [UPSTREAM_ITEM_TYPE_PROJECT, UPSTREAM_ITEM_TYPE_BUG, UPSTREAM_ITEM_TYPE_MILESTONE,
384 UPSTREAM_ITEM_TYPE_TASK, UPSTREAM_ITEM_TYPE_FILE])) {
385 throw new UpStream_Import_Exception(sprintf(__('Item type %s is not valid.', 'upstream'), $itemType));
386 }
387
388 // TODO: check if field is valid
389 $s = new stdClass();
390 $s->itemType = $itemType;
391 $s->fieldName = $fieldName;
392 }
393
394 $this->columns[] = $s;
395
396 }
397 }
398
399 }
400