yurenery/rest-actions

该包最新版本(6.0.0)没有可用的许可证信息。

Amondar Rest Actions

6.0.0 2022-10-18 00:44 UTC

This package is not auto-updated.

Last update: 2024-10-01 03:11:29 UTC


README

有任何问题,请通过电子邮件联系 - yurenery@gmail.com
!!!!!! 仅适用于 Laravel >= 5.5+

能力表

安装

"repositories": [
    {
        "url": "https://git.attractgroup.com/amondar/RestActions.git",
        "type": "git"
    },
    {
        "url": "https://git.attractgroup.com/amondar/sextant.git",
        "type": "git"
    },
    {
        "url": "https://git.attractgroup.com/amondar/model-remember.git",
        "type": "git"
    }
]
    "amondar/rest-actions": "^4.2",
    "amondar/sextant": "^1.1",

连接

为了正确工作所有功能,建议安装以下包:

  1. MYSQL Amondar's Sextant..


将 **RestActions** 特性连接到控制器。请注意,控制器中必须存在 **public function serverFunction** 函数。
    abstract class CoreController extends Controller
    {
        use RestActions;

        ...

        public function serverResponse()
        {
            return (new ServerResponse());
        }
    }

ServerResponse 类不与当前特性一起提供,以便与任何项目直接兼容。由于每个项目的响应和API特性,示例实现可以在该存储库中找到。所需的功能来包装该类

    status - Функция для установки статуса в ответ.
    resource - Функция для передачи данных в ответ. Принимает на вход параметр Resource:class instance или просто массив.
    extend - Функция необходимая для расширения стандартных данных в ответе, если такие необходимы.

示例使用

class CategoryController extends CoreController
{
    use IndexAction, ShowAction, StoreAction, UpdateAction, DestroyAction;

    protected $actions = [
        'index' => [
            'request'     => CategoryRequest::class,
            'view'        => 'backend.categories.index',
        ],
        'show'  => [
            'request'     => CategoryRequest::class,
        ],
        'store' => [
            'request' => CategoryRequest::class,
        ],
        'update' => [
            'request' => CategoryRequest::class,
            'parameters' => [
                'category' => Category::class
            ]
        ],
        'destroy' => [
            'request' => CategoryRequest::class,
        ]
    ];

    /**
     * UserController constructor.
     *
     * @param CategoryRepository $repository
     */
    public function __construct(CategoryRepository $repository)
    {
        $this->repository = $repository;
    }
}

处理 Nemesis Filter 和排序

使用键 - conditions 传递参数到过滤器

'index'   => [
    'request'    => CourseRequest::class,
    'view'       => '',
    'ajaxTransform' => false,
    'conditions' => [
        'limit' => 20,
    ],
],

对于计数操作,可以将 limit=count 添加到请求中,并在响应中获取数量。例如,这对于处理通知计数非常有用。

无仓库使用

要无仓库使用,请指定变量 modelClass,它表示在当前控制器中工作的模型类的名称。

protected $modelCAlss = SubCategory::calss;

通过仓库使用

通常,通过仓库工作,特性会在仓库本身中查找与控制器中函数名称相同的函数。但在某些实现中这并不方便。要覆盖仓库内的函数

'update' => [
    'request' => CategoryRequest::class,
    'repository' => 'someOtherUpdateFunctionName'
],

从 URL 传递参数到仓库方法

要传递参数到仓库,只需在仓库方法中指定所需的参数即可。但是这里有一些细节。标准参数传递示例

'update' => [
    'request' => CategoryRequest::class,
    'parameters' => [
        'category' => Category::class // ключ массива в точности повторяет ключ из урла. Для правильности ввода воспользоваться php artisan route:list.
    ]
],

仓库中的函数

    public function update(Repository $repository, Category $category)

如果仓库中的参数具有不同的类名,例如在继承的情况下,则可以按其名称传递参数

'update' => [
    'request' => CategoryRequest::class,
    'parameters' => [
        // ключ массива parameters в точности повторяет ключ из урла. Для правильности ввода воспользоваться php artisan route:list.
        'category' => ['class' => Category::class, 'parameter_name' => 'vocabulariable'], 
    ]
],

仓库中的函数

    public function update(Repository $repository, Vocabulariable $vocabulariable);

特性会自动确定所需参数并将它们传递到仓库。请求将指定为指定的请求,然后是来自数组 parameters 的参数。重要:也可以使用参数来处理多功能函数。例如

public function update(Repository $repository, Category $category, $someParam = false);

在上面的示例中,需要将参数 $someParams=true 传递给函数,但它既不在 URL 也不在路由请求中

