我正在尝试编写一个自定义 phpstan 规则,不允许其他开发人员从代码库中的任何位置调用
Cart::save()
($cart->save()
),而只能从 CartRepository
调用,如果它是在存储库之外调用的,我想要看到类似 Calling Cart::save() method outside of CartRepository class is not allowed.
的错误
我尝试做这样的事情
class CartSaveRule implements Rule
{
public function getNodeType(): string
{
return MethodCall::class;
}
/**
* @param MethodCall $node
* @param Scope $scope
* @return array
*/
public function processNode(Node $node, Scope $scope): array
{
// Check if the method call is to the "save" method
if ($node->name->toString() === 'save') {
$className = $scope->getClassReflection()->getName();
// Check if the method call is made from the Product class
if ($className === 'Cart') {
// Get the method call location
$line = $node->getLine();
$file = $scope->getFile();
// Check if the method call is not made from inside the ProductRepository class
if (!$this->isCalledFromProductRepository($scope)) {
return [
RuleErrorBuilder::message('Calling save() method of Cart class outside of CartRepository class is not allowed.')
->line($line)
->file($file)
->build()
];
}
}
}
return [];
}
private function isCalledFromRepository(Scope $scope): bool
{
// Check if the calling class is CartRepository or its subclass
return $scope->getClassReflection()->isSubclassOf('CartRepository');
}
}
但它没有像我预期的那样工作,让我们说在
Cart
我有一个方法:
private function updateVariant()
{
$variant = Variant::
->where('id', '=', $this->variantId)
->first();
// logic to update variant
$variant->save();
}
我的规则会在网上尖叫
$variant->save();
,因为save
是由Cart
调用的,但它与Cart
无关save
为什么不直接覆盖购物车的
save()
方法呢?像这样的东西:
<?php
class Cart
{
public function save(object $repo = null)
{
if ($repo === null || !$repo instanceof CartRepository) {
throw new Exception('Save the cart using the CartRepository' . "\n");
}
$repo->save($this);
}
}
class CartRepository
{
public function save(Cart $cart)
{
return 'saved!';
}
}
$repo = new CartRepository();
$cart = new Cart();
try {
$cart->save();
} catch (Exception $e) {
echo $e->getMessage();
}
echo $repo->save($cart);
这将输出:
Save the cart using the CartRepository
saved!
您可以在这里尝试一下https://3v4l.org/uHW1e