lordphnx / ez-cake
一组用于增强频繁使用行为的CakePHP质量提升器
9.0.0
2023-10-04 14:51 UTC
Requires
- php: ^8.1
- ext-json: *
- cakephp/authorization: ^3
- cakephp/cakephp: ^5
Requires (Dev)
- illuminate/support: ^10
- phpunit/phpunit: ^8.0
This package is auto-updated.
Last update: 2024-09-28 18:58:33 UTC
README
EasyCake是一组库,用于使常见的CakePHP任务更简洁。它包括多个子项目
- EasyTest,用于辅助模拟ORM实体以进行测试用例
- EasyAuth,用于辅助编写
isAuthorized(User $user) : bool
方法 - ErrorPrevention,用于防止烦人的wordpress扫描器扰乱你的(Sentry)错误日志
为什么选择EasyCake
对于我的公司,我运行了大量的不同CakePHP项目,并且不断地重复编写相同的逻辑。所以我决定将它们放入一个库中。随着时间的推移,其他开发人员朋友开始借用这些库,所以我感觉是时候将这些开源了。
EasyTest
让我感到非常烦恼的是,当模拟具有大量字段实体的测试用例时,你通常只关心一两个字段。所以EasyTestTrait
的核心是createGeneric
方法。
以下代码将生成两个Project
实体,它们具有(主要)随机值,除了
- project1.name将name属性设置为"ExampleProject"
- project2.name将name属性设置为"ExampleProject2"
- 注意,这些实体实际上将被保存在它们相应的模型上。
- EasyTestTrait将检查表架构,并根据每列的类型生成随机值
$project1 = $this->genericCreate("Project",[
"name" => "ExampleProject"
]);
$project2 = $this->genericCreate("Project",[
"name" => "ExampleProject2"
]);
//Project1
Project {
"project_id" => 1,
"name" => "ExampleProject",
"is_premium" => true,
"size" => 5
}
Project {
"project_id" => 2,
"name" => "ExampleProject2",
"is_premium" => false,
"size" => 17
}
关系
有时你会有强制性的依赖关系,所以我会这样做
创建一个特定项目的测试特性(例如ProjectTestTrait.php
)
function createUser(array $overrides = []) : User{
return $this->genericCreate("Users", [
"password" => hash("sha256","stupidPassword")
], $overrides);
}
function createProject(User $owner, array $overrides = []) : Project {
return $this->genericCreate("Users", [
"owner_id" => $owner->user_id
], $overrides);
}
//create a User entity, and ensure it's is_admin property is set to true
$user = $this->createUser(['is_admin' => true]);
//create a project, using the created user as its owner
$project = $this->createProject($user);
EasyAuth
对我来说,最常见的授权方式如下
- 有人发起了一个请求,例如,
/projects/view/1
。 - 你需要确认当前登录的
User
是否与具有project_id =1
的Project
有特定的关系
使用EasyAuth,你只需要这样做
- 第一个参数是
Project
的标识符
GET请求
function isAuthorized(?User $user = null) : bool {
switch ($this->getRequest()->getAction()) {
case "view":
//Here we tell EasyAuth that param 0 should be used to ->get() on the Projects model.
return $this->easyAuth([0 => "Projects"], function (Project $project) {
return $project->isMember($user);
}) ;
default:
return parent::isAuthorized($user);
}
}
这可以更简洁地表示
$action = $this->getRequest()->getAction();
if ($action === "view") {
$this->loadModel("Projects");
try {
$project = $this->Projects->get($this->getRequest()->getParam(0));
return $project->isMember($user);
} catch (Exception e) {
return false;
}
}
这也具有优势,即可以将具有相同授权逻辑的多个操作分组在一起
function isAuthorized(?User $user = null) : bool {
switch ($this->getRequest()->getAction()) {
case "view":
case "delete":
case "edit":
//Here we tell EasyAuth that param 0 should be used to ->get() on the Projects model.
return $this->easyAuth([0 => "Projects"], function (Project $project) {
return $project->isMember($user);
}) ;
default:
return parent::isAuthorized($user);
}
}
POST请求
可以为POST请求执行与GET请求类似的操作,但参数的命名与POST名称相同
function isAuthorized(?User $user = null) : bool {
switch ($this->getRequest()->getAction()) {
case "view":
case "delete":
case "edit":
//Here we tell EasyAuth that post-param "project_id" should be used to ->get() on the Projects model.
return $this->eastPostAuth(["project_id" => "Projects"], function (Project $project) {
return $project->isMember($user);
}) ;
default:
return parent::isAuthorized($user);
}
}
ErrorPrevention
由于WordPress漏洞扫描器扰乱我的Sentry日志(或任何错误日志),我感到非常痛苦。所以我决定编写一些基本的规则,以防止每次从GET /wp-admin
或GET /rpc.php
获得ControllerNotFoundException
时,CakeSentry记录错误。这变成了一种可扩展的系统,可以轻松地忽略你明显不关心的错误。
//in Application.php
function buildMiddlewareQueue(MiddlewareQueue $middleWare) : MiddlewareQueue{
parent::buildMiddlewareQueue($middleWare);
$errorPrevention = new ErrorPreventionMiddleware();
$errorPrevention->add(WordpressRequests::class);
$errorPrevention->add(ASPRequests::class);
$errorPrevention->add(ExternalInvalidUrls::class);
$middleWare->add($errorPrevention);
return $middleWare;
}
- WordPressRequests将忽略所有与某人请求WordPress URL相关的异常
- ExternalInvalidUrl检查由于无效请求URL(例如
MissingControllerException
和ArgumentCountError
)而产生的异常。然后它会尝试确认此请求是由于我们的应用程序内的链接错误,还是某人手动输入了错误的URL(例如referer = /
)。在后一种情况下,这几乎不是我们应用程序的问题。因此,错误不是我们应用程序的错。 - ASPRequests 会忽略由用户请求
.asp
文件引起的所有异常