1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* @copyright 2017 Vladimir Jimenez |
5
|
|
|
* @license https://github.com/allejo/stakx/blob/master/LICENSE.md MIT |
6
|
|
|
*/ |
7
|
|
|
|
8
|
|
|
namespace allejo\stakx\Document; |
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
|
|
|
class JailedDocument implements \ArrayAccess, \IteratorAggregate |
17
|
|
|
{ |
18
|
|
|
/** |
19
|
|
|
* @var string[] |
20
|
|
|
*/ |
21
|
|
|
private $whiteListFunctions; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* @var string[] |
25
|
|
|
*/ |
26
|
|
|
private $jailedFunctions; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* @var JailedDocumentInterface |
30
|
|
|
*/ |
31
|
|
|
private $object; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* JailObject constructor. |
35
|
|
|
* |
36
|
|
|
* @param JailedDocumentInterface $object The object that will be jailed |
37
|
|
|
* @param array $whiteListFunctions A list of function names that can be called |
38
|
|
|
* @param array $jailedFunctions |
39
|
|
|
*/ |
40
|
51 |
|
public function __construct(&$object, array $whiteListFunctions, array $jailedFunctions = array()) |
41
|
|
|
{ |
42
|
51 |
|
if (!($object instanceof JailedDocumentInterface) && |
43
|
|
|
!($object instanceof \ArrayAccess) && |
44
|
|
|
!($object instanceof \IteratorAggregate)) |
45
|
|
|
{ |
46
|
|
|
throw new \InvalidArgumentException('Must implement the ArrayAccess and Jailable interfaces'); |
47
|
|
|
} |
48
|
|
|
|
49
|
51 |
|
$this->object = &$object; |
50
|
51 |
|
$this->whiteListFunctions = $whiteListFunctions; |
51
|
51 |
|
$this->jailedFunctions = $jailedFunctions; |
52
|
51 |
|
} |
53
|
|
|
|
54
|
10 |
|
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
|
10 |
|
$lcName = lcfirst($name); |
59
|
10 |
|
$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
|
10 |
|
if (array_key_exists($getFxnCall, $this->jailedFunctions)) |
64
|
|
|
{ |
65
|
3 |
|
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
|
22 |
|
public function offsetExists($offset) |
90
|
|
|
{ |
91
|
22 |
|
return $this->object->offsetExists($offset); |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* {@inheritdoc} |
96
|
|
|
*/ |
97
|
30 |
|
public function offsetGet($offset) |
98
|
|
|
{ |
99
|
30 |
|
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
|
|
|
|
118
|
|
|
// |
119
|
|
|
// IteratorAggregate implementation |
120
|
|
|
// |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* {@inheritdoc} |
124
|
|
|
*/ |
125
|
18 |
|
public function getIterator() |
126
|
|
|
{ |
127
|
18 |
|
return $this->object->getIterator(); |
|
|
|
|
128
|
|
|
} |
129
|
|
|
} |
130
|
|
|
|
This check examines a number of code elements and verifies that they conform to the given naming conventions.
You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.