Replacing WP Post content HTML element using PHP DOMDocument

I’m working on updating/replacing the html structure of this slightly scrambled html element which is being distorted by the classic editor with a new element that by my estimation should be more functional… Any suggestion would be welcomed. Thank you.

<p><a href="https://www.website.com/?=urlll0" class="product-link" target="_blank" rel="noopener"></p>
<div class="button-block">
<div class="button-image"><img class="webpexpress-processed" src="https://www.website.com/wp-content/uploads/2023/12/image.png" alt="Image" /></div>
<div class="product-title"><span class="product-name">product title</span></div>
<div class="prices-container"><span class="original-price">390</span><br />
<span class="discount-price">152 EUR</span></div>
<div class="button-container"><button class="product-button">Go to Product</button></div>
</div>
<p></a></p>

the new element

$new_structure = '<div class="product-link_wrap" data-href="%1$s">
                    <div class="button-block">
                        <div class="button-image"><img src="%2$s" alt="Image" class="webpexpress-processed"></div>
                        <div class="product-title"><p class="product-name">%3$s</p></div>
                        <div class="prices-container"><span class="original-price">%4$s</span><span class="discount-price">%5$s</span></div>
                        <div class="button-container"><button class="product-button">Go to Product</button></div>
                    </div>
                </div>';

My attempt through these several days, which returns partially complete new structure. I assume I am missing a foreach loop, which should replace first child and last child by tag

. Could this work?

      while ($query->have_posts()) {
            $query->the_post();
            $post_id = get_the_ID();
            $post_content = get_post_field('post_content', $post_id);
      
     $dom = new DOMDocument();
            @$dom->loadHTML(mb_convert_encoding($post_content, 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
            $xpath = new DOMXPath($dom);

$oldStructure = $xpath->query("//p/a[contains(@class, 'product-link')]")->item(0);

            error_log("XPath query result for post ID: " . $post_id . ": " . ($oldStructure ? "Found" : "Not found"));

            if ($oldStructure) {
         $productUrlQuery = '//a[contains(@class, "product-link_wrap")]/@href';
                $imageSrcQuery = '//div[contains(@class, "button-image")]/img/@src';
                $productNameQuery = '//div[contains(@class, "product-title")]/span[contains(@class, "product-name")]';
                $originalPriceQuery = '//div[contains(@class, "prices-container")]/span[contains(@class, "original-price")]';
                $discountPriceQuery = '//div[contains(@class, "prices-container")]/span[contains(@class, "discount-price")]';
                
                
                $productUrl = trim($xpath->evaluate('string(' . $productUrlQuery . ')'));
                $imageSrc = trim($xpath->evaluate('string(' . $imageSrcQuery . ')'));
                $productName = trim($xpath->evaluate('string(' . $productNameQuery . ')'));
                $originalPrice = trim($xpath->evaluate('string(' . $originalPriceQuery . ')'));
                $discountPrice = trim($xpath->evaluate('string(' . $discountPriceQuery . ')'));


                error_log("Img: " . $imageSrc);
                error_log("URL: " . $productUrl);
                error_log("discount: " . $discountPrice);
                error_log("original: " . $originalPrice);
                error_log("title: " . $productName);
                

                $new_structure = '<div class="product-link" data-href="%1$s">
                    <div class="button-block">
                        <div class="button-image"><img src="%2$s" alt="Product" class="webpexpress-processed"></div>
                        <div class="product-title"><p class="product-name">%3$s</p></div>
                        <div class="prices-container"><span class="original-price">%4$s</span><span class="discount-price">%5$s</span></div>
                        <div class="button-container"><button class="product-button">Go to Product</button></div>
                    </div>
                </div>';
                
                $constructed_html = sprintf(
                    $new_structure,
                    esc_url($productUrl), 
                    esc_url($imageSrc), 
                    esc_html($productName), 
                    esc_html($originalPrice), 
                    esc_html($discountPrice) 
                );
                error_log("Constructed content: " . $constructed_html);
                
               
                $tempDom = new DOMDocument();
                
                libxml_use_internal_errors(true);
                $tempDom->loadHTML($constructed_html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
                libxml_use_internal_errors(false);
                
                $importedNode = $dom->importNode($tempDom->documentElement, true);
       
                $oldStructure->parentNode->replaceChild($importedNode, $oldStructure);
                
                $updated_content = $dom->saveHTML();
                
                error_log("New content: " . $updated_content);

                $result = wp_update_post([
                    'ID' => $post_id,
                    'post_content' => $updated_content,
                ]);
                
                if ($result === 0 || $result === false) {
                    error_log("Failed to update post ID: " . $post_id);
                } else {
                    error_log("Successfully updated post ID: " . $post_id);
                }

After testing on a single post I get the following structure:

<p></p><div class="button-block">
<div class="button-image"><img class="webpexpress-processed" src="https://www.website.com/wp-content/uploads/2023/12/image.png" alt="Product Image"></div>
<div class="product-title"><span class="product-name">Title</span></div>
<div class="prices-container"><span class="original-price">390</span><br>
<span class="discount-price">152 EUR</span></div>
<div class="button-container"><button class="product-button">Go to Product</button></div>
</div><p></p>

@bork I am looking for paid task to assist.
Please let me know If you are interested

Sponsor our Newsletter | Privacy Policy | Terms of Service