HEX
Server: Apache/2.4.41 (Amazon) OpenSSL/1.0.2k-fips PHP/5.6.40
System: Linux ip-172-31-40-18 4.14.146-93.123.amzn1.x86_64 #1 SMP Tue Sep 24 00:45:23 UTC 2019 x86_64
User: apache (48)
PHP: 5.6.40
Disabled: NONE
Upload Files
File: /var/www/html/pmw24/app/vendor/vinceg/usps-php-api/src/USPSBase.php
<?php

namespace USPS;

/**
 * USPS Base class
 * used to perform the actual api calls.
 *
 * @since  1.0
 *
 * @author Vincent Gabriel
 */
abstract class USPSBase
{
    const LIVE_API_URL = 'http://production.shippingapis.com/ShippingAPI.dll';
    const TEST_API_URL = 'http://production.shippingapis.com/ShippingAPITest.dll';

    /**
     * @var string - the usps username provided by the usps website
     */
    protected $username = '';
    /**
     *  the error code if one exists.
     *
     * @var int
     */
    protected $errorCode = 0;
    /**
     * the error message if one exists.
     *
     * @var string
     */
    protected $errorMessage = '';
    /**
     *  the response message.
     *
     * @var string
     */
    protected $response = '';
    /**
     *  the headers returned from the call made.
     *
     * @var array
     */
    protected $headers = '';
    /**
     * The response represented as an array.
     *
     * @var array
     */
    protected $arrayResponse = [];
    /**
     * All the post fields we will add to the call.
     *
     * @var array
     */
    protected $postFields = [];
    /**
     * The api type we are about to call.
     *
     * @var string
     */
    protected $apiVersion = '';
    /**
     * @var bool - set whether we are in a test mode or not
     */
    public static $testMode = false;
    /**
     * @var array - different kind of supported api calls by this wrapper
     */
    protected $apiCodes = [
        'RateV2'                          => 'RateV2Request',
        'RateV4'                          => 'RateV4Request',
        'IntlRateV2'                      => 'IntlRateV2Request',
        'Verify'                          => 'AddressValidateRequest',
        'ZipCodeLookup'                   => 'ZipCodeLookupRequest',
        'CityStateLookup'                 => 'CityStateLookupRequest',
        'TrackV2'                         => 'TrackFieldRequest',
        'FirstClassMail'                  => 'FirstClassMailRequest',
        'SDCGetLocations'                 => 'SDCGetLocationsRequest',
        'ExpressMailLabel'                => 'ExpressMailLabelRequest',
        'PriorityMail'                    => 'PriorityMailRequest',
        'OpenDistributePriorityV2'        => 'OpenDistributePriorityV2.0Request',
        'OpenDistributePriorityV2Certify' => 'OpenDistributePriorityV2.0CertifyRequest',
        'ExpressMailIntl'                 => 'ExpressMailIntlRequest',
        'PriorityMailIntl'                => 'PriorityMailIntlRequest',
        'FirstClassMailIntl'              => 'FirstClassMailIntlRequest',
    ];
    /**
     * Default options for curl.
     */
    public static $CURL_OPTS = [
        CURLOPT_CONNECTTIMEOUT => 30,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 60,
        CURLOPT_FRESH_CONNECT  => 1,
        CURLOPT_PORT           => 443,
        CURLOPT_USERAGENT      => 'usps-php',
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_RETURNTRANSFER => true,
    ];

    /**
     * Constructor.
     *
     * @param string $username - the usps api username
     */
    public function __construct($username = '')
    {
        $this->username = $username;
    }

    /**
     * set the usps api username we are going to user.
     *
     * @param string $username - the usps api username
     */
    public function setUsername($username)
    {
        $this->username = $username;
    }

    /**
     * Return the post data fields as an array.
     *
     * @return array
     */
    public function getPostData()
    {
        $fields = ['API' => $this->apiVersion, 'XML' => $this->getXMLString()];

        return $fields;
    }

    /**
     * Set the api version we are going to use.
     *
     * @param string $version the new api version
     *
     * @return void
     */
    public function setApiVersion($version)
    {
        $this->apiVersion = $version;
    }

    /**
     * Set whether we are in a test mode or not.
     *
     * @param bool $value
     *
     * @return void
     */
    public function setTestMode($value)
    {
        self::$testMode = (bool) $value;
    }

    /**
     * Response api name.
     *
     * @return string
     */
    public function getResponseApiName()
    {
        return str_replace('Request', 'Response', $this->apiCodes[$this->apiVersion]);
    }

    /**
     * Makes an HTTP request. This method can be overriden by subclasses if
     * developers want to do fancier things or use something other than curl to
     * make the request.
     *
     * @param resource $ch Optional initialized cURL handle
     *
     * @return string the response text
     */
    protected function doRequest($ch = null)
    {
        if (!$ch) {
            $ch = curl_init();
        }

        $opts = self::$CURL_OPTS;
        $opts[CURLOPT_POSTFIELDS] = http_build_query($this->getPostData(), null, '&');
        $opts[CURLOPT_URL] = $this->getEndpoint();

        // Replace 443 with 80 if it's not secured
        if (strpos($opts[CURLOPT_URL], 'https://') === false) {
            $opts[CURLOPT_PORT] = 80;
        }

        // set options
        curl_setopt_array($ch, $opts);

        // execute
        $this->setResponse(curl_exec($ch));
        $this->setHeaders(curl_getinfo($ch));

        // fetch errors
        $this->setErrorCode(curl_errno($ch));
        $this->setErrorMessage(curl_error($ch));

        // Convert response to array
        $this->convertResponseToArray();

        // If it failed then set error code and message
        if ($this->isError()) {
            $arrayResponse = $this->getArrayResponse();

            // Find the error number
            $errorInfo = $this->getValueByKey($arrayResponse, 'Error');

            if ($errorInfo) {
                $this->setErrorCode($errorInfo['Number']);
                $this->setErrorMessage($errorInfo['Description']);
            }
        }

        // close
        curl_close($ch);

        return $this->getResponse();
    }

    public function getEndpoint()
    {
        return self::$testMode ? self::TEST_API_URL : self::LIVE_API_URL;
    }

    abstract public function getPostFields();

    /**
     * Return the xml string built that we are about to send over to the api.
     *
     * @return string
     */
    protected function getXMLString()
    {
        // Add in the defaults
        $postFields = [
            '@attributes' => ['USERID' => $this->username],
        ];

        // Add in the sub class data
        $postFields = array_merge($postFields, $this->getPostFields());

        $xml = XMLParser::createXML($this->apiCodes[$this->apiVersion], $postFields);

        return $xml->saveXML();
    }

    /**
     * Did we encounter an error?
     *
     * @return bool
     */
    public function isError()
    {
        $headers = $this->getHeaders();
        $response = $this->getArrayResponse();
        // First make sure we got a valid response
        if ($headers['http_code'] != 200) {
            return true;
        }

        // Make sure the response does not have error in it
        if (isset($response['Error'])) {
            return true;
        }

        // Check to see if we have the Error word in the response
        if (strpos($this->getResponse(), '<Error>') !== false) {
            return true;
        }

        // No error
        return false;
    }

    /**
     * Was the last call successful.
     *
     * @return bool
     */
    public function isSuccess()
    {
        return !$this->isError() ? true : false;
    }

    /**
     * Return the response represented as string.
     *
     * @return array
     */
    public function convertResponseToArray()
    {
        if ($this->getResponse()) {
            $this->setArrayResponse(XML2Array::createArray($this->getResponse()));
        }

        return $this->getArrayResponse();
    }

    /**
     * Set the array response value.
     *
     * @param array $value
     *
     * @return void
     */
    public function setArrayResponse($value)
    {
        $this->arrayResponse = $value;
    }

    /**
     * Return the array representation of the last response.
     *
     * @return array
     */
    public function getArrayResponse()
    {
        return $this->arrayResponse;
    }

    /**
     * Set the response.
     *
     * @param mixed $response The response returned from the call
     *
     * @return self
     */
    public function setResponse($response = '')
    {
        $this->response = $response;

        return $this;
    }

    /**
     * Get the response data.
     *
     * @return mixed the response data
     */
    public function getResponse()
    {
        return $this->response;
    }

    /**
     * Set the headers.
     *
     * @param array $headers the headers array
     *
     * @return self
     */
    public function setHeaders($headers = [])
    {
        $this->headers = $headers;

        return $this;
    }

    /**
     * Get the headers.
     *
     * @return array the headers returned from the call
     */
    public function getHeaders()
    {
        return $this->headers;
    }

    /**
     * Set the error code number.
     *
     * @param int $code the error code number
     *
     * @return self
     */
    public function setErrorCode($code = 0)
    {
        $this->errorCode = $code;

        return $this;
    }

    /**
     * Get the error code number.
     *
     * @return int error code number
     */
    public function getErrorCode()
    {
        return $this->errorCode;
    }

    /**
     * Set the error message.
     *
     * @param string $message the error message
     *
     * @return self
     */
    public function setErrorMessage($message = '')
    {
        $this->errorMessage = $message;

        return $this;
    }

    /**
     * Get the error code message.
     *
     * @return string error code message
     */
    public function getErrorMessage()
    {
        return $this->errorMessage;
    }

    /**
     * Find a key inside a multi dim. array.
     *
     * @param array  $array
     * @param string $key
     *
     * @return mixed
     */
    protected function getValueByKey($array, $key)
    {
        foreach ($array as $k => $each) {
            if ($k == $key) {
                return $each;
            }

            if (is_array($each)) {
                if ($return = $this->getValueByKey($each, $key)) {
                    return $return;
                }
            }
        }

        // Nothing matched
    }
}