php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #42060
Patch paged-ldap-5.3 revision 2011-04-28 23:00 UTC by bryant dot david at gmail dot com
Patch api-rename.patch revision 2010-11-04 21:16 UTC by jeanseb at au-fil-du dot net
Patch php-trunk_ldap-pagination.patch revision 2010-11-04 20:47 UTC by jeanseb at au-fil-du dot net
revision 2010-11-03 21:50 UTC by jeanseb at au-fil-du dot net
revision 2010-05-21 15:27 UTC by jeanseb at au-fil-du dot net
Patch ext-ldap-review.patch revision 2010-08-04 15:54 UTC by jeanseb at au-fil-du dot net

Patch php-trunk_ldap-pagination.patch for *General Issues Bug #42060

Patch version 2010-05-21 15:27 UTC

Return to Bug #42060 | Download this patch
This patch is obsolete

Obsoleted by patches:

Patch Revisions:

Developer: jeanseb@au-fil-du.net

Index: ext/ldap/ldap.c
===================================================================
--- ext/ldap/ldap.c	(révision 40035)
+++ ext/ldap/ldap.c	(révision 40105)
@@ -19,6 +19,10 @@
    |          Jani Taskinen  <sniper@iki.fi>                              |
    |          Stig Venaas    <venaas@uninett.no>                          |
    |          Doug Goldstein <cardoe@cardoe.com>                          |
+   |          Pierangelo Masarati <ando@OpenLDAP.org>                     |
+   |          Iñaki Arenaza <iarenuno@eteo.mondragon.edu>                 |
+   |          Jean-Sébastien Hedde <jeanseb@au-fil-du.net>                |
+   |          Rémy Saissy <remy.saissy@gmail.com>                         |
    | PHP 4.0 updates:  Zeev Suraski <zeev@zend.com>                       |
    +----------------------------------------------------------------------+
  */
@@ -2047,6 +2051,192 @@
 }
 /* }}} */
 #endif
