123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\PageCache\Console\Command;
- use Magento\Framework\App\Config\ScopeConfigInterface;
- use Magento\Framework\Console\Cli;
- use Magento\Framework\Filesystem\DriverPool;
- use Magento\Framework\Filesystem\File\WriteFactory;
- use Magento\Framework\HTTP\PhpEnvironment\Request;
- use Magento\Framework\Serialize\Serializer\Json;
- use Magento\PageCache\Model\VclGeneratorInterfaceFactory;
- use Magento\PageCache\Model\Config;
- use Magento\PageCache\Model\Varnish\VclTemplateLocator;
- use Magento\Store\Model\ScopeInterface;
- use Symfony\Component\Console\Command\Command;
- use Symfony\Component\Console\Input\InputInterface;
- use Symfony\Component\Console\Input\InputOption;
- use Symfony\Component\Console\Output\OutputInterface;
- /**
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
- class GenerateVclCommand extends Command
- {
- /**
- * Access list option name
- */
- const ACCESS_LIST_OPTION = 'access-list';
- /**
- * Backend host option name
- */
- const BACKEND_HOST_OPTION = 'backend-host';
- /**
- * Backend port option name
- */
- const BACKEND_PORT_OPTION = 'backend-port';
- /**
- * Varnish version option name
- */
- const EXPORT_VERSION_OPTION = 'export-version';
- /**
- * Grace period option name
- */
- const GRACE_PERIOD_OPTION = 'grace-period';
- /**
- * Output file option name
- */
- const OUTPUT_FILE_OPTION = 'output-file';
- /**
- * @var \Magento\Framework\Filesystem\Directory\WriteFactory
- */
- private $writeFactory;
- /**
- * @var VclGeneratorInterfaceFactory
- */
- private $vclGeneratorFactory;
- /**
- * @var array
- */
- private $inputToVclMap = [
- self::ACCESS_LIST_OPTION => 'accessList',
- self::BACKEND_PORT_OPTION => 'backendPort',
- self::BACKEND_HOST_OPTION => 'backendHost',
- self::GRACE_PERIOD_OPTION => 'gracePeriod',
- ];
- /**
- * @var ScopeConfigInterface
- */
- private $scopeConfig;
- /**
- * @var Json
- */
- private $serializer;
- /**
- * @inheritdoc
- */
- protected function configure()
- {
- $this->setName('varnish:vcl:generate')
- ->setDescription('Generates Varnish VCL and echos it to the command line')
- ->setDefinition($this->getOptionList());
- }
- /**
- * @param VclGeneratorInterfaceFactory $vclGeneratorFactory
- * @param WriteFactory $writeFactory
- * @param ScopeConfigInterface $scopeConfig
- * @param Json $serializer
- */
- public function __construct(
- VclGeneratorInterfaceFactory $vclGeneratorFactory,
- WriteFactory $writeFactory,
- ScopeConfigInterface $scopeConfig,
- Json $serializer
- ) {
- parent::__construct();
- $this->writeFactory = $writeFactory;
- $this->vclGeneratorFactory = $vclGeneratorFactory;
- $this->scopeConfig = $scopeConfig;
- $this->serializer = $serializer;
- }
- /**
- * @inheritdoc
- */
- protected function execute(InputInterface $input, OutputInterface $output)
- {
- $errors = $this->validate($input);
- if ($errors) {
- foreach ($errors as $error) {
- $output->writeln('<error>'.$error.'</error>');
- return Cli::RETURN_FAILURE;
- }
- }
- try {
- $outputFile = $input->getOption(self::OUTPUT_FILE_OPTION);
- $varnishVersion = $input->getOption(self::EXPORT_VERSION_OPTION);
- $vclParameters = array_merge($this->inputToVclParameters($input), [
- 'sslOffloadedHeader' => $this->getSslOffloadedHeader(),
- 'designExceptions' => $this->getDesignExceptions(),
- ]);
- $vclGenerator = $this->vclGeneratorFactory->create($vclParameters);
- $vcl = $vclGenerator->generateVcl($varnishVersion);
- if ($outputFile) {
- $writer = $this->writeFactory->create($outputFile, DriverPool::FILE, 'w+');
- $writer->write($vcl);
- $writer->close();
- } else {
- $output->writeln($vcl);
- }
- return Cli::RETURN_SUCCESS;
- } catch (\Exception $e) {
- $output->writeln('<error>'.$e->getMessage().'</error>');
- if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) {
- $output->writeln($e->getTraceAsString());
- }
- return Cli::RETURN_FAILURE;
- }
- }
- /**
- * Get list of options for the command
- *
- * @return InputOption[]
- */
- private function getOptionList()
- {
- return [
- new InputOption(
- self::ACCESS_LIST_OPTION,
- null,
- InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
- 'IPs access list that can purge Varnish',
- ['localhost']
- ),
- new InputOption(
- self::BACKEND_HOST_OPTION,
- null,
- InputOption::VALUE_REQUIRED,
- 'Host of the web backend',
- 'localhost'
- ),
- new InputOption(
- self::BACKEND_PORT_OPTION,
- null,
- InputOption::VALUE_REQUIRED,
- 'Port of the web backend',
- 8080
- ),
- new InputOption(
- self::EXPORT_VERSION_OPTION,
- null,
- InputOption::VALUE_REQUIRED,
- 'The version of Varnish file',
- VclTemplateLocator::VARNISH_SUPPORTED_VERSION_4
- ),
- new InputOption(
- self::GRACE_PERIOD_OPTION,
- null,
- InputOption::VALUE_REQUIRED,
- 'Grace period in seconds',
- 300
- ),
- new InputOption(
- self::OUTPUT_FILE_OPTION,
- null,
- InputOption::VALUE_REQUIRED,
- 'Path to the file to write vcl'
- ),
- ];
- }
- /**
- * @param InputInterface $input
- * @return array
- */
- private function inputToVclParameters(InputInterface $input)
- {
- $parameters = [];
- foreach ($this->inputToVclMap as $inputKey => $vclKey) {
- $parameters[$vclKey] = $input->getOption($inputKey);
- }
- return $parameters;
- }
- /**
- * Input validation
- *
- * @param InputInterface $input
- * @return array
- */
- private function validate(InputInterface $input)
- {
- $errors = [];
- if ($input->hasOption(self::BACKEND_PORT_OPTION)
- && ($input->getOption(self::BACKEND_PORT_OPTION) < 0
- || $input->getOption(self::BACKEND_PORT_OPTION) > 65535)
- ) {
- $errors[] = 'Invalid backend port value';
- }
- if ($input->hasOption(self::GRACE_PERIOD_OPTION)
- && $input->getOption(self::GRACE_PERIOD_OPTION) < 0
- ) {
- $errors[] = 'Grace period can\'t be lower than 0';
- }
- return $errors;
- }
- /**
- * Get ssl Offloaded header
- *
- * @return mixed
- */
- private function getSslOffloadedHeader()
- {
- return $this->scopeConfig->getValue(Request::XML_PATH_OFFLOADER_HEADER);
- }
- /**
- * Get design exceptions
- *
- * @return array
- */
- private function getDesignExceptions()
- {
- $expressions = $this->scopeConfig->getValue(
- Config::XML_VARNISH_PAGECACHE_DESIGN_THEME_REGEX,
- ScopeInterface::SCOPE_STORE
- );
- return $expressions ? $this->serializer->unserialize($expressions) : [];
- }
- }
|