main_plugin_file = Jutranslation::$main_plugin_file; $addon->extension_name = Jutranslation::$extension_name; $addon->extension_slug = Jutranslation::$extension_slug; $addon->text_domain = Jutranslation::$text_domain; $addon->language_file = Jutranslation::$language_file; $addons[$addon->extension_slug] = $addon; return $addons; }); //Only need Jutranslation on admin side if(!is_admin()){ return; } // Check if the current user add_action('admin_init', function(){ if(current_user_can('manage_options')) { //Initialize needed ajax mehtods add_action( 'wp_ajax_jutranslation_'.Jutranslation::$extension_slug, array(__CLASS__, 'dispatchQuery') ); } }); } /** * Ajax queries dispatcher */ public static function dispatchQuery() { if(!isset($_REQUEST['task'])) { die; } switch ($_REQUEST['task']) { case 'jutranslation.saveStrings': Jutranslation::saveStrings(); break; case 'jutranslation.getTranslation': Jutranslation::getTranslation(); break; case 'jutranslation.showViewForm': Jutranslation::showViewForm(); break; } } /** * Return the main html content for jutranslation * @return void */ public static function getInput(){ echo '
'; echo '
'; //Declare all js and css to include $jsInline = array( 'jutranslation_token="'.wp_create_nonce( 'jutranslation' ).'";', 'jutranslation_ajax_action="jutranslation_'.Jutranslation::$extension_slug.'";', 'jutranslation_base_url=ajaxurl+"?";' ); echo ''; wp_enqueue_script('jutranslation', plugin_dir_url( Jutranslation::$main_plugin_file ) . 'jutranslation/assets/js/jutranslation.js'); wp_enqueue_style('jutranslation', plugin_dir_url( Jutranslation::$main_plugin_file ) . 'jutranslation/assets/css/jutranslation.css'); add_thickbox(); //Get all installed languages $installed_languages = array(); foreach ( wp_get_installed_translations('core') as $type) { foreach ( $type as $lang => $value ) { $lang = str_replace('_', '-', $lang); $installed_languages[] = $lang; } } //Add Polylang languages if(function_exists('pll_languages_list')){ foreach ( pll_languages_list(array('fields'=>'locale')) as $pll_language) { $lang = str_replace('_', '-', $pll_language); $installed_languages[] = $lang; } } //Add WPML languages if(!function_exists('pll_languages_list') && function_exists('icl_get_languages')){ foreach ( icl_get_languages() as $wpml_language) { $lang = str_replace('_', '-', $wpml_language['default_locale']); $installed_languages[] = $lang; } } //Add default en-US language if(!isset($installed_languages['en-US'])){ $installed_languages = array_merge(array('en-US'), $installed_languages); } $installed_languages = array_unique($installed_languages); //Get addons $addons = apply_filters(Jutranslation::$extension_slug.'_get_addons', array()); ksort($addons); $languages = array(); foreach ($installed_languages as $installed_language) { foreach ($addons as $addon) { $langObject = new \stdClass(); $langObject->extension = $addon; $langObject->installed = false; $langObject->extension_version = ''; $langObject->language_version = ''; $langObject->revision = '1'; $langObject->languageCode = $installed_language; $langObject->modified = '0'; $languages[] = $langObject; } } //Check if language is installed foreach ($languages as &$language) { if (str_replace('-', '_', $language->languageCode) === 'en_US') { $file = $language->extension->language_file; } else { $file = WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'languages' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . $language->extension->text_domain . '-' . str_replace('-', '_', $language->languageCode) . '.mo'; } if (file_exists($file)) { $language->installed = true; // Load language file $mo = new \MO(); $mo->import_from_file($file); //Assign it to the language if (isset($mo->headers['Version'])) { $language->language_version = $mo->headers['Version']; } if (isset($mo->headers['Revision'])) { $language->revision = $mo->headers['Revision']; } if (isset($mo->headers['Modified'])) { $language->modified = $mo->headers['Modified']; } else { //The header has not been found, so the language file has not been add by jutranslation $language->modified = '1'; } } //Check for language override $language->overrided = 0; $file = WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'languages' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . $language->extension->text_domain . '-' . str_replace('-', '_', $language->languageCode) . '.override.mo';; if (file_exists($file)) { // Load language file $mo = new \MO(); $mo->import_from_file($file); $language->overrided = 0; //Check if a translation exists for each entry foreach ($mo->entries as $entry) { if (count($entry->translations[0])) { $language->overrided++; } } } } unset($language); //Show documentation link echo '

You can refer to the documentation page on Joomunited for more informations about extension translation

'; echo '

'; foreach ($addons as $addon) { //Get extension version $plugin_data = get_plugin_data( $addon->main_plugin_file ); $extension_version = $plugin_data['Version']; echo 'Current ' . $addon->extension_name . ' version is ' . $extension_version . '
'; } echo '

'; $julanguages = array(); echo ''; foreach ($languages as $language) { echo ''; echo ''; echo ''; echo ''; echo ''; echo ''; if (!isset($julanguages[$language->extension->extension_slug])) { $plugin_data = get_plugin_data($language->extension->main_plugin_file); $julanguages[$language->extension->extension_slug] = array(); $julanguages[$language->extension->extension_slug]['extension'] = $language->extension->extension_slug; $julanguages[$language->extension->extension_slug]['extension_version'] = $plugin_data['Version']; $julanguages[$language->extension->extension_slug]['language_version'] = $language->language_version; $julanguages[$language->extension->extension_slug]['languages'] = array(); $julanguages[$language->extension->extension_slug]['versions'] = array(); $julanguages[$language->extension->extension_slug]['revisions'] = array(); } $julanguages[$language->extension->extension_slug]['languages'][] = $language->languageCode; $julanguages[$language->extension->extension_slug]['versions'][$language->languageCode] = $language->language_version; $julanguages[$language->extension->extension_slug]['revisions'][$language->languageCode] = $language->revision; } echo '
1?'':'style="display:none;"') . '>Plugin Language Current version Latest available version
1?'':'style="display:none;"') . '>' . $language->extension->extension_name . '' . $language->languageCode . '' . ($language->installed?($language->language_version?($language->revision?$language->language_version.' rev'.$language->revision:$language->language_version.' rev'.$language->revision):'Unknown'):'Not installed') . '
'; echo 'loading
'; echo 'Override (' . $language->overrided . ') '; if($language->languageCode !== 'en-US'){ //Reference en-US file can't be modified echo 'Edit original file'; } //No sharing for en-US if($language->languageCode!=='en-US'){ echo ' Share with Joomunited'; } echo '
'; echo ''; echo '
'; } /** * Save a post translation for a given language */ protected static function saveStrings(){ //Security check if(!wp_verify_nonce( $_REQUEST['wp_nonce'], 'jutranslation' )){ echo json_encode(array('status'=>'error','message'=>'nonce error')); die(); } //Get and check language $language = $_POST['language']; if(!$language){ echo json_encode(array('status'=>'error','message'=>'language empty')); die(); } if(!preg_match('/^[a-z]{2,3}(?:-[a-zA-Z]{4})?(?:-[A-Z]{2,3})?$/',$language)){ echo json_encode(array('status'=>'error','message'=>'invalid language code')); die(); } $plugin = $_POST['slug']; if(!$plugin){ echo json_encode(array('status'=>'error','message'=>'plugin empty')); die(); } if(!preg_match('/^[a-zA-Z-_]+$/',$plugin)){ echo json_encode(array('status'=>'error','message'=>'invalid plugin slug')); die(); } $addons = apply_filters(Jutranslation::$extension_slug.'_get_addons', array()); if (!isset($addons[$plugin])) { echo json_encode(array('status'=>'error','message'=>'plugin not found')); die(); } //Get the file to write to $destination = $_POST['destination']; $file = WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'languages' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . $addons[$plugin]->text_domain . '-' . str_replace('-', '_', $language) ; switch ($destination){ case 'override': $file .= '.override.mo'; break; case 'edition': //Disallow editing main en-US file if($language === 'en-US'){ echo json_encode(array('status'=>'error','message'=>'editing main reference file not allowed')); die(); } $file .= '.mo'; //Get informations about previous installed file // Load language file $mo = new \MO(); $mo->import_from_file( $file ); //Get the file version if(isset($mo->headers['Version']) && $mo->headers['Version']){ $extension_version = $mo->headers['Version']; }else{ //Use the current extension version $plugin_data = get_plugin_data($addons[$plugin]->main_plugin_file); $extension_version = $plugin_data['Version']; } //Get the file revision if(isset($mo->headers['Revision'])){ $revision = $mo->headers['Revision']; }else{ //Use the current extension version $revision = (int)$_POST['revision']; } break; default: //Case new language version installation from Joomunited //Get the version $extension_version = $_POST['extension_version']; if(!$extension_version){ echo json_encode(array('status'=>'error','message'=>'version empty')); die(); } //Get revision $revision = (int)$_POST['revision']; $file .= '.mo'; break; } //Check version number if($destination!=='override' && !preg_match('/^([0-9]+)\.([0-9]+)(\.([0-9]+))?(\.([0-9]+))?$/',$extension_version)){ echo json_encode(array('status'=>'error','message'=>'invalid version number')); die(); } $modified = $_POST['modified']; //Get strings and remove slashes auto added by WP $strings = stripslashes($_POST['strings']); //Check if strings is a valid array $strings = json_decode($strings); if($strings === false || !is_object($strings) || !count((array)$strings)){ $strings = new \StdClass(); } // Load translation class $mo = new \MO(); //Generate the file header if($destination !== 'override'){ $mo->headers['Version'] = $extension_version; $mo->headers['Revision'] = $revision; $mo->headers['Modified'] = (int)$modified; } foreach ($strings as $code => $string) { //Only save reference language empty strings if($string !== '' || $language === 'en-US') { $entry = &$mo->make_entry($code, $string); $mo->entries[$code] = &$entry; } } //Create parents folders of language file wp_mkdir_p(dirname($file)); //Write the language file if($mo->export_to_file($file)){ echo json_encode(array('status'=>'success','message'=>'file created')); die(); } echo json_encode(array('status'=>'error','message'=>'writing file failed')); die(); } protected static function getTranslation(){ //Get and check language $language =$_POST['language']; if(!$language){ echo json_encode(array('status'=>'error','message'=>'language empty')); die(); } if(!preg_match('/^[a-z]{2,3}(?:-[a-zA-Z]{4})?(?:-[A-Z]{2,3})?$/',$language)){ echo json_encode(array('status'=>'error','message'=>'invalid language code')); die(); } $plugin = $_POST['slug']; if(!$plugin){ echo json_encode(array('status'=>'error','message'=>'plugin empty')); die(); } if(!preg_match('/^[a-zA-Z-_]+$/',$plugin)){ echo json_encode(array('status'=>'error','message'=>'invalid plugin slug')); die(); } $addons = apply_filters(Jutranslation::$extension_slug.'_get_addons', array()); if (!isset($addons[$plugin])) { echo json_encode(array('status'=>'error','message'=>'plugin not found')); die(); } //Get the language file for reference language en-US $file = $addons[$plugin]->language_file; $mo = new \MO(); $mo->import_from_file( $file ); //Retrieve reference the strings $reference_strings = array(); foreach($mo->entries as $entry) { $reference_strings[$entry->singular] = $entry->translations[0]; } //Get the default language file for this language $file = WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'languages' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . $addons[$plugin]->text_domain . '-' . str_replace('-', '_', $language) . '.mo'; $mo = new \MO(); $mo->import_from_file( $file ); //Retrieve default strings $language_strings = array(); foreach($mo->entries as $entry) { $language_strings[$entry->singular] = $entry->translations[0]; } //Get the override file content if exists $file = WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'languages' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . $addons[$plugin]->text_domain . '-' . str_replace('-', '_', $language) . '.override.mo'; if(file_exists($file)){ $mo = new \MO(); $mo->import_from_file( $file ); //Retrieve override strings $override_strings = array(); foreach($mo->entries as $entry) { $override_strings[$entry->singular] = $entry->translations[0]; } }else{ $override_strings = array(); } //Generate the final variable cotaining all strings $final_result = array(); foreach (array('reference_strings' => $reference_strings, 'language_strings' => $language_strings, 'override_strings' => $override_strings) as $variable => $strings) { foreach ($strings as $constant => $value) { if(empty($final_result[$constant])) { $obj = new \stdClass(); $obj->key = $constant; $obj->reference = ''; $obj->language = ''; $obj->override = ''; $final_result[$constant] = $obj; } switch ($variable) { case 'reference_strings' : $final_result[$constant]->reference = $value; break; case 'language_strings' : $final_result[$constant]->language = $value; break; case 'override_strings' : $final_result[$constant]->override = $value; break; } } } echo json_encode(array('status'=>'success','datas'=> array('language'=> $language, 'strings' => $final_result))); die(); } /** * Show submit form to share translation */ protected static function showViewForm(){ echo ''; echo ''; echo ''; echo ' '; echo ' Share with Joomunited'; echo ''; echo ''; //Get and check language $language = $_GET['language']; if(!$language){ throw new Exception('language empty'); } if(!preg_match('/^[a-z]{2,3}(?:-[a-zA-Z]{4})?(?:-[A-Z]{2,3})?$/',$language)){ throw new Exception('invalid language code'); } $plugin = $_GET['slug']; if(!$plugin){ echo json_encode(array('status'=>'error','message'=>'plugin empty')); die(); } if(!preg_match('/^[a-zA-Z-_]+$/',$plugin)){ echo json_encode(array('status'=>'error','message'=>'invalid plugin slug')); die(); } $addons = apply_filters(Jutranslation::$extension_slug.'_get_addons', array()); if (!isset($addons[$plugin])) { echo json_encode(array('status'=>'error','message'=>'plugin not found')); die(); } $file = WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'languages' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . $addons[$plugin]->text_domain . '-' . str_replace('-', '_', $language) . '.mo'; if(!file_exists($file)){ throw new Exception('language file doesn\'t exist'); } //Get informations $mo = new \MO(); $mo->import_from_file( $file ); //Check if the file has been modified by the user if(isset($mo->headers['Modified']) && $mo->headers['Modified']!=='1'){ throw new Exception('language file not modified'); } $strings = array(); //Check if a translation exists for each entry foreach($mo->entries as $entry) { $strings[$entry->singular] = $entry->translations[0]; } $strings = json_encode($strings); //Get the current extension version $plugin_data = get_plugin_data( $addons[$plugin]->main_plugin_file ); $version = $plugin_data['Version']; echo '
'; echo ''; echo ''; echo ''; echo ''; echo '
'; //Add waiting image echo '
'; //Submit automatically the form on page loading echo ''; echo ''; echo ''; wp_die(); } public static function overrideLanguage($text_domain, $mofile){ //Only for our plugin and addons $addons = apply_filters(Jutranslation::$extension_slug.'_get_addons', array()); foreach ($addons as $addon) { if ($text_domain === $addon->text_domain) { $path_parts = explode(DIRECTORY_SEPARATOR, $mofile); $filename = $path_parts[count($path_parts)-1]; $filename_parts = explode('.',$filename); //Return if it's action already for overrode file if(count($filename_parts)>2 || $filename_parts[count($filename_parts)-2] === 'override'){ return; } //Load the overrode file $path_parts[count($path_parts)-1] = str_replace('.mo', '.override.mo', $path_parts[count($path_parts)-1]); if(file_exists(implode(DIRECTORY_SEPARATOR, $path_parts))){ load_textdomain($text_domain, implode(DIRECTORY_SEPARATOR, $path_parts)); } } } } }