/** * Returns collection of all javascript translations data for requested language * * This is a javascript special function! * The data will be preseted to be included as javascript on client side! * * NOTE: This function is called from release.php cli script. In this case no * tine 2.0 core initialisation took place beforehand * * @param Zend_Locale|string $_locale * @return string javascript */ public static function getJsTranslations($_locale, $_appName = 'all') { $locale = $_locale instanceof Zend_Locale ? $_locale : new Zend_Locale($_locale); $localeString = (string) $_locale; $availableTranslations = self::getAvailableTranslations(); $info = isset($availableTranslations[$localeString]) || array_key_exists($localeString, $availableTranslations) ? $availableTranslations[$localeString] : array('locale' => $localeString); $baseDir = (isset($info['path']) || array_key_exists('path', $info) ? dirname($info['path']) . '/..' : dirname(__FILE__)) . '/..'; $defaultDir = dirname(__FILE__) . "/.."; $genericTranslationFile = "{$baseDir}/Tinebase/js/Locale/static/generic-{$localeString}.js"; $genericTranslationFile = is_readable($genericTranslationFile) ? $genericTranslationFile : "{$defaultDir}/Tinebase/js/Locale/static/generic-{$localeString}.js"; $extjsTranslationFile = "{$baseDir}/library/ExtJS/src/locale/ext-lang-{$localeString}.js"; $extjsTranslationFile = is_readable($extjsTranslationFile) ? $extjsTranslationFile : "{$defaultDir}/library/ExtJS/src/locale/ext-lang-{$localeString}.js"; if (!is_readable($extjsTranslationFile)) { // trying language as fallback if lang_region file can not be found, @see 0008242: Turkish does not work / throws an error $language = $locale->getLanguage(); $extjsTranslationFile = "{$baseDir}/library/ExtJS/src/locale/ext-lang-{$language}.js"; $extjsTranslationFile = is_readable($extjsTranslationFile) ? $extjsTranslationFile : "{$defaultDir}/library/ExtJS/src/locale/ext-lang-{$language}.js"; } $tine20TranslationFiles = self::getPoTranslationFiles($info); $allTranslationFiles = array_merge(array($genericTranslationFile, $extjsTranslationFile), $tine20TranslationFiles); $jsTranslations = NULL; if (Tinebase_Core::get(Tinebase_Core::CACHE) && $_appName == 'all') { // setup cache (saves about 20% @2010/01/28) $cache = new Zend_Cache_Frontend_File(array('master_files' => $allTranslationFiles)); $cache->setBackend(Tinebase_Core::get(Tinebase_Core::CACHE)->getBackend()); $cacheId = __CLASS__ . "_" . __FUNCTION__ . "_{$localeString}"; $jsTranslations = $cache->load($cacheId); } if (!$jsTranslations) { $jsTranslations = ""; if (in_array($_appName, array('Tinebase', 'all'))) { $jsTranslations .= "/************************** generic translations **************************/ \n"; $jsTranslations .= file_get_contents($genericTranslationFile); $jsTranslations .= "/*************************** extjs translations ***************************/ \n"; if (file_exists($extjsTranslationFile)) { $jsTranslations .= file_get_contents($extjsTranslationFile); } else { $jsTranslations .= "console.error('Translation Error: extjs changed their lang file name again ;-(');"; } } $poFiles = self::getPoTranslationFiles($info); foreach ($poFiles as $appName => $poPath) { if ($_appName != 'all' && $_appName != $appName) { continue; } $poObject = self::po2jsObject($poPath); //if (! json_decode($poObject)) { // $jsTranslations .= "console.err('tanslations for application $appName are broken');"; //} else { $jsTranslations .= "/********************** tine translations of {$appName}**********************/ \n"; $jsTranslations .= "Locale.Gettext.prototype._msgs['./LC_MESSAGES/{$appName}'] = new Locale.Gettext.PO({$poObject}); \n"; //} } if (isset($cache)) { $cache->save($jsTranslations, $cacheId); } } return $jsTranslations; }
/** * check if js or css files have changed and return all js/css as one big file or return "HTTP/1.0 304 Not Modified" if files don't have changed * * @param string $_fileType * @param array $filesToWatch */ protected function _deliverChangedFiles($_fileType, $filesToWatch = null) { // close session to allow other requests Tinebase_Session::writeClose(true); $config = Tinebase_Config::getInstance(); $cacheId = null; $clientETag = null; $ifModifiedSince = null; if (isset($_SERVER['If_None_Match'])) { $clientETag = trim($_SERVER['If_None_Match'], '"'); $ifModifiedSince = trim($_SERVER['If_Modified_Since'], '"'); } elseif (isset($_SERVER['HTTP_IF_NONE_MATCH'])) { $clientETag = trim($_SERVER['HTTP_IF_NONE_MATCH'], '"'); $ifModifiedSince = trim($_SERVER['HTTP_IF_MODIFIED_SINCE'], '"'); } $filesToWatch = $filesToWatch ? $filesToWatch : $this->_getFilesToWatch($_fileType); if ($_fileType == 'js' && TINE20_BUILDTYPE != 'DEVELOPMENT') { $customJSFiles = Tinebase_Config::getInstance()->get(Tinebase_Config::FAT_CLIENT_CUSTOM_JS); if (!empty($customJSFiles)) { $filesToWatch = array_merge($filesToWatch, (array) $customJSFiles); } } $lastModified = $this->_getLastModified($filesToWatch); // use last modified time also $serverETag = hash('sha1', implode('', $filesToWatch) . $lastModified); $cache = new Zend_Cache_Frontend_File(array('master_files' => $filesToWatch)); $cache->setBackend(Tinebase_Core::get(Tinebase_Core::CACHE)->getBackend()); if ($clientETag && $ifModifiedSince) { $cacheId = __CLASS__ . "_" . __FUNCTION__ . hash('sha1', $clientETag . $ifModifiedSince); } // cache for 60 seconds $maxAge = 60; header('Cache-Control: private, max-age=' . $maxAge); header("Expires: " . gmdate('D, d M Y H:i:s', Tinebase_DateTime::now()->addSecond($maxAge)->getTimestamp()) . " GMT"); // overwrite Pragma header from session header("Pragma: cache"); // if the cache id is still valid, the files don't have changed on disk if ($clientETag == $serverETag && $cache->test($cacheId)) { header("Last-Modified: " . $ifModifiedSince); header("HTTP/1.0 304 Not Modified"); header('Content-Length: 0'); } else { // get new cacheId $cacheId = __CLASS__ . "_" . __FUNCTION__ . hash('sha1', $serverETag . $lastModified); // do we need to update the cache? maybe the client did not send an etag if (!$cache->test($cacheId)) { $cache->save(TINE20_BUILDTYPE, $cacheId, array(), null); } header("Last-Modified: " . $lastModified); header('Content-Type: ' . ($_fileType == 'css' ? 'text/css' : 'application/javascript')); header('Etag: "' . $serverETag . '"'); flush(); // send files to client foreach ($filesToWatch as $file) { readfile($file); } } }
/** * get JSON from cache or new instance * * @param array $classes for Zend_Cache_Frontend_File * @return Zend_Json_Server */ protected static function _getServer($classes = null) { // setup cache if available if (is_array($classes) && Tinebase_Core::getCache()) { $masterFiles = array(); $dirname = dirname(__FILE__) . '/../../'; foreach ($classes as $class => $namespace) { $masterFiles[] = $dirname . str_replace('_', '/', $class) . '.php'; } try { $cache = new Zend_Cache_Frontend_File(array('master_files' => $masterFiles, 'lifetime' => null, 'automatic_serialization' => true, 'automatic_cleaning_factor' => 0, 'write_control' => false, 'logging' => Tinebase_Core::isLogLevel(Zend_Log::DEBUG), 'logger' => Tinebase_Core::getLogger())); $cache->setBackend(Tinebase_Core::getCache()->getBackend()); $cacheId = Tinebase_Helper::convertCacheId('_handle_' . sha1(Zend_Json_Encoder::encode($classes)) . '_' . (self::userIsRegistered() ? Tinebase_Core::getUser()->getId() : 'anon')); $server = $cache->load($cacheId); if ($server instanceof Zend_Json_Server) { return $server; } } catch (Zend_Cache_Exception $zce) { if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) { Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . " Failed to create cache. Exception: \n" . $zce); } } } $server = new Zend_Json_Server(); $server->setAutoEmitResponse(false); $server->setAutoHandleExceptions(false); if (is_array($classes)) { foreach ($classes as $class => $namespace) { try { $server->setClass($class, $namespace); } catch (Exception $e) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " Failed to add JSON API for '{$class}' => '{$namespace}' Exception: \n" . $e); } } } } if (self::userIsRegistered()) { $definitions = self::_getModelConfigMethods(); $server->loadFunctions($definitions); } if (isset($cache)) { $cache->save($server, $cacheId, array(), null); } return $server; }