DevelEventSubscriber.php
6.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
<?php
/**
* @file
* Contains \Drupal\devel\EventSubscriber\DevelEventSubscriber.
*/
namespace Drupal\devel\EventSubscriber;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Database\Database;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Page\DefaultHtmlPageRenderer;
use Drupal\Core\Routing\UrlGeneratorInterface;
use Drupal\Core\Session\AccountInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
class DevelEventSubscriber implements EventSubscriberInterface {
/**
* The devel.settings config object.
*
* @var \Drupal\Core\Config\Config;
*/
protected $config;
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $account;
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* @var \Drupal\Core\Routing\UrlGeneratorInterface
*/
protected $urlGenerator;
/**
* Constructs a DevelEventSubscriber object.
*/
public function __construct(ConfigFactoryInterface $config, AccountInterface $account, ModuleHandlerInterface $module_handler, UrlGeneratorInterface $url_generator) {
$this->config = $config->get('devel.settings');
$this->account = $account;
$this->moduleHandler = $module_handler;
$this->urlGenerator = $url_generator;
}
/**
* Initializes devel module requirements.
*/
public function onRequest(GetResponseEvent $event) {
if (!devel_silent()) {
if ($this->config->get('memory')) {
global $memory_init;
$memory_init = memory_get_usage();
}
if (devel_query_enabled()) {
Database::startLog('devel');
}
if ($this->account->hasPermission('access devel information')) {
devel_set_handler(devel_get_handlers());
// We want to include the class early so that anyone may call krumo()
// as needed. See http://krumo.sourceforge.net/
has_krumo();
// See http://www.firephp.org/HQ/Install.htm
$path = NULL;
if ((@include_once 'fb.php') || (@include_once 'FirePHPCore/fb.php')) {
// FirePHPCore is in include_path. Probably a PEAR installation.
$path = '';
}
elseif ($this->moduleHandler->moduleExists('libraries')) {
// Support Libraries API - http://drupal.org/project/libraries
$firephp_path = libraries_get_path('FirePHPCore');
$firephp_path = ($firephp_path ? $firephp_path . '/lib/FirePHPCore/' : '');
$chromephp_path = libraries_get_path('chromephp');
}
else {
$firephp_path = DRUPAL_ROOT . '/libraries/FirePHPCore/lib/FirePHPCore/';
$chromephp_path = './' . drupal_get_path('module', 'devel') . '/chromephp';
}
// Include FirePHP if it exists.
if (!empty($firephp_path) && file_exists($firephp_path . 'fb.php')) {
include_once $firephp_path . 'fb.php';
include_once $firephp_path . 'FirePHP.class.php';
}
// Include ChromePHP if it exists.
if (!empty($chromephp_path) && file_exists($chromephp_path .= '/ChromePhp.php')) {
include_once $chromephp_path;
}
}
}
if ($this->config->get('rebuild_theme')) {
drupal_theme_rebuild();
// Ensure that the active theme object is cleared.
$theme_name = \Drupal::theme()->getActiveTheme()->getName();
\Drupal::state()->delete('theme.active_theme.' . $theme_name);
\Drupal::theme()->resetActiveTheme();
/** @var \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler*/
$theme_handler = \Drupal::service('theme_handler');
$theme_handler->refreshInfo();
// @todo This is not needed after https://www.drupal.org/node/2330755
$list = $theme_handler->listInfo();
$theme_handler->addTheme($list[$theme_name]);
if (\Drupal::service('flood')->isAllowed('devel.rebuild_theme_warning', 1)) {
\Drupal::service('flood')->register('devel.rebuild_theme_warning');
if (!devel_silent() && $this->account->hasPermission('access devel information')) {
drupal_set_message(t('The theme information is being rebuilt on every request. Remember to <a href="@url">turn off</a> this feature on production websites.', array('@url' => $this->urlGenerator->generateFromRoute('devel.admin_settings'))));
}
}
}
drupal_register_shutdown_function('devel_shutdown');
}
/**
* Prevents page redirection so that the developer can see the intermediate debug data.
* @param FilterResponseEvent $event
*/
public function onResponse(FilterResponseEvent $event) {
$response = $event->getResponse();
if ($response instanceOf RedirectResponse && !devel_silent()) {
if ($this->account->hasPermission('access devel information') && $this->config->get('redirect_page')) {
$output = t_safe('<p>The user is being redirected to <a href="@destination">@destination</a>.</p>', array('@destination' => $response->getTargetUrl()));
// Replace RedirectResponse with a fresh Response that includes our content.
// We pass array() as last param in order to avoid adding regions which would add queries, etc.
$response = new Response(DefaultHtmlPageRenderer::renderPage($output, 'Devel Redirect', '', array()), 200);
$event->setResponse($response);
}
else {
$GLOBALS['devel_redirecting'] = TRUE;
}
}
}
/**
* Implements EventSubscriberInterface::getSubscribedEvents().
*
* @return array
* An array of event listener definitions.
*/
static function getSubscribedEvents() {
// Set a low value to start as early as possible.
$events[KernelEvents::REQUEST][] = array('onRequest', -100);
// Why only large positive value works here?
$events[KernelEvents::RESPONSE][] = array('onResponse', 1000);
return $events;
}
}