public parseResponse ( $fp ) : object | ||
Результат | object |
public function parseResponse($fp)
{
$data = '';
while ($datum = fread($fp, 4096)) {
$data .= $datum;
}
// Display HTTP content for debugging
if ($this->debug === TRUE) {
echo "<pre>---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n</pre>";
}
// Check for data
if ($data === '') {
error_log($this->xmlrpcstr['no_data']);
return new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']);
}
// Check for HTTP 200 Response
if (strpos($data, 'HTTP') === 0 && !preg_match('/^HTTP\\/[0-9\\.]+ 200 /', $data)) {
$errstr = substr($data, 0, strpos($data, "\n") - 1);
return new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error'] . ' (' . $errstr . ')');
}
//-------------------------------------
// Create and Set Up XML Parser
//-------------------------------------
$parser = xml_parser_create($this->xmlrpc_defencoding);
$pname = (string) $parser;
$this->xh[$pname] = array('isf' => 0, 'ac' => '', 'headers' => array(), 'stack' => array(), 'valuestack' => array(), 'isf_reason' => 0);
xml_set_object($parser, $this);
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, TRUE);
xml_set_element_handler($parser, 'open_tag', 'closing_tag');
xml_set_character_data_handler($parser, 'character_data');
//xml_set_default_handler($parser, 'default_handler');
// Get headers
$lines = explode("\r\n", $data);
while ($line = array_shift($lines)) {
if (strlen($line) < 1) {
break;
}
$this->xh[$pname]['headers'][] = $line;
}
$data = implode("\r\n", $lines);
// Parse XML data
if (!xml_parse($parser, $data, count($data))) {
$errstr = sprintf('XML error: %s at line %d', xml_error_string(xml_get_error_code($parser)), xml_get_current_line_number($parser));
$r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return']);
xml_parser_free($parser);
return $r;
}
xml_parser_free($parser);
// Got ourselves some badness, it seems
if ($this->xh[$pname]['isf'] > 1) {
if ($this->debug === TRUE) {
echo "---Invalid Return---\n" . $this->xh[$pname]['isf_reason'] . "---Invalid Return---\n\n";
}
return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return'] . ' ' . $this->xh[$pname]['isf_reason']);
} elseif (!is_object($this->xh[$pname]['value'])) {
return new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'], $this->xmlrpcstr['invalid_return'] . ' ' . $this->xh[$pname]['isf_reason']);
}
// Display XML content for debugging
if ($this->debug === TRUE) {
echo '<pre>';
if (count($this->xh[$pname]['headers'] > 0)) {
echo "---HEADERS---\n";
foreach ($this->xh[$pname]['headers'] as $header) {
echo $header . "\n";
}
echo "---END HEADERS---\n\n";
}
echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n---PARSED---\n";
var_dump($this->xh[$pname]['value']);
echo "\n---END PARSED---</pre>";
}
// Send response
$v = $this->xh[$pname]['value'];
if ($this->xh[$pname]['isf']) {
$errno_v = $v->me['struct']['faultCode'];
$errstr_v = $v->me['struct']['faultString'];
$errno = $errno_v->scalarval();
if ($errno === 0) {
// FAULT returned, errno needs to reflect that
$errno = -1;
}
$r = new XML_RPC_Response($v, $errno, $errstr_v->scalarval());
} else {
$r = new XML_RPC_Response($v);
}
$r->headers = $this->xh[$pname]['headers'];
return $r;
}
function event_hook($event, &$bag, &$eventData) { global $serendipity; $hooks =& $bag->get('event_hooks'); if (isset($hooks[$event])) { switch ($event) { case 'backend_display': ?> <fieldset style="margin: 5px"> <legend><?php echo PLUGIN_EVENT_WEBLOGPING_PING; ?> </legend> <?php $noneclick = ''; foreach ($this->services as $index => $service) { // Detect if the current checkbox needs to be saved. We use the field chk_timestamp to see, // if the form has already been submitted and individual changes shall be preserved $selected = $serendipity['POST']['chk_timestamp'] && $serendipity['POST']['announce_entries_' . $service['name']] || !isset($serendipity['POST']['chk_timestamp']) && $this->get_config($service['name']) == 'true' ? 'checked="checked"' : ''; $noneclick .= 'document.getElementById(\'serendipity[announce_entries_' . $service['name'] . ']\').checked = false; '; $onclick = ''; if (!empty($service['supersedes'])) { $onclick = 'onclick="'; $supersedes = explode(', ', $service['supersedes']); foreach ($supersedes as $sid => $servicename) { $onclick .= 'document.getElementById(\'serendipity[announce_entries_' . $servicename . ']\').checked = false; '; } $onclick .= '"'; } $title = sprintf(PLUGIN_EVENT_WEBLOGPING_SENDINGPING, $service['name']) . (!empty($service['supersedes']) ? ' ' . sprintf(PLUGIN_EVENT_WEBLOGPING_SUPERSEDES, $service['supersedes']) : ''); ?> <input <?php echo $onclick; ?> class="input_checkbox" style="margin: 0px; padding: 0px; vertical-align: bottom;" type="checkbox" name="serendipity[announce_entries_<?php echo $service['name']; ?> ]" id="serendipity[announce_entries_<?php echo $service['name']; ?> ]" value="true" <?php echo $selected; ?> /> <label title="<?php echo $title; ?> " style="vertical-align: bottom; margin: 0px; padding: 0px;" for="serendipity[announce_entries_<?php echo $service['name']; ?> ]"> <?php echo $service['name']; ?> </label><br /> <?php } ?> <input onclick="<?php echo $noneclick; ?> " class="input_checkbox" style="margin: 0px; padding: 0px; vertical-align: bottom;" type="checkbox" value="none" id="serendipity[announce_entries_none]" /> <label title="<?php echo NONE; ?> " style="vertical-align: bottom; margin: 0px; padding: 0px;" for="serendipity[announce_entries_none]"> <?php echo NONE; ?> </label><br /> </fieldset> <?php return true; break; case 'backend_publish': if (!class_exists('XML_RPC_Base')) { include_once S9Y_PEAR_PATH . "XML/RPC.php"; } // First cycle through list of services to remove superseding services which may have been checked foreach ($this->services as $index => $service) { if (!empty($service['supersedes']) && isset($serendipity['POST']['announce_entries_' . $service['name']])) { $supersedes = explode(', ', $service['supersedes']); foreach ($supersedes as $sid => $servicename) { // A service has been checked that is superseded by another checked meta-service. Remove that service from the list of services to be ping'd unset($serendipity['POST']['announce_entries_' . $servicename]); } } } foreach ($this->services as $index => $service) { if (isset($serendipity['POST']['announce_entries_' . $service['name']]) || defined('SERENDIPITY_IS_XMLRPC') && serendipity_db_bool($this->get_config($service['name']))) { if (!defined('SERENDIPITY_IS_XMLRPC') || defined('SERENDIPITY_XMLRPC_VERBOSE')) { printf(PLUGIN_EVENT_WEBLOGPING_SENDINGPING . '...', $service['host']); } flush(); # XXX append $serendipity['indexFile'] to baseURL? $args = array(new XML_RPC_Value($serendipity['blogTitle'], 'string'), new XML_RPC_Value($serendipity['baseURL'], 'string')); if ($service['extended']) { # the checkUrl: for when the main page is not really the main page $args[] = new XML_RPC_Value('', 'string'); # the rssUrl $args[] = new XML_RPC_Value($serendipity['baseURL'] . 'rss.php?version=2.0', 'string'); } $message = new XML_RPC_Message($service['extended'] ? 'weblogUpdates.extendedPing' : 'weblogUpdates.ping', $args); $client = new XML_RPC_Client(trim($service['path']), trim($service['host'])); # 15 second timeout may not be long enough for weblogs.com $message->createPayload(); $options = array(); serendipity_plugin_api::hook_event('backend_http_request', $options, 'weblogping'); serendipity_request_start(); $req = new HTTP_Request("http://" . $service['host'] . $service['path'], $options); $req->setMethod(HTTP_REQUEST_METHOD_POST); $req->addHeader("Content-Type", "text/xml"); if (strtoupper(LANG_CHARSET) != 'UTF-8') { $payload = utf8_encode($message->payload); } else { $payload = $message->payload; } $req->addRawPostData($payload); $http_result = $req->sendRequest(); $http_response = $req->getResponseBody(); $xmlrpc_result = $message->parseResponse($http_response); if ($xmlrpc_result->faultCode()) { $out = sprintf(PLUGIN_EVENT_WEBLOGPING_SEND_FAILURE . "<br />", htmlspecialchars($xmlrpc_result->faultString())); } else { $out = PLUGIN_EVENT_WEBLOGPING_SEND_SUCCESS . "<br />"; } serendipity_request_end(); if (!defined('SERENDIPITY_IS_XMLRPC') || defined('SERENDIPITY_XMLRPC_VERBOSE')) { echo $out; } } } return true; break; case 'external_plugin': if ($eventData == 'xmlrpc_ping') { echo "XMLRPC START\n"; @define('SERENDIPITY_IS_XMLRPC', true); @define('SERENDIPITY_XMLRPC_VERBOSE', true); $this->event_hook('backend_publish', $bag, $eventData); echo "XMLRPC DONE\n"; } return true; case 'frontend_display': case 'backend_insert': case 'backend_update': case 'backend_draft': default: return false; break; } } else { return false; } }