| 
4 | 4 | 
 
  | 
5 | 5 | use Casbin\Persist\Adapter as AdapterContract;  | 
6 | 6 | use Casbin\Persist\BatchAdapter as BatchAdapterContract;  | 
 | 7 | +use Casbin\Persist\FilteredAdapter as FilteredAdapterContract;  | 
7 | 8 | use Casbin\Persist\AdapterHelper;  | 
8 | 9 | use Laminas\Db\Adapter\AdapterInterface as LaminasDbAdapterInterface;  | 
9 | 10 | use Laminas\Db\Adapter\Adapter as LaminasDbAdapter;  | 
10 | 11 | use Laminas\Db\TableGateway\TableGateway;  | 
11 | 12 | use Laminas\Db\TableGateway\TableGatewayInterface;  | 
12 | 13 | use Laminas\Db\Sql\Select;  | 
13 | 14 | use Casbin\Model\Model;  | 
 | 15 | +use Casbin\Persist\Adapters\Filter;  | 
 | 16 | +use Casbin\Exceptions\InvalidFilterTypeException;  | 
14 | 17 | 
 
  | 
15 | 18 | /**  | 
16 | 19 |  * Laminas DB Adapter for Casbin.  | 
17 | 20 |  *  | 
18 | 21 |  | 
19 | 22 |  */  | 
20 |  | -class Adapter implements AdapterContract, BatchAdapterContract  | 
 | 23 | +class Adapter implements AdapterContract, BatchAdapterContract, FilteredAdapterContract  | 
21 | 24 | {  | 
22 | 25 |     use AdapterHelper;  | 
23 | 26 | 
 
  | 
 | 27 | +    /**  | 
 | 28 | +     * @var bool  | 
 | 29 | +     */  | 
 | 30 | +    private $filtered = false;  | 
 | 31 | + | 
24 | 32 |     /**  | 
25 | 33 |      * @var TableGatewayInterface  | 
26 | 34 |      */  | 
@@ -235,4 +243,57 @@ public function removeFilteredPolicy($sec, $ptype, $fieldIndex, ...$fieldValues)  | 
235 | 243 | 
 
  | 
236 | 244 |         $this->tableGateway->delete($where);  | 
237 | 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)) {  | 
 | 256 | +            $where = $filter;  | 
 | 257 | +        } elseif ($filter instanceof Filter) {  | 
 | 258 | +            foreach ($filter->p as $k => $v) {  | 
 | 259 | +                $where[$v] = $filter->g[$k];  | 
 | 260 | +            }  | 
 | 261 | +        } elseif ($filter instanceof \Closure) {  | 
 | 262 | +            $where = $filter;  | 
 | 263 | +        } else {  | 
 | 264 | +            throw new InvalidFilterTypeException('invalid filter type');  | 
 | 265 | +        }  | 
 | 266 | +        $rows = $this->tableGateway->select($where)->toArray();  | 
 | 267 | + | 
 | 268 | +        foreach ($rows as $row) {  | 
 | 269 | +            $row = array_filter($row, function ($value) {  | 
 | 270 | +                return !is_null($value) && $value !== '';  | 
 | 271 | +            });  | 
 | 272 | +            $line = implode(', ', array_filter($row, function ($val) {  | 
 | 273 | +                return '' != $val && !is_null($val);  | 
 | 274 | +            }));  | 
 | 275 | +            $this->loadPolicyLine(trim($line), $model);  | 
 | 276 | +        }  | 
 | 277 | +        $this->setFiltered(true);  | 
 | 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;  | 
 | 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;  | 
 | 298 | +    }  | 
238 | 299 | }  | 
0 commit comments