• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

php-casbin / laminas-db-adapter / 15495989240

06 Jun 2025 05:13PM UTC coverage: 94.737% (-2.8%) from 97.561%
15495989240

push

github

web-flow
Merge pull request #6 from php-casbin/develop

feat: upgrade php-casbin 4.0

72 of 76 relevant lines covered (94.74%)

48.08 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.74
/src/Adapter.php
1
<?php
2

3
namespace CasbinAdapter\LaminasDb;
4

5
use Casbin\Persist\Adapter as AdapterContract;
6
use Casbin\Persist\BatchAdapter as BatchAdapterContract;
7
use Casbin\Persist\FilteredAdapter as FilteredAdapterContract;
8
use Casbin\Persist\AdapterHelper;
9
use Laminas\Db\Adapter\AdapterInterface as LaminasDbAdapterInterface;
10
use Laminas\Db\Adapter\Adapter as LaminasDbAdapter;
11
use Laminas\Db\TableGateway\TableGateway;
12
use Laminas\Db\TableGateway\TableGatewayInterface;
13
use Laminas\Db\Sql\Select;
14
use Casbin\Model\Model;
15
use Casbin\Persist\Adapters\Filter;
16
use Casbin\Exceptions\InvalidFilterTypeException;
17

18
/**
19
 * Laminas DB Adapter for Casbin.
20
 *
21
 * @author techlee@qq.com
22
 */
