Need to extend a class to generate new DOM element inside element generated by the original class.

I have a class that generates a grid of images. Now I need to add a title to the images without touching the original class.

Example:

class Foo
{public $img_url;
function make_img() {
echo '<div><img src="' . $this->img_url . '"></div>';
}

The desired result:

<div><div class="imageTitle">Img Title</div><img src="imgurl"></div>

1 Answers

1
Joffrey Schmitz On

If the function really use echo, you have no other solution than override the whole behaviour :

class FooExtended extends Foo{
    public $title ;

    public function __construct()
    {
        $this->title = 'my Title';
    }

    function make_img() {
        echo '<div><div class="imageTitle">' . $this->title . '</div><img src="' . $this->img_url . '"></div>' ;
    }
}

Now, if you create your element with $foo2 = new FooExtended(); the new behaviour will be applied each time make_img() will be called. The problem is if the Foo class is modified, you will need to remember to edit FooExtended too.

If your function return a string instead of printing it, you can first call the parent function, and then process the result string to add the information you want.

function make_img() {
    $basic = parent::make_img(); // call the parent function

    $tmpDoc = new DOMDocument();
    $tmpDoc->loadXml($basic);

    $titleNode = $tmpDoc->createElement('div', $this->title);
    $titleClass = $tmpDoc->createAttribute('class');
    $titleClass->value = 'imageTitle';
    $titleNode->appendChild($titleClass);

    $imgNode = $tmpDoc->getElementsByTagName('img')->item(0);
    $imgNode->parentNode->insertBefore($titleNode, $imgNode);

    return $tmpDoc->saveXml($tmpDoc->documentElement, LIBXML_NOEMPTYTAG) ;
}