Ok got it working like a charm using "proxy pattern" with traits. The idea being declaring the common methods inside a "trait" in order for extended and registered Node Classes to have access even if not derived / child of the extended DOMNode…
Here a small snippet :
traittNode{// We need the magic method __get in order to add properties such as DOMNode->parentElementpublic function__get($name)
{ if(property_exists($this,$name)){return$this->$name;}
if(method_exists($this,$name)){return$this->$name();}
throw newErrorException('my\Node property ''.(string)$name.'' not found…',42,E_USER_WARNING);
}// parentElement property definitionprivate functionparentElement()
{ if($this->parentNode===null){returnnull;}
if($this->parentNode->nodeType===XML_ELEMENT_NODE){return$this->parentNode;}
return$this->parentNode->parentElement();
}// JavaScript equivalentpublic functionisEqualNode(DOMNode $node){return$this->isSameNode($node);}
public functioncompareDocumentPosition(DOMNode $otherNode)
{ if($this->ownerDocument!==$otherNode->ownerDocument){returnDOCUMENT_POSITION_DISCONNECTED;}$c=strcmp($this->getNodePath(),$otherNode->getNodePath());
if($c===0){return0;}
else if($c<0){returnDOCUMENT_POSITION_FOLLOWING($c< -1?DOCUMENT_POSITION_CONTAINED_BY:0);}
returnDOCUMENT_POSITION_PRECEDING($c>1?DOCUMENT_POSITION_CONTAINS:0);
}
public functioncontains(DOMNode $otherNode){return ($this->compareDocumentPosition($otherNode) >=DOCUMENT_POSITION_CONTAINED_BY);}
}
classDocumentextendsDomDocument{ public function__construct($version=null,$encoding=null)
{parent::__construct($version,$encoding);$this->registerNodeClass('DOMNode','myNode');$this->registerNodeClass('DOMElement','myElement');$this->registerNodeClass('DOMDocument','myDocument');/* [...] */}
}
classElementextendsDOMElement{ usetNode;/* [...] */}
classNodeextendsDOMNode{ usetNode;/* [...] */}?>