Your IP : 216.73.216.44


Current Path : /home/krobertfnz/www/wp-content/plugins/vamtam-importers/
Upload File :
Current File : /home/krobertfnz/www/wp-content/plugins/vamtam-importers/vamtam-import-attachments.php

<?php

class Vamtam_Import_Attachments extends WP_Background_Process {

	/**
	 * @var string
	 */
	protected $action = 'vamtam_import_attachments';

	private $base_url = '';

	private function log( $message ) {
		error_log( $message );
	}

	public function get_queue_length() {
		global $wpdb;

		$table  = $wpdb->options;
		$column = 'option_name';
		$data_in = 'option_value';

		if ( is_multisite() ) {
			$table  = $wpdb->sitemeta;
			$column = 'meta_key';
			$data_in = 'meta_value';
		}

		$key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%';

		$batches = $wpdb->get_results( $wpdb->prepare( "
		SELECT *
		FROM {$table}
		WHERE {$column} LIKE %s
	", $key ) );

		$count = 0;

		foreach ( $batches as $batch ) {
			if ( isset( $batch->$data_in ) ) {
				$data = maybe_unserialize( $batch->$data_in );
				if ( is_countable( $data ) ) {
					$count += count( $data );
				}
			}
		}

		return $count;
	}

	/**
	 * Generate thumbnails for each imported image
	 * @return false
	 */
	protected function task( $task ) {
		// import, generate thumbnails, replace URLs
		if ( is_array( $task ) && isset( $task['step'] ) ) {
			$data = $task['data'];

			if ( $task['step'] === 1 ) {
				$this->base_url = $data['base_url'];

				$imported = $this->process_attachment( $data['attachment'][0], $data['attachment'][1] );

				if ( is_wp_error( $imported ) ) {
					$message = 'VAMTAM -- importing attachment failed:' . $data['attachment'][1] . " \n ";
					$message .='error: ' . $imported->get_error_message();
					$this->log( $message );

					return false;
				}

				$message = 'VAMTAM -- imported attachment:' . $data['attachment'][1] . " \n ";
				$this->log( $message );

				$old_remap = get_option( 'vamtam_import_attachments_url_remap', [] );
				update_option( 'vamtam_import_attachments_url_remap', array_merge( $old_remap, $imported['url_remap'] ) );

				return [
					'step' => 2,
					'data' => $imported,
				];
			} elseif ( $task['step'] === 2 ) {
				if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) {
					include ABSPATH . 'wp-admin/includes/image.php';
				}

				$new_metadata = wp_generate_attachment_metadata( $data['post_id'], get_attached_file( $data['post_id'] ) );

				$message = 'VAMTAM -- updating attachment ' . $data['post_id'] . get_attached_file( $data['post_id'] ) . " \n ";
				$message .='result: ' . (int)wp_update_attachment_metadata( $data['post_id'], $new_metadata );

				$this->log( $message );

				return false;
			}
		}

		return false;
	}

	protected function complete() {
		parent::complete();

		require 'vamtam-import-search-replace.php';

		$map = get_option( 'vamtam_last_import_map' );

		$this->remap_featured_images( $map['featured_images'], $map['posts'] );
		$this->backfill_attachment_urls( get_option( 'vamtam_import_attachments_url_remap', [] ) );
	}

	/**
	 * @override
	 * Maybe process queue
	 *
	 * Checks whether data exists within the queue and that
	 * the process is not already running.
	 */
	public function maybe_handle() {
		// Don't lock up other requests while processing
		session_write_close();

		$is_vamtam_importer = $this->action === 'vamtam_import_attachments';
		if ( $this->is_process_running() && ! $is_vamtam_importer ) {
			// Background process already running.
			wp_die();
		}

		if ( $this->is_queue_empty() ) {
			// No data to process.
			wp_die();
		}

		check_ajax_referer( $this->identifier, 'nonce' );

		$this->handle();

		wp_die();
	}

	/**
	 * Update _thumbnail_id meta to new, imported attachment IDs
	 */
	protected function remap_featured_images( $featured_images, $processed_posts ) {
		// cycle through posts that have a featured image
		foreach ( $featured_images as $post_id => $value ) {
			if ( isset( $processed_posts[$value] ) ) {
				$new_id = $processed_posts[$value];
				// only update if there's a difference
				if ( $new_id != $value ) {
					update_post_meta( $post_id, '_thumbnail_id', $new_id );
				}
			}
		}
	}

	/**
	 * Use stored mapping information to update old attachment URLs
	 *
	 * With Beaver support - see https://stackoverflow.com/a/3277781/635882
	 */
	protected function backfill_attachment_urls( $url_remap ) {
		global $wpdb;

		// make sure we do the longest urls first, in case one is a substring of another
		uksort( $url_remap, function( $a, $b ) {
			return strlen( $b ) - strlen( $a );
		} );

		foreach ( $url_remap as $from_url => $to_url ) {
			// remap urls in post_content
			$wpdb->query( $wpdb->prepare("UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)", $from_url, $to_url) );

			// Beaver Builder support - replace serialized data in the postmeta and options tables
			$search = 's:' . strlen( $from_url) . ':"' . $from_url . '"';
			$replace = 's:' . strlen( $to_url ) . ':"' . $to_url . '"';

			$result = $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_value = REPLACE(meta_value, %s, %s)", $search, $replace ) );
			$result = $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->options} SET option_value = REPLACE(option_value, %s, %s)", $search, $replace ) );

			$meta_to_repace = $wpdb->get_results( $wpdb->prepare( "SELECT meta_id, meta_value FROM {$wpdb->postmeta} WHERE meta_value LIKE '%%%s%%'", $from_url ) );

			foreach ( $meta_to_repace as $meta ) {
				$meta->meta_value = Vamtam_Import_Search_Replace::recursive_unserialize_replace( $from_url, $to_url, $meta->meta_value );

				if ( ! is_string( $meta->meta_value ) ) {
					$meta->meta_value = serialize( $meta->meta_value );
				}

				$wpdb->update(
					$wpdb->postmeta,
					array(
						'meta_value' => $meta->meta_value,
					),
					array( 'meta_id' => $meta->meta_id ),
					array(
						'%s',
					),
					array( '%d' )
				);
			}
		}
	}

