<?php
/*
* This file is part of Psy Shell.
*
* (c) 2012-2023 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 = ['_', '_e', '__out', '__psysh__', 'this'];
// Include 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 = [
'__function', '__method', '__class', '__namespace', '__file', '__line', '__dir',
];
private $scopeVariables = [];
private $commandScopeVariables = [];
private $returnValue;
private $lastException;
private $lastStdout;
private $boundObject;
private $boundClass;
/**
* Get a context variable.
*
* @throws \InvalidArgumentException If the variable is not found in the current context
*
* @param string $name
*
* @return mixed
*/
public function get(string $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.
*/
public function getAll(): array
{
return \array_merge($this->scopeVariables, $this->getSpecialVariables());
}
/**
* Get all defined magic variables: $_, $_e, $__out, $__class, $__file, etc.
*/
public function getSpecialVariables(): array
{
$vars = [
'_' => $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 or Error.
*
* @param \Throwable $e
*/
public function setLastException(\Throwable $e)
{
$this->lastException = $e;
}
/**
* Get the most recent Exception or Error.
*
* @throws \InvalidArgumentException If no Exception has been caught
*
* @return \Throwable|null
*/
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(string $lastStdout)
{
$this->lastStdout = $lastStdout;
}
/**
* Get the most recent output from evaluated code.
*
* @throws \InvalidArgumentException If no output has happened yet
*
* @return string|null
*/
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.
*
* Note that this unsets the bound class, if any exists.
*
* @param object|null $boundObject
*/
public function setBoundObject($boundObject)
{
$this->boundObject = \is_object($boundObject) ? $boundObject : null;
$this->boundClass = null;
}
/**
* Get the bound object ($this variable) for the interactive shell.
*
* @return object|null
*/
public function getBoundObject()
{
return $this->boundObject;
}
/**
* Set the bound class (self) for the interactive shell.
*
* Note that this unsets the bound object, if any exists.
*
* @param string|null $boundClass
*/
public function setBoundClass($boundClass)
{
$this->boundClass = (\is_string($boundClass) && $boundClass !== '') ? $boundClass : null;
$this->boundObject = null;
}
/**
* Get the bound class (self) for the interactive shell.
*
* @return string|null
*/
public function getBoundClass()
{
return $this->boundClass;
}
/**
* Set command-scope magic variables: $__class, $__file, etc.
*
* @param array $commandScopeVariables
*/
public function setCommandScopeVariables(array $commandScopeVariables)
{
$vars = [];
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.
*/
public function getCommandScopeVariables(): array
{
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(): array
{
return \array_diff(self::$commandScopeNames, \array_keys($this->commandScopeVariables));
}
/**
* Check whether a variable name is a magic variable.
*
* @param string $name
*/
public static function isSpecialVariableName(string $name): bool
{
return \in_array($name, self::$specialNames) || \in_array($name, self::$commandScopeNames);
}
}
At NFC Pay, we strive to provide a seamless and satisfactory experience with our services. This Refund Policy outlines the circumstances under which refunds may be issued for transactions made through our platform. Please read this policy carefully to understand your rights regarding refunds.
1. Eligibility for Refunds
Refunds may be considered under the following circumstances:
2. Non-Refundable Situations
Refunds will generally not be issued in the following situations:
3. Refund Process
To request a refund, please follow these steps:
4. Refund Exceptions
Certain transactions may be subject to specific terms and conditions, including non-refundable fees or charges. Please review the terms associated with each transaction carefully, as some fees may not be eligible for refunds.
5. Modifications to the Refund Policy
NFC Pay reserves the right to modify this Refund Policy at any time. Changes will be communicated through updates on our website and app, and the effective date will be updated accordingly. We encourage you to review this policy periodically to stay informed about our refund practices.
By using NFC Pay, you agree to this Refund Policy and understand the terms under which refunds may be issued. Our goal is to ensure a fair and transparent refund process, providing you with confidence and peace of mind when using our services.