Changelog
0.8
- added show_current_blog / added params for show_linked_elements
- removed get_linked_elements request for is_home
- added filter to remove the static ?noredirect= parameter
0.7
- Added mlp_get_interlinked_permalinks
- Added mlp_get_blog_language
0.6
- Codexified
- Fixed Notices
0.5.2a
- Initial Commit
/** * Get markup and language title for each site * * @param string $column_name not used * @param int $blog_id * * @return string */ function mlp_render_site_language_column($column_name, $blog_id) { switch_to_blog($blog_id); $lang = Mlp_Helpers::get_current_blog_language(); restore_current_blog(); if (empty($lang)) { return esc_html__('none', 'multilingualpress'); } $lang = Mlp_Helpers::get_lang_by_iso($lang); return '<div class="mlp_site_language">' . $lang . '</div>'; }
/** * @param WP_Post $source_post * @param int $blog_id * @return WP_Post */ public function get_remote_post(WP_Post $source_post, $blog_id) { $post = NULL; $linked = Mlp_Helpers::load_linked_elements($source_post->ID, '', get_current_blog_id()); if (!empty($linked[$blog_id]) && blog_exists($blog_id)) { $post = get_blog_post($blog_id, $linked[$blog_id]); } if ($post) { return $post; } return $this->get_dummy_post($source_post->post_type); }
/** * Add related site title for each site to network site view * * @param string $column_name not used * @param int $blog_id * * @return string */ function mlp_render_related_blog_column($column_name, $blog_id) { switch_to_blog($blog_id); $blogs = (array) Mlp_Helpers::get_available_languages_titles(); restore_current_blog(); unset($blogs[$blog_id]); if (empty($blogs)) { return esc_html__('none', 'multilingual-press'); } $blogs = array_map('esc_html', $blogs); return '<div class="mlp_interlinked_blogs">' . join('<br>', $blogs) . '</div>'; }
/** * Frontend display. * * When a widget is restored from trash, the instance might be incomplete, hence the preparations. * * @param array $args Widget arguments. * @param array $instance Widget settings. * * @return void */ public function widget($args, $instance) { $instance = $this->adapt_settings($instance); $link_type = 'text'; if (!empty($instance['widget_link_type'])) { $link_type = $instance['widget_link_type']; } $display_flag = FALSE; if (!empty($instance['widget_display_flag'])) { $display_flag = $instance['widget_display_flag']; } $show_current = TRUE; if (isset($instance['widget_show_current_blog'])) { $show_current = (int) $instance['widget_show_current_blog'] === 1; } $output_args = array('link_text' => $link_type, 'show_current_blog' => $show_current, 'display_flag' => $display_flag); $output = Mlp_Helpers::show_linked_elements($output_args); if (!$output) { return; } $title = ''; if (isset($instance['widget_title'])) { $title = $instance['widget_title']; } /** This filter is documented in wp-includes/default-widgets.php */ $title = apply_filters('widget_title', $title); echo $args['before_widget']; if (!empty($instance['widget_title'])) { echo $args['before_title'] . $title . $args['after_title']; } echo $output; echo $args['after_widget']; }
/** * @param array $site_option * @return void */ private function show_blog_relationships($site_option) { if (!is_array($site_option)) { return; } unset($site_option[$this->blog_id]); if (empty($site_option)) { return; } ?> <tr> <td><?php esc_html_e('Relationships', 'multilingualpress'); ?> </td> <td> <?php foreach ($site_option as $blog_id => $meta) { $blog_id = (int) $blog_id; // Get blog display name switch_to_blog($blog_id); $blog_name = esc_html(get_bloginfo('Name')); restore_current_blog(); // Get current settings $related_blogs = $this->relations->get_related_sites($this->blog_id, FALSE); $checked = checked(TRUE, in_array($blog_id, $related_blogs), FALSE); $id = "related_blog_{$blog_id}"; ?> <p> <label for="<?php echo $id; ?> "> <input id="<?php echo $id; ?> " <?php echo $checked; ?> type="checkbox" name="related_blogs[]" value="<?php echo $blog_id; ?> " /> <?php echo $blog_name; ?> - <?php echo Mlp_Helpers::get_blog_language($blog_id); ?> </label> </p> <?php } ?> <p class="description"> <?php esc_html_e('You can connect this site only to sites with an assigned language. Other sites will not show up here.', 'multilingualpress'); ?> </p> </td> </tr> <?php }
/** * Print tab content and provide two hooks. * * @return void */ public function render_content() { $languages = $this->language_api->get_db()->get_items(array('page' => -1)); ob_start(); ?> <h3>MultilingualPress</h3> <table class="form-table"> <tr class="form-field"> <td> <label for="inpsyde_multilingual_lang"> <?php esc_html_e('Language', 'multilingualpress'); ?> </label> </td> <td> <select name="inpsyde_multilingual_lang" id="inpsyde_multilingual_lang"> <option value="-1"><?php esc_html_e('Choose language', 'multilingualpress'); ?> </option> <?php foreach ($languages as $language) { // missing HTTP code if (empty($language->http_name)) { continue; } echo '<option value="' . esc_attr($language->http_name) . '">' . $language->english_name . '/' . $language->native_name . '</option>'; } ?> </select> </td> </tr> <tr class="form-field"> <td> <label for="inpsyde_multilingual_text"> <?php esc_html_e('Alternative language title', 'multilingualpress'); ?> </label> </td> <td> <input class="regular-text" type="text" id="inpsyde_multilingual_text" name="inpsyde_multilingual_text" /> <p class="description"><?php esc_html_e('Enter a title here that you want to be displayed in the frontend instead of the default one (i.e. "My English Site")', 'multilingualpress'); ?> </p> </td> </tr> <tr class="form-field"> <td> <label for="inpsyde_multilingual_text"> <?php esc_html_e('Relationships', 'multilingualpress'); ?> </label> </td> <td><?php $site_option = get_site_option('inpsyde_multilingual', array()); foreach ($site_option as $blog_id => $meta) { $blog_id = (int) $blog_id; // Get blog display name switch_to_blog($blog_id); $blog_name = esc_html(get_bloginfo('Name')); restore_current_blog(); $id = "related_blog_{$blog_id}"; ?> <p> <label for="<?php echo $id; ?> "> <input style="width:auto;" id="<?php echo $id; ?> " type="checkbox" name="related_blogs[]" value="<?php echo $blog_id; ?> " /> <?php echo $blog_name; ?> - <?php echo Mlp_Helpers::get_blog_language($blog_id); ?> </label> </p> <?php } ?> <p class="description"> <?php esc_html_e('You can connect this site only to sites with an assigned language. Other sites will not show up here.', 'multilingualpress'); ?> </p> </td> </tr> <?php do_action('mlp_after_new_blog_fields'); ?> </table> <?php $template = ob_get_contents(); ob_end_clean(); ?> <script> ( function( $ ) { $(document).ready( function(){ var submit = $( 'form' ).find( '.submit' ), template = '<?php echo str_replace("\n", "", $template); ?> ' ; submit.before( template ); } ); } )( jQuery ); </script> <?php }
/** * @return void */ private function prepare_helpers() { Mlp_Helpers::$link_table = $this->link_table; Mlp_Helpers::insert_dependency('site_relations', $this->plugin_data->get('site_relations')); Mlp_Helpers::insert_dependency('language_api', $this->plugin_data->get('language_api')); Mlp_Helpers::insert_dependency('plugin_data', $this->plugin_data); }
/** * Initial setup handler. * * @global $wpdb wpdb WordPress Database Wrapper * @global $pagenow string Current Page Wrapper * @return void */ public function setup() { global $pagenow; $this->link_table = $this->wpdb->base_prefix . 'multilingual_linked'; $this->plugin_dir_path = $this->plugin_data->plugin_dir_path; $this->plugin_file_path = $this->plugin_data->plugin_file_path; $this->plugin_data->module_manager = new Mlp_Module_Manager('state_modules'); $this->plugin_data->site_manager = new Mlp_Module_Manager('inpsyde_multilingual'); $this->plugin_data->link_table = $this->link_table; $this->plugin_data->content_relations = new Mlp_Content_Relations($this->wpdb, $this->plugin_data->site_relations, $this->link_table); $this->plugin_data->language_api = new Mlp_Language_Api($this->plugin_data, 'mlp_languages', $this->plugin_data->site_relations, $this->plugin_data->content_relations, $this->wpdb); $this->plugin_data->assets = new Mlp_Assets($this->plugin_data->locations); $this->load_assets(); Mlp_Helpers::$link_table = $this->link_table; Mlp_Helpers::insert_dependency('site_relations', $this->plugin_data->site_relations); Mlp_Helpers::insert_dependency('language_api', $this->plugin_data->language_api); Mlp_Helpers::insert_dependency('plugin_data', $this->plugin_data); $this->plugin_data->freeze(); // no changes allowed anymore require 'functions.php'; // This check prevents the use of this plugin in a not-setted blog if ('admin-post.php' != $pagenow && 'admin-ajax.php' != $pagenow && !is_network_admin() && !array_key_exists(get_current_blog_id(), get_site_option('inpsyde_multilingual', array()))) { return; } // The Plugins Basename // used by features/class-Multilingual_Press_Auto_Update.php only self::$plugin_base_name = $this->plugin_data->plugin_base_name; // The Plugins URL self::$plugin_url = $this->plugin_data->plugin_uri; // The Plugins Name self::$plugin_name = $this->plugin_data->plugin_name; // Textdomain Path self::$textdomainpath = $this->plugin_data->text_domain_path; // Hooks and filters add_action('inpsyde_mlp_loaded', array($this, 'load_plugin_textdomain'), 1); // Load modules $this->load_features(); /** * Kick-Off Init * @return Void */ do_action('inpsyde_mlp_init', $this->plugin_data); // Enqueue scripts add_action('admin_enqueue_scripts', array($this, 'admin_scripts')); // Cleanup upon blog delete add_filter('delete_blog', array($this, 'delete_blog'), 10, 2); // Checkup blog cleanup add_filter('admin_head', array($this, 'checkup_blog_message')); add_filter('wp_ajax_checkup_blogs', array($this, 'checkup_blog')); // Check for errors add_filter('all_admin_notices', array($this, 'check_for_user_errors_admin_notice')); add_action('wp_loaded', array($this, 'late_load'), 0); /** * Everything loaded * @param Inpsyde_Property_List_Interface */ do_action('inpsyde_mlp_loaded', $this->plugin_data); if (is_admin()) { if ($this->plugin_data->module_manager->has_modules()) { $this->load_module_settings_page(); } if ($this->plugin_data->site_manager->has_modules()) { $this->load_site_settings_page(); } new Mlp_Network_Site_Settings_Controller($this->plugin_data); new Mlp_Network_New_Site_Controller($this->plugin_data->language_api, $this->plugin_data->site_relations); } else { // frontend-hooks $hreflang = new Mlp_Hreflang_Header_Output($this->plugin_data->language_api); add_action('template_redirect', array($hreflang, 'http_header')); add_action('wp_head', array($hreflang, 'wp_head')); } }
/** * Get language representation. * * @since 1.0.4 * @param string $iso Two-letter code like "en" or "de" * @param string $field Sub-key name: "iso_639_2", "en" or "native", * defaults to "native", "all" returns the complete list. * @return boolean|array|string FALSE for unknown language codes or fields, * array for $field = 'all' and string for specific fields */ function mlp_get_lang_by_iso($iso, $field = 'native') { return Mlp_Helpers::mlp_get_lang_by_iso($iso, $field); }
/** * @return void */ public function prepare_plugin_data() { $site_relations = $this->container['multilingualpress.site_relations']; $content_relations = $this->container['multilingualpress.content_relations']; $type_factory = $this->container['multilingualpress.type_factory']; $language_api = new Mlp_Language_Api($this->plugin_data, 'mlp_languages', $site_relations, $content_relations, $this->wpdb, $type_factory, $this->container['multilingualpress.request']); $this->plugin_data->set('module_manager', $this->container['multilingualpress.module_manager']); $this->plugin_data->set('site_relations', $site_relations); $this->plugin_data->set('type_factory', $type_factory); $this->plugin_data->set('link_table', $this->container['multilingualpress.content_relations_table']->name()); $this->plugin_data->set('content_relations', $content_relations); $this->plugin_data->set('language_api', $language_api); // TODO: Remove as soon as the whole Assets structures have been refactored (Locations -> Assets\Locator). $this->plugin_data->set('assets', $this->container['multilingualpress.asset_manager']); $this->plugin_data->set('languages', $this->container['multilingualpress.languages']); $this->plugin_data->set('locations', $this->container['multilingualpress.internal_locations']); $this->plugin_data->set('nonce_factory', $this->container['multilingualpress.nonce_factory']); Mlp_Helpers::insert_dependency('language_api', $this->plugin_data->get('language_api')); }
/** * Renders the relationship settings. * * @return void */ private function render_relationships() { $sites = get_site_option('inpsyde_multilingual', array()); foreach (array_keys($sites) as $site_id) { $site_id = (int) $site_id; $id = "related_blog_{$site_id}"; switch_to_blog($site_id); $blog_name = get_bloginfo('name'); restore_current_blog(); ?> <p> <label for="<?php echo $id; ?> "> <input type="checkbox" name="related_blogs[]" value="<?php echo $site_id; ?> " id="<?php echo $id; ?> "> <?php echo esc_html($blog_name) . '-' . Mlp_Helpers::get_blog_language($site_id); ?> </label> </p> <?php } }
/** * get the linked elements with a lot of more information * * @since 0.7 * * @param int $element_id current post / page / whatever * * @return array */ function mlp_get_interlinked_permalinks($element_id = 0) { return Mlp_Helpers::get_interlinked_permalinks($element_id); }
/** * Save the post to the blogs * * @access public * @since 0.1 * @uses DOING_AUTOSAVE, get_option, current_user_can, get_post_status, get_site_option, get_current_blog_id, * wp_verify_nonce, plugin_basename, switch_to_blog, restore_current_blog, wp_update_post, wp_insert_post, * has_post_thumbnail, ABSPATH, get_post_thumbnail_id, wp_get_attachment_metadata, wp_upload_dir, * wp_unique_filename, wp_check_filetype, get_current_user_id, wp_insert_attachment, is_wp_error, * wp_update_attachment_metadata, wp_generate_attachment_metadata, update_post_meta * @global $wpdb WordPress Database Wrapper * @return void */ public function save_post($post_id, $post = NULL) { // Preventing Autosave, we don't want that if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return; } // We don't need to save because there is no Post array if (empty($_POST)) { return; } $related_blogs = get_option('inpsyde_multilingual_blog_relationship'); // We don't need to save because there is no related blog if (empty($related_blogs)) { return; } // We need an array, if it is not, there are no related blogs if (!is_array($related_blogs)) { return; } // Make me unique $related_blogs = array_unique($related_blogs); // Check permissions if ('page' === $post->post_type && !current_user_can('edit_page', $post_id)) { return; } else { if (!current_user_can('edit_post', $post_id)) { return; } } // We only need this, when the post is published oder drafted if (!in_array($post->post_status, array('publish', 'draft', 'private'))) { return; } // Check Post Type if (!in_array($post->post_type, array('post', 'page'))) { return; } global $wpdb; $available_blogs = get_site_option('inpsyde_multilingual'); // Avoid recursion: // wp_insert_post() invokes the save_post hook, so we have to make sure // the loop below is only entered once per save action. Therefore we save // the source_blog in a static class variable. If it is already set we // know the loop has already been entered and we can exit the save action. if (NULL === self::$source_blog) { self::$source_blog = get_current_blog_id(); } else { return; } // Setting up relationship data $ml_type = ''; if ('post' !== $post->post_type) { $ml_type = $post->post_type; } $post_meta = $this->get_post_meta_to_transfer($post_id); $post_meta = apply_filters('mlp_pre_save_post_meta', $post_meta); // Set source $this->set_linked_element($_POST['ID'], $_POST['ID'], self::$source_blog, $ml_type, self::$source_blog); foreach ($related_blogs as $blog_to_translate) { if ($blog_to_translate != self::$source_blog) { $lang = $available_blogs[$blog_to_translate]['lang']; // verify this came from the our screen and with proper authorization, // because save_post can be triggered at other times if (isset($_POST['multilingualpress' . '-' . $lang]) && !wp_verify_nonce($_POST['multilingualpress' . '-' . $lang], plugin_basename(__FILE__))) { continue; } // If we don't want to save the post for this language, go to the next one if (!isset($_POST['do_translate_' . $lang])) { continue; } // We need to switch the blog to save the post switch_to_blog($blog_to_translate); // Setup Post Data if ('' != $_POST['post_title_' . $lang]) { $mlp_post_title = $_POST['post_title_' . $lang]; } else { $mlp_post_title = $_POST['post_title']; } if ('' != $_POST['content_' . $lang]) { $mlp_post_content = $_POST['content_' . $lang]; } else { $mlp_post_content = $_POST['content']; } if (!isset($_POST['category_' . $lang])) { $mlp_post_categories = array(); } else { $mlp_post_categories = $_POST['category_' . $lang]; } $mlp_post_data = array('post_author' => get_current_user_id(), 'post_type' => $post->post_type, 'post_format' => isset($_POST['post_format']) ? $_POST['post_format'] : '', 'post_title' => $mlp_post_title, 'post_content' => $mlp_post_content, 'post_category' => $mlp_post_categories, 'tags_input' => isset($_POST['tags_' . $lang]) ? $_POST['tags_' . $lang] : ''); // Check for Update $update_post_id = $_POST['old_post_id_' . $lang]; // Double Check $update_post_id $has_link = Mlp_Helpers::load_linked_elements($post_id, '', self::$source_blog); if (0 < $update_post_id && !$linked) { // Update Post $mlp_post_data['ID'] = $update_post_id; // use filter to change postdata for every blog $mlp_post_data = apply_filters('mlp_pre_update_post', $mlp_post_data); $translated_post_id = wp_update_post($mlp_post_data); } else { $mlp_post_data['post_status'] = 'draft'; // use filter to change postdata for every blog $mlp_post_data = apply_filters('mlp_pre_insert_post', $mlp_post_data); // Insert Post $translated_post_id = wp_insert_post($mlp_post_data); // Insert Relationship $this->set_linked_element($translated_post_id, $post_id, self::$source_blog, $ml_type, $blog_to_translate); // Insert postmeta $this->update_remote_post_meta($translated_post_id, $post_meta); } // We have to get back to the original blog to load the thumbnail restore_current_blog(); // Post Thumbnail if (isset($_POST['copy_thumbnail_' . $lang]) && 'on' == $_POST['copy_thumbnail_' . $lang]) { // Stop if there is no thumbnail if (!has_post_thumbnail($post_id)) { continue; } // We need some image and media functions in here include_once ABSPATH . 'wp-admin/includes/image.php'; include_once ABSPATH . 'wp-includes/media.php'; // Load Original Image $original_attachment_id = get_post_thumbnail_id($post_id); $original_attachment = wp_get_attachment_metadata($original_attachment_id); // Build Path to Originial Image $original_filedir = wp_upload_dir(); $original_file_path = $original_filedir['basedir'] . '/' . $original_attachment['file']; // Now switch to the new blog and post the image switch_to_blog($blog_to_translate); // Prepare and Copy the image $filedir = wp_upload_dir(); if (!is_dir($filedir['path'])) { wp_mkdir_p($filedir['path']); } $filename = wp_unique_filename($filedir['path'], $original_attachment['file']); $copy = copy($original_file_path, $filedir['path'] . '/' . $filename); // Now insert it into the posts if ($copy) { $wp_filetype = wp_check_filetype($filedir['url'] . '/' . $filename); $attachment = array('post_mime_type' => $wp_filetype['type'], 'guid' => $filedir['url'] . '/' . $filename, 'post_parent' => $translated_post_id, 'post_title' => '', 'post_excerpt' => '', 'post_author' => get_current_user_id(), 'post_content' => ''); $attach_id = wp_insert_attachment($attachment, $filedir['path'] . '/' . $filename); // Everything went well? if (!is_wp_error($attach_id)) { wp_update_attachment_metadata($attach_id, wp_generate_attachment_metadata($attach_id, $filedir['path'] . '/' . $filename)); update_post_meta($translated_post_id, '_thumbnail_id', $attach_id); } } // Aaaaand finish! restore_current_blog(); } } } }