@@ -61,6 +61,26 @@ public function setFiltered(bool $filtered): void
6161 $ this ->filtered = $ filtered ;
6262 }
6363
64+ /**
65+ * Filter the rule.
66+ *
67+ * @param array $rule
68+ * @return array
69+ */
70+ public function filterRule (array $ rule ): array
71+ {
72+ $ rule = array_values ($ rule );
73+
74+ $ i = count ($ rule ) - 1 ;
75+ for (; $ i >= 0 ; $ i --) {
76+ if ($ rule [$ i ] != '' && !is_null ($ rule [$ i ])) {
77+ break ;
78+ }
79+ }
80+
81+ return array_slice ($ rule , 0 , $ i + 1 );
82+ }
83+
6484 public static function newAdapter (array $ config )
6585 {
6686 return new static ($ config );
@@ -195,16 +215,16 @@ public function removePolicy(string $sec, string $ptype, array $rule): void
195215 }
196216
197217 /**
198- * RemoveFilteredPolicy removes policy rules that match the filter from the storage.
199- * This is part of the Auto-Save feature.
200- *
201218 * @param string $sec
202219 * @param string $ptype
203- * @param int $fieldIndex
204- * @param string ...$fieldValues
220+ * @param int $fieldIndex
221+ * @param string|null ...$fieldValues
222+ * @return array
223+ * @throws Throwable
205224 */
206- public function removeFilteredPolicy (string $ sec , string $ ptype , int $ fieldIndex , string ...$ fieldValues ): void
225+ public function _removeFilteredPolicy (string $ sec , string $ ptype , int $ fieldIndex , ? string ...$ fieldValues ): array
207226 {
227+ $ removedRules = [];
208228 $ where ['ptype ' ] = $ ptype ;
209229 $ condition [] = 'ptype = :ptype ' ;
210230 foreach (range (0 , 5 ) as $ value ) {
@@ -216,9 +236,35 @@ public function removeFilteredPolicy(string $sec, string $ptype, int $fieldIndex
216236 }
217237 }
218238
219- $ sql = ' DELETE FROM ' . $ this ->casbinRuleTableName . ' WHERE ' . implode (' AND ' , $ condition );
239+ $ deleteSql = " DELETE FROM { $ this ->casbinRuleTableName } WHERE " . implode (' AND ' , $ condition );
220240
221- $ this ->connection ->execute ($ sql , $ where );
241+ $ selectSql = "SELECT * FROM {$ this ->casbinRuleTableName } WHERE " . implode (' AND ' , $ condition );
242+
243+ $ oldP = $ this ->connection ->query ($ selectSql , $ where );
244+ foreach ($ oldP as &$ item ) {
245+ unset($ item ['ptype ' ]);
246+ unset($ item ['id ' ]);
247+ $ item = $ this ->filterRule ($ item );
248+ $ removedRules [] = $ item ;
249+ }
250+
251+ $ this ->connection ->execute ($ deleteSql , $ where );
252+ return $ removedRules ;
253+ }
254+
255+ /**
256+ * RemoveFilteredPolicy removes policy rules that match the filter from the storage.
257+ * This is part of the Auto-Save feature.
258+ *
259+ * @param string $sec
260+ * @param string $ptype
261+ * @param int $fieldIndex
262+ * @param string ...$fieldValues
263+ * @throws Exception|Throwable
264+ */
265+ public function removeFilteredPolicy (string $ sec , string $ ptype , int $ fieldIndex , string ...$ fieldValues ): void
266+ {
267+ $ this ->_removeFilteredPolicy ($ sec , $ ptype , $ fieldIndex , ...$ fieldValues );
222268 }
223269
224270 /**
@@ -330,66 +376,27 @@ public function updatePolicies(string $sec, string $ptype, array $oldRules, arra
330376 }
331377
332378 /**
333- * UpdateFilteredPolicies deletes old rules and adds new rules.
334- *
335379 * @param string $sec
336380 * @param string $ptype
337- * @param array $newPolicies
338- * @param integer $fieldIndex
381+ * @param array $newRules
382+ * @param int $fieldIndex
339383 * @param string ...$fieldValues
340384 * @return array
385+ * @throws Throwable
341386 */
342- public function updateFilteredPolicies (string $ sec , string $ ptype , array $ newPolicies , int $ fieldIndex , string ...$ fieldValues ): array
387+ public function updateFilteredPolicies (string $ sec , string $ ptype , array $ newRules , int $ fieldIndex , ? string ...$ fieldValues ): array
343388 {
344- $ deleteWhere ['ptype ' ] = $ ptype ;
345- $ deleteCondition [] = 'ptype = :ptype ' ;
346- foreach ($ fieldValues as $ value ) {
347- $ key = $ fieldIndex ++;
348- if (!is_null ($ value ) && $ value !== '' ) {
349- $ placeholder = "v " . strval ($ key );
350- $ deleteWhere ['v ' . strval ($ key )] = $ value ;
351- $ deleteCondition [] = 'v ' . strval ($ key ) . ' = : ' . $ placeholder ;
352- }
353- }
354- $ deleteSql = "DELETE FROM {$ this ->casbinRuleTableName } WHERE " . implode (' AND ' , $ deleteCondition );
355-
356- $ selectSql = "SELECT * FROM {$ this ->casbinRuleTableName } WHERE " . implode (' AND ' , $ deleteCondition );
357- $ oldP = $ this ->connection ->query ($ selectSql , $ deleteWhere );
358- foreach ($ oldP as &$ item ) {
359- $ item = array_filter ($ item , function ($ value ) {
360- return !is_null ($ value ) && $ value !== '' ;
361- });
362- unset($ item ['ptype ' ]);
363- unset($ item ['id ' ]);
364- }
365-
366- $ columns = ['ptype ' , 'v0 ' , 'v1 ' , 'v2 ' , 'v3 ' , 'v4 ' , 'v5 ' ];
367- $ values = [];
368- $ sets = [];
369- $ columnsCount = count ($ columns );
370- foreach ($ newPolicies as $ newPolicy ) {
371- array_unshift ($ newPolicy , $ ptype );
372- $ values = array_merge ($ values , array_pad ($ newPolicy , $ columnsCount , null ));
373- $ sets [] = array_pad ([], $ columnsCount , '? ' );
374- }
375- $ valuesStr = implode (', ' , array_map (function ($ set ) {
376- return '( ' . implode (', ' , $ set ) . ') ' ;
377- }, $ sets ));
378- $ insertSql = 'INSERT INTO ' . $ this ->casbinRuleTableName . ' ( ' . implode (', ' , $ columns ) . ') ' . ' VALUES ' . $ valuesStr ;
379-
380- // start transaction
389+ $ oldRules = [];
381390 $ this ->connection ->getPdo ()->beginTransaction ();
382391 try {
383- // delete old data
384- $ this ->connection ->execute ($ deleteSql , $ deleteWhere );
385- // insert new data
386- $ this ->connection ->execute ($ insertSql , $ values );
392+ $ oldRules = $ this ->_removeFilteredPolicy ($ sec , $ ptype , $ fieldIndex , ...$ fieldValues );
393+ $ this ->addPolicies ($ sec , $ ptype , $ newRules );
387394 $ this ->connection ->getPdo ()->commit ();
388395 } catch (Throwable $ e ) {
389396 $ this ->connection ->getPdo ()->rollback ();
390397 throw $ e ;
391398 }
392399
393- return $ oldP ;
400+ return $ oldRules ;
394401 }
395402}
0 commit comments