array(), ); } /** * Prepare a manifest based on the item. * * @param Item $as3cf_item * @param array $options * * @return Manifest */ protected function pre_handle( Item $as3cf_item, array $options ) { $manifest = new Manifest(); $file_paths = array(); foreach ( $as3cf_item->objects() as $object_key => $object ) { $file = $as3cf_item->full_source_path( $object_key ); if ( 0 < count( $options['full_source_paths'] ) && ! in_array( $file, $options['full_source_paths'] ) ) { continue; } $file_paths[ $object_key ] = $file; } $file_paths = array_unique( $file_paths ); foreach ( $file_paths as $object_key => $file_path ) { if ( ! file_exists( $file_path ) ) { $manifest->objects[] = array( 'args' => array( 'Bucket' => $as3cf_item->bucket(), 'Key' => $as3cf_item->provider_key( $object_key ), 'SaveAs' => $file_path, ), ); } } return $manifest; } /** * Perform the downloads. * * @param Item $as3cf_item * @param Manifest $manifest * @param array $options * * @return boolean|WP_Error * @throws Exception */ protected function handle_item( Item $as3cf_item, Manifest $manifest, array $options ) { if ( ! empty( $manifest->objects ) ) { // This test is "late" so that we don't raise the error if the local files exist anyway. // If the provider of this item is different from what's currently configured, // we'll return an error. $current_provider = $this->as3cf->get_storage_provider(); if ( ! is_null( $current_provider ) && $current_provider::get_provider_key_name() !== $as3cf_item->provider() ) { $error_msg = sprintf( __( '%1$s with ID %2$d is offloaded to a different provider than currently configured', 'amazon-s3-and-cloudfront' ), $this->as3cf->get_source_type_name( $as3cf_item->source_type() ), $as3cf_item->source_id() ); return $this->return_handler_error( $error_msg ); } else { $provider_client = $this->as3cf->get_provider_client( $as3cf_item->region() ); foreach ( $manifest->objects as &$manifest_object ) { // Save object to a file. $result = $this->download_object( $provider_client, $manifest_object['args'] ); $manifest_object['download_result']['status'] = self::STATUS_OK; if ( is_wp_error( $result ) ) { $manifest_object['download_result']['status'] = self::STATUS_FAILED; $manifest_object['download_result']['message'] = $result->get_error_message(); } } } } return true; } /** * Perform post handle tasks. Log errors, update filesize totals etc. * * @param Item $as3cf_item * @param Manifest $manifest * @param array $options * * @return bool|WP_Error */ protected function post_handle( Item $as3cf_item, Manifest $manifest, array $options ) { $error_count = 0; foreach ( $manifest->objects as $manifest_object ) { if ( self::STATUS_OK !== $manifest_object['download_result']['status'] ) { $error_count++; } } if ( $error_count > 0 ) { $error_message = sprintf( __( 'There were %1$d errors downloading files for %2$s ID %3$d from bucket', 'amazon-s3-and-cloudfront' ), $error_count, $this->as3cf->get_source_type_name( $as3cf_item->source_type() ), $as3cf_item->source_id() ); return new WP_Error( 'download-error', $error_message ); } $as3cf_item->update_filesize_after_download_local(); return true; } /** * Download an object from provider. * * @param Storage_Provider $provider_client * @param array $object * * @return bool|WP_Error */ private function download_object( $provider_client, $object ) { // Make sure the local directory exists. $dir = dirname( $object['SaveAs'] ); if ( ! is_dir( $dir ) && ! wp_mkdir_p( $dir ) ) { $error_msg = sprintf( __( 'The local directory %s does not exist and could not be created.', 'amazon-s3-and-cloudfront' ), $dir ); $error_msg = sprintf( __( 'There was an error attempting to download the file %1$s from the bucket: %2$s', 'amazon-s3-and-cloudfront' ), $object['Key'], $error_msg ); return $this->return_handler_error( $error_msg ); } try { $provider_client->get_object( $object ); } catch ( Exception $e ) { // If storage provider file doesn't exist, an empty local file will be created, clean it up. @unlink( $object['SaveAs'] ); //phpcs:ignore $error_msg = sprintf( __( 'Error downloading %1$s from bucket: %2$s', 'amazon-s3-and-cloudfront' ), $object['Key'], $e->getMessage() ); return $this->return_handler_error( $error_msg ); } return true; } }