Created
June 6, 2013 23:32
-
-
Save TheFrozenFire/5725866 to your computer and use it in GitHub Desktop.
ZF2 DOM Hydrator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Zend\Stdlib\Hydrator; | |
use DOMNode; | |
use DOMElement; | |
use DOMXPath; | |
use Zend\Stdlib\Exception; | |
use Zend\Stdlib\Hydrator as ZendHydrator; | |
class DOM extends ZendHydrator\AbstractHydrator implements ZendHydrator\HydratorOptionsInterface { | |
protected $queryMap = array(); | |
protected $namespaces = array(); | |
protected $xpath; | |
public function __construct($queryMap = null, $namespaces = null, $xpath = null) { | |
parent::__construct(); | |
$this->setQueryMap($queryMap); | |
$this->setNamespaces($namespaces); | |
$this->setXPath($xpath); | |
} | |
public function setOptions($options) { | |
if($options instanceof Traversable) { | |
$options = ArrayUtils::iteratorToArray($options); | |
} elseif(!is_array($options)) { | |
throw new Exception\InvalidArgumentException( | |
'The options parameter must be an array or a Traversable' | |
); | |
} | |
if(isset($options['queryMap'])) { | |
$this->setQueryMap($options['queryMap']); | |
} | |
if(isset($options["namespaces"])) { | |
$this->setNamespaces($options["namespaces"]); | |
} | |
if(isset($options["xpath"])) { | |
$this->setXPath($options["xpath"]); | |
} | |
return $this; | |
} | |
public function getQueryMap() { | |
return $this->queryMap?:array(); | |
} | |
public function setQueryMap($queryMap) { | |
$queryMap = is_array($queryMap)?$queryMap:null; | |
$this->queryMap = $queryMap; | |
return $this; | |
} | |
public function getNamespaces() { | |
return $this->namespaces?:array(); | |
} | |
public function setNamespaces($namespaces) { | |
$this->namespaces = $namespaces; | |
return $this; | |
} | |
public function getXPath() { | |
return $this->xpath; | |
} | |
public function setXPath($xpath) { | |
if(!is_null($xpath) && !($xpath instanceof DOMXPath)) | |
throw new Exception\InvalidArgumentException( | |
"The xpath must be null or a DOMXPath" | |
); | |
$this->xpath = $xpath; | |
return $this; | |
} | |
public function extract($node) { | |
if(!($node instanceof DOMElement)) | |
throw new Exception\BadMethodCallException(sprintf( | |
'%s expects the provided $object to be a DOMElement', __METHOD__ | |
)); | |
if(!($this->xpath instanceof DOMXPath)) { | |
$this->setXPath(new DOMXPath($node->ownerDocument)); | |
} | |
$xpath = $this->getXPath(); | |
foreach($this->getNamespaces() as $prefix => $namespace) { | |
$xpath->registerNamespace($prefix, $namespace); | |
} | |
$attributes = array(); | |
foreach($this->getQueryMap() as $attribute => $query) { | |
$attributeNodes = $xpath->query($query, $node); | |
if(!$attributeNodes) | |
throw new \InvalidArgumentException("Malformed query"); | |
if($attributeNodes->length === 1) { | |
$attributeNode = $attributeNodes->item(0); | |
if($attributeNode instanceof DOMNode) { | |
$attributes[$attribute] = $attributeNode->nodeValue; | |
} | |
} elseif($attributeNodes->length > 1) { | |
$attributes[$attribute] = array(); | |
foreach($attributeNodes as $attributeNode) { | |
if($attributeNode instanceof DOMNode) { | |
$attributes[$attribute][] = $attributeNode->nodeValue; | |
} | |
} | |
} | |
} | |
return $attributes; | |
} | |
public function hydrate(array $data, $node) { | |
if(!($node instanceof DOMElement)) | |
throw new Exception\BadMethodCallException(sprintf( | |
'%s expects the provided $object to be a DOMElement)', __METHOD__ | |
)); | |
if(!($this->xpath instanceof DOMXPath)) { | |
$this->setXPath(new DOMXPath($node->ownerDocument)); | |
} | |
$xpath = $this->getXPath(); | |
foreach($this->getNamespaces() as $prefix => $namespace) { | |
$xpath->registerNamespace($prefix, $namespace); | |
} | |
$queryMap = $this->getQueryMap(); | |
foreach($data as $attribute => $value) { | |
if(!isset($queryMap[$attribute])) | |
continue; | |
$attributeNode = $xpath->query($query, $node)->item(0); | |
if($attributeNode instanceof DOMNode) { | |
$attributeNode->nodeValue = $value; | |
} | |
} | |
return $node; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment