= WP 3.0 - This plugin is a tool using wordpress's taxonomy for localized themes or multilingual themes managed by xili-language - a powerful tool to create .mo file(s) on the fly in the theme's folder and more... -
Author: dev.xiligroup - MS
Version: 1.4.0
Author URI: http://dev.xiligroup.com
License: GPLv2
*/
# beta 1.4.0 - 111111 - add context translation ( msgctxt lines )
# beta 1.3.6 - 111001 - fixes import mo (rebuild hierarchy)
# beta 1.3.5 - 110628 - new folder organization - fixes only > 3.1
# beta 1.3.4 - 110521 - compatible with xili-language premium - fixes (for previous version < 3.0 use previous release)
# beta 1.3.3 - 101205 - now able to use ja.mo and ja.po for japanese, fixes db issues.
# beta 1.3.2 - 101203 - fixes for mode standalone w/o xili-language
# beta 1.3.1 - 101128 - add translation links for each target lang.
# beta 1.3.0 - 101107 - js in list with dataTables library
# beta 1.2.2 - 101101 - contextual help - remove filter of delete term Tracs #15264 - add help context
# beta 1.2.1 - 101030 - repairs a bug created by beta xili-language 1.8.1
# beta 1.2.0 - 101028 - compatibility with child theme and xili-language >= 1.8.1 - better folder detection
# beta 1.1.1 - 100627 - fixes issues in multisite mode (empty .mo)
# beta 1.1.0 - 100625 - list of terms with more infos in multisite mode, fixes some issues
# beta 1.1.0 - 100614 - fixes some issues, add some UI features and keep new features from xili-language 1.6.0
# beta 1.0.6 - 100503 - fixes some issues in differential saving (theme's mo and others).
# beta 1.0.5 - 100417 - add features to save .mo of blog structure in uploads folder - compatible with xili-language 1.5.2
# beta 1.0.4 - 100410 - minor modifications for WP 3.0 and WPMU
# beta 1.0.3 - fixes some directories issues in (rare) xamp servers and in theme's terms import. Create .po with empty translations.
# beta 1.0.2 - JS and vars, create lang list, if xili-language absent, for international themes - lot of fixes
# beta 1.0.1 - add scripts for form with plural msg (id or str)
# beta 1.0.0 - use pomo libraries and classes - ONLY >= 2.8
# beta 0.9.9 - fixes existing msgid terms - better log display when importing theme's terms
# beta 0.9.8.2 - more html tags in msg str or id
# beta 0.9.8.1 - some fixes for IIS server and PHP 5.2.1
# beta 0.9.8 - WP 2.8 - fix query error
# beta 0.9.7.3 <- to - see readme.txt - from 0.9.4
# beta 0.9.3 - first published - 090131 MS
# This plugin is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This plugin is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this plugin; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
define('XILIDICTIONARY_VER','1.4.0');
include_once(ABSPATH . WPINC . '/pomo/po.php'); /* not included in wp-settings */
class xili_dictionary {
var $subselect = ''; /* used to subselect by msgid or languages*/
var $xililanguage = ''; /* neveractive isactive wasactive */
var $xililanguagepremium = false;
var $tempoutput = "";
var $langfolder ='/'; /* where po or mo files */
var $xili_settings; /* saved in options */
var $ossep = "/"; /* for recursive file search in xamp */
var $notwp3 = true; // to detect WP3 since alpha
function xili_dictionary($langsfolder = '/') {
global $wp_version;
/* activated when first activation of plug */
$this->notwp3 = (version_compare($wp_version, '3.0-alpha', '<')) ? true : false;
register_activation_hook(__FILE__,array(&$this,'xili_dictionary_activation'));
$this->ossep = strtoupper(substr(PHP_OS,0,3)=='WIN')?'\\':'/'; /* for rare xamp servers*/
/* get current settings - name of taxonomy - name of query-tag */
$this->xililanguage_state();
$this->xili_settings = get_option('xili_dictionary_settings'); // print_r($this->xili_settings);
if(empty($this->xili_settings) || $this->xili_settings['taxonomy'] != 'dictionary') { // to fix
$this->xili_dictionary_activation();
$this->xili_settings = get_option('xili_dictionary_settings');
}
define('DTAXONAME', $this->xili_settings['taxonomy']);
define('XDDICTLANGS','xl-'.DTAXONAME.'-langs');
/** * @since 1.0 */
define('XPLURAL','[XPLURAL]'); /* to separate singular and plural entries */
define('XCTXT','[XCTXT]'); /* to separate context and singular 1.4 */
/* test if version changed */
$version = $this->xili_settings['version'];
if ($version <= '0.2') {
/* update relationships for grouping existing dictionary terms */
$this->update_terms_langs_grouping();
$this->xili_settings['version'] = '1.0';
update_option('xili_dictionary_settings', $this->xili_settings);
}
$this->fill_default_languages_list();
/* Actions */
/* admin */
add_action('admin_init', array(&$this,'admin_init') ); // 1.3.0
add_action('admin_menu', array(&$this,'xili_add_dict_pages'));
add_action('init', array(&$this, 'init_textdomain'));
add_action('init', array(&$this, 'xili_dictionary_register_taxonomies')); /* wp 3.0 WPMU */
add_filter('plugin_action_links', array(&$this,'xilidict_filter_plugin_actions'), 10, 2);
/* special to detect theme changing since 1.1.9 */
add_action('switch_theme', array(&$this,'xd_theme_switched'));
if (!$this->notwp3) {
add_action( 'contextual_help', array(&$this,'add_help_text'), 10, 3 ); /* 1.2.2 */
}
if (function_exists('is_child_theme') && is_child_theme() ) { //
if ( $this->xili_settings['langs_in_root_theme'] == 'root' ) { // for future uses
$this->get_template_directory = get_template_directory();
} else {
$this->get_template_directory = get_stylesheet_directory();
}
} else {
$this->get_template_directory = get_template_directory();
}
if ( class_exists('xili_language_ms') ) $this->xililanguagepremium = true; // 1.3.4
}
/* wp 3.0 WPMU */
function xili_dictionary_register_taxonomies () {
/* add new taxonomy in available taxonomies here dictionary terms */
register_taxonomy( DTAXONAME, 'post',array('hierarchical' => true, 'label'=>false, 'rewrite' => false, 'update_count_callback' => '','show_ui' => false));
/* groups of terms by langs */
register_taxonomy( XDDICTLANGS, 'term',array('hierarchical' => false, 'label'=>false, 'rewrite' => false, 'update_count_callback' => ''));
if ( is_admin() ) {
global $wp_roles;
if ( current_user_can ('activate_plugins') ) {
$wp_roles->add_cap ('administrator', 'xili_dictionary_set');
}
}
}
function xili_dictionary_activation() {
$this->xili_settings = get_option('xili_dictionary_settings');
if(empty($this->xili_settings) || $this->xili_settings['taxonomy'] != 'dictionary') { // to fix
$submitted_settings = array(
'taxonomy' => 'dictionary',
'langs_folder' => '',
'version' => '1.0'
);
update_option('xili_dictionary_settings', $submitted_settings);
}
}
/**
* Reset values when theme was changed... updated by previous function
* @since 1.0.5
*/
function xd_theme_switched ($theme) {
$this->xili_settings['langs_folder'] ="unknown";
/* to force future search in new theme */
update_option('xili_dictionary_settings', $this->xili_settings);
}
/**
* @since 1.3.0 for js
*/
function admin_enqueue_scripts() {
wp_enqueue_script( 'datatables', plugins_url('js/jquery.dataTables.min.js', __FILE__ ) , array( 'jquery' ), '1.7.4', true );
}
function admin_enqueue_styles() {
wp_enqueue_style('table_xdstyle'); // style of js table
}
function admin_init()
{
/* Register our script. */
wp_register_script( 'datatables', plugins_url('js/jquery.dataTables.min.js', __FILE__ ) );
wp_register_style( 'table_xdstyle', plugins_url('/css/xd_table.css', __FILE__ ) );
}
/** * add js in admin * @updated 1.0.2 */
function xili_add_js() {
wp_enqueue_script( 'xd-plural', plugins_url('include/plural.php?varp='.XPLURAL.'&varc='.XCTXT , __FILE__ ), array('jquery'), XILIDICTIONARY_VER);
}
/** *add admin menu and associated page */
function xili_add_dict_pages() {
$this->thehook = add_management_page(__('Xili Dictionary','xili-dictionary'), __('xili Dictionary','xili-dictionary'), 'import', 'dictionary_page', array(&$this,'xili_dictionary_settings'));
add_action('load-'.$this->thehook, array(&$this,'on_load_page'));
add_action( "admin_print_scripts-".$this->thehook, array(&$this,'xili_add_js'));
add_action( 'admin_print_scripts-'.$this->thehook, array(&$this,'admin_enqueue_scripts') );
add_action( 'admin_print_styles-'.$this->thehook, array(&$this,'admin_enqueue_styles') );
}
function on_load_page() {
wp_enqueue_script('common');
wp_enqueue_script('wp-lists');
wp_enqueue_script('postbox');
add_meta_box('xili-dictionary-sidebox-1', __('Message','xili-dictionary'), array(&$this,'on_sidebox_1_content'), $this->thehook , 'side', 'core');
add_meta_box('xili-dictionary-sidebox-2', __('Info','xili-dictionary'), array(&$this,'on_sidebox_2_content'), $this->thehook , 'side', 'core');
}
/**
* Add action link(s) to plugins page
*
* @since 0.9.3
* @author MS
* @copyright Dion Hulse, http://dd32.id.au/wordpress-plugins/?configure-link and scripts@schloebe.de
*/
function xilidict_filter_plugin_actions($links, $file){
static $this_plugin;
if (!$this_plugin ) $this_plugin = plugin_basename(__FILE__);
if ($file == $this_plugin ) {
$settings_link = '' . __('Settings') . '';
$links = array_merge( array($settings_link), $links); // before other links
}
return $links;
}
function init_textdomain() {
/*multilingual for admin pages and menu*/
load_plugin_textdomain('xili-dictionary', false, 'xili-dictionary/languages' );
$this->xili_settings['langs_folder'] = 'unknown';
if (!$this->notwp3 && class_exists('xili_language')) {
global $xili_language ;
$langs_folder = $xili_language->xili_settings['langs_folder']; // set by override_load_textdomain filter
if ( $this->xili_settings['langs_folder'] != $langs_folder ) {
$this->xili_settings['langs_folder'] = $langs_folder ;
update_option('xili_dictionary_settings', $this->xili_settings);
}
} else {
if ( file_exists( $this->get_template_directory ) ) // when theme was unavailable
$this->find_files($this->get_template_directory, '/^.*\.(mo|po|pot)$/', array(&$this,'searchpath'));
if (!defined('THEME_LANGS_FOLDER') && $this->notwp3)
define('THEME_LANGS_FOLDER',$this->xili_settings['langs_folder']); // for bkwd compatibility
}
}
/* call by findfiles */
function searchpath($path, $filename) {
$langs_folder = str_replace($this->get_template_directory,'',$path); // updated 1.2.0
if ( $this->xili_settings['langs_folder'] != $langs_folder ) {
$this->xili_settings['langs_folder'] = $langs_folder ;
update_option('xili_dictionary_settings', $this->xili_settings);
}
}
function xililanguage_state() {
/* test if xili-language is present or was present */
if (class_exists('xili_language')) {
$this->xililanguage = 'isactive';
} else {
/* test if language taxonomy relationships are present */
$xl_settings = get_option('xili_language_settings');
if (empty($xl_settings)) {
$this->xililanguage = 'neveractive';
} else {
$this->xililanguage = 'wasactive';
}
}
}
/** * @since 1.02 */
function fill_default_languages_list() {
if ($this->xililanguage == 'neveractive' || $this->xililanguage == 'wasactive') {
if (!$this->xili_settings[XDDICTLANGS]) {
$default_langs_array = array(
'en_us' => array('en_US', 'english'),
'fr_fr' => array('fr_FR', 'french'),
'de_de' => array('de_DE', 'german'),
'es_es' => array('es_ES', 'spanish'),
'it_it' => array('it_IT', 'italian'),
'pt_pt' => array('pt_PT', 'portuguese'),
'ru_ru' => array('ru_RU', 'russian'),
'zh_cn' => array('zh_CN', 'chinese'),
'ja_ja' => array('ja_JA', 'japanese'),
'ar_ar' => array('ar_AR', 'arabic')
);
/* add wp admin lang */
if (defined ('WPLANG')) {
$lkey = strtolower(WPLANG);
if (!array_key_exists($lkey, $default_langs_array)) $default_langs_array[$lkey] = array (WPLANG, WPLANG);
}
$this->xili_settings[XDDICTLANGS] = $default_langs_array;
update_option('xili_dictionary_settings', $this->xili_settings);
}
}
}
/**
* private function to update grouping of terms if xili-language is active
*
*
*
*/
function update_terms_langs_grouping() {
if ($this->xililanguage == 'isactive') {
$listdictiolines = get_terms(DTAXONAME, array('hide_empty' => false,'get'=>'all'));
if (!empty($listdictiolines)) {
foreach ($listdictiolines as $dictioline) {
/* check slug before creating relationship if parent = O select msgid */
if ($dictioline->parent != 0) {
$extend = $this->extract_extend ( $dictioline->slug ) ; // substr($dictioline->slug,-5);
$lang = get_term_by('slug',$extend,TAXONAME,OBJECT);
if ( $lang ) {
$term = $lang->slug;
} else {
$term = $extend;
}
$args = array( 'alias_of' => '', 'description' => 'Dictionary Group in '.$term, 'parent' => 0, 'slug' =>$extend);
$theids = wp_update_term( $term, XDDICTLANGS, $args); // 1.8.8 instead insert
wp_set_object_terms((int) $dictioline->term_id, $extend, XDDICTLANGS,false);
}
}
}
}
}
/**
* for slug with 5 (_fr_fr) or 2 letters (as japanese)
*
*/
function extract_extend ( $line_slug ) {
$end = substr($line_slug, -6 ) ;
if ( substr($end, 0, 1) == '_' && substr($end, 3, 1) == '_' ) {
return substr($line_slug, -5 );
} else {
return substr($line_slug, -2 ); // as ja
}
}
/**
* private functions for dictionary_settings
* @since 0.9.3
*
* fill the content of the boxes (right side and normal)
*
*/
function on_sidebox_1_content($data) {
extract($data);
?>
\n"; /*to complete*/
echo $line;
}
}
}
function is_intheme_mos ($msgid, $entries) {
//if (array_key_exists($msgid, $entries) {
//} else {
//}
foreach ($entries as $entry) {
$diff = strcmp(htmlspecialchars_decode($msgid),$entry->singular);
if ( $diff != 0) {echo $msgid.' i= '.strlen($msgid); echo $entry->singular.') e= '.strlen($entry->singular); }
if ( $diff == 0) return true;
}
return false;
}
/**
* Detect if translations are saved in theme's languages folder
* @since 1.0.4 - WPMU
* @updated 1.4 - msgctxt
*/
function is_saved_in_theme($msgfull) {
$listlanguages = get_terms(TAXONAME, array('hide_empty' => false));
$thelist = array();
$msgid = "";
if ( false === strpos( $msgfull, XCTXT ) ) {
$msg = $msgfull;
} else {
$context_msg = explode ( XCTXT, $msgfull ) ;
$msg = $context_msg[0].chr(4).$context_msg[1];
}
if ( false === strpos($msg,XPLURAL) ) {
$msgid = $msg;
} else {
$msgidplural = explode(XPLURAL,$msg);
$msgid = $msgidplural[0];
}
foreach ($listlanguages as $reflanguage) {
if ( isset($this->theme_mos[$reflanguage->slug]) ) {
$mess = ( array_key_exists( $msgid, $this->theme_mos[$reflanguage->slug]) ) ? $reflanguage : "";
if ( "" != $mess ) $thelist[] = $reflanguage->name.".mo";
}
}
$output = ($thelist == array()) ? ' **' : ' '. implode(', ',$thelist).'';
return $output;
}
function display_singular_or_plural ($msgfull, $onlyfirst = false) {
if (false === strpos($msgfull,XCTXT)) {
$msg = $msgfull;
$context = "";
} else {
$context_msg = explode ( XCTXT, $msgfull );
$context = $context_msg[0];
$msg = $context_msg[1];
}
if (false === strpos($msg,XPLURAL)) {
if ( $context == "" ) {
return wp_filter_kses($msg);
} else {
return wp_filter_kses($msg).' '.__('with context:','xili-dictionary').' '.$context.'';
}
} else {
$list = explode (XPLURAL,$msg);
if ($onlyfirst === false) {
$list = array_map('wp_filter_kses',$list);
$return = implode(' ',$list);
} else {
$return = wp_filter_kses($list[0]);
}
if ( $context == "" ) {
return $return;
} else {
return $return.' '.__('with context:','xili-dictionary').' '.$context.'';
}
}
}
/**
* Import PO file in class PO
*
*
* @since 1.0 - only WP >= 2.8.4
* @updated 1.05 - import .pot if domain name - fixed 1.3.1
*/
function pomo_import_PO ($lang = "") {
$po = new PO();
$t = "";
if ( function_exists('the_theme_domain') ) {
$t = ($lang == the_theme_domain()) ? 't': ''; /* from UI to select .pot */
} else {
if ( function_exists('is_child_theme') && is_child_theme() ) { // 1.8.1 and WP 3.0
$theme_name = get_option("stylesheet").' '.__('child of','xili-dictionary').' '.get_option("template");
} else {
$theme_name = get_option("template");
}
$t = ( $lang == $theme_name ) ? 't': ''; /* from UI to select .pot */
}
$pofile = $this->get_template_directory.$this->langfolder.$lang.'.po'.$t;
if (file_exists($pofile)) {
if ( !$po->import_from_file( $pofile ) ) {
return false;
} else {
return $po;
}
} else {
return false;
}
}
/**
* Import MO file in class PO
*
*
* @since 1.0.2 - only WP >= 2.8.4
* @updated 1.0.5 - for wpmu
* @param lang
* @param $mofile since 1.0.5
*/
function pomo_import_MO ($lang = "", $mofile = "") {
$mo = new MO();
if ('' == $mofile)
$mofile = $this->get_template_directory.$this->langfolder.$lang.'.mo';
if (file_exists($mofile)) {
if ( !$mo->import_from_file( $mofile ) ) {
return false;
} else {
return $mo;
}
} else {
return false;
}
}
/**
* import mo for temporary diff mo files or check if saved
*
* @since 1.0.6
*
*/
function import_mo_file_wpmu ($lang = "", $istheme = true){
if ($istheme == true) {
return $this->pomo_import_MO ($lang);
} else {
global $wpdb;
$thesite_ID = $wpdb->blogid;
if (($uploads = wp_upload_dir()) && false === $uploads['error'] ) {
//if ($thesite_ID > 1) {
$mofile = $uploads['basedir']."/languages/".$lang.'.mo'; //normally inside theme's folder if root wpmu
return $this->pomo_import_MO ($lang, $mofile);
//} else {
//return false; // normally inside theme's folder if root wpmu
//}
} else {
return false;
}
}
}
/**
* the PO object to twinlines (msgid - msgstr) for list
*
*
* @since 1.0 - only WP >= 2.8.4
* @updated for msgctxt 1.4
*/
function from_PO_to_twin ($po) {
$twinlines = array();
foreach ($po->entries as $pomsgid => $pomsgstr) {
if ( $pomsgstr->context != null ) {
$twin_index = ($pomsgstr->is_plural == null) ? $pomsgstr->context.XCTXT.$pomsgstr->singular : $pomsgstr->context.XCTXT.$pomsgstr->singular.XPLURAL.$pomsgstr->plural ;
} else {
$twin_index = ($pomsgstr->is_plural == null) ? $pomsgid : $pomsgstr->singular.XPLURAL.$pomsgstr->plural ;
}
if ($pomsgstr->is_plural == null) {
$twinlines[$twin_index] = $pomsgstr->translations[0];
} else {
$twinlines[$twin_index] = implode (XPLURAL, $pomsgstr->translations);
}
}
return $twinlines;
}
/**
* the MO object to twinlines (msgid - msgstr) for list
*
*
* @since 1.0.2 - only WP >= 2.8.4
* @updated for msgctxt 1.4
*/
function from_MO_to_twin ( $mo ) {
$twinlines = array();
foreach ( $mo->entries as $pomsgid => $pomsgstr ) {
if ( $pomsgstr->context != null ) {
$twin_index = ($pomsgstr->is_plural == null) ? $pomsgstr->context.XCTXT.$pomsgstr->singular : $pomsgstr->context.XCTXT.$pomsgstr->singular.XPLURAL.$pomsgstr->plural ;
} else {
$twin_index = ($pomsgstr->is_plural == null) ? $pomsgid : $pomsgstr->singular.XPLURAL.$pomsgstr->plural ;
}
if ($pomsgstr->is_plural == null) {
$twinlines[$twin_index] = $pomsgstr->translations[0];
} else {
$twinlines[$twin_index] = implode (XPLURAL, $pomsgstr->translations);
}
}
return $twinlines;
}
/**
* convert twinlines (msgid - msgstr) to MOs in wpmu
* @since 1.0.4
*
* @params as from_twin_to_POMO and $superadmin
*/
function from_twin_to_POMO_wpmu ($curlang, $obj='mo', $superadmin = false) {
// the table array
$table_mo = $this->from_twin_to_POMO($curlang);
$site_mo = $table_mo;
// array diff
if (false === $superadmin) {
// special for superadmin who don't need diff.
// the pomo array available in theme's folder
$theme_mo = $this->import_mo_file_wpmu ($curlang, true);
if (false !== $theme_mo) {
$site_mo->entries = array_diff_key($table_mo->entries,$theme_mo->entries);
// without keys available in theme' mo
}
}
return $site_mo;
}
/**
* convert twinlines (msgid - msgstr) to MO
*
*
* @since 1.0 - only WP >= 2.8.4
* @updated for msgctxt 1.4
*/
function from_twin_to_POMO ( $curlang, $obj='mo' ) {
global $user_identity,$user_url,$user_email;
if ($obj == 'mo') {
$mo = new MO(); /* par default */
} else {
$mo = new PO();
}
/* header */
$translation ='
Project-Id-Version: theme: '.get_option("template").'\n
Report-Msgid-Bugs-To: contact@xiligroup.com\n
POT-Creation-Date: '.date("c").'\n
PO-Revision-Date: '.date("c").'\n
Last-Translator: '.$user_identity.' <'.$user_email.'>\n
Language-Team: xili-dictionary WP plugin and '.$user_url.' <'.$user_email.'>\n
MIME-Version: 1.0\n
Content-Type: text/plain; charset=utf-8\n
Content-Transfer-Encoding: 8bit\n
Plural-Forms: '.$this->plural_forms_rule($curlang).'\n
X-Poedit-Language: '.$curlang.'\n
X-Poedit-Country: '.$curlang.'\n
X-Poedit-SourceCharset: utf-8\n';
$mo->set_headers($mo->make_headers($translation));
/* entries */
$listterms = get_terms(DTAXONAME, array('hide_empty' => false,'parent' => ''));
foreach ($listterms as $curterm) {
if ($curterm->parent == 0) {
/* select child to create translated term */
$listchildterms = get_terms(DTAXONAME, array('hide_empty' => false, 'parent' => $curterm->term_id));
$noentry = true; /* to create po with empty translation */
if ( $listchildterms ) { //print_r($listchildterms);
foreach ($listchildterms as $curchildterm) {
if ( $this->extract_extend ($curchildterm->slug ) == strtolower($curlang) ) {
if ($obj == 'mo') {
if (false === strpos($curterm->description,XPLURAL)) {
$msgidctxt = explode( XCTXT, $curterm->description ); // only one if w/o CTXT
$original = implode( chr(4), $msgidctxt );
$mo->add_entry( $mo->make_entry( $original, $curchildterm->description) );
} else {
if ( false === strpos($curterm->description,XCTXT) ) { // PLURAL
$msgidplural = explode( XPLURAL, $curterm->description );
$original = implode( chr(0), $msgidplural );
$msgstrplural = explode( XPLURAL, $curchildterm->description );
$translation = implode( chr(0), $msgstrplural );
$mo->add_entry($mo->make_entry($original, $translation));
} else { // CONTEXT + PLURAL
$msgidctxt = explode( XCTXT, $curterm->description );
$context = $msgidctxt[0];
$msgidplural = explode( XPLURAL, $msgidctxt[1] );
$original = $context.chr(4).implode( chr(0), $msgidplural );
$msgstrplural = explode( XPLURAL, $curchildterm->description );
$translation = implode( chr(0), $msgstrplural );
$mo->add_entry( $mo->make_entry($original, $translation) );
}
}
} else { /* po */
if (false === strpos($curterm->description,XPLURAL)) {
if (false === strpos($curterm->description,XCTXT)) {
$entry = & new Translation_Entry(array('singular'=>$curterm->description,'translations'=> explode(XPLURAL, $curchildterm->description)));
} else {
$array_msgid = explode(XCTXT,$curterm->description);
$context = $array_msgid[0];
$entry = & new Translation_Entry(array('context'=>$context, 'singular'=>$array_msgid[1], 'translations'=> explode(XPLURAL, $curchildterm->description)));
}
} else { // PLURAL
if (false === strpos($curterm->description,XCTXT)) {
$msgidplural = explode(XPLURAL,$curterm->description);
$msgstrplural = explode(XPLURAL,$curchildterm->description);
$entry = & new Translation_Entry(array('singular' => $msgidplural[0],'plural' => $msgidplural[1], 'is_plural' =>1, 'translations' => $msgstrplural));
} else { // CONTEXT + PLURAL
$array_msgid = explode(XCTXT,$curterm->description);
$context = $array_msgid[0];
$msgidplural = explode(XPLURAL, $array_msgid[1]);
$msgstrplural = explode(XPLURAL,$curchildterm->description);
$entry = & new Translation_Entry(array('context'=>$context, 'singular' => $msgidplural[0],'plural' => $msgidplural[1], 'is_plural' =>1, 'translations' => $msgstrplural));
}
}
$mo->add_entry($entry);
$noentry = false;
}
}
}
}
/* to create po with empty translations */
if ($obj == 'po' && $noentry == true) {
$entry = & new Translation_Entry(array('singular'=>$curterm->description,'translations'=> ""));
$mo->add_entry($entry);
}
}
}
return $mo;
}
/**
* Save MO object to file
*
*
* @since 1.0 - only WP >= 2.8.4
* @updated 1.0.5 - wpmu
*/
function Save_MO_to_file ($curlang , $mo, $createfile = "" ) {
$filename = ( strlen ($curlang) == 5 ) ? substr($curlang,0,3).strtoupper(substr($curlang,-2)) : $curlang;
$filename .= '.mo';
if ("" == $createfile)
$createfile = $this->get_template_directory.$this->langfolder.$filename;
//echo $createfile;
if (false === $mo->export_to_file($createfile)) return false;
}
/**
* Save PO object to file
*
*
* @since 1.0 - only WP >= 2.8.4
*/
function Save_PO_to_file ($curlang , $po ) {
$filename = ( strlen ($curlang) == 5 ) ? substr($curlang,0,3).strtoupper(substr($curlang,-2)) : $curlang;
$filename .= '.po';
$createfile = $this->get_template_directory.$this->langfolder.$filename;
if (false === $po->export_to_file($createfile)) return false;
}
/**
* thanks to http://urbangiraffe.com/articles/translating-wordpress-themes-and-plugins/2/#plural_forms
* @since 1.0 - only WP >= 2.8
*/
function plural_forms_rule($curlang) {
$curlang = ( strlen ($curlang) == 5 ) ? substr($curlang,0,3).strtoupper(substr($curlang,-2)) : $curlang;
$rulesarrays = array(
'nplurals=1; plural=0' => array('tr_TR','ja_JA','ja'),
'nplurals=2; plural=1' => array('zh_ZH'),
'nplurals=2; plural=n != 1' => array('en_US','en_UK','es_ES','da_DA'),
'nplurals=2; plural=n>1' => array('fr_FR','fr_CA','fr_BE','pt_BR'),
'nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2' => array('lv_LV'),
'nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2' => array('gd_GD'),
'nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2' => array('lt_LT'),
'nplurals=3; plural=n%100/10==1 ? 2 : n%10==1 ? 0 : (n+9)%10>3 ? 2 : 1' => array('hr_HR','cs_CS','ru_RU','uk_UK'),
'nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0' => array('sk_SK'),
'nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2' => array('pl_PL'),
'nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3' => array('sl_SL')
);
foreach ($rulesarrays as $rule => $langs) {
if (in_array($curlang, $langs)) return $rule;
}
return 'nplurals=2; plural=n != 1'; /* english and most... */
}
/*
* import array of twintexts in terms tables
*
* @since 0.9.0
* @updated 0.9.7 to set in langs group
* @updated 1.0.0 to manage plural
*
* @param array of msgid/msgstr, language (xx_XX)
*
*/
function xili_import_in_tables( $twintexts=Array(), $translang ) {
$nbline = 0;
$nbtline = 0;
foreach ($twintexts as $key => $line) {
/* is content plural */
if (false === strpos($key,XPLURAL)) {
$thekey = htmlentities($key);
} else {
$plurals = explode (XPLURAL,$key);
$thekey = htmlentities($plurals[0]); /* in term slug only first*/
}
// verify if origin msgid term exist sanitize_title_with_dashes($thekey)
$cur_id = term_exists($thekey, DTAXONAME);
if ($cur_id == 0) {
// create term
$theslug = $this->test_and_create_slug ( $key , $thekey, '' ) ;
$args = array('description' => $key, 'slug'=> $theslug );
$cur_id = term_exists( $theslug, DTAXONAME );
if ($cur_id == 0) {
$result = $this->xili_dic_insert_term(htmlentities($thekey), DTAXONAME, $args);
$insertid = $result['term_id'];
$nbline++;
} else {
$insertid = $cur_id['term_id'];
}
$parent_term = get_term( (int)$insertid, DTAXONAME, OBJECT, 'edit');
/* create the translated term */
$sslug = $parent_term->slug.'_'.strtolower($translang);
$args = array('parent' => $parent_term->term_id, 'slug' => $sslug,'description' => $line);
$existing = get_term_by('slug', $sslug, DTAXONAME, OBJECT);
if ($existing == null && !is_wp_error($existing)) { /* perhaps in another lang */
/* msgstr don't exist */
/* is content plural */
if (false === strpos($line,XPLURAL)) {
$theline = htmlentities($line);
} else {
$plurals = explode (XPLURAL,$line);
$theline = htmlentities($plurals[0]); /* in term slug only first*/
}
$result = $this->xili_dic_insert_term($theline, DTAXONAME, $args);
if (!is_wp_error($result))
$this->xd_wp_set_object_terms((int) $result['term_id'], strtolower($translang), XDDICTLANGS,false);
$nbtline++;
} else {
/* test slug of existing term */
if ($line != $existing->description) {
$this->xili_dic_update_term($existing->term_id, DTAXONAME, $args);
$nbuline++;
}
}
} else {
/* echo msgid exist */
$parent_term = get_term( (int)$cur_id['term_id'], DTAXONAME, OBJECT, 'edit' );
/* verify translated term msgstr */
if (''!=$line) {
$sslug = $parent_term->slug.'_'.strtolower($translang);
$args = array('parent' => $parent_term->term_id, 'slug' => $sslug, 'description' => $line);
$existing = get_term_by('slug', $sslug, DTAXONAME, OBJECT);
if ($existing == null && !is_wp_error($existing)) {
/* no term msgstr */
/* is content plural */
if (false === strpos($line,XPLURAL)) {
$theline = htmlentities($line);
} else {
$plurals = explode (XPLURAL,$line);
$theline = htmlentities($plurals[0]); /* in term slug only first*/
}
$result = $this->xili_dic_insert_term($theline, DTAXONAME, $args);
if (!is_wp_error($result))
$this->xd_wp_set_object_terms((int) $result['term_id'], strtolower($translang), XDDICTLANGS,false);
$nbtline++;
} else {
/* term exists */
if ($line != $existing->description) {
$this->xili_dic_update_term($existing->term_id, DTAXONAME, $args);
$nbuline++;
}
}
} /* empty line */
} /* parent exist */
} /* loop */
return array($nbline,$nbtline,$nbuline); //root id lines, translated lines and updated translated lines
}
/** bloginfo term and others in table * @since 1.6.0 */
function xili_read_infosterms () {
$nbname = 0;
$terms_to_import = array();
$terms_to_import[] = get_bloginfo( 'blogname', 'display' );
$terms_to_import[] = get_bloginfo( 'description', 'display' );
$terms_to_import[] = get_option('time_format');
$terms_to_import[] = get_option('date_format');
if ( class_exists ('xili_language') ) {
global $xili_language;
if (!$xili_language->notwp3) {
foreach ($xili_language->comment_form_labels as $key => $label) {
$terms_to_import[] = $label ;
}
}
}
foreach ( $terms_to_import as $term ) {
$cur_id = term_exists($term, DTAXONAME);
if ($cur_id == 0) {
$args = array('description' => $term);
$result = $this->xili_dic_insert_term( $term, DTAXONAME, $args);
$nbname++;
}
}
return $nbname;
}
/* cat's terms in array (name - slug - description)*/
function xili_read_catsterms(){
$listcategories = get_terms('category', array('hide_empty' => false));
foreach ($listcategories as $category) {
$catterms[] = Array($category->name,$category->description);
}
return $catterms;
}
/* array in tables */
function xili_importcatsterms_in_tables($catterms= Array()){
$nbname = 0;
$nbdesc = 0;
foreach ($catterms as $onecat) {
$cur_id = term_exists( $onecat[0], DTAXONAME );
if ($cur_id == 0) {
$args = array('description' => $onecat[0]);
$result = $this->xili_dic_insert_term( $onecat[0], DTAXONAME, $args);
$nbname++;
}
$cur_id = term_exists(htmlentities($onecat[1]), DTAXONAME);
if ($cur_id == 0 && ""!=$onecat[1]) {
$args = array('description' => $onecat[1]);
$result = $this->xili_dic_insert_term(htmlentities($onecat[1]), DTAXONAME, $args);
$nbdesc++;
}
}
return array($nbname,$nbdesc); // quantities imported
}
function scan_import_theme_terms($callback,$display) {
$path = $this->get_template_directory ;
$themefiles = array();
$dir_handle = @opendir($path) or die("Unable to open $path");
while ($file = readdir($dir_handle)) {
if (substr($file,0,1) == "_" || substr($file,0,1) == "." || substr($file,-4) != ".php")
continue;
$themefiles[] = $file;
}
closedir($dir_handle);
$resultterms = array();
foreach ($themefiles as $themefile) {
if( ! is_file( $path.'/'.$themefile) )
{
$dualtexts = __('error');
} elseif ($themefile != 'functions.php'){
$lines = @file( $path.'/'.$themefile);
$t=0;
foreach ($lines as $line) {
$i = preg_match_all("/_[_e]\('(.*)', ?'/Ui", $line, $matches,PREG_PATTERN_ORDER);
if ($i > 0) {
$resultterms = array_merge ($resultterms, $matches[1]);
$t += $i;
}
}
if ($display >= 1)
call_user_func($callback, $themefile, $t);
}
}
if ($display == 2)
call_user_func($callback, $themefile, $t, $resultterms);
return $resultterms;
}
function build_scanned_files ($themefile, $t, $resultterms = array()) {
if ($resultterms == array()) {
$this->tempoutput .= "- ".$themefile." (".$t.") ";
} else {
$this->tempoutput .= " ".__('List of found terms','xili-dictionary').": ";
$this->tempoutput .= implode (', ',$resultterms);
}
}
/*
* Import theme terms array in table
*
*
*/
function xili_importthemeterms_in_tables($themeterms= Array()){
$nbname = 0;
foreach ($themeterms as $onecat) {
$cur_id = term_exists( $onecat, DTAXONAME );
if ($cur_id == 0) {
$args = array('description' => $onecat);
$result = $this->xili_dic_insert_term(htmlentities($onecat), DTAXONAME, $args);
$nbname++;
}
}
return $nbname;
}
/**
* Recursive search of files in a path
* @since 1.0
*
*/
function find_files($path, $pattern, $callback) {
//$path = rtrim(str_replace("\\", "/", $path), '/') . '/';
$matches = Array();
$entries = Array();
$dir = dir($path);
while (false !== ($entry = $dir->read())) {
$entries[] = $entry;
}
$dir->close();
foreach ($entries as $entry) {
$fullname = $path .$this->ossep. $entry;
if ($entry != '.' && $entry != '..' && is_dir($fullname)) {
$this->find_files($fullname, $pattern, $callback);
} else if (is_file($fullname) && preg_match($pattern, $entry)) {
call_user_func($callback, $path , $entry);
}
}
}
/**
* display lines of files in special sidebox
* @since 1.0
*/
function available_mo_files($path , $filename) {
//echo $filename . " in : " . "/".str_replace("/","",str_replace(get_template_directory(),'',$path)) . " ";
echo str_replace(".mo","",$filename ). " (".$this->ossep.str_replace($this->ossep,"",str_replace($this->get_template_directory,'',$path)).") ";
}
/**
* Contextual help
*
* @since 1.2.2
*/
function add_help_text($contextual_help, $screen_id, $screen) {
// $contextual_help = var_dump($screen); // use this to help determine $screen->id
//echo $contextual_help;
//echo $screen_id;
//print_r($screen);
if ('tools_page_dictionary_page' == $screen->id ) {
$contextual_help =
'
' . __('Things to remember to set xili-dictionary:','xili-dictionary') . '
' .
'
' .
'
' . __('Verify that the theme is localizable (like kubrick, fusion or twentyten).','xili-dictionary') . '
' .
'
' . __('Define the list of targeted languages.','xili-dictionary') . '
' .
'
' . __('Prepare a sub-folder .po and .mo files for each language (use the default delivered with the theme or add the pot of the theme and put them inside.','xili-dictionary') . '
' .
'
' . __('If you have files: import them to create a base dictionary. If not : add a term or use buttons of import and export metabox.','xili-dictionary') . '