Blame view

php/classes/TimeTableMgr.php 23.5 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
		}
		$attributesToReturn['id'] = $objToGet->getAttribute('xml:id');
		$attributes = $objToGet->childNodes;

		$nbInt = 0;
6a679a7f   Erdogan Furkan   #11478 - Infobulle
77
		$nbParam = 0;
139a8045   Nathanaël Jourdane   autocleanup
78
79
		foreach ($attributes as $attribute) {
			if ($attribute->nodeType == XML_ELEMENT_NODE) {
6a679a7f   Erdogan Furkan   #11478 - Infobulle
80
81
82
83
84
				if($attribute->tagName == 'parameters'){
					foreach($attribute->childNodes as $parameter){
						$nbParam++;
					}
				}
139a8045   Nathanaël Jourdane   autocleanup
85
86
87
88
89
90
91
				/*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...
92
				//BRE - load all except intervals - Intervals will be loaded later with 'loadIntervalsFromObject' function
af94e42d   Benjamin Renard   Fix catalog upload
93
94
95
96
97
98
				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
99
100
					$attributesToReturn[$attribute->tagName] = $attribute->nodeValue;
				} else {
2ff71aba   Hacene SI HADJ MOHAND   correcting survey...
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
					
                                                                                                    // 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
117
118
119
				}
			}
		}
2ff71aba   Hacene SI HADJ MOHAND   correcting survey...
120
121
122
123
                                        if($attributesToReturn['surveyStart'] == "")
                                            $attributesToReturn['surveyStart']  = $start;
                                        if($attributesToReturn['surveyStop'] == "" )
                                            $attributesToReturn['surveyStop'] = $stop;
139a8045   Nathanaël Jourdane   autocleanup
124
		$attributesToReturn['nbIntervals'] = $nbInt;
6a679a7f   Erdogan Furkan   #11478 - Infobulle
125
		$attributesToReturn['nbParam'] = $nbParam;
139a8045   Nathanaël Jourdane   autocleanup
126
127

		return $attributesToReturn;
16035364   Benjamin Renard   First commit
128
129
	}

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

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

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

16035364   Benjamin Renard   First commit
214
		$this->id = $this->setId();
1fe67f2c   Hacene SI HADJ MOHAND   progress
215
		$this->created = date('Y-m-d\TH:i:s.u');
139a8045   Nathanaël Jourdane   autocleanup
216
		if (!$this->id) {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
217
			return ['error' => ID_CREATION_ERROR];
139a8045   Nathanaël Jourdane   autocleanup
218
219
220
		}

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

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

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

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
256
257
258
259
260
	/**
	 * Set parameter description
	 * TODO
	 * @param $param string The parameter
	 * @return DOMNode
139a8045   Nathanaël Jourdane   autocleanup
261
	 */
139a8045   Nathanaël Jourdane   autocleanup
262
	protected function setParamDescription($param)
4a438b99   elena   catalog draft
263
	{
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
264
		return new DOMNode();
4a438b99   elena   catalog draft
265
	}
139a8045   Nathanaël Jourdane   autocleanup
266

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
267
	/**
53048303   Benjamin Renard   Cleanup TimeTable...
268
	 * Load TT content from dom documentElement
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
269
	 */
53048303   Benjamin Renard   Cleanup TimeTable...
270
271
	 protected function loadObjectFile($dom, $onlyDescription, $start = null, $limit = null) {
		$attributesToReturn = array();
16035364   Benjamin Renard   First commit
272

139a8045   Nathanaël Jourdane   autocleanup
273
274
275
276
		$descNodes = $dom->getElementsByTagName('description');
		if ($descNodes->length > 0) {
			$attributesToReturn['description'] = $descNodes->item(0)->nodeValue;
		}
16035364   Benjamin Renard   First commit
277

139a8045   Nathanaël Jourdane   autocleanup
278
279
280
281
282
283
284
285
286
287
		$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...
288
289
290
291
		$nameNodes = $dom->getElementsByTagName('name');
		if ($nameNodes->length > 0) {
			$attributesToReturn['name'] = $nameNodes->item(0)->nodeValue;
		}
139a8045   Nathanaël Jourdane   autocleanup
292
293

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

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

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

53048303   Benjamin Renard   Cleanup TimeTable...
300
301
302
			if (!isset($start) || !isset($limit)) {
				foreach ($intervals as $interval) {
					$attributesToReturn['intervals'][] = $this->loadIntervalElement($interval);
139a8045   Nathanaël Jourdane   autocleanup
303
				}
53048303   Benjamin Renard   Cleanup TimeTable...
304
305
306
307
308
309
			} 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
310
				}
16035364   Benjamin Renard   First commit
311
			}
16035364   Benjamin Renard   First commit
312
		}
139a8045   Nathanaël Jourdane   autocleanup
313
314

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

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

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
404
405
406
		$final = [];
		for ($iId = 0; $iId < count($obj->ids); $iId++) {
			$final = array_merge($final, $interval[$iId]);
139a8045   Nathanaël Jourdane   autocleanup
407
408
409
410
411
		}
		sort($final);

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

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

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
449
		$res = $this->createParameter($objTT, $folder); // FIXME $folder is undefined
139a8045   Nathanaël Jourdane   autocleanup
450
451
452
453
454
		if ($res['error']) {
			return $res;
		}

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

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

 		//load intervals from TT id
 		if (!file_exists($path)) {
d54a1a7b   Benjamin Renard   Fix load from sha...
479
 			return ['success' => false, 'message' => "Cannot find TT file " . $id ];
53048303   Benjamin Renard   Cleanup TimeTable...
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
 		}

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

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

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

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

3ed056c4   Elena.Budnik   redmine #5278
524
		while ($crtNode) {
139a8045   Nathanaël Jourdane   autocleanup
525
			if (($crtNode->nodeType != XML_ELEMENT_NODE) || ($crtNode->tagName != 'intervals')) {
3ed056c4   Elena.Budnik   redmine #5278
526
527
528
529
530
531
532
533
				$crtNode = $crtNode->nextSibling;
				continue;
			}
			$toRemove = $crtNode;
			$crtNode = $crtNode->nextSibling;
			$objToGet->removeChild($toRemove);
			unset($toRemove);
		}