	/**
	 * If fetching attachments is enabled then attempt to create a new attachment
	 *
	 * @param array $post Attachment post details from WXR
	 * @param string $url URL to fetch attachment from
	 * @return int|WP_Error Post ID on success, WP_Error otherwise
	 */
	protected function process_attachment( $post, $url ) {
		if ( ! apply_filters( 'import_allow_fetch_attachments', true ) ) {
			return new WP_Error( 'attachment_processing_error',
				__( 'Fetching attachments is not enabled', 'wordpress-importer' ) );
		}

		$post_exists = post_exists( $post['post_title'], '', $post['post_date'] );

		/**
		* Filter ID of the existing post corresponding to post currently importing.
		*
		* Return 0 to force the post to be imported. Filter the ID to be something else
		* to override which existing post is mapped to the imported post.
		*
		* @see post_exists()
		* @since 0.6.2
		*
		* @param int   $post_exists  Post ID, or 0 if post did not exist.
		* @param array $post         The post array to be inserted.
		*/
		$post_exists = apply_filters( 'wp_import_existing_post', $post_exists, $post );

		// if the URL is absolute, but does not contain address, then upload it assuming base_site_url
		if ( preg_match( '|^/[\w\W]+$|', $url ) ) {
			$url = rtrim( $this->base_url, '/' ) . $url;
		}

		$fetched = $this->fetch_remote_file( $url, $post );
		if ( is_wp_error( $fetched ) ) {
			return $fetched;
		}

		extract( $fetched );

		if ( $info = wp_check_filetype( $upload['file'] ) ) {
			$post['post_mime_type'] = $info['type'];
		} else {
			return new WP_Error( 'attachment_processing_error', __('Invalid file type', 'wordpress-importer') );
		}

		$post['guid'] = $upload['url'];

		// as per wp-admin/includes/upload.php
		$post_id = wp_insert_attachment( $post, $upload['file'] );

		add_filter( 'intermediate_image_sizes_advanced', '__return_false' );
		wp_update_attachment_metadata( $post_id, wp_generate_attachment_metadata( $post_id, $upload['file'] ) );
		remove_filter( 'intermediate_image_sizes_advanced', '__return_false' );

		$result = [
			'post_id'   => $post_id,
			'url_remap' => $url_remap,
		];

		// remap resized image URLs, works by stripping the extension and remapping the URL stub.
		if ( preg_match( '!^image/!', $info['type'] ) ) {
			$parts = pathinfo( $url );
			$name = basename( $parts['basename'], ".{$parts['extension']}" ); // PATHINFO_FILENAME in PHP 5.2

			$parts_new = pathinfo( $upload['url'] );
			$name_new = basename( $parts_new['basename'], ".{$parts_new['extension']}" );

			$result['url_remap'][ $parts['dirname'] . '/' . $name ] = $parts_new['dirname'] . '/' . $name_new;
		}

		$map = get_option( 'vamtam_last_import_map' );

		$map['posts'][ $post['import_id'] ] = $post_id;

		update_option( 'vamtam_last_import_map', $map );

		Vamtam_Importers::process_post_additional_data( $post, $post_id, $post_exists, $map['authors'] );

		return $result;
	}

