sitepress = $sitepress; $this->wpdb = $wpdb; add_action( 'wpml_loaded', array( $this, 'loaded' ), 2 ); add_action( 'init', array( $this, 'verify_wpml' ) ); } function verify_wpml() { if ( is_admin() ) { $dependencies = new WPML_Media_Dependencies(); $dependencies->check(); } } public static function has_settings() { return get_option( self::$settings_option_key ); } function loaded() { global $sitepress; if ( ! isset( $sitepress ) || ! $sitepress->get_setting( 'setup_complete' ) ) { return null; } add_action( 'shutdown', array( $this, 'invalidate_cache' ), - PHP_INT_MAX ); $this->plugin_localization(); if ( is_admin() ) { WPML_Media_Upgrade::run(); } self::init_settings(); $this->overrides(); global $wpdb, $sitepress_settings, $pagenow; $active_languages = $sitepress->get_active_languages(); if ( ! self::get_setting( 'starting_help' ) && ( empty( $_GET['page'] ) || $_GET['page'] !== 'wpml-media' ) ) { $total_attachments_prepared = $wpdb->prepare(" SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type = %s AND ID NOT IN (SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = %s)", array('attachment', 'wpml_media_processed')); $total_attachments = $wpdb->get_var( $total_attachments_prepared ); if ( $total_attachments ) { if ( count( $active_languages ) > 1 ) { add_action( 'admin_notices', array( $this, 'first_time_notice' ) ); } } else { self::update_setting( 'starting_help', 1 ); } } $this->languages = null; add_action( 'save_post', array( $this, 'save_post_actions' ), 100, 2 ); add_action( 'added_post_meta', array( $this, 'added_post_meta' ), 10, 4 ); add_action( 'updated_postmeta', array( $this, 'updated_postmeta' ), 10, 4 ); // do not run this when user is importing posts in Tools > Import if ( ! isset( $_GET[ 'import' ] ) || $_GET[ 'import' ] !== 'wordpress' ) { add_action( 'add_attachment', array( $this, 'save_attachment_actions' ) ); } add_action( 'add_attachment', array( $this, 'save_translated_attachments' ) ); // Attachment metadata hooks add_filter( 'wp_generate_attachment_metadata', array( $this, 'wp_generate_attachment_metadata' ), 10, 2 ); if ( $this->is_admin_or_xmlrpc() && !$this->is_uploading_plugin_or_theme() ) { add_action( 'admin_head', array( $this, 'js_scripts' ) ); if ( 1 < count( $active_languages ) ) { add_action( 'admin_menu', array( $this, 'menu' ) ); add_filter( 'manage_media_columns', array( $this, 'manage_media_columns' ), 10, 1 ); add_action( 'manage_media_custom_column', array( $this, 'manage_media_custom_column' ), 10, 2 ); add_action( 'parse_query', array( $this, 'parse_query' ) ); add_filter( 'views_upload', array( $this, 'views_upload' ) ); add_action( 'icl_post_languages_options_after', array( $this, 'language_options' ) ); // Post/page save actions add_action( 'icl_make_duplicate', array( $this, 'make_duplicate' ), 10, 4 ); add_action( 'edit_attachment', array( $this, 'save_attachment_actions' ) ); //wp_delete_file file filter add_filter( 'wp_delete_file', array( $this, 'delete_file' ) ); if ( $pagenow == 'media-upload.php' ) { //Add the language filter to the media library add_action( 'media_upload_library', array( $this, 'language_filter' ), 1 ); add_action( 'pre_get_posts', array( $this, 'filter_media_upload_items' ), 10, 1 ); } add_action( 'wpml_media_create_duplicate_attachment', array( $this, 'queue_for_cache_invalidation' ), 10, 2 ); if ( $pagenow == 'media.php' ) { add_action( 'admin_footer', array( $this, 'media_language_options' ) ); } if ( $pagenow == 'upload.php' ) { //Add the language filter to the media library (language_filter): /wp-admin/upload.php add_action( 'admin_footer', array( $this, 'language_filter_upload_page' ) ); } add_action( 'wp_ajax_wpml_media_dismiss_starting_help', array( $this, 'dismiss_wpml_media_starting_help' ) ); add_action( 'wp_ajax_wpml_media_set_initial_language', array( $this, 'batch_set_initial_language' ) ); add_action( 'wp_ajax_wpml_media_translate_media', array( $this, 'batch_translate_media' ) ); add_action( 'wp_ajax_wpml_media_duplicate_media', array( $this, 'batch_duplicate_media' ) ); add_action( 'wp_ajax_wpml_media_duplicate_featured_images', array( $this, 'batch_duplicate_featured_images' ) ); add_action( 'wp_ajax_wpml_media_mark_processed', array( $this, 'batch_mark_processed' ) ); add_action( 'wp_ajax_wpml_media_scan_prepare', array( $this, 'batch_scan_prepare' ) ); add_action( 'wp_ajax_wpml_media_set_content_prepare', array( $this, 'set_content_defaults_prepare' ) ); add_action( 'wp_ajax_wpml_media_set_content_defaults', array( $this, 'set_content_defaults' ) ); add_action( 'wp_ajax_set-post-thumbnail', array( $this, 'ajax_set_post_thumbnail' ), 0 ); add_action( 'wp_ajax_find_posts', array( $this, 'find_posts_filter' ), 0 ); } add_action( 'icl_pro_translation_saved', array( $this, 'icl_pro_translation_saved' ), 10, 1 ); } else { if($sitepress_settings[ 'language_negotiation_type' ] == 2) { // Translate media url when in front-end and only when using custom domain add_filter( 'wp_get_attachment_url', array( $this, 'wp_get_attachment_url' ), 10, 2 ); } } add_filter( 'WPML_filter_link', array( $this, 'filter_link' ), 10, 2 ); add_filter( 'icl_ls_languages', array( $this, 'icl_ls_languages' ), 10, 1 ); return null; } function is_admin_or_xmlrpc() { $is_admin = is_admin(); $is_xmlrpc = (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST); return $is_admin || $is_xmlrpc; } function is_uploading_plugin_or_theme() { global $action; return ( isset( $action ) && ($action == 'upload-plugin' || $action == 'upload-theme') ); } function plugin_localization() { load_plugin_textdomain( 'wpml-media', false, WPML_MEDIA_FOLDER . '/locale' ); } /** * Needed by class init and by all static methods that use self::$settings */ public static function init_settings() { if ( ! self::$settings ) { self::$settings = get_option( self::$settings_option_key ); } $default_settings = array( 'version' => false, 'starting_help' => false, 'new_content_settings' => array( 'always_translate_media' => true, 'duplicate_media' => true, 'duplicate_featured' => true ), 'media_files_localization' => array( 'posts' => true, 'custom_fields' => true, 'strings' => true ) ); if ( ! self::$settings ) { self::$settings = $default_settings; } } /** * This method, called on 'plugins_loaded' action, overrides or replaces WPML default behavior */ public function overrides() { global $sitepress, $pagenow; //Removes the WPML language metabox on media and replace it with the custom one remove_action( 'admin_head', array( $sitepress, 'post_edit_language_options' ) ); if ( $pagenow == 'post.php' || $pagenow == 'post-new.php' || $pagenow == 'edit.php' ) { add_action( 'admin_head', array( $this, 'post_edit_language_options' ) ); } } public static function get_setting( $name, $default = false ) { self::init_settings(); if ( !isset( self::$settings[ $name ] ) || !self::$settings[ $name ] ) return $default; return self::$settings[ $name ]; } public static function update_setting( $name, $value ) { self::init_settings(); self::$settings[ $name ] = $value; return update_option( self::$settings_option_key, self::$settings ); } function post_edit_language_options() { global $post, $sitepress, $pagenow; //Removes the language metabox on media if ( ( isset( $_POST['wp-preview'] ) && $_POST['wp-preview'] === 'dopreview' ) || is_preview() ) { $is_preview = true; } else { $is_preview = false; } //If not a media admin page, call the default WPML post_edit_language_options() method if ( ! ( $pagenow === 'upload.php' || $pagenow === 'media-upload.php' || $is_preview || ( isset( $post ) && $post->post_type === 'attachment' ) || is_attachment() ) ) { $sitepress->post_edit_language_options(); } } function first_time_notice() { ?>
__( 'Started...', 'wpml-media' ) ); echo wp_json_encode( $response ); exit; } function set_content_defaults() { $always_translate_media = $_POST[ 'always_translate_media' ]; $duplicate_media = $_POST[ 'duplicate_media' ]; $duplicate_featured = $_POST[ 'duplicate_featured' ]; $content_defaults_option = array( 'always_translate_media' => $always_translate_media == 'true', 'duplicate_media' => $duplicate_media == 'true', 'duplicate_featured' => $duplicate_featured == 'true' ); self::update_setting( 'new_content_settings', $content_defaults_option ); $response = array( 'result' => true, 'message' => __( 'Settings saved', 'wpml-media' ) ); wp_send_json_success( $response ); } function batch_scan_prepare() { global $wpdb; $response = array(); $wpdb->delete( $wpdb->postmeta, array( 'meta_key' => 'wpml_media_processed' ) ); $response[ 'message' ] = __( 'Started...', 'wpml-media' ); echo wp_json_encode( $response ); exit; } function batch_set_initial_language() { global $wpdb, $sitepress; $default_language = $sitepress->get_default_language(); $limit = 10; $response = array(); $attachments_prepared = $wpdb->prepare( " SELECT SQL_CALC_FOUND_ROWS ID FROM {$wpdb->posts} WHERE post_type = %s AND ID NOT IN (SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE element_type=%s) LIMIT %d", array( 'attachment', 'post_attachment', $limit ) ); $attachments = $wpdb->get_col( $attachments_prepared ); $found = $wpdb->get_var( "SELECT FOUND_ROWS()" ); foreach ( $attachments as $attachment_id ) { $sitepress->set_element_language_details( $attachment_id, 'post_attachment', false, $default_language ); } $response[ 'left' ] = max( $found - $limit, 0 ); if ( $response[ 'left' ] ) { $response[ 'message' ] = sprintf( __( 'Setting language to media. %d left', 'wpml-media' ), $response[ 'left' ] ); } else { $response[ 'message' ] = sprintf( __( 'Setting language to media: done!', 'wpml-media' ), $response[ 'left' ] ); } echo wp_json_encode( $response ); exit; } function batch_translate_media() { $response = array(); $active_languages = count( $this->sitepress->get_active_languages() ); $limit = $this->get_batch_translate_limit( $active_languages ); $sql = " SELECT SQL_CALC_FOUND_ROWS p1.ID, p1.post_parent FROM {$this->wpdb->prefix}icl_translations t INNER JOIN {$this->wpdb->posts} p1 ON t.element_id = p1.ID LEFT JOIN {$this->wpdb->prefix}icl_translations tt ON t.trid = tt.trid WHERE t.element_type = 'post_attachment' AND t.source_language_code IS null GROUP BY p1.ID, p1.post_parent HAVING count(tt.language_code) < %d LIMIT %d "; $sql_prepared = $this->wpdb->prepare($sql, array($active_languages, $limit)); $attachments = $this->wpdb->get_results( $sql_prepared ); $found = $this->wpdb->get_var( "SELECT FOUND_ROWS()" ); if ( $attachments ) { foreach ( $attachments as $attachment ) { $lang = $this->sitepress->get_element_language_details( $attachment->ID, 'post_attachment' ); $this->translate_attachments( $attachment->ID, $lang->language_code ); } } $response[ 'left' ] = max( $found - $limit, 0 ); if ( $response[ 'left' ] ) { $response[ 'message' ] = sprintf( esc_html__( 'Translating media. %d left', 'wpml-media' ), $response[ 'left' ] ); } else { $response[ 'message' ] = sprintf( esc_html__( 'Translating media: done!', 'wpml-media' ), $response[ 'left' ] ); } wp_send_json( $response ); } /** * @param int $active_languages * * @return int */ private function get_batch_translate_limit( $active_languages ) { $limit = $this->sitepress->get_wp_api()->constant( 'WPML_MEDIA_BATCH_LIMIT' ); $limit = ! $limit ? floor( 10 / max( $active_languages - 1, 1 ) ) : $limit; return max( $limit, 1 ); } function translate_attachments( $attachment_id, $source_language ) { $content_defaults = self::get_setting( 'new_content_settings' ); if ( !empty( $source_language ) && $content_defaults[ 'always_translate_media' ] ) { global $sitepress; $original_attachment_id = false; $trid = $sitepress->get_element_trid( $attachment_id, 'post_attachment' ); if ( $trid ) { $translations = $sitepress->get_element_translations( $trid, 'post_attachment', true, true ); $translated_languages = false; $default_language = $sitepress->get_default_language(); $default_language_attachment_id = false; foreach ( $translations as $translation ) { //Get the default language attachment ID if ( $translation->original ) { $original_attachment_id = $translation->element_id; } if($translation->language_code == $default_language) { $default_language_attachment_id = $translation->element_id; } //Store already translated versions $translated_languages[ ] = $translation->language_code; } // Original attachment is missing if ( !$original_attachment_id ) { $attachment = get_post( $attachment_id ); if(!$default_language_attachment_id) { self::create_duplicate_attachment( $attachment_id, $attachment->post_parent, $default_language ); } else { $sitepress->set_element_language_details($default_language_attachment_id, 'post_attachment', $trid, $default_language, null); } //Start over $this->translate_attachments( $attachment->ID, $source_language ); } else { //Original attachment is present $original = get_post( $original_attachment_id ); $codes = array_keys( $sitepress->get_active_languages() ); foreach ( $codes as $code ) { //If translation is not present, create it if ( !in_array( $code, $translated_languages ) ) { self::create_duplicate_attachment( $attachment_id, $original->post_parent, $code ); } } } } } } static function create_duplicate_attachment( $attachment_id, $parent_id, $target_language ) { global $sitepress; $attachments_model = new WPML_Model_Attachments( $sitepress, wpml_get_post_status_helper() ); $attachment_duplication = new WPML_Media_Attachments_Duplication( $sitepress, $attachments_model ); return $attachment_duplication->create_duplicate_attachment( $attachment_id, $parent_id, $target_language ); } static function is_valid_post_type( $post_type ) { global $wp_post_types; $post_types = array_keys( (array)$wp_post_types ); return in_array( $post_type, $post_types ); } function update_attachment_metadata( $source_attachment_id ) { global $sitepress; $original_element_id = $sitepress->get_original_element_id( $source_attachment_id, 'post_attachment', false, false, true ); if ( $original_element_id ) { $metadata = wp_get_attachment_metadata( $original_element_id ); $this->synchronize_attachment_metadata( $metadata, $original_element_id ); } } function wp_generate_attachment_metadata( $metadata, $attachment_id ) { $this->synchronize_attachment_metadata($metadata, $attachment_id); return $metadata; } function added_post_meta( $meta_id, $object_id, $meta_key, $_meta_value ) { if ( $meta_key != '_wp_attachment_metadata' ) { return; } $attachment_id = $object_id; $metadata = $_meta_value; $this->synchronize_attachment_metadata( $metadata, $attachment_id ); } /** * @param array $metadata * @param int $attachment_id */ public function synchronize_attachment_metadata( $metadata, $attachment_id ) { //Update _wp_attachment_metadata to all translations (excluding the current one) $attachment = new WPML_Post_Element( $attachment_id, $this->sitepress ); $attachment_source = $attachment->get_source_element(); if ( null === $attachment_source ) { $trid = $this->sitepress->get_element_trid( $attachment_id, 'post_attachment' ); if ( $trid ) { $translations = $this->sitepress->get_element_translations( $trid, 'post_attachment', true, true, true ); $attached_file = get_post_meta( $attachment_id, '_wp_attached_file', true ); foreach ( $translations as $translation ) { if ( (int) $translation->element_id !== $attachment_id ) { $translation_attached_file = get_post_meta( $translation->element_id, '_wp_attached_file', true ); if( empty( $translation_attached_file ) || $translation_attached_file === $attached_file ){ update_post_meta( $translation->element_id, '_wp_attachment_metadata', $metadata ); $mime_type = get_post_mime_type( $attachment_id ); if ( $mime_type ) { $this->wpdb->update( $this->wpdb->posts, array( 'post_mime_type' => $mime_type ), array( 'ID' => $translation->element_id ) ); } } } } } } } function batch_duplicate_media() { global $wpdb; $limit = 10; $response = array(); $attachments_prepared = $wpdb->prepare( " SELECT SQL_CALC_FOUND_ROWS p1.ID, p1.post_parent FROM {$wpdb->posts} p1 WHERE post_type = %s AND ID NOT IN (SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = %s) ORDER BY p1.ID ASC LIMIT %d", array('attachment', 'wpml_media_processed', $limit)); $attachments = $wpdb->get_results( $attachments_prepared ); $found = $wpdb->get_var( "SELECT FOUND_ROWS()" ); if ( $attachments ) { foreach ( $attachments as $attachment ) { $this->create_duplicated_media( $attachment ); } } $response[ 'left' ] = max( $found - $limit, 0 ); if ( $response[ 'left' ] ) { $response[ 'message' ] = sprintf( __( 'Duplicating media. %d left', 'wpml-media' ), $response[ 'left' ] ); } else { $response[ 'message' ] = sprintf( __( 'Duplicating media: done!', 'wpml-media' ), $response[ 'left' ] ); } echo wp_json_encode( $response ); exit; } /** * @param $attachment WP_Post */ function create_duplicated_media( $attachment ) { global $wpdb, $sitepress; static $parents_processed = array(); if ( $attachment->post_parent && !in_array( $attachment->post_parent, $parents_processed ) ) { // see if we have translations. $post_type_prepared = $wpdb->prepare("SELECT post_type FROM {$wpdb->posts} WHERE ID = %d", array($attachment->post_parent)); $post_type = $wpdb->get_var( $post_type_prepared ); $trid_prepared = $wpdb->prepare("SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id=%d AND element_type = %s", array($attachment->post_parent, 'post_' . $post_type)); $trid = $wpdb->get_var( $trid_prepared ); if ( $trid ) { update_post_meta( $attachment->post_parent, '_wpml_media_duplicate', 1 ); $attachments_prepared = $wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_parent = %d", array('attachment', $attachment->post_parent)); $attachments = $wpdb->get_col( $attachments_prepared ); $translations = $sitepress->get_element_translations( $trid, 'post_' . $post_type ); foreach ( $translations as $translation ) { if ( $translation->element_id && $translation->element_id != $attachment->post_parent ) { $attachments_in_translation_prepared = $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_parent = %d", array('attachment', $translation->element_id)); $attachments_in_translation = $wpdb->get_col( $attachments_in_translation_prepared ); if ( sizeof( $attachments_in_translation ) == 0 ) { // only duplicate attachments if there a none already. foreach ( $attachments as $attachment_id ) { // duplicate the attachment self::create_duplicate_attachment( $attachment_id, $translation->element_id, $translation->language_code ); } } } } } $parents_processed[ ] = $attachment->post_parent; } else { // no parent - set to default language $target_language = $sitepress->get_default_language(); //Getting the trid and language, just in case image translation already exists $trid = $sitepress->get_element_trid( $attachment->ID, 'post_attachment' ); if ( $trid ) { $target_language = $sitepress->get_language_for_element( $attachment->ID, 'post_attachment' ); } $sitepress->set_element_language_details( $attachment->ID, 'post_attachment', $trid, $target_language ); } //Duplicate the post meta of the source element the translation $source_element_id = SitePress::get_original_element_id_by_trid( $trid ); if ( $source_element_id ) { $this->update_attachment_metadata( $source_element_id ); } update_post_meta( $attachment->ID, 'wpml_media_processed', 1 ); } function batch_duplicate_featured_images() { $limit = 10; $response = array(); $found = self::duplicate_featured_images( $limit ); $response[ 'left' ] = max( $found - $limit, 0 ); if ( $response[ 'left' ] ) { $response[ 'message' ] = sprintf( __( 'Duplicating featured images. %d left', 'wpml-media' ), $response[ 'left' ] ); } else { $response[ 'message' ] = sprintf( __( 'Duplicating featured images: done!', 'wpml-media' ), $response[ 'left' ] ); } echo wp_json_encode( $response ); exit; } static function duplicate_featured_images( $limit = 0 ) { global $wpdb, $sitepress; $count = 0; $featured_images_sql = "SELECT * FROM {$wpdb->postmeta} WHERE meta_key = %s"; if ( $limit > 0 ) { $featured_images_sql .= " LIMIT %d"; } $featured_images_sql_prepared = $wpdb->prepare($featured_images_sql, array('_thumbnail_id', $limit)); $featured_images = $wpdb->get_results( $featured_images_sql_prepared ); $processed = $wpdb->get_var( "SELECT FOUND_ROWS()" ); $thumbnails = array(); foreach ( $featured_images as $featured ) { $thumbnails[ $featured->post_id ] = $featured->meta_value; } if ( sizeof( $thumbnails ) ) { //Posts IDs with found featured images $post_ids = wpml_prepare_in( array_keys( $thumbnails ), '%d' ); $posts_prepared = "SELECT ID, post_type FROM {$wpdb->posts} WHERE ID IN ({$post_ids})"; $posts = $wpdb->get_results( $posts_prepared ); foreach ( $posts as $post ) { $row_prepared = $wpdb->prepare("SELECT trid, source_language_code FROM {$wpdb->prefix}icl_translations WHERE element_id=%d AND element_type = %s", array($post->ID, 'post_' . $post->post_type)); $row = $wpdb->get_row( $row_prepared ); if ( $row && $row->trid && ( $row->source_language_code == null || $row->source_language_code == "" ) ) { update_post_meta( $post->ID, '_wpml_media_featured', 1 ); $translations = $sitepress->get_element_translations( $row->trid, 'post_' . $post->post_type ); foreach ( $translations as $translation ) { if ( $translation->element_id != $post->ID ) { if ( !in_array( $translation->element_id, array_keys( $thumbnails ) ) ) { // translation doesn't have a featured image $t_thumbnail_id = icl_object_id( $thumbnails[ $post->ID ], 'attachment', false, $translation->language_code ); if ( $t_thumbnail_id == null ) { $dup_att_id = self::create_duplicate_attachment( $thumbnails[ $post->ID ], $translation->element_id, $translation->language_code ); $t_thumbnail_id = $dup_att_id; } if ( $t_thumbnail_id != null ) { update_post_meta( $translation->element_id, '_thumbnail_id', $t_thumbnail_id ); } $count += 1; } elseif ( $thumbnails[ $post->ID ] ) { update_post_meta( $translation->element_id, '_thumbnail_id', $thumbnails[ $post->ID ] ); } //Double check that there is a _thumbnail_id set and in case update _wpml_media_featured if ( get_post_meta( $translation->element_id, '_thumbnail_id', true ) ) { update_post_meta( $translation->element_id, '_wpml_media_featured', 1 ); } } } } } } return $processed; } function batch_mark_processed() { /** @var $wpdb WPDB */ global $wpdb; $response = array(); $attachments_prepared = $wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_type=%s", array('attachment')); $attachments = $wpdb->get_col( $attachments_prepared ); foreach ( $attachments as $attachment_id ) { $find_meta_prepared = $wpdb->prepare("SELECT count(post_id) FROM {$wpdb->postmeta} WHERE meta_key=%s AND post_id = %d", array('wpml_media_processed', $attachment_id)); $meta_exists = $wpdb->get_var($find_meta_prepared); if($meta_exists) { $wpdb->update($wpdb->postmeta, array('meta_value' => 1), array('meta_key' => 'wpml_media_processed', 'post_id' => $attachment_id)); } else { $wpdb->insert($wpdb->postmeta, array('meta_value'=>1, 'post_id' => $attachment_id, 'meta_key' => 'wpml_media_processed')); } } self::update_setting( 'starting_help', 1 ); $response[ 'message' ] = __( 'Done!', 'wpml-media' ); echo wp_json_encode( $response ); exit; } function ajax_set_post_thumbnail() { $request_post_post_id = filter_input(INPUT_POST, 'post_id', FILTER_SANITIZE_NUMBER_INT, FILTER_NULL_ON_FAILURE); $this->sync_post_thumbnail( $request_post_post_id ); } function sync_post_thumbnail( $post_id ) { global $sitepress; if ( $post_id && get_post_meta( $post_id, '_wpml_media_featured', true ) ) { $request_post_thumbnail_id = filter_input(INPUT_POST, 'thumbnail_id', FILTER_SANITIZE_NUMBER_INT, FILTER_NULL_ON_FAILURE); $thumbnail_id = $request_post_thumbnail_id ? $request_post_thumbnail_id : get_post_meta( $post_id, '_thumbnail_id', true ); $trid = $sitepress->get_element_trid( $post_id, 'post_' . get_post_type( $post_id ) ); $translations = $sitepress->get_element_translations( $trid, 'post_' . get_post_type( $post_id ) ); // is original $is_original = false; foreach ( $translations as $translation ) { if ( $translation->original == 1 && $translation->element_id == $post_id ) { $is_original = true; } } if ( $is_original ) { foreach ( $translations as $translation ) { if ( !$translation->original && $translation->element_id ) { if ( !$thumbnail_id || $thumbnail_id == "-1" ) { delete_post_meta( $translation->element_id, '_thumbnail_id' ); } else { $translated_thumbnail_id = icl_object_id( $thumbnail_id, 'attachment', false, $translation->language_code ); update_post_meta( $translation->element_id, '_thumbnail_id', $translated_thumbnail_id ); } } } } } } function find_posts_filter() { add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) ); } function pre_get_posts( $query ) { $query->query[ 'suppress_filters' ] = 0; $query->query_vars[ 'suppress_filters' ] = 0; } function media_language_options() { global $sitepress; $att_id = filter_input(INPUT_GET, 'attachment_id', FILTER_SANITIZE_NUMBER_INT, FILTER_NULL_ON_FAILURE); $translations = $sitepress->get_element_translations( $att_id, 'post_attachment' ); $current_lang = ''; foreach ( $translations as $lang => $id ) { if ( $id == $att_id ) { $current_lang = $lang; unset( $translations[ $lang ] ); break; } } $active_languages = icl_get_languages( 'orderby=id&order=asc&skip_missing=0' ); $lang_links = ''; if ( $current_lang ) { $lang_links = '' . $active_languages[ $current_lang ][ 'native_name' ] . ''; } foreach ( $translations as $lang => $id ) { $lang_links .= ' | ' . $active_languages[ $lang ][ 'native_name' ] . ''; } echo ' '; } function icl_pro_translation_saved( $new_post_id ) { global $wpdb; // Note: We can't use filter_input here because in only filters the original post values // and not ones that are added programatically. // http://php.net/manual/en/function.filter-input.php#99124 $trid = filter_var( $_POST[ 'trid' ], FILTER_SANITIZE_NUMBER_INT, FILTER_NULL_ON_FAILURE); $lang = filter_var( $_POST[ 'lang' ], FILTER_SANITIZE_SPECIAL_CHARS, FILTER_NULL_ON_FAILURE); $source_lang_prepared = $wpdb->prepare( "SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE trid=%d AND source_language_code IS NULL", array($trid)); $source_lang = $wpdb->get_var( $source_lang_prepared ); $this->duplicate_post_attachments( $new_post_id, $trid, $source_lang, $lang ); } function duplicate_post_attachments( $pidd, $icl_trid, $source_lang = null, $lang = null ) { global $wpdb; $request_post_icl_ajx_action = filter_input(INPUT_POST, 'icl_ajx_action', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_NULL_ON_FAILURE); $request_post_icl_post_language = filter_input(INPUT_POST, 'icl_post_language', FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_NULL_ON_FAILURE); $request_post_post_id = filter_input(INPUT_POST, 'post_id', FILTER_SANITIZE_NUMBER_INT, FILTER_NULL_ON_FAILURE); if ( $icl_trid == "" ) { return; } if ( !$source_lang ) { $source_lang_prepared = $wpdb->prepare( "SELECT source_language_code FROM {$wpdb->prefix}icl_translations WHERE element_id = %d AND trid=%d", array($pidd, $icl_trid)); $source_lang = $wpdb->get_var( $source_lang_prepared ); } // exception for making duplicates. language info not set when this runs and creating the duplicated posts 1/3 if ( $request_post_icl_ajx_action == 'make_duplicates' && $request_post_icl_post_language ) { $source_lang_prepared = $wpdb->prepare( "SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE element_id = %d AND trid = %d", array($request_post_post_id, $icl_trid )); $source_lang = $wpdb->get_var( $source_lang_prepared ); $lang = $request_post_icl_post_language; } if ( $source_lang == null || $source_lang == "" ) { // This is the original see if we should copy to translations if ( $this->is_media_marked_to_duplication( $pidd ) || $this->is_feature_image_marked_to_duplication( $pidd ) ) { $translations_prepared = $wpdb->prepare("SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid = %d", array($icl_trid)); $translations = $wpdb->get_col( $translations_prepared ); foreach ( $translations as $element_id ) { if ( $element_id && $element_id != $pidd ) { $lang_prepared = $wpdb->prepare( "SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE element_id = %d AND trid = %d", array($element_id, $icl_trid )); $lang = $wpdb->get_var( $lang_prepared ); if ( $this->is_media_marked_to_duplication( $element_id ) ) { $source_attachments_prepared = $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = %s", array($pidd, 'attachment' )); $source_attachments = $wpdb->get_col( $source_attachments_prepared ); $attachments_prepared = $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = %s", array($element_id, 'attachment' )); $attachments = $wpdb->get_col( $attachments_prepared ); foreach ( $source_attachments as $source_attachment_id ) { foreach ( $attachments as $attachment_id ) { $translation_attachment_id = icl_object_id( $attachment_id, 'attachment', false, $lang ); if ( ! $translation_attachment_id ) { $this->create_duplicate_attachment_not_static( $source_attachment_id, $element_id, $lang ); } } } } if ( $this->is_feature_image_marked_to_duplication( $element_id ) ) { $thumbnail_id = get_post_meta( $pidd, '_thumbnail_id', true ); if ( $thumbnail_id ) { $t_thumbnail_id = icl_object_id( $thumbnail_id, 'attachment', false, $lang ); if ( $t_thumbnail_id == null ) { $dup_att_id = $this->create_duplicate_attachment_not_static( $thumbnail_id, $element_id, $lang ); $t_thumbnail_id = $dup_att_id; } if ( $t_thumbnail_id != null ) { update_post_meta( $element_id, '_thumbnail_id', $t_thumbnail_id ); } } } } } } } else { // This is a translation. // exception for making duplicates. language info not set when this runs and creating the duplicated posts 2/3 if ( $request_post_icl_ajx_action === 'make_duplicates' ) { $source_id = $request_post_post_id; } else { $source_id_prepared = $wpdb->prepare("SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE language_code = %s AND trid = %d", array($source_lang, $icl_trid)); $source_id = $wpdb->get_var( $source_id_prepared ); } if ( !$lang ) { $lang_prepared = $wpdb->prepare( "SELECT language_code FROM {$wpdb->prefix}icl_translations WHERE element_id = %d AND trid = %d", array($pidd, $icl_trid)); $lang = $wpdb->get_var( $lang_prepared ); } // exception for making duplicates. language info not set when this runs and creating the duplicated posts 3/3 if ( $request_post_icl_ajx_action === 'make_duplicates' ) { $duplicate = get_post_meta( $source_id, '_wpml_media_duplicate', true ); } else { $duplicate = get_post_meta( $pidd, '_wpml_media_duplicate', true ); if ( !$duplicate ) { // check the original state $duplicate = get_post_meta( $source_id, '_wpml_media_duplicate', true ); } } if ( $duplicate ) { $source_attachments_prepared = $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = %s", array($source_id, 'attachment')); $source_attachments = $wpdb->get_col( $source_attachments_prepared ); foreach ( $source_attachments as $source_attachment_id ) { $translation_attachment_id = icl_object_id( $source_attachment_id, 'attachment', false, $lang ); if ( !$translation_attachment_id ) { self::create_duplicate_attachment( $source_attachment_id, $pidd, $lang ); } else { $translated_attachment = get_post( $translation_attachment_id ); if ( $translated_attachment && !$translated_attachment->post_parent ) { $translated_attachment->post_parent = $pidd; wp_update_post( $translated_attachment ); } } } } $featured = get_post_meta( $pidd, '_wpml_media_featured', true ); if ( $featured === "" ) { // check the original state $featured = get_post_meta( $source_id, '_wpml_media_featured', true ); } if ( $featured ) { $thumbnail_id = get_post_meta( $source_id, '_thumbnail_id', true ); if ( $thumbnail_id ) { $t_thumbnail_id = icl_object_id( $thumbnail_id, 'attachment', false, $lang ); if ( $t_thumbnail_id == null ) { $dup_att_id = self::create_duplicate_attachment( $thumbnail_id, $pidd, $lang ); $t_thumbnail_id = $dup_att_id; } if ( $t_thumbnail_id != null ) { update_post_meta( $pidd, '_thumbnail_id', $t_thumbnail_id ); } } } } } /** * @param $source_attachment_id * @param $pidd * @param $lang * * @return int|null|WP_Error */ public function create_duplicate_attachment_not_static( $source_attachment_id, $pidd, $lang ) { return self::create_duplicate_attachment( $source_attachment_id, $pidd, $lang ); } /** * @param int $post_id * * @return bool */ private function is_media_marked_to_duplication( $post_id ) { $t = get_post_meta( $post_id, '_wpml_media_duplicate', true ); return ! empty( $t ); } /** * @param int $post_id * * @return bool */ private function is_feature_image_marked_to_duplication( $post_id ) { $t = get_post_meta( $post_id, '_wpml_media_featured', true ); return ! empty( $t ); } /** * @param $pidd int * @param $post WP_Post */ function save_post_actions( $pidd, $post ) { if ( $post->post_type != 'attachment' && $post->post_status != "auto-draft" ) { $this->sync_attachments( $pidd, $post ); $this->sync_post_thumbnail( $pidd ); } if ( $post->post_type === 'attachment' ) { $metadata = wp_get_attachment_metadata( $post->ID ); $attachment_id = $pidd; if ( $metadata ) { $this->synchronize_attachment_metadata( $metadata, $attachment_id ); } } } /** * @param $pidd int * @param $post WP_Post */ function sync_attachments( $pidd, $post ) { if ( $post->post_type == 'attachment' || $post->post_status == "auto-draft" ) return; global $wpdb, $sitepress; $posts_prepared = $wpdb->prepare("SELECT post_type, post_status FROM {$wpdb->posts} WHERE ID = %d", array($pidd)); list( $post_type, $post_status ) = $wpdb->get_row( $posts_prepared, ARRAY_N ); //checking - if translation and not saved before if ( isset( $_GET[ 'trid' ] ) && !empty( $_GET[ 'trid' ] ) && $post_status == 'auto-draft' ) { //get source language if ( isset( $_GET[ 'source_lang' ] ) && !empty( $_GET[ 'source_lang' ] ) ) { $src_lang = $_GET[ 'source_lang' ]; } else { $src_lang = $sitepress->get_default_language(); } //get source id $src_id_prepared = $wpdb->prepare("SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE trid=%d AND language_code=%s", array($_GET['trid'], $src_lang)); $src_id = $wpdb->get_var( $src_id_prepared ); //delete exist auto-draft post media $results_prepared = $wpdb->prepare("SELECT p.id FROM {$wpdb->posts} AS p LEFT JOIN {$wpdb->posts} AS p1 ON p.post_parent = p1.id WHERE p1.post_status = %s", array('auto-draft')); $results = $wpdb->get_results( $results_prepared, ARRAY_A ); $attachments = array(); if ( !empty( $results ) ) { foreach ( $results as $result ) { $attachments[ ] = $result[ "id" ]; } if ( !empty( $attachments ) ) { $in_attachments = wpml_prepare_in( $attachments, '%d' ); $delete_prepared = "DELETE FROM {$wpdb->posts} WHERE id IN (" . $in_attachments . ")"; $wpdb->query( $delete_prepared ); $delete_prepared = "DELETE FROM {$wpdb->postmeta} WHERE post_id IN (" . $in_attachments . ")"; $wpdb->query( $delete_prepared ); } } //checking - if set duplicate media if ( get_post_meta( $src_id, '_wpml_media_duplicate', true ) ) { //duplicate media before first save $this->duplicate_post_attachments( $pidd, $_GET[ 'trid' ], $src_lang, $sitepress->get_language_for_element( $pidd, 'post_' . $post_type ) ); } } // exceptions if ( !$sitepress->is_translated_post_type( $post_type ) || isset( $_POST[ 'autosave' ] ) || ( isset( $_POST[ 'post_ID' ] ) && $_POST[ 'post_ID' ] != $pidd ) || ( isset( $_POST[ 'post_type' ] ) && $_POST[ 'post_type' ] === 'revision' ) || $post_type === 'revision' || get_post_meta( $pidd, '_wp_trash_meta_status', true ) || ( isset( $_GET[ 'action' ] ) && $_GET[ 'action' ] === 'restore' ) || $post_status === 'auto-draft' ) { return; } if ( isset( $_POST[ 'icl_trid' ] ) ) { $content_defaults_option = self::get_setting( 'new_content_settings' ); $duplicate = false; $featured = false; if ( $content_defaults_option ) { if ( isset( $_POST[ 'icl_duplicate_attachments' ] ) ) { $duplicate = (int) $_POST['icl_duplicate_attachments']; } if ( isset( $_POST[ 'icl_duplicate_featured_image' ] ) ) { $featured = (int) $_POST['icl_duplicate_featured_image']; } } // save the post from the edit screen. update_post_meta( $pidd, '_wpml_media_duplicate', $duplicate ); update_post_meta( $pidd, '_wpml_media_featured', $featured ); $icl_trid = $_POST[ 'icl_trid' ]; } else { // get trid from database. $icl_trid_prepared = $wpdb->prepare("SELECT trid FROM {$wpdb->prefix}icl_translations WHERE element_id=%d AND element_type = %s", array($pidd, 'post_' . $post_type)); $icl_trid = $wpdb->get_var( $icl_trid_prepared ); } if ( $icl_trid ) { $language_details = $sitepress->get_element_language_details( $pidd, 'post_' . $post_type ); // In some cases the sitepress cache doesn't get updated (e.g. when posts are created with wp_insert_post() // Only in this case, the sitepress cache will be cleared so we can read the element language details if ( !$language_details ) { $sitepress->get_translations_cache()->clear(); $language_details = $sitepress->get_element_language_details( $pidd, 'post_' . $post_type ); } if ( $language_details ) { $this->duplicate_post_attachments( $pidd, $icl_trid, $language_details->source_language_code, $language_details->language_code ); } } } // function sync_attachments_metadata($post_id) { // $data = // } function make_duplicate( $master_post_id, $target_lang, $post_array, $target_post_id ) { global $wpdb, $sitepress; $translated_attachment_id = false; //Get Master Post attachments $master_post_attachment_ids_prepared = $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_parent = %d AND post_type = %s", array($master_post_id, 'attachment')); $master_post_attachment_ids = $wpdb->get_col( $master_post_attachment_ids_prepared ); if ( $master_post_attachment_ids ) { foreach ( $master_post_attachment_ids as $master_post_attachment_id ) { $attachment_trid = $sitepress->get_element_trid( $master_post_attachment_id, 'post_attachment' ); if ( $attachment_trid ) { //Get attachment translation $attachment_translations = $sitepress->get_element_translations( $attachment_trid, 'post_attachment' ); foreach ( $attachment_translations as $attachment_translation ) { if ( $attachment_translation->language_code == $target_lang ) { $translated_attachment_id = $attachment_translation->element_id; break; } } if ( !$translated_attachment_id ) { $translated_attachment_id = self::create_duplicate_attachment( $master_post_attachment_id, wp_get_post_parent_id( $master_post_id ), $target_lang ); } if ( $translated_attachment_id ) { //Set the parent post, if not already set $translated_attachment = get_post( $translated_attachment_id ); if ( !$translated_attachment->post_parent ) { $prepared_query = $wpdb->prepare( "UPDATE {$wpdb->posts} SET post_parent=%d WHERE ID=%d", array($target_post_id, $translated_attachment_id )); $wpdb->query( $prepared_query ); } } } } } // Duplicate the featured image. $thumbnail_id = get_post_meta( $master_post_id, '_thumbnail_id', true ); if ( $thumbnail_id ) { $thumbnail_trid = $sitepress->get_element_trid( $thumbnail_id, 'post_attachment' ); if ( $thumbnail_trid ) { // translation doesn't have a featured image $t_thumbnail_id = icl_object_id( $thumbnail_id, 'attachment', false, $target_lang ); if ( $t_thumbnail_id == null ) { $dup_att_id = self::create_duplicate_attachment( $thumbnail_id, $target_post_id, $target_lang ); $t_thumbnail_id = $dup_att_id; } if ( $t_thumbnail_id != null ) { update_post_meta( $target_post_id, '_thumbnail_id', $t_thumbnail_id ); } } } return $translated_attachment_id; } /** * Synchronizes _wpml_media_* meta fields with all translations * * @param int $meta_id * @param int $object_id * @param string $meta_key * @param string|mixed $meta_value */ function updated_postmeta( $meta_id, $object_id, $meta_key, $meta_value ) { if ( in_array( $meta_key, array( '_wpml_media_duplicate', '_wpml_media_featured' ) ) ) { global $sitepress; $el_type = 'post_' . get_post_type( $object_id ); $trid = $sitepress->get_element_trid( $object_id, $el_type ); $translations = $sitepress->get_element_translations( $trid, $el_type, true, true ); foreach ( $translations as $translation ) { if ( $translation->element_id != $object_id ) { $t_meta_value = get_post_meta( $translation->element_id, $meta_key, true ); if ( $t_meta_value != $meta_value ) { update_post_meta( $translation->element_id, $meta_key, $meta_value ); } } } } } function save_attachment_actions( $post_id ) { if ( $this->is_uploading_plugin_or_theme() && get_post_type($post_id) == 'attachment' ) return; global $wpdb, $sitepress; $media_language = $sitepress->get_language_for_element( $post_id, 'post_attachment' ); $trid = false; if ( !empty( $media_language ) ) { $trid = $sitepress->get_element_trid( $post_id, 'post_attachment' ); } if ( empty( $media_language ) ) { $parent_post_sql = "SELECT p2.ID, p2.post_type FROM {$wpdb->posts} p1 JOIN {$wpdb->posts} p2 ON p1.post_parent = p2.ID WHERE p1.ID=%d"; $parent_post_prepared = $wpdb->prepare( $parent_post_sql, array( $post_id ) ); $parent_post = $wpdb->get_row( $parent_post_prepared ); if ( $parent_post ) { $media_language = $sitepress->get_language_for_element( $parent_post->ID, 'post_' . $parent_post->post_type ); } if ( empty( $media_language ) ) { $media_language = $sitepress->get_admin_language_cookie(); } if ( empty( $media_language ) ) { $media_language = $sitepress->get_default_language(); } } if ( !empty( $media_language ) ) { $sitepress->set_element_language_details( $post_id, 'post_attachment', $trid, $media_language ); $this->save_translated_attachments( $post_id ); $this->update_attachment_metadata( $post_id ); } } function save_translated_attachments( $post_id ) { if ( $this->is_uploading_plugin_or_theme() && get_post_type($post_id) == 'attachment' ) return; global $sitepress; $language_details = $sitepress->get_element_language_details( $post_id, 'post_attachment' ); if ( isset( $language_details ) ) { $this->translate_attachments( $post_id, $language_details->language_code ); } } function language_options() { $translation = false; $translated_id = null; $source_id = $this->get_original_post_id(); //This is a translation with no original content if ( $translation && !$translated_id ) return; echo '