class/DataProvider/Curl.php
<?php
/**
* This file is part of Internship Inventory.
*
* Internship Inventory is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* Internship Inventory is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License version 3
* along with Internship Inventory. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2011-2018 Appalachian State University
*/
namespace Intern\DataProvider;
class Curl {
const DEFAULT_TIMEOUT = 30;
public $curl;
public $id = null;
public $url = null;
public $requestHeaders = null;
public $responseHeaders = null;
public $rawResponseHeaders = '';
public $responseCookies = array();
public $rawResponse = null;
public $response = 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 $httpErrorMesasge = null;
public $options = array();
/**
* 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->initialize($base_url);
}
/**
* Close
*
* @access public
*/
public function close()
{
if (is_resource($this->curl)) {
curl_close($this->curl);
}
}
/**
* Exec
*
* @access public
* @param $ch
*
* @return mixed Returns the raw response.
*/
public function exec($ch = null)
{
if ($ch === null) {
$this->rawResponse = curl_exec($this->curl);
$this->curlErrorCode = curl_errno($this->curl);
$this->curlErrorMessage = curl_error($this->curl);
} else {
$this->rawResponse = curl_multi_getcontent($ch);
$this->curlErrorMessage = curl_error($ch);
}
$this->curlError = $this->curlErrorCode !== 0;
// Include additional error code information in error message when possible.
if ($this->curlError && function_exists('curl_strerror')) {
$this->curlErrorMessage =
curl_strerror($this->curlErrorCode) . (
empty($this->curlErrorMessage) ? '' : ': ' . $this->curlErrorMessage
);
}
$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->getInfo(CURLINFO_HEADER_OUT);
}
/**
* We could be fancy about this and add parsing functions to look at the response headers
* and parse the response on the found Content-Type header. But we'll just return
* the raw response for now.
*
*$this->responseHeaders = $this->parseResponseHeaders($this->rawResponseHeaders);
*$this->response = $this->parseResponse($this->responseHeaders, $this->rawResponse);
*/
$this->response = $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;
// Reset nobody setting possibly set from a HEAD request.
$this->setOpt(CURLOPT_NOBODY, false);
return $this->response;
}
/**
* 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;
}
/**
* Get Opt
*
* @access public
* @param $option
*
* @return mixed
*/
public function getOpt($option) {
return isset($this->options[$option]) ? $this->options[$option] : null;
}
/**
* Set Url
*
* @access public
* @param $url
* @param $mixed_data
*/
public function setUrl($url, $mixed_data = '') {
$this->url = $this->buildUrl($url, $mixed_data);
$this->setOpt(CURLOPT_URL, $this->url);
}
/**
* Build Url
*
* @access private
* @param $url
* @param $mixed_data
*
* @return string
*/
private function buildUrl($url, $mixed_data = '') {
$query_string = '';
if (!empty($mixed_data)) {
$query_mark = strpos($url, '?') > 0 ? '&' : '?';
if (is_string($mixed_data)) {
$query_string .= $query_mark . $mixed_data;
} elseif (is_array($mixed_data)) {
$query_string .= $query_mark . http_build_query($mixed_data, '', '&');
}
}
return $url . $query_string;
}
/**
* Get Info
*
* @access public
* @param $opt
*
* @return mixed
*/
public function getInfo($opt = null){
$args = array();
$args[] = $this->curl;
if (func_num_args()) {
$args[] = $opt;
}
return call_user_func_array('curl_getinfo', $args);
}
/**
* Initialize
*
* @access private
* @param $base_url
*/
private function initialize($base_url = null) {
$this->id = uniqid('', true);
// $this->setDefaultUserAgent();
// $this->setDefaultTimeout();
$this->setOpt(CURLINFO_HEADER_OUT, true);
$this->setOpt(CURLOPT_SSL_VERIFYPEER, false);
$this->setOpt(CURLOPT_SSL_VERIFYHOST, false);
$this->setOpt(CURLOPT_RETURNTRANSFER, true);
$this->setUrl($base_url);
}
}