| 
6 | 6 | use Casbin\Model\Model;  | 
7 | 7 | use Casbin\Persist\Adapter as AdapterContract;  | 
8 | 8 | use Casbin\Persist\BatchAdapter as BatchAdapterContract;  | 
 | 9 | +use Casbin\Persist\FilteredAdapter as FilteredAdapterContract;  | 
9 | 10 | use Casbin\Persist\AdapterHelper;  | 
 | 11 | +use Casbin\Persist\Adapters\Filter;  | 
 | 12 | +use Casbin\Exceptions\InvalidFilterTypeException;  | 
10 | 13 | 
 
  | 
11 | 14 | /**  | 
12 | 15 |  * DatabaseAdapter.  | 
13 | 16 |  *  | 
14 | 17 |  | 
15 | 18 |  */  | 
16 |  | -class Adapter implements AdapterContract, BatchAdapterContract  | 
 | 19 | +class Adapter implements AdapterContract, BatchAdapterContract, FilteredAdapterContract  | 
17 | 20 | {  | 
18 | 21 |     use AdapterHelper;  | 
19 | 22 | 
 
  | 
20 | 23 |     protected $casbinRule;  | 
21 | 24 | 
 
  | 
 | 25 | +    /**  | 
 | 26 | +     * @var bool  | 
 | 27 | +     */  | 
 | 28 | +    private $filtered = false;  | 
 | 29 | + | 
22 | 30 |     public function __construct(CasbinRule $casbinRule)  | 
23 | 31 |     {  | 
24 | 32 |         $this->casbinRule = $casbinRule;  | 
@@ -181,4 +189,60 @@ public function removeFilteredPolicy(string $sec, string $ptype, int $fieldIndex  | 
181 | 189 | 
 
  | 
182 | 190 |         $this->casbinRule->deleteAll($where);  | 
183 | 191 |     }  | 
 | 192 | + | 
 | 193 | +    /**  | 
 | 194 | +     * Loads only policy rules that match the filter.  | 
 | 195 | +     *  | 
 | 196 | +     * @param Model $model  | 
 | 197 | +     * @param mixed $filter  | 
 | 198 | +     */  | 
 | 199 | +    public function loadFilteredPolicy(Model $model, $filter): void  | 
 | 200 | +    {  | 
 | 201 | +        $entity = clone $this->casbinRule;  | 
 | 202 | +        $entity = $entity->find();  | 
 | 203 | + | 
 | 204 | +        if (is_string($filter)) {  | 
 | 205 | +            $entity->where($filter);  | 
 | 206 | +        } elseif ($filter instanceof Filter) {  | 
 | 207 | +            foreach ($filter->p as $k => $v) {  | 
 | 208 | +                $where[$v] = $filter->g[$k];  | 
 | 209 | +                $entity->where([$v => $filter->g[$k]]);  | 
 | 210 | +            }  | 
 | 211 | +        } elseif ($filter instanceof \Closure) {  | 
 | 212 | +            $filter($entity);  | 
 | 213 | +        } else {  | 
 | 214 | +            throw new InvalidFilterTypeException('invalid filter type');  | 
 | 215 | +        }  | 
 | 216 | + | 
 | 217 | +        $rows = $entity->all();  | 
 | 218 | +        foreach ($rows as $row) {  | 
 | 219 | +            unset($row->id);  | 
 | 220 | +            $row = $row->toArray();  | 
 | 221 | +            $line = implode(', ', array_filter($row, function ($val) {  | 
 | 222 | +                return '' != $val && !is_null($val);  | 
 | 223 | +            }));  | 
 | 224 | +            $this->loadPolicyLine(trim($line), $model);  | 
 | 225 | +        }  | 
 | 226 | +        $this->setFiltered(true);  | 
 | 227 | +    }  | 
 | 228 | + | 
 | 229 | +    /**  | 
 | 230 | +     * Returns true if the loaded policy has been filtered.  | 
 | 231 | +     *  | 
 | 232 | +     * @return bool  | 
 | 233 | +     */  | 
 | 234 | +    public function isFiltered(): bool  | 
 | 235 | +    {  | 
 | 236 | +        return $this->filtered;  | 
 | 237 | +    }  | 
 | 238 | + | 
 | 239 | +    /**  | 
 | 240 | +     * Sets filtered parameter.  | 
 | 241 | +     *  | 
 | 242 | +     * @param bool $filtered  | 
 | 243 | +     */  | 
 | 244 | +    public function setFiltered(bool $filtered): void  | 
 | 245 | +    {  | 
 | 246 | +        $this->filtered = $filtered;  | 
 | 247 | +    }  | 
184 | 248 | }  | 
0 commit comments