<?php

/**
 * @package Sami's cURL class
 * @version $Id: HttpCurlRequest.php v.2.0 2019-11-15 16:09:00 $
 * @author Samuil Banti
 * @copyright (C) 2019 - Samuil Banti
 * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
**/
class HttpCurlRequest
{
    /**
     * The URL that the request will be sent to.
     *
     * @var string
     */
    private $url;

    /**
     * Any files that may be attached to the request.
     *
     * @var array
     */
    private $files = [];

    /**
     * Conatins the request headers.
     *
     * @var array
     */
    private $headers = [];

    /**
     * The cookies included in the request.
     *
     * @var array
     */
    private $cookies = [];

    /**
     * All parameters that schould be sent via the request.
     *
     * @var array
     */
    private $parameters = [];

    /**
     * Set the URL that will be requested.
     *
     * @param string $url - The URL as a string.
     * @return object - Instance of the class itself.
     */
    public function setUrl(string $url)
    {
        $this->url = $url;
        return $this;
    }

    /**
     * Set any headers if required.
     *
     * @param array $headers - The keys should contain the names of the headers.
     * @return object - Instance of the class itself.
     */
    public function setHeaders(array $headers)
    {
        foreach ($headers as $key => $value) {
            $this->headers[] = "{$key}: {$value}";
        }
        return $this;
    }

    /**
     * Set the request parameters.
     *
     * @param array $parameters - The keys should contain the names of the parameters.
     * @return object - Instance of the class itself.
     */
    public function setParameters(array $parameters)
    {
        $this->parameters = $parameters;
        return $this;
    }

    /**
     * Set any files to be sent via the request.
     *
     * @param array $files - The paths should contain the file names. The values should contain the paths to the files.
     * @return object - Instance of the class itself.
     */
    public function setFiles (array $files)
    {
        foreach ($files as $fileName => $filePath) {
            $this->files[$fileName] = curl_file_create($filePath);
        }
        return $this;
    }

    /**
     * Set any cookies related to the request.
     *
     * @param array $cookies - The cookie names should be described in the array keys.
     * @return object - Instance of the class itself.
     */
    public function setCookies(array $cookies)
    {
        foreach($cookies as $cookieName => $cookieValue) {
            $this->cookies[] = "{$cookieValue}={$cookieValue}";
        }
    }

    /**
     * Send GET HTTP request.
     *
     * @return mixed - The remote server response.
     */
    public function get()
    {
        return $this->sendRequest('GET');
    }

    /**
     * Send POST HTTP request.
     *
     * @return mixed - The remote server response.
     */
    public function post()
    {
        return $this->sendRequest('POST');
    }

    /**
     * Send PATCH HTTP request.
     *
     * @return mixed - The remote server response.
     */
    public function patch()
    {
        return $this->sendRequest('PATCH');
    }

    /**
     * Send DELETE HTTP request.
     *
     * @return mixed - The remote server response.
     */
    public function delete()
    {
        return $this->sendRequest('DELETE');
    }

    /**
     * Send any HTTP request.
     *
     * @return mixed - The remote server response.
     */
    private function sendRequest($httpVerb)
    {
        $curlParameters = array_merge($this->files, $this->parameters);

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->url);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $httpVerb);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers);
        curl_setopt($ch, CURLOPT_COOKIE, implode(';', $this->cookies));
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($curlParameters));
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		$response = curl_exec($ch);
		curl_close ($ch);
		return $response;
    }
}