summaryrefslogtreecommitdiff
path: root/ext/soap/php_packet_soap.c
blob: 3414f970ebaf7e122d4fb5e4f6eaecffd4d02186 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "php_soap.h"

int parse_packet_soap(zval *this_ptr, char *buffer, int buffer_size, sdlFunctionPtr fn, char *fn_name, zval ***ret, int *num_params)
{
	xmlDocPtr response;
	xmlNodePtr trav, trav2, env, body, resp, cur, fault;
	zval **tmp_ret;
	TSRMLS_FETCH();

	response = xmlParseMemory(buffer, buffer_size);
	xmlCleanupParser();

	trav = response->children;
	FOREACHNODE(trav,"Envelope",env)
	{
		trav2 = env->children;
		FOREACHNODE(trav2,"Body",body)
		{
			fault = get_node(body->children,"Fault");
			if(fault != NULL)
			{
				char *faultcode = NULL, *faultstring = NULL, *faultactor = NULL;
				zval *details = NULL;
				xmlNodePtr tmp;

				tmp = get_node(fault->children,"faultcode");
				if(tmp != NULL && tmp->children != NULL)
					faultcode = tmp->children->content;

				tmp = get_node(fault->children,"faultstring");
				if(tmp != NULL && tmp->children != NULL)
					faultstring = tmp->children->content;

				tmp = get_node(fault->children,"faultactor");
				if(tmp != NULL && tmp->children != NULL)
					faultactor = tmp->children->content;

				tmp = get_node(fault->children,"detail");
				if(tmp != NULL)
				{
					encodePtr enc;
					enc = get_conversion(UNKNOWN_TYPE);
					details = enc->to_zval(enc->details, tmp);
				}

				add_soap_fault(this_ptr, faultcode, faultstring, faultactor, details);
			}
			else
			{
				resp = body->children;
				if(fn != NULL)
				{
					cur = get_node(resp, fn->responseName);
					if(cur != NULL)
					{
						int num_resp = zend_hash_num_elements(fn->responseParameters);
						if(num_resp <= 1)
						{
							sdlParamPtr *h_param, param;
							xmlNodePtr val;

							zend_hash_internal_pointer_reset(fn->responseParameters);
							if(zend_hash_get_current_data(fn->responseParameters, (void **)&h_param) != SUCCESS)
							{
								(*num_params) = 0;
							}
							else
							{
								param = (*h_param);
								val = get_node(cur->children, param->paramName);
								if(val != NULL)
								{
									encodePtr enc;
									tmp_ret = emalloc(sizeof(zval **));
									if(param != NULL)
										enc = param->encode;
									else
										enc = get_conversion(UNKNOWN_TYPE);

									tmp_ret[0] = master_to_zval(enc, val);
									(*ret) = tmp_ret;
									(*num_params) = 1;
								}
								else
									php_error(E_ERROR, "Can't find response parameter \"%s\"", param->paramName);
							}
						}
						else
						{
							php_error(E_ERROR,"Doesn't handle multiple return values");
						}
					}
				}
				else
				{
					cur = resp;
					while(cur && cur->type != XML_ELEMENT_NODE)
							cur = cur->next;
					if(cur != NULL)
					{
						xmlNodePtr val;
						val = cur->children;
						while(val && val->type != XML_ELEMENT_NODE)
							val = val->next;

						if(val != NULL)
						{
							encodePtr enc;
							enc = get_conversion(UNKNOWN_TYPE);
							tmp_ret = emalloc(sizeof(zval **));
							tmp_ret[0] = master_to_zval(enc, val);
							(*ret) = tmp_ret;
							(*num_params) = 1;
						}
					}
				}
			}
		}
		ENDFOREACH(trav2);
	}
	ENDFOREACH(trav);
	xmlFreeDoc(response);
	return TRUE;
}