skip to Main Content

I am making a WordPress plugin that should load 2 types of XML files (product feed files), then locate the stock status field, and then retain all in-stock products and return a list of in-stock product URLs from these XML product feeds.

I have hardcoded all the possible in-stock values the stock status field can take, and until now, these values have only been "instock", "in stock", "yes" and values over 0. But in a new product feed I just added, the in-stock value is "På lager". And I thought that I could just add this new value to my function (in the part where i hardcode the values), but that does not work.

I have tried everything, but nothing helps… I have also tried to echo the values, and see the values my plugin outputs (which is "PÃ¥ lager"), but I am not able to decode it as ‘på lager’.

I don’t know if it has something to do with the encoding of the XML or something completely different. I really hope someone can help me out here…

I have attached my function code, and i have attached an example of the new product feed.

Function:

function fetch_and_parse_product_feed_with_xmlreader($feed_entry) {
    $reader = new XMLReader();
    // Access the 'url' key from the feed entry
    if (!$reader->open($feed_entry['url'])) {
        echo "<p>Failed to open feed: " . esc_url($feed_entry['url']) . "</p>";
        return array();
    }

    $in_stock_products = array();
    while ($reader->read()) {
        if ($reader->nodeType == XMLReader::ELEMENT) {
            if ($reader->localName == 'produkt') {
                // Handling for Feed type 1
                $productXml = $reader->readOuterXML();
                $product = simplexml_load_string($productXml);
                $stock_status = strtolower((string)$product->lagerantal);
                if ($stock_status === 'instock' || $stock_status === 'in stock' || intval($stock_status) > 0 || $stock_status === 'yes' || $stock_status === 'på lager') {
                    $processed_url = process_url_for_comparison((string)$product->vareurl);
                    $in_stock_products[] = $processed_url;
                }
            } elseif ($reader->localName == 'product') {
                // Handling for Feed type 2
                $productXml = $reader->readOuterXML();
                $product = simplexml_load_string($productXml);
                $stock_status = strtolower((string)$product->Instock);
                if ($stock_status === 'instock' || $stock_status === 'in stock' || intval($stock_status) > 0 || $stock_status === 'yes') {
                    $processed_url = process_url_for_comparison((string)$product->TrackingUrl);
                    $in_stock_products[] = $processed_url;
                }
            }
        }
    }

    $reader->close();
    return $in_stock_products;
}

XML product feed:

<?xml version="1.0" encoding="iso-8859-1"?>
<produkter>
<produkt>
<forhandler>Cykelpartner</forhandler>
<kategorinavn>Rullebremser &amp; fodbremser</kategorinavn>
<brand>Shimano</brand>
<produktnavn>Shimano Nexus - Skrue og møtrik for bremsewire ved rullebremser bag - BR-IM45-R</produktnavn>
<produktid>4524667690467</produktid>
<ean>4524667690467</ean>
<beskrivelse>Original øjebolt med møtrik der anvendes til fastgørelse af bremsewiren på en Shimano Nexus rullebremse i bag model BR-I...</beskrivelse>
<nypris>24.00</nypris>
<glpris>24.00</glpris>
<fragtomk>45</fragtomk>
<lagerantal>På lager</lagerantal>
<leveringstid>1-3 dage</leveringstid>
<size></size>
<color></color>
</produkt>
<produkt>
<forhandler>Cykelpartner</forhandler>
<kategorinavn>Bremsegreb</kategorinavn>
<brand>Shimano</brand>
<produktnavn>Shimano GRX - STI greb Højre - ST-RX820 - Til 12 gears kassetter - Hydraulisk</produktnavn>
<produktid>4550170173432</produktid>
<ean>4550170173432</ean>
<beskrivelse>Dette STI skifte- og bremsegreb fra Shimanos GRX gravel 12 gears serie, tilhører den kvalitetsmæssige top. Grebet er model ST-RX820, o...</beskrivelse>
<nypris>2349.00</nypris>
<glpris>2349.00</glpris>
<fragtomk>0</fragtomk>
<lagerantal>Ikke på lager</lagerantal>
<leveringstid>Ukendt leveringstid</leveringstid>
<size></size>
<color></color>
<billedurl>https://resources.chainbox.io/5/cykelpartner/public/pim/bb10bd81-d2af-401d-a50c-ed5f3adcc159/istrx820rbi_a_default.jpg</billedurl>
</produkt>
</produkter>

So basically, i want the function to solely return the URL for the first product in the product feed (because the first product has the in-stock value "På lager" while the second product has the out-of-stock value "Ikke på lager".

I have tried debugging by echoing the initial stock status value.

2

Answers


  1. Chosen as BEST ANSWER

    Thank you so much for the help. It is correct that you have to temporarily download the feed, in order to process æ,ø,å.


  2. After some tests, I could reproduce this strange issue. It occurs on PHP versions starting from 8.1 when parsing directly from HTTP.

    As a workaround, download the feed to a local temp file:

    $file = tempnam('.', 'feed');
    $local = fopen($file, 'w');
    $remote = fopen('https://...', 'r');
    stream_copy_to_stream($remote, $local);
    fclose($local);
    fclose($remote);
    
    $nb = 0;
    $reader = new XMLReader();
    $reader->open($file);
    while ($reader->read()) {
        if ($reader->nodeType == XMLReader::ELEMENT) {
            if ($reader->localName == 'produkt') {
                $productXml = $reader->readOuterXML();
                $product = simplexml_load_string($productXml);
                $stock_status = strtolower((string)$product->lagerantal);
                if ($stock_status === 'på lager')
                    $nb++;
            }
        }
    }
    $reader->close();
    echo "På lager found: $nb";
    
    unlink($file);
    

    Output:

    På lager found: 22026
    

    Remark: I didn’t do any error checking in the download part, I will let you do it properly.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search