Stubs de archivos personalizados de Laravel

stubs de archivos

Stubs de archivos personalizados de Laravel

Cree su propio archivo de plantilla de inicio usando stubs de archivos personalizados en Laravel desde cero…

So how to start a business without money?


Existe la función de personalización de stubs en Laravel en la que puede modificar los archivos de stubs que se generan cuando ejecuta php artisan vendor:publish.

Mientras que en este tutorial vamos a crear nuestra propia plantilla de inicio que se define en nuestros propios archivos stub personalizados desde cero.

Si aún no ha instalado el proyecto Laravel, cree uno. Como estoy usando Laravel versión 8.12 mientras escribo este artículo.

Ahora, codifiquemos.

Paso 1: Cree una carpeta de stubs y un archivo de stub

Cree apéndices de nombre de carpeta en el directorio raíz del proyecto si no hay ninguno. Luego crea el nombre de archivo inteface.stub que se verá así

<?php

namespace $NAMESPACE$;

interface $CLASS_NAME$Interface
{

}

Arriba está la plantilla de código auxiliar inicial para un archivo de interfaz donde $ NAMESPACE $ y $ CLASS_NAME $ son las variables de código auxiliar (marcadores de posición). Por ahora, no se preocupe por sus usos, veremos en detalle más adelante.

Paso 2: crear un comando de consola

Ejecute el comando php artisan make:command MakeInterfaceCommand. Creará un comando de consola en la ruta relativa aplicación / Consola / Comandos, donde ocurre toda la magia. Eche un vistazo más profundo al comando de la consola aquí.

La esencia de esta magia de comandos de consola es obtener el contenido del archivo stub intereface.stub y cambiar la variable stub del archivo, es decir, $NAMESPACE$ y $CLASS_NAME$ con el valor definido por el usuario y colocarlo en la ruta deseada en su proyecto .

El aspecto final de MakeInterfaceCommand.php se encuentra al final de este artículo. Sin embargo, los detalles de cada paso y función de MakeInterfaceCommand se explican a continuación.

Después de ejecutar php artisan make:command MakeInterfaceCommand, agregue lo siguiente en el comando de consola generado paso a paso.

a. Cambiar el nombre y la firma del comando de la consola

Cambie el nombre y la firma del comando generate console junto con una descripción como se indica a continuación

protected $signature = 'make:interface {name}'

protected $description = 'Make and interface class'

b. Agregue las funciones para obtener el nombre singular en mayúsculas

/**
 * Return the Singular Capitalize Name
 * @param $name
 * @return string
 */
public function getSingularClassName($name)
{
    return ucwords(Pluralizer::singular($name));
}

Utilice el siguiente espacio de nombres para Pluralizer

use Illuminate\Support\Pluralizer;

c. Agregue la función getStubPath que devolverá la ruta de los stubs de archivos de la interfaz raíz

/**
 * Return the stub file path
 * @return string
 *
 */
public function getStubPath()
{
    return __DIR__ . '/../../../stubs/interface.stub';
}

d. Agregue la función getStubVariables que mapeará la variable stub presente en los stubs de archivos (interface.stub) mencionado anteriormente a su valor

/**
**
* Map the stub variables present in stub to its value
*
* @return array
*
*/
public function getStubVariables()
{
    return [
        'NAMESPACE'         => 'App\\Interfaces',
        'CLASS_NAME'        => $this->getSingularClassName($this->argument('name')),
    ];
}

En la matriz de retorno anterior, la clave NAMESPACE y CLASS_NAME son la variable de código auxiliar (marcador de posición) presente en el archivo de código auxiliar con su valor respectivo para reemplazar el marcador de posición.

Nota: $this->argument('name') se usa para obtener los argumentos de la línea de comando.

e. Agregue la función getSourceFile y getStubContents que obtendrá el contenido del archivo de código auxiliar de la interfaz y lo reemplazará con la función getStubVariables de ayuda

/**
 * Get the stub path and the stub variables
 *
 * @return bool|mixed|string
 *
 */
public function getSourceFile()
{
    return $this->getStubContents($this->getStubPath(), $this->getStubVariables());
}


/**
 * Replace the stub variables(key) with the desire value
 *
 * @param $stub
 * @param array $stubVariables
 * @return bool|mixed|string
 */
public function getStubContents($stub , $stubVariables = [])
{
    $contents = file_get_contents($stub);

    foreach ($stubVariables as $search => $replace)
    {
        $contents = str_replace('$'.$search.'$' , $replace, $contents);
    }

    return $contents;

}

