3 namespace Drupal\webprofiler\DataCollector;
5 use Drupal\Core\Theme\ThemeManagerInterface;
6 use Drupal\Core\Theme\ThemeNegotiatorInterface;
7 use Drupal\webprofiler\DrupalDataCollectorInterface;
8 use Drupal\Core\StringTranslation\StringTranslationTrait;
9 use Drupal\webprofiler\Theme\ThemeNegotiatorWrapper;
10 use Drupal\webprofiler\Twig\Dumper\HtmlDumper;
11 use Symfony\Component\HttpFoundation\Request;
12 use Symfony\Component\HttpFoundation\Response;
13 use Symfony\Component\HttpKernel\DataCollector\DataCollector;
14 use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
17 * Class ThemeDataCollector
19 class ThemeDataCollector extends DataCollector implements DrupalDataCollectorInterface, LateDataCollectorInterface {
21 use StringTranslationTrait, DrupalDataCollectorTrait;
24 * @var \Drupal\Core\Theme\ThemeManagerInterface
26 private $themeManager;
29 * @var \Drupal\Core\Theme\ThemeNegotiatorInterface
31 private $themeNegotiator;
34 * @var \Twig_Profiler_Profile
44 * @param \Drupal\Core\Theme\ThemeManagerInterface $themeManager
45 * @param \Drupal\Core\Theme\ThemeNegotiatorInterface $themeNegotiator
46 * @param \Twig_Profiler_Profile $profile
48 public function __construct(ThemeManagerInterface $themeManager, ThemeNegotiatorInterface $themeNegotiator, \Twig_Profiler_Profile $profile) {
49 $this->themeManager = $themeManager;
50 $this->themeNegotiator = $themeNegotiator;
51 $this->profile = $profile;
57 public function collect(Request $request, Response $response, \Exception $exception = NULL) {
58 $activeTheme = $this->themeManager->getActiveTheme();
60 $this->data['activeTheme'] = [
61 'name' => $activeTheme->getName(),
62 'path' => $activeTheme->getPath(),
63 'engine' => $activeTheme->getEngine(),
64 'owner' => $activeTheme->getOwner(),
65 'baseThemes' => $activeTheme->getBaseThemes(),
66 'extension' => $activeTheme->getExtension(),
67 'styleSheetsRemove' => $activeTheme->getStyleSheetsRemove(),
68 'libraries' => $activeTheme->getLibraries(),
69 'regions' => $activeTheme->getRegions(),
72 if ($this->themeNegotiator instanceof ThemeNegotiatorWrapper) {
73 $this->data['negotiator'] = [
74 'class' => $this->getMethodData($this->themeNegotiator->getNegotiator(), 'determineActiveTheme'),
75 'id' => $this->themeNegotiator->getNegotiator()->_serviceId,
83 public function lateCollect() {
84 $this->data['twig'] = serialize($this->profile);
90 public function getActiveTheme() {
91 return $this->data['activeTheme'];
97 public function getThemeNegotiator() {
98 return $this->data['negotiator'];
104 public function getTime() {
105 return $this->getProfile()->getDuration() * 1000;
111 public function getTemplateCount() {
112 return $this->getComputedData('template_count');
118 public function getTemplates() {
119 return $this->getComputedData('templates');
125 public function getBlockCount() {
126 return $this->getComputedData('block_count');
132 public function getMacroCount() {
133 return $this->getComputedData('macro_count');
137 * @return \Twig_Markup
139 public function getHtmlCallGraph() {
140 $dumper = new HtmlDumper();
142 return new \Twig_Markup($dumper->dump($this->getProfile()), 'UTF-8');
148 public function getName() {
155 public function getTitle() {
156 return $this->t('Theme');
162 public function getPanelSummary() {
163 return $this->t('Name: @name', ['@name' => $this->getActiveTheme()['name']]);
169 public function getIcon() {
170 return 'iVBORw0KGgoAAAANSUhEUgAAABUAAAAcCAYAAACOGPReAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAlVJREFUeNrMlk1IVFEUx53K6AOjUBQri6SihQiRziaRQegDlKJFBCpSiZtoE4hWtFFRwcCVBqEWfaAE7SoXajXLQoRcFAUSaBgUJQxKYUrT78D/wevx3psaE7rw49x377ln7vl4500kmUxm/OuxJmMVxrqwzVgsth5xHKogCnthCd7BU7gdj8envOciQe5j8CyiFQq0tAgDsA+OaG0eLmF4INQoxrYg+iEXhqEGiqGBw/3SGUeU6MgC61mBMUU5GzEKJ6ES5S5knbbXui/jmv8MjCkGMxEPFbsFyAeL1y6pXEenSO4fctlIhCXqqtmGj5ADcblZoX1z8aLn/Es475soDhcyfwt3LPDK8jPYFlIcZrCCEH0LqlP7NXN/CCUL/CvmkynKcczPoNv9Y5LXuHVC2Y6mMFoetOG4/0kl9LfDquMyN076ue/I11ANHSqVH0pgLUz7GK2HjUHuf1DGm/jVYZVYJeILz5163oy46Tn/GL5r396yc+hXOzcckiyVQp7CsVNvmI2DHoODcMFcR6eZ+RO4747pJuYjcFilssMM6vB7+Or8IGMWWjDWx7ntzHvglCWZtfbf3n0UtiJ6FVO/8QbuQh+H59C37nUD9sAj1k6ENZQylctuJWsGJswDDibY32C3gitKsCUwyt7nlK0vpMc2Wh/Q4zIcxeDztDu/QjSoPmujzWswZef3GLRXuV2xPa3u/yDwjfoDgxE1nP1aquOG91b64StWlp0xtaKvKbfMUS1maukWvEj7a6pxBg6oL1iddnsbSFox/S/+TKyK0V8CDABrCdI/1oTqiQAAAABJRU5ErkJggg==';
176 public function getData() {
180 'callgraph' => (string) $this->getHtmlCallGraph(),
181 'render_time' => $this->getTime(),
182 'template_count' => $this->getTemplateCount(),
183 'templates' => $this->getTemplates(),
184 'block_count' => $this->getBlockCount(),
185 'macro_count' => $this->getMacroCount(),
192 * @return mixed|\Twig_Profiler_Profile
194 private function getProfile() {
195 if (NULL === $this->profile) {
196 $this->profile = unserialize($this->data['twig']);
199 return $this->profile;
207 private function getComputedData($index) {
208 if (NULL === $this->computed) {
209 $this->computed = $this->computeData($this->getProfile());
212 return $this->computed[$index];
216 * @param \Twig_Profiler_Profile $profile
220 private function computeData(\Twig_Profiler_Profile $profile) {
222 'template_count' => 0,
228 foreach ($profile as $p) {
229 $d = $this->computeData($p);
231 $data['template_count'] += ($p->isTemplate() ? 1 : 0) + $d['template_count'];
232 $data['block_count'] += ($p->isBlock() ? 1 : 0) + $d['block_count'];
233 $data['macro_count'] += ($p->isMacro() ? 1 : 0) + $d['macro_count'];
235 if ($p->isTemplate()) {
236 if (!isset($templates[$p->getTemplate()])) {
237 $templates[$p->getTemplate()] = 1;
240 $templates[$p->getTemplate()]++;
244 foreach ($d['templates'] as $template => $count) {
245 if (!isset($templates[$template])) {
246 $templates[$template] = $count;
249 $templates[$template] += $count;
253 $data['templates'] = $templates;