File: /usr/local/www/apache24/noexec/open-the-door/wp-content/plugins/trustedblogs/class.curl.php
<?php
namespace Curl;
class Curl {
const VERSION = '3.6.6';
const DEFAULT_TIMEOUT = 30;
public $curl;
public $id = null;
public $error = false;
public $error_code = 0;
public $error_message = null;
public $curl_error = false;
public $curl_error_code = 0;
public $curl_error_message = null;
public $http_error = false;
public $http_status_code = 0;
public $http_error_message = null;
public $base_url = null;
public $url = null;
public $request_headers = null;
public $response_headers = null;
public $raw_response_headers = '';
public $response = null;
public $raw_response = null;
public $before_send_function = null;
public $download_complete_function = null;
private $success_function = null;
private $error_function = null;
private $complete_function = null;
private $cookies = array();
private $headers = array();
private $options = array();
private $json_decoder = null;
private $json_pattern = '/^(?:application|text)\/(?:[a-z]+(?:[\.-][0-9a-z]+){0,}[\+\.]|x-)?json(?:-[a-z]+)?/i';
private $xml_pattern = '~^(?:text/|application/(?:atom\+|rss\+)?)xml~i';
/**
* Construct
*
* @access public
*
* @param $base_url
*
* @throws \ErrorException
*/
public function __construct( $base_url = null ) {
if ( ! extension_loaded( 'curl' ) ) {
throw new \ErrorException( 'cURL library is not loaded' );
}
$this->curl = curl_init();
$this->id = 1;
$this->setDefaultUserAgent();
$this->setDefaultJsonDecoder();
$this->setDefaultTimeout();
$this->setOpt( CURLINFO_HEADER_OUT, true );
$this->setOpt( CURLOPT_HEADERFUNCTION, array( $this, 'headerCallback' ) );
$this->setOpt( CURLOPT_RETURNTRANSFER, true );
$this->headers = new CaseInsensitiveArray();
$this->setURL( $base_url );
}
/**
* Before Send
*
* @access public
*
* @param $callback
*/
public function beforeSend( $callback ) {
$this->before_send_function = $callback;
}
/**
* Build Post Data
*
* @access public
*
* @param $data
*
* @return array|string
*/
public function buildPostData( $data ) {
if ( is_array( $data ) ) {
if ( self::is_array_multidim( $data ) ) {
if ( isset( $this->headers['Content-Type'] ) &&
preg_match( $this->json_pattern, $this->headers['Content-Type'] )
) {
$json_str = json_encode( $data );
if ( ! ( $json_str === false ) ) {
$data = $json_str;
}
} else {
$data = self::http_build_multi_query( $data );
}
} else {
$binary_data = false;
foreach ( $data as $key => $value ) {
// Fix "Notice: Array to string conversion" when $value in
// curl_setopt($ch, CURLOPT_POSTFIELDS, $value) is an array
// that contains an empty array.
if ( is_array( $value ) && empty( $value ) ) {
$data[ $key ] = '';
// Fix "curl_setopt(): The usage of the @filename API for
// file uploading is deprecated. Please use the CURLFile
// class instead".
} elseif ( is_string( $value ) && strpos( $value, '@' ) === 0 ) {
$binary_data = true;
if ( class_exists( 'CURLFile' ) ) {
$data[ $key ] = new \CURLFile( substr( $value, 1 ) );
}
} elseif ( $value instanceof \CURLFile ) {
$binary_data = true;
}
}
if ( ! $binary_data ) {
if ( isset( $this->headers['Content-Type'] ) &&
preg_match( $this->json_pattern, $this->headers['Content-Type'] )
) {
$json_str = json_encode( $data );
if ( ! ( $json_str === false ) ) {
$data = $json_str;
}
} else {
$data = http_build_query( $data, '', '&' );
}
}
}
}
return $data;
}
/**
* Call
*
* @access public
*/
public function call() {
$args = func_get_args();
$function = array_shift( $args );
if ( is_callable( $function ) ) {
array_unshift( $args, $this );
call_user_func_array( $function, $args );
}
}
/**
* Close
*
* @access public
*/
public function close() {
if ( is_resource( $this->curl ) ) {
curl_close( $this->curl );
}
$this->options = null;
$this->json_decoder = null;
}
/**
* Complete
*
* @access public
*
* @param $callback
*/
public function complete( $callback ) {
$this->complete_function = $callback;
}
/**
* Progress
*
* @access public
*
* @param $callback
*/
public function progress( $callback ) {
$this->setOpt( CURLOPT_PROGRESSFUNCTION, $callback );
$this->setOpt( CURLOPT_NOPROGRESS, false );
}
/**
* Delete
*
* @access public
*
* @param $url
* @param $query_parameters
* @param $data
*
* @return string
*/
public function delete( $url, $query_parameters = array(), $data = array() ) {
if ( is_array( $url ) ) {
$data = $query_parameters;
$query_parameters = $url;
$url = $this->base_url;
}
$this->setURL( $url, $query_parameters );
$this->setOpt( CURLOPT_CUSTOMREQUEST, 'DELETE' );
$this->setOpt( CURLOPT_POSTFIELDS, $this->buildPostData( $data ) );
return $this->exec();
}
/**
* Download Complete
*
* @access public
*
* @param $fh
*/
public function downloadComplete( $fh ) {
if ( ! $this->error && $this->download_complete_function ) {
rewind( $fh );
$this->call( $this->download_complete_function, $fh );
$this->download_complete_function = null;
}
if ( is_resource( $fh ) ) {
fclose( $fh );
}
// Fix "PHP Notice: Use of undefined constant STDOUT" when reading the
// PHP script from stdin. Using null causes "Warning: curl_setopt():
// supplied argument is not a valid File-Handle resource".
if ( ! defined( 'STDOUT' ) ) {
define( 'STDOUT', fopen( 'php://stdout', 'w' ) );
}
// Reset CURLOPT_FILE with STDOUT to avoid: "curl_exec(): CURLOPT_FILE
// resource has gone away, resetting to default".
$this->setOpt( CURLOPT_FILE, STDOUT );
// Reset CURLOPT_RETURNTRANSFER to tell cURL to return subsequent
// responses as the return value of curl_exec(). Without this,
// curl_exec() will revert to returning boolean values.
$this->setOpt( CURLOPT_RETURNTRANSFER, true );
}
/**
* Download
*
* @access public
*
* @param $url
* @param $mixed_filename
*
* @return boolean
*/
public function download( $url, $mixed_filename ) {
if ( is_callable( $mixed_filename ) ) {
$this->download_complete_function = $mixed_filename;
$fh = tmpfile();
} else {
$filename = $mixed_filename;
$fh = fopen( $filename, 'wb' );
}
$this->setOpt( CURLOPT_FILE, $fh );
$this->get( $url );
$this->downloadComplete( $fh );
return ! $this->error;
}
/**
* Error
*
* @access public
*
* @param $callback
*/
public function error( $callback ) {
$this->error_function = $callback;
}
/**
* Exec
*
* @access public
*
* @param $ch
*
* @return string
*/
public function exec( $ch = null ) {
if ( ! ( $ch === null ) ) {
$this->raw_response = curl_multi_getcontent( $ch );
} else {
$this->call( $this->before_send_function );
$this->raw_response = curl_exec( $this->curl );
$this->curl_error_code = curl_errno( $this->curl );
}
$this->curl_error_message = curl_error( $this->curl );
$this->curl_error = ! ( $this->curl_error_code === 0 );
$this->http_status_code = curl_getinfo( $this->curl, CURLINFO_HTTP_CODE );
$this->http_error = in_array( floor( $this->http_status_code / 100 ), array( 4, 5 ) );
$this->error = $this->curl_error || $this->http_error;
$this->error_code = $this->error ? ( $this->curl_error ? $this->curl_error_code : $this->http_status_code ) : 0;
$this->request_headers = $this->parseRequestHeaders( curl_getinfo( $this->curl, CURLINFO_HEADER_OUT ) );
$this->response_headers = $this->parseResponseHeaders( $this->raw_response_headers );
list( $this->response, $this->raw_response ) = $this->parseResponse( $this->response_headers, $this->raw_response );
$this->http_error_message = '';
if ( $this->error ) {
if ( isset( $this->response_headers['Status-Line'] ) ) {
$this->http_error_message = $this->response_headers['Status-Line'];
}
}
$this->error_message = $this->curl_error ? $this->curl_error_message : $this->http_error_message;
if ( ! $this->error ) {
$this->call( $this->success_function );
} else {
$this->call( $this->error_function );
}
$this->call( $this->complete_function );
return $this->response;
}
/**
* Get
*
* @access public
*
* @param $url
* @param $data
*
* @return string
*/
public function get( $url, $data = array() ) {
if ( is_array( $url ) ) {
$data = $url;
$url = $this->base_url;
}
$this->setURL( $url, $data );
$this->setOpt( CURLOPT_CUSTOMREQUEST, 'GET' );
$this->setOpt( CURLOPT_HTTPGET, true );
return $this->exec();
}
/**
* Get Opt
*
* @access public
*
* @param $option
*
* @return mixed
*/
public function getOpt( $option ) {
return $this->options[ $option ];
}
/**
* Head
*
* @access public
*
* @param $url
* @param $data
*
* @return string
*/
public function head( $url, $data = array() ) {
if ( is_array( $url ) ) {
$data = $url;
$url = $this->base_url;
}
$this->setURL( $url, $data );
$this->setOpt( CURLOPT_CUSTOMREQUEST, 'HEAD' );
$this->setOpt( CURLOPT_NOBODY, true );
return $this->exec();
}
/**
* Header Callback
*
* @access public
*
* @param $ch
* @param $header
*
* @return integer
*/
public function headerCallback( $ch, $header ) {
$this->raw_response_headers .= $header;
return strlen( $header );
}
/**
* Options
*
* @access public
*
* @param $url
* @param $data
*
* @return string
*/
public function options( $url, $data = array() ) {
if ( is_array( $url ) ) {
$data = $url;
$url = $this->base_url;
}
$this->setURL( $url, $data );
$this->unsetHeader( 'Content-Length' );
$this->setOpt( CURLOPT_CUSTOMREQUEST, 'OPTIONS' );
return $this->exec();
}
/**
* Patch
*
* @access public
*
* @param $url
* @param $data
*
* @return string
*/
public function patch( $url, $data = array() ) {
if ( is_array( $url ) ) {
$data = $url;
$url = $this->base_url;
}
$this->setURL( $url );
$this->unsetHeader( 'Content-Length' );
$this->setOpt( CURLOPT_CUSTOMREQUEST, 'PATCH' );
$this->setOpt( CURLOPT_POSTFIELDS, $data );
return $this->exec();
}
/**
* Post
*
* @access public
*
* @param $url
* @param $data
*
* @return string
*/
public function post( $url, $data = array() ) {
if ( is_array( $url ) ) {
$data = $url;
$url = $this->base_url;
}
if ( is_array( $data ) && empty( $data ) ) {
$this->unsetHeader( 'Content-Length' );
}
$this->setURL( $url );
$this->setOpt( CURLOPT_CUSTOMREQUEST, 'POST' );
$this->setOpt( CURLOPT_POST, true );
$this->setOpt( CURLOPT_POSTFIELDS, $this->buildPostData( $data ) );
return $this->exec();
}
/**
* Put
*
* @access public
*
* @param $url
* @param $data
*
* @return string
*/
public function put( $url, $data = array() ) {
if ( is_array( $url ) ) {
$data = $url;
$url = $this->base_url;
}
$this->setURL( $url );
$this->setOpt( CURLOPT_CUSTOMREQUEST, 'PUT' );
$put_data = $this->buildPostData( $data );
if ( empty( $this->options[ CURLOPT_INFILE ] ) && empty( $this->options[ CURLOPT_INFILESIZE ] ) ) {
$this->setHeader( 'Content-Length', strlen( $put_data ) );
}
$this->setOpt( CURLOPT_POSTFIELDS, $put_data );
return $this->exec();
}
/**
* Set Basic Authentication
*
* @access public
*
* @param $username
* @param $password
*/
public function setBasicAuthentication( $username, $password = '' ) {
$this->setOpt( CURLOPT_HTTPAUTH, CURLAUTH_BASIC );
$this->setOpt( CURLOPT_USERPWD, $username . ':' . $password );
}
/**
* Set Digest Authentication
*
* @access public
*
* @param $username
* @param $password
*/
public function setDigestAuthentication( $username, $password = '' ) {
$this->setOpt( CURLOPT_HTTPAUTH, CURLAUTH_DIGEST );
$this->setOpt( CURLOPT_USERPWD, $username . ':' . $password );
}
/**
* Set Cookie
*
* @access public
*
* @param $key
* @param $value
*/
public function setCookie( $key, $value ) {
$this->cookies[ $key ] = $value;
$this->setOpt( CURLOPT_COOKIE, str_replace( ' ', '%20', urldecode( http_build_query( $this->cookies, '', '; ' ) ) ) );
}
/**
* Set Port
*
* @access public
*
* @param $port
*/
public function setPort( $port ) {
$this->setOpt( CURLOPT_PORT, intval( $port ) );
}
/**
* Set Connect Timeout
*
* @access public
*
* @param $seconds
*/
public function setConnectTimeout( $seconds ) {
$this->setOpt( CURLOPT_CONNECTTIMEOUT, $seconds );
}
/**
* Set Cookie File
*
* @access public
*
* @param $cookie_file
*/
public function setCookieFile( $cookie_file ) {
$this->setOpt( CURLOPT_COOKIEFILE, $cookie_file );
}
/**
* Set Cookie Jar
*
* @access public
*
* @param $cookie_jar
*/
public function setCookieJar( $cookie_jar ) {
$this->setOpt( CURLOPT_COOKIEJAR, $cookie_jar );
}
/**
* Set Default JSON Decoder
*
* @access public
*/
public function setDefaultJsonDecoder() {
$this->json_decoder = function ( $response ) {
$json_obj = json_decode( $response, false );
if ( ! ( $json_obj === null ) ) {
$response = $json_obj;
}
return $response;
};
}
/**
* Set Default Timeout
*
* @access public
*/
public function setDefaultTimeout() {
$this->setTimeout( self::DEFAULT_TIMEOUT );
}
/**
* Set Default User Agent
*
* @access public
*/
public function setDefaultUserAgent() {
$user_agent = 'PHP-Curl-Class/' . self::VERSION . ' (+https://github.com/php-curl-class/php-curl-class)';
$user_agent .= ' PHP/' . PHP_VERSION;
$curl_version = curl_version();
$user_agent .= ' curl/' . $curl_version['version'];
$this->setUserAgent( $user_agent );
}
/**
* Set Header
*
* @access public
*
* @param $key
* @param $value
*
* @return string
*/
public function setHeader( $key, $value ) {
$this->headers[ $key ] = $value;
$headers = array();
foreach ( $this->headers as $key => $value ) {
$headers[ $key ] = $value;
}
$this->setOpt( CURLOPT_HTTPHEADER, array_map( function ( $value, $key ) {
return $key . ': ' . $value;
}, $headers, array_keys( $headers ) ) );
}
/**
* Set JSON Decoder
*
* @access public
*
* @param $function
*/
public function setJsonDecoder( $function ) {
if ( is_callable( $function ) ) {
$this->json_decoder = $function;
}
}
/**
* Set Opt
*
* @access public
*
* @param $option
* @param $value
*
* @return boolean
*/
public function setOpt( $option, $value ) {
$required_options = array(
CURLINFO_HEADER_OUT => 'CURLINFO_HEADER_OUT',
CURLOPT_RETURNTRANSFER => 'CURLOPT_RETURNTRANSFER',
);
if ( in_array( $option, array_keys( $required_options ), true ) && ! ( $value === true ) ) {
trigger_error( $required_options[ $option ] . ' is a required option', E_USER_WARNING );
}
$this->options[ $option ] = $value;
return curl_setopt( $this->curl, $option, $value );
}
/**
* Set Referer
*
* @access public
*
* @param $referer
*/
public function setReferer( $referer ) {
$this->setReferrer( $referer );
}
/**
* Set Referrer
*
* @access public
*
* @param $referrer
*/
public function setReferrer( $referrer ) {
$this->setOpt( CURLOPT_REFERER, $referrer );
}
/**
* Set Timeout
*
* @access public
*
* @param $seconds
*/
public function setTimeout( $seconds ) {
$this->setOpt( CURLOPT_TIMEOUT, $seconds );
}
/**
* Set Url
*
* @access public
*
* @param $url
* @param $data
*/
public function setURL( $url, $data = array() ) {
$this->base_url = $url;
$this->url = $this->buildURL( $url, $data );
$this->setOpt( CURLOPT_URL, $this->url );
}
/**
* Set User Agent
*
* @access public
*
* @param $user_agent
*/
public function setUserAgent( $user_agent ) {
$this->setOpt( CURLOPT_USERAGENT, $user_agent );
}
/**
* Success
*
* @access public
*
* @param $callback
*/
public function success( $callback ) {
$this->success_function = $callback;
}
/**
* Unset Header
*
* @access public
*
* @param $key
*/
public function unsetHeader( $key ) {
$this->setHeader( $key, '' );
unset( $this->headers[ $key ] );
}
/**
* Verbose
*
* @access public
*
* @param $on
*/
public function verbose( $on = true ) {
$this->setOpt( CURLOPT_VERBOSE, $on );
}
/**
* Destruct
*
* @access public
*/
public function __destruct() {
$this->close();
}
/**
* Build Url
*
* @access private
*
* @param $url
* @param $data
*
* @return string
*/
private function buildURL( $url, $data = array() ) {
return $url . ( empty( $data ) ? '' : '?' . http_build_query( $data ) );
}
/**
* Parse Headers
*
* @access private
*
* @param $raw_headers
*
* @return array
*/
private function parseHeaders( $raw_headers ) {
$raw_headers = preg_split( '/\r\n/', $raw_headers, null, PREG_SPLIT_NO_EMPTY );
$http_headers = new CaseInsensitiveArray();
$raw_headers_count = count( $raw_headers );
for ( $i = 1; $i < $raw_headers_count; $i ++ ) {
list( $key, $value ) = explode( ':', $raw_headers[ $i ], 2 );
$key = trim( $key );
$value = trim( $value );
// Use isset() as array_key_exists() and ArrayAccess are not compatible.
if ( isset( $http_headers[ $key ] ) ) {
$http_headers[ $key ] .= ',' . $value;
} else {
$http_headers[ $key ] = $value;
}
}
return array( isset( $raw_headers['0'] ) ? $raw_headers['0'] : '', $http_headers );
}
/**
* Parse Request Headers
*
* @access private
*
* @param $raw_headers
*
* @return array
*/
private function parseRequestHeaders( $raw_headers ) {
$request_headers = new CaseInsensitiveArray();
list( $first_line, $headers ) = $this->parseHeaders( $raw_headers );
$request_headers['Request-Line'] = $first_line;
foreach ( $headers as $key => $value ) {
$request_headers[ $key ] = $value;
}
return $request_headers;
}
/**
* Parse Response
*
* @access private
*
* @param $response_headers
* @param $raw_response
*
* @return array
*/
private function parseResponse( $response_headers, $raw_response ) {
$response = $raw_response;
if ( isset( $response_headers['Content-Type'] ) ) {
if ( preg_match( $this->json_pattern, $response_headers['Content-Type'] ) ) {
$json_decoder = $this->json_decoder;
if ( is_callable( $json_decoder ) ) {
$response = $json_decoder( $response );
}
} elseif ( preg_match( $this->xml_pattern, $response_headers['Content-Type'] ) ) {
$xml_obj = @simplexml_load_string( $response );
if ( ! ( $xml_obj === false ) ) {
$response = $xml_obj;
}
}
}
return array( $response, $raw_response );
}
/**
* Parse Response Headers
*
* @access private
*
* @param $raw_response_headers
*
* @return array
*/
private function parseResponseHeaders( $raw_response_headers ) {
$response_header_array = explode( "\r\n\r\n", $raw_response_headers );
$response_header = '';
for ( $i = count( $response_header_array ) - 1; $i >= 0; $i -- ) {
if ( stripos( $response_header_array[ $i ], 'HTTP/' ) === 0 ) {
$response_header = $response_header_array[ $i ];
break;
}
}
$response_headers = new CaseInsensitiveArray();
list( $first_line, $headers ) = $this->parseHeaders( $response_header );
$response_headers['Status-Line'] = $first_line;
foreach ( $headers as $key => $value ) {
$response_headers[ $key ] = $value;
}
return $response_headers;
}
/**
* Http Build Multi Query
*
* @access public
*
* @param $data
* @param $key
*
* @return string
*/
public static function http_build_multi_query( $data, $key = null ) {
$query = array();
if ( empty( $data ) ) {
return $key . '=';
}
$is_array_assoc = self::is_array_assoc( $data );
foreach ( $data as $k => $value ) {
if ( is_string( $value ) || is_numeric( $value ) ) {
$brackets = $is_array_assoc ? '[' . $k . ']' : '[]';
$query[] = urlencode( $key === null ? $k : $key . $brackets ) . '=' . rawurlencode( $value );
} elseif ( is_array( $value ) ) {
$nested = $key === null ? $k : $key . '[' . $k . ']';
$query[] = self::http_build_multi_query( $value, $nested );
}
}
return implode( '&', $query );
}
/**
* Is Array Assoc
*
* @access public
*
* @param $array
*
* @return boolean
*/
public static function is_array_assoc( $array ) {
return (bool) count( array_filter( array_keys( $array ), 'is_string' ) );
}
/**
* Is Array Multidim
*
* @access public
*
* @param $array
*
* @return boolean
*/
public static function is_array_multidim( $array ) {
if ( ! is_array( $array ) ) {
return false;
}
return (bool) count( array_filter( $array, 'is_array' ) );
}
}
class CaseInsensitiveArray implements \ArrayAccess, \Countable, \Iterator {
private $container = array();
public function offsetSet( $offset, $value ) {
if ( $offset === null ) {
$this->container[] = $value;
} else {
$index = array_search( strtolower( $offset ), array_keys( array_change_key_case( $this->container, CASE_LOWER ) ) );
if ( ! ( $index === false ) ) {
$keys = array_keys( $this->container );
unset( $this->container[ $keys[ $index ] ] );
}
$this->container[ $offset ] = $value;
}
}
public function offsetExists( $offset ) {
return array_key_exists( strtolower( $offset ), array_change_key_case( $this->container, CASE_LOWER ) );
}
public function offsetUnset( $offset ) {
unset( $this->container[ $offset ] );
}
public function offsetGet( $offset ) {
$index = array_search( strtolower( $offset ), array_keys( array_change_key_case( $this->container, CASE_LOWER ) ) );
if ( $index === false ) {
return null;
}
$values = array_values( $this->container );
return $values[ $index ];
}
public function count() {
return count( $this->container );
}
public function current() {
return current( $this->container );
}
public function next() {
return next( $this->container );
}
public function key() {
return key( $this->container );
}
public function valid() {
return ! ( $this->current() === false );
}
public function rewind() {
reset( $this->container );
}
}