@@ -91,9 +91,55 @@ public function removePolicy($sec, $ptype, $rule): void
91
91
$ this ->table ->delete ($ entity );
92
92
}
93
93
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
95
141
{
96
- throw new CasbinException ( ' not implemented ' );
142
+ $ this -> _removeFilteredPolicy ( $ sec , $ ptype , $ fieldIndex , ... $ fieldValues );
97
143
}
98
144
99
145
/**
@@ -186,57 +232,22 @@ public function updatePolicies(string $sec, string $ptype, array $oldRules, arra
186
232
}
187
233
188
234
/**
189
- * UpdateFilteredPolicies deletes old rules and adds new rules.
190
- *
191
235
* @param string $sec
192
236
* @param string $ptype
193
- * @param array $newPolicies
194
- * @param integer $fieldIndex
237
+ * @param array $newRules
238
+ * @param int $fieldIndex
195
239
* @param string ...$fieldValues
196
240
* @return array
241
+ * @throws Throwable
197
242
*/
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
199
244
{
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 );
236
249
});
237
-
238
- // return deleted rules
239
- return $ oldP ;
250
+ return $ oldRules ;
240
251
}
241
252
242
253
/**
@@ -277,6 +288,26 @@ public function loadFilteredPolicy(Model $model, $filter): void
277
288
$ this ->setFiltered (true );
278
289
}
279
290
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
+
280
311
/**
281
312
* Returns true if the loaded policy has been filtered.
282
313
*
0 commit comments