Yaffs site version 1.1
[yaffs-website] / vendor / psy / psysh / src / Psy / Context.php
1 <?php
2
3 /*
4  * This file is part of Psy Shell.
5  *
6  * (c) 2012-2017 Justin Hileman
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Psy;
13
14 /**
15  * The Shell execution context.
16  *
17  * This class encapsulates the current variables, most recent return value and
18  * exception, and the current namespace.
19  */
20 class Context
21 {
22     private static $specialNames = array('_', '_e', '__psysh__', 'this');
23
24     // Whitelist a very limited number of command-scope magic variable names.
25     // This might be a bad idea, but future me can sort it out.
26     private static $commandScopeNames = array(
27         '__function', '__method', '__class', '__namespace', '__file', '__line', '__dir',
28     );
29
30     private $scopeVariables = array();
31     private $commandScopeVariables = array();
32     private $lastException;
33     private $returnValue;
34     private $boundObject;
35
36     /**
37      * Get a context variable.
38      *
39      * @throws InvalidArgumentException If the variable is not found in the current context
40      *
41      * @param string $name
42      *
43      * @return mixed
44      */
45     public function get($name)
46     {
47         switch ($name) {
48             case '_':
49                 return $this->returnValue;
50
51             case '_e':
52                 if (isset($this->lastException)) {
53                     return $this->lastException;
54                 }
55                 break;
56
57             case 'this':
58                 if (isset($this->boundObject)) {
59                     return $this->boundObject;
60                 }
61                 break;
62
63             case '__function':
64             case '__method':
65             case '__class':
66             case '__namespace':
67             case '__file':
68             case '__line':
69             case '__dir':
70                 if (array_key_exists($name, $this->commandScopeVariables)) {
71                     return $this->commandScopeVariables[$name];
72                 }
73                 break;
74
75             default:
76                 if (array_key_exists($name, $this->scopeVariables)) {
77                     return $this->scopeVariables[$name];
78                 }
79                 break;
80         }
81
82         throw new \InvalidArgumentException('Unknown variable: $' . $name);
83     }
84
85     /**
86      * Get all defined variables.
87      *
88      * @return array
89      */
90     public function getAll()
91     {
92         return array_merge($this->scopeVariables, $this->getSpecialVariables());
93     }
94
95     /**
96      * Get all defined magic variables: $_, $_e, $__class, $__file, etc.
97      *
98      * @return array
99      */
100     public function getSpecialVariables()
101     {
102         $vars = array(
103             '_' => $this->returnValue,
104         );
105
106         if (isset($this->lastException)) {
107             $vars['_e'] = $this->lastException;
108         }
109
110         if (isset($this->boundObject)) {
111             $vars['this'] = $this->boundObject;
112         }
113
114         return array_merge($vars, $this->commandScopeVariables);
115     }
116
117     /**
118      * Set all scope variables.
119      *
120      * This method does *not* set any of the magic variables: $_, $_e, $__class, $__file, etc.
121      *
122      * @param array $vars
123      */
124     public function setAll(array $vars)
125     {
126         foreach (self::$specialNames as $key) {
127             unset($vars[$key]);
128         }
129
130         foreach (self::$commandScopeNames as $key) {
131             unset($vars[$key]);
132         }
133
134         $this->scopeVariables = $vars;
135     }
136
137     /**
138      * Set the most recent return value.
139      *
140      * @param mixed $value
141      */
142     public function setReturnValue($value)
143     {
144         $this->returnValue = $value;
145     }
146
147     /**
148      * Get the most recent return value.
149      *
150      * @return mixed
151      */
152     public function getReturnValue()
153     {
154         return $this->returnValue;
155     }
156
157     /**
158      * Set the most recent Exception.
159      *
160      * @param \Exception $e
161      */
162     public function setLastException(\Exception $e)
163     {
164         $this->lastException = $e;
165     }
166
167     /**
168      * Get the most recent Exception.
169      *
170      * @throws InvalidArgumentException If no Exception has been caught
171      *
172      * @return null|Exception
173      */
174     public function getLastException()
175     {
176         if (!isset($this->lastException)) {
177             throw new \InvalidArgumentException('No most-recent exception');
178         }
179
180         return $this->lastException;
181     }
182
183     /**
184      * Set the bound object ($this variable) for the interactive shell.
185      *
186      * @param object|null $boundObject
187      */
188     public function setBoundObject($boundObject)
189     {
190         $this->boundObject = is_object($boundObject) ? $boundObject : null;
191     }
192
193     /**
194      * Get the bound object ($this variable) for the interactive shell.
195      *
196      * @return object|null
197      */
198     public function getBoundObject()
199     {
200         return $this->boundObject;
201     }
202
203     /**
204      * Set command-scope magic variables: $__class, $__file, etc.
205      *
206      * @param array $commandScopeVariables
207      */
208     public function setCommandScopeVariables(array $commandScopeVariables)
209     {
210         $vars = array();
211         foreach ($commandScopeVariables as $key => $value) {
212             // kind of type check
213             if (is_scalar($value) && in_array($key, self::$commandScopeNames)) {
214                 $vars[$key] = $value;
215             }
216         }
217
218         $this->commandScopeVariables = $vars;
219     }
220
221     /**
222      * Get command-scope magic variables: $__class, $__file, etc.
223      *
224      * @return array
225      */
226     public function getCommandScopeVariables()
227     {
228         return $this->commandScopeVariables;
229     }
230
231     /**
232      * Get unused command-scope magic variables names: __class, __file, etc.
233      *
234      * This is used by the shell to unset old command-scope variables after a
235      * new batch is set.
236      *
237      * @return array Array of unused variable names
238      */
239     public function getUnusedCommandScopeVariableNames()
240     {
241         return array_diff(self::$commandScopeNames, array_keys($this->commandScopeVariables));
242     }
243
244     /**
245      * Check whether a variable name is a magic variable.
246      *
247      * @param string $name
248      *
249      * @return bool
250      */
251     public static function isSpecialVariableName($name)
252     {
253         return in_array($name, self::$specialNames) || in_array($name, self::$commandScopeNames);
254     }
255 }