escolalms/model-fields

Escola LMS model-fields 扩展。

安装量: 26,497

依赖: 5

建议者: 0

安全: 0

星星: 1

关注者: 1

分支: 0

开放问题: 0

类型:package

0.0.24 2024-06-11 08:46 UTC

README

swagger codecov phpunit downloads downloads downloads Maintainability Test Coverage Mutation testing badge

它做什么

此软件包允许您为任何模型添加无限多的额外基本字段。

可用的字段类型

  • booleandoc
  • number
  • varchar
  • text
  • json

详细信息文档提供示例

安装

  • composer require escolalms/model-fields
  • php artisan migrate
  • php artisan db:seed --class="EscolaLms\ModelFields\Database\Seeders\PermissionTableSeeder"

数据库

该软件包允许通过在数据库中保存特殊的元描述值来添加额外的字段。

在元数据描述旁边是与之一起工作的值。

以下是元数据和值在数据库中存储的示例

model_fields_metadata 表示例行

model_fields_values 表示例行

请参阅 tests 文件夹,上面的行是从测试生成的。

示例

最佳文档是通过实际示例操作的,所以这里是。

假设您有用户模型

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected $table = 'users';
    protected $fillable = ['first_name', 'last_name', 'email'];
    protected $appends = ['foo'];
    public function getFooAttribute()
    {
        return 'bar';
    }
}

为了向用户模型添加额外字段,您需要创建新列并在迁移中添加这些字段。这是处理此问题的标准方法,但此软件包引入了新的方法。

选项 1. 扩展模型

此选项用 EscolaLms\ModelFields\Models\Model 替换 Illuminate\Database\Eloquent\Model

use EscolaLms\ModelFields\Models\Model;

class User extends Model
{
    protected $table = 'users';
    protected $fillable = ['first_name', 'last_name', 'email'];
    protected $appends = ['foo'];
    public function getFooAttribute()
    {
        return 'bar';
    }
}

选项 2. 模型中的特性。

此选项使用 EscolaLms\ModelFields\Traits\ModelFields 而不是扩展类;

use Illuminate\Database\Eloquent\Model;
use EscolaLms\ModelFields\Traits\ModelFields;

class User extends Model
{
    use ModelFields;

    protected $table = 'users';
    protected $fillable = ['first_name', 'last_name', 'email'];
    protected $appends = ['foo'];
    public function getFooAttribute()
    {
        return 'bar';
    }
}

}

基本上,这是允许模型可扩展所需的全部步骤。

在选定的模型上定义新字段。

现在让我们创建一个新的字段元描述。我们将向用户添加一个名为 description 的字段,它将是长文本。

use EscolaLms\ModelFields\Facades\ModelFields;

ModelFields::addOrUpdateMetadataField(
    User::class, // Model class that we want to extents
    'description', // name of new field
    'text', // type of new field
    'lorem ipsum', // default value
    ['required', 'string', 'max:255'] // validation rules
);

此方法接口如下

use EscolaLms\ModelFields\Models\Metadata;

public function addOrUpdateMetadataField(string $class_type, string $name, string $type, string $default = '', array $rules = null, $visibility = 1 << 0): Metadata;

一旦添加了新字段,就可以像使用模型的任何其他属性一样使用它

$extraAttributes = [
    'description' => 'to be or not to be',
];


$user = User::create(array_merge([
    'first_name' => 'John',
    'last_name' => 'Deo',
    'email' => 'john@email.com',
], $extraAttributes));

$user = User::find($user->id);

assert($user->description === $extraAttributes['description']);

就是这样,您的用户模型已准备好扩展。您可以像创建标准方式一样获取和设置属性。

 $extraAttributes = [
    'description' => 'aaa',
    'interested_in_tests' => false,
    'aaaa' => 'aaaa', // this will not be saved as is neither in model attributes nor in extra fields
    'consents' => ['consent1' => true, 'consent2' => false]
];

$user = User::create(array_merge([
    'first_name' => 'aaa',
    'last_name' => 'aaa',
    'email' => 'aaa@email.com',
], $extraAttributes));

$user->fill(['a' => 'nb']);  // this will not be saved as is neither in model attributes nor in extra fields

$user = User::find($user->id); // fetch user from database

assert($user->description === $extraAttributes['description']);
assert($user->interested_in_tests === $extraAttributes['interested_in_tests']);
assert($user->consents === $extraAttributes['consents']);
assert($user->aaaa === null);

$user->description = 'abc';
$user->interested_in_tests = true;
$user->save();

$user = User::find($user->id); // fetch user from database

assert($user->description === 'abc');
assert($user->interested_in_tests === true);

$user->update([
    'description' => 'zzz',
    'interested_in_tests' => false
]);

$user = User::find($user->id);  // fetch user from database

assert($user->description === 'zzz');
assert($user->interested_in_tests === false);

资源和字段可见性

使用资源很简单,请看以下示例