23
class Adapter implements AdapterContract, BatchAdapterContract, FilteredAdapterContract
24
{
25
    use AdapterHelper;
26

27
    /**
28
     * @var bool
29
     */
30
    private $filtered = false;
31

32
    /**
33
     * @var TableGatewayInterface
34
     */
35
    protected $tableGateway;
36

37
    /**
38
     * @var LaminasDbAdapterInterface
39
     */
40
    protected $dbAdapter;
41

42
    /**
43
     * default table name.
44
     *
45
     * @var string
46
     */
47
    public $casbinRuleTableName = 'casbin_rule';
48

49
    /**
50
     * the Adapter constructor.
51
     *
52
     * @param TableGatewayInterface|LaminasDbAdapterInterface|array $config
53
     */
54
    public function __construct($config)
55
    {
56
        if ($config instanceof TableGatewayInterface) {
180✔
57
            $this->tableGateway = $config;
18✔
58
        } else {
59
            if ($config instanceof LaminasDbAdapterInterface) {
162✔
60
                $dbAdapter = $config;
18✔
61
            } else {
62
                $dbAdapter = new LaminasDbAdapter($config);
144✔
63
            }
64

65
            $this->tableGateway = new TableGateway($this->casbinRuleTableName, $dbAdapter);
162✔
66
        }
67
    }
68

69
    /**
70
     * Initialize a new Adapter.
71
     *
72
     * @param TableGatewayInterface|LaminasDbAdapterInterface|array $config
73
     */
74
    public static function newAdapter($config)
75
    {
76
        return new static($config);
180✔
77
    }
78

79
    /**
80
     * gets TableGateway.
81
     *
82
     * @return TableGatewayInterface
83
     */
84
    public function getTableGateway()
85
    {
86
        return $this->tableGateway;
×
87
    }
88

89
    /**
90
     * savePolicyLine function.
91
     *
92
     * @param string $ptype
93
     * @param array  $rule
94
     */
95
    public function savePolicyLine($ptype, array $rule)
96
    {
97
        $col['ptype'] = $ptype;
54✔
98
        foreach ($rule as $key => $value) {
54✔
99
            $col['v'.strval($key).''] = $value;
54✔
100
        }
101

102
        $this->tableGateway->insert($col);
54✔
103
    }
104

105
    /**
106
     * loads all policy rules from the storage.
107
     *
108
     * @param Model $model
109
     */
110
    public function loadPolicy($model): void
111
    {
112
        $rows = $this->tableGateway->select(function (Select $select) {
180✔
113
            $select->columns(['ptype', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5']);
180✔
114
        })->toArray();
180✔
115

116
        foreach ($rows as $row) {
180✔
117
            $line = implode(', ', array_filter($row, function ($val) {
180✔
118
                return '' != $val && !is_null($val);
180✔
119
            }));
180✔
120
            $this->loadPolicyLine(trim($line), $model);
180✔
121
        }
122
    }
123

124
    /**
125
     * saves all policy rules to the storage.
126
     *
127
     * @param Model $model
128
     *
129
     * @return bool
130
     */
131
    public function savePolicy($model): void
132
    {
133
        foreach ($model['p'] as $ptype => $ast) {
18✔
134
            foreach ($ast->policy as $rule) {
18✔
135
                $this->savePolicyLine($ptype, $rule);
18✔
136
            }
137
        }
138

139
        foreach ($model['g'] as $ptype => $ast) {
18✔
140
            foreach ($ast->policy as $rule) {
18✔
141
                $this->savePolicyLine($ptype, $rule);
×
142
            }
143
        }
144
    }
145

146
    /**
147
     * Adds a policy rule to the storage.
148
     * This is part of the Auto-Save feature.
149
     *
150
     * @param string $sec
151
     * @param string $ptype
152
     * @param array  $rule
153
     *
154
     * @return mixed
155
     */
156
    public function addPolicy($sec, $ptype, $rule): void
157
    {
158
        $this->savePolicyLine($ptype, $rule);
36✔
159
    }
160

161
    /**
162
     * Adds a policy rules to the storage.
163
     * This is part of the Auto-Save feature.
164
     *
165
     * @param string $sec
166
     * @param string $ptype
167
     * @param string[][] $rules
168
     */
169
    public function addPolicies(string $sec, string $ptype, array $rules): void
170
    {
171
        $columns = ['ptype', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5'];
18✔
172
        $values = [];
18✔
173
        $sets = [];
18✔
174
        $columnsCount = count($columns);
18✔
175
        foreach ($rules as $rule) {
18✔
176
            array_unshift($rule, $ptype);
18✔
177
            $values = array_merge($values, array_pad($rule, $columnsCount, null));
18✔
178
            $sets[] = array_pad([], $columnsCount, '?');
18✔
179
        }
180
        $valuesStr = implode(', ', array_map(function ($set) {
18✔
181
            return '(' . implode(', ', $set) . ')';
18✔
182
        }, $sets));
18✔
183
        $sql = 'INSERT INTO ' . $this->casbinRuleTableName . ' (' . implode(', ', $columns) . ')' . ' VALUES' . $valuesStr;
18✔
184
        
185
        $driver = $this->tableGateway->adapter->getDriver();
18✔
186
        $statement = $driver->createStatement($sql);
18✔
187
        $result = $statement->execute($values);
18✔
188
    }
189

190
    /**
191
     * This is part of the Auto-Save feature.
192
     *
193
     * @param string $sec
194
     * @param string $ptype
195
     * @param array  $rule
196
     */
197
    public function removePolicy($sec, $ptype, $rule): void
198
    {
199
        $where['ptype'] = $ptype;
18✔
200
        foreach ($rule as $key => $value) {
18✔
201
            $where['v'.strval($key)] = $value;
18✔
202
        }
203

204
        $this->tableGateway->delete($where);
18✔
205
    }
206

207
    /**
208
     * Removes policy rules from the storage.
209
     * This is part of the Auto-Save feature.
210
     *
211
     * @param string $sec
212
     * @param string $ptype
213
     * @param string[][] $rules
214
     */
215
    public function removePolicies(string $sec, string $ptype, array $rules): void
216
    {
217
        $this->tableGateway->adapter->getDriver()->getConnection()->beginTransaction(function () use ($sec, $ptype, $rules) {
18✔
218
            foreach ($rules as $rule) {
×
219
                $this->removePolicy($sec, $ptype, $rule);
×
220
            }
221
        });
18✔
222
    }
223

224
    /**
225
     * RemoveFilteredPolicy removes policy rules that match the filter from the storage.
226
     * This is part of the Auto-Save feature.
227
     *
228
     * @param string $sec
229
     * @param string $ptype
230
     * @param int    $fieldIndex
231
     * @param mixed  ...$fieldValues
232
     */
233
    public function removeFilteredPolicy($sec, $ptype, $fieldIndex, ...$fieldValues): void
234
    {
235
        $where['ptype'] = $ptype;
18✔
236
        foreach (range(0, 5) as $value) {
18✔
237
            if ($fieldIndex <= $value && $value < $fieldIndex + count($fieldValues)) {
18✔
238
                if ('' != $fieldValues[$value - $fieldIndex]) {
18✔
239
                    $where['v'.strval($value)] = $fieldValues[$value - $fieldIndex];
18✔
240
                }
241
            }
242
        }
243

244
        $this->tableGateway->delete($where);
18✔
245
    }
246

247
    /**
248
     * Loads only policy rules that match the filter.
249
     *
250
     * @param Model $model
251
     * @param mixed $filter
252
     */
253
    public function loadFilteredPolicy(Model $model, $filter): void
254
    {
255
        if (is_string($filter)) {
18✔
256
            $where = $filter;
18✔
257
        } elseif ($filter instanceof Filter) {
18✔
258
            foreach ($filter->p as $k => $v) {
18✔
259
                $where[$v] = $filter->g[$k];
18✔
260
            }
261
        } elseif ($filter instanceof \Closure) {
18✔
262
            $where = $filter;
18✔
263
        } else {
264
            throw new InvalidFilterTypeException('invalid filter type');
18✔
265
        }
266
        $rows = $this->tableGateway->select($where)->toArray();
18✔
267

268
        foreach ($rows as $row) {
18✔
269
            $row = array_filter($row, function ($value) {
18✔
270
                return !is_null($value) && $value !== '';
18✔
271
            });
18✔
272
            $line = implode(', ', array_filter($row, function ($val) {
18✔
273
                return '' != $val && !is_null($val);
18✔
274
            }));
18✔
275
            $this->loadPolicyLine(trim($line), $model);
18✔
276
        }
277
        $this->setFiltered(true);
18✔
278
    }
279

280
    /**
281
     * Returns true if the loaded policy has been filtered.
282
     *
283
     * @return bool
284
     */
285
    public function isFiltered(): bool
286
    {
287
        return $this->filtered;
180✔
288
    }
289

290
    /**
291
     * Sets filtered parameter.
292
     *
293
     * @param bool $filtered
294
     */
295
    public function setFiltered(bool $filtered): void
296
    {
297
        $this->filtered = $filtered;
18✔
298
    }
299
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc