d7d053499dec06bf95cafc4c68ed7f54a4f31828
[yaffs-website] / vendor / drupal / console / src / Command / Multisite / NewCommand.php
1 <?php
2
3 /**
4  * @file
5  * Contains \Drupal\AppConsole\Command\Multisite\NewCommand.
6  */
7
8 namespace Drupal\Console\Command\Multisite;
9
10 use Drupal\Console\Core\Command\Command;
11 use Symfony\Component\Console\Input\InputArgument;
12 use Symfony\Component\Console\Input\InputInterface;
13 use Symfony\Component\Console\Input\InputOption;
14 use Symfony\Component\Console\Output\OutputInterface;
15 use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
16 use Symfony\Component\Filesystem\Filesystem;
17 use Symfony\Component\Filesystem\Exception\FileNotFoundException;
18
19 /**
20  * Class NewCommand
21  *
22  * @package Drupal\Console\Command\Multisite
23  */
24 class NewCommand extends Command
25 {
26     protected $appRoot;
27
28     /**
29      * DebugCommand constructor.
30      *
31      * @param $appRoot
32      */
33     public function __construct($appRoot)
34     {
35         $this->appRoot = $appRoot;
36         parent::__construct();
37     }
38
39     /**
40      * @var Filesystem;
41      */
42     protected $fs;
43
44     /**
45      * @var string
46      */
47     protected $directory = '';
48
49     /**
50      * {@inheritdoc}
51      */
52     public function configure()
53     {
54         $this->setName('multisite:new')
55             ->setDescription($this->trans('commands.multisite.new.description'))
56             ->setHelp($this->trans('commands.multisite.new.help'))
57             ->addArgument(
58                 'directory',
59                 InputArgument::REQUIRED,
60                 $this->trans('commands.multisite.new.arguments.directory')
61             )
62             ->addArgument(
63                 'uri',
64                 InputArgument::REQUIRED,
65                 $this->trans('commands.multisite.new.arguments.uri')
66             )
67             ->addOption(
68                 'copy-default',
69                 null,
70                 InputOption::VALUE_NONE,
71                 $this->trans('commands.multisite.new.options.copy-default')
72             )
73             ->setAliases(['mun']);
74     }
75
76     /**
77      * {@inheritdoc}
78      */
79     protected function execute(InputInterface $input, OutputInterface $output)
80     {
81         $this->fs = new Filesystem();
82         $this->directory = $input->getArgument('directory');
83
84         if (!$this->directory) {
85             $this->getIo()->error($this->trans('commands.multisite.new.errors.subdir-empty'));
86
87             return 1;
88         }
89
90         if ($this->fs->exists($this->appRoot . '/sites/' . $this->directory)) {
91             $this->getIo()->error(
92                 sprintf(
93                     $this->trans('commands.multisite.new.errors.subdir-exists'),
94                     $this->directory
95                 )
96             );
97
98             return 1;
99         }
100
101         if (!$this->fs->exists($this->appRoot . '/sites/default')) {
102             $this->getIo()->error($this->trans('commands.multisite.new.errors.default-missing'));
103
104             return 1;
105         }
106
107         try {
108             $this->fs->mkdir($this->appRoot . '/sites/' . $this->directory, 0755);
109         } catch (IOExceptionInterface $e) {
110             $this->getIo()->error(
111                 sprintf(
112                     $this->trans('commands.multisite.new.errors.mkdir-fail'),
113                     $this->directory
114                 )
115             );
116
117             return 1;
118         }
119
120         $uri = $input->getArgument('uri');
121         try {
122             $this->addToSitesFile($uri);
123         } catch (\Exception $e) {
124             $this->getIo()->error($e->getMessage());
125
126             return 1;
127         }
128
129         $this->createFreshSite();
130
131         return 0;
132     }
133
134     /**
135      * Adds line to sites.php that is needed for the new site to be recognized.
136      *
137      * @param string      $uri
138      *
139      * @throws FileNotFoundException
140      */
141     protected function addToSitesFile($uri)
142     {
143         if ($this->fs->exists($this->appRoot . '/sites/sites.php')) {
144             $sites_is_dir = is_dir($this->appRoot . '/sites/sites.php');
145             $sites_readable = is_readable($this->appRoot . '/sites/sites.php');
146             if ($sites_is_dir || !$sites_readable) {
147                 throw new FileNotFoundException($this->trans('commands.multisite.new.errors.sites-invalid'));
148             }
149             $sites_file_contents = file_get_contents($this->appRoot . '/sites/sites.php');
150         } elseif ($this->fs->exists($this->appRoot . '/sites/example.sites.php')) {
151             $sites_file_contents = file_get_contents($this->appRoot . '/sites/example.sites.php');
152             $sites_file_contents .= "\n\$sites = [];";
153         } else {
154             throw new FileNotFoundException($this->trans('commands.multisite.new.errors.sites-missing'));
155         }
156
157         $sites_file_contents .= "\n\$sites['$this->directory'] = '$this->directory';";
158
159         try {
160             $this->fs->dumpFile($this->appRoot . '/sites/sites.php', $sites_file_contents);
161             $this->fs->chmod($this->appRoot . '/sites/sites.php', 0640);
162         } catch (IOExceptionInterface $e) {
163             $this->getIo()->error('commands.multisite.new.errors.sites-other');
164         }
165     }
166
167     /**
168      * Copies detected default install alters settings.php to fit the new directory.
169      */
170     protected function copyExistingInstall()
171     {
172         if (!$this->fs->exists($this->appRoot . '/sites/default/settings.php')) {
173             $this->getIo()->error(
174                 sprintf(
175                     $this->trans('commands.multisite.new.errors.file-missing'),
176                     'sites/default/settings.php'
177                 )
178             );
179             return 1;
180         }
181
182         if ($this->fs->exists($this->appRoot . '/sites/default/files')) {
183             try {
184                 $this->fs->mirror(
185                     $this->appRoot . '/sites/default/files',
186                     $this->appRoot . '/sites/' . $this->directory . '/files'
187                 );
188             } catch (IOExceptionInterface $e) {
189                 $this->getIo()->error(
190                     sprintf(
191                         $this->trans('commands.multisite.new.errors.copy-fail'),
192                         'sites/default/files',
193                         'sites/' . $this->directory . '/files'
194                     )
195                 );
196                 return 1;
197             }
198         } else {
199             $this->getIo()->warning($this->trans('commands.multisite.new.warnings.missing-files'));
200         }
201
202         $settings = file_get_contents($this->appRoot . '/sites/default/settings.php');
203         $settings = str_replace('sites/default', 'sites/' . $this->directory, $settings);
204
205         try {
206             $this->fs->dumpFile(
207                 $this->appRoot . '/sites/' . $this->directory . '/settings.php',
208                 $settings
209             );
210         } catch (IOExceptionInterface $e) {
211             $this->getIo()->error(
212                 sprintf(
213                     $this->trans('commands.multisite.new.errors.write-fail'),
214                     'sites/' . $this->directory . '/settings.php'
215                 )
216             );
217             return 1;
218         }
219
220         $this->chmodSettings();
221
222         $this->getIo()->success(
223             sprintf(
224                 $this->trans('commands.multisite.new.messages.copy-default'),
225                 $this->directory
226             )
227         );
228     }
229
230     /**
231      * Creates site folder with clean settings.php file.
232      */
233     protected function createFreshSite()
234     {
235         if ($this->fs->exists($this->appRoot . '/sites/default/default.settings.php')) {
236             try {
237                 $this->fs->copy(
238                     $this->appRoot . '/sites/default/default.settings.php',
239                     $this->appRoot . '/sites/' . $this->directory . '/settings.php'
240                 );
241             } catch (IOExceptionInterface $e) {
242                 $this->getIo()->error(
243                     sprintf(
244                         $this->trans('commands.multisite.new.errors.copy-fail'),
245                         $this->appRoot . '/sites/default/default.settings.php',
246                         $this->appRoot . '/sites/' . $this->directory . '/settings.php'
247                     )
248                 );
249                 return 1;
250             }
251         } else {
252             $this->getIo()->error(
253                 sprintf(
254                     $this->trans('commands.multisite.new.errors.file-missing'),
255                     'sites/default/default.settings.php'
256                 )
257             );
258             return 1;
259         }
260
261         $this->chmodSettings();
262
263         $this->getIo()->success(
264             sprintf(
265                 $this->trans('commands.multisite.new.messages.fresh-site'),
266                 $this->directory
267             )
268         );
269
270         return 0;
271     }
272
273     /**
274      * Changes permissions of settings.php to 640.
275      *
276      * The copy will have 444 permissions by default, which makes it readable by
277      * anyone. Also, Drupal likes being able to write to it during, for example,
278      * a fresh install.
279      */
280     protected function chmodSettings()
281     {
282         try {
283             $this->fs->chmod($this->appRoot . '/sites/' . $this->directory . '/settings.php', 0640);
284         } catch (IOExceptionInterface $e) {
285             $this->getIo()->error(
286                 sprintf(
287                     $this->trans('commands.multisite.new.errors.chmod-fail'),
288                     $this->appRoot . '/sites/' . $this->directory . '/settings.php'
289                 )
290             );
291
292             return 1;
293         }
294     }
295 }