Completed
Push — master ( 507aa8...65f31c )
by Vladimir
02:23
created

JailObject::offsetGet()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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