Расширить класс Blueprint?

Я хочу переопределить функцию timestamps(), найденную в классе Blueprint. Как я могу это сделать?

например.

public function up() {
    Schema::create('users', function (Blueprint $table) {
        $table->increments('id');
        $table->string('username')->unique();
        $table->string('password');
        $table->string('email');
        $table->string('name');
        $table->timestamps(); // <-- I want this to call my method instead of the one found in the base Blueprint class
    });
}

Ответ 1

Существует новая функция blueprintResolver, которая принимает функцию обратного вызова, которая затем возвращает экземпляр Blueprint.

Создайте свой собственный класс Blueprint следующим образом:

class CustomBlueprint extends Illuminate\Database\Schema\Blueprint{

    public function timestamps() {
        //Your custom timestamp code. Any output is not shown on the console so don't expect anything
    }
}

И затем вызовите функцию blueprintResolver, где вы вернете экземпляр CustomBlueprint.

public function up()
{
    $schema = DB::connection()->getSchemaBuilder();

    $schema->blueprintResolver(function($table, $callback) {
        return new CustomBlueprint($table, $callback);
    });

    $schema->create('users', function($table) {
        //Call your custom functions
    });
}

Я не уверен, что создание нового экземпляра схемы с DB::connection()->getSchemaBuilder(); является современным, но оно работает.

Вы можете дополнительно переопределить фасад Schema и по умолчанию добавить пользовательский проект.

Ответ 2

Просто добавьте несколько моментов к ответу Марселя Гвердера (что уже отлично):


(edit 2016-03-06)
Недавно была открыта проблема GitHub: # 12539.

Ответ 3

Ответ марселя Гвердера был спасителем жизни. Как прокомментировали некоторые пользователи, я подумал, можно ли сделать это более автоматически. Моей целью было также переписать метод timestamps. После некоторого возни, вот что я закончил, и это работает для меня:

Я создал файл в app/Classes/Database/Blueprint.php:

<?php

namespace App\Classes\Database;


use Illuminate\Support\Facades\DB;
use Illuminate\Database\Schema\Blueprint as BaseBlueprint;

class Blueprint extends BaseBlueprint
{
    /**
     * Add automatic creation and update timestamps to the table.
     *
     * @param  int  $precision
     */
    public function timestamps($precision = 0): void
    {
        $this->timestamp('created_at', $precision)->default(DB::raw('CURRENT_TIMESTAMP'));
        $this->timestamp('updated_at', $precision)->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
    }
}

Я создал файл в app/Facades/Schema.php

<?php

namespace App\Facades;

use App\Classes\Database\Blueprint;
use Illuminate\Database\Schema\Builder;
use Illuminate\Support\Facades\Schema as BaseSchema;

class Schema extends BaseSchema
{
    /**
     * Get a schema builder instance for a connection.
     *
     * @param  string|null  $name
     * @return Builder
     */
    public static function connection($name): Builder
    {
        /** @var \Illuminate\Database\Schema\Builder $builder */
        $builder = static::$app['db']->connection($name)->getSchemaBuilder();
        $builder->blueprintResolver(static function($table, $callback) {
            return new Blueprint($table, $callback);
        });
        return $builder;
    }

    /**
     * Get a schema builder instance for the default connection.
     *
     * @return Builder
     */
    protected static function getFacadeAccessor(): Builder
    {
        /** @var \Illuminate\Database\Schema\Builder $builder */
        $builder = static::$app['db']->connection()->getSchemaBuilder();
        $builder->blueprintResolver(static function($table, $callback) {
            return new Blueprint($table, $callback);
        });
        return $builder;
    }
}

Внутри config/app.php я обновил псевдоним для Схемы следующим образом:

'aliases' => [
    'Schema' => App\Facades\Schema::class,
],

Теперь, в моих миграциях, как показано ниже, когда я вызываю timestamps(), он вызывает мой перезаписанный метод.

<?php

use App\Classes\Database\Blueprint;
use \Illuminate\Database\Migrations\Migration;

class TimestampTest extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     * @throws \Throwable
     */
    public function up(): void
    {
        Schema::connection('mysql')->create('some_table', static function (Blueprint $table) {
            $table->string('some_column')->nullable();
            $table->timestamps();
        });

    }

    // ....
}