*/ // must be run within Dokuwiki if(!defined('DOKU_INC')) die(); /** * Class helper_plugin_translation */ class helper_plugin_translation extends DokuWiki_Plugin { var $translations = array(); var $translationNs = ''; var $defaultlang = ''; var $LN = array(); // hold native names var $opts = array(); // display options /** * Initialize */ function __construct() { global $conf; require_once(DOKU_INC . 'inc/pageutils.php'); require_once(DOKU_INC . 'inc/utf8.php'); $this->loadTranslationNamespaces(); // load language names $this->LN = confToHash(dirname(__FILE__) . '/lang/langnames.txt'); // display options $this->opts = $this->getConf('display'); $this->opts = explode(',', $this->opts); $this->opts = array_map('trim', $this->opts); $this->opts = array_fill_keys($this->opts, true); // get default translation if(!$conf['lang_before_translation']) { $dfl = $conf['lang']; } else { $dfl = $conf['lang_before_translation']; } if(in_array($dfl, $this->translations)) { $this->defaultlang = $dfl; } else { $this->defaultlang = ''; array_unshift($this->translations, ''); } $this->translationNs = cleanID($this->getConf('translationns')); if($this->translationNs) $this->translationNs .= ':'; } /** * Parse 'translations'-setting into $this->translations */ public function loadTranslationNamespaces() { // load wanted translation into array $this->translations = strtolower(str_replace(',', ' ', $this->getConf('translations'))); $this->translations = array_unique(array_filter(explode(' ', $this->translations))); sort($this->translations); } /** * Check if the given ID is a translation and return the language code. * * @param string $id * @return string */ function getLangPart($id) { list($lng) = $this->getTransParts($id); return $lng; } /** * Check if the given ID is a translation and return the language code and * the id part. * * @param string $id * @return array */ function getTransParts($id) { $rx = '/^' . $this->translationNs . '(' . join('|', $this->translations) . '):(.*)/'; if(preg_match($rx, $id, $match)) { return array($match[1], $match[2]); } return array('', $id); } /** * Returns the browser language if it matches with one of the configured * languages */ function getBrowserLang() { global $conf; $langs = $this->translations; if (!in_array($conf['lang'], $langs)) { $langs[] = $conf['lang']; } $rx = '/(^|,|:|;|-)(' . join('|', $langs) . ')($|,|:|;|-)/i'; if(preg_match($rx, $_SERVER['HTTP_ACCEPT_LANGUAGE'], $match)) { return strtolower($match[2]); } return false; } /** * Returns the ID and name to the wanted translation, empty * $lng is default lang * * @param string $lng * @param string $idpart * @return array */ function buildTransID($lng, $idpart) { if($lng && in_array($lng, $this->translations)) { $link = ':' . $this->translationNs . $lng . ':' . $idpart; $name = $lng; } else { $link = ':' . $this->translationNs . $idpart; $name = $this->realLC(''); } return array($link, $name); } /** * Returns the real language code, even when an empty one is given * (eg. resolves th default language) * * @param string $lc * @return string */ function realLC($lc) { global $conf; if($lc) { return $lc; } elseif(!$conf['lang_before_translation']) { return $conf['lang']; } else { return $conf['lang_before_translation']; } } /** * Check if current ID should be translated and any GUI * should be shown * * @param string $id * @param bool $checkact * @return bool */ function istranslatable($id, $checkact = true) { global $ACT; if($checkact && $ACT != 'show') return false; if($this->translationNs && strpos($id, $this->translationNs) !== 0) return false; $skiptrans = trim($this->getConf('skiptrans')); if($skiptrans && preg_match('/' . $skiptrans . '/ui', ':' . $id)) return false; $meta = p_get_metadata($id); if(!empty($meta['plugin']['translation']['notrans'])) return false; return true; } /** * Return the (localized) about link */ function showAbout() { global $ID; $curlc = $this->getLangPart($ID); $about = $this->getConf('about'); if($this->getConf('localabout')) { list(/* $lc */, $idpart) = $this->getTransParts($about); list($about, /* $name */) = $this->buildTransID($curlc, $idpart); $about = cleanID($about); } $out = ''; $out .= ''; $out .= html_wikilink($about, '?'); $out .= ''; return $out; } /** * Returns a list of (lc => link) for all existing translations of a page * * @param $id * @return array */ function getAvailableTranslations($id) { $result = array(); list($lc, $idpart) = $this->getTransParts($id); foreach($this->translations as $t) { if($t == $lc) continue; //skip self list($link, $name) = $this->buildTransID($t, $idpart); if(page_exists($link)) { $result[$name] = $link; } } return $result; } /** * Creates an UI for linking to the available and configured translations * * Can be called from the template or via the ~~TRANS~~ syntax component. */ public function showTranslations() { global $conf; global $INFO; if(!$this->istranslatable($INFO['id'])) return ''; $this->checkage(); list($lc, $idpart) = $this->getTransParts($INFO['id']); $lang = $this->realLC($lc); $out = '