Вход Регистрация
Файл: vendor/laravel/framework/src/Illuminate/Console/GeneratorCommand.php
Строк: 355
<?php

namespace IlluminateConsole;

use 
IlluminateConsoleConcernsCreatesMatchingTest;
use 
IlluminateFilesystemFilesystem;
use 
IlluminateSupportStr;
use 
SymfonyComponentConsoleInputInputArgument;

abstract class 
GeneratorCommand extends Command
{
    
/**
     * The filesystem instance.
     *
     * @var IlluminateFilesystemFilesystem
     */
    
protected $files;

    
/**
     * The type of class being generated.
     *
     * @var string
     */
    
protected $type;

    
/**
     * Reserved names that cannot be used for generation.
     *
     * @var string[]
     */
    
protected $reservedNames = [
        
'__halt_compiler',
        
'abstract',
        
'and',
        
'array',
        
'as',
        
'break',
        
'callable',
        
'case',
        
'catch',
        
'class',
        
'clone',
        
'const',
        
'continue',
        
'declare',
        
'default',
        
'die',
        
'do',
        
'echo',
        
'else',
        
'elseif',
        
'empty',
        
'enddeclare',
        
'endfor',
        
'endforeach',
        
'endif',
        
'endswitch',
        
'endwhile',
        
'enum',
        
'eval',
        
'exit',
        
'extends',
        
'false',
        
'final',
        
'finally',
        
'fn',
        
'for',
        
'foreach',
        
'function',
        
'global',
        
'goto',
        
'if',
        
'implements',
        
'include',
        
'include_once',
        
'instanceof',
        
'insteadof',
        
'interface',
        
'isset',
        
'list',
        
'match',
        
'namespace',
        
'new',
        
'or',
        
'print',
        
'private',
        
'protected',
        
'public',
        
'readonly',
        
'require',
        
'require_once',
        
'return',
        
'static',
        
'switch',
        
'throw',
        
'trait',
        
'true',
        
'try',
        
'unset',
        
'use',
        
'var',
        
'while',
        
'xor',
        
'yield',
        
'__CLASS__',
        
'__DIR__',
        
'__FILE__',
        
'__FUNCTION__',
        
'__LINE__',
        
'__METHOD__',
        
'__NAMESPACE__',
        
'__TRAIT__',
    ];

    
/**
     * Create a new controller creator command instance.
     *
     * @param  IlluminateFilesystemFilesystem  $files
     * @return void
     */
    
public function __construct(Filesystem $files)
    {
        
parent::__construct();

        if (
in_array(CreatesMatchingTest::class, class_uses_recursive($this))) {
            
$this->addTestOptions();
        }

        
$this->files $files;
    }

    
/**
     * Get the stub file for the generator.
     *
     * @return string
     */
    
abstract protected function getStub();

    
/**
     * Execute the console command.
     *
     * @return bool|null
     *
     * @throws IlluminateContractsFilesystemFileNotFoundException
     */
    
public function handle()
    {
        
// First we need to ensure that the given name is not a reserved word within the PHP
        // language and that the class name will actually be valid. If it is not valid we
        // can error now and prevent from polluting the filesystem using invalid files.
        
if ($this->isReservedName($this->getNameInput())) {
            
$this->components->error('The name "'.$this->getNameInput().'" is reserved by PHP.');

            return 
false;
        }

        
$name $this->qualifyClass($this->getNameInput());

        
$path $this->getPath($name);

        
// Next, We will check to see if the class already exists. If it does, we don't want
        // to create the class and overwrite the user's code. So, we will bail out so the
        // code is untouched. Otherwise, we will continue generating this class' files.
        
if ((! $this->hasOption('force') ||
             ! 
$this->option('force')) &&
             
$this->alreadyExists($this->getNameInput())) {
            
$this->components->error($this->type.' already exists.');

            return 
false;
        }

        
// Next, we will generate the path to the location where this class' file should get
        // written. Then, we will build the class and make the proper replacements on the
        // stub files so that it gets the correctly formatted namespace and class name.
        
$this->makeDirectory($path);

        
$this->files->put($path$this->sortImports($this->buildClass($name)));

        
$info $this->type;

        if (
in_array(CreatesMatchingTest::class, class_uses_recursive($this))) {
            if (
$this->handleTestCreation($path)) {
                
$info .= ' and test';
            }
        }

        
$this->components->info(sprintf('%s [%s] created successfully.'$info$path));
    }

    
/**
     * Parse the class name and format according to the root namespace.
     *
     * @param  string  $name
     * @return string
     */
    
protected function qualifyClass($name)
    {
        
$name ltrim($name'\/');

        
$name str_replace('/''\', $name);

        $rootNamespace = $this->rootNamespace();

        if (Str::startsWith($name, $rootNamespace)) {
            return $name;
        }

        return $this->qualifyClass(
            $this->getDefaultNamespace(trim($rootNamespace, '
\')).'\'.$name
        );
    }

    /**
     * Qualify the given model class base name.
     *
     * @param  string  $model
     * @return string
     */
    protected function qualifyModel(string $model)
    {
        $model = ltrim($model, '
\/');

        $model = str_replace('
/', '\', $model);

        $rootNamespace = $this->rootNamespace();

        if (Str::startsWith($model, $rootNamespace)) {
            return $model;
        }

        return is_dir(app_path('
Models'))
                    ? $rootNamespace.'
Models\'.$model
                    : $rootNamespace.$model;
    }

    /**
     * Get the default namespace for the class.
     *
     * @param  string  $rootNamespace
     * @return string
     */
    protected function getDefaultNamespace($rootNamespace)
    {
        return $rootNamespace;
    }

    /**
     * Determine if the class already exists.
     *
     * @param  string  $rawName
     * @return bool
     */
    protected function alreadyExists($rawName)
    {
        return $this->files->exists($this->getPath($this->qualifyClass($rawName)));
    }

    /**
     * Get the destination class path.
     *
     * @param  string  $name
     * @return string
     */
    protected function getPath($name)
    {
        $name = Str::replaceFirst($this->rootNamespace(), '', $name);

        return $this->laravel['
path'].'/'.str_replace('\', '/', $name).'.php';
    }

    /**
     * Build the directory for the class if necessary.
     *
     * @param  string  $path
     * @return string
     */
    protected function makeDirectory($path)
    {
        if (! $this->files->isDirectory(dirname($path))) {
            $this->files->makeDirectory(dirname($path), 0777, true, true);
        }

        return $path;
    }

    /**
     * Build the class with the given name.
     *
     * @param  string  $name
     * @return string
     *
     * @throws IlluminateContractsFilesystemFileNotFoundException
     */
    protected function buildClass($name)
    {
        $stub = $this->files->get($this->getStub());

        return $this->replaceNamespace($stub, $name)->replaceClass($stub, $name);
    }

    /**
     * Replace the namespace for the given stub.
     *
     * @param  string  $stub
     * @param  string  $name
     * @return $this
     */
    protected function replaceNamespace(&$stub, $name)
    {
        $searches = [
            ['
DummyNamespace', 'DummyRootNamespace', 'NamespacedDummyUserModel'],
            ['
{{ namespace }}', '{{ rootNamespace }}', '{{ namespacedUserModel }}'],
            ['
{{namespace}}', '{{rootNamespace}}', '{{namespacedUserModel}}'],
        ];

        foreach ($searches as $search) {
            $stub = str_replace(
                $search,
                [$this->getNamespace($name), $this->rootNamespace(), $this->userProviderModel()],
                $stub
            );
        }

        return $this;
    }

    /**
     * Get the full namespace for a given class, without the class name.
     *
     * @param  string  $name
     * @return string
     */
    protected function getNamespace($name)
    {
        return trim(implode('
\', array_slice(explode('\', $name), 0, -1)), '\');
    }

    /**
     * Replace the class name for the given stub.
     *
     * @param  string  $stub
     * @param  string  $name
     * @return string
     */
    protected function replaceClass($stub, $name)
    {
        $class = str_replace($this->getNamespace($name).'
\', '', $name);

        return str_replace(['
DummyClass', '{{ class }}', '{{class}}'], $class, $stub);
    }

    /**
     * Alphabetically sorts the imports for the given stub.
     *
     * @param  string  $stub
     * @return string
     */
    protected function sortImports($stub)
    {
        if (preg_match('
/(?P<imports>(?:^use [^;{]+;$n?)+)/m', $stub, $match)) {
            $imports = explode("n", trim($match['
imports']));

            sort($imports);

            return str_replace(trim($match['
imports']), implode("n", $imports), $stub);
        }

        return $stub;
    }

    /**
     * Get the desired class name from the input.
     *
     * @return string
     */
    protected function getNameInput()
    {
        return trim($this->argument('
name'));
    }

    /**
     * Get the root namespace for the class.
     *
     * @return string
     */
    protected function rootNamespace()
    {
        return $this->laravel->getNamespace();
    }

    /**
     * Get the model for the default guard'
s user provider.
     *
     * @return 
string|null
     
*/
    protected function 
userProviderModel()
    {
        
$config $this->laravel['config'];

        
$provider $config->get('auth.guards.'.$config->get('auth.defaults.guard').'.provider');

        return 
$config->get("auth.providers.{$provider}.model");
    }

    
/**
     * Checks whether the given name is reserved.
     *
     * @param  string  $name
     * @return bool
     */
    
protected function isReservedName($name)
    {
        
$name strtolower($name);

        return 
in_array($name$this->reservedNames);
    }

    
/**
     * Get the first view directory path from the application configuration.
     *
     * @param  string  $path
     * @return string
     */
    
protected function viewPath($path '')
    {
        
$views $this->laravel['config']['view.paths'][0] ?? resource_path('views');

        return 
$views.($path DIRECTORY_SEPARATOR.$path $path);
    }

    
/**
     * Get the console command arguments.
     *
     * @return array
     */
    
protected function getArguments()
    {
        return [
            [
'name'InputArgument::REQUIRED'The name of the class'],
        ];
    }
}
Онлайн: 2
Реклама