'update' => [
    'request' => CategoryRequest::class,
    'parameters' => [
        'category' => Category::class, // ключ в точности повторяет ключ из урла. Для правильности ввода воспользоваться php artisan route:list.
        'someParam' => true
    ]
],

如果您的仓库类实现了 setModel 方法来设置模型和 model 方法来返回模型,则可以在仓库中不传递模型参数。RestActions 会尝试从仓库中设置模型,如果它能在路由中找到它。

处理视图

某些特性函数可以加载视图。目前与视图一起工作的有两个函数 - index 和 show。要指示处理器使用所需的视图

'index' => [
    'request'     => CategoryRequest::class,
    'view'        => 'backend.categories.index',
],

请注意,对于 index 视图,将提供对象 $data,其中包含从数据库中检索的选择。在 show 方法中,这是模型的 "snake case" 名称。例如,SubCategory 变为 - $sub_category。还有一个用于扩展所有视图数据的函数,例如用于构建和显示菜单数据的函数

/**
 * TODO redeclare to add default data for all views.
 *
 * @return array
 */
protected function restDefaultData()
{
    return [];
}

细节和扩展

为与上述包一起工作,编写了用于限制选择和扩展响应的函数。函数 index & show。重写以下函数以更改过滤器和响应视图的工作方式。键 parameters 是过滤器的参数数组

/**
 * Return index additional parameters to filter.
 *
 * TODO Redeclare this function in controller to make request a little bit secure for example.
 *
 * @param Request $request
 * @param Router  $router
 *
 * @return array
 */
protected function getIndexFilterParameters(Request $request, Router $router)
{
    return [
        //'parameters'  => $this->getActionConditions($router)->toArray(), - Стандартное использование, достает параметры из массива $actions.
        'parameters'  => [
            'filter' => [
                'sub_category.category_id' => 1
            ]
        ],
    ];
}

/**
 * Extend index response.
 *
 * TODO redeclare this function in controller and return extended information.
 *
 * @param Request $request
 * @param Router  $router
 *
 * @return array
 */
protected function extendIndexResponse(Request $request, Router $router)
{
    return [ ];
}

// ДЛЯ SHOW ФУНКЦИИ

/**
 * Return index additional parameters to filter.
 *
 * TODO Redeclare this function in controller to make request a little bit secure for example.
 *
 * @param Request $request
 * @param Router  $router
 *
 * @return array
 */
protected function getShowFilterParameters(Request $request, Router $router)
{
    return [
        'parameters'  => $this->getActionConditions($router)->toArray(),
    ];
}

/**
 * Extend index response.
 *
 * TODO redeclare this function in controller and return extended information.
 *
 * @param Request $request
 * @param Router  $router
 *
 * @return array
 */
protected function extendShowResponse(Request $request, Router $router)
{
    return [ ];
}

如果您的模型在路由中使用不是 id 的任何其他参数,请重写模型中的标准 Laravel 函数 - getRouteKeyName

/**
 * Return route key name.
 *
 * @return string
 */
public function getRouteKeyName()
{
    return 'uri';
}

很多人在自己的路由器中使用绑定,但对于交易来说,这相当困难。为了限制当前正在工作的模型绑定的范围,重写以下函数并添加自己的限制。此函数在所有需要处理当前已安装模型和从路由器中提取参数的函数中使用

 /**
 * Return model for actions.
 *
 * TODO redeclare this function and append more secure db request if needed.
 *
 * @param $id
 *
 * @return mixed
 */
protected function getModelForActions($id, Model $model, Request $request)
{
     // Check if we receive current REST model.
    if($model->is($this->restMakeModel())){
        $query =  $this->getBaseFilterQuery($request);
    }else{
        $query = $model->newQuery();
    }

    return $query->where($model->getRouteKeyName(), $id)->firstOrFail();
}

对于其他请求,例如索引、显示、更新和删除,可以重写函数 getBaseFilterQuery

 /**
  * Return base query builder.
  *
  * @param $actionName - name of the action from actions array.
  * @param Request $request
  *                    
  * @return \Illuminate\Database\Eloquent\Builder
  */
 protected function getBaseFilterQuery(Request $request)
 {
     return $this->restMakeModel()->newQuery();
 }

如你所见,函数接收当前操作名称作为输入,因此可以创建任何基本请求,包括创建、更新和删除等操作。

控制器继承

在直接继承的情况下,可能会遇到需要添加缺失动作的情况。为了避免重复整个 actions 数组

    /**
     * Return extended actions.
     *
     * @param Router $router
     *
     * @return array
     */
    public function getActions(Router $router)
    {
        $actions = parent::getActions($router); // parent - Расширяемый контроллер.

        return array_merge($actions, [
            'store' => [
                'request'     => CampaignRequest::class,
                'transformer' => CampaignResource::class,
            ],
        ]);
    }

