_page = $page; parent::__construct($page); } private function _getBasePath() { return Prado::getPathOfNamespace('Web') . DIRECTORY_SEPARATOR; } private function _getBasePaths($urls) { $basePath = $this->_getBasePath(); return array_map( function($path) use($basePath) { return $basePath . DIRECTORY_SEPARATOR . $path; }, $urls ); } private function _getCachePath($subdir = 'assets') { $cachePath = $this->Application->RuntimePath . DIRECTORY_SEPARATOR . $subdir; if (!is_dir($cachePath)) { if (file_exists($cachePath)) { throw new TIOException( 'Client script manager cache path "' . $cachePath . ' "exists and is not a directory' ); } else { mkdir($cachePath); } } return $cachePath; } private function _getCacheFilePath($path, $type) { return $this->_getCachePath($type) . DIRECTORY_SEPARATOR . $path; } private function _getFileCollectionCacheKey($files) { sort($files); return md5(implode(PHP_EOL, $files)); } private function _getFileCollectionMTime($files) { return max(array_map('filemtime', $files)); } private function _getRenderedAssetsStoreKey($type) { $template = $this->_page->Master; if (!$template instanceof Layout) { throw new TNotSupportedException( 'Compiled assets may only be used within Layout master class controls' ); } return 'Rendered' . $type . '.' . $template->generateViewID(); } private function _getRenderedScriptsStoreKey() { return $this->_getRenderedAssetsStoreKey('Scripts'); } private function _getRenderedSheetsStoreKey() { return $this->_getRenderedAssetsStoreKey('Sheets'); } private function _getCache() { $cache = $this->Application->Cache; if (!$cache) { throw new TNotSupportedException( 'Compiled assets require cache to be configured' ); } return $cache; } // Scripts private $_renderedScriptsInitialized = FALSE; private function _getRenderedScripts() { $sessionKey = $this->_getRenderedScriptsStoreKey(); if ($this->_page->IsCallBack || $this->_renderedScriptsInitialized) { return $this->_getCache()->get($sessionKey) ?: []; } else { $this->_getCache()->delete($sessionKey); $this->_renderedScriptsInitialized = TRUE; return []; } } private function _appendRenderedScripts(array $newScripts, $compiledFileKey) { $scripts = $this->_getRenderedScripts(); if (!isset($scripts[$compiledFileKey])) { $scripts[$compiledFileKey] = []; } $scripts[$compiledFileKey] = array_unique( array_merge( $scripts[$compiledFileKey], $newScripts ) ); $this->_getCache()->set( $this->_getRenderedScriptsStoreKey(), $scripts ); } private function _compileFiles($files) { foreach ($files as $file) { $this->markScriptFileAsRendered($file); } $paths = $this->_getBasePaths($files); $cacheKey = $this->_getFileCollectionCacheKey($paths); $cacheFile = $this->_getCacheFilePath($cacheKey . '.js', 'scripts'); $this->_appendRenderedScripts($files, $cacheFile); if (!file_exists($cacheFile) || (filemtime($cacheFile) < $this->_getFileCollectionMTime($paths))) { $scriptContent = implode( PHP_EOL, array_map( function($path) { return trim( TJavaScript::JSMin( file_get_contents($path) ) ); }, $paths ) ); file_put_contents($cacheFile, $scriptContent); } return $this->Application->AssetManager->publishFilePath($cacheFile); } private function _determineLocalScriptFiles($files) { $basePath = $this->_getBasePath(); return array_filter( $files, function($file) use($basePath) { return file_exists($basePath . DIRECTORY_SEPARATOR . $file); } ); } private function _renderLocalScriptFiles($writer, $localFiles) { if ($localFiles) { $assetPath = $this->_compileFiles($localFiles); $writer->write(TJavascript::renderScriptFile($assetPath)); } } private function _renderExternalScriptFiles($writer, $externalFiles) { if ($externalFiles) { foreach ($externalFiles as $file) { $this->markScriptFileAsRendered($file); $this->_appendRenderedScripts([$file], $file); } parent::renderScriptFiles($writer, $externalFiles); } } public function renderScriptFiles($writer, Array $files) { if ($this->getApplication()->getMode() !== TApplicationMode::Debug) { if ($files) { $localFiles = $this->_determineLocalScriptFiles($files); $this->_renderLocalScriptFiles($writer, $localFiles); $externalFiles = array_diff($files, $localFiles); $this->_renderExternalScriptFiles($writer, $externalFiles); } } else { parent::renderScriptFiles($writer, $files); } } private function _getRenderedScriptUrl($registeredScript) { $renderedScripts = $this->_getRenderedScripts(); foreach ($renderedScripts as $compiledFile => $scripts) { if (in_array($registeredScript, $scripts)) { if (file_exists($compiledFile)) { return $this->Application->AssetManager->getPublishedUrl( $compiledFile ); } else { return $registeredScript; } } } return FALSE; } public function getScriptUrls() { if ($this->getApplication()->getMode() !== TApplicationMode::Debug) { $registeredScripts = array_unique( array_merge( $this->_scripts, $this->_headScripts ) ); $scriptUrls = []; $newScripts = []; foreach ($registeredScripts as $registeredScript) { $renderedScriptUrl = $this->_getRenderedScriptUrl( $registeredScript ); if ($renderedScriptUrl) { $scriptUrls[] = $renderedScriptUrl; } else { $newScripts[] = $registeredScript; } } $newLocalScripts = $this->_determineLocalScriptFiles($newScripts); $newRemoteScripts = array_diff($newScripts, $newLocalScripts); if ($newLocalScripts) { $scriptUrls[] = $this->_compileFiles($newLocalScripts); } $scriptUrls = array_values( array_unique(array_merge($scriptUrls, $newRemoteScripts)) ); return $scriptUrls; } else { return parent::getScriptUrls(); } } private $_scripts = []; private $_headScripts = []; public function registerScriptFile($key, $file) { $this->_scripts[$key] = $file; return parent::registerScriptFile($key, $file); } public function registerHeadScriptFile($key, $file) { $this->_headScripts[$key] = $file; return parent::registerHeadScriptFile($key, $file); } } ?>