314 lines
7.4 KiB
PHP
314 lines
7.4 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* Class CLI
|
||
|
*
|
||
|
* @since 3.1
|
||
|
* @package Smush\Core
|
||
|
*/
|
||
|
|
||
|
namespace Smush\Core;
|
||
|
|
||
|
use Smush\Core\Media\Media_Item_Cache;
|
||
|
use Smush\Core\Media\Media_Item_Optimizer;
|
||
|
use WP_CLI;
|
||
|
use WP_CLI_Command;
|
||
|
use WP_Smush;
|
||
|
|
||
|
if ( ! defined( 'WPINC' ) ) {
|
||
|
die;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Reduce image file sizes, improve performance and boost your SEO using the free WPMU DEV Smush API.
|
||
|
*/
|
||
|
class CLI extends WP_CLI_Command {
|
||
|
|
||
|
/**
|
||
|
* Optimize image.
|
||
|
*
|
||
|
* ## OPTIONS
|
||
|
*
|
||
|
* [--type=<type>]
|
||
|
* : Optimize single image, batch or all images.
|
||
|
* ---
|
||
|
* default: all
|
||
|
* options:
|
||
|
* - all
|
||
|
* - single
|
||
|
* - batch
|
||
|
* ---
|
||
|
*
|
||
|
* [--image=<ID>]
|
||
|
* : Attachment ID to compress.
|
||
|
* ---
|
||
|
* default: 0
|
||
|
* ---
|
||
|
*
|
||
|
* ## EXAMPLES
|
||
|
*
|
||
|
* # Smush all images.
|
||
|
* $ wp smush compress
|
||
|
*
|
||
|
* # Smush single image with ID = 10.
|
||
|
* $ wp smush compress --type=single --image=10
|
||
|
*
|
||
|
* # Smush first 5 images.
|
||
|
* $ wp smush compress --type=batch --image=5
|
||
|
*
|
||
|
* @param array $args All the positional arguments.
|
||
|
* @param array $assoc_args All the arguments defined like --key=value or --flag or --no-flag.
|
||
|
*/
|
||
|
public function compress( $args, $assoc_args ) {
|
||
|
$type = $assoc_args['type'];
|
||
|
$image = $assoc_args['image'];
|
||
|
|
||
|
switch ( $type ) {
|
||
|
case 'single':
|
||
|
/* translators: %d - image ID */
|
||
|
$msg = sprintf( __( 'Smushing image ID: %d', 'wp-smushit' ), absint( $image ) );
|
||
|
$this->smush( $msg, array( $image ) );
|
||
|
$this->_list( array() );
|
||
|
break;
|
||
|
case 'batch':
|
||
|
/* translators: %d - number of images */
|
||
|
$msg = sprintf( __( 'Smushing first %d images', 'wp-smushit' ), absint( $image ) );
|
||
|
$this->smush_all( $msg, $image );
|
||
|
break;
|
||
|
case 'all':
|
||
|
default:
|
||
|
$this->smush_all( __( 'Smushing all images', 'wp-smushit' ) );
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* List unoptimized images.
|
||
|
*
|
||
|
* ## OPTIONS
|
||
|
*
|
||
|
* [<count>]
|
||
|
* : Limit number of images to get.
|
||
|
*
|
||
|
* ## EXAMPLES
|
||
|
*
|
||
|
* # Get all unoptimized images.
|
||
|
* $ wp smush list
|
||
|
*
|
||
|
* # Get the first 100 images that are not optimized.
|
||
|
* $ wp smush list 100
|
||
|
*
|
||
|
* @subcommand list
|
||
|
* @when after_wp_load
|
||
|
*
|
||
|
* @param array $args All the positional arguments.
|
||
|
*/
|
||
|
public function _list( $args ) {
|
||
|
if ( ! empty( $args ) ) {
|
||
|
list( $count ) = $args;
|
||
|
} else {
|
||
|
$count = -1;
|
||
|
}
|
||
|
|
||
|
$response = WP_CLI::launch_self(
|
||
|
'post list',
|
||
|
array( '--meta_compare=NOT EXISTS' ),
|
||
|
array(
|
||
|
'post_type' => 'attachment',
|
||
|
'fields' => 'ID, guid, post_mime_type',
|
||
|
'meta_key' => 'wp-smpro-smush-data',
|
||
|
'format' => 'json',
|
||
|
'posts_per_page' => (int) $count,
|
||
|
),
|
||
|
false,
|
||
|
true
|
||
|
);
|
||
|
|
||
|
$images = json_decode( $response->stdout );
|
||
|
|
||
|
if ( empty( $images ) ) {
|
||
|
WP_CLI::success( __( 'No uncompressed images found', 'wp-smushit' ) );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
WP_CLI::success( __( 'Unsmushed images:', 'wp-smushit' ) );
|
||
|
WP_CLI\Utils\format_items( 'table', $images, array( 'ID', 'guid', 'post_mime_type' ) );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Restore image.
|
||
|
*
|
||
|
* ## OPTIONS
|
||
|
*
|
||
|
* [--id=<ID>]
|
||
|
* : Attachment ID to restore.
|
||
|
* ---
|
||
|
* default: all
|
||
|
* ---
|
||
|
*
|
||
|
* ## EXAMPLES
|
||
|
*
|
||
|
* # Restore all images that have backups.
|
||
|
* $ wp smush restore
|
||
|
*
|
||
|
* # Restore single image with ID = 10.
|
||
|
* $ wp smush restore --id=10
|
||
|
*
|
||
|
* @param array $args All the positional arguments.
|
||
|
* @param array $assoc_args All the arguments defined like --key=value or --flag or --no-flag.
|
||
|
*/
|
||
|
public function restore( $args, $assoc_args ) {
|
||
|
$id = $assoc_args['id'];
|
||
|
|
||
|
if ( 'all' === $id ) {
|
||
|
$this->restore_image();
|
||
|
} else {
|
||
|
$this->restore_image( absint( $id ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Smush single image.
|
||
|
*
|
||
|
* @since 3.1
|
||
|
*
|
||
|
* @param string $msg Message for progress bar status.
|
||
|
* @param array $images Attachment IDs.
|
||
|
*/
|
||
|
private function smush( $msg = '', $images = array() ) {
|
||
|
$success = false;
|
||
|
$errors = array();
|
||
|
$progress = WP_CLI\Utils\make_progress_bar( $msg, count( $images ) + 1 );
|
||
|
|
||
|
$core = WP_Smush::get_instance()->core();
|
||
|
|
||
|
// We need to initialize the database module (maybe all other modules as well?).
|
||
|
Settings::get_instance()->init();
|
||
|
|
||
|
$unsmushed_attachments = $core->get_unsmushed_attachments();
|
||
|
|
||
|
while ( $images ) {
|
||
|
$progress->tick();
|
||
|
|
||
|
$attachment_id = array_pop( $images );
|
||
|
|
||
|
// Skip if already Smushed.
|
||
|
$should_convert = $core->mod->webp->should_be_converted( $attachment_id );
|
||
|
if ( ! in_array( (int) $attachment_id, $unsmushed_attachments, true ) && ! $should_convert ) {
|
||
|
/* translators: %d - attachment ID */
|
||
|
$errors[] = sprintf( __( 'Image (ID: %d) already compressed', 'wp-smushit' ), $attachment_id );
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
$status = $core->mod->smush->smush_single( $attachment_id, true );
|
||
|
|
||
|
if ( is_array( $status ) && isset( $status['error'] ) ) {
|
||
|
/* translators: %1$d - attachment ID, %2$s - error. */
|
||
|
$errors[] = sprintf( __( 'Error compressing image (ID: %1$d). %2$s', 'wp-smushit' ), $attachment_id, $status['error'] );
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
$success = true;
|
||
|
}
|
||
|
|
||
|
$progress->tick();
|
||
|
$progress->finish();
|
||
|
|
||
|
if ( ! empty( $errors ) ) {
|
||
|
foreach ( $errors as $error ) {
|
||
|
WP_CLI::warning( $error );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( $success ) {
|
||
|
WP_CLI::success( __( 'Image compressed', 'wp-smushit' ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Smush all uncompressed images.
|
||
|
*
|
||
|
* @since 3.1
|
||
|
*
|
||
|
* @param string $msg Message for progress bar status.
|
||
|
* @param int $batch Compress only this number of images.
|
||
|
*/
|
||
|
private function smush_all( $msg, $batch = 0 ) {
|
||
|
$attachments = WP_Smush::get_instance()->core()->get_unsmushed_attachments();
|
||
|
|
||
|
if ( $batch > 0 ) {
|
||
|
$attachments = array_slice( $attachments, 0, $batch );
|
||
|
}
|
||
|
|
||
|
$progress = WP_CLI\Utils\make_progress_bar( $msg, count( $attachments ) );
|
||
|
|
||
|
foreach ( $attachments as $attachment_id ) {
|
||
|
WP_Smush::get_instance()->core()->mod->smush->smush_single( $attachment_id, true );
|
||
|
$progress->tick();
|
||
|
}
|
||
|
|
||
|
$progress->finish();
|
||
|
WP_CLI::success( __( 'All images compressed', 'wp-smushit' ) );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Restore all images.
|
||
|
*
|
||
|
* @since 3.1
|
||
|
*
|
||
|
* @param int $id Image ID to restore. Default: 0 - restores all images.
|
||
|
*/
|
||
|
private function restore_image( $id = 0 ) {
|
||
|
$core = WP_Smush::get_instance()->core();
|
||
|
|
||
|
$attachments = $core->get_smushed_attachments();
|
||
|
if ( empty( $attachments ) ) {
|
||
|
WP_CLI::success( __( 'No images available to restore', 'wp-smushit' ) );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( 0 !== $id ) {
|
||
|
if ( ! in_array( (string) $id, $attachments, true ) ) {
|
||
|
WP_CLI::warning( __( 'Image with defined ID not found', 'wp-smushit' ) );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
$attachments = array( $id );
|
||
|
}
|
||
|
|
||
|
$progress = WP_CLI\Utils\make_progress_bar( __( 'Restoring images', 'wp-smushit' ), count( $attachments ) );
|
||
|
|
||
|
$warning = false;
|
||
|
foreach ( $attachments as $attachment_id ) {
|
||
|
if ( ! $core->mod->backup->backup_exists( $attachment_id ) ) {
|
||
|
$warning = true;
|
||
|
|
||
|
$warning_text = sprintf(/* translators: %d - attachment ID */
|
||
|
esc_html__( 'Image %d cannot be restored', 'wp-smushit' ),
|
||
|
(int) $attachment_id
|
||
|
);
|
||
|
WP_CLI::warning( $warning_text );
|
||
|
$progress->tick();
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
$media_item = Media_Item_Cache::get_instance()->get( $attachment_id );
|
||
|
$optimizer = new Media_Item_Optimizer( $media_item );
|
||
|
$restored = $optimizer->restore();
|
||
|
if ( ! $restored ) {
|
||
|
$warning = true;
|
||
|
}
|
||
|
|
||
|
$progress->tick();
|
||
|
}
|
||
|
|
||
|
$progress->finish();
|
||
|
|
||
|
if ( $warning ) {
|
||
|
WP_CLI::error( __( 'There were issues restoring some images', 'wp-smushit' ) );
|
||
|
} else {
|
||
|
WP_CLI::success( __( 'All images restored', 'wp-smushit' ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|