PageRenderTime 55ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/sites/all/modules/devel/drupalforfirebug/drupalforfirebug.module

https://bitbucket.org/drushop/main
Unknown | 552 lines | 511 code | 41 blank | 0 comment | 0 complexity | d83a822c7bcdc57689ca17c6cd873845 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-2.1
  1. <?php
  2. /**
  3. * Implementation of hook_init()
  4. */
  5. function drupalforfirebug_exit() {
  6. $dff = TRUE;
  7. // Try not to break non html pages. [from devel.module]
  8. if (function_exists('drupal_get_headers')) {
  9. $headers = drupal_get_headers();
  10. $formats = array('xml', 'javascript', 'json', 'plain', 'image', 'application', 'csv', 'x-comma-separated-values');
  11. foreach ($formats as $format) {
  12. if (strstr($headers, $format)) {
  13. $dff = FALSE;
  14. }
  15. }
  16. }
  17. // Check with Devel if Installed
  18. if (module_exists('devel')) {
  19. if (devel_verify_cli()) {
  20. $dff = FALSE;
  21. }
  22. }
  23. if ($dff) {
  24. // Load Relevant Files and Register Shutdown
  25. drupal_load('module', 'user');
  26. register_shutdown_function('drupalforfirebug_shutdown');
  27. }
  28. }
  29. /**
  30. * Implementation of hook_menu()
  31. */
  32. function drupalforfirebug_menu() {
  33. $items['admin/firebug/exec'] = array(
  34. 'page callback' => 'drupalforfirebug_get_exec_php_callback',
  35. 'access arguments' => array('access content'),
  36. 'type' => MENU_CALLBACK,
  37. );
  38. return $items;
  39. }
  40. /**
  41. * Implementation of hook_nodeapi()
  42. */
  43. function drupalforfirebug_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  44. global $dfp_runtime;
  45. if (!user_access('Access Firebug Debug')) {
  46. return;
  47. }
  48. $nid = (isset($node->nid)) ? $node->nid : '*'. t('NEW') . '*';
  49. $data = drupalforfirebug_array_compare((array) $dfp_runtime['drupalforfirebug_nodes']['original'][$node->type][$nid], (array) $node);
  50. $output = drupalforfirebug_field_object('node', $nid, $op, $data);
  51. drupalforfirebug_log($output, 'hook_nodeapi');
  52. }
  53. /**
  54. * Implementation of hook_views_pre_view();
  55. */
  56. function drupalforfirebug_views_pre_view(&$view, &$display_id) {
  57. global $dfp_runtime;
  58. if (!user_access('Access Firebug Debug')) {
  59. return;
  60. }
  61. $data = drupalforfirebug_array_compare((array) $dfp_runtime['drupalforfirebug_views']['original'][$view->name], (array) $view);
  62. $output = drupalforfirebug_field_object('view', $view->name, NULL, $data);
  63. drupalforfirebug_log($output, 'hook_views');
  64. }
  65. /**
  66. * Implementation of hook_form_alter()
  67. */
  68. function drupalforfirebug_form_alter(&$form, $form_state, $form_id) {
  69. global $dfp_runtime;
  70. if (!user_access('Access Firebug Debug')) {
  71. return;
  72. }
  73. if ($form_id != 'drupalforfirebug_execute_form') {
  74. $form_modified = (array) $form;
  75. $data = drupalforfirebug_array_compare($dfp_runtime['drupalforfirebug_forms']['original'][$form_id], $form_modified);
  76. $output = drupalforfirebug_field_object('form', $form_id, NULL, $data);
  77. drupalforfirebug_log($output, 'hook_form_alter');
  78. }
  79. }
  80. /**
  81. * Implementation of hook_user()
  82. */
  83. function drupalforfirebug_user($op, &$edit, &$account, $category = NULL) {
  84. global $dfp_runtime;
  85. if (!user_access('Access Firebug Debug')) {
  86. return;
  87. }
  88. if (isset($account->uid)) {
  89. $uid = $account->uid;
  90. $name = $account->name;
  91. } else {
  92. $uid = '*' . t('NEW') . '*';
  93. $name = '*' . t('NEW') . '*';
  94. }
  95. if (is_object($account)) {
  96. $account_clone = drupal_clone($account);
  97. $account_clone->pass = '**' . t('Not shown for security reasons') . '**';
  98. $data = drupalforfirebug_array_compare((array) $account_clone, (array) $account_clone);
  99. $output = drupalforfirebug_field_object('user', $uid, $op, $data);
  100. drupalforfirebug_log($output, 'hook_user');
  101. }
  102. }
  103. /**
  104. * API Function to Record a Message to the Drupal Firebug Log
  105. */
  106. function drupalforfirebug_log($message, $type = 'general') {
  107. global $dfp_runtime;
  108. $dfp_runtime['firebug_messages'][$type][] = $message;
  109. }
  110. /**
  111. * Command Function to Record a Data Element to the Drupal Firebug Log
  112. */
  113. function firep($element, $title = NULL) {
  114. if ($title) {
  115. drupalforfirebug_log('<strong>'.$title.':</strong>');
  116. }
  117. drupalforfirebug_log('<PRE>'. print_r($element, true) . '<br><br></PRE>', 'general');
  118. }
  119. /**
  120. * Output Function to Return the Results of the Log
  121. */
  122. function drupalforfirebug_get($panetype) {
  123. global $dfp_runtime;
  124. $output = '';
  125. if (isset($dfp_runtime['firebug_messages'][$panetype])) {
  126. foreach($dfp_runtime['firebug_messages'][$panetype] as $message) {
  127. $output .= '<div>'. $message .'</div>';
  128. }
  129. unset($dfp_runtime['firebug_messages'][$panetype]);
  130. return $output;
  131. }
  132. }
  133. /**
  134. * Output Function to Return the Results of the SQL Log
  135. */
  136. function drupalforfirebug_get_sql_log() {
  137. $output = '<fieldset>';
  138. if (!module_exists('devel')) {
  139. $output .= '<legend>' . t('Devel Module is Not Installed') . '</legend>';
  140. $output .= t('Please install and enable the Devel Module to display the SQL queries.');
  141. } elseif (!variable_get('dev_query', 0)) {
  142. $output .= '<legend>' . t('Query Logging is Not Enabled') . '</legend>';
  143. $output .= t('Please enable "Collect query info" in the Devel Module Settings (admin/settings/devel) to use this feature.');
  144. } else {
  145. global $queries;
  146. list($counts, $query_summary) = devel_query_summary();
  147. $output .= '<legend>' . t('SQL Query Log') . '</legend>';
  148. $output .= $query_summary;
  149. $output .= drupalforfirebug_devel_query_table($queries, $counts);
  150. }
  151. $output .= '</fieldset>';
  152. return $output;
  153. }
  154. /**
  155. * Generates an Execute PHP Drupal For Firebug Form
  156. **/
  157. function drupalforfirebug_execute_form() {
  158. $form['code'] = array(
  159. '#type' => 'textarea',
  160. '#description' => t('Enter PHP code for execution. Do not use <code>&#60;?php ?&#62;</code> tags.')
  161. );
  162. $form['token'] = array(
  163. '#type' => 'hidden',
  164. '#value' => drupal_get_token(),
  165. );
  166. $form['op'] = array('#type' => 'submit', '#value' => t('Execute'));
  167. $form['#redirect'] = FALSE;
  168. $form['#action'] = url('admin/firebug/exec', array('absolute' => TRUE));
  169. $form['#skip_duplicate_check'] = TRUE;
  170. return $form;
  171. }
  172. function drupalforfirebug_get_php_exec_area() {
  173. #$output = '<iframe style="width=100%;frameborder=0;height=100%;margin-bottom:-3px;" src="' . url('admin/firebug/exec', array('absolute' => TRUE)) . '"></iframe>';
  174. $output = '<object style="width:100%;frameborder=0;height=100%;margin-bottom:-3px;" type="text/html" data="' . url('admin/firebug/exec', array('absolute' => TRUE)) . '"></object>';
  175. return $output;
  176. }
  177. function drupalforfirebug_get_php_exec($code = NULL, $token = NULL) {
  178. $output = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
  179. $output .= '<html><head><title>Execute PHP Code</title></head><body>';
  180. $output .= '<fieldset>';
  181. if (!user_access('Execute Firebug PHP') || (!is_null($code) && !drupal_valid_token($token))) {
  182. $output .= '<legend>' . t('Execute Firebug PHP') . '</legend>';
  183. $output .= t('You do not have the proper permissions to use this functionality.');
  184. $output .= '</fieldset></body></html>';
  185. print $output;
  186. exit();
  187. } else {
  188. if (!$code) {
  189. $output .= '<legend>' . t('Execute Firebug PHP') . '</legend>';
  190. $output .= drupal_get_form('drupalforfirebug_execute_form');
  191. $output .= '</fieldset></body></html>';
  192. print $output;
  193. exit();
  194. } else {
  195. $output = '<legend>' . t('PHP Code Execution Results') . '</legend>';
  196. // Run the PHP command, get output in variable
  197. ob_start();
  198. eval($code);
  199. $eval_result = ob_get_contents();
  200. ob_end_clean();
  201. $output .= '<PRE>' . $eval_result . '</PRE>';
  202. $output .= '</fieldset>';
  203. $output .= '<fieldset>';
  204. $output .= '<legend>' . t('Execute Firebug PHP') . '</legend>';
  205. $output .= drupal_get_form('drupalforfirebug_execute_form');
  206. $output .= '</fieldset></body></html>';
  207. print $output;
  208. exit();
  209. }
  210. }
  211. }
  212. /**
  213. * Outputs a Execute PHP Form
  214. */
  215. function drupalforfirebug_get_exec_php_callback() {
  216. $code = (isset($_POST['code'])) ? $_POST['code'] : NULL;
  217. $token = (isset($_POST['token'])) ? $_POST['token'] : NULL;
  218. return drupalforfirebug_get_php_exec($code, $token);
  219. }
  220. /**
  221. * Output Function to Return Hidden Div Containers in Footer
  222. */
  223. function drupalforfirebug_shutdown() {
  224. if (!user_access('Access Firebug Debug')) {
  225. return;
  226. }
  227. $output = '<div style="display: none" id="drupalforfirebug_general">';
  228. $output .= '<fieldset>';
  229. $output .= '<legend>' . t('Drupal for Firebug General Messages') . '</legend>';
  230. $general_messages = drupalforfirebug_get('general');
  231. $output .= $general_messages;
  232. if (!$general_messages) {
  233. $output .= t('There were no messages sent to the general log. Please use "firep($item, $optional_title)" to output messages to this console.');
  234. }
  235. $output .= '</div>';
  236. $output .= '<div style="display: none" id="drupalforfirebug_sql">';
  237. $output .= drupalforfirebug_get_sql_log();
  238. $output .= '</div>';
  239. $output .= '<div style="display: none" id="drupalforfirebug_hook_form_alter">';
  240. $output .= $form_alter_output = drupalforfirebug_get('hook_form_alter');
  241. if (!$form_alter_output) { $output .= t('There was no form altering.'); }
  242. $output .= '</div>';
  243. $output .= '<div style="display: none" id="drupalforfirebug_hook_user">';
  244. $output .= $user_output = drupalforfirebug_get('hook_user');
  245. if (!$user_output) { $output .= t('There was no user processing.'); }
  246. $output .= '</div>';
  247. $output .= '<div style="display: none" id="drupalforfirebug_hook_nodeapi">';
  248. $output .= $node_api_output = drupalforfirebug_get('hook_nodeapi');
  249. if (!$node_api_output) { $output .= t('There was no node processing.'); }
  250. $output .= '</div>';
  251. $output .= '<div style="display: none" id="drupalforfirebug_hook_views">';
  252. if (module_exists('views')) {
  253. $output .= $views_output = drupalforfirebug_get('hook_views');
  254. if (!$views_output) { $output .= t('There was no views processing.'); }
  255. } else {
  256. $output .= t('The views module is not installed.');
  257. }
  258. $output .= '</div>';
  259. $output .= '<div style="display: none" id="drupalforfirebug_php">';
  260. $output .= drupalforfirebug_get_php_exec_area();
  261. $output .= '</div>';
  262. $output .= '<div style="display: none" id="drupalforfirebug_hook_page_alter">';
  263. $output .= t('This feature is only available in Drupal 7.');
  264. $output .= '</div>';
  265. print $output;
  266. unset($GLOBALS['dfp_runtime']);
  267. }
  268. /**
  269. * Implementation of hook_perm()
  270. */
  271. function drupalforfirebug_perm() {
  272. return array('Access Firebug Debug', 'Execute Firebug PHP');
  273. }
  274. /**
  275. * Generalized Array Comparision Function
  276. */
  277. function drupalforfirebug_array_compare($a, $b) {
  278. $data = drupalforfirebug_array_compare_code($a, $b);
  279. $style = drupalforfirebug_array_highlight_code($data);
  280. return $style;
  281. }
  282. /**
  283. * Specialized Function to Return an Array Row
  284. */
  285. function drupalforfirebug_array_row_build($key, $value, $style, $depth) {
  286. $spacing = '';
  287. for ($x = 0; $x <= $depth; $x++) {
  288. $spacing .= '&nbsp;&nbsp;&nbsp;&nbsp;';
  289. }
  290. switch ($style) {
  291. case 'ADDED':
  292. $color = '<span style="color: green;">';
  293. $colorend = '</span>';
  294. break;
  295. case 'REMOVED':
  296. $color = '<span style="color: red;">';
  297. $colorend = '</span>';
  298. break;
  299. case 'SAME':
  300. $color = '<span style="color: black;">';
  301. $colorend = '</span>';
  302. break;
  303. case 'DIFFERENT':
  304. $color = '<span style="color: orange;">';
  305. $colorend = '</span>';
  306. break;
  307. default: // suppose to be for objects
  308. $color = '<span style="color: grey;">'.$style;
  309. $colorend = '</span>';
  310. break;
  311. }
  312. $output = '';
  313. if (is_array($value) || is_object($value)) {
  314. if ($style == 'DIFFERENT') { // do not highlight if contained item is just changed.
  315. $color = '';
  316. $colorend = '';
  317. }
  318. if (is_array($value)) {
  319. $output .= "<div>$spacing $color [$key] => array ( $colorend </div>";
  320. } else {
  321. $output .= '<div>$spacing <span style="color: grey;"> [' . $key .'] => stdClass (' . $colorend .'</div>';
  322. }
  323. $output .= drupalforfirebug_array_highlight_code($value, $depth + 1);
  324. $output .= "<div>$spacing $color ) $colorend </div>";
  325. } else {
  326. if (isset($key) || isset($value)) {
  327. if (is_resource($value)) {
  328. $output .= "<div>$spacing $color [$key] => RESOURCE $colorend </div>";
  329. } else {
  330. $output .= "<div>$spacing $color [$key] => [" . check_plain($value) . "] $colorend </div>";
  331. }
  332. }
  333. }
  334. return $output;
  335. }
  336. /**
  337. * Specialized Array Data Style Function
  338. */
  339. function drupalforfirebug_array_highlight_code($data, $depth = 0) {
  340. // Smartly Handling Recursion for Objects
  341. if (is_object($data)) {
  342. $data = (array) $data;
  343. static $refChain = array();
  344. foreach ($refChain as $refVal) {
  345. if ($refVal === $data) {
  346. $data = array('**' . t('Recursion Detected') . '**');
  347. }
  348. }
  349. array_push($refChain, $data);
  350. }
  351. $output = '';
  352. foreach($data as $key => $value) {
  353. if ((string) $key != '#firebug_style') {
  354. if (isset($data['#firebug_style'])) {
  355. $output .= drupalforfirebug_array_row_build($key, $value, $data['#firebug_style'][$key], $depth);
  356. }
  357. }
  358. }
  359. return $output;
  360. }
  361. /**
  362. * Specialized Array Data Comparision Code
  363. */
  364. function drupalforfirebug_array_compare_code($a, $b, $c = array()) {
  365. // Create the Compared Data Object
  366. $maxcount = count($a) > count($b) ? count($a) : count($b);
  367. $akeys = is_array($a) ? array_keys($a) : array();
  368. $bkeys = is_array($b) ? array_keys($b) : array();
  369. for ($x = 0; $x < $maxcount; $x++) {
  370. // Set the Proper Styling
  371. if (isset($akeys[$x]) && array_key_exists($akeys[$x], array_flip($bkeys))) { // is it in B array?
  372. if ($a[$akeys[$x]] === $b[$akeys[$x]]) {
  373. $c['#firebug_style'][$akeys[$x]] = 'SAME';
  374. } else {
  375. $c['#firebug_style'][$akeys[$x]] = 'DIFFERENT';
  376. }
  377. } else { // not in B array, must be removed
  378. if (isset($akeys[$x])) {
  379. $c['#firebug_style'][$akeys[$x]] = 'REMOVED';
  380. }
  381. }
  382. // Set the Proper Element
  383. if (isset($akeys[$x]) && is_array($a[$akeys[$x]])) { // is b a valid array
  384. if (isset($c[$akeys[$x]])) {
  385. $c[$akeys[$x]] = drupalforfirebug_array_compare_code($a[$akeys[$x]], $b[$akeys[$x]], $c[$akeys[$x]]);
  386. } else {
  387. $c[$akeys[$x]] = drupalforfirebug_array_compare_code($a[$akeys[$x]], $b[$akeys[$x]], array());
  388. }
  389. } else {
  390. if (isset($akeys[$x]) && array_key_exists($akeys[$x], array_flip($bkeys))) { // is it in B array?
  391. if ($a[$akeys[$x]] === $b[$akeys[$x]]) {
  392. $c[$akeys[$x]] = $a[$akeys[$x]];
  393. } else {
  394. $c[$akeys[$x]] = $b[$akeys[$x]];
  395. }
  396. } else { // not in B array, must be removed
  397. if (isset($akeys[$x])) {
  398. $c[$akeys[$x]] = $a[$akeys[$x]];
  399. }
  400. }
  401. }
  402. if (isset($bkeys[$x]) && isset($b[$bkeys[$x]])) { // does b have a valid argument
  403. // Set the Proper Styling
  404. if (array_key_exists($bkeys[$x], array_flip($akeys))) { // is it in A array?
  405. // exists in the A array, already processed
  406. } else {
  407. $c[$bkeys[$x]] = $b[$bkeys[$x]];
  408. $c['#firebug_style'][$bkeys[$x]] = 'ADDED';
  409. }
  410. // Set the Proper Element
  411. if (isset($b[$bkeys[$x]]) && is_array($b[$bkeys[$x]])) { // is b a valid array
  412. $c[$bkeys[$x]] = drupalforfirebug_array_compare_code($a[$bkeys[$x]], $b[$bkeys[$x]], $c[$bkeys[$x]]);
  413. }
  414. }
  415. }
  416. return $c;
  417. }
  418. // Array Handling Helper Function
  419. function do_offset($level) {
  420. $offset = ""; // offset for subarry
  421. for ($i=1; $i<$level;$i++) {
  422. $offset = $offset . "<td></td>";
  423. }
  424. return $offset;
  425. }
  426. // Array Handling Helper Function
  427. function drupalforfirebug_show_array($array, $level, $sub){
  428. $output = '';
  429. if (is_array($array) == 1){ // check if input is an array
  430. foreach($array as $key_val => $value) {
  431. $offset = "";
  432. if (is_array($value) == 1){ // array is multidimensional
  433. $output .= "<tr>";
  434. $offset = do_offset($level);
  435. $output .= $offset . "<td>" . $key_val . "</td>";
  436. $output .= drupalforfirebug_show_array($value, $level+1, 1);
  437. }
  438. else{ // (sub)array is not multidim
  439. if ($sub != 1){ // first entry for subarray
  440. $output .= "<tr nosub>";
  441. $offset = do_offset($level);
  442. }
  443. $sub = 0;
  444. $output .= $offset . "<td main ".$sub." width=\"120\">" . $key_val .
  445. "</td><td width=\"120\">" . $value . "</td>";
  446. $output .= "</tr>\n";
  447. }
  448. } //foreach $array
  449. }
  450. return $output;
  451. }
  452. // Function to Show an Array
  453. function html_drupalforfirebug_show_array($array){
  454. $output = "<table cellspacing=\"0\" border=\"2\">\n";
  455. $output .= drupalforfirebug_show_array($array, 1, 0);
  456. $output .= "</table>\n";
  457. return $output;
  458. }
  459. /**
  460. * Function for fieldsets that wrap object dumps
  461. *
  462. * For efficiency and consistent behavior in firebug window
  463. * Use to be a theme function, but that broke things
  464. */
  465. function drupalforfirebug_field_object($marker, $id, $op = NULL, $data) {
  466. $output = '<fieldset class="toggler">';
  467. $output .= '<legend><strong><a href="#"><em>' . $op . '</em> $'. $marker .'->'. $id . '</a></strong></legend>';
  468. $output .= '<div class="content" style="display: none;">';
  469. $output .= '<div>' . '&nbsp;$'. $marker .' = (' . '</div>';
  470. $output .= $data;
  471. $output .= '<div>' . '&nbsp;);</div>';
  472. $output .= '</div>';
  473. $output .= '</fieldset>';
  474. return $output;
  475. }
  476. /**
  477. * Replication of Devel Query Display (but as a table instead of CSS styled div structure)
  478. * This is done to work with the Firefox extension which has a harder time loading CSS
  479. */
  480. function drupalforfirebug_devel_query_table($queries, $counts) {
  481. $header = array ('ms', '#', 'where', 'query');
  482. $i = 0;
  483. foreach ($queries as $query) {
  484. $ar = explode("\n", $query[0]);
  485. $function=array_shift($ar);
  486. $count = isset($counts[$query[0]]) ? $counts[$query[0]] : 0;
  487. $query[0]=join(' ',$ar);
  488. $diff = round($query[1] * 1000, 2);
  489. if ($diff > variable_get('devel_execution', 5)) {
  490. $cell[$i][] = array ('data' => $diff, 'class' => 'marker');
  491. }
  492. else {
  493. $cell[$i][] = $diff;
  494. }
  495. if ($count > 1) {
  496. $cell[$i][] = array ('data' => $count, 'class' => 'marker');
  497. }
  498. else {
  499. $cell[$i][] = $count;
  500. }
  501. $cell[$i][] = $function;
  502. $pos = strpos($query[0], '*/') + 3;
  503. $cell[$i][] = check_plain(substr($query[0], $pos));
  504. $i++;
  505. unset($diff, $count);
  506. }
  507. if (variable_get('devel_query_sort', DEVEL_QUERY_SORT_BY_SOURCE)) {
  508. usort($cell, '_devel_table_sort');
  509. }
  510. return theme('table', $header, $cell);
  511. }