123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Deploy\Model;
- use Symfony\Component\Console\Output\OutputInterface;
- use Magento\Framework\App\State;
- use Magento\Framework\App\DeploymentConfig\Writer;
- use Magento\Framework\App\Filesystem\DirectoryList;
- use Magento\Framework\Exception\LocalizedException;
- use Magento\Framework\Validator\Locale;
- use Magento\User\Model\ResourceModel\User\Collection as UserCollection;
- /**
- * Generate static files, compile
- *
- * Сlear generated/code, generated/metadata/, var/view_preprocessed and pub/static directories
- *
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
- class Filesystem
- {
- /**
- * File access permissions
- *
- * @deprecated As magento2 doesn't control indirectly the access permissions to the files anymore.
- * Access permissions to the files are set during deploy Magento 2, directly after
- * uploading code of Magento. Also it is possible to specify the value
- * of inverse mask for setting access permissions to files generated by Magento.
- * @link https://devdocs.magento.com/guides/v2.0/install-gde/install/post-install-umask.html
- * @link https://devdocs.magento.com/guides/v2.0/install-gde/prereq/file-system-perms.html
- */
- const PERMISSIONS_FILE = 0640;
- /**
- * Directory access permissions
- *
- * @deprecated As magento2 doesn't control indirectly the access permissions to the directories anymore.
- * Access permissions to the directories are set during deploy Magento 2, directly after
- * uploading code of Magento. Also it is possible to specify the value
- * of inverse mask for setting access permissions to directories generated by Magento.
- * @link https://devdocs.magento.com/guides/v2.0/install-gde/install/post-install-umask.html
- * @link https://devdocs.magento.com/guides/v2.0/install-gde/prereq/file-system-perms.html
- */
- const PERMISSIONS_DIR = 0750;
- /**
- * Default theme when no theme is stored in configuration
- */
- const DEFAULT_THEME = 'Magento/blank';
- /**
- * @var \Magento\Framework\App\DeploymentConfig\Writer
- */
- private $writer;
- /**
- * @var \Magento\Framework\App\DeploymentConfig\Reader
- */
- private $reader;
- /**
- * @var \Magento\Framework\ObjectManagerInterface
- */
- private $objectManager;
- /**
- * @var \Magento\Framework\Filesystem
- */
- private $filesystem;
- /**
- * @var \Magento\Framework\App\Filesystem\DirectoryList
- */
- private $directoryList;
- /**
- * @var \Magento\Framework\Filesystem\Driver\File
- */
- private $driverFile;
- /**
- * @var \Magento\Store\Model\Config\StoreView
- */
- private $storeView;
- /**
- * @var \Magento\Framework\ShellInterface
- */
- private $shell;
- /**
- * @var string
- */
- private $functionCallPath;
- /**
- * @var UserCollection
- */
- private $userCollection;
- /**
- * @var Locale
- */
- private $locale;
- /**
- * @param \Magento\Framework\App\DeploymentConfig\Writer $writer
- * @param \Magento\Framework\App\DeploymentConfig\Reader $reader
- * @param \Magento\Framework\ObjectManagerInterface $objectManager
- * @param \Magento\Framework\Filesystem $filesystem
- * @param \Magento\Framework\App\Filesystem\DirectoryList $directoryList
- * @param \Magento\Framework\Filesystem\Driver\File $driverFile
- * @param \Magento\Store\Model\Config\StoreView $storeView
- * @param \Magento\Framework\ShellInterface $shell
- * @param UserCollection|null $userCollection
- * @param Locale|null $locale
- * @SuppressWarnings(PHPMD.ExcessiveParameterList)
- */
- public function __construct(
- \Magento\Framework\App\DeploymentConfig\Writer $writer,
- \Magento\Framework\App\DeploymentConfig\Reader $reader,
- \Magento\Framework\ObjectManagerInterface $objectManager,
- \Magento\Framework\Filesystem $filesystem,
- \Magento\Framework\App\Filesystem\DirectoryList $directoryList,
- \Magento\Framework\Filesystem\Driver\File $driverFile,
- \Magento\Store\Model\Config\StoreView $storeView,
- \Magento\Framework\ShellInterface $shell,
- UserCollection $userCollection = null,
- Locale $locale = null
- ) {
- $this->writer = $writer;
- $this->reader = $reader;
- $this->objectManager = $objectManager;
- $this->filesystem = $filesystem;
- $this->directoryList = $directoryList;
- $this->driverFile = $driverFile;
- $this->storeView = $storeView;
- $this->shell = $shell;
- $this->userCollection = $userCollection ?: $this->objectManager->get(UserCollection::class);
- $this->locale = $locale ?: $this->objectManager->get(Locale::class);
- $this->functionCallPath =
- PHP_BINARY . ' -f ' . BP . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'magento ';
- }
- /**
- * Regenerate static
- *
- * @param OutputInterface $output
- * @return void
- * @throws LocalizedException
- * @throws \Exception
- */
- public function regenerateStatic(
- OutputInterface $output
- ) {
- // Сlear generated/code, generated/metadata/, var/view_preprocessed and pub/static directories
- $this->cleanupFilesystem(
- [
- DirectoryList::CACHE,
- DirectoryList::GENERATED_CODE,
- DirectoryList::GENERATED_METADATA,
- DirectoryList::TMP_MATERIALIZATION_DIR,
- DirectoryList::STATIC_VIEW
- ]
- );
- $this->reinitCacheDirectories();
- // Trigger code generation
- $this->compile($output);
- $this->reinitCacheDirectories();
- // Trigger static assets compilation and deployment
- $this->deployStaticContent($output);
- }
- /**
- * Deploy static content
- *
- * @param OutputInterface $output
- * @return void
- * @throws \Exception
- */
- protected function deployStaticContent(
- OutputInterface $output
- ) {
- $output->writeln('Starting deployment of static content');
- $cmd = $this->functionCallPath . 'setup:static-content:deploy -f '
- . implode(' ', $this->getUsedLocales());
- /**
- * @todo eliminate exec
- */
- try {
- $execOutput = $this->shell->execute($cmd);
- } catch (LocalizedException $e) {
- $output->writeln('Something went wrong while deploying static content. See the error log for details.');
- throw $e;
- }
- $output->writeln($execOutput);
- $output->writeln('Deployment of static content complete');
- }
- /**
- * Get admin user locales
- *
- * @return array
- */
- private function getAdminUserInterfaceLocales()
- {
- $locales = [];
- foreach ($this->userCollection as $user) {
- $locales[] = $user->getInterfaceLocale();
- }
- return $locales;
- }
- /**
- * Get used store and admin user locales.
- *
- * @return array
- * @throws \InvalidArgumentException if unknown locale is provided by the store configuration
- * @throws \Magento\Framework\Exception\FileSystemException
- */
- private function getUsedLocales()
- {
- $usedLocales = array_merge(
- $this->storeView->retrieveLocales(),
- $this->getAdminUserInterfaceLocales()
- );
- return array_map(
- function ($locale) {
- if (!$this->locale->isValid($locale)) {
- throw new \InvalidArgumentException(
- $locale . ' argument has invalid value, run info:language:list for list of available locales'
- );
- }
- return $locale;
- },
- array_unique($usedLocales)
- );
- }
- /**
- * Runs compiler
- *
- * @param OutputInterface $output
- * @return void
- * @throws LocalizedException
- */
- protected function compile(OutputInterface $output)
- {
- $output->writeln('Starting compilation');
- $cmd = $this->functionCallPath . 'setup:di:compile';
- /**
- * exec command is necessary for now to isolate the autoloaders in the compiler from the memory state
- * of this process, which would prevent some classes from being generated
- *
- * @todo eliminate exec
- */
- try {
- $execOutput = $this->shell->execute($cmd);
- } catch (LocalizedException $e) {
- $output->writeln('Something went wrong while compiling generated code. See the error log for details.');
- throw $e;
- }
- $output->writeln($execOutput);
- $output->writeln('Compilation complete');
- }
- /**
- * Deletes specified directories by code
- *
- * @param array $directoryCodeList
- * @return void
- * @throws \Magento\Framework\Exception\FileSystemException
- */
- public function cleanupFilesystem($directoryCodeList)
- {
- $excludePatterns = ['#.htaccess#', '#deployed_version.txt#'];
- foreach ($directoryCodeList as $code) {
- if ($code == DirectoryList::STATIC_VIEW) {
- $directoryPath = $this->directoryList->getPath(DirectoryList::STATIC_VIEW);
- if ($this->driverFile->isExists($directoryPath)) {
- $files = $this->driverFile->readDirectory($directoryPath);
- foreach ($files as $file) {
- foreach ($excludePatterns as $pattern) {
- if (preg_match($pattern, $file)) {
- continue 2;
- }
- }
- if ($this->driverFile->isFile($file)) {
- $this->driverFile->deleteFile($file);
- } else {
- $this->driverFile->deleteDirectory($file);
- }
- }
- }
- } else {
- $this->filesystem->getDirectoryWrite($code)
- ->delete();
- }
- }
- }
- /**
- * Changes permissions for directories by their code.
- *
- * @param array $directoryCodeList
- * @param int $dirPermissions
- * @param int $filePermissions
- * @return void
- * @deprecated 100.0.6 As magento2 doesn't control indirectly
- * the access permissions to the files and directories anymore.
- * Access permissions to the files and directories are set during deploy Magento 2, directly after
- * uploading code of Magento. Also it is possible to specify the value
- * of inverse mask for setting access permissions to files and directories generated by Magento.
- * @link https://devdocs.magento.com/guides/v2.0/install-gde/install/post-install-umask.html
- * @link https://devdocs.magento.com/guides/v2.0/install-gde/prereq/file-system-perms.html
- * @throws \Magento\Framework\Exception\FileSystemException
- */
- protected function changePermissions($directoryCodeList, $dirPermissions, $filePermissions)
- {
- foreach ($directoryCodeList as $code) {
- $directoryPath = $this->directoryList->getPath($code);
- if ($this->driverFile->isExists($directoryPath)) {
- $this->filesystem->getDirectoryWrite($code)
- ->changePermissionsRecursively('', $dirPermissions, $filePermissions);
- } else {
- $this->driverFile->createDirectory($directoryPath, $dirPermissions);
- }
- }
- }
- /**
- * Change permissions on static resources
- *
- * @return void
- * @deprecated 100.0.6 As magento2 doesn't control indirectly the access permissions to the files
- * and directories anymore.
- * Access permissions to the files and directories are set during deploy Magento 2, directly after
- * uploading code of Magento. Also it is possible to specify the value
- * of inverse mask for setting access permissions to files and directories generated by Magento.
- * @link https://devdocs.magento.com/guides/v2.0/install-gde/install/post-install-umask.html
- * @link https://devdocs.magento.com/guides/v2.0/install-gde/prereq/file-system-perms.html
- * @throws \Magento\Framework\Exception\FileSystemException
- */
- public function lockStaticResources()
- {
- // Lock /generated/code, /generated/metadata/ and /var/view_preprocessed directories
- $this->changePermissions(
- [
- DirectoryList::GENERATED_CODE,
- DirectoryList::GENERATED_METADATA,
- DirectoryList::TMP_MATERIALIZATION_DIR,
- ],
- self::PERMISSIONS_DIR,
- self::PERMISSIONS_FILE
- );
- }
- /**
- * Flush cache and restore the basic cache directories.
- *
- * @throws LocalizedException
- */
- private function reinitCacheDirectories()
- {
- $command = $this->functionCallPath . 'cache:flush';
- $this->shell->execute($command);
- }
- }
|