railken/laravel-manager

v4.0.5 2024-04-09 04:44 UTC

README

Actions Status

构建API时,通过精确的结构化逻辑提高代码的可读性和可维护性。

要求

PHP 8.1 及以上版本。

安装

您可以通过以下命令使用 Composer 安装它

composer require railken/lem

该包将自动注册自己。

用法

首先,您需要生成一个新的结构文件夹,使用

php artisan railken:make:manager app App\Foo.

现在您可以使用它了。

use App\Foo\FooManager;

$manager = new FooManager();
$result = $manager->create(['name' => 'foo']);

if ($result->ok()) {
    $foo = $result->getResource();
} else {
    $result->getErrors(); // All errors go here.
}

在操作过程中如何获取错误?当验证或授权失败时发生错误。令人兴奋的是,在每个过程中您都有完全的控制权:使用 ValidatorAuthorizer。当您检索错误时,您接收一个 Collection,这在开发 API 时进行得很好。以下是一个示例

$manager = new FooManager();
$result = $manager->create(['name' => 'f'));

print_r($result->getErrors()->toArray());
/*
Array
    (
        [0] => Array
            (
                [code] => FOO_TITLE_NOT_DEFINED
                [attribute] => title
                [message] => The title is required
                [value] =>
            )

        [1] => Array
            (
                [code] => FOO_NAME_NOT_DEFINED
                [attribute] => name
                [message] => The name isn't valid
                [value] => f
            )
    )
*/

那么,关于授权部分呢?首先,我们需要编辑 User 类。

use Railken\Lem\Contracts\AgentContract;

class User implements AgentContract
{
    public function can($permission, $arguments = [])
    {
        return true;
    }
}

您可以根据需要设置 can 方法,如果使用权限库(如 https://github.com/Zizaco/entrusthttps://github.com/spatie/laravel-permission)会更好。

如果不需要系统权限,只需简单地返回 true。

use Railken\Lem\Agents\SystemAgent;

$manager = new FooManager(Auth::user());
$result = $manager->create(['title' => 'f']);

print_r($result->getErrors()->toArray());
/*
Array
    (
        [0] => Array
            (
                [code] => FOO_TITLE_NOT AUTHORIZED
                [attribute] => title
                [message] => You're not authorized to interact with title, missing foo.attributes.title.fill permission
                [value] =>
            )
    )
*

"foo.attributes.title.fill" 被传递给 User::can(),如果返回值为 false,则结果将包含错误。

注意:如果您没有设置任何代理,则将使用 SystemAgent(所有权限授予)。

有关更多信息,请参阅 Authorizer

命令

  • 生成一组新文件 php artisan railken:make:manager [path] [namespace]。例如:php artisan railken:make:manager App "App\Foo"

管理器

这是主类,所有操作都是通过它来执行的:创建、更新、删除、检索。此类由以下组件组成:验证器、存储库、授权者、参数、序列化器

请参阅 Manager

namespace App\Foo;

use Railken\Lem\Manager;
use Railken\Lem\Contracts\AgentContract;

class FooManager extends Manager
{
    /**
     * Class name entity
     *
     * @var string
     */
    public $entity = Foo::class;

    /**
     * Construct
     *
     * @param AgentContract|null $agent
     */
    public function __construct(AgentContract $agent = null)
    {
        parent::__construct($agent);
    }
}

模型

这是 Eloquent 模型,没有变化,只是增加了一个接口

namespace App\Foo;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Railken\Lem\Contracts\EntityContract;

class Foo extends Model implements EntityContract
{

    use SoftDeletes;

    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'foo';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['name'];

    /**
     * The attributes that should be mutated to dates.
     *
     * @var array
     */
    protected $dates = ['deleted_at'];
}

存储库

这是一个存储库,其概念与 Symfony 的存储库非常相似,在这里编写所有查询。

请参阅 Repository 以获取更多信息。

namespace App\Foo;

use Railken\Lem\Repository;

class FooRepository extends Repository
{

    /**
     * Custom method
     *
     * @param string $name
     *
     * @return Foo
     */
    public function findOneByName($name)
    {
        return $this->findOneBy(['name' => $name]);
    }

}

验证器

接下来是验证器,同样很简单。每当创建或更新操作被调用时,都会调用 validate()。记住:始终返回错误集合。当然,您可以添加特定的验证库并将其用于此处。

namespace App\Foo;

use Railken\Lem\Contracts\EntityContract;
use Railken\Lem\Contracts\ValidatorContract;
use Railken\Lem\ParameterBag;
use Illuminate\Support\Collection;
use App\Foo\Exceptions as Exceptions;


class FooValidator implements ValidatorContract
{

    /**
     * Validate
     *
     * @param EntityContract $entity
     * @param ParameterBag $parameters
     *
     * @return Collection
     */
    public function validate(EntityContract $entity, ParameterBag $parameters)
    {

        $errors = new Collection();

        if (!$entity->exists)
            $errors = $errors->merge($this->validateRequired($parameters));

        $errors = $errors->merge($this->validateValue($entity, $parameters));

        return $errors;
    }

}

序列化器

这个类将序列化您的模型

namespace App\Foo;

use Railken\Lem\Contracts\SerializerContract;
use Railken\Lem\Contracts\EntityContract;
use Illuminate\Support\Collection;
use Railken\Bag;

class FooSerializer implements SerializerContract
{

	/**
	 * Serialize entity
	 *
	 * @param EntityContract $entity
	 *
	 * @return Bag
	 */
    public function serialize(EntityContract $entity, Collection $select)
    {
        $bag = (new Bag($entity->toArray()))->only($select->toArray());

		return $bag;
	}

}