Completed
Push — master ( 4bb447...b82aa8 )
by Vladimir
9s
created

JailedDocument::offsetUnset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
/**
4
 * @copyright 2018 Vladimir Jimenez
5
 * @license   https://github.com/stakx-io/stakx/blob/master/LICENSE.md MIT
6
 */
7
8
namespace allejo\stakx\Document;
9
10
/**
11
 * A wrapper object to only allow certain functions on the white list to be called and will redirect "jailed" function
12
 * calls to their appropriate jailed calls. This is used in order to limit which functions a user can call from
13
 * templates to prevent unexpected behavior.
14
 */
15
class JailedDocument implements \ArrayAccess, \IteratorAggregate, \JsonSerializable
16
{
17
    /** @var string[] */
18
    private $whiteListFunctions;
19
20
    /** @var string[] */
21
    private $jailedFunctions;
22
23
    /** @var TemplateReadyDocument */
24
    private $object;
25
26
    /**
27
     * JailObject constructor.
28
     *
29
     * @param TemplateReadyDocument $object             the object that will be jailed
30
     * @param array                 $whiteListFunctions a list of function names that can be called
31
     * @param array                 $jailedFunctions    a list of functions that will be redirected to another function
32
     */
33 53
    public function __construct(TemplateReadyDocument &$object, array $whiteListFunctions, array $jailedFunctions = [])
34
    {
35 53
        $this->object = &$object;
36 53
        $this->whiteListFunctions = $whiteListFunctions;
37 53
        $this->jailedFunctions = $jailedFunctions;
38 53
    }
39
40 11
    public function __call($name, $arguments)
41
    {
42
        // White listed functions will always be getter functions, so somehow get the name of a possible getter function
43
        // name.
44 11
        $lcName = lcfirst($name);
45 11
        $getFxnCall = ($lcName[0] === '_' || strpos($lcName, 'get') === 0) ? $lcName : sprintf('get%s', ucfirst($name));
46
47
        // Check if our function call is a jailed call, meaning the function should be mapped to special "jailed"
48
        // jailed version of the function call.
49 11
        if (array_key_exists($getFxnCall, $this->jailedFunctions))
50
        {
51 3
            return call_user_func_array([$this->object, $this->jailedFunctions[$getFxnCall]], $arguments);
52
        }
53
54
        // Otherwise, test to see if the function call is in our white list and call it
55 8
        if (in_array($getFxnCall, $this->whiteListFunctions))
56
        {
57 7
            return call_user_func_array([$this->object, $getFxnCall], $arguments);
58
        }
59
60 1
        throw new \BadMethodCallException();
61
    }
62
63
    /**
64
     * Check if the jailed object is an instance of a given class.
65
     *
66
     * @param string $class
67
     *
68
     * @return bool
69
     */
70
    public function _coreInstanceOf($class)
71
    {
72
        return ($this->object instanceof $class) || is_subclass_of($this->object, $class);
73
    }
74
75
    ///
76
    // ArrayAccess Implementation
77
    ///
78
79
    /**
80
     * {@inheritdoc}
81
     */
82 22
    public function offsetExists($offset)
83
    {
84 22
        return $this->object->offsetExists($offset);
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90 32
    public function offsetGet($offset)
91
    {
92 32
        return $this->object->offsetGet($offset);
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98
    public function offsetSet($offset, $value)
99
    {
100
        throw new \LogicException('A jailed document is read-only.');
101
    }
102
103
    /**
104
     * {@inheritdoc}
105
     */
106
    public function offsetUnset($offset)
107
    {
108
        throw new \LogicException('A jailed document is read-only.');
109
    }
110
111
    ///
112
    // IteratorAggregate implementation
113
    ///
114
115
    /**
116
     * {@inheritdoc}
117
     */
118 19
    public function getIterator()
119
    {
120 19
        return $this->object->getIterator();
121
    }
122
123
    ///
124
    // JsonSerializable implementation
125
    ///
126
127
    /**
128
     * {@inheritdoc}
129
     */
130
    public function jsonSerialize()
131
    {
132
        return $this->object->jsonSerialize();
133
    }
134
}
135