0

I need to insert an image with a div element in the middle of an article. The page is generated using PHP from a CRM. I have a routine to count the characters for all the paragraph tags, and insert the HTML after the paragraph that has the 120th character. I am using appendXML and it works, until I try to insert an image element.

When I put the <img> element in, it is stripped out. I understand it is looking for XML, however, I am closing the <img> tag which I understood would help.

Is there a way to use appendXML and not strip out the img elements?

$mcustomHTML = "<div style="position:relative; overflow:hidden;"><a href="https://example.com/code=123456"><img src="https://s3.amazonaws.com/a.example.com/image.png" alt="No image" /></img></a></div>";

$doc = new DOMDocument();
$doc->loadHTML('<?xml encoding="utf-8" ?>' . $content);        

// read all <p> tags and count the text until reach character 120        
// then add the custom html into current node
$pTags = $doc->getElementsByTagName('p');
foreach($pTags as $tag) {
    $characterCounter += strlen($tag->nodeValue);
    if($characterCounter > 120) {
        // this is the desired node, so put html code here
        $template = $doc->createDocumentFragment();
        $template->appendXML($mcustomHTML);
        $tag->appendChild($template);
        break;
    }
}
return $doc->saveHTML();
miken32
  • 35,483
  • 13
  • 81
  • 108
HamletHub
  • 301
  • 3
  • 16
  • Probably need to use Cdata, tags. this guy `` I don't know if DomDocument has a method for it, typically I use XMLWriter for XML which has http://php.net/manual/en/function.xmlwriter-start-cdata.php – ArtisticPhoenix Oct 31 '18 at 00:43
  • For more on CDATA https://stackoverflow.com/questions/2784183/what-does-cdata-in-xml-mean `CDATA stands for Character Data and it means that the data in between these strings includes data that could be interpreted as XML markup, but should not be.` In other words put your HTML in there and the XML parser will ignore it. AS I mentioned too, I probably wouldn't pick DomDocument as my first choice for writing XML. (personally I never had good experiences using Dom) – ArtisticPhoenix Oct 31 '18 at 00:47
  • You're not working with XML. You use `loadHTML()` and `saveHTML()`. What is in `$content` and why do you put an XML declaration before it? – miken32 Oct 31 '18 at 01:50
  • $content is the HTML article that will be published to the site. It is created on the fly – HamletHub Oct 31 '18 at 02:00
  • Someone suggested to use the xml command, not sure why – HamletHub Oct 31 '18 at 02:01
  • You should not use code that you don't understand! Also you should look at the warnings coming from your code; what you had there would have given you "Unexpected end tag" because you're closing the image element twice. It's a self-closing element and doesn't need ``. – miken32 Oct 31 '18 at 02:27

1 Answers1

1

This should work for you. It uses a temporary DOM document to convert the HTML string that you have into something workable. Then we import the contents of the temporary document into the main one. Once it's imported we can simply append it like any other node.

<?php
$mcustomHTML = '<div style="position:relative; overflow:hidden;"><a href="https://example.com/code=123456"><img src="https://s3.amazonaws.com/a.example.com/image.png" alt="No image" /></a></div>';
$customDoc = new DOMDocument();
$customDoc->loadHTML($mcustomHTML, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

$doc = new DOMDocument();
$doc->loadHTML($content);

$customImport = $doc->importNode($customDoc->documentElement, true);

// read all <p> tags and count the text until reach character 120        
// then add the custom html into current node
$pTags = $doc->getElementsByTagName('p');
foreach($pTags as $tag) {
    $characterCounter += strlen($tag->nodeValue);
    if($characterCounter > 120) {
        // this is the desired node, so put html code here
        $tag->appendChild($customImport);
        break;
    }
}
return $doc->saveHTML();
miken32
  • 35,483
  • 13
  • 81
  • 108