rinvex / laravel-subscriptions

⚠️ [ABANDONED] Rinvex Subscribable is a flexible plans and subscription management system for Laravel, with the required tools to run your SAAS like services efficiently. It's simple architecture, accompanied by powerful underlying to afford solid platform for your business.
MIT License
727 stars 347 forks source link

Fix feature validation when feature doesn't exist #171

Closed jecovier closed 2 years ago

jecovier commented 3 years ago

Description

Fix the exception caused by trying to access getKey() method on a null feature. This error occurs when you try to check a feature that does not exist in the subscription.

Error

Error occurs when you try to check a feature using canUseFeature() method. If the feature you try to check doesn't exist in the subscription, it gets this exception:

{
    "message": "Call to a member function getKey() on null",
    "exception": "Error",
    "file": "D:\\negocios\\touristock\\app\\vendor\\rinvex\\laravel-subscriptions\\src\\Models\\PlanSubscriptionUsage.php",
    "line": 138,
    "trace": [
        {
            "file": "D:\\negocios\\touristock\\app\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Eloquent\\Model.php",
            "line": 1467,
            "function": "scopeByFeatureSlug",
            "class": "Rinvex\\Subscriptions\\Models\\PlanSubscriptionUsage",
            "type": "->"
        },
        {
            "file": "D:\\negocios\\touristock\\app\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Eloquent\\Builder.php",
            "line": 1206,
            "function": "callNamedScope",
            "class": "Illuminate\\Database\\Eloquent\\Model",
            "type": "->"
        },
        {
            "file": "D:\\negocios\\touristock\\app\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Eloquent\\Builder.php",
            "line": 1187,
            "function": "Illuminate\\Database\\Eloquent\\{closure}",
            "class": "Illuminate\\Database\\Eloquent\\Builder",
            "type": "->"
        },
        {
            "file": "D:\\negocios\\touristock\\app\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Eloquent\\Builder.php",
            "line": 1205,
            "function": "callScope",
            "class": "Illuminate\\Database\\Eloquent\\Builder",
            "type": "->"
        },
        {
            "file": "D:\\negocios\\touristock\\app\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Eloquent\\Builder.php",
            "line": 1637,
            "function": "callNamedScope",
            "class": "Illuminate\\Database\\Eloquent\\Builder",
            "type": "->"
        },
        {
            "file": "D:\\negocios\\touristock\\app\\vendor\\laravel\\framework\\src\\Illuminate\\Support\\Traits\\ForwardsCalls.php",
            "line": 23,
            "function": "__call",
            "class": "Illuminate\\Database\\Eloquent\\Builder",
            "type": "->"
        },
        {
            "file": "D:\\negocios\\touristock\\app\\vendor\\laravel\\framework\\src\\Illuminate\\Support\\Traits\\ForwardsCalls.php",
            "line": 52,
            "function": "forwardCallTo",
            "class": "Illuminate\\Database\\Eloquent\\Relations\\Relation",
            "type": "->"
        },
        {
            "file": "D:\\negocios\\touristock\\app\\vendor\\laravel\\framework\\src\\Illuminate\\Database\\Eloquent\\Relations\\Relation.php",
            "line": 481,
            "function": "forwardDecoratedCallTo",
            "class": "Illuminate\\Database\\Eloquent\\Relations\\Relation",
            "type": "->"
        },
        {
            "file": "D:\\negocios\\touristock\\app\\vendor\\rinvex\\laravel-subscriptions\\src\\Models\\PlanSubscription.php",
            "line": 503,
            "function": "__call",
            "class": "Illuminate\\Database\\Eloquent\\Relations\\Relation",
            "type": "->"
        },
        {
            "file": "D:\\negocios\\touristock\\app\\app\\Models\\User.php",
            "line": 143,
            "function": "canUseFeature",
            "class": "Rinvex\\Subscriptions\\Models\\PlanSubscription",
            "type": "->"
        },
        ...
    ]
}

The exception is caused by this line:

return $builder->where('feature_id', $feature->getKey() ?? null);

the problem is null coalescing operator ( ?? ) check if the previous variable is set or not null, trying to access a method on a null object(as in the code above) throw a exception that is not catch by the null coalescing operator.

Solutions

one posible solution is replace the null coalescing operator with a ternary operator:

return $builder->where('feature_id', $feature ? $feature->getKey() : null);

This works as expected returning null in case no feature is found.

codeclimate[bot] commented 3 years ago

Code Climate has analyzed commit c9185a51 and detected 0 issues on this pull request.

View more on Code Climate.