@@ -115,9 +115,16 @@ public function getParent()
115115 *
116116 * @param Node $parent
117117 * @chainable
118+ * @throws Exception
118119 */
119120 public function setParent (Node $ parent )
120121 {
122+ // check integrity
123+ if ($ this ->isDescendant ($ parent ->id ()))
124+ {
125+ throw new Exception ('Can not add descendant " ' .$ parent ->id ().'" as my parent. ' );
126+ }
127+
121128 // remove from old parent
122129 if ( ! is_null ($ this ->parent ))
123130 {
@@ -177,6 +184,12 @@ public function addChild(Node $child)
177184 $ key = null ;
178185 $ newKey = 0 ;
179186
187+ // check integrity
188+ if ($ this ->isAncestor ($ child ->id ()))
189+ {
190+ throw new Exception ('Can not add child. It is my ancestor. ' );
191+ }
192+
180193 // check if child is itself
181194 if ($ child ->id () == $ this ->id )
182195 {
@@ -266,7 +279,7 @@ public function previousChild($id)
266279 }
267280
268281 /**
269- * Checks if the give node id is a decendant of the
282+ * Checks if the given node id is a decendant of the
270283 * current node.
271284 *
272285 * @param int $id
@@ -280,9 +293,9 @@ public function isDescendant($id)
280293 {
281294 return true ;
282295 }
283- elseif ($ child ->hasChildren ())
296+ elseif ($ child[ ' node ' ] ->hasChildren ())
284297 {
285- if ($ child ->isDescendant ($ id ))
298+ if ($ child[ ' node ' ] ->isDescendant ($ id ))
286299 {
287300 return true ;
288301 }
@@ -292,6 +305,27 @@ public function isDescendant($id)
292305 return false ;
293306 }
294307
308+ /**
309+ * Checks if the given node id is an ancestor of
310+ * the current node.
311+ *
312+ * @param int $id
313+ * @return bool
314+ */
315+ public function isAncestor ($ id )
316+ {
317+ if ( ! is_null ($ this ->parent ))
318+ {
319+ if ($ this ->parent ->id () == $ id )
320+ {
321+ return true ;
322+ }
323+ return $ this ->parent ->isAncestor ($ id );
324+ }
325+
326+ return false ;
327+ }
328+
295329 /**
296330 * Shortcut to return the first child.
297331 *
0 commit comments