En la función getStubContents, acepta la ruta stub y la variable stub como parámetros. Luego, obtendrá el contenido de los stubs de archivos (interface.stub) que recorrerá su contenido para encontrar la clave (marcador de posición) que se menciona en la matriz de retorno de la función getStubVariables y reemplazarla con su valor respectivo.

Por ejemplo, se buscará $NAMESPACE$ y se reemplazará por 'App\Intefaces' y finalmente la devolución del contenido reemplazando el marcador de posición con su valor original.

f. Devuelve la ruta donde generar la clase de interfaz

/**
 * Get the full path of generate class
 *
 * @return string
 */
public function getSourceFilePath()
{
    return base_path('App\\Interfaces') .'\\' .$this->getSingularClassName($this->argument('name')) . 'Interface.php';
}

g. Cambie su constructor a lo siguiente

/**
 * Filesystem instance
 * @var Filesystem
 */
protected $files;

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

    $this->files = $files;
}

Y agregue el siguiente espacio de nombres del sistema de archivos.

use Illuminate\Filesystem\Filesystem;

h. Agregue la función para hacer el directorio

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

    return $path;
}

Puede ver más sobre cómo hacer el directorio aquí.

i. Finalmente, actualice la función handle con el siguiente código

/**
 * Execute the console command.
 */
public function handle()
{
    $path = $this->getSourceFilePath();

    $this->makeDirectory(dirname($path));

    $contents = $this->getSourceFile();

    if (!$this->files->exists($path)) {
        $this->files->put($path, $contents);
        $this->info("File : {$path} created");
    } else {
        $this->info("File : {$path} already exits");
    }

}

En primer lugar, la $path almacena la ruta absoluta del archivo que se va a generar, luego con eso generará la carpeta (directorio) y el archivo. Además, $contents obtendrá la plantilla de inicio, y el resto de las declaraciones a continuación colocará esa plantilla de inicio en la ruta deseada.

Finalmente, puede ejecutar php artisan make:interface User (mencionado anteriormente en la variable de firma) para crear el archivo

UserInterface.php.El usuario es solo un ejemplo, mientras que ahora puede crear el archivo que desee. Puede ver el archivo generado en la aplicación / interfaces con el contenido a continuación.

Stubs de archivos

Por fin, el MakeInterfaceCommand se verá como

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Pluralizer;
use Illuminate\Filesystem\Filesystem;

class MakeInterfaceCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'make:interface {name}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Make an Interface Class';

    /**
     * Filesystem instance
     * @var Filesystem
     */
    protected $files;

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

        $this->files = $files;
    }

    /**
     * Execute the console command.
     */
    public function handle()
    {
        $path = $this->getSourceFilePath();

        $this->makeDirectory(dirname($path));

        $contents = $this->getSourceFile();

        if (!$this->files->exists($path)) {
            $this->files->put($path, $contents);
            $this->info("File : {$path} created");
        } else {
            $this->info("File : {$path} already exits");
        }

    }

    /**
     * Return the stub file path
     * @return string
     *
     */
    public function getStubPath()
    {
        return __DIR__ . '/../../../stubs/interface.stub';
    }

    /**
    **
    * Map the stub variables present in stub to its value
    *
    * @return array
    *
    */
    public function getStubVariables()
    {
        return [
            'NAMESPACE'         => 'App\\Interfaces',
            'CLASS_NAME'        => $this->getSingularClassName($this->argument('name')),
        ];
    }

    /**
     * Get the stub path and the stub variables
     *
     * @return bool|mixed|string
     *
     */
    public function getSourceFile()
    {
        return $this->getStubContents($this->getStubPath(), $this->getStubVariables());
    }


    /**
     * Replace the stub variables(key) with the desire value
     *
     * @param $stub
     * @param array $stubVariables
     * @return bool|mixed|string
     */
    public function getStubContents($stub , $stubVariables = [])
    {
        $contents = file_get_contents($stub);

        foreach ($stubVariables as $search => $replace)
        {
            $contents = str_replace('$'.$search.'$' , $replace, $contents);
        }

        return $contents;

    }

    /**
     * Get the full path of generate class
     *
     * @return string
     */
    public function getSourceFilePath()
    {
        return base_path('App\\Interfaces') .'\\' .$this->getSingularClassName($this->argument('name')) . 'Interface.php';
    }

    /**
     * Return the Singular Capitalize Name
     * @param $name
     * @return string
     */
    public function getSingularClassName($name)
    {
        return ucwords(Pluralizer::singular($name));
    }

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

        return $path;
    }

}

De esta manera, puede crear una plantilla de inicio simple según lo desee y ampliar esta lógica para crear la estructura y los archivos de inicio de su propio módulo personalizado.