Skip to content

Commit 330aa5c

Browse files
committed
Add BarOutput
1 parent c9a6d29 commit 330aa5c

9 files changed

+332
-3
lines changed

config/soar.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
*/
3131
'except' => [
3232
'*telescope*',
33+
'*horizon*',
3334
],
3435

3536
/*

src/Bootstrapper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
namespace Guanguans\LaravelSoar;
1212

1313
use Guanguans\LaravelSoar\Facades\Soar;
14-
use Guanguans\LaravelSoar\Middleware\OutputSoarScoreMiddleware;
14+
use Guanguans\LaravelSoar\Http\Middleware\OutputSoarScoreMiddleware;
1515
use Illuminate\Console\Events\CommandFinished;
1616
use Illuminate\Contracts\Container\Container;
1717
use Illuminate\Contracts\Http\Kernel;
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the guanguans/laravel-soar.
5+
*
6+
* (c) guanguans <ityaozm@gmail.com>
7+
*
8+
* This source file is subject to the MIT license that is bundled.
9+
*/
10+
11+
namespace Guanguans\LaravelSoar\Http\Controllers;
12+
13+
use DateTime;
14+
use Guanguans\LaravelSoar\SoarDebugBar;
15+
use Illuminate\Http\Response;
16+
use Illuminate\Routing\Controller;
17+
18+
/**
19+
* This is modified from the https://github.com/barryvdh/laravel-debugbar.
20+
*
21+
* @see https://github.com/barryvdh/laravel-debugbar/blob/master/src/Controllers/AssetController.php
22+
*/
23+
class AssetController extends Controller
24+
{
25+
public function __construct(SoarDebugBar $debugBar)
26+
{
27+
$this->debugBar = $debugBar;
28+
}
29+
30+
/**
31+
* Return the javascript for the DebugBar.
32+
*
33+
* @return \Symfony\Component\HttpFoundation\Response
34+
*/
35+
public function js()
36+
{
37+
$renderer = $this->debugBar->getJavascriptRenderer();
38+
$content = $renderer->dumpAssetsToString('js');
39+
$response = new Response(
40+
$content,
41+
200,
42+
['Content-Type' => 'text/javascript']
43+
);
44+
45+
return $this->cacheResponse($response);
46+
}
47+
48+
/**
49+
* Return the stylesheets for the DebugBar.
50+
*
51+
* @return \Symfony\Component\HttpFoundation\Response
52+
*/
53+
public function css()
54+
{
55+
$renderer = $this->debugBar->getJavascriptRenderer();
56+
$content = $renderer->dumpAssetsToString('css');
57+
$response = new Response(
58+
$content,
59+
200,
60+
['Content-Type' => 'text/css']
61+
);
62+
63+
return $this->cacheResponse($response);
64+
}
65+
66+
/**
67+
* Cache the response 1 year (31536000 sec).
68+
*/
69+
protected function cacheResponse(Response $response)
70+
{
71+
$response->setSharedMaxAge(31536000);
72+
$response->setMaxAge(31536000);
73+
$response->setExpires(new DateTime('+1 year'));
74+
75+
return $response;
76+
}
77+
}

src/Middleware/OutputSoarScoreMiddleware.php renamed to src/Http/Middleware/OutputSoarScoreMiddleware.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* This source file is subject to the MIT license that is bundled.
99
*/
1010

11-
namespace Guanguans\LaravelSoar\Middleware;
11+
namespace Guanguans\LaravelSoar\Http\Middleware;
1212

1313
use Closure;
1414
use Guanguans\LaravelSoar\Bootstrapper;

src/Http/routes.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the guanguans/laravel-soar.
5+
*
6+
* (c) guanguans <ityaozm@gmail.com>
7+
*
8+
* This source file is subject to the MIT license that is bundled.
9+
*/
10+
11+
$routeOptions = [
12+
'namespace' => 'Guanguans\LaravelSoar\Http\Controllers',
13+
'prefix' => app('config')->get('soar.route_prefix', 'soar-debugbar'),
14+
'domain' => app('config')->get('soar.route_domain', null),
15+
'middleware' => [],
16+
];
17+
18+
app('router')->group($routeOptions, function ($router) {
19+
$router->get('assets/stylesheets', [
20+
'uses' => 'AssetController@css',
21+
'as' => 'soar.debugbar.assets.css',
22+
]);
23+
24+
$router->get('assets/javascript', [
25+
'uses' => 'AssetController@js',
26+
'as' => 'soar.debugbar.assets.js',
27+
]);
28+
});

