Request::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
c 0
b 0
f 0
nc 2
nop 2
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 2
rs 10
1
<?php
2
3
namespace PhpXmlRpc;
4
5
use PhpXmlRpc\Exception\HttpException;
6
use PhpXmlRpc\Helper\Http;
7
use PhpXmlRpc\Helper\XMLParser;
8
use PhpXmlRpc\Traits\CharsetEncoderAware;
9
use PhpXmlRpc\Traits\DeprecationLogger;
10
use PhpXmlRpc\Traits\ParserAware;
11
use PhpXmlRpc\Traits\PayloadBearer;
12
13
/**
14
 * This class provides the representation of a request to an XML-RPC server.
15
 * A client sends a PhpXmlrpc\Request to a server, and receives back an PhpXmlrpc\Response.
16
 *
17
 * @todo feature creep - add a protected $httpRequest member, in the same way the Response has one
18
 *
19
 * @property string $methodname deprecated - public access left in purely for BC. Access via method()/__construct()
20
 * @property Value[] $params deprecated - public access left in purely for BC. Access via getParam()/__construct()
21
 * @property int $debug deprecated - public access left in purely for BC. Access via .../setDebug()
22
 * @property string $payload deprecated - public access left in purely for BC. Access via getPayload()/setPayload()
23
 * @property string $content_type deprecated - public access left in purely for BC. Access via getContentType()/setPayload()
24
 */
