<commit_before><?php

namespace ManaPHP\Http;

use ManaPHP\Component;
use ManaPHP\Http\Cookies\Exception as CookiesException;

/**
 * Class ManaPHP\Http\Cookies
 *
 * @package cookies
 *
 * @property-read \ManaPHP\Security\CryptInterface $crypt
 */
class Cookies extends Component implements CookiesInterface
{
    /**
     * @var array
     */
    protected $_cookies = [];

    /**
     * @var string
     */
    protected $_key;

    /**
     * Cookies constructor.
     *
     * @param string|array $options
     */
    public function __construct($options = [])
    {
        if (is_string($options)) {
            $options = ['key' => $options];
        }

        if (isset($options['key'])) {
            $this->_key = $options['key'];
        }
    }

    public function saveInstanceState()
    {
        return true;
    }

    public function restoreInstanceState($data)
    {
        $this->_cookies = [];
    }

    /**
     * Sets a cookie to be sent at the end of the request
     *
     * @param string $name
     * @param mixed  $value
     * @param int    $expire
     * @param string $path
     * @param string $domain
     * @param bool   $secure
     * @param bool   $httpOnly
     *
     * @return static
     */
    public function set($name, $value, $expire = 0, $path = null, $domain = null, $secure = false, $httpOnly = true)
    {
        if ($expire > 0) {
            $current = time();
            if ($expire < $current) {
                $expire += $current;
            }
        }

        if ($name[0] === '!') {
            $name = (string)substr($name, 1);
            $value = $this->_encrypt($name, $value);
        }

        $this->_cookies[$name] = [
            'name' => $name,
            'value' => $value,
            'expire' => $expire,
            'path' => $path,
            'domain' => $domain,
            'secure' => $secure,
            'httpOnly' => $httpOnly
        ];

        $_COOKIE[$name] = $value;

        return $this;
    }

    /**
     * @param string $name
     * @param string $value
     *
     * @return string
     * @throws \ManaPHP\Http\Cookies\Exception
     */
    protected function _decrypt($name, $value)
    {
        if ($this->_key === null) {
            $this->_key = $this->crypt->getDerivedKey('cookies');
        }

        $data = $this->crypt->decrypt(base64_decode($value), $this->_key . $name);
        $json = json_decode($data, true);
        if (!is_array($json) || !isset($json['value'])) {
            throw new CookiesException('cookie value is corrupted');
        }

        return $json['value'];
    }

    /**
     * @param string $name
     * @param string $value
     *
     * @return string
     */
    protected function _encrypt($name, $value)
    {
        if ($this->_key === null) {
            $this->_key = $this->crypt->getDerivedKey('cookies');
        }

        return base64_encode($this->crypt->encrypt(json_encode(['value' => $value]), $this->_key . $name));
    }

    /**
     * Gets a cookie
     *
     * @param string $name
     * @param string $default
     *
     * @return mixed|null
     * @throws \ManaPHP\Http\Cookies\Exception
     */
    public function get($name, $default = null)
    {
        if ($name[0] === '!') {
            $name = (string)substr($name, 1);
            if (isset($_COOKIE[$name])) {
                return $this->_decrypt($name, $_COOKIE[$name]);
            }
        } else {
            if (isset($_COOKIE[$name])) {
                return $_COOKIE[$name];
            }
        }

        return $default;
    }

    /**
     * Check if a cookie is defined in the bag or exists in the $_COOKIE<commit_msg>Modified   ManaPHP/Http/Cookies.php<commit_after><?php

namespace ManaPHP\Http;

use ManaPHP\Component;
use ManaPHP\Http\Cookies\Exception as CookiesException;

/**
 * Class ManaPHP\Http\Cookies
 *
 * @package cookies
 *
 * @property-read \ManaPHP\Security\CryptInterface $crypt
 */
class Cookies extends Component implements CookiesInterface
{
    /**
     * @var array
     */
    protected $_cookies = [];

    /**
     * @var string
     */
    protected $_key;

    /**
     * Cookies constructor.
     *
     * @param string|array $options
     */
    public function __construct($options = [])
    {
        if (is_string($options)) {
            $options = ['key' => $options];
        }

        if (isset($options['key'])) {
            $this->_key = $options['key'];
        }
    }

    public function saveInstanceState()
    {
        return true;
    }

    public function restoreInstanceState($data)
    {
        $this->_cookies = [];
    }

    /**
     * Sets a cookie to be sent at the end of the request
     *
     * @param string $name
     * @param mixed  $value
     * @param int    $expire
     * @param string $path
     * @param string $domain
     * @param bool   $secure
     * @param bool   $httpOnly
     *
     * @return static
     */
    public function set($name, $value, $expire = 0, $path = null, $domain = null, $secure = false, $httpOnly = true)
    {
        if ($expire > 0) {
            $current = time();
            if ($expire < $current) {
                $expire += $current;
            }
        }

        if ($name[0] === '!') {
            $name = (string)substr($name, 1);
            $value = $this->_encrypt($name, $value);
        }

        $this->_cookies[$name] = [
            'name' => $name,
            'value' => $value,
            'expire' => $expire,
            'path' => $path,
            'domain' => $domain,
            'secure' => $secure,
            'httpOnly' => $httpOnly
        ];

        $_COOKIE[$name] = $value;

        return $this;
    }

    /**
     * @param string $name
     * @param string $value
     *
     * @return string
     * @throws \ManaPHP\Http\Cookies\Exception
     */
    protected function _decrypt($name, $value)
    {
        if ($this->_key === null) {
            $this->_key = $this->crypt->getDerivedKey('cookies');
        }

        $data = $this->crypt->decrypt(base64_decode($value), $this->_key . $name);
        $json = json_decode($data, true);
        if (!is_array($json) || !isset($json['value'])) {
            throw new CookiesException('cookie value is corrupted');
        }

        return $json['value'];
    }

    /**
     * @param string $name
     * @param string $value
     *
     * @return string
     */
    protected function _encrypt($name, $value)
    {
        if ($this->_key === null) {
            $this->_key = $this->crypt->getDerivedKey('cookies');
        }

        return base64_encode($this->crypt->encrypt(json_encode(['value' => $value]), $this->_key . $name));
    }

    /**
     * Gets a cookie
     *
     * @param string $name
     * @param string $default
     *
     * @return mixed|null
     * @throws \ManaPHP\Http\Cookies\Exception
     */
    public function get($name, $default = null)
    {
        if ($name[0] === '!') {
            $name = (string)substr($name, 1);
            if (isset($_COOKIE[$name])) {
                return $this->_decrypt($name, $_COOKIE[$name]);
            }
        } elseif (isset($_COOKIE[$name])) {
            return $_COOKIE[$name];
        }

        return $default;
    }

    /**
     * Check if a cookie is defined in the bag or exists in the $_COOKIE
{'fraction_non_alphanumeric': 0.15650156910901897, 'fraction_numerical': 0.0027288852503752218, 'mean_word_length': 1.7535687453042825, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 61, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4477474', 'n_tokens_mistral': 2291, 'n_tokens_neox': 2203, 'n_words': 499}