src/JavascriptRenderer.php

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the guanguans/laravel-soar.
5+
*
6+
* (c) guanguans <ityaozm@gmail.com>
7+
*
8+
* This source file is subject to the MIT license that is bundled.
9+
*/
10+
11+
namespace Guanguans\LaravelSoar;
12+
13+
/**
14+
* This is modified from the https://github.com/barryvdh/laravel-debugbar.
15+
*
16+
* @see https://github.com/barryvdh/laravel-debugbar/blob/master/src/JavascriptRenderer.php
17+
*/
18+
class JavascriptRenderer extends \DebugBar\JavascriptRenderer
19+
{
20+
// Use XHR handler by default, instead of jQuery
21+
protected $ajaxHandlerBindToJquery = false;
22+
23+
protected $ajaxHandlerBindToXHR = true;
24+
25+
/**
26+
* Set the URL Generator.
27+
*
28+
* @param \Illuminate\Routing\UrlGenerator $url
29+
*
30+
* @deprecated
31+
*/
32+
public function setUrlGenerator($url)
33+
{
34+
}
35+
36+
/**
37+
* {@inheritdoc}
38+
*/
39+
public function renderHead()
40+
{
41+
$cssRoute = route('soar.debugbar.assets.css', [
42+
'v' => $this->getModifiedTime('css'),
43+
'theme' => config('debugbar.theme', 'auto'),
44+
]);
45+
46+
$jsRoute = route('soar.debugbar.assets.js', [
47+
'v' => $this->getModifiedTime('js'),
48+
]);
49+
50+
$cssRoute = preg_replace('/\Ahttps?:/', '', $cssRoute);
51+
$jsRoute = preg_replace('/\Ahttps?:/', '', $jsRoute);
52+
53+
$html = "<link rel='stylesheet' type='text/css' property='stylesheet' href='{$cssRoute}'>";
54+
$html .= "<script src='{$jsRoute}'></script>";
55+
56+
if ($this->isJqueryNoConflictEnabled()) {
57+
$html .= '<script>jQuery.noConflict(true);</script>'."\n";
58+
}
59+
60+
$html .= $this->getInlineHtml();
61+
62+
return $html;
63+
}
64+
65+
protected function getInlineHtml()
66+
{
67+
$html = '';
68+
69+
foreach (['head', 'css', 'js'] as $asset) {
70+
foreach ($this->getAssets('inline_'.$asset) as $item) {
71+
$html .= $item."\n";
72+
}
73+
}
74+
75+
return $html;
76+
}
77+
78+
/**
79+
* Get the last modified time of any assets.
80+
*
81+
* @param string $type 'js' or 'css'
82+
*
83+
* @return int
84+
*/
85+
protected function getModifiedTime($type)
86+
{
87+
$files = $this->getAssets($type);
88+
89+
$latest = 0;
90+
foreach ($files as $file) {
91+
$mtime = filemtime($file);
92+
if ($mtime > $latest) {
93+
$latest = $mtime;
94+
}
95+
}
96+
97+
return $latest;
98+
}
99+
100+
/**
101+
* Return assets as a string.
102+
*
103+
* @param string $type 'js' or 'css'
104+
*
105+
* @return string
106+
*/
107+
public function dumpAssetsToString($type)
108+
{
109+
$files = $this->getAssets($type);
110+
111+
$content = '';
112+
foreach ($files as $file) {
113+
$content .= file_get_contents($file)."\n";
114+
}
115+
116+
return $content;
117+
}
118+
119+
/**
120+
* Makes a URI relative to another.
121+
*
122+
* @param string|array $uri
123+
* @param string $root
124+
*
125+
* @return array|string
126+
*/
127+
protected function makeUriRelativeTo($uri, $root)
128+
{
129+
if (! $root) {
130+
return $uri;
131+
}
132+
133+
if (is_array($uri)) {
134+
$uris = [];
135+
foreach ($uri as $u) {
136+
$uris[] = $this->makeUriRelativeTo($u, $root);
137+
}
138+
139+
return $uris;
140+
}
141+
142+
if ('/' === substr($uri ?? '', 0, 1) || preg_match('/^([a-zA-Z]+:\/\/|[a-zA-Z]:\/|[a-zA-Z]:\\\)/', $uri ?? '')) {
143+
return $uri;
144+
}
145+
146+
return rtrim($root, '/')."/$uri";
147+
}
148+
}

