Skip to content

Commit 8dc21ad

Browse files
committed
fix: refactor the logic of loadFilteredPolicy method
1 parent acf902c commit 8dc21ad

File tree

2 files changed

+52
-47
lines changed

2 files changed

+52
-47
lines changed

Diff for: src/Adapter.php

+31-35
Original file line numberDiff line numberDiff line change
@@ -229,51 +229,47 @@ public function removeFilteredPolicy(string $sec, string $ptype, int $fieldIndex
229229
*/
230230
public function loadFilteredPolicy(Model $model, $filter): void
231231
{
232-
// if $filter is empty, load all policies
233-
if (is_null($filter)) {
234-
$this->loadPolicy($model);
235-
return;
236-
}
237232
// the basic sql
238233
$sql = 'SELECT ptype, v0, v1, v2, v3, v4, v5 FROM '.$this->casbinRuleTableName . ' WHERE ';
239-
240-
if ($filter instanceof Filter) {
241-
$type = '';
242-
$filter = (array) $filter;
243-
// choose which ptype to use
244-
foreach($filter as $i => $v) {
245-
if (!empty($v)) {
246-
array_unshift($filter[$i], $i);
247-
$type = $i;
248-
break;
249-
}
250-
}
251-
$items = ['ptype', 'v0', 'v1', 'v2', 'v3', 'v4', 'v5'];
252-
$temp = [];
253-
$values = [];
254-
foreach($items as $i => $item) {
255-
if (isset($filter[$type][$i]) && !empty($filter[$type][$i])) {
256-
array_push($temp, $item . '=:' . $item);
257-
$values[$item] = $filter[$type][$i];
258-
}
234+
235+
$bind = [];
236+
237+
if (is_string($filter)) {
238+
$filter = str_replace(' ', '', $filter);
239+
$filter = str_replace('\'', '', $filter);
240+
$filter = explode('=', $filter);
241+
$sql .= "$filter[0] = :{$filter[0]}";
242+
$bind[$filter[0]] = $filter[1];
243+
} else if ($filter instanceof Filter) {
244+
foreach($filter->p as $k => $v) {
245+
$where[] = $v . ' = :' . $v;
246+
$bind[$v] = $filter->g[$k];
259247
}
260-
$sql .= implode(' and ', $temp);
261-
$rows = $this->connection->query($sql, $values);
262-
} elseif (is_string($filter)) {
263-
$sql .= $filter;
264-
$rows = $this->connection->query($sql);
248+
$where = implode(' AND ', $where);
249+
$sql .= $where;
265250
} else if ($filter instanceof Closure) {
266-
$filter($this->connection, $sql, $this->rows);
251+
$where = '';
252+
$filter($where);
253+
$where = str_replace(' ', '', $where);
254+
$where = str_replace('\'', '', $where);
255+
$where = explode('=', $where);
256+
$sql .= "$where[0] = :{$where[0]}";
257+
$bind[$where[0]] = $where[1];
267258
} else {
268259
throw new InvalidFilterTypeException('invalid filter type');
269260
}
270261

271-
$rows = $rows ?? $this->rows;
262+
$rows = $this->connection->query($sql, $bind);
272263
foreach($rows as $row) {
273-
$line = implode(', ', $row);
274-
$this->loadPolicyLine($line, $model);
264+
$row = array_filter($row, function($value) { return !is_null($value) && $value !== ''; });
265+
unset($row['id']);
266+
$line = implode(', ', array_filter($row, function ($val) {
267+
return '' != $val && !is_null($val);
268+
}));
269+
$this->loadPolicyLine(trim($line), $model);
275270
}
276-
$this->filtered = true;
271+
272+
$this->setFiltered(true);
277273
}
278274

279275
/**

Diff for: tests/AdapterTest.php

+21-12
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use PHPUnit\Framework\TestCase;
1010
use TechOne\Database\Manager;
1111
use Casbin\Persist\Adapters\Filter;
12+
use Casbin\Exceptions\InvalidFilterTypeException;
1213

1314
class AdapterTest extends TestCase
1415
{
@@ -85,34 +86,42 @@ public function testLoadPolicy()
8586
public function testLoadFilteredPolicy()
8687
{
8788
$this->initConfig();
88-
$adapter = DatabaseAdapter::newAdapter($this->config);
89-
$adapter->setFiltered(true);
90-
$e = $this->getEnforcerWithAdapter($adapter);
89+
$this->initDb(DatabaseAdapter::newAdapter($this->config));
90+
$e = $this->getEnforcer();
91+
$e->clearPolicy();
9192
$this->assertEquals([], $e->getPolicy());
9293

94+
// invalid filter type
95+
try {
96+
$filter = ['alice', 'data1', 'read'];
97+
$e->loadFilteredPolicy($filter);
98+
$exception = InvalidFilterTypeException::class;
99+
$this->fail("Expected exception $exception not thrown");
100+
} catch (InvalidFilterTypeException $exception) {
101+
$this->assertEquals("invalid filter type", $exception->getMessage());
102+
}
103+
93104
// string
94105
$filter = "v0 = 'bob'";
95106
$e->loadFilteredPolicy($filter);
96107
$this->assertEquals([
97-
//
98-
['bob', 'data2', 'write', '', '', '']
108+
['bob', 'data2', 'write']
99109
], $e->getPolicy());
100110

101111
// Filter
102-
$filter = new Filter(['', '', 'read']);
112+
$filter = new Filter(['v2'], ['read']);
103113
$e->loadFilteredPolicy($filter);
104114
$this->assertEquals([
105-
['alice', 'data1', 'read', '', '', ''],
106-
['data2_admin', 'data2', 'read', '', '', ''],
115+
['alice', 'data1', 'read'],
116+
['data2_admin', 'data2', 'read'],
107117
], $e->getPolicy());
108118

109-
// Closure
110-
$e->loadFilteredPolicy(function ($connection, $sql, &$rows) {
111-
$rows = $connection->query($sql . "v0 = 'alice'");
119+
$e->loadFilteredPolicy(function (&$sql) {
120+
$sql .= "v0 = 'alice'";
112121
});
113122

114123
$this->assertEquals([
115-
['alice', 'data1', 'read', '', '', ''],
124+
['alice', 'data1', 'read'],
116125
], $e->getPolicy());
117126
}
118127

0 commit comments

Comments
 (0)