@@ -91,9 +91,55 @@ public function removePolicy($sec, $ptype, $rule): void
9191 $ this ->table ->delete ($ entity );
9292 }
9393
94- public function removeFilteredPolicy ($ sec , $ ptype , $ fieldIndex , ...$ fieldValues ) :void
94+ /**
95+ * @param string $sec
96+ * @param string $ptype
97+ * @param int $fieldIndex
98+ * @param string|null ...$fieldValues
99+ * @return array
100+ * @throws Throwable
101+ */
102+ public function _removeFilteredPolicy (string $ sec , string $ ptype , int $ fieldIndex , ?string ...$ fieldValues ): array
103+ {
104+ $ removedRules = [];
105+ $ this ->table ->getConnection ()->transactional (function () use ($ ptype , $ fieldIndex , $ fieldValues , &$ removedRules ) {
106+ $ conditions = ['ptype ' => $ ptype ];
107+ $ entity = $ this ->table ->find ();
108+
109+ foreach ($ fieldValues as $ value ) {
110+ if (!is_null ($ value ) && $ value !== '' ) {
111+ $ conditions ['v ' . strval ($ fieldIndex )] = $ value ;
112+ }
113+ $ fieldIndex ++;
114+ }
115+
116+ $ removedRules = [];
117+ $ rows = $ entity ->where ($ conditions );
118+ $ rows = $ entity ->all ();
119+ foreach ($ rows as $ row ) {
120+ unset($ row ->id );
121+ unset($ row ->ptype );
122+ $ removedRules [] = $ this ->filterRule ($ row ->toArray ());
123+ }
124+ $ this ->table ->deleteAll ($ conditions );
125+ });
126+
127+ return $ removedRules ;
128+ }
129+
130+ /**
131+ * RemoveFilteredPolicy removes policy rules that match the filter from the storage.
132+ * This is part of the Auto-Save feature.
133+ *
134+ * @param string $sec
135+ * @param string $ptype
136+ * @param int $fieldIndex
137+ * @param string ...$fieldValues
138+ * @throws Exception|Throwable
139+ */
140+ public function removeFilteredPolicy (string $ sec , string $ ptype , int $ fieldIndex , string ...$ fieldValues ): void
95141 {
96- throw new CasbinException ( ' not implemented ' );
142+ $ this -> _removeFilteredPolicy ( $ sec , $ ptype , $ fieldIndex , ... $ fieldValues );
97143 }
98144
99145 /**
@@ -186,57 +232,22 @@ public function updatePolicies(string $sec, string $ptype, array $oldRules, arra
186232 }
187233
188234 /**
189- * UpdateFilteredPolicies deletes old rules and adds new rules.
190- *
191235 * @param string $sec
192236 * @param string $ptype
193- * @param array $newPolicies
194- * @param integer $fieldIndex
237+ * @param array $newRules
238+ * @param int $fieldIndex
195239 * @param string ...$fieldValues
196240 * @return array
241+ * @throws Throwable
197242 */
198- public function updateFilteredPolicies (string $ sec , string $ ptype , array $ newPolicies , int $ fieldIndex , string ...$ fieldValues ): array
243+ public function updateFilteredPolicies (string $ sec , string $ ptype , array $ newRules , int $ fieldIndex , ? string ...$ fieldValues ): array
199244 {
200- $ where ['ptype ' ] = $ ptype ;
201-
202- foreach ($ fieldValues as $ fieldValue ) {
203- $ suffix = $ fieldIndex ++;
204- if (!is_null ($ fieldValue ) && $ fieldValue !== '' ) {
205- $ where ['v ' . $ suffix ] = $ fieldValue ;
206- }
207- }
208-
209- $ newP = [];
210- $ oldP = [];
211- foreach ($ newPolicies as $ newRule ) {
212- $ col ['ptype ' ] = $ ptype ;
213- foreach ($ newRule as $ key => $ value ) {
214- $ col ['v ' . strval ($ key )] = $ value ;
215- }
216- $ newP [] = $ col ;
217- }
218-
219- $ this ->table ->getConnection ()->transactional (function () use ($ where , $ newP , &$ oldP ) {
220- $ oldRules = $ this ->table ->find ()->where ($ where );
221- $ oldP = $ oldRules ->all ()->toArray ();
222-
223- foreach ($ oldP as &$ item ) {
224- unset($ item ->id );
225- $ item = $ item ->toArray ();
226- $ item = array_filter ($ item , function ($ value ) {
227- return !is_null ($ value ) && $ value !== '' ;
228- });
229- unset($ item ['ptype ' ]);
230- }
231-
232- $ oldRules ->delete ()->execute ();
233-
234- $ entities = $ this ->table ->newEntities ($ newP );
235- $ this ->table ->saveMany ($ entities );
245+ $ oldRules = [];
246+ $ this ->table ->getConnection ()->transactional (function () use ($ sec , $ ptype , $ newRules , $ fieldIndex , $ fieldValues , &$ oldRules ) {
247+ $ oldRules = $ this ->_removeFilteredPolicy ($ sec , $ ptype , $ fieldIndex , ...$ fieldValues );
248+ $ this ->addPolicies ($ sec , $ ptype , $ newRules );
236249 });
237-
238- // return deleted rules
239- return $ oldP ;
250+ return $ oldRules ;
240251 }
241252
242253 /**
@@ -277,6 +288,26 @@ public function loadFilteredPolicy(Model $model, $filter): void
277288 $ this ->setFiltered (true );
278289 }
279290
291+ /**
292+ * Filter the rule.
293+ *
294+ * @param array $rule
295+ * @return array
296+ */
297+ public function filterRule (array $ rule ): array
298+ {
299+ $ rule = array_values ($ rule );
300+
301+ $ i = count ($ rule ) - 1 ;
302+ for (; $ i >= 0 ; $ i --) {
303+ if ($ rule [$ i ] != "" && !is_null ($ rule [$ i ])) {
304+ break ;
305+ }
306+ }
307+
308+ return array_slice ($ rule , 0 , $ i + 1 );
309+ }
310+
280311 /**
281312 * Returns true if the loaded policy has been filtered.
282313 *
0 commit comments