[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pecl-cvs
Subject:    [PECL-CVS] com =?UTF-8?Q?pecl/search=5Fengine/solr=3A=20Request=20=23=37=30=39=37=34?= =?UTF-8?Q?=20
From:       Omar Shaban <omars () php ! net>
Date:       2015-11-26 0:40:08
Message-ID: php-mail-908328e26ef5344158781b6d68318f02409227438 () git ! php ! net
[Download RAW message or body]

Commit:    993c7c96ff02fa96a796f31ead88a2a5878ffcec
Author:    Omar Shaban <omars@php.net>         Thu, 26 Nov 2015 02:40:08 +0200
Parents:   4df1b1d3c6050a81a611911b2ea74115d77b143f
Branches:  master

Link:       http://git.php.net/?p=pecl/search_engine/solr.git;a=commitdiff;h=993c7c96ff02fa96a796f31ead88a2a5878ffcec


Log:
Request #70974 	Support nested documents parsing [SolrDocument]

Support Response parsing using SolrDocument parsing mode, \
serialization/unserialization of children API:
bool  SolrDocument::hasChildDocuments( void )
array SolrDocument::getChildDocuments( void )
int   SolrDocument::getChildDocumentsCount( void )

Bugs:
https://bugs.php.net/70974

Changed paths:
  M  docs/documentation.php
  M  php_solr.c
  M  php_solr.h
  M  php_solr_document.c
  M  solr_functions_helpers.c
  A  tests/030.solrdocument_child_doc_response_solrdoc.phpt
  A  tests/031.solrdocument_haschilddocuments.phpt
  A  tests/032.solrdocument_getchilddocscount.phpt


["diff_993c7c96ff02fa96a796f31ead88a2a5878ffcec.txt" (text/plain)]

diff --git a/docs/documentation.php b/docs/documentation.php
index 831bed4..da3cca9 100644
--- a/docs/documentation.php
+++ b/docs/documentation.php
@@ -22,10 +22,10 @@
 /* $Id$ */
 
 define('SOLR_MAJOR_VERSION', 2);
-define('SOLR_MINOR_VERSION', 2);
-define('SOLR_PATCH_VERSION', 1);
+define('SOLR_MINOR_VERSION', 3);
+define('SOLR_PATCH_VERSION', 0);
 
-define('SOLR_EXTENSION_VERSION', '2.2.1');
+define('SOLR_EXTENSION_VERSION', '2.3.0');
 
 /**
  * Returns the current version of the Apache Solr extension
@@ -408,6 +408,7 @@ final class SolrInputDocument
  *
  * @link http://docs.php.net/manual/en/class.solrdocument.php
  * @author Israel Ekpo <iekpo@php.net>
+ * @author Omar Shaban <omars@php.net>
  */
 final class SolrDocument implements ArrayAccess, Iterator, Serializable
 {
@@ -506,8 +507,7 @@ final class SolrDocument implements ArrayAccess, Iterator, \
Serializable  
     public function __isset($fieldName) {}
 
-    public function key()
-    {}
+    public function key() {}
 
     /**
      * Merges source to the current SolrDocument
@@ -518,47 +518,54 @@ final class SolrDocument implements ArrayAccess, Iterator, \
                Serializable
      */
     public function merge(SolrDocument $sourceDoc, $overwrite = true) {}
 
-    public function next()
-    {}
+    public function next() {}
+
+    public function offsetExists($fieldName) {}
 
-    public function offsetExists($fieldName)
-    {}
+    public function offsetGet($fieldName) {}
 
-    public function offsetGet($fieldName)
-    {}
+    public function offsetSet($fieldName, $fieldValue) {}
 
-    public function offsetSet($fieldName, $fieldValue)
-    {}
+    public function offsetUnset($fieldName) {}
 
-    public function offsetUnset($fieldName)
-    {}
+    public function reset() {}
 
-    public function reset()
-    {}
+    public function rewind() {}
 
-    public function rewind()
-    {}
+    public function serialize() {}
 
-    public function serialize()
-    {}
+    public function __set($fieldName, $fieldValue) {}
 
-    public function __set($fieldName, $fieldValue)
-    {}
+    public function sort($sortOrderBy, $sortDirection) {}
 
-    public function sort($sortOrderBy, $sortDirection)
-    {}
+    public function toArray() {}
 
-    public function toArray()
-    {}
+    public function unserialize($serialized) {}
 
-    public function unserialize($serialized)
-    {}
+    public function __unset($fieldName) {}
+
+    public function valid() {}
+
+    /**
+     * Checks whether this document contains child documents
+     *
+     * @return bool
+     */
+    public function hasChildDocuments() {}
 
-    public function __unset($fieldName)
-    {}
+    /**
+     * Returns an array of child documents (SolrDocument)
+     *
+     * @return array
+     */
+    public function getChildDocuments() {}
 
-    public function valid()
-    {}
+    /**
+     * Returns the number of child documents
+     *
+     * @return int
+     */
+    public function getChildDocumentsCount() {}
 }
 
 /**
diff --git a/php_solr.c b/php_solr.c
index 2f96d49..ad63250 100644
--- a/php_solr.c
+++ b/php_solr.c
@@ -602,7 +602,9 @@ static zend_function_entry solr_document_methods[] = {
 	PHP_ME(SolrDocument, sort, SolrDocument_sort_args, ZEND_ACC_PUBLIC)
 	PHP_ME(SolrDocument, merge, SolrDocument_merge_args, ZEND_ACC_PUBLIC)
 	PHP_ME(SolrDocument, getInputDocument, SolrDocument_getInputDocument_args, \
                ZEND_ACC_PUBLIC)
-
+	PHP_ME(SolrDocument, getChildDocumentsCount, Solr_no_args, ZEND_ACC_PUBLIC)
+	PHP_ME(SolrDocument, hasChildDocuments, Solr_no_args, ZEND_ACC_PUBLIC)
+	PHP_ME(SolrDocument, getChildDocuments, Solr_no_args, ZEND_ACC_PUBLIC)
 	{ NULL, NULL, NULL }
 };
 /* }}} */
diff --git a/php_solr.h b/php_solr.h
index 6cc3b55..2d3ad37 100644
--- a/php_solr.h
+++ b/php_solr.h
@@ -43,6 +43,7 @@
 #include <ext/standard/url.h>
 #include <ext/standard/php_var.h>
 #include <ext/standard/php_string.h>
+#include <ext/standard/base64.h>
 #include <ext/pcre/php_pcre.h>
    
 
@@ -209,6 +210,10 @@ PHP_METHOD(SolrDocument, deleteField);
 PHP_METHOD(SolrDocument, sort);
 PHP_METHOD(SolrDocument, merge);
 PHP_METHOD(SolrDocument, getInputDocument);
+PHP_METHOD(SolrDocument, hasChildDocuments);
+PHP_METHOD(SolrDocument, getChildDocuments);
+PHP_METHOD(SolrDocument, getChildDocumentsCount);
+
 /* }}} */
 
 /* {{{ SolrDocumentField methods */
diff --git a/php_solr_document.c b/php_solr_document.c
index 17eeb9c..0abee06 100644
--- a/php_solr_document.c
+++ b/php_solr_document.c
@@ -288,108 +288,184 @@ static void solr_unserialize_document_field(HashTable \
*document_fields, xmlNode  }
 /* }}} */
 
-/* {{{ static int solr_unserialize_document_object(HashTable *document_fields, char \
                *serialized, int size TSRMLS_DC) */
-static int solr_unserialize_document_object(HashTable *document_fields, char \
*serialized, int size TSRMLS_DC) +/* {{{ static int \
solr_unserialize_child_documents(xmlDoc *doc, solr_document_t *doc_entry TSRMLS_DC) + \
* 1. retrieve doc hashes + * 2. base64_decode
+ * 3. unserialize (call php method)
+ * 4. add child to solr_doc_t.children
+ */
+static int solr_unserialize_child_documents(xmlDoc *doc, solr_document_t *doc_entry \
TSRMLS_DC)  {
-	xmlXPathContext *xpathctxt = NULL;
 
-	xmlDoc *doc = NULL;
+    xmlXPathContext *xp_ctx = NULL;
+    xmlXPathObject *xp_obj = NULL;
+    xmlNodeSet *result = NULL;
+    xmlChar *hash, * xp_expression = "/solr_document/child_docs/dochash";
+    unsigned int num_nodes = 0;
+    unsigned int idx = 0;
+
+    xmlNode *curr_node;
+    int hash_len=0;
+    /* unserialize vars */
+    php_unserialize_data_t var_hash = NULL;
+    const unsigned char *str_end;
+    zval *solr_doc_zv = NULL;
+
+    xp_ctx = xmlXPathNewContext(doc);
+    xp_obj = xmlXPathEvalExpression(xp_expression, xp_ctx);
+
+    result = xp_obj->nodesetval;
+    num_nodes = result->nodeNr;
+
+    if (num_nodes > 0)
+    {
+        for (;idx < num_nodes; idx++)
+        {
+            char *sdoc;
+            hash = result->nodeTab[idx]->children->content;
+
+            sdoc = (char *)php_base64_decode((const unsigned char*)hash, \
strlen((char *)hash), &hash_len); +            memset(&var_hash, 0, \
sizeof(php_unserialize_data_t)); +            PHP_VAR_UNSERIALIZE_INIT(var_hash);
+            MAKE_STD_ZVAL(solr_doc_zv);
+
+            if (!php_var_unserialize(&solr_doc_zv, (const unsigned char **)&sdoc, \
str_end, &var_hash TSRMLS_CC)){ +                \
PHP_VAR_UNSERIALIZE_DESTROY(var_hash); +                php_error_docref(NULL \
TSRMLS_CC, E_ERROR, "Unable to unserialize child document"); +
+                xmlXPathFreeContext(xp_ctx);
+                xmlXPathFreeObject(xp_obj);
+
+                return FAILURE;
+            }
+
+            if (zend_hash_next_index_insert(doc_entry->children, &solr_doc_zv, \
sizeof(zval *), NULL) == FAILURE) +            {
+                php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unable to add child \
document to parent document post-unserialize"); +            }
+            PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
+        }
+    }
+    xmlXPathFreeContext(xp_ctx);
+    xmlXPathFreeObject(xp_obj);
+
+    return SUCCESS;
+}
+/* }}} */
 
-	xmlChar *xpath_expression = NULL;
+static int solr_unserialize_document_fields(xmlDoc *doc, HashTable *document_fields \
TSRMLS_DC) +{
+    xmlXPathContext *xpathctxt = NULL;
+    xmlChar *xpath_expression = NULL;
+    xmlXPathObject *xpathObj = NULL;
+    xmlNodeSet *result = NULL;
 
-	xmlXPathObject *xpathObj = NULL;
+    register size_t num_nodes = 0U;
 
-	xmlNodeSet *result = NULL;
+    register size_t i = 0U;
+    xpathctxt = xmlXPathNewContext(doc);
 
-	register size_t num_nodes = 0U;
+    if (!xpathctxt)
+    {
+        xmlFreeDoc(doc);
 
-	register size_t i = 0U;
+        php_error_docref(NULL TSRMLS_CC, E_WARNING, "A valid XML xpath context could \
not be created");  
-	doc = xmlReadMemory(serialized, size, NULL, "UTF-8", 0);
+        return FAILURE;
+    }
 
-	if (!doc)
-	{
-		php_error_docref(NULL TSRMLS_CC, E_WARNING, "The serialized document string is \
invalid"); +    xpath_expression = (xmlChar *) "/solr_document/fields/field/@name";
 
-		return FAILURE;
-	}
+    xpathObj = xmlXPathEval(xpath_expression, xpathctxt);
 
-	xpathctxt = xmlXPathNewContext(doc);
+    if (!xpathObj)
+    {
+        xmlXPathFreeContext(xpathctxt);
 
-	if (!xpathctxt)
-	{
-		xmlFreeDoc(doc);
+        xmlFreeDoc(doc);
 
-		php_error_docref(NULL TSRMLS_CC, E_WARNING, "A valid XML xpath context could not \
be created"); +        php_error_docref(NULL TSRMLS_CC, E_WARNING, "A valid XML xpath \
object could not be created from the expression");  
-		return FAILURE;
-	}
+        return FAILURE;
+    }
 
-	xpath_expression = (xmlChar *) "/solr_document/fields/field/@name";
+    result = xpathObj->nodesetval;
 
-	xpathObj = xmlXPathEval(xpath_expression, xpathctxt);
+    if (!result)
+    {
+        xmlXPathFreeContext(xpathctxt);
 
-	if (!xpathObj)
-	{
-		xmlXPathFreeContext(xpathctxt);
+        xmlXPathFreeObject(xpathObj);
 
-		xmlFreeDoc(doc);
+        xmlFreeDoc(doc);
 
-		php_error_docref(NULL TSRMLS_CC, E_WARNING, "A valid XML xpath object could not be \
created from the expression"); +        php_error_docref(NULL TSRMLS_CC, E_WARNING, \
"Document has no fields");  
-		return FAILURE;
-	}
+        return FAILURE;
+    }
 
-	result = xpathObj->nodesetval;
+    num_nodes = result->nodeNr;
 
-	if (!result)
-	{
-		xmlXPathFreeContext(xpathctxt);
+    i = 0U;
 
-		xmlXPathFreeObject(xpathObj);
+    if (!num_nodes)
+    {
+        xmlXPathFreeContext(xpathctxt);
 
-		xmlFreeDoc(doc);
+        xmlXPathFreeObject(xpathObj);
 
-		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document has no fields");
+        xmlFreeDoc(doc);
 
-		return FAILURE;
-	}
+        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document has no fields");
 
-	num_nodes = result->nodeNr;
+        return FAILURE;
+    }
 
-	i = 0U;
+    for (i = 0U; i < num_nodes; i++)
+    {
+        xmlNode *currNode = result->nodeTab[i];
 
-	if (!num_nodes)
-	{
-		xmlXPathFreeContext(xpathctxt);
+        /* Absolutely No assumptions. I have to make sure that this is the name \
attribute */ +        if (currNode->type == XML_ATTRIBUTE_NODE && \
solr_xml_match_node(currNode, "name")) +        {
+            /* Get the field node */
+            xmlNode *field_xml_node = currNode->parent;
 
-		xmlXPathFreeObject(xpathObj);
+            /* Retrieve all the values for this field and put them in the HashTable \
*/ +            solr_unserialize_document_field(document_fields, field_xml_node \
TSRMLS_CC); +        }
+    }
 
-		xmlFreeDoc(doc);
+    xmlXPathFreeContext(xpathctxt);
 
-		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Document has no fields");
+    xmlXPathFreeObject(xpathObj);
+    return SUCCESS;
+}
 
+/* {{{ static int solr_unserialize_document_object(HashTable *document_fields, char \
*serialized, int size TSRMLS_DC) */ +static int \
solr_unserialize_document_object(solr_document_t *doc_entry, char *serialized, int \
size TSRMLS_DC) +{
+	xmlDoc *doc = NULL;
+
+	doc = xmlReadMemory(serialized, size, NULL, "UTF-8", 0);
+
+	if (!doc)
+	{
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "The serialized document string is \
invalid");  return FAILURE;
 	}
 
-	for (i = 0U; i < num_nodes; i++)
+	if (solr_unserialize_document_fields(doc, doc_entry->fields TSRMLS_CC) == FAILURE)
 	{
-		xmlNode *currNode = result->nodeTab[i];
-
-		/* Absolutely No assumptions. I have to make sure that this is the name attribute \
                */
-		if (currNode->type == XML_ATTRIBUTE_NODE && solr_xml_match_node(currNode, "name"))
-		{
-			/* Get the field node */
-			xmlNode *field_xml_node = currNode->parent;
-
-			/* Retrieve all the values for this field and put them in the HashTable */
-			solr_unserialize_document_field(document_fields, field_xml_node TSRMLS_CC);
-		}
+	    php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to unserialize document \
fields"); +	    return FAILURE;
 	}
 
-	xmlXPathFreeContext(xpathctxt);
-
-	xmlXPathFreeObject(xpathObj);
+	if (solr_unserialize_child_documents(doc, doc_entry TSRMLS_CC) == FAILURE)
+	{
+	    php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to unserialize document \
fields"); +	    return FAILURE;
+	}
 
 	xmlFreeDoc(doc);
 
@@ -856,9 +932,11 @@ PHP_METHOD(SolrDocument, unserialize)
 
 	/* Allocated memory for the fields HashTable using fast cache for HashTables */
 	ALLOC_HASHTABLE(doc_entry->fields);
+	ALLOC_HASHTABLE(doc_entry->children);
 
 	/* Initializing the hash table used for storing fields in this SolrDocument */
 	zend_hash_init(doc_entry->fields, nSize, NULL, (dtor_func_t) \
solr_destroy_field_list, SOLR_DOCUMENT_FIELD_PERSISTENT); \
+	zend_hash_init(doc_entry->children, nSize, NULL, ZVAL_PTR_DTOR, \
SOLR_DOCUMENT_FIELD_PERSISTENT);  
 	/* Let's check one more time before insert into the HashTable */
 	if (zend_hash_index_exists(SOLR_GLOBAL(documents), document_index)) {
@@ -880,7 +958,7 @@ PHP_METHOD(SolrDocument, unserialize)
 	/* Overriding the default object handlers */
 	Z_OBJ_HT_P(objptr) = &solr_input_document_object_handlers;
 
-	if (solr_unserialize_document_object(doc_ptr->fields, serialized, serialized_length \
TSRMLS_CC) == FAILURE) +	if (solr_unserialize_document_object(doc_ptr, serialized, \
serialized_length TSRMLS_CC) == FAILURE)  {
 		return;
 	}
@@ -1308,6 +1386,65 @@ PHP_METHOD(SolrDocument, getInputDocument)
 }
 /* }}} */
 
+/* {{{ proto array SolrInputDocument::getChildDocuments( void )
+     Returns child documents or null if none */
+PHP_METHOD(SolrDocument, getChildDocuments)
+{
+    solr_document_t *solr_doc = NULL;
+
+    if (solr_fetch_document_entry(getThis(), &solr_doc TSRMLS_CC) == FAILURE)
+    {
+        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unable to fetch document entry \
for current object"); +        return;
+    }
+
+    if (zend_hash_num_elements(solr_doc->children) > 0)
+    {
+        array_init(return_value);
+        zend_hash_init(Z_ARRVAL_P(return_value), \
zend_hash_num_elements(solr_doc->children), NULL, ZVAL_PTR_DTOR, 0); +        \
zend_hash_copy(Z_ARRVAL_P(return_value), solr_doc->children, \
(copy_ctor_func_t)zval_add_ref, NULL, sizeof(zval *)); +    }
+}
+/* }}} */
+
+/* {{{ proto bool SolrInputDocument::hasChildDocuments( void )
+     Checks whether this document has child documents */
+PHP_METHOD(SolrDocument, hasChildDocuments)
+{
+    solr_document_t *solr_doc = NULL;
+
+    if (solr_fetch_document_entry(getThis(), &solr_doc TSRMLS_CC) == FAILURE)
+    {
+        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unable to fetch document entry \
for current object"); +        return;
+    }
+
+    if (zend_hash_num_elements(solr_doc->children) > 0)
+    {
+        RETURN_TRUE;
+    } else {
+        RETURN_FALSE;
+    }
+}
+/* }}} */
+
+/* {{{ proto int SolrInputDocument::getChildDocumentsCount( void )
+     Returns the number of child documents */
+PHP_METHOD(SolrDocument, getChildDocumentsCount)
+{
+    solr_document_t *solr_doc = NULL;
+
+    if (solr_fetch_document_entry(getThis(), &solr_doc TSRMLS_CC) == FAILURE)
+    {
+        php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unable to fetch document entry \
for current object"); +        return;
+    }
+
+    Z_TYPE_P(return_value) = IS_LONG;
+    Z_LVAL_P(return_value) = zend_hash_num_elements(solr_doc->children);
+}
+/* }}} */
+
 /* {{{ proto SolrDocumentField::__construct(void)
    Constructor */
 PHP_METHOD(SolrDocumentField, __construct)
diff --git a/solr_functions_helpers.c b/solr_functions_helpers.c
index 00b4b77..2fc229b 100644
--- a/solr_functions_helpers.c
+++ b/solr_functions_helpers.c
@@ -657,49 +657,127 @@ static void solr_write_array_opener(const xmlNode *node, \
solr_string_t *buffer,  }
 /* }}} */
 
-/**
- *
- * The @enc_type parameter must be SOLR_ENCODE_ARRAY_INDEX
- */
-/* {{{ static void solr_encode_solr_document(const xmlNode *node, solr_string_t \
                *buffer, solr_encoding_type_t enc_type, long int array_index, long \
                int parse_mode) */
-static void solr_encode_solr_document(const xmlNode *node, solr_string_t *buffer, \
solr_encoding_type_t enc_type, long int array_index, long int parse_mode) +static \
void solr_serialize_solr_document(const xmlNode *node, solr_string_t *dest); +static \
void solr_encode_solr_document_children(const xmlNode *node, xmlNode* builder_node, \
int child_docs_found); +static void solr_encode_solr_document(const xmlNode *node, \
solr_string_t *buffer, solr_encoding_type_t enc_type, long int array_index, long int \
parse_mode); +
+static void solr_serialize_solr_document(const xmlNode *node, solr_string_t *dest)
 {
+    xmlChar *doc_txt_buffer = NULL;
+    int doc_txt_len = 0;
     xmlNode *solr_document_node = NULL;
     xmlDoc *doc_ptr = solr_xml_create_xml_doc((xmlChar *) "solr_document", \
                &solr_document_node);
     xmlNode *fields_node = xmlNewChild(solr_document_node, NULL, (xmlChar *) \
"fields", NULL);  xmlNode *curr_node = node->children;
     int format = 1;
-    xmlChar *doc_txt_buffer = NULL;
-    int doc_txt_len = 0;
+    int child_docs_found = 0;
 
     while(curr_node != NULL)
     {
         if (XML_ELEMENT_NODE == curr_node->type)
         {
-             xmlNode *field = xmlNewChild(fields_node, NULL, (xmlChar *)"field", \
                NULL);
-
-             solr_encode_document_field(curr_node, field);
+            if (strcmp((const char *)curr_node->name, "doc") == 0)
+            {
+                child_docs_found++;
+            } else {
+                xmlNode *field = xmlNewChild(fields_node, NULL, (xmlChar *)"field", \
NULL); +                solr_encode_document_field(curr_node, field);
+            }
         }
 
         curr_node = curr_node->next;
     }
 
-    /* We have written all the fields to the document */
-
-    xmlIndentTreeOutput = 1;
+    if (child_docs_found > 0)
+    {
+        solr_encode_solr_document_children(node, solr_document_node, \
child_docs_found); +    }
 
+    /* We have written all the fields to the document */
     /* Dumping the document from memory to the buffer */
     xmlDocDumpFormatMemoryEnc(doc_ptr, &doc_txt_buffer, &doc_txt_len, "UTF-8", \
format);  
-    solr_write_solr_document_opener(NULL, buffer, enc_type, array_index, \
doc_txt_len); +    solr_string_appends_ex(dest, doc_txt_buffer, doc_txt_len);
 
-    solr_string_appends(buffer, (char *) doc_txt_buffer, doc_txt_len);
+    xmlFreeDoc(doc_ptr);
+    xmlFree(doc_txt_buffer);
+}
 
-    solr_write_object_closer(buffer);
+/* {{{ static void solr_encode_document_children(const xmlNode *node, solr_string_t* \
buffer, int child_docs_found, long int parse_mode) +   encodes the doc/doc \
child/nested documents */ +static void solr_encode_solr_document_children(const \
xmlNode *node, xmlNode* builder_node, int child_docs_found) +{
+    int current_index = 0;
+    xmlXPathContext *xpathctxt = NULL;
+    const xmlChar *xpath_expression = (xmlChar *) "child::doc";
+    xmlXPathObject *xpathObj = NULL;
+    xmlNodeSet *result = NULL;
 
-    xmlFree(doc_txt_buffer);
+    xpathctxt = xmlXPathNewContext(node->doc);
+    xpathctxt->node = (xmlNodePtr) node;
+    xpathObj = xmlXPathEval(xpath_expression, xpathctxt);
+    result = xpathObj->nodesetval;
+    child_docs_found = result->nodeNr;
 
-    xmlFreeDoc(doc_ptr);
+    size_t size = (result) ? result->nodeNr : 0;
+
+    xmlNode *child_docs_node = xmlNewChild(builder_node, NULL, (xmlChar \
*)"child_docs", NULL); +
+    for (current_index=0; current_index < child_docs_found; current_index++)
+    {
+        xmlNode * child_doc = NULL;
+        int encoded_len;
+        char *encoded;
+
+        solr_string_t tmp_buffer;
+        solr_string_t tmp_s_buffer;
+        memset(&tmp_buffer, 0, sizeof(solr_string_t));
+        memset(&tmp_s_buffer, 0, sizeof(solr_string_t));
+
+        solr_serialize_solr_document(result->nodeTab[current_index], &tmp_buffer);
+
+        solr_string_append_const(&tmp_s_buffer, "C:12:\"SolrDocument\":");
+
+        solr_string_append_long(&tmp_s_buffer, tmp_buffer.len);
+
+        solr_string_append_const(&tmp_s_buffer, ":{");
+
+        solr_string_appends_ex(&tmp_s_buffer, tmp_buffer.str, tmp_buffer.len);
+
+        solr_write_object_closer(&tmp_s_buffer);
+
+        encoded = (char *)php_base64_encode((unsigned char*)tmp_s_buffer.str, \
tmp_s_buffer.len, &encoded_len); +
+        child_doc = xmlNewChild(child_docs_node, NULL, (const xmlChar *) "dochash", \
(xmlChar *)encoded); +
+        solr_string_free_ex(&tmp_buffer);
+        solr_string_free_ex(&tmp_s_buffer);
+        if (encoded)
+        {
+            efree(encoded);
+        }
+    }
+}
+/* }}} */
+
+/**
+ *
+ * The @enc_type parameter must be SOLR_ENCODE_ARRAY_INDEX
+ */
+/* {{{ static void solr_encode_solr_document(const xmlNode *node, solr_string_t \
*buffer, solr_encoding_type_t enc_type, long int array_index, long int parse_mode) */ \
+static void solr_encode_solr_document(const xmlNode *node, solr_string_t *buffer, \
solr_encoding_type_t enc_type, long int array_index, long int parse_mode) +{
+    solr_string_t doc_serialized_buffer;
+    memset(&doc_serialized_buffer, 0, sizeof(solr_string_t));
+
+    solr_serialize_solr_document(node, &doc_serialized_buffer);
+
+    solr_write_solr_document_opener(NULL, buffer, enc_type, array_index, \
doc_serialized_buffer.len); +
+    solr_string_appends(buffer, (char *) doc_serialized_buffer.str, \
doc_serialized_buffer.len); +
+    solr_write_object_closer(buffer);
+    solr_string_free(&doc_serialized_buffer);
 }
 /* }}} */
 
@@ -720,7 +798,7 @@ static void solr_write_object_opener_child_doc(const xmlNode \
*node, int num_chil  /* }}} */
 
 /* {{{ static void solr_encode_document_children(const xmlNode *node, solr_string_t* \
                buffer, int child_docs_found, long int parse_mode)
-   encodes the doc/doc child/nested documents */
+   encodes the doc/doc child/nested documents ONLY FOR SolrObject */
 static void solr_encode_document_children(const xmlNode *node, solr_string_t* \
buffer, int child_docs_found, long int parse_mode)  {
     int current_index = 0;
@@ -813,6 +891,11 @@ static void solr_encode_document(const xmlNode *node, \
solr_string_t *buffer, sol  static void solr_encode_document_field_simple(const \
xmlNode *fieldNode, xmlNode *field)  {
 	xmlChar *fieldname = solr_xml_get_node_contents(fieldNode->properties);
+	if (strcmp((const char *)fieldname, "")== 0)
+	{
+	    /** todo throw an IllegalOperationException */
+	    return;
+	}
 
 	xmlChar *field_value = xmlEncodeEntitiesReentrant(fieldNode->doc, \
solr_xml_get_node_contents(fieldNode));  
diff --git a/tests/030.solrdocument_child_doc_response_solrdoc.phpt \
b/tests/030.solrdocument_child_doc_response_solrdoc.phpt new file mode 100644
index 0000000..ec9a014
--- /dev/null
+++ b/tests/030.solrdocument_child_doc_response_solrdoc.phpt
@@ -0,0 +1,70 @@
+--TEST--
+SolrUtils::digestXmlResponse() - Response with child documents
+--FILE--
+<?php
+
+require_once "bootstrap.inc";
+
+$fixtureXml = file_get_contents(EXAMPLE_RESPONSE_XML_2);
+
+$response = SolrUtils::digestXmlResponse($fixtureXml, SolrResponse::PARSE_SOLR_DOC);
+print_r($response);
+foreach($response->response->docs as $doc)
+{
+	print_r($doc->toArray());
+	echo "children".PHP_EOL;
+	print_r($doc->getChildDocuments());
+}
+?>
+--EXPECT--
+SolrDocument Object
+(
+    [response] => SolrDocument Object
+        (
+            [numFound] => 3
+            [start] => 0
+            [docs] => Array
+                (
+                    [0] => SolrDocument Object
+                        (
+                            [id] => parent_1
+                            [_childDocuments_] => Array
+                                (
+                                    [0] => SolrDocument Object
+                                        (
+                                            [id] => CHILD_1_1
+                                        )
+
+                                )
+
+                        )
+
+                    [1] => SolrDocument Object
+                        (
+                            [id] => parent_2
+                            [_childDocuments_] => Array
+                                (
+                                    [0] => SolrDocument Object
+                                        (
+                                            [id] => CHILD_2_1
+                                        )
+
+                                    [1] => SolrDocument Object
+                                        (
+                                            [id] => CHILD_2_2
+                                        )
+
+                                )
+
+                        )
+
+                    [2] => SolrDocument Object
+                        (
+                            [id] => not_a_parent_1
+                        )
+
+                )
+
+        )
+
+)
diff --git a/tests/031.solrdocument_haschilddocuments.phpt \
b/tests/031.solrdocument_haschilddocuments.phpt new file mode 100644
index 0000000..8069639
--- /dev/null
+++ b/tests/031.solrdocument_haschilddocuments.phpt
@@ -0,0 +1,15 @@
+--TEST--
+SolrDocument::hasChildDocuments() - Method test
+--FILE--
+<?php
+
+require_once "bootstrap.inc";
+
+$fixtureXml = file_get_contents(EXAMPLE_RESPONSE_XML_2);
+
+$response = SolrUtils::digestXmlResponse($fixtureXml, SolrResponse::PARSE_SOLR_DOC);
+print_r($response);
+var_dump($response->response->docs[0]->hasChildDocuments());
+?>
+--EXPECT--
+bool(true)
\ No newline at end of file
diff --git a/tests/032.solrdocument_getchilddocscount.phpt \
b/tests/032.solrdocument_getchilddocscount.phpt new file mode 100644
index 0000000..91f21c1
--- /dev/null
+++ b/tests/032.solrdocument_getchilddocscount.phpt
@@ -0,0 +1,15 @@
+--TEST--
+SolrDocument::getChildDocumentsCount() - Method test
+--FILE--
+<?php
+
+require_once "bootstrap.inc";
+
+$fixtureXml = file_get_contents(EXAMPLE_RESPONSE_XML_2);
+
+$response = SolrUtils::digestXmlResponse($fixtureXml, SolrResponse::PARSE_SOLR_DOC);
+print_r($response);
+var_dump($response->response->docs[0]->getChildDocumentsCount());
+?>
+--EXPECT--
+int(1)
\ No newline at end of file



-- 
PECL CVS Mailing List 
To unsubscribe, visit: http://www.php.net/unsub.php

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic