| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282 | 
							- <?php
 
- namespace App\Services\Common;
 
- class CurlService
 
- {
 
-     const VERSION = '5.1.0';
 
-     const DEFAULT_TIMEOUT = 30;
 
-     public static $RFC2616 = array(
 
-         // RFC2616: "any CHAR except CTLs or separators".
 
-         // CHAR           = <any US-ASCII character (octets 0 - 127)>
 
-         // CTL            = <any US-ASCII control character
 
-         //                  (octets 0 - 31) and DEL (127)>
 
-         // separators     = "(" | ")" | "<" | ">" | "@"
 
-         //                | "," | ";" | ":" | "\" | <">
 
-         //                | "/" | "[" | "]" | "?" | "="
 
-         //                | "{" | "}" | SP | HT
 
-         // SP             = <US-ASCII SP, space (32)>
 
-         // HT             = <US-ASCII HT, horizontal-tab (9)>
 
-         // <">            = <US-ASCII double-quote mark (34)>
 
-         '!', '#', '$', '%', '&', "'", '*', '+', '-', '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
 
-         'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
 
-         'Y', 'Z', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
 
-         'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '|', '~',
 
-     );
 
-     public static $RFC6265 = array(
 
-         // RFC6265: "US-ASCII characters excluding CTLs, whitespace DQUOTE, comma, semicolon, and backslash".
 
-         // %x21
 
-         '!',
 
-         // %x23-2B
 
-         '#', '$', '%', '&', "'", '(', ')', '*', '+',
 
-         // %x2D-3A
 
-         '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':',
 
-         // %x3C-5B
 
-         '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
 
-         'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[',
 
-         // %x5D-7E
 
-         ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
 
-         's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
 
-     );
 
-     public $curl;
 
-     public $id = null;
 
-     public $error = false;
 
-     public $errorCode = 0;
 
-     public $errorMessage = null;
 
-     public $curlError = false;
 
-     public $curlErrorCode = 0;
 
-     public $curlErrorMessage = null;
 
-     public $httpError = false;
 
-     public $httpStatusCode = 0;
 
-     public $httpErrorMessage = null;
 
-     public $baseUrl = null;
 
-     public $url = null;
 
-     public $requestHeaders = null;
 
-     public $responseHeaders = null;
 
-     public $rawResponseHeaders = '';
 
-     public $response = null;
 
-     public $rawResponse = null;
 
-     public $beforeSendFunction = null;
 
-     public $downloadCompleteFunction = null;
 
-     public $successFunction = null;
 
-     public $errorFunction = null;
 
-     public $completeFunction = null;
 
-     public $fileHandle = null;
 
-     private $cookies = array();
 
-     private $responseCookies = array();
 
-     private $headers = array();
 
-     private $options = array();
 
-     private $jsonDecoder = null;
 
-     private $jsonPattern = '/^(?:application|text)\/(?:[a-z]+(?:[\.-][0-9a-z]+){0,}[\+\.]|x-)?json(?:-[a-z]+)?/i';
 
-     private $xmlDecoder = null;
 
-     private $xmlPattern = '~^(?:text/|application/(?:atom\+|rss\+)?)xml~i';
 
-     private $defaultDecoder = null;
 
-     private static $deferredProperties = array(
 
-         'effectiveUrl',
 
-         'totalTime',
 
-     );
 
-     /**
 
-      * 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->setDefaultXmlDecoder();
 
-         $this->setDefaultTimeout();
 
-         $this->setOpt(CURLINFO_HEADER_OUT, true);
 
-         $this->setOpt(CURLOPT_HEADERFUNCTION, array($this, 'headerCallback'));
 
-         $this->setOpt(CURLOPT_RETURNTRANSFER, true);
 
-         $this->headers = new CaseInsensitiveArrayService();
 
-         $this->setURL($base_url);
 
-         $this->rfc2616 = array_fill_keys(self::$RFC2616, true);
 
-         $this->rfc6265 = array_fill_keys(self::$RFC6265, true);
 
-     }
 
-     /**
 
-      * Before Send
 
-      *
 
-      * @access public
 
-      * @param  $callback
 
-      */
 
-     public function beforeSend($callback)
 
-     {
 
-         $this->beforeSendFunction = $callback;
 
-     }
 
-     /**
 
-      * Build Post Data
 
-      *
 
-      * @access public
 
-      * @param  $data
 
-      *
 
-      * @return array|string
 
-      */
 
-     public function buildPostData($data)
 
-     {
 
-         $binary_data = false;
 
-         if (is_array($data)) {
 
-             // Return JSON-encoded string when the request's content-type is JSON.
 
-             if (isset($this->headers['Content-Type']) &&
 
-                 preg_match($this->jsonPattern, $this->headers['Content-Type'])) {
 
-                 $json_str = json_encode($data);
 
-                 if (!($json_str === false)) {
 
-                     $data = $json_str;
 
-                 }
 
-             } else {
 
-                 // Manually build a single-dimensional array from a multi-dimensional array as using curl_setopt($ch,
 
-                 // CURLOPT_POSTFIELDS, $data) doesn't correctly handle multi-dimensional arrays when files are
 
-                 // referenced.
 
-                 if (self::is_array_multidim($data)) {
 
-                     $data = self::array_flatten_multidim($data);
 
-                 }
 
-                 // Modify array values to ensure any referenced files are properly handled depending on the support of
 
-                 // the @filename API or CURLFile usage. This also fixes the warning "curl_setopt(): The usage of the
 
-                 // @filename API for file uploading is deprecated. Please use the CURLFile class instead". Ignore
 
-                 // non-file values prefixed with the @ character.
 
-                 foreach ($data as $key => $value) {
 
-                     if (is_string($value) && strpos($value, '@') === 0 && is_file(substr($value, 1))) {
 
-                         $binary_data = true;
 
-                         if (class_exists('CURLFile')) {
 
-                             $data[$key] = new \CURLFile(substr($value, 1));
 
-                         }
 
-                     } elseif ($value instanceof \CURLFile) {
 
-                         $binary_data = true;
 
-                     }
 
-                 }
 
-             }
 
-         }
 
-         if (!$binary_data && (is_array($data) || is_object($data))) {
 
-             $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->jsonDecoder = null;
 
-         $this->xmlDecoder = null;
 
-     }
 
-     /**
 
-      * Complete
 
-      *
 
-      * @access public
 
-      * @param  $callback
 
-      */
 
-     public function complete($callback)
 
-     {
 
-         $this->completeFunction = $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->baseUrl;
 
-         }
 
-         $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->downloadCompleteFunction) {
 
-             rewind($fh);
 
-             $this->call($this->downloadCompleteFunction, $fh);
 
-             $this->downloadCompleteFunction = 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->downloadCompleteFunction = $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->errorFunction = $callback;
 
-     }
 
-     /**
 
-      * Exec
 
-      *
 
-      * @access public
 
-      * @param  $ch
 
-      *
 
-      * @return mixed Returns the value provided by parseResponse.
 
-      */
 
-     public function exec($ch = null)
 
-     {
 
-         $this->responseCookies = array();
 
-         if ($ch === null) {
 
-             $this->call($this->beforeSendFunction);
 
-             $this->rawResponse = curl_exec($this->curl);
 
-             $this->curlErrorCode = curl_errno($this->curl);
 
-         } else {
 
-             $this->rawResponse = curl_multi_getcontent($ch);
 
-         }
 
-         $this->curlErrorMessage = curl_error($this->curl);
 
-         $this->curlError = !($this->curlErrorCode === 0);
 
-         $this->httpStatusCode = $this->getInfo(CURLINFO_HTTP_CODE);
 
-         $this->httpError = in_array(floor($this->httpStatusCode / 100), array(4, 5));
 
-         $this->error = $this->curlError || $this->httpError;
 
-         $this->errorCode = $this->error ? ($this->curlError ? $this->curlErrorCode : $this->httpStatusCode) : 0;
 
-         // NOTE: CURLINFO_HEADER_OUT set to true is required for requestHeaders
 
-         // to not be empty (e.g. $curl->setOpt(CURLINFO_HEADER_OUT, true);).
 
-         if ($this->getOpt(CURLINFO_HEADER_OUT) === true) {
 
-             $this->requestHeaders = $this->parseRequestHeaders($this->getInfo(CURLINFO_HEADER_OUT));
 
-         }
 
-         $this->responseHeaders = $this->parseResponseHeaders($this->rawResponseHeaders);
 
-         $this->response = $this->parseResponse($this->responseHeaders, $this->rawResponse);
 
-         $this->httpErrorMessage = '';
 
-         if ($this->error) {
 
-             if (isset($this->responseHeaders['Status-Line'])) {
 
-                 $this->httpErrorMessage = $this->responseHeaders['Status-Line'];
 
-             }
 
-         }
 
-         $this->errorMessage = $this->curlError ? $this->curlErrorMessage : $this->httpErrorMessage;
 
-         if (!$this->error) {
 
-             $this->call($this->successFunction);
 
-         } else {
 
-             $this->call($this->errorFunction);
 
-         }
 
-         $this->call($this->completeFunction);
 
-         return $this->response;
 
-     }
 
-     /**
 
-      * Get
 
-      *
 
-      * @access public
 
-      * @param  $url
 
-      * @param  $data
 
-      *
 
-      * @return mixed Returns the value provided by exec.
 
-      */
 
-     public function get($url, $data = array())
 
-     {
 
-         if (is_array($url)) {
 
-             $data = $url;
 
-             $url = $this->baseUrl;
 
-         }
 
-         $this->setURL($url, $data);
 
-         $this->setOpt(CURLOPT_CUSTOMREQUEST, 'GET');
 
-         $this->setOpt(CURLOPT_HTTPGET, true);
 
-         return $this->exec();
 
-     }
 
-     /**
 
-      * Get Info
 
-      *
 
-      * @access public
 
-      * @param  $opt
 
-      */
 
-     public function getInfo($opt)
 
-     {
 
-         return curl_getinfo($this->curl, $opt);
 
-     }
 
-     /**
 
-      * 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->baseUrl;
 
-         }
 
-         $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)
 
-     {
 
-         if (preg_match('/^Set-Cookie:\s*([^=]+)=([^;]+)/mi', $header, $cookie) === 1) {
 
-             $this->responseCookies[$cookie[1]] = trim($cookie[2], " \n\r\t\0\x0B");
 
-         }
 
-         $this->rawResponseHeaders .= $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->baseUrl;
 
-         }
 
-         $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->baseUrl;
 
-         }
 
-         if (is_array($data) && empty($data)) {
 
-             $this->unsetHeader('Content-Length');
 
-         }
 
-         $this->setURL($url);
 
-         $this->setOpt(CURLOPT_CUSTOMREQUEST, 'PATCH');
 
-         $this->setOpt(CURLOPT_POSTFIELDS, $this->buildPostData($data));
 
-         return $this->exec();
 
-     }
 
-     /**
 
-      * Post
 
-      *
 
-      * @access public
 
-      * @param  $url
 
-      * @param  $data
 
-      * @param  $follow_303_with_post If true, will cause 303 redirections to be followed using
 
-      *     a POST request (default: false).
 
-      *     Notes:
 
-      *       - Redirections are only followed if the CURLOPT_FOLLOWLOCATION option is set to true.
 
-      *       - According to the HTTP specs (see [1]), a 303 redirection should be followed using
 
-      *         the GET method. 301 and 302 must not.
 
-      *       - In order to force a 303 redirection to be performed using the same method, the
 
-      *         underlying cURL object must be set in a special state (the CURLOPT_CURSTOMREQUEST
 
-      *         option must be set to the method to use after the redirection). Due to a limitation
 
-      *         of the cURL extension of PHP < 5.5.11 ([2], [3]) and of HHVM, it is not possible
 
-      *         to reset this option. Using these PHP engines, it is therefore impossible to
 
-      *         restore this behavior on an existing php-curl-class Curl object.
 
-      *
 
-      * @return string
 
-      *
 
-      * [1] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.2
 
-      * [2] https://github.com/php/php-src/pull/531
 
-      * [3] http://php.net/ChangeLog-5.php#5.5.11
 
-      */
 
-     public function post($url, $data = array(), $follow_303_with_post = false)
 
-     {
 
-         if (is_array($url)) {
 
-             $follow_303_with_post = (bool)$data;
 
-             $data = $url;
 
-             $url = $this->baseUrl;
 
-         }
 
-         $this->setURL($url);
 
-         if ($follow_303_with_post) {
 
-             $this->setOpt(CURLOPT_CUSTOMREQUEST, 'POST');
 
-         } else {
 
-             if (isset($this->options[CURLOPT_CUSTOMREQUEST])) {
 
-                 if ((version_compare(PHP_VERSION, '5.5.11') < 0) || defined('HHVM_VERSION')) {
 
-                     trigger_error('Due to technical limitations of PHP <= 5.5.11 and HHVM, it is not possible to '
 
-                         . 'perform a post-redirect-get request using a php-curl-class Curl object that '
 
-                         . 'has already been used to perform other types of requests. Either use a new '
 
-                         . 'php-curl-class Curl object or upgrade your PHP engine.',
 
-                         E_USER_ERROR);
 
-                 } else {
 
-                     $this->setOpt(CURLOPT_CUSTOMREQUEST, null);
 
-                 }
 
-             }
 
-         }
 
-         $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->baseUrl;
 
-         }
 
-         $this->setURL($url);
 
-         $this->setOpt(CURLOPT_CUSTOMREQUEST, 'PUT');
 
-         $put_data = $this->buildPostData($data);
 
-         if (empty($this->options[CURLOPT_INFILE]) && empty($this->options[CURLOPT_INFILESIZE])) {
 
-             if (is_string($put_data)) {
 
-                 $this->setHeader('Content-Length', strlen($put_data));
 
-             }
 
-         }
 
-         if (!empty($put_data)) {
 
-             $this->setOpt(CURLOPT_POSTFIELDS, $put_data);
 
-         }
 
-         return $this->exec();
 
-     }
 
-     /**
 
-      * Search
 
-      *
 
-      * @access public
 
-      * @param  $url
 
-      * @param  $data
 
-      *
 
-      * @return string
 
-      */
 
-     public function search($url, $data = array())
 
-     {
 
-         if (is_array($url)) {
 
-             $data = $url;
 
-             $url = $this->baseUrl;
 
-         }
 
-         $this->setURL($url);
 
-         $this->setOpt(CURLOPT_CUSTOMREQUEST, 'SEARCH');
 
-         $put_data = $this->buildPostData($data);
 
-         if (empty($this->options[CURLOPT_INFILE]) && empty($this->options[CURLOPT_INFILESIZE])) {
 
-             if (is_string($put_data)) {
 
-                 $this->setHeader('Content-Length', strlen($put_data));
 
-             }
 
-         }
 
-         if (!empty($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)
 
-     {
 
-         $name_chars = array();
 
-         foreach (str_split($key) as $name_char) {
 
-             if (!isset($this->rfc2616[$name_char])) {
 
-                 $name_chars[] = rawurlencode($name_char);
 
-             } else {
 
-                 $name_chars[] = $name_char;
 
-             }
 
-         }
 
-         $value_chars = array();
 
-         foreach (str_split($value) as $value_char) {
 
-             if (!isset($this->rfc6265[$value_char])) {
 
-                 $value_chars[] = rawurlencode($value_char);
 
-             } else {
 
-                 $value_chars[] = $value_char;
 
-             }
 
-         }
 
-         $this->cookies[implode('', $name_chars)] = implode('', $value_chars);
 
-         $this->setOpt(CURLOPT_COOKIE, implode('; ', array_map(function($k, $v) {
 
-             return $k . '=' . $v;
 
-         }, array_keys($this->cookies), array_values($this->cookies))));
 
-     }
 
-     /**
 
-      * Get cookie.
 
-      *
 
-      * @access public
 
-      * @param  $key
 
-      * @return mixed
 
-      */
 
-     public function getCookie($key)
 
-     {
 
-         return $this->getResponseCookie($key);
 
-     }
 
-     /**
 
-      * Get response cookie.
 
-      *
 
-      * @access public
 
-      * @param  $key
 
-      * @return mixed
 
-      */
 
-     public function getResponseCookie($key)
 
-     {
 
-         return isset($this->responseCookies[$key]) ? $this->responseCookies[$key] : null;
 
-     }
 
-     /**
 
-      * Get response cookies.
 
-      *
 
-      * @access public
 
-      * @return array
 
-      */
 
-     public function getResponseCookies()
 
-     {
 
-         return $this->responseCookies;
 
-     }
 
-     /**
 
-      * 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 String
 
-      *
 
-      * @access public
 
-      * @param  $string
 
-      */
 
-     public function setCookieString($string)
 
-     {
 
-         return $this->setOpt(CURLOPT_COOKIE, $string);
 
-     }
 
-     /**
 
-      * 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
 
-      * @param  $assoc
 
-      * @param  $depth
 
-      * @param  $options
 
-      */
 
-     public function setDefaultJsonDecoder()
 
-     {
 
-         $args = func_get_args();
 
-         $this->jsonDecoder = function($response) use ($args) {
 
-             array_unshift($args, $response);
 
-             // Call json_decode() without the $options parameter in PHP
 
-             // versions less than 5.4.0 as the $options parameter was added in
 
-             // PHP version 5.4.0.
 
-             if (version_compare(PHP_VERSION, '5.4.0', '<')) {
 
-                 $args = array_slice($args, 0, 3);
 
-             }
 
-             $json_obj = call_user_func_array('json_decode', $args);
 
-             if (!($json_obj === null)) {
 
-                 $response = $json_obj;
 
-             }
 
-             return $response;
 
-         };
 
-     }
 
-     /**
 
-      * Set Default XML Decoder
 
-      *
 
-      * @access public
 
-      */
 
-     public function setDefaultXmlDecoder()
 
-     {
 
-         $this->xmlDecoder = function($response) {
 
-             $xml_obj = @simplexml_load_string($response);
 
-             if (!($xml_obj === false)) {
 
-                 $response = $xml_obj;
 
-             }
 
-             return $response;
 
-         };
 
-     }
 
-     /**
 
-      * Set Default Decoder
 
-      *
 
-      * @access public
 
-      * @param  $decoder string|callable
 
-      */
 
-     public function setDefaultDecoder($decoder = 'json')
 
-     {
 
-         if (is_callable($decoder)) {
 
-             $this->defaultDecoder = $decoder;
 
-         } else {
 
-             if ($decoder === 'json') {
 
-                 $this->defaultDecoder = $this->jsonDecoder;
 
-             } elseif ($decoder === 'xml') {
 
-                 $this->defaultDecoder = $this->xmlDecoder;
 
-             }
 
-         }
 
-     }
 
-     /**
 
-      * 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
 
-      */
 
-     public function setHeader($key, $value)
 
-     {
 
-         $this->headers[$key] = $value;
 
-         $headers = array();
 
-         foreach ($this->headers as $key => $value) {
 
-             $headers[] = $key . ': ' . $value;
 
-         }
 
-         $this->setOpt(CURLOPT_HTTPHEADER, $headers);
 
-     }
 
-     /**
 
-      * Set JSON Decoder
 
-      *
 
-      * @access public
 
-      * @param  $function
 
-      */
 
-     public function setJsonDecoder($function)
 
-     {
 
-         if (is_callable($function)) {
 
-             $this->jsonDecoder = $function;
 
-         }
 
-     }
 
-     /**
 
-      * Set XML Decoder
 
-      *
 
-      * @access public
 
-      * @param  $function
 
-      */
 
-     public function setXmlDecoder($function)
 
-     {
 
-         if (is_callable($function)) {
 
-             $this->xmlDecoder = $function;
 
-         }
 
-     }
 
-     /**
 
-      * Set Opt
 
-      *
 
-      * @access public
 
-      * @param  $option
 
-      * @param  $value
 
-      *
 
-      * @return boolean
 
-      */
 
-     public function setOpt($option, $value)
 
-     {
 
-         $required_options = array(
 
-             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);
 
-         }
 
-         $success = curl_setopt($this->curl, $option, $value);
 
-         if ($success) {
 
-             $this->options[$option] = $value;
 
-         }
 
-         return $success;
 
-     }
 
-     /**
 
-      * Set Opts
 
-      *
 
-      * @access public
 
-      * @param  $options
 
-      *
 
-      * @return boolean
 
-      *   Returns true if all options were successfully set. If an option could not be successfully set, false is
 
-      *   immediately returned, ignoring any future options in the options array. Similar to curl_setopt_array().
 
-      */
 
-     public function setOpts($options)
 
-     {
 
-         foreach ($options as $option => $value) {
 
-             if (!$this->setOpt($option, $value)) {
 
-                 return false;
 
-             }
 
-         }
 
-     }
 
-     /**
 
-      * 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->baseUrl = $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->successFunction = $callback;
 
-     }
 
-     /**
 
-      * Unset Header
 
-      *
 
-      * @access public
 
-      * @param  $key
 
-      */
 
-     public function unsetHeader($key)
 
-     {
 
-         $this->setHeader($key, '');
 
-         unset($this->headers[$key]);
 
-     }
 
-     /**
 
-      * Verbose
 
-      *
 
-      * @access public
 
-      * @param  bool $on
 
-      * @param  resource $output
 
-      */
 
-     public function verbose($on = true, $output = STDERR)
 
-     {
 
-         // Turn off CURLINFO_HEADER_OUT for verbose to work. This has the side
 
-         // effect of causing Curl::requestHeaders to be empty.
 
-         if ($on) {
 
-             $this->setOpt(CURLINFO_HEADER_OUT, false);
 
-         }
 
-         $this->setOpt(CURLOPT_VERBOSE, $on);
 
-         $this->setOpt(CURLOPT_STDERR, $output);
 
-     }
 
-     /**
 
-      * Destruct
 
-      *
 
-      * @access public
 
-      */
 
-     public function __destruct()
 
-     {
 
-         $this->close();
 
-     }
 
-     public function __get($name)
 
-     {
 
-         $return = null;
 
-         if (in_array($name, self::$deferredProperties) && is_callable(array($this, $getter = '__get_' . $name))) {
 
-             $return = $this->$name = $this->$getter();
 
-         }
 
-         return $return;
 
-     }
 
-     /**
 
-      * Get Effective Url
 
-      *
 
-      * @access private
 
-      */
 
-     private function __get_effectiveUrl() {
 
-         return $this->getInfo(CURLINFO_EFFECTIVE_URL);
 
-     }
 
-     /**
 
-      * Get Total Time
 
-      *
 
-      * @access private
 
-      */
 
-     private function __get_totalTime() {
 
-         return $this->getInfo(CURLINFO_TOTAL_TIME);
 
-     }
 
-     /**
 
-      * 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 CaseInsensitiveArrayService();
 
-         $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 CaseInsensitiveArrayService();
 
-         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 mixed
 
-      *   Provided the content-type is determined to be json or xml:
 
-      *     Returns stdClass object when the default json decoder is used and the content-type is json.
 
-      *     Returns SimpleXMLElement object when the default xml decoder is used and the content-type is xml.
 
-      */
 
-     private function parseResponse($response_headers, $raw_response)
 
-     {
 
-         $response = $raw_response;
 
-         if (isset($response_headers['Content-Type'])) {
 
-             if (preg_match($this->jsonPattern, $response_headers['Content-Type'])) {
 
-                 $json_decoder = $this->jsonDecoder;
 
-                 if (is_callable($json_decoder)) {
 
-                     $response = $json_decoder($response);
 
-                 }
 
-             } elseif (preg_match($this->xmlPattern, $response_headers['Content-Type'])) {
 
-                 $xml_decoder = $this->xmlDecoder;
 
-                 if (is_callable($xml_decoder)) {
 
-                     $response = $xml_decoder($response);
 
-                 }
 
-             } else {
 
-                 $decoder = $this->defaultDecoder;
 
-                 if (is_callable($decoder)) {
 
-                     $response = $decoder($response);
 
-                 }
 
-             }
 
-         }
 
-         return $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 CaseInsensitiveArrayService();
 
-         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;
 
-     }
 
-     /**
 
-      * 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'));
 
-     }
 
-     /**
 
-      * Array Flatten Multidim
 
-      *
 
-      * @access public
 
-      * @param  $array
 
-      * @param  $prefix
 
-      *
 
-      * @return array
 
-      */
 
-     public static function array_flatten_multidim($array, $prefix = false)
 
-     {
 
-         $return = array();
 
-         if (is_array($array) || is_object($array)) {
 
-             if (empty($array)) {
 
-                 $return[$prefix] = '';
 
-             } else {
 
-                 foreach ($array as $key => $value) {
 
-                     if (is_scalar($value)) {
 
-                         if ($prefix) {
 
-                             $return[$prefix . '[' . $key . ']'] = $value;
 
-                         } else {
 
-                             $return[$key] = $value;
 
-                         }
 
-                     } else {
 
-                         if ($value instanceof \CURLFile) {
 
-                             $return[$key] = $value;
 
-                         } else {
 
-                             $return = array_merge(
 
-                                 $return, self::array_flatten_multidim(
 
-                                 $value, $prefix ? $prefix . '[' . $key . ']' : $key));
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-         } elseif ($array === null) {
 
-             $return[$prefix] = $array;
 
-         }
 
-         return $return;
 
-     }
 
- }
 
 
  |