x1nfly
10/22/2018 - 12:37 AM

Laravel Model generator from database.

Laravel Model generator from database.

<?php

namespace App\Console\Commands\Generators;

use Illuminate\Console\GeneratorCommand;
use Symfony\Component\Console\Input\InputOption;
use DB;

class ModelGenerator extends GeneratorCommand
{
    /**
     * The console command name.
     *
     * @var string
     */
    protected $name = 'generate:model';

    /**
     * Get the root namespace for the class.
     *
     * @return string
     */
    protected function rootNamespace()
    {
        return 'App\\Http\\Models';
    }

    /**
     * Get the destination class path.
     *
     * @param  string  $name
     * @return string
     */
    protected function getPath($name)
    {
        $name = base_path(str_replace('\\', '/', $name) . ".php");
        return $name;
    }

    /**
     * Get the stub file for the generator.
     *
     * @return string
     */
    protected function getStub()
    {
        $dir = __DIR__.'/stubs/model.stub';
        return $dir;
    }

    /**
     * Build the class with the given name.
     *
     * @param  string  $name
     * @return string
     */
    protected function buildClass($name)
    {
        $tableName = $this->option('table');
        $stub = $this->files->get($this->getStub());
        $result = $this->replaceNamespace($stub, $name)
            ->replaceContent($stub, $tableName)
            ->replaceClass($stub, $name);
        return $result;
    }

    protected function replaceAuthorInfo(&$stub)
    {
        $stub = str_replace('DummyUser', 'X.FLY', $stub);
        $stub = str_replace('DummyDate', date('Y/m/d'), $stub);

        $hour = date('H');
        if ($hour < 12) {
            $stub = str_replace('DummyTime', '上午' . date('h:i'), $stub);
        } else {
            $stub = str_replace('DummyTime', '下午' . date('h:i'), $stub);
        }
        return $this;
    }

    protected function replaceContent(&$stub, $tableName)
    {
        $stub = str_replace('TableName', '\'' . $tableName . '\'', $stub);
        $fieldList = DB::table('Information_schema.columns')
            ->where('TABLE_SCHEMA', 'bcode')
            ->where('table_name', $tableName)
            ->get();

        if ($fieldList->count() == 0) {
            $this->error('table ' . $tableName . ' doesn\'t exists!');
            exit;
        }
        $primaryKey = $fieldList->where('COLUMN_KEY', 'PRI')->first();
        $primaryKey = $primaryKey->COLUMN_NAME;
        $columnNames = $fieldList->pluck('COLUMN_NAME')->toArray();
        $useTimestamp = in_array('created_at', $columnNames);
        $useSoftDelete = in_array('deleted_at', $columnNames);

        $content = "";
        $this->appendSoftDelete($content, $useSoftDelete)
             ->appendTableName($content, $tableName)
             ->appendPrimaryKey($content, $primaryKey)
             ->appendTimestamp($content, $useTimestamp)
             ->appendFillable($content, $fieldList)
             ->appendDates($content, $fieldList);
        $stub = str_replace('DummyContent', $content, $stub);

        $namespace = '';
        $this->appendSoftDeleteNamespace($namespace, $useSoftDelete);
        if (!empty($namespace)) {
            $stub = str_replace('DummyUseNamespace', $namespace, $stub);
        } else {
            $stub = str_replace("\nDummyUseNamespace\n", $namespace, $stub);
        }
        return $this;
    }

    protected function appendSoftDeleteNamespace(&$namespace, $useSoftDelete)
    {
        if ($useSoftDelete) {
            $namespace .= "use Illuminate\Database\Eloquent\SoftDeletes;";
        }
        return $this;
    }

    protected function appendTableName(&$content, $primaryKey)
    {
        $content .= "\n    protected \$table = '$primaryKey';\n";
        return $this;
    }

    protected function appendPrimaryKey(&$content, $primaryKey)
    {
        $content .= "\n    protected \$primaryKey = '$primaryKey';\n";
        return $this;
    }

    protected function appendTimestamp(&$content, $useTimestamp)
    {
        if ($useTimestamp) {
            $content .= "\n    public \$timestamps = true;";
        } else {
            $content .= "\n    public \$timestamps = false;";
        }
        return $this;
    }

    protected function appendSoftDelete(&$content, $useSoftDelete)
    {
        if ($useSoftDelete) {
            $content .= "use SoftDeletes;\n";
        }
        return $this;
    }

    protected function appendFillable(&$content, $fieldList)
    {
        $fillableArray = "";
        foreach ($fieldList as $fieldInfo) {
            if ($fieldInfo->COLUMN_KEY == 'PRI') {
                continue;
            }

            if (!in_array($fieldInfo->COLUMN_NAME, ['created_at', 'updated_at', 'deleted_at'])) {
                $fillableArray .= "\n        '" . $fieldInfo->COLUMN_NAME . "',";
                if (!empty($fieldInfo->COLUMN_COMMENT)) {
                    $fillableArray .= " // " . $fieldInfo->COLUMN_COMMENT;
                }
            }
        }

        if (!empty($fillableArray)) {
            $fillableArray = "[{$fillableArray}\n    ];";
            $content .= "\n\n    protected \$fillable = " . $fillableArray;
        }
        return $this;
    }

    protected function appendDates(&$content, $fieldList)
    {
        $dates = "";
        foreach ($fieldList as $fieldInfo) {
            if (in_array($fieldInfo->COLUMN_NAME, ['created_at', 'updated_at', 'deleted_at'])) {
                continue;
            }

            if ($fieldInfo->COLUMN_TYPE == 'timestamp') {
                $dates .= "\n        '" . $fieldInfo->COLUMN_NAME . "',";
                if (!empty($fieldInfo->COLUMN_COMMENT)) {
                    $dates .= "//" . $fieldInfo->COLUMN_COMMENT;
                }
            }
        }
        if (!empty($dates)) {
            $dates = "[{$dates}\n    ];";
            $content .= "\n\n    protected \$dates = " . $dates;
        }
        return $this;
    }

    /**
     * Get the console command options.
     *
     * @return array
     */
    protected function getOptions()
    {
        return [
            ['table', 't', InputOption::VALUE_OPTIONAL, 'Specified tableName.'],
        ];
    }
}
<?php

namespace DummyNamespace;

DummyUseNamespace

class DummyClass extends BaseModel
{
    DummyContent
}