+
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+/* {{{ proto bool ldap_ctrl_paged_results(resource link, int pagesize [, bool iscritical [, string cookie]])
+   Inject paged results control*/
+PHP_FUNCTION(ldap_ctrl_paged_results) 
+{
+	int pagesize;
+	int iscritical;
+	zval *link, *cookie;
+	struct berval lcookie = { 0, NULL };
+	ldap_linkdata *ld;
+	LDAP *ldap;
+	BerElement *ber = NULL;
+	LDAPControl	ctrl, *ctrlsp[2];
+	int rc, myargcount = ZEND_NUM_ARGS();
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|bz", &link, &pagesize, &iscritical, &cookie) != SUCCESS) {
+		return;
+	}
+
+	if (Z_TYPE_PP(&link) == IS_NULL) {
+		ldap = NULL;
+	} else {
+		ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
+		ldap = ld->link;
+	}
+
+	ber = ber_alloc_t(LBER_USE_DER);
+	if (ber == NULL) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to alloc BER encoding resources for paged results control");
+		RETURN_FALSE;
+	}
+
+	ctrl.ldctl_iscritical = 0;
+
+	switch (myargcount) {
+		case 4:
+			convert_to_string_ex(&cookie);
+			lcookie.bv_val = Z_STRVAL_PP(&cookie);
+			lcookie.bv_len = Z_STRLEN_PP(&cookie);
+			/* fallthru */
+		case 3:
+			ctrl.ldctl_iscritical = iscritical;
+			/* fallthru */
+	}
+
+	if (ber_printf(ber, "{iO}", pagesize, &lcookie) == LBER_ERROR) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to BER printf paged results control");
+		RETVAL_BOOL(0);
+		goto lcpr_error_out;
+	}
+	rc = ber_flatten2(ber, &ctrl.ldctl_value, 0);
+	if (rc == LBER_ERROR) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to BER encode paged results control");
+		RETVAL_BOOL(0);
+		goto lcpr_error_out;
+	}
+
+	ctrl.ldctl_oid = LDAP_CONTROL_PAGEDRESULTS;
+
+	if (ldap) {
+		/* directly set the option */
+		ctrlsp[0] = &ctrl;
+		ctrlsp[1] = NULL;
+
+		rc = ldap_set_option(ldap, LDAP_OPT_SERVER_CONTROLS, ctrlsp);
+		if (rc != LDAP_SUCCESS) {
+			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set paged results control: %s (%d)", ldap_err2string(rc), rc);
+			RETVAL_BOOL(0);
+			goto lcpr_error_out;
+		}
+		RETVAL_BOOL(1);
+	} else {
+		/* return a PHP control object */
+		array_init(return_value);
+
+		add_assoc_string(return_value, "oid", ctrl.ldctl_oid, 1);
+		if ( ctrl.ldctl_value.bv_len ) {
+			add_assoc_stringl(return_value, "value", ctrl.ldctl_value.bv_val, ctrl.ldctl_value.bv_len, 1);
+		}
+		if (ctrl.ldctl_iscritical) {
+			add_assoc_bool(return_value, "iscritical", ctrl.ldctl_iscritical);
+		}
+	}
+
+lcpr_error_out:
+    if (ber != NULL) {
+		ber_free(ber, 1);
+	}
+	return;
+}
+/* }}} */
+
+/* {{{ proto bool ldap_ctrl_paged_results_resp(resource link, resource result [, string cookie [, int estimated]])
+   Extract paged results control response */
+PHP_FUNCTION(ldap_ctrl_paged_results_resp) 
+{
+	zval *link, *result, *cookie, *estimated;
+	struct berval lcookie;
+	int lestimated;
+	ldap_linkdata *ld;
+	LDAPMessage *ldap_result;
+	LDAPControl **lserverctrls, *lctrl;
+	BerElement *ber;
+	ber_tag_t tag;
+	int rc, lerrcode, myargcount = ZEND_NUM_ARGS();
+
+
+	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rr|zz", &link, &result, &cookie, &estimated) != SUCCESS) {
+		return;
+	}
+
+	ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link);
+	ZEND_FETCH_RESOURCE(ldap_result, LDAPMessage *, &result, -1, "ldap result", le_result);
+
+	rc = ldap_parse_result(ld->link,
+				ldap_result,
+				&lerrcode,
+				NULL,		/* matcheddn */
+				NULL,		/* errmsg */
+				NULL,		/* referrals */
+				&lserverctrls,
+				0);
+
+	if (rc != LDAP_SUCCESS) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse result: %s (%d)", ldap_err2string(rc), rc);
+		RETURN_FALSE;
+	}
+
+	if (lerrcode != LDAP_SUCCESS) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Result is: %s (%d)", ldap_err2string(lerrcode), lerrcode);
+		RETURN_FALSE;
+	}
+
+	if (lserverctrls == NULL) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "No server controls in result");
+		RETURN_FALSE;
+	}
+
+	lctrl = ldap_find_control(LDAP_CONTROL_PAGEDRESULTS, lserverctrls);
+	if (lctrl == NULL) {
+		ldap_controls_free(lserverctrls);
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "No paged results control response in result");
+		RETURN_FALSE;
+	}
+
+	ber = ber_init(&lctrl->ldctl_value);
+	if (ber == NULL) {
+		ldap_controls_free(lserverctrls);
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to alloc BER decoding resources for paged results control response");
+		RETURN_FALSE;
+	}
+
+	tag = ber_scanf(ber, "{io}", &lestimated, &lcookie);
+	(void)ber_free(ber, 1);
+
+	if (tag == LBER_ERROR) {
+		ldap_controls_free(lserverctrls);
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to decode paged results control response");
+		RETURN_FALSE;
+	}
+
+	if (lestimated < 0) {
+		ldap_controls_free(lserverctrls);
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid paged results control response value");
+		RETURN_FALSE;
+	}
+
+	ldap_controls_free(lserverctrls);
+	if (myargcount == 4) {
+		zval_dtor(estimated);
+		ZVAL_LONG(estimated, lestimated);
+	}
+	zval_dtor(cookie);
+	
+ 	if (lcookie.bv_len == 0) {
+		ZVAL_EMPTY_STRING(cookie);
+ 	} else {
+		ZVAL_STRINGL(cookie, lcookie.bv_val, lcookie.bv_len, 1);
+ 	}
+ 	ldap_memfree(lcookie.bv_val);
+
+	RETURN_TRUE;
+}
+/* }}} */
+#endif
 #endif /* (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 */
 
 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
