mirror of
https://github.com/getgrav/grav.git
synced 2026-02-27 09:01:36 +01:00
Updated Clockwork to v5.0 [#3072]
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
* Added search option `same_as` to Flex Objects
|
||||
* Added PHP 8 compatible `function_exists()`: `Utils::functionExists()`
|
||||
* New sites have `compatibility` features turned off by default, upgrading from older versions will keep the settings on
|
||||
* Updated Clockwork to v5.0
|
||||
1. [](#improved)
|
||||
* Updated bundled JQuery to latest version `3.5.1`
|
||||
* Forward a `sid` to GPM when downloading a premium package via CLI
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
"dragonmantank/cron-expression": "^1.2",
|
||||
"phive/twig-extensions-deferred": "^1.0",
|
||||
"willdurand/negotiation": "2.x-dev",
|
||||
"itsgoingd/clockwork": "^4.1",
|
||||
"itsgoingd/clockwork": "^5.0",
|
||||
"enshrined/svg-sanitize": "~0.13",
|
||||
"symfony/http-client": "^4.4"
|
||||
},
|
||||
|
||||
20
composer.lock
generated
20
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "2bef5ff955b35b0f8f2e7f05956a18a0",
|
||||
"content-hash": "5018a33d28d9548d37318a86986c8d07",
|
||||
"packages": [
|
||||
{
|
||||
"name": "antoligy/dom-string-iterators",
|
||||
@@ -730,21 +730,21 @@
|
||||
},
|
||||
{
|
||||
"name": "itsgoingd/clockwork",
|
||||
"version": "v4.1.8",
|
||||
"version": "v5.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/itsgoingd/clockwork.git",
|
||||
"reference": "0dc2e5be39de88b18719bb4f3cdacfa605ad2146"
|
||||
"reference": "a6665903018ea5ac2d0219ccb6e9e03ed1339c3f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/itsgoingd/clockwork/zipball/0dc2e5be39de88b18719bb4f3cdacfa605ad2146",
|
||||
"reference": "0dc2e5be39de88b18719bb4f3cdacfa605ad2146",
|
||||
"url": "https://api.github.com/repos/itsgoingd/clockwork/zipball/a6665903018ea5ac2d0219ccb6e9e03ed1339c3f",
|
||||
"reference": "a6665903018ea5ac2d0219ccb6e9e03ed1339c3f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": ">=5.5",
|
||||
"php": ">=5.6",
|
||||
"psr/log": "1.*"
|
||||
},
|
||||
"type": "library",
|
||||
@@ -774,7 +774,7 @@
|
||||
"homepage": "https://twitter.com/itsgoingd"
|
||||
}
|
||||
],
|
||||
"description": "php dev tools integrated to your browser",
|
||||
"description": "php dev tools in your browser",
|
||||
"homepage": "https://underground.works/clockwork",
|
||||
"keywords": [
|
||||
"Devtools",
|
||||
@@ -785,11 +785,7 @@
|
||||
"profiling",
|
||||
"slim"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/itsgoingd/clockwork/issues",
|
||||
"source": "https://github.com/itsgoingd/clockwork/tree/v4.1.8"
|
||||
},
|
||||
"time": "2020-09-17T19:21:25+00:00"
|
||||
"time": "2020-11-22T00:14:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "kodus/psr7-server",
|
||||
|
||||
@@ -38,6 +38,7 @@ use Psr\Http\Message\ServerRequestInterface;
|
||||
use ReflectionObject;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Throwable;
|
||||
use Twig\Environment;
|
||||
use Twig\Template;
|
||||
use Twig\TemplateWrapper;
|
||||
use function array_slice;
|
||||
@@ -162,16 +163,17 @@ class Debugger
|
||||
$clockwork->addDataSource(new MonologDataSource($log));
|
||||
}
|
||||
|
||||
$clockwork->addDataSource(new TwigClockworkDataSource());
|
||||
|
||||
$timeLine = $clockwork->getTimeline();
|
||||
$timeline = $clockwork->timeline();
|
||||
if ($this->requestTime !== GRAV_REQUEST_TIME) {
|
||||
$timeLine->addEvent('server', 'Server', $this->requestTime, GRAV_REQUEST_TIME);
|
||||
$event = $timeline->event('Server');
|
||||
$event->finalize($this->requestTime, GRAV_REQUEST_TIME);
|
||||
}
|
||||
if ($this->currentTime !== GRAV_REQUEST_TIME) {
|
||||
$timeLine->addEvent('loading', 'Loading', GRAV_REQUEST_TIME, $this->currentTime);
|
||||
$event = $timeline->event('Loading');
|
||||
$event->finalize(GRAV_REQUEST_TIME, $this->currentTime);
|
||||
}
|
||||
$timeLine->addEvent('setup', 'Site Setup', $this->currentTime, microtime(true));
|
||||
$event = $timeline->event('Site Setup');
|
||||
$event->finalize($this->currentTime, microtime(true));
|
||||
}
|
||||
|
||||
if ($this->censored) {
|
||||
@@ -253,7 +255,7 @@ class Debugger
|
||||
|
||||
$this->finalize();
|
||||
|
||||
$clockwork->getTimeline()->finalize($request->getAttribute('request_time'));
|
||||
$clockwork->timeline()->finalize($request->getAttribute('request_time'));
|
||||
|
||||
if ($this->censored) {
|
||||
$censored = 'CENSORED';
|
||||
@@ -344,21 +346,20 @@ class Debugger
|
||||
}
|
||||
|
||||
$nowTime = microtime(true);
|
||||
$clkTimeLine = $this->clockwork ? $this->clockwork->getTimeline() : null;
|
||||
$clkTimeLine = $this->clockwork ? $this->clockwork->timeline() : null;
|
||||
$debTimeLine = $this->debugbar ? $this->debugbar['time'] : null;
|
||||
foreach ($this->timers as $name => $data) {
|
||||
$description = $data[0];
|
||||
$startTime = $data[1] ?? null;
|
||||
$endTime = $data[2] ?? $nowTime;
|
||||
if ($endTime - $startTime < 0.001) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($clkTimeLine) {
|
||||
$clkTimeLine->addEvent($name, $description ?? $name, $startTime, $endTime);
|
||||
}
|
||||
$event = $clkTimeLine->event($description);
|
||||
$event->finalize($startTime, $endTime);
|
||||
} elseif ($debTimeLine) {
|
||||
if ($endTime - $startTime < 0.001) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($debTimeLine) {
|
||||
$debTimeLine->addMeasure($description ?? $name, $startTime, $endTime);
|
||||
}
|
||||
}
|
||||
@@ -412,7 +413,7 @@ class Debugger
|
||||
$this->renderer = $this->debugbar->getJavascriptRenderer();
|
||||
$this->renderer->setIncludeVendors(false);
|
||||
|
||||
list($css_files, $js_files) = $this->renderer->getAssets(null, JavascriptRenderer::RELATIVE_URL);
|
||||
[$css_files, $js_files] = $this->renderer->getAssets(null, JavascriptRenderer::RELATIVE_URL);
|
||||
|
||||
foreach ((array)$css_files as $css) {
|
||||
$assets->addCss($css);
|
||||
@@ -545,6 +546,16 @@ class Debugger
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function addTwigProfiler(Environment $twig): void
|
||||
{
|
||||
$clockwork = $this->getClockwork();
|
||||
if ($clockwork) {
|
||||
$source = new TwigClockworkDataSource($twig);
|
||||
$source->listenToEvents();
|
||||
$clockwork->addDataSource($source);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start profiling code.
|
||||
*
|
||||
@@ -756,20 +767,18 @@ class Debugger
|
||||
*/
|
||||
public function addEvent(string $name, $event, EventDispatcherInterface $dispatcher)
|
||||
{
|
||||
if ($this->enabled) {
|
||||
if ($this->clockwork) {
|
||||
$data = null;
|
||||
if ($event && method_exists($event, '__debugInfo')) {
|
||||
$data = $event;
|
||||
}
|
||||
|
||||
$listeners = [];
|
||||
foreach ($dispatcher->getListeners($name) as $listener) {
|
||||
$listeners[] = $this->resolveCallable($listener);
|
||||
}
|
||||
|
||||
$this->clockwork->addEvent($name, $data, microtime(true), ['listeners' => $listeners]);
|
||||
if ($this->enabled && $this->clockwork) {
|
||||
$data = null;
|
||||
if ($event && method_exists($event, '__debugInfo')) {
|
||||
$data = $event;
|
||||
}
|
||||
|
||||
$listeners = [];
|
||||
foreach ($dispatcher->getListeners($name) as $listener) {
|
||||
$listeners[] = $this->resolveCallable($listener);
|
||||
}
|
||||
|
||||
$this->clockwork->addEvent($name, $data, microtime(true), ['listeners' => $listeners]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
||||
@@ -461,10 +461,11 @@ class Grav extends Container
|
||||
{
|
||||
/** @var EventDispatcherInterface $events */
|
||||
$events = $this['events'];
|
||||
$eventName = get_class($event);
|
||||
|
||||
/** @var Debugger $debugger */
|
||||
$debugger = $this['debugger'];
|
||||
$debugger->addEvent(get_class($event), $event, $events);
|
||||
$debugger->addEvent($eventName, $event, $events);
|
||||
|
||||
return $events->dispatch($event);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
namespace Grav\Common\Twig;
|
||||
|
||||
use Grav\Common\Debugger;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Language\Language;
|
||||
@@ -24,7 +25,6 @@ use Twig\Environment;
|
||||
use Twig\Error\LoaderError;
|
||||
use Twig\Extension\CoreExtension;
|
||||
use Twig\Extension\DebugExtension;
|
||||
use Twig\Extension\ProfilerExtension;
|
||||
use Twig\Extension\StringLoaderExtension;
|
||||
use Twig\Loader\ArrayLoader;
|
||||
use Twig\Loader\ChainLoader;
|
||||
@@ -192,8 +192,9 @@ class Twig
|
||||
$this->twig->addExtension(new DeferredExtension());
|
||||
$this->twig->addExtension(new StringLoaderExtension());
|
||||
|
||||
$this->profile = new Profile();
|
||||
$this->twig->addExtension(new ProfilerExtension($this->profile));
|
||||
/** @var Debugger $debugger */
|
||||
$debugger = $this->grav['debugger'];
|
||||
$debugger->addTwigProfiler($this->twig);
|
||||
|
||||
$this->grav->fireEvent('onTwigExtensions');
|
||||
|
||||
|
||||
@@ -11,8 +11,9 @@ namespace Grav\Common\Twig;
|
||||
|
||||
use Clockwork\DataSource\DataSource;
|
||||
use Clockwork\Request\Request;
|
||||
use Clockwork\Request\Timeline;
|
||||
use Grav\Common\Grav;
|
||||
use Twig\Environment;
|
||||
use Twig\Extension\ProfilerExtension;
|
||||
use Twig\Profiler\Profile;
|
||||
|
||||
/**
|
||||
* Class TwigClockworkDataSource
|
||||
@@ -20,33 +21,37 @@ use Grav\Common\Grav;
|
||||
*/
|
||||
class TwigClockworkDataSource extends DataSource
|
||||
{
|
||||
/** @var Timeline Views data structure */
|
||||
protected $views;
|
||||
/** @var Environment */
|
||||
protected $twig;
|
||||
|
||||
/**
|
||||
* TwigClockworkDataSource constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
/** @var Profile */
|
||||
protected $profile;
|
||||
|
||||
// Create a new data source, takes Twig instance as an argument
|
||||
public function __construct(Environment $twig)
|
||||
{
|
||||
$this->views = new Timeline();
|
||||
$this->twig = $twig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves and adds the Twig profiler data to the request
|
||||
* Register the Twig profiler extension
|
||||
*/
|
||||
public function listenToEvents(): void
|
||||
{
|
||||
$this->twig->addExtension(new ProfilerExtension($this->profile = new Profile()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds rendered views to the request
|
||||
*
|
||||
* @param Request $request
|
||||
* @return Request
|
||||
*/
|
||||
public function resolve(Request $request)
|
||||
{
|
||||
$profile = Grav::instance()['twig']->profile();
|
||||
$timeline = (new TwigClockworkDumper())->dump($this->profile);
|
||||
|
||||
if ($profile) {
|
||||
$processor = new TwigProfileProcessor();
|
||||
|
||||
$processor->process($profile, $this->views);
|
||||
$request->viewsData = $this->views->finalize();
|
||||
}
|
||||
$request->viewsData = array_merge($request->viewsData, $timeline->finalize());
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
72
system/src/Grav/Common/Twig/TwigClockworkDumper.php
Normal file
72
system/src/Grav/Common/Twig/TwigClockworkDumper.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav\Common\Twig
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2020 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Common\Twig;
|
||||
|
||||
use Clockwork\Request\Timeline\Timeline;
|
||||
use Twig\Profiler\Profile;
|
||||
|
||||
/**
|
||||
* Class TwigClockworkDumper
|
||||
* @package Grav\Common\Twig
|
||||
*/
|
||||
class TwigClockworkDumper
|
||||
{
|
||||
protected $lastId = 1;
|
||||
|
||||
/**
|
||||
* Dumps a profile into a new rendered views timeline
|
||||
*
|
||||
* @param Profile $profile
|
||||
* @return Timeline
|
||||
*/
|
||||
public function dump(Profile $profile)
|
||||
{
|
||||
$timeline = new Timeline;
|
||||
|
||||
$this->dumpProfile($profile, $timeline);
|
||||
|
||||
return $timeline;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profile $profile
|
||||
* @param Timeline $timeline
|
||||
* @param null $parent
|
||||
*/
|
||||
public function dumpProfile(Profile $profile, Timeline $timeline, $parent = null)
|
||||
{
|
||||
$id = $this->lastId++;
|
||||
|
||||
if ($profile->isRoot()) {
|
||||
$name = $profile->getName();
|
||||
} elseif ($profile->isTemplate()) {
|
||||
$name = $profile->getTemplate();
|
||||
} else {
|
||||
$name = $profile->getTemplate() . '::' . $profile->getType() . '(' . $profile->getName() . ')';
|
||||
}
|
||||
|
||||
foreach ($profile as $p) {
|
||||
$this->dumpProfile($p, $timeline, $id);
|
||||
}
|
||||
|
||||
$data = $profile->__serialize();
|
||||
|
||||
$timeline->event($name, [
|
||||
'name' => $id,
|
||||
'start' => $data[3]['wt'] ?? null,
|
||||
'end' => $data[4]['wt'] ?? null,
|
||||
'data' => [
|
||||
'data' => [],
|
||||
'memoryUsage' => $data[4]['mu'] ?? null,
|
||||
'parent' => $parent
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav\Common\Twig
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2020 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Common\Twig;
|
||||
|
||||
use Grav\Common\Utils;
|
||||
use Twig\Profiler\Profile;
|
||||
use Clockwork\Request\Timeline;
|
||||
|
||||
/**
|
||||
* Class TwigProfileProcessor
|
||||
* @package Grav\Common\Twig
|
||||
*/
|
||||
class TwigProfileProcessor
|
||||
{
|
||||
/** @var float */
|
||||
private $root;
|
||||
|
||||
/**
|
||||
* @param Profile $profile
|
||||
* @param Timeline $views
|
||||
* @param int $counter
|
||||
* @param string $prefix
|
||||
* @param false $sibling
|
||||
* @return void
|
||||
*/
|
||||
public function process(Profile $profile, Timeline $views, $counter = 0, $prefix = '', $sibling = false)
|
||||
{
|
||||
if ($profile->isRoot()) {
|
||||
$this->root = $profile->getDuration();
|
||||
$name = $profile->getName();
|
||||
} else {
|
||||
if ($profile->isTemplate()) {
|
||||
$name = $this->formatTemplate($profile, $prefix);
|
||||
} else {
|
||||
$name = $this->formatNonTemplate($profile, $prefix);
|
||||
}
|
||||
$prefix .= '⎯⎯';
|
||||
}
|
||||
|
||||
$percent = $this->root ? $profile->getDuration() / $this->root * 100 : 0;
|
||||
|
||||
$data = [
|
||||
'tm' => $this->formatTime($profile, $percent),
|
||||
'mu' => Utils::prettySize($profile->getMemoryUsage())
|
||||
];
|
||||
|
||||
if ($profile->isRoot()) {
|
||||
$data += ['pmu' => Utils::prettySize($profile->getPeakMemoryUsage())];
|
||||
}
|
||||
|
||||
|
||||
$views->addEvent(
|
||||
$counter,
|
||||
$profile->getTemplate(),
|
||||
0,
|
||||
$profile->getDuration(),
|
||||
[ 'name' => $name, 'data' => $data ]
|
||||
);
|
||||
|
||||
$nCount = count($profile->getProfiles());
|
||||
foreach ($profile as $i => $p) {
|
||||
$this->process($p, $views, ++$counter, $prefix, $i + 1 !== $nCount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profile $profile
|
||||
* @param string $prefix
|
||||
* @return string
|
||||
*/
|
||||
protected function formatTemplate(Profile $profile, $prefix)
|
||||
{
|
||||
return sprintf('%s⤍ %s', $prefix, $profile->getTemplate());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profile $profile
|
||||
* @param string $prefix
|
||||
* @return string
|
||||
*/
|
||||
protected function formatNonTemplate(Profile $profile, $prefix)
|
||||
{
|
||||
return sprintf('%s⤍ %s::%s(%s)', $prefix, $profile->getTemplate(), $profile->getType(), $profile->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Profile $profile
|
||||
* @param float $percent
|
||||
* @return string
|
||||
*/
|
||||
protected function formatTime(Profile $profile, $percent)
|
||||
{
|
||||
return sprintf('%.2fms/%.0f%%', $profile->getDuration() * 1000, $percent);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user