123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Framework\Code\Generator;
- use Magento\Framework\Exception\FileSystemException;
- /**
- * Manages generated code.
- */
- class Io
- {
- /**
- * Default code generation directory
- * Should correspond the value from \Magento\Framework\Filesystem
- */
- const DEFAULT_DIRECTORY = 'generated/code';
- /**
- * Path to directory where new file must be created
- *
- * @var string
- */
- private $_generationDirectory;
- /**
- * @var \Magento\Framework\Filesystem\Driver\File
- */
- private $filesystemDriver;
- /**
- * @param \Magento\Framework\Filesystem\Driver\File $filesystemDriver
- * @param null|string $generationDirectory
- */
- public function __construct(
- \Magento\Framework\Filesystem\Driver\File $filesystemDriver,
- $generationDirectory = null
- ) {
- $this->filesystemDriver = $filesystemDriver;
- $this->initGeneratorDirectory($generationDirectory);
- }
- /**
- * Get path to generation directory
- *
- * @param null|string $directory
- * @return string
- */
- protected function initGeneratorDirectory($directory = null)
- {
- if ($directory) {
- $this->_generationDirectory = rtrim($directory, '/') . '/';
- } else {
- $this->_generationDirectory = realpath(__DIR__ . '/../../../../') . '/' . self::DEFAULT_DIRECTORY . '/';
- }
- }
- /**
- * @param string $className
- * @return string
- */
- public function getResultFileDirectory($className)
- {
- $fileName = $this->generateResultFileName($className);
- $pathParts = explode('/', $fileName);
- unset($pathParts[count($pathParts) - 1]);
- return implode('/', $pathParts) . '/';
- }
- /**
- * @param string $className
- * @return string
- */
- public function generateResultFileName($className)
- {
- return $this->_generationDirectory . ltrim(str_replace(['\\', '_'], '/', $className), '/') . '.php';
- }
- /**
- * @param string $fileName
- * @param string $content
- * @throws FileSystemException
- * @return bool
- */
- public function writeResultFile($fileName, $content)
- {
- /**
- * Rename is atomic on *nix systems, while file_put_contents is not. Writing to a
- * temporary file whose name is process-unique and renaming to the real location helps
- * avoid race conditions. Race condition can occur if the compiler has not been run, when
- * multiple processes are attempting to access the generated file simultaneously.
- */
- $content = "<?php\n" . $content;
- $tmpFile = $fileName . "." . getmypid();
- $this->filesystemDriver->filePutContents($tmpFile, $content);
- try {
- $success = $this->filesystemDriver->rename($tmpFile, $fileName);
- } catch (FileSystemException $e) {
- if (!$this->fileExists($fileName)) {
- throw $e;
- } else {
- /**
- * Due to race conditions, file may have already been written, causing rename to fail. As long as
- * the file exists, everything is okay.
- */
- $success = true;
- }
- }
- return $success;
- }
- /**
- * @return bool
- */
- public function makeGenerationDirectory()
- {
- return $this->_makeDirectory($this->_generationDirectory);
- }
- /**
- * @param string $className
- * @return bool
- */
- public function makeResultFileDirectory($className)
- {
- return $this->_makeDirectory($this->getResultFileDirectory($className));
- }
- /**
- * @return string
- */
- public function getGenerationDirectory()
- {
- return $this->_generationDirectory;
- }
- /**
- * @param string $fileName
- * @return bool
- */
- public function fileExists($fileName)
- {
- return $this->filesystemDriver->isExists($fileName);
- }
- /**
- * Wrapper for include
- *
- * @param string $fileName
- * @return mixed
- * @codeCoverageIgnore
- */
- public function includeFile($fileName)
- {
- return include $fileName;
- }
- /**
- * @param string $directory
- * @return bool
- */
- private function _makeDirectory($directory)
- {
- if ($this->filesystemDriver->isWritable($directory)) {
- return true;
- }
- try {
- if (!$this->filesystemDriver->isDirectory($directory)) {
- $this->filesystemDriver->createDirectory($directory);
- }
- return true;
- } catch (FileSystemException $e) {
- return false;
- }
- }
- }
|