Jamie Talbot, Paolo Tresso, the Gengo community.
Author: Julien Viard de Galbert
Author URI: http://silicone.homelinux.org/
Version: 2.6-hacked
Text Domain: gengo
Domain Path: /languages
*/
/*
Gengo - Multi-language blogging for WordPress.
Copyright (c) 2006-2008 Jamie Talbot
Patches and Mods (c) 2008+ Paolo Tresso (http://pixline.net) and the Gengo community
A lot more Mods (c) 2009+ Julien Viard de Galbert (http://silicone.homelinux.org/)
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to
do so, subject to the following conditions:
The above copyright notice and this permission notice shall
be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
// Load some variables for when running as ajax or activating.
if (!defined('ABSPATH')) {
require_once(dirname(dirname(dirname(dirname(__FILE__)))) . '/wp-config.php');
}
// Pre-2.6 compatibility
if ( ! defined( 'WP_CONTENT_URL' ) )
define( 'WP_CONTENT_URL', get_option( 'siteurl' ) . '/wp-content' );
if ( ! defined( 'WP_CONTENT_DIR' ) )
define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' );
if ( ! defined( 'WP_PLUGIN_URL' ) )
define( 'WP_PLUGIN_URL', WP_CONTENT_URL. '/plugins' );
if ( ! defined( 'WP_PLUGIN_DIR' ) )
define( 'WP_PLUGIN_DIR', WP_CONTENT_DIR . '/plugins' );
define ("GENGO_VERSION", "2.5.5");
define ("GENGO_BASE_DIR", "gengo/");
define ("GENGO_DIR", WP_PLUGIN_URL."/" . GENGO_BASE_DIR);
define ("GENGO_PATH", WP_PLUGIN_DIR."/" . GENGO_BASE_DIR);
define ("GENGO_LANGUAGES_DIR", WP_CONTENT_DIR."/languages"); // @see LANGDIR in WP 2.6
define ("GENGO_LANGUAGES_PAGE", "gengo_languages_page.php");
define ("GENGO_TRANSLATIONS_PAGE", "gengo_translations_page.php");
define ("GENGO_SYNONYMS_PAGE", "gengo_synonyms_page.php");
define ("GENGO_EXCLUSIONS_PAGE", "gengo_exclusions_page.php");
define ("GENGO_LANGUAGE_TABLE", $wpdb->prefix . "languages");
define ("GENGO_POST2LANG_TABLE", $wpdb->prefix . "post2lang");
define ("GENGO_SUMMARY_TABLE", $wpdb->prefix . "summaries");
define ("GENGO_TERM2SYN_TABLE", $wpdb->prefix . "term2syn");
define ("GENGO_SYNBLOCK_TABLE", $wpdb->prefix . "synblocks");
define ("GENGO_SIDEBAR_TITLE_LENGTH", 80);
define ("GENGO_SIDEBAR_SELECT_LENGTH", 50);
define ("GENGO_POSTS_LIMIT", 10);
define ("GENGO_GROUPS_LIMIT", 3);
define ("GENGO_TRANSLATIONS_PAGED", 5);
define ("GENGO_DOMAIN", "gengo");
// You can alter this if you really want to, but I don't recommend it. For a start all your
// permalinks will change, and your permalink structure may break entirely. There has been
// no testing on anything other than '+', which works. So leave it :D Your other alternative
// is to turn off code-appending entirely.
define ("GENGO_LANGUAGE_DIVIDER", '+');
// this must be the preg esxaped version of the above for rewrite rules
define ("GENGO_LANGUAGE_DIVIDER_PREG", '\+');
// make sure to save permalinks structure in wp config if you update this (also clean your cookies)
class Language {
var $code;
var $language;
var $locale;
var $rtl;
var $charset;
function Language($code, $language, $locale, $rtl, $charset) {
$this->code = $code;
$this->language = $language;
$this->locale = $locale;
$this->rtl = $rtl;
$this->charset = $charset;
}
}
class Gengo {
var $version;
var $language_table;
var $summary_table;
var $post2lang_table;
var $term2syn_table;
var $synblock_table;
var $languages;
var $language_cookie;
var $language_preference;
var $language_preference_id;
var $blog_default_language_id;
var $default_url_exclusions;
function Gengo($ajax = false) {
static $language_preference;
static $language_preference_id;
static $languages;
static $codes2ids;
static $blog_default_language_id;
static $viewable_code_string;
$this->version = GENGO_VERSION;
$this->language_table = GENGO_LANGUAGE_TABLE;
$this->post2lang_table = GENGO_POST2LANG_TABLE;
$this->summary_table = GENGO_SUMMARY_TABLE;
$this->term2syn_table = GENGO_TERM2SYN_TABLE;
$this->synblock_table = GENGO_SYNBLOCK_TABLE;
$this->language_cookie = 'gengo_language' . COOKIEHASH;
$this->default_url_exclusions = array('/wp-content', 'wp-login.php', 'xmlrpc.php', 'wp-pass.php', 'wp-register.php', 'theme-editor.php', '/wp-includes', 'wp-cron.php');
$this->append_urls = get_option('gengo_append_urls');
$this->site_home = get_option('home');
$this->site_url = get_option('siteurl');
$this->ajax = $ajax;
$this->languages = & $languages;
$this->codes2ids = & $codes2ids;
$this->language_preference = & $language_preference;
$this->language_preference_id = & $language_preference_id;
$this->blog_default_language_id = & $blog_default_language_id;
$this->viewable_code_string = & $viewable_code_string;
// Populate a languages array for future use.
$this->set_defined_languages();
$this->set_blog_default_language();
$this->language_preference = array();
$this->language_preference_id = array();
$this->strict_links = true;
$this->viewable_code_string = '';
if (!$ajax) {
// Admin UI.
if (is_admin()) {
if (did_action('locale')) {
echo "Another plugin is incorrectly localised.";
}
// @todo: http://adambrown.info/p/wp_hooks/hook/plugins_api
// http://codex.wordpress.org/Migrating_Plugins_and_Themes_to_2.7
// Installer.
register_activation_hook(__FILE__, array(& $this, 'activated'));
register_deactivation_hook(__FILE__, array(& $this, 'deactivated'));
// see:
// http://adambrown.info/p/wp_hooks/hook/admin_print_scripts-$hook_suffix
// http://adambrown.info/p/wp_hooks/hook/admin_print_styles-$hook_suffix
add_action('admin_head', array(& $this, 'admin_head')); // 2.7 deprecated ?!?
add_action('admin_menu', array(& $this, 'admin_menu'));
// http://codex.wordpress.org/Function_Reference/add_meta_box convert to new box
add_action('edit_form_advanced', array(& $this, 'post_sidebar'));
add_action('edit_page_form', array(& $this, 'post_sidebar'));
add_action('edit_form_advanced', array(& $this, 'edit_form_advanced'));
add_action('edit_page_form', array(& $this, 'edit_form_advanced'));
add_action('admin_footer', array(& $this, 'admin_footer'));
// User actions.
add_action('profile_personal_options', array(& $this,'profile_personal_options'));
add_action('personal_options_update', array(& $this,'personal_options_update'));
add_action('delete_user', array(& $this,'delete_user'));
// Manage tables.
add_filter('manage_posts_columns', array(& $this,'manage_posts_columns'));
add_action('manage_posts_custom_column', array(& $this,'manage_posts_custom_column'), 10, 2);
add_filter('manage_pages_columns', array(& $this,'manage_posts_columns'));
add_action('manage_pages_custom_column', array(& $this,'manage_posts_custom_column'), 10, 2);
// Post updating.
add_action('save_post', array(& $this, 'edit_post'));
add_action('delete_post', array(& $this, 'delete_post'));
// Miscellaneous.
add_action('activity_box_end', array(& $this,'activity_box_end'));
} else {
// Links and permalinks.
add_filter('category_link', array(& $this,'append_links'));
add_filter('author_link', array(& $this,'append_links'));
add_filter('year_link', array(& $this,'append_links'));
add_filter('month_link', array(& $this,'append_links'));
add_filter('day_link', array(& $this,'append_links'));
add_filter('feed_link', array(& $this,'append_links'));
add_filter('tag_link', array(& $this, 'append_links'));
add_filter('post_comments_feed_link', array(& $this,'post_comments_feed_link'));
add_filter('trackback_url', array(& $this,'trackback_url'));
// SQL control.
add_filter('query_vars', array(& $this,'query_vars'));
add_filter('posts_fields', array(& $this,'posts_fields'));
add_filter('posts_join_paged', array(& $this,'posts_join'));
add_filter('posts_where_paged', array(& $this,'posts_where'));
add_filter('getarchives_join', array(& $this,'posts_join'));
add_filter('getarchives_where', array(& $this,'posts_where'));
add_filter('comment_feed_join', array(& $this,'comments_join'));
add_filter('comment_feed_where', array(& $this,'posts_where'));
// 2.5 renamed, see:
// http://adambrown.info/p/wp_hooks/hook/get_%7B$adjacent%7D_post_join
add_filter('get_previous_post_join', array(& $this,'previous_next_posts_join'));
add_filter('get_previous_post_where', array(& $this,'previous_next_posts_where'));
add_filter('get_next_post_join', array(& $this,'previous_next_posts_join'));
add_filter('get_next_post_where', array(& $this,'previous_next_posts_where'));
add_filter('posts_request', array(& $this,'posts_request'));
//
add_action('parse_query', array(& $this,'parse_query'));
add_filter('get_pages', array(& $this,'get_pages'), 10, 2);
// add_filter('get_categories', array(& $this,'get_categories'), 10, 2);
// Correct categories for wp_list_cats();
add_filter('list_cats', array(& $this,'list_cats'), 8, 2);
// Correct categories for the_category();
// see http://adambrown.info/p/wp_hooks/hook/get_categories_taxonomy
add_filter('get_category', array(& $this,'get_category')); // 2.3 renamed: http://adambrown.info/p/wp_hooks/hook/get_category
add_filter('query_string', array(& $this,'query_string'));
// Semantic information.
add_action('wp_head', array(& $this,'wp_head'));
// Static front page compatibility
add_action('pre_get_posts', array(& $this, 'pre_get_posts'));
add_filter('option_page_on_front', array(& $this,'option_page_on_front'));
}
// Term manipulation can happen either in the admin or when doing ajax.
add_action('create_term', array(& $this, 'create_term'), 10, 2);
add_action('edit_term', array(& $this, 'edit_term'), 10, 2);
add_action('delete_term', array(& $this, 'delete_term'));
// Tags
add_filter('get_term', array(& $this, 'get_term'), 10, 2);
add_filter('get_terms', array(& $this, 'get_terms'), 10, 1);
add_filter('wp_get_object_terms', array(& $this, 'get_terms'), 10, 1);
add_filter('get_the_tags', array(& $this, 'get_terms'), 10, 1);
// Rewrite rules.
add_filter('rewrite_rules_array', array(& $this,'everybody_wants_prosthetic_rewrite_rules'));
remove_filter('template_redirect', 'redirect_canonical');
// Language appending throughout the site.
add_filter('post_link', array(& $this,'post_link'), 100, 2);
add_filter('page_link', array(& $this,'page_link'), 100, 2);
add_filter('get_pagenum_link', array(& $this,'get_pagenum_link'));
// try to fix paged comments #951
add_filter('get_comment_link', array(& $this,'get_comment_link'), 100, 2);
// Miscellaneous
add_action('init', array(& $this,'init'));
add_action('plugins_loaded', array(& $this,'plugins_loaded'), 0);
add_filter('locale', array(& $this, 'locale'), 0);
add_filter('option_rss_language', array(& $this,'option_rss_language'));
// Title, description and charset filtering.
add_filter('option_blogname', array(& $this,'option_blogname'));
add_filter('option_blogdescription', array(& $this,'option_blogdescription'));
add_filter('option_blog_charset', array(& $this,'option_blog_charset'));
}
}
// Filters and Actions.
/**
* Triggered on the 'activated' hook.
*
* Creates synonym entries for those terms that have been entered since
* the last time Gengo was activated. Sends users to the configuration
* page.
*
* Have to add the prefix again, because $wpdb->prefix isn't set when
* gengo.php is included.
*
*/
function activated() {
global $wp_rewrite, $wpdb;
$wp_rewrite->flush_rules();
if (get_option('gengo_version')) {
$this->language_table = $wpdb->prefix . $this->language_table;
$this->term2syn_table = $wpdb->prefix . $this->term2syn_table;
$this->set_defined_languages();
// We are reactivating Gengo, so add category synonym entries for all categories added since Gengo was deactivated.
foreach ($this->languages as $language_id => $entry) {
if ($language_id == $this->blog_default_language_id) {
$wpdb->query("INSERT INTO $this->term2syn_table(term_id, language_id, synonym, sanitised, description) SELECT t.term_id, $language_id, name, slug, '' FROM $wpdb->terms AS t LEFT JOIN $this->term2syn_table AS t2s ON (t.term_id = t2s.term_id AND t2s.language_id = $language_id) WHERE t2s.term_id IS NULL");
} else {
$wpdb->query("INSERT INTO $this->term2syn_table(term_id, language_id, synonym, sanitised, description) SELECT t.term_id, $language_id, '', '', '' FROM $wpdb->terms AS t LEFT JOIN $this->term2syn_table AS t2s ON (t.term_id = t2s.term_id AND t2s.language_id = $language_id) WHERE t2s.term_id IS NULL");
}
}
}
header('Location: admin.php?page=' . GENGO_BASE_DIR . GENGO_LANGUAGES_PAGE);
die();
}
/**
* Remove rewrite rules when Gengo is deactivated.
*
*/
function deactivated() {
global $wp_rewrite;
remove_filter('rewrite_rules_array', array(& $this,'everybody_wants_prosthetic_rewrite_rules'));
$wp_rewrite->flush_rules();
}
function option_rss_language($language) {
$codes = explode(GENGO_LANGUAGE_DIVIDER, $this->viewable_code_string);
return $codes[0];
}
/**
* Add the Gengo options page to the menu.
*
*/
function admin_menu() {
global $language_menu;
if (current_user_can('configure_gengo')) {
if (!$language_menu) {
add_menu_page(__('Language Options', GENGO_DOMAIN), __('Languages', GENGO_DOMAIN), 1, GENGO_BASE_DIR . GENGO_LANGUAGES_PAGE);
$language_menu = GENGO_BASE_DIR . GENGO_LANGUAGES_PAGE;
}
add_submenu_page($language_menu, __('Gengo Languages', GENGO_DOMAIN), __('Languages', GENGO_DOMAIN), 1, GENGO_BASE_DIR . GENGO_LANGUAGES_PAGE);
add_submenu_page($language_menu, __('Gengo Translations', GENGO_DOMAIN), __('Translations', GENGO_DOMAIN), 1, GENGO_BASE_DIR . GENGO_TRANSLATIONS_PAGE);
add_submenu_page($language_menu, __('Gengo Synonyms', GENGO_DOMAIN), __('Synonyms', GENGO_DOMAIN), 1, GENGO_BASE_DIR . GENGO_SYNONYMS_PAGE);
if (current_user_can('modify_gengo_exclusions')) {
if (($this->append_urls && !((isset($_POST['gengo_action']) && $_POST['gengo_action'] == "update_appending") && !isset($_POST['gengo_append_urls']))) || (isset($_POST['gengo_append_urls']))) {
add_submenu_page($language_menu, __('Gengo Exclusions', GENGO_DOMAIN), __('Exclusions', GENGO_DOMAIN), 1, GENGO_BASE_DIR . GENGO_EXCLUSIONS_PAGE);
}
}
}
}
/**
* Print required code in the admin
section.
* @todo jQuery port of all js code...
*/
function admin_head() {
?>
languages)) {
$default_language_id = $this->get_default_language_id();
if ($post_language_info = $this->get_post_language_data($post_id, 'l.language_id AS post_language_id, p2l.translation_group AS post_translation_group')) {
extract($post_language_info, EXTR_OVERWRITE);
} else {
$post_language_id = 0;
$post_translation_group = 0;
}
?>
get_var("SELECT summary_group FROM $this->post2lang_table WHERE post_id = $post_id")) ? $sum : 0;
?>
get_col("SELECT DISTINCT s.summary_group AS summary_group FROM $this->summary_table AS s LEFT JOIN $this->post2lang_table AS p2l ON s.summary_group = p2l.summary_group WHERE p2l.summary_group IS NULL")) {
$orphans = implode(',', $orphaned_summaries);
$wpdb->query("DELETE FROM $this->summary_table WHERE summary_group IN ($orphans)");
}
}
/**
* Handle language information when a post is saved.
*
* @param int $post_id
* @return int
*/
function edit_post($post_id) {
global $wpdb;
if(!isset($post_id)) {
// We are creating a new post.
$post_id = $_POST['post_ID'];
$language_id = isset($_POST['gengo_use_language']) ? $_POST['gengo_use_language'] : $this->get_default_language_id();
$existing_language_id = isset($_POST['gengo_language_id']) ? $_POST['gengo_language_id'] : 0;
} else {
// We are editing a post. Can't support updating language by XMLRPC at the moment.
$existing_language_id = isset($_POST['gengo_language_id']) ? $_POST['gengo_language_id'] : $wpdb->get_var("SELECT language_id FROM $this->post2lang_table WHERE post_id = $post_id");
$language_id = isset($_POST['gengo_use_language']) ? $_POST['gengo_use_language'] : $existing_language_id;
}
$existing_translation_group = isset($_POST['gengo_existing_translation_group']) ? $_POST['gengo_existing_translation_group'] : 0;
$translation_id = $_POST['gengo_translation_post'];
// Get a group number if we are creating a new one.
if (isset($_POST['gengo_translation'])) {
if (isset($_POST['gengo_translation_group']) && ($_POST['gengo_translation_group'] == 0) && $translation_id) {
$new_group = true;
$translation_group = $wpdb->get_var("SELECT MAX(translation_group) FROM $this->post2lang_table") + 1;
} else {
$translation_group = ($_POST['gengo_translation_group']) ? $_POST['gengo_translation_group'] : 0;
}
} else {
$translation_group = 0;
}
// If the language and translation hasn't changed, do nothing.
if ($language_id == $existing_language_id && $translation_group == $existing_translation_group) return $post_id;
// Insert or update the new or altered data.
if (!$wpdb->query("UPDATE $this->post2lang_table SET language_id = $language_id, translation_group = $translation_group WHERE post_id = $post_id")) {
$wpdb->query("INSERT INTO $this->post2lang_table(post_id, language_id, translation_group, summary_group) VALUES ($post_id, $language_id, $translation_group, 0)");
}
// Check if we now don't need a translation group for the one that was deleted.
if ($existing_translation_group && ($existing_translation_group != $translation_group)) {
if ('1' == $wpdb->get_var("SELECT COUNT(*) FROM $this->post2lang_table WHERE translation_group = $existing_translation_group")) {
$wpdb->query("UPDATE $this->post2lang_table SET translation_group = 0 WHERE translation_group = $existing_translation_group LIMIT 1");
}
}
// Put the other post in the same translation group if we have just created a new one.
if ($new_group) $wpdb->query("UPDATE $this->post2lang_table SET translation_group = $translation_group WHERE post_id = $translation_id LIMIT 1");
if (!$summary_group = $wpdb->get_var("SELECT summary_group FROM $this->post2lang_table AS p2l WHERE p2l.translation_group = $translation_group AND p2l.post_id != $post_id AND p2l.translation_group != 0 LIMIT 1")) {
$summary_group = (!$existing_translation_group) ? $wpdb->get_var("SELECT summary_group FROM $this->post2lang_table AS p2l WHERE p2l.post_id = $post_id LIMIT 1") : 0;
}
// Make sure the summary group is correct..
$wpdb->query("UPDATE $this->post2lang_table SET summary_group = $summary_group WHERE post_id = $post_id LIMIT 1");
$this->remove_orphan_summaries();
return $post_id;
}
/**
* Handle language alterations when a post is deleted.
*
* @param int $post_id
*/
function delete_post($post_id) {
global $wpdb, $current_user;
if (!$deleted_translation_group = $this->get_post_language_data($post_id, "p2l.translation_group")) {
$deleted_translation_group = 0;
}
// @TODO: Why isn't this working?
if ($_GET['gengo_delete_all_translations'] && 'true' == $_GET['gengo_delete_all_translations']) {
if ($translations = $this->get_the_translations($post_id)) {
foreach ($translations as $translation) {
if (!current_user_can('edit_post', $translation['translation_id'])) continue;
// Temporarily unregister the action to prevent an infinite loop and delete this translation.
remove_action('delete_post', array(&$this, 'delete_post'));
wp_delete_post($translation['translation_id']);
add_action('delete_post', array(&$this, 'delete_post'));
$post_id .= ", $translation[translation_id]";
}
}
}
$wpdb->query("DELETE FROM $this->post2lang_table WHERE post_id IN ($post_id)");
if ('1' == $wpdb->get_var("SELECT COUNT(*) FROM $this->post2lang_table WHERE translation_group = $deleted_translation_group")) {
$wpdb->query("UPDATE $this->post2lang_table SET translation_group = 0 WHERE translation_group = $deleted_translation_group");
}
// Remove summaries that have been orphaned.
$this->remove_orphan_summaries();
}
/**
* Add language table columns to the manage posts table.
*
* @param array $post_columns
* @return array
* @todo single column, refactorize all
* @see manage_posts_custom_column
*/
function manage_posts_columns($post_columns) {
$post_columns['gengo_language'] = __('Language', GENGO_DOMAIN);
#$post_columns['gengo_translations'] = __('Translations', GENGO_DOMAIN);
#$post_columns['gengo_summaries'] = __('Summaries', GENGO_DOMAIN);
$this->mixed_categories = true;
return $post_columns;
}
/**
* Add language information to the manage posts table.
*
* @param string $column_name
* @param int $id
* @todo update to 2.7 layout. make a single column, with icons and numbers (like comments) for translations and summaries.
* @todo flag for languages, or just language link?
*/
function manage_posts_custom_column($column_name, $id) {
if ('gengo_language' == $column_name) {
echo "
languages as $language) if ($language->code == $code) return true;
return false;
}
/**
* Checks if a language code is recognised.
*
* @param string $code
* @return bool
*/
function is_recognised_code($code) {
include_once (GENGO_PATH . 'gengo_languages.php');
if (isset($gengo_recognised_languages[$code])) return true;
return false;
}
/**
* Returns the order of preference for the given language id, or false if it is not set.
*
* @param int $language_id
* @return bool
*/
function is_set_language($language_id) {
foreach ($this->language_preference_id as $order => $id) if ($id == $language_id) return $order;
return false;
}
/**
* Returns the order of preference for given language, including languages not being displayed.
*
* @param int $language_id
* @return int
*/
function is_viewable_language($language_id) {
$viewable_codes = explode(GENGO_LANGUAGE_DIVIDER, $this->viewable_code_string);
foreach ($viewable_codes as $viewable_code) $ids[] = $this->codes2ids[$viewable_code];
foreach ($ids as $order => $id) if ($id == $language_id) return $order;
return false;
}
/**
* Determines which URLs should never have language codes appended to them.
*
* @return bool
*/
function is_excluded_url($url) {
if (strstr($url, 'async-upload')) return true;
if (defined('DOING_AJAX')) return true;
foreach ($this->default_url_exclusions as $exclusion) if (strstr($url, $exclusion)) return true;
if (($manual_exclusions = get_option('gengo_url_exclusions')) && ($exclusions = explode("\n", $manual_exclusions))) foreach ($exclusions as $exclusion) if (strstr($url, $exclusion)) return true;
return false;
}
/**
* Check if gengo is installed or needs upgrading.
*
* @return bool
*/
function is_installed() {
return version_compare(get_option('gengo_version'), $this->version, '==');
}
/**
* Remove information from the database.
*/
function uninstall() {
global $wpdb, $wp_rewrite;
// Remove database tables.
$wpdb->query("DROP TABLE $this->post2lang_table");
$wpdb->query("DROP TABLE $this->language_table");
$wpdb->query("DROP TABLE $this->summary_table");
$wpdb->query("DROP TABLE $this->term2syn_table");
$wpdb->query("DROP TABLE $this->synblock_table");
// Remove user options.
$wpdb->query("DELETE FROM $wpdb->usermeta WHERE meta_key = 'gengo_default_language'");
// Remove options.
delete_option('gengo_blog_default_language');
delete_option('gengo_version');
delete_option('gengo_url_exclusions');
delete_option('gengo_append_urls');
delete_option('gengo_allow_multiread');
delete_option('gengo_default_reading_language');
$new = $active = get_option('active_plugins');
unset($new[array_search('gengo/gengo.php',$active)]);
update_option('active_plugins',$new);
header("Location: $this->site_url/wp-admin/plugins.php?deactivate=true");
die();
}
/**
* Add Gengo's tables to the database and create the blog default language option.
*
* @param int $current_version
* @return string
* @todo update to WP 2.7 and check permissions.
*/
function install($current_version = 0) {
global $wpdb, $wp_rewrite, $wp_roles;
require_once(ABSPATH . 'wp-admin/upgrade-functions.php');
require_once(GENGO_PATH . 'gengo_schema.php');
dbdelta($schema);
if ($current_version) {
global $table_prefix;
if (version_compare($current_version, '0.5', '<=')) {
// Consolidate post2sum and post2lang.
$post2sum_table = $wpdb->prefix . "post2sum";
if ($summaries = $wpdb->get_results("SELECT * FROM $post2sum_table")) foreach ($summaries as $sum) $wpdb->query("UPDATE $this->post2lang_table SET summary_group = $sum->summary_group WHERE post_id = $sum->post_id");
$wpdb->query("DROP TABLE $post2sum_table");
// Split synonyms into normalised form.
$synonym_table = $wpdb->prefix . "synonyms";
$wpdb->query("INSERT INTO $this->term2syn_table(term_id, language_id, synonym, sanitised) SELECT item_id, language_id, synonym, sanitised FROM $synonym_table WHERE item_id != 0");
$wpdb->query("INSERT INTO $this->synblock_table(block_name, language_id, text) SELECT item_type, language_id, synonym FROM $synonym_table WHERE item_id = 0");
$wpdb->query("DROP TABLE $synonym_table");
}
}
if( version_compare($current_version, '0.5', '>') && version_compare($current_version, '2.5', '<')){
$cat2syn = $wpdb->prefix."cat2syn";
$wpdb->query("INSERT INTO $this->term2syn_table(term_id,language_id,synonym,sanitised) SELECT cat_id, language_id, synonym, sanitised FROM $cat2syn;");
$wpdb->query("ALTER TABLE $this->language_table ADD 'charset' varchar(16) NOT NULL;");
$wpdb->query("UPDATE $this->language_table SET charset='UTF-8' WHERE charset='';");
$wpdb->query("DROP TABLE $cat2syn");
}
$this->set_defined_languages();
if ($current_version) $wp_rewrite->flush_rules();
add_option('gengo_blog_default_language', '', 'Sets the default language code for the blog.', 'yes');
add_option('gengo_url_exclusions', '', 'URL language code exclusions.', 'yes');
add_option('gengo_append_urls', 1, 'Append URLs.', 'yes');
add_option('gengo_default_reading_language', 0, 'The language to show users when they visit for the first time.', 'yes');
$role = $wp_roles->get_role('administrator');
$role->add_cap('configure_gengo');
$role->add_cap('delete_languages');
$role->add_cap('modify_gengo_settings');
$role->add_cap('set_blog_default_language');
$role->add_cap('uninstall_gengo');
$role->add_cap('modify_gengo_exclusions');
$role = $wp_roles->get_role('author');
$role->add_cap('configure_gengo');
$role = $wp_roles->get_role('editor');
$role->add_cap('configure_gengo');
if ($this->mysql_int_version() > 40100) {
add_option('gengo_allow_multiread', 1, 'Controls whether users can read in multiple languages.', 'yes');
} else {
update_option('gengo_allow_multiread', 'x', 'Reading in multiple languages is disabled because your MySQL version is less than 4.1.', 'yes');
}
update_option('gengo_version', $this->version, 'Current version of Gengo.', 'yes');
$message = ($current_version) ? __('Gengo successfully upgraded.', GENGO_DOMAIN) : __('Gengo installed.', GENGO_DOMAIN);
// maybe no return and header() to another page?
return $this->update_message($message);
}
/**
* Return an integer representing MySQL version. Maybe stolen from phpMyAdmin.
*
* @return int
*/
function mysql_int_version() {
global $wpdb;
$version = (explode('.', $wpdb->get_var('SELECT VERSION()')));
return (int) sprintf('%d%02d%02d', $version[0], $version[1], intval($version[2]));
}
/**
* Return the user's default language.
*
* @return int
*/
function get_default_language_id() {
global $current_user;
if ($default = get_usermeta($current_user->id, 'gengo_default_language')) return $default;
else return $this->blog_default_language_id;
}
/**
* Return the blog default language.
*
* @return int
*/
function set_blog_default_language() {
$this->blog_default_language_id = get_option('gengo_blog_default_language');
}
/**
* Set WordPRess default language.
*
* @param string $locale
* @return bool
*/
function set_wplang($locale) {
if (WPLANG) return true;
if (!is_writeable(ABSPATH . 'wp-config.php')) {
return false;
}
$config = str_replace("define ('WPLANG', '');", "define ('WPLANG', '$locale');", implode('', file(ABSPATH . 'wp-config.php')));
$handle = fopen(ABSPATH . 'wp-config.php', 'w');
fwrite($handle, $config);
fclose($handle);
$this->wplang = $locale;
$this->update_message(sprintf(__("WPLANG automatically updated to '%s'.", GENGO_DOMAIN), $locale));
return true;
}
/**
* Set all posts with no language to the default language.
*
* @param bool $silent
* @return bool
*/
function set_no_lang_posts_default($silent = false) {
global $wpdb;
if (!$default = $this->blog_default_language_id) return $this->error_message(__("Please set the default language first.", GENGO_DOMAIN));
// Add entries to the language table for all those posts that don't have an entry.
$wpdb->query("INSERT INTO $this->post2lang_table(post_id, language_id, translation_group, summary_group) SELECT p.ID, 1, 0, 0 FROM $wpdb->posts AS p LEFT JOIN $this->post2lang_table AS p2l ON p2l.post_id = p.ID WHERE p2l.post_id IS NULL;");
$language = $this->languages[$default]->language;
if (!$silent) $this->update_message(sprintf(__("Posts with no language have been set to '%s'.", GENGO_DOMAIN), $language));
return true;
}
/**
* Set a user's default language.
*
* @param int $id
* @return string
*/
function set_default_language($id) {
global $current_user;
$language = $this->languages[$id]->language;
update_usermeta($current_user->id, 'gengo_default_language', $id);
return $this->update_message(sprintf(__("Default language set to '%s'.", GENGO_DOMAIN), $language));
}
/**
* Set the blog default language.
*
* @param int $id
* @return string
*/
function save_blog_default_language($id) {
$language = $this->languages[$id]->language;
update_option('gengo_blog_default_language', $id);
$this->set_blog_default_language($id);
return $this->update_message(sprintf(__("Default blog language set to '%s'.", GENGO_DOMAIN), $language));
}
/**
* Gets language data associated with a post.
*
* @param int $post_id The post ID
* @param string $fields Comma delimited string of fields to query
*/
function get_post_language_data($post_id, $fields) {
global $wpdb;
if (count(explode(',', $fields)) > 1) return $wpdb->get_row("SELECT $fields FROM $this->post2lang_table AS p2l INNER JOIN $this->language_table AS l ON p2l.language_id = l.language_id WHERE post_id = $post_id LIMIT 1", ARRAY_A);
else return $wpdb->get_var("SELECT $fields FROM $this->post2lang_table AS p2l INNER JOIN $this->language_table AS l ON p2l.language_id = l.language_id WHERE post_id = $post_id LIMIT 1");
}
/**
* Fetch an array of languages and codes from the database.
*
*/
function set_defined_languages() {
global $wpdb;
$this->languages = array();
$wpdb->hide_errors();
if ($defined_languages = $wpdb->get_results("SELECT * FROM $this->language_table ORDER BY language_id", ARRAY_A)) {
foreach ($defined_languages as $defined_language) {
extract ($defined_language, EXTR_OVERWRITE);
$this->languages[$language_id] = new Language($code, $language, $locale, $rtl, $charset);
$this->codes2ids[$code] = $language_id;
}
}
$wpdb->show_errors();
}
/**
* Return counts for the number of posts, pages or all, in all languages.
*
* @param string $type
*/
function get_totals($type = 'all') {
global $wpdb;
if (!$this->languages) return array();
switch ($type) {
case 'all':
$results = $wpdb->get_results("SELECT language_id, COUNT(*) AS total FROM $this->post2lang_table GROUP BY language_id");
break;
default:
$results = $wpdb->get_results("SELECT p2l.language_id, COUNT(*) AS total FROM $this->post2lang_table AS p2l INNER JOIN $wpdb->posts AS p ON p.ID = p2l.post_id WHERE p.post_status = 'publish' AND p.post_type = '$type' GROUP BY p2l.language_id");
break;
}
if ($results) {
foreach ($results as $result) {
$return[$result->language_id] = $result->total;
}
return $return;
} else {
return array();
}
}
/**
* Return counts for the number of posts, pages or all of a certain language, for a given language id.
*
* @param int $id
* @param string $type
*/
function get_total_by_language_id($id, $type = 'all') {
global $wpdb;
if (!$this->languages) return 0;
switch ($type) {
case 'all':
return $wpdb->get_var("SELECT COUNT(*) FROM $this->post2lang_table WHERE language_id = '$id'");
default:
return $wpdb->get_var("SELECT COUNT(*) FROM $this->post2lang_table AS p2l INNER JOIN $wpdb->posts AS p ON p.ID = p2l.post_id WHERE p2l.language_id = '$id' AND p.post_status = 'publish' AND p.post_type = '$type'");
}
return 0;
}
/**
* Return one complete translation link.
*
* @param array $translation_data
* @param string $type Can be a, link, comments, home_link
* @param string $text
* @return string
*/
function translation_link($translation_data, $type = 'a', $text = '') {
global $wp_rewrite;
$post_id = $translation_data['translation_id'];
$code = $this->languages[$translation_data['translation_language']]->code;
$language = $this->languages[$translation_data['translation_language']]->language;
if (!$text) $text = $language;
switch ($type) {
case 'link':
return "";
case 'a':
return "$text";
case 'comments':
return "$text ";
case 'home_link':
$home = $this->site_home . '/';
if ($wp_rewrite->using_index_permalinks()) $home .= $wp_rewrite->index . '/';
$home = $this->append_link_language($home, $code);
return "";
}
return '';
}
/**
* Given a post_id, returns an array of posts that are a translation of this one.
* With no post_id, assumes we are in The Loop and uses $post->translation_group.
*
* @param int $id
* @return array
*/
function get_the_translations($id = 0) {
global $wpdb, $post;
if (isset($this->post_language_cache[$id])) {
return $this->post_language_cache[$id]->translations;
} else {
$translation_group = ($id) ? $wpdb->get_var("SELECT translation_group FROM $this->post2lang_table WHERE post_id = $id LIMIT 1") : $post->translation_group;
if ($translation_group) {
if ($translations = $wpdb->get_results("SELECT language_id AS translation_language, post_id AS translation_id, p.post_date AS translation_date, u.display_name AS translation_author, p.post_title AS translation_title FROM $this->post2lang_table AS p2l INNER JOIN $wpdb->posts AS p ON p.ID = p2l.post_id INNER JOIN $wpdb->users AS u ON p.post_author = u.ID WHERE p2l.translation_group = $translation_group AND p2l.post_ID != $post->ID ORDER BY language_id", ARRAY_A)) {
return $translations;
}
}
}
return array();
}
/**
* Get all the summaries in a specified group.
*
* @param int $summary_group
* @return array
*/
function get_the_summaries_by_summary_group($summary_group) {
global $wpdb;
if (!$this->languages) return array();
if ($summaries = $wpdb->get_results("SELECT language_id, summary_id, summary, summary_group FROM $this->summary_table WHERE summary_group = $summary_group", ARRAY_A)) {
return $summaries;
}
return array();
}
/**
* Given a post_id, returns an array of summaries of that post.
*
* @param int $post_id
* @return array
*/
function get_the_summaries($post_id = false) {
global $wpdb, $post;
if (!$post_id) $post_id = $post->ID;
if (!$post_id || !$this->languages) return array();
if (is_array($post_id)) $post_id = implode(',', $post_id);
if ($summaries = $wpdb->get_results("SELECT post_id, s.language_id AS language_id, summary_id, summary, s.summary_group AS summary_group FROM $this->post2lang_table p2l INNER JOIN $this->summary_table s ON s.summary_group = p2l.summary_group WHERE post_id IN ($post_id) ORDER BY language_id, summary_group", ARRAY_A)) {
return $summaries;
}
return array();
}
/**
* Ajax: Returns JSON formatted information about potential translation group components.
*
* @param array $posts
*/
function get_group_components($posts) {
global $wpdb;
if (!$summaries = $this->get_the_summaries($posts)) return;
if (is_array($posts)) $posts = implode(',', $posts);
$post_languages = $wpdb->get_results("SELECT post_id, language_id FROM $this->post2lang_table WHERE post_id in ($posts)", ARRAY_A);
foreach ($post_languages as $entry) $lookup[$entry['post_id']] = $entry['language_id'];
foreach ($summaries as $key => $summary) {
$post_language_id = $lookup[$summary['post_id']];
$summary_language_id = $summary['language_id'];
if (($summaries[$key + 1]['language_id'] == $summary['language_id']) || ($summaries[$key - 1]['language_id'] == $summary['language_id'])) {
$clashes[$summary['language_id']] = true;
ob_start();
$this->print_summary($summary, 'clash', false, 55, true);
$summary = '"' . htmlspecialchars(ob_get_clean()) . '"';
} else {
ob_start();
$this->print_summary($summary, 'existing', false); ?>
get_results("SELECT language_id, text FROM $this->synblock_table WHERE block_name = '$block_name'")) {
foreach ($synonyms as $synonym) {
$synblocks[$synonym->language_id] = $synonym->text;
}
if ($unspecified_languages = array_diff(array_keys($this->languages), array_keys($synblocks))) {
foreach ($unspecified_languages as $unspecified) {
$synblocks[$unspecified] = '';
}
}
}
return $synblocks;
}
/**
* Ajax: Returns a JSON formatted object of synonym blocks.
*
* @param string $block_name
*/
function get_synblocks_by_name($block_name) {
$responses = array();
$synblocks = $this->get_synblocks($block_name);
$count = 0;
foreach ($synblocks as $language_id => $synblock) {
$responses[] = "synblock_$language_id: " . '"' . htmlspecialchars($synblock) . '"';
if ($synblock) $count++;
}
$success_message = sprintf(__("%d Snippet(s) for %s retrieved.", GENGO_DOMAIN), $count, $block_name);
header("X-JSON: {success: '$success_message'}");
echo '{' . implode(', ', $responses) . '}';
}
/**
* Ajax: Return JSON formatted translation information for the specified post id.
*
* @param int $post_id
*/
function get_translation_content($post_id) {
global $wpdb;
$readonly = current_user_can('edit_post', $post_id) ? 'false' : 'true';
$post_data = $wpdb->get_row("SELECT post_content, post_title, l.rtl FROM $wpdb->posts p INNER JOIN $this->post2lang_table p2l ON p.ID = p2l.post_id INNER JOIN $this->language_table l ON p2l.language_id = l.language_id WHERE ID = $post_id LIMIT 1", ARRAY_A);
$post_content = '"' . htmlspecialchars($post_data['post_content']) . '"';
$post_title = '"' . htmlspecialchars($post_data['post_title']) . '"';
$direction = $post_data['rtl'] ? '"rtl"' : '"ltr"';
$success_message = __('Translation content retrieved.', GENGO_DOMAIN);
header("X-JSON: {success: '$success_message'}");
echo "{title: $post_title, readonly: $readonly, content: $post_content, direction: $direction}";
}
/**
* Ajax: Return JSON formatted summary content.
*
* @param int $summary_id
*/
function get_summary_content($summary_id) {
global $wpdb;
$summary_data = $wpdb->get_row("SELECT language_id, summary FROM $this->summary_table WHERE summary_id = $summary_id", ARRAY_A);
$content = '"' . htmlspecialchars($summary_data['summary']) . '"';
$success_message = __('Summary content retrieved', GENGO_DOMAIN);
header("X-JSON: {success: '$success_message'}");
echo "{language_id: $summary_data[language_id], content: $content}";
}
/**
* Ajax: Save the translation from the second translation pane.
*
* @param int $translation_id
* @param string $translation_content
*/
function update_translation_content($translation_id, $translation_content) {
global $wpdb;
if (!current_user_can('unfiltered_html')) $translation_content = wp_filter_post_kses($translation_content);
$wpdb->query("UPDATE $wpdb->posts SET post_content = '$translation_content', post_modified = '" . current_time('mysql') . "', post_modified_gmt = '" . current_time('mysql', true) . "' WHERE ID = $translation_id");
$success_message = __('Translation updated.', GENGO_DOMAIN);
header("X-JSON: {success: '$success_message'}");
}
/**
* Ajax: Update a summary with the given content.
*
* @param int $summary_id
* @param string $summary_content
*/
function update_summary_content($summary_id, $summary_content) {
global $wpdb;
if (!current_user_can('unfiltered_html')) $summary_content = wp_filter_post_kses($summary_content);
$wpdb->query("UPDATE $this->summary_table SET summary = '$summary_content' WHERE summary_id = $summary_id");
$success_message = __('Summary successfully updated.', GENGO_DOMAIN);
header("X-JSON: {success: '$success_message'}");
}
/**
* Ajax: Add a new summary to a post.
*
* @param int $post_id
* @param int $summary_group
* @param int $language_id
* @param string $summary_content
* @param int $translation_group
*/
function add_summary_content($post_id, $summary_group, $language_id, $summary_content, $translation_group) {
global $wpdb;
if (!current_user_can('unfiltered_html')) $summary_content = wp_filter_post_kses($summary_content);
if (!$summary_group) $summary_group = $wpdb->get_var("SELECT MAX(summary_group) FROM $this->post2lang_table") + 1;
$wpdb->query("INSERT INTO $this->summary_table(summary_group, language_id, summary) VALUES ($summary_group, $language_id, '$summary_content')");
$posts = ($translation_group && ($post_ids = $wpdb->get_col("SELECT post_id FROM $this->post2lang_table WHERE translation_group = $translation_group"))) ? implode(',', $post_ids) : $post_id;
$wpdb->query("UPDATE $this->post2lang_table SET summary_group = $summary_group WHERE post_id IN ($posts)");
$success_message = __('Summary successfully added.', GENGO_DOMAIN);
header("X-JSON: {success: '$success_message'}");
echo $summary_group;
}
/**
* Ajax: Deletes a summary.
*
* @params int $summary_id
* @params int $summary_group
*/
function delete_summary($summary_id, $summary_group) {
global $wpdb;
// Remove the summary.
$wpdb->query("DELETE FROM $this->summary_table WHERE summary_id = $summary_id");
// Remove the summary group if this was the last one.
if (!$wpdb->get_var("SELECT COUNT(*) FROM $this->summary_table WHERE summary_group = $summary_group")) {
$wpdb->query("UPDATE $this->post2lang_table SET summary_group = 0 WHERE summary_group = $summary_group");
}
$success_message = __('Summary successfully deleted.', GENGO_DOMAIN);
header("X-JSON: {success: '$success_message'}");
}
/**
* Ajax: Prints a single block summary.
*
* @params int $summary_info
* @params string $highlight
* @params int $edit
* @params int $max_width
* @params bool $check
*/
function print_summary($summary_info, $highlight, $edit, $max_width = 55, $check = false) {
extract($summary_info, EXTR_OVERWRITE);
if ('clash' == $highlight) {
$background = '#ffebeb';
} elseif ('added' == $highlight) {
$background = '#ebffeb';
} else {
$background = '#e9e9e9';
}
?>
print_summary($sum, $highlight, $edit);
$excluded[] = $sum['language_id'];
}
}
/**
* (Maybe) Ajax: Generate a list of summaries
*
* @params int $post_id
* @params int $existing_summary_group
* @params string $is_in_group
* @params int $translation_number
*/
function generate_summary_lists($post_id, $existing_summary_group, $is_in_group, $translation_number = 0, $existing_translation_group = 0) {
global $wpdb;
if ($this->ajax) {
$success_message = __('Summary list retrieved.', GENGO_DOMAIN);
header("X-JSON: {success: '$success_message'}");
}
$post_summaries = $this->get_the_summaries_by_summary_group($existing_summary_group);
if ($translation_number) {
if ('true' == $is_in_group) {
if (!$summary_group = $wpdb->get_var("SELECT summary_group FROM $this->post2lang_table WHERE translation_group = $translation_number LIMIT 1")) {
$summary_group = 0;
}
if ($summary_group != $existing_summary_group) {
$translation_summaries = $this->get_the_summaries_by_summary_group($summary_group);
}
} else {
$translation_summaries = $this->get_the_summaries($translation_number);
if (!$summary_group = $wpdb->get_var("SELECT summary_group FROM $this->post2lang_table WHERE post_id = $translation_number LIMIT 1")) {
$summary_group = 0;
}
}
} else {
$summary_group = ($existing_translation_group) ? 0 : $existing_summary_group;
}
$excluded = array();
if ($summary_group == $existing_summary_group) {
$this->list_summaries($post_summaries, $excluded);
} else {
// We have changed the summary group and this posts' summaries will be unlinked.
$changed = true;
if ($translation_summaries) {
?>
list_summaries($translation_summaries, $excluded, 'added');
}
if ($post_summaries) {
?>
list_summaries($post_summaries, $dummy, 'clash', false);
}
}
foreach ($this->languages as $language_id => $entry) if (!in_array($language_id, $excluded)) $summary_language .= "";
?>
ajax) {
$success_message = __('Translation options updated.', GENGO_DOMAIN);
header("X-JSON: {success: '$success_message'}");
}
// First display the current group if we are in a group and we haven't changed the language.
if ($post_translation_group) {
$existing_language_id = $this->get_post_language_data($existing_post_id, 'p2l.language_id');
if ($existing_language_id == $post_language_id || !$wpdb->get_var("SELECT post_id FROM $this->post2lang_table WHERE language_id = $post_language_id AND translation_group = $post_translation_group LIMIT 1")) {
?>
()
get_results("SELECT ID as post_id, post_title, translation_group FROM $this->post2lang_table p2l INNER JOIN $wpdb->posts p ON p.ID = p2l.post_id WHERE translation_group = $post_translation_group", ARRAY_A);
foreach ($group_info as $group) {
extract($group, EXTR_OVERWRITE);
$title = (strlen($post_title) > GENGO_SIDEBAR_TITLE_LENGTH) ? substr($post_title, 0, GENGO_SIDEBAR_TITLE_LENGTH - 2) . ".." : $post_title;
if ($existing_post_id != $post_id) {
?>
get_col("SELECT DISTINCT translation_group FROM $this->post2lang_table GROUP BY translation_group HAVING 0 = COUNT(CASE WHEN language_id = $post_language_id OR translation_group = 0 OR translation_group = $post_translation_group THEN 37337 END) ORDER BY translation_group DESC LIMIT $first_group, 3")) {
$included_groups = implode(',', $inclusions);
if ($group_info = $wpdb->get_results("SELECT p.ID AS post_id, p.post_title AS post_title, p2l.translation_group AS translation_group FROM $this->post2lang_table p2l INNER JOIN $wpdb->posts p ON p.ID = p2l.post_id WHERE translation_group IN ($included_groups) ORDER BY translation_group", ARRAY_A)) {
foreach ($group_info as $group) {
extract($group, EXTR_OVERWRITE);
if ($translation_group != $previous_translation_group) {
if ($previous_translation_group){
?>
get_col("SELECT DISTINCT translation_group FROM $this->post2lang_table GROUP BY translation_group HAVING 0 = COUNT(CASE WHEN language_id = $post_language_id OR translation_group = 0 OR translation_group = $post_translation_group THEN 37337 END)"));
if ($group_count > ($first_group + GENGO_GROUPS_LIMIT)) {
$remaining = $group_count - ($first_group + GENGO_GROUPS_LIMIT);
if ($remaining > GENGO_GROUPS_LIMIT) $remaining = GENGO_GROUPS_LIMIT;
?>
get_results("SELECT DISTINCT p.ID AS post_id, p.post_title AS post_title, p.post_date AS post_date FROM $wpdb->posts AS p INNER JOIN $this->post2lang_table p2l ON p.ID = p2l.post_ID WHERE p2l.language_id != $post_language_id AND p2l.post_id != $existing_post_id AND p2l.translation_group = 0 AND (p.post_type = 'page' OR p.post_type = 'post') ORDER BY ID DESC LIMIT $first_post, " . GENGO_POSTS_LIMIT, ARRAY_A)) {
if (!$group_info) {
// Hack to force an array if we can only select a post for the translation.
?>
GENGO_SIDEBAR_SELECT_LENGTH) ? substr($post_title, 0, GENGO_SIDEBAR_SELECT_LENGTH - 2) . ".." : $post_title;
$label = $title." (".date("j M",strtotime($post_date)).")";
$translation_list .= "";
}
?>
get_var("SELECT COUNT(*) FROM $wpdb->posts AS p INNER JOIN $this->post2lang_table p2l ON p.ID = p2l.post_ID WHERE p2l.language_id != $post_language_id AND p2l.post_id != $existing_post_id AND p2l.translation_group = 0");
if ($post_count > ($first_post + GENGO_POSTS_LIMIT)) {
$remaining = $post_count - ($first_post + GENGO_POSTS_LIMIT);
if ($remaining > GENGO_POSTS_LIMIT) $remaining = GENGO_POSTS_LIMIT;
?>
languages[$post_language_id]->language;
// Nasty hack to prevent javascript errors.
?>
generate_translation_lists($_POST['post_language_id'], $_POST['post_translation_group'], $_POST['post_id'], $_POST['first_post'], $_POST['first_group']);
break;
case 'ajax_get_translation_post':
$gengo->get_translation_content($_POST['post_id']);
break;
case 'ajax_update_translation_content':
$gengo->update_translation_content($_POST['translation_id'], $_POST['translation_content']);
break;
case 'ajax_get_summary_content':
$gengo->get_summary_content($_POST['summary_id']);
break;
case 'ajax_refresh_summary_lists':
$gengo->generate_summary_lists($_POST['post_id'], $_POST['summary_group'], $_POST['is_in_group'], $_POST['translation_number'], $_POST['existing_translation_group']);
break;
case 'ajax_update_summary_content':
$gengo->update_summary_content($_POST['summary_id'], $_POST['summary_content']);
break;
case 'ajax_add_summary_content':
$gengo->add_summary_content($_POST['post_id'], $_POST['summary_group'], $_POST['language_id'], $_POST['summary_content'], $_POST['translation_group']);
break;
case 'ajax_delete_summary':
$gengo->delete_summary($_POST['summary_id'], $_POST['summary_group']);
break;
case 'ajax_get_group_components':
$gengo->get_group_components($_POST['post_ids']);
break;
case 'ajax_get_synblock':
$gengo->get_synblocks_by_name($_POST['block_name']);
break;
}
exit;
}
$gengo = new Gengo();