Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ianmjones/5458a46be6508865618a33eb587bdcf9 to your computer and use it in GitHub Desktop.
Save ianmjones/5458a46be6508865618a33eb587bdcf9 to your computer and use it in GitHub Desktop.
Process WooCommerce products and set correct downloadable files if they've been offloaded by WP Offload Media
<?php
namespace Mosaika;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Register our custom commands.
* * Usage:
* * Dry run: wp as3cf update_products_downloadable_files
* * Real run: wp as3cf update_products_downloadable_files --dry-run=0
*/
if ( class_exists( 'WP_CLI' ) ) {
\WP_CLI::add_command( 'as3cf', 'Mosaika\Commands' );
}
class Commands {
/**
* Update WooCommerce products downloadable files to benefit from WP Offload Media features.
* Products downloadable files will be linked to their offloaded version,
* and this offloaded media will be set as private.
*
* @param array $args
* @param array $assoc_args
* @return void
*/
public function update_products_downloadable_files( $args, $assoc_args ) {
$defaults = [
'dry-run' => true,
'batch-size' => 100,
];
$this->args = wp_parse_args( $assoc_args, $defaults );
$dry_run = (bool) $this->args['dry-run'];
$batch_size = (int) $this->args['batch-size'];
$query_args = [
'downloadable' => 'true',
'status' => [ 'draft', 'pending', 'private', 'publish' ],
'return' => 'ids',
'limit' => 9999,
];
$products = new \WC_Product_Query( $query_args );
$total_products = count( $products->get_products() );
$num_batches = ceil( $total_products / $batch_size );
$products_processed = 0;
$downloads_processed = 0;
if ( empty( $products->get_products() ) ) {
\WP_CLI::line( 'No products found, stopping here.' );
return;
}
if ( $dry_run ) {
$intro = sprintf( 'Fake-processing %1$d products: link to S3 media and turn private.', $total_products );
} else {
$intro = sprintf( 'Processing %1$d products: link to S3 media and turn private.', $total_products );
}
$progress = \WP_CLI\Utils\make_progress_bar( $intro, $num_batches );
\WP_CLI::line( '=============================================================================' );
\WP_CLI::line( sprintf(
'Going through %1$d products: now analyzing %2$d batches of %3$d items.',
$total_products,
$num_batches,
$batch_size
) );
\WP_CLI::line( '=============================================================================' );
for ( $j = 0; $j < $num_batches; $j++ ) {
\WP_CLI::line( sprintf( 'Starting batch #%1$d / %2$d.', $j, $num_batches ) );
$offset = $j * $batch_size;
$query_args['offset'] = $offset;
$products = new \WC_Product_Query( $query_args );
foreach ( $products->get_products() as $product_id ) {
$product = wc_get_product( $product_id );
$downloads = $product->get_downloads( 'edit' );
$new_downloads = [];
foreach ( $downloads as $k => $download ) {
$media_id = attachment_url_to_postid( $download->get_file() );
$s3_info = ( (int) $media_id > 0 ) ? get_post_meta( (int) $media_id, 'amazonS3_info', true ) : null;
// Can't find media, or we do not have any S3 data: keep downloadable file as it is.
if ( (int) $media_id === 0 || empty( $s3_info ) || ! is_array( $s3_info ) || ! isset( $s3_info['provider'] ) || $s3_info['provider'] !== 'aws' ) {
$new_downloads[ $k ] = $download;
continue;
}
$s3_shortcode = sprintf( '[amazon_s3 id="%1$d"]', (int) $media_id );
$new_key = wp_generate_uuid4();
$download->set_file( $s3_shortcode );
$download->set_id( $new_key );
$new_downloads[ $new_key ] = $download;
$downloads_processed++;
}
if ( ! empty( $new_downloads ) && ! $dry_run ) {
$product->set_downloads( $new_downloads );
$product->save();
}
$products_processed++;
}
$progress->tick();
}
$progress->finish();
\WP_CLI::line( "- {$products_processed} products were processed: {$downloads_processed} downloadable files were updated." );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment