From 0cd873a6dd75a416c6ebd8793fcc3f773cab5812 Mon Sep 17 00:00:00 2001 From: Steve Pfisterer Date: Fri, 20 Jul 2018 15:29:45 -0500 Subject: [PATCH 1/4] Update composer --- .gitignore | 1 + composer.json | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 798afc40..88f79a69 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ composer.lock vendor/ phpunit.xml +.idea \ No newline at end of file diff --git a/composer.json b/composer.json index bb7115f4..7879148a 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "thesoftwarefanatics/php-html-parser", + "name": "stoutlogic/php-html-parser", "type": "library", "description": "An HTML DOM parser. It allows you to manipulate HTML. Find tags on an HTML page with selectors just like jQuery.", "keywords": ["html", "dom", "parser"], @@ -15,6 +15,10 @@ "name": "The Software Fanatics GmbH", "email": "dev@thesoftwarefanatics.com", "homepage": "https://thesoftwarefanatics.com" + }, + { + "name": "Stout Logic, LLC", + "email": "steve@stoutlogic.com" } ], "require": { From c94f0514e8aa4667c006b7beb014d29a60e45b6f Mon Sep 17 00:00:00 2001 From: Steve Pfisterer Date: Fri, 20 Jul 2018 15:30:09 -0500 Subject: [PATCH 2/4] Fix firstChild and lastChild --- src/PHPHtmlParser/Dom/InnerNode.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/PHPHtmlParser/Dom/InnerNode.php b/src/PHPHtmlParser/Dom/InnerNode.php index 6f458460..1e7fc52e 100644 --- a/src/PHPHtmlParser/Dom/InnerNode.php +++ b/src/PHPHtmlParser/Dom/InnerNode.php @@ -252,10 +252,11 @@ public function replaceChild($childId, AbstractNode $newChild) */ public function firstChild() { - reset($this->children); - $key = key($this->children); + $first = array_values(array_filter($this->children, function($child) { + return $child['prev'] === null; + })); - return $this->getChild($key); + return $this->getChild($first[0]['node']->id()); } /** @@ -265,10 +266,11 @@ public function firstChild() */ public function lastChild() { - end($this->children); - $key = key($this->children); + $last = array_values(array_filter($this->children, function($child) { + return $child['next'] === null; + })); - return $this->getChild($key); + return $this->getChild($last[0]['node']->id()); } /** From 5a4b894d14e4dfc5b0949517c5bc0c6316a04b10 Mon Sep 17 00:00:00 2001 From: Steve Pfisterer Date: Fri, 20 Jul 2018 15:31:14 -0500 Subject: [PATCH 3/4] Fix replace child, set next and prev links, clear cache --- src/PHPHtmlParser/Dom/InnerNode.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/PHPHtmlParser/Dom/InnerNode.php b/src/PHPHtmlParser/Dom/InnerNode.php index 1e7fc52e..d2c635ba 100644 --- a/src/PHPHtmlParser/Dom/InnerNode.php +++ b/src/PHPHtmlParser/Dom/InnerNode.php @@ -235,13 +235,31 @@ public function isChild($id) */ public function replaceChild($childId, AbstractNode $newChild) { + // handle moving next and previous assignments. + $next = $this->children[$childId]['next']; + $prev = $this->children[$childId]['prev']; $oldChild = $this->getChild($childId); $keys = array_keys($this->children); $index = array_search($childId, $keys, true); $keys[$index] = $newChild->id(); $this->children = array_combine($keys, $this->children); - $this->children[$newChild->id()] = $newChild; + $this->children[$newChild->id()] = [ + 'node' => $newChild, + 'next' => $next, + 'prev' => $prev, + ]; + + if ($prev) { + $this->children[$prev]['next'] = $newChild->id(); + } + if ($next) { + $this->children[$next]['prev'] = $newChild->id(); + } + + //clear any cache + $this->clear(); unset($oldChild); + return $this; } /** From 6688f628018be162abee58fe1c14be6da483f7e2 Mon Sep 17 00:00:00 2001 From: Steve Pfisterer Date: Fri, 20 Jul 2018 15:31:38 -0500 Subject: [PATCH 4/4] Add insertBefore and insertAfter functions --- src/PHPHtmlParser/Dom/InnerNode.php | 81 +++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/src/PHPHtmlParser/Dom/InnerNode.php b/src/PHPHtmlParser/Dom/InnerNode.php index d2c635ba..80469e45 100644 --- a/src/PHPHtmlParser/Dom/InnerNode.php +++ b/src/PHPHtmlParser/Dom/InnerNode.php @@ -143,6 +143,87 @@ public function addChild(AbstractNode $child) return true; } + public function insertBefore($id, AbstractNode $child) + { + $key = null; + + if ( ! isset($this->children[$id])) { + return $this; + } + + // check integrity + if ($this->isAncestor($child->id())) { + throw new CircularException('Can not add child. It is my ancestor.'); + } + + // check if child is itself + if ($child->id() == $this->id) { + throw new CircularException('Can not set itself as a child.'); + } + + $prevId = $this->children[$id]['prev']; + $this->children[$id]['prev'] = $child->id(); + + if ($prevId) { + $this->children[$prevId]['next'] = $child->id(); + } + + // add the child + $this->children[$child->id()] = [ + 'node' => $child, + 'next' => $id, + 'prev' => $prevId, + ]; + + // tell child I am the new parent + $child->setParent($this); + + //clear any cache + $this->clear(); + + return true; + } + + public function insertAfter($id, AbstractNode $child) + { + $key = null; + + if ( ! isset($this->children[$id])) { + return $this; + } + + // check integrity + if ($this->isAncestor($child->id())) { + throw new CircularException('Can not add child. It is my ancestor.'); + } + + // check if child is itself + if ($child->id() == $this->id) { + throw new CircularException('Can not set itself as a child.'); + } + + $nextId = $this->children[$id]['next']; + $this->children[$id]['next'] = $child->id(); + + if ($nextId) { + $this->children[$nextId]['prev'] = $child->id(); + } + + // add the child + $this->children[$child->id()] = [ + 'node' => $child, + 'next' => $nextId, + 'prev' => $id, + ]; + + // tell child I am the new parent + $child->setParent($this); + + //clear any cache + $this->clear(); + + return true; + } /** * Removes the child by id.