Newer
Older
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
<?php
//$Id$
/**
* Page callback to display syntax hilighted source code
*
* note: the path for this function is received via $_GET['path']
* example http://www.example.com/devel/source?file=modules/node/node.module
*
* @param $standalone
* Set to FALSE to place the code inside a Drupal page. Otherwise code displays on its own.
*/
function devel_display_source($standalone = TRUE) {
$path = $_GET['file'];
// take out the nasties
$path = str_replace('../', '', $path);
$output = devel_highlight_file($path, $standalone);
if ($output) {
if ($standalone) {
print $output;
drupal_exit();
}
return $output;
}
else {
drupal_set_message(t('Invalid file path'), 'error');
drupal_not_found();
}
}
/**
* Return PHP highlighted file
*
* @param $path
* path to the file
* *warning* there is NO VALIDATION in this function
* Beware of paths such as '../../../../../etc/apache/httpd.conf'
*
* @param $standalone
* should the returned HTML be wrapped in a full <html> page or will it be output by Drupal?
*/
function devel_highlight_file($path = NULL, $standalone = FALSE) {
if (file_exists($path)) {
$source = highlight_file($path, TRUE);
// add anchor links before all functions
// with doxygen
// $source = preg_replace('!(\/\*\*.*?\*\/.*?)<br.*?function.*?#0000BB">(.*?)<\/span>!', '<a id="$2"></a> $0', $source);
//$source = preg_replace('!(\/\*\*.*?\*\/).*?function.*?#0000BB">(.*?)<\/span>!', '<a id="$2"></a> $0', $source);
if ($standalone) {
$source = <<<EOT
<head><title>$path</title></head>
<body>$source</body>
EOT;
}
return $source;
}
else {
return FALSE;
}
}
// Menu callback that shows menu item.
function devel_menu_item() {
$item = menu_get_item($_GET['path']);
return kdevel_print_object($item);
}
/**
* Returns a list of all currently defined user functions in the current
* request lifecycle, with links their documentation.
*/
function devel_function_reference() {
$functions = get_defined_functions();
$version = devel_get_core_version(VERSION);
$ufunctions = $functions['user'];
sort($ufunctions);
$api = variable_get('devel_api_url', 'api.drupal.org');
foreach ($ufunctions as $function) {
$links[] = l($function, "http://$api/api/$version/function/$function");
}
return theme('item_list', array('items' => $links));
}
/**
* Menu callback; clears all caches, then redirects to the previous page.
*/
function devel_cache_clear() {
drupal_flush_all_caches();
drupal_set_message('Cache cleared.');
drupal_goto();
}
// A menu callback. Called by the AJAX link in query log.
function devel_querylog_explain($request_id, $qid) {
if (!is_numeric($request_id)) {
return MENU_ACCESS_DENIED;
}
$path = "temporary://devel_querylog/$request_id.txt";
$path = file_stream_wrapper_uri_normalize($path);
Moshe Weitzman
committed
$queries = json_decode(file_get_contents($path));
$query = $queries[$qid];
Moshe Weitzman
committed
$result = db_query('EXPLAIN ' . $query->query, (array)$query->args)->fetchAllAssoc('table');
$i = 1;
foreach ($result as $row) {
$row = (array)$row;
if ($i == 1) {
$header = array_keys($row);
}
$rows[] = array_values($row);
$i++;
}
// Print and return nothing thus avoiding page wrapper.
$output = theme('table', array('header' => $header, 'rows' => $rows));
print $output;
$GLOBALS['devel_shutdown'] = FALSE;
}
// A menu callback. Called by the AJAX link in query log.
function devel_querylog_arguments($request_id, $qid) {
if (!is_numeric($request_id)) {
return MENU_ACCESS_DENIED;
}
$path = "temporary://devel_querylog/$request_id.txt";
$path = file_stream_wrapper_uri_normalize($path);
Moshe Weitzman
committed
$queries = json_decode(file_get_contents($path));
$query = $queries[$qid];
$conn = Database::getConnection();
$quoted = array();
Moshe Weitzman
committed
foreach ((array)$query->args as $key => $val) {
$quoted[$key] = $conn->quote($val);
}
Moshe Weitzman
committed
$output = strtr($query->query, $quoted);
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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// print and return nothing thus avoiding page wrapper.
print $output;
$GLOBALS['devel_shutdown'] = FALSE;
}
/**
* Menu callback; clear the database, resetting the menu to factory defaults.
*/
function devel_menu_rebuild() {
menu_rebuild();
drupal_set_message(t('The menu router has been rebuilt.'));
drupal_goto();
}
/**
* Display a dropdown of installed modules with the option to reinstall them.
*/
function devel_reinstall($form, &$form_state) {
$output = '';
$modules = module_list();
sort($modules);
$options = drupal_map_assoc($modules);
$form['list'] = array(
'#type' => 'checkboxes',
'#options' => $options,
'#description' => t('Uninstall and then install the selected modules. <code>hook_uninstall()</code> and <code>hook_install()</code> will be executed and the schema version number will be set to the most recent update number. You may have to manually clear out any existing tables first if the module doesn\'t implement <code>hook_uninstall()</code>.'),
);
$form['submit'] = array(
'#value' => t('Reinstall'),
'#type' => 'submit',
);
return $form;
}
/**
* Process reinstall menu form submissions.
*/
function devel_reinstall_submit($form, &$form_state) {
// require_once './includes/install.inc';
$modules = array_filter($form_state['values']['list']);
module_disable($modules, FALSE);
drupal_uninstall_modules($modules);
module_enable($modules, FALSE);
drupal_set_message(t('Uninstalled and installed: %names.', array('%names' => implode(', ', $modules))));
}
// Menu callback.
function devel_theme_registry() {
drupal_theme_initialize();
$hooks = theme_get_registry();
ksort($hooks);
return kprint_r($hooks, TRUE);
}
// Menu callback. $entity_type argument not currently used in the UI.
function devel_entity_info_page($entity_type = NULL) {
$info = entity_get_info($entity_type);
ksort($info);
return kprint_r($info, TRUE);
}
// Menu callback.
function devel_field_info_page() {
$info = field_info_fields();
$output = kprint_r($info, TRUE, t('Fields'));
$info = field_info_instances();
$output .= kprint_r($info, TRUE, t('Instances'));
$info = field_info_bundles();
$output .= kprint_r($info, TRUE, t('Bundles'));
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
}
/**
* Menu callback; display all variables.
*/
function devel_variable_page() {
// We return our own $page so as to avoid blocks.
$output = drupal_get_form('devel_variable_form');
drupal_set_page_content($output);
$page = element_info('page');
return $page;
}
function devel_variable_form() {
$header = array(
'name' => array('data' => t('Name'), 'field' => 'name', 'sort' => 'asc'),
'value' => array('data' => t('Value'), 'field' => 'value'),
'length' => array('data' => t('Length'), 'field' => 'length'),
'edit' => array('data' => t('Operations')),
);
// TODO: we could get variables out of $conf but that would include hard coded ones too. ideally i would highlight overrridden/hard coded variables
$query = db_select('variable', 'v')->extend('TableSort');
$query->fields('v', array('name', 'value'));
switch (db_driver()) {
case 'mssql':
$query->addExpression("COL_LENGTH('{variable}', 'value')", 'length');
break;
default:
$query->addExpression("CONVERT(LENGTH(v.value), UNSIGNED INTEGER)", 'length');
break;
}
$result = $query
->orderByHeader($header)
->execute();
foreach ($result as $row) {
// $variables[$row->name] = '';
$options[$row->name]['name'] = check_plain($row->name);
if (merits_krumo($row->value)) {
$value = krumo_ob(variable_get($row->name, NULL));
}
else {
if (drupal_strlen($row->value) > 70) {
$value = check_plain(drupal_substr($row->value, 0, 65)) .'...';
}
else {
$value = check_plain($row->value);
}
}
$options[$row->name]['value'] = $value;
$options[$row->name]['length'] = $row->length;
$options[$row->name]['edit'] = l(t('Edit'), "devel/variable/edit/$row->name");
}
$form['variables'] = array(
'#type' => 'tableselect',
'#header' => $header,
'#options' => $options,
'#empty' => t('No variables.'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Delete'),
);
// krumo($form);
return $form;
}
function devel_variable_form_submit($form, &$form_state) {
$deletes = array_filter($form_state['values']['variables']);
array_walk($deletes, 'variable_del');
Moshe Weitzman
committed
if (count($deletes)) {
drupal_set_message(format_plural(count($deletes), 'One variable deleted.', '@count variables deleted.'));
}
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
}
function devel_variable_edit($form, &$form_state, $name) {
$value = variable_get($name, 'not found');
$form['name'] = array(
'#type' => 'value',
'#value' => $name
);
$form['value'] = array(
'#type' => 'item',
'#title' => t('Old value'),
'#markup' => dpr($value, TRUE),
);
if (is_string($value) || is_numeric($value)) {
$form['new'] = array(
'#type' => 'textarea',
'#title' => t('New value'),
'#default_value' => $value
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
}
else {
$api = variable_get('devel_api_url', 'api.drupal.org');
$form['new'] = array(
'#type' => 'item',
'#title' => t('New value'),
'#value' => t('Sorry, complex variable types may not be edited yet. Use the <em>Execute PHP</em> block and the <a href="@variable-set-doc">variable_set()</a> function.', array('@variable-set-doc' => "http://$api/api/HEAD/function/variable_set"))
);
}
drupal_set_title($name);
return $form;
}
function devel_variable_edit_submit($form, &$form_state) {
variable_set($form_state['values']['name'], $form_state['values']['new']);
drupal_set_message(t('Saved new value for %name.', array('%name' => $form_state['values']['name'])));
'devel/variable';
}
/**
* Menu callback: display the session.
*/
function devel_session() {
global $user;
$output = kprint_r($_SESSION, TRUE);
$headers = array(t('Session name'), t('Session ID'));
$output .= theme('table', array('headers' => $headers, 'rows' => array(array(session_name(), session_id()))));
return $output;
}
/**
* Menu callback; prints the loaded structure of the current node/user.
*/
function devel_load_object($type, $object, $name = NULL) {
$name = isset($name) ? $name : $type;
return kdevel_print_object($object, '$'. $name .'->');
}
/**
* Menu callback; prints the render structure of the current object (currently node or user).
*/
function devel_render_object($type, $object, $name = NULL) {
$name = isset($name) ? $name : $type;
$function = $type . '_view';
$build = $function($object);
return kdevel_print_object($build, '$'. $name .'->');
}
function devel_elements_page() {
return kdevel_print_object(module_invoke_all('element_info'));
}
function devel_phpinfo() {
print phpinfo();
drupal_exit();
}