diff --git a/src/Symfony/Bundle/FrameworkBundle/Profiler/ProfilerListener.php b/src/Symfony/Bundle/FrameworkBundle/Profiler/ProfilerListener.php index 22167fdca9051..33a5b20b79fed 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Profiler/ProfilerListener.php +++ b/src/Symfony/Bundle/FrameworkBundle/Profiler/ProfilerListener.php @@ -46,6 +46,19 @@ public function __construct(ContainerInterface $container, RequestMatcherInterfa $this->onlyException = $onlyException; } + /** + * Handles the core.request event + * + * This method initialize the profiler to be able to get it as a scoped + * service when handleResponse() will collect the sub request + * + * @param EventInterface $event An EventInterface instance + */ + public function handleRequest(EventInterface $event) + { + $this->container->get('profiler'); + } + /** * Handles the core.exception event. * @@ -71,10 +84,6 @@ public function handleException(EventInterface $event) */ public function handleResponse(EventInterface $event, Response $response) { - if (HttpKernelInterface::MASTER_REQUEST !== $event->get('request_type')) { - return $response; - } - if (null !== $this->matcher && !$this->matcher->matches($event->get('request'))) { return $response; } @@ -83,7 +92,13 @@ public function handleResponse(EventInterface $event, Response $response) return $response; } - $this->container->get('profiler')->collect($event->get('request'), $response, $this->exception); + $profiler = $this->container->get('profiler'); + + if (($parent = $this->container->getCurrentScopedStack('request'))) { + $profiler->setParent($parent['request']['profiler']->getToken()); + } + + $profiler->collect($event->get('request'), $response, $this->exception); $this->exception = null; return $response; diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml index 72794e98ff23d..d2e5026818bd9 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/profiling.xml @@ -27,6 +27,7 @@ + %profiler_listener.only_exceptions% diff --git a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig index fea19f2a2b5f9..30435c246b537 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig +++ b/src/Symfony/Bundle/WebProfilerBundle/Resources/views/Collector/request.html.twig @@ -76,4 +76,21 @@ Request {% else %} No request session attributes {% endif %} + + + {% if profiler.parent %} +

Parent request: {{ profiler.parent }}

