Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I wrote a PHP connector that will allow me to communicate with a REST API using PHP.

The class was little over 1500 lines of code, it was difficult to manage it. It was a nightmare to even look at it as you can probably imagine. My intention was to better my code to a point where I can share it on GitHub and help me become a better OOP programmer. The original class can be foubd in my part 1 question.

After taking the feedback in consideration and doing research on "Single Responsibility Principle" I revised my class and broke the huge class into 11 different smaller classes.

Now, I would like to ask this question as a part 2 which extends my first question and like to see if I can get the experts to review my code and tell me how can I make it even better as I like to learn from my mistakes.

Due to the characters restrictions here, I will post a single class here and the rest can be downloaded from this URL.

Please tell me what else can be done to better my code?

Any idea that will help me improve it?

<?php

namespace ICWS;

/**
 * ApiCallsHandler
 *
 * @package ICWS
 */
class ApiCallsHandler {

    protected $cookiesFile = 'icwsCookies';
    protected $timeOutMS = '5000';
    protected $url = null;
    protected $uri = null;
    protected $method = null;
    protected $params = null;
    protected $header = null;
    protected $debug = null;
    protected $httpCode = 0;
    protected $caCertLocation= null;
    protected $filename = null;

    public function __construct($url, $debug = false, $caCertLocation = null){

        $this->url = $url;
        $this->caCertLocation = $caCertLocation;
        $this->debug = $debug;
    }

    /**
    * Initialize the cURL session
    *
    * @return curl_init session
    */  
    private function initializeSession()
    {

        $url = $this->url . '/' . $this->uri;


        $ch = curl_init();

        if(
               ($this->method == 'POST' || $this->method == 'PUT') 
            && $this->params
        ){
            $jsonString = json_encode($this->params);
            curl_setopt( $ch, CURLOPT_POSTFIELDS, $jsonString );

        }

        if($this->method == 'POST'){
            curl_setopt($ch, CURLOPT_POST, true);
        } elseif( $this->method == 'PUT'){
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
        } else {
            if ($this->params){
                $url = sprintf("%s?%s", $url, http_build_query($this->params, '', '&'));
            }
        }   

        //echo $url .'<br>';

        //set the URL
        curl_setopt($ch, CURLOPT_URL, $url);

        //disable the use of cached connection
        curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);

        //return the respond from the API
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        //return the HEADER respond from the API
        curl_setopt($ch, CURLOPT_HEADER, true);

        //add custom headers
        if(!empty($this->header)){
            curl_setopt($ch, CURLOPT_HTTPHEADER, $this->header);
        }

        //add the cookie value
        curl_setopt($ch, CURLOPT_COOKIEJAR, $this->cookiesFile); // write
        curl_setopt($ch, CURLOPT_COOKIEFILE, $this->cookiesFile); // read

        curl_setopt($ch, CURLOPT_TIMEOUT_MS, $this->timeOutMS);


        //enable SSL
        if( !empty($this->caCertLocation)){
            curl_setopt($ch, CURLOPT_CAINFO, $this->caCertLocation);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, true);
        }

        if( $this->debug){

            $requestFile = $this->getFileName();

            $file = fopen($requestFile, 'w');
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
            curl_setopt($ch, CURLOPT_VERBOSE, true);    
            curl_setopt($ch, CURLOPT_STDERR, $file);

            echo '<br>================================= START REQUEST =================================<br>';
            echo 'Method: ' . $this->method .'<br>';
            echo 'url: ' . $url .'<br>';
            echo 'Headers<br>';
            echo '<pre>';
            print_r($this->header);
            echo '</pre>';

            print 'Body<br><pre>' . json_encode( $this->params, JSON_PRETTY_PRINT) .'</pre><br>';
            echo '================================= END REQUEST =================================<br><br>';
        }


        return $ch;
    }

    public function getHttpCode(){
        return $this->httpCode;
    }

    /**
    * Calls any Method that does not require a sessionId using a GET method
    *
    * @param string $uri 
    * @param array $params
    * @return array or false
    */
    public function getData($uri, $params = false){

        $httpCode = 0;
        $data = (object) $this->processRequest('GET', $uri, $params, $httpCode);

        if( $this->debug){
            new showVar($data, false, 'HTTP Code: ' . $httpCode);
        }

        return $data;
    }

    /**
    * returns a the filename to output the request to
    *
    * @return string
    */      
    private function getFileName(){

        $requestFile = null;
        if(empty($this->filename)){
            $requestFile = rand(1, 100) . '.txt';
        } else {
            if(!strpos($this->filename, '.')){
                $requestFile = $this->filename . '.txt';
            }
        }
        return $requestFile;
    }

    /**
    * Handle the cURL call to the API
    *
    * @throws ApiException
    * @param string $method GET/POST/PUT
    * @param string $uri 
    * @param array $data
    * @param array &$httpCode
    * @param string $filename
    * @return array
    */  
    public function processRequest( $method, $uri, $params = false, array $header = array(), $filename = null)
    {
        $this->method = $method;
        $this->uri = $uri;
        $this->params = $params;
        $this->header = $header;
        $this->filename = $filename;
        $ch = $this->initializeSession();

        //send the request to the API
        $respond = curl_exec($ch);

        //read the http code returned from ICWS
        $this->httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        if($this->debug){
            new showVar(curl_getinfo($ch));
        }

        //throw cURL exception
        if($respond === false){
            $errorNo = curl_errno($this->ch);
            $errorMessage = curl_error($this->ch);

            throw new ApiException($errorMessage, $errorNo);
        }   

        list($header, $body) = explode("\r\n\r\n", $respond, 2);

        if($uri == 'connection'){
            $this->_handleReceivedHeaders($header);
        }

        //convert respond to an array
        $result = json_decode($body);

        //throw API exception
        if(  $this->_hasAPIError($result) ){
            $errorCode = 0;
            if(isset($result->errorCode)){
                $errorCode = $result->errorCode;
            }
            throw new ApiException($result->message, $errorCode);
        }

        return $result;
    }


    /**
    * Checks if the API return an error
    *
    * @param array $result
    * @return boolean
    */

    private function _hasAPIError($result){
        if(    isset($result->errorId) && !empty($result->errorId)
            && isset($result->message) && !empty($result->message)
        ){          
            return true;
        }

        return false;       
    }


    /**
    * Get the cookie HTTP headers and set them as cookie
    *
    * @param array $httpRespond
    * @return void
    */  
    private function _handleReceivedHeaders($httpRespond){

        $header = $this->_http_parse_headers($httpRespond);
        //new showVar($header); 
        //set the ININ-ICWS-CSRF-Token value
        if( isset($header['ININ-ICWS-CSRF-Token']) ){
            $this->ININ_ICWS_CSRF_Token = $header['ININ-ICWS-CSRF-Token'];
            $_SESSION['ININ-ICWS-CSRF-Token'] = $this->ININ_ICWS_CSRF_Token;
        }       

    }


    /**
     * convert cURL header into an array
     *
     * @param string $raw_headers
     * @return array
     */ 
    private function _http_parse_headers($raw_headers)
    {
        $headers = array();
        $key = '';

        foreach(explode("\n", $raw_headers) as $i => $h)
        {
            $h = explode(':', $h, 2);

            if (isset($h[1])){
                if (!isset($headers[$h[0]])){
                    $headers[$h[0]] = trim($h[1]);
                } elseif (is_array($headers[$h[0]])){
                    $headers[$h[0]] = array_merge($headers[$h[0]], array(trim($h[1]))); // [+]
                } else {
                    $headers[$h[0]] = array_merge(array($headers[$h[0]]), array(trim($h[1]))); // [+]
                }

                $key = $h[0];
            } else {
                if (substr($h[0], 0, 1) == "\t"){
                    $headers[$key] .= "\r\n\t".trim($h[0]);
                } elseif (!$key){
                    $headers[0] = trim($h[0]);trim($h[0]);
                }
            }
        }

        return $headers;
    }

}
share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.