@@ -30,6 +30,9 @@ class Query extends AbstractQuery
30
30
/** @var resource[] */
31
31
private $ results ;
32
32
33
+ /** @var array */
34
+ private $ serverctrls = [];
35
+
33
36
public function __construct (Connection $ connection , string $ dn , string $ query , array $ options = [])
34
37
{
35
38
parent ::__construct ($ connection , $ dn , $ query , $ options );
@@ -97,22 +100,13 @@ public function execute()
97
100
$ cookie = '' ;
98
101
do {
99
102
if ($ pageControl ) {
100
- ldap_control_paged_result ($ con , $ pageSize, true , $ cookie );
103
+ $ this -> controlPagedResult ($ con , $ pageSize , $ cookie );
101
104
}
102
105
$ sizeLimit = $ itemsLeft ;
103
106
if ($ pageSize > 0 && $ sizeLimit >= $ pageSize ) {
104
107
$ sizeLimit = 0 ;
105
108
}
106
- $ search = @$ func (
107
- $ con ,
108
- $ this ->dn ,
109
- $ this ->query ,
110
- $ this ->options ['filter ' ],
111
- $ this ->options ['attrsOnly ' ],
112
- $ sizeLimit ,
113
- $ this ->options ['timeout ' ],
114
- $ this ->options ['deref ' ]
115
- );
109
+ $ search = $ this ->callSearchFunction ($ con , $ func , $ sizeLimit );
116
110
117
111
if (false === $ search ) {
118
112
$ ldapError = '' ;
@@ -133,7 +127,7 @@ public function execute()
133
127
break ;
134
128
}
135
129
if ($ pageControl ) {
136
- ldap_control_paged_result_response ($ con , $ search , $ cookie );
130
+ $ cookie = $ this -> controlPagedResultResponse ($ con , $ search , $ cookie );
137
131
}
138
132
} while (null !== $ cookie && '' !== $ cookie );
139
133
@@ -180,7 +174,8 @@ public function getResources(): array
180
174
private function resetPagination ()
181
175
{
182
176
$ con = $ this ->connection ->getResource ();
183
- ldap_control_paged_result ($ con , 0 );
177
+ $ this ->controlPagedResultResponse ($ con , 0 , '' );
178
+ $ this ->serverctrls = [];
184
179
185
180
// This is a workaround for a bit of a bug in the above invocation
186
181
// of ldap_control_paged_result. Instead of indicating to extldap that
@@ -203,4 +198,62 @@ private function resetPagination()
203
198
ldap_set_option ($ con , \LDAP_OPT_SERVER_CONTROLS , $ ctl );
204
199
}
205
200
}
201
+
202
+ /**
203
+ * Sets LDAP pagination controls.
204
+ *
205
+ * @param resource $con
206
+ */
207
+ private function controlPagedResult ($ con , int $ pageSize , string $ cookie ): bool
208
+ {
209
+ if (\PHP_VERSION_ID < 70300 ) {
210
+ return ldap_control_paged_result ($ con , $ pageSize , true , $ cookie );
211
+ }
212
+ $ this ->serverctrls = [
213
+ [
214
+ 'oid ' => \LDAP_CONTROL_PAGEDRESULTS ,
215
+ 'isCritical ' => true ,
216
+ 'value ' => [
217
+ 'size ' => $ pageSize ,
218
+ 'cookie ' => $ cookie ,
219
+ ],
220
+ ],
221
+ ];
222
+
223
+ return true ;
224
+ }
225
+
226
+ /**
227
+ * Retrieve LDAP pagination cookie.
228
+ *
229
+ * @param resource $con
230
+ * @param resource $result
231
+ */
232
+ private function controlPagedResultResponse ($ con , $ result , string $ cookie = '' ): string
233
+ {
234
+ if (\PHP_VERSION_ID < 70300 ) {
235
+ ldap_control_paged_result_response ($ con , $ result , $ cookie );
236
+
237
+ return $ cookie ;
238
+ }
239
+ ldap_parse_result ($ con , $ result , $ errcode , $ matcheddn , $ errmsg , $ referrals , $ controls );
240
+
241
+ return $ controls [\LDAP_CONTROL_PAGEDRESULTS ]['value ' ]['cookie ' ] ?? '' ;
242
+ }
243
+
244
+ /**
245
+ * Calls actual LDAP search function with the prepared options and parameters.
246
+ *
247
+ * @param resource $con
248
+ *
249
+ * @return resource
250
+ */
251
+ private function callSearchFunction ($ con , string $ func , int $ sizeLimit )
252
+ {
253
+ if (\PHP_VERSION_ID < 70300 ) {
254
+ return @$ func ($ con , $ this ->dn , $ this ->query , $ this ->options ['filter ' ], $ this ->options ['attrsOnly ' ], $ sizeLimit , $ this ->options ['timeout ' ], $ this ->options ['deref ' ]);
255
+ }
256
+
257
+ return @$ func ($ con , $ this ->dn , $ this ->query , $ this ->options ['filter ' ], $ this ->options ['attrsOnly ' ], $ sizeLimit , $ this ->options ['timeout ' ], $ this ->options ['deref ' ], $ this ->serverctrls );
258
+ }
206
259
}
0 commit comments