/home/preegmxb/byeaglytics-co.com/plugins/system/debug/src/DataCollector/ProfileCollector.php
<?php
/**
* This file is part of the DebugBar package.
*
* @copyright (c) 2013 Maxime Bouroumeau-Fuseau
* @license For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Joomla\Plugin\System\Debug\DataCollector;
use DebugBar\DebugBarException;
use Joomla\CMS\Profiler\Profiler;
use Joomla\Plugin\System\Debug\AbstractDataCollector;
use Joomla\Registry\Registry;
/**
* Collects info about the request duration as well as providing
* a way to log duration of any operations
*
* @since version
*/
class ProfileCollector extends AbstractDataCollector
{
/**
* Request start time.
*
* @var float
* @since 4.0.0
*/
protected $requestStartTime;
/**
* Request end time.
*
* @var float
* @since 4.0.0
*/
protected $requestEndTime;
/**
* Started measures.
*
* @var array
* @since 4.0.0
*/
protected $startedMeasures = [];
/**
* Measures.
*
* @var array
* @since 4.0.0
*/
protected $measures = [];
/**
* Constructor.
*
* @param Registry $params Parameters.
*
* @since 4.0.0
*/
public function __construct(Registry $params)
{
if (isset($_SERVER['REQUEST_TIME_FLOAT']))
{
$this->requestStartTime = $_SERVER['REQUEST_TIME_FLOAT'];
}
else
{
$this->requestStartTime = microtime(true);
}
parent::__construct($params);
}
/**
* Starts a measure.
*
* @param string $name Internal name, used to stop the measure
* @param string|null $label Public name
* @param string|null $collector The source of the collector
*
* @since 4.0.0
* @return void
*/
public function startMeasure($name, $label = null, $collector = null)
{
$start = microtime(true);
$this->startedMeasures[$name] = [
'label' => $label ?: $name,
'start' => $start,
'collector' => $collector,
];
}
/**
* Check a measure exists
*
* @param string $name Group name.
*
* @since 4.0.0
* @return bool
*/
public function hasStartedMeasure($name): bool
{
return isset($this->startedMeasures[$name]);
}
/**
* Stops a measure.
*
* @param string $name Measurement name.
* @param array $params Parameters
*
* @since 4.0.0
* @throws DebugBarException
* @return void
*/
public function stopMeasure($name, array $params = [])
{
$end = microtime(true);
if (!$this->hasStartedMeasure($name))
{
throw new DebugBarException("Failed stopping measure '$name' because it hasn't been started");
}
$this->addMeasure(
$this->startedMeasures[$name]['label'],
$this->startedMeasures[$name]['start'],
$end,
$params,
$this->startedMeasures[$name]['collector']
);
unset($this->startedMeasures[$name]);
}
/**
* Adds a measure
*
* @param string $label A label.
* @param float $start Start of request.
* @param float $end End of request.
* @param array $params Parameters.
* @param string|null $collector A collector.
*
* @since 4.0.0
* @return void
*/
public function addMeasure($label, $start, $end, array $params = [], $collector = null)
{
$this->measures[] = [
'label' => $label,
'start' => $start,
'relative_start' => $start - $this->requestStartTime,
'end' => $end,
'relative_end' => $end - $this->requestEndTime,
'duration' => $end - $start,
'duration_str' => $this->getDataFormatter()->formatDuration($end - $start),
'params' => $params,
'collector' => $collector,
];
}
/**
* Utility function to measure the execution of a Closure
*
* @param string $label A label.
* @param \Closure $closure A closure.
* @param string|null $collector A collector.
*
* @since 4.0.0
* @return void
*/
public function measure($label, \Closure $closure, $collector = null)
{
$name = spl_object_hash($closure);
$this->startMeasure($name, $label, $collector);
$result = $closure();
$params = \is_array($result) ? $result : [];
$this->stopMeasure($name, $params);
}
/**
* Returns an array of all measures
*
* @since 4.0.0
* @return array
*/
public function getMeasures(): array
{
return $this->measures;
}
/**
* Returns the request start time
*
* @since 4.0.0
* @return float
*/
public function getRequestStartTime(): float
{
return $this->requestStartTime;
}
/**
* Returns the request end time
*
* @since 4.0.0
* @return float
*/
public function getRequestEndTime(): float
{
return $this->requestEndTime;
}
/**
* Returns the duration of a request
*
* @since 4.0.0
* @return float
*/
public function getRequestDuration(): float
{
if ($this->requestEndTime !== null)
{
return $this->requestEndTime - $this->requestStartTime;
}
return microtime(true) - $this->requestStartTime;
}
/**
* Called by the DebugBar when data needs to be collected
*
* @since 4.0.0
* @return array Collected data
*/
public function collect(): array
{
$this->requestEndTime = microtime(true);
$start = $this->requestStartTime;
$marks = Profiler::getInstance('Application')->getMarks();
foreach ($marks as $mark)
{
$mem = $this->getDataFormatter()->formatBytes(abs($mark->memory) * 1048576);
$label = $mark->label . " ($mem)";
$end = $start + $mark->time / 1000;
$this->addMeasure($label, $start, $end);
$start = $end;
}
foreach (array_keys($this->startedMeasures) as $name)
{
$this->stopMeasure($name);
}
usort(
$this->measures,
function ($a, $b)
{
if ($a['start'] === $b['start'])
{
return 0;
}
return $a['start'] < $b['start'] ? -1 : 1;
}
);
return [
'start' => $this->requestStartTime,
'end' => $this->requestEndTime,
'duration' => $this->getRequestDuration(),
'duration_str' => $this->getDataFormatter()->formatDuration($this->getRequestDuration()),
'measures' => array_values($this->measures),
'rawMarks' => $marks,
];
}
/**
* Returns the unique name of the collector
*
* @since 4.0.0
* @return string
*/
public function getName(): string
{
return 'profile';
}
/**
* Returns a hash where keys are control names and their values
* an array of options as defined in {@see \DebugBar\JavascriptRenderer::addControl()}
*
* @since 4.0.0
* @return array
*/
public function getWidgets(): array
{
return [
'profileTime' => [
'icon' => 'clock-o',
'tooltip' => 'Request Duration',
'map' => 'profile.duration_str',
'default' => "'0ms'",
],
'profile' => [
'icon' => 'clock-o',
'widget' => 'PhpDebugBar.Widgets.TimelineWidget',
'map' => 'profile',
'default' => '{}',
],
];
}
}