<?php
/*
* This file is part of Chevere.
*
* (c) Rodolfo Berrios <rodolfo@chevere.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Chevere\Xr {
use function Chevere\Filesystem\dirForPath;
use Chevere\Writer\Interfaces\WriterInterface;
use function Chevere\Writer\streamTemp;
use Chevere\Writer\StreamWriter;
use Chevere\Xr\Interfaces\XrInterface;
use LogicException;
use Throwable;
/**
* @codeCoverageIgnore
*/
function getWriter(): WriterInterface
{
try {
return XrWriterInstance::get();
} catch (LogicException) {
return new StreamWriter(streamTemp(''));
}
}
function getXr(): XrInterface
{
try {
return XrInstance::get();
} catch (LogicException) {
$xr = (new Xr())
->withConfigDir(
dirForPath(getcwd())
);
return (new XrInstance($xr))::get();
}
}
/**
* Register XR throwable handler.
*
* @param bool $callPrevious True to call the previous handler.
* False to disable the previous handler.
*
* @codeCoverageIgnore
*/
function registerThrowableHandler(bool $callPrevious = true): void
{
/** @var callable $xrHandler */
$xrHandler = __NAMESPACE__ . '\\throwableHandler';
$previous = set_exception_handler($xrHandler);
if ($callPrevious === false || $previous === null) {
return;
}
set_exception_handler(
function (Throwable $throwable) use ($xrHandler, $previous) {
$xrHandler($throwable);
$previous($throwable);
}
);
}
/**
* Handle a Throwable using XR.
*
* @param Throwable $throwable The throwable to handle
* @param string $extra Extra contents to append to the XR message
*
* @codeCoverageIgnore
*/
function throwableHandler(Throwable $throwable, string $extra = ''): void
{
if (getXr()->enable() === false) {
return; // @codeCoverageIgnore
}
$parser = new XrThrowableParser($throwable, $extra);
getXr()->client()
->sendMessage(
(new XrMessage(
backtrace: $parser->throwableRead()->trace(),
))
->withBody($parser->body())
->withTopic($parser->topic())
->withEmote($parser->emote())
);
}
}
namespace {
use function Chevere\Xr\getWriter;
use function Chevere\Xr\getXr;
use Chevere\Xr\Inspector\XrInspector;
use Chevere\Xr\Inspector\XrInspectorInstance;
use Chevere\Xr\Inspector\XrInspectorNull;
use Chevere\Xr\Interfaces\XrInspectorInterface;
use Chevere\Xr\XrMessage;
// @codeCoverageIgnoreStart
if (!defined('XR_BACKTRACE')) {
define('XR_BACKTRACE', 1);
}
// @codeCoverageIgnoreEnd
if (!function_exists('xr')) { // @codeCoverageIgnore
/**
* Dumps information about one or more variables to XR.
*
* ```php
* xr($foo, $bar,...);
* ```
*
* @param mixed ...$vars Variable(s) to dump
* @param string $t Topic
* @param string $e Emote
* @param int $f `XR_BACKTRACE`
*/
function xr(...$vars): void
{
if (getXr()->enable() === false) {
return; // @codeCoverageIgnore
}
$defaultArgs = ['e' => '', 't' => '', 'f' => 0];
$args = array_merge($defaultArgs, $vars);
foreach (array_keys($defaultArgs) as $name) {
if (array_key_exists($name, $vars)) {
unset($vars[$name]);
}
}
getXr()->client()
->sendMessage(
(new XrMessage(
backtrace: debug_backtrace(),
))
->withWriter(getWriter())
->withVars(...$vars)
->withTopic(strval($args['t']))
->withEmote(strval($args['e']))
->withFlags(intval($args['f']))
);
}
}
if (!function_exists('xrr')) { // @codeCoverageIgnore
/**
* Send a raw html message to XR.
*
* ```php
* xrr($html, ...);
* ```
*
* @param string $body Message to send
* @param string $t Topic
* @param string $e Emote
* @param int $f `XR_BACKTRACE`
*
* @codeCoverageIgnore
*/
function xrr(
string $body,
string $t = '',
string $e = '',
int $f = 0
): void {
if (getXr()->enable() === false) {
return;
}
getXr()->client()
->sendMessage(
(new XrMessage(
backtrace: debug_backtrace(),
))
->withWriter(getWriter())
->withBody($body)
->withTopic($t)
->withEmote($e)
->withFlags($f)
);
}
}
if (!function_exists('xri')) { // @codeCoverageIgnore
/**
* Access XR inspector to send debug information.
*
* @codeCoverageIgnore
*/
function xri(): XrInspectorInterface
{
try {
return XrInspectorInstance::get();
} catch (LogicException) {
$xrInspector = getXr()->enable()
? XrInspector::class
: XrInspectorNull::class;
$xrInspector = new $xrInspector(getXr()->client());
return (new XrInspectorInstance($xrInspector))::get();
}
}
}
}
|