25
class Request
26
{
27
    use CharsetEncoderAware;
28
    use DeprecationLogger;
29
    use ParserAware;
30
    use PayloadBearer;
31
32
    /** @var string */
33
    protected $methodname;
34 3
    /** @var Value[] */
35
    protected $params = array();
36 3
    /** @var int */
37 3
    protected $debug = 0;
38
39 3
    /**
40
     * holds data while parsing the response. NB: Not a full Response object
41
     * @deprecated will be removed in a future release; still accessible by subclasses for the moment
42
     */
43
    private $httpResponse = array();
44
45
    /**
46
     * @param string $methodName the name of the method to invoke
47 707
     * @param Value[] $params array of parameters to be passed to the method (NB: Value objects, not plain php values)
48
     */
49 707
    public function __construct($methodName, $params = array())
50 8
    {
51
        $this->methodname = $methodName;
52 707
        foreach ($params as $param) {
53
            $this->addParam($param);
54
        }
55
    }
56
57
    /**
58
     * Gets/sets the xml-rpc method to be invoked.
59
     *
60 652
     * @param string $methodName the method to be set (leave empty not to set it)
61
     * @return string the method that will be invoked
62 652
     */
63 9
    public function method($methodName = '')
64
    {
65 652
        if ($methodName != '') {
66
            $this->methodname = $methodName;
67
        }
68
69
        return $this->methodname;
70
    }
71
72
    /**
73
     * Add a parameter to the list of parameters to be used upon method invocation.
74
     * Checks that $params is actually a Value object and not a plain php value.
75
     *
76
     * @param Value $param
77 715
     * @return boolean false on failure
78
     */
79 715
    public function addParam($param)
80 715
    {
81 500
        // check: do not add to self params which are not xml-rpc values
82
        if (is_object($param) && is_a($param, 'PhpXmlRpc\Value')) {
83 715
            $this->params[] = $param;
84
85
            return true;
86
        } else {
87
            $this->getLogger()->error('XML-RPC: ' . __METHOD__ . ': value passed in must be a PhpXmlRpc\Value');
88
            return false;
89
        }
90 652
    }
91
92 652
    /**
93 60
     * Returns the nth parameter in the request. The index zero-based.
94
     *
95 592
     * @param integer $i the index of the parameter to fetch (zero based)
96
     * @return Value the i-th parameter
97
     */
98
    public function getParam($i)
99
    {
100
        return $this->params[$i];
101
    }
102
103 652
    /**
104
     * Returns the number of parameters in the message.
105 652
     *
106
     * @return integer the number of parameters currently set
107
     */
108
    public function getNumParams()
109
    {
110
        return count($this->params);
111
    }
112 652
113
    /**
114 652
     * Returns xml representation of the message, XML prologue included. Sets `payload` and `content_type` properties
115 60
     *
116
     * @param string $charsetEncoding
117 592
     * @return string the xml representation of the message, xml prologue included
118
     */
119 652
    public function serialize($charsetEncoding = '')
120 652
    {
121 652
        $this->createPayload($charsetEncoding);
122 652
123 652
        return $this->payload;
124 609
    }
125 609
126
    /**
127 652
     * @internal this function will become protected in the future (and be folded into serialize)
128 652
     *
129 652
     * @param string $charsetEncoding
130
     * @return void
131
     */
132
    public function createPayload($charsetEncoding = '')
133
    {
134
        $this->logDeprecationUnlessCalledBy('serialize');
135
136
        if ($charsetEncoding != '') {
137
            $this->content_type = 'text/xml; charset=' . $charsetEncoding;
138 562
        } else {
139
            $this->content_type = 'text/xml';
140 562
        }
141
142
        $result = $this->xml_header($charsetEncoding);
143
        $result .= '<methodName>' . $this->getCharsetEncoder()->encodeEntities(
144 562
                $this->methodname, PhpXmlRpc::$xmlrpc_internalencoding, $charsetEncoding) . "</methodName>\n";
145
        $result .= "<params>\n";
146
        foreach ($this->params as $p) {
147
            $result .= "<param>\n" . $p->serialize($charsetEncoding) .
148
                "</param>\n";
149
        }
150
        $result .= "</params>\n";
151
        $result .= $this->xml_footer();
152
153
        $this->payload = $result;
154 652
    }
155
156 652
    /**
157
     * @internal this function will become protected in the future (and be folded into serialize)
158 652
     *
159
     * @param string $charsetEncoding
160
     * @return string
161
     */
162
    public function xml_header($charsetEncoding = '')
163
    {
164
        $this->logDeprecationUnlessCalledBy('createPayload');
165
166
        if ($charsetEncoding != '') {
167
            return "<?xml version=\"1.0\" encoding=\"$charsetEncoding\" ?" . ">\n<methodCall>\n";
168
        } else {
169
            return "<?xml version=\"1.0\"?" . ">\n<methodCall>\n";
170 657
        }
171
    }
172
173 657
    /**
174 657
     * @internal this function will become protected in the future (and be folded into serialize)
175
     *
176 657
     * @return string
177
     */
178
    public function xml_footer()
179
    {
180
        $this->logDeprecationUnlessCalledBy('createPayload');
181
182
        return '</methodCall>';
183
    }
184
185
    /**
186
     * Given an open file handle, read all data available and parse it as an xml-rpc response.
187
     *
188
     * NB: the file handle is not closed by this function.
189 517
     * NNB: might have trouble in rare cases to work on network streams, as we check for a read of 0 bytes instead of
190
     *      feof($fp). But since checking for feof(null) returns false, we would risk an infinite loop in that case,
191 517
     *      because we cannot trust the caller to give us a valid pointer to an open file...
192
     *
193
     * @param resource $fp stream pointer
194
     * @param bool $headersProcessed
195
     * @param string $returnType
196
     * @return Response
197
     *
198
     * @todo arsing Responses is not really the responsibility of the Request class. Maybe of the Client...
199 538
     * @todo feature creep - add a flag to disable trying to parse the http headers
200
     */
201 538
    public function parseResponseFile($fp, $headersProcessed = false, $returnType = 'xmlrpcvals')
202
    {
203
        $ipd = '';
204
        // q: is there an optimal buffer size? Is there any value in making the buffer size a tuneable?
205
        while ($data = fread($fp, 32768)) {
206
            $ipd .= $data;
207
        }
208
        return $this->parseResponse($ipd, $headersProcessed, $returnType);
209
    }
210
211
    /**
212
     * Parse the xml-rpc response contained in the string $data and return a Response object.
213
     *
214
     * When $this->debug has been set to a value greater than 0, will echo debug messages to screen while decoding.
215
     *
216
     * @param string $data the xml-rpc response, possibly including http headers
217
     * @param bool $headersProcessed when true prevents parsing HTTP headers for interpretation of content-encoding and
218
     *                               consequent decoding
219
     * @param string $returnType decides return type, i.e. content of response->value(). Either 'xmlrpcvals', 'xml' or
220
     *                           'phpvals'
221
     * @return Response
222
     *
223
     * @todo parsing Responses is not really the responsibility of the Request class. Maybe of the Client...
224
     * @todo what about only populating 'raw_data' in httpResponse when debug mode is > 0?
225
     * @todo feature creep - allow parsing data gotten from a stream pointer instead of a string: read it piecewise,
226
     *       looking first for separation between headers and body, then for charset indicators, server debug info and
227
     *       </methodResponse>. That would require a notable increase in code complexity...
228
     */
229
    public function parseResponse($data = '', $headersProcessed = false, $returnType = XMLParser::RETURN_XMLRPCVALS)
230
    {
231
        if ($this->debug > 0) {
232
            $this->getLogger()->debug("---GOT---\n$data\n---END---");
233
        }
234
235
        $this->httpResponse = array('raw_data' => $data, 'headers' => array(), 'cookies' => array());
0 ignored issues
show
Deprecated Code introduced by
The property PhpXmlRpc\Request::$httpResponse has been deprecated: will be removed in a future release; still accessible by subclasses for the moment ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

235
        /** @scrutinizer ignore-deprecated */ $this->httpResponse = array('raw_data' => $data, 'headers' => array(), 'cookies' => array());

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
236
237
        if ($data == '') {
238
            $this->getLogger()->error('XML-RPC: ' . __METHOD__ . ': no response received from server.');
239
            return new Response(0, PhpXmlRpc::$xmlrpcerr['no_data'], PhpXmlRpc::$xmlrpcstr['no_data']);
240
        }
241
242 711
        // parse the HTTP headers of the response, if present, and separate them from data
243
        if (substr($data, 0, 4) == 'HTTP') {
244 711
            $httpParser = new Http();
245 3
            try {
246
                $httpResponse = $httpParser->parseResponseHeaders($data, $headersProcessed, $this->debug > 0);
0 ignored issues
show
Bug introduced by
$this->debug > 0 of type boolean is incompatible with the type integer expected by parameter $debug of PhpXmlRpc\Helper\Http::parseResponseHeaders(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

246
                $httpResponse = $httpParser->parseResponseHeaders($data, $headersProcessed, /** @scrutinizer ignore-type */ $this->debug > 0);
Loading history...
247
            } catch (HttpException $e) {
248 711
                // failed processing of HTTP response headers
249
                // save into response obj the full payload received, for debugging
250 711
                return new Response(0, $e->getCode(), $e->getMessage(), '', array('raw_data' => $data, 'status_code' => $e->statusCode()));
251
            } catch(\Exception $e) {
252
                return new Response(0, $e->getCode(), $e->getMessage(), '', array('raw_data' => $data));
253
            }
254
        } else {
255
            $httpResponse = $this->httpResponse;
0 ignored issues
show
Deprecated Code introduced by
The property PhpXmlRpc\Request::$httpResponse has been deprecated: will be removed in a future release; still accessible by subclasses for the moment ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

255
            $httpResponse = /** @scrutinizer ignore-deprecated */ $this->httpResponse;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
256 711
        }
257 699
258
        // be tolerant of extra whitespace in response body
259 699
        $data = trim($data);
260 3
261
        /// @todo optimization creep - return an error msg if $data == ''
262
263 3
        // be tolerant of junk after methodResponse (e.g. javascript ads automatically inserted by free hosts)
264
        // idea from Luca Mariano, originally in PEARified version of the lib
265
        $pos = strrpos($data, '</methodResponse>');
266
        if ($pos !== false) {
267
            $data = substr($data, 0, $pos + 17);
268
        }
269
270 708
        // try to 'guestimate' the character encoding of the received response
271
        $respEncoding = XMLParser::guessEncoding(
272
            isset($httpResponse['headers']['content-type']) ? $httpResponse['headers']['content-type'] : '',
273
            $data
274
        );
275
276 708
        if ($this->debug >= 0) {
277 708
            $this->httpResponse = $httpResponse;
0 ignored issues
show
Deprecated Code introduced by
The property PhpXmlRpc\Request::$httpResponse has been deprecated: will be removed in a future release; still accessible by subclasses for the moment ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

277
            /** @scrutinizer ignore-deprecated */ $this->httpResponse = $httpResponse;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
278 708
        } else {
279
            $httpResponse = null;
280
        }
281
282 708
        if ($this->debug > 0) {
283
            $start = strpos($data, '<!-- SERVER DEBUG INFO (BASE64 ENCODED):');
284 708
            if ($start) {
285 3
                $start += strlen('<!-- SERVER DEBUG INFO (BASE64 ENCODED):');
286 3
                /// @todo what if there is no end tag?
287 3
                $end = strpos($data, '-->', $start);
288 3
                $comments = substr($data, $start, $end - $start);
289 3
                $this->getLogger()->debug("---SERVER DEBUG INFO (DECODED)---\n\t" .
290 3
                    str_replace("\n", "\n\t", base64_decode($comments)) . "\n---END---", array('encoding' => $respEncoding));
291 3
            }
292
        }
293
294
        // if the user wants back raw xml, give it to her
295
        if ($returnType == 'xml') {
296 708
            return new Response($data, 0, '', 'xml', $httpResponse);
297 1
        }
298
299
        /// @todo move this block of code into the XMLParser
300 707
        if ($respEncoding != '') {
301
            // Since parsing will fail if charset is not specified in the xml declaration,
302
            // the encoding is not UTF8 and there are non-ascii chars in the text, we try to work round that...
303
            // The following code might be better for mb_string enabled installs, but makes the lib about 200% slower...
304
            //if (!is_valid_charset($respEncoding, array('UTF-8')))
305
            if (!in_array($respEncoding, array('UTF-8', 'US-ASCII')) && !XMLParser::hasEncoding($data)) {
306 707
                if (function_exists('mb_convert_encoding')) {
307 1
                    $data = mb_convert_encoding($data, 'UTF-8', $respEncoding);
308 1
                } else {
309
                    if ($respEncoding == 'ISO-8859-1') {
310
                        $data = utf8_encode($data);
311
                    } else {
312
                        $this->getLogger()->error('XML-RPC: ' . __METHOD__ . ': unsupported charset encoding of received response: ' . $respEncoding);
313
                    }
314
                }
315
            }
316
        }
317
        // PHP internally might use ISO-8859-1, so we have to tell the xml parser to give us back data in the expected charset.
318
        // What if internal encoding is not in one of the 3 allowed? We use the broadest one, i.e. utf8
319
        if (in_array(PhpXmlRpc::$xmlrpc_internalencoding, array('UTF-8', 'ISO-8859-1', 'US-ASCII'))) {
320
            $options = array(XML_OPTION_TARGET_ENCODING => PhpXmlRpc::$xmlrpc_internalencoding);
321
        } else {
322
            $options = array(XML_OPTION_TARGET_ENCODING => 'UTF-8', 'target_charset' => PhpXmlRpc::$xmlrpc_internalencoding);
323
        }
324 707
325
        $xmlRpcParser = $this->getParser();
326
        $_xh = $xmlRpcParser->parse($data, $returnType, XMLParser::ACCEPT_RESPONSE, $options);
327
        // BC
328 707
        if (!is_array($_xh)) {
329
            $_xh = $xmlRpcParser->_xh;
330
        }
331 707
332 707
        // first error check: xml not well-formed
333
        if ($_xh['isf'] == 3) {
334
335 707
            // BC break: in the past for some cases we used the error message: 'XML error at line 1, check URL'
336
337
            // Q: should we give back an error with variable error number, as we do server-side? But if we do, will
338
            //    we be able to tell apart the two cases? In theory, we never emit invalid xml on our end, but
339 3
            //    there could be proxies meddling with the request, or network data corruption...
340 3
341 3
            $r = new Response(0, PhpXmlRpc::$xmlrpcerr['invalid_xml'],
342
                PhpXmlRpc::$xmlrpcstr['invalid_xml'] . ' ' . $_xh['isf_reason'], '', $httpResponse);
343
344 3
            if ($this->debug > 0) {
345 3
                $this->getLogger()->debug($_xh['isf_reason']);
346
            }
347
        }
348
        // second error check: xml well-formed but not xml-rpc compliant
349 707
        elseif ($_xh['isf'] == 2) {
350 4
            $r = new Response(0, PhpXmlRpc::$xmlrpcerr['xml_not_compliant'],
351 4
                PhpXmlRpc::$xmlrpcstr['xml_not_compliant'] . ' ' . $_xh['isf_reason'], '', $httpResponse);
352 4
353
            /// @todo echo something for the user? check if it was already done by the parser...
354
            //if ($this->debug > 0) {
355 4
            //    $this->getLogger()->debug($_xh['isf_reason']);
356
            //}
357
        }
358
        // third error check: parsing of the response has somehow gone boink.
359
        /// @todo shall we omit the 2nd part of this check, since we trust the parsing code?
360
        ///       Either that, or check the fault results too...
361 704
        elseif ($_xh['isf'] > 3 || ($returnType == XMLParser::RETURN_XMLRPCVALS && !$_xh['isf'] && !is_object($_xh['value']))) {
362
            // something odd has happened and it's time to generate a client side error indicating something odd went on
363
            $r = new Response(0, PhpXmlRpc::$xmlrpcerr['xml_parsing_error'], PhpXmlRpc::$xmlrpcstr['xml_parsing_error'],
364
                '', $httpResponse
365
            );
366
367
            /// @todo echo something for the user?
368
        } else {
369 704
            if ($this->debug > 1) {
370 2
                $this->getLogger()->debug(
371 2
                    "---PARSED---\n".var_export($_xh['value'], true)."\n---END---"
372
                );
373
            }
374
375 704
            $v = $_xh['value'];
376
377 704
            if ($_xh['isf']) {
378
                /// @todo we should test (here or preferably in the parser) if server sent an int and a string, and/or
379 109
                ///       coerce them into such...
380 109
                if ($returnType == XMLParser::RETURN_XMLRPCVALS) {
381 109
                    $errNo_v = $v['faultCode'];
382 109
                    $errStr_v = $v['faultString'];
383 109
                    $errNo = $errNo_v->scalarVal();
384
                    $errStr = $errStr_v->scalarVal();
385
                } else {
386
                    $errNo = $v['faultCode'];
387
                    $errStr = $v['faultString'];
388
                }
389 109
390
                if ($errNo == 0) {
391
                    // FAULT returned, errno needs to reflect that
392
                    /// @todo feature creep - add this code to PhpXmlRpc::$xmlrpcerr
393
                    $this->getLogger()->error('XML-RPC: ' . __METHOD__ . ': fault response received with faultCode 0 or null. Converted it to -1');
394 109
                    /// @todo in Encoder::decodeXML, we use PhpXmlRpc::$xmlrpcerr['invalid_return'] for this case (see
395
                    ///       also the todo 17 lines above)
396 680
                    $errNo = -1;
397
                }
398
399
                $r = new Response(0, $errNo, $errStr, '', $httpResponse);
400 707
            } else {
401
                $r = new Response($v, 0, '', $returnType, $httpResponse);
402
            }
403
        }
404
405
        return $r;
406
    }
407
408 150
    /**
409
     * Kept the old name even if Request class was renamed, for BC.
410 150
     *
411
     * @return string
412
     */
413
    public function kindOf()
414
    {
415
        return 'msg';
416
    }
417
418 712
    /**
419
     * Enables/disables the echoing to screen of the xml-rpc responses received.
420 712
     *
421 712
     * @param integer $level values <0, 0, 1, >1 are supported
422
     * @return $this
423
     */
424
    public function setDebug($level)
425
    {
426
        $this->debug = $level;
427
        return $this;
428
    }
429
430
    // *** BC layer ***
431
432
    // we have to make this return by ref in order to allow calls such as `$resp->_cookies['name'] = ['value' => 'something'];`
433
    public function &__get($name)
434
    {
435
        switch ($name) {
436
            case 'me':
437
            case 'mytype':
438
            case '_php_class':
439
            case 'payload':
440
            case 'content_type':
441
                $this->logDeprecation('Getting property Request::' . $name . ' is deprecated');
442
                return $this->$name;
443
            case 'httpResponse':
444
                // manually implement the 'protected property' behaviour
445
                $canAccess = false;
446
                $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
447
                if (isset($trace[1]) && isset($trace[1]['class'])) {
448
                    if (is_subclass_of($trace[1]['class'], 'PhpXmlRpc\Request')) {
449
                        $canAccess = true;
450
                    }
451
                }
452
                if ($canAccess) {
453
                    $this->logDeprecation('Getting property Request::' . $name . ' is deprecated');
454
                    return $this->httpResponse;
0 ignored issues
show
Deprecated Code introduced by
The property PhpXmlRpc\Request::$httpResponse has been deprecated: will be removed in a future release; still accessible by subclasses for the moment ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

454
                    return /** @scrutinizer ignore-deprecated */ $this->httpResponse;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
455
                } else {
456
                    trigger_error("Cannot access protected property Request::httpResponse in " . __FILE__, E_USER_ERROR);
457
                }
458
                break;
459
            default:
460
                /// @todo throw instead? There are very few other places where the lib trigger errors which can potentially reach stdout...
461
                $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
462
                trigger_error('Undefined property via __get(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_WARNING);
463
                $result = null;
464
                return $result;
465
        }
466
    }
467
468
    public function __set($name, $value)
469
    {
470
        switch ($name) {
471
            case 'methodname':
472
            case 'params':
473
            case 'debug':
474
            case 'payload':
475
            case 'content_type':
476
                $this->logDeprecation('Setting property Request::' . $name . ' is deprecated');
477
                $this->$name = $value;
478
                break;
479
            case 'httpResponse':
480
                // manually implement the 'protected property' behaviour
481
                $canAccess = false;
482
                $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
483
                if (isset($trace[1]) && isset($trace[1]['class'])) {
484
                    if (is_subclass_of($trace[1]['class'], 'PhpXmlRpc\Request')) {
485
                        $canAccess = true;
486
                    }
487
                }
488
                if ($canAccess) {
489
                    $this->logDeprecation('Setting property Request::' . $name . ' is deprecated');
490
                    $this->httpResponse = $value;
0 ignored issues
show
Deprecated Code introduced by
The property PhpXmlRpc\Request::$httpResponse has been deprecated: will be removed in a future release; still accessible by subclasses for the moment ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

490
                    /** @scrutinizer ignore-deprecated */ $this->httpResponse = $value;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
491
                } else {
492
                    trigger_error("Cannot access protected property Request::httpResponse in " . __FILE__, E_USER_ERROR);
493
                }
494
                break;
495
            default:
496
                /// @todo throw instead? There are very few other places where the lib trigger errors which can potentially reach stdout...
497
                $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
498
                trigger_error('Undefined property via __set(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_WARNING);
499
        }
500
    }
501
502
    public function __isset($name)
503
    {
504
        switch ($name) {
505
            case 'methodname':
506
            case 'params':
507
            case 'debug':
508
            case 'payload':
509
            case 'content_type':
510
                $this->logDeprecation('Checking property Request::' . $name . ' is deprecated');
511
                return isset($this->$name);
512
            case 'httpResponse':
513
                // manually implement the 'protected property' behaviour
514
                $canAccess = false;
515
                $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
516
                if (isset($trace[1]) && isset($trace[1]['class'])) {
517
                    if (is_subclass_of($trace[1]['class'], 'PhpXmlRpc\Request')) {
518
                        $canAccess = true;
519
                    }
520
                }
521
                if ($canAccess) {
522
                    $this->logDeprecation('Checking property Request::' . $name . ' is deprecated');
523
                    return isset($this->httpResponse);
0 ignored issues
show
Deprecated Code introduced by
The property PhpXmlRpc\Request::$httpResponse has been deprecated: will be removed in a future release; still accessible by subclasses for the moment ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

523
                    return isset(/** @scrutinizer ignore-deprecated */ $this->httpResponse);

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
524
                }
525
                // break through voluntarily
526
            default:
527
                return false;
528
        }
529
    }
530
531
    public function __unset($name)
532
    {
533
        switch ($name) {
534
            case 'methodname':
535
            case 'params':
536
            case 'debug':
537
            case 'payload':
538
            case 'content_type':
539
                $this->logDeprecation('Unsetting property Request::' . $name . ' is deprecated');
540
                unset($this->$name);
541
                break;
542
            case 'httpResponse':
543
                // manually implement the 'protected property' behaviour
544
                $canAccess = false;
545
                $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
546
                if (isset($trace[1]) && isset($trace[1]['class'])) {
547
                    if (is_subclass_of($trace[1]['class'], 'PhpXmlRpc\Request')) {
548
                        $canAccess = true;
549
                    }
550
                }
551
                if ($canAccess) {
552
                    $this->logDeprecation('Unsetting property Request::' . $name . ' is deprecated');
553
                    unset($this->httpResponse);
0 ignored issues
show
Deprecated Code introduced by
The property PhpXmlRpc\Request::$httpResponse has been deprecated: will be removed in a future release; still accessible by subclasses for the moment ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

553
                    unset(/** @scrutinizer ignore-deprecated */ $this->httpResponse);

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
554
                } else {
555
                    trigger_error("Cannot access protected property Request::httpResponse in " . __FILE__, E_USER_ERROR);
556
                }
557
                break;
558
            default:
559
                /// @todo throw instead? There are very few other places where the lib trigger errors which can potentially reach stdout...
560
                $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1);
561
                trigger_error('Undefined property via __unset(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_WARNING);
562
        }
563
    }
564
}
565