MDL-67118 enrol_ldap: paged results functions deprecated php74 and up
authorEloy Lafuente (stronk7) <stronk7@moodle.org>
Wed, 27 Nov 2019 22:17:20 +0000 (23:17 +0100)
committerEloy Lafuente (stronk7) <stronk7@moodle.org>
Thu, 16 Jan 2020 18:16:14 +0000 (19:16 +0100)
Starting with php74 the following functions are deprecated:
- ldap_control_paged_result()
- ldap_control_paged_result_response()

Starting with php73, ldap servercontrols were included. One of those
servercontrols, LDAP_CONTROL_PAGEDRESULTS, is the one in charge of
controlling paged results.

So, we are going to add some conditional code here:

1) if php < 7.3, use old paged result functions.
2) if php >= 7.3, switch to LDAP_CONTROL_PAGEDRESULTS servercontrol.

With a TODO about removing 1) in Moodle 4.1, once php73 becomes required.

enrol/ldap/lib.php

index 4d37457..8c4672d 100644 (file)
@@ -379,6 +379,7 @@ class enrol_ldap_plugin extends enrol_plugin {
             }
 
             $ldap_cookie = '';
+            $servercontrols = array();
             foreach ($ldap_contexts as $ldap_context) {
                 $ldap_context = trim($ldap_context);
                 if (empty($ldap_context)) {
@@ -388,28 +389,60 @@ class enrol_ldap_plugin extends enrol_plugin {
                 $flat_records = array();
                 do {
                     if ($ldap_pagedresults) {
-                        ldap_control_paged_result($this->ldapconnection, $this->config->pagesize, true, $ldap_cookie);
+                        // TODO: Remove the old branch of code once PHP 7.3.0 becomes required (Moodle 4.1).
+                        if (version_compare(PHP_VERSION, '7.3.0', '<')) {
+                            // Before 7.3, use this function that was deprecated in PHP 7.4.
+                            ldap_control_paged_result($this->ldapconnection, $this->config->pagesize, true, $ldap_cookie);
+                        } else {
+                            // PHP 7.3 and up, use server controls.
+                            $servercontrols = array(array(
+                                'oid' => LDAP_CONTROL_PAGEDRESULTS, 'value' => array(
+                                    'size' => $this->config->pagesize, 'cookie' => $ldap_cookie)));
+                        }
                     }
 
                     if ($this->config->course_search_sub) {
                         // Use ldap_search to find first user from subtree
-                        $ldap_result = @ldap_search($this->ldapconnection,
-                                                    $ldap_context,
-                                                    $ldap_search_pattern,
-                                                    $ldap_fields_wanted);
+                        // TODO: Remove the old branch of code once PHP 7.3.0 becomes required (Moodle 4.1).
+                        if (version_compare(PHP_VERSION, '7.3.0', '<')) {
+                            $ldap_result = @ldap_search($this->ldapconnection, $ldap_context,
+                                $ldap_search_pattern, $ldap_fields_wanted);
+                        } else {
+                            $ldap_result = @ldap_search($this->ldapconnection, $ldap_context,
+                                $ldap_search_pattern, $ldap_fields_wanted,
+                                0, -1, -1, LDAP_DEREF_NEVER, $servercontrols);
+                        }
                     } else {
                         // Search only in this context
-                        $ldap_result = @ldap_list($this->ldapconnection,
-                                                  $ldap_context,
-                                                  $ldap_search_pattern,
-                                                  $ldap_fields_wanted);
+                        // TODO: Remove the old branch of code once PHP 7.3.0 becomes required (Moodle 4.1).
+                        if (version_compare(PHP_VERSION, '7.3.0', '<')) {
+                            $ldap_result = @ldap_list($this->ldapconnection, $ldap_context,
+                                $ldap_search_pattern, $ldap_fields_wanted);
+                        } else {
+                            $ldap_result = @ldap_list($this->ldapconnection, $ldap_context,
+                                $ldap_search_pattern, $ldap_fields_wanted,
+                                0, -1, -1, LDAP_DEREF_NEVER, $servercontrols);
+                        }
                     }
                     if (!$ldap_result) {
                         continue; // Next
                     }
 
                     if ($ldap_pagedresults) {
-                        ldap_control_paged_result_response($this->ldapconnection, $ldap_result, $ldap_cookie);
+                        // Get next server cookie to know if we'll need to continue searching.
+                        $ldap_cookie = '';
+                        // TODO: Remove the old branch of code once PHP 7.3.0 becomes required (Moodle 4.1).
+                        if (version_compare(PHP_VERSION, '7.3.0', '<')) {
+                            // Before 7.3, use this function that was deprecated in PHP 7.4.
+                            ldap_control_paged_result_response($this->ldapconnection, $ldap_result, $ldap_cookie);
+                        } else {
+                            // Get next cookie from controls.
+                            ldap_parse_result($this->ldapconnection, $ldap_result, $errcode, $matcheddn,
+                                $errmsg, $referrals, $controls);
+                            if (isset($controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'])) {
+                                $ldap_cookie = $controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'];
+                            }
+                        }
                     }
 
                     // Check and push results
@@ -769,24 +802,44 @@ class enrol_ldap_plugin extends enrol_plugin {
             }
 
             $ldap_cookie = '';
+            $servercontrols = array();
             $flat_records = array();
             do {
                 if ($ldap_pagedresults) {
-                    ldap_control_paged_result($this->ldapconnection, $this->config->pagesize, true, $ldap_cookie);
+                    // TODO: Remove the old branch of code once PHP 7.3.0 becomes required (Moodle 4.1).
+                    if (version_compare(PHP_VERSION, '7.3.0', '<')) {
+                        // Before 7.3, use this function that was deprecated in PHP 7.4.
+                        ldap_control_paged_result($this->ldapconnection, $this->config->pagesize, true, $ldap_cookie);
+                    } else {
+                        // PHP 7.3 and up, use server controls.
+                        $servercontrols = array(array(
+                            'oid' => LDAP_CONTROL_PAGEDRESULTS, 'value' => array(
+                                'size' => $this->config->pagesize, 'cookie' => $ldap_cookie)));
+                    }
                 }
 
                 if ($this->get_config('course_search_sub')) {
                     // Use ldap_search to find first user from subtree
-                    $ldap_result = @ldap_search($this->ldapconnection,
-                                                $context,
-                                                $ldap_search_pattern,
-                                                $ldap_fields_wanted);
+                    // TODO: Remove the old branch of code once PHP 7.3.0 becomes required (Moodle 4.1).
+                    if (version_compare(PHP_VERSION, '7.3.0', '<')) {
+                        $ldap_result = @ldap_search($this->ldapconnection, $context,
+                            $ldap_search_pattern, $ldap_fields_wanted);
+                    } else {
+                        $ldap_result = @ldap_search($this->ldapconnection, $context,
+                            $ldap_search_pattern, $ldap_fields_wanted,
+                            0, -1, -1, LDAP_DEREF_NEVER, $servercontrols);
+                    }
                 } else {
                     // Search only in this context
-                    $ldap_result = @ldap_list($this->ldapconnection,
-                                              $context,
-                                              $ldap_search_pattern,
-                                              $ldap_fields_wanted);
+                    // TODO: Remove the old branch of code once PHP 7.3.0 becomes required (Moodle 4.1).
+                    if (version_compare(PHP_VERSION, '7.3.0', '<')) {
+                        $ldap_result = @ldap_list($this->ldapconnection, $context,
+                            $ldap_search_pattern, $ldap_fields_wanted);
+                    } else {
+                        $ldap_result = @ldap_list($this->ldapconnection, $context,
+                            $ldap_search_pattern, $ldap_fields_wanted,
+                            0, -1, -1, LDAP_DEREF_NEVER, $servercontrols);
+                    }
                 }
 
                 if (!$ldap_result) {
@@ -794,7 +847,20 @@ class enrol_ldap_plugin extends enrol_plugin {
                 }
 
                 if ($ldap_pagedresults) {
-                    ldap_control_paged_result_response($this->ldapconnection, $ldap_result, $ldap_cookie);
+                    // Get next server cookie to know if we'll need to continue searching.
+                    $ldap_cookie = '';
+                    // TODO: Remove the old branch of code once PHP 7.3.0 becomes required (Moodle 4.1).
+                    if (version_compare(PHP_VERSION, '7.3.0', '<')) {
+                        // Before 7.3, use this function that was deprecated in PHP 7.4.
+                        ldap_control_paged_result_response($this->ldapconnection, $ldap_result, $ldap_cookie);
+                    } else {
+                        // Get next cookie from controls.
+                        ldap_parse_result($this->ldapconnection, $ldap_result, $errcode, $matcheddn,
+                            $errmsg, $referrals, $controls);
+                        if (isset($controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'])) {
+                            $ldap_cookie = $controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'];
+                        }
+                    }
                 }
 
                 // Check and push results. ldap_get_entries() already