00001 <?php
00002
00003 class aliroLanguageExtended extends aliroLanguageBasic {
00004
00005 public function __construct ($lang=null, $path=null, $load_catalogs=false) {
00006 if ($lang) parent::__construct ($lang, $path, $load_catalogs);
00007 else {
00008 $this->path = $path ? $path : _ALIRO_CLASS_BASE.'/language/';
00009 $this->isValid = true;
00010 }
00011 }
00012
00013 public function update () {
00014 $vars = array_keys(get_object_vars($this));
00015 foreach ($_POST as $k => $v) {
00016 if (in_array($k, $vars)) {
00017 $this->$k = $v;
00018 }
00019 }
00020 $this->setPlurals($_POST['plural_form']);
00021 $this->save();
00022 }
00023
00024 public function export () {
00025 $zipbase = $this->class_base;
00026 chdir($zipbase);
00027 $filename = "AliroLanguage_{$this->name}.zip";
00028 $zipfile = $zipbase.'/media/'.$filename;
00029
00030 $archive = new zipfile();
00031 foreach ($this->files as $file) {
00032
00033 $archive->addfile(file_get_contents($zipbase.'/language/'.$this->name.'/'.$file['filename']), $file['filename']);
00034
00035 }
00036 $archive->output($zipfile);
00037 @ob_end_clean();
00038 ob_start();
00039 header('Content-Type: application/x-zip');
00040 header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
00041 if (isset($_SERVER['HTTP_USER_AGENT']) AND false !== strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE')) {
00042 header('Content-Disposition: inline; filename="' . $filename . '"');
00043 header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
00044 header('Pragma: public');
00045 } else {
00046 header('Content-Disposition: attachment; filename="' . $filename . '"');
00047 header('Pragma: no-cache');
00048 }
00049 readfile($zipfile);
00050 ob_end_flush();
00051 aliroFileManager::getInstance()->deleteFile($zipfile);
00052 exit(0);
00053 }
00054
00055 public function createLanguage ($iso639, $iso3166, $iso3166_3) {
00056 $lang = $iso639;
00057 $lang .= strlen($iso3166) == 2 ? '-'.$iso3166 : '';
00058 $locales = $this->getLocales();
00059 $default = $this->getLocale($iso639);
00060 $lvars = array_keys(get_class_vars('aliroLanguageBasic'));
00061 foreach ($default as $k => $v) if (in_array($k, $lvars)) $this->$k = $v;
00062 foreach ($_POST as $k => $v) if (in_array($k, $lvars)) $this->$k = $v;
00063 $this->name = $lang;
00064 $this->description = $this->title.' Locale';
00065 if (!empty($this->territory)) $this->description .= ' For '.$this->territory;
00066 $this->locale = $lang.'.'.$this->charset.','.$lang.','.$iso639.','.strtolower($this->title);
00067 $this->iso3166_3 = $iso3166_3;
00068 $this->creationdate = date('d-m-Y');
00069 $this->author = 'Aliro Software';
00070 $this->authorurl = 'http://www.aliro.org';
00071 $this->authoremail = 'translation@aliro.org';
00072 $this->copyright = 'Refer to root index.php';
00073 $this->license = 'http://www.gnu.org/copyleft/gpl.html GNU/GPL';
00074 $this->setPlurals($_POST['plural_form']);
00075 if (!$this->canCreateLanguage()) {
00076 aliroRequest::getInstance()->setErrorMessage (T_('Cannot create language, it already exists'), _ALIRO_ERROR_FATAL);
00077 die('Cannot create language, already exists');
00078 return;
00079 }
00080
00081
00082 $dir = $this->path.$this->name;
00083 $untranslated = $this->path.'untranslated';
00084 $charset = $this->charset;
00085 $untransdir = new aliroDirectory($untranslated);
00086 $langfiles = $untransdir->listFiles('\.pot$', 'file');
00087
00088 $fmanager = aliroFileManager::getInstance();
00089 $fmanager->createDirectory($dir.'/LC_MESSAGES');
00090
00091
00092
00093
00094 foreach ($langfiles as $domain) {
00095 $domain = substr($domain,0,-4);
00096
00097
00098
00099
00100
00101 $fmanager->forceCopy("$untranslated/$domain.pot", "$dir/$domain.po");
00102
00103 }
00104
00105
00106
00107 $this->save();
00108 }
00109
00110 private function canCreateLanguage () {
00111 if ('en' == $this->name OR aliroExtensionHandler::getInstance()->getExtensionByName($this->name)) {
00112 return false;
00113 }
00114 $extension = new aliroExtension();
00115 $extension->name = $this->title;
00116 $extension->formalname = $this->name;
00117 $extension->type = 'language';
00118 $extension->description = $this->description;
00119 $extension->timestamp = date('Y-m-d');
00120 $extension->store();
00121 aliroExtensionHandler::getInstance()->clearCache();
00122 return true;
00123 }
00124
00125 public function save() {
00126 $mapcharset = charsetmapping::getInstance()->map();
00127 $request = aliroRequest::getInstance();
00128 $task = $request->getParam($_REQUEST, 'task');
00129 $this->updateFiles();
00130 $xml = $this->toXML();
00131 if (("addpage" == $request->getParam($_POST, 'page_') AND $task=="save") OR $task=="convert") {
00132 if (false AND strtolower($this->charset) != 'utf-8') {
00133 $xml = $this->iconvert("utf-8", $mapcharset[$this->charset], $xml);
00134 }
00135 }
00136 $name = $this->getFileName();
00137 file_put_contents($this->path.$name.'/'.$name.'.xml', $xml);
00138 }
00139
00140 public function setPlurals($exp) {
00141 preg_match('/nplurals\s*=\s*(\d+)\s*;\s*plural\s*=\s*(.*)\s*;/', $exp, $plurals);
00142 $this->plural_form = array('nplurals' => $plurals[1], 'plural' => $plurals[2], 'expression' => $plurals[0]);
00143 }
00144
00145 protected function updateFiles() {
00146 $dir = $this->path . $this->name . '/';
00147 $langdir = new aliroDirectory($dir);
00148 $pofiles = $langdir->listFiles('\.po$', 'file');
00149 set_time_limit(60);
00150 foreach ($pofiles as $lf) {
00151 $domain = substr($lf, 0, -3);
00152 $catalog = new PHPGettextFilePO (true, $domain, $this->path, $this->name);
00153 $file['filename'] = $lf;
00154 $file['domain'] = $domain;
00155 $file['strings'] = count($catalog->strings);
00156 $file['percent'] = '';
00157 $file['translated'] = 0;
00158 $file['fuzzy'] = 0;
00159 $file['filetype'] = 'po';
00160 $pluralfuzz = false;
00161 foreach ($catalog->strings as $msg) {
00162 if (is_array($msg->msgstr)) {
00163 foreach ($msg->msgstr as $i) $unt = empty($i);
00164 if (!$unt) $file['translated']++;
00165 }
00166 if (!is_array($msg->msgstr) AND !empty($msg->msgstr) AND !$msg->is_fuzzy) $file['translated']++;
00167 if ($msg->is_fuzzy) $file['fuzzy']++;
00168 }
00169 $nonfuzzy = $file['strings'] - $file['fuzzy'];
00170 $nonfuzzy = max(1, $nonfuzzy);
00171 $file['percent'] = round($file['translated'] * 100 / $nonfuzzy, 2);
00172 unset($nonfuzzy);
00173 $this->files[] = $file;
00174 }
00175 $this->files[] = array('filename'=>"$this->name.xml",'domain'=>"",'strings'=>"",'percent'=>"",'translated'=>0,'fuzzy'=>0,'filetype'=>'xml');
00176 $langdir = new aliroDirectory($dir.'LC_MESSAGES/');
00177 $mofiles = $langdir->listFiles('\.mo$', 'file');
00178 set_time_limit(60);
00179 foreach ($mofiles as $lf) {
00180 $this->files[] = array('filename'=>"LC_MESSAGES/$lf",'domain'=>"",'strings'=>"",'percent'=>"",'translated'=>0,'fuzzy'=>0,'filetype'=>'mo');
00181 }
00182 if (file_exists($this->path."/glossary/{$this->name}.{$this->charset}.po")) {
00183 $this->files[] = array('filename'=>"glossary/{$this->name}.{$this->charset}.po",'domain'=>"",'strings'=>"",'percent'=>"",'translated'=>0,'fuzzy'=>0,'filetype'=>'gl');
00184 }
00185 }
00186
00187 protected function toXML() {
00188 $array[] = array('tag' => 'extinstall', 'type' => 'open', 'level' => 1, 'attributes' => array('version' => '2.0', 'type' => 'language'));
00189 $array[] = array('tag' => 'name', 'type' => 'complete', 'level' => 2, 'value' => $this->title);
00190 $array[] = array('tag' => 'formalname', 'type' => 'complete', 'level' => 2, 'value' => $this->name);
00191 $array[] = array('tag' => 'version', 'type' => 'complete', 'level' => 2, 'value' => $this->version);
00192 $array[] = array('tag' => 'description', 'type' => 'complete', 'level' => 2, 'value' => $this->description);
00193 $array[] = array('tag' => 'creationdate', 'type' => 'complete', 'level' => 2, 'value' => $this->creationdate);
00194 $array[] = array('tag' => 'author', 'type' => 'complete', 'level' => 2, 'value' => $this->author);
00195 $array[] = array('tag' => 'authorurl', 'type' => 'complete', 'level' => 2, 'value' => $this->authorurl);
00196 $array[] = array('tag' => 'authoremail', 'type' => 'complete', 'level' => 2, 'value' => $this->authoremail);
00197 $array[] = array('tag' => 'copyright', 'type' => 'complete', 'level' => 2, 'value' => $this->copyright);
00198 $array[] = array('tag' => 'license', 'type' => 'complete', 'level' => 2, 'value' => $this->license);
00199 $array[] = array('tag' => 'files', 'type' => 'open', 'level' => 2);
00200 foreach ($this->files as $file) {
00201 $array[] = array('tag' => 'filename', 'type' => 'complete', 'level' => 3, 'value' => $file['filename'], 'attributes' => array('domain' => $file['domain'] , 'strings' => $file['strings'] , 'translated' => $file['translated'] , 'fuzzy' => $file['fuzzy'] , 'percent' => $file['percent'], 'filetype' => $file['filetype']));
00202 }
00203 $array[] = array('tag' => 'files', 'type' => 'close', 'level' => 2);
00204 $array[] = array('tag' => 'params', 'type' => 'open', 'level' => 2);
00205 $array[] = array('tag' => 'param', 'type' => 'complete', 'level' => 3, 'attributes' => array('name' => 'locale', 'type' => 'text', 'default' => $this->locale, 'label' => 'Locale String', 'description' => 'Locale string for setlocale() (eg. en, english)'));
00206 $array[] = array('tag' => 'param', 'type' => 'complete', 'level' => 3, 'attributes' => array('name' => 'charset', 'type' => 'text', 'default' => $this->charset, 'label' => 'Character Set', 'description' => 'Character set for this language.'));
00207 $array[] = array('tag' => 'param', 'type' => 'complete', 'level' => 3, 'attributes' => array('name' => 'text_direction', 'type' => 'text', 'default' => $this->text_direction, 'label' => 'Text Direction', 'description' => 'left-to-right or light-to-left'));
00208 $array[] = array('tag' => 'param', 'type' => 'complete', 'level' => 3, 'attributes' => array('name' => 'date_format', 'type' => 'text', 'default' => $this->date_format, 'label' => 'Date Format', 'description' => 'Date format for strftime() (eg. %A, %d %B %Y)'));
00209 $array[] = array('tag' => 'param', 'type' => 'complete', 'level' => 3, 'attributes' => array('name' => 'plural_form', 'type' => 'text', 'default' => htmlentities($this->plural_form['expression']), 'label' => 'Plural Forms', 'description' => 'Plural Forms expression'));
00210 $array[] = array('tag' => 'params', 'type' => 'close', 'level' => 2);
00211 $array[] = array('tag' => 'locale', 'type' => 'open', 'level' => 2, 'attributes' => array('name' => $this->name, 'title' => $this->title, 'territory' => $this->territory, 'locale' => $this->locale, 'text_direction' => $this->text_direction, 'iso639' => $this->iso639, 'iso3166_2' => $this->iso3166_2, 'iso3166_3' => $this->iso3166_3, 'charset' => $this->charset));
00212 $array[] = array('tag' => 'plural_form', 'type' => 'complete', 'level' => 3, 'attributes' => array('nplurals' => $this->plural_form['nplurals'] , 'plural' => htmlentities($this->plural_form['plural']), 'expression' => htmlentities($this->plural_form['expression'])));
00213 $array[] = array('tag' => 'date_format', 'type' => 'complete', 'level' => 3, 'value' => $this->date_format);
00214 $array[] = array('tag' => 'codesets', 'type' => 'open', 'level' => 3);
00215 foreach ($this->codesets as $charset) $array[] = array('tag' => 'charset', 'type' => 'complete', 'level' => 4, 'value' => $charset);
00216 $array[] = array('tag' => 'codesets', 'type' => 'close', 'level' => 3);
00217 foreach ($this->days as $name => $day) $days[$name] = $day;
00218 $array[] = array('tag' => 'days', 'type' => 'complete', 'level' => 3, 'attributes' => $days);
00219 foreach ($this->months as $name => $month) $months[$name] = $month;
00220 $array[] = array('tag' => 'months', 'type' => 'complete', 'level' => 3, 'attributes' => $months);
00221 $array[] = array('tag' => 'locale', 'type' => 'close', 'level' => 2);
00222 $array[] = array('tag' => 'extinstall', 'type' => 'close', 'level' => 1);
00223
00224 $xml = "<?xml version=\"1.0\" encoding=\"$this->charset\"?>\n";
00225 if ((!empty($array)) AND (is_array($array))) {
00226 foreach ($array as $key => $value) {
00227 switch ($value["type"]) {
00228 case "open":
00229 $xml .= str_repeat("\t", $value["level"] - 1);
00230 $xml .= "<" . $value["tag"];
00231 if (isset($value["attributes"])) {
00232 foreach ($value["attributes"] as $k => $v) {
00233 $xml .= sprintf(' %s="%s"', $k, $v);
00234 }
00235 }
00236 $xml .= ">\n";
00237 break;
00238 case "complete":
00239 $xml .= str_repeat("\t", $value["level"] - 1);
00240 $xml .= "<" . $value["tag"];
00241 if (isset($value["attributes"])) {
00242 foreach ($value["attributes"] as $k => $v) {
00243 $xml .= sprintf(' %s="%s"', $k, $v);
00244 }
00245 }
00246 $xml .= ">";
00247 $xml .= isset($value['value']) ? $value['value'] : false;
00248 $xml .= "</" . $value["tag"] . ">\n";
00249 break;
00250 case "close":
00251 $xml .= str_repeat("\t", $value["level"] - 1);
00252 $xml .= "</" . $value["tag"] . ">\n";
00253 break;
00254 default:
00255 break;
00256 }
00257 }
00258 }
00259 return $xml;
00260 }
00261
00262 private function getLocale ($iso639) {
00263 try {
00264 $handler = aliroLanguageExtended::loadLocales();
00265 foreach ($handler->getXML('locale') as $locale) if ($iso639 == (string) $locale['iso639']) {
00266 return aliroLanguageExtended::extractOneLocale($locale);
00267 }
00268 }
00269 catch (aliroXMLException $exception) {
00270 echo $exception->getMessage();
00271 die('xml error');
00272 }
00273 }
00274
00275 private static function extractOneLocale ($locale) {
00276 $defaults = aliroXML::attribArray($locale);
00277 $defaults['days'] = aliroXML::attribArray($locale->days);
00278 $defaults['months'] = aliroXML::attribArray($locale->months);
00279 $defaults['plural_form'] = aliroXML::attribArray($locale->plural_form);
00280 $defaults['codesets'] = aliroXML::elementArray($locale->codesets->charset);
00281 return $defaults;
00282 }
00283
00284 private static function loadLocales () {
00285 $xmlhandler = new aliroXML();
00286 $file = criticalInfo::getInstance()->class_base.'/language/locales.xml';
00287 $xmlhandler->loadFile($file);
00288 return $xmlhandler;
00289 }
00290
00291
00292
00293 public function getLanguages() {
00294 $path = criticalInfo::getInstance()->absolute_path.'/language/';
00295 $alldir = new aliroDirectory($path);
00296 $langs = array();
00297 foreach ($alldir->listAll('dir', false, true) as $dir) {
00298 $langdir = new aliroDirectory($dir);
00299 foreach ($langdir->listFiles ('.xml$') as $xml) {
00300 if (substr($xml, 0, -4) != 'locales') {
00301 $lobj = new aliroLanguageBasic(substr($xml, 0, -4), $path);
00302 $langs[$lobj->name] = $lobj;
00303 }
00304 }
00305 }
00306 return $langs;
00307 }
00308
00309 public function getLocales () {
00310
00311 $cache = new aliroCache('aliroLanguage');
00312 $result = $cache->get('getLocales');
00313 if (is_array($result) AND sha1_file(_ALIRO_ABSOLUTE_PATH.'/language/locales.xml') == $result['sha1_file']) return $result;
00314 $result = array('sha1_file' => sha1_file(_ALIRO_ABSOLUTE_PATH.'/language/locales.xml'));
00315 try {
00316 $handler = aliroLanguageExtended::loadLocales();
00317 foreach ($handler->getXML('locale') as $locale) {
00318 $iso639 = (string) $locale['iso639'];
00319 $locarray = aliroLanguageExtended::extractOneLocale($locale);
00320
00321
00322 $result['locales'][$iso639] = $locarray;
00323 $result['languages'][$iso639] = $locarray['title'];
00324 $territories = array();
00325 foreach ($locale->territories->territory as $territory) {
00326 $attribs = aliroXML::attribArray($territory);
00327 $attribs['territory'] = (string) $territory;
00328 $territories[] = $attribs;
00329 }
00330 $result['territories'][$iso639] = $territories;
00331 $result['codesets'][$iso639] = $locarray['codesets'];
00332 $result['directions'][$iso639] = $locarray['text_direction'];
00333 $result['plural_forms'][$iso639] = $locarray['plural_form']['expression'];
00334 $result['dateformats'][$iso639] = (string)$locale->date_format;
00335 }
00336 }
00337 catch (aliroXMLException $exception) {
00338 echo $exception->getMessage();
00339 die('locales.xml error');
00340 }
00341 $cache->save($result);
00342 return $result;
00343 }
00344
00345 public function renderNewlanguage ($renderer) {
00346 $locales = $this->getlocales();
00347 $renderer->addvar('language', $this);
00348 $renderer->addvar('locales', $locales['locales']);
00349 $renderer->addvar('territories', $locales['territories'] );
00350 $renderer->addvar('codesets', $locales['codesets']);
00351 $renderer->addvar('dateformats', $locales['dateformats']);
00352 $renderer->addvar('directions', $locales['directions']);
00353 $renderer->addvar('plural_forms', $locales['plural_forms']);
00354 }
00355
00356 public static function oldGetLocales() {
00357 $xmlfile = criticalInfo::getInstance()->absolute_path.'/language/locales.xml';
00358 $p = xml_parser_create();
00359 xml_parser_set_option($p, XML_OPTION_CASE_FOLDING, 0);
00360 xml_parser_set_option($p, XML_OPTION_SKIP_WHITE, 1);
00361 xml_parse_into_struct($p, implode("", file($xmlfile)), $values);
00362 xml_parser_free($p);
00363 $locales = array();
00364 foreach($values as $key => $value) {
00365 switch ($value['tag']) {
00366 case 'locale':
00367 if ($value['type'] == 'open') {
00368 $iso639 = $value['attributes']['iso639'];
00369 $language[$iso639] = $value['attributes']['title'];
00370 $locale[$iso639] = $value['attributes'];
00371 $directions[$iso639] = $value['attributes']['text_direction'];
00372 }
00373 break;
00374 case 'territory':
00375 $t['iso3166_2'] = $value['attributes']['iso3166_2'];
00376 $t['iso3166_3'] = $value['attributes']['iso3166_3'];
00377 $t['territory'] = $value['value'];
00378 $territories[$iso639][] = $t;
00379 break;
00380 case 'charset':
00381 $locale[$iso639]['codesets'][] = $codesets[$iso639][] = $value['value'];
00382 break;
00383 case 'date_format':
00384 $locale[$iso639]['dateformats'] = $dateformats[$iso639] = $value['value'];
00385 break;
00386 case 'days':
00387 $locale[$iso639]['days'] = $value['attributes'];
00388 break;
00389 case 'months':
00390 $locale[$iso639]['months'] = $value['attributes'];
00391 break;
00392 case 'plural_form':
00393 $exp = '';
00394 if (!empty($value['attributes']['expression'])) {
00395 $locale[$iso639]['plural_form'] = $value['attributes'];
00396 $plural_forms[$iso639] = $value['attributes']['expression'];
00397 }
00398 break;
00399 }
00400 }
00401 $locales['locales'] = $locale;
00402 $locales['languages'] = $language;
00403 $locales['territories'] = $territories;
00404 $locales['codesets'] = $codesets;
00405 $locales['dateformats'] = $dateformats;
00406 $locales['directions'] = $directions;
00407 $locales['plural_forms'] = $plural_forms;
00408 return $locales;
00409 }
00410
00411
00412 }