views:

183

answers:

3

How could I extend objects provided with Document Object Model? Seems that there is no way according to this issue.

class Application_Model_XmlSchema extends DOMElement
{
    const ELEMENT_NAME = 'schema';

    /**
     * @var DOMElement
     */
    private $_schema;

    /**
     * @param DOMDocument $document
     * @return void
     */
    public function __construct(DOMDocument $document) {
        $this->setSchema($document->getElementsByTagName(self::ELEMENT_NAME)->item(0));
    }

    /**
     * @param DOMElement $schema
     * @return void
     */
    public function setSchema(DOMElement $schema){
        $this->_schema = $schema;
    }

    /**
     * @return DOMElement
     */
    public function getSchema(){
        return $this->_schema;
    }

    /**
     * @param  string $name
     * @param  array $arguments
     * @return mixed
     */
    public function __call($name, $arguments) {
        if (method_exists($this->_schema, $name)) {
            return call_user_func_array(
                array($this->_schema, $name),
                $arguments
            );
        }
    }
}

$version = $this->getRequest()->getParam('version', null);
$encoding = $this->getRequest()->getParam('encoding', null);
$source = 'http://www.w3.org/2001/XMLSchema.xsd';

$document = new DOMDocument($version, $encoding);
$document->load($source);

$xmlSchema = new Application_Model_XmlSchema($document);
$xmlSchema->getAttribute('version');

I got an error:

Warning: DOMElement::getAttribute(): Couldn't fetch Application_Model_XmlSchema in C:\Nevermind.php on line newvermind

A: 

Workaround is:

$xmlSchema->getSchema()->getAttribute('version');

But I would like use "normal" access to methods.

Comma
+1  A: 

Since getAttribute is already defined in DOMElement, your __call will not be used. As a consequence, any calls made to Application_Model_XmlSchema::getAttribute will go through the inherited DOMElement::getAttribute resulting in your problem.

A quick workaround would be to get rid of extends DOMElement from the class definition and route calls through to DOMElement methods/properties with magic methods if you need that functionality: have your class act as a wrapper rather than child.

salathe
+1  A: 

Try this: http://www.php.net/manual/en/domdocument.registernodeclass.php

I use it in my DOMDocument extended class and it works great, allowing me to add methods to DOMNode and DOMElement.

grantwparks