Blame view

php/classes/TimeTableMgr.php 22.3 KB
16035364   Benjamin Renard   First commit
1
2
3
4
5
6
7
8
9
<?php

/**
 * @class TimeTableMgr
 * @version $Id: TimeTableMgr.php 2809 2015-03-05 09:50:52Z natacha $
 * @todo MANAGE TT created by Search and Plot interactive - HERE?
 *
 */

4a438b99   elena   catalog draft
10
class TimeTableMgr extends AmdaObjectMgr
139a8045   Nathanaël Jourdane   autocleanup
11
{
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
12
13
14
15
16
17
	/**
	 * TimeTableMgr constructor.
	 * @param null $user The user
	 * @param bool $sharedObject Shared object
	 */
	public function __construct($user = null, $sharedObject = false)
4a438b99   elena   catalog draft
18
	{
16035364   Benjamin Renard   First commit
19
20
21
		parent::__construct('Tt.xml');
		$this->contentRootId = 'timeTable-treeRootNode';
		$this->contentRootTag = 'timetabList';
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
22
23
		$this->attributes = ['name' => '', 'intervals' => ''];
		$this->optionalAttributes = [];
16035364   Benjamin Renard   First commit
24
25
26
		$this->objTagName = 'timetab';
		$this->id_prefix = 'tt_';

169f14d2   Benjamin Renard   Add shared object...
27
		if (!$sharedObject && !file_exists($this->xmlName)) {
139a8045   Nathanaël Jourdane   autocleanup
28
29
			$this->createDom();
			$this->xp = new domxpath($this->contentDom);
16035364   Benjamin Renard   First commit
30
31
		}
	}
139a8045   Nathanaël Jourdane   autocleanup
32
33

	protected function createDom()
3ed056c4   Elena.Budnik   redmine #5278
34
	{
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
35
		$types = ['timetab' => 'timeTable', 'catalog' => 'catalog'];
16035364   Benjamin Renard   First commit
36
37

		$rootElement = $this->contentDom->createElement('ws');
139a8045   Nathanaël Jourdane   autocleanup
38

3ed056c4   Elena.Budnik   redmine #5278
39
		foreach ($types as $key => $value) {
139a8045   Nathanaël Jourdane   autocleanup
40
41
			$contentId = $value . '-treeRootNode';
			$contentTag = $key . 'List';
3ed056c4   Elena.Budnik   redmine #5278
42
43
44
			$typeElement = $this->contentDom->createElement($contentTag);
			$typeElement->setAttribute('xml:id', $contentId);
			$rootElement->appendChild($typeElement);
16035364   Benjamin Renard   First commit
45
		}
4a438b99   elena   catalog draft
46
		$this->contentDom->appendChild($rootElement);
16035364   Benjamin Renard   First commit
47
		$this->contentDom->save($this->xmlName);
3ed056c4   Elena.Budnik   redmine #5278
48
	}
16035364   Benjamin Renard   First commit
49

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
50
51
52
53
54
55
56
	/**
	 * Get object
	 * @param $id
	 * @param $nodeType
	 * @return array
	 */
	public function getObject($id, $nodeType = null)
4a438b99   elena   catalog draft
57
	{
139a8045   Nathanaël Jourdane   autocleanup
58
59
60
61
62
63
64
		if (substr($nodeType, 0, 6) == 'shared') {
			//Shared object
			$sharedObjMgr = new SharedObjectsMgr();
			$path = $sharedObjMgr->getDataFilePath(str_replace('shared', '', $nodeType), $id);
		} else {
			$path = USERTTDIR . $id . '.xml';
		}
16035364   Benjamin Renard   First commit
65

139a8045   Nathanaël Jourdane   autocleanup
66
		if (!file_exists($path)) {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
67
			return ['error' => NO_OBJECT_FILE];
139a8045   Nathanaël Jourdane   autocleanup
68
69
70
		}
		$this->objectDom->load($path);
		if (!($objToGet = $this->objectDom->getElementById($id))) {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
71
			return ['error' => NO_SUCH_ID];
139a8045   Nathanaël Jourdane   autocleanup
72
73
74
75
76
77
78
79
80
81
82
83
84
85
		}
		$attributesToReturn['id'] = $objToGet->getAttribute('xml:id');
		$attributes = $objToGet->childNodes;

		$nbInt = 0;
		foreach ($attributes as $attribute) {
			if ($attribute->nodeType == XML_ELEMENT_NODE) {
				/*if ($attribute->tagName == 'intervals') {
					$start = $attribute -> getElementsByTagName('start')->item(0) -> nodeValue;
					$stop = $attribute -> getElementsByTagName('stop')->item(0) -> nodeValue;
					$attributesToReturn['intervals'][] = array('start' => $start, 'stop' => $stop);
				}
				else
				$attributesToReturn[$attribute->tagName] =  $attribute->nodeValue;*/
0fea5567   Benjamin Renard   First step for re...
86
				//BRE - load all except intervals - Intervals will be loaded later with 'loadIntervalsFromObject' function
139a8045   Nathanaël Jourdane   autocleanup
87
88
89
				if ($attribute->tagName != 'intervals') {
					$attributesToReturn[$attribute->tagName] = $attribute->nodeValue;
				} else {
2ff71aba   Hacene SI HADJ MOHAND   correcting survey...
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
					
                                                                                                    // get 'surveyStart' and 
                                                                                                    if($attributesToReturn['surveyStart'] == "" || $attributesToReturn['surveyStop'] == "" ){
                                                                                                    if($nbInt == 0){
                                                                                                        foreach ($attribute->childNodes  as $ch ){
                                                                                                          if($ch->tagName == 'start')  $start =  $ch->nodeValue;
                                                                                                          if($ch->tagName == 'stop')  $stop =  $ch->nodeValue;
                                                                                                        }
                                                                                                    }else{
                                                                                                        foreach ($attribute->childNodes  as $ch ){
                                                                                                        if($ch->tagName == 'start' && $start >  $ch->nodeValue)  $start =  $ch->nodeValue;
                                                                                                        if($ch->tagName == 'stop' && $stop <  $ch->nodeValue)  $stop =  $ch->nodeValue;
                                                                                                        }
                                                                                                    }
                                                                                                    }
                                                                                                    $nbInt++;
139a8045   Nathanaël Jourdane   autocleanup
106
107
108
				}
			}
		}
2ff71aba   Hacene SI HADJ MOHAND   correcting survey...
109
110
111
112
                                        if($attributesToReturn['surveyStart'] == "")
                                            $attributesToReturn['surveyStart']  = $start;
                                        if($attributesToReturn['surveyStop'] == "" )
                                            $attributesToReturn['surveyStop'] = $stop;
139a8045   Nathanaël Jourdane   autocleanup
113
114
115
		$attributesToReturn['nbIntervals'] = $nbInt;

		return $attributesToReturn;
16035364   Benjamin Renard   First commit
116
117
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
118
119
120
121
122
	/**
	 * Modify an object
	 * @param $p
	 * @return array
	 */
139a8045   Nathanaël Jourdane   autocleanup
123
	public function modifyObject($p)
4a438b99   elena   catalog draft
124
	{
139a8045   Nathanaël Jourdane   autocleanup
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
		$folder = $this->getObjectFolder($p->id);

		//Copy TT in a tempory file
		$ttFilePath = USERTTDIR . $p->id . '.xml';
		$tmpFileExist = false;
		if (file_exists($ttFilePath)) {
			$tmpFileExist = copy($ttFilePath, $ttFilePath . ".tmp");
		}

		//Delete TT
		$this->deleteObject($p);

		//Save modifications
		try {
			$result = $this->createObject($p, $folder);
			if ($result['error']) {
				throw new Exception($result['error']);
			}
			if ($tmpFileExist) {
				unlink($ttFilePath . ".tmp");
			}
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
146
147
			return ['id' => $p->id, 'info' => $result['info']];
		} catch (Exception $exception) {
139a8045   Nathanaël Jourdane   autocleanup
148
149
150
151
152
			//Restore TT file
			if ($tmpFileExist) {
				copy($ttFilePath . ".tmp", $ttFilePath);
				unlink($ttFilePath . ".tmp");
			}
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
153
			return ['error' => $exception->getMessage()];
139a8045   Nathanaël Jourdane   autocleanup
154
		}
16035364   Benjamin Renard   First commit
155
156
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
157
158
159
160
161
162
	/**
	 * Create an object
	 * @param $p
	 * @param $folder
	 * @return array
	 */
139a8045   Nathanaël Jourdane   autocleanup
163
164
165
166
167
168
169
170
171
	public function createObject($p, $folder)
	{
		if ($p->leaf) {
			$result = $this->createParameter($p, $folder);
			if ($result['error']) {
				return $result;
			}
			$cacheMgr = new TimeTableCacheMgr();
			if (isset($p->cacheToken) && ($p->cacheToken != '')) {
0fea5567   Benjamin Renard   First step for re...
172
				$resultSaveInt = $cacheMgr->saveInObject($result['id'], "update", $p->cacheToken);
139a8045   Nathanaël Jourdane   autocleanup
173
174
				if (!$resultSaveInt['success']) {
					if ($resultSaveInt['message']) {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
175
						return ['error' => $resultSaveInt['message']];
139a8045   Nathanaël Jourdane   autocleanup
176
					} else {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
177
						return ['error' => 'Unknown error during intervals save'];
139a8045   Nathanaël Jourdane   autocleanup
178
179
180
181
					}
				}
			}
			return $result;
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
182
183
184
185
		} else {
			return ['error' => 'createFolder should be called from RENAME'];
			// return $this->createFolder($p);
			// TODO check if this is possible?
139a8045   Nathanaël Jourdane   autocleanup
186
		}
16035364   Benjamin Renard   First commit
187
	}
16035364   Benjamin Renard   First commit
188

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
189
190
191
192
193
194
	/**
	 * Create parameter (in case of catalogs)
	 * @param $p
	 * @param $folder
	 * @return array
	 */
4a438b99   elena   catalog draft
195
196
	protected function createParameter($p, $folder)
	{
139a8045   Nathanaël Jourdane   autocleanup
197
198
199
		if ($this->objectExistsByName($p->name)) {
			$p->id = $this->getObjectIdByName($p->name);
			$this->deleteObject($p);
16035364   Benjamin Renard   First commit
200
		}
139a8045   Nathanaël Jourdane   autocleanup
201

16035364   Benjamin Renard   First commit
202
203
		$this->id = $this->setId();
		$this->created = date('Y-m-d\TH:i:s');
139a8045   Nathanaël Jourdane   autocleanup
204
		if (!$this->id) {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
205
			return ['error' => ID_CREATION_ERROR];
139a8045   Nathanaël Jourdane   autocleanup
206
207
208
		}

		$this->resFileName = USERTTDIR . $this->id . '.xml';
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
209
		// TODO catalog root element = 'timetable'
16035364   Benjamin Renard   First commit
210
		$rootElement = $this->objectDom->createElement('timetable');
139a8045   Nathanaël Jourdane   autocleanup
211
212
213
		$rootElement->setAttribute('xml:id', $this->id);

		foreach ($p as $key => $value) {
3ed056c4   Elena.Budnik   redmine #5278
214
215
			if ($key != 'id' && $key != 'leaf' && $key != 'nodeType' &&
				$key != 'objName' && $key != 'objFormat' && $key != 'folderId' && $key != 'cacheToken') {
139a8045   Nathanaël Jourdane   autocleanup
216
217
218
219
220
221
222
223
224
				if ($key == 'created') {
					$rootElement->appendChild($this->objectDom->createElement($key, $this->created));
				} // it is catalog
				else {
					if ($key == 'parameters') {
						$paramsElement = $this->setParamDescription($value);
						if ($paramsElement) {
							$rootElement->appendChild($paramsElement);
						}
139a8045   Nathanaël Jourdane   autocleanup
225
226
227
228
					} else {
						if ($key != 'intervals') {
							$rootElement->appendChild($this->objectDom->createElement($key, htmlspecialchars($value)));
						}
3ed056c4   Elena.Budnik   redmine #5278
229
					}
139a8045   Nathanaël Jourdane   autocleanup
230
				}
d18b535d   elena   catalog draft + c...
231
			}
139a8045   Nathanaël Jourdane   autocleanup
232
		}
16035364   Benjamin Renard   First commit
233
234
235
236
237
238

		$this->objectDom->appendChild($rootElement);
		$this->objectDom->save($this->resFileName);
		$obj = new stdClass();
		$obj->name = $p->name;
		$obj->intervals = $p->nbIntervals;
139a8045   Nathanaël Jourdane   autocleanup
239
		$this->addToContent($obj, $folder);
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
240
241
		// FIXME field created is undefined
		return ['id' => $this->id, 'created' => $this->created, 'info' => $obj->intervals . ' intervals'];
16035364   Benjamin Renard   First commit
242
243
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
244
245
246
247
248
	/**
	 * Set parameter description
	 * TODO
	 * @param $param string The parameter
	 * @return DOMNode
139a8045   Nathanaël Jourdane   autocleanup
249
	 */
139a8045   Nathanaël Jourdane   autocleanup
250
	protected function setParamDescription($param)
4a438b99   elena   catalog draft
251
	{
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
252
		return new DOMNode();
4a438b99   elena   catalog draft
253
	}
139a8045   Nathanaël Jourdane   autocleanup
254

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
255
	/**
53048303   Benjamin Renard   Cleanup TimeTable...
256
	 * Load TT content from dom documentElement
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
257
	 */
53048303   Benjamin Renard   Cleanup TimeTable...
258
259
	 protected function loadObjectFile($dom, $onlyDescription, $start = null, $limit = null) {
		$attributesToReturn = array();
16035364   Benjamin Renard   First commit
260

139a8045   Nathanaël Jourdane   autocleanup
261
262
263
264
		$descNodes = $dom->getElementsByTagName('description');
		if ($descNodes->length > 0) {
			$attributesToReturn['description'] = $descNodes->item(0)->nodeValue;
		}
16035364   Benjamin Renard   First commit
265

139a8045   Nathanaël Jourdane   autocleanup
266
267
268
269
270
271
272
273
274
275
		$creatNodes = $dom->getElementsByTagName('created');
		if ($creatNodes->length > 0) {
			$attributesToReturn['created'] = $creatNodes->item(0)->nodeValue;
		}

		$histNodes = $dom->getElementsByTagName('history');
		if ($histNodes->length > 0) {
			$attributesToReturn['history'] = $histNodes->item(0)->nodeValue;
		}

53048303   Benjamin Renard   Cleanup TimeTable...
276
277
278
279
		$nameNodes = $dom->getElementsByTagName('name');
		if ($nameNodes->length > 0) {
			$attributesToReturn['name'] = $nameNodes->item(0)->nodeValue;
		}
139a8045   Nathanaël Jourdane   autocleanup
280
281

		if (!$onlyDescription) {
53048303   Benjamin Renard   Cleanup TimeTable...
282
283
			$attributesToReturn['intervals'] = array();

e01ca7c5   Benjamin Renard   Improve performan...
284
			$xpath = new DOMXPath($dom);
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
285

e01ca7c5   Benjamin Renard   Improve performan...
286
287
			$intervals = $xpath->query('//intervals');

53048303   Benjamin Renard   Cleanup TimeTable...
288
289
290
			if (!isset($start) || !isset($limit)) {
				foreach ($intervals as $interval) {
					$attributesToReturn['intervals'][] = $this->loadIntervalElement($interval);
139a8045   Nathanaël Jourdane   autocleanup
291
				}
53048303   Benjamin Renard   Cleanup TimeTable...
292
293
294
295
296
297
			} else {
				for ($iInt = 0; $iInt < $limit; ++$iInt) {
					if ($start + $iInt >= $intervals->length) {
						break;
					}
					$attributesToReturn['intervals'][] = $this->loadIntervalElement($intervals->item($start + $iInt));
16035364   Benjamin Renard   First commit
298
				}
16035364   Benjamin Renard   First commit
299
			}
16035364   Benjamin Renard   First commit
300
		}
139a8045   Nathanaël Jourdane   autocleanup
301
302

		return $attributesToReturn;
16035364   Benjamin Renard   First commit
303
	}
139a8045   Nathanaël Jourdane   autocleanup
304

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
305
	/**
53048303   Benjamin Renard   Cleanup TimeTable...
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
	 * Get uploaded object
	 * @param $name
	 * @param $format
	 * @param bool $onlyDescription
	 * @return mixed
	 */
  public function getUploadedObject($name, $format, $onlyDescription = false)
 {
	 if (strpos($name, '.xml') !== false) {
		 $temp = explode('.xml', $name);
		 $name = $temp[0];
	 }

	 if (!file_exists(USERTEMPDIR . $name . '.xml')) {
		 return ['error' => 'no such name'];
	 }

	 $this->objectDom->load(USERTEMPDIR . $name . '.xml');
	 if (!($objToGet = $this->objectDom->getElementsByTagName('timetable')->item(0)) &&
		 !($objToGet = $this->objectDom->getElementsByTagName('TimeTable')->item(0))) {
		 return ['error' => 'no time table'];
	 }

	 return array(
		 'name'      => $name,
		 'objName'   => $name,
		 'objFormat' => $format,
		 'success'   => TRUE,
	 ) + $this->loadObjectFile($this->objectDom, $onlyDescription);
 }


	/*****************************************************************
	 *                           PUBLIC FUNCTIONS
	 *****************************************************************/

	/*
	 *   Get Object into Edit
	 */
	public function getTmpObject($folderId, $name, $onlyDescription = false)
 	{
 		$filePath = USERWORKINGDIR . $folderId . '/' . $name . '.xml';
 		if (!file_exists($filePath)) {
 			return ['error' => 'Cannot find result file'];
 		}

 		$dom = new DomDocument('1.0');
 		$dom->formatOutput = true;

 		if (!$dom->load($filePath)) {
 			return ['error' => 'Cannot load result file'];
 		}

 		return array(
 			'objName' => $name,
 			'folderId' => $folderId,
			'success' => TRUE,
 		) + $this->loadObjectFile($dom, $onlyDescription);
 	}

	/**
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
367
368
369
370
	 * Merge time tables
	 * @param $obj
	 * @return array
	 */
139a8045   Nathanaël Jourdane   autocleanup
371
372
373
374
375
376
377
378
379
	public function merge($obj)
	{
		/**
		 * Array of intervals, used like :
		 * [{start:'2010-01-01T23:00:00',stop:'2011-01-01T20:00:00'},{start:'2009-01-01T23:00:00',stop:'2010-01-01T20:00:00'}]
		 * $attributesToReturn['intervals'][] = array('start' => $start, 'stop' => $stop);
		 */

		$intervals = 0;
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
380
		for ($iId = 0; $iId < count($obj->ids); $iId++) {
ff9a9bbf   Benjamin Renard   Fix TT operation ...
381
			$table[$iId] = $this->loadIntervalsFromObject($obj->ids[$iId]->id, $obj->ids[$iId]->nodeType);
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
382
383
384
			for ($jId = 0; $jId < count($table[$iId]['intervals']); $jId++) {
				$interval[$iId][$jId][0] = $table[$iId]['intervals'][$jId]['start'];
				$interval[$iId][$jId][1] = $table[$iId]['intervals'][$jId]['stop'];
139a8045   Nathanaël Jourdane   autocleanup
385
			}
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
386
			$intervals += count($interval[$iId]);
16035364   Benjamin Renard   First commit
387
		}
139a8045   Nathanaël Jourdane   autocleanup
388
389
390
391
		if ($intervals > 10000) {
			set_time_limit(1800);
		}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
392
393
394
		$final = [];
		for ($iId = 0; $iId < count($obj->ids); $iId++) {
			$final = array_merge($final, $interval[$iId]);
139a8045   Nathanaël Jourdane   autocleanup
395
396
397
398
399
		}
		sort($final);

		// Algorithm of union
		$line = 0;
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
400
401
402
403
404
		$iId = 0;
		$val = $final[$iId][0];
		while ($iId < count($final) - 1) {
			if ($final[$iId + 1][1] <= $final[$iId][1]) {
				array_splice($final, $iId + 1, 1);
139a8045   Nathanaël Jourdane   autocleanup
405
			} else {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
406
407
				if (($final[$iId + 1][0] <= $final[$iId][1]) && ($final[$iId + 1][1] >= $final[$iId][1])) {
					$iId++;
139a8045   Nathanaël Jourdane   autocleanup
408
				} else {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
409
410
411
					$start[$line] = $val;
					$stop[$line] = $final[$iId][1];
					$iId++;
139a8045   Nathanaël Jourdane   autocleanup
412
					$line++;
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
413
					$val = $final[$iId][0];
139a8045   Nathanaël Jourdane   autocleanup
414
				}
16035364   Benjamin Renard   First commit
415
			}
16035364   Benjamin Renard   First commit
416
		}
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
417
418
		$start[$line] = $val;
		$stop[$line] = $final[$iId][1];
139a8045   Nathanaël Jourdane   autocleanup
419
420
421
422
423
424
425

		$objTT = new stdClass();
		$objTT->name = $obj->name;
		$objTT->nodeType = 'timeTable';
		$objTT->leaf = true;
		$objTT->created = null;
		$objTT->history = $obj->history;
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
426
		for ($iId = 0; $iId < count($start); $iId++) {
a9285c23   Benjamin Renard   Fix TT merge & in...
427
428
429
430
			$inter = array(
				'start' => $start[$iId],
				'stop' => $stop[$iId],
			);
139a8045   Nathanaël Jourdane   autocleanup
431
432
433
434
435
436
			$objTT->intervals[] = $inter;
		}
		$objTT->nbIntervals = count($start);
		$this->objectDom = new DomDocument('1.0');
		$this->objectDom->formatOutput = true;

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
437
		$res = $this->createParameter($objTT, $folder); // FIXME $folder is undefined
139a8045   Nathanaël Jourdane   autocleanup
438
439
440
441
442
		if ($res['error']) {
			return $res;
		}

		$this->saveIntervals($res['id'], $objTT->intervals, 'merge');
139a8045   Nathanaël Jourdane   autocleanup
443
		return $res;
16035364   Benjamin Renard   First commit
444
	}
139a8045   Nathanaël Jourdane   autocleanup
445

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
446
447
448
449
450
451
452
453
	/**
	 * Load intervals from time table
	 * @param $id
	 * @param $typeTT
	 * @param null $start
	 * @param null $limit
	 * @return array
	 */
53048303   Benjamin Renard   Cleanup TimeTable...
454
455
	 public function loadIntervalsFromObject($id, $typeTT = '', $start = null, $limit = null)
 	{
d54a1a7b   Benjamin Renard   Fix load from sha...
456
 		if ($typeTT == 'sharedtimeTable' || $typeTT == 'sharedcatalog') {
53048303   Benjamin Renard   Cleanup TimeTable...
457
458
 			//Shared object
 			$sharedObjMgr = new SharedObjectsMgr();
d54a1a7b   Benjamin Renard   Fix load from sha...
459
460
			$sharedType = ($typeTT == 'sharedcatalog') ? 'catalog' : 'timeTable';
 			$path = $sharedObjMgr->getDataFilePath($sharedType, $id);
53048303   Benjamin Renard   Cleanup TimeTable...
461
462
463
464
465
466
 		} else {
 			$path = USERTTDIR . $id . '.xml';
 		}

 		//load intervals from TT id
 		if (!file_exists($path)) {
d54a1a7b   Benjamin Renard   Fix load from sha...
467
 			return ['success' => false, 'message' => "Cannot find TT file " . $id ];
53048303   Benjamin Renard   Cleanup TimeTable...
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
 		}

 		$this->objectDom->load($path);
 		if (!($objToGet = $this->objectDom->getElementById($id))) {
 			return ['success' => false, 'message' => NO_SUCH_ID . " " . $id];
 		}

 		$result = $this->loadObjectFile($this->objectDom, FALSE, $start, $limit);

 		return array(
 			'totalCount' => $result['totalCount'],
 			'intervals' => $result['intervals'],
 			'start' => isset($start) ? $start : 0,
 			'limit' => isset($limit) ? $limit : 0,
 			'success' => true,
 		);
 	}
139a8045   Nathanaël Jourdane   autocleanup
485

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
486
487
488
489
490
491
492
	/**
	 * Save intervals
	 * @param $id
	 * @param $intervals
	 * @param $action
	 * @return array
	 */
42e2e019   Benjamin Renard   Next step for cac...
493
	public function saveIntervals($id, $intervals, $action, $options = array())
3ed056c4   Elena.Budnik   redmine #5278
494
	{
139a8045   Nathanaël Jourdane   autocleanup
495
		if (substr($id, 0, 6) == 'shared') {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
496
			return ['success' => false, 'message' => "Cannot save shared TimeTable"];
139a8045   Nathanaël Jourdane   autocleanup
497
498
499
500
		} else {
			$path = USERTTDIR . $id . '.xml';
		}
		if (!file_exists($path)) {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
501
			return ['success' => false, 'message' => "Cannot find TT file " . $id];
139a8045   Nathanaël Jourdane   autocleanup
502
503
504
505
		}
		$this->objectDom->load($path);

		if (!($objToGet = $this->objectDom->getElementById($id))) {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
506
			return ['success' => false, 'message' => NO_SUCH_ID . " " . $id];
3ed056c4   Elena.Budnik   redmine #5278
507
		}
16035364   Benjamin Renard   First commit
508

3ed056c4   Elena.Budnik   redmine #5278
509
510
		//remove old intervals
		$crtNode = $objToGet->firstChild;
139a8045   Nathanaël Jourdane   autocleanup
511

3ed056c4   Elena.Budnik   redmine #5278
512
		while ($crtNode) {
139a8045   Nathanaël Jourdane   autocleanup
513
			if (($crtNode->nodeType != XML_ELEMENT_NODE) || ($crtNode->tagName != 'intervals')) {
3ed056c4   Elena.Budnik   redmine #5278
514
515
516
517
518
519
520
521
				$crtNode = $crtNode->nextSibling;
				continue;
			}
			$toRemove = $crtNode;
			$crtNode = $crtNode->nextSibling;
			$objToGet->removeChild($toRemove);
			unset($toRemove);
		}
139a8045   Nathanaël Jourdane   autocleanup
522

3ed056c4   Elena.Budnik   redmine #5278
523
		//add new intervals
139a8045   Nathanaël Jourdane   autocleanup
524
		foreach ($intervals as $interval) {
42e2e019   Benjamin Renard   Next step for cac...
525
			$newInterval = $this->createIntervalElement($interval, $options);
3ed056c4   Elena.Budnik   redmine #5278
526
527
			$this->objectDom->documentElement->appendChild($newInterval);
		}
16035364   Benjamin Renard   First commit
528

3ed056c4   Elena.Budnik   redmine #5278
529
530
		//save modifications
		$this->id = $id;
139a8045   Nathanaël Jourdane   autocleanup
531
		$this->resFileName = USERTTDIR . $this->id . '.xml';
3ed056c4   Elena.Budnik   redmine #5278
532
		$this->objectDom->save($this->resFileName);
139a8045   Nathanaël Jourdane   autocleanup
533

3ed056c4   Elena.Budnik   redmine #5278
534
		unset($this->objectDom);
139a8045   Nathanaël Jourdane   autocleanup
535

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
536
		return ['success' => true, 'action' => $action, 'nbIntervals' => count($intervals)];
3ed056c4   Elena.Budnik   redmine #5278
537
	}
139a8045   Nathanaël Jourdane   autocleanup
538

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
539
	/**
53048303   Benjamin Renard   Cleanup TimeTable...
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
	 * Load interval from DOMElement
	 * @param DOMElement
	 * @return interval
	 */
	protected function loadIntervalElement($intervalNode)
	{
		$startTimes = $intervalNode->getElementsByTagName('start');
		$stopTimes = $intervalNode->getElementsByTagName('stop');

		if (($startTimes->length != 1) || ($stopTimes->length != 1)) {
			return FALSE;
		}

		return array(
			'start' => $startTimes->item(0)->nodeValue,
			'stop' => $stopTimes->item(0)->nodeValue,
		);
	}

	/**
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
560
561
562
563
	 * Create interval element
	 * @param $interval
	 * @return DOMElement
	 */
42e2e019   Benjamin Renard   Next step for cac...
564
	protected function createIntervalElement($interval, $options = array())
3ed056c4   Elena.Budnik   redmine #5278
565
	{
139a8045   Nathanaël Jourdane   autocleanup
566
		$newInterval = $this->objectDom->createElement('intervals');
42e2e019   Benjamin Renard   Next step for cac...
567
568
		$newInterval->appendChild($this->objectDom->createElement('start', $interval['start']));
		$newInterval->appendChild($this->objectDom->createElement('stop', $interval['stop']));
139a8045   Nathanaël Jourdane   autocleanup
569
570
571
		return $newInterval;
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
572
573
574
575
576
	/**
	 * Intersect time tables
	 * @param $obj
	 * @return array|string
	 */
139a8045   Nathanaël Jourdane   autocleanup
577
578
	public function intersect($obj)
	{
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
579
580
		$intervals = 0;
		for ($iId = 0; $iId < count($obj->ids); $iId++) {
ff9a9bbf   Benjamin Renard   Fix TT operation ...
581
			$table[$iId] = $this->loadIntervalsFromObject($obj->ids[$iId]->id, $obj->ids[$iId]->nodeType);
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
582
583
584
			for ($jId = 0; $jId < count($table[$iId]['intervals']); $jId++) {
				$interval[$iId][$jId][0] = $table[$iId]['intervals'][$jId]['start'];
				$interval[$iId][$jId][1] = $table[$iId]['intervals'][$jId]['stop'];
139a8045   Nathanaël Jourdane   autocleanup
585
			}
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
586
			$intervals += count($interval[$iId]);
16035364   Benjamin Renard   First commit
587
		}
139a8045   Nathanaël Jourdane   autocleanup
588
589
		if ($intervals > 10000) {
			set_time_limit(1800);
16035364   Benjamin Renard   First commit
590
		}
16035364   Benjamin Renard   First commit
591

139a8045   Nathanaël Jourdane   autocleanup
592
593
594
		// Sort intervals in time tables
		sort($interval[0]);
		sort($interval[1]);
16035364   Benjamin Renard   First commit
595

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
596
597
		$iId = 0;
		$jId = 0;
139a8045   Nathanaël Jourdane   autocleanup
598
599
		$line = 0;

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
600
601
		while (($iId < count($interval[0])) && ($jId < count($interval[1]))) {
			$inter = $this->callIntersection($interval[0][$iId], $interval[1][$jId]);
139a8045   Nathanaël Jourdane   autocleanup
602
603
604
605
606
607
608

			if ($inter[0][0] != 0 && $inter[0][1] != 0) {
				$start[$line] = $inter[0][0];
				$stop[$line] = $inter[0][1];
				$line++;
			}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
609
610
			if ($interval[0][$iId][1] < $interval[1][$jId][1]) {
				$iId++;
139a8045   Nathanaël Jourdane   autocleanup
611
			} else {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
612
				$jId++;
139a8045   Nathanaël Jourdane   autocleanup
613
614
615
616
617
618
619
			}
		}

		// Intersection is empty
		if ($line == 0) {
			$result = "empty";
		} else {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
620
			$objTT->name = $obj->name;  // FIXME $objTT is undefined
139a8045   Nathanaël Jourdane   autocleanup
621
622
623
624
			$objTT->nodeType = 'timeTable';
			$objTT->leaf = true;
			$objTT->created = null;
			$objTT->history = $obj->history;
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
625
			for ($iId = 0; $iId < count($start); $iId++) {
a9285c23   Benjamin Renard   Fix TT merge & in...
626
627
628
629
				$inter = array(
					'start' => $start[$iId],
					'stop' => $stop[$iId],
				);
139a8045   Nathanaël Jourdane   autocleanup
630
631
632
633
634
635
636
637
638
				$objTT->intervals[] = $inter;
			}
			$objTT->nbIntervals = count($start);

			if (count($objTT->intervals) == 0) {
				$result = "empty";
			} else {
				$this->objectDom = new DomDocument('1.0');
				$this->objectDom->formatOutput = true;
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
639
				$result = $this->createObject($objTT, $folder); // FIXME $folder is undefined
139a8045   Nathanaël Jourdane   autocleanup
640
641
642

				if (!isset($result['error'])) {
					$this->saveIntervals($result['id'], $objTT->intervals, 'intersect');
3ed056c4   Elena.Budnik   redmine #5278
643
				}
16035364   Benjamin Renard   First commit
644
			}
3ed056c4   Elena.Budnik   redmine #5278
645
		}
139a8045   Nathanaël Jourdane   autocleanup
646
647
648
		return $result;
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
649
650
651
652
653
654
655
	/**
	 * Call intersection
	 * @param $fst
	 * @param $snd
	 * @return array
	 */
	protected function callIntersection($fst, $snd)
139a8045   Nathanaël Jourdane   autocleanup
656
657
658
	{
		$inf = ($fst[0] > $snd[0]) ? $fst[0] : $snd[0];
		$sup = ($fst[1] < $snd[1]) ? $fst[1] : $snd[1];
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
659
		$inter[] = ($inf >= $sup) ? [0, 0] : [$inf, $sup];
139a8045   Nathanaël Jourdane   autocleanup
660
		return $inter;
16035364   Benjamin Renard   First commit
661
662
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
663
664
665
666
667
668
669
	/**
	 * Valid name object
	 * TODO getObject only!!!! => change DD_Search output
	 * @param $p
	 * @return array
	 */
	public function validNameObject($p)
139a8045   Nathanaël Jourdane   autocleanup
670
671
672
673
674
675
676
677
678
679
	{
		// overwritten
		$res = parent::validNameObject($p);

		if (!$res['valid']) {
			return $res;
		}

		//no space
		if (strpos($p->name, ' ') === false) {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
680
			return ['valid' => true];
16035364   Benjamin Renard   First commit
681
		}
139a8045   Nathanaël Jourdane   autocleanup
682

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
683
		return ['valid' => false, 'error' => 'Space character is not allowed'];
16035364   Benjamin Renard   First commit
684
685
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
686
687
688
689
690
691
692
693
694
	/**
	 * Copy time table
	 * @param $src_path
	 * @param $dst_path
	 * @param $newId
	 * @param $newName
	 * @param null $newDescription
	 * @return bool
	 */
139a8045   Nathanaël Jourdane   autocleanup
695
	public function copyTT($src_path, $dst_path, $newId, $newName, $newDescription = null)
3ed056c4   Elena.Budnik   redmine #5278
696
	{
139a8045   Nathanaël Jourdane   autocleanup
697
698
699
700
701
702
703
704
		if (!file_exists($src_path)) {
			return false;
		}

		if (!is_dir($dst_path)) {
			return false;
		}

169f14d2   Benjamin Renard   Add shared object...
705
706
		$dom = new DomDocument('1.0');
		$dom->formatOutput = true;
139a8045   Nathanaël Jourdane   autocleanup
707
708
709
710
711

		if (!$dom->load($src_path)) {
			return false;
		}

169f14d2   Benjamin Renard   Add shared object...
712
		$timeTableNodes = $dom->getElementsByTagName('timetable');
139a8045   Nathanaël Jourdane   autocleanup
713
714
715
716
		if ($timeTableNodes->length <= 0) {
			return false;
		}

169f14d2   Benjamin Renard   Add shared object...
717
		$timeTableNode = $timeTableNodes->item(0);
139a8045   Nathanaël Jourdane   autocleanup
718

169f14d2   Benjamin Renard   Add shared object...
719
		$timeTableNode->setAttribute('xml:id', $newId);
139a8045   Nathanaël Jourdane   autocleanup
720

169f14d2   Benjamin Renard   Add shared object...
721
		$nameNodes = $timeTableNode->getElementsByTagName('name');
139a8045   Nathanaël Jourdane   autocleanup
722

247b38e9   Benjamin Renard   Fix function used...
723
		if ($nameNodes->length <= 0) {
169f14d2   Benjamin Renard   Add shared object...
724
725
726
			//create name node (normally never append)
			$nameNode = $dom->createElement('name');
			$timeTableNode->appendChild($nameNode);
139a8045   Nathanaël Jourdane   autocleanup
727
		} else {
169f14d2   Benjamin Renard   Add shared object...
728
			$nameNode = $nameNodes->item(0);
139a8045   Nathanaël Jourdane   autocleanup
729
730
		}

169f14d2   Benjamin Renard   Add shared object...
731
		$nameNode->nodeValue = $newName;
139a8045   Nathanaël Jourdane   autocleanup
732

09eefb2d   Benjamin Renard   Shared TT and Cat...
733
734
		if (isset($newDescription) && !empty($newDescription)) {
			$descriptionNodes = $timeTableNode->getElementsByTagName('description');
247b38e9   Benjamin Renard   Fix function used...
735
			if ($descriptionNodes->length <= 0) {
09eefb2d   Benjamin Renard   Shared TT and Cat...
736
737
738
				//create description node (normally never append)
				$descriptionNode = $dom->createElement('description');
				$timeTableNode->appendChild($descriptionNode);
139a8045   Nathanaël Jourdane   autocleanup
739
			} else {
09eefb2d   Benjamin Renard   Shared TT and Cat...
740
				$descriptionNode = $descriptionNodes->item(0);
139a8045   Nathanaël Jourdane   autocleanup
741
742
			}

09eefb2d   Benjamin Renard   Shared TT and Cat...
743
744
			$descriptionNode->nodeValue = $newDescription;
		}
139a8045   Nathanaël Jourdane   autocleanup
745

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
746
747
		$dstFilePath = $dst_path . "/" . $newId . ".xml";
		if ($dom->save($dstFilePath) === false) {
139a8045   Nathanaël Jourdane   autocleanup
748
749
750
			return false;
		}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
751
752
		chgrp($dstFilePath, APACHE_USER);
		chmod($dstFilePath, 0775);
139a8045   Nathanaël Jourdane   autocleanup
753
754
755
756

		return true;
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
757
758
759
760
761
	/**
	 * Rename in resource
	 * @param $name
	 * @param $id
	 * @return bool
139a8045   Nathanaël Jourdane   autocleanup
762
	 */
139a8045   Nathanaël Jourdane   autocleanup
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
	protected function renameInResource($name, $id)
	{
		if (!file_exists(USERTTDIR . $id . '.xml')) {
			return false;
		}

		$this->objectDom->load(USERTTDIR . $id . '.xml');
		if (!($objToRename = $this->objectDom->getElementById($id))) {
			return false;
		}
		$objToRename->getElementsByTagName('name')->item(0)->nodeValue = $name;
		$this->objectDom->save(USERTTDIR . $id . '.xml');

		return true;
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
779
780
781
782
	/**
	 * Delete parameter
	 * @param $id
	 */
139a8045   Nathanaël Jourdane   autocleanup
783
784
785
786
787
788
789
	protected function deleteParameter($id)
	{
		if (file_exists(USERTTDIR . $id . '.xml')) {
			unlink(USERTTDIR . $id . '.xml');
		}
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
790
791
792
793
794
	/**
	 * Rename only
	 * @param $p
	 * @return bool
	 */
139a8045   Nathanaël Jourdane   autocleanup
795
796
797
798
	protected function renameOnly($p)
	{
		//if (!($p->intervals)) return true;
		return false;
3ed056c4   Elena.Budnik   redmine #5278
799
	}
16035364   Benjamin Renard   First commit
800
}