first commit
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
class WPML_Media_Add_To_Translation_Package_Factory implements IWPML_Backend_Action_Loader {
|
||||
|
||||
public function create() {
|
||||
return new WPML_Media_Add_To_Translation_Package( new WPML_Media_Post_With_Media_Files_Factory() );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
|
||||
class WPML_Media_Add_To_Translation_Package implements IWPML_Action {
|
||||
|
||||
const ALT_PLACEHOLDER = '{%ALT_TEXT%}';
|
||||
const CAPTION_PLACEHOLDER = '{%CAPTION%}';
|
||||
|
||||
/** @var WPML_Media_Post_With_Media_Files_Factory $post_media_factory */
|
||||
private $post_media_factory;
|
||||
|
||||
public function __construct( WPML_Media_Post_With_Media_Files_Factory $post_media_factory ) {
|
||||
$this->post_media_factory = $post_media_factory;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
|
||||
add_action( 'wpml_tm_translation_job_data', array( $this, 'add_media_strings' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
|
||||
public function add_media_strings( $package, $post ) {
|
||||
|
||||
$basket = TranslationProxy_Basket::get_basket( true );
|
||||
|
||||
$bundled_media_data = $this->get_bundled_media_to_translate( $post );
|
||||
if ( $bundled_media_data ) {
|
||||
|
||||
foreach ( $bundled_media_data as $attachment_id => $data ) {
|
||||
foreach ( $data as $field => $value ) {
|
||||
if (
|
||||
isset( $basket['post'][ $post->ID ]['media-translation'] ) &&
|
||||
! in_array( $attachment_id, $basket['post'][ $post->ID ]['media-translation'] )
|
||||
) {
|
||||
$options = array(
|
||||
'translate' => 0,
|
||||
'data' => true,
|
||||
'format' => '',
|
||||
);
|
||||
} else {
|
||||
$options = array(
|
||||
'translate' => 1,
|
||||
'data' => base64_encode( $value ),
|
||||
'format' => 'base64',
|
||||
);
|
||||
}
|
||||
$package['contents'][ 'media_' . $attachment_id . '_' . $field ] = $options;
|
||||
}
|
||||
|
||||
if (
|
||||
isset( $basket['post'][ $post->ID ]['media-translation'] ) &&
|
||||
in_array( $attachment_id, $basket['post'][ $post->ID ]['media-translation'] )
|
||||
) {
|
||||
$package['contents'][ 'should_translate_media_image_' . $attachment_id ] = array(
|
||||
'translate' => 0,
|
||||
'data' => true,
|
||||
'format' => '',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$package = $this->add_placeholders_for_duplicate_fields( $package, $bundled_media_data );
|
||||
|
||||
}
|
||||
|
||||
return $package;
|
||||
}
|
||||
|
||||
private function get_bundled_media_to_translate( $post ) {
|
||||
|
||||
$post_media = $this->post_media_factory->create( $post->ID );
|
||||
$bundled_media_data = array();
|
||||
|
||||
foreach ( $post_media->get_media_ids() as $attachment_id ) {
|
||||
$attachment = get_post( $attachment_id );
|
||||
|
||||
if ( $attachment->post_title ) {
|
||||
$bundled_media_data[ $attachment_id ]['title'] = $attachment->post_title;
|
||||
}
|
||||
if ( $attachment->post_excerpt ) {
|
||||
$bundled_media_data[ $attachment_id ]['caption'] = $attachment->post_excerpt;
|
||||
}
|
||||
if ( $attachment->post_content ) {
|
||||
$bundled_media_data[ $attachment_id ]['description'] = $attachment->post_content;
|
||||
}
|
||||
if ( $alt = get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) {
|
||||
$bundled_media_data[ $attachment_id ]['alt_text'] = $alt;
|
||||
}
|
||||
}
|
||||
|
||||
return $bundled_media_data;
|
||||
|
||||
}
|
||||
|
||||
private function add_placeholders_for_duplicate_fields( $package, $bundled_media_data ) {
|
||||
|
||||
$caption_parser = new WPML_Media_Caption_Tags_Parse();
|
||||
|
||||
foreach ( $package['contents'] as $field => $data ) {
|
||||
if ( $data['translate'] && 'base64' === $data['format'] ) {
|
||||
$original = $content = base64_decode( $data['data'] );
|
||||
|
||||
$captions = $caption_parser->get_captions( $content );
|
||||
|
||||
foreach ( $captions as $caption ) {
|
||||
$caption_id = $caption->get_id();
|
||||
$caption_shortcode = $new_caption_shortcode = $caption->get_shortcode_string();
|
||||
|
||||
if ( isset( $bundled_media_data[ $caption_id ] ) ) {
|
||||
|
||||
if ( isset( $bundled_media_data[ $caption_id ]['caption'] ) && $bundled_media_data[ $caption_id ]['caption'] === $caption->get_caption() ) {
|
||||
$new_caption_shortcode = $this->replace_caption_with_placeholder( $new_caption_shortcode, $caption );
|
||||
}
|
||||
|
||||
if ( isset( $bundled_media_data[ $caption_id ]['alt_text'] ) && $bundled_media_data[ $caption_id ]['alt_text'] === $caption->get_image_alt() ) {
|
||||
$new_caption_shortcode = $this->replace_alt_text_with_placeholder( $new_caption_shortcode, $caption );
|
||||
}
|
||||
|
||||
if ( $new_caption_shortcode !== $caption_shortcode ) {
|
||||
$content = str_replace( $caption_shortcode, $new_caption_shortcode, $content );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $content !== $original ) {
|
||||
$package['contents'][ $field ]['data'] = base64_encode( $content );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $package;
|
||||
}
|
||||
|
||||
private function replace_caption_with_placeholder( $caption_shortcode, WPML_Media_Caption $caption ) {
|
||||
$caption_content = $caption->get_content();
|
||||
$search_pattern = '/(>\s?)(' . preg_quote( $caption->get_caption(), '/' ) . ')/';
|
||||
$new_caption_content = preg_replace( $search_pattern, '$1' . self::CAPTION_PLACEHOLDER, $caption_content, 1 );
|
||||
|
||||
return str_replace( $caption_content, $new_caption_content, $caption_shortcode );
|
||||
|
||||
}
|
||||
|
||||
private function replace_alt_text_with_placeholder( $caption_shortcode, WPML_Media_Caption $caption ) {
|
||||
|
||||
$alt_text = $caption->get_image_alt();
|
||||
return str_replace( 'alt="' . $alt_text . '"', 'alt="' . self::ALT_PLACEHOLDER . '"', $caption_shortcode );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_Media_Attachment_Image_Update_Factory
|
||||
*/
|
||||
class WPML_Media_Attachment_Image_Update_Factory implements IWPML_Backend_Action_Loader {
|
||||
|
||||
public function create() {
|
||||
global $wpdb;
|
||||
|
||||
return new WPML_Media_Attachment_Image_Update( $wpdb );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_Media_Attachment_Image_Update
|
||||
* Allows adding a custom image to a translated attachment
|
||||
*/
|
||||
class WPML_Media_Attachment_Image_Update implements IWPML_Action {
|
||||
|
||||
const TRANSIENT_FILE_UPLOAD_PREFIX = 'wpml_media_file_update_';
|
||||
|
||||
/**
|
||||
* @var wpdb
|
||||
*/
|
||||
private $wpdb;
|
||||
|
||||
/**
|
||||
* WPML_Media_Attachment_Image_Update constructor.
|
||||
*
|
||||
* @param wpdb $wpdb
|
||||
*/
|
||||
public function __construct( wpdb $wpdb ) {
|
||||
$this->wpdb = $wpdb;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'wp_ajax_wpml_media_upload_file', array( $this, 'handle_upload' ) );
|
||||
}
|
||||
|
||||
public function handle_upload() {
|
||||
if ( $this->is_valid_action() ) {
|
||||
|
||||
$original_attachment_id = (int) $_POST['original-attachment-id'];
|
||||
$attachment_id = (int) $_POST['attachment-id'];
|
||||
$file_array = $_FILES['file'];
|
||||
$target_language = $_POST['language'];
|
||||
|
||||
$thumb_path = '';
|
||||
$thumb_url = '';
|
||||
|
||||
$upload_overrides = apply_filters( 'wpml_media_wp_upload_overrides', array( 'test_form' => false ) );
|
||||
$file = wp_handle_upload( $file_array, $upload_overrides );
|
||||
|
||||
if ( ! isset( $file['error'] ) ) {
|
||||
|
||||
if ( wp_image_editor_supports( array( 'mime_type' => $file['type'] ) ) ) {
|
||||
|
||||
$editor = wp_get_image_editor( $file['file'] );
|
||||
|
||||
if ( ! is_wp_error( $editor ) ) {
|
||||
|
||||
$size = $editor->get_size();
|
||||
if ( $size['width'] > 150 || $size['height'] > 150 ) {
|
||||
$resizing = $editor->resize( 150, 150, true );
|
||||
|
||||
if ( is_wp_error( $resizing ) ) {
|
||||
wp_send_json_error( $resizing->get_error_message() );
|
||||
}
|
||||
}
|
||||
$thumb = $editor->save();
|
||||
|
||||
if ( ! empty( $thumb ) ) {
|
||||
$uploads_dir = wp_get_upload_dir();
|
||||
|
||||
$thumb_url = $uploads_dir['baseurl'] . $uploads_dir['subdir'] . '/' . $thumb['file'];
|
||||
$thumb_path = $thumb['path'];
|
||||
}
|
||||
} else {
|
||||
wp_send_json_error( __( 'Failed to load the image editor', 'wpml-media' ) );
|
||||
}
|
||||
} elseif ( 0 === strpos( $file['type'], 'image/' ) ) {
|
||||
$thumb_url = $file['url'];
|
||||
$thumb_path = $file['file'];
|
||||
} else {
|
||||
$thumb_url = wp_mime_type_icon( $original_attachment_id );
|
||||
}
|
||||
|
||||
set_transient(
|
||||
self::TRANSIENT_FILE_UPLOAD_PREFIX . $original_attachment_id . '_' . $target_language,
|
||||
array(
|
||||
'upload' => $file,
|
||||
'thumb' => $thumb_path,
|
||||
),
|
||||
HOUR_IN_SECONDS
|
||||
);
|
||||
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'attachment_id' => $attachment_id,
|
||||
'thumb' => $thumb_url,
|
||||
'name' => basename( $file['file'] ),
|
||||
)
|
||||
);
|
||||
|
||||
} else {
|
||||
wp_send_json_error( $file['error'] );
|
||||
}
|
||||
} else {
|
||||
wp_send_json_error( 'invalid action' );
|
||||
}
|
||||
}
|
||||
|
||||
private function is_valid_action() {
|
||||
$is_attachment_id = isset( $_POST['attachment-id'] );
|
||||
$is_post_action = isset( $_POST['action'] ) && 'wpml_media_upload_file' === $_POST['action'];
|
||||
|
||||
return $is_attachment_id && $is_post_action && wp_verify_nonce( $_POST['wpnonce'], 'media-translation' );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_Media_Caption_Tags_Parse
|
||||
*/
|
||||
class WPML_Media_Caption_Tags_Parse {
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_captions( $text ) {
|
||||
$captions = array();
|
||||
|
||||
if ( preg_match_all( '/\[caption (.+)\](.+)\[\/caption\]/sU', $text, $matches ) ) {
|
||||
|
||||
for ( $i = 0; $i < count( $matches[0] ); $i++ ) {
|
||||
$captions[] = new WPML_Media_Caption( $matches[0][ $i ], $matches[1][ $i ], $matches[2][ $i ] );
|
||||
}
|
||||
}
|
||||
|
||||
return $captions;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_Media_Caption
|
||||
*/
|
||||
class WPML_Media_Caption {
|
||||
|
||||
private $shortcode;
|
||||
private $content_string;
|
||||
private $attributes;
|
||||
private $attachment_id;
|
||||
private $link;
|
||||
private $img;
|
||||
private $caption;
|
||||
|
||||
public function __construct( $caption_shortcode, $attributes_data, $content_string ) {
|
||||
$this->shortcode = $caption_shortcode;
|
||||
$this->content_string = $content_string;
|
||||
|
||||
$this->attributes = $this->find_attributes_array( $attributes_data );
|
||||
$this->attachment_id = $this->find_attachment_id( $this->attributes );
|
||||
|
||||
$this->link = $this->find_link( $content_string );
|
||||
|
||||
$img_parser = new WPML_Media_Img_Parse();
|
||||
$this->img = current( $img_parser->get_imgs( $content_string ) );
|
||||
$this->caption = trim( strip_tags( $content_string ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_id() {
|
||||
return $this->attachment_id;
|
||||
}
|
||||
|
||||
public function get_caption() {
|
||||
return $this->caption;
|
||||
}
|
||||
|
||||
public function get_shortcode_string() {
|
||||
return $this->shortcode;
|
||||
}
|
||||
|
||||
public function get_content() {
|
||||
return $this->content_string;
|
||||
}
|
||||
|
||||
public function get_image_alt() {
|
||||
if ( isset( $this->img['attributes']['alt'] ) ) {
|
||||
return $this->img['attributes']['alt'];
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
public function get_link() {
|
||||
return $this->link;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $attributes_list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function find_attributes_array( $attributes_list ) {
|
||||
$attributes = array();
|
||||
if ( preg_match_all( '/(\S+)=["\']?((?:.(?!["\']?\s+(?:\S+)=|[>"\']))+.)["\']?/', $attributes_list, $attribute_matches ) ) {
|
||||
foreach ( $attribute_matches[1] as $k => $key ) {
|
||||
$attributes[ $key ] = $attribute_matches[2][ $k ];
|
||||
}
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return null|int
|
||||
*/
|
||||
private function find_attachment_id( $attributes ) {
|
||||
$attachment_id = null;
|
||||
if ( isset( $attributes['id'] ) ) {
|
||||
if ( preg_match( '/attachment_([0-9]+)\b/', $attributes['id'], $id_match ) ) {
|
||||
if ( 'attachment' === get_post_type( (int) $id_match[1] ) ) {
|
||||
$attachment_id = (int) $id_match[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $attachment_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $string
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function find_link( $string ) {
|
||||
$link = array();
|
||||
if ( preg_match( '/<a ([^>]+)>(.+)<\/a>/s', $string, $a_match ) ) {
|
||||
if ( preg_match( '/href=["\']([^"]+)["\']/', $a_match[1], $url_match ) ) {
|
||||
$link['url'] = $url_match[1];
|
||||
}
|
||||
}
|
||||
|
||||
return $link;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_Media_Custom_Field_Images_Translation_Factory
|
||||
*/
|
||||
class WPML_Media_Custom_Field_Images_Translation_Factory implements IWPML_Backend_Action_Loader {
|
||||
|
||||
public function create() {
|
||||
global $sitepress, $iclTranslationManagement;
|
||||
|
||||
$media_localization_settings = WPML_Media::get_setting( 'media_files_localization' );
|
||||
|
||||
if ( $media_localization_settings['custom_fields'] || WPML_Media_Custom_Field_Batch_Url_Translation::is_ajax_request() ) {
|
||||
$image_translator = new WPML_Media_Image_Translate( $sitepress, new WPML_Media_Attachment_By_URL_Factory() );
|
||||
$image_updater = new WPML_Media_Translated_Images_Update( new WPML_Media_Img_Parse(), $image_translator, new WPML_Media_Sizes() );
|
||||
|
||||
return new WPML_Media_Custom_Field_Images_Translation( $image_updater, $sitepress, $iclTranslationManagement );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_Media_Custom_Field_Images_Translation
|
||||
* Translate images in posts custom fields translations when a custom field is created or updated
|
||||
*/
|
||||
class WPML_Media_Custom_Field_Images_Translation implements IWPML_Action {
|
||||
|
||||
/**
|
||||
* @var WPML_Media_Custom_Field_Images_Translation
|
||||
*/
|
||||
private $images_updater;
|
||||
/**
|
||||
* @var SitePress
|
||||
*/
|
||||
private $sitepress;
|
||||
/**
|
||||
* @var TranslationManagement
|
||||
*/
|
||||
private $iclTranslationManagement;
|
||||
|
||||
/**
|
||||
* WPML_Media_Custom_Field_Images_Translation constructor.
|
||||
*
|
||||
* @param WPML_Media_Translated_Images_Update $images_updater
|
||||
* @param SitePress $sitepress
|
||||
* @param TranslationManagement $iclTranslationManagement
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_Media_Translated_Images_Update $images_updater,
|
||||
SitePress $sitepress,
|
||||
TranslationManagement $iclTranslationManagement
|
||||
|
||||
) {
|
||||
$this->images_updater = $images_updater;
|
||||
$this->sitepress = $sitepress;
|
||||
$this->iclTranslationManagement = $iclTranslationManagement;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'updated_post_meta', array( $this, 'translate_images' ), PHP_INT_MAX, 4 );
|
||||
add_action( 'added_post_meta', array( $this, 'translate_images' ), PHP_INT_MAX, 4 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $meta_id
|
||||
* @param int $object_id
|
||||
* @param string $meta_key
|
||||
* @param string $meta_value
|
||||
*/
|
||||
public function translate_images( $meta_id, $object_id, $meta_key, $meta_value ) {
|
||||
|
||||
$settings_factory = new WPML_Custom_Field_Setting_Factory( $this->iclTranslationManagement );
|
||||
$setting = $settings_factory->post_meta_setting( $meta_key );
|
||||
|
||||
$is_custom_field_translatable = $this->sitepress->get_wp_api()
|
||||
->constant( 'WPML_TRANSLATE_CUSTOM_FIELD' ) === $setting->status();
|
||||
$post_type = get_post_type( $object_id );
|
||||
$is_post_translatable = $this->sitepress->is_translated_post_type( $post_type );
|
||||
|
||||
if ( is_string( $meta_value ) && $is_post_translatable && $is_custom_field_translatable ) {
|
||||
$post_element = new WPML_Post_Element( $object_id, $this->sitepress );
|
||||
$source_language = $post_element->get_source_language_code();
|
||||
if ( null !== $source_language ) {
|
||||
$this->filter_meta_value_and_update(
|
||||
$meta_value,
|
||||
$meta_key,
|
||||
$post_element->get_language_code(),
|
||||
$source_language,
|
||||
$object_id
|
||||
);
|
||||
} else {
|
||||
foreach ( array_keys( $this->sitepress->get_active_languages() ) as $language ) {
|
||||
$translation = $post_element->get_translation( $language );
|
||||
if ( $translation ) {
|
||||
$this->filter_meta_value_and_update(
|
||||
$meta_value,
|
||||
$meta_key,
|
||||
$language,
|
||||
$source_language,
|
||||
$translation->get_id()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $meta_value
|
||||
* @param string $meta_key
|
||||
* @param string $target_language
|
||||
* @param string $source_language
|
||||
* @param int $post_id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function filter_meta_value_and_update( $meta_value, $meta_key, $target_language, $source_language, $post_id ) {
|
||||
$meta_value_filtered = $this->images_updater->replace_images_with_translations(
|
||||
$meta_value,
|
||||
$target_language,
|
||||
$source_language
|
||||
);
|
||||
|
||||
if ( $meta_value_filtered !== $meta_value ) {
|
||||
remove_action( 'updated_post_meta', array( $this, 'translate_images' ), PHP_INT_MAX );
|
||||
update_post_meta( $post_id, $meta_key, wp_slash( $meta_value_filtered ), $meta_value );
|
||||
add_action( 'updated_post_meta', array( $this, 'translate_images' ), PHP_INT_MAX, 4 );
|
||||
}
|
||||
|
||||
return $meta_value_filtered;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_Media_Image_Translate
|
||||
* Allows getting translated images in a give language from an attachment
|
||||
*/
|
||||
class WPML_Media_Image_Translate {
|
||||
|
||||
/**
|
||||
* @var SitePress
|
||||
*/
|
||||
private $sitepress;
|
||||
|
||||
/**
|
||||
* @var WPML_Media_Attachment_By_URL_Factory
|
||||
*/
|
||||
private $attachment_by_url_factory;
|
||||
|
||||
/**
|
||||
* WPML_Media_Image_Translate constructor.
|
||||
*
|
||||
* @param SitePress $sitepress
|
||||
* @param WPML_Media_Attachment_By_URL_Factory $attachment_by_url_factory
|
||||
*/
|
||||
public function __construct( SitePress $sitepress, WPML_Media_Attachment_By_URL_Factory $attachment_by_url_factory ) {
|
||||
$this->sitepress = $sitepress;
|
||||
$this->attachment_by_url_factory = $attachment_by_url_factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $attachment_id
|
||||
* @param string $language
|
||||
* @param string $size
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_translated_image( $attachment_id, $language, $size = null ) {
|
||||
$image_url = '';
|
||||
$attachment = new WPML_Post_Element( $attachment_id, $this->sitepress );
|
||||
$attachment_translation = $attachment->get_translation( $language );
|
||||
|
||||
if ( $attachment_translation ) {
|
||||
$uploads_dir = wp_get_upload_dir();
|
||||
$attachment_id = $attachment_translation->get_id();
|
||||
if ( null === $size ) {
|
||||
$image_url = $uploads_dir['baseurl'] . '/' . get_post_meta( $attachment_id, '_wp_attached_file', true );
|
||||
} else {
|
||||
$image_url = $this->get_sized_image_url( $attachment_id, $size, $uploads_dir );
|
||||
}
|
||||
}
|
||||
|
||||
return $image_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $img_src
|
||||
* @param string $source_language
|
||||
* @param string $target_language
|
||||
*
|
||||
* @return string|bool
|
||||
*/
|
||||
public function get_translated_image_by_url( $img_src, $source_language, $target_language ) {
|
||||
|
||||
$attachment_id = $this->get_attachment_id_by_url( $img_src, $source_language );
|
||||
|
||||
if ( $attachment_id ) {
|
||||
$size = $this->get_image_size_from_url( $img_src, $attachment_id );
|
||||
try {
|
||||
$img_src = $this->get_translated_image( $attachment_id, $target_language, $size );
|
||||
} catch ( Exception $e ) {
|
||||
$img_src = false;
|
||||
}
|
||||
} else {
|
||||
$img_src = false;
|
||||
}
|
||||
|
||||
return $img_src;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $img_src
|
||||
* @param string $source_language
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_attachment_id_by_url( $img_src, $source_language ) {
|
||||
$attachment_by_url = $this->attachment_by_url_factory->create( $img_src, $source_language );
|
||||
return (int) $attachment_by_url->get_id();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param int $attachment_id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_image_size_from_url( $url, $attachment_id ) {
|
||||
$media_sizes = new WPML_Media_Sizes();
|
||||
return $media_sizes->get_image_size_from_url( $url, $attachment_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $attachment_id
|
||||
* @param $size
|
||||
* @param $uploads_dir
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_sized_image_url( $attachment_id, $size, $uploads_dir ) {
|
||||
$image_url = '';
|
||||
$meta_data = wp_get_attachment_metadata( $attachment_id );
|
||||
|
||||
if ( array_key_exists( $size, $meta_data['sizes'] ) ) {
|
||||
$image_url_parts = array( $uploads_dir['baseurl'] );
|
||||
|
||||
if ( array_key_exists( 'file', $meta_data ) ) {
|
||||
$file_subdirectory = $meta_data['file'];
|
||||
$file_subdirectory_parts = explode( '/', $file_subdirectory );
|
||||
|
||||
array_pop( $file_subdirectory_parts );
|
||||
$image_url_parts[] = implode( '/', $file_subdirectory_parts );
|
||||
}
|
||||
$image_url_parts[] = $meta_data['sizes'][ $size ]['file'];
|
||||
|
||||
$image_url = implode( '/', $image_url_parts );
|
||||
}
|
||||
|
||||
return $image_url;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_Media_Img_Parse
|
||||
*/
|
||||
class WPML_Media_Img_Parse {
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_imgs( $text ) {
|
||||
$images = $this->get_from_img_tags( $text );
|
||||
|
||||
if ( $this->can_parse_blocks( $text ) ) {
|
||||
$blocks = parse_blocks( $text );
|
||||
$images = array_merge( $images, $this->get_from_css_background_images_in_blocks( $blocks ) );
|
||||
} else {
|
||||
$images = array_merge( $images, $this->get_from_css_background_images( $text ) );
|
||||
}
|
||||
|
||||
return $images;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_from_img_tags( $text ) {
|
||||
$images = array();
|
||||
|
||||
if ( preg_match_all( '/<img ([^>]+)>/s', $text, $matches ) ) {
|
||||
foreach ( $matches[1] as $i => $match ) {
|
||||
if ( preg_match_all( '/(\S+)\\s*=\\s*["\']?((?:.(?!["\']?\s+(?:\S+)=|[>"\']))+.)["\']?/', $match, $attribute_matches ) ) {
|
||||
$attributes = array();
|
||||
foreach ( $attribute_matches[1] as $k => $key ) {
|
||||
$attributes[ $key ] = $attribute_matches[2][ $k ];
|
||||
}
|
||||
if ( isset( $attributes['src'] ) ) {
|
||||
$images[ $i ]['attributes'] = $attributes;
|
||||
$images[ $i ]['attachment_id'] = $this->get_attachment_id_from_attributes( $images[ $i ]['attributes'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $images;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_from_css_background_images( $text ) {
|
||||
$images = array();
|
||||
|
||||
if ( preg_match_all( '/<\w+[^>]+style\s?=\s?"[^"]*?background-image:url\(\s?([^\s\)]+)\s?\)/', $text, $matches ) ) {
|
||||
foreach ( $matches[1] as $src ) {
|
||||
$images[] = array(
|
||||
'attributes' => array( 'src' => $src ),
|
||||
'attachment_id' => null,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $images;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $blocks
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_from_css_background_images_in_blocks( $blocks ) {
|
||||
$images = array();
|
||||
|
||||
foreach ( $blocks as $block ) {
|
||||
$block = $this->sanitize_block( $block );
|
||||
|
||||
if ( ! empty( $block->innerBlocks ) ) {
|
||||
$inner_images = $this->get_from_css_background_images_in_blocks( $block->innerBlocks );
|
||||
$images = array_merge( $images, $inner_images );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! isset( $block->innerHTML, $block->attrs->id ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$background_images = $this->get_from_css_background_images( $block->innerHTML );
|
||||
$image = reset( $background_images );
|
||||
|
||||
if ( $image ) {
|
||||
$image['attachment_id'] = $block->attrs->id;
|
||||
$images[] = $image;
|
||||
}
|
||||
}
|
||||
|
||||
return $images;
|
||||
}
|
||||
|
||||
/**
|
||||
* `parse_blocks` does not specify which kind of collection it should return
|
||||
* (not always an array of `WP_Block_Parser_Block`) and the block parser can be filtered,
|
||||
* so we'll cast it to a standard object for now.
|
||||
*
|
||||
* @param mixed $block
|
||||
*
|
||||
* @return stdClass|WP_Block_Parser_Block
|
||||
*/
|
||||
private function sanitize_block( $block ) {
|
||||
$block = (object) $block;
|
||||
|
||||
if ( isset( $block->attrs ) ) {
|
||||
/** Sometimes `$block->attrs` is an object or an array, so we'll use an object */
|
||||
$block->attrs = (object) $block->attrs;
|
||||
}
|
||||
|
||||
return $block;
|
||||
}
|
||||
|
||||
function can_parse_blocks( $string ) {
|
||||
return false !== strpos( $string, '<!-- wp:' ) && function_exists( 'parse_blocks' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $attributes
|
||||
*
|
||||
* @return null|int
|
||||
*/
|
||||
private function get_attachment_id_from_attributes( $attributes ) {
|
||||
$attachment_id = null;
|
||||
if ( isset( $attributes['class'] ) ) {
|
||||
if ( preg_match( '/wp-image-([0-9]+)\b/', $attributes['class'], $id_match ) ) {
|
||||
if ( 'attachment' === get_post_type( (int) $id_match[1] ) ) {
|
||||
$attachment_id = (int) $id_match[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $attachment_id;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_Media_Post_Images_Translation_Factory
|
||||
*/
|
||||
class WPML_Media_Post_Images_Translation_Factory implements IWPML_REST_Action_Loader, IWPML_Backend_Action_Loader {
|
||||
|
||||
/**
|
||||
* @return IWPML_Action|null|WPML_Media_Post_Images_Translation
|
||||
*/
|
||||
public function create() {
|
||||
global $wpdb, $sitepress;
|
||||
|
||||
$media_localization_settings = WPML_Media::get_setting( 'media_files_localization' );
|
||||
if ( $media_localization_settings['posts'] ) {
|
||||
$image_translator = new WPML_Media_Image_Translate( $sitepress, new WPML_Media_Attachment_By_URL_Factory() );
|
||||
$image_updater = new WPML_Media_Translated_Images_Update( new WPML_Media_Img_Parse(), $image_translator, new WPML_Media_Sizes() );
|
||||
|
||||
return new WPML_Media_Post_Images_Translation(
|
||||
$image_updater,
|
||||
$sitepress,
|
||||
$wpdb,
|
||||
new WPML_Translation_Element_Factory( $sitepress ),
|
||||
new WPML_Media_Custom_Field_Images_Translation_Factory(),
|
||||
new WPML_Media_Usage_Factory()
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_Media_Post_Images_Translation
|
||||
* Translate images in posts translations when a post is created or updated
|
||||
*/
|
||||
class WPML_Media_Post_Images_Translation implements IWPML_Action {
|
||||
|
||||
/**
|
||||
* @var WPML_Media_Translated_Images_Update
|
||||
*/
|
||||
private $images_updater;
|
||||
|
||||
/**
|
||||
* @var SitePress
|
||||
*/
|
||||
private $sitepress;
|
||||
|
||||
/**
|
||||
* @var wpdb
|
||||
*/
|
||||
private $wpdb;
|
||||
/**
|
||||
* @var WPML_Translation_Element_Factory
|
||||
*/
|
||||
private $translation_element_factory;
|
||||
/**
|
||||
* @var WPML_Media_Custom_Field_Images_Translation_Factory
|
||||
*/
|
||||
private $custom_field_images_translation_factory;
|
||||
/**
|
||||
* @var WPML_Media_Usage_Factory
|
||||
*/
|
||||
private $media_usage_factory;
|
||||
|
||||
private $captions_map = array();
|
||||
|
||||
private $translate_locks = array();
|
||||
|
||||
public function __construct(
|
||||
WPML_Media_Translated_Images_Update $images_updater,
|
||||
SitePress $sitepress,
|
||||
wpdb $wpdb,
|
||||
WPML_Translation_Element_Factory $translation_element_factory,
|
||||
WPML_Media_Custom_Field_Images_Translation_Factory $custom_field_images_translation_factory,
|
||||
WPML_Media_Usage_Factory $media_usage_factory
|
||||
) {
|
||||
$this->images_updater = $images_updater;
|
||||
$this->sitepress = $sitepress;
|
||||
$this->wpdb = $wpdb;
|
||||
$this->translation_element_factory = $translation_element_factory;
|
||||
$this->custom_field_images_translation_factory = $custom_field_images_translation_factory;
|
||||
$this->media_usage_factory = $media_usage_factory;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'save_post', array( $this, 'translate_images' ), PHP_INT_MAX, 1 );
|
||||
add_filter( 'wpml_pre_save_pro_translation', array( $this, 'translate_images_in_content' ), PHP_INT_MAX, 2 );
|
||||
add_filter( 'wpml_pre_save_pro_translation', array(
|
||||
$this,
|
||||
'replace_placeholders_and_id_in_caption_shortcode'
|
||||
), PHP_INT_MAX, 2 );
|
||||
add_action( 'wpml_tm_job_fields',
|
||||
array( $this, 'replace_caption_placeholders_in_fields' ), 10, 2 );
|
||||
add_filter( 'wpml_tm_job_data_post_content', array(
|
||||
$this,
|
||||
'restore_placeholders_in_translated_job_body'
|
||||
), 10, 1 );
|
||||
|
||||
add_action( 'icl_make_duplicate', array( $this, 'translate_images_in_duplicate' ), PHP_INT_MAX, 4 );
|
||||
|
||||
add_action( 'wpml_added_media_file_translation', array( $this, 'translate_url_in_post' ), PHP_INT_MAX, 1 );
|
||||
add_action( 'wpml_pro_translation_completed', array( $this, 'translate_images' ), PHP_INT_MAX, 1 );
|
||||
add_action( 'wpml_restored_media_file_translation', array( $this, 'translate_url_in_post' ), PHP_INT_MAX, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $post_id
|
||||
*/
|
||||
public function translate_images( $post_id ) {
|
||||
if ( isset( $this->translate_locks[ $post_id ] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->translate_locks[ $post_id ] = true;
|
||||
|
||||
$post = get_post( $post_id );
|
||||
|
||||
if ( ! $post ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var WPML_Post_Element $post_element */
|
||||
$post_element = $this->translation_element_factory->create( $post_id, 'post' );
|
||||
$source_language = $post_element->get_source_language_code();
|
||||
|
||||
if ( null !== $source_language ) {
|
||||
|
||||
$this->translate_images_in_post_content( $post, $post_element );
|
||||
$this->translate_images_in_custom_fields( $post_id );
|
||||
|
||||
} else { // is original
|
||||
foreach ( array_keys( $this->sitepress->get_active_languages() ) as $target_language ) {
|
||||
/** @var WPML_Post_Element $translation */
|
||||
$translation = $post_element->get_translation( $target_language );
|
||||
if ( null !== $translation && $post_id !== $translation->get_id() ) {
|
||||
$this->translate_images_in_post_content( get_post( $translation->get_id() ), $translation );
|
||||
$this->translate_images_in_custom_fields( $translation->get_id() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset( $this->translate_locks[ $post_id ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $master_post_id
|
||||
* @param string $language
|
||||
* @param array $post_array
|
||||
* @param int $post_id
|
||||
*/
|
||||
public function translate_images_in_duplicate( $master_post_id, $language, $post_array, $post_id ) {
|
||||
$this->translate_images( $post_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WP_Post $post
|
||||
* @param WPML_Post_Element $post_element
|
||||
*/
|
||||
private function translate_images_in_post_content( WP_Post $post, WPML_Post_Element $post_element ) {
|
||||
|
||||
if ( (bool) apply_filters( 'wpml_pb_should_body_be_translated', true, $post, 'translate_images_in_post_content' ) ) {
|
||||
$post_content_filtered = $this->images_updater->replace_images_with_translations(
|
||||
$post->post_content,
|
||||
$post_element->get_language_code(),
|
||||
$post_element->get_source_language_code()
|
||||
);
|
||||
|
||||
if ( $post_content_filtered !== $post->post_content ) {
|
||||
$this->wpdb->update(
|
||||
$this->wpdb->posts,
|
||||
array( 'post_content' => $post_content_filtered ),
|
||||
array( 'ID' => $post->ID ),
|
||||
array( '%s' ),
|
||||
array( '%d' )
|
||||
);
|
||||
}
|
||||
} elseif ( $this->is_updated_from_media_translation_menu() ) {
|
||||
do_action( 'wpml_pb_resave_post_translation', $post_element );
|
||||
}
|
||||
}
|
||||
|
||||
private function is_updated_from_media_translation_menu() {
|
||||
$allowed_actions = array(
|
||||
'wpml_media_save_translation',
|
||||
'wpml_media_translate_media_url_in_posts',
|
||||
);
|
||||
|
||||
return isset( $_POST['action'] ) && in_array( $_POST['action'], $allowed_actions, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $post_id
|
||||
*/
|
||||
private function translate_images_in_custom_fields( $post_id ) {
|
||||
|
||||
$custom_fields_image_translation = $this->custom_field_images_translation_factory->create();
|
||||
if ( $custom_fields_image_translation ) {
|
||||
$post_meta = get_metadata( 'post', $post_id );
|
||||
foreach ( $post_meta as $meta_key => $meta_value ) {
|
||||
$custom_fields_image_translation->translate_images( null, $post_id, $meta_key, $meta_value[0] );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $postarr
|
||||
* @param stdClass $job
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function translate_images_in_content( array $postarr, stdclass $job ) {
|
||||
|
||||
$postarr['post_content'] = $this->images_updater->replace_images_with_translations(
|
||||
$postarr['post_content'],
|
||||
$job->language_code,
|
||||
$job->source_language_code
|
||||
);
|
||||
|
||||
return $postarr;
|
||||
}
|
||||
|
||||
public function translate_url_in_post( $attachment_id, $posts = array() ) {
|
||||
if ( ! $posts ) {
|
||||
$media_usage = $this->media_usage_factory->create( $attachment_id );
|
||||
$posts = $media_usage->get_posts();
|
||||
}
|
||||
|
||||
foreach ( $posts as $post_id ) {
|
||||
$this->translate_images( $post_id );
|
||||
}
|
||||
}
|
||||
|
||||
public function replace_placeholders_and_id_in_caption_shortcode( array $postarr, stdClass $job ) {
|
||||
|
||||
$media = $this->find_media_in_job( $job );
|
||||
|
||||
$postarr['post_content'] = $this->replace_caption_placeholders_in_string(
|
||||
$postarr['post_content'],
|
||||
$media,
|
||||
$job->language_code
|
||||
);
|
||||
|
||||
return $postarr;
|
||||
}
|
||||
|
||||
public function replace_caption_placeholders_in_string( $text, $media, $language ) {
|
||||
|
||||
$caption_parser = new WPML_Media_Caption_Tags_Parse();
|
||||
$captions = $caption_parser->get_captions( $text );
|
||||
|
||||
foreach ( $captions as $caption ) {
|
||||
$attachment_id = $caption->get_id();
|
||||
$caption_shortcode = $new_caption_shortcode = $caption->get_shortcode_string();
|
||||
|
||||
if ( isset( $media[ $attachment_id ] ) ) {
|
||||
|
||||
if ( isset( $media[ $attachment_id ]['caption'] ) ) {
|
||||
$new_caption_shortcode = $this->replace_placeholder_with_caption( $new_caption_shortcode, $caption, $media[ $attachment_id ]['caption'] );
|
||||
}
|
||||
|
||||
if ( isset( $media[ $attachment_id ]['alt'] ) ) {
|
||||
$new_caption_shortcode = $this->replace_placeholder_with_alt_text( $new_caption_shortcode, $caption, $media[ $attachment_id ]['alt'] );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( $attachment_id ) {
|
||||
$new_caption_shortcode = $this->replace_caption_id_with_translated_id(
|
||||
$new_caption_shortcode,
|
||||
$attachment_id,
|
||||
$language
|
||||
);
|
||||
}
|
||||
|
||||
if ( $new_caption_shortcode !== $caption_shortcode ) {
|
||||
$text = str_replace( $caption_shortcode, $new_caption_shortcode, $text );
|
||||
$this->captions_map[ $caption_shortcode ] = $new_caption_shortcode;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $new_post_id
|
||||
* @param array $fields
|
||||
* @param stdClass $job
|
||||
*/
|
||||
public function replace_caption_placeholders_in_fields( array $fields, stdClass $job ) {
|
||||
|
||||
$media = $this->find_media_in_job( $job );
|
||||
|
||||
foreach ( $fields as $field_id => $field ) {
|
||||
$fields[ $field_id ]['data'] = $this->replace_caption_placeholders_in_string(
|
||||
$field['data'],
|
||||
$media,
|
||||
$job->language_code
|
||||
);
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
private function replace_placeholder_with_caption( $caption_shortcode, WPML_Media_Caption $caption, $new_caption ) {
|
||||
$caption_content = $caption->get_content();
|
||||
$new_caption_content = str_replace( WPML_Media_Add_To_Translation_Package::CAPTION_PLACEHOLDER, $new_caption, $caption_content );
|
||||
|
||||
return str_replace( $caption_content, $new_caption_content, $caption_shortcode );
|
||||
}
|
||||
|
||||
private function replace_placeholder_with_alt_text( $caption_shortcode, WPML_Media_Caption $caption, $new_alt_text ) {
|
||||
return str_replace( 'alt="' . WPML_Media_Add_To_Translation_Package::ALT_PLACEHOLDER . '"', 'alt="' . $new_alt_text . '"', $caption_shortcode );
|
||||
}
|
||||
|
||||
private function replace_caption_id_with_translated_id( $caption_shortcode, $attachment_id, $language ) {
|
||||
$post_element = $this->translation_element_factory->create( $attachment_id, 'post' );
|
||||
$translation = $post_element->get_translation( $language );
|
||||
if ( $translation ) {
|
||||
|
||||
$translated_id = $translation->get_id();
|
||||
|
||||
$caption_shortcode = str_replace(
|
||||
'id="attachment_' . $attachment_id . '"',
|
||||
'id="attachment_' . $translated_id . '"',
|
||||
$caption_shortcode
|
||||
);
|
||||
}
|
||||
|
||||
return $caption_shortcode;
|
||||
}
|
||||
private function find_media_in_job( stdClass $job ) {
|
||||
$media = array();
|
||||
|
||||
foreach ( $job->elements as $element ) {
|
||||
$field_type = explode( '_', $element->field_type );
|
||||
if ( 'media' === $field_type[0] ) {
|
||||
if ( ! isset( $media[ $field_type[1] ] ) ) {
|
||||
$media[ $field_type[1] ] = array();
|
||||
}
|
||||
$media[ $field_type[1] ][ $field_type[2] ] = base64_decode( $element->field_data_translated );
|
||||
}
|
||||
}
|
||||
|
||||
return $media;
|
||||
}
|
||||
|
||||
public function restore_placeholders_in_translated_job_body( $new_body ) {
|
||||
/**
|
||||
* Translation management is updating the translated job data with the post_content
|
||||
* from the translated post.
|
||||
* We want the translated job data to contain the placeholders so we need to
|
||||
* find the captions we replaced and restore it with the version with the placeholders
|
||||
*/
|
||||
|
||||
foreach ( $this->captions_map as $caption_with_placeholder => $caption_in_post ) {
|
||||
$new_body = str_replace( $caption_in_post, $caption_with_placeholder, $new_body );
|
||||
}
|
||||
$this->captions_map = array();
|
||||
|
||||
return $new_body;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
class WPML_Media_Post_With_Media_Files_Factory {
|
||||
/**
|
||||
* @param $post_id
|
||||
*
|
||||
* @return WPML_Media_Post_With_Media_Files
|
||||
*/
|
||||
public function create( $post_id ) {
|
||||
global $sitepress, $iclTranslationManagement;
|
||||
|
||||
return new WPML_Media_Post_With_Media_Files(
|
||||
$post_id,
|
||||
new WPML_Media_Img_Parse(),
|
||||
new WPML_Media_Attachment_By_URL_Factory(),
|
||||
$sitepress,
|
||||
new WPML_Custom_Field_Setting_Factory( $iclTranslationManagement )
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
|
||||
class WPML_Media_Post_With_Media_Files {
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $post_id;
|
||||
/**
|
||||
* @var WPML_Media_Img_Parse
|
||||
*/
|
||||
private $media_parser;
|
||||
/**
|
||||
* @var WPML_Media_Attachment_By_URL_Factory
|
||||
*/
|
||||
private $attachment_by_url_factory;
|
||||
/**
|
||||
* @var SitePress $sitepress
|
||||
*/
|
||||
private $sitepress;
|
||||
/**
|
||||
* @var WPML_Custom_Field_Setting_Factory
|
||||
*/
|
||||
private $cf_settings_factory;
|
||||
|
||||
/**
|
||||
* WPML_Media_Post_With_Media_Files constructor.
|
||||
*
|
||||
* @param $post_id
|
||||
* @param WPML_Media_Img_Parse $media_parser
|
||||
* @param WPML_Media_Attachment_By_URL_Factory $attachment_by_url_factory
|
||||
* @param SitePress $sitepress
|
||||
* @param WPML_Custom_Field_Setting_Factory $cf_settings_factory
|
||||
*/
|
||||
public function __construct(
|
||||
$post_id,
|
||||
WPML_Media_Img_Parse $media_parser,
|
||||
WPML_Media_Attachment_By_URL_Factory $attachment_by_url_factory,
|
||||
SitePress $sitepress,
|
||||
WPML_Custom_Field_Setting_Factory $cf_settings_factory
|
||||
) {
|
||||
$this->post_id = $post_id;
|
||||
$this->media_parser = $media_parser;
|
||||
$this->attachment_by_url_factory = $attachment_by_url_factory;
|
||||
$this->sitepress = $sitepress;
|
||||
$this->cf_settings_factory = $cf_settings_factory;
|
||||
}
|
||||
|
||||
public function get_media_ids() {
|
||||
$media_ids = array();
|
||||
|
||||
if ( $post = get_post( $this->post_id ) ) {
|
||||
|
||||
$content_to_parse = apply_filters( 'wpml_media_content_for_media_usage', $post->post_content, $post );
|
||||
$post_content_media = $this->media_parser->get_imgs( $content_to_parse );
|
||||
$media_ids = $this->_get_ids_from_media_array( $post_content_media );
|
||||
|
||||
if ( $featured_image = get_post_meta( $this->post_id, '_thumbnail_id', true ) ) {
|
||||
$media_ids[] = $featured_image;
|
||||
}
|
||||
|
||||
$media_localization_settings = WPML_Media::get_setting( 'media_files_localization' );
|
||||
if ( $media_localization_settings['custom_fields'] ) {
|
||||
$custom_fields_content = $this->get_content_in_translatable_custom_fields();
|
||||
$custom_fields_media = $this->media_parser->get_imgs( $custom_fields_content );
|
||||
$media_ids = array_merge( $media_ids, $this->_get_ids_from_media_array( $custom_fields_media ) );
|
||||
}
|
||||
|
||||
if ( $gallery_media_ids = $this->get_gallery_media_ids( $content_to_parse ) ) {
|
||||
$media_ids = array_unique( array_values( array_merge( $media_ids, $gallery_media_ids ) ) );
|
||||
}
|
||||
|
||||
if ( $attached_media_ids = $this->get_attached_media_ids( $this->post_id ) ) {
|
||||
$media_ids = array_unique( array_values( array_merge( $media_ids, $attached_media_ids ) ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return apply_filters( 'wpml_ids_of_media_used_in_post', $media_ids, $this->post_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $media_array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function _get_ids_from_media_array( $media_array ) {
|
||||
$media_ids = array();
|
||||
foreach ( $media_array as $media ) {
|
||||
if ( isset( $media['attachment_id'] ) ) {
|
||||
$media_ids[] = $media['attachment_id'];
|
||||
} else {
|
||||
$attachment_by_url = $this->attachment_by_url_factory->create( $media['attributes']['src'], wpml_get_current_language() );
|
||||
if ( $attachment_id = $attachment_by_url->get_id() ) {
|
||||
$media_ids[] = $attachment_id;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $media_ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $post_content
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_gallery_media_ids( $post_content ) {
|
||||
|
||||
$galleries_media_ids = array();
|
||||
$gallery_shortcode_regex = '/\[gallery [^[]*ids=["\']([0-9,\s]+)["\'][^[]*\]/m';
|
||||
if ( preg_match_all( $gallery_shortcode_regex, $post_content, $matches ) ) {
|
||||
foreach ( $matches[1] as $gallery_ids_string ) {
|
||||
$media_ids_array = explode( ',', $gallery_ids_string );
|
||||
foreach ( $media_ids_array as $media_id ) {
|
||||
if ( 'attachment' === get_post_type ( $media_id ) ) {
|
||||
$galleries_media_ids[] = (int) $media_id;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $galleries_media_ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $languages
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_untranslated_media( $languages ) {
|
||||
|
||||
$untranslated_media = array();
|
||||
|
||||
$post_media = $this->get_media_ids();
|
||||
|
||||
foreach ( $post_media as $attachment_id ) {
|
||||
|
||||
$post_element = new WPML_Post_Element( $attachment_id, $this->sitepress );
|
||||
foreach ( $languages as $language ) {
|
||||
$translation = $post_element->get_translation( $language );
|
||||
if ( null === $translation || ! $this->media_file_is_translated( $attachment_id, $translation->get_id() ) ) {
|
||||
$untranslated_media[] = $attachment_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $untranslated_media;
|
||||
}
|
||||
|
||||
private function media_file_is_translated( $attachment_id, $translated_attachment_id ) {
|
||||
return get_post_meta( $attachment_id, '_wp_attached_file', true )
|
||||
!== get_post_meta( $translated_attachment_id, '_wp_attached_file', true );
|
||||
}
|
||||
|
||||
private function get_content_in_translatable_custom_fields() {
|
||||
$content = '';
|
||||
|
||||
$post_meta = get_metadata( 'post', $this->post_id );
|
||||
|
||||
foreach ( $post_meta as $meta_key => $meta_value ) {
|
||||
$setting = $this->cf_settings_factory->post_meta_setting( $meta_key );
|
||||
$is_translatable = $this->sitepress->get_wp_api()
|
||||
->constant( 'WPML_TRANSLATE_CUSTOM_FIELD' ) === $setting->status();
|
||||
if ( is_string( $meta_value[0] ) && $is_translatable ) {
|
||||
$content .= $meta_value[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
private function get_attached_media_ids( $post_id ) {
|
||||
$attachments = get_children(
|
||||
array(
|
||||
'post_parent' => $post_id,
|
||||
'post_status' => 'inherit',
|
||||
'post_type' => 'attachment',
|
||||
)
|
||||
);
|
||||
return array_keys( $attachments );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_Media_Save_Translation_Factory
|
||||
*/
|
||||
class WPML_Media_Save_Translation_Factory implements IWPML_Backend_Action_Loader {
|
||||
|
||||
public function create() {
|
||||
global $sitepress, $wpdb;
|
||||
|
||||
return new WPML_Media_Save_Translation( $sitepress, $wpdb, new WPML_Media_File_Factory(), new WPML_Translation_Element_Factory( $sitepress ) );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
<?php
|
||||
|
||||
class WPML_Media_Save_Translation implements IWPML_Action {
|
||||
|
||||
/**
|
||||
* @var SitePress
|
||||
*/
|
||||
private $sitepress;
|
||||
/**
|
||||
* @var wpdb
|
||||
*/
|
||||
private $wpdb;
|
||||
/**
|
||||
* @var WPML_Media_File_Factory
|
||||
*/
|
||||
private $media_file_factory;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $post_data;
|
||||
/**
|
||||
* @var WPML_Translation_Element_Factory
|
||||
*/
|
||||
private $translation_element_factory;
|
||||
|
||||
|
||||
/**
|
||||
* WPML_Media_Save_Translation constructor.
|
||||
*
|
||||
* @param SitePress $sitepress
|
||||
* @param wpdb $wpdb
|
||||
* @param WPML_Media_File_Factory $media_file_factory
|
||||
* @param WPML_Translation_Element_Factory $translation_element_factory
|
||||
*/
|
||||
public function __construct( SitePress $sitepress, wpdb $wpdb, WPML_Media_File_Factory $media_file_factory, WPML_Translation_Element_Factory $translation_element_factory ) {
|
||||
$this->sitepress = $sitepress;
|
||||
$this->wpdb = $wpdb;
|
||||
$this->media_file_factory = $media_file_factory;
|
||||
$this->translation_element_factory = $translation_element_factory;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'wp_ajax_wpml_media_save_translation', array( $this, 'save_media_translation' ) );
|
||||
}
|
||||
|
||||
public function save_media_translation() {
|
||||
|
||||
if ( wp_verify_nonce( $_POST['wpnonce'], 'media-translation' ) ) {
|
||||
$post_array['ID'] = (int) $_POST['translated-attachment-id'];
|
||||
$original_attachment_id = (int) $_POST['original-attachment-id'];
|
||||
$translated_language = sanitize_text_field( $_POST['translated-language'] );
|
||||
|
||||
if ( isset( $_POST['translation']['title'] ) ) {
|
||||
$post_array['post_title'] = sanitize_text_field( $_POST['translation']['title'] );
|
||||
}
|
||||
if ( isset( $_POST['translation']['caption'] ) ) {
|
||||
$post_array['post_excerpt'] = sanitize_text_field( $_POST['translation']['caption'] );
|
||||
}
|
||||
if ( isset( $_POST['translation']['description'] ) ) {
|
||||
$post_array['post_content'] = sanitize_text_field( $_POST['translation']['description'] );
|
||||
}
|
||||
|
||||
if ( $post_array['ID'] ) {
|
||||
$attachment_id = wp_update_post( $post_array );
|
||||
|
||||
if ( $this->should_restore_media() ) {
|
||||
$this->restore_media_file( $attachment_id, $original_attachment_id, $translated_language );
|
||||
}
|
||||
} else {
|
||||
|
||||
$post_array['post_type'] = 'attachment';
|
||||
$post_array['post_status'] = 'inherit';
|
||||
$post_array['guid'] = get_post_field( 'guid', $original_attachment_id );
|
||||
$post_array['post_mime_type'] = get_post_field( 'post_mime_type', $original_attachment_id );
|
||||
|
||||
$attachment_id = $this->create_attachment_translation( $original_attachment_id, $post_array );
|
||||
|
||||
$this->sitepress->set_element_language_details(
|
||||
$attachment_id,
|
||||
'post_attachment',
|
||||
$this->get_post_trid_value(),
|
||||
$this->get_post_lang_value()
|
||||
);
|
||||
|
||||
if ( ! $this->has_media_upload() ) {
|
||||
$this->copy_attached_file_info_from_original( $attachment_id, $original_attachment_id );
|
||||
}
|
||||
|
||||
$this->mark_media_as_not_translated( $attachment_id, $translated_language );
|
||||
|
||||
}
|
||||
$translation_status = WPML_Media_Translation_Status::NEEDS_MEDIA_TRANSLATION;
|
||||
|
||||
if ( $this->has_media_upload() ) {
|
||||
$this->update_media_file( $attachment_id, $original_attachment_id, $translated_language );
|
||||
$translation_status = WPML_Media_Translation_Status::TRANSLATED;
|
||||
}
|
||||
|
||||
if ( isset( $_POST['translation']['alt-text'] ) ) {
|
||||
update_post_meta(
|
||||
$attachment_id,
|
||||
'_wp_attachment_image_alt',
|
||||
sanitize_text_field( $_POST['translation']['alt-text'] )
|
||||
);
|
||||
}
|
||||
|
||||
if ( 0 === strpos( get_post_field( 'post_mime_type', $original_attachment_id ), 'image/' ) ) {
|
||||
$translated_thumb = wp_get_attachment_thumb_url( $attachment_id );
|
||||
$original_thumb = wp_get_attachment_thumb_url( $original_attachment_id );
|
||||
$media_file_is_translated = $translated_thumb !== $original_thumb;
|
||||
} else {
|
||||
$media_file_is_translated = get_attached_file( $attachment_id ) !== get_attached_file( $original_attachment_id );
|
||||
$translated_thumb = wp_mime_type_icon( $original_attachment_id );
|
||||
}
|
||||
|
||||
$media_usage = get_post_meta( $original_attachment_id, WPML_Media_Usage::FIELD_NAME, true );
|
||||
$posts_list = array();
|
||||
if ( isset( $media_usage['posts'] ) ) {
|
||||
foreach ( $media_usage['posts'] as $post_id ) {
|
||||
$post_element = $this->translation_element_factory->create( $post_id, 'post' );
|
||||
$post_translation = $post_element->get_translation( $translated_language );
|
||||
if ( $post_translation ) {
|
||||
$posts_list[] = array(
|
||||
'url' => get_edit_post_link( $post_translation->get_id() ),
|
||||
'title' => get_post_field( 'post_title', $post_translation->get_id() ),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $media_usage['posts'] ) && $this->should_restore_media() ) {
|
||||
do_action( 'wpml_restored_media_file_translation', $attachment_id, $media_usage['posts'] );
|
||||
}
|
||||
|
||||
$response = array(
|
||||
'attachment_id' => $attachment_id,
|
||||
'thumb' => $media_file_is_translated ? $translated_thumb : false,
|
||||
'status' => $translation_status,
|
||||
'usage' => $posts_list,
|
||||
);
|
||||
|
||||
wp_send_json_success( $response );
|
||||
} else {
|
||||
wp_send_json_error( array( 'error' => __( 'Invalid nonce', 'wpml-media' ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
private function has_media_upload() {
|
||||
return ! empty( $_POST['update-media-file'] );
|
||||
}
|
||||
|
||||
private function should_restore_media() {
|
||||
return ! empty( $_POST['restore-media'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $original_attachment_id
|
||||
* @param array $post_array
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function create_attachment_translation( $original_attachment_id, $post_array ) {
|
||||
|
||||
$post_element = $this->translation_element_factory->create( $original_attachment_id, 'post' );
|
||||
$this->set_post_trid_value( $post_element->get_trid() );
|
||||
$this->set_post_lang_value( $_POST['translated-language'] );
|
||||
|
||||
add_filter( 'wpml_tm_save_post_trid_value', array( $this, 'get_post_trid_value' ) );
|
||||
add_filter( 'wpml_tm_save_post_lang_value', array( $this, 'get_post_lang_value' ) );
|
||||
|
||||
$attachment_id = wp_insert_post( $post_array );
|
||||
|
||||
remove_filter( 'wpml_tm_save_post_trid_value', array( $this, 'get_post_trid_value' ) );
|
||||
remove_filter( 'wpml_tm_save_post_lang_value', array( $this, 'get_post_lang_value' ) );
|
||||
|
||||
return $attachment_id;
|
||||
}
|
||||
|
||||
private function set_post_trid_value( $value ) {
|
||||
$this->post_data['post_icl_trid'] = $value;
|
||||
}
|
||||
|
||||
public function get_post_trid_value() {
|
||||
return $this->post_data['post_icl_trid'];
|
||||
}
|
||||
|
||||
private function set_post_lang_value( $value ) {
|
||||
$this->post_data['post_icl_language'] = $value;
|
||||
}
|
||||
|
||||
public function get_post_lang_value() {
|
||||
return $this->post_data['post_icl_language'];
|
||||
}
|
||||
|
||||
private function restore_media_file( $attachment_id, $original_attachment_id, $language ) {
|
||||
|
||||
$media_file = $this->media_file_factory->create( $attachment_id );
|
||||
$media_file->delete();
|
||||
|
||||
$this->copy_attached_file_info_from_original( $attachment_id, $original_attachment_id );
|
||||
$this->mark_media_as_not_translated( $original_attachment_id, $language );
|
||||
}
|
||||
|
||||
private function copy_attached_file_info_from_original( $attachment_id, $original_attachment_id ) {
|
||||
$meta_keys = array(
|
||||
'_wp_attachment_metadata',
|
||||
'_wp_attached_file',
|
||||
'_wp_attachment_backup_sizes',
|
||||
);
|
||||
foreach ( $meta_keys as $meta_key ) {
|
||||
update_post_meta(
|
||||
$attachment_id,
|
||||
$meta_key,
|
||||
get_post_meta( $original_attachment_id, $meta_key, true )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fires after attachment post meta is copied
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @param int $original_attachment_id The ID of the source/original attachment.
|
||||
* @param int $attachment_id The ID of the duplicated attachment.
|
||||
*/
|
||||
do_action( 'wpml_after_copy_attached_file_postmeta', $original_attachment_id, $attachment_id );
|
||||
}
|
||||
|
||||
private function mark_media_as_not_translated( $attachment_id, $language ) {
|
||||
update_post_meta( $attachment_id, WPML_Media_Translation_Status::STATUS_PREFIX . $language, WPML_Media_Translation_Status::NEEDS_MEDIA_TRANSLATION );
|
||||
}
|
||||
|
||||
private function mark_media_as_translated( $attachment_id, $language ) {
|
||||
update_post_meta( $attachment_id, WPML_Media_Translation_Status::STATUS_PREFIX . $language, WPML_Media_Translation_Status::TRANSLATED );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $file
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_attachment_post_data( $file ) {
|
||||
$postarr = array(
|
||||
'post_mime_type' => $file['type'],
|
||||
'guid' => $file['url'],
|
||||
'post_modified' => current_time( 'mysql' ),
|
||||
'post_modified_gmt' => current_time( 'mysql', 1 ),
|
||||
);
|
||||
|
||||
return $postarr;
|
||||
}
|
||||
|
||||
private function update_media_file( $attachment_id, $original_attachment_id, $translated_language_code ) {
|
||||
$transient_key = WPML_Media_Attachment_Image_Update::TRANSIENT_FILE_UPLOAD_PREFIX . $original_attachment_id . '_' . $translated_language_code;
|
||||
|
||||
$media_file_upload = get_transient( $transient_key );
|
||||
if ( $media_file_upload ) {
|
||||
|
||||
$file = $media_file_upload['upload'];
|
||||
|
||||
// delete previous media file + sizes
|
||||
$media_file = $this->media_file_factory->create( $attachment_id );
|
||||
$media_file->delete();
|
||||
|
||||
$post_data = $this->get_attachment_post_data( $file );
|
||||
$this->wpdb->update( $this->wpdb->posts, $post_data, array( 'ID' => $attachment_id ) );
|
||||
update_attached_file( $attachment_id, $file['file'] );
|
||||
|
||||
/**
|
||||
* Fires after attached file is updated
|
||||
*
|
||||
* @since 4.1.0
|
||||
*
|
||||
* @param int $attachment_id The ID of uploaded attachment.
|
||||
* @param array $file {
|
||||
* Uploaded file data.
|
||||
*
|
||||
* @type string file Absolute path to file.
|
||||
*
|
||||
* @type string url File URL.
|
||||
*
|
||||
* @type string type File type.
|
||||
* }
|
||||
* @param string $translated_language_code Attachment language code.
|
||||
*/
|
||||
do_action( 'wpml_updated_attached_file', $attachment_id, $file, $translated_language_code );
|
||||
|
||||
wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file['file'] ) );
|
||||
|
||||
$this->mark_media_as_translated( $original_attachment_id, $translated_language_code );
|
||||
do_action( 'wpml_added_media_file_translation', $original_attachment_id, $file, $translated_language_code );
|
||||
|
||||
delete_transient( $transient_key );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
class WPML_Media_Set_Posts_Media_Flag_Factory implements IWPML_Backend_Action_Loader {
|
||||
|
||||
public function create() {
|
||||
global $wpdb;
|
||||
|
||||
$post_media_usage_factory = new WPML_Media_Post_Media_Usage_Factory();
|
||||
|
||||
return new WPML_Media_Set_Posts_Media_Flag(
|
||||
$wpdb,
|
||||
wpml_get_admin_notices(),
|
||||
$post_media_usage_factory->create(),
|
||||
new WPML_Media_Post_With_Media_Files_Factory()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
class WPML_Media_Set_Posts_Media_Flag implements IWPML_Action {
|
||||
const HAS_MEDIA_POST_FLAG = '_wpml_media_has_media';
|
||||
|
||||
const BATCH_SIZE = 100;
|
||||
/**
|
||||
* @var wpdb $wpdb
|
||||
*/
|
||||
private $wpdb;
|
||||
/**
|
||||
* @var WPML_Notices
|
||||
*/
|
||||
private $wpml_notices;
|
||||
/**
|
||||
* @var WPML_Media_Post_Media_Usage
|
||||
*/
|
||||
private $post_media_usage;
|
||||
/**
|
||||
* @var WPML_Media_Post_With_Media_Files_Factory
|
||||
*/
|
||||
private $post_with_media_files_factory;
|
||||
|
||||
public function __construct(
|
||||
wpdb $wpdb,
|
||||
WPML_Notices $wpml_notices,
|
||||
WPML_Media_Post_Media_Usage $post_media_usage,
|
||||
WPML_Media_Post_With_Media_Files_Factory $post_with_media_files_factory
|
||||
) {
|
||||
$this->wpdb = $wpdb;
|
||||
$this->wpml_notices = $wpml_notices;
|
||||
$this->post_media_usage = $post_media_usage;
|
||||
$this->post_with_media_files_factory = $post_with_media_files_factory;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'wp_ajax_' . WPML_Media_Posts_Media_Flag_Notice::PREPARE_ACTION, array( $this, 'clear_flags' ) );
|
||||
add_action( 'wp_ajax_' . WPML_Media_Posts_Media_Flag_Notice::PROCESS_ACTION, array( $this, 'process_batch' ) );
|
||||
|
||||
add_action( 'save_post', array( $this, 'update_post_flag' ) );
|
||||
}
|
||||
|
||||
public function clear_flags() {
|
||||
if ( $this->verify_nonce( WPML_Media_Posts_Media_Flag_Notice::PREPARE_ACTION ) ) {
|
||||
|
||||
if ( ! WPML_Media::has_setup_started() ) {
|
||||
$this->wpdb->delete( $this->wpdb->postmeta, array( 'meta_key' => self::HAS_MEDIA_POST_FLAG ), array( '%s' ) );
|
||||
}
|
||||
wp_send_json_success( array( 'status' => __( 'Running setup...', 'wpml-media' ) ) );
|
||||
|
||||
} else {
|
||||
wp_send_json_error( array( 'status' => 'Invalid nonce' ) );
|
||||
}
|
||||
}
|
||||
|
||||
public function process_batch() {
|
||||
if ( $this->verify_nonce( WPML_Media_Posts_Media_Flag_Notice::PROCESS_ACTION ) ) {
|
||||
$this->mark_started();
|
||||
|
||||
$continue = false;
|
||||
$status = __( 'Setup complete!', 'wpml-media' );
|
||||
$offset = isset( $_POST['offset'] ) ? (int) $_POST['offset'] : 0;
|
||||
|
||||
if ( ! WPML_Media::has_setup_run() ) {
|
||||
|
||||
$sql = $this->wpdb->prepare( "
|
||||
SELECT SQL_CALC_FOUND_ROWS ID, post_content FROM {$this->wpdb->posts} p
|
||||
JOIN {$this->wpdb->prefix}icl_translations t
|
||||
ON t.element_id = p.ID AND t.element_type LIKE 'post_%'
|
||||
LEFT JOIN {$this->wpdb->prefix}postmeta m ON p.ID = m.post_id AND m.meta_key='%s'
|
||||
WHERE p.post_type NOT IN ( 'auto-draft', 'attachment', 'revision' )
|
||||
AND t.source_language_code IS NULL AND m.meta_id IS NULL
|
||||
ORDER BY ID ASC
|
||||
LIMIT %d, %d
|
||||
", self::HAS_MEDIA_POST_FLAG, $offset, self::BATCH_SIZE );
|
||||
|
||||
$posts = $this->wpdb->get_results( $sql );
|
||||
|
||||
$total_posts_found = $this->wpdb->get_var( 'SELECT FOUND_ROWS()' );
|
||||
|
||||
if ( $continue = ( count( $posts ) > 0 ) ) {
|
||||
$this->flag_posts( $posts );
|
||||
$this->record_media_usage( $posts );
|
||||
$progress = round( 100*min( $offset, $total_posts_found )/$total_posts_found );
|
||||
$status = sprintf( __( 'Setup in progress: %d%% complete...', 'wpml-media' ), $progress );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $continue ) {
|
||||
$this->mark_complete();
|
||||
}
|
||||
|
||||
wp_send_json_success( array(
|
||||
'status' => $status,
|
||||
'offset' => $offset + self::BATCH_SIZE,
|
||||
'continue' => $continue
|
||||
) );
|
||||
|
||||
} else {
|
||||
wp_send_json_error( array( 'status' => 'Invalid nonce' ) );
|
||||
}
|
||||
}
|
||||
|
||||
private function verify_nonce( $action ) {
|
||||
return isset( $_POST['nonce'] ) && wp_verify_nonce( $_POST['nonce'], $action );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $posts
|
||||
*/
|
||||
private function flag_posts( $posts ) {
|
||||
foreach ( $posts as $post ) {
|
||||
$this->update_post_flag( $post->ID );
|
||||
}
|
||||
}
|
||||
|
||||
public function update_post_flag( $post_id ) {
|
||||
|
||||
$post_with_media_files = $this->post_with_media_files_factory->create( $post_id );
|
||||
|
||||
if ( $post_with_media_files->get_media_ids() ) {
|
||||
update_post_meta( $post_id, self::HAS_MEDIA_POST_FLAG, 1 );
|
||||
} else {
|
||||
delete_post_meta( $post_id, self::HAS_MEDIA_POST_FLAG );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $posts
|
||||
*/
|
||||
private function record_media_usage( $posts ) {
|
||||
foreach ( $posts as $post ) {
|
||||
$this->post_media_usage->update_media_usage( $post->ID );
|
||||
}
|
||||
}
|
||||
|
||||
private function mark_complete() {
|
||||
WPML_Media::set_setup_run();
|
||||
$this->wpml_notices->remove_notice(
|
||||
WPML_Media_Posts_Media_Flag_Notice::NOTICE_GROUP,
|
||||
WPML_Media_Posts_Media_Flag_Notice::NOTICE_ID
|
||||
);
|
||||
}
|
||||
|
||||
private function mark_started() {
|
||||
WPML_Media::set_setup_started();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author OnTheGo Systems
|
||||
*/
|
||||
class WPML_Media_Sizes {
|
||||
/**
|
||||
* @param array $img
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function get_size_from_class( array $img ) {
|
||||
if ( array_key_exists( 'attributes', $img ) && array_key_exists( 'class', $img['attributes'] ) ) {
|
||||
|
||||
$classes = explode( ' ', $img['attributes']['class'] );
|
||||
foreach ( $classes as $class ) {
|
||||
if ( strpos( $class, 'size-' ) === 0 ) {
|
||||
$class_parts = explode( '-', $class );
|
||||
if ( count( $class_parts ) >= 2 ) {
|
||||
unset( $class_parts[0] );
|
||||
|
||||
return implode( '-', $class_parts );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $img
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function get_size_from_attributes( array $img ) {
|
||||
if (
|
||||
array_key_exists( 'attributes', $img )
|
||||
&& array_key_exists( 'width', $img['attributes'] )
|
||||
&& array_key_exists( 'height', $img['attributes'] )
|
||||
) {
|
||||
|
||||
$width = $img['attributes']['width'];
|
||||
$height = $img['attributes']['height'];
|
||||
|
||||
$size_name = $this->get_image_size_name( $width, $height );
|
||||
|
||||
if ( $size_name ) {
|
||||
return $size_name;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $img
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function get_attachment_size( array $img ) {
|
||||
$size = null;
|
||||
if ( array_key_exists( 'size', $img ) ) {
|
||||
$size = $img['size'];
|
||||
}
|
||||
if ( ! $size ) {
|
||||
$size = $this->get_size_from_class( $img );
|
||||
}
|
||||
if ( ! $size ) {
|
||||
$size = $this->get_size_from_attributes( $img );
|
||||
}
|
||||
if ( ! $size ) {
|
||||
$size = $this->get_size_from_url( $img );
|
||||
}
|
||||
|
||||
return $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $width
|
||||
* @param string $height
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
private function get_image_size_name( $width, $height ) {
|
||||
global $_wp_additional_image_sizes;
|
||||
|
||||
foreach ( get_intermediate_image_sizes() as $size ) {
|
||||
if ( isset( $_wp_additional_image_sizes[ $size ] ) ) {
|
||||
if ( $width == $_wp_additional_image_sizes[ $size ]['width'] && $height == $_wp_additional_image_sizes[ $size ]['height'] ) {
|
||||
return $size;
|
||||
}
|
||||
} elseif ( in_array( $size, array( 'thumbnail', 'medium', 'medium_large', 'large' ) ) ) {
|
||||
if ( $width == get_option( "{$size}_size_w" ) && $height == get_option( "{$size}_size_h" ) ) {
|
||||
return $size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $img
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
private function get_size_from_url( array $img ) {
|
||||
$size = null;
|
||||
|
||||
if ( isset( $img['attributes']['src'], $img['attachment_id'] ) ) {
|
||||
$size = $this->get_image_size_from_url( $img['attributes']['src'], $img['attachment_id'] );
|
||||
}
|
||||
|
||||
return $size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $url
|
||||
* @param $attachment_id
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function get_image_size_from_url( $url, $attachment_id ) {
|
||||
$size = null;
|
||||
|
||||
$thumb_file_name = basename( $url );
|
||||
$attachment_meta_data = wp_get_attachment_metadata( $attachment_id );
|
||||
foreach ( $attachment_meta_data['sizes'] as $key => $size_array ) {
|
||||
if ( $thumb_file_name === $size_array['file'] ) {
|
||||
$size = $key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $size;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_Media_String_Images_Translation_Factory
|
||||
*/
|
||||
class WPML_Media_String_Images_Translation_Factory implements IWPML_Backend_Action_Loader {
|
||||
|
||||
public function create() {
|
||||
global $wpdb, $sitepress;
|
||||
|
||||
$media_localization_settings = WPML_Media::get_setting( 'media_files_localization' );
|
||||
|
||||
if ( $media_localization_settings['strings'] ) {
|
||||
$image_translator = new WPML_Media_Image_Translate( $sitepress, new WPML_Media_Attachment_By_URL_Factory() );
|
||||
$image_updater = new WPML_Media_Translated_Images_Update( new WPML_Media_Img_Parse(), $image_translator, new WPML_Media_Sizes() );
|
||||
$string_factory = new WPML_ST_String_Factory( $wpdb );
|
||||
|
||||
return new WPML_Media_String_Images_Translation( $image_updater, $string_factory );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_Media_String_Images_Translation
|
||||
* Translate images in posts strings translations when a string translation is created or updated
|
||||
*/
|
||||
class WPML_Media_String_Images_Translation implements IWPML_Action {
|
||||
|
||||
/**
|
||||
* @var WPML_Media_String_Images_Translation
|
||||
*/
|
||||
private $images_updater;
|
||||
/**
|
||||
* @var WPML_ST_String_Factory
|
||||
*/
|
||||
private $string_factory;
|
||||
|
||||
/**
|
||||
* WPML_Media_String_Images_Translation constructor.
|
||||
*
|
||||
* @param WPML_Media_Translated_Images_Update $images_updater
|
||||
* @param WPML_ST_String_Factory $string_factory
|
||||
*/
|
||||
public function __construct( WPML_Media_Translated_Images_Update $images_updater, WPML_ST_String_Factory $string_factory ) {
|
||||
$this->images_updater = $images_updater;
|
||||
$this->string_factory = $string_factory;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_filter( 'wpml_st_string_translation_before_save', array( $this, 'translate_images' ), PHP_INT_MAX, 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $translation_data
|
||||
* @param string $target_language
|
||||
* @param int $string_id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function translate_images( $translation_data, $target_language, $string_id ) {
|
||||
if ( ! empty( $translation_data['value'] ) ) {
|
||||
$original_string = $this->string_factory->find_by_id( $string_id );
|
||||
|
||||
$translation_data['value'] = $this->images_updater->replace_images_with_translations(
|
||||
$translation_data['value'],
|
||||
$target_language,
|
||||
$original_string->get_language()
|
||||
);
|
||||
}
|
||||
|
||||
return $translation_data;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_Media_Translated_Images_Update
|
||||
* Translates images in a given text
|
||||
*/
|
||||
class WPML_Media_Translated_Images_Update {
|
||||
|
||||
/**
|
||||
* @var WPML_Media_Img_Parse
|
||||
*/
|
||||
private $img_parser;
|
||||
|
||||
/**
|
||||
* @var WPML_Media_Image_Translate
|
||||
*/
|
||||
private $image_translator;
|
||||
/**
|
||||
* @var WPML_Media_Sizes
|
||||
*/
|
||||
private $media_sizes;
|
||||
|
||||
/**
|
||||
* WPML_Media_Translated_Images_Update constructor.
|
||||
*
|
||||
* @param WPML_Media_Img_Parse $img_parser
|
||||
* @param WPML_Media_Image_Translate $image_translator
|
||||
* @param WPML_Media_Sizes $media_sizes
|
||||
*/
|
||||
public function __construct( WPML_Media_Img_Parse $img_parser, WPML_Media_Image_Translate $image_translator, WPML_Media_Sizes $media_sizes ) {
|
||||
$this->img_parser = $img_parser;
|
||||
$this->image_translator = $image_translator;
|
||||
$this->media_sizes = $media_sizes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
* @param string $source_language
|
||||
* @param string $target_language
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function replace_images_with_translations( $text, $target_language, $source_language = null ) {
|
||||
|
||||
$imgs = $this->img_parser->get_imgs( $text );
|
||||
|
||||
foreach ( $imgs as $img ) {
|
||||
$attachment_id = $translated_id = false;
|
||||
if ( isset( $img['attachment_id'] ) && $img['attachment_id'] ) {
|
||||
$attachment_id = $img['attachment_id'];
|
||||
$translated_id = apply_filters(
|
||||
'wpml_object_id',
|
||||
$attachment_id,
|
||||
'attachment',
|
||||
true,
|
||||
$target_language
|
||||
);
|
||||
$size = $this->media_sizes->get_attachment_size( $img );
|
||||
$translated_src = $this->image_translator->get_translated_image( $attachment_id, $target_language, $size );
|
||||
} else {
|
||||
$translated_src = $this->get_translated_image_by_url( $target_language, $source_language, $img );
|
||||
}
|
||||
if ( $translated_src && $translated_src !== $img['attributes']['src'] ) {
|
||||
$text = $this->replace_image_src( $text, $img['attributes']['src'], $translated_src );
|
||||
}
|
||||
if ( $attachment_id && $attachment_id !== $translated_id ) {
|
||||
$text = $this->replace_att_class( $text, $attachment_id, $translated_id );
|
||||
$text = $this->replace_att_in_block( $text, $attachment_id, $translated_id );
|
||||
}
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function replace_image_src( $text, $from, $to ) {
|
||||
return str_replace( $from, $to, $text );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function replace_att_class( $text, $from, $to ) {
|
||||
$pattern = '/\bwp-image-' . $from . '\b/u';
|
||||
$replacement = 'wp-image-' . $to;
|
||||
return preg_replace( $pattern, $replacement, $text );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function replace_att_in_block( $text, $from, $to ) {
|
||||
$pattern = '/<!-- wp:image {.*?"id":(' . $from . '),.*?-->/u';
|
||||
$replacement = function ( $matches ) use ( $to ) {
|
||||
return str_replace( '"id":' . $matches[1], '"id":' . $to, $matches[0] );
|
||||
};
|
||||
|
||||
return preg_replace_callback( $pattern, $replacement, $text );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $target_language
|
||||
* @param $source_language
|
||||
* @param $img
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
private function get_translated_image_by_url( $target_language, $source_language, $img ) {
|
||||
if ( null === $source_language ) {
|
||||
$source_language = wpml_get_current_language();
|
||||
}
|
||||
$translated_src = $this->image_translator->get_translated_image_by_url(
|
||||
$img['attributes']['src'],
|
||||
$source_language,
|
||||
$target_language
|
||||
);
|
||||
|
||||
return $translated_src;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
class WPML_Media_Translation_Status_Factory implements IWPML_Backend_Action_Loader, IWPML_REST_Action_Loader {
|
||||
|
||||
public function create() {
|
||||
global $sitepress;
|
||||
|
||||
return new WPML_Media_Translation_Status( $sitepress );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
class WPML_Media_Translation_Status implements IWPML_Action {
|
||||
|
||||
const NOT_TRANSLATED = 'media-not-translated';
|
||||
const IN_PROGRESS = 'in-progress';
|
||||
const TRANSLATED = 'media-translated';
|
||||
const NEEDS_MEDIA_TRANSLATION = 'needs-media-translation';
|
||||
|
||||
const STATUS_PREFIX = '_translation_status_';
|
||||
|
||||
/**
|
||||
* @var SitePress
|
||||
*/
|
||||
private $sitepress;
|
||||
|
||||
public function __construct( SitePress $sitepress ) {
|
||||
$this->sitepress = $sitepress;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'wpml_tm_send_post_jobs', array( $this, 'set_translation_status_in_progress' ) );
|
||||
add_action( 'wpml_pro_translation_completed', array( $this, 'save_bundled_media_translation' ), 10, 3 );
|
||||
}
|
||||
|
||||
public function set_translation_status_in_progress( WPML_TM_Translation_Batch $batch ) {
|
||||
foreach ( $batch->get_elements() as $item ) {
|
||||
foreach ( $item->get_media_to_translations() as $attachment_id ) {
|
||||
foreach ( array_keys( $item->get_target_langs() ) as $lang ) {
|
||||
$this->set_status( $attachment_id, $lang, self::IN_PROGRESS );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function set_status( $attachment_id, $language, $status ) {
|
||||
update_post_meta( $attachment_id, self::STATUS_PREFIX . $language, $status );
|
||||
}
|
||||
|
||||
public function save_bundled_media_translation( $new_post_id, $fields, $job ) {
|
||||
|
||||
$media_translations = $this->get_media_translations( $job );
|
||||
$translation_package = new WPML_Element_Translation_Package();
|
||||
|
||||
foreach ( $media_translations as $attachment_id => $translation_data ) {
|
||||
$attachment_translation_id = $this->save_attachment_translation(
|
||||
$attachment_id,
|
||||
$translation_data,
|
||||
$translation_package,
|
||||
$job->language_code
|
||||
);
|
||||
if ( $this->should_translate_media_image( $job, $attachment_id ) ) {
|
||||
$this->set_status( $attachment_id, $job->language_code, self::NEEDS_MEDIA_TRANSLATION );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function should_translate_media_image( $job, $attachment_id ) {
|
||||
foreach ( $job->elements as $element ) {
|
||||
if ( 'should_translate_media_image_' . $attachment_id === $element->field_type && $element->field_data ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function get_media_translations( $job ) {
|
||||
|
||||
$media = array();
|
||||
|
||||
$media_field_regexp = '#^media_([0-9]+)_([a-z_]+)$#';
|
||||
foreach ( $job->elements as $element ) {
|
||||
if ( preg_match( $media_field_regexp, $element->field_type, $matches ) ) {
|
||||
list( , $attachment_id, $media_field ) = $matches;
|
||||
$media[ $attachment_id ][ $media_field ] = $element;
|
||||
}
|
||||
}
|
||||
|
||||
return $media;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $attachment_id
|
||||
* @param array $translation_data
|
||||
* @param WPML_Element_Translation_Package $translation_package
|
||||
* @param string $language
|
||||
* @return bool|int|WP_Error
|
||||
*/
|
||||
private function save_attachment_translation( $attachment_id, $translation_data, $translation_package, $language ) {
|
||||
|
||||
$postarr = array();
|
||||
$alt_text = null;
|
||||
|
||||
foreach ( $translation_data as $field => $data ) {
|
||||
|
||||
$translated_value = $translation_package->decode_field_data(
|
||||
$data->field_data_translated,
|
||||
$data->field_format
|
||||
);
|
||||
|
||||
if ( 'alt_text' === $field ) {
|
||||
$alt_text = $translated_value;
|
||||
} else {
|
||||
|
||||
switch ( $field ) {
|
||||
case 'title':
|
||||
$wp_post_field = 'post_title';
|
||||
break;
|
||||
case 'caption':
|
||||
$wp_post_field = 'post_excerpt';
|
||||
break;
|
||||
case 'description':
|
||||
$wp_post_field = 'post_content';
|
||||
break;
|
||||
default:
|
||||
$wp_post_field = '';
|
||||
|
||||
}
|
||||
|
||||
if ( $wp_post_field ) {
|
||||
$postarr[ $wp_post_field ] = $translated_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$post_element = new WPML_Post_Element( $attachment_id, $this->sitepress );
|
||||
$attachment_translation = $post_element->get_translation( $language );
|
||||
$attachment_translation_id = null !== $attachment_translation ? $attachment_translation->get_id() : false;
|
||||
|
||||
if ( $attachment_translation_id ) {
|
||||
$postarr['ID'] = $attachment_translation_id;
|
||||
wp_update_post( $postarr );
|
||||
} else {
|
||||
$postarr['post_type'] = 'attachment';
|
||||
$postarr['post_status'] = 'inherit';
|
||||
$postarr['guid'] = get_post_field( 'guid', $attachment_id );
|
||||
$postarr['post_mime_type'] = get_post_field( 'post_mime_type', $attachment_id );
|
||||
|
||||
$attachment_translation_id = wp_insert_post( $postarr );
|
||||
|
||||
$this->sitepress->set_element_language_details( $attachment_translation_id, 'post_attachment', $post_element->get_trid(), $language );
|
||||
|
||||
$this->copy_attached_file_info_from_original( $attachment_translation_id, $attachment_id );
|
||||
|
||||
}
|
||||
|
||||
if ( null !== $alt_text ) {
|
||||
update_post_meta( $attachment_translation_id, '_wp_attachment_image_alt', $alt_text );
|
||||
}
|
||||
|
||||
return $attachment_translation_id;
|
||||
}
|
||||
|
||||
private function copy_attached_file_info_from_original( $attachment_id, $original_attachment_id ) {
|
||||
$meta_keys = array(
|
||||
'_wp_attachment_metadata',
|
||||
'_wp_attached_file',
|
||||
'_wp_attachment_backup_sizes',
|
||||
);
|
||||
foreach ( $meta_keys as $meta_key ) {
|
||||
update_post_meta(
|
||||
$attachment_id,
|
||||
$meta_key,
|
||||
get_post_meta( $original_attachment_id, $meta_key, true )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
class WPML_Media_Populate_Media_Strings_Translations_Factory implements IWPML_Backend_Action_Loader {
|
||||
public function create() {
|
||||
global $sitepress;
|
||||
|
||||
if ( class_exists( 'WPML_Element_Translation_Package' ) ) {
|
||||
return new WPML_Media_Populate_Media_Strings_Translations(
|
||||
new WPML_Translation_Element_Factory( $sitepress ),
|
||||
new WPML_Element_Translation_Package()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
class WPML_Media_Populate_Media_Strings_Translations implements IWPML_Action {
|
||||
|
||||
/**
|
||||
* @var WPML_Translation_Element_Factory
|
||||
*/
|
||||
private $translation_element_factory;
|
||||
|
||||
/**
|
||||
* @var WPML_Element_Translation_Package
|
||||
*/
|
||||
private $translation_package;
|
||||
|
||||
public function __construct(
|
||||
WPML_Translation_Element_Factory $translation_element_factory,
|
||||
WPML_Element_Translation_Package $translation_package
|
||||
) {
|
||||
$this->translation_element_factory = $translation_element_factory;
|
||||
$this->translation_package = $translation_package;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_filter( 'wpml_tm_populate_prev_translation', array( $this, 'populate' ), 10, 3 );
|
||||
}
|
||||
|
||||
public function populate( $prev_translation, $package, $lang ) {
|
||||
|
||||
if ( ! $prev_translation ) {
|
||||
foreach ( $package['contents'] as $field => $data ) {
|
||||
if ( $media_field = $this->is_media_field( $field ) ) {
|
||||
|
||||
$attachment = $this->translation_element_factory->create( $media_field['id'], 'post' );
|
||||
$attachment_translation = $attachment->get_translation( $lang );
|
||||
|
||||
if ( $attachment_translation ) {
|
||||
$original_id = (int) $media_field['id'];
|
||||
$translation_id = $attachment_translation->get_id();
|
||||
|
||||
switch ( $media_field['field'] ) {
|
||||
case 'title':
|
||||
$translated_value = $this->get_post_field( 'post_title', $original_id, $translation_id );
|
||||
break;
|
||||
case 'caption':
|
||||
$translated_value = $this->get_post_field( 'post_excerpt', $original_id, $translation_id );
|
||||
break;
|
||||
case 'description':
|
||||
$translated_value = $this->get_post_field( 'post_content', $original_id, $translation_id );
|
||||
break;
|
||||
case 'alt_text':
|
||||
$translated_value = get_post_meta( $translation_id, '_wp_attachment_image_alt', true );
|
||||
if ( ! $translated_value ) {
|
||||
$translated_value = get_post_meta( $original_id, '_wp_attachment_image_alt', true );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$translated_value = false;
|
||||
|
||||
}
|
||||
|
||||
if ( $translated_value ) {
|
||||
$prev_translation[ $field ] = wpml_tm_create_translated_field(
|
||||
'', $this->translation_package->encode_field_data( $translated_value ), true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return $prev_translation;
|
||||
}
|
||||
|
||||
private function is_media_field( $field ) {
|
||||
$media_field = array();
|
||||
|
||||
if ( preg_match( '#^media_([0-9]+)_([a-z_]+)$#', $field, $matches ) ) {
|
||||
$media_field['id'] = $matches[1];
|
||||
$media_field['field'] = $matches[2];
|
||||
}
|
||||
|
||||
return $media_field;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $field
|
||||
* @param int $original_id
|
||||
* @param int $translation_id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_post_field( $field, $original_id, $translation_id ) {
|
||||
$value = get_post_field( $field, $translation_id );
|
||||
|
||||
if ( ! $value ) {
|
||||
$value = get_post_field( $field, $original_id );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user