Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
CRAP
100.00% covered (success)
100.00%
1 / 1
PolicyTrait
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
6
100.00% covered (success)
100.00%
1 / 1
 can
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
6
1<?php
2declare(strict_types=1);
3/**
4 * Pop PHP Framework (https://www.popphp.org/)
5 *
6 * @link       https://github.com/popphp/popphp-framework
7 * @author     Nick Sagona, III <nick@popphp.org>
8 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
9 * @license    https://www.popphp.org/license     New BSD License
10 */
11
12/**
13 * @namespace
14 */
15namespace Pop\Acl\Policy;
16
17use Pop\Acl\AclResource;
18
19/**
20 * Policy trait
21 *
22 * @category   Pop
23 * @package    Pop\Acl
24 * @author     Nick Sagona, III <nick@popphp.org>
25 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
26 * @license    https://www.popphp.org/license     New BSD License
27 * @version    5.0.0
28 * @phpstan-require-implements PolicyInterface
29 */
30trait PolicyTrait
31{
32
33    /**
34     * Evaluate policy
35     *
36     * @param  string       $method
37     * @param  ?AclResource $resource
38     * @throws Exception
39     * @return bool|null
40     */
41    public function can(string $method, ?AclResource $resource = null): bool|null
42    {
43        $result  = null;
44        $methods = (str_contains($method, ',')) ?
45            array_map('trim', explode(',', $method)) : [$method];
46
47        // Validate all methods are callable first
48        foreach ($methods as $method) {
49            if (!is_callable([$this, $method])) {
50                throw new Exception(
51                    "Error: The policy method '" . $method . "' is not callable on '" . static::class . "'."
52                );
53            }
54        }
55
56        // Now call all methods
57        foreach ($methods as $method) {
58            $result = $this->{$method}($this, $resource);
59
60            if ($result === false) {
61                return false;
62            }
63        }
64
65        return $result;
66    }
67
68}