Skip to content

Commit

Permalink
Merge pull request ezsystems#1129 from ezsystems/fix_EZP-23864_fixLeg…
Browse files Browse the repository at this point in the history
…acyDebugBundle

Fix EZP-23864: Fix coupling with legacy in debug bundle
  • Loading branch information
lolautruche committed Jan 13, 2015
2 parents 96f48df + 27bbe23 commit cbae7e0
Show file tree
Hide file tree
Showing 21 changed files with 765 additions and 225 deletions.
54 changes: 54 additions & 0 deletions doc/specifications/debug/data_collectors.md
@@ -0,0 +1,54 @@
# eZ data collectors

Symfony profiler let any bundle register *data collectors* and displayed collected data in the web profiler toolbar
and debug panel. eZ has its own data collector.

## Extensibility
As of v6.0, it is possible to display custom collected data under eZ toolbar / panel.
The main data collector has been splitted into several dedicated ones and now only aggregates data collected by
registered sub-collectors.

## Native data collectors
Following data collectors are part of `EzPublishDebugBundle`:

* `PersistenceCacheCollector`: Collects information on persistence cache (aka SPI cache) efficiency (hits/miss).
* `TemplatesDataCollector`: Collects information on loaded templates.

## Custom data collector
For data to appear under eZ toolbar / panel, it is only needed to write a service implementing
`Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface`, or simply extending `Symfony\Component\HttpKernel\DataCollector\DataCollector`.

This service, instead of being tagged as `data_collector`, needs to be tagged as `ezpublish_data_collector`.
This service tag takes 2 additional arguments indicating which template(s) to use for displaying collected data in the
toolbar and/or panel. Those templates will be *included* by the main eZ data collector, exposing your collector object,
like for any regular data collector.

### Example
```yml
parameters:
ezpublish_debug.persistence_collector.class: eZ\Bundle\EzPublishDebugBundle\Collector\PersistenceCacheCollector
ezpublish_debug.templates_collector.class: eZ\Bundle\EzPublishDebugBundle\Collector\TemplatesDataCollector

services:
ezpublish_debug.persistence_collector:
class: %ezpublish_debug.persistence_collector.class%
arguments: [@ezpublish.spi.persistence.cache.persistenceLogger]
tags:
-
name: ezpublish_data_collector
id: "ezpublish.debug.persistence"
panelTemplate: "EzPublishDebugBundle:Profiler/persistence:panel.html.twig"
toolbarTemplate: "EzPublishDebugBundle:Profiler/persistence:toolbar.html.twig"

ezpublish_debug.templates_collector:
class: %ezpublish_debug.templates_collector.class%
tags:
-
name: ezpublish_data_collector
panelTemplate: "EzPublishDebugBundle:Profiler/templates:panel.html.twig"
toolbarTemplate: "EzPublishDebugBundle:Profiler/templates:toolbar.html.twig"

```

