GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

NestedSetBehavior::moveNode()   F
last analyzed

Complexity

Conditions 20
Paths 422

Size

Total Lines 117

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 420

Importance

Changes 0
Metric Value
cc 20
nc 422
nop 3
dl 0
loc 117
rs 0.6422
c 0
b 0
f 0
ccs 0
cts 77
cp 0
crap 420

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * NestedSetBehavior class file.
4
 *
5
 * @author Alexander Kochetov <[email protected]>
6
 * @link https://github.com/yiiext/nested-set-behavior
7
 */
8
9
/**
10
 * Provides nested set functionality for a model.
11
 *
12
 * @version 1.06
13
 * @package yiiext.behaviors.model.trees
14
 */
15
class NestedSetBehavior extends CActiveRecordBehavior
16
{
17
	public $hasManyRoots=false;
18
	public $rootAttribute='root';
19
	public $leftAttribute='lft';
20
	public $rightAttribute='rgt';
21
	public $levelAttribute='level';
22
	private $_ignoreEvent=false;
23
	private $_deleted=false;
24
	private $_id;
25
	private static $_cached;
26
	private static $_c=0;
27
28
	/**
29
	 * Named scope. Gets descendants for node.
30
	 * @param int $depth the depth.
31
	 * @return CActiveRecord the owner.
32
	 */
33 3 View Code Duplication
	public function descendants($depth=null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
34
	{
35 3
		$owner=$this->getOwner();
36 3
		$db=$owner->getDbConnection();
37 3
		$criteria=$owner->getDbCriteria();
38 3
		$alias=$db->quoteColumnName($owner->getTableAlias());
39
40 3
		$criteria->mergeWith(array(
41 3
			'condition'=>$alias.'.'.$db->quoteColumnName($this->leftAttribute).'>'.$owner->{$this->leftAttribute}.
42 3
				' AND '.$alias.'.'.$db->quoteColumnName($this->rightAttribute).'<'.$owner->{$this->rightAttribute},
43 3
			'order'=>$alias.'.'.$db->quoteColumnName($this->leftAttribute),
44 3
		));
45
46 3
		if($depth!==null)
47 3
			$criteria->addCondition($alias.'.'.$db->quoteColumnName($this->levelAttribute).'<='.($owner->{$this->levelAttribute}+$depth));
48
49 3
		if($this->hasManyRoots)
50 3
		{
51
			$criteria->addCondition($alias.'.'.$db->quoteColumnName($this->rootAttribute).'='.CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount);
52
			$criteria->params[CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount++]=$owner->{$this->rootAttribute};
53
		}
54
55 3
		return $owner;
56
	}
57
58
	/**
59
	 * Named scope. Gets children for node (direct descendants only).
60
	 * @return CActiveRecord the owner.
61
	 */
62 1
	public function children()
63
	{
64 1
		return $this->descendants(1);
65
	}
66
67
	/**
68
	 * Named scope. Gets ancestors for node.
69
	 * @param int $depth the depth.
70
	 * @return CActiveRecord the owner.
71
	 */
72 View Code Duplication
	public function ancestors($depth=null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
73
	{
74
		$owner=$this->getOwner();
75
		$db=$owner->getDbConnection();
76
		$criteria=$owner->getDbCriteria();
77
		$alias=$db->quoteColumnName($owner->getTableAlias());
78
79
		$criteria->mergeWith(array(
80
			'condition'=>$alias.'.'.$db->quoteColumnName($this->leftAttribute).'<'.$owner->{$this->leftAttribute}.
81
				' AND '.$alias.'.'.$db->quoteColumnName($this->rightAttribute).'>'.$owner->{$this->rightAttribute},
82
			'order'=>$alias.'.'.$db->quoteColumnName($this->leftAttribute),
83
		));
84
85
		if($depth!==null)
86
			$criteria->addCondition($alias.'.'.$db->quoteColumnName($this->levelAttribute).'>='.($owner->{$this->levelAttribute}-$depth));
87
88
		if($this->hasManyRoots)
89
		{
90
			$criteria->addCondition($alias.'.'.$db->quoteColumnName($this->rootAttribute).'='.CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount);
91
			$criteria->params[CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount++]=$owner->{$this->rootAttribute};
92
		}
93
94
		return $owner;
95
	}
96
97
	/**
98
	 * Named scope. Gets root node(s).
99
	 * @return CActiveRecord the owner.
100
	 */
101
	public function roots()
102
	{
103
		$owner=$this->getOwner();
104
		$db=$owner->getDbConnection();
105
		$owner->getDbCriteria()->addCondition($db->quoteColumnName($owner->getTableAlias()).'.'.$db->quoteColumnName($this->leftAttribute).'=1');
106
107
		return $owner;
108
	}
109
110
	/**
111
	 * Named scope. Gets parent of node.
112
	 * @return CActiveRecord the owner.
113
	 */
114 1
	public function parent()
115
	{
116 1
		$owner=$this->getOwner();
117 1
		$db=$owner->getDbConnection();
118 1
		$criteria=$owner->getDbCriteria();
119 1
		$alias=$db->quoteColumnName($owner->getTableAlias());
120
121 1
		$criteria->mergeWith(array(
122 1
			'condition'=>$alias.'.'.$db->quoteColumnName($this->leftAttribute).'<'.$owner->{$this->leftAttribute}.
123 1
				' AND '.$alias.'.'.$db->quoteColumnName($this->rightAttribute).'>'.$owner->{$this->rightAttribute},
124 1
			'order'=>$alias.'.'.$db->quoteColumnName($this->rightAttribute),
125 1
		));
126
127 1
		if($this->hasManyRoots)
128 1
		{
129
			$criteria->addCondition($alias.'.'.$db->quoteColumnName($this->rootAttribute).'='.CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount);
130
			$criteria->params[CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount++]=$owner->{$this->rootAttribute};
131
		}
132
133 1
		return $owner;
134
	}
135
136
	/**
137
	 * Named scope. Gets previous sibling of node.
138
	 * @return CActiveRecord the owner.
139
	 */
140 View Code Duplication
	public function prev()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
141
	{
142
		$owner=$this->getOwner();
143
		$db=$owner->getDbConnection();
144
		$criteria=$owner->getDbCriteria();
145
		$alias=$db->quoteColumnName($owner->getTableAlias());
146
		$criteria->addCondition($alias.'.'.$db->quoteColumnName($this->rightAttribute).'='.($owner->{$this->leftAttribute}-1));
147
148
		if($this->hasManyRoots)
149
		{
150
			$criteria->addCondition($alias.'.'.$db->quoteColumnName($this->rootAttribute).'='.CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount);
151
			$criteria->params[CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount++]=$owner->{$this->rootAttribute};
152
		}
153
154
		return $owner;
155
	}
156
157
	/**
158
	 * Named scope. Gets next sibling of node.
159
	 * @return CActiveRecord the owner.
160
	 */
161 View Code Duplication
	public function next()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
162
	{
163
		$owner=$this->getOwner();
164
		$db=$owner->getDbConnection();
165
		$criteria=$owner->getDbCriteria();
166
		$alias=$db->quoteColumnName($owner->getTableAlias());
167
		$criteria->addCondition($alias.'.'.$db->quoteColumnName($this->leftAttribute).'='.($owner->{$this->rightAttribute}+1));
168
169
		if($this->hasManyRoots)
170
		{
171
			$criteria->addCondition($alias.'.'.$db->quoteColumnName($this->rootAttribute).'='.CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount);
172
			$criteria->params[CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount++]=$owner->{$this->rootAttribute};
173
		}
174
175
		return $owner;
176
	}
177
178
	/**
179
	 * Create root node if multiple-root tree mode. Update node if it's not new.
180
	 * @param boolean $runValidation whether to perform validation.
181
	 * @param boolean $attributes list of attributes.
182
	 * @return boolean whether the saving succeeds.
183
	 */
184
	public function save($runValidation=true,$attributes=null)
185
	{
186
		$owner=$this->getOwner();
187
188
		if($runValidation && !$owner->validate($attributes))
189
			return false;
190
191
		if($owner->getIsNewRecord())
192
			return $this->makeRoot($attributes);
193
194
		$this->_ignoreEvent=true;
195
		$result=$owner->update($attributes);
196
		$this->_ignoreEvent=false;
197
198
		return $result;
199
	}
200
201
	/**
202
	 * Create root node if multiple-root tree mode. Update node if it's not new.
203
	 * @param boolean $runValidation whether to perform validation.
204
	 * @param boolean $attributes list of attributes.
205
	 * @return boolean whether the saving succeeds.
206
	 */
207
	public function saveNode($runValidation=true,$attributes=null)
208
	{
209
		return $this->save($runValidation,$attributes);
210
	}
211
212
	/**
213
	 * Deletes node and it's descendants.
214
	 * @return boolean whether the deletion is successful.
215
	 */
216 2
	public function delete()
217
	{
218 2
		$owner=$this->getOwner();
219
220 2
		if($owner->getIsNewRecord())
221 2
			throw new CDbException(Yii::t('yiiext','The node cannot be deleted because it is new.'));
222
223 2
		if($this->getIsDeletedRecord())
224 2
			throw new CDbException(Yii::t('yiiext','The node cannot be deleted because it is already deleted.'));
225
226 2
		$db=$owner->getDbConnection();
227
228 2
		if($db->getCurrentTransaction()===null)
229 2
			$transaction=$db->beginTransaction();
230
231
		try
232
		{
233 2
			if($owner->isLeaf())
234 2
			{
235 2
				$this->_ignoreEvent=true;
236 2
				$result=$owner->delete();
237 2
				$this->_ignoreEvent=false;
238 2
			}
239
			else
240
			{
241
				$condition=$db->quoteColumnName($this->leftAttribute).'>='.$owner->{$this->leftAttribute}.' AND '.
242
					$db->quoteColumnName($this->rightAttribute).'<='.$owner->{$this->rightAttribute};
243
244
				$params=array();
245
246
				if($this->hasManyRoots)
247
				{
248
					$condition.=' AND '.$db->quoteColumnName($this->rootAttribute).'='.CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount;
249
					$params[CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount++]=$owner->{$this->rootAttribute};
250
				}
251
252
				$result=$owner->deleteAll($condition,$params)>0;
253
			}
254
255 2
			if(!$result)
256 2
			{
257
				if(isset($transaction))
258
					$transaction->rollback();
259
260
				return false;
261
			}
262
263 2
			$this->shiftLeftRight($owner->{$this->rightAttribute}+1,$owner->{$this->leftAttribute}-$owner->{$this->rightAttribute}-1);
264
265 2
			if(isset($transaction))
266 2
				$transaction->commit();
267
268 2
			$this->correctCachedOnDelete();
269
		}
270 2
		catch(Exception $e)
271
		{
272
			if(isset($transaction))
273
				$transaction->rollback();
274
275
			throw $e;
276
		}
277
278 2
		return true;
279
	}
280
281
	/**
282
	 * Deletes node and it's descendants.
283
	 * @return boolean whether the deletion is successful.
284
	 */
285 2
	public function deleteNode()
286
	{
287 2
		return $this->delete();
288
	}
289
290
	/**
291
	 * Prepends node to target as first child.
292
	 * @param CActiveRecord $target the target.
293
	 * @param boolean $runValidation whether to perform validation.
294
	 * @param array $attributes list of attributes.
295
	 * @return boolean whether the prepending succeeds.
296
	 */
297
	public function prependTo($target,$runValidation=true,$attributes=null)
298
	{
299
		return $this->addNode($target,$target->{$this->leftAttribute}+1,1,$runValidation,$attributes);
300
	}
301
302
	/**
303
	 * Prepends target to node as first child.
304
	 * @param CActiveRecord $target the target.
305
	 * @param boolean $runValidation whether to perform validation.
306
	 * @param array $attributes list of attributes.
307
	 * @return boolean whether the prepending succeeds.
308
	 */
309
	public function prepend($target,$runValidation=true,$attributes=null)
310
	{
311
		return $target->prependTo($this->getOwner(),$runValidation,$attributes);
312
	}
313
314
	/**
315
	 * Appends node to target as last child.
316
	 * @param CActiveRecord $target the target.
317
	 * @param boolean $runValidation whether to perform validation.
318
	 * @param array $attributes list of attributes.
319
	 * @return boolean whether the appending succeeds.
320
	 */
321
	public function appendTo($target,$runValidation=true,$attributes=null)
322
	{
323
		return $this->addNode($target,$target->{$this->rightAttribute},1,$runValidation,$attributes);
324
	}
325
326
	/**
327
	 * Appends target to node as last child.
328
	 * @param CActiveRecord $target the target.
329
	 * @param boolean $runValidation whether to perform validation.
330
	 * @param array $attributes list of attributes.
331
	 * @return boolean whether the appending succeeds.
332
	 */
333
	public function append($target,$runValidation=true,$attributes=null)
334
	{
335
		return $target->appendTo($this->getOwner(),$runValidation,$attributes);
336
	}
337
338
	/**
339
	 * Inserts node as previous sibling of target.
340
	 * @param CActiveRecord $target the target.
341
	 * @param boolean $runValidation whether to perform validation.
342
	 * @param array $attributes list of attributes.
343
	 * @return boolean whether the inserting succeeds.
344
	 */
345
	public function insertBefore($target,$runValidation=true,$attributes=null)
346
	{
347
		return $this->addNode($target,$target->{$this->leftAttribute},0,$runValidation,$attributes);
348
	}
349
350
	/**
351
	 * Inserts node as next sibling of target.
352
	 * @param CActiveRecord $target the target.
353
	 * @param boolean $runValidation whether to perform validation.
354
	 * @param array $attributes list of attributes.
355
	 * @return boolean whether the inserting succeeds.
356
	 */
357
	public function insertAfter($target,$runValidation=true,$attributes=null)
358
	{
359
		return $this->addNode($target,$target->{$this->rightAttribute}+1,0,$runValidation,$attributes);
360
	}
361
362
	/**
363
	 * Move node as previous sibling of target.
364
	 * @param CActiveRecord $target the target.
365
	 * @return boolean whether the moving succeeds.
366
	 */
367
	public function moveBefore($target)
368
	{
369
		return $this->moveNode($target,$target->{$this->leftAttribute},0);
370
	}
371
372
	/**
373
	 * Move node as next sibling of target.
374
	 * @param CActiveRecord $target the target.
375
	 * @return boolean whether the moving succeeds.
376
	 */
377
	public function moveAfter($target)
378
	{
379
		return $this->moveNode($target,$target->{$this->rightAttribute}+1,0);
380
	}
381
382
	/**
383
	 * Move node as first child of target.
384
	 * @param CActiveRecord $target the target.
385
	 * @return boolean whether the moving succeeds.
386
	 */
387
	public function moveAsFirst($target)
388
	{
389
		return $this->moveNode($target,$target->{$this->leftAttribute}+1,1);
390
	}
391
392
	/**
393
	 * Move node as last child of target.
394
	 * @param CActiveRecord $target the target.
395
	 * @return boolean whether the moving succeeds.
396
	 */
397
	public function moveAsLast($target)
398
	{
399
		return $this->moveNode($target,$target->{$this->rightAttribute},1);
400
	}
401
402
	/**
403
	 * Move node as new root.
404
	 * @return boolean whether the moving succeeds.
405
	 */
406
	public function moveAsRoot()
407
	{
408
		$owner=$this->getOwner();
409
410
		if(!$this->hasManyRoots)
411
			throw new CException(Yii::t('yiiext','Many roots mode is off.'));
412
413
		if($owner->getIsNewRecord())
414
			throw new CException(Yii::t('yiiext','The node should not be new record.'));
415
416
		if($this->getIsDeletedRecord())
417
			throw new CDbException(Yii::t('yiiext','The node should not be deleted.'));
418
419
		if($owner->isRoot())
420
			throw new CException(Yii::t('yiiext','The node already is root node.'));
421
422
		$db=$owner->getDbConnection();
423
424
		if($db->getCurrentTransaction()===null)
425
			$transaction=$db->beginTransaction();
426
427
		try
428
		{
429
			$left=$owner->{$this->leftAttribute};
430
			$right=$owner->{$this->rightAttribute};
431
			$levelDelta=1-$owner->{$this->levelAttribute};
432
			$delta=1-$left;
433
434
			$owner->updateAll(
435
				array(
436
					$this->leftAttribute=>new CDbExpression($db->quoteColumnName($this->leftAttribute).sprintf('%+d',$delta)),
437
					$this->rightAttribute=>new CDbExpression($db->quoteColumnName($this->rightAttribute).sprintf('%+d',$delta)),
438
					$this->levelAttribute=>new CDbExpression($db->quoteColumnName($this->levelAttribute).sprintf('%+d',$levelDelta)),
439
					$this->rootAttribute=>$owner->getPrimaryKey(),
440
				),
441
				$db->quoteColumnName($this->leftAttribute).'>='.$left.' AND '.
442
				$db->quoteColumnName($this->rightAttribute).'<='.$right.' AND '.
443
				$db->quoteColumnName($this->rootAttribute).'='.CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount,
444
				array(CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount++=>$owner->{$this->rootAttribute}));
445
446
			$this->shiftLeftRight($right+1,$left-$right-1);
447
448
			if(isset($transaction))
449
				$transaction->commit();
450
451
			$this->correctCachedOnMoveBetweenTrees(1,$levelDelta,$owner->getPrimaryKey());
452
		}
453
		catch(Exception $e)
454
		{
455
			if(isset($transaction))
456
				$transaction->rollback();
457
458
			throw $e;
459
		}
460
461
		return true;
462
	}
463
464
	/**
465
	 * Determines if node is descendant of subject node.
466
	 * @param CActiveRecord $subj the subject node.
467
	 * @return boolean whether the node is descendant of subject node.
468
	 */
469
	public function isDescendantOf($subj)
470
	{
471
		$owner=$this->getOwner();
472
		$result=($owner->{$this->leftAttribute}>$subj->{$this->leftAttribute})
473
			&& ($owner->{$this->rightAttribute}<$subj->{$this->rightAttribute});
474
475
		if($this->hasManyRoots)
476
			$result=$result && ($owner->{$this->rootAttribute}===$subj->{$this->rootAttribute});
477
478
		return $result;
479
	}
480
481
	/**
482
	 * Determines if node is leaf.
483
	 * @return boolean whether the node is leaf.
484
	 */
485 2
	public function isLeaf()
486
	{
487 2
		$owner=$this->getOwner();
488
489 2
		return $owner->{$this->rightAttribute}-$owner->{$this->leftAttribute}===1;
490
	}
491
492
	/**
493
	 * Determines if node is root.
494
	 * @return boolean whether the node is root.
495
	 */
496
	public function isRoot()
497
	{
498
		return $this->getOwner()->{$this->leftAttribute}==1;
499
	}
500
501
	/**
502
	 * Returns if the current node is deleted.
503
	 * @return boolean whether the node is deleted.
504
	 */
505 2
	public function getIsDeletedRecord()
506
	{
507 2
		return $this->_deleted;
508
	}
509
510
	/**
511
	 * Sets if the current node is deleted.
512
	 * @param boolean $value whether the node is deleted.
513
	 */
514 2
	public function setIsDeletedRecord($value)
515
	{
516 2
		$this->_deleted=$value;
517 2
	}
518
519
	/**
520
	 * Handle 'afterConstruct' event of the owner.
521
	 * @param CEvent $event event parameter.
522
	 */
523 1
	public function afterConstruct($event)
524
	{
525 1
		$owner=$this->getOwner();
526 1
		self::$_cached[get_class($owner)][$this->_id=self::$_c++]=$owner;
527 1
	}
528
529
	/**
530
	 * Handle 'afterFind' event of the owner.
531
	 * @param CEvent $event event parameter.
532
	 */
533 23
	public function afterFind($event)
534
	{
535 23
		$owner=$this->getOwner();
536 23
		self::$_cached[get_class($owner)][$this->_id=self::$_c++]=$owner;
537 23
	}
538
539
	/**
540
	 * Handle 'beforeSave' event of the owner.
541
	 * @param CEvent $event event parameter.
542
	 * @return boolean.
0 ignored issues
show
Documentation introduced by
The doc-type boolean. could not be parsed: Unknown type name "boolean." at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
543
	 */
544
	public function beforeSave($event)
545
	{
546
		if($this->_ignoreEvent)
547
			return true;
548
		else
549
			throw new CDbException(Yii::t('yiiext','You should not use CActiveRecord::save() method when NestedSetBehavior attached.'));
550
	}
551
552
	/**
553
	 * Handle 'beforeDelete' event of the owner.
554
	 * @param CEvent $event event parameter.
555
	 * @return boolean.
0 ignored issues
show
Documentation introduced by
The doc-type boolean. could not be parsed: Unknown type name "boolean." at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
556
	 */
557 2
	public function beforeDelete($event)
558
	{
559 2
		if($this->_ignoreEvent)
560 2
			return true;
561
		else
562
			throw new CDbException(Yii::t('yiiext','You should not use CActiveRecord::delete() method when NestedSetBehavior attached.'));
563
	}
564
565
	/**
566
	 * @param int $key.
0 ignored issues
show
Bug introduced by
There is no parameter named $key.. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
567
	 * @param int $delta.
0 ignored issues
show
Documentation introduced by
There is no parameter named $delta.. Did you maybe mean $delta?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
568
	 */
569 2
	private function shiftLeftRight($key,$delta)
570
	{
571 2
		$owner=$this->getOwner();
572 2
		$db=$owner->getDbConnection();
573
574 2
		foreach(array($this->leftAttribute,$this->rightAttribute) as $attribute)
575
		{
576 2
			$condition=$db->quoteColumnName($attribute).'>='.$key;
577 2
			$params=array();
578
579 2
			if($this->hasManyRoots)
580 2
			{
581
				$condition.=' AND '.$db->quoteColumnName($this->rootAttribute).'='.CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount;
582
				$params[CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount++]=$owner->{$this->rootAttribute};
583
			}
584
585 2
			$owner->updateAll(array($attribute=>new CDbExpression($db->quoteColumnName($attribute).sprintf('%+d',$delta))),$condition,$params);
586 2
		}
587 2
	}
588
589
	/**
590
	 * @param CActiveRecord $target.
0 ignored issues
show
Documentation introduced by
There is no parameter named $target.. Did you maybe mean $target?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
591
	 * @param int $key.
0 ignored issues
show
Bug introduced by
There is no parameter named $key.. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
592
	 * @param int $levelUp.
0 ignored issues
show
Documentation introduced by
There is no parameter named $levelUp.. Did you maybe mean $levelUp?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
593
	 * @param boolean $runValidation.
0 ignored issues
show
Documentation introduced by
There is no parameter named $runValidation.. Did you maybe mean $runValidation?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
594
	 * @param array $attributes.
0 ignored issues
show
Documentation introduced by
There is no parameter named $attributes.. Did you maybe mean $attributes?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
595
	 * @return boolean.
0 ignored issues
show
Documentation introduced by
The doc-type boolean. could not be parsed: Unknown type name "boolean." at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
596
	 */
597
	private function addNode($target,$key,$levelUp,$runValidation,$attributes)
598
	{
599
		$owner=$this->getOwner();
600
601
		if(!$owner->getIsNewRecord())
602
			throw new CDbException(Yii::t('yiiext','The node cannot be inserted because it is not new.'));
603
604
		if($this->getIsDeletedRecord())
605
			throw new CDbException(Yii::t('yiiext','The node cannot be inserted because it is deleted.'));
606
607
		if($target->getIsDeletedRecord())
608
			throw new CDbException(Yii::t('yiiext','The node cannot be inserted because target node is deleted.'));
609
610
		if($owner->equals($target))
611
			throw new CException(Yii::t('yiiext','The target node should not be self.'));
612
613
		if(!$levelUp && $target->isRoot())
614
			throw new CException(Yii::t('yiiext','The target node should not be root.'));
615
616
		if($runValidation && !$owner->validate())
617
			return false;
618
619
		if($this->hasManyRoots)
620
			$owner->{$this->rootAttribute}=$target->{$this->rootAttribute};
621
622
		$db=$owner->getDbConnection();
623
624
		if($db->getCurrentTransaction()===null)
625
			$transaction=$db->beginTransaction();
626
627
		try
628
		{
629
			$this->shiftLeftRight($key,2);
630
			$owner->{$this->leftAttribute}=$key;
631
			$owner->{$this->rightAttribute}=$key+1;
632
			$owner->{$this->levelAttribute}=$target->{$this->levelAttribute}+$levelUp;
633
			$this->_ignoreEvent=true;
634
			$result=$owner->insert($attributes);
635
			$this->_ignoreEvent=false;
636
637
			if(!$result)
638
			{
639
				if(isset($transaction))
640
					$transaction->rollback();
641
642
				return false;
643
			}
644
645
			if(isset($transaction))
646
				$transaction->commit();
647
648
			$this->correctCachedOnAddNode($key);
649
		}
650
		catch(Exception $e)
651
		{
652
			if(isset($transaction))
653
				$transaction->rollback();
654
655
			throw $e;
656
		}
657
658
		return true;
659
	}
660
661
	/**
662
	 * @param array $attributes.
0 ignored issues
show
Documentation introduced by
There is no parameter named $attributes.. Did you maybe mean $attributes?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
663
	 * @return boolean.
0 ignored issues
show
Documentation introduced by
The doc-type boolean. could not be parsed: Unknown type name "boolean." at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
664
	 */
665
	private function makeRoot($attributes)
666
	{
667
		$owner=$this->getOwner();
668
		$owner->{$this->leftAttribute}=1;
669
		$owner->{$this->rightAttribute}=2;
670
		$owner->{$this->levelAttribute}=1;
671
672
		if($this->hasManyRoots)
673
		{
674
			$db=$owner->getDbConnection();
675
676
			if($db->getCurrentTransaction()===null)
677
				$transaction=$db->beginTransaction();
678
679
			try
680
			{
681
				$this->_ignoreEvent=true;
682
				$result=$owner->insert($attributes);
683
				$this->_ignoreEvent=false;
684
685
				if(!$result)
686
				{
687
					if(isset($transaction))
688
						$transaction->rollback();
689
690
					return false;
691
				}
692
693
				$pk=$owner->{$this->rootAttribute}=$owner->getPrimaryKey();
694
				$owner->updateByPk($pk,array($this->rootAttribute=>$pk));
695
696
				if(isset($transaction))
697
					$transaction->commit();
698
			}
699
			catch(Exception $e)
700
			{
701
				if(isset($transaction))
702
					$transaction->rollback();
703
704
				throw $e;
705
			}
706
		}
707
		else
708
		{
709
			if($owner->roots()->exists())
710
				throw new CException(Yii::t('yiiext','Cannot create more than one root in single root mode.'));
711
712
			$this->_ignoreEvent=true;
713
			$result=$owner->insert($attributes);
714
			$this->_ignoreEvent=false;
715
716
			if(!$result)
717
				return false;
718
		}
719
720
		return true;
721
	}
722
723
	/**
724
	 * @param CActiveRecord $target.
0 ignored issues
show
Documentation introduced by
There is no parameter named $target.. Did you maybe mean $target?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
725
	 * @param int $key.
0 ignored issues
show
Bug introduced by
There is no parameter named $key.. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
726
	 * @param int $levelUp.
0 ignored issues
show
Documentation introduced by
There is no parameter named $levelUp.. Did you maybe mean $levelUp?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
727
	 * @return boolean.
0 ignored issues
show
Documentation introduced by
The doc-type boolean. could not be parsed: Unknown type name "boolean." at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
728
	 */
729
	private function moveNode($target,$key,$levelUp)
730
	{
731
		$owner=$this->getOwner();
732
733
		if($owner->getIsNewRecord())
734
			throw new CException(Yii::t('yiiext','The node should not be new record.'));
735
736
		if($this->getIsDeletedRecord())
737
			throw new CDbException(Yii::t('yiiext','The node should not be deleted.'));
738
739
		if($target->getIsDeletedRecord())
740
			throw new CDbException(Yii::t('yiiext','The target node should not be deleted.'));
741
742
		if($owner->equals($target))
743
			throw new CException(Yii::t('yiiext','The target node should not be self.'));
744
745
		if($target->isDescendantOf($owner))
746
			throw new CException(Yii::t('yiiext','The target node should not be descendant.'));
747
748
		if(!$levelUp && $target->isRoot())
749
			throw new CException(Yii::t('yiiext','The target node should not be root.'));
750
751
		$db=$owner->getDbConnection();
752
753
		if($db->getCurrentTransaction()===null)
754
			$transaction=$db->beginTransaction();
755
756
		try
757
		{
758
			$left=$owner->{$this->leftAttribute};
759
			$right=$owner->{$this->rightAttribute};
760
			$levelDelta=$target->{$this->levelAttribute}-$owner->{$this->levelAttribute}+$levelUp;
761
762
			if($this->hasManyRoots && $owner->{$this->rootAttribute}!==$target->{$this->rootAttribute})
763
			{
764
				foreach(array($this->leftAttribute,$this->rightAttribute) as $attribute)
765
				{
766
					$owner->updateAll(array($attribute=>new CDbExpression($db->quoteColumnName($attribute).sprintf('%+d',$right-$left+1))),
767
						$db->quoteColumnName($attribute).'>='.$key.' AND '.$db->quoteColumnName($this->rootAttribute).'='.CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount,
768
						array(CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount++=>$target->{$this->rootAttribute}));
769
				}
770
771
				$delta=$key-$left;
772
773
				$owner->updateAll(
774
					array(
775
						$this->leftAttribute=>new CDbExpression($db->quoteColumnName($this->leftAttribute).sprintf('%+d',$delta)),
776
						$this->rightAttribute=>new CDbExpression($db->quoteColumnName($this->rightAttribute).sprintf('%+d',$delta)),
777
						$this->levelAttribute=>new CDbExpression($db->quoteColumnName($this->levelAttribute).sprintf('%+d',$levelDelta)),
778
						$this->rootAttribute=>$target->{$this->rootAttribute},
779
					),
780
					$db->quoteColumnName($this->leftAttribute).'>='.$left.' AND '.
781
					$db->quoteColumnName($this->rightAttribute).'<='.$right.' AND '.
782
					$db->quoteColumnName($this->rootAttribute).'='.CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount,
783
					array(CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount++=>$owner->{$this->rootAttribute}));
784
785
				$this->shiftLeftRight($right+1,$left-$right-1);
786
787
				if(isset($transaction))
788
					$transaction->commit();
789
790
				$this->correctCachedOnMoveBetweenTrees($key,$levelDelta,$target->{$this->rootAttribute});
791
			}
792
			else
793
			{
794
				$delta=$right-$left+1;
795
				$this->shiftLeftRight($key,$delta);
796
797
				if($left>=$key)
798
				{
799
					$left+=$delta;
800
					$right+=$delta;
801
				}
802
803
				$condition=$db->quoteColumnName($this->leftAttribute).'>='.$left.' AND '.$db->quoteColumnName($this->rightAttribute).'<='.$right;
804
				$params=array();
805
806
				if($this->hasManyRoots)
807
				{
808
					$condition.=' AND '.$db->quoteColumnName($this->rootAttribute).'='.CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount;
809
					$params[CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount++]=$owner->{$this->rootAttribute};
810
				}
811
812
				$owner->updateAll(array($this->levelAttribute=>new CDbExpression($db->quoteColumnName($this->levelAttribute).sprintf('%+d',$levelDelta))),$condition,$params);
813
814
				foreach(array($this->leftAttribute,$this->rightAttribute) as $attribute)
815
				{
816
					$condition=$db->quoteColumnName($attribute).'>='.$left.' AND '.$db->quoteColumnName($attribute).'<='.$right;
817
					$params=array();
818
819
					if($this->hasManyRoots)
820
					{
821
						$condition.=' AND '.$db->quoteColumnName($this->rootAttribute).'='.CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount;
822
						$params[CDbCriteria::PARAM_PREFIX.CDbCriteria::$paramCount++]=$owner->{$this->rootAttribute};
823
					}
824
825
					$owner->updateAll(array($attribute=>new CDbExpression($db->quoteColumnName($attribute).sprintf('%+d',$key-$left))),$condition,$params);
826
				}
827
828
				$this->shiftLeftRight($right+1,-$delta);
829
830
				if(isset($transaction))
831
					$transaction->commit();
832
833
				$this->correctCachedOnMoveNode($key,$levelDelta);
834
			}
835
		}
836
		catch(Exception $e)
837
		{
838
			if(isset($transaction))
839
				$transaction->rollback();
840
841
			throw $e;
842
		}
843
844
		return true;
845
	}
846
847
	/**
848
	 * Correct cache for {@link NestedSetBehavior::delete()} and {@link NestedSetBehavior::deleteNode()}.
849
	 */
850 2
	private function correctCachedOnDelete()
851
	{
852 2
		$owner=$this->getOwner();
853 2
		$left=$owner->{$this->leftAttribute};
854 2
		$right=$owner->{$this->rightAttribute};
855 2
		$key=$right+1;
856 2
		$delta=$left-$right-1;
857
858 2
		foreach(self::$_cached[get_class($owner)] as $node)
859
		{
860 2
			if($node->getIsNewRecord() || $node->getIsDeletedRecord())
861 2
				continue;
862
863 2
			if($this->hasManyRoots && $owner->{$this->rootAttribute}!==$node->{$this->rootAttribute})
864 2
				continue;
865
866 2
			if($node->{$this->leftAttribute}>=$left && $node->{$this->rightAttribute}<=$right)
867 2
				$node->setIsDeletedRecord(true);
868
			else
869
			{
870 1
				if($node->{$this->leftAttribute}>=$key)
871 1
					$node->{$this->leftAttribute}+=$delta;
872
873 1
				if($node->{$this->rightAttribute}>=$key)
874 1
					$node->{$this->rightAttribute}+=$delta;
875
			}
876 2
		}
877 2
	}
878
879
	/**
880
	 * Correct cache for {@link NestedSetBehavior::addNode()}.
881
	 * @param int $key.
0 ignored issues
show
Bug introduced by
There is no parameter named $key.. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
882
	 */
883
	private function correctCachedOnAddNode($key)
884
	{
885
		$owner=$this->getOwner();
886
887
		foreach(self::$_cached[get_class($owner)] as $node)
888
		{
889
			if($node->getIsNewRecord() || $node->getIsDeletedRecord())
890
				continue;
891
892
			if($this->hasManyRoots && $owner->{$this->rootAttribute}!==$node->{$this->rootAttribute})
893
				continue;
894
895
			if($owner===$node)
896
				continue;
897
898
			if($node->{$this->leftAttribute}>=$key)
899
				$node->{$this->leftAttribute}+=2;
900
901
			if($node->{$this->rightAttribute}>=$key)
902
				$node->{$this->rightAttribute}+=2;
903
		}
904
	}
905
906
	/**
907
	 * Correct cache for {@link NestedSetBehavior::moveNode()}.
908
	 * @param int $key.
0 ignored issues
show
Bug introduced by
There is no parameter named $key.. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
909
	 * @param int $levelDelta.
0 ignored issues
show
Documentation introduced by
There is no parameter named $levelDelta.. Did you maybe mean $levelDelta?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
910
	 */
911
	private function correctCachedOnMoveNode($key,$levelDelta)
912
	{
913
		$owner=$this->getOwner();
914
		$left=$owner->{$this->leftAttribute};
915
		$right=$owner->{$this->rightAttribute};
916
		$delta=$right-$left+1;
917
918
		if($left>=$key)
919
		{
920
			$left+=$delta;
921
			$right+=$delta;
922
		}
923
924
		$delta2=$key-$left;
925
926
		foreach(self::$_cached[get_class($owner)] as $node)
927
		{
928
			if($node->getIsNewRecord() || $node->getIsDeletedRecord())
929
				continue;
930
931
			if($this->hasManyRoots && $owner->{$this->rootAttribute}!==$node->{$this->rootAttribute})
932
				continue;
933
934
			if($node->{$this->leftAttribute}>=$key)
935
				$node->{$this->leftAttribute}+=$delta;
936
937
			if($node->{$this->rightAttribute}>=$key)
938
				$node->{$this->rightAttribute}+=$delta;
939
940
			if($node->{$this->leftAttribute}>=$left && $node->{$this->rightAttribute}<=$right)
941
				$node->{$this->levelAttribute}+=$levelDelta;
942
943
			if($node->{$this->leftAttribute}>=$left && $node->{$this->leftAttribute}<=$right)
944
				$node->{$this->leftAttribute}+=$delta2;
945
946
			if($node->{$this->rightAttribute}>=$left && $node->{$this->rightAttribute}<=$right)
947
				$node->{$this->rightAttribute}+=$delta2;
948
949
			if($node->{$this->leftAttribute}>=$right+1)
950
				$node->{$this->leftAttribute}-=$delta;
951
952
			if($node->{$this->rightAttribute}>=$right+1)
953
				$node->{$this->rightAttribute}-=$delta;
954
		}
955
	}
956
957
	/**
958
	 * Correct cache for {@link NestedSetBehavior::moveNode()}.
959
	 * @param int $key.
0 ignored issues
show
Bug introduced by
There is no parameter named $key.. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
960
	 * @param int $levelDelta.
0 ignored issues
show
Documentation introduced by
There is no parameter named $levelDelta.. Did you maybe mean $levelDelta?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
961
	 * @param int $root.
0 ignored issues
show
Bug introduced by
There is no parameter named $root.. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
962
	 */
963
	private function correctCachedOnMoveBetweenTrees($key,$levelDelta,$root)
964
	{
965
		$owner=$this->getOwner();
966
		$left=$owner->{$this->leftAttribute};
967
		$right=$owner->{$this->rightAttribute};
968
		$delta=$right-$left+1;
969
		$delta2=$key-$left;
970
		$delta3=$left-$right-1;
971
972
		foreach(self::$_cached[get_class($owner)] as $node)
973
		{
974
			if($node->getIsNewRecord() || $node->getIsDeletedRecord())
975
				continue;
976
977
			if($node->{$this->rootAttribute}===$root)
978
			{
979
				if($node->{$this->leftAttribute}>=$key)
980
					$node->{$this->leftAttribute}+=$delta;
981
982
				if($node->{$this->rightAttribute}>=$key)
983
					$node->{$this->rightAttribute}+=$delta;
984
			}
985
			else if($node->{$this->rootAttribute}===$owner->{$this->rootAttribute})
986
			{
987
				if($node->{$this->leftAttribute}>=$left && $node->{$this->rightAttribute}<=$right)
988
				{
989
					$node->{$this->leftAttribute}+=$delta2;
990
					$node->{$this->rightAttribute}+=$delta2;
991
					$node->{$this->levelAttribute}+=$levelDelta;
992
					$node->{$this->rootAttribute}=$root;
993
				}
994
				else
995
				{
996
					if($node->{$this->leftAttribute}>=$right+1)
997
						$node->{$this->leftAttribute}+=$delta3;
998
999
					if($node->{$this->rightAttribute}>=$right+1)
1000
						$node->{$this->rightAttribute}+=$delta3;
1001
				}
1002
			}
1003
		}
1004
	}
1005
1006
	/**
1007
	 * Destructor.
1008
	 */
1009
	public function __destruct()
1010
	{
1011
		unset(self::$_cached[get_class($this->getOwner())][$this->_id]);
1012
	}
1013
1014
  public function getTreeView($rootNodeId = null, $isReturnRootNode = true, $nodeUrl = null, $currentId = null)
1015
  {
1016
    $tree  = array();
0 ignored issues
show
Unused Code introduced by
$tree is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1017
    $owner = $this->getOwner();
1018
1019
    if ($rootNodeId == null)
1020
      $rawTree = $owner->findAll(array('order' => $this->leftAttribute));
1021
    else
1022
      $rawTree = $owner->findAll(array('condition' => $this->rootAttribute.'=:rootId',
1023
                                   'order'     => $this->leftAttribute,
1024
                                   'params'    => array(':rootId' => $rootNodeId)));
1025
1026
    $tree = $this->buildTree(
1027
      $rawTree,
1028
      array($this, 'buildTreeItem'),
1029
      array('nodeUrl' => $nodeUrl, 'currentId' => $currentId)
1030
    );
1031
1032
    if( !$isReturnRootNode )
1033
    {
1034
      reset($tree);
1035
      $tree = $tree[key($tree)]['children'];
1036
    }
1037
1038
    return $tree;
1039
  }
1040
1041
  protected function buildTreeItem($node, $params)
1042
  {
1043
    return array(
1044
      'id'          => 'node_'.$node->id,
1045
      'text'        => $params['nodeUrl'] ? '<a href="'.$params['nodeUrl'].'/'.$node->id.'">'.$node->name.'</a>' : $node->name,
1046
      'level'       => $node->level,
1047
      'node'        => $node,
1048
      'children'    => array(),
1049
      'htmlOptions' => array('class' => 'file'.($params['currentId'] === $node->id ? ' current' : ''))
1050
    );
1051
  }
1052
1053
  protected function buildTree($rawTree, $buildItemFunc, $buildParams = array(), $childrenKey = 'children')
1054
  {
1055
    $tree  = array();
1056
    $stack = array();
1057
1058
    foreach($rawTree as $node)
1059
    {
1060
      $item = call_user_func_array($buildItemFunc, array($node, $buildParams));
1061
1062
      // Number of stack items
1063
      $level = count($stack);
1064
1065
      // Check if we're dealing with different levels
1066
      while($level > 0 && $stack[$level - 1]['level'] >= $item['level'])
1067
      {
1068
        array_pop($stack);
1069
        $level--;
1070
      }
1071
1072
      // Stack is empty (we are inspecting the root)
1073
      if($level == 0)
1074
      {
1075
        // Assigning the root node
1076
        $i        = count($tree);
1077
        $tree[$i] = $item;
1078
        $stack[]  = &$tree[$i];
1079
      }
1080
      else
1081
      {
1082
        // Add node to parent
1083
        $i = count($stack[$level - 1][$childrenKey]);
1084
        $stack[$level - 1]['htmlOptions']['class'] = str_replace('file', 'folder', $stack[$level - 1]['htmlOptions']['class']);
1085
        $stack[$level - 1][$childrenKey][$i] = $item;
1086
        $stack[] = &$stack[$level - 1][$childrenKey][$i];
1087
      }
1088
    }
1089
1090
    return $tree;
1091
  }
1092
}