	/**
	 * Attempt to download a remote file attachment
	 *
	 * @param string $url URL of item to fetch
	 * @param array $post Attachment details
	 * @return array|WP_Error Local file location details on success, WP_Error otherwise
	 */
	protected function fetch_remote_file( $url, $post ) {
		// extract the file name and extension from the url
		$file_name = basename( $url );

		// get placeholder file in the upload dir with a unique, sanitized filename
		$upload = wp_upload_bits( $file_name, 0, '', $post['upload_date'] );
		if ( $upload['error'] ) {
			return new WP_Error( 'upload_dir_error', $upload['error'] );
		}

		// fetch the remote url and write it to the placeholder file
		$remote_response = wp_safe_remote_get( $url, array(
			'timeout' => 300,
			'stream' => true,
			'filename' => $upload['file'],
		) );
		$headers = wp_remote_retrieve_headers( $remote_response );

		// request failed
		if ( ! $headers ) {
			@unlink( $upload['file'] );
			return new WP_Error( 'import_file_error', __('Remote server did not respond', 'wordpress-importer') );
		}

		$remote_response_code = wp_remote_retrieve_response_code( $remote_response );

		// make sure the fetch was successful
		if ( $remote_response_code != '200' ) {
			@unlink( $upload['file'] );
			return new WP_Error( 'import_file_error', sprintf( __('Remote server returned error response %1$d %2$s', 'wordpress-importer'), esc_html($remote_response_code), get_status_header_desc($remote_response_code) ) );
		}

		$filesize = filesize( $upload['file'] );

		if ( isset( $headers['content-length'] ) && $filesize != $headers['content-length'] ) {
			@unlink( $upload['file'] );
			return new WP_Error( 'import_file_error', __('Remote file is incorrect size', 'wordpress-importer') );
		}

		if ( 0 == $filesize ) {
			@unlink( $upload['file'] );
			return new WP_Error( 'import_file_error', __('Zero size file downloaded', 'wordpress-importer') );
		}

		$max_size = (int) apply_filters( 'import_attachment_size_limit', 0 );
		if ( ! empty( $max_size ) && $filesize > $max_size ) {
			@unlink( $upload['file'] );
			return new WP_Error( 'import_file_error', sprintf(__('Remote file is too large, limit is %s', 'wordpress-importer'), size_format($max_size) ) );
		}

		// keep track of the old and new urls so we can substitute them later
		$result = [
			'upload'    => $upload,
			'url_remap' => [
				$url          => $upload['url'],
				$post['guid'] => $upload['url'],
			]
		];
		// keep track of the destination if the remote url is redirected somewhere else
		if ( isset($headers['x-final-location']) && $headers['x-final-location'] != $url ) {
			$result['url_remap'][ $headers['x-final-location'] ] = $upload['url'];
		}

		return $result;
	}
}