diff --git a/aucor-polylang-translation-mapper.php b/aucor-polylang-translation-mapper.php new file mode 100644 index 0000000..51c4766 --- /dev/null +++ b/aucor-polylang-translation-mapper.php @@ -0,0 +1,165 @@ +plugin_name = 'Aucor: Polylang Translation Mapper'; + $this->plugin_slug = 'aucor-polylang-translation-mapper'; + + $this->post_type = 'post'; // post type + $this->meta_key = 'master_id'; // "master id" that all translations share + + $this->updated = 0; + $this->ignored = 0; + + if (defined('DOING_AJAX') && DOING_AJAX) { + return; // don't mess up ajax calls + } + + add_action('admin_init', array(&$this, 'iterate')); + add_action('admin_notices', array(&$this, 'admin_notice')); + + } + + /** + * Iterate + */ + + function iterate() { + + $used_master_ids = array(); + + if( isset($_GET[ $this->plugin_slug ]) ) { + + $paged = ($_GET[ $this->plugin_slug . '-p' ]) ? $_GET[ $this->plugin_slug . '-p' ] : 1; // Paged because running too many posts at a time causes memory overflow + + $args = array( + 'post_type' => $this->post_type, + 'posts_per_page' => 50, // Make me less if PHP can't handle it + 'paged' => $paged, + 'orderby' => 'title', + 'order' => 'DESC', + 'lang' => '', + 'post_status' => 'any', + 'meta_query' => array( + array( + 'key' => $this->meta_key, + 'compare' => 'EXISTS' + ), + ) + ); + + $query = new WP_Query( $args ); + $max_num_pages = $query->max_num_pages; + + while ( $query->have_posts() ) : $query->the_post(); + + $master_id = get_post_meta( $query->post->ID, $this->meta_key, true ); + $translations = pll_get_post_translations( $query->post->ID ); + + if(in_array($master_id, $used_master_ids)) { + continue; // already linked, skip + } + + $args_sub = array( + 'post_type' => $this->post_type, + 'posts_per_page' => -1, + 'no_found_rows' => true, + 'lang' => '', + 'post_status' => 'any', + 'meta_query' => array( + array( + 'key' => $this->meta_key, + 'compare' => '=', + 'value' => $master_id + ), + ) + ); + $sub_query = new WP_Query( $args_sub ); + while ( $sub_query->have_posts() ) : $sub_query->the_post(); + + $translations[ pll_get_post_language( $sub_query->post->ID ) ] = $sub_query->post->ID; + + endwhile; + wp_reset_query(); + + if(!empty($translations)) { + pll_save_post_translations($translations); + $this->updated++; + } + + array_push($used_master_ids, $master_id); // Doesn't carry to the next page but it's only small optimization + + endwhile; + wp_reset_query(); + + $this->admin_notice = 'In this step: ' . $this->updated . ' translation connections made'; + + $next_page = ($paged < $max_num_pages) ? $paged + 1 : null; + + if(!empty($next_page)) { + $full_url = "//$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; + $full_url = str_replace($this->plugin_slug . '-p=' . $paged, $this->plugin_slug . '-p=' . $next_page, $full_url); + $this->admin_notice .= 'Continue (step ' . $next_page . '/' . $max_num_pages . ')'; + } else { + $this->admin_notice .= '

Done! You should deactivate and remove me now!'; + } + + } else { + + $full_url = "//$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; + $full_url .= (strpos($full_url, '?') === false) ? '?' : '&'; + $full_url .= $this->plugin_slug . '=start&' . $this->plugin_slug . '-p=1'; + + $this->admin_notice = '

Post type: ' . $this->post_type . '
'; + $this->admin_notice .= 'Master meta key: ' . $this->meta_key . '

'; + $this->admin_notice .= '

Take a backup of your database. There is no return.

'; + $this->admin_notice .= 'Start connecting translations'; + + } + } + + /** + * Admin message displayer + */ + + function admin_notice() { + ?> +
+

plugin_name; ?>
+ admin_notice; ?> +

+
+