/** * 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); } } }