@@ -2414,6 +2604,21 @@
 	ZEND_ARG_INFO(1, referrals)
 ZEND_END_ARG_INFO()
 #endif
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_ctrl_paged_results, 0, 0, 2)
+	ZEND_ARG_INFO(0, link)
+	ZEND_ARG_INFO(0, pagesize)
+	ZEND_ARG_INFO(0, iscritical)
+	ZEND_ARG_INFO(0, cookie)
+ZEND_END_ARG_INFO();
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_ctrl_paged_results_resp, 0, 0, 2)
+	ZEND_ARG_INFO(0, link)
+	ZEND_ARG_INFO(0, result)
+	ZEND_ARG_INFO(1, cookie)
+	ZEND_ARG_INFO(1, estimated)
+ZEND_END_ARG_INFO();
+
 #endif
 
 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
@@ -2489,14 +2694,22 @@
 #ifdef HAVE_LDAP_PARSE_REFERENCE
 	PHP_FE(ldap_parse_reference,						arginfo_ldap_parse_reference)
 #endif
+
 #ifdef HAVE_LDAP_PARSE_RESULT
 	PHP_FE(ldap_parse_result,							arginfo_ldap_parse_result)
 #endif
+
 #ifdef HAVE_LDAP_START_TLS_S
 	PHP_FE(ldap_start_tls,								arginfo_ldap_resource)
 #endif
+
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+	PHP_FE(ldap_ctrl_paged_results,							arginfo_ldap_ctrl_paged_results)
+	PHP_FE(ldap_ctrl_paged_results_resp,						arginfo_ldap_ctrl_paged_results_resp)
 #endif
 
+#endif
+
 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
 	PHP_FE(ldap_set_rebind_proc,						arginfo_ldap_set_rebind_proc)
 #endif
