Blame view

php/classes/TimeTableMgr.php 22.6 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
af94e42d   Benjamin Renard   Fix catalog upload
87
88
89
90
91
92
				if ($attribute->tagName == 'parameters'  && method_exists($this,'getCatalogParamDescription')) {
					$parameters_desc = $this->getCatalogParamDescription(array('id' => $id, 'type' => $nodeType));
					if ($parameters_desc['success'])
						$attributesToReturn[$attribute->tagName] = $parameters_desc['parameters'];
				}
				else if ($attribute->tagName != 'intervals') {
139a8045   Nathanaël Jourdane   autocleanup
93
94
					$attributesToReturn[$attribute->tagName] = $attribute->nodeValue;
				} else {
2ff71aba   Hacene SI HADJ MOHAND   correcting survey...
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
					
                                                                                                    // 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
111
112
113
				}
			}
		}
2ff71aba   Hacene SI HADJ MOHAND   correcting survey...
114
115
116
117
                                        if($attributesToReturn['surveyStart'] == "")
                                            $attributesToReturn['surveyStart']  = $start;
                                        if($attributesToReturn['surveyStop'] == "" )
                                            $attributesToReturn['surveyStop'] = $stop;
139a8045   Nathanaël Jourdane   autocleanup
118
119
120
		$attributesToReturn['nbIntervals'] = $nbInt;

		return $attributesToReturn;
16035364   Benjamin Renard   First commit
121
122
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
123
124
125
126
127
	/**
	 * Modify an object
	 * @param $p
	 * @return array
	 */
139a8045   Nathanaël Jourdane   autocleanup
128
	public function modifyObject($p)
4a438b99   elena   catalog draft
129
	{
139a8045   Nathanaël Jourdane   autocleanup
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
		$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
151
152
			return ['id' => $p->id, 'info' => $result['info']];
		} catch (Exception $exception) {
139a8045   Nathanaël Jourdane   autocleanup
153
154
155
156
157
			//Restore TT file
			if ($tmpFileExist) {
				copy($ttFilePath . ".tmp", $ttFilePath);
				unlink($ttFilePath . ".tmp");
			}
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
158
			return ['error' => $exception->getMessage()];
139a8045   Nathanaël Jourdane   autocleanup
159
		}
16035364   Benjamin Renard   First commit
160
161
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
162
163
164
165
166
167
	/**
	 * Create an object
	 * @param $p
	 * @param $folder
	 * @return array
	 */
139a8045   Nathanaël Jourdane   autocleanup
168
169
170
171
172
173
174
175
176
	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...
177
				$resultSaveInt = $cacheMgr->saveInObject($result['id'], "update", $p->cacheToken);
139a8045   Nathanaël Jourdane   autocleanup
178
179
				if (!$resultSaveInt['success']) {
					if ($resultSaveInt['message']) {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
180
						return ['error' => $resultSaveInt['message']];
139a8045   Nathanaël Jourdane   autocleanup
181
					} else {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
182
						return ['error' => 'Unknown error during intervals save'];
139a8045   Nathanaël Jourdane   autocleanup
183
184
185
186
					}
				}
			}
			return $result;
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
187
188
189
190
		} else {
			return ['error' => 'createFolder should be called from RENAME'];
			// return $this->createFolder($p);
			// TODO check if this is possible?
139a8045   Nathanaël Jourdane   autocleanup
191
		}
16035364   Benjamin Renard   First commit
192
	}
16035364   Benjamin Renard   First commit
193

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

16035364   Benjamin Renard   First commit
207
		$this->id = $this->setId();
1fe67f2c   Hacene SI HADJ MOHAND   progress
208
		$this->created = date('Y-m-d\TH:i:s.u');
139a8045   Nathanaël Jourdane   autocleanup
209
		if (!$this->id) {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
210
			return ['error' => ID_CREATION_ERROR];
139a8045   Nathanaël Jourdane   autocleanup
211
212
213
		}

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

		foreach ($p as $key => $value) {
3ed056c4   Elena.Budnik   redmine #5278
219
220
			if ($key != 'id' && $key != 'leaf' && $key != 'nodeType' &&
				$key != 'objName' && $key != 'objFormat' && $key != 'folderId' && $key != 'cacheToken') {
139a8045   Nathanaël Jourdane   autocleanup
221
222
223
224
225
226
227
228
229
				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
230
231
232
233
					} else {
						if ($key != 'intervals') {
							$rootElement->appendChild($this->objectDom->createElement($key, htmlspecialchars($value)));
						}
3ed056c4   Elena.Budnik   redmine #5278
234
					}
139a8045   Nathanaël Jourdane   autocleanup
235
				}
d18b535d   elena   catalog draft + c...
236
			}
139a8045   Nathanaël Jourdane   autocleanup
237
		}
16035364   Benjamin Renard   First commit
238
239
240
241
242
243

		$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
