devel.pages.inc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. <?php
  2. /**
  3. * @file
  4. * Page callbacks for Devel.
  5. */
  6. /**
  7. * Page callback: Shows a menu item.
  8. */
  9. function devel_menu_item() {
  10. $item = menu_get_item($_GET['path']);
  11. return kdevel_print_object($item);
  12. }
  13. /**
  14. * Page callback: Returns a list of all currently defined user functions.
  15. *
  16. * Returns a list of all currently defined user functions in the current request
  17. * lifecycle, with links their documentation.
  18. */
  19. function devel_function_reference() {
  20. $functions = get_defined_functions();
  21. $version = devel_get_core_version(VERSION);
  22. $ufunctions = $functions['user'];
  23. sort($ufunctions);
  24. $api = variable_get('devel_api_url', 'api.drupal.org');
  25. foreach ($ufunctions as $function) {
  26. $links[] = l($function, "http://$api/api/$version/function/$function");
  27. }
  28. return theme('item_list', array('items' => $links));
  29. }
  30. /**
  31. * Page callback: Clears all caches, then redirects to the previous page.
  32. */
  33. function devel_cache_clear() {
  34. if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], 'devel-cache-clear')) {
  35. return MENU_ACCESS_DENIED;
  36. }
  37. drupal_flush_all_caches();
  38. drupal_set_message('Cache cleared.');
  39. drupal_goto();
  40. }
  41. /**
  42. * Page callback: Called by the AJAX link in query log.
  43. */
  44. function devel_querylog_explain($request_id, $qid) {
  45. if (!is_numeric($request_id)) {
  46. return MENU_ACCESS_DENIED;
  47. }
  48. $path = "temporary://devel_querylog/$request_id.txt";
  49. $path = file_stream_wrapper_uri_normalize($path);
  50. $output = t('No explain log found.');
  51. if (file_exists($path)) {
  52. $queries = json_decode(file_get_contents($path));
  53. if ($queries !== FALSE && isset($queries[$qid])) {
  54. $header = $rows = array();
  55. $query = $queries[$qid];
  56. $result = db_query('EXPLAIN ' . $query->query, (array)$query->args)->fetchAllAssoc('table');
  57. $i = 1;
  58. foreach ($result as $row) {
  59. $row = (array)$row;
  60. if ($i == 1) {
  61. $header = array_keys($row);
  62. }
  63. $rows[] = array_values($row);
  64. $i++;
  65. }
  66. $output = theme('table', array('header' => $header, 'rows' => $rows));
  67. }
  68. }
  69. // Print and return nothing thus avoiding page wrapper.
  70. print $output;
  71. $GLOBALS['devel_shutdown'] = FALSE;
  72. }
  73. /**
  74. * Page callback: Called by the AJAX link in query log.
  75. */
  76. function devel_querylog_arguments($request_id, $qid) {
  77. if (!is_numeric($request_id)) {
  78. return MENU_ACCESS_DENIED;
  79. }
  80. $path = "temporary://devel_querylog/$request_id.txt";
  81. $path = file_stream_wrapper_uri_normalize($path);
  82. $output = t('No arguments log found.');
  83. if (file_exists($path)) {
  84. $queries = json_decode(file_get_contents($path));
  85. if ($queries !== FALSE && isset($queries[$qid])) {
  86. $query = $queries[$qid];
  87. $conn = Database::getConnection();
  88. $quoted = array();
  89. foreach ((array)$query->args as $key => $val) {
  90. $quoted[$key] = $conn->quote($val);
  91. }
  92. $output = strtr($query->query, $quoted);
  93. }
  94. }
  95. // Print and return nothing thus avoiding page wrapper.
  96. print $output;
  97. $GLOBALS['devel_shutdown'] = FALSE;
  98. }
  99. /**
  100. * Page callback: Clears the database, resetting the menu to factory defaults.
  101. */
  102. function devel_menu_rebuild() {
  103. menu_rebuild();
  104. drupal_set_message(t('The menu router has been rebuilt.'));
  105. drupal_goto();
  106. }
  107. /**
  108. * Form constructor for reinstalling any module from a dropdown.
  109. *
  110. * @see devel_reinstall_submit()
  111. *
  112. * @ingroup forms
  113. */
  114. function devel_reinstall($form, &$form_state) {
  115. $output = '';
  116. $modules = module_list();
  117. sort($modules);
  118. $options = drupal_map_assoc($modules);
  119. $form['list'] = array(
  120. '#type' => 'checkboxes',
  121. '#options' => $options,
  122. '#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>.'),
  123. );
  124. $form['actions'] = array('#type' => 'actions');
  125. $form['actions']['submit'] = array(
  126. '#value' => t('Reinstall'),
  127. '#type' => 'submit',
  128. );
  129. return $form;
  130. }
  131. /**
  132. * Form submission callback for devel_reinstall().
  133. */
  134. function devel_reinstall_submit($form, &$form_state) {
  135. // require_once './includes/install.inc';
  136. $modules = array_filter($form_state['values']['list']);
  137. module_disable($modules, FALSE);
  138. drupal_uninstall_modules($modules, FALSE);
  139. module_enable($modules, FALSE);
  140. drupal_set_message(t('Uninstalled and installed: %names.', array('%names' => implode(', ', $modules))));
  141. }
  142. /**
  143. * Page callback: Rebuilds the theme registry.
  144. */
  145. function devel_theme_registry() {
  146. drupal_theme_initialize();
  147. $hooks = theme_get_registry();
  148. ksort($hooks);
  149. return kprint_r($hooks, TRUE);
  150. }
  151. /**
  152. * Page callback: Returns information from hook_entity_info().
  153. *
  154. * @param string $entity_type
  155. * (optional) Limit results to the specified entity type. The default is to
  156. * return information about all entity types. The $entity_type argument is not
  157. * currently used in the UI.
  158. *
  159. * @return
  160. * The results from kprint_r().
  161. */
  162. function devel_entity_info_page($entity_type = NULL) {
  163. $info = entity_get_info($entity_type);
  164. ksort($info);
  165. return kprint_r($info, TRUE);
  166. }
  167. /**
  168. * Page callback: Returns information about fields.
  169. */
  170. function devel_field_info_page() {
  171. $info = field_info_fields();
  172. $output = kprint_r($info, TRUE, t('Fields'));
  173. $info = field_info_instances();
  174. $output .= kprint_r($info, TRUE, t('Instances'));
  175. $info = field_info_bundles();
  176. $output .= kprint_r($info, TRUE, t('Bundles'));
  177. $info = field_info_field_types();
  178. $output .= kprint_r($info, TRUE, t('Field types'));
  179. $info = field_info_formatter_types();
  180. $output .= kprint_r($info, TRUE, t('Formatter types'));
  181. $info = field_info_storage_types();
  182. $output .= kprint_r($info, TRUE, t('Storage types'));
  183. $info = field_info_widget_types();
  184. $output .= kprint_r($info, TRUE, t('Widget types'));
  185. return $output;
  186. }
  187. /**
  188. * Form constructor for displaying and editing variables.
  189. *
  190. * @see devel_variable_form_submit()
  191. *
  192. * @ingroup forms.
  193. */
  194. function devel_variable_form() {
  195. $header = array(
  196. 'name' => array('data' => t('Name'), 'field' => 'name', 'sort' => 'asc'),
  197. 'value' => array('data' => t('Value'), 'field' => 'value'),
  198. 'length' => array('data' => t('Length'), 'field' => 'length'),
  199. 'edit' => array('data' => t('Operations')),
  200. );
  201. // @todo: We could get variables out of $conf but that would include
  202. // hard-coded ones too. Ideally I would highlight overridden/hard-coded
  203. // variables.
  204. $query = db_select('variable', 'v')->extend('TableSort');
  205. $query->fields('v', array('name', 'value'));
  206. switch (db_driver()) {
  207. case 'mssql':
  208. $query->addExpression("LEN(v.value)", 'length');
  209. break;
  210. default:
  211. $query->addExpression("LENGTH(v.value)", 'length');
  212. break;
  213. }
  214. $result = $query
  215. ->orderByHeader($header)
  216. ->execute();
  217. foreach ($result as $row) {
  218. // $variables[$row->name] = '';
  219. $options[$row->name]['name'] = check_plain($row->name);
  220. if (merits_krumo($row->value)) {
  221. $value = krumo_ob(variable_get($row->name, NULL));
  222. }
  223. else {
  224. if (drupal_strlen($row->value) > 70) {
  225. $value = check_plain(drupal_substr($row->value, 0, 65)) .'...';
  226. }
  227. else {
  228. $value = check_plain($row->value);
  229. }
  230. }
  231. $options[$row->name]['value'] = $value;
  232. $options[$row->name]['length'] = $row->length;
  233. $options[$row->name]['edit'] = l(t('Edit'), "devel/variable/edit/$row->name");
  234. }
  235. $form['variables'] = array(
  236. '#type' => 'tableselect',
  237. '#header' => $header,
  238. '#options' => $options,
  239. '#empty' => t('No variables.'),
  240. );
  241. $form['actions'] = array('#type' => 'actions');
  242. $form['actions']['submit'] = array(
  243. '#type' => 'submit',
  244. '#value' => t('Delete'),
  245. );
  246. $form['#after_build'][] = 'devel_variable_form_after_build';
  247. // krumo($form);
  248. return $form;
  249. }
  250. /**
  251. * Form submission handler for devel_variable_form().
  252. */
  253. function devel_variable_form_submit($form, &$form_state) {
  254. $deletes = array_filter($form_state['values']['variables']);
  255. array_walk($deletes, 'variable_del');
  256. if (count($deletes)) {
  257. drupal_set_message(format_plural(count($deletes), 'One variable deleted.', '@count variables deleted.'));
  258. }
  259. }
  260. /**
  261. * After build callback for devel_variable_form().
  262. *
  263. * Wrap each variable name in a <label> element.
  264. */
  265. function devel_variable_form_after_build($form, &$form_state) {
  266. foreach ($form['variables']['#options'] as $variable => $element) {
  267. $form['variables']['#options'][$variable]['name'] = '<label for="' . $form['variables'][$variable]['#id'] . '">' . $element['name'] . '</label>';
  268. }
  269. return $form;
  270. }
  271. /**
  272. * Form constructor for editing a variable.
  273. *
  274. * @see devel_variable_edit_submit()
  275. *
  276. * @ingroup forms
  277. */
  278. function devel_variable_edit($form, &$form_state, $name) {
  279. $value = variable_get($name, 'not found');
  280. $form['name'] = array(
  281. '#type' => 'value',
  282. '#value' => $name
  283. );
  284. $form['value'] = array(
  285. '#type' => 'item',
  286. '#title' => t('Old value'),
  287. '#markup' => dpr($value, TRUE),
  288. );
  289. if (is_string($value) || is_numeric($value)) {
  290. $form['new'] = array(
  291. '#type' => 'textarea',
  292. '#title' => t('New value'),
  293. '#default_value' => $value
  294. );
  295. $form['actions'] = array('#type' => 'actions');
  296. $form['actions']['submit'] = array(
  297. '#type' => 'submit',
  298. '#value' => t('Submit'),
  299. );
  300. }
  301. else {
  302. $api = variable_get('devel_api_url', 'api.drupal.org');
  303. $form['new'] = array(
  304. '#type' => 'item',
  305. '#title' => t('New value'),
  306. '#markup' => 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"))
  307. );
  308. }
  309. drupal_set_title($name);
  310. return $form;
  311. }
  312. /**
  313. * Form submission handler for devel_variable_edit().
  314. */
  315. function devel_variable_edit_submit($form, &$form_state) {
  316. variable_set($form_state['values']['name'], $form_state['values']['new']);
  317. drupal_set_message(t('Saved new value for %name.', array('%name' => $form_state['values']['name'])));
  318. 'devel/variable';
  319. }
  320. /**
  321. * Page callback: Displays the session.
  322. */
  323. function devel_session() {
  324. global $user;
  325. $output = kprint_r($_SESSION, TRUE);
  326. $headers = array(t('Session name'), t('Session ID'));
  327. $output .= theme('table', array('headers' => $headers, 'rows' => array(array(session_name(), session_id()))));
  328. return $output;
  329. }
  330. /**
  331. * Page callback: Prints the loaded structure of the current node/user.
  332. */
  333. function devel_load_object($type, $object, $name = NULL) {
  334. $name = isset($name) ? $name : $type;
  335. return kdevel_print_object($object, '$'. $name .'->');
  336. }
  337. /**
  338. * Page callback: Prints the render structure of the current object.
  339. *
  340. * @param string $type
  341. * The type of entity that will be displayed.
  342. * @param object $object
  343. * The entity to display.
  344. * @param string $name
  345. * (optional) The label to use when displaying the entity.
  346. *
  347. * @return
  348. * The results from kdevel_print_object().
  349. */
  350. function devel_render_object($type, $object, $name = NULL) {
  351. $name = isset($name) ? $name : $type;
  352. $function = $type . '_view';
  353. switch ($function) {
  354. case 'comment_view':
  355. $node = node_load($object->nid);
  356. $build = $function($object, $node);
  357. break;
  358. default:
  359. $build = $function($object);
  360. }
  361. return kdevel_print_object($build, '$'. $name .'->');
  362. }
  363. /**
  364. * Page callback: Returns information from hook_elements().
  365. */
  366. function devel_elements_page() {
  367. return kdevel_print_object(module_invoke_all('element_info'));
  368. }
  369. /**
  370. * Page callback: Returns the results from phpinfo().
  371. */
  372. function devel_phpinfo() {
  373. print phpinfo();
  374. drupal_exit();
  375. }