自定义 PHPStan rul l 允许仅从特定类调用类方法

问题描述 投票:0回答:1

我正在尝试编写一个自定义 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

php reflection phpstan
1个回答
0
投票

为什么不直接覆盖购物车的

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

© www.soinside.com 2019 - 2024. All rights reserved.