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