244
		$this->addToContent($obj, $folder);
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
245
246
		// FIXME field created is undefined
		return ['id' => $this->id, 'created' => $this->created, 'info' => $obj->intervals . ' intervals'];
16035364   Benjamin Renard   First commit
247
248
	}

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

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

139a8045   Nathanaël Jourdane   autocleanup
266
267
268
269
		$descNodes = $dom->getElementsByTagName('description');
		if ($descNodes->length > 0) {
			$attributesToReturn['description'] = $descNodes->item(0)->nodeValue;
		}
16035364   Benjamin Renard   First commit
270

139a8045   Nathanaël Jourdane   autocleanup
271
272
273
274
275
276
277
278
279
280
		$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...
281
282
283
284
		$nameNodes = $dom->getElementsByTagName('name');
		if ($nameNodes->length > 0) {
			$attributesToReturn['name'] = $nameNodes->item(0)->nodeValue;
		}
139a8045   Nathanaël Jourdane   autocleanup
285
286

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

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

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

53048303   Benjamin Renard   Cleanup TimeTable...
293
294
295
			if (!isset($start) || !isset($limit)) {
				foreach ($intervals as $interval) {
					$attributesToReturn['intervals'][] = $this->loadIntervalElement($interval);
139a8045   Nathanaël Jourdane   autocleanup
296
				}
53048303   Benjamin Renard   Cleanup TimeTable...
297
298
299
300
301
302
			} 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
303
				}
16035364   Benjamin Renard   First commit
304
			}
16035364   Benjamin Renard   First commit
305
		}
139a8045   Nathanaël Jourdane   autocleanup
306
307

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

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
310
	/**
53048303   Benjamin Renard   Cleanup TimeTable...
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
367
368
369
370
371
	 * 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
372
373
374
375
	 * Merge time tables
	 * @param $obj
	 * @return array
	 */
139a8045   Nathanaël Jourdane   autocleanup
376
377
378
379
380
381
382
383
384
	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
385
		for ($iId = 0; $iId < count($obj->ids); $iId++) {
ff9a9bbf   Benjamin Renard   Fix TT operation ...
386
			$table[$iId] = $this->loadIntervalsFromObject($obj->ids[$iId]->id, $obj->ids[$iId]->nodeType);
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
387
388
389
			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
390
			}
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
391
			$intervals += count($interval[$iId]);
16035364   Benjamin Renard   First commit
392
		}
139a8045   Nathanaël Jourdane   autocleanup
393
394
395
396
		if ($intervals > 10000) {
			set_time_limit(1800);
		}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
397
398
399
		$final = [];
		for ($iId = 0; $iId < count($obj->ids); $iId++) {
			$final = array_merge($final, $interval[$iId]);
139a8045   Nathanaël Jourdane   autocleanup
400
401
402
403
404
		}
		sort($final);

		// Algorithm of union
		$line = 0;
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
405
406
407
408
409
		$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
410
			} else {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
411
412
				if (($final[$iId + 1][0] <= $final[$iId][1]) && ($final[$iId + 1][1] >= $final[$iId][1])) {
					$iId++;
139a8045   Nathanaël Jourdane   autocleanup
413
				} else {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
414
415
416
					$start[$line] = $val;
					$stop[$line] = $final[$iId][1];
					$iId++;
139a8045   Nathanaël Jourdane   autocleanup
417
					$line++;
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
418
					$val = $final[$iId][0];
139a8045   Nathanaël Jourdane   autocleanup
419
				}
16035364   Benjamin Renard   First commit
420
			}
16035364   Benjamin Renard   First commit
421
		}
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
422
423
		$start[$line] = $val;
		$stop[$line] = $final[$iId][1];
139a8045   Nathanaël Jourdane   autocleanup
424
425
426
427
428
429
430

		$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
431
		for ($iId = 0; $iId < count($start); $iId++) {
a9285c23   Benjamin Renard   Fix TT merge & in...
432
433
434
435
			$inter = array(
				'start' => $start[$iId],
				'stop' => $stop[$iId],
			);
139a8045   Nathanaël Jourdane   autocleanup
436
437
438
439
440
441
			$objTT->intervals[] = $inter;
		}
		$objTT->nbIntervals = count($start);
		$this->objectDom = new DomDocument('1.0');
		$this->objectDom->formatOutput = true;

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
442
		$res = $this->createParameter($objTT, $folder); // FIXME $folder is undefined
139a8045   Nathanaël Jourdane   autocleanup
443
444
445
446
447
		if ($res['error']) {
			return $res;
		}

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

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

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

 		$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
490

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

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

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

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

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

3ed056c4   Elena.Budnik   redmine #5278
534
535
		//save modifications
		$this->id = $id;
139a8045   Nathanaël Jourdane   autocleanup
536
		$this->resFileName = USERTTDIR . $this->id . '.xml';
3ed056c4   Elena.Budnik   redmine #5278
537
		$this->objectDom->save($this->resFileName);