Index: ext/ldap/tests/ldap_ctrl_paged_results_variation1.phpt
===================================================================
--- ext/ldap/tests/ldap_ctrl_paged_results_variation1.phpt	(révision 0)
+++ ext/ldap/tests/ldap_ctrl_paged_results_variation1.phpt	(révision 40105)
@@ -0,0 +1,56 @@
+--TEST--
+ldap_ldap_ctrl_paged_results() test (fetching the first page)
+--CREDITS--
+Jean-Sebastien Hedde <jeanseb@au-fil-du.net>
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifbindfailure.inc');
+?>
+--FILE--
+<?php
+include "connect.inc";
+
+$link = ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version);
+insert_dummy_data($link);
+
+$dn = "dc=my-domain,dc=com";
+$filter = "(cn=*)";
+var_dump(
+	ldap_ctrl_paged_results($link, 1),
+	$result = ldap_search($link, $dn, $filter, array('cn')),
+	ldap_get_entries($link, $result)
+);
+?>
+===DONE===
+--CLEAN--
+<?php
+include "connect.inc";
+
+$link = ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version);
+remove_dummy_data($link);
+?>
+--EXPECTF--
+bool(true)
+resource(6) of type (ldap result)
+array(2) {
+  ["count"]=>
+  int(1)
+  [0]=>
+  array(4) {
+    ["cn"]=>
+    array(2) {
+      ["count"]=>
+      int(1)
+      [0]=>
+      string(5) "userA"
+    }
+    [0]=>
+    string(2) "cn"
+    ["count"]=>
+    int(1)
+    ["dn"]=>
+    string(28) "cn=userA,dc=my-domain,dc=com"
+  }
+}
+===DONE===
Index: ext/ldap/tests/ldap_ctrl_paged_results_variation2.phpt
===================================================================
--- ext/ldap/tests/ldap_ctrl_paged_results_variation2.phpt	(révision 0)
+++ ext/ldap/tests/ldap_ctrl_paged_results_variation2.phpt	(révision 40105)
@@ -0,0 +1,72 @@
+--TEST--
+ldap_ldap_ctrl_paged_results() test (fetching the first page with a pagesize=2)
+--CREDITS--
+Jean-Sebastien Hedde <jeanseb@au-fil-du.net>
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifbindfailure.inc');
+?>
+--FILE--
+<?php
+include "connect.inc";
+
+$link = ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version);
+insert_dummy_data($link);
+
+$dn = "dc=my-domain,dc=com";
+$filter = "(cn=*)";
+var_dump(
+	ldap_ctrl_paged_results($link, 2),
+	$result = ldap_search($link, $dn, $filter, array('cn')),
+	ldap_get_entries($link, $result)
+);
+?>
+===DONE===
+--CLEAN--
+<?php
+include "connect.inc";
+
+$link = ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version);
+remove_dummy_data($link);
+?>
+--EXPECTF--
+bool(true)
+resource(6) of type (ldap result)
+array(3) {
+  ["count"]=>
+  int(2)
+  [0]=>
+  array(4) {
+    ["cn"]=>
+    array(2) {
+      ["count"]=>
+      int(1)
+      [0]=>
+      string(5) "userA"
+    }
+    [0]=>
+    string(2) "cn"
+    ["count"]=>
+    int(1)
+    ["dn"]=>
+    string(28) "cn=userA,dc=my-domain,dc=com"
+  }
+  [1]=>
+  array(4) {
+    ["cn"]=>
+    array(2) {
+      ["count"]=>
+      int(1)
+      [0]=>
+      string(5) "userB"
+    }
+    [0]=>
+    string(2) "cn"
+    ["count"]=>
+    int(1)
+    ["dn"]=>
+    string(28) "cn=userB,dc=my-domain,dc=com"
+  }
+}
+===DONE===
Index: ext/ldap/tests/ldap_ctrl_paged_results_variation3.phpt
===================================================================
--- ext/ldap/tests/ldap_ctrl_paged_results_variation3.phpt	(révision 0)
+++ ext/ldap/tests/ldap_ctrl_paged_results_variation3.phpt	(révision 40105)
@@ -0,0 +1,100 @@
+--TEST--
+ldap_ldap_ctrl_paged_results() test (fetching the first page then the next final page)
+--CREDITS--
+Jean-Sebastien Hedde <jeanseb@au-fil-du.net>
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifbindfailure.inc');
+?>
+--FILE--
+<?php
+include "connect.inc";
+
+$link = ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version);
+insert_dummy_data($link);
+
+$dn = "dc=my-domain,dc=com";
+$filter = "(cn=*)";
+$cookie = '';
+var_dump(
+	ldap_ctrl_paged_results($link, 2, true, $cookie),
+	$result = ldap_search($link, $dn, $filter, array('cn')),
+	ldap_get_entries($link, $result),
+	ldap_ctrl_paged_results_resp($link, $result, $cookie),
+	ldap_ctrl_paged_results($link, 20, true, $cookie),
+	$result = ldap_search($link, $dn, $filter, array('cn')),
+	ldap_get_entries($link, $result)
+);
+?>
+===DONE===
+--CLEAN--
+<?php
+include "connect.inc";
+
+$link = ldap_connect_and_bind($host, $port, $user, $passwd, $protocol_version);
+remove_dummy_data($link);
+?>
+--EXPECTF--
+bool(true)
+resource(%d) of type (ldap result)
+array(3) {
+  ["count"]=>
+  int(2)
+  [0]=>
+  array(4) {
+    ["cn"]=>
+    array(2) {
+      ["count"]=>
+      int(1)
+      [0]=>
+      string(5) "userA"
+    }
+    [0]=>
+    string(2) "cn"
+    ["count"]=>
+    int(1)
+    ["dn"]=>
+    string(28) "cn=userA,dc=my-domain,dc=com"
+  }
+  [1]=>
+  array(4) {
+    ["cn"]=>
+    array(2) {
+      ["count"]=>
+      int(1)
+      [0]=>
+      string(5) "userB"
+    }
+    [0]=>
+    string(2) "cn"
+    ["count"]=>
+    int(1)
+    ["dn"]=>
+    string(28) "cn=userB,dc=my-domain,dc=com"
+  }
+}
+bool(true)
+bool(true)
+resource(%d) of type (ldap result)
+array(2) {
+  ["count"]=>
+  int(1)
+  [0]=>
+  array(4) {
+    ["cn"]=>
+    array(2) {
+      ["count"]=>
+      int(1)
+      [0]=>
+      string(5) "userC"
+    }
+    [0]=>
+    string(2) "cn"
+    ["count"]=>
+    int(1)
+    ["dn"]=>
+    string(37) "cn=userC,cn=userB,dc=my-domain,dc=com"
+  }
+}
+===DONE===
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sat Apr 19 22:02:16 2014 UTC