5535e93a   Erdogan Furkan   Filter(#10688)/So...
534
535
		$minStart =0;
		$maxStop=0;
139a8045   Nathanaël Jourdane   autocleanup
536

3ed056c4   Elena.Budnik   redmine #5278
537
		//add new intervals
139a8045   Nathanaël Jourdane   autocleanup
538
		foreach ($intervals as $interval) {
5535e93a   Erdogan Furkan   Filter(#10688)/So...
539
540
541
542
543
544
545
546
			$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...
547
			$newInterval = $this->createIntervalElement($interval, $options);
3ed056c4   Elena.Budnik   redmine #5278
548
549
			$this->objectDom->documentElement->appendChild($newInterval);
		}
16035364   Benjamin Renard   First commit
550

1d3f12bb   Erdogan Furkan   #11583 - Done
551
552
553
554
555
556
557
558
		// Update SurveyStart & SurveyStop
		$surveyStartNodes = $objToGet->getElementsByTagName('surveyStart');
		$surveyStopNodes = $objToGet->getElementsByTagName('surveyStop');
		if ($surveyStartNodes->length > 0 && $surveyStopNodes->length > 0) {
			$surveyStartNodes->item(0)->nodeValue = TimeUtils::stamp2iso($minStart);
			$surveyStopNodes->item(0)->nodeValue = TimeUtils::stamp2iso($maxStop);
		}

3ed056c4   Elena.Budnik   redmine #5278
559
560
		//save modifications
		$this->id = $id;
139a8045   Nathanaël Jourdane   autocleanup
561
		$this->resFileName = USERTTDIR . $this->id . '.xml';
3ed056c4   Elena.Budnik   redmine #5278
562
		$this->objectDom->save($this->resFileName);
139a8045   Nathanaël Jourdane   autocleanup
563

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

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

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
570
	/**
53048303   Benjamin Renard   Cleanup TimeTable...
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
	 * 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
591
592
593
594
	 * Create interval element
	 * @param $interval
	 * @return DOMElement
	 */
42e2e019   Benjamin Renard   Next step for cac...
595
	protected function createIntervalElement($interval, $options = array())
3ed056c4   Elena.Budnik   redmine #5278
596
	{
139a8045   Nathanaël Jourdane   autocleanup
597
		$newInterval = $this->objectDom->createElement('intervals');
42e2e019   Benjamin Renard   Next step for cac...
598
599
		$newInterval->appendChild($this->objectDom->createElement('start', $interval['start']));
		$newInterval->appendChild($this->objectDom->createElement('stop', $interval['stop']));
139a8045   Nathanaël Jourdane   autocleanup
600
601
602
		return $newInterval;
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
603
604
605
606
607
	/**
	 * Intersect time tables
	 * @param $obj
	 * @return array|string
	 */
139a8045   Nathanaël Jourdane   autocleanup
608
609
	public function intersect($obj)
	{
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
610
611
		$intervals = 0;
		for ($iId = 0; $iId < count($obj->ids); $iId++) {
ff9a9bbf   Benjamin Renard   Fix TT operation ...
612
			$table[$iId] = $this->loadIntervalsFromObject($obj->ids[$iId]->id, $obj->ids[$iId]->nodeType);
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
613
614
615
			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
616
			}
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
617
			$intervals += count($interval[$iId]);
16035364   Benjamin Renard   First commit
618
		}
139a8045   Nathanaël Jourdane   autocleanup
619
620
		if ($intervals > 10000) {
			set_time_limit(1800);
16035364   Benjamin Renard   First commit
621
		}
16035364   Benjamin Renard   First commit
622

139a8045   Nathanaël Jourdane   autocleanup
623
624
625
		// Sort intervals in time tables
		sort($interval[0]);
		sort($interval[1]);
16035364   Benjamin Renard   First commit
626

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
627
628
		$iId = 0;
		$jId = 0;
139a8045   Nathanaël Jourdane   autocleanup
629
630
		$line = 0;

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
631
632
		while (($iId < count($interval[0])) && ($jId < count($interval[1]))) {
			$inter = $this->callIntersection($interval[0][$iId], $interval[1][$jId]);
139a8045   Nathanaël Jourdane   autocleanup
633
634
635
636
637
638
639

			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
640
641
			if ($interval[0][$iId][1] < $interval[1][$jId][1]) {
				$iId++;
139a8045   Nathanaël Jourdane   autocleanup
642
			} else {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
643
				$jId++;
139a8045   Nathanaël Jourdane   autocleanup
644
645
646
647
648
649
650
			}
		}

		// Intersection is empty
		if ($line == 0) {
			$result = "empty";
		} else {
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
651
			$objTT->name = $obj->name;  // FIXME $objTT is undefined
139a8045   Nathanaël Jourdane   autocleanup
652
653
654
655
			$objTT->nodeType = 'timeTable';
			$objTT->leaf = true;
			$objTT->created = null;
			$objTT->history = $obj->history;
d8ec1623   Nathanaël Jourdane   fix phpcs warnings
656
			for ($iId = 0; $iId < count($start); $iId++) {
a9285c23   Benjamin Renard   Fix TT merge & in...
657
658
659
660
				$inter = array(
					'start' => $start[$iId],
					'stop' => $stop[$iId],
				);
139a8045   Nathanaël Jourdane   autocleanup
661
662
663
664
665
666
667
668
669
				$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
670
				$result = $this->createObject($objTT, $folder); // FIXME $folder is undefined
139a8045   Nathanaël Jourdane   autocleanup
671
672
673

				if (!isset($result['error'])) {
					$this->saveIntervals($result['id'], $objTT->intervals, 'intersect');
3ed056c4   Elena.Budnik   redmine #5278
674
				}
16035364   Benjamin Renard   First commit
675
			}
3ed056c4   Elena.Budnik   redmine #5278
676
		}
139a8045   Nathanaël Jourdane   autocleanup
677
678
679
		return $result;
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
680
681
682
683
684
685
686
	/**
	 * Call intersection
	 * @param $fst
	 * @param $snd
	 * @return array
	 */
	protected function callIntersection($fst, $snd)
139a8045   Nathanaël Jourdane   autocleanup
687
688
689
	{
		$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
690
		$inter[] = ($inf >= $sup) ? [0, 0] : [$inf, $sup];
139a8045   Nathanaël Jourdane   autocleanup
691
		return $inter;
16035364   Benjamin Renard   First commit
692
693
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
694
695
696
697
698
699
700
	/**
	 * Valid name object
	 * TODO getObject only!!!! => change DD_Search output
	 * @param $p
	 * @return array
	 */
	public function validNameObject($p)
139a8045   Nathanaël Jourdane   autocleanup
701
702
703
704
705
706
707
708
709
710
	{
		// overwritten
		$res = parent::validNameObject($p);

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

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

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

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
717
718
719
720
721
722
723
724
725
	/**
	 * Copy time table
	 * @param $src_path
	 * @param $dst_path
	 * @param $newId
	 * @param $newName
	 * @param null $newDescription
	 * @return bool
	 */
139a8045   Nathanaël Jourdane   autocleanup
726
	public function copyTT($src_path, $dst_path, $newId, $newName, $newDescription = null)
3ed056c4   Elena.Budnik   redmine #5278
727
	{
139a8045   Nathanaël Jourdane   autocleanup
728
729
730
731
732
733
734
735
		if (!file_exists($src_path)) {
			return false;
		}

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

169f14d2   Benjamin Renard   Add shared object...
736
737
		$dom = new DomDocument('1.0');
		$dom->formatOutput = true;
139a8045   Nathanaël Jourdane   autocleanup
738
739
740
741
742

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

169f14d2   Benjamin Renard   Add shared object...
743
		$timeTableNodes = $dom->getElementsByTagName('timetable');
139a8045   Nathanaël Jourdane   autocleanup
744
745
746
747
		if ($timeTableNodes->length <= 0) {
			return false;
		}

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

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

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

247b38e9   Benjamin Renard   Fix function used...
754
		if ($nameNodes->length <= 0) {
169f14d2   Benjamin Renard   Add shared object...
755
756
757
			//create name node (normally never append)
			$nameNode = $dom->createElement('name');
			$timeTableNode->appendChild($nameNode);
139a8045   Nathanaël Jourdane   autocleanup
758
		} else {
169f14d2   Benjamin Renard   Add shared object...
759
			$nameNode = $nameNodes->item(0);
139a8045   Nathanaël Jourdane   autocleanup
760
761
		}

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

09eefb2d   Benjamin Renard   Shared TT and Cat...
764
765
		if (isset($newDescription) && !empty($newDescription)) {
			$descriptionNodes = $timeTableNode->getElementsByTagName('description');
247b38e9   Benjamin Renard   Fix function used...
766
			if ($descriptionNodes->length <= 0) {
09eefb2d   Benjamin Renard   Shared TT and Cat...
767
768
769
				//create description node (normally never append)
				$descriptionNode = $dom->createElement('description');
				$timeTableNode->appendChild($descriptionNode);
139a8045   Nathanaël Jourdane   autocleanup
770
			} else {
09eefb2d   Benjamin Renard   Shared TT and Cat...
771
				$descriptionNode = $descriptionNodes->item(0);
139a8045   Nathanaël Jourdane   autocleanup
772
773
			}

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

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
777
778
		$dstFilePath = $dst_path . "/" . $newId . ".xml";
		if ($dom->save($dstFilePath) === false) {
139a8045   Nathanaël Jourdane   autocleanup
779
780
781
			return false;
		}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
782
783
		chgrp($dstFilePath, APACHE_USER);
		chmod($dstFilePath, 0775);
139a8045   Nathanaël Jourdane   autocleanup
784
785
786
787

		return true;
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
788
789
790
791
792
	/**
	 * Rename in resource
	 * @param $name
	 * @param $id
	 * @return bool
139a8045   Nathanaël Jourdane   autocleanup
793
	 */
139a8045   Nathanaël Jourdane   autocleanup
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
	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
810
811
812
813
	/**
	 * Delete parameter
	 * @param $id
	 */
139a8045   Nathanaël Jourdane   autocleanup
814
815
816
817
818
819
820
	protected function deleteParameter($id)
	{
		if (file_exists(USERTTDIR . $id . '.xml')) {
			unlink(USERTTDIR . $id . '.xml');
		}
	}

d8ec1623   Nathanaël Jourdane   fix phpcs warnings
821
822
823
824
825
	/**
	 * Rename only
	 * @param $p
	 * @return bool
	 */
139a8045   Nathanaël Jourdane   autocleanup
826
827
828
829
	protected function renameOnly($p)
	{
		//if (!($p->intervals)) return true;
		return false;
3ed056c4   Elena.Budnik   redmine #5278
830
	}
16035364   Benjamin Renard   First commit
831
}