Файловый менеджер - Редактировать - /home/easybachat/hisabat365.com/4a7891/filp.zip
Ðазад
PK �)[��Ţ� � % whoops/src/Whoops/Exception/Frame.phpnu �[��� <?php /** * Whoops - php errors for cool kids * @author Filipe Dobreira <http://github.com/filp> */ namespace Whoops\Exception; use InvalidArgumentException; use Serializable; class Frame implements Serializable { /** * @var array */ protected $frame; /** * @var string */ protected $fileContentsCache; /** * @var array[] */ protected $comments = []; /** * @var bool */ protected $application; public function __construct(array $frame) { $this->frame = $frame; } /** * @param bool $shortened * @return string|null */ public function getFile($shortened = false) { if (empty($this->frame['file'])) { return null; } $file = $this->frame['file']; // Check if this frame occurred within an eval(). // @todo: This can be made more reliable by checking if we've entered // eval() in a previous trace, but will need some more work on the upper // trace collector(s). if (preg_match('/^(.*)\((\d+)\) : (?:eval\(\)\'d|assert) code$/', $file, $matches)) { $file = $this->frame['file'] = $matches[1]; $this->frame['line'] = (int) $matches[2]; } if ($shortened && is_string($file)) { // Replace the part of the path that all frames have in common, and add 'soft hyphens' for smoother line-breaks. $dirname = dirname(dirname(dirname(dirname(dirname(dirname(__DIR__)))))); if ($dirname !== '/') { $file = str_replace($dirname, "…", $file); } $file = str_replace("/", "/­", $file); } return $file; } /** * @return int|null */ public function getLine() { return isset($this->frame['line']) ? $this->frame['line'] : null; } /** * @return string|null */ public function getClass() { return isset($this->frame['class']) ? $this->frame['class'] : null; } /** * @return string|null */ public function getFunction() { return isset($this->frame['function']) ? $this->frame['function'] : null; } /** * @return array */ public function getArgs() { return isset($this->frame['args']) ? (array) $this->frame['args'] : []; } /** * Returns the full contents of the file for this frame, * if it's known. * @return string|null */ public function getFileContents() { if ($this->fileContentsCache === null && $filePath = $this->getFile()) { // Leave the stage early when 'Unknown' or '[internal]' is passed // this would otherwise raise an exception when // open_basedir is enabled. if ($filePath === "Unknown" || $filePath === '[internal]') { return null; } try { $this->fileContentsCache = file_get_contents($filePath); } catch (ErrorException $exception) { // Internal file paths of PHP extensions cannot be opened } } return $this->fileContentsCache; } /** * Adds a comment to this frame, that can be received and * used by other handlers. For example, the PrettyPage handler * can attach these comments under the code for each frame. * * An interesting use for this would be, for example, code analysis * & annotations. * * @param string $comment * @param string $context Optional string identifying the origin of the comment */ public function addComment($comment, $context = 'global') { $this->comments[] = [ 'comment' => $comment, 'context' => $context, ]; } /** * Returns all comments for this frame. Optionally allows * a filter to only retrieve comments from a specific * context. * * @param string $filter * @return array[] */ public function getComments($filter = null) { $comments = $this->comments; if ($filter !== null) { $comments = array_filter($comments, function ($c) use ($filter) { return $c['context'] == $filter; }); } return $comments; } /** * Returns the array containing the raw frame data from which * this Frame object was built * * @return array */ public function getRawFrame() { return $this->frame; } /** * Returns the contents of the file for this frame as an * array of lines, and optionally as a clamped range of lines. * * NOTE: lines are 0-indexed * * @example * Get all lines for this file * $frame->getFileLines(); // => array( 0 => '<?php', 1 => '...', ...) * @example * Get one line for this file, starting at line 10 (zero-indexed, remember!) * $frame->getFileLines(9, 1); // array( 9 => '...' ) * * @throws InvalidArgumentException if $length is less than or equal to 0 * @param int $start * @param int $length * @return string[]|null */ public function getFileLines($start = 0, $length = null) { if (null !== ($contents = $this->getFileContents())) { $lines = explode("\n", $contents); // Get a subset of lines from $start to $end if ($length !== null) { $start = (int) $start; $length = (int) $length; if ($start < 0) { $start = 0; } if ($length <= 0) { throw new InvalidArgumentException( "\$length($length) cannot be lower or equal to 0" ); } $lines = array_slice($lines, $start, $length, true); } return $lines; } } /** * Implements the Serializable interface, with special * steps to also save the existing comments. * * @see Serializable::serialize * @return string */ public function serialize() { $frame = $this->frame; if (!empty($this->comments)) { $frame['_comments'] = $this->comments; } return serialize($frame); } public function __serialize() { $frame = $this->frame; if (!empty($this->comments)) { $frame['_comments'] = $this->comments; } return $frame; } /** * Unserializes the frame data, while also preserving * any existing comment data. * * @see Serializable::unserialize * @param string $serializedFrame */ public function unserialize($serializedFrame) { $frame = unserialize($serializedFrame); if (!empty($frame['_comments'])) { $this->comments = $frame['_comments']; unset($frame['_comments']); } $this->frame = $frame; } public function __unserialize($frame) { if (!empty($frame['_comments'])) { $this->comments = $frame['_comments']; unset($frame['_comments']); } $this->frame = $frame; } /** * Compares Frame against one another * @param Frame $frame * @return bool */ public function equals(Frame $frame) { if (!$this->getFile() || $this->getFile() === 'Unknown' || !$this->getLine()) { return false; } return $frame->getFile() === $this->getFile() && $frame->getLine() === $this->getLine(); } /** * Returns whether this frame belongs to the application or not. * * @return boolean */ public function isApplication() { return $this->application; } /** * Mark as an frame belonging to the application. * * @param boolean $application */ public function setApplication($application) { $this->application = $application; } } PK �)["�sCc c . whoops/src/Whoops/Exception/ErrorException.phpnu �[��� <?php /** * Whoops - php errors for cool kids * @author Filipe Dobreira <http://github.com/filp> */ namespace Whoops\Exception; use ErrorException as BaseErrorException; /** * Wraps ErrorException; mostly used for typing (at least now) * to easily cleanup the stack trace of redundant info. */ class ErrorException extends BaseErrorException { } PK �)[9Un�� � ) whoops/src/Whoops/Exception/Formatter.phpnu �[��� <?php /** * Whoops - php errors for cool kids * @author Filipe Dobreira <http://github.com/filp> */ namespace Whoops\Exception; use Whoops\Inspector\InspectorInterface; class Formatter { /** * Returns all basic information about the exception in a simple array * for further convertion to other languages * @param InspectorInterface $inspector * @param bool $shouldAddTrace * @param array<callable> $frameFilters * @return array */ public static function formatExceptionAsDataArray(InspectorInterface $inspector, $shouldAddTrace, array $frameFilters = []) { $exception = $inspector->getException(); $response = [ 'type' => get_class($exception), 'message' => $exception->getMessage(), 'code' => $exception->getCode(), 'file' => $exception->getFile(), 'line' => $exception->getLine(), ]; if ($shouldAddTrace) { $frames = $inspector->getFrames($frameFilters); $frameData = []; foreach ($frames as $frame) { /** @var Frame $frame */ $frameData[] = [ 'file' => $frame->getFile(), 'line' => $frame->getLine(), 'function' => $frame->getFunction(), 'class' => $frame->getClass(), 'args' => $frame->getArgs(), ]; } $response['trace'] = $frameData; } return $response; } public static function formatExceptionPlain(InspectorInterface $inspector) { $message = $inspector->getException()->getMessage(); $frames = $inspector->getFrames(); $plain = $inspector->getExceptionName(); $plain .= ' thrown with message "'; $plain .= $message; $plain .= '"'."\n\n"; $plain .= "Stacktrace:\n"; foreach ($frames as $i => $frame) { $plain .= "#". (count($frames) - $i - 1). " "; $plain .= $frame->getClass() ?: ''; $plain .= $frame->getClass() && $frame->getFunction() ? ":" : ""; $plain .= $frame->getFunction() ?: ''; $plain .= ' in '; $plain .= ($frame->getFile() ?: '<#unknown>'); $plain .= ':'; $plain .= (int) $frame->getLine(). "\n"; } return $plain; } } PK �)[�� �) ) / whoops/src/Whoops/Exception/FrameCollection.phpnu �[��� <?php /** * Whoops - php errors for cool kids * @author Filipe Dobreira <http://github.com/filp> */ namespace Whoops\Exception; use ArrayAccess; use ArrayIterator; use Countable; use IteratorAggregate; use ReturnTypeWillChange; use Serializable; use UnexpectedValueException; /** * Exposes a fluent interface for dealing with an ordered list * of stack-trace frames. */ class FrameCollection implements ArrayAccess, IteratorAggregate, Serializable, Countable { /** * @var array[] */ private $frames; public function __construct(array $frames) { $this->frames = array_map(function ($frame) { return new Frame($frame); }, $frames); } /** * Filters frames using a callable, returns the same FrameCollection * * @param callable $callable * @return FrameCollection */ public function filter($callable) { $this->frames = array_values(array_filter($this->frames, $callable)); return $this; } /** * Map the collection of frames * * @param callable $callable * @return FrameCollection */ public function map($callable) { // Contain the map within a higher-order callable // that enforces type-correctness for the $callable $this->frames = array_map(function ($frame) use ($callable) { $frame = call_user_func($callable, $frame); if (!$frame instanceof Frame) { throw new UnexpectedValueException( "Callable to " . __CLASS__ . "::map must return a Frame object" ); } return $frame; }, $this->frames); return $this; } /** * Returns an array with all frames, does not affect * the internal array. * * @todo If this gets any more complex than this, * have getIterator use this method. * @see FrameCollection::getIterator * @return array */ public function getArray() { return $this->frames; } /** * @see IteratorAggregate::getIterator * @return ArrayIterator */ #[ReturnTypeWillChange] public function getIterator() { return new ArrayIterator($this->frames); } /** * @see ArrayAccess::offsetExists * @param int $offset */ #[ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->frames[$offset]); } /** * @see ArrayAccess::offsetGet * @param int $offset */ #[ReturnTypeWillChange] public function offsetGet($offset) { return $this->frames[$offset]; } /** * @see ArrayAccess::offsetSet * @param int $offset */ #[ReturnTypeWillChange] public function offsetSet($offset, $value) { throw new \Exception(__CLASS__ . ' is read only'); } /** * @see ArrayAccess::offsetUnset * @param int $offset */ #[ReturnTypeWillChange] public function offsetUnset($offset) { throw new \Exception(__CLASS__ . ' is read only'); } /** * @see Countable::count * @return int */ #[ReturnTypeWillChange] public function count() { return count($this->frames); } /** * Count the frames that belongs to the application. * * @return int */ public function countIsApplication() { return count(array_filter($this->frames, function (Frame $f) { return $f->isApplication(); })); } /** * @see Serializable::serialize * @return string */ #[ReturnTypeWillChange] public function serialize() { return serialize($this->frames); } /** * @see Serializable::unserialize * @param string $serializedFrames */ #[ReturnTypeWillChange] public function unserialize($serializedFrames) { $this->frames = unserialize($serializedFrames); } public function __serialize() { return $this->frames; } public function __unserialize(array $serializedFrames) { $this->frames = $serializedFrames; } /** * @param Frame[] $frames Array of Frame instances, usually from $e->getPrevious() */ public function prependFrames(array $frames) { $this->frames = array_merge($frames, $this->frames); } /** * Gets the innermost part of stack trace that is not the same as that of outer exception * * @param FrameCollection $parentFrames Outer exception frames to compare tail against * @return Frame[] */ public function topDiff(FrameCollection $parentFrames) { $diff = $this->frames; $parentFrames = $parentFrames->getArray(); $p = count($parentFrames)-1; for ($i = count($diff)-1; $i >= 0 && $p >= 0; $i--) { /** @var Frame $tailFrame */ $tailFrame = $diff[$i]; if ($tailFrame->equals($parentFrames[$p])) { unset($diff[$i]); } $p--; } return $diff; } } PK �)[�.���% �% ) whoops/src/Whoops/Exception/Inspector.phpnu �[��� <?php /** * Whoops - php errors for cool kids * @author Filipe Dobreira <http://github.com/filp> */ namespace Whoops\Exception; use Whoops\Inspector\InspectorFactory; use Whoops\Inspector\InspectorInterface; use Whoops\Util\Misc; class Inspector implements InspectorInterface { /** * @var \Throwable */ private $exception; /** * @var \Whoops\Exception\FrameCollection */ private $frames; /** * @var \Whoops\Exception\Inspector */ private $previousExceptionInspector; /** * @var \Throwable[] */ private $previousExceptions; /** * @var \Whoops\Inspector\InspectorFactoryInterface|null */ protected $inspectorFactory; /** * @param \Throwable $exception The exception to inspect * @param \Whoops\Inspector\InspectorFactoryInterface $factory */ public function __construct($exception, $factory = null) { $this->exception = $exception; $this->inspectorFactory = $factory ?: new InspectorFactory(); } /** * @return \Throwable */ public function getException() { return $this->exception; } /** * @return string */ public function getExceptionName() { return get_class($this->exception); } /** * @return string */ public function getExceptionMessage() { return $this->extractDocrefUrl($this->exception->getMessage())['message']; } /** * @return string[] */ public function getPreviousExceptionMessages() { return array_map(function ($prev) { /** @var \Throwable $prev */ return $this->extractDocrefUrl($prev->getMessage())['message']; }, $this->getPreviousExceptions()); } /** * @return int[] */ public function getPreviousExceptionCodes() { return array_map(function ($prev) { /** @var \Throwable $prev */ return $prev->getCode(); }, $this->getPreviousExceptions()); } /** * Returns a url to the php-manual related to the underlying error - when available. * * @return string|null */ public function getExceptionDocrefUrl() { return $this->extractDocrefUrl($this->exception->getMessage())['url']; } private function extractDocrefUrl($message) { $docref = [ 'message' => $message, 'url' => null, ]; // php embbeds urls to the manual into the Exception message with the following ini-settings defined // http://php.net/manual/en/errorfunc.configuration.php#ini.docref-root if (!ini_get('html_errors') || !ini_get('docref_root')) { return $docref; } $pattern = "/\[<a href='([^']+)'>(?:[^<]+)<\/a>\]/"; if (preg_match($pattern, $message, $matches)) { // -> strip those automatically generated links from the exception message $docref['message'] = preg_replace($pattern, '', $message, 1); $docref['url'] = $matches[1]; } return $docref; } /** * Does the wrapped Exception has a previous Exception? * @return bool */ public function hasPreviousException() { return $this->previousExceptionInspector || $this->exception->getPrevious(); } /** * Returns an Inspector for a previous Exception, if any. * @todo Clean this up a bit, cache stuff a bit better. * @return Inspector */ public function getPreviousExceptionInspector() { if ($this->previousExceptionInspector === null) { $previousException = $this->exception->getPrevious(); if ($previousException) { $this->previousExceptionInspector = $this->inspectorFactory->create($previousException); } } return $this->previousExceptionInspector; } /** * Returns an array of all previous exceptions for this inspector's exception * @return \Throwable[] */ public function getPreviousExceptions() { if ($this->previousExceptions === null) { $this->previousExceptions = []; $prev = $this->exception->getPrevious(); while ($prev !== null) { $this->previousExceptions[] = $prev; $prev = $prev->getPrevious(); } } return $this->previousExceptions; } /** * Returns an iterator for the inspected exception's * frames. * * @param array<callable> $frameFilters * * @return \Whoops\Exception\FrameCollection */ public function getFrames(array $frameFilters = []) { if ($this->frames === null) { $frames = $this->getTrace($this->exception); // Fill empty line/file info for call_user_func_array usages (PHP Bug #44428) foreach ($frames as $k => $frame) { if (empty($frame['file'])) { // Default values when file and line are missing $file = '[internal]'; $line = 0; $next_frame = !empty($frames[$k + 1]) ? $frames[$k + 1] : []; if ($this->isValidNextFrame($next_frame)) { $file = $next_frame['file']; $line = $next_frame['line']; } $frames[$k]['file'] = $file; $frames[$k]['line'] = $line; } } // Find latest non-error handling frame index ($i) used to remove error handling frames $i = 0; foreach ($frames as $k => $frame) { if ($frame['file'] == $this->exception->getFile() && $frame['line'] == $this->exception->getLine()) { $i = $k; } } // Remove error handling frames if ($i > 0) { array_splice($frames, 0, $i); } $firstFrame = $this->getFrameFromException($this->exception); array_unshift($frames, $firstFrame); $this->frames = new FrameCollection($frames); if ($previousInspector = $this->getPreviousExceptionInspector()) { // Keep outer frame on top of the inner one $outerFrames = $this->frames; $newFrames = clone $previousInspector->getFrames(); // I assume it will always be set, but let's be safe if (isset($newFrames[0])) { $newFrames[0]->addComment( $previousInspector->getExceptionMessage(), 'Exception message:' ); } $newFrames->prependFrames($outerFrames->topDiff($newFrames)); $this->frames = $newFrames; } // Apply frame filters callbacks on the frames stack if (!empty($frameFilters)) { foreach ($frameFilters as $filterCallback) { $this->frames->filter($filterCallback); } } } return $this->frames; } /** * Gets the backtrace from an exception. * * If xdebug is installed * * @param \Throwable $e * @return array */ protected function getTrace($e) { $traces = $e->getTrace(); // Get trace from xdebug if enabled, failure exceptions only trace to the shutdown handler by default if (!$e instanceof \ErrorException) { return $traces; } if (!Misc::isLevelFatal($e->getSeverity())) { return $traces; } if (!extension_loaded('xdebug') || !function_exists('xdebug_is_enabled') || !xdebug_is_enabled()) { return $traces; } // Use xdebug to get the full stack trace and remove the shutdown handler stack trace $stack = array_reverse(xdebug_get_function_stack()); $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); $traces = array_diff_key($stack, $trace); return $traces; } /** * Given an exception, generates an array in the format * generated by Exception::getTrace() * @param \Throwable $exception * @return array */ protected function getFrameFromException($exception) { return [ 'file' => $exception->getFile(), 'line' => $exception->getLine(), 'class' => get_class($exception), 'args' => [ $exception->getMessage(), ], ]; } /** * Given an error, generates an array in the format * generated by ErrorException * @param ErrorException $exception * @return array */ protected function getFrameFromError(ErrorException $exception) { return [ 'file' => $exception->getFile(), 'line' => $exception->getLine(), 'class' => null, 'args' => [], ]; } /** * Determine if the frame can be used to fill in previous frame's missing info * happens for call_user_func and call_user_func_array usages (PHP Bug #44428) * * @return bool */ protected function isValidNextFrame(array $frame) { if (empty($frame['file'])) { return false; } if (empty($frame['line'])) { return false; } if (empty($frame['function']) || !stristr($frame['function'], 'call_user_func')) { return false; } return true; } } PK �)[6y+"�? �? whoops/src/Whoops/Run.phpnu �[��� <?php /** * Whoops - php errors for cool kids * @author Filipe Dobreira <http://github.com/filp> */ namespace Whoops; use InvalidArgumentException; use Throwable; use Whoops\Exception\ErrorException; use Whoops\Handler\CallbackHandler; use Whoops\Handler\Handler; use Whoops\Handler\HandlerInterface; use Whoops\Inspector\CallableInspectorFactory; use Whoops\Inspector\InspectorFactory; use Whoops\Inspector\InspectorFactoryInterface; use Whoops\Inspector\InspectorInterface; use Whoops\Util\Misc; use Whoops\Util\SystemFacade; final class Run implements RunInterface { /** * @var bool */ private $isRegistered; /** * @var bool */ private $allowQuit = true; /** * @var bool */ private $sendOutput = true; /** * @var integer|false */ private $sendHttpCode = 500; /** * @var integer|false */ private $sendExitCode = 1; /** * @var HandlerInterface[] */ private $handlerStack = []; /** * @var array * @psalm-var list<array{patterns: string, levels: int}> */ private $silencedPatterns = []; /** * @var SystemFacade */ private $system; /** * In certain scenarios, like in shutdown handler, we can not throw exceptions. * * @var bool */ private $canThrowExceptions = true; /** * The inspector factory to create inspectors. * * @var InspectorFactoryInterface */ private $inspectorFactory; /** * @var array<callable> */ private $frameFilters = []; public function __construct(SystemFacade $system = null) { $this->system = $system ?: new SystemFacade; $this->inspectorFactory = new InspectorFactory(); } /** * Explicitly request your handler runs as the last of all currently registered handlers. * * @param callable|HandlerInterface $handler * * @return Run */ public function appendHandler($handler) { array_unshift($this->handlerStack, $this->resolveHandler($handler)); return $this; } /** * Explicitly request your handler runs as the first of all currently registered handlers. * * @param callable|HandlerInterface $handler * * @return Run */ public function prependHandler($handler) { return $this->pushHandler($handler); } /** * Register your handler as the last of all currently registered handlers (to be executed first). * Prefer using appendHandler and prependHandler for clarity. * * @param callable|HandlerInterface $handler * * @return Run * * @throws InvalidArgumentException If argument is not callable or instance of HandlerInterface. */ public function pushHandler($handler) { $this->handlerStack[] = $this->resolveHandler($handler); return $this; } /** * Removes and returns the last handler pushed to the handler stack. * * @see Run::removeFirstHandler(), Run::removeLastHandler() * * @return HandlerInterface|null */ public function popHandler() { return array_pop($this->handlerStack); } /** * Removes the first handler. * * @return void */ public function removeFirstHandler() { array_pop($this->handlerStack); } /** * Removes the last handler. * * @return void */ public function removeLastHandler() { array_shift($this->handlerStack); } /** * Returns an array with all handlers, in the order they were added to the stack. * * @return array */ public function getHandlers() { return $this->handlerStack; } /** * Clears all handlers in the handlerStack, including the default PrettyPage handler. * * @return Run */ public function clearHandlers() { $this->handlerStack = []; return $this; } public function getFrameFilters() { return $this->frameFilters; } public function clearFrameFilters() { $this->frameFilters = []; return $this; } /** * Registers this instance as an error handler. * * @return Run */ public function register() { if (!$this->isRegistered) { // Workaround PHP bug 42098 // https://bugs.php.net/bug.php?id=42098 class_exists("\\Whoops\\Exception\\ErrorException"); class_exists("\\Whoops\\Exception\\FrameCollection"); class_exists("\\Whoops\\Exception\\Frame"); class_exists("\\Whoops\\Exception\\Inspector"); class_exists("\\Whoops\\Inspector\\InspectorFactory"); $this->system->setErrorHandler([$this, self::ERROR_HANDLER]); $this->system->setExceptionHandler([$this, self::EXCEPTION_HANDLER]); $this->system->registerShutdownFunction([$this, self::SHUTDOWN_HANDLER]); $this->isRegistered = true; } return $this; } /** * Unregisters all handlers registered by this Whoops\Run instance. * * @return Run */ public function unregister() { if ($this->isRegistered) { $this->system->restoreExceptionHandler(); $this->system->restoreErrorHandler(); $this->isRegistered = false; } return $this; } /** * Should Whoops allow Handlers to force the script to quit? * * @param bool|int $exit * * @return bool */ public function allowQuit($exit = null) { if (func_num_args() == 0) { return $this->allowQuit; } return $this->allowQuit = (bool) $exit; } /** * Silence particular errors in particular files. * * @param array|string $patterns List or a single regex pattern to match. * @param int $levels Defaults to E_STRICT | E_DEPRECATED. * * @return Run */ public function silenceErrorsInPaths($patterns, $levels = 10240) { $this->silencedPatterns = array_merge( $this->silencedPatterns, array_map( function ($pattern) use ($levels) { return [ "pattern" => $pattern, "levels" => $levels, ]; }, (array) $patterns ) ); return $this; } /** * Returns an array with silent errors in path configuration. * * @return array */ public function getSilenceErrorsInPaths() { return $this->silencedPatterns; } /** * Should Whoops send HTTP error code to the browser if possible? * Whoops will by default send HTTP code 500, but you may wish to * use 502, 503, or another 5xx family code. * * @param bool|int $code * * @return int|false * * @throws InvalidArgumentException */ public function sendHttpCode($code = null) { if (func_num_args() == 0) { return $this->sendHttpCode; } if (!$code) { return $this->sendHttpCode = false; } if ($code === true) { $code = 500; } if ($code < 400 || 600 <= $code) { throw new InvalidArgumentException( "Invalid status code '$code', must be 4xx or 5xx" ); } return $this->sendHttpCode = $code; } /** * Should Whoops exit with a specific code on the CLI if possible? * Whoops will exit with 1 by default, but you can specify something else. * * @param int $code * * @return int * * @throws InvalidArgumentException */ public function sendExitCode($code = null) { if (func_num_args() == 0) { return $this->sendExitCode; } if ($code < 0 || 255 <= $code) { throw new InvalidArgumentException( "Invalid status code '$code', must be between 0 and 254" ); } return $this->sendExitCode = (int) $code; } /** * Should Whoops push output directly to the client? * If this is false, output will be returned by handleException. * * @param bool|int $send * * @return bool */ public function writeToOutput($send = null) { if (func_num_args() == 0) { return $this->sendOutput; } return $this->sendOutput = (bool) $send; } /** * Handles an exception, ultimately generating a Whoops error page. * * @param Throwable $exception * * @return string Output generated by handlers. */ public function handleException($exception) { // Walk the registered handlers in the reverse order // they were registered, and pass off the exception $inspector = $this->getInspector($exception); // Capture output produced while handling the exception, // we might want to send it straight away to the client, // or return it silently. $this->system->startOutputBuffering(); // Just in case there are no handlers: $handlerResponse = null; $handlerContentType = null; try { foreach (array_reverse($this->handlerStack) as $handler) { $handler->setRun($this); $handler->setInspector($inspector); $handler->setException($exception); // The HandlerInterface does not require an Exception passed to handle() // and neither of our bundled handlers use it. // However, 3rd party handlers may have already relied on this parameter, // and removing it would be possibly breaking for users. $handlerResponse = $handler->handle($exception); // Collect the content type for possible sending in the headers. $handlerContentType = method_exists($handler, 'contentType') ? $handler->contentType() : null; if (in_array($handlerResponse, [Handler::LAST_HANDLER, Handler::QUIT])) { // The Handler has handled the exception in some way, and // wishes to quit execution (Handler::QUIT), or skip any // other handlers (Handler::LAST_HANDLER). If $this->allowQuit // is false, Handler::QUIT behaves like Handler::LAST_HANDLER break; } } $willQuit = $handlerResponse == Handler::QUIT && $this->allowQuit(); } finally { $output = $this->system->cleanOutputBuffer(); } // If we're allowed to, send output generated by handlers directly // to the output, otherwise, and if the script doesn't quit, return // it so that it may be used by the caller if ($this->writeToOutput()) { // @todo Might be able to clean this up a bit better if ($willQuit) { // Cleanup all other output buffers before sending our output: while ($this->system->getOutputBufferLevel() > 0) { $this->system->endOutputBuffering(); } // Send any headers if needed: if (Misc::canSendHeaders() && $handlerContentType) { header("Content-Type: {$handlerContentType}"); } } $this->writeToOutputNow($output); } if ($willQuit) { // HHVM fix for https://github.com/facebook/hhvm/issues/4055 $this->system->flushOutputBuffer(); $this->system->stopExecution( $this->sendExitCode() ); } return $output; } /** * Converts generic PHP errors to \ErrorException instances, before passing them off to be handled. * * This method MUST be compatible with set_error_handler. * * @param int $level * @param string $message * @param string|null $file * @param int|null $line * * @return bool * * @throws ErrorException */ public function handleError($level, $message, $file = null, $line = null) { if ($level & $this->system->getErrorReportingLevel()) { foreach ($this->silencedPatterns as $entry) { $pathMatches = (bool) preg_match($entry["pattern"], $file); $levelMatches = $level & $entry["levels"]; if ($pathMatches && $levelMatches) { // Ignore the error, abort handling // See https://github.com/filp/whoops/issues/418 return true; } } // XXX we pass $level for the "code" param only for BC reasons. // see https://github.com/filp/whoops/issues/267 $exception = new ErrorException($message, /*code*/ $level, /*severity*/ $level, $file, $line); if ($this->canThrowExceptions) { throw $exception; } else { $this->handleException($exception); } // Do not propagate errors which were already handled by Whoops. return true; } // Propagate error to the next handler, allows error_get_last() to // work on silenced errors. return false; } /** * Special case to deal with Fatal errors and the like. * * @return void */ public function handleShutdown() { // If we reached this step, we are in shutdown handler. // An exception thrown in a shutdown handler will not be propagated // to the exception handler. Pass that information along. $this->canThrowExceptions = false; $error = $this->system->getLastError(); if ($error && Misc::isLevelFatal($error['type'])) { // If there was a fatal error, // it was not handled in handleError yet. $this->allowQuit = false; $this->handleError( $error['type'], $error['message'], $error['file'], $error['line'] ); } } /** * @param InspectorFactoryInterface $factory * * @return void */ public function setInspectorFactory(InspectorFactoryInterface $factory) { $this->inspectorFactory = $factory; } public function addFrameFilter($filterCallback) { if (!is_callable($filterCallback)) { throw new \InvalidArgumentException(sprintf( "A frame filter must be of type callable, %s type given.", gettype($filterCallback) )); } $this->frameFilters[] = $filterCallback; return $this; } /** * @param Throwable $exception * * @return InspectorInterface */ private function getInspector($exception) { return $this->inspectorFactory->create($exception); } /** * Resolves the giving handler. * * @param callable|HandlerInterface $handler * * @return HandlerInterface * * @throws InvalidArgumentException */ private function resolveHandler($handler) { if (is_callable($handler)) { $handler = new CallbackHandler($handler); } if (!$handler instanceof HandlerInterface) { throw new InvalidArgumentException( "Handler must be a callable, or instance of " . "Whoops\\Handler\\HandlerInterface" ); } return $handler; } /** * Echo something to the browser. * * @param string $output * * @return Run */ private function writeToOutputNow($output) { if ($this->sendHttpCode() && Misc::canSendHeaders()) { $this->system->setHttpResponseCode( $this->sendHttpCode() ); } echo $output; return $this; } } PK �)[� A � � 0 whoops/src/Whoops/Handler/XmlResponseHandler.phpnu �[��� <?php /** * Whoops - php errors for cool kids * @author Filipe Dobreira <http://github.com/filp> */ namespace Whoops\Handler; use SimpleXMLElement; use Whoops\Exception\Formatter; /** * Catches an exception and converts it to an XML * response. Additionally can also return exception * frames for consumption by an API. */ class XmlResponseHandler extends Handler { /** * @var bool */ private $returnFrames = false; /** * @param bool|null $returnFrames * @return bool|static */ public function addTraceToOutput($returnFrames = null) { if (func_num_args() == 0) { return $this->returnFrames; } $this->returnFrames = (bool) $returnFrames; return $this; } /** * @return int */ public function handle() { $response = [ 'error' => Formatter::formatExceptionAsDataArray( $this->getInspector(), $this->addTraceToOutput(), $this->getRun()->getFrameFilters() ), ]; echo self::toXml($response); return Handler::QUIT; } /** * @return string */ public function contentType() { return 'application/xml'; } /** * @param SimpleXMLElement $node Node to append data to, will be modified in place * @param array|\Traversable $data * @return SimpleXMLElement The modified node, for chaining */ private static function addDataToNode(\SimpleXMLElement $node, $data) { assert(is_array($data) || $data instanceof Traversable); foreach ($data as $key => $value) { if (is_numeric($key)) { // Convert the key to a valid string $key = "unknownNode_". (string) $key; } // Delete any char not allowed in XML element names $key = preg_replace('/[^a-z0-9\-\_\.\:]/i', '', $key); if (is_array($value)) { $child = $node->addChild($key); self::addDataToNode($child, $value); } else { $value = str_replace('&', '&', print_r($value, true)); $node->addChild($key, $value); } } return $node; } /** * The main function for converting to an XML document. * * @param array|\Traversable $data * @return string XML */ private static function toXml($data) { assert(is_array($data) || $data instanceof Traversable); $node = simplexml_load_string("<?xml version='1.0' encoding='utf-8'?><root />"); return self::addDataToNode($node, $data)->asXML(); } } PK �)[����z z % whoops/src/Whoops/Handler/Handler.phpnu �[��� <?php /** * Whoops - php errors for cool kids * @author Filipe Dobreira <http://github.com/filp> */ namespace Whoops\Handler; use Whoops\Inspector\InspectorInterface; use Whoops\RunInterface; /** * Abstract implementation of a Handler. */ abstract class Handler implements HandlerInterface { /* Return constants that can be returned from Handler::handle to message the handler walker. */ const DONE = 0x10; // returning this is optional, only exists for // semantic purposes /** * The Handler has handled the Throwable in some way, and wishes to skip any other Handler. * Execution will continue. */ const LAST_HANDLER = 0x20; /** * The Handler has handled the Throwable in some way, and wishes to quit/stop execution */ const QUIT = 0x30; /** * @var RunInterface */ private $run; /** * @var InspectorInterface $inspector */ private $inspector; /** * @var \Throwable $exception */ private $exception; /** * @param RunInterface $run */ public function setRun(RunInterface $run) { $this->run = $run; } /** * @return RunInterface */ protected function getRun() { return $this->run; } /** * @param InspectorInterface $inspector */ public function setInspector(InspectorInterface $inspector) { $this->inspector = $inspector; } /** * @return InspectorInterface */ protected function getInspector() { return $this->inspector; } /** * @param \Throwable $exception */ public function setException($exception) { $this->exception = $exception; } /** * @return \Throwable */ protected function getException() { return $this->exception; } } PK �)[�Է�� � . whoops/src/Whoops/Handler/HandlerInterface.phpnu �[��� <?php /** * Whoops - php errors for cool kids * @author Filipe Dobreira <http://github.com/filp> */ namespace Whoops\Handler; use Whoops\Inspector\InspectorInterface; use Whoops\RunInterface; interface HandlerInterface { /** * @return int|null A handler may return nothing, or a Handler::HANDLE_* constant */ public function handle(); /** * @param RunInterface $run * @return void */ public function setRun(RunInterface $run); /** * @param \Throwable $exception * @return void */ public function setException($exception); /** * @param InspectorInterface $inspector * @return void */ public function setInspector(InspectorInterface $inspector); } PK �)[BU�$H H - whoops/src/Whoops/Handler/CallbackHandler.phpnu �[��� <?php /** * Whoops - php errors for cool kids * @author Filipe Dobreira <http://github.com/filp> */ namespace Whoops\Handler; use InvalidArgumentException; /** * Wrapper for Closures passed as handlers. Can be used * directly, or will be instantiated automagically by Whoops\Run * if passed to Run::pushHandler */ class CallbackHandler extends Handler { /** * @var callable */ protected $callable; /** * @throws InvalidArgumentException If argument is not callable * @param callable $callable */ public function __construct($callable) { if (!is_callable($callable)) { throw new InvalidArgumentException( 'Argument to ' . __METHOD__ . ' must be valid callable' ); } $this->callable = $callable; } /** * @return int|null */ public function handle() { $exception = $this->getException(); $inspector = $this->getInspector(); $run = $this->getRun(); $callable = $this->callable; // invoke the callable directly, to get simpler stacktraces (in comparison to call_user_func). // this assumes that $callable is a properly typed php-callable, which we check in __construct(). return $callable($exception, $inspector, $run); } } PK �)[�*�ܤd �d / whoops/src/Whoops/Handler/PrettyPageHandler.phpnu �[��� <?php /** * Whoops - php errors for cool kids * @author Filipe Dobreira <http://github.com/filp> */ namespace Whoops\Handler; use InvalidArgumentException; use RuntimeException; use Symfony\Component\VarDumper\Cloner\AbstractCloner; use Symfony\Component\VarDumper\Cloner\VarCloner; use UnexpectedValueException; use Whoops\Exception\Formatter; use Whoops\Util\Misc; use Whoops\Util\TemplateHelper; class PrettyPageHandler extends Handler { const EDITOR_SUBLIME = "sublime"; const EDITOR_TEXTMATE = "textmate"; const EDITOR_EMACS = "emacs"; const EDITOR_MACVIM = "macvim"; const EDITOR_PHPSTORM = "phpstorm"; const EDITOR_IDEA = "idea"; const EDITOR_VSCODE = "vscode"; const EDITOR_ATOM = "atom"; const EDITOR_ESPRESSO = "espresso"; const EDITOR_XDEBUG = "xdebug"; const EDITOR_NETBEANS = "netbeans"; /** * Search paths to be scanned for resources. * * Stored in the reverse order they're declared. * * @var array */ private $searchPaths = []; /** * Fast lookup cache for known resource locations. * * @var array */ private $resourceCache = []; /** * The name of the custom css file. * * @var string|null */ private $customCss = null; /** * The name of the custom js file. * * @var string|null */ private $customJs = null; /** * @var array[] */ private $extraTables = []; /** * @var bool */ private $handleUnconditionally = false; /** * @var string */ private $pageTitle = "Whoops! There was an error."; /** * @var array[] */ private $applicationPaths; /** * @var array[] */ private $blacklist = [ '_GET' => [], '_POST' => [], '_FILES' => [], '_COOKIE' => [], '_SESSION' => [], '_SERVER' => [], '_ENV' => [], ]; /** * An identifier for a known IDE/text editor. * * Either a string, or a calalble that resolves a string, that can be used * to open a given file in an editor. If the string contains the special * substrings %file or %line, they will be replaced with the correct data. * * @example * "txmt://open?url=%file&line=%line" * * @var callable|string $editor */ protected $editor; /** * A list of known editor strings. * * @var array */ protected $editors = [ "sublime" => "subl://open?url=file://%file&line=%line", "textmate" => "txmt://open?url=file://%file&line=%line", "emacs" => "emacs://open?url=file://%file&line=%line", "macvim" => "mvim://open/?url=file://%file&line=%line", "phpstorm" => "phpstorm://open?file=%file&line=%line", "idea" => "idea://open?file=%file&line=%line", "vscode" => "vscode://file/%file:%line", "atom" => "atom://core/open/file?filename=%file&line=%line", "espresso" => "x-espresso://open?filepath=%file&lines=%line", "netbeans" => "netbeans://open/?f=%file:%line", ]; /** * @var TemplateHelper */ protected $templateHelper; /** * Constructor. * * @return void */ public function __construct() { if (ini_get('xdebug.file_link_format') || get_cfg_var('xdebug.file_link_format')) { // Register editor using xdebug's file_link_format option. $this->editors['xdebug'] = function ($file, $line) { return str_replace(['%f', '%l'], [$file, $line], ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format')); }; // If xdebug is available, use it as default editor. $this->setEditor('xdebug'); } // Add the default, local resource search path: $this->searchPaths[] = __DIR__ . "/../Resources"; // blacklist php provided auth based values $this->blacklist('_SERVER', 'PHP_AUTH_PW'); $this->templateHelper = new TemplateHelper(); if (class_exists('Symfony\Component\VarDumper\Cloner\VarCloner')) { $cloner = new VarCloner(); // Only dump object internals if a custom caster exists for performance reasons // https://github.com/filp/whoops/pull/404 $cloner->addCasters(['*' => function ($obj, $a, $stub, $isNested, $filter = 0) { $class = $stub->class; $classes = [$class => $class] + class_parents($obj) + class_implements($obj); foreach ($classes as $class) { if (isset(AbstractCloner::$defaultCasters[$class])) { return $a; } } // Remove all internals return []; }]); $this->templateHelper->setCloner($cloner); } } /** * @return int|null * * @throws \Exception */ public function handle() { if (!$this->handleUnconditionally()) { // Check conditions for outputting HTML: // @todo: Make this more robust if (PHP_SAPI === 'cli') { // Help users who have been relying on an internal test value // fix their code to the proper method if (isset($_ENV['whoops-test'])) { throw new \Exception( 'Use handleUnconditionally instead of whoops-test' .' environment variable' ); } return Handler::DONE; } } $templateFile = $this->getResource("views/layout.html.php"); $cssFile = $this->getResource("css/whoops.base.css"); $zeptoFile = $this->getResource("js/zepto.min.js"); $prismJs = $this->getResource("js/prism.js"); $prismCss = $this->getResource("css/prism.css"); $clipboard = $this->getResource("js/clipboard.min.js"); $jsFile = $this->getResource("js/whoops.base.js"); if ($this->customCss) { $customCssFile = $this->getResource($this->customCss); } if ($this->customJs) { $customJsFile = $this->getResource($this->customJs); } $inspector = $this->getInspector(); $frames = $this->getExceptionFrames(); $code = $this->getExceptionCode(); // List of variables that will be passed to the layout template. $vars = [ "page_title" => $this->getPageTitle(), // @todo: Asset compiler "stylesheet" => file_get_contents($cssFile), "zepto" => file_get_contents($zeptoFile), "prismJs" => file_get_contents($prismJs), "prismCss" => file_get_contents($prismCss), "clipboard" => file_get_contents($clipboard), "javascript" => file_get_contents($jsFile), // Template paths: "header" => $this->getResource("views/header.html.php"), "header_outer" => $this->getResource("views/header_outer.html.php"), "frame_list" => $this->getResource("views/frame_list.html.php"), "frames_description" => $this->getResource("views/frames_description.html.php"), "frames_container" => $this->getResource("views/frames_container.html.php"), "panel_details" => $this->getResource("views/panel_details.html.php"), "panel_details_outer" => $this->getResource("views/panel_details_outer.html.php"), "panel_left" => $this->getResource("views/panel_left.html.php"), "panel_left_outer" => $this->getResource("views/panel_left_outer.html.php"), "frame_code" => $this->getResource("views/frame_code.html.php"), "env_details" => $this->getResource("views/env_details.html.php"), "title" => $this->getPageTitle(), "name" => explode("\\", $inspector->getExceptionName()), "message" => $inspector->getExceptionMessage(), "previousMessages" => $inspector->getPreviousExceptionMessages(), "docref_url" => $inspector->getExceptionDocrefUrl(), "code" => $code, "previousCodes" => $inspector->getPreviousExceptionCodes(), "plain_exception" => Formatter::formatExceptionPlain($inspector), "frames" => $frames, "has_frames" => !!count($frames), "handler" => $this, "handlers" => $this->getRun()->getHandlers(), "active_frames_tab" => count($frames) && $frames->offsetGet(0)->isApplication() ? 'application' : 'all', "has_frames_tabs" => $this->getApplicationPaths(), "tables" => [ "GET Data" => $this->masked($_GET, '_GET'), "POST Data" => $this->masked($_POST, '_POST'), "Files" => isset($_FILES) ? $this->masked($_FILES, '_FILES') : [], "Cookies" => $this->masked($_COOKIE, '_COOKIE'), "Session" => isset($_SESSION) ? $this->masked($_SESSION, '_SESSION') : [], "Server/Request Data" => $this->masked($_SERVER, '_SERVER'), "Environment Variables" => $this->masked($_ENV, '_ENV'), ], ]; if (isset($customCssFile)) { $vars["stylesheet"] .= file_get_contents($customCssFile); } if (isset($customJsFile)) { $vars["javascript"] .= file_get_contents($customJsFile); } // Add extra entries list of data tables: // @todo: Consolidate addDataTable and addDataTableCallback $extraTables = array_map(function ($table) use ($inspector) { return $table instanceof \Closure ? $table($inspector) : $table; }, $this->getDataTables()); $vars["tables"] = array_merge($extraTables, $vars["tables"]); $plainTextHandler = new PlainTextHandler(); $plainTextHandler->setRun($this->getRun()); $plainTextHandler->setException($this->getException()); $plainTextHandler->setInspector($this->getInspector()); $vars["preface"] = "<!--\n\n\n" . $this->templateHelper->escape($plainTextHandler->generateResponse()) . "\n\n\n\n\n\n\n\n\n\n\n-->"; $this->templateHelper->setVariables($vars); $this->templateHelper->render($templateFile); return Handler::QUIT; } /** * Get the stack trace frames of the exception currently being handled. * * @return \Whoops\Exception\FrameCollection */ protected function getExceptionFrames() { $frames = $this->getInspector()->getFrames($this->getRun()->getFrameFilters()); if ($this->getApplicationPaths()) { foreach ($frames as $frame) { foreach ($this->getApplicationPaths() as $path) { if (strpos($frame->getFile(), $path) === 0) { $frame->setApplication(true); break; } } } } return $frames; } /** * Get the code of the exception currently being handled. * * @return string */ protected function getExceptionCode() { $exception = $this->getException(); $code = $exception->getCode(); if ($exception instanceof \ErrorException) { // ErrorExceptions wrap the php-error types within the 'severity' property $code = Misc::translateErrorCode($exception->getSeverity()); } return (string) $code; } /** * @return string */ public function contentType() { return 'text/html'; } /** * Adds an entry to the list of tables displayed in the template. * * The expected data is a simple associative array. Any nested arrays * will be flattened with `print_r`. * * @param string $label * * @return static */ public function addDataTable($label, array $data) { $this->extraTables[$label] = $data; return $this; } /** * Lazily adds an entry to the list of tables displayed in the table. * * The supplied callback argument will be called when the error is * rendered, it should produce a simple associative array. Any nested * arrays will be flattened with `print_r`. * * @param string $label * @param callable $callback Callable returning an associative array * * @throws InvalidArgumentException If $callback is not callable * * @return static */ public function addDataTableCallback($label, /* callable */ $callback) { if (!is_callable($callback)) { throw new InvalidArgumentException('Expecting callback argument to be callable'); } $this->extraTables[$label] = function (\Whoops\Inspector\InspectorInterface $inspector = null) use ($callback) { try { $result = call_user_func($callback, $inspector); // Only return the result if it can be iterated over by foreach(). return is_array($result) || $result instanceof \Traversable ? $result : []; } catch (\Exception $e) { // Don't allow failure to break the rendering of the original exception. return []; } }; return $this; } /** * Returns all the extra data tables registered with this handler. * * Optionally accepts a 'label' parameter, to only return the data table * under that label. * * @param string|null $label * * @return array[]|callable */ public function getDataTables($label = null) { if ($label !== null) { return isset($this->extraTables[$label]) ? $this->extraTables[$label] : []; } return $this->extraTables; } /** * Set whether to handle unconditionally. * * Allows to disable all attempts to dynamically decide whether to handle * or return prematurely. Set this to ensure that the handler will perform, * no matter what. * * @param bool|null $value * * @return bool|static */ public function handleUnconditionally($value = null) { if (func_num_args() == 0) { return $this->handleUnconditionally; } $this->handleUnconditionally = (bool) $value; return $this; } /** * Adds an editor resolver. * * Either a string, or a closure that resolves a string, that can be used * to open a given file in an editor. If the string contains the special * substrings %file or %line, they will be replaced with the correct data. * * @example * $run->addEditor('macvim', "mvim://open?url=file://%file&line=%line") * @example * $run->addEditor('remove-it', function($file, $line) { * unlink($file); * return "http://stackoverflow.com"; * }); * * @param string $identifier * @param string|callable $resolver * * @return static */ public function addEditor($identifier, $resolver) { $this->editors[$identifier] = $resolver; return $this; } /** * Set the editor to use to open referenced files. * * Pass either the name of a configured editor, or a closure that directly * resolves an editor string. * * @example * $run->setEditor(function($file, $line) { return "file:///{$file}"; }); * @example * $run->setEditor('sublime'); * * @param string|callable $editor * * @throws InvalidArgumentException If invalid argument identifier provided * * @return static */ public function setEditor($editor) { if (!is_callable($editor) && !isset($this->editors[$editor])) { throw new InvalidArgumentException( "Unknown editor identifier: $editor. Known editors:" . implode(",", array_keys($this->editors)) ); } $this->editor = $editor; return $this; } /** * Get the editor href for a given file and line, if available. * * @param string $filePath * @param int $line * * @throws InvalidArgumentException If editor resolver does not return a string * * @return string|bool */ public function getEditorHref($filePath, $line) { $editor = $this->getEditor($filePath, $line); if (empty($editor)) { return false; } // Check that the editor is a string, and replace the // %line and %file placeholders: if (!isset($editor['url']) || !is_string($editor['url'])) { throw new UnexpectedValueException( __METHOD__ . " should always resolve to a string or a valid editor array; got something else instead." ); } $editor['url'] = str_replace("%line", rawurlencode($line), $editor['url']); $editor['url'] = str_replace("%file", rawurlencode($filePath), $editor['url']); return $editor['url']; } /** * Determine if the editor link should act as an Ajax request. * * @param string $filePath * @param int $line * * @throws UnexpectedValueException If editor resolver does not return a boolean * * @return bool */ public function getEditorAjax($filePath, $line) { $editor = $this->getEditor($filePath, $line); // Check that the ajax is a bool if (!isset($editor['ajax']) || !is_bool($editor['ajax'])) { throw new UnexpectedValueException( __METHOD__ . " should always resolve to a bool; got something else instead." ); } return $editor['ajax']; } /** * Determines both the editor and if ajax should be used. * * @param string $filePath * @param int $line * * @return array */ protected function getEditor($filePath, $line) { if (!$this->editor || (!is_string($this->editor) && !is_callable($this->editor))) { return []; } if (is_string($this->editor) && isset($this->editors[$this->editor]) && !is_callable($this->editors[$this->editor])) { return [ 'ajax' => false, 'url' => $this->editors[$this->editor], ]; } if (is_callable($this->editor) || (isset($this->editors[$this->editor]) && is_callable($this->editors[$this->editor]))) { if (is_callable($this->editor)) { $callback = call_user_func($this->editor, $filePath, $line); } else { $callback = call_user_func($this->editors[$this->editor], $filePath, $line); } if (empty($callback)) { return []; } if (is_string($callback)) { return [ 'ajax' => false, 'url' => $callback, ]; } return [ 'ajax' => isset($callback['ajax']) ? $callback['ajax'] : false, 'url' => isset($callback['url']) ? $callback['url'] : $callback, ]; } return []; } /** * Set the page title. * * @param string $title * * @return static */ public function setPageTitle($title) { $this->pageTitle = (string) $title; return $this; } /** * Get the page title. * * @return string */ public function getPageTitle() { return $this->pageTitle; } /** * Adds a path to the list of paths to be searched for resources. * * @param string $path * * @throws InvalidArgumentException If $path is not a valid directory * * @return static */ public function addResourcePath($path) { if (!is_dir($path)) { throw new InvalidArgumentException( "'$path' is not a valid directory" ); } array_unshift($this->searchPaths, $path); return $this; } /** * Adds a custom css file to be loaded. * * @param string|null $name * * @return static */ public function addCustomCss($name) { $this->customCss = $name; return $this; } /** * Adds a custom js file to be loaded. * * @param string|null $name * * @return static */ public function addCustomJs($name) { $this->customJs = $name; return $this; } /** * @return array */ public function getResourcePaths() { return $this->searchPaths; } /** * Finds a resource, by its relative path, in all available search paths. * * The search is performed starting at the last search path, and all the * way back to the first, enabling a cascading-type system of overrides for * all resources. * * @param string $resource * * @throws RuntimeException If resource cannot be found in any of the available paths * * @return string */ protected function getResource($resource) { // If the resource was found before, we can speed things up // by caching its absolute, resolved path: if (isset($this->resourceCache[$resource])) { return $this->resourceCache[$resource]; } // Search through available search paths, until we find the // resource we're after: foreach ($this->searchPaths as $path) { $fullPath = $path . "/$resource"; if (is_file($fullPath)) { // Cache the result: $this->resourceCache[$resource] = $fullPath; return $fullPath; } } // If we got this far, nothing was found. throw new RuntimeException( "Could not find resource '$resource' in any resource paths." . "(searched: " . join(", ", $this->searchPaths). ")" ); } /** * @deprecated * * @return string */ public function getResourcesPath() { $allPaths = $this->getResourcePaths(); // Compat: return only the first path added return end($allPaths) ?: null; } /** * @deprecated * * @param string $resourcesPath * * @return static */ public function setResourcesPath($resourcesPath) { $this->addResourcePath($resourcesPath); return $this; } /** * Return the application paths. * * @return array */ public function getApplicationPaths() { return $this->applicationPaths; } /** * Set the application paths. * * @return void */ public function setApplicationPaths(array $applicationPaths) { $this->applicationPaths = $applicationPaths; } /** * Set the application root path. * * @param string $applicationRootPath * * @return void */ public function setApplicationRootPath($applicationRootPath) { $this->templateHelper->setApplicationRootPath($applicationRootPath); } /** * blacklist a sensitive value within one of the superglobal arrays. * Alias for the hideSuperglobalKey method. * * @param string $superGlobalName The name of the superglobal array, e.g. '_GET' * @param string $key The key within the superglobal * @see hideSuperglobalKey * * @return static */ public function blacklist($superGlobalName, $key) { $this->blacklist[$superGlobalName][] = $key; return $this; } /** * Hide a sensitive value within one of the superglobal arrays. * * @param string $superGlobalName The name of the superglobal array, e.g. '_GET' * @param string $key The key within the superglobal * @return static */ public function hideSuperglobalKey($superGlobalName, $key) { return $this->blacklist($superGlobalName, $key); } /** * Checks all values within the given superGlobal array. * * Blacklisted values will be replaced by a equal length string containing * only '*' characters for string values. * Non-string values will be replaced with a fixed asterisk count. * We intentionally dont rely on $GLOBALS as it depends on the 'auto_globals_jit' php.ini setting. * * @param array|\ArrayAccess $superGlobal One of the superglobal arrays * @param string $superGlobalName The name of the superglobal array, e.g. '_GET' * * @return array $values without sensitive data */ private function masked($superGlobal, $superGlobalName) { $blacklisted = $this->blacklist[$superGlobalName]; $values = $superGlobal; foreach ($blacklisted as $key) { if (isset($superGlobal[$key])) { $values[$key] = str_repeat('*', is_string($superGlobal[$key]) ? strlen($superGlobal[$key]) : 3); } } return $values; } } PK �)[��U# # . whoops/src/Whoops/Handler/PlainTextHandler.phpnu �[��� <?php /** * Whoops - php errors for cool kids * @author Filipe Dobreira <http://github.com/filp> * Plaintext handler for command line and logs. * @author Pierre-Yves Landuré <https://howto.biapy.com/> */ namespace Whoops\Handler; use InvalidArgumentException; use Psr\Log\LoggerInterface; use Whoops\Exception\Frame; /** * Handler outputing plaintext error messages. Can be used * directly, or will be instantiated automagically by Whoops\Run * if passed to Run::pushHandler */ class PlainTextHandler extends Handler { const VAR_DUMP_PREFIX = ' | '; /** * @var \Psr\Log\LoggerInterface */ protected $logger; /** * @var callable */ protected $dumper; /** * @var bool */ private $addTraceToOutput = true; /** * @var bool|integer */ private $addTraceFunctionArgsToOutput = false; /** * @var integer */ private $traceFunctionArgsOutputLimit = 1024; /** * @var bool */ private $addPreviousToOutput = true; /** * @var bool */ private $loggerOnly = false; /** * Constructor. * @throws InvalidArgumentException If argument is not null or a LoggerInterface * @param \Psr\Log\LoggerInterface|null $logger */ public function __construct($logger = null) { $this->setLogger($logger); } /** * Set the output logger interface. * @throws InvalidArgumentException If argument is not null or a LoggerInterface * @param \Psr\Log\LoggerInterface|null $logger */ public function setLogger($logger = null) { if (! (is_null($logger) || $logger instanceof LoggerInterface)) { throw new InvalidArgumentException( 'Argument to ' . __METHOD__ . " must be a valid Logger Interface (aka. Monolog), " . get_class($logger) . ' given.' ); } $this->logger = $logger; } /** * @return \Psr\Log\LoggerInterface|null */ public function getLogger() { return $this->logger; } /** * Set var dumper callback function. * * @param callable $dumper * @return static */ public function setDumper(callable $dumper) { $this->dumper = $dumper; return $this; } /** * Add error trace to output. * @param bool|null $addTraceToOutput * @return bool|static */ public function addTraceToOutput($addTraceToOutput = null) { if (func_num_args() == 0) { return $this->addTraceToOutput; } $this->addTraceToOutput = (bool) $addTraceToOutput; return $this; } /** * Add previous exceptions to output. * @param bool|null $addPreviousToOutput * @return bool|static */ public function addPreviousToOutput($addPreviousToOutput = null) { if (func_num_args() == 0) { return $this->addPreviousToOutput; } $this->addPreviousToOutput = (bool) $addPreviousToOutput; return $this; } /** * Add error trace function arguments to output. * Set to True for all frame args, or integer for the n first frame args. * @param bool|integer|null $addTraceFunctionArgsToOutput * @return static|bool|integer */ public function addTraceFunctionArgsToOutput($addTraceFunctionArgsToOutput = null) { if (func_num_args() == 0) { return $this->addTraceFunctionArgsToOutput; } if (! is_integer($addTraceFunctionArgsToOutput)) { $this->addTraceFunctionArgsToOutput = (bool) $addTraceFunctionArgsToOutput; } else { $this->addTraceFunctionArgsToOutput = $addTraceFunctionArgsToOutput; } return $this; } /** * Set the size limit in bytes of frame arguments var_dump output. * If the limit is reached, the var_dump output is discarded. * Prevent memory limit errors. * @var integer * @return static */ public function setTraceFunctionArgsOutputLimit($traceFunctionArgsOutputLimit) { $this->traceFunctionArgsOutputLimit = (integer) $traceFunctionArgsOutputLimit; return $this; } /** * Create plain text response and return it as a string * @return string */ public function generateResponse() { $exception = $this->getException(); $message = $this->getExceptionOutput($exception); if ($this->addPreviousToOutput) { $previous = $exception->getPrevious(); while ($previous) { $message .= "\n\nCaused by\n" . $this->getExceptionOutput($previous); $previous = $previous->getPrevious(); } } return $message . $this->getTraceOutput() . "\n"; } /** * Get the size limit in bytes of frame arguments var_dump output. * If the limit is reached, the var_dump output is discarded. * Prevent memory limit errors. * @return integer */ public function getTraceFunctionArgsOutputLimit() { return $this->traceFunctionArgsOutputLimit; } /** * Only output to logger. * @param bool|null $loggerOnly * @return static|bool */ public function loggerOnly($loggerOnly = null) { if (func_num_args() == 0) { return $this->loggerOnly; } $this->loggerOnly = (bool) $loggerOnly; return $this; } /** * Test if handler can output to stdout. * @return bool */ private function canOutput() { return !$this->loggerOnly(); } /** * Get the frame args var_dump. * @param \Whoops\Exception\Frame $frame [description] * @param integer $line [description] * @return string */ private function getFrameArgsOutput(Frame $frame, $line) { if ($this->addTraceFunctionArgsToOutput() === false || $this->addTraceFunctionArgsToOutput() < $line) { return ''; } // Dump the arguments: ob_start(); $this->dump($frame->getArgs()); if (ob_get_length() > $this->getTraceFunctionArgsOutputLimit()) { // The argument var_dump is to big. // Discarded to limit memory usage. ob_clean(); return sprintf( "\n%sArguments dump length greater than %d Bytes. Discarded.", self::VAR_DUMP_PREFIX, $this->getTraceFunctionArgsOutputLimit() ); } return sprintf( "\n%s", preg_replace('/^/m', self::VAR_DUMP_PREFIX, ob_get_clean()) ); } /** * Dump variable. * * @param mixed $var * @return void */ protected function dump($var) { if ($this->dumper) { call_user_func($this->dumper, $var); } else { var_dump($var); } } /** * Get the exception trace as plain text. * @return string */ private function getTraceOutput() { if (! $this->addTraceToOutput()) { return ''; } $inspector = $this->getInspector(); $frames = $inspector->getFrames($this->getRun()->getFrameFilters()); $response = "\nStack trace:"; $line = 1; foreach ($frames as $frame) { /** @var Frame $frame */ $class = $frame->getClass(); $template = "\n%3d. %s->%s() %s:%d%s"; if (! $class) { // Remove method arrow (->) from output. $template = "\n%3d. %s%s() %s:%d%s"; } $response .= sprintf( $template, $line, $class, $frame->getFunction(), $frame->getFile(), $frame->getLine(), $this->getFrameArgsOutput($frame, $line) ); $line++; } return $response; } /** * Get the exception as plain text. * @param \Throwable $exception * @return string */ private function getExceptionOutput($exception) { return sprintf( "%s: %s in file %s on line %d", get_class($exception), $exception->getMessage(), $exception->getFile(), $exception->getLine() ); } /** * @return int */ public function handle() { $response = $this->generateResponse(); if ($this->getLogger()) { $this->getLogger()->error($response); } if (! $this->canOutput()) { return Handler::DONE; } echo $response; return Handler::QUIT; } /** * @return string */ public function contentType() { return 'text/plain'; } } PK �)[kZ�= = 1 whoops/src/Whoops/Handler/JsonResponseHandler.phpnu �[��� <?php /** * Whoops - php errors for cool kids * @author Filipe Dobreira <http://github.com/filp> */ namespace Whoops\Handler; use Whoops\Exception\Formatter; /** * Catches an exception and converts it to a JSON * response. Additionally can also return exception * frames for consumption by an API. */ class JsonResponseHandler extends Handler { /** * @var bool */ private $returnFrames = false; /** * @var bool */ private $jsonApi = false; /** * Returns errors[[]] instead of error[] to be in compliance with the json:api spec * @param bool $jsonApi Default is false * @return static */ public function setJsonApi($jsonApi = false) { $this->jsonApi = (bool) $jsonApi; return $this; } /** * @param bool|null $returnFrames * @return bool|static */ public function addTraceToOutput($returnFrames = null) { if (func_num_args() == 0) { return $this->returnFrames; } $this->returnFrames = (bool) $returnFrames; return $this; } /** * @return int */ public function handle() { if ($this->jsonApi === true) { $response = [ 'errors' => [ Formatter::formatExceptionAsDataArray( $this->getInspector(), $this->addTraceToOutput(), $this->getRun()->getFrameFilters() ), ] ]; } else { $response = [ 'error' => Formatter::formatExceptionAsDataArray( $this->getInspector(), $this->addTraceToOutput(), $this->getRun()->getFrameFilters() ), ]; } echo json_encode($response, defined('JSON_PARTIAL_OUTPUT_ON_ERROR') ? JSON_PARTIAL_OUTPUT_ON_ERROR : 0); return Handler::QUIT; } /** * @return string */ public function contentType() { return 'application/json'; } } PK �)[�e5+ + 9 whoops/src/Whoops/Inspector/InspectorFactoryInterface.phpnu �[��� <?php /** * Whoops - php errors for cool kids * @author Filipe Dobreira <http://github.com/filp> */ namespace Whoops\Inspector; interface InspectorFactoryInterface { /** * @param \Throwable $exception * @return InspectorInterface */ public function create($exception); } PK �)[^>�� 2 whoops/src/Whoops/Inspector/InspectorInterface.phpnu �[��� <?php /** * Whoops - php errors for cool kids * @author Filipe Dobreira <http://github.com/filp> */ namespace Whoops\Inspector; interface InspectorInterface { /** * @return \Throwable */ public function getException(); /** * @return string */ public function getExceptionName(); /** * @return string */ public function getExceptionMessage(); /** * @return string[] */ public function getPreviousExceptionMessages(); /** * @return int[] */ public function getPreviousExceptionCodes(); /** * Returns a url to the php-manual related to the underlying error - when available. * * @return string|null */ public function getExceptionDocrefUrl(); /** * Does the wrapped Exception has a previous Exception? * @return bool */ public function hasPreviousException(); /** * Returns an Inspector for a previous Exception, if any. * @todo Clean this up a bit, cache stuff a bit better. * @return InspectorInterface */ public function getPreviousExceptionInspector(); /** * Returns an array of all previous exceptions for this inspector's exception * @return \Throwable[] */ public function getPreviousExceptions(); /** * Returns an iterator for the inspected exception's * frames. * * @param array<callable> $frameFilters * * @return \Whoops\Exception\FrameCollection */ public function getFrames(array $frameFilters = []); } PK �)[eY��� � 0 whoops/src/Whoops/Inspector/InspectorFactory.phpnu �[��� <?php /** * Whoops - php errors for cool kids * @author Filipe Dobreira <http://github.com/filp> */ namespace Whoops\Inspector; use Whoops\Exception\Inspector; class InspectorFactory implements InspectorFactoryInterface { /** * @param \Throwable $exception * @return InspectorInterface */ public function create($exception) { return new Inspector($exception, $this); } } PK �)[J�� � '