Skip to content

Instantly share code, notes, and snippets.

@dergachev
Last active August 29, 2015 13:56
Show Gist options
  • Save dergachev/9008810 to your computer and use it in GitHub Desktop.
Save dergachev/9008810 to your computer and use it in GitHub Desktop.

When debugging Drupal, I often stick dpm($some_array, "my array"); calls to see what the value of $some_array is. This fails spectacularly if the code I'm debugging is run very late in the request after drupal_get_messages() has already been called. (Eg most hook_preprocess_THEMEHOOK functions).

In that case, I've found it useful to add these helper functions somewhere (any enabled custom module, or even index.php), use them instead of dpm. They'll serialize objects to apache's error_log (wherever that is), which you can track by opening a terminal tab and running:

tail -f /var/log/apache2/error.log | tr '%' "\n"

Here are the basic helper functions:

<?php
/**
 * Like dpm() but for error_log
 */
function adpm($obj, $message="") {
  if (is_string($obj)) {
    error_log("[adpm $message] $obj");
  }
  else {
    error_log("[adpm $message START]");
    $str = print_r($obj, 1);
    $str = str_replace(array("\r", "\n"), '%', $str);
    error_log($str);
    error_log("[adpm $message END]");
  }
}

/**
 * Cleans up debug_backtrace output by removing everything but the function names.
 *
 * Usage: adpm(adb(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)), "Debugging my function");
 */
function adb($trace) {
  $functions = array();
  for($i=0; $i<count($trace); $i++) {
    $functions[] = $trace[$i]['function'];
  }
  return $functions;
}

When debugging Drupal menu trees, these functions can be useful:

<?php
/**
 * Tidies up the menu_tree before output by removing extra link properties. 
 *
 * @param $tree
 *   The menu tree to tidy up.
 * @return
 *   The cloned menu_tree with all link properties removed except 'in_active_trail' and 'link_path'
 */
function admenu($tree) {
  if(!$tree) {
    return;
  }
  $new_tree = array();
  foreach($tree as $key => $value) {
    $new_tree[$key] = array(
      'link' => array('link_path' => $value['link']['link_path'], 'in_active_trail' => $value['link']['in_active_trail']),
      'below' => admenu($value['below']),
    );
  }
  return $new_tree;
}

/**
 * For debugging, returns an array of menu item keys corresponding to the active trail.
 *
 * @param $tree
 *   The menu tree to tidy up.
 * @return
 *   Array of keys of active trail menu items. 
 */
function adtrail($tree) {
  if(!$tree) {
    return;
  }
  foreach($tree as $key => $value) {
    if($value['link']['in_active_trail']) {
      if ($value['below']) {
        return array_merge( array($key), adtrail($value['below']));
      }
      else {
        return array($key);
      }
    }
  }
  return array();
}

Finally, if you just want dpm() but want to ensure it doesn't run on ajax requests (like ones caused by admin_menu):

// like dpm, but no ajax
function xdpm($item, $message=NULL) {
  if(!isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
      dpm($item, $message);
  }

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment