Showing posts with label debug. Show all posts
Showing posts with label debug. Show all posts

Wednesday, 5 March 2014

Debugging quickie: Objects

How do you display the contents of an object that has private and protected properties - which means dpm($object) doesn't give you what you want?

You could do this:

dpm('<pre>' . print_r($object, TRUE) . '</pre>');

But that's a lot to type and you get a huge horrible list (particularly if it's a View object).

Try this instead:

dpm((array) $object);

Works a treat.

And while we're on the subject of dpm() have you tried this:

dpm($var, __FUNCTION__);

or

dpm($var, __METHOD__);

It can help.

Monday, 23 September 2013

Field Complete and Profile2

So I thought I'd promote the latest dev version of my Field Complete module to a release candidate yesterday. There were two reasons for this: (a) it's pretty solid, and (b) people are more likely to use it if it's out of dev.

It wasn't a mistake. Within a couple of hours I had a new bug report: Doesn't work with Profile2.

Which surprised me a lot, why on earth would it not work with a popular entity-based module? My code is very standard and does nothing naughty.

The answer, of course, is that Profile2 is naughty. Or at least it's non-standard. I'm not going to go into detail but they bypassed standard edit-form processing and do odd awkward things with the display URL. So my form interceptions don't get a chance to work and the completeness progress bar (and the Incomplete fields block) can't work.

What to do?

On the one hand I don't see why I should hack my code to work with something non-standard. On the other, Profile2 is a very popular module and using Field Completeness with it is a natural thing to do. And I want people to use my module.

So I spent a couple of hours figuring out the nasty that Profile2 does and modifying my code to cope with it. It wasn't too horrible, but I can't say I enjoyed it as a process. My nice clean code now has hacks in it.

Oh well.

Monday, 30 January 2012

Little debugging aid

I had been having a real problem tracking down a PHP error in Drupal which was passing an array to htmlspecialchars() in check_plain() instead of a string. I needed to use debug_backtrace() but the issue was related to Views which meant that the arguments being passed at higher levels were catastrophically huge.

It was a real problem, using krumo just resulted in out-of-memory errors. And the problem was also happening inside AJAX calls so any attempt to simply print the output was doomed.

I needed a way to get a function backtrace which was not too verbose, didn't crash the machine and would work in an AJAX call.

The solution is the following routine which takes a debug_backtrace() extracts only the information we need and outputs to a file. It's not Drupal-specific but you may need to set up the directory:


/**
 * Backtrace to a file for when nothing else works
 */
function debug_backtrace_file($fname = 'backtrace') {
  $file = fopen("c:\\tmp\\{$fname}.log", 'ab');
  if (!$file) {
    return;
  }
  fputs($file, '=============== ' . date('Y-m-d H:i:s') . " ===============\n");
  $line = __LINE__;
  foreach (debug_backtrace() as $entry) {
    $function = $entry['function'];
    if ($function!=__FUNCTION__) {
      if (isset($entry['class']) && $entry['class']) {
        $function = "{$entry['class']}::$function";
      }
      fputs($file, sprintf("function %s at line %d in file %s\n", $function, $line, isset($entry['file'])?$entry['file']:t('unknown')));
    }
    $line = $entry['line'];
  }
  fclose($file);
}


Happy bug hunting.

Tuesday, 19 April 2011

Conditions for using where

Just to help you avoid spending as many hours as I have trying to force a nasty little query with a subquery to do what I wanted...

If you want to have a WHERE clause that contains something like "fss.entity_id = n.nid", you can't use the condition function. In other words, you can't do this:

$query->condition('fss.entity_id', 'n.nid');

You have to use this:

$query->where('fss.entity_id = n.nid');

Because the first version gets translated into fss.entity_id = 'n.nid' in the SQL, which will never be true.

In debugging this it slowly became obvious that something fundamental was wrong - because when I output the $query string and then replaced the placeholders with the right arguments, and shoved it straight into the MySQL server - it worked.

Eventually it dawned on me to use the Devel query output to see what was actually being called and found the error - though by that time I was looking for it, having exhausted every other option.

Here's a quick tip for outputting the entire contents of an object which contains public and private properties:

dpm(print_r($object, TRUE));

I could have done without that today.