WIP - more bugfixes and start of testsuite reimplementation
[plcapi.git] / src / Response.php
1 <?php
2
3 namespace PhpXmlRpc;
4
5 use PhpXmlRpc\Helper\Charset;
6
7 class Response
8 {
9
10     /// @todo: do these need to be public?
11     public $val = 0;
12     public $valtyp;
13     public $errno = 0;
14     public $errstr = '';
15     public $payload;
16     public $hdrs = array();
17     public $_cookies = array();
18     public $content_type = 'text/xml';
19     public $raw_data = '';
20
21     /**
22      * @param mixed $val either an xmlrpcval obj, a php value or the xml serialization of an xmlrpcval (a string)
23      * @param integer $fcode set it to anything but 0 to create an error response
24      * @param string $fstr the error string, in case of an error response
25      * @param string $valtyp either 'xmlrpcvals', 'phpvals' or 'xml'
26      *
27      * @todo add check that $val / $fcode / $fstr is of correct type???
28      * NB: as of now we do not do it, since it might be either an xmlrpcval or a plain
29      * php val, or a complete xml chunk, depending on usage of Client::send() inside which creator is called...
30      */
31     function __construct($val, $fcode = 0, $fstr = '', $valtyp='')
32     {
33         if($fcode != 0)
34         {
35             // error response
36             $this->errno = $fcode;
37             $this->errstr = $fstr;
38             //$this->errstr = htmlspecialchars($fstr); // XXX: encoding probably shouldn't be done here; fix later.
39         }
40         else
41         {
42             // successful response
43             $this->val = $val;
44             if ($valtyp == '')
45             {
46                 // user did not declare type of response value: try to guess it
47                 if (is_object($this->val) && is_a($this->val, 'PhpXmlRpc\Value'))
48                 {
49                     $this->valtyp = 'xmlrpcvals';
50                 }
51                 else if (is_string($this->val))
52                 {
53                     $this->valtyp = 'xml';
54                 }
55                 else
56                 {
57                     $this->valtyp = 'phpvals';
58                 }
59             }
60             else
61             {
62                 // user declares type of resp value: believe him
63                 $this->valtyp = $valtyp;
64             }
65         }
66     }
67
68     /**
69      * Returns the error code of the response.
70      * @return integer the error code of this response (0 for not-error responses)
71      */
72     public function faultCode()
73     {
74         return $this->errno;
75     }
76
77     /**
78      * Returns the error code of the response.
79      * @return string the error string of this response ('' for not-error responses)
80      */
81     public function faultString()
82     {
83         return $this->errstr;
84     }
85
86     /**
87      * Returns the value received by the server.
88      * @return mixed the xmlrpcval object returned by the server. Might be an xml string or php value if the response has been created by specially configured Client objects
89      */
90     public function value()
91     {
92         return $this->val;
93     }
94
95     /**
96      * Returns an array with the cookies received from the server.
97      * Array has the form: $cookiename => array ('value' => $val, $attr1 => $val1, $attr2 = $val2, ...)
98      * with attributes being e.g. 'expires', 'path', domain'.
99      * NB: cookies sent as 'expired' by the server (i.e. with an expiry date in the past)
100      * are still present in the array. It is up to the user-defined code to decide
101      * how to use the received cookies, and whether they have to be sent back with the next
102      * request to the server (using Client::setCookie) or not
103      * @return array array of cookies received from the server
104      */
105     public function cookies()
106     {
107         return $this->_cookies;
108     }
109
110     /**
111      * Returns xml representation of the response. XML prologue not included
112      * @param string $charset_encoding the charset to be used for serialization. if null, US-ASCII is assumed
113      * @return string the xml representation of the response
114      */
115     public function serialize($charset_encoding='')
116     {
117         if ($charset_encoding != '')
118             $this->content_type = 'text/xml; charset=' . $charset_encoding;
119         else
120             $this->content_type = 'text/xml';
121         if (PhpXmlRpc::$xmlrpc_null_apache_encoding)
122         {
123             $result = "<methodResponse xmlns:ex=\"".PhpXmlRpc::$xmlrpc_null_apache_encoding_ns."\">\n";
124         }
125         else
126         {
127             $result = "<methodResponse>\n";
128         }
129         if($this->errno)
130         {
131             // G. Giunta 2005/2/13: let non-ASCII response messages be tolerated by clients
132             // by xml-encoding non ascii chars
133             $charsetEncoder =
134             $result .= "<fault>\n" .
135 "<value>\n<struct><member><name>faultCode</name>\n<value><int>" . $this->errno .
136 "</int></value>\n</member>\n<member>\n<name>faultString</name>\n<value><string>" .
137 Charset::instance()->encode_entities($this->errstr, PhpXmlRpc::$xmlrpc_internalencoding, $charset_encoding) . "</string></value>\n</member>\n" .
138 "</struct>\n</value>\n</fault>";
139         }
140         else
141         {
142             if(!is_object($this->val) || !is_a($this->val, 'PhpXmlRpc\Value'))
143             {
144                 if (is_string($this->val) && $this->valtyp == 'xml')
145                 {
146                     $result .= "<params>\n<param>\n" .
147                         $this->val .
148                         "</param>\n</params>";
149                 }
150                 else
151                 {
152                     /// @todo try to build something serializable?
153                     die('cannot serialize xmlrpc response objects whose content is native php values');
154                 }
155             }
156             else
157             {
158                 $result .= "<params>\n<param>\n" .
159                     $this->val->serialize($charset_encoding) .
160                     "</param>\n</params>";
161             }
162         }
163         $result .= "\n</methodResponse>";
164         $this->payload = $result;
165         return $result;
166     }
167 }