verify_s3_access_constants() ) { return; } // Get S3 Upload instance. $instance = Infinite_Uploads::get_instance(); // Create a path in the base directory, with a random file name to avoid potentially overwriting existing data. $upload_dir = wp_upload_dir(); $s3_path = $upload_dir['basedir'] . '/' . mt_rand() . '.txt'; // Attempt to copy the local Canola test file to the generated path on Infinite Uploads cloud. WP_CLI::print_value( 'Attempting to upload file ' . $s3_path ); $copy = copy( dirname( dirname( __FILE__ ) ) . '/readme.txt', $s3_path ); // Check that the copy worked. if ( ! $copy ) { WP_CLI::error( 'Failed to copy / write to Infinite Uploads cloud - check your policy?' ); return; } WP_CLI::print_value( 'File uploaded to Infinite Uploads cloud successfully.' ); // Delete the file off Infinite Uploads cloud. WP_CLI::print_value( 'Attempting to delete file. ' . $s3_path ); $delete = unlink( $s3_path ); // Check that the delete worked. if ( ! $delete ) { WP_CLI::error( 'Failed to delete ' . $s3_path ); return; } WP_CLI::print_value( 'File deleted from Infinite Uploads cloud successfully.' ); WP_CLI::success( 'Looks like your configuration is correct!' ); } /** * Verify that the required constants for the Infinite Uploads cloud connections are set. * * @return bool true if all constants are set, else false. */ private function verify_s3_access_constants() { if ( ! Infinite_Uploads::get_instance()->bucket ) { WP_CLI::error( sprintf( 'This site is not yet connected to the Infinite Uploads cloud. Please connect using the settings page: %s', Infinite_Uploads_Admin::get_instance()->settings_url() ), false ); return false; } return true; } /** * List the files in the Infinite Uploads cloud. Optionally filter to the provided path. * * @synopsis [] */ public function ls( $args ) { // Verify first that we have the necessary access keys to connect to S3. if ( ! $this->verify_s3_access_constants() ) { return; } $s3 = Infinite_Uploads::get_instance()->s3(); $prefix = ''; if ( strpos( Infinite_Uploads::get_instance()->bucket, '/' ) ) { $prefix = trailingslashit( str_replace( strtok( Infinite_Uploads::get_instance()->bucket, '/' ) . '/', '', Infinite_Uploads::get_instance()->bucket ) ); } if ( isset( $args[0] ) ) { $prefix .= trailingslashit( ltrim( $args[0], '/' ) ); } try { $objects = $s3->getIterator( 'ListObjects', [ 'Bucket' => strtok( Infinite_Uploads::get_instance()->bucket, '/' ), 'Prefix' => $prefix, ] ); foreach ( $objects as $object ) { WP_CLI::line( str_replace( $prefix, '', $object['Key'] ) . "\t" . size_format( $object['Size'] ) . "\t" . $object['LastModified']->__toString() ); } } catch ( Exception $e ) { WP_CLI::error( $e->getMessage() ); } } /** * Copy files to / from the uploads directory. Use iu://bucket/location for Infinite Uploads cloud * * @synopsis */ private function cp( $args ) { $from = $args[0]; $to = $args[1]; if ( is_dir( $from ) ) { $this->recurse_copy( $from, $to ); } else { copy( $from, $to ); } WP_CLI::success( sprintf( 'Completed copy from %s to %s', $from, $to ) ); } private function recurse_copy( $src, $dst ) { $dir = opendir( $src ); @mkdir( $dst ); while ( false !== ( $file = readdir( $dir ) ) ) { if ( ( '.' !== $file ) && ( '..' !== $file ) ) { if ( is_dir( $src . '/' . $file ) ) { $this->recurse_copy( $src . '/' . $file, $dst . '/' . $file ); } else { WP_CLI::line( sprintf( 'Copying from %s to %s', $src . '/' . $file, $dst . '/' . $file ) ); copy( $src . '/' . $file, $dst . '/' . $file ); } } } closedir( $dir ); } /** * Upload a directory to Infinite Uploads cloud * * @subcommand upload-directory * @synopsis [] [--concurrency=] [--verbose] */ private function upload_directory( $args, $args_assoc ) { $from = $args[0]; $to = ''; if ( isset( $args[1] ) ) { $to = $args[1]; } $s3 = Infinite_Uploads::get_instance()->s3(); $args_assoc = wp_parse_args( $args_assoc, [ 'concurrency' => 20, 'verbose' => false ] ); $transfer_args = [ 'concurrency' => $args_assoc['concurrency'], 'debug' => (bool) $args_assoc['verbose'], 'before' => function ( UglyRobot\Infinite_Uploads\Aws\Command $command ) { if ( in_array( $command->getName(), [ 'PutObject', 'CreateMultipartUpload' ], true ) ) { /// Expires: if ( defined( 'INFINITE_UPLOADS_HTTP_EXPIRES' ) ) { $command['Expires'] = INFINITE_UPLOADS_HTTP_EXPIRES; } // Cache-Control: if ( defined( 'INFINITE_UPLOADS_HTTP_CACHE_CONTROL' ) ) { if ( is_numeric( INFINITE_UPLOADS_HTTP_CACHE_CONTROL ) ) { $command['CacheControl'] = 'max-age=' . INFINITE_UPLOADS_HTTP_CACHE_CONTROL; } else { $command['CacheControl'] = INFINITE_UPLOADS_HTTP_CACHE_CONTROL; } } } }, ]; try { $manager = new Transfer( $s3, $from, 's3://' . Infinite_Uploads::get_instance()->bucket . '/' . $to, $transfer_args ); $manager->transfer(); } catch ( Exception $e ) { WP_CLI::error( $e->getMessage() ); } } /** * Sync the uploads directory to Infinite Uploads cloud storage. * * @subcommand sync * @synopsis [--concurrency=] [--noscan] [--verbose] */ public function sync( $args, $args_assoc ) { global $wpdb; $instance = Infinite_Uploads::get_instance(); $args_assoc = wp_parse_args( $args_assoc, [ 'concurrency' => 20, 'noscan' => false, 'verbose' => false ] ); $path = $instance->get_original_upload_dir_root(); if ( ! $args_assoc['noscan'] ) { if ( ! $this->build_scan() ) { return; } $stats = $instance->get_sync_stats(); WP_CLI::line( sprintf( esc_html__( '%s files (%s) remaining to be synced.', 'infinite-uploads' ), $stats['remaining_files'], $stats['remaining_size'] ) ); } elseif ( ! $this->verify_s3_access_constants() ) { return; } $s3 = $instance->s3(); //begin transfer $synced = $wpdb->get_var( "SELECT count(*) AS files FROM `{$wpdb->base_prefix}infinite_uploads_files` WHERE synced = 1" ); $unsynced = $wpdb->get_var( "SELECT count(*) AS files FROM `{$wpdb->base_prefix}infinite_uploads_files` WHERE synced = 0" ); $progress_bar = null; if ( ! $args_assoc['verbose'] ) { $progress_bar = \WP_CLI\Utils\make_progress_bar( esc_html__( 'Copying to the cloud...', 'infinite-uploads' ), $synced + $unsynced ); for ( $i = 0; $i < $synced; $i ++ ) { $progress_bar->tick(); } } $progress = get_site_option( 'iup_files_scanned' ); if ( ! $progress['sync_started'] ) { $progress['sync_started'] = time(); update_site_option( 'iup_files_scanned', $progress ); } $uploaded = 0; $break = false; while ( ! $break ) { $to_sync = $wpdb->get_col( "SELECT file FROM `{$wpdb->base_prefix}infinite_uploads_files` WHERE synced = 0 AND errors < 3 LIMIT 1000" ); //build full paths $to_sync_full = []; foreach ( $to_sync as $key => $file ) { $to_sync_full[] = $path['basedir'] . $file; } $obj = new ArrayObject( $to_sync_full ); $from = $obj->getIterator(); $transfer_args = [ 'concurrency' => $args_assoc['concurrency'], 'base_dir' => $path['basedir'], 'before' => function ( UglyRobot\Infinite_Uploads\Aws\Command $command ) use ( $args_assoc, $progress_bar, $wpdb, $unsynced, &$uploaded ) { if ( in_array( $command->getName(), [ 'PutObject', 'CreateMultipartUpload' ], true ) ) { /// Expires: if ( defined( 'INFINITE_UPLOADS_HTTP_EXPIRES' ) ) { $command['Expires'] = INFINITE_UPLOADS_HTTP_EXPIRES; } // Cache-Control: if ( defined( 'INFINITE_UPLOADS_HTTP_CACHE_CONTROL' ) ) { if ( is_numeric( INFINITE_UPLOADS_HTTP_CACHE_CONTROL ) ) { $command['CacheControl'] = 'max-age=' . INFINITE_UPLOADS_HTTP_CACHE_CONTROL; } else { $command['CacheControl'] = INFINITE_UPLOADS_HTTP_CACHE_CONTROL; } } } //add middleware to intercept result of each file upload if ( in_array( $command->getName(), [ 'PutObject', 'CompleteMultipartUpload' ], true ) ) { $command->getHandlerList()->appendSign( Middleware::mapResult( function ( ResultInterface $result ) use ( $args_assoc, $progress_bar, $command, $wpdb, $unsynced, &$uploaded ) { $uploaded ++; $file = '/' . urldecode( strstr( substr( $result['@metadata']["effectiveUri"], ( strrpos( $result['@metadata']["effectiveUri"], Infinite_Uploads::get_instance()->bucket ) + strlen( Infinite_Uploads::get_instance()->bucket ) ) ), '?', true ) ?: substr( $result['@metadata']["effectiveUri"], ( strrpos( $result['@metadata']["effectiveUri"], Infinite_Uploads::get_instance()->bucket ) + strlen( Infinite_Uploads::get_instance()->bucket ) ) ) ); $wpdb->update( "{$wpdb->base_prefix}infinite_uploads_files", [ 'synced' => 1, 'errors' => 0 ], [ 'file' => $file ] ); if ( $args_assoc['verbose'] ) { WP_CLI::success( sprintf( esc_html__( '%s - Synced %s of %s files.', 'infinite-uploads' ), $file, number_format_i18n( $uploaded ), number_format_i18n( $unsynced ) ) ); } else { $progress_bar->tick(); } return $result; } ) ); } }, ]; try { $manager = new Transfer( $s3, $from, 's3://' . $instance->bucket . '/', $transfer_args ); $manager->transfer(); } catch ( Exception $e ) { if ( method_exists( $e, 'getRequest' ) ) { $file = str_replace( trailingslashit( $instance->bucket ), '', $e->getRequest()->getRequestTarget() ); $error_count = $wpdb->get_var( $wpdb->prepare( "SELECT errors FROM `{$wpdb->base_prefix}infinite_uploads_files` WHERE file = %s", $file ) ); $error_count ++; if ( $error_count >= 3 ) { WP_CLI::warning( sprintf( esc_html__( 'Error uploading %s. Retries exceeded.', 'infinite-uploads' ), $file ) ); } else { WP_CLI::warning( sprintf( esc_html__( '%s error uploading %s. Queued for retry.', 'infinite-uploads' ), $e->getAwsErrorCode(), $file ) ); } $wpdb->update( "{$wpdb->base_prefix}infinite_uploads_files", [ 'errors' => $error_count ], [ 'file' => $file ] ); } elseif ( method_exists( $e, 'getMessage' ) ) { WP_CLI::warning( sprintf( esc_html__( 'There was an error during upload: %s. Queued for retry.', 'infinite-uploads' ), $e->getMessage() ) ); } else { WP_CLI::warning( sprintf( esc_html__( 'There was an error during upload: %s. Queued for retry.', 'infinite-uploads' ), 'Unknown Error' ) ); } } $is_done = ! (bool) $wpdb->get_var( "SELECT count(*) FROM `{$wpdb->base_prefix}infinite_uploads_files` WHERE synced = 0 AND errors < 3" ); if ( $is_done ) { $break = true; $progress = get_site_option( 'iup_files_scanned' ); $progress['sync_finished'] = time(); update_site_option( 'iup_files_scanned', $progress ); if ( ! $args_assoc['verbose'] ) { $progress_bar->finish(); } $error_count = $wpdb->get_var( "SELECT count(*) FROM `{$wpdb->base_prefix}infinite_uploads_files` WHERE synced = 0 AND errors >= 3" ); if ( $error_count ) { WP_CLI::warning( sprintf( esc_html__( 'Unable to upload %s files.', 'infinite-uploads' ), number_format_i18n( $error_count ) ) ); } WP_CLI::success( esc_html__( 'Sync complete!', 'infinite-uploads' ) ); } } } private function build_scan() { global $wpdb; $instance = Infinite_Uploads::get_instance(); $path = $instance->get_original_upload_dir_root(); WP_CLI::line( esc_html__( 'Scanning local filesystem...', 'infinite-uploads' ) ); $filelist = new Infinite_Uploads_Filelist( $path['basedir'], 9999, [] ); $filelist->start(); $stats = $instance->get_sync_stats(); WP_CLI::line( sprintf( esc_html__( '%s files (%s) found in uploads.', 'infinite-uploads' ), $stats['local_files'], $stats['local_size'] ) ); //now verify that we are logged into cloud if ( ! $this->verify_s3_access_constants() ) { return false; } $s3 = $instance->s3(); WP_CLI::line( esc_html__( 'Comparing to the cloud...', 'infinite-uploads' ) ); $prefix = ''; if ( strpos( $instance->bucket, '/' ) ) { $prefix = trailingslashit( str_replace( strtok( $instance->bucket, '/' ) . '/', '', $instance->bucket ) ); } $args = [ 'Bucket' => strtok( $instance->bucket, '/' ), 'Prefix' => $prefix, ]; //set flag $progress = get_site_option( 'iup_files_scanned' ); $progress['compare_started'] = time(); update_site_option( 'iup_files_scanned', $progress ); try { $results = $s3->getPaginator( 'ListObjectsV2', $args ); foreach ( $results as $result ) { $cloud_only_files = []; if ( $result['Contents'] ) { foreach ( $result['Contents'] as $object ) { $local_key = str_replace( untrailingslashit( $prefix ), '', $object['Key'] ); $file = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->base_prefix}infinite_uploads_files WHERE file = %s", $local_key ) ); if ( $file && ! $file->synced && $file->size == $object['Size'] ) { $wpdb->update( "{$wpdb->base_prefix}infinite_uploads_files", [ 'synced' => 1 ], [ 'file' => $local_key ] ); } if ( ! $file ) { $cloud_only_files[] = [ 'name' => $local_key, 'size' => $object['Size'], 'mtime' => strtotime( $object['LastModified']->__toString() ), 'type' => $instance->get_file_type( $local_key ), ]; } } } //flush new files to db if ( count( $cloud_only_files ) ) { $values = []; foreach ( $cloud_only_files as $file ) { $values[] = $wpdb->prepare( "(%s,%d,%d,%s,1,1)", $file['name'], $file['size'], $file['mtime'], $file['type'] ); } $query = "INSERT INTO {$wpdb->base_prefix}infinite_uploads_files (file, size, modified, type, synced, deleted) VALUES "; $query .= implode( ",\n", $values ); $query .= " ON DUPLICATE KEY UPDATE size = VALUES(size), modified = VALUES(modified), type = VALUES(type), synced = 1, deleted = 1, errors = 0"; $wpdb->query( $query ); } } //set flag $progress = get_site_option( 'iup_files_scanned' ); $progress['compare_finished'] = time(); update_site_option( 'iup_files_scanned', $progress ); } catch ( Exception $e ) { WP_CLI::error( $e->getMessage() ); } return true; } /** * Delete all files from the uploads directory that have been synced to Infinite Uploads cloud storage. * * @subcommand delete * @synopsis [--noscan] [--verbose] */ public function delete( $args, $args_assoc ) { global $wpdb; // Verify first that we have the necessary access keys to connect to S3. if ( ! $this->verify_s3_access_constants() ) { return; } $instance = Infinite_Uploads::get_instance(); $args_assoc = wp_parse_args( $args_assoc, [ 'noscan' => false, 'verbose' => false ] ); $path = $instance->get_original_upload_dir_root(); if ( ! $args_assoc['noscan'] ) { $this->build_scan(); $stats = $instance->get_sync_stats(); WP_CLI::line( sprintf( esc_html__( '%s files (%s) remaining to be synced.', 'infinite-uploads' ), $stats['remaining_files'], $stats['remaining_size'] ) ); } //begin deleting $deleted = 0; $to_delete = $wpdb->get_col( "SELECT file FROM `{$wpdb->base_prefix}infinite_uploads_files` WHERE synced = 1 AND deleted = 0" ); $progress_bar = null; if ( ! $args_assoc['verbose'] ) { $progress_bar = \WP_CLI\Utils\make_progress_bar( esc_html__( 'Deleting local copies of synced files...', 'infinite-uploads' ), count( $to_delete ) ); } foreach ( $to_delete as $file ) { if ( @unlink( $path['basedir'] . $file ) ) { $wpdb->update( "{$wpdb->base_prefix}infinite_uploads_files", [ 'deleted' => 1 ], [ 'file' => $file ] ); $deleted ++; if ( $args_assoc['verbose'] ) { WP_CLI::success( sprintf( esc_html__( '%s - Deleted %s of %s files.', 'infinite-uploads' ), $file, number_format_i18n( $deleted ), number_format_i18n( count( $to_delete ) ) ) ); } else { $progress_bar->tick(); } } else { WP_CLI::warning( sprintf( esc_html__( 'Could not delete %s.', 'infinite-uploads' ), $file ) ); } } if ( ! $args_assoc['verbose'] ) { $progress_bar->finish(); } WP_CLI::success( esc_html__( 'Delete complete!', 'infinite-uploads' ) ); } /** * Download all files only in Infinite Uploads cloud storage to the local uploads directory. * * @subcommand download * @synopsis [--concurrency=] [--noscan] [--verbose] */ public function download( $args, $args_assoc ) { global $wpdb; // Verify first that we have the necessary access keys to connect to S3. if ( ! $this->verify_s3_access_constants() ) { return; } $instance = Infinite_Uploads::get_instance(); $s3 = $instance->s3(); $args_assoc = wp_parse_args( $args_assoc, [ 'concurrency' => 20, 'noscan' => false, 'verbose' => false ] ); $path = $instance->get_original_upload_dir_root(); if ( ! $args_assoc['noscan'] ) { $this->build_scan(); $unsynced = $wpdb->get_row( "SELECT count(*) AS files, SUM(`size`) as size FROM `{$wpdb->base_prefix}infinite_uploads_files` WHERE synced = 1 AND deleted = 1" ); WP_CLI::line( sprintf( esc_html__( '%s files (%s) remaining to be downloaded.', 'infinite-uploads' ), $unsynced->files, size_format( $unsynced->size, 2 ) ) ); } //begin transfer if ( empty( $unsynced ) ) { $unsynced = $wpdb->get_row( "SELECT count(*) AS files, SUM(`size`) as size FROM `{$wpdb->base_prefix}infinite_uploads_files` WHERE synced = 1 AND deleted = 1" ); } $progress_bar = null; if ( ! $args_assoc['verbose'] ) { $progress_bar = \WP_CLI\Utils\make_progress_bar( esc_html__( 'Downloading from the cloud...', 'infinite-uploads' ), $unsynced->files ); } $progress = get_site_option( 'iup_files_scanned' ); if ( empty( $progress['download_started'] ) ) { $progress['download_started'] = time(); update_site_option( 'iup_files_scanned', $progress ); } $downloaded = 0; $break = false; while ( ! $break ) { $to_sync = $wpdb->get_col( "SELECT file FROM `{$wpdb->base_prefix}infinite_uploads_files` WHERE synced = 1 AND deleted = 1 AND errors < 3 LIMIT 1000" ); //build full paths $to_sync_full = []; foreach ( $to_sync as $key => $file ) { $to_sync_full[] = 's3://' . untrailingslashit( $instance->bucket ) . $file; } $obj = new ArrayObject( $to_sync_full ); $from = $obj->getIterator(); $transfer_args = [ 'concurrency' => $args_assoc['concurrency'], 'base_dir' => 's3://' . $instance->bucket, 'before' => function ( UglyRobot\Infinite_Uploads\Aws\Command $command ) use ( $args_assoc, $progress_bar, $wpdb, $unsynced, &$downloaded ) { //add middleware to intercept result of each file upload if ( in_array( $command->getName(), [ 'GetObject' ], true ) ) { $command->getHandlerList()->appendSign( Middleware::mapResult( function ( ResultInterface $result ) use ( $args_assoc, $progress_bar, $command, $wpdb, $unsynced, &$downloaded ) { $downloaded ++; $file = '/' . urldecode( strstr( substr( $result['@metadata']["effectiveUri"], ( strrpos( $result['@metadata']["effectiveUri"], Infinite_Uploads::get_instance()->bucket ) + strlen( Infinite_Uploads::get_instance()->bucket ) ) ), '?', true ) ?: substr( $result['@metadata']["effectiveUri"], ( strrpos( $result['@metadata']["effectiveUri"], Infinite_Uploads::get_instance()->bucket ) + strlen( Infinite_Uploads::get_instance()->bucket ) ) ) ); $wpdb->update( "{$wpdb->base_prefix}infinite_uploads_files", [ 'deleted' => 0, 'errors' => 0 ], [ 'file' => $file ] ); if ( $args_assoc['verbose'] ) { WP_CLI::success( sprintf( esc_html__( '%s - Downloaded %s of %s files.', 'infinite-uploads' ), $file, number_format_i18n( $downloaded ), number_format_i18n( $unsynced->files ) ) ); } else { $progress_bar->tick(); } return $result; } ) ); } }, ]; try { $manager = new Transfer( $s3, $from, $path['basedir'], $transfer_args ); $manager->transfer(); } catch ( Exception $e ) { if ( method_exists( $e, 'getRequest' ) ) { $file = str_replace( untrailingslashit( $path['basedir'] ), '', str_replace( trailingslashit( $instance->bucket ), '', $e->getRequest()->getRequestTarget() ) ); $error_count = $wpdb->get_var( $wpdb->prepare( "SELECT errors FROM `{$wpdb->base_prefix}infinite_uploads_files` WHERE file = %s", $file ) ); $error_count ++; if ( $error_count >= 3 ) { WP_CLI::warning( sprintf( esc_html__( 'Error downloading %s. Retries exceeded.', 'infinite-uploads' ), $file ) ); } else { WP_CLI::warning( sprintf( esc_html__( 'Error downloading %s. Queued for retry.', 'infinite-uploads' ), $file ) ); } $wpdb->update( "{$wpdb->base_prefix}infinite_uploads_files", [ 'errors' => $error_count ], [ 'file' => $file ] ); } else { WP_CLI::warning( sprintf( esc_html__( '%s error downloading %s. Queued for retry.', 'infinite-uploads' ), $e->getAwsErrorCode(), $file ) ); } } $is_done = ! (bool) $wpdb->get_var( "SELECT count(*) FROM `{$wpdb->base_prefix}infinite_uploads_files` WHERE synced = 1 AND deleted = 1 AND errors < 3" ); if ( $is_done ) { $break = true; $progress = get_site_option( 'iup_files_scanned' ); $progress['download_finished'] = time(); update_site_option( 'iup_files_scanned', $progress ); if ( ! $args_assoc['verbose'] ) { $progress_bar->finish(); } $error_count = $wpdb->get_var( "SELECT count(*) FROM `{$wpdb->base_prefix}infinite_uploads_files` WHERE synced = 1 AND deleted = 1 AND errors >= 3" ); if ( $error_count ) { WP_CLI::warning( sprintf( esc_html__( 'Unable to download %s files.', 'infinite-uploads' ), number_format_i18n( $error_count ) ) ); } WP_CLI::success( esc_html__( 'Download complete!', 'infinite-uploads' ) ); } } } /** * Delete files from Infinite Uploads cloud * * @synopsis [--regex=] */ public function rm( $args, $args_assoc ) { // Verify first that we have the necessary access keys to connect to S3. if ( ! $this->verify_s3_access_constants() ) { return; } $s3 = Infinite_Uploads::get_instance()->s3(); $prefix = ''; $regex = isset( $args_assoc['regex'] ) ? $args_assoc['regex'] : ''; if ( strpos( Infinite_Uploads::get_instance()->bucket, '/' ) ) { $prefix = trailingslashit( str_replace( strtok( Infinite_Uploads::get_instance()->bucket, '/' ) . '/', '', Infinite_Uploads::get_instance()->bucket ) ); } if ( isset( $args[0] ) ) { $prefix .= ltrim( $args[0], '/' ); if ( strpos( $args[0], '.' ) === false ) { $prefix = trailingslashit( $prefix ); } } try { $s3->deleteMatchingObjects( strtok( Infinite_Uploads::get_instance()->bucket, '/' ), $prefix, $regex, [ 'before_delete', function () { WP_CLI::line( sprintf( 'Deleting file' ) ); }, ] ); } catch ( Exception $e ) { WP_CLI::error( $e->getMessage() ); } WP_CLI::success( sprintf( 'Successfully deleted %s', $prefix ) ); } /** * Enable the auto-rewriting of media links to Infinite Uploads cloud */ public function enable( $args, $assoc_args ) { // Verify first that we have the necessary access keys to connect to S3. if ( ! $this->verify_s3_access_constants() ) { return; } Infinite_Uploads::get_instance()->toggle_cloud( true ); WP_CLI::success( 'Media URL rewriting enabled.' ); } /** * Disable the auto-rewriting of media links to Infinite Uploads cloud */ public function disable( $args, $assoc_args ) { Infinite_Uploads::get_instance()->toggle_cloud( false ); WP_CLI::success( 'Media URL rewriting disabled.' ); } } WP_CLI::add_command( 'infinite-uploads', 'Infinite_Uploads_WP_CLI_Command' );