ZIP to XML error

Closed

Import WP Pro Updated 2 weeks ago 11 Replies

Evelien asked 3 weeks ago on October 5, 2024 at 9:41 am

Hi James,

We have this zip feed with loose xml files. You suggested this should work, however I receive an error: See this screenshot:  Config Index Not Found

And the log doesn’t give any errors. These files are create in wp-content, see this screenshot: /wp-content/uploads/importwp/.

Thank you.
Demian

ET

Evelien replied privately

3 weeks ago on October 5, 2024 at 9:42 am

J

James replied Support Agent

3 weeks ago on October 5, 2024 at 9:44 am

Thanks, 

From the zip file i can see there are many xml files in the zip, currently the importer only expects 1 zip file as it can only import 1 file at a time, let me have a think about what can be done to solve your issue.

James

ET

Evelien replied

3 weeks ago on October 5, 2024 at 9:51 am

Yes, last week I wrote myself a plugin to unpack and merge the XML files into a new XML file. That is the XML file you have seen last couple of days: https://a1executiveestate.com/wp-content/uploads/kolibri-xml-feed/merged_kolibri_feed.xml. So this works.The only thing I struggle with is to set a Cron date, and to have it automatically unpacked and merged into a new xml file.
J

James replied Support Agent

2 weeks ago on October 7, 2024 at 1:47 pm

Are you able to send the merge code, this way i can see the best place to trigger this before the import.

ET

Evelien replied

2 weeks ago on October 8, 2024 at 3:07 pm

See attachment. The generation of a new XML file happens in zip-xml-merge.zip. 

First choose manual download > download now button

Then Generate XML and the link should appear.

It's Ajax calls.

I hope it works in your environment, it's in development progress.

J

James replied privately Support Agent

2 weeks ago on October 9, 2024 at 9:40 pm

ET

Evelien replied

2 weeks ago on October 10, 2024 at 12:51 pm

Hi James, 

Thank you for this, but the zip link is not local it's from an external source. Local path hits an error.

J

James replied Support Agent

2 weeks ago on October 10, 2024 at 12:54 pm

Yes, the zip is not local, but your plugin fetches it triggerd by zip_process_scheduled_download(), and the previously attached code returns the local path of the merged xml file. which the importer will then use the local path to import.

ET

Evelien replied

2 weeks ago on October 10, 2024 at 2:03 pm

Can you explain to me what I need to do? My plugin is still involved?

J

James replied Support Agent

2 weeks ago on October 10, 2024 at 2:55 pm

Sorry, i just presumed you wanted to continue using your plugin, so i have now replaced the file downloader with the importer.

add_filter('iwp/importer/datasource/local', function ($source, $raw_source, $importer) {

    // 1. download file 

    /**
     * @var \ImportWP\Common\Filesystem\Filesystem $filesystem
     */
    $filesystem = \ImportWP\Container::getInstance()->get('filesystem');
    $result = $filesystem->download_file($source);
    if (is_wp_error($result)) {
        return '';
    }

    // 2. get filepath
    $upload_dir = wp_upload_dir();
    $zip_file_path = $result['dest'];

    // 3. generate merge file
    $zip_xml_dir = $upload_dir['basedir'] . '/zip-xml-feed/download/';
    if (!file_exists($zip_xml_dir)) {
        wp_mkdir_p($zip_xml_dir);
    }

    $unpacked_dir = $upload_dir['basedir'] . '/zip-xml-feed/xml-files/';
    if (!file_exists($unpacked_dir)) {
        wp_mkdir_p($unpacked_dir);
    }

    // Unzip the file
    $zip = new ZipArchive;
    if ($zip->open($zip_file_path) === TRUE) {
        $zip->extractTo($unpacked_dir);
        $zip->close();
    } else {
        return '';
    }

    // Initialize a new XML document for the merged file
    $main_xml = new SimpleXMLElement('<MainFile/>');

    // Get all XML files from the extracted folder
    foreach (glob($unpacked_dir . '*.xml') as $xml_file) {
        // Load each XML file
        $xml_content = file_get_contents($xml_file);

        // Check for empty or invalid XML
        if (empty($xml_content)) {
            continue; // Skip empty files
        }

        // Attempt to load the XML, handle errors
        try {
            $xml_data = new SimpleXMLElement($xml_content);
        } catch (Exception $e) {
            continue; // Skip invalid XML
        }

        // Add each XML file's content under the <MainChild> tag
        $property = $main_xml->addChild('MainChild');
        $property_dom = dom_import_simplexml($property);
        $property_dom->appendChild($property_dom->ownerDocument->importNode(dom_import_simplexml($xml_data), true));
    }

    // Save the merged XML to a new file
    $merged_file_path = $zip_xml_dir . 'merged_zip_xml.xml';
    $main_xml->asXML($merged_file_path);

    // Prepare the URL for the generated XML file
    return $merged_file_path;
}, 10, 3);

To use: Create an importer, set the Datasource to Local FIle, and setting the local path input to that of your remote zip file.

You may want to modify the script to clear the extracted files and merged at the start before each download.

ET

Evelien replied

2 weeks ago on October 10, 2024 at 3:19 pm

Thank you for this solution, this all works.