For further example, refer to [`PersistenceCacheCollector`](https://github.com/ezsystems/ezpublish-kernel/blob/master/eZ/Bundle/EzPublishDebugBundle/Collector/PersistenceCacheCollector.php)
or [`TemplatesDataCollector`](https://github.com/ezsystems/ezpublish-kernel/blob/master/eZ/Bundle/EzPublishDebugBundle/Collector/TemplatesDataCollector.php) implementation.
112 changes: 112 additions & 0 deletions eZ/Bundle/EzPublishDebugBundle/Collector/EzPublishCoreCollector.php
@@ -0,0 +1,112 @@
<?php
/**
* File containing the EzPublishDataCollector class.
*
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
* @version //autogentag//
*/

namespace eZ\Bundle\EzPublishDebugBundle\Collector;

use Symfony\Component\HttpKernel\DataCollector\DataCollector;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use InvalidArgumentException;
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;

class EzPublishCoreCollector extends DataCollector
{
public function __construct()
{
$this->data = [
'collectors' => [],
'panelTemplates' => [],
'toolbarTemplates' => []
];
}

public function collect( Request $request, Response $response, \Exception $exception = null )
{
/** @var DataCollectorInterface $innerCollector */
foreach ( $this->data['collectors'] as $innerCollector )
{
$innerCollector->collect( $request, $response, $exception );
}
}

public function getName()
{
return 'ezpublish.debug.toolbar';
}

/**
* @param DataCollectorInterface $collector
*/
public function addCollector( DataCollectorInterface $collector, $panelTemplate = null, $toolbarTemplate = null )
{
$name = $collector->getName();
$this->data['collectors'][$name] = $collector;
$this->data['panelTemplates'][$name] = $panelTemplate;
$this->data['toolbarTemplates'][$name] = $toolbarTemplate;
}

/**
* @param string $name Name of the collector
*
* @return DataCollectorInterface
*
* @throws \InvalidArgumentException
*/
public function getCollector( $name )
{
if ( !isset( $this->data['collectors'][$name] ) )
{
throw new InvalidArgumentException( "Invalid debug collector '$name'" );
}

return $this->data['collectors'][$name];
}

/**
* @return DataCollectorInterface[]
*/
public function getAllCollectors()
{
return $this->data['collectors'];
}

/**
* Returns toolbar template for given collector name.
*
* @param string $collectorName Name of corresponding collector.
*
* @return string
*/
public function getToolbarTemplate( $collectorName )
{
if ( !isset( $this->data['toolbarTemplates'][$collectorName] ) )
{
return null;
}

return $this->data['toolbarTemplates'][$collectorName];
}

/**
* Returns panel template to use for given collector name.
*
* @param string $collectorName Name of corresponding collector.
*
* @return string
*/
public function getPanelTemplate( $collectorName )
{
if ( !isset( $this->data['panelTemplates'][$collectorName] ) )
{
return null;
}

return $this->data['panelTemplates'][$collectorName];
}
}
@@ -1,6 +1,6 @@
<?php
/**
* File containing the EzPublishDataCollector class.
* This file is part of the eZ Publish Kernel package.
*
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
Expand All @@ -9,67 +9,39 @@

namespace eZ\Bundle\EzPublishDebugBundle\Collector;

use Symfony\Component\HttpKernel\DataCollector\DataCollector;
use eZ\Publish\Core\Persistence\Cache\PersistenceLogger;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use eZ\Publish\Core\Persistence\Cache\PersistenceLogger;
use Symfony\Component\HttpKernel\DataCollector\DataCollector;

/**
* Collects list of templates from eZ 5 stack or Legacy Stack
* Collects number of calls made to SPI Persistence as logged by eZ\Publish\Core\Persistence\Cache\*.
* Data collector listing SPI cache calls.
*/
class EzPublishDataCollector extends DataCollector
class PersistenceCacheCollector extends DataCollector
{
/**
* @var \eZ\Publish\Core\Persistence\Cache\PersistenceLogger
* @var PersistenceLogger
*/
protected $logger;
private $logger;

/**
* @var \Closure
*/
protected $legacyKernel;

/**
* @param \eZ\Publish\Core\Persistence\Cache\PersistenceLogger $logger
*/
public function __construct( PersistenceLogger $logger, \Closure $legacyKernel )
public function __construct( PersistenceLogger $logger )
{
$this->logger = $logger;
$this->legacyKernel = $legacyKernel;
}

/**
* Collects data for the given Request and Response.
*
* @param Request $request A Request instance
* @param Response $response A Response instance
* @param \Exception $exception An Exception instance
*
* @api
*/
public function collect( Request $request, Response $response, \Exception $exception = null )
{
$this->data = array(
$this->data = [
'count' => $this->logger->getCount(),
'calls_logging_enabled' => $this->logger->isCallsLoggingEnabled(),
'calls' => $this->logger->getCalls(),
'handlers' => $this->logger->getLoadedUnCachedHandlers(),
'templates' => TemplateDebugInfo::getTemplatesList(),
'legacy_templates' => TemplateDebugInfo::getLegacyTemplatesList( $this->legacyKernel )
);
];
}

/**
* Returns the name of the collector.
*
* @return string The collector name
*
* @api
*/
public function getName()
{
return 'ezpublish.debug.toolbar';
return 'ezpublish.debug.persistence';
}

/**
Expand Down Expand Up @@ -101,7 +73,7 @@ public function getCallsLoggingEnabled()
*/
public function getCalls()
{
$calls = array();
$calls = [];
foreach ( $this->data['calls'] as $call )
{
list( $class, $method ) = explode( '::', $call['method'] );
Expand All @@ -126,7 +98,7 @@ public function getCalls()
*/
public function getHandlers()
{
$handlers = array();
$handlers = [];
foreach ( $this->data['handlers'] as $handler => $count )
{
list( $class, $method ) = explode( '::', $handler );
Expand All @@ -145,24 +117,4 @@ public function getHandlersCount()
{
return array_sum( $this->data['handlers'] );
}

/**
* Returns templates list
*
* @return array
*/
public function getTemplates()
{
return $this->data['templates'];
}

/**
* Returns templates list
*
* @return array
*/
public function getLegacyTemplates()
{
return $this->data['legacy_templates'];
}
}
69 changes: 1 addition & 68 deletions eZ/Bundle/EzPublishDebugBundle/Collector/TemplateDebugInfo.php
@@ -1,6 +1,6 @@
<?php
/**
* File containing the DebugKernel class.
* This file is part of the eZ Publish Kernel package.
*
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
Expand All @@ -9,18 +9,8 @@

namespace eZ\Bundle\EzPublishDebugBundle\Collector;

use eZ\Publish\Core\MVC\Legacy\Kernel as LegacyKernel;
use eZTemplate;
use ezxFormToken;
use RuntimeException;

/**
* Class TemplateDebugInfo
* @package eZ\Bundle\EzPublishCoreBundle\Collector
*
*
* Holds debug info about twig templates and exposes function to get legacy template info
* @todo Move legacy code to LegacyBundle, and then consider moving left overs to DebugTemplate class (rename TwigDebugTemplate?)
*/
class TemplateDebugInfo
{
Expand Down Expand Up @@ -62,61 +52,4 @@ public static function getTemplatesList()
{
return self::$templateList;
}

/**
* Returns array of loaded legacy templates
*
* @param \Closure $legacyKernel
*
* @return array
*/
public static function getLegacyTemplatesList( \Closure $legacyKernel )
{
$templateList = array( 'compact' => array(), 'full' => array() );
// Only retrieve legacy templates list if the kernel has been booted at least once.
if ( !LegacyKernel::hasInstance() )
{
return $templateList;
}

try
{
$templateStats = $legacyKernel()->runCallback(
function ()
{
return eZTemplate::templatesUsageStatistics();
},
false,
false
);
}
catch ( RuntimeException $e )
{
// Ignore the exception thrown by legacy kernel as this would break debug toolbar (and thus debug info display).
// Furthermore, some legacy kernel handlers don't support runCallback (e.g. ezpKernelTreeMenu)
$templateStats = array();
}

foreach ( $templateStats as $tplInfo )
{
$requestedTpl = $tplInfo["requested-template-name"];
$actualTpl = $tplInfo["actual-template-name"];
$fullPath = $tplInfo["template-filename"];

$templateList["full"][$actualTpl] = array(
"loaded" => $requestedTpl,
"fullPath" => $fullPath
);
if ( !isset( $templateList["compact"][$actualTpl] ) )
{
$templateList["compact"][$actualTpl] = 1;
}
else
{
$templateList["compact"][$actualTpl]++;
}
}

return $templateList;
}
}

0 comments on commit cbae7e0

Please sign in to comment.