Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
9 / 9
CRAP
100.00% covered (success)
100.00%
1 / 1
AclForm
100.00% covered (success)
100.00%
30 / 30
100.00% covered (success)
100.00%
9 / 9
17
100.00% covered (success)
100.00%
1 / 1
 setAcl
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setRole
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addRole
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 addRoles
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 setAclStrict
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setPermissions
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 isAclStrict
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPermissions
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 render
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
8
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\Form;
16
17use Pop\Acl\Acl;
18use Pop\Acl\AclRole;
19use ReturnTypeWillChange;
20
21/**
22 * ACL Form class
23 *
24 * @category   Pop
25 * @package    Pop\Form
26 * @author     Nick Sagona, III <nick@popphp.org>
27 * @copyright  Copyright (c) 2009-2026 Nick Sagona, III
28 * @license    https://www.popphp.org/license     New BSD License
29 * @version    5.0.0
30 */
31
32class AclForm extends Form
33{
34
35    /**
36     * Acl object
37     * @var ?Acl
38     */
39    protected ?Acl $acl = null;
40
41    /**
42     * AclRole role objects
43     * @var array
44     */
45    protected array $roles = [];
46
47    /**
48     * Acl strict flag
49     * @var bool
50     */
51    protected bool $aclStrict = false;
52
53    /**
54     * Acl flag to manage how to display/manage fields
55     * @var array
56     */
57    protected array $permissions = [
58        'display' => 'view', // permission to display a field
59        'modify'  => 'edit'  // permission to modify a field
60    ];
61
62    /**
63     * Set the Acl object
64     *
65     * @param  ?Acl $acl
66     * @return AclForm
67     */
68    public function setAcl(?Acl $acl = null): AclForm
69    {
70        $this->acl = $acl;
71        return $this;
72    }
73
74    /**
75     * Set a AclRole object (alias method)
76     *
77     * @param  ?AclRole $role
78     * @return AclForm
79     */
80    public function setRole(?AclRole $role = null): AclForm
81    {
82        $this->roles[$role->getName()] = $role;
83        return $this;
84    }
85
86    /**
87     * Add a AclRole object
88     *
89     * @param  ?AclRole $role
90     * @return AclForm
91     */
92    public function addRole(?AclRole $role = null): AclForm
93    {
94        return $this->setRole($role);
95    }
96
97    /**
98     * Add AclRole objects
99     *
100     * @param  array $roles
101     * @return AclForm
102     */
103    public function addRoles(array $roles): AclForm
104    {
105        foreach ($roles as $role) {
106            $this->setRole($role);
107        }
108
109        return $this;
110    }
111
112    /**
113     * Set the Acl object as strict evaluation
114     *
115     * @param  bool $strict
116     * @return AclForm
117     */
118    public function setAclStrict(bool $strict): AclForm
119    {
120        $this->aclStrict = $strict;
121        return $this;
122    }
123
124    /**
125     * Set the Acl field permissions
126     *
127     * @param  string $displayPermission
128     * @param  string $modifyPermission
129     * @return AclForm
130     */
131    public function setPermissions(string $displayPermission, string $modifyPermission): AclForm
132    {
133        $this->permissions['display'] = $displayPermission;
134        $this->permissions['modify']  = $modifyPermission;
135
136        return $this;
137    }
138
139    /**
140     * Is the Acl object set to strict evaluation
141     *
142     * @return bool
143     */
144    public function isAclStrict(): bool
145    {
146        return $this->aclStrict;
147    }
148    /**
149     * Get field permissions
150     *
151     * @return array
152     */
153    public function getPermissions(): array
154    {
155        return $this->permissions;
156    }
157
158    /**
159     * Render the form object
160     *
161     * @param  int     $depth
162     * @param  ?string $indent
163     * @param  bool    $inner
164     * @return string|null
165     */
166    public function render(int $depth = 0, ?string $indent = null, bool $inner = false): string|null
167    {
168        foreach ($this->fieldsets as $fieldset) {
169            foreach ($fieldset->getAllFields() as $field) {
170                $fieldName   = $field->getName();
171                if ($this->acl->hasResource($fieldName)) {
172                    $viewDenied = ($this->aclStrict) ?
173                        $this->acl->isDeniedMultiStrict($this->roles, $fieldName, $this->permissions['display']) :
174                        $this->acl->isDeniedMulti($this->roles, $fieldName, $this->permissions['display']);
175
176                    if ($viewDenied) {
177                        unset($fieldset[$fieldName]);
178                    } else {
179                        $modifyDenied = ($this->aclStrict) ?
180                            $this->acl->isDeniedMultiStrict($this->roles, $fieldName, $this->permissions['modify']) :
181                            $this->acl->isDeniedMulti($this->roles, $fieldName, $this->permissions['modify']);
182                        if ($modifyDenied) {
183                            $field->setReadonly(true);
184                        }
185                    }
186                }
187            }
188        }
189
190        return parent::render($depth, $indent, $inner);
191    }
192
193}