139a8045   Nathanaël Jourdane   autocleanup
538

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

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

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
544
	/**
53048303   Benjamin Renard   Cleanup TimeTable...
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
	 * 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
565
566
567
568
	 * Create interval element
	 * @param $interval
	 * @return DOMElement
	 */
42e2e019   Benjamin Renard   Next step for cac...
569
	protected function createIntervalElement($interval, $options = array())
3ed056c4   Elena.Budnik   redmine #5278
570
	{
139a8045   Nathanaël Jourdane   autocleanup
571
		$newInterval = $this->objectDom->createElement('intervals');
42e2e019   Benjamin Renard   Next step for cac...
572
573
		$newInterval->appendChild($this->objectDom->createElement('start', $interval['start']));
		$newInterval->appendChild($this->objectDom->createElement('stop', $interval['stop']));
139a8045   Nathanaël Jourdane   autocleanup
574
575
576
		return $newInterval;
	}

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

139a8045   Nathanaël Jourdane   autocleanup
597
598
599
		// Sort intervals in time tables
		sort($interval[0]);
		sort($interval[1]);
16035364   Benjamin Renard   First commit
600

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
601
602
		$iId = 0;
		$jId = 0;
139a8045   Nathanaël Jourdane   autocleanup
603
604
		$line = 0;

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
605
606
		while (($iId < count($interval[0])) && ($jId < count($interval[1]))) {
			$inter = $this->callIntersection($interval[0][$iId], $interval[1][$jId]);
139a8045   Nathanaël Jourdane   autocleanup
607
608
609
610
611
612
613

			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
614
615
			if ($interval[0][$iId][1] < $interval[1][$jId][1]) {
				$iId++;
139a8045   Nathanaël Jourdane   autocleanup
616
			} else {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
617
				$jId++;
139a8045   Nathanaël Jourdane   autocleanup
618
619
620
621
622
623
624
			}
		}

		// Intersection is empty
		if ($line == 0) {
			$result = "empty";
		} else {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
625
			$objTT->name = $obj->name;  // FIXME $objTT is undefined
139a8045   Nathanaël Jourdane   autocleanup
626
627
628
629
			$objTT->nodeType = 'timeTable';
			$objTT->leaf = true;
			$objTT->created = null;
			$objTT->history = $obj->history;
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
630
			for ($iId = 0; $iId < count($start); $iId++) {
a9285c23   Benjamin Renard   Fix TT merge & in...
631
632
633
634
				$inter = array(
					'start' => $start[$iId],
					'stop' => $stop[$iId],
				);
139a8045   Nathanaël Jourdane   autocleanup
635
636
637
638
639
640
641
642
643
				$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
644
				$result = $this->createObject($objTT, $folder); // FIXME $folder is undefined
139a8045   Nathanaël Jourdane   autocleanup
645
646
647

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

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
654
655
656
657
658
659
660
	/**
	 * Call intersection
	 * @param $fst
	 * @param $snd
	 * @return array
	 */
	protected function callIntersection($fst, $snd)
139a8045   Nathanaël Jourdane   autocleanup
661
662
663
	{
		$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
664
		$inter[] = ($inf >= $sup) ? [0, 0] : [$inf, $sup];
139a8045   Nathanaël Jourdane   autocleanup
665
		return $inter;
16035364   Benjamin Renard   First commit
666
667
	}

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

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

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

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

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

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

169f14d2   Benjamin Renard   Add shared object...
710
711
		$dom = new DomDocument('1.0');
		$dom->formatOutput = true;
139a8045   Nathanaël Jourdane   autocleanup
712
713
714
715
716

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

169f14d2   Benjamin Renard   Add shared object...
717
		$timeTableNodes = $dom->getElementsByTagName('timetable');
139a8045   Nathanaël Jourdane   autocleanup
718
719
720
721
		if ($timeTableNodes->length <= 0) {
			return false;
		}

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

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

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

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

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

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

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

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
751
752
		$dstFilePath = $dst_path . "/" . $newId . ".xml";
		if ($dom->save($dstFilePath) === false) {
139a8045   Nathanaël Jourdane   autocleanup
753
754
755
			return false;
		}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
756
757
		chgrp($dstFilePath, APACHE_USER);
		chmod($dstFilePath, 0775);
139a8045   Nathanaël Jourdane   autocleanup
758
759
760
761

		return true;
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
762
763
764
765
766
	/**
	 * Rename in resource
	 * @param $name
	 * @param $id
	 * @return bool
139a8045   Nathanaël Jourdane   autocleanup
767
	 */
139a8045   Nathanaël Jourdane   autocleanup
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
	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
784
785
786
787
	/**
	 * Delete parameter
	 * @param $id
	 */
139a8045   Nathanaël Jourdane   autocleanup
788
789
790
791
792
793
794
	protected function deleteParameter($id)
	{
		if (file_exists(USERTTDIR . $id . '.xml')) {
			unlink(USERTTDIR . $id . '.xml');
		}
	}

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