* @copyright Since 2007 PrestaShop SA and Contributors * @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0) */ namespace PrestaShop\PrestaShop\Adapter\Cache; use PrestaShop\PrestaShop\Adapter\Configuration; use PrestaShop\PrestaShop\Adapter\Tools; use PrestaShop\PrestaShop\Core\Configuration\DataConfigurationInterface; use PrestaShop\PrestaShop\Core\Foundation\Filesystem\FileSystem as PsFileSystem; use Symfony\Component\Filesystem\Exception\IOExceptionInterface; use Symfony\Component\Filesystem\Filesystem; /** * This class manages CCC features configuration for a Shop. */ class CombineCompressCacheConfiguration implements DataConfigurationInterface { /** * @var Configuration */ private $configuration; /** * @var Filesystem */ private $filesystem; /** * @var Tools */ private $tools; /** * @var string Absolute path to the theme directory */ private $themePath; /** * @var string Current active theme name */ private $themeName; public function __construct( Configuration $configuration, Filesystem $filesystem, Tools $tools, $themePath, $themeName ) { $this->configuration = $configuration; $this->filesystem = $filesystem; $this->tools = $tools; $this->themePath = $themePath; $this->themeName = $themeName; } /** * {@inheritdoc} */ public function getConfiguration() { return [ 'smart_cache_css' => $this->configuration->getBoolean('PS_CSS_THEME_CACHE'), 'smart_cache_js' => $this->configuration->getBoolean('PS_JS_THEME_CACHE'), 'apache_optimization' => $this->configuration->getBoolean('PS_HTACCESS_CACHE_CONTROL'), ]; } /** * {@inheritdoc} */ public function updateConfiguration(array $configuration) { $errors = []; if ($this->validateConfiguration($configuration)) { $this->updateCachesVersionsIfNeeded($configuration); if ($configuration['smart_cache_css'] || $configuration['smart_cache_js']) { // Manage JS & CSS Smart cache if (!$this->createThemeCacheFolder()) { $errors[] = [ 'key' => 'To use Smarty Cache, the directory %directorypath% must be writable.', 'domain' => 'Admin.Advparameters.Notification', 'parameters' => [ '%directorypath%' => $this->getThemeCacheFolder(), ], ]; } } // Manage Apache optimization $apacheError = $this->manageApacheOptimization((bool) $configuration['apache_optimization']); if (count($apacheError) > 0) { $errors[] = $apacheError; } } return $errors; } /** * {@inheritdoc} */ public function validateConfiguration(array $configuration) { return isset( $configuration['smart_cache_css'], $configuration['smart_cache_js'], $configuration['apache_optimization'] ); } /** * @return string Absolute path the the current active theme */ private function getThemeCacheFolder() { return $this->themePath . '/' . $this->themeName . '/cache/'; } /** * Creates Cache folder for the active theme. * * @return bool */ private function createThemeCacheFolder() { try { $folder = $this->getThemeCacheFolder(); $this->filesystem->mkdir($folder, PsFileSystem::DEFAULT_MODE_FOLDER); return true; } catch (IOExceptionInterface $e) { return false; } } /** * Update Cache version of assets if needed. * * @param array $configuration */ private function updateCachesVersionsIfNeeded(array $configuration) { $cacheCSS = $configuration['smart_cache_css']; $currentCacheCSS = $this->configuration->get('PS_CSS_THEME_CACHE'); $cacheJS = $configuration['smart_cache_js']; $currentCacheJS = $this->configuration->get('PS_JS_THEME_CACHE'); if ($cacheCSS !== $currentCacheCSS) { $cssCacheVersion = $this->configuration->get('PS_CCCCSS_VERSION') + 1; $this->configuration->set('PS_CCCCSS_VERSION', $cssCacheVersion); $this->configuration->set('PS_CSS_THEME_CACHE', $cacheCSS); } if ($cacheJS !== $currentCacheJS) { $jsCacheVersion = $this->configuration->get('PS_CCCJS_VERSION') + 1; $this->configuration->set('PS_CCCCSS_VERSION', $jsCacheVersion); $this->configuration->set('PS_JS_THEME_CACHE', $cacheJS); } } /** * Creates .htaccess if Apache optimization feature is enabled. * * @param bool $enabled * * @return array not empty in case of error */ private function manageApacheOptimization($enabled) { $errors = []; $isCurrentlyEnabled = (bool) $this->configuration->get('PS_HTACCESS_CACHE_CONTROL'); // feature activation if (false === $isCurrentlyEnabled && true === $enabled) { $this->configuration->set('PS_HTACCESS_CACHE_CONTROL', true); if (!$this->tools->generateHtaccess()) { $errors = [ 'key' => 'Before being able to use this tool, you need to:[1][2]Create a blank .htaccess in your root directory.[/2][2]Give it write permissions (CHMOD 666 on Unix system).[/2][/1]', 'domain' => 'Admin.Advparameters.Notification', 'parameters' => [ '[1]' => '', '[2]' => '
  • ', '[/2]' => '
  • ', ], ]; $this->configuration->set('PS_HTACCESS_CACHE_CONTROL', false); } } if (true === $isCurrentlyEnabled && false === $enabled) { $this->configuration->set('PS_HTACCESS_CACHE_CONTROL', false); $this->tools->generateHtaccess(); } return $errors; } }