/** * Hooks the WP admin_init action to redirect any requests accessing * content which is not in the current language. * * @return void **/ function bbl_admin_init() { global $pagenow; $taxonomy = isset($_GET['taxonomy']) ? sanitize_text_field($_GET['taxonomy']) : false; $post_type = isset($_GET['post_type']) ? sanitize_text_field($_GET['post_type']) : false; // Deal with the special URL case of the listing screens for vanilla posts if (!$post_type && 'edit.php' == $pagenow) { $post_type = 'post'; } $cur_lang_code = bbl_get_current_lang_code(); if ($taxonomy) { $new_taxonomy = bbl_get_taxonomy_in_lang($taxonomy, $cur_lang_code); if ($taxonomy != $new_taxonomy) { $url = add_query_arg(array('taxonomy' => rawurlencode($new_taxonomy))); wp_safe_redirect($url); exit; } } if ($post_type) { $new_post_type = bbl_get_post_type_in_lang($post_type, $cur_lang_code); if ($post_type != $new_post_type) { $url = add_query_arg(array('post_type' => rawurlencode($new_post_type))); wp_safe_redirect($url); exit; } } }
/** * Hooks the Babble bbl_pre_sync_properties filter to * log any changes to parent. We're not making changes * to the data, just logging significant changes for * debug purposes. * * @param array $postdata The data which will be applied to the post as part of the sync * @param int $origin_id The ID of the post we are syncing from * @return array The data which will be applied to the post as part of the sync **/ public function pre_sync_properties($postdata, $origin_id) { $current_post = get_post($postdata['ID']); if ($current_post->post_parent != $postdata['post_parent']) { $user = wp_get_current_user(); $remote_ip = $_SERVER['REMOTE_ADDR']; $referer = $_SERVER['HTTP_REFERER']; $lang = bbl_get_current_lang_code(); $origin_lang = bbl_get_post_lang_code($origin_id); bbl_log("Babble: {$user->user_login} has changed {$postdata['ID']} parent from {$current_post->post_parent} ({$current_post->post_type}) to {$postdata['post_parent']}. \tOrigin: {$origin_id}. Origin lang: {$origin_lang}. IP {$remote_ip}. User lang: {$lang}. Referer {$referer}.", true); } return $postdata; }
/** * Takes a set of query vars and amends them to show the content * in the current language. * * @param array $query_vars A set of WordPress query vars (sometimes called query arguments) * @param string|boolean $request If this is called on the parse_request hook, $request contains the root relative URL * @return array $query_vars A set of WordPress query vars **/ protected function translate_query_vars(array $query_vars, $request = false) { // Sequester the original query, in case we need it to get the default content later $query_vars['bbl_original_query'] = $query_vars; // We've done this already (avoid re-translating the vars) if (isset($query_vars['bbl_done_translation']) && $query_vars['bbl_done_translation']) { return $query_vars; } $query_vars['bbl_done_translation'] = true; $lang_url_prefix = isset($query_vars['lang_url_prefix']) ? $query_vars['lang_url_prefix'] : get_query_var('lang_url_prefix'); $lang = isset($query_vars['lang']) ? $query_vars['lang'] : get_query_var('lang'); // Detect language specific homepages if ($request == $lang_url_prefix) { // This is running in Admin, and as such seems to be f*****g up the menus. Idk when this became an issue. if (isset($query_vars['post_type']) && 'nav_menu_item' == $query_vars['post_type']) { return $query_vars; } unset($query_vars['error']); // @FIXME: Cater for front pages which don't list the posts if ('page' == get_option('show_on_front') && ($page_on_front = get_option('page_on_front'))) { // @TODO: Get translated page ID $query_vars['p'] = $this->get_post_in_lang($page_on_front, bbl_get_current_lang_code())->ID; $query_vars['post_type'] = $this->get_post_type_in_lang('page', bbl_get_current_lang_code()); return $query_vars; } // Trigger the archive listing for the relevant shadow post type // of 'post' for this language. if (bbl_get_default_lang_code() != $lang && empty($query_vars['s'])) { $post_type = isset($query_vars['post_type']) ? $query_vars['post_type'] : 'post'; $query_vars['post_type'] = $this->get_post_type_in_lang($post_type, bbl_get_current_lang_code()); } return $query_vars; } // If we're asking for the default content, it's fine if (bbl_get_default_lang_code() == $lang) { return $query_vars; } // Now swap the query vars so we get the content in the right language post_type // @FIXME: Do I need to change $wp->matched query? I think $wp->matched_rule is fine? // @FIXME: Danger of post type slugs clashing?? if (isset($query_vars['pagename']) && $query_vars['pagename']) { // Substitute post_type for $query_vars['name'] = $query_vars['pagename']; $query_vars[bbl_get_post_type_in_lang('page', $query_vars['lang'])] = $query_vars['pagename']; $query_vars['post_type'] = bbl_get_post_type_in_lang('page', bbl_get_current_lang_code()); // Trigger a listing of translated posts if this is meant to // be the blog page. if ('page' == get_option('show_on_front')) { // Test if the current page is in the same translation group as // the 'page_for_posts. $current_post = get_page_by_path($query_vars['pagename'], null, $query_vars['post_type']); if ($this->get_transid(get_option('page_for_posts')) == $this->get_transid($current_post)) { $query_vars['post_type'] = bbl_get_post_type_in_lang('post', bbl_get_current_lang_code()); unset($query_vars['name']); unset($query_vars[bbl_get_post_type_in_lang('page', $query_vars['lang'])]); } } unset($query_vars['page']); unset($query_vars['pagename']); } elseif (isset($query_vars['year']) && $query_vars['year']) { // @FIXME: This is not a reliable way to detect queries for the 'post' post_type. $query_vars['post_type'] = bbl_get_post_type_in_lang('post', bbl_get_current_lang_code()); } elseif (isset($query_vars['post_type'])) { if (is_array($query_vars['post_type'])) { $new_post_types = array(); foreach ($query_vars['post_type'] as $post_type) { $new_post_types[] = bbl_get_post_type_in_lang($post_type, bbl_get_current_lang_code()); } $query_vars['post_type'] = $new_post_types; } else { $query_vars['post_type'] = bbl_get_post_type_in_lang($query_vars['post_type'], bbl_get_current_lang_code()); } } else { // @FIXME: A solution to the plugin's inability to translate base posts AND pages. global $wpdb; $query_slug = !empty($query_vars['name']) ? $query_vars['name'] : $query_vars['attachment']; $request_language = strtolower(bbl_get_current_lang_code()); $results = $wpdb->get_row("SELECT * FROM {$wpdb->posts} WHERE {$wpdb->posts}.post_name='{$query_slug}' AND post_type LIKE '%{$request_language}' ", OBJECT); if ($results && !is_wp_error($results) && !empty($results->post_type)) { $query_vars['post_type'] = $results->post_type; } else { $query_vars['post_type'] = bbl_get_post_type_in_lang('post', bbl_get_current_lang_code()); } } return $query_vars; }
/** * Returns the link to a post type in a particular language. * * @param string $post_type A post type for which you want a translated archive link * @param string $lang_code The code for the language the link is requested in * @return void **/ function bbl_get_post_type_archive_link_in_lang($post_type, $lang_code = null) { if (is_null($lang_code)) { $lang_code = bbl_get_current_lang_code(); } bbl_switch_to_lang($lang_code); $lang_post_type = bbl_get_post_type_in_lang($post_type, $lang_code); $link = get_post_type_archive_link($lang_post_type); bbl_restore_lang(); return apply_filters('bbl_post_type_archive_link_in_lang', $link); }
/** * Add a link to an arbitrary link, e.g. 404, within the site. * * @param object $lang A Babble language object for this link * @return void **/ protected function add_arbitrary_link($lang) { $classes = array(); if (!preg_match('|^/[^/]+/(.*)?|', $_SERVER['REQUEST_URI'], $matches)) { return; } bbl_switch_to_lang($lang->code); $href = home_url($matches[1]); bbl_restore_lang(); $href = apply_filters('bbl_switch_arbitrary_link', $href, $lang); $title = sprintf(__('Switch to %s', 'babble'), $lang->display_name); $classes[] = 'bbl-existing'; $classes[] = 'bbl-existing-term'; $classes[] = "bbl-lang-{$lang->code} bbl-lang-{$lang->url_prefix}"; $classes[] = 'bbl-lang'; $classes[] = 'bbl-term'; if ($lang == bbl_get_current_lang_code()) { $classes[] = 'bbl-active'; } $this->links[$lang->code] = array('classes' => $classes, 'href' => $href, 'id' => $lang->url_prefix, 'meta' => array('class' => strtolower(join(' ', array_unique($classes)))), 'title' => $title, 'lang' => $lang); }
/** * Takes a set of query vars and amends them to show the content * in the current language. * * @param array $query_vars A set of WordPress query vars (sometimes called query arguments) * @param string|boolean $request If this is called on the parse_request hook, $request contains the root relative URL * @return array $query_vars A set of WordPress query vars **/ protected function translate_query_vars(array $query_vars, $request = false) { // Sequester the original query, in case we need it to get the default content later $query_vars['bbl_original_query'] = $query_vars; // We've done this already (avoid re-translating the vars) if (isset($query_vars['bbl_done_translation']) && $query_vars['bbl_done_translation']) { return $query_vars; } $query_vars['bbl_done_translation'] = true; $lang_url_prefix = isset($query_vars['lang_url_prefix']) ? $query_vars['lang_url_prefix'] : get_query_var('lang_url_prefix'); $lang = isset($query_vars['lang']) ? $query_vars['lang'] : get_query_var('lang'); // Detect language specific homepages if ($request == $lang_url_prefix) { unset($query_vars['error']); // @FIXME: Cater for front pages which don't list the posts if ('page' == get_option('show_on_front') && ($page_on_front = get_option('page_on_front'))) { // @TODO: Get translated page ID $query_vars['p'] = $this->get_post_in_lang($page_on_front, bbl_get_current_lang_code())->ID; $query_vars['post_type'] = $this->get_post_type_in_lang('page', bbl_get_current_lang_code()); return $query_vars; } // Trigger the archive listing for the relevant shadow post type // of 'post' for this language. if (bbl_get_default_lang_code() != $lang && empty($query_vars['s'])) { $post_type = isset($query_vars['post_type']) ? $query_vars['post_type'] : 'post'; $query_vars['post_type'] = $this->get_post_type_in_lang($post_type, bbl_get_current_lang_code()); } return $query_vars; } // If we're asking for the default content, it's fine if (bbl_get_default_lang_code() == $lang) { return $query_vars; } // Now swap the query vars so we get the content in the right language post_type // @FIXME: Do I need to change $wp->matched query? I think $wp->matched_rule is fine? // @FIXME: Danger of post type slugs clashing?? if (isset($query_vars['pagename']) && $query_vars['pagename']) { // Substitute post_type for $query_vars['name'] = $query_vars['pagename']; $query_vars[bbl_get_post_type_in_lang('page', $query_vars['lang'])] = $query_vars['pagename']; $query_vars['post_type'] = bbl_get_post_type_in_lang('page', bbl_get_current_lang_code()); // Trigger a listing of translated posts if this is meant to // be the blog page. if ('page' == get_option('show_on_front')) { // Test if the current page is in the same translation group as // the 'page_for_posts. $current_post = get_page_by_path($query_vars['pagename'], null, $query_vars['post_type']); if ($this->get_transid(get_option('page_for_posts')) == $this->get_transid($current_post)) { $query_vars['post_type'] = bbl_get_post_type_in_lang('post', bbl_get_current_lang_code()); unset($query_vars['name']); unset($query_vars[bbl_get_post_type_in_lang('page', $query_vars['lang'])]); } } unset($query_vars['page']); unset($query_vars['pagename']); } elseif (isset($query_vars['year']) && $query_vars['year']) { // @FIXME: This is not a reliable way to detect queries for the 'post' post_type. $query_vars['post_type'] = bbl_get_post_type_in_lang('post', bbl_get_current_lang_code()); } elseif (isset($query_vars['post_type'])) { if (is_array($query_vars['post_type'])) { $new_post_types = array(); foreach ($query_vars['post_type'] as $post_type) { $new_post_types[] = bbl_get_post_type_in_lang($post_type, bbl_get_current_lang_code()); } $query_vars['post_type'] = $new_post_types; } else { $query_vars['post_type'] = bbl_get_post_type_in_lang($query_vars['post_type'], bbl_get_current_lang_code()); } } else { $query_vars['post_type'] = bbl_get_post_type_in_lang('post', bbl_get_current_lang_code()); } return $query_vars; }
/** * Hooks the WP filter get_edit_post_link * * @filter get_edit_post_link * @param string $url The edit post link URL * @param int $post_ID The ID of the post to edit * @param string $context The link context. * * @return string The edit post link URL * @author Simon Wheatley **/ public function get_edit_post_link($url, $post_ID, $context) { if ($this->no_recursion) { return $url; } if (bbl_get_default_lang_code() == bbl_get_post_lang_code($post_ID)) { return $url; } $completed_jobs = $this->get_completed_post_jobs(bbl_get_default_lang_post($post_ID)); if (!isset($completed_jobs[bbl_get_current_lang_code()])) { return $url; } $job = $completed_jobs[bbl_get_current_lang_code()]; if (!current_user_can('publish_post', $job->ID)) { return $url; } $this->no_recursion = true; $url = get_edit_post_link($completed_jobs[bbl_get_current_lang_code()]->ID); $this->no_recursion = false; return $url; }
/** * Returns a slug translated into a particular language. * * @TODO: This is more or less the same method as Babble_Post_Public::get_taxonomy_lang_code, do I need to DRY that up? * * @param string $slug The slug to translate * @param string $lang_code The language code for the required language (optional, defaults to current) * @return string A translated slug **/ public function get_slug_in_lang($slug, $lang_code = null) { if (is_null($lang_code)) { $lang_code = bbl_get_current_lang_code(); } $_slug = mb_strtolower(apply_filters('bbl_translate_taxonomy_slug', $slug, $lang_code)); // @FIXME: For some languages the translation might be the same as the original if ($_slug && $_slug != $slug) { return $_slug; } // Do we need to check that the slug is unique at this point? return mb_strtolower("{$_slug}_{$lang_code}"); }