organizrnginxsonarrradarrplexdashboardcouchpotatonzbgetbookmarkapplication-dashboardmuximuxlandingpagestartpagelandinghtpcserverhomepagesabnzbdheimdallemby
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
293 lines
7.1 KiB
293 lines
7.1 KiB
<?php
|
|
|
|
/*
|
|
* This file is part of Psy Shell.
|
|
*
|
|
* (c) 2012-2017 Justin Hileman
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Psy;
|
|
|
|
/**
|
|
* The Shell execution context.
|
|
*
|
|
* This class encapsulates the current variables, most recent return value and
|
|
* exception, and the current namespace.
|
|
*/
|
|
class Context
|
|
{
|
|
private static $specialNames = array('_', '_e', '__out', '__psysh__', 'this');
|
|
|
|
// Whitelist a very limited number of command-scope magic variable names.
|
|
// This might be a bad idea, but future me can sort it out.
|
|
private static $commandScopeNames = array(
|
|
'__function', '__method', '__class', '__namespace', '__file', '__line', '__dir',
|
|
);
|
|
|
|
private $scopeVariables = array();
|
|
private $commandScopeVariables = array();
|
|
private $returnValue;
|
|
private $lastException;
|
|
private $lastStdout;
|
|
private $boundObject;
|
|
|
|
/**
|
|
* Get a context variable.
|
|
*
|
|
* @throws InvalidArgumentException If the variable is not found in the current context
|
|
*
|
|
* @param string $name
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function get($name)
|
|
{
|
|
switch ($name) {
|
|
case '_':
|
|
return $this->returnValue;
|
|
|
|
case '_e':
|
|
if (isset($this->lastException)) {
|
|
return $this->lastException;
|
|
}
|
|
break;
|
|
|
|
case '__out':
|
|
if (isset($this->lastStdout)) {
|
|
return $this->lastStdout;
|
|
}
|
|
break;
|
|
|
|
case 'this':
|
|
if (isset($this->boundObject)) {
|
|
return $this->boundObject;
|
|
}
|
|
break;
|
|
|
|
case '__function':
|
|
case '__method':
|
|
case '__class':
|
|
case '__namespace':
|
|
case '__file':
|
|
case '__line':
|
|
case '__dir':
|
|
if (array_key_exists($name, $this->commandScopeVariables)) {
|
|
return $this->commandScopeVariables[$name];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if (array_key_exists($name, $this->scopeVariables)) {
|
|
return $this->scopeVariables[$name];
|
|
}
|
|
break;
|
|
}
|
|
|
|
throw new \InvalidArgumentException('Unknown variable: $' . $name);
|
|
}
|
|
|
|
/**
|
|
* Get all defined variables.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getAll()
|
|
{
|
|
return array_merge($this->scopeVariables, $this->getSpecialVariables());
|
|
}
|
|
|
|
/**
|
|
* Get all defined magic variables: $_, $_e, $__out, $__class, $__file, etc.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getSpecialVariables()
|
|
{
|
|
$vars = array(
|
|
'_' => $this->returnValue,
|
|
);
|
|
|
|
if (isset($this->lastException)) {
|
|
$vars['_e'] = $this->lastException;
|
|
}
|
|
|
|
if (isset($this->lastStdout)) {
|
|
$vars['__out'] = $this->lastStdout;
|
|
}
|
|
|
|
if (isset($this->boundObject)) {
|
|
$vars['this'] = $this->boundObject;
|
|
}
|
|
|
|
return array_merge($vars, $this->commandScopeVariables);
|
|
}
|
|
|
|
/**
|
|
* Set all scope variables.
|
|
*
|
|
* This method does *not* set any of the magic variables: $_, $_e, $__out,
|
|
* $__class, $__file, etc.
|
|
*
|
|
* @param array $vars
|
|
*/
|
|
public function setAll(array $vars)
|
|
{
|
|
foreach (self::$specialNames as $key) {
|
|
unset($vars[$key]);
|
|
}
|
|
|
|
foreach (self::$commandScopeNames as $key) {
|
|
unset($vars[$key]);
|
|
}
|
|
|
|
$this->scopeVariables = $vars;
|
|
}
|
|
|
|
/**
|
|
* Set the most recent return value.
|
|
*
|
|
* @param mixed $value
|
|
*/
|
|
public function setReturnValue($value)
|
|
{
|
|
$this->returnValue = $value;
|
|
}
|
|
|
|
/**
|
|
* Get the most recent return value.
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function getReturnValue()
|
|
{
|
|
return $this->returnValue;
|
|
}
|
|
|
|
/**
|
|
* Set the most recent Exception.
|
|
*
|
|
* @param \Exception $e
|
|
*/
|
|
public function setLastException(\Exception $e)
|
|
{
|
|
$this->lastException = $e;
|
|
}
|
|
|
|
/**
|
|
* Get the most recent Exception.
|
|
*
|
|
* @throws InvalidArgumentException If no Exception has been caught
|
|
*
|
|
* @return null|Exception
|
|
*/
|
|
public function getLastException()
|
|
{
|
|
if (!isset($this->lastException)) {
|
|
throw new \InvalidArgumentException('No most-recent exception');
|
|
}
|
|
|
|
return $this->lastException;
|
|
}
|
|
|
|
/**
|
|
* Set the most recent output from evaluated code.
|
|
*
|
|
* @param string $lastStdout
|
|
*/
|
|
public function setLastStdout($lastStdout)
|
|
{
|
|
$this->lastStdout = $lastStdout;
|
|
}
|
|
|
|
/**
|
|
* Get the most recent output from evaluated code.
|
|
*
|
|
* @throws InvalidArgumentException If no output has happened yet
|
|
*
|
|
* @return null|string
|
|
*/
|
|
public function getLastStdout()
|
|
{
|
|
if (!isset($this->lastStdout)) {
|
|
throw new \InvalidArgumentException('No most-recent output');
|
|
}
|
|
|
|
return $this->lastStdout;
|
|
}
|
|
|
|
/**
|
|
* Set the bound object ($this variable) for the interactive shell.
|
|
*
|
|
* @param object|null $boundObject
|
|
*/
|
|
public function setBoundObject($boundObject)
|
|
{
|
|
$this->boundObject = is_object($boundObject) ? $boundObject : null;
|
|
}
|
|
|
|
/**
|
|
* Get the bound object ($this variable) for the interactive shell.
|
|
*
|
|
* @return object|null
|
|
*/
|
|
public function getBoundObject()
|
|
{
|
|
return $this->boundObject;
|
|
}
|
|
|
|
/**
|
|
* Set command-scope magic variables: $__class, $__file, etc.
|
|
*
|
|
* @param array $commandScopeVariables
|
|
*/
|
|
public function setCommandScopeVariables(array $commandScopeVariables)
|
|
{
|
|
$vars = array();
|
|
foreach ($commandScopeVariables as $key => $value) {
|
|
// kind of type check
|
|
if (is_scalar($value) && in_array($key, self::$commandScopeNames)) {
|
|
$vars[$key] = $value;
|
|
}
|
|
}
|
|
|
|
$this->commandScopeVariables = $vars;
|
|
}
|
|
|
|
/**
|
|
* Get command-scope magic variables: $__class, $__file, etc.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getCommandScopeVariables()
|
|
{
|
|
return $this->commandScopeVariables;
|
|
}
|
|
|
|
/**
|
|
* Get unused command-scope magic variables names: __class, __file, etc.
|
|
*
|
|
* This is used by the shell to unset old command-scope variables after a
|
|
* new batch is set.
|
|
*
|
|
* @return array Array of unused variable names
|
|
*/
|
|
public function getUnusedCommandScopeVariableNames()
|
|
{
|
|
return array_diff(self::$commandScopeNames, array_keys($this->commandScopeVariables));
|
|
}
|
|
|
|
/**
|
|
* Check whether a variable name is a magic variable.
|
|
*
|
|
* @param string $name
|
|
*
|
|
* @return bool
|
|
*/
|
|
public static function isSpecialVariableName($name)
|
|
{
|
|
return in_array($name, self::$specialNames) || in_array($name, self::$commandScopeNames);
|
|
}
|
|
}
|
|
|