namespace EscolaLms\ModelFields\Tests\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;
use EscolaLms\ModelFields\Tests\Models\User;
use EscolaLms\ModelFields\Facades\ModelFields;
use EscolaLms\ModelFields\Enum\MetaFieldVisibilityEnum;

class UserResource extends JsonResource
{
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function toArray($request)
    {
        return [
            'id' => $this->user->id,
            'first_name' => $this->user->first_name,
            'last_name'  => $this->user->last_name,
            'email' => $this->user->email,
            ...ModelFields::getExtraAttributesValues($this->user, MetaFieldVisibilityEnum::PUBLIC) //  MetaFieldVisibilityEnum::PUBLIC === 1
        ];
    }
}

注意。在 php 7.4 中,使用 array_merge 而不是扩展操作符 ...

查看上面示例中的可见性字段。软件包允许定义元字段的可见性。在这里,我们定义了两个字段,一个是公共的,另一个仅供管理员。

use EscolaLms\ModelFields\Facades\ModelFields;
use EscolaLms\ModelFields\Facades\ModelFields;

ModelFields::addOrUpdateMetadataField(
    User::class,
    'title',
    'varchar',
    '',
    ['required', 'string', 'max:255']
);

ModelFields::addOrUpdateMetadataField(
    User::class,
    'admin_secret',
    'varchar',
    'super_secret',
    ['required', 'string', 'max:255'],
    MetaFieldVisibilityEnum::ADMIN
);

现在我们可以有两个端点,一个列出具有公共字段的用户,另一个仅对管理员可见。

namespace EscolaLms\ModelFields\Tests\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;
use EscolaLms\ModelFields\Tests\Models\User;
use EscolaLms\ModelFields\Facades\ModelFields;
use EscolaLms\ModelFields\Enum\MetaFieldVisibilityEnum;

class UserResource extends JsonResource
{
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function toArray($request)
    {
        return [
            'first_name' => $this->user->first_name,
            'last_name'  => $this->user->last_name,
            'email' => $this->user->email,
            ...ModelFields::getExtraAttributesValues($this->user, MetaFieldVisibilityEnum::PUBLIC)
        ];
    }
}

现在让我们看看管理员资源将是什么样子。

namespace EscolaLms\ModelFields\Tests\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;
use EscolaLms\ModelFields\Tests\Models\User;
use EscolaLms\ModelFields\Facades\ModelFields;
use EscolaLms\ModelFields\Enum\MetaFieldVisibilityEnum;

class UserAdminResource extends JsonResource
{
    public function __construct(User $user)
    {
        $this->user = $user;
    }

    public function toArray($request)
    {
        return [
            'id' => $this->user->id,
            'first_name' => $this->user->first_name,
            'last_name'  => $this->user->last_name,
            'email' => $this->user->email,
            ...ModelFields::getExtraAttributesValues($this->user, MetaFieldVisibilityEnum::ADMIN | MetaFieldVisibilityEnum::PUBLIC)
        ];
    }
}

MetaFieldVisibilityEnum::ADMIN | MetaFieldVisibilityEnum::PUBLIC 是一个 标志/位枚举MetaFieldVisibilityEnum 只是建议 - 您可以使用任何权限,但定义值时必须使用 2 的幂,例如。

    const ReadComments      = 1 << 0;
    const WriteComments     = 1 << 1;
    const EditComments      = 1 << 2;
    const DeleteComments    = 1 << 3;

使用 FormRequest 进行验证

以下示例说明了如何从元字段获取验证规则

namespace EscolaLms\ModelFields\Tests\Http\Requests;

use EscolaLms\ModelFields\Tests\Models\User;

use Illuminate\Foundation\Http\FormRequest;
use EscolaLms\ModelFields\Facades\ModelFields;

class UserCreateRequest extends FormRequest
{
    /**
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'first_name' => ['required', 'string'],
            'last_name' => ['required', 'string'],
            'email' => ['required', 'unique:users'],
            ...ModelFields::getFieldsMetadataRules(User::class)
        ];
    }
}

注意。在 php 7.4 中,使用 array_merge 而不是扩展操作符 ...

端点

所有端点均在swagger中定义。

测试

运行./vendor/bin/phpunit以运行测试。请参阅tests文件夹,作为文档附录的良好起点。

测试详情codecov phpunit

事件

此包不派发任何事件。

监听器

此包不监听任何事件

如何在前端使用此功能。

管理面板

swagger中定义的所有端点用于管理面板。

您可以在管理面板中使用原生组件来实现此功能,适用于任何允许扩展的模型。

<ModelFields class_type="EscolaLms\Auth\Models\User" />

管理面板示例

用户模型字段列表

List of user model fields

创建/编辑模型字段

Creating/editing model field

前端应用程序

请参阅上面的示例,了解如何扩展控制器以CRUD模型字段,从而为模型提供功能。

权限

权限定义在seeder

路线图。待办事项。故障排除。

  • firstOrCreate在传递额外属性时不工作