2014-02-16 3 views
9

Ich habe eine Basisklasse für meine Migrationen erstellt. Im Moment starte ich den Befehl artisan migrate und es erstellt eine neue Migration, die die Migrationsdatei erweitert. Ich möchte jedoch meine BaseMigration einbeziehen und von dort aus erweitern. Ich habe diese Änderungen manuell vorgenommen, aber ich fühle mich, als würde ich mich unnötigerweise wiederholen.Kann man die Vorlagen ändern, die mit dem Befehl artisan migrate erstellt wurden?

Gibt es eine Empfehlung, wie neue Migrationen automatisch meine Basismigration erweitern und laden?

+1

Wenn jemand interessiert ist, machte ich ein Paket, das dieses Problem löst L5 + https://github.com/Kyslik/artisan-stubs – Kyslik

Antwort

5

Ich glaube nicht, Sie können, weil Laravel Migrationen aus dem vendor/laravel/framework/src/Illuminate/Database/Migrations/stubs Ordner dauert und Sie können das nicht ändern, aber Sie haben einige Optionen:

1) Erstellen Sie Ihre eigenen handwerklichen Befehl migrate:makemyown.

2) Verwenden Sie Jeffrey Way's Laravel 4 Generators. Sie lassen Sie Ihre Migrationen erstellen, indem Sie:

php artisan generate:migration create_posts_table --fields="title:string, description:text" 

Wenn Sie nur einige Felder haben Sie mit und nicht etwas präziser als die beginnen müssen, es funktioniert wirklich gut.

3) Bearbeiten Sie Laravel Stubs, aber das Problem ist, dass Sie, sobald Sie composer update von Composer überschrieben werden können.

+0

