dweineratl/laravel-model-abstraction-helper

并非每个Laravel模型都支持Doctrine。这是一个帮助从模型中抽象获取列信息的辅助工具

1.0.1 2019-07-03 20:27 UTC

This package is auto-updated.

Last update: 2024-09-04 08:51:08 UTC


README

为什么要付出这么多努力?

我正在尝试在我的Laravel项目中回补测试,我非常希望使用 Laravel Test Factory Generator 来为测试生成 工厂。但我遇到了一个问题--我使用了 Jens SegersLaravel MongoDB Eloquent扩展。

由于MongoDB的工作性质,它没有Doctrine驱动。所以我无法使用它。或者我能吗?我一直在给我的模型添加完整的PHP DocBlocks,使用 @property 帮助在IDE中进行提示和变量完成。

我正在与 Jason McCreary 讨论这个问题,因为他就是那个指向Laravel Test Factory Generator的人。他建议将其抽象成一个可以使用Doctrine、DocBlocks、自定义驱动,并且最终回退到使用Laravel模型中应存在的 $fillable 数组的工厂,于是 Laravel Model Abstraction Helper 诞生了。

安装

使用以下命令使用composer安装此包

composer require dweineratl/laravel-model-abstraction-helper

如何使用

例如,Laravel Test Factory Generator使用以下代码片段获取模型列名和类型

    protected function getPropertiesFromTable($model)
    {
        $table = $model->getConnection()->getTablePrefix() . $model->getTable();
        $schema = $model->getConnection()->getDoctrineSchemaManager($table);
        $databasePlatform = $schema->getDatabasePlatform();
        $databasePlatform->registerDoctrineTypeMapping('enum', 'string');

        $platformName = $databasePlatform->getName();
        $customTypes = $this->laravel['config']->get("ide-helper.custom_db_types.{$platformName}", array());
        foreach ($customTypes as $yourTypeName => $doctrineTypeName) {
            $databasePlatform->registerDoctrineTypeMapping($yourTypeName, $doctrineTypeName);
        }

        $database = null;
        if (strpos($table, '.')) {
            list($database, $table) = explode('.', $table);
        }

        $columns = $schema->listTableColumns($table, $database);

        if ($columns) {
            foreach ($columns as $column) {
                $name = $column->getName();
                if (in_array($name, $model->getDates())) {
                    $type = 'datetime';
                } else {
                    $type = $column->getType()->getName();
                }
                if (!($model->incrementing && $model->getKeyName() === $name) &&
                    $name !== $model::CREATED_AT &&
                    $name !== $model::UPDATED_AT
                ) {
                    if (!method_exists($model, 'getDeletedAtColumn') || (method_exists($model, 'getDeletedAtColumn') && $name !== $model->getDeletedAtColumn())) {
                        $this->setProperty($name, $type);
                    }
                }
            }
        }
    }

它可以重构为

    protected function getPropertiesFromTable($model)
    {
        $columns = ModelAbstractionFactory::getColumns($model);

        if ($columns) {
            foreach ($columns as $column) {
                $name = $column->getName();
                if (in_array($name, $model->getDates())) {
                    $type = 'datetime';
                } else {
                    $type = $column->getType();
                }
                if (!($model->incrementing && $model->getKeyName() === $name) &&
                    $name !== $model::CREATED_AT &&
                    $name !== $model::UPDATED_AT
                ) {
                    if (!method_exists($model, 'getDeletedAtColumn') || (method_exists($model, 'getDeletedAtColumn') && $name !== $model->getDeletedAtColumn())) {
                        $this->setProperty($name, $type);
                    }
                }
            }
        }
    }

驱动程序

Laravel Model Abstraction Helper使用“驱动程序”的概念来处理不同类型的模型。Laravel Model Abstraction Helper附带三个驱动程序。ModelAbstractionFactory将检测要使用哪个驱动程序

  • Doctrine驱动程序

    此驱动程序适用于使用Doctrine的RDBMS模型,如MySQL、Postgres或SQLite。

  • DocBloc

    此驱动程序适用于不使用传统RDBMS的模型,如MongoDB,它不使用Doctrine并且具有带有 @property 标签的PHP DocBloc。

  • Fillable

    这是当模型不使用Doctrine且没有至少一个 @property 标签的DocBlock时的回退驱动程序。它使用每个Laravel模型中应存在的 $fillable 数组。

类方法

ModelAbstractionFactory

ModelAbstractionFactory有两个公开的静态方法

  /**
   * Factory to return an abstraction class to get information about a model
   *
   * @param $model
   *
   * @return \Dweineratl\LaravelModelHelper\Driver\DocBlocDriver|\Dweineratl\LaravelModelHelper\Driver\DoctrineDriver|\Dweineratl\LaravelModelHelper\Driver\FillableDriver
   * @throws \ReflectionException
   */
  public static function create($model)
  
  /**
   * Instantiate a LaravelModelHelper driver and return an array of Dweineratl\LaravelModelHelper\Column objects
   * 
   * @param $model
   * @return array
   * @throws \ReflectionException
   */
    public static function getColumns($model)

DriverInterface

每个驱动程序都实现了 Dweineratl\LaravelModelHelper\DriverInterface,该接口只有一个方法

  /**
   * Process the model and return an array of Dweineratl\LaravelModelHelper\Column objects
   * 
   * @param \Illuminate\Database\Eloquent\model $model
   *
   * @return array
   */
  public function getColumns(Eloquent $model);

Column

  /**
   * Column constructor.
   *
   * @param $name Column Name
   * @param $type Column Type
   */
  public function __construct($name, $type)

  /**
   * Get the column name
   *
   * @return string
   */
  public function getName()

  /**
   * Get the column type
   *
   * @return string
   */
  public function getType()

  /**
   * Set the column name
   *
   * @param $name
   */
  public function setName($name)

  /**
   * Set the column type
   *
   * @param $type
   */
  public function setType($type)

自定义驱动程序

为了支持获取模型列的其他方法,Laravel模型抽象助手支持位于Dweineratl\LaravelModelHelper\Driver命名空间中的驱动程序,类名是config('database.default')与'Driver'拼接并使用PascalCase形式(例如,Dweineratl\LaravelModelHelper\Driver\CouchdbDriver)。它至少需要实现Dweineratl\LaravelModelHelper\DriverInterface接口,并提供返回一个Dweineratl\LaravelModelHelper\Column对象数组的getColumns()方法。ModelAbstractionFactory首先会检查模型是否支持Doctrine。如果不支持Doctrine,它将使用config('database.default')获取默认数据库驱动程序的值,并检查是否存在该数据库的自定义驱动程序。如果没有,它将检查模型是否有合适的DocBlock。最后,如果之前的所有驱动程序都无法使用,将使用默认的回退方式,即使用$fillable数组。

许可证

Laravel模型抽象助手是免费软件,根据MIT许可证授权。