Variables.php 3.93 KB
Newer Older
Indra Raja's avatar
Indra Raja committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
<?php
/**
 * Zend Framework (http://framework.zend.com/)
 *
 * @link      http://github.com/zendframework/zf2 for the canonical source repository
 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd New BSD License
 */

namespace Zend\View;

use ArrayObject;

/**
 * Class for Zend\View\Renderer\PhpRenderer to help enforce private constructs.
 *
 * @todo       Allow specifying string names for manager, filter chain, variables
 * @todo       Move escaping into variables object
 * @todo       Move strict variables into variables object
 */
class Variables extends ArrayObject
{
    /**
     * Strict variables flag; when on, undefined variables accessed in the view
     * scripts will trigger notices
     *
     * @var bool
     */
    protected $strictVars = false;

    /**
     * Constructor
     *
     * @param  array $variables
     * @param  array $options
     */
    public function __construct(array $variables = [], array $options = [])
    {
        parent::__construct(
            $variables,
            ArrayObject::ARRAY_AS_PROPS,
            'ArrayIterator'
        );

        $this->setOptions($options);
    }

    /**
     * Configure object
     *
     * @param  array $options
     * @return Variables
     */
    public function setOptions(array $options)
    {
        foreach ($options as $key => $value) {
            switch (strtolower($key)) {
                case 'strict_vars':
                    $this->setStrictVars($value);
                    break;
                default:
                    // Unknown options are considered variables
                    $this[$key] = $value;
                    break;
            }
        }
        return $this;
    }

    /**
     * Set status of "strict vars" flag
     *
     * @param  bool $flag
     * @return Variables
     */
    public function setStrictVars($flag)
    {
        $this->strictVars = (bool) $flag;
        return $this;
    }

    /**
     * Are we operating with strict variables?
     *
     * @return bool
     */
    public function isStrict()
    {
        return $this->strictVars;
    }

    /**
     * Assign many values at once
     *
     * @param  array|object $spec
     * @return Variables
     * @throws Exception\InvalidArgumentException
     */
    public function assign($spec)
    {
        if (is_object($spec)) {
            if (method_exists($spec, 'toArray')) {
                $spec = $spec->toArray();
            } else {
                $spec = (array) $spec;
            }
        }
        if (! is_array($spec)) {
            throw new Exception\InvalidArgumentException(sprintf(
                'assign() expects either an array or an object as an argument; received "%s"',
                gettype($spec)
            ));
        }
        foreach ($spec as $key => $value) {
            $this[$key] = $value;
        }

        return $this;
    }

    /**
     * Get the variable value
     *
     * If the value has not been defined, a null value will be returned; if
     * strict vars on in place, a notice will also be raised.
     *
     * Otherwise, returns _escaped_ version of the value.
     *
     * @param  mixed $key
     * @return mixed
     */
    public function offsetGet($key)
    {
        if (! $this->offsetExists($key)) {
            if ($this->isStrict()) {
                trigger_error(sprintf(
                    'View variable "%s" does not exist',
                    $key
                ), E_USER_NOTICE);
            }
            return;
        }

        $return = parent::offsetGet($key);

        // If we have a closure/functor, invoke it, and return its return value
        if (is_object($return) && is_callable($return)) {
            $return = call_user_func($return);
        }

        return $return;
    }

    /**
     * Clear all variables
     *
     * @return void
     */
    public function clear()
    {
        $this->exchangeArray([]);
    }
}