ersezar
ersezar

Reputation: 57

Split WP_Query output into chunks in Wordpress

I'm trying to extract an xml feed for about 30k products.

In the lower one, the output reaches the level of 7-8 thousand and does not continue. I need to include all products in the output.

Can I split the process or output files into parts, would something like this require a lot of code?

Or if anyone has any other ideas, I'm open to that, as this seems to be an important issue I need to resolve.

I get data from database with WP_Query() loop starts with foreach and outputs with XMLWriter().

<?php
add_action( 'wp_loaded', 'product_feeds_output_writer');
function product_feeds_output_writer() {

    $args = array(
        'post_type' => 'product', // Total product 30k.
        'post_status' => 'publish',
        'posts_per_page' => -1,
        'meta_query' => array(
            array(
                'key' => '_stock_status',
                'value' => 'instock',
                'compare' => '='
            )
        )
    );

    $query = new WP_Query();

    if (! $posts = $query->query( $args ) ) {
            
        $error = new WP_Error( '003', 'No products found.' );

        wp_send_json_error( $error );
    }

    $bloginfo = array(
        'name' => get_bloginfo('name'),
        'url' => get_bloginfo('url'),
        'description' => get_bloginfo('description')
    );
       
    $xml = new XMLWriter();
    
    $xml->openURI( $_SERVER['DOCUMENT_ROOT'] . '/wp-content/uploads/woo-products-feed-generator/XMLWriter.xml' );
    
    $xml->startDocument('1.0','UTF-8');
    
    $xml->setIndent( 4 );
    
    $xml->startElement('rss');
    
    $xml->writeAttribute('version', '2.0');
    
    $xml->writeAttribute('xmlns:g', 'http://base.google.com/ns/1.0');
    
    $xml->startElement('channel');
    
    $xml->writeElement('title', $bloginfo['name']);
    
    $xml->writeElement('link', $bloginfo['url']);
    
    $xml->writeElement('description', $bloginfo['description']);

    foreach ( $posts as $post ) {

        $product = wc_get_product( $post->ID );
        
        $bir = random_int( 0, 9 );

        $on = random_int( 10, 99 );     
        
        $yuz = random_int( 100, 999 );
        
        $bin = random_int( 1000, 9999 );
        
        $mil = random_int( 1000000, 9999999 );
            
        $id = $product->get_id();
            
        $title = $product->get_title();
            
        $link = $product->get_permalink();
            
        $description = $product->get_description();

        $price = $product->get_regular_price() ?: $product->get_price();
            
        $sale_price = $product->get_sale_price() ?: '';

        $availability = $product->get_stock_status() == 'instock' ? 'in_stock' : 'out_of_stock';
            
        $brand = $product->get_attribute( 'pa_marka' );
            
        $image_link = $product->get_meta('_product_image_thumbnail') ?: wp_get_attachment_url( $product->get_image_id() );
        
        $type = implode( '', wp_get_post_terms( $product->id, 'product_cat', array('fields' => 'names') ) );
            
        $xml->startElement('item');
            
            $xml->writeElement( 'g:id', $id );
            
            $xml->writeElement( 'g:title', $title );
            
            $xml->writeElement( 'g:description', $description ); 
            
            $xml->writeElement( 'g:link', $link );
            
            $xml->writeElement( 'g:price', $price.' '.'TRY' );
            
            if( $sale_price ) {
            $xml->writeElement( 'g:sale_price', $sale_price.' '.'TRY' );
            }
            
            $xml->writeElement( 'g:availability', $availability );
            
            $xml->writeElement( 'g:brand', $brand );   
            
            //$xml->writeElement( 'g:google_product_category', $track );  
            
            $xml->writeElement( 'g:product_type', $type );
            
            $xml->writeElement( 'g:identifier_exists', 'yes' ); 
            
            $xml->writeElement( 'g:gtin', $mil.'-'.'K'.$yuz.'DK' );
            
            $xml->writeElement( 'g:mpn', $bin.'BS'.'-'.'L'.$on.$bir.'ZP' );
            
            $xml->writeElement( 'g:condition', 'Yeni' );
            
            //$xml->writeElement( 'g:shipping', $track );
            
            $xml->writeElement( 'g:image_link', $image_link ); 
            
            if( $attachment_images = $product->get_gallery_image_ids() ) {
                
                $attachment_images = array_slice( $attachment_images, 0, 10 );
                
                foreach( $attachment_images as $attachment_id ) {
                    
                    $image_link = wp_get_attachment_url( $attachment_id );
                
                    $xml->writeElement( 'g:additional_image_link', $image_link );
                }
            }
            
            $xml->writeElement( 'g:material', 'Polipropilen' );
            
            if( $value = $product->get_attribute( 'pa_renk' ) ) {
            
                $xml->startElement('g:product_detail');
                    
                    $xml->writeElement('g:section_name', 'Additional information' );
            
                    $xml->writeElement('g:attribute_name', 'Renk' );
                
                    $xml->writeElement('g:attribute_value', $value );
                
                $xml->endElement();
            }
            
            if( $value = $product->get_attribute( 'pa_beden' ) ) {
            
                $xml->startElement('g:product_detail');
                    
                    $xml->writeElement('g:section_name', 'Additional information' );
            
                    $xml->writeElement('g:attribute_name', 'Beden' );
                
                    $xml->writeElement('g:attribute_value', $value );
                
                $xml->endElement();
            }
            
        $xml->endElement();
    }
    
    $xml->endElement();
    
    $xml->endElement();
    
    $xml->endDocument();
    
    $xml->flush();
    
    unset($xml);
}

Upvotes: 0

Views: 240

Answers (1)

amarinediary
amarinediary

Reputation: 5449

Would going through the WooCommerce REST API not be a better approach?

I believe the endpoint for products is :

/wp-json/wc/v3/products

You should be able to page jump through the page= url parameter:

/wp-json/wc/v3/products?page=1&per_page=5000

Parameter Description
page (integer) Current page of the collection. Default is 1.
per_page (integer) Maximum number of items to be returned in result set. Default is 10.

Upvotes: 1

Related Questions