+ + {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': profiler.parenttoken.get('request').requestattributes } only %} + {% endif %} + + {% if profiler.children|length %} +

Sub requests

+ + {% for subrequest in profiler.children %} +

{{ subrequest.token }}

+ {% include 'WebProfilerBundle:Profiler:bag.html.twig' with { 'bag': subrequest.get('request').requestattributes } only %} + {% endfor %} + {% endif %} + {% endblock %} diff --git a/src/Symfony/Component/DependencyInjection/Container.php b/src/Symfony/Component/DependencyInjection/Container.php index 321fceb608854..c1ed6b40d252a 100644 --- a/src/Symfony/Component/DependencyInjection/Container.php +++ b/src/Symfony/Component/DependencyInjection/Container.php @@ -295,6 +295,22 @@ public function enterScope($name) $this->scopedServices[$name] = array(); } + + /** + * Returns the current stacked service scope for the given name + * + * @param string $name The service name + * @return array The service scope + */ + public function getCurrentScopedStack($name) + { + if (!isset($this->scopeStacks[$name]) || 0 === $this->scopeStacks[$name]->count()) { + return null; + } + + return $this->scopeStacks[$name]->current(); + } + /** * This is called to leave the current scope, and move back to the parent * scope. diff --git a/src/Symfony/Component/HttpKernel/Profiler/Profiler.php b/src/Symfony/Component/HttpKernel/Profiler/Profiler.php index 6c256b7b2868a..e82b22e83762d 100644 --- a/src/Symfony/Component/HttpKernel/Profiler/Profiler.php +++ b/src/Symfony/Component/HttpKernel/Profiler/Profiler.php @@ -35,6 +35,7 @@ class Profiler protected $url; protected $time; protected $empty; + protected $children; /** * Constructor. @@ -142,7 +143,7 @@ public function setToken($token) $this->token = $token; if (false !== $items = $this->storage->read($token)) { - list($data, $this->ip, $this->url, $this->time) = $items; + list($data, $this->parent, $this->ip, $this->url, $this->time) = $items; $this->set(unserialize(base64_decode($data))); $this->empty = false; @@ -151,6 +152,30 @@ public function setToken($token) } } + /** + * Sets the parent token + * + * @param string $parent The parent token + */ + public function setParent($parent) + { + $this->parent = $parent; + } + + /** + * Returns an instance of the parent token + * + * @return Profiler + */ + public function getParentToken() + { + if (null !== $this->parent) { + return $this->loadFromToken($this->parent); + } + + return null; + } + /** * Gets the token. * @@ -229,6 +254,23 @@ public function find($ip, $url, $limit) return $this->storage->find($ip, $url, $limit); } + /** + * Finds children profilers. + * + * @return array An array of Profiler + */ + public function getChildren() + { + if (null === $this->children) { + $this->children = array(); + foreach ($this->storage->findChildren($this->token) as $token) { + $this->children[] = $this->loadFromToken($token['token']); + } + } + + return $this->children; + } + /** * Collects data for the given Response. * @@ -248,7 +290,6 @@ public function collect(Request $request, Response $response, \Exception $except $collector->collect($request, $response, $exception); } - $this->parent = ''; $this->ip = $request->server->get('REMOTE_ADDR'); $this->url = $request->getUri(); $this->time = time(); diff --git a/src/Symfony/Component/HttpKernel/Profiler/ProfilerStorageInterface.php b/src/Symfony/Component/HttpKernel/Profiler/ProfilerStorageInterface.php index 1fbd2a0ae441c..830fa198d52a7 100644 --- a/src/Symfony/Component/HttpKernel/Profiler/ProfilerStorageInterface.php +++ b/src/Symfony/Component/HttpKernel/Profiler/ProfilerStorageInterface.php @@ -29,6 +29,15 @@ interface ProfilerStorageInterface */ function find($ip, $url, $limit); + /** + * Finds profiler tokens for the given parent token. + * + * @param string $token The parent token + * + * @return array An array of tokens + */ + function findChildren($token); + /** * Reads data associated with the given token. * diff --git a/src/Symfony/Component/HttpKernel/Profiler/SqliteProfilerStorage.php b/src/Symfony/Component/HttpKernel/Profiler/SqliteProfilerStorage.php index bc01087ac8808..fbd2fca82e474 100644 --- a/src/Symfony/Component/HttpKernel/Profiler/SqliteProfilerStorage.php +++ b/src/Symfony/Component/HttpKernel/Profiler/SqliteProfilerStorage.php @@ -56,7 +56,7 @@ public function find($ip, $url, $limit) $criteria = $criteria ? 'WHERE '.implode(' AND ', $criteria) : ''; $db = $this->initDb(); - $tokens = $this->fetch($db, 'SELECT token, ip, url, time FROM data '.$criteria.' ORDER BY time DESC LIMIT '.((integer) $limit), $args); + $tokens = $this->fetch($db, 'SELECT token, ip, url, time, parent FROM data '.$criteria.' ORDER BY time DESC LIMIT '.((integer) $limit), $args); $this->close($db); return $tokens; @@ -69,15 +69,28 @@ public function read($token) { $db = $this->initDb(); $args = array(':token' => $token); - $data = $this->fetch($db, 'SELECT data, ip, url, time FROM data WHERE token = :token LIMIT 1', $args); + $data = $this->fetch($db, 'SELECT data, parent, ip, url, time FROM data WHERE token = :token LIMIT 1', $args); $this->close($db); if (isset($data[0]['data'])) { - return array($data[0]['data'], $data[0]['ip'], $data[0]['url'], $data[0]['time']); + return array($data[0]['data'], $data[0]['parent'], $data[0]['ip'], $data[0]['url'], $data[0]['time']); } else { return false; } } + /** + * {@inheritdoc} + */ + public function findChildren($token) + { + $db = $this->initDb(); + $args = array(':token' => $token); + $tokens = $this->fetch($db, 'SELECT token FROM data WHERE parent = :token LIMIT 1', $args); + $this->close($db); + + return $tokens; + } + /** * {@inheritdoc} */ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy