Created
October 7, 2011 09:46
-
-
Save marcalj/1269918 to your computer and use it in GitHub Desktop.
Kohana: i18n strings generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php defined('SYSPATH') or die('No direct script access.'); | |
class Controller_Cron extends Controller { | |
public function before() | |
{ | |
// Set default language | |
I18n::$lang = Kohana::$config->load('i18n.default'); | |
} | |
public function action_i18n_generator() | |
{ | |
if ( ! Kohana::$is_cli) | |
{ | |
echo 'Usage: php index.php --uri=/cron/i18n_generator'; | |
return; | |
} | |
$this->auto_render = FALSE; | |
$path = APPPATH; | |
$data = array(); | |
$unique_phrases_helper = array(); | |
$scan_files = $this->get_dir_files($path, array('php')); | |
foreach ($scan_files as $file) | |
{ | |
$file_path_human = substr($file, strlen($path)); | |
// echo Kohana::debug($file_path_human); | |
// Get each line of the file | |
$file_lines = file($file, FILE_IGNORE_NEW_LINES); | |
$data_file = array(); | |
foreach ($file_lines as $num_line => $file_line) | |
{ | |
$num_line++; | |
// echo Kohana::debug($num_line, $file_line, $file_path_human); | |
// if (preg_match_all('/(?P<key>\w+):(?P<name>[\p{L}+|\D+])/u', $file_line, $matches)) | |
// if (preg_match('/^(?P<name>.*?[^(TO|COPYTO)]+)( TO (?P<assignedto>\w[^(COPYTO)]+))?( COPYTO (?P<copyto>\w[^(TO)]+))?$/u', trim($email['Subject']), $matches)) | |
// if (preg_match_all('/__\(\'(?P<phrase>.+)\'(, ?array\(.+\))?\)/u', $file_line, $matches)) | |
// if (preg_match_all('/__\(\'(?P<phrase>.*)(, ?array\(.+\))?\'\)/u', $file_line, $matches)) | |
// if (preg_match_all("/__\('(?P<phrase>.*?[^;])'\)/u", $file_line, $matches)) | |
// if (preg_match_all("/__\([^'.+'$]\)/u", $file_line, $matches)) | |
// if (preg_match_all("/__\([^_]+\)/u", $file_line, $matches)) | |
// if (preg_match_all("/__\([^\b__]+\)/u", $file_line, $matches)) | |
// if (preg_match_all("/__\((?P<phrase>((?!__).)+)\)/u", $file_line, $matches)) /// NOTE IT WORKS!!! | |
// if (preg_match_all("/__\((?P<phrase>((?!__)|(?!array).)+)\)/u", $file_line, $matches)) | |
// if (preg_match_all("/__\(('|\")(?P<phrase>((?!__)|(?! ?array ?\().)+)('|\")/u", $file_line, $matches)) /// NOTE IT WORKS!!! | |
if (preg_match_all("/__\(('|\")(?P<phrase>((?!__)|(?! ?array ?\().)+)('\)|',|\"\)|\",)/u", $file_line, $matches)) /// NOTE IT WORKS!!! | |
{ | |
// echo Kohana::debug($file_path_human, $num_line, $file_line, $matches); | |
// echo Kohana::debug($file_path_human, $num_line, $file_line, $matches['phrase']); | |
// echo Kohana::debug($matches['phrase']); | |
$new_phrases = array_diff(array_unique($matches['phrase']), $unique_phrases_helper); | |
if ($new_phrases) | |
{ | |
$data_file[] = array( | |
'line_number' => $num_line, | |
'line_string' => $file_line, | |
'phrases' => $new_phrases, | |
); | |
$unique_phrases_helper = array_merge($new_phrases, $unique_phrases_helper); | |
} | |
} | |
} | |
if ($data_file) | |
{ | |
$data[] = array( | |
'filepath' => $file, | |
'filepath_human' => $file_path_human, | |
'lines' => $data_file, | |
); | |
} | |
} | |
// echo Kohana::debug($data); | |
$languages = Kohana::$config->load('i18n.languages'); | |
$default_language = Kohana::$config->load('i18n.default'); | |
$orphe_phrases = array(); | |
// Fix phrases | |
foreach ($unique_phrases_helper as $key => $phrase) | |
{ | |
$unique_phrases_helper[$key] = str_replace('\\\'', '\'', $unique_phrases_helper[$key]); | |
$unique_phrases_helper[$key] = str_replace('\\"', '"', $unique_phrases_helper[$key]); | |
} | |
// Add phrases present in current i18n language files but are not present in current code | |
foreach ($languages as $language_code => $language) | |
{ | |
$i18n_messages = array_keys(I18n::load($language_code)); | |
$orphe_phrases = array_merge($orphe_phrases, array_diff($i18n_messages, $unique_phrases_helper)); | |
} | |
$orphe_phrases = array_unique($orphe_phrases); | |
// echo Kohana::debug($orphe_phrases); | |
// Generate new i18n files | |
foreach ($languages as $language_code => $language) | |
{ | |
if ($default_language !== $language_code) | |
{ | |
$filename = APPPATH.'i18n/'.$language_code.'.php'; | |
if (file_exists($filename)) | |
{ | |
rename($filename, $filename.'.old'); | |
} | |
$content = View::factory('i18n_generator') | |
->bind('data', $data) | |
->set('orphe_phrases', $orphe_phrases) | |
->set('language_code', $language_code); | |
if (FALSE === file_put_contents($filename, $content)) | |
{ | |
echo 'There\'s an error writing the file: '.$filename."\n"; | |
} | |
else | |
{ | |
echo 'File ok: '.$filename."\n"; | |
} | |
} | |
} | |
// Fix permissions | |
// system('chown marcalj:marcalj '.APPPATH.'logs/i18n/*'); | |
echo 'Finish'; | |
} | |
/** | |
* Working tests: | |
* | |
* <?php echo __('tèst1'); ?> | |
* <?php echo __('tést2 :mico', array(':mico' => I18n::$lang)); ?> | |
* <?php echo __('tëst3 :mico', array(':mico' => I18n::$lang)); ?><?php echo __('test4'); ?> | |
* <?php echo __('test5 :mico', array(':mico' => I18n::$lang)).__('test6'); ?> | |
* <?php echo __('test7 :mico', array(':mico' => HTML::anchor(Route::get('website/new-tradu')->uri(array('language' => I18n::$lang)), __('test8')))); ?> | |
* <?php echo __('test9 :mico', array(':mico' => HTML::anchor(Route::get('website/new-tradu')->uri(array('language' => I18n::$lang)), __('test10 :moco', array(':moco' => I18n::$lang))))); ?> | |
* <?php echo __('tést11'); ?><?php echo __('tést12'); ?> | |
* <?php echo __('test13'); ?><?php echo __('tëst14 :mico', array(':mico' => I18n::$lang)); ?> | |
* <?php echo __('tést15'); ?><?php echo __('tést16'); ?><?php echo __('tést17'); ?> | |
* <?php echo __('tést18_jodete'); ?> | |
* <?php echo __('tést19;'); ?> | |
* <?php echo __("tést20;"); ?> | |
* <?php echo __('tést21 you\'re'); ?> | |
* <?php echo __('tést21 "enviar"'); ?> | |
*/ | |
public function get_dir_files($dir, $types = NULL) | |
{ | |
// Remove DIRECTORY_SEPARATOR at the end | |
$dir = rtrim($dir, DIRECTORY_SEPARATOR); | |
$path = ''; | |
$stack[] = $dir; | |
while ($stack) | |
{ | |
$thisdir = array_pop($stack); | |
if ($dircont = scandir($thisdir)) | |
{ | |
$i = 0; | |
while (isset($dircont[$i])) | |
{ | |
if ($dircont[$i] !== '.' && $dircont[$i] !== '..') | |
{ | |
$current_file = $thisdir.DIRECTORY_SEPARATOR.$dircont[$i]; | |
if (is_file($current_file)) | |
{ | |
if (is_array($types)) | |
{ | |
if (in_array(strtolower(pathinfo($thisdir.$dircont[$i], PATHINFO_EXTENSION)), $types, TRUE)) | |
{ | |
$path[] = $thisdir.DIRECTORY_SEPARATOR.$dircont[$i]; | |
} | |
} | |
} | |
elseif (is_dir($current_file)) | |
{ | |
$stack[] = $current_file; | |
} | |
} | |
$i++; | |
} | |
} | |
} | |
return $path; | |
} | |
/// FIXME use this function (alert!! it's recursive!) | |
/** | |
* Recursively finds all of the files in the specified directory at any | |
* location in the [Cascading Filesystem](kohana/files), and returns an | |
* array of all the files found, sorted alphabetically. | |
* | |
* // Find all view files. | |
* $views = Kohana::list_files('views'); | |
* | |
* @param string directory name | |
* @param array list of paths to search | |
* @return array | |
*/ | |
// public static function list_files($directory = NULL, array $paths = NULL) | |
} // End Cron |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php defined('SYSPATH') or die('No direct access allowed.'); | |
return array | |
( | |
'languages' => array( | |
'en' => 'English', | |
'ca' => 'Català', | |
'es' => 'Español', | |
'fr' => 'Français', | |
), | |
// The default language correspond to the language wrote in PHP code | |
'default' => 'en', | |
); | |
/// NOTE when adding more languages we need to check for the respective JS plugins' translations |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
print(Kohana::FILE_SECURITY."\n\n"); | |
print("return array(\n"); | |
foreach ($data as $file) | |
{ | |
print("\t// ".$file['filepath_human']."\n"); | |
foreach ($file['lines'] as $line) | |
{ | |
$line['line_string'] = str_replace('<?php', '', $line['line_string']); | |
$line['line_string'] = str_replace('<?', '', $line['line_string']); | |
$line['line_string'] = str_replace('?>', '', $line['line_string']); | |
$line['line_string'] = trim($line['line_string']); | |
foreach ($line['phrases'] as $phrase) | |
{ | |
$phrase_fixed = str_replace('\\\'', '\'', $phrase); | |
$phrase_fixed = str_replace('\\"', '"', $phrase_fixed); | |
$phrase_translated = I18n::get($phrase_fixed, $language_code); | |
$phrase_translated_fixed = str_replace('\'', '\\\'', $phrase_translated); | |
$not_translated = ''; | |
if ($phrase_fixed === $phrase_translated) | |
{ | |
$not_translated = '/// TODO'; | |
$phrase_translated_fixed = ''; | |
} | |
// print($not_translated."\t'$phrase' => '".$phrase_translated_fixed."', // ".$line['line_number'].": ".$line['line_string']."\n"); | |
print($not_translated."\t'$phrase' => '".$phrase_translated_fixed."', // ".$line['line_number']."\n"); | |
} | |
} | |
print("\n"); | |
} | |
// Orphan phrases | |
print("\t// Orphan phrases\n"); | |
foreach ($orphe_phrases as $phrase) | |
{ | |
$phrase_translated = I18n::get($phrase, $language_code); | |
$not_translated = ''; | |
if ($phrase === $phrase_translated) | |
{ | |
$not_translated = '/// TODO'; | |
$phrase_translated = ''; | |
} | |
print($not_translated."\t'$phrase' => '".$phrase_translated."',\n"); | |
} | |
print(");\n"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment