bookboon/api-php

View on GitHub
src/Client/Headers.php

Summary

Maintainability
A
1 hr
Test Coverage
D
68%
<?php

namespace Bookboon\Api\Client;


use ArrayAccess;

class Headers implements ArrayAccess
{
    const HEADER_BRANDING = 'X-Bookboon-Branding';
    const HEADER_ROTATION = 'X-Bookboon-Rotation';
    const HEADER_PREMIUM = 'X-Bookboon-PremiumLevel';
    const HEADER_CURRENCY = 'X-Bookboon-Currency';
    const HEADER_LANGUAGE = 'Accept-Language';
    const HEADER_XFF = 'X-Forwarded-For';

    /** @var array */
    private $headers = [];

    public function __construct(array $headers = [])
    {
        foreach ($headers as $k => $v) {
            $this->offsetSet($k, $v);
        }

        $this->set(static::HEADER_XFF, $this->getRemoteAddress() ?? '');
    }

    /**
     * Set or override header.
     *
     * @param string $header
     * @param string $value
     * @return void
     */
    public function set(string $header, string $value) : void
    {
        $this->headers[$header] = $value;
    }

    /**
     * Get specific header.
     *
     * @param string $header
     *
     * @return string|null false if header is not set or string value of header
     */
    public function get(string $header) : ?string
    {
        return $this->headers[$header] ?? null;
    }

    /**
     * Get all headers in CURL format.
     *
     * @return array
     */
    public function getAll() : array
    {
        $headers = [];
        foreach ($this->headers as $h => $v) {
            $headers[] = $h.': '.$v;
        }

        return $headers;
    }

    /**
     * @return array
     */
    public function getHeadersArray() : array
    {
        return $this->headers;
    }

    /**
     * Returns the remote address either directly or if set XFF header value.
     *
     * @return string|null The ip address
     */
    private function getRemoteAddress() : ?string
    {
        $hostname = null;

        if (isset($_SERVER['REMOTE_ADDR'])) {
            $hostname = filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP);

            if (false === $hostname) {
                $hostname = null;
            }
        }

        if (function_exists('apache_request_headers')) {
            $headers = apache_request_headers();

            if ($headers === false) {
                return $hostname;
            }

            foreach ($headers as $k => $v) {
                if (strcasecmp($k, 'x-forwarded-for')) {
                    continue;
                }

                $hostname = explode(',', $v);
                $hostname = trim($hostname[0]);
                break;
            }
        }

        return $hostname;
    }

    /**
     * Whether a offset exists
     * @link https://php.net/manual/en/arrayaccess.offsetexists.php
     * @param mixed $offset <p>
     * An offset to check for.
     * </p>
     * @return bool true on success or false on failure.
     * </p>
     * <p>
     * The return value will be casted to boolean if non-boolean was returned.
     * @since 5.0.0
     */
    public function offsetExists($offset)
    {
        return isset($this->headers[strtolower($offset)]);
    }

    /**
     * Offset to retrieve
     * @link https://php.net/manual/en/arrayaccess.offsetget.php
     * @param mixed $offset <p>
     * The offset to retrieve.
     * </p>
     * @return mixed Can return all value types.
     * @since 5.0.0
     */
    public function offsetGet($offset)
    {
        return $this->headers[strtolower($offset)] ?? null;
    }

    /**
     * Offset to set
     * @link https://php.net/manual/en/arrayaccess.offsetset.php
     * @param mixed $offset <p>
     * The offset to assign the value to.
     * </p>
     * @param mixed $value <p>
     * The value to set.
     * </p>
     * @return void
     * @since 5.0.0
     */
    public function offsetSet($offset, $value)
    {
        if (is_string($offset) && $offset !== '') {
            $this->headers[strtolower($offset)] = $value;
        }
    }

    /**
     * Offset to unset
     * @link https://php.net/manual/en/arrayaccess.offsetunset.php
     * @param mixed $offset <p>
     * The offset to unset.
     * </p>
     * @return void
     * @since 5.0.0
     */
    public function offsetUnset($offset)
    {
        unset($this->headers[strtolower($offset)]);
    }
}