Server : Apache System : Linux indy02.toastserver.com 3.10.0-962.3.2.lve1.5.85.el7.x86_64 #1 SMP Thu Apr 18 15:18:36 UTC 2024 x86_64 User : palandch ( 1163) PHP Version : 7.1.33 Disable Function : NONE Directory : /home/palandch/www/core/model/modx/rest/ |
<?php /** * @package modx * @subpackage rest */ require_once dirname(__FILE__) . '/modrestclient.class.php'; /** * Handles REST requests through a cURL-based client * @package modx * @subpackage rest */ class modRestCurlClient extends modRestClient { /** * @param modX $modx A reference to the modX object * @param array $config An array of configuration options */ function __construct(modX &$modx,array $config = array()) { parent::__construct($modx, $config); $this->config = array_merge(array( ),$this->config); } /** * Extends modRestClient::request to provide cURL specific request handling * * @param string $host The host of the REST server. * @param string $path The path to request to on the REST server. * @param string $method The HTTP method to use for the request. May be GET, * PUT or POST. * @param array $params An array of parameters to send with the request. * @param array $options An array of options to pass to the request. * @return modRestResponse The response object. */ public function request($host,$path,$method = 'GET',array $params = array(),array $options = array()) { /* start our cURL connection */ $ch = curl_init(); /* setup request */ $this->setUrl($ch,$host,$path,$method,$params,$options); $this->setAuth($ch,$options); $this->setProxy($ch,$options); $this->setOptions($ch,$options); /* execute request */ $result = trim(curl_exec($ch)); /* make sure to close connection */ curl_close($ch); return $result; } /** * Configure and set the URL to use, along with any request parameters. * * @param resource $ch The cURL connection resource * @param string $host The host to send the request to * @param string $path The path of the request * @param string $method The method of the request (GET/POST) * @param array $params An array of request parameters to attach to the URL * @param array $options An array of options when setting the URL * @return boolean Whether or not the URL was set * @see modRestClient::request for parameter documentation. */ public function setUrl($ch,$host,$path,$method = 'GET',array $params = array(),array $options = array()) { $q = http_build_query($params); switch ($method) { case 'GET': $path .= (strpos($host,'?') === false ? '?' : '&').$q; break; case 'POST': curl_setopt($ch,CURLOPT_POST,1); $contentType = $this->modx->getOption('contentType',$options,'xml'); switch ($contentType) { case 'json': $json = $this->modx->toJSON($params); curl_setopt($ch,CURLOPT_HTTPHEADER, array('Content-Type: application/json')); curl_setopt($ch,CURLOPT_POSTFIELDS,$json); break; case 'xml': curl_setopt($ch,CURLOPT_HTTPHEADER, array('Content-Type: application/xml')); $xml = modRestArrayToXML::toXML($params,!empty($options['rootNode']) ? $options['rootNode'] : 'request'); curl_setopt($ch,CURLOPT_POSTFIELDS,$xml); break; default: curl_setopt($ch,CURLOPT_POSTFIELDS,$params); break; } break; } /* prevent invalid xhtml ampersands in request path */ $url = str_replace('&', '&', $host.$path); return curl_setopt($ch, CURLOPT_URL,$url); } /** * Set up cURL-specific options * * @param resource $ch The cURL connection resource * @param array $options An array of options */ public function setOptions($ch,array $options = array()) { /* always return us the result */ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); /* we dont want header gruft */ curl_setopt($ch, CURLOPT_HEADER, 0); /* default timeout to 30 seconds */ curl_setopt($ch, CURLOPT_TIMEOUT,$this->config[modRestClient::OPT_TIMEOUT]); /* disable verifypeer since it's not helpful on most environments */ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); /* send a useragent to allow proper responses */ curl_setopt($ch, CURLOPT_USERAGENT,$this->config[modRestCurlClient::OPT_USERAGENT]); /* can only use follow location if safe_mode and open_basedir are off */ $safeMode = ini_get('safe_mode'); $openBasedir = ini_get('open_basedir'); if (empty($safeMode) && empty($openBasedir)) { curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); } } /** * Set up authentication configuration , if specified, to be used with REST request. * * @param resource $ch The cURL connection resource. * @param array $options An array of options * @return boolean True if authentication was used. */ public function setAuth($ch,array $options = array()) { $auth = false; if (!empty($options[modRestClient::OPT_USERPWD])) { $options[modRestClient::OPT_AUTHTYPE] = $this->modx->getOption(modRestClient::OPT_AUTHTYPE,$options,'BASIC'); switch ($options[modRestClient::OPT_AUTHTYPE]) { case 'ANY': curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); break; case 'ANYSAFE': curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANYSAFE); break; case 'DIGEST': curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); break; case 'GSSNEGOTIATE': curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_GSSNEGOTIATE); break; case 'NTLM': curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM); break; default: case 'BASIC': curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); break; } $auth = curl_setopt($ch, CURLOPT_USERPWD, !empty($options[modRestClient::OPT_USERPWD]) ? $options[modRestClient::OPT_USERPWD] : 'username:password'); } return $auth; } /** * Set up proxy configuration , if specified, to be used with REST request. * * @param resource $ch The cURL connection resource. * @param array $options An array of options * @return boolean True if the proxy was setup. */ public function setProxy($ch,array $options = array()) { $proxyEnabled = false; /* if proxy is set, attempt to use it */ $proxyHost = $this->modx->getOption('proxy_host',null,''); if (!empty($proxyHost)) { $proxyEnabled = curl_setopt($ch, CURLOPT_PROXY,$proxyHost); $proxyPort = $this->modx->getOption('proxy_port',null,''); if (!empty($proxyPort)) { curl_setopt($ch, CURLOPT_PROXYPORT,$proxyPort); } $proxyUserpwd = $this->modx->getOption('proxy_username',null,''); if (!empty($proxyUserpwd)) { $proxyAuthType = $this->modx->getOption('proxy_auth_type',null,'BASIC'); $proxyAuthType = $proxyAuthType == 'NTLM' ? CURLAUTH_NTLM : CURLAUTH_BASIC; curl_setopt($ch, CURLOPT_PROXYAUTH,$proxyAuthType); $proxyPassword = $this->modx->getOption('proxy_password',null,''); if (!empty($proxyPassword)) $proxyUserpwd .= ':'.$proxyPassword; curl_setopt($ch, CURLOPT_PROXYUSERPWD,$proxyUserpwd); } } return $proxyEnabled; } } if (!class_exists('modRestArrayToXML')) { /** * Utility class for array-to-XML transformations. * * @package modx * @subpackage rest */ class modRestArrayToXML { /** * The main function for converting to an XML document. * Pass in a multi dimensional array and this recrusively loops through and builds up an XML document. * * @param array $data * @param string $rootNodeName - what you want the root node to be - defaultsto data. * @param SimpleXMLElement $xml - should only be used recursively * @return string XML */ public static function toXML( $data, $rootNodeName = 'ResultSet', &$xml=null ) { // turn off compatibility mode as simple xml throws a wobbly if you don't. if ( ini_get('zend.ze1_compatibility_mode') == 1 ) ini_set ( 'zend.ze1_compatibility_mode', 0 ); if ( is_null( $xml ) ) $xml = simplexml_load_string('<?xml version="1.0" encoding="UTF-8" standalone="yes"?><'.$rootNodeName.'></'.$rootNodeName.'>'); // loop through the data passed in. foreach( $data as $key => $value ) { // no numeric keys in our xml please! if ( is_numeric( $key ) ) { $numeric = 1; $key = $rootNodeName; } // delete any char not allowed in XML element names $key = preg_replace('/[^a-z0-9\-\_\.\:]/i', '', $key); // if there is another array found recrusively call this function if ( is_array( $value ) ) { $node = modRestArrayToXML::isAssoc( $value ) || $numeric ? $xml->addChild( $key ) : $xml; // recrusive call. if ( $numeric ) $key = 'anon'; modRestArrayToXML::toXml( $value, $key, $node ); } else { // add single node. $value = htmlentities( $value ); $xml->addChild( $key, $value ); } } // pass back as XML //return $xml->asXML(); // if you want the XML to be formatted, use the below instead to return the XML $doc = new DOMDocument('1.0'); $doc->preserveWhiteSpace = false; $doc->loadXML( $xml->asXML() ); $doc->formatOutput = true; return $doc->saveXML(); } /** * Convert an XML document to a multi dimensional array * Pass in an XML document (or SimpleXMLElement object) and this recrusively loops through and builds a representative array * * @param string $xml - XML document - can optionally be a SimpleXMLElement object * @return array ARRAY */ public static function toArray( $xml ) { if ( is_string( $xml ) ) $xml = new SimpleXMLElement( $xml ); $children = $xml->children(); if ( !$children ) return (string) $xml; $arr = array(); foreach ( $children as $key => $node ) { $node = modRestArrayToXML::toArray( $node ); // support for 'anon' non-associative arrays if ( $key == 'anon' ) $key = count( $arr ); // if the node is already set, put it into an array if ( isset( $arr[$key] ) ) { if ( !is_array( $arr[$key] ) || $arr[$key][0] == null ) $arr[$key] = array( $arr[$key] ); $arr[$key][] = $node; } else { $arr[$key] = $node; } } return $arr; } /** * Determine if a variable is an associative array * * @static * @param mixed $array The variable to check * @return boolean True if is an array */ public static function isAssoc( $array ) { return (is_array($array) && 0 !== count(array_diff_key($array, array_keys(array_keys($array))))); } } }