c791f51c901ab4150e758904176db4bcacbf4064
[yaffs-website] / vendor / drupal / console / src / Command / Site / ModeCommand.php
1 <?php
2
3 /**
4  * @file
5  * Contains \Drupal\Console\Command\Site\ModeCommand.
6  */
7 namespace Drupal\Console\Command\Site;
8
9 use Symfony\Component\Console\Input\InputArgument;
10 use Symfony\Component\Console\Input\InputOption;
11 use Symfony\Component\Console\Input\InputInterface;
12 use Symfony\Component\Console\Output\OutputInterface;
13 use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
14 use Symfony\Component\Yaml\Yaml;
15 use Symfony\Component\Console\Command\Command;
16 use Symfony\Component\Filesystem\Filesystem;
17 use Novia713\Maginot\Maginot;
18 use Drupal\Console\Core\Command\Shared\ContainerAwareCommandTrait;
19 use Drupal\Console\Core\Style\DrupalStyle;
20 use Drupal\Console\Core\Utils\ConfigurationManager;
21 use Drupal\Core\Config\ConfigFactory;
22 use Drupal\Console\Core\Utils\ChainQueue;
23
24 class ModeCommand extends Command
25 {
26     use ContainerAwareCommandTrait;
27
28     /**
29      * @var ConfigFactory
30      */
31     protected $configFactory;
32
33     /**
34      * @var ConfigurationManager
35      */
36     protected $configurationManager;
37
38     /**
39      * @var string
40      */
41     protected $appRoot;
42
43     /**
44      * @var ChainQueue
45      */
46     protected $chainQueue;
47
48     /**
49      * DebugCommand constructor.
50      *
51      * @param ConfigFactory        $configFactory
52      * @param ConfigurationManager $configurationManager
53      * @param $appRoot
54      * @param ChainQueue           $chainQueue,
55      */
56     public function __construct(
57         ConfigFactory $configFactory,
58         ConfigurationManager $configurationManager,
59         $appRoot,
60         ChainQueue $chainQueue
61     ) {
62         $this->configFactory = $configFactory;
63         $this->configurationManager = $configurationManager;
64         $this->appRoot = $appRoot;
65         $this->chainQueue = $chainQueue;
66
67         $this->local = null;
68
69         $this->services_file =
70             $this->appRoot.'/sites/default/services.yml';
71
72         $this->local_services_file =
73             $this->appRoot.'/sites/development.services.yml';
74
75         $this->settings_file =
76             $this->appRoot.'/sites/default/settings.php';
77
78         $this->local_settings_file =
79             $this->appRoot.'/sites/default/settings.local.php';
80
81         $this->local_settings_file_original =
82             $this->appRoot.'/sites/example.settings.local.php';
83
84         $this->fs = new Filesystem();
85         $this->maginot = new Maginot();
86         $this->yaml = new Yaml();
87
88         $this->environment = null;
89
90         parent::__construct();
91     }
92
93     protected function configure()
94     {
95         $this
96             ->setName('site:mode')
97             ->setDescription($this->trans('commands.site.mode.description'))
98             ->addArgument(
99                 'environment',
100                 InputArgument::REQUIRED,
101                 $this->trans('commands.site.mode.arguments.environment')
102             )
103             ->addOption(
104                 'local',
105                 null,
106                 InputOption::VALUE_NONE,
107                 $this->trans('commands.site.mode.options.local')
108             );
109     }
110
111     protected function execute(InputInterface $input, OutputInterface $output)
112     {
113         $io = new DrupalStyle($input, $output);
114
115         $this->environment = $input->getArgument('environment');
116         $this->local = $input->getOption('local');
117
118         $loadedConfigurations = [];
119         if (in_array($this->environment, ['dev', 'prod'])) {
120             $loadedConfigurations = $this->loadConfigurations($this->environment);
121         } else {
122             $io->error($this->trans('commands.site.mode.messages.invalid-env'));
123         }
124
125         $configurationOverrideResult = $this->overrideConfigurations(
126             $loadedConfigurations['configurations'],
127             $io
128         );
129
130         foreach ($configurationOverrideResult as $configName => $result) {
131             $io->info(
132                 $this->trans('commands.site.mode.messages.configuration').':',
133                 false
134             );
135             $io->comment($configName);
136
137             $tableHeader = [
138                 $this->trans('commands.site.mode.messages.configuration-key'),
139                 $this->trans('commands.site.mode.messages.original'),
140                 $this->trans('commands.site.mode.messages.updated'),
141             ];
142
143             $io->table($tableHeader, $result);
144         }
145
146         $servicesOverrideResult = $this->overrideServices(
147             $loadedConfigurations['services'],
148             $io
149         );
150
151         if (!empty($servicesOverrideResult)) {
152             $io->info(
153                 $this->trans('commands.site.mode.messages.new-services-settings')
154             );
155
156             $tableHeaders = [
157                 $this->trans('commands.site.mode.messages.service'),
158                 $this->trans('commands.site.mode.messages.service-parameter'),
159                 $this->trans('commands.site.mode.messages.service-value'),
160             ];
161
162             $io->table($tableHeaders, $servicesOverrideResult);
163         }
164
165         $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'all']);
166     }
167
168     protected function overrideConfigurations($configurations, $io)
169     {
170         $result = [];
171         foreach ($configurations as $configName => $options) {
172             $config = $this->configFactory->getEditable($configName);
173             foreach ($options as $key => $value) {
174                 $original = $config->get($key);
175                 if (is_bool($original)) {
176                     $original = $original ? 'true' : 'false';
177                 }
178                 $updated = $value;
179                 if (is_bool($updated)) {
180                     $updated = $updated ? 'true' : 'false';
181                 }
182
183                 $result[$configName][] = [
184                     'configuration' => $key,
185                     'original' => $original,
186                     'updated' => $updated,
187                 ];
188                 $config->set($key, $value);
189             }
190             $config->save();
191         }
192
193         $line_include_settings =
194             '<?php include __DIR__ . "/settings.local.php"; ?>';
195
196         if ($this->environment == 'dev') {
197
198             // copy sites/example.settings.local.php sites/default/settings.local.php
199             $this->fs->copy($this->local_settings_file_original, $this->local_settings_file, true);
200
201             // uncomment cache bins in settings.local.php
202             $this->maginot->unCommentLine(
203                 '# $settings[\'cache\'][\'bins\'][\'render\'] = \'cache.backend.null\';',
204                 $this->local_settings_file
205             );
206
207             $this->maginot->unCommentLine(
208                 '// $settings[\'cache\'][\'bins\'][\'render\'] = \'cache.backend.null\';',
209                 $this->local_settings_file
210             );
211
212             $this->maginot->unCommentLine(
213                 '# $settings[\'cache\'][\'bins\'][\'dynamic_page_cache\'] = \'cache.backend.null\';',
214                 $this->local_settings_file
215             );
216
217             $this->maginot->unCommentLine(
218                 '// $settings[\'cache\'][\'bins\'][\'dynamic_page_cache\'] = \'cache.backend.null\';',
219                 $this->local_settings_file
220             );
221
222             // include settings.local.php in settings.php
223             // -- check first line if it is already this
224             if ($this->maginot->getFirstLine($this->settings_file)!= $line_include_settings
225             ) {
226                 chmod($this->settings_file, (int)0775);
227                 $this->maginot->setFirstLine(
228                     $line_include_settings,
229                     $this->settings_file
230                 );
231             }
232
233             $io->commentBlock(
234                 sprintf(
235                     '%s',
236                     $this->trans('commands.site.mode.messages.cachebins')
237                 )
238             );
239         }
240         if ($this->environment == 'prod') {
241             if (!$this->local) {
242
243                 // comment local.settings.php in settings.php
244                 if ($this->maginot->getFirstLine($this->settings_file)==$line_include_settings
245                 ) {
246                     $this->maginot->deleteFirstLine(
247                         $this->settings_file
248                     );
249                 }
250
251
252                 try {
253                     $this->fs->remove(
254                         $this->local_settings_file
255                     );
256                     //@TODO: msg user "local.settings.php deleted"
257                 } catch (IOExceptionInterface $e) {
258                     echo $e->getMessage();
259                 }
260             } else {
261
262                 // comment cache bins in local.settings.php,
263                 // we still use local.settings.php for testing PROD
264                 // settings in local
265
266                 $this->maginot->CommentLine(
267                     ' $settings[\'cache\'][\'bins\'][\'render\'] = \'cache.backend.null\';',
268                     $this->local_settings_file
269                 );
270
271                 $this->maginot->CommentLine(
272                     ' $settings[\'cache\'][\'bins\'][\'dynamic_page_cache\'] = \'cache.backend.null\';',
273                     $this->local_settings_file
274                 );
275             }
276         }
277
278         /**
279          * would be better if this were replaced by $config->save?
280          */
281         //@TODO: 0444 should be a better permission for settings.php
282         chmod($this->settings_file, (int)0644);
283         //@TODO: 0555 should be a better permission for sites/default
284         chmod($this->appRoot.'/sites/default/', (int)0755);
285
286         return $result;
287     }
288
289     protected function overrideServices($servicesSettings, DrupalStyle $io)
290     {
291         $directory = sprintf(
292             '%s/%s',
293             $this->appRoot,
294             \Drupal::service('site.path')
295         );
296
297         $settingsServicesFile = $directory.'/services.yml';
298         if (!file_exists($settingsServicesFile)) {
299             // Copying default services
300             $defaultServicesFile = $this->appRoot.'/sites/default/default.services.yml';
301             if (!copy($defaultServicesFile, $settingsServicesFile)) {
302                 $io->error(
303                     sprintf(
304                         '%s: %s/services.yml',
305                         $this->trans('commands.site.mode.messages.error-copying-file'),
306                         $directory
307                     )
308                 );
309
310                 return [];
311             }
312         }
313
314         $services = $this->yaml->parse(file_get_contents($settingsServicesFile));
315
316         $result = [];
317         foreach ($servicesSettings as $service => $parameters) {
318             if (is_array($parameters)) {
319                 foreach ($parameters as $parameter => $value) {
320                     $services['parameters'][$service][$parameter] = $value;
321                     // Set values for output
322                     $result[$parameter]['service'] = $service;
323                     $result[$parameter]['parameter'] = $parameter;
324                     if (is_bool($value)) {
325                         $value = $value ? 'true' : 'false';
326                     }
327                     $result[$parameter]['value'] = $value;
328                 }
329             } else {
330                 $services['parameters'][$service] = $parameters;
331                 // Set values for output
332                 $result[$service]['service'] = $service;
333                 $result[$service]['parameter'] = '';
334                 if (is_bool($parameters)) {
335                     $value = $parameters ? 'true' : 'false';
336                 }
337                 $result[$service]['value'] = $value;
338             }
339         }
340
341         if (file_put_contents($settingsServicesFile, $this->yaml->dump($services))) {
342             $io->commentBlock(
343                 sprintf(
344                     $this->trans('commands.site.mode.messages.services-file-overwritten'),
345                     $settingsServicesFile
346                 )
347             );
348         } else {
349             $io->error(
350                 sprintf(
351                     '%s : %s/services.yml',
352                     $this->trans('commands.site.mode.messages.error-writing-file'),
353                     $directory
354                 )
355             );
356
357             return [];
358         }
359
360         sort($result);
361
362         return $result;
363     }
364
365     protected function loadConfigurations($env)
366     {
367         $configFile = sprintf(
368             '%s/.console/site.mode.yml',
369             $this->configurationManager->getHomeDirectory()
370         );
371
372         if (!file_exists($configFile)) {
373             $configFile = sprintf(
374                 '%s/config/dist/site.mode.yml',
375                 $this->configurationManager->getApplicationDirectory().DRUPAL_CONSOLE_CORE
376             );
377         }
378
379         $siteModeConfiguration = $this->yaml->parse(file_get_contents($configFile));
380         $configKeys = array_keys($siteModeConfiguration);
381
382         $configurationSettings = [];
383         foreach ($configKeys as $configKey) {
384             $siteModeConfigurationItem = $siteModeConfiguration[$configKey];
385             foreach ($siteModeConfigurationItem as $setting => $parameters) {
386                 if (array_key_exists($env, $parameters)) {
387                     $configurationSettings[$configKey][$setting] = $parameters[$env];
388                 } else {
389                     foreach ($parameters as $parameter => $value) {
390                         $configurationSettings[$configKey][$setting][$parameter] = $value[$env];
391                     }
392                 }
393             }
394         }
395
396         return $configurationSettings;
397     }
398 }