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