1 /*
2    +----------------------------------------------------------------------+
3    | Copyright (c) The PHP Group                                          |
4    +----------------------------------------------------------------------+
5    | This source file is subject to version 3.01 of the PHP license,      |
6    | that is bundled with this package in the file LICENSE, and is        |
7    | available through the world-wide-web at the following url:           |
8    | http://www.php.net/license/3_01.txt                                  |
9    | If you did not receive a copy of the PHP license and are unable to   |
10    | obtain it through the world-wide-web, please send a note to          |
11    | license@php.net so we can mail you a copy immediately.               |
12    +----------------------------------------------------------------------+
13    | Authors:                                                             |
14    |          Israel Ekpo <iekpo@php.net>                                 |
15    |          Omar Shaban <omars@php.net>                                 |
16    +----------------------------------------------------------------------+
17 */
18 
19 #include "php_solr.h"
20 
21 /* {{{ Macros */
22 
23 
24 /* resets the key_str with key and tries to find the zv */
solr_opt_check(HashTable * options_ht,const char * key,zend_string * key_str,zval ** zv)25 static inline int solr_opt_check(HashTable *options_ht, const char * key, zend_string * key_str, zval ** zv)
26 {
27     int result = 0;
28     key_str = zend_string_init(key, strlen (key), 0);
29     result = (*zv = zend_hash_find(options_ht, key_str)) != NULL;
30     zend_string_release(key_str);
31     return result;
32 }
33 
34 /* {{{ static void solr_client_init_urls(solr_client_t *solr_client) */
solr_client_init_urls(solr_client_t * solr_client)35 static void solr_client_init_urls(solr_client_t *solr_client)
36 {
37 	solr_string_t url_prefix;
38 
39 	solr_client_options_t *options = &(solr_client->options);
40 
41 	memset(&url_prefix, 0, sizeof(solr_string_t));
42 
43 	/* Release all previously allocated URL values, if any */
44 	solr_string_free(&(options->update_url));
45 	solr_string_free(&(options->extract_url));
46 	solr_string_free(&(options->search_url));
47 	solr_string_free(&(options->thread_url));
48 	solr_string_free(&(options->ping_url));
49 	solr_string_free(&(options->terms_url));
50 	solr_string_free(&(options->system_url));
51 	solr_string_free(&(options->get_url));
52 
53 	/* Making http://hostname:host_port/path/ */
54 
55 	if (options->secure)
56 	{
57 		solr_string_append_const(&url_prefix, "https://");
58 
59 	} else {
60 
61 		solr_string_append_const(&url_prefix, "http://");
62 	}
63 
64 	solr_string_append_solr_string(&url_prefix, &(options->hostname));
65 	solr_string_appendc(&url_prefix, ':');
66 	solr_string_append_long(&url_prefix, options->host_port);
67 	solr_string_appendc(&url_prefix, '/');
68 	solr_string_append_solr_string(&url_prefix, &(options->path));
69 	solr_string_appendc(&url_prefix, '/');
70 
71 	/* Copying over the prefixes */
72 	solr_string_append_solr_string(&(options->update_url), &url_prefix);
73 	solr_string_append_solr_string(&(options->extract_url), &url_prefix);
74 	solr_string_append_solr_string(&(options->search_url), &url_prefix);
75 	solr_string_append_solr_string(&(options->thread_url), &url_prefix);
76 	solr_string_append_solr_string(&(options->ping_url),   &url_prefix);
77 	solr_string_append_solr_string(&(options->terms_url),  &url_prefix);
78 	solr_string_append_solr_string(&(options->system_url),  &url_prefix);
79 	solr_string_append_solr_string(&(options->get_url),  &url_prefix);
80 
81 	/* Making http://hostname:host_port/path/servlet/ */
82 	solr_string_append_solr_string(&(options->update_url), &(options->update_servlet));
83 	solr_string_append_solr_string(&(options->extract_url), &(options->extract_servlet));
84 	solr_string_append_solr_string(&(options->search_url), &(options->search_servlet));
85 	solr_string_append_solr_string(&(options->thread_url), &(options->thread_servlet));
86 	solr_string_append_solr_string(&(options->ping_url),   &(options->ping_servlet));
87 	solr_string_append_solr_string(&(options->terms_url),  &(options->terms_servlet));
88 	solr_string_append_solr_string(&(options->system_url),  &(options->system_servlet));
89 	solr_string_append_solr_string(&(options->get_url), &(options->get_servlet));
90 
91 	solr_string_append_const(&(options->update_url), "/?version=2.2&indent=on&wt=");
92 	solr_string_append_const(&(options->extract_url), "/?version=2.2&indent=on&wt=");
93 	solr_string_append_const(&(options->search_url), "/?version=2.2&indent=on&wt=");
94 	solr_string_append_const(&(options->thread_url), "/?version=2.2&indent=on&wt=");
95 	solr_string_append_const(&(options->ping_url),   "/?version=2.2&indent=on&wt=");
96 	solr_string_append_const(&(options->terms_url),  "/?version=2.2&indent=on&wt=");
97 	solr_string_append_const(&(options->system_url),  "/?version=2.2&indent=on&wt=");
98 	solr_string_append_const(&(options->get_url),  "/?version=2.2&indent=on&wt=");
99 
100 	solr_string_append_solr_string(&(options->update_url), &(options->response_writer));
101 	solr_string_append_solr_string(&(options->extract_url), &(options->response_writer));
102 	solr_string_append_solr_string(&(options->search_url), &(options->response_writer));
103 	solr_string_append_solr_string(&(options->thread_url), &(options->response_writer));
104 	solr_string_append_solr_string(&(options->ping_url),   &(options->response_writer));
105 	solr_string_append_solr_string(&(options->terms_url),  &(options->response_writer));
106 	solr_string_append_solr_string(&(options->system_url),  &(options->response_writer));
107 	solr_string_append_solr_string(&(options->get_url),  &(options->response_writer));
108 
109 	solr_string_free(&url_prefix);
110 }
111 /* }}} */
112 
113 /* {{{ static int solr_http_build_query(solr_string_t *buffer, zval *params_objptr, const solr_char_t *delimiter, int delimiter_length) */
solr_http_build_query(solr_string_t * buffer,solr_params_t * solr_params,const solr_char_t * delimiter,int delimiter_length)114 static int solr_http_build_query(solr_string_t *buffer, solr_params_t *solr_params, const solr_char_t *delimiter, int delimiter_length)
115 {
116 	HashTable *params = NULL;
117 	solr_param_t *solr_param = NULL;
118 
119 	params = solr_params->params;
120 
121 	ZEND_HASH_FOREACH_PTR(params, solr_param)
122 	{
123 
124 		solr_string_t tmp_values_buffer;
125 
126 		memset(&tmp_values_buffer, 0, sizeof(solr_string_t));
127 
128 		solr_param->fetch_func(solr_param, &tmp_values_buffer);
129 
130 		solr_string_append_solr_string(buffer, &tmp_values_buffer);
131 		solr_string_appends(buffer, delimiter, delimiter_length);
132 		solr_string_free(&tmp_values_buffer);
133 	} ZEND_HASH_FOREACH_END();
134 
135 
136 	solr_string_remove_last_char(buffer);
137 
138 	return SUCCESS;
139 }
140 /* }}} */
141 
142 /* {{{ PHP_SOLR_API solr_client_t* solr_init_client(zval * objptr)
143   inititialize solr_client_t and update zval's index
144  */
solr_init_client(zval * objptr)145 PHP_SOLR_API solr_client_t *solr_init_client(zval *objptr)
146 {
147     long int client_index = SOLR_UNIQUE_CLIENT_INDEX();
148     solr_client_t *solr_client = NULL;
149 
150     zend_update_property_long(solr_ce_SolrClient, OBJ_FOR_PROP(objptr), SOLR_INDEX_PROPERTY_NAME, sizeof(SOLR_INDEX_PROPERTY_NAME) - 1, client_index);
151 
152     solr_client = (solr_client_t *) pemalloc(sizeof(solr_client_t), SOLR_CLIENT_PERSISTENT);
153 
154     memset(solr_client, 0, sizeof(solr_client_t));
155 
156     solr_client->client_index = client_index;
157     if ((solr_client = zend_hash_index_update_ptr(SOLR_GLOBAL(clients), client_index, (void *)solr_client)) == NULL) {
158         pefree(solr_client, SOLR_CLIENT_PERSISTENT);
159         php_error_docref(NULL, E_ERROR, "Error while registering client in HashTable");
160         return NULL;
161     }
162     return solr_client;
163 }
164 /* }}} */
165 
166 /******************************************************************************/
167 /** DEFINITIONS FOR SOLR CLIENT METHODS                                      **/
168 /******************************************************************************/
169 
170 /* {{{ proto SolrClient::__construct(array options )
171    Constructor for SolrClient */
PHP_METHOD(SolrClient,__construct)172 PHP_METHOD(SolrClient, __construct)
173 {
174 	zval *options = NULL;
175 	zval *objptr  = getThis();
176 	HashTable *options_ht = NULL;
177 	zval *tmp1 = NULL, *tmp2 = NULL;
178 	solr_client_t *solr_client_dest = NULL;
179 	solr_client_options_t *client_options = NULL;
180 	solr_curl_t *handle = NULL;
181 	zend_string *key_str; /* tmp storage to use with zend_hash_find */
182 	key_str = zend_string_init("", 0, 0);
183 
184 	size_t num_options = 0;
185 
186 	long int secure = 0L;
187 	long int verify_peer = 0L;
188 	long int verify_host = 2L;
189 	long int timeout = 30L;
190 
191 	/* Process the parameters passed to the default constructor */
192 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &options) == FAILURE) {
193 	    zend_string_release(key_str);
194 		solr_throw_exception_ex(solr_ce_SolrIllegalArgumentException, SOLR_ERROR_4000, SOLR_FILE_LINE_FUNC, "Invalid parameter. The client options array is required for a SolrClient instance. It must also be passed as the only parameter");
195 		return;
196 	}
197 
198 	options_ht = Z_ARRVAL_P(options);
199 
200 	num_options = zend_hash_num_elements(options_ht);
201 
202 	if (!num_options) {
203 	    zend_string_release(key_str);
204 		solr_throw_exception_ex(solr_ce_SolrIllegalArgumentException, SOLR_ERROR_4000, SOLR_FILE_LINE_FUNC, "The SolrClient options cannot be an empty array");
205 		return;
206 	}
207 
208 	solr_client_dest = solr_init_client(objptr);
209 	if (!solr_client_dest) {
210 	    zend_string_release(key_str);
211 	    solr_throw_exception_ex(solr_ce_SolrIllegalArgumentException, SOLR_ERROR_4000, SOLR_FILE_LINE_FUNC, "Unable to initialize solr_client_t ");
212 	    return;
213 	}
214 
215 	/* Release the original pointer */
216 
217 	client_options = &(solr_client_dest->options);
218 	handle = &(solr_client_dest->handle);
219 
220 	solr_init_options(client_options);
221 
222 	solr_string_append_const(&(client_options->response_writer), SOLR_XML_RESPONSE_WRITER);
223 
224 	solr_string_append_const(&(client_options->update_servlet), SOLR_DEFAULT_UPDATE_SERVLET);
225 	solr_string_append_const(&(client_options->extract_servlet), SOLR_DEFAULT_EXTRACT_SERVLET);
226 	solr_string_append_const(&(client_options->search_servlet), SOLR_DEFAULT_SEARCH_SERVLET);
227 	solr_string_append_const(&(client_options->thread_servlet), SOLR_DEFAULT_THREADS_SERVLET);
228 	solr_string_append_const(&(client_options->ping_servlet),   SOLR_DEFAULT_PING_SERVLET);
229 	solr_string_append_const(&(client_options->terms_servlet),  SOLR_DEFAULT_TERMS_SERVLET);
230 	solr_string_append_const(&(client_options->system_servlet),  SOLR_DEFAULT_SYSTEM_SERVLET);
231 	solr_string_append_const(&(client_options->get_servlet), SOLR_DEFAULT_GET_SERVLET);
232 
233 	if ( solr_opt_check(options_ht, "wt", key_str, &tmp1) && Z_TYPE_P(tmp1) == IS_STRING && Z_STRLEN_P(tmp1))
234 	{
235 		if (solr_is_supported_response_writer((solr_char_t *)Z_STRVAL_P(tmp1), Z_STRLEN_P(tmp1))) {
236 			solr_string_set(&(client_options->response_writer), (const solr_char_t *) Z_STRVAL_P(tmp1), Z_STRLEN_P(tmp1));
237 		} else {
238 			php_error_docref(NULL, E_WARNING, "Unsupported response writer %s. This value will be ignored", Z_STRVAL_P(tmp1));
239 		}
240 	}
241 
242 	if (solr_opt_check(options_ht, "secure", key_str, &tmp1))
243 	{
244 		if (Z_TYPE_P(tmp1) == IS_TRUE)
245 		{
246 			secure = (long int) 1L;
247 		} else if (Z_TYPE_P(tmp1) == IS_LONG) {
248 			secure = Z_LVAL_P(tmp1);
249 		}
250 	}
251 
252 	client_options->secure = secure;
253 
254 /**
255  * FOR NOW LET'S LEAVE IT AT 2 : This will force and require a match on the common name
256  *
257 	if (secure && zend_hash_find(options_ht, "ssl_verifyhost", sizeof("ssl_verifyhost"), (void**) &tmp1) == SUCCESS && Z_TYPE_P(tmp1) == IS_LONG)
258 	{
259 		verify_host = ((Z_LVAL_P(tmp1) > 0L && Z_LVAL_P(tmp1) < 3L) ? Z_LVAL_P(tmp1) : verify_host);
260 	}
261 */
262 	client_options->ssl_verify_host = verify_host;
263 
264 	if (secure && solr_opt_check(options_ht, "ssl_cert", key_str, &tmp1) && Z_TYPE_P(tmp1) == IS_STRING && Z_STRLEN_P(tmp1))
265 	{
266 		verify_peer = 1L;
267 
268 		solr_string_appends(&(client_options->ssl_cert), Z_STRVAL_P(tmp1), Z_STRLEN_P(tmp1));
269 	}
270 
271 	if (secure && solr_opt_check(options_ht, "ssl_key", key_str, &tmp1) && Z_TYPE_P(tmp1) == IS_STRING && Z_STRLEN_P(tmp1))
272 	{
273 		verify_peer = 1L;
274 		solr_string_appends(&(client_options->ssl_key), (solr_char_t *) Z_STRVAL_P(tmp1), Z_STRLEN_P(tmp1));
275 	}
276 
277 	if (secure && solr_opt_check(options_ht, "ssl_keypassword", key_str, &tmp1) && Z_TYPE_P(tmp1) == IS_STRING && Z_STRLEN_P(tmp1))
278 	{
279 		verify_peer = 1L;
280 
281 		solr_string_appends(&(client_options->ssl_keypassword), (solr_char_t *) Z_STRVAL_P(tmp1), Z_STRLEN_P(tmp1));
282 	}
283 	// ssl_cainfo
284 	if (secure && solr_opt_check(options_ht, "ssl_cainfo", key_str, &tmp1) && Z_TYPE_P(tmp1) == IS_STRING && Z_STRLEN_P(tmp1))
285 	{
286 		verify_peer = 1L;
287 
288 		solr_string_appends(&(client_options->ssl_cainfo), (solr_char_t *) Z_STRVAL_P(tmp1), Z_STRLEN_P(tmp1));
289 	}
290 	// ssl_capath
291 	if (secure && solr_opt_check(options_ht, "ssl_capath", key_str, &tmp1) && Z_TYPE_P(tmp1) == IS_STRING && Z_STRLEN_P(tmp1))
292 	{
293 		verify_peer = 1L;
294 
295 		solr_string_appends(&(client_options->ssl_capath), (solr_char_t *) Z_STRVAL_P(tmp1), Z_STRLEN_P(tmp1));
296 	}
297 
298 	client_options->ssl_verify_peer = verify_peer;
299 	// hostname
300 	if (solr_opt_check(options_ht, "hostname", key_str, &tmp1) && Z_TYPE_P(tmp1) == IS_STRING && Z_STRLEN_P(tmp1))
301 	{
302 		solr_string_appends(&(client_options->hostname), (solr_char_t *) Z_STRVAL_P(tmp1), Z_STRLEN_P(tmp1));
303 	} else {
304 		solr_string_append_const(&(client_options->hostname), SOLR_REQUEST_DEFAULT_HOST);
305 	}
306 
307 	// port
308 	if (solr_opt_check(options_ht, "port", key_str, &tmp1) && Z_TYPE_P(tmp1) == IS_LONG)
309 	{
310 		client_options->host_port = Z_LVAL_P(tmp1);
311 	} else if (solr_opt_check(options_ht, "port", key_str, &tmp1) && Z_TYPE_P(tmp1) == IS_STRING && Z_STRLEN_P(tmp1)) {
312 
313 		long int host_port = atol(Z_STRVAL_P(tmp1));
314 
315 		if (host_port) {
316 			client_options->host_port = host_port;
317 		} else {
318 			client_options->host_port = SOLR_REQUEST_DEFAULT_PORT;
319 		}
320 
321 	} else {
322 		client_options->host_port = SOLR_REQUEST_DEFAULT_PORT;
323 	}
324 
325 	if (solr_opt_check(options_ht, "timeout", key_str, &tmp1))
326 	{
327 		long int timeout_value = 30L;
328 
329 		if (Z_TYPE_P(tmp1) == IS_LONG)
330 		{
331 			timeout_value = Z_LVAL_P(tmp1);
332 
333 		} else if (Z_TYPE_P(tmp1) == IS_STRING && Z_STRLEN_P(tmp1)) {
334 
335 			timeout_value = atol(Z_STRVAL_P(tmp1));
336 		}
337 
338 		timeout = ((timeout_value > 0L) ? timeout_value : timeout);
339 	}
340 
341 	client_options->timeout = timeout;
342 
343 	if (solr_opt_check(options_ht, "path", key_str, &tmp1) && Z_TYPE_P(tmp1) == IS_STRING && Z_STRLEN_P(tmp1))
344 	{
345 		char *path_to_solr = Z_STRVAL_P(tmp1);
346 
347 		size_t path_to_solr_start = 0;
348 
349 		size_t length_adjustment  = 0;
350 
351 		if (path_to_solr[0] == '/')
352 		{
353 			path_to_solr_start = length_adjustment = 1;
354 		}
355 
356 		if (path_to_solr[Z_STRLEN_P(tmp1)] == '/')
357 		{
358 			length_adjustment++;
359 		}
360 
361 		solr_string_appends(&(client_options->path), Z_STRVAL_P(tmp1) + path_to_solr_start, Z_STRLEN_P(tmp1) - length_adjustment);
362 
363 	} else {
364 		solr_string_append_const(&(client_options->path), SOLR_REQUEST_DEFAULT_PATH);
365 	}
366 
367 	if (
368 	        solr_opt_check(options_ht, "query_string_delimiter", key_str, &tmp1)
369 	        && Z_TYPE_P(tmp1) == IS_STRING)
370 	{
371 		solr_string_appends(&(client_options->qs_delimiter), Z_STRVAL_P(tmp1), Z_STRLEN_P(tmp1));
372 	} else {
373 		solr_string_append_const(&(client_options->qs_delimiter), SOLR_REQUEST_DEFAULT_QS_DELIMITER);
374 	}
375 
376 	if (
377 	        solr_opt_check(options_ht, "login", key_str, &tmp1) && Z_TYPE_P(tmp1) == IS_STRING
378 	        && solr_opt_check(options_ht, "password", key_str, &tmp2) && Z_TYPE_P(tmp2) == IS_STRING)
379 	{
380 		solr_string_appends(&(client_options->http_auth_credentials), Z_STRVAL_P(tmp1), Z_STRLEN_P(tmp1));
381 		solr_string_appendc(&(client_options->http_auth_credentials), ':');
382 		solr_string_appends(&(client_options->http_auth_credentials), Z_STRVAL_P(tmp2), Z_STRLEN_P(tmp2));
383 	}
384 
385 	if (solr_opt_check(options_ht, "proxy_host", key_str, &tmp1) && Z_TYPE_P(tmp1) == IS_STRING)
386 	{
387 		solr_string_appends(&(client_options->proxy_hostname), Z_STRVAL_P(tmp1), Z_STRLEN_P(tmp1));
388 	}
389 
390 	if (solr_opt_check(options_ht, "proxy_port", key_str, &tmp1))
391 	{
392 		long int proxy_port_value = 0L;
393 
394 		if (Z_TYPE_P(tmp1) == IS_LONG)
395 		{
396 			proxy_port_value = Z_LVAL_P(tmp1);
397 		} else if (Z_TYPE_P(tmp1) == IS_STRING && Z_STRLEN_P(tmp1)) {
398 			proxy_port_value = atol(Z_STRVAL_P(tmp1));
399 		}
400 
401 		if (proxy_port_value > 0L)
402 		{
403 			client_options->proxy_port = proxy_port_value;
404 		}
405 	}
406 
407 	if (solr_opt_check(options_ht, "proxy_login", key_str, &tmp1) && Z_TYPE_P(tmp1) == IS_STRING
408 	        && solr_opt_check(options_ht, "proxy_password", key_str, &tmp2) && Z_TYPE_P(tmp2) == IS_STRING)
409 	{
410 		solr_string_appends(&(client_options->proxy_auth_credentials), Z_STRVAL_P(tmp1), Z_STRLEN_P(tmp1));
411 		solr_string_appendc(&(client_options->proxy_auth_credentials), ':');
412 		solr_string_appends(&(client_options->proxy_auth_credentials), Z_STRVAL_P(tmp2), Z_STRLEN_P(tmp2));
413 	}
414 
415 	solr_init_handle(handle, client_options);
416 	zend_string_free(key_str);
417 
418 	SOLR_GLOBAL(client_count)++;
419 }
420 /* }}} */
421 
422 /* {{{ proto SolrClient::__destruct(void)
423    Destructor for SolrClient */
PHP_METHOD(SolrClient,__destruct)424 PHP_METHOD(SolrClient, __destruct)
425 {
426 	solr_client_t *solr_client = NULL;
427 
428 	if (solr_fetch_client_entry(getThis(), &solr_client) == SUCCESS) 	{
429 
430 		zend_hash_index_del(SOLR_GLOBAL(clients), solr_client->client_index);
431 
432 		/* Keep track of how many SolrClient instances we have. */
433 		SOLR_GLOBAL(client_count)--;
434 
435 		return ;
436 	}
437 }
438 /* }}} */
439 
440 /* {{{ proto SolrClient::__sleep(void)
441    Should not be called directly. Serialization is not supported. */
PHP_METHOD(SolrClient,__sleep)442 PHP_METHOD(SolrClient, __sleep)
443 {
444     solr_init_client(getThis());
445     solr_throw_exception_ex(solr_ce_SolrIllegalOperationException, SOLR_ERROR_1001, SOLR_FILE_LINE_FUNC, SOLR_ERROR_1001_MSG);
446 }
447 /* }}} */
448 
449 /* {{{ proto SolrClient::__wakeup(void)
450    Should not be called directly. Serialization is not supported. */
PHP_METHOD(SolrClient,__wakeup)451 PHP_METHOD(SolrClient, __wakeup)
452 {
453     solr_init_client(getThis());
454     solr_throw_exception_ex(solr_ce_SolrIllegalOperationException, SOLR_ERROR_1001, SOLR_FILE_LINE_FUNC, SOLR_ERROR_1001_MSG);
455 }
456 /* }}} */
457 
458 /* {{{ proto SolrClient::__clone(void)
459    Should not be called directly. Cloning is not supported. */
PHP_METHOD(SolrClient,__clone)460 PHP_METHOD(SolrClient, __clone)
461 {
462     solr_init_client(getThis());
463     solr_throw_exception_ex(solr_ce_SolrIllegalOperationException, SOLR_ERROR_4001, SOLR_FILE_LINE_FUNC, "Cloning of SolrClient objects is currently not supported");
464 }
465 /* }}} */
466 
467 /* {{{ proto bool SolrClient::setServelet(int servlet_type, string new_value)
468    Changes the specified servlet type to a new value */
PHP_METHOD(SolrClient,setServlet)469 PHP_METHOD(SolrClient, setServlet)
470 {
471 	long int servlet_type_value = 0L;
472 	solr_char_t *new_servlet_value = NULL;
473 	COMPAT_ARG_SIZE_T new_servlet_value_length = 0;
474 	solr_client_t *client = NULL;
475 	solr_servlet_type_t servlet_type = SOLR_SERVLET_TYPE_BEGIN;
476 
477 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &servlet_type_value, &new_servlet_value, &new_servlet_value_length) == FAILURE) {
478 
479 		php_error_docref(NULL, E_WARNING, "Invalid parameter.");
480 
481 		RETURN_FALSE;
482 	}
483 
484 	if (!new_servlet_value_length)
485 	{
486 		php_error_docref(NULL, E_WARNING, "Invalid servlet value.");
487 
488 		RETURN_FALSE;
489 	}
490 
491 	/* Retrieve the client entry */
492 	if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
493 	{
494 		php_error_docref(NULL, E_ERROR, "Unable to retrieve client");
495 
496 		RETURN_FALSE;
497 	}
498 
499 	servlet_type = (solr_servlet_type_t) servlet_type_value;
500 
501 	switch(servlet_type)
502 	{
503 		case SOLR_SERVLET_TYPE_SEARCH :
504 		{
505 			solr_string_set(&(client->options.search_servlet), new_servlet_value, new_servlet_value_length);
506 		}
507 		break;
508 
509 		case SOLR_SERVLET_TYPE_TERMS :
510 		{
511 			solr_string_set(&(client->options.terms_servlet), new_servlet_value, new_servlet_value_length);
512 		}
513 		break;
514 
515 		case SOLR_SERVLET_TYPE_UPDATE :
516 		{
517 			solr_string_set(&(client->options.update_servlet), new_servlet_value, new_servlet_value_length);
518 		}
519 		break;
520 
521 		case SOLR_SERVLET_TYPE_THREADS :
522 		{
523 			solr_string_set(&(client->options.thread_servlet), new_servlet_value, new_servlet_value_length);
524 		}
525 		break;
526 
527 		case SOLR_SERVLET_TYPE_PING :
528 		{
529 			solr_string_set(&(client->options.ping_servlet), new_servlet_value, new_servlet_value_length);
530 		}
531 		break;
532 		case SOLR_SERVLET_TYPE_SYSTEM :
533 				{
534 					solr_string_set(&(client->options.system_servlet), new_servlet_value, new_servlet_value_length);
535 				}
536 		break;
537 
538 		default :
539 		{
540 			solr_throw_exception_ex(solr_ce_SolrIllegalArgumentException, SOLR_ERROR_4000, SOLR_FILE_LINE_FUNC, "Invalid Servlet type %ld specified. Value discarded.", servlet_type_value);
541 
542 			RETURN_FALSE;
543 		}
544 	}
545 
546 	RETURN_TRUE;
547 }
548 /* }}} */
549 
550 // client->handle.err.str client->handle.request_body_debug.buffer.str
551 
552 /* {{{ proto SolrQueryResponse SolrClient::query(SolrParams query)
553    Sends a name-value pair request to the Solr server. */
PHP_METHOD(SolrClient,query)554 PHP_METHOD(SolrClient, query)
555 {
556 	zval *solr_params_obj = NULL;
557 	solr_client_t *client = NULL;
558 	solr_params_t *solr_params = NULL;
559 	solr_string_t *buffer = NULL;
560 	solr_char_t *delimiter = NULL;
561 	COMPAT_ARG_SIZE_T delimiter_length = 0;
562 	zend_bool success = 1;
563 	solr_request_type_t solr_request_type = SOLR_REQUEST_SEARCH;
564 	solr_string_t *request_url = NULL;
565 
566 	/* Process the parameters passed to the default constructor */
567 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &solr_params_obj, solr_ce_SolrParams) == FAILURE) {
568 
569 		solr_throw_exception_ex(solr_ce_SolrIllegalArgumentException, SOLR_ERROR_4000, SOLR_FILE_LINE_FUNC, SOLR_ERROR_4000_MSG);
570 
571 		return;
572 	}
573 
574 	/* Retrieve the client entry */
575 	if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
576 	{
577 		php_error_docref(NULL, E_ERROR, "Unable to retrieve client");
578 
579 		return;
580 	}
581 
582 	/* Make sure the SolrParams object passed is a valid one */
583 	if (solr_fetch_params_entry(solr_params_obj, &solr_params) == FAILURE) {
584 
585 		solr_throw_exception_ex(solr_ce_SolrIllegalArgumentException, SOLR_ERROR_4000, SOLR_FILE_LINE_FUNC, "SolrParams parameter passed is not a valid one.");
586 
587 		return ;
588 	}
589 
590 	/* The SolrParams instance must contain at least one parameter */
591 	if (zend_hash_num_elements(solr_params->params) < 1)
592 	{
593 		solr_throw_exception_ex(solr_ce_SolrIllegalArgumentException, SOLR_ERROR_4000, SOLR_FILE_LINE_FUNC, "SolrParams parameter passed contains no parameters.");
594 
595 		return ;
596 	}
597 
598 	buffer = &(client->handle.request_body.buffer);
599 
600 	/* Get rid of all the data from the previous request */
601 	solr_string_free(buffer);
602 
603 	delimiter = client->options.qs_delimiter.str;
604 
605 	delimiter_length = client->options.qs_delimiter.len;
606 
607 	/* Remove wt if any */
608 	zend_hash_str_del(solr_params->params, "wt", sizeof("wt")-1);
609 
610 	if (solr_http_build_query(buffer, solr_params, delimiter, delimiter_length) == FAILURE)
611 	{
612 		solr_throw_exception_ex(solr_ce_SolrException, SOLR_ERROR_1003, SOLR_FILE_LINE_FUNC, "Error building HTTP query from parameters");
613 
614 		return;
615 	}
616 
617 	/* Always reset the URLs before making any request */
618 	solr_client_init_urls(client);
619 
620 	request_url = &(client->options.search_url);
621 	/* terms.fl is a required parameter for the TermsComponent */
622 	if (zend_hash_str_exists(solr_params->params, "terms.fl", sizeof("terms.fl")-1))
623 	{
624 		/* Change the request type to a TermsComponent request */
625 		solr_request_type = SOLR_REQUEST_TERMS;
626 		request_url =&(client->options.terms_url);
627 	}
628 
629 	/* Make the HTTP request to the Solr instance */
630 	if (solr_make_request(client, solr_request_type) == FAILURE)
631 	{
632 
633 		success = 0;
634 		/* if there was an error with the http request solr_make_request throws an exception by itself
635 		 * if it wasn't a curl connection error, throw exception (omars)
636 		 */
637 		HANDLE_SOLR_SERVER_ERROR(client,"query");
638 
639 		/* SOLR_SHOW_CURL_WARNING; commented by: omars <omars@php.net> */
640 	}
641 
642 	object_init_ex(return_value, solr_ce_SolrQueryResponse);
643 
644 	solr_set_response_object_properties(solr_ce_SolrQueryResponse, return_value, client, request_url, success);
645 }
646 /* }}} */
647 
648 /* {{{ proto SolrUpdateResponse SolrClient::addDocument(SolrInputDocument doc [, bool overwrite [, int commitWithin]])
649    Adds a document to the Solr server. */
PHP_METHOD(SolrClient,addDocument)650 PHP_METHOD(SolrClient, addDocument)
651 {
652 	zval *solr_input_doc = NULL;
653 	zend_bool overwrite = 1;
654 	long int commitWithin = 0L;
655 	solr_document_t *doc_entry = NULL;
656 	solr_client_t *client = NULL;
657 	HashTable *document_fields;
658 	xmlNode *root_node = NULL;
659 	xmlDoc *doc_ptr = NULL;
660 	char *overwriteValue = NULL;
661 	int format = 1;
662 	int size   = 0;
663 	xmlChar *request_string = NULL;
664 	zend_bool success = 1;
665 
666 	/* Process the parameters passed to the default constructor */
667 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|bl", &solr_input_doc, solr_ce_SolrInputDocument, &overwrite, &commitWithin) == FAILURE) {
668 
669 		php_error_docref(NULL, E_WARNING, "Invalid parameter.");
670 
671 		return;
672 	}
673 
674 	if (solr_fetch_document_entry(OBJ_FOR_PROP(solr_input_doc), &doc_entry) == FAILURE) {
675 
676 		php_error_docref(NULL, E_WARNING, "SolrInputDocument is not valid. Object not present in HashTable");
677 
678 		return;
679 	}
680 
681 	document_fields = doc_entry->fields;
682 
683 	/* Document must contain at least one field */
684 	if (0 == zend_hash_num_elements(document_fields)) {
685 
686 		php_error_docref(NULL, E_WARNING, "SolrInputDocument has no fields");
687 
688 		return;
689 	}
690 
691 	/* Retrieve the client entry */
692 	if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
693 	{
694 		php_error_docref(NULL, E_ERROR, "Unable to retrieve client");
695 
696 		return;
697 	}
698 
699 	doc_ptr = solr_xml_create_xml_doc((xmlChar *) "add", &root_node);
700 	overwriteValue = (overwrite)? "true" : "false";
701 
702 	xmlNewProp(root_node, (xmlChar *) "overwrite", (xmlChar *) overwriteValue);
703 
704 	if (commitWithin > 0L)
705 	{
706 		auto char commitWithinBuffer[32];
707 
708 		memset(commitWithinBuffer, 0, sizeof(commitWithinBuffer));
709 
710 		php_sprintf(commitWithinBuffer, "%ld", commitWithin);
711 
712 		xmlNewProp(root_node, (xmlChar *) "commitWithin", (xmlChar *) commitWithinBuffer);
713 	}
714 
715 	solr_add_doc_node(root_node, doc_entry);
716 
717 	xmlIndentTreeOutput = 1;
718 	xmlDocDumpFormatMemoryEnc(doc_ptr, &request_string, &size, "UTF-8", format);
719 
720 	/* The XML request we are sending to Solr */
721 	solr_string_set(&(client->handle.request_body.buffer), (solr_char_t *) request_string, size);
722 
723 	xmlFree(request_string);
724 	xmlFreeDoc(doc_ptr);
725 
726 	/* Always reset the URLs before making any request */
727 	solr_client_init_urls(client);
728 
729 	/* Make the HTTP request to the Solr instance */
730 	if (solr_make_request(client, SOLR_REQUEST_UPDATE) == FAILURE)
731 	{
732 		success = 0;
733 
734 		/* if there was an error with the http request solr_make_request throws an exception by itself
735 		 * if it wasn't a curl connection error, throw exception (omars)
736 		 */
737 		HANDLE_SOLR_SERVER_ERROR(client,"update");
738 
739 		/* SOLR_SHOW_CURL_WARNING; commented by: omars <omars@php.net> */
740 	}
741 
742 	object_init_ex(return_value, solr_ce_SolrUpdateResponse);
743 
744 	solr_set_response_object_properties(solr_ce_SolrUpdateResponse, return_value, client, &(client->options.update_url), success);
745 }
746 /* }}} */
747 
748 /* {{{ proto SolrUpdateResponse SolrClient::addDocuments(array docs [, bool overwrite [, int commitWithin]])
749    Adds an array of SolrInputDocuments to the Solr server. */
PHP_METHOD(SolrClient,addDocuments)750 PHP_METHOD(SolrClient, addDocuments)
751 {
752 	zval *docs_array = NULL;
753 	zend_bool overwrite = 1;
754 	long int commitWithin = 0L;
755 	HashTable *solr_input_docs;
756 	size_t num_input_docs = 0;
757 	solr_client_t *client = NULL;
758 	solr_document_t **doc_entries = NULL;
759 	size_t curr_pos = 0U;
760 	xmlNode *root_node = NULL;
761 	xmlDoc *doc_ptr = NULL;
762 	xmlChar *overwriteValue = NULL;
763 	size_t pos = 0U;
764 	solr_document_t *current_doc_entry = NULL;
765 	int format = 1;
766 	int size = 0;
767 	zend_bool success = 1;
768 	xmlChar *request_string = NULL;
769 
770 
771 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|bl", &docs_array, &overwrite, &commitWithin) == FAILURE) {
772 
773 		php_error_docref(NULL, E_WARNING, "Invalid parameter");
774 
775 		return;
776 	}
777 
778 	solr_input_docs = Z_ARRVAL_P(docs_array);
779 	num_input_docs = zend_hash_num_elements(solr_input_docs);
780 
781 	if(!num_input_docs)
782 	{
783 		php_error_docref(NULL, E_WARNING, "The array parameter passed is empty");
784 
785 		return;
786 	}
787 
788 	/* This should be released if there is an error */
789 	doc_entries = (solr_document_t **) pemalloc((sizeof(solr_document_t *) * (num_input_docs + 1)), SOLR_DOCUMENT_PERSISTENT);
790 
791 	memset(doc_entries, 0, sizeof(solr_document_t *) * (num_input_docs + 1));
792 
793 	/* Please check all the SolrInputDocument instances passed via the array */
794 	SOLR_HASHTABLE_FOR_LOOP(solr_input_docs)
795 	{
796 		zval *solr_input_doc = NULL;
797 		solr_document_t *doc_entry = NULL;
798 		HashTable *document_fields;
799 
800 		solr_input_doc = zend_hash_get_current_data(solr_input_docs);
801 
802 		if (Z_TYPE_P(solr_input_doc) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(solr_input_doc), solr_ce_SolrInputDocument))
803 		{
804 			SOLR_FREE_DOC_ENTRIES(doc_entries);
805 
806 			solr_throw_exception_ex(solr_ce_SolrIllegalArgumentException, SOLR_ERROR_4000, SOLR_FILE_LINE_FUNC, "SolrInputDocument number %u is not a valid SolrInputDocument instance", (curr_pos + 1U));
807 
808 			return;
809 		}
810 
811 		if (solr_fetch_document_entry(OBJ_FOR_PROP(solr_input_doc), &doc_entry) == FAILURE) {
812 
813 			SOLR_FREE_DOC_ENTRIES(doc_entries);
814 
815 			solr_throw_exception_ex(solr_ce_SolrIllegalArgumentException, SOLR_ERROR_4000, SOLR_FILE_LINE_FUNC, "SolrInputDocument number %u is not valid. Object not present in HashTable", (curr_pos + 1U));
816 
817 			return;
818 		}
819 
820 		document_fields = doc_entry->fields;
821 
822 		/* SolrInputDocument must contain at least one field */
823 		if (0 == zend_hash_num_elements(document_fields)) {
824 
825 			SOLR_FREE_DOC_ENTRIES(doc_entries);
826 
827 			solr_throw_exception_ex(solr_ce_SolrIllegalArgumentException, SOLR_ERROR_4000, SOLR_FILE_LINE_FUNC, "SolrInputDocument number %u has no fields", (curr_pos + 1U));
828 
829 			return;
830 		}
831 
832 		doc_entries[curr_pos] = doc_entry;
833 
834 		curr_pos++;
835 	}
836 
837 	/* Mark the end of the list */
838 	doc_entries[curr_pos] = NULL;
839 
840 	/* All the input documents have been validated. We can now retrieve the client entry */
841 	if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
842 	{
843 		SOLR_FREE_DOC_ENTRIES(doc_entries);
844 
845 		php_error_docref(NULL, E_ERROR, "Unable to retrieve client from HashTable");
846 
847 		return;
848 	}
849 
850 	doc_ptr = solr_xml_create_xml_doc((xmlChar *) "add", &root_node);
851 	overwriteValue = (overwrite) ? (xmlChar *) "true" : (xmlChar *) "false";
852 
853 	xmlNewProp(root_node, (xmlChar *) "overwrite", overwriteValue);
854 
855 	if (commitWithin > 0L)
856 	{
857 		auto char commitWithinBuffer[32];
858 
859 		memset(commitWithinBuffer, 0, sizeof(commitWithinBuffer));
860 
861 		php_sprintf(commitWithinBuffer, "%ld", commitWithin);
862 
863 		xmlNewProp(root_node, (xmlChar *) "commitWithin", (xmlChar *) commitWithinBuffer);
864 	}
865 
866 	/* Grab the first (solr_document_t *) pointer */
867 	current_doc_entry = doc_entries[pos];
868 
869 	while(current_doc_entry != NULL)
870 	{
871 		solr_add_doc_node(root_node, current_doc_entry);
872 
873 		pos++;
874 
875 		/* Grab the next (solr_document_t *) pointer */
876 		current_doc_entry = doc_entries[pos];
877 	}
878 
879 	/* We are done with the doc_entries pointer */
880 	SOLR_FREE_DOC_ENTRIES(doc_entries);
881 
882 	xmlIndentTreeOutput = 1;
883 
884 	xmlDocDumpFormatMemoryEnc(doc_ptr, &request_string, &size, "UTF-8", format);
885 
886 	/* The XML request we are sending to Solr */
887 	solr_string_set(&(client->handle.request_body.buffer), (solr_char_t *) request_string, size);
888 
889 	xmlFree(request_string);
890 	xmlFreeDoc(doc_ptr);
891 
892 	/* Always reset the URLs before making any request */
893 	solr_client_init_urls(client);
894 
895 	/* Make the HTTP request to the Solr instance */
896 	if (solr_make_request(client, SOLR_REQUEST_UPDATE) == FAILURE)
897 	{
898 		success = 0;
899 
900 		/* if there was an error with the http request solr_make_request throws an exception by itself
901 		 * if it wasn't a curl connection error, throw exception (omars)
902 		 */
903 		HANDLE_SOLR_SERVER_ERROR(client,"update");
904 
905 		/* SOLR_SHOW_CURL_WARNING; commented by: omars <omars@php.net> */
906 	}
907 
908 	object_init_ex(return_value, solr_ce_SolrUpdateResponse);
909 
910 	solr_set_response_object_properties(solr_ce_SolrUpdateResponse, return_value, client, &(client->options.update_url), success);
911 }
912 /* }}} */
913 
914 /* {{{ proto SolrUpdateResponse SolrClient::request(string request_string)
915    Allows the user to send a manual XML update request */
PHP_METHOD(SolrClient,request)916 PHP_METHOD(SolrClient, request)
917 {
918 	solr_char_t *request_string = NULL;
919 	COMPAT_ARG_SIZE_T request_length = 0;
920 	solr_client_t *client = NULL;
921 	zend_bool success = 1;
922 
923 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &request_string, &request_length) == FAILURE) {
924 
925 		php_error_docref(NULL, E_WARNING, "Invalid parameter");
926 
927 		return;
928 	}
929 
930 	if (!request_length)
931 	{
932 		solr_throw_exception(solr_ce_SolrIllegalArgumentException, "Invalid request length. Request string is empty.", SOLR_ERROR_4000, SOLR_FILE_LINE_FUNC);
933 
934 		return;
935 	}
936 
937 	if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
938 	{
939 		php_error_docref(NULL, E_ERROR, "Unable to retrieve client from HashTable");
940 
941 		return;
942 	}
943 
944 	/* The update request we are sending to Solr */
945 	solr_string_set(&(client->handle.request_body.buffer), request_string, request_length);
946 
947 	/* Always reset the URLs before making any request */
948 	solr_client_init_urls(client);
949 
950 	/* Make the HTTP request to the Solr instance */
951 	if (solr_make_request(client, SOLR_REQUEST_UPDATE) == FAILURE)
952 	{
953 		success = 0;
954 
955 		/* if there was an error with the http request solr_make_request throws an exception by itself
956 		 * if it wasn't a curl connection error, throw exception (omars)
957 		 */
958 		HANDLE_SOLR_SERVER_ERROR(client,"update");
959 
960 		/* SOLR_SHOW_CURL_WARNING; commented by: omars <omars@php.net> */
961 	}
962 
963 	object_init_ex(return_value, solr_ce_SolrUpdateResponse);
964 
965 	solr_set_response_object_properties(solr_ce_SolrUpdateResponse, return_value, client, &(client->options.update_url), success);
966 
967 }
968 /* }}} */
969 
970 /* {{{ proto SolrUpdateResponse SolrClient::sendUpdateStream(SolrExtractRequest request)
971    sends an update stream request. */
PHP_METHOD(SolrClient,sendUpdateStream)972 PHP_METHOD(SolrClient, sendUpdateStream)
973 {
974     zval *request_zv = NULL, *params_zv = NULL;
975     solr_ustream_t *stream = NULL;
976     solr_client_t *client = NULL;
977     solr_string_t *qs_buffer;                   /* query string buffer */
978     solr_char_t *delimiter = NULL;
979     size_t delimiter_length = 0L;
980     solr_params_t *params = NULL;
981     zend_bool success = 1;
982 
983     if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &request_zv) == FAILURE) {
984         return;
985     }
986 
987     if (solr_fetch_client_entry(getThis(), &client) == FAILURE) {
988         return;
989     }
990 
991     stream = Z_USTREAM_P(Z_REFVAL_P(request_zv));
992 
993     params_zv = stream->params;
994 
995     if (params_zv && IS_NULL != Z_TYPE_P(params_zv)) {
996         solr_fetch_params_entry(params_zv, &params);
997     }
998 
999     /* Always reset the URLs before making any request */
1000     solr_client_init_urls(client);
1001 
1002     qs_buffer = &(client->handle.request_body.buffer);
1003 
1004     /* Get rid of all the data from the previous request */
1005     solr_string_free(qs_buffer);
1006 
1007     delimiter = client->options.qs_delimiter.str;
1008 
1009     delimiter_length = client->options.qs_delimiter.len;
1010 
1011     if (solr_http_build_query(qs_buffer, params, delimiter, delimiter_length) == FAILURE){
1012         solr_throw_exception_ex(solr_ce_SolrException, SOLR_ERROR_1003, SOLR_FILE_LINE_FUNC, SOLR_ERROR_1003_MSG);
1013         return;
1014     }
1015 
1016     if (solr_make_update_stream_request(client, stream, qs_buffer) == FAILURE) {
1017         success = 0;
1018         /* if there was an error with the http request solr_make_request throws an exception by itself
1019          * if it wasn't a curl connection error, throw exception (omars)
1020          */
1021         HANDLE_SOLR_SERVER_ERROR(client,"extract");
1022     }
1023     object_init_ex(return_value, solr_ce_SolrUpdateResponse);
1024     solr_set_response_object_properties(solr_ce_SolrUpdateResponse, return_value, client, &(client->options.extract_url), success);
1025 }
1026 /* }}} */
1027 
1028 /* {{{ proto SolrUpdateResponse SolrClient::deleteById(string id)
1029    Allows the user to delete a document by id */
PHP_METHOD(SolrClient,deleteById)1030 PHP_METHOD(SolrClient, deleteById)
1031 {
1032 	solr_char_t *id = NULL;
1033 	COMPAT_ARG_SIZE_T id_length = 0L;
1034 	solr_client_t *client = NULL;
1035 	xmlNode *root_node = NULL;
1036 	xmlDoc *doc_ptr = NULL;
1037 	xmlChar *escaped_id_value = NULL;
1038 	int format = 1;
1039 	int size = 0;
1040 	xmlChar *request_string = NULL;
1041 	zend_bool success = 1;
1042 
1043 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &id, &id_length) == FAILURE) {
1044 
1045 		php_error_docref(NULL, E_WARNING, "Invalid parameter");
1046 
1047 		return;
1048 	}
1049 
1050 	if (!id_length)
1051 	{
1052 		solr_throw_exception(solr_ce_SolrIllegalArgumentException, "Invalid id parameter", SOLR_ERROR_4000, SOLR_FILE_LINE_FUNC);
1053 
1054 		return;
1055 	}
1056 
1057 	if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
1058 	{
1059 		php_error_docref(NULL, E_ERROR, "Unable to retrieve client from HashTable");
1060 
1061 		return;
1062 	}
1063 
1064 	doc_ptr = solr_xml_create_xml_doc((xmlChar *) "delete", &root_node);
1065 	escaped_id_value = xmlEncodeEntitiesReentrant(doc_ptr, (xmlChar *) id);
1066 
1067 	xmlNewChild(root_node, NULL, (xmlChar *) "id", escaped_id_value);
1068 	xmlFree(escaped_id_value);
1069 
1070 	xmlIndentTreeOutput = 1;
1071 
1072 	xmlDocDumpFormatMemoryEnc(doc_ptr, &request_string, &size, "UTF-8", format);
1073 
1074 	/* The XML request we are sending to Solr */
1075 	solr_string_set(&(client->handle.request_body.buffer), (solr_char_t *) request_string, size);
1076 
1077 	xmlFree(request_string);
1078 	xmlFreeDoc(doc_ptr);
1079 
1080 	/* Always reset the URLs before making any request */
1081 	solr_client_init_urls(client);
1082 
1083 	/* Make the HTTP request to the Solr instance */
1084 	if (solr_make_request(client, SOLR_REQUEST_UPDATE) == FAILURE)
1085 	{
1086 		success = 0;
1087 
1088 		/* if there was an error with the http request solr_make_request throws an exception by itself
1089 		 * if it wasn't a curl connection error, throw exception (omars)
1090 		 */
1091 		HANDLE_SOLR_SERVER_ERROR(client,"update");
1092 
1093 		/* SOLR_SHOW_CURL_WARNING; commented by: omars <omars@php.net> */
1094 	}
1095 
1096 	object_init_ex(return_value, solr_ce_SolrUpdateResponse);
1097 	solr_set_response_object_properties(solr_ce_SolrUpdateResponse, return_value, client, &(client->options.update_url), success);
1098 }
1099 /* }}} */
1100 
1101 /* {{{ proto SolrUpdateResponse SolrClient::request(array ids)
1102    Allows the user to delete a set of documents by ids. This should be an array of strings */
PHP_METHOD(SolrClient,deleteByIds)1103 PHP_METHOD(SolrClient, deleteByIds)
1104 {
1105 	zval *ids_array = NULL;
1106 	HashTable *doc_ids = NULL;
1107 	size_t num_ids = 0;
1108 	xmlNode *root_node = NULL;
1109 	xmlDoc *doc_ptr = NULL;
1110 	zend_bool invalid_param = 0;
1111 	size_t error_pos = 1, current_position = 1;
1112 	solr_client_t *client = NULL;
1113 	int format = 1;
1114 	int size = 0;
1115 	xmlChar *request_string = NULL;
1116 	zend_bool success = 1;
1117 	HashPosition loop_pos;
1118 
1119 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &ids_array) == FAILURE) {
1120 		php_error_docref(NULL, E_WARNING, "Invalid parameter");
1121 		return;
1122 	}
1123 
1124 	doc_ids = Z_ARRVAL_P(ids_array);
1125 	num_ids = zend_hash_num_elements(doc_ids);
1126 
1127 	if(!num_ids)
1128 	{
1129 		solr_throw_exception(solr_ce_SolrIllegalArgumentException, "The array parameter passed is empty", SOLR_ERROR_4000, SOLR_FILE_LINE_FUNC);
1130 		return;
1131 	}
1132 
1133 	doc_ptr = solr_xml_create_xml_doc((xmlChar *) "delete", &root_node);
1134 	if (doc_ids->nNumOfElements) {
1135 	    SOLR_HASHTABLE_FOR_LOOP_EX(doc_ids, loop_pos)
1136 	    {
1137 	        zval *id_zval = NULL;
1138 
1139 	        id_zval = zend_hash_get_current_data_ex(doc_ids, &loop_pos);
1140 
1141 	        if (Z_TYPE_P(id_zval) == IS_STRING && Z_STRLEN_P(id_zval) > 0)
1142 	        {
1143 	            xmlChar *escaped_id_value = xmlEncodeEntitiesReentrant(doc_ptr, (xmlChar *) Z_STRVAL_P(id_zval));
1144 	            xmlNewChild(root_node, NULL, (xmlChar *) "id", escaped_id_value);
1145 	            xmlFree(escaped_id_value);
1146 	        } else {
1147 	            invalid_param = 1; /* This id is not a valid string */
1148 	            error_pos = current_position;
1149 	             goto end_doc_ids_loop;
1150 	        }
1151 
1152 	        current_position++;
1153 	    }
1154 	}
1155 
1156 
1157 end_doc_ids_loop :
1158 
1159 	if (invalid_param)
1160 	{
1161 		xmlFreeDoc(doc_ptr);
1162 		solr_throw_exception_ex(solr_ce_SolrIllegalArgumentException, SOLR_ERROR_4000, SOLR_FILE_LINE_FUNC, "Id number %u is not a valid string", error_pos);
1163 		return;
1164 	}
1165 
1166 	if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
1167 	{
1168 		php_error_docref(NULL, E_ERROR, "Unable to retrieve client from HashTable");
1169 		return;
1170 	}
1171 
1172 	xmlIndentTreeOutput = 1;
1173 
1174 	xmlDocDumpFormatMemoryEnc(doc_ptr, &request_string, &size, "UTF-8", format);
1175 
1176 	/* The XML request we are sending to Solr */
1177 	solr_string_set(&(client->handle.request_body.buffer), (solr_char_t *) request_string, size);
1178 
1179 	xmlFree(request_string);
1180 	xmlFreeDoc(doc_ptr);
1181 
1182 	/* Always reset the URLs before making any request */
1183 	solr_client_init_urls(client);
1184 
1185 	/* Make the HTTP request to the Solr instance */
1186 	if (solr_make_request(client, SOLR_REQUEST_UPDATE) == FAILURE)
1187 	{
1188 		success = 0;
1189 
1190 		/* if there was an error with the http request solr_make_request throws an exception by itself
1191 		 * if it wasn't a curl connection error, throw exception (omars)
1192 		 */
1193 		HANDLE_SOLR_SERVER_ERROR(client,"update");
1194 	}
1195 
1196 	object_init_ex(return_value, solr_ce_SolrUpdateResponse);
1197 	solr_set_response_object_properties(solr_ce_SolrUpdateResponse, return_value, client, &(client->options.update_url), success);
1198 }
1199 /* }}} */
1200 
1201 /* {{{ proto SolrUpdateResponse SolrClient::deleteByQuery(string query)
1202    Allows the user to delete a set of documents matching the query */
PHP_METHOD(SolrClient,deleteByQuery)1203 PHP_METHOD(SolrClient, deleteByQuery)
1204 {
1205 	solr_char_t *query = NULL;
1206 	COMPAT_ARG_SIZE_T query_length = 0L;
1207 	solr_client_t *client = NULL;
1208 	xmlNode *root_node = NULL;
1209 	xmlDoc *doc_ptr = NULL;
1210 	xmlChar *escaped_query_value = NULL;
1211 	int format = 1;
1212 	int size = 0;
1213 	xmlChar *request_string = NULL;
1214 	zend_bool success = 1;
1215 
1216 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &query, &query_length) == FAILURE) {
1217 
1218 		php_error_docref(NULL, E_WARNING, "Invalid parameter");
1219 
1220 		return;
1221 	}
1222 
1223 	if (!query_length)
1224 	{
1225 		solr_throw_exception_ex(solr_ce_SolrIllegalArgumentException, SOLR_ERROR_4000, SOLR_FILE_LINE_FUNC, "The query parameter is not a valid id");
1226 
1227 		return;
1228 	}
1229 
1230 	if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
1231 	{
1232 		php_error_docref(NULL, E_ERROR, "Unable to retrieve client from HashTable");
1233 
1234 		return;
1235 	}
1236 
1237 	doc_ptr = solr_xml_create_xml_doc((xmlChar *) "delete", &root_node);
1238 	escaped_query_value = xmlEncodeEntitiesReentrant(doc_ptr, (xmlChar *) query);
1239 
1240 	xmlNewChild(root_node, NULL, (xmlChar *) "query", escaped_query_value);
1241 	xmlFree(escaped_query_value);
1242 
1243 	xmlIndentTreeOutput = 1;
1244 
1245 	xmlDocDumpFormatMemoryEnc(doc_ptr, &request_string, &size, "UTF-8", format);
1246 
1247 	/* The XML request we are sending to Solr */
1248 	solr_string_set(&(client->handle.request_body.buffer), (solr_char_t *) request_string, size);
1249 
1250 	xmlFree(request_string);
1251 	xmlFreeDoc(doc_ptr);
1252 
1253 	/* Always reset the URLs before making any request */
1254 	solr_client_init_urls(client);
1255 
1256 	/* Make the HTTP request to the Solr instance */
1257 	if (solr_make_request(client, SOLR_REQUEST_UPDATE) == FAILURE)
1258 	{
1259 		success = 0;
1260 
1261 		/* if there was an error with the http request solr_make_request throws an exception by itself
1262 		 * if it wasn't a curl connection error, throw exception (omars)
1263 		 */
1264 		HANDLE_SOLR_SERVER_ERROR(client,"update");
1265 
1266 		/* SOLR_SHOW_CURL_WARNING; commented by: omars <omars@php.net> */
1267 	}
1268 
1269 	object_init_ex(return_value, solr_ce_SolrUpdateResponse);
1270 	solr_set_response_object_properties(solr_ce_SolrUpdateResponse, return_value, client, &(client->options.update_url), success);
1271 }
1272 /* }}} */
1273 
1274 /* {{{ proto SolrQueryResponse SolrClient::getById(string id)
1275    Get Document By Id. Utilizes Solr Realtime Get (RTG) */
PHP_METHOD(SolrClient,getById)1276 PHP_METHOD(SolrClient, getById)
1277 {
1278     solr_client_t *client;
1279     solr_char_t *id;
1280     COMPAT_ARG_SIZE_T id_len = 0;
1281     solr_string_t query_string;
1282     int success = 1;
1283 
1284     if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &id, &id_len) == FAILURE)
1285     {
1286         php_error_docref(NULL, E_WARNING, "Invalid parameter");
1287         return;
1288     }
1289 
1290     if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
1291     {
1292         php_error_docref(NULL, E_WARNING, "Invalid parameter");
1293         return;
1294     }
1295     /* Always reset the URLs before making any request */
1296     solr_client_init_urls(client);
1297 
1298     solr_string_init(&query_string);
1299     solr_string_appends(&query_string, "id=", sizeof("id=")-1);
1300     solr_string_appends(&query_string, id, id_len);
1301 
1302     solr_string_set_ex(&(client->handle.request_body.buffer), query_string.str, query_string.len);
1303     if (solr_make_request(client, SOLR_REQUEST_GET) == FAILURE)
1304     {
1305         /* if there was an error with the http request solr_make_request throws an exception by itself
1306          * if it wasn't a curl connection error, throw exception (omars)
1307          */
1308         HANDLE_SOLR_SERVER_ERROR(client,"get");
1309         success = 0;
1310     }
1311 
1312     object_init_ex(return_value, solr_ce_SolrQueryResponse);
1313     solr_set_response_object_properties(solr_ce_SolrQueryResponse, return_value, client, &(client->options.get_url), success);
1314     solr_string_free(&query_string);
1315 }
1316 /* }}} */
1317 
1318 /* {{{ proto SolrQueryResponse SolrClient::getByIds(array ids)
1319    Get Documents by their Ids. Utilizes Solr Realtime Get (RTG) */
PHP_METHOD(SolrClient,getByIds)1320 PHP_METHOD(SolrClient, getByIds)
1321 {
1322     solr_client_t *client;
1323     HashTable *ids = NULL;
1324     zval *ids_z = NULL;
1325     zend_bool invalid_param = 0;
1326     solr_string_t query_string;
1327     size_t current_position = 0;
1328     int success = 1;
1329     HashPosition loop_pos;
1330 
1331     if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &ids_z) == FAILURE)
1332     {
1333         php_error_docref(NULL, E_WARNING, "Invalid parameter");
1334         return;
1335     }
1336 
1337     if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
1338     {
1339         php_error_docref(NULL, E_WARNING, "Internal Error: Cannot fetch client object");
1340         return;
1341     }
1342     ids = Z_ARRVAL_P(ids_z);
1343     if (ids->nNumOfElements < 1)
1344     {
1345         solr_throw_exception_ex(solr_ce_SolrIllegalArgumentException, 4000, SOLR_FILE_LINE_FUNC, "Invalid parameter: at least 1 ID is required. Passed an empty array.", current_position);
1346     }
1347     /* Always reset the URLs before making any request */
1348     solr_client_init_urls(client);
1349 
1350     solr_string_init(&query_string);
1351     solr_string_appends(&query_string, "ids=", sizeof("ids=")-1);
1352 
1353     if (ids->nNumOfElements) {
1354         SOLR_HASHTABLE_FOR_LOOP_EX(ids, loop_pos)
1355         {
1356             zval *id_zv = NULL;
1357             id_zv = zend_hash_get_current_data_ex(ids, &loop_pos);
1358             if (Z_TYPE_P(id_zv) == IS_STRING && Z_STRLEN_P(id_zv) > 0) {
1359                 solr_string_appends(&query_string, Z_STRVAL_P(id_zv), Z_STRLEN_P(id_zv));
1360                 solr_string_appendc(&query_string, ',');
1361             } else {
1362                 invalid_param = 1;
1363                 goto solr_getbyids_exit;
1364             }
1365             current_position++;
1366         }
1367     }
1368 
1369 
1370 solr_getbyids_exit:
1371     if (invalid_param) {
1372         solr_string_free(&query_string);
1373         solr_throw_exception_ex(solr_ce_SolrIllegalArgumentException, 4000, SOLR_FILE_LINE_FUNC, "Invalid id at position %ld", current_position);
1374         return;
1375     }
1376     solr_string_remove_last_char(&query_string);
1377 
1378     solr_string_set_ex(&(client->handle.request_body.buffer), query_string.str, query_string.len);
1379     if (solr_make_request(client, SOLR_REQUEST_GET) == FAILURE)
1380     {
1381         /* if there was an error with the http request solr_make_request throws an exception by itself
1382          * if it wasn't a curl connection error, throw exception (omars)
1383          */
1384 
1385         HANDLE_SOLR_SERVER_ERROR(client,"get");
1386         success = 0;
1387     }
1388 
1389     object_init_ex(return_value, solr_ce_SolrQueryResponse);
1390     solr_set_response_object_properties(solr_ce_SolrQueryResponse, return_value, client, &(client->options.get_url), success);
1391 
1392     solr_string_set_ex(&(client->handle.request_body.buffer),(solr_char_t *)0x00, 0);
1393     solr_string_free(&query_string);
1394 }
1395 /* }}} */
1396 
1397 /* {{{ proto void SolrClient::setResponseWriter(string responseWriter)
1398    Allows the user to specify which response writer to use */
PHP_METHOD(SolrClient,setResponseWriter)1399 PHP_METHOD(SolrClient, setResponseWriter)
1400 {
1401 	solr_char_t *wt = NULL;
1402 	COMPAT_ARG_SIZE_T wt_length = 0L;
1403 	solr_client_t *client = NULL;
1404 
1405 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &wt, &wt_length) == FAILURE) {
1406 
1407 		php_error_docref(NULL, E_WARNING, "Invalid parameter");
1408 
1409 		return;
1410 	}
1411 
1412 	if (!wt_length)
1413 	{
1414 		solr_throw_exception_ex(solr_ce_SolrIllegalArgumentException, SOLR_ERROR_4000, SOLR_FILE_LINE_FUNC, "The response writer is not a valid string");
1415 
1416 		return;
1417 	}
1418 
1419 	if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
1420 	{
1421 		php_error_docref(NULL, E_ERROR, "Unable to retrieve client from HashTable");
1422 
1423 		return;
1424 	}
1425 
1426 	if (solr_is_supported_response_writer((const solr_char_t *) wt, wt_length)) {
1427 
1428 		/* The response writer used to present the response from Solr */
1429 		solr_string_set(&(client->options.response_writer), (solr_char_t *) wt, wt_length);
1430 
1431 	} else {
1432 
1433 		php_error_docref(NULL, E_WARNING, "Unsupported response writer %s. This value will be ignored", wt);
1434 	}
1435 }
1436 /* }}} */
1437 
1438 
1439 /* {{{ proto SolrUpdateResponse SolrClient::deleteByQueries(array queries)
1440    Allows the user to delete a set of documents matching the queries specified */
PHP_METHOD(SolrClient,deleteByQueries)1441 PHP_METHOD(SolrClient, deleteByQueries)
1442 {
1443 	zval *queries_array = NULL;
1444 	HashTable *doc_queries = NULL;
1445 	size_t num_queries = 0;
1446 	xmlNode *root_node = NULL;
1447 	xmlDoc *doc_ptr = NULL;
1448 	zend_bool invalid_param = 0;
1449 	size_t error_pos, current_position = 1;
1450 	solr_client_t *client = NULL;
1451 	int format = 1;
1452 	int size = 0;
1453 	xmlChar *request_string = NULL;
1454 	zend_bool success = 1;
1455 	HashPosition loop_pos;
1456 
1457 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &queries_array) == FAILURE) {
1458 
1459 		php_error_docref(NULL, E_WARNING, "Invalid parameter");
1460 
1461 		return;
1462 	}
1463 
1464 	doc_queries = Z_ARRVAL_P(queries_array);
1465 	num_queries = zend_hash_num_elements(doc_queries);
1466 
1467 	if(!num_queries)
1468 	{
1469 		php_error_docref(NULL, E_WARNING, "The array parameter passed is empty");
1470 
1471 		return;
1472 	}
1473 
1474 	doc_ptr = solr_xml_create_xml_doc((xmlChar *) "delete", &root_node);
1475 
1476 	SOLR_HASHTABLE_FOR_LOOP_EX(doc_queries, loop_pos)
1477 	{
1478 		zval *query_zval = NULL;
1479 
1480 		query_zval = zend_hash_get_current_data_ex(doc_queries, &loop_pos);
1481 
1482 		if (Z_TYPE_P(query_zval) == IS_STRING && Z_STRLEN_P(query_zval))
1483 		{
1484 			xmlChar *escaped_query_value = xmlEncodeEntitiesReentrant(doc_ptr, (xmlChar *) Z_STRVAL_P(query_zval));
1485 
1486 			xmlNewChild(root_node, NULL, (xmlChar *) "query", escaped_query_value);
1487 
1488 			xmlFree(escaped_query_value);
1489 
1490 		} else {
1491 
1492 			invalid_param = 1; /* This query is not a valid string */
1493 
1494 			error_pos = current_position;
1495 
1496 			goto end_doc_queries_loop;
1497 		}
1498 
1499 		current_position++;
1500 	}
1501 
1502 end_doc_queries_loop :
1503 
1504 	if (invalid_param)
1505 	{
1506 		xmlFreeDoc(doc_ptr);
1507 
1508 		solr_throw_exception_ex(solr_ce_SolrIllegalArgumentException, SOLR_ERROR_4000, SOLR_FILE_LINE_FUNC, "Query number %u is not a valid query string", error_pos);
1509 
1510 		return;
1511 	}
1512 
1513 	if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
1514 	{
1515 		php_error_docref(NULL, E_ERROR, "Unable to retrieve client from HashTable");
1516 
1517 		return;
1518 	}
1519 
1520 	xmlIndentTreeOutput = 1;
1521 
1522 	xmlDocDumpFormatMemoryEnc(doc_ptr, &request_string, &size, "UTF-8", format);
1523 
1524 	/* The XML request we are sending to Solr */
1525 	solr_string_set(&(client->handle.request_body.buffer), (solr_char_t *) request_string, size);
1526 
1527 	xmlFree(request_string);
1528 	xmlFreeDoc(doc_ptr);
1529 
1530 	/* Always reset the URLs before making any request */
1531 	solr_client_init_urls(client);
1532 
1533 	/* Make the HTTP request to the Solr instance */
1534 	if (solr_make_request(client, SOLR_REQUEST_UPDATE) == FAILURE)
1535 	{
1536 		success = 0;
1537 
1538 		/* if there was an error with the http request solr_make_request throws an exception by itself
1539 		 * if it wasn't a curl connection error, throw exception (omars)
1540 		 */
1541 		HANDLE_SOLR_SERVER_ERROR(client,"update");
1542 
1543 		/* SOLR_SHOW_CURL_WARNING; commented by: omars <omars@php.net> */
1544 	}
1545 
1546 	object_init_ex(return_value, solr_ce_SolrUpdateResponse);
1547 	solr_set_response_object_properties(solr_ce_SolrUpdateResponse, return_value, client, &(client->options.update_url), success);
1548 }
1549 /* }}} */
1550 
1551 /* {{{ proto SolrUpdateResponse SolrClient::optimize([string maxSegments [, bool softCommit [, bool waitSearcher]])
1552    Sends an optimize XML request to the server. */
PHP_METHOD(SolrClient,optimize)1553 PHP_METHOD(SolrClient, optimize)
1554 {
1555 	zend_bool softCommit = 0, waitSearcher = 1;
1556 	char *maxSegments = "1";
1557 	int maxSegmentsLen = sizeof("1")-1;
1558 	char *softCommitValue, *waitSearcherValue;
1559 	xmlNode *root_node = NULL;
1560 	xmlDoc *doc_ptr = NULL;
1561 	solr_client_t *client = NULL;
1562 	int format = 1;
1563 	int size = 0;
1564 	xmlChar *request_string = NULL;
1565 	zend_bool success = 1;
1566 
1567 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "|sbb", &maxSegments, &maxSegmentsLen, &softCommit, &waitSearcher) == FAILURE) {
1568 
1569 		php_error_docref(NULL, E_WARNING, "Invalid parameter");
1570 
1571 		return;
1572 	}
1573 
1574 	softCommitValue = (softCommit)? "true" : "false";
1575 	waitSearcherValue = (waitSearcher)? "true" : "false";
1576 
1577 	doc_ptr = solr_xml_create_xml_doc((xmlChar *) "optimize", &root_node);
1578 
1579 	xmlNewProp(root_node, (xmlChar *) "maxSegments", (xmlChar *) maxSegments);
1580 	xmlNewProp(root_node, (xmlChar *) "softCommit", (xmlChar *) softCommitValue);
1581 	xmlNewProp(root_node, (xmlChar *) "waitSearcher", (xmlChar *) waitSearcherValue);
1582 
1583 	if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
1584 	{
1585 		php_error_docref(NULL, E_ERROR, "Unable to retrieve client from HashTable");
1586 
1587 		return;
1588 	}
1589 
1590 	xmlIndentTreeOutput = 1;
1591 
1592 	xmlDocDumpFormatMemoryEnc(doc_ptr, &request_string, &size, "UTF-8", format);
1593 
1594 	/* The XML request we are sending to Solr */
1595 	solr_string_set(&(client->handle.request_body.buffer), (solr_char_t *) request_string, size);
1596 
1597 	xmlFree(request_string);
1598 	xmlFreeDoc(doc_ptr);
1599 
1600 	/* Always reset the URLs before making any request */
1601 	solr_client_init_urls(client);
1602 
1603 	/* Make the HTTP request to the Solr instance */
1604 	if (solr_make_request(client, SOLR_REQUEST_UPDATE) == FAILURE)
1605 	{
1606 		success = 0;
1607 
1608 		/* if there was an error with the http request solr_make_request throws an exception by itself
1609 		 * if it wasn't a curl connection error, throw exception (omars)
1610 		 */
1611 		HANDLE_SOLR_SERVER_ERROR(client,"update");
1612 
1613 		/* SOLR_SHOW_CURL_WARNING; commented by: omars <omars@php.net> */
1614 	}
1615 
1616 	object_init_ex(return_value, solr_ce_SolrUpdateResponse);
1617 	solr_set_response_object_properties(solr_ce_SolrUpdateResponse, return_value, client, &(client->options.update_url), success);
1618 }
1619 /* }}} */
1620 
1621 /* {{{ proto SolrUpdateResponse SolrClient::commit( [bool softCommit [, bool waitSearcher [, bool expungeDeletes]]])
1622    Sends a commit XML request to the server. */
PHP_METHOD(SolrClient,commit)1623 PHP_METHOD(SolrClient, commit)
1624 {
1625 	zend_bool softCommit = 0, waitSearcher = 1, expungeDeletes = 0;
1626 	char *softCommitValue, *waitSearcherValue, *expungeDeletesValue;
1627 	xmlNode *root_node = NULL;
1628 	xmlDoc *doc_ptr = NULL;
1629 	solr_client_t *client = NULL;
1630 	int format = 1;
1631 	int size = 0;
1632 	xmlChar *request_string = NULL;
1633 	zend_bool success = 1;
1634 
1635 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "|bbb", &softCommit, &waitSearcher, &expungeDeletes) == FAILURE) {
1636 
1637 		php_error_docref(NULL, E_WARNING, "Invalid parameter");
1638 
1639 		return;
1640 	}
1641 
1642 	softCommitValue = (softCommit)? "true" : "false";
1643 	waitSearcherValue = (waitSearcher)? "true" : "false";
1644 	expungeDeletesValue = (expungeDeletes)? "true": "false";
1645 
1646 	doc_ptr = solr_xml_create_xml_doc((xmlChar *) "commit", &root_node);
1647 
1648 	xmlNewProp(root_node, (xmlChar *) "softCommit", (xmlChar *) softCommitValue);
1649 	xmlNewProp(root_node, (xmlChar *) "waitSearcher", (xmlChar *) waitSearcherValue);
1650 	xmlNewProp(root_node, (xmlChar *) "expungeDeletes", (xmlChar *) expungeDeletesValue);
1651 
1652 	if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
1653 	{
1654 		php_error_docref(NULL, E_ERROR, "Unable to retrieve client from HashTable");
1655 
1656 		return;
1657 	}
1658 
1659 	xmlIndentTreeOutput = 1;
1660 
1661 	xmlDocDumpFormatMemoryEnc(doc_ptr, &request_string, &size, "UTF-8", format);
1662 
1663 	/* The XML request we are sending to Solr */
1664 	solr_string_set(&(client->handle.request_body.buffer), (solr_char_t *) request_string, size);
1665 
1666 	xmlFree(request_string);
1667 	xmlFreeDoc(doc_ptr);
1668 
1669 	/* Always reset the URLs before making any request */
1670 	solr_client_init_urls(client);
1671 
1672 	/* Make the HTTP request to the Solr instance */
1673 	if (solr_make_request(client, SOLR_REQUEST_UPDATE) == FAILURE)
1674 	{
1675 		success = 0;
1676 
1677 		/* if there was an error with the http request solr_make_request throws an exception by itself
1678 		 * if it wasn't a curl connection error, throw exception (omars)
1679 		 */
1680 		HANDLE_SOLR_SERVER_ERROR(client,"update");
1681 
1682 		/* SOLR_SHOW_CURL_WARNING; commented by: omars <omars@php.net> */
1683 	}
1684 
1685 	object_init_ex(return_value, solr_ce_SolrUpdateResponse);
1686 	solr_set_response_object_properties(solr_ce_SolrUpdateResponse, return_value, client, &(client->options.update_url), success);
1687 }
1688 /* }}} */
1689 
1690 /* {{{ proto SolrUpdateResponse SolrClient::rollback(void)
1691    Sends a rollback XML request to the server. */
PHP_METHOD(SolrClient,rollback)1692 PHP_METHOD(SolrClient, rollback)
1693 {
1694 	xmlNode *root_node = NULL;
1695 	zend_bool success = 1;
1696 	xmlDoc *doc_ptr = NULL;
1697 	solr_client_t *client = NULL;
1698 	int format = 1;
1699 	int size = 0;
1700 	xmlChar *request_string = NULL;
1701 
1702 	doc_ptr = solr_xml_create_xml_doc((xmlChar *) "rollback", &root_node);
1703 
1704 	if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
1705 	{
1706 		php_error_docref(NULL, E_ERROR, "Unable to retrieve client from HashTable");
1707 
1708 		return;
1709 	}
1710 
1711 	xmlIndentTreeOutput = 1;
1712 
1713 	xmlDocDumpFormatMemoryEnc(doc_ptr, &request_string, &size, "UTF-8", format);
1714 
1715 	/* The XML request we are sending to Solr */
1716 	solr_string_set(&(client->handle.request_body.buffer), (solr_char_t *) request_string, size);
1717 
1718 	xmlFree(request_string);
1719 	xmlFreeDoc(doc_ptr);
1720 
1721 	/* Always reset the URLs before making any request */
1722 	solr_client_init_urls(client);
1723 
1724 	/* Make the HTTP request to the Solr instance */
1725 	if (solr_make_request(client, SOLR_REQUEST_UPDATE) == FAILURE)
1726 	{
1727 		success = 0;
1728 
1729 		/* if there was an error with the http request solr_make_request throws an exception by itself
1730 		 * if it wasn't a curl connection error, throw exception (omars)
1731 		 */
1732 		HANDLE_SOLR_SERVER_ERROR(client,"update");
1733 
1734 		/* SOLR_SHOW_CURL_WARNING; commented by: omars <omars@php.net> */
1735 	}
1736 
1737 	object_init_ex(return_value, solr_ce_SolrUpdateResponse);
1738 	solr_set_response_object_properties(solr_ce_SolrUpdateResponse, return_value, client, &(client->options.update_url), success);
1739 }
1740 /* }}} */
1741 
1742 /* {{{ proto SolrPingResponse SolrClient::ping()
1743    Sends a HEAD request to check if the server is still up and running. */
PHP_METHOD(SolrClient,ping)1744 PHP_METHOD(SolrClient, ping)
1745 {
1746 	solr_client_t *client = NULL;
1747 	zend_bool success = 1;
1748 
1749 	/* Retrieve the client entry */
1750 	if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
1751 	{
1752 		php_error_docref(NULL, E_ERROR, "Unable to retrieve client");
1753 
1754 		return;
1755 	}
1756 
1757 	/* Always reset the URLs before making any request */
1758 	solr_client_init_urls(client);
1759 
1760 	/* Make the HTTP request to the Solr instance */
1761 	if (solr_make_request(client, SOLR_REQUEST_PING) == FAILURE)
1762 	{
1763 		success = 0;
1764 
1765 		/* if there was an error with the http request solr_make_request throws an exception by itself
1766 		 * if it wasn't a curl connection error, throw exception (omars)
1767 		 */
1768 		HANDLE_SOLR_SERVER_ERROR(client,"ping");
1769 
1770 		/* SOLR_SHOW_CURL_WARNING; commented by: omars <omars@php.net> */
1771 	}
1772 
1773 	object_init_ex(return_value, solr_ce_SolrPingResponse);
1774 	solr_set_response_object_properties(solr_ce_SolrPingResponse, return_value, client, &(client->options.ping_url), success);
1775 }
1776 /* }}} */
1777 
1778 /* {{{ proto SolrGenericResponse SolrClient::threads()
1779    Sends a request to get info about threads. */
PHP_METHOD(SolrClient,threads)1780 PHP_METHOD(SolrClient, threads)
1781 {
1782 	zend_bool success = 1;
1783 	solr_client_t *client = NULL;
1784 
1785 	/* Retrieve the client entry */
1786 	if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
1787 	{
1788 		php_error_docref(NULL, E_ERROR, "Unable to retrieve client");
1789 
1790 		return;
1791 	}
1792 
1793 	/* Always reset the URLs before making any request */
1794 	solr_client_init_urls(client);
1795 
1796 	/* Make the HTTP request to the Solr instance */
1797 	if (solr_make_request(client, SOLR_REQUEST_THREADS) == FAILURE)
1798 	{
1799 		success = 0;
1800 		/* if there was an error with the http request solr_make_request throws an exception by itself
1801 		 * if it wasn't a curl connection error, throw exception (omars)
1802 		 */
1803 		HANDLE_SOLR_SERVER_ERROR(client,"threads");
1804 
1805 		/* SOLR_SHOW_CURL_WARNING; commented by: omars <omars@php.net> */
1806 	}
1807 
1808 	object_init_ex(return_value, solr_ce_SolrGenericResponse);
1809 	solr_set_response_object_properties(solr_ce_SolrGenericResponse, return_value, client, &(client->options.thread_url), success);
1810 }
1811 /* }}} */
1812 
1813 /* {{{ proto SolrGenericResponse SolrClient::info()
1814    Sends a request to get system info. */
PHP_METHOD(SolrClient,system)1815 PHP_METHOD(SolrClient, system)
1816 {
1817 	zend_bool success = 1;
1818 	solr_client_t *client = NULL;
1819 
1820 	/* Retrieve the client entry */
1821 	if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
1822 	{
1823 		php_error_docref(NULL, E_ERROR, "Unable to retrieve client");
1824 
1825 		return;
1826 	}
1827 
1828 	/* Always reset the URLs before making any request */
1829 	solr_client_init_urls(client);
1830 
1831 	/* Make the HTTP request to the Solr instance */
1832 	if (solr_make_request(client, SOLR_REQUEST_SYSTEM) == FAILURE)
1833 	{
1834 		success = 0;
1835 		/* if there was an error with the http request solr_make_request throws an exception by itself
1836 		 * if it wasn't a curl connection error, throw exception (omars)
1837 		 */
1838 		HANDLE_SOLR_SERVER_ERROR(client,"system");
1839 
1840 		/* SOLR_SHOW_CURL_WARNING; commented by: omars <omars@php.net> */
1841 	}
1842 
1843 	object_init_ex(return_value, solr_ce_SolrGenericResponse);
1844 	solr_set_response_object_properties(solr_ce_SolrGenericResponse, return_value, client, &(client->options.system_url), success);
1845 }
1846 /* }}} */
1847 
1848 /* {{{ proto array SolrClient::getOptions()
1849    Returns all the options for this client. */
PHP_METHOD(SolrClient,getOptions)1850 PHP_METHOD(SolrClient, getOptions)
1851 {
1852 	solr_client_t *client = NULL;
1853 
1854 	solr_client_options_t *options = NULL;
1855 
1856 	/* Retrieve the client entry */
1857 	if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
1858 	{
1859 		php_error_docref(NULL, E_ERROR, "Unable to retrieve client");
1860 
1861 		return;
1862 	}
1863 
1864 	options = &(client->options);
1865 
1866 	array_init(return_value);
1867 
1868 	add_assoc_long(return_value, "timeout", options->timeout);
1869 	add_assoc_bool(return_value, "secure", (int) options->secure);
1870 
1871 	add_assoc_stringl(return_value, "hostname", options->hostname.str, options->hostname.len);
1872 	add_assoc_stringl(return_value, "wt", options->response_writer.str, options->response_writer.len);
1873 	add_assoc_long(return_value, "port", options->host_port);
1874 
1875 	add_assoc_stringl(return_value, "proxy_host", options->proxy_hostname.str, options->proxy_hostname.len);
1876 	add_assoc_long(return_value, "proxy_port", options->proxy_port);
1877 
1878 
1879 	add_assoc_stringl(return_value, "path", options->path.str, options->path.len);
1880 
1881 	add_assoc_stringl(return_value, "http_auth", options->http_auth_credentials.str, options->http_auth_credentials.len);
1882 	add_assoc_stringl(return_value, "proxy_auth", options->proxy_auth_credentials.str, options->proxy_auth_credentials.len);
1883 
1884 	add_assoc_bool(return_value, "ssl_verify_peer", (int) options->ssl_verify_peer);
1885 	add_assoc_long(return_value, "ssl_verify_host", options->ssl_verify_host);
1886 
1887 	add_assoc_stringl(return_value, "ssl_cert", options->ssl_cert.str, options->ssl_cert.len);
1888 	add_assoc_stringl(return_value, "ssl_key", options->ssl_key.str, options->ssl_key.len);
1889 	add_assoc_stringl(return_value, "ssl_keypassword", options->ssl_keypassword.str, options->ssl_keypassword.len);
1890 	add_assoc_stringl(return_value, "ssl_cainfo", options->ssl_cainfo.str, options->ssl_cainfo.len);
1891 	add_assoc_stringl(return_value, "ssl_capath", options->ssl_capath.str, options->ssl_capath.len);
1892 }
1893 /* }}} */
1894 
1895 
1896 /* {{{ proto string SolrClient::getDebug()
1897    Returns all debug data captured in the process of making the request. */
PHP_METHOD(SolrClient,getDebug)1898 PHP_METHOD(SolrClient, getDebug)
1899 {
1900 	solr_client_t *client = NULL;
1901 
1902 	solr_curl_t *handle = NULL;
1903 
1904 	/* Retrieve the client entry */
1905 	if (solr_fetch_client_entry(getThis(), &client) == FAILURE)
1906 	{
1907 		php_error_docref(NULL, E_ERROR, "Unable to retrieve client");
1908 
1909 		return;
1910 	}
1911 
1912 	handle = &(client->handle);
1913 
1914 	if (!handle->debug_data_buffer.len)
1915 	{
1916 		RETURN_NULL();
1917 	}
1918 
1919 	RETVAL_STRINGL(handle->debug_data_buffer.str, handle->debug_data_buffer.len);
1920 }
1921 
1922 /*
1923  * Local variables:
1924  * tab-width: 4
1925  * c-basic-offset: 4
1926  * indent-tabs-mode: t
1927  * End:
1928  * vim600: fdm=marker
1929  * vim: noet sw=4 ts=4
1930  */
1931