Example #1
0
 private function toXLIFF($lang, $extension, &$xliff)
 {
     $default = array('about' => array(), 'dictionary' => $this->_tm->defaultDictionary($extension), 'transliterations' => array());
     $warnings = array_shift($default['dictionary']);
     $translation = $this->_tm->get($lang, $extension);
     if (empty($translation)) {
         $translation = array('about' => array('name' => $lang), 'dictionary' => array(), 'transliterations' => array());
         // Try to find language name in other translations for selected language
         $others = $this->_tm->listExtensions($lang);
         foreach ($others as $t_ext) {
             $t_trans = $this->_tm->get($lang, $t_ext);
             if (!empty($t_trans['about']['name'])) {
                 $translation['about']['name'] = $t_trans['about']['name'];
                 break;
             }
         }
     }
     $file = new XMLElement('file');
     $file->setAttribute('original', basename(TranslationManager::filePath($lang, $extension)));
     $file->setAttribute('source-language', 'en');
     $file->setAttribute('target-language', $lang);
     $file->setAttribute('datatype', 'x-symphony');
     $file->setAttribute('xml:space', 'preserve');
     if ($extension) {
         $file->setAttribute('product-name', $extension);
     }
     if (is_array($temp = $this->_Parent->ExtensionManager->about($extension))) {
         $file->setAttribute('product-version', $temp['version']);
     }
     // TODO: Make sure that date is specified in valid format (http://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html#date)?
     if ($translation['about']['release-date']) {
         $file->setAttribute('date', $translation['about']['release-date']);
     }
     if ($translation['about']['name']) {
         $file->setAttribute('category', $translation['about']['name']);
     }
     $header = new XMLElement('header');
     $tool = new XMLElement('tool');
     $tool->setAttribute('tool-id', 'tm');
     $tool->setAttribute('tool-name', 'Symphony - Translation Manager');
     $tool->setAttribute('tool-version', '1.0');
     $header->appendChild($tool);
     if (is_array($translation['about']['author'])) {
         $group = new XMLElement('phase-group');
         $appended = 0;
         if (is_string($translation['about']['author']['name'])) {
             $temp = $translation['about']['author'];
             $translation['about']['author'][$temp['name']] = $temp;
         }
         foreach ($translation['about']['author'] as $name => $author) {
             if (!$author['name']) {
                 continue;
             }
             $phase = new XMLElement('phase');
             $phase->setAttribute('phase-name', $author['name']);
             $phase->setAttribute('phase-process', 'translation');
             $phase->setAttribute('tool-id', 'tm');
             if ($author['release-date']) {
                 $phase->setAttribute('date', $author['release-date']);
             }
             if ($author['name']) {
                 $phase->setAttribute('contact-name', $author['name']);
             }
             if ($author['email']) {
                 $phase->setAttribute('contact-email', $author['email']);
             }
             if ($author['website']) {
                 $phase->setAttribute('company-name', $author['website']);
             }
             $group->appendChild($phase);
             $appended++;
         }
         if ($appended) {
             $header->appendChild($group);
         }
     }
     $body = new XMLElement('body');
     $group = new XMLElement('group');
     $group->setAttribute('resname', 'dictionary');
     $sklDictionary = array();
     $translated = array_intersect_key(array_filter($translation['dictionary'], 'trim'), $default['dictionary']);
     foreach ($translated as $k => $v) {
         $sklDictionary[$k] = md5($k);
         $unit = new XMLElement('trans-unit');
         $unit->setAttribute('id', $sklDictionary[$k]);
         $unit->appendChild(new XMLElement('source', General::sanitize($k)));
         $unit->appendChild(new XMLElement('target', General::sanitize($v), array('state' => 'translated')));
         $group->appendChild($unit);
     }
     $missing = array_diff_key($default['dictionary'], $translated);
     foreach ($missing as $k => $v) {
         $sklDictionary[$k] = md5($k);
         $unit = new XMLElement('trans-unit');
         $unit->setAttribute('id', $sklDictionary[$k]);
         $unit->appendChild(new XMLElement('source', General::sanitize($k)));
         $unit->appendChild(new XMLElement('target', '', array('state' => 'new')));
         $group->appendChild($unit);
     }
     $obsolete = array_diff_key($translation['dictionary'], $default['dictionary']);
     foreach ($obsolete as $k => $v) {
         $sklDictionary[$k] = md5($k);
         $unit = new XMLElement('trans-unit');
         $unit->setAttribute('id', $sklDictionary[$k]);
         $unit->appendChild(new XMLElement('source', General::sanitize($k)));
         $unit->appendChild(new XMLElement('target', General::sanitize($v), array('state' => 'x-obsolete')));
         $group->appendChild($unit);
     }
     $body->appendChild($group);
     $group = new XMLElement('group');
     $group->setAttribute('resname', 'transliterations');
     $sklTransliterations = array();
     if (is_array($translation['transliterations']) && !empty($translation['transliterations'])) {
         foreach ($translation['transliterations'] as $k => $v) {
             $sklTransliterations[$k] = md5($k);
             $unit = new XMLElement('trans-unit');
             $unit->setAttribute('id', $sklTransliterations[$k]);
             $unit->appendChild(new XMLElement('source', General::sanitize($k)));
             $unit->appendChild(new XMLElement('target', General::sanitize($v), array('state' => 'translated')));
             $group->appendChild($unit);
         }
     } else {
         if ($extension == 'symphony' || empty($extension)) {
             foreach (TranslationManager::defaultTransliterations() as $k => $v) {
                 $sklTransliterations[$k] = md5($k);
                 $unit = new XMLElement('trans-unit');
                 $unit->setAttribute('id', $sklTransliterations[$k]);
                 $unit->appendChild(new XMLElement('source', General::sanitize($k)));
                 $unit->appendChild(new XMLElement('target', General::sanitize($v), array('state' => 'new')));
                 $group->appendChild($unit);
             }
         }
     }
     $body->appendChild($group);
     // Generate skeleton
     $skl = new XMLElement('skl');
     $translation['dictionary'] = $sklDictionary;
     $translation['transliterations'] = $sklTransliterations;
     $skl->appendChild(new XMLElement('internal-file', '<![CDATA[' . TranslationManager::toPHP($translation) . ']]>', array('form' => 'application/x-php')));
     $header->appendChild($skl);
     $file->appendChild($header);
     $file->appendChild($body);
     $xliff->appendChild($file);
 }
 function exportZIP($lang)
 {
     require_once TOOLKIT . '/class.archivezip.php';
     $zip = new ArchiveZip();
     foreach ($this->_tm->listExtensions($lang) as $extension) {
         $path = TranslationManager::filePath($lang, $extension);
         if (!$zip->addFromFile($path, str_replace(DOCROOT, '', $path))) {
             $this->pageAlert(__('Cannot add <code>%s</code> to ZIP file. Please check file permissions.', array($path)), Alert::ERROR);
             return false;
         }
     }
     $data = $zip->save();
     if (!$data) {
         $this->pageAlert(__('Cannot generate ZIP data.'), Alert::ERROR);
         return false;
     }
     header('Content-Type: application/zip; charset=utf-8');
     header('Content-Disposition: attachment; filename="symphony-language-' . $lang . '.zip"');
     header("Content-Description: File Transfer");
     header("Cache-Control: no-cache, must-revalidate");
     header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
     echo $data;
     exit;
 }
    function view()
    {
        $lang = $this->_context[0];
        $extension = $this->_context[1];
        $isSymphony = empty($extension) || $extension == 'symphony';
        if (strlen($lang) < 1) {
            $this->setPageType('form');
            $this->pageAlert(__('Language code is required.'), Alert::ERROR);
            return;
        }
        $default = array('about' => array(), 'dictionary' => $this->_tm->defaultDictionary($extension), 'transliterations' => array());
        $warnings = array_shift($default['dictionary']);
        $translation = $this->_tm->get($lang, $extension);
        if (empty($translation)) {
            $translation = array('about' => array('name' => $lang), 'dictionary' => array(), 'transliterations' => array());
            // Try to find language name in other translations for selected language
            $others = $this->_tm->listExtensions($lang);
            foreach ($others as $t_ext) {
                $t_trans = $this->_tm->get($lang, $t_ext);
                if (!empty($t_trans['about']['name'])) {
                    $translation['about']['name'] = $t_trans['about']['name'];
                    break;
                }
            }
        }
        $dictionary = array();
        $translated = array_intersect_key(array_filter($translation['dictionary'], 'trim'), $default['dictionary']);
        $missing = array_diff_key($default['dictionary'], $translated);
        $obsolete = array_diff_key($translation['dictionary'], $default['dictionary']);
        if (is_array($translated) && count($translated) > 0) {
            $dictionary['%%%%%%TRANSLATED%%%%%%'] = '%%%%%%TRANSLATED%%%%%%';
            $dictionary += $translated;
        }
        if (is_array($missing) && count($missing) > 0) {
            $dictionary['%%%%%%MISSING%%%%%%'] = '%%%%%%MISSING%%%%%%';
            $dictionary += array_fill_keys(array_keys($missing), false);
        }
        if (is_array($obsolete) && count($obsolete) > 0) {
            $dictionary['%%%%%%OBSOLETE%%%%%%'] = '%%%%%%OBSOLETE%%%%%%';
            $dictionary += $obsolete;
        }
        if ((!is_array($translation['transliterations']) || empty($translation['transliterations'])) && $isSymphony) {
            $translation['transliterations'] = TranslationManager::defaultTransliterations();
        }
        if ($isSymphony) {
            $name = 'Symphony';
        } else {
            $temp = $this->_Parent->ExtensionManager->about($extension);
            $name = $temp['name'];
        }
        $path = $isSymphony ? TranslationManager::filePath($lang, 'symphony') : TranslationManager::filePath($lang, $extension);
        $file = basename($path);
        $path = str_replace(DOCROOT, '', dirname($path));
        $php = '<' . "?php\n\n";
        $php .= <<<END
/*
\tThis is translation file for {$name}.
\tTo make it available for Symphony installation, rename it {$file} and upload to {$path}/ directory on server.
*/

END;
        $php .= '$about = ' . var_export($translation['about'], true) . ";\n\n";
        $php .= <<<END
/*
\tDictionary array contains translations of texts (labels, guidelines, titles, etc...) used by Symphony.

\tThere are 3 states of translations:
\t- Translated: already used by Symphony,
\t- Missing: there was no translation available at the time of generating this template file,
\t- Obsolete: translated text which is no longer used by Symphony and can be removed from translation file.

\tTo add missing translations, simply scroll down to part of array marked as "// MISSING"
\tand change each "false" value into something like "'New translation of original text'"
\t(notice single quotes around translated text! Text has to be wrapped either by them or by double quotes).
\tSo instead of something like:

\t\t'Original text' =>
\t\tfalse,

\tYou'll have something like:

\t\t'Original text' =>
\t\t'Tekst oryginaƂu',

\tYou should leave all parts of text which look like "%s" or "%1\$s" (usually there is "s" or "d" character there).
\tThey are placeholders for other text or HTML which will be put in their place when needed by Symphony.
\tYou can move them around inside translated text, but not remove them. For example:

\t\t'Original %s is here' =>
\t\t'Tu jest oryginalny %s'

\tPlaceholders with numbers inside them are used when there are more than one of them inside original text.
\tYou can switch their positions if needed, but do not change numbers into something else.
\tFor example text used in page titles looks like "Symphony - Language - English" and is generated with:

\t\t'%1\$s &ndash; %2\$s &ndash; %3\$s'

\tTo make titles look like "Language: English | Symphony" simply move placeholders around:

\t\t'%2\$s: %3\$s | %1\$s'
*/

END;
        $php .= '$dictionary = ' . str_replace(' => ', " =>\n  ", str_replace(",\n", ",\n\n", preg_replace('/\\n\\s+\'%%%%%%(TRANSLATED|MISSING|OBSOLETE)%%%%%%\'\\s+=>\\s+\'%%%%%%(\\1)%%%%%%\',\\n/', "\n// \\1\n", var_export($dictionary, true)))) . ";\n\n";
        $php .= <<<END
/*
\tTransliterations are used to generate handles of entry fields and filenames.
\tThey specify which characters (or bunch of characters) have to be changed, and what should be put into their place when entry or file is saved.
\tFor example:

\t\t'/_and_/' => '+',

\twill change every instance of "_and_" into "+", so:

\t\tme_and_family.jpg

\twill turn into:

\t\tme+family.jpg

\tPlease notice slashes at the beginning and end of original text. They are required there.
\tYou can change them into different character, but that character cannot be used inside original text or has to be escaped by backslash, like this:

\t\t'/original\\/path/' => 'new/path',

\tYou can use full syntax of regular expressions there too. Read more about it on: http://php.net/manual/en/regexp.reference.php

\tTransliterations are required only inside translations of Symphony. They are not needed for extensions.
*/

END;
        $php .= '$transliterations = ' . var_export($translation['transliterations'], true) . ";\n\n";
        $php .= '?>';
        if (!empty($php)) {
            header('Content-Type: application/x-php; charset=utf-8');
            header('Content-Disposition: attachment; filename="' . $extension . '-lang.' . $lang . '.php"');
            header("Content-Description: File Transfer");
            header("Cache-Control: no-cache, must-revalidate");
            header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
            echo trim($php);
            exit;
        }
    }
 public function remove($lang, $name = NULL)
 {
     if ($name === NULL) {
         if (!$this->remove($lang, 'symphony')) {
             return false;
         }
         foreach ($this->_Parent->ExtensionManager->listAll() as $extension => $about) {
             if (!$this->remove($lang, $extension)) {
                 return false;
             }
         }
         return true;
     }
     $file = TranslationManager::filePath($lang, $name);
     if (file_exists($file) && !General::deleteFile($file)) {
         return false;
     }
     return true;
 }