namespace PhalconPlus\Curl;
use PhalconPlus\Curl\Curl;
class Request
{
/**
* ENCODING_* constants,
* used for specifying encoding options
*/
const ENCODING_QUERY = 0;
const ENCODING_JSON = 1;
const ENCODING_RAW = 2;
/**
* Allowed methods => allows postdata
*
* @var array
*/
public static methods = [
"get" : false,
"head" : false,
"post" : true,
"put" : true,
"patch" : true,
"delete" : true,
"options" : false
];
/**
* The URL the request is sent to.
*
* @var string
*/
private url = "";
/**
* The headers sent with the request.
*
* @var array
*/
private headers = [];
/**
* The cookies sent with the request.
*
* @var array
*/
private cookies = [];
/**
* POST data sent with the request.
*
* @var mixed
*/
private data = [];
/**
* Optional cURL options.
*
* @var array
*/
private options = [];
/**
* Username to authenticate the request of cURL.
*
* @var string
*/
private user = "";
/**
* Password to authenticate the request of cURL.
*
* @var string
*/
private pass = "";
/**
* The type of processing to perform to encode the POST data
*
* @var int
*/
private encoding = self::ENCODING_QUERY;
/*
* Http method
*
* @var string
*/
private method = "";
/**
* Curl client
*
* @var
*/
private curl = null;
/**
* Constructor
*
*/
public function __construct( curl)
{
let this->curl = curl;
}
/**
* Set the HTTP method of the request.
*
*/
public function setMethod(string method)
{
let method = strtolower(method);
if (!array_key_exists(method, self::methods)) {
throw new \InvalidArgumentException("Method [".method." not a valid HTTP method.");
}
if (this->data && !self::methods[method]) {
throw new \LogicException("Request has POST data, but tried changing HTTP method to one that does not allow POST data");
}
let this->method = method;
return this;
}
/**
* Get the HTTP method of the request.
*
* @return string
*/
public function getMethod()
{
return this->method;
}
/**
* Set the URL of the request.
*
* @param string $url
*/
public function setUrl(string url)
{
let this->url = $url;
return this;
}
/**
* Get the URL of the request.
*
* @return string
*/
public function getUrl()
{
return this->url;
}
/**
* Set a specific header to be sent with the request.
*
* @param string $key Can also be a string in "foo: bar" format
* @param mixed $value
* @param boolean $preserveCase
*/
public function setHeader(var key, var value = null, bool preserveCase = false)
{
if (value === null) {
var parts = explode(":", value, 2);
let key = parts[0];
let value = parts[1];
}
if (!preserveCase) {
let key = strtolower(key);
}
let key = trim(key);
let this->headers[key] = trim(value);
return this;
}
/**
* Set the headers to be sent with the request.
*
* Pass an associative array - e.g. ['Content-Type' => 'application/json']
* and the correct header formatting - e.g. 'Content-Type: application/json'
* will be done for you when the request is sent.
*
* @param array $headers
*/
public function setHeaders(array headers)
{
let this->headers = [];
var key, val;
for key, val in headers {
this->setHeader(key, val);
}
return this;
}
/**
* Get a specific header from the request.
*
* @param string $key
*
* @return mixed
*/
public function getHeader(string key)
{
let key = strtolower(key);
return isset(this->headers[key]) ? this->headers[key] : null;
}
/**
* Get the headers to be sent with the request.
*
* @return array
*/
public function getHeaders()
{
return this->headers;
}
/**
* Set a cookie.
*
* @param string $key
* @param string $value
*/
public function setCookie(string key, string value)
{
let this->cookies[key] = value;
this->updateCookieHeader();
return this;
}
/**
* Replace the request's cookies.
*
* @param array $cookies
*/
public function setCookies(array cookies)
{
let this->cookies = cookies;
this->updateCookieHeader();
return this;
}
/**
* Read the request cookies and set the cookie header.
*
* @return void
*/
private function updateCookieHeader()
{
var strings = [], key, val;
for key, val in this->cookies {
let strings[] = key."=".val;
}
this->setHeader("cookie", implode("; ", strings));
}
/**
* Get a specific cookie from the request.
*
* @param string $key
*
* @return string|null
*/
public function getCookie(string key)
{
return isset(this->cookies[key]) ? this->cookies[key] : null;
}
/**
* Get all the request's cookies.
*
* @return string[]
*/
public function getCookies()
{
return this->cookies;
}
/**
* Format the headers to an array of 'key: val' which can be passed to
* curl_setopt.
*
* @return array
*/
public function formatHeaders()
{
var headers = [], key, val;
for key, val in this->headers {
if (is_string(key)) {
let headers[] = key . ": " . val;
} else {
let headers[] = val;
}
}
return headers;
}
/**
* Set the POST data to be sent with the request.
*
* @param mixed $data
*/
public function setData(var data)
{
if (data && !self::methods[this->method]) {
throw new \InvalidArgumentException("HTTP method [".this->method."] does not allow POST data.");
}
let this->data = data;
return this;
}
/**
* Check whether the request has any data.
*
* @return boolean
*/
public function hasData()
{
return self::methods[this->method] && (bool) this->encodeData();
}
/**
* Get the POST data to be sent with the request.
*
* @return mixed
*/
public function getData()
{
return this->data;
}
/**
* Set the encoding to use on the POST data, and (possibly) associated Content-Type headers
*
* @param int $encoding a Request::ENCODING_* constant
*/
public function setEncoding(int encoding)
{
if (
encoding !== self::ENCODING_QUERY &&
encoding !== self::ENCODING_JSON &&
encoding !== self::ENCODING_RAW
) {
throw new \InvalidArgumentException("Encoding [".encoding."] not a known Request::ENCODING_* constant");
}
if (encoding === self::ENCODING_JSON && !this->getHeader("Content-Type")) {
this->setHeader("Content-Type", "application/json");
}
let this->encoding = encoding;
return this;
}
/**
* Get the current encoding which will be used on the POST data
*
* @return int a Request::ENCODING_* constant
*/
public function getEncoding()
{
return this->encoding;
}
/**
* Encode the POST data as a string.
*
* @return string
*/
public function encodeData()
{
var msg = "";
switch (this->encoding) {
case self::ENCODING_JSON:
return json_encode(this->data);
case self::ENCODING_QUERY:
return !is_null(this->data) ? http_build_query(this->data) : "";
case self::ENCODING_RAW:
return this->data;
default:
let msg = "Encoding [".this->encoding."] not a known Request::ENCODING_* constant";
throw new \UnexpectedValueException(msg);
}
}
/**
* Set a specific curl option for the request.
*
* @param string $key
* @param mixed $value
*/
public function setOption(string key, var value)
{
let this->options[key] = value;
return this;
}
/**
* Set the cURL options for the request.
*
* @param array $options
*/
public function setOptions(array options)
{
let this->options = options;
return this;
}
/**
* Get a specific curl option from the request.
*
* @param string $key
*
* @return mixed
*/
public function getOption(string key)
{
return isset(this->options[key]) ? this->options[key] : null;
}
/**
* Get the cURL options for the request.
*
* @return array
*/
public function getOptions()
{
return this->options;
}
/**
* Set the HTTP basic username and password.
*
* @param string $user
* @param string $pass
*
* @return string
*/
public function auth(string user, string pass)
{
let this->user = user;
let this->pass = pass;
return this;
}
/**
* Set an username to authenticate the request of curl.
*
* @param string $user
*
* @return static
*/
public function setUser(string user)
{
let this->user = user;
return this;
}
/**
* Set a password to authenticate the request of curl.
*
* @param string $pass
*
* @return static
*/
public function setPass(string pass)
{
let this->pass = pass;
return this;
}
/**
* If username and password is set, returns a string of 'username:password'.
* If not, returns null.
*
* @return string|null
*/
public function getUserAndPass()
{
if (this->user) {
return this->user . ":" . this->pass;
}
return null;
}
/**
* Whether the request is JSON or not.
*
* @return boolean
*/
public function isJson()
{
return this->encoding === self::ENCODING_JSON;
}
/**
* Send the request.
*
* @return Response
*/
public function send()
{
return this->curl->sendRequest(this);
}
}