Blame view

php/classes/TimeTableMgr.php 22.9 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");
			}
5535e93a   Erdogan Furkan   Filter(#10688)/So...
151
			return $result;
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
152
		} 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);
		}
5535e93a   Erdogan Furkan   Filter(#10688)/So...
527
528
		$minStart =0;
		$maxStop=0;
139a8045   Nathanaël Jourdane   autocleanup
529

3ed056c4   Elena.Budnik   redmine #5278
530
		//add new intervals
139a8045   Nathanaël Jourdane   autocleanup
531
		foreach ($intervals as $interval) {
5535e93a   Erdogan Furkan   Filter(#10688)/So...
532
533
534
535
536
537
538
539
			$startTime = TimeUtils::iso2stamp($interval['start']);
			$stopTime = TimeUtils::iso2stamp($interval['stop']);
			if ($minStart == 0)
				$minStart = $startTime;
			elseif ($startTime < $minStart )
				$minStart = $startTime;
			if ($stopTime > $maxStop )
			 	$maxStop = $stopTime;
42e2e019   Benjamin Renard   Next step for cac...
540
			$newInterval = $this->createIntervalElement($interval, $options);
3ed056c4   Elena.Budnik   redmine #5278
541
542
			$this->objectDom->documentElement->appendChild($newInterval);
		}
16035364   Benjamin Renard   First commit
543

3ed056c4   Elena.Budnik   redmine #5278
544
545
		//save modifications
		$this->id = $id;
139a8045   Nathanaël Jourdane   autocleanup
546
		$this->resFileName = USERTTDIR . $this->id . '.xml';
3ed056c4   Elena.Budnik   redmine #5278
547
		$this->objectDom->save($this->resFileName);
139a8045   Nathanaël Jourdane   autocleanup
548

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

5535e93a   Erdogan Furkan   Filter(#10688)/So...
551
552
		return ['success' => true, 'action' => $action, 'nbIntervals' => count($intervals), 
				'minStart' => $minStart, 'maxStop' => $maxStop];
3ed056c4   Elena.Budnik   redmine #5278
553
	}
139a8045   Nathanaël Jourdane   autocleanup
554

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

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
588
589
590
591
592
	/**
	 * Intersect time tables
	 * @param $obj
	 * @return array|string
	 */
139a8045   Nathanaël Jourdane   autocleanup
593
594
	public function intersect($obj)
	{
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
595
596
		$intervals = 0;
		for ($iId = 0; $iId < count($obj->ids); $iId++) {
ff9a9bbf   Benjamin Renard   Fix TT operation ...
597
			$table[$iId] = $this->loadIntervalsFromObject($obj->ids[$iId]->id, $obj->ids[$iId]->nodeType);
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
598
599
600
			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
601
			}
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
602
			$intervals += count($interval[$iId]);
16035364   Benjamin Renard   First commit
603
		}
139a8045   Nathanaël Jourdane   autocleanup
604
605
		if ($intervals > 10000) {
			set_time_limit(1800);
16035364   Benjamin Renard   First commit
606
		}
16035364   Benjamin Renard   First commit
607

139a8045   Nathanaël Jourdane   autocleanup
608
609
610
		// Sort intervals in time tables
		sort($interval[0]);
		sort($interval[1]);
16035364   Benjamin Renard   First commit
611

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
612
613
		$iId = 0;
		$jId = 0;
139a8045   Nathanaël Jourdane   autocleanup
614
615
		$line = 0;

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
616
617
		while (($iId < count($interval[0])) && ($jId < count($interval[1]))) {
			$inter = $this->callIntersection($interval[0][$iId], $interval[1][$jId]);
139a8045   Nathanaël Jourdane   autocleanup
618
619
620
621
622
623
624

			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
625
626
			if ($interval[0][$iId][1] < $interval[1][$jId][1]) {
				$iId++;
139a8045   Nathanaël Jourdane   autocleanup
627
			} else {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
628
				$jId++;
139a8045   Nathanaël Jourdane   autocleanup
629
630
631
632
633
634
635
			}
		}

		// Intersection is empty
		if ($line == 0) {
			$result = "empty";
		} else {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
636
			$objTT->name = $obj->name;  // FIXME $objTT is undefined
139a8045   Nathanaël Jourdane   autocleanup
637
638
639
640
			$objTT->nodeType = 'timeTable';
			$objTT->leaf = true;
			$objTT->created = null;
			$objTT->history = $obj->history;
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
641
			for ($iId = 0; $iId < count($start); $iId++) {
a9285c23   Benjamin Renard   Fix TT merge & in...
642
643
644
645
				$inter = array(
					'start' => $start[$iId],
					'stop' => $stop[$iId],
				);
139a8045   Nathanaël Jourdane   autocleanup
646
647
648
649
650
651
652
653
654
				$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
655
				$result = $this->createObject($objTT, $folder); // FIXME $folder is undefined
139a8045   Nathanaël Jourdane   autocleanup
656
657
658

				if (!isset($result['error'])) {
					$this->saveIntervals($result['id'], $objTT->intervals, 'intersect');
3ed056c4   Elena.Budnik   redmine #5278
659
				}
16035364   Benjamin Renard   First commit
660
			}
3ed056c4   Elena.Budnik   redmine #5278
661
		}
139a8045   Nathanaël Jourdane   autocleanup
662
663
664
		return $result;
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
665
666
667
668
669
670
671
	/**
	 * Call intersection
	 * @param $fst
	 * @param $snd
	 * @return array
	 */
	protected function callIntersection($fst, $snd)
139a8045   Nathanaël Jourdane   autocleanup
672
673
674
	{
		$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
675
		$inter[] = ($inf >= $sup) ? [0, 0] : [$inf, $sup];
139a8045   Nathanaël Jourdane   autocleanup
676
		return $inter;
16035364   Benjamin Renard   First commit
677
678
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
679
680
681
682
683
684
685
	/**
	 * Valid name object
	 * TODO getObject only!!!! => change DD_Search output
	 * @param $p
	 * @return array
	 */
	public function validNameObject($p)
139a8045   Nathanaël Jourdane   autocleanup
686
687
688
689
690
691
692
693
694
695
	{
		// overwritten
		$res = parent::validNameObject($p);

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

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

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

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
702
703
704
705
706
707
708
709
710
	/**
	 * Copy time table
	 * @param $src_path
	 * @param $dst_path
	 * @param $newId
	 * @param $newName
	 * @param null $newDescription
	 * @return bool
	 */
139a8045   Nathanaël Jourdane   autocleanup
711
	public function copyTT($src_path, $dst_path, $newId, $newName, $newDescription = null)
3ed056c4   Elena.Budnik   redmine #5278
712
	{
139a8045   Nathanaël Jourdane   autocleanup
713
714
715
716
717
718
719
720
		if (!file_exists($src_path)) {
			return false;
		}

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

169f14d2   Benjamin Renard   Add shared object...
721
722
		$dom = new DomDocument('1.0');
		$dom->formatOutput = true;
139a8045   Nathanaël Jourdane   autocleanup
723
724
725
726
727

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

169f14d2   Benjamin Renard   Add shared object...
728
		$timeTableNodes = $dom->getElementsByTagName('timetable');
139a8045   Nathanaël Jourdane   autocleanup
729
730
731
732
		if ($timeTableNodes->length <= 0) {
			return false;
		}

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

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

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

247b38e9   Benjamin Renard   Fix function used...
739
		if ($nameNodes->length <= 0) {
169f14d2   Benjamin Renard   Add shared object...
740
741
742
			//create name node (normally never append)
			$nameNode = $dom->createElement('name');
			$timeTableNode->appendChild($nameNode);
139a8045   Nathanaël Jourdane   autocleanup
743
		} else {
169f14d2   Benjamin Renard   Add shared object...
744
			$nameNode = $nameNodes->item(0);
139a8045   Nathanaël Jourdane   autocleanup
745
746
		}

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

09eefb2d   Benjamin Renard   Shared TT and Cat...
749
750
		if (isset($newDescription) && !empty($newDescription)) {
			$descriptionNodes = $timeTableNode->getElementsByTagName('description');
247b38e9   Benjamin Renard   Fix function used...
751
			if ($descriptionNodes->length <= 0) {
09eefb2d   Benjamin Renard   Shared TT and Cat...
752
753
754
				//create description node (normally never append)
				$descriptionNode = $dom->createElement('description');
				$timeTableNode->appendChild($descriptionNode);
139a8045   Nathanaël Jourdane   autocleanup
755
			} else {
09eefb2d   Benjamin Renard   Shared TT and Cat...
756
				$descriptionNode = $descriptionNodes->item(0);
139a8045   Nathanaël Jourdane   autocleanup
757
758
			}

d486c5cd   Benjamin Renard   Fix pb with & in ...
759
			$descriptionNode->textContent = $newDescription;
09eefb2d   Benjamin Renard   Shared TT and Cat...
760
		}
139a8045   Nathanaël Jourdane   autocleanup
761

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
762
763
		$dstFilePath = $dst_path . "/" . $newId . ".xml";
		if ($dom->save($dstFilePath) === false) {
139a8045   Nathanaël Jourdane   autocleanup
764
765
766
			return false;
		}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
767
768
		chgrp($dstFilePath, APACHE_USER);
		chmod($dstFilePath, 0775);
139a8045   Nathanaël Jourdane   autocleanup
769
770
771
772

		return true;
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
773
774
775
776
777
	/**
	 * Rename in resource
	 * @param $name
	 * @param $id
	 * @return bool
139a8045   Nathanaël Jourdane   autocleanup
778
	 */
139a8045   Nathanaël Jourdane   autocleanup
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
	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
795
796
797
798
	/**
	 * Delete parameter
	 * @param $id
	 */
139a8045   Nathanaël Jourdane   autocleanup
799
800
801
802
803
804
805
	protected function deleteParameter($id)
	{
		if (file_exists(USERTTDIR . $id . '.xml')) {
			unlink(USERTTDIR . $id . '.xml');
		}
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
806
807
808
809
810
	/**
	 * Rename only
	 * @param $p
	 * @return bool
	 */
139a8045   Nathanaël Jourdane   autocleanup
811
812
813
814
	protected function renameOnly($p)
	{
		//if (!($p->intervals)) return true;
		return false;
3ed056c4   Elena.Budnik   redmine #5278
815
	}
16035364   Benjamin Renard   First commit
816
}