Ich würde Jeffrey Way Laravel Generatoren hoch empfehlen. Der obige Link ist defekt und Sie sollten wahrscheinlich seine Version 5-Generatoren verwenden, die Sie [hier] finden können (https://github.com/laracasts/Laravel-5-Generators-Extended). –

-3

Für Laravel 5 würden Sie eine der .stub Dateien in bearbeiten:

vendor/laravel/framework/src/Illuminate/Database/Migrations/stubs 

Es gibt keinen Grund, warum Sie diese Dateien nicht bearbeiten.

Suchen Sie in vendor/laravel/framework/src/ für .stub Dateien, um alle anderen Stubs (Vorlagen) Handwerker zu finden.

+8

Das ist eine schlechte Praxis und Sie sollten wirklich vermeiden, Bibliotheken zu bearbeiten, die Sie nicht besitzen. Zum Beispiel, wenn es eine neue Version des Laravel gibt und Sie darauf aktualisieren möchten, können Sie es wirklich nicht tun, ohne die Änderungen zu verlieren, die Sie gemacht haben. – Subash

3

Ich glaube, dass es keine Möglichkeit gibt, dies zu überschreiben (vorerst), aber ich denke, dass Sie Ihren benutzerdefinierten Befehl erstellen können, der Laravel-Logik verwenden wird. Dies wurde für Laravel erstellt 5.

Zuerst haben Generator Befehl erstellen app/Console/Commands/Generator.php:

<?php namespace App\Console\Commands; 

use Illuminate\Console\Command; 
use Illuminate\Filesystem\Filesystem; 
use Symfony\Component\Console\Input\InputArgument; 

class Generator extends Command 
{ 

    /** 
    * Command name 
    * 
    * @var string 
    */ 
    protected $name = 'generate'; 

    /** 
    * Command description 
    * 
    * @var string 
    */ 
    protected $description = 'Custom object generator'; 

    /** 
    * An array with all available generator classes 
    * 
    * @var array 
    */ 
    protected $types = ['request', 'model', 'middleware']; 

    /** 
    * Execute command 
    * 
    * @return mixed 
    */ 
    public function handle() 
    { 
     $type = $this->argument('type'); 
     if (!in_array($type, $this->types)) { 
      return $this->error('Type must be one of: '.implode(', ', $this->types)); 
     } 

     // Create new instance 
     $generatorClass = 'App\Console\Commands\Generators\\'.ucfirst($type); 
     $generator = new $generatorClass(new Filesystem()); 

     // Each generator has "fire" method 
     $this->comment($generator->setClassName($this->argument('name'))->fire()); 
    } 

    /** 
    * @return array 
    */ 
    public function getArguments() 
    { 
     return [ 
      ['type', InputArgument::REQUIRED, 'Type of class to generate: '.implode(', ', $this->types)], 
      ['name', InputArgument::REQUIRED, 'Name of class to generate'], 
     ]; 
    } 

} 

Dann haben Sie eine abstrakte Klasse für alle Ihre Generatoren Klassen app/Console/Commands/Generators/Generator.php zu erstellen:

<?php namespace App\Console\Commands\Generators; 

use Illuminate\Console\GeneratorCommand; 

abstract class Generator extends GeneratorCommand 
{ 
    // Directory name with whole application (by default app) 
    const APP_PATH = 'app'; 

    /* 
    * Name and description of command wont be used 
    * Generators Commands are not loaded via Kernel 
    * Name and description property has been put just to avoid Exception thrown by Symfony Command class 
    */ 
    protected $name = 'fake'; 
    protected $description = 'fake'; 

    /** 
    * Class name to generate 
    * 
    * @var string 
    */ 
    protected $className; 

    /** 
    * Returns class name to generate 
    * 
    * @return string 
    */ 
    protected function getNameInput() 
    { 
     return $this->className; 
    } 

    /** 
    * Returns path under which class should be generated 
    * 
    * @param string $name 
    * @return string 
    */ 
    protected function getPath($name) 
    { 
     $name = str_replace($this->getAppNamespace(), '', $name); 

     return self::APP_PATH.'/'.str_replace('\\', '/', $name).'.php'; 
    } 

    /** 
    * Sets class name to generate 
    * 
    * @param string $name 
    * @return $this 
    */ 
    public function setClassName($name) 
    { 
     $this->className = $name; 
     return $this; 
    } 

    /** 
    * Execute command 
    * 
    * @return string 
    */ 
    public function fire() 
    { 
     $name = $this->parseName($this->getNameInput()); 

     if ($this->files->exists($path = $this->getPath($name))) 
     { 
      return $this->type.' already exists!'; 
     } 

     $this->makeDirectory($path); 

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

     return $this->type.' '.$this->className.' created successfully.'; 
    } 

} 

Am Ende können Sie Ihre erste Generator-Klasse erstellen! app/Console/Commands/Generators/Request.php

<?php namespace App\Console\Commands\Generators; 

class Request extends Generator 
{ 

    /** 
    * Class type to generate 
    * 
    * @var string 
    */ 
    protected $type = 'Request'; 

    /** 
    * Returns default namespace for objects being generated 
    * 
    * @param string $rootNamespace 
    * @return string 
    */ 
    protected function getDefaultNamespace($rootNamespace) 
    { 
     return $rootNamespace.'\Http\Requests'; 
    } 

    /** 
    * Returns path to custom stub 
    * 
    * @return string 
    */ 
    public function getStub() 
    { 
     return base_path('resources').'/stubs/request.stub'; 
    } 

} 

Vergessen Sie nicht, Ihren erzeugen Befehl Kernel hinzufügen app/Console/Kernel.php:

<?php namespace App\Console; 

use Illuminate\Console\Scheduling\Schedule; 
use Illuminate\Foundation\Console\Kernel as ConsoleKernel; 

class Kernel extends ConsoleKernel { 

    /** 
    * The Artisan commands provided by your application. 
    * 
    * @var array 
    */ 
    protected $commands = [ 
    ... 
    'App\Console\Commands\Generator', 
    ... 
    ]; 

Ihre Stubs Setzen unter resources/stubs Verzeichnis. Lassen Sie uns zunächst einen für Request Generator resources/stubs/request.stub erstellen:

<?php namespace {{namespace}}; 

class {{class}} extends Request 
{ 

    /** 
    * @return bool 
    */ 
    public function authorize() 
    { 
    // CUSTOM LOGIC 

    return false; 
    } 

    /** 
    * @return array 
    */ 
    public function rules() 
    { 
    $rules = []; 

    // CUSTOM LOGIC 

    return $rules; 
    } 

} 

Dann rufen Sie mit php artisan generate request MyRequest.

Sie können Ihr benutzerdefiniertes Modell, Middleware, Controller usw. erstellenGeneratoren, es ist sehr einfach - Sie müssen neue Generator-Klasse unter app/Commands/Console/Generators erstellen - werfen Sie einen Blick auf Request.php Generator, um zu sehen, wie es funktioniert!

7

Es ist machbar in einem ziemlich logisch, zumindest in Laravel 5

Subclass MigrationCreator und getStubPath() außer Kraft setzen, sondern nur die Funktion über von der ursprünglichen Klasse Kopieren

<?php 

namespace App\Database; 

use Illuminate\Database\Migrations\MigrationCreator; 

class AppMigrationCreator extends MigrationCreator 
{ 
    public function getStubPath() 
    { 
     return __DIR__.'/stubs'; 
    } 
} 
(es wird die Unterklasse der __DIR__ verwenden)

Schreiben Sie einen Service Provider, um migration.creator mit Ihrer eigenen Unterklasse zu überschreiben (es muss ein deferenter Service Provider sein, da Sie eine verzögerte Bindung nicht mit einer eifrigen Bindung überschreiben können):

<?php 

namespace App\Database; 

use Illuminate\Support\ServiceProvider; 

class AppMigrationServiceProvider extends ServiceProvider 
{ 
    protected $defer = true; 

    public function register() 
    { 
     $this->app->singleton('migration.creator', function ($app) { 
      return new AppMigrationCreator($app['files']); 
     }); 
    } 

    public function provides() 
    { 
     return ['migration.creator']; 
    } 
} 

Fügen Sie Ihren Service-Provider config/app.phpnach die Standardeinstellungen.

Schließlich kopieren Sie vendor/laravel/framework/src/Illuminate/Database/Migrations/stubs neben Ihrer MigrationCreator-Unterklasse (in diesem Beispiel würde es app/Database/stubs werden) und bearbeiten Sie die Vorlagen an Ihre Bedürfnisse.

Die Namen DummyClass und DummyTable beibehalten, da sie durch str_replace() ersetzt werden, um die eigentlichen Migrationsdateien zu erstellen.

+0

Es ist in einer ziemlich logischen Weise machbar. Ich weiß nicht, ob ich es "ziemlich einfach" nennen würde :) – Blizz

+0

@Blizz ok, notiert – Tobia

+0

Beachten Sie, dass der Klassenname 'AppMigrationServiceProvider' sehr wichtig ist, weil Laravel die Verarbeitung meines eigenen 'MigrationServiceProvider' zu scheitern scheint. Ja, sogar sein Namensraum ist sicherlich anders als der eingebaute ... – mpyw