src/Outputs/BarOutput.php

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,59 @@
1010

1111
namespace Guanguans\LaravelSoar\Outputs;
1212

13+
use Guanguans\LaravelSoar\SoarDebugBar;
1314
use Illuminate\Support\Collection;
1415

1516
class BarOutput extends Output
1617
{
18+
public function __construct(SoarDebugBar $debugBar)
19+
{
20+
$this->debugBar = $debugBar;
21+
}
22+
1723
/**
1824
* @param \Symfony\Component\HttpFoundation\Response $response
1925
*
2026
* @return mixed
2127
*/
2228
public function output(Collection $scores, $response)
2329
{
24-
// TODO: Implement output() method.
30+
if (! $this->shouldOutputInHtmlResponse($response) || $this->shouldOutputInDebugBar($response)) {
31+
return;
32+
}
33+
34+
$debugBar = $this->debugBar;
35+
$renderer = $debugBar->getJavascriptRenderer();
36+
$scores->each(function (array $score) use ($debugBar) {
37+
$summary = $score['Summary'];
38+
$level = $score['Basic']['Level'];
39+
unset($score['Summary'], $score['Basic']);
40+
$debugBar['messages']->addMessage($summary.PHP_EOL.var_output($score, true), $level, false);
41+
});
42+
43+
$content = $response->getContent();
44+
$head = $renderer->renderHead();
45+
$widget = $renderer->render();
46+
47+
// Try to put the js/css directly before the </head>
48+
$pos = strripos($content, '</head>');
49+
if (false !== $pos) {
50+
$content = substr($content, 0, $pos).$head.substr($content, $pos);
51+
} else {
52+
// Append the head before the widget
53+
$widget = $head.$widget;
54+
}
55+
56+
// Try to put the widget at the end, directly before the </body>
57+
$pos = strripos($content, '</body>');
58+
if (false !== $pos) {
59+
$content = substr($content, 0, $pos).$widget.substr($content, $pos);
60+
} else {
61+
$content = $content.$widget;
62+
}
63+
64+
// Update the new content and reset the content length
65+
$response->setContent($content);
66+
$response->headers->remove('Content-Length');
2567
}
2668
}

src/SoarDebugBar.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the guanguans/laravel-soar.
5+
*
6+
* (c) guanguans <ityaozm@gmail.com>
7+
*
8+
* This source file is subject to the MIT license that is bundled.
9+
*/
10+
11+
namespace Guanguans\LaravelSoar;
12+
13+
use DebugBar\DataCollector\MemoryCollector;
14+
use DebugBar\DataCollector\MessagesCollector;
15+
use DebugBar\DataCollector\PhpInfoCollector;
16+
use DebugBar\DebugBar;
17+
18+
class SoarDebugBar extends DebugBar
19+
{
20+
public function __construct()
21+
{
22+
$this->addCollector(new PhpInfoCollector());
23+
$this->addCollector(new MessagesCollector());
24+
$this->addCollector(new MemoryCollector());
25+
$this->jsRenderer = new JavascriptRenderer($this);
26+
}
27+
}

src/SoarServiceProvider.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public function register()
4242
$this->registerSingletons();
4343
$this->registerSoar();
4444
$this->registerOutputManager();
45+
$this->registerRoutes();
4546
}
4647

4748
public function boot()
@@ -109,6 +110,11 @@ protected function registerOutputManager(): void
109110
$this->app->alias(OutputManager::class, 'output_manager');
110111
}
111112

113+
protected function registerRoutes(): void
114+
{
115+
$this->loadRoutesFrom(realpath(__DIR__.'/Http/routes.php'));
116+
}
117+
112118
/**
113119
* {@inheritdoc}
114120
*/

0 commit comments

Comments
 (0)