方法 getActions 在选择要调用的方法时只调用一次。请确保连接到扩展方法的方法。
在继承时,我们通常会更改验证请求。因此,添加了一个变量 - restActionsRequest
示例

    class UserController extends CoreController
    {
    
        use IndexAction;
    
    
        /**
         * Main request class.
         *
         * @var string
         */
        protected $restActionsRequest = UserRequest::class;
    
        /**
         * Possible actions.
         *
         * @var array
         */
        protected $actions = [
            'index'   => [
                'onlyAjax'    => true,
                'transformer' => UserResource::class,
            ],
        ];
        
        /**
         * UserController constructor.
         *
         * @param UserRepository $repository
         */
        public function __construct(UserRepository $repository)
        {
    
            $this->repository = $repository;
        }
    }
    
    class PostOwnerController extends UserController
    {
        /**
         * Main request class.
         *
         * @var string
         */
        protected $restActionsRequest = PostOwnerRequest::class;
    
    
        /**
         * PostOwnerRepository constructor.
         *
         * @param PostOwnerRepository $repository
         */
        public function __construct(PostOwnerRepository $repository)
        {
            parent::__construct($repository);
        }
    
        /**
         * Return base filter builder.
         *
         * @param $actionName
         *
         * @return \Illuminate\Database\Eloquent\Builder
         */
        protected function getBaseFilterQuery(Request $request)
        {
            return $this->repository->newQuery()->hasPermission([ Permission::CAN_OWN_POST ]);
        }
    }

重要:在上面的示例中,仓库必须是父控制器仓库的继承者。

通过在其他控制器中创建控制器实例进行扩展

对于索引和显示函数,可以提供额外的配置转换。例如,您可能需要创建一个控制器类实例,从数据库中选择数据,但以改变回答的方式,使其符合您的需求。在这种情况下,您可以使用键 - ajaxTransform

'index'   => [
    'request'    => CourseRequest::class,
    'view'       => '',
    'ajaxTransform' => false,
    'conditions' => [
        'limit' => 20,
    ],
],
$response = app(CourseController::class)->index($router);

if($response instanceof Collection){
    //return response for filter and change it
    //or render spesific view with collectioned data or transform it for your self.

}

//return view
return $response;

同样,也可以在调用动作之前设置所需动作的可变参数

app(CourseController::class)
    ->setActionView('index', 'frontend.filter.sub_category')
    ->setActionRepositoryMethod('index', 'newMethodName')
    ->setActionConditions('index', [ 'limit' => 20 ])
    ->setActionParameters('index', [ 'course' => SubCategory::class ])
    ->index($router);

缓存

缓存在每个选择动作的每个动作中都是可用的 - index, show

'index'   => [
    'request'    => CourseRequest::class,
    'cache' => [
        'time' => 120, // in secs
        'tags' => 'courses_list' // tag is not available on all cache drivers, but always required field.
    ]
],

有任何问题,请通过电子邮件联系 - yurenery@gmail.com

动作管理

控制器中指定的任何动作都会扩展这些参数

[
    'request' => Request::class,
    'model' => null, 
    'view' => null,
    'conditions' => [],
    'transformer' => Resource::class,
    'ajaxTransform' => true,
    'simpleView' => false,
    'onlyAjax' => false,
    'onlyBrowser' => false,
    'cache' => [
        'time' => false,
        'tag' => null
    ],
    'protectedLimit' => self::$PROTECTED_LIMIT,
    
]   

说明

  • request - 验证请求的请求
  • model - 重写模型以处理请求。 NULL - 如果指定了仓库或定义了全局模型。
  • view - 请求的视图(按照 blade 规则)需要在前端对无 json 请求做出响应。
  • conditions - 额外的静态过滤参数。
  • transformer - 特定动作的变压器类参数。如果没有指定,则使用普通的 toArray。
  • ajaxTransform - 参数确定是否调用变压器来获取该方法的响应信息。如果指定为 false - 则使用 toArray()。
  • simpleView - 参数确定是否在请求 HTML 页面时仅加载页面,而不进行数据库连接和过滤。data = collection([])。
  • onlyAjax - 参数确定是否仅在请求 JSON 数据时工作,并使用相应的 headers。
  • onlyBrowser - 参数确定是否仅在请求 HTML 页面时工作。
  • cache - 缓存参数数组。见上文。
  • protectedLimit - 重写最大可能选择数据的单个选择限制的参数。用于防止在未分页的情况下从数据库中选择大量数据时服务器挂起。也可以通过重写全局变量 protected static $PROTECTED_LIMIT 设置全局限制,默认为 100 条记录;
  • sextantRestrictions - Sextant 约束的集成。有关更详细的信息,请阅读 sextant 过滤器文档的相应部分。