Security update for Core, with self-updated composer
[yaffs-website] / vendor / drupal / console / src / Command / Multisite / UpdateCommand.php
1 <?php
2
3 /**
4  * @file
5  * Contains \Drupal\AppConsole\Command\Multisite\UpdateCommand.
6  */
7
8 namespace Drupal\Console\Command\Multisite;
9
10 use Drupal\Console\Core\Command\Command;
11 use Symfony\Component\Console\Input\InputInterface;
12 use Symfony\Component\Console\Input\InputOption;
13 use Symfony\Component\Console\Output\OutputInterface;
14 use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
15 use Symfony\Component\Filesystem\Filesystem;
16
17 /**
18  * Class UpdateCommand
19  *
20  * @package Drupal\Console\Command\Multisite
21  */
22 class UpdateCommand extends Command
23 {
24     protected $appRoot;
25
26     /**
27      * DebugCommand constructor.
28      *
29      * @param $appRoot
30      */
31     public function __construct($appRoot)
32     {
33         $this->appRoot = $appRoot;
34         parent::__construct();
35     }
36
37     /**
38      * @var Filesystem;
39      */
40     protected $fs;
41
42     /**
43      * @var string
44      */
45     protected $uri = '';
46
47     /**
48      * @var string
49      */
50     protected $directory = '';
51
52     /**
53      * @var array
54      */
55     protected $explodeUriDirectory = [];
56
57     /**
58      * @var array
59      */
60     protected $explodeDirectory = [];
61
62     /**
63      * {@inheritdoc}
64      */
65     public function configure()
66     {
67         $this->setName('multisite:update')
68             ->setDescription($this->trans('commands.multisite.update.description'))
69             ->setHelp($this->trans('commands.multisite.update.help'))
70             ->addOption(
71                 'directory',
72                 null,
73                 InputOption::VALUE_REQUIRED,
74                 $this->trans('commands.multisite.update.options.directory')
75             )
76             ->setAliases(['muu']);
77     }
78
79     /**
80      * {@inheritdoc}
81      */
82     protected function interact(InputInterface $input, OutputInterface $output)
83     {
84         $this->uri = parse_url($input->getParameterOption(['--uri', '-l'], 'default'), PHP_URL_HOST);
85
86         $sites = $this->getMultisite($this->uri);
87         if ($this->uri == "default") {
88             $this->uri = $this->getIo()->choice(
89                 $this->trans('commands.multisite.update.questions.uri'),
90                 $sites
91             );
92         } elseif (!array_key_exists($this->uri, $sites)) {
93             $this->getIo()->error(
94                 $this->trans('commands.multisite.update.error.invalid-uri')
95             );
96
97             return 1;
98         }
99         $this->uri = $sites[$this->uri];
100
101         $directory = $input->getOption('directory');
102         if (!$directory) {
103             $directory = $this->getIo()->ask($this->trans('commands.multisite.update.questions.directory'));
104         }
105         $input->setOption('directory', $directory);
106     }
107
108     /**
109      * {@inheritdoc}
110      */
111     protected function execute(InputInterface $input, OutputInterface $output)
112     {
113         $this->fs = new Filesystem();
114
115         if (empty($this->uri)) {
116             $uri =  parse_url($input->getParameterOption(['--uri', '-l'], 'default'), PHP_URL_HOST);
117             $sites = $this->getMultisite($uri);
118             $this->uri = $sites[$uri];
119         }
120
121         $this->directory = $input->getOption('directory');
122         $this->explodeDirectory = explode('/', $this->directory);
123         $this->explodeUriDirectory = explode('/', $this->uri);
124
125         if (count($this->explodeDirectory) <= 2) {
126             try {
127                 $multiSiteFile = sprintf(
128                     '%s/sites/sites.php',
129                     $this->appRoot
130                 );
131                 //Replace Multisite name in sites/sites.php
132                 $string_to_replace="sites['".$this->explodeUriDirectory[0]."'] = '".$this->uri."';";
133                 $replace_with="sites['".$this->explodeDirectory[0]."'] = '".$this->directory."';";
134                 $content=file_get_contents($multiSiteFile);
135                 $content_chunks=explode($string_to_replace, $content);
136                 $content=implode($replace_with, $content_chunks);
137                 file_put_contents($multiSiteFile, $content);
138             } catch (IOExceptionInterface $e) {
139                 $this->getIo()->error(
140                     sprintf(
141                         $this->trans('commands.multisite.update.errors.write-fail'),
142                         $this->uri,
143                         $this->directory
144                     )
145                 );
146                 return 1;
147             }
148
149             //Directory == 1 folder
150             if (count($this->explodeDirectory) == 1) {
151                 $this->recurse_copy(
152                     $this->appRoot.'/sites/'.$this->uri,
153                     $this->appRoot.'/sites/'.$this->directory
154                 );
155
156                 if ($this->explodeDirectory[0] != $this->explodeUriDirectory[0]
157                     && $this->fs->exists($this->appRoot.'/sites/'.$this->explodeUriDirectory[0].'/files')
158                 ) {
159                     $this->fs->remove($this->appRoot.'/sites/'.$this->directory.'/files');
160
161                     $this->recurse_copy(
162                         $this->appRoot.'/sites/'.$this->explodeUriDirectory[0].'/files',
163                         $this->appRoot.'/sites/'.$this->directory.'/files'
164                     );
165                 }
166
167                 $this->fs->chmod($this->appRoot.'/sites/'.$this->uri, 0755);
168                 $this->fs->remove($this->appRoot.'/sites/'.$this->uri);
169             } else {
170                 //Directory == 2 folders && uri == 2 folders
171                 if (count($this->explodeUriDirectory) != 1) {
172                     if (!$this->fs->exists($this->appRoot . '/sites/' . $this->directory)) {
173                         $this->fs->rename(
174                             $this->appRoot . '/sites/' . $this->uri,
175                             $this->appRoot . '/sites/' . $this->directory
176                         );
177                     }
178
179                     if (count(scandir($this->appRoot.'/sites/'.$this->explodeUriDirectory[0])) != 2) {
180                         $this->recurse_copy(
181                             $this->appRoot.'/sites/'.$this->explodeUriDirectory[0].'/files',
182                             $this->appRoot . '/sites/' . $this->explodeDirectory[0].'/files'
183                         );
184                     } else {
185                         $this->fs->remove($this->appRoot.'/sites/'.$this->explodeUriDirectory[0]);
186                     }
187                 }
188                 //Directory == 2 folders && uri == 1 folder
189                 else {
190                     if (!$this->fs->exists($this->appRoot.'/sites/'.$this->directory)) {
191                         try {
192                             $this->fs->chmod($this->appRoot.'/sites/'.$this->uri, 0755);
193                             $this->fs->mkdir($this->appRoot.'/sites/'.$this->directory, 0755);
194
195                             if ($this->explodeUriDirectory[0] != $this->explodeDirectory[0]) {
196                                 $this->recurse_copy(
197                                     $this->appRoot.'/sites/'.$this->uri,
198                                     $this->appRoot.'/sites/'.$this->explodeDirectory[0]
199                                 );
200                                 $this->fs->remove($this->appRoot.'/sites/'.$this->uri);
201                             }
202                         } catch (IOExceptionInterface $e) {
203                             $this->getIo()->error(
204                                 sprintf(
205                                     $this->trans('commands.multisite.update.errors.mkdir-fail'),
206                                     $this->directory
207                                 )
208                             );
209                         }
210                     }
211                     $this->moveSettings();
212                 }
213             }
214
215             $this->editSettings();
216         } else {
217             $this->getIo()->error(
218                 sprintf(
219                     $this->trans('commands.multisite.update.errors.invalid-new-dir'),
220                     $this->directory
221                 )
222             );
223         }
224     }
225
226     /**
227      * Get all Multisites.
228      */
229     protected function getMultisite()
230     {
231         $sites = [];
232         $multiSiteFile = sprintf(
233             '%s/sites/sites.php',
234             $this->appRoot
235         );
236
237         if (file_exists($multiSiteFile)) {
238             include $multiSiteFile;
239         }
240
241         if (!$sites) {
242             $this->getIo()->error(
243                 $this->trans('commands.debug.multisite.messages.no-multisites')
244             );
245
246             return 1;
247         }
248
249         return $sites;
250     }
251
252     /**
253      * Move the settings.php file to new directory.
254      */
255     protected function moveSettings()
256     {
257         try {
258             if (!$this->fs->exists($this->appRoot.'/sites/'.$this->directory.'/settings.php')) {
259                 $this->fs->copy(
260                     $this->appRoot.'/sites/'.$this->uri.'/settings.php',
261                     $this->appRoot.'/sites/'.$this->directory.'/settings.php'
262                 );
263                 $this->fs->remove($this->appRoot.'/sites/'.$this->uri.'/settings.php');
264             }
265         } catch (IOExceptionInterface $e) {
266             $this->getIo()->error(
267                 sprintf(
268                     $this->trans('commands.multisite.update.errors.copy-fail'),
269                     $this->appRoot.'/sites/'.$this->explodeDirectory[0].'/settings.php',
270                     $this->directory.'/settings.php'
271                 )
272             );
273             return 1;
274         }
275     }
276
277     /**
278      * Edit the settings.php file to change the database parameters, because the settings.php file was moved.
279      */
280     protected function editSettings()
281     {
282         $multiSiteSettingsFile = sprintf(
283             '%s/sites/'.$this->explodeDirectory[0].'/settings.php',
284             $this->appRoot
285         );
286         if (!$this->fs->exists($multiSiteSettingsFile)) {
287             $multiSiteSettingsFile = sprintf(
288                 '%s/sites/'.$this->directory.'/settings.php',
289                 $this->appRoot
290             );
291         }
292
293         $databases = [];
294         $config_directories = [];
295
296         if (file_exists($multiSiteSettingsFile)) {
297             include $multiSiteSettingsFile;
298         }
299
300         try {
301             if (!empty($databases) || !empty($config_directories)) {
302                 //Replace $databases['default']['default']['database']
303                 $line = explode('/', $databases['default']['default']['database']);
304                 $string_to_replace= $databases['default']['default']['database'];
305                 $replace_with="sites/".$this->explodeDirectory[0]."/files/".end($line);
306                 $content=file_get_contents($multiSiteSettingsFile);
307                 $content_chunks=explode($string_to_replace, $content);
308                 $content=implode($replace_with, $content_chunks);
309
310                 //Replace $config_directories['sync']
311                 $string_to_replace= $config_directories['sync'];
312                 $replace_with=str_replace($this->uri, $this->directory, $config_directories['sync']);
313                 $content_chunks=explode($string_to_replace, $content);
314                 $content=implode($replace_with, $content_chunks);
315                 file_put_contents($multiSiteSettingsFile, $content);
316             }
317         } catch (IOExceptionInterface $e) {
318             $this->getIo()->error(
319                 sprintf(
320                     $this->trans('commands.multisite.update.messages.write-fail'),
321                     $multiSiteSettingsFile
322                 )
323             );
324             return 1;
325         }
326     }
327
328     /**
329      * Custom function to recursively copy all file and folders in new destination
330      *
331      * @param $source
332      * @param $destination
333      */
334     public function recurse_copy($source, $destination)
335     {
336         $directory = opendir($source);
337         $this->fs->mkdir($destination, 0755);
338         while (false !== ($file = readdir($directory))) {
339             if (($file != '.') && ($file != '..')) {
340                 if (is_dir($source . '/' . $file)) {
341                     $this->recurse_copy($source . '/' . $file, $destination . '/' . $file);
342                 } else {
343                     $this->fs->copy($source . '/' . $file, $destination . '/' . $file);
344                 }
345             }
346         }
347         closedir($directory);
348     }
349 }