Atlantic Business Technologies, Inc.

Category: PHP

  • WordPress Debugging – “Doing It Wrong” warnings

    WordPress recently added some “helpful” error messages warning you when you’re not doing certain things correctly. Specifically, adding scripts and/or styles incorrectly using the wp_enqueue_* function.

    However, even though it appears they tell you where things went wrong (via trigger_error), it actually just points you to the _doing_it_wrong function.

    Fortunately, those hook-crazy developers threw us a bone in that function:
    [php]
    do_action( ‘doing_it_wrong_run’, $function, $message, $version );
    //
    [/php]

    Now we can figure out the offender ourselves with a hook:
    [php highlight=”13″]
    /**
    * Because new WP 3.3 “doing it wrong” warnings don’t really tell you where you screwed up…
    * @param string $function The function that was called.
    * @param string $message A message explaining what has been done incorrectly.
    * @param string $version The version of WordPress where the message was added.
    */
    function abt_doing_it_wrong_helper($function, $message, $version){
    $before = <<<EOD
    <strong>$function:</strong> v$version
    EOD;
    debug_whereat(3, 5, $before);
    }
    add_action( ‘doing_it_wrong_run’, ‘abt_doing_it_wrong_helper’, 10, 3 );
    //
    [/php]

    And the helper function for printing debug_backtrace (use your own flavor):
    [php]
    /**
    * Pretty-print debug_backtrace()
    * @param int $limit {optional} when to stop printing – how many recursions up/down
    * @param int $skip {optional} when to start printing – how many calls to skip over
    * @param string $before {optional} extra html to print before the table, inside debug container
    * @param string $after {optional} extra html to print before the table, inside debug container
    * */
    function debug_whereat($limit = false, $skip = false, $before = ”, $after = ”){
    static $debug_whereat_counter; if( !$debug_whereat_counter) $debug_whereat_counter = 0;
    $uid = $debug_whereat_counter++;
    ?>
    <div class=”debug trace”>
    <?php echo $before; ?>
    <table>
    <thead><tr>
    <th id=”th-index-<?=$uid?>”><i>nth</i></th>
    <th id=”th-line-<?=$uid?>”>Line</th>
    <th id=”th-file-<?=$uid?>”>File</th>
    <th id=”th-method-<?=$uid?>”>Method</th>
    </tr></thead>
    <tbody>
    <?php

    $backtrace = debug_backtrace();
    if( $skip ) $backtrace = array_slice($backtrace, $skip);

    foreach($backtrace as $index => $trace){
    //force quit
    if($limit !== false && $index == $limit){
    ?>
    <tr><td colspan=”4″><em>—– FORCE STOP RECURSION —–</em></td></tr>
    <?php
    break;
    }

    ?>
    <tr class=”trace-item”>
    <th headers=”th-index-<?=$uid?>”><?=$index?></th>
    <td headers=”th-line-<?=$uid?>” class=”line”><?=$trace[‘line’]?></td>
    <td headers=”th-file-<?=$uid?>” class=”file”><?=$trace[‘file’]?></td>
    <td headers=”th-method-<?=$uid?>” class=”method”>
    <code><?=$trace[‘function’]?></code>
    <?php
    if(!empty($trace[‘args’])){
    echo ‘<br />’;
    while(!empty($trace[‘args’])){
    ?> {<i><?php print_r(array_shift($trace[‘args’]) ); ?></i>} <?php
    }// while !empty $trace[‘args’]
    }
    ?>
    </td>
    </tr>
    <?php
    }
    ?>
    </tbody></table><?php echo $after; ?></div>
    <?php

    }// function debug_whereat
    [/php]

  • WordPress 3.3 Shortcode Issue

    If you find yourself scratching your head over why your shortcodes have stopped working in WordPress 3.3, we’ve discovered a funny quirk. Granted, this fix may actually be the right way to call all shortcodes, but previously we’ve been able to lazily call it directly from our functions.php file and no one cared. But, now it seems, with the upgrade, that WordPress 3.3 does care. It requires your add_shortcode() function to be called within their init() hook. Calling it directly after your newly declared shortcode function won’t work anymore.

    The lazy method we got away with before:

    [php]
    function abtcore_shortcode_button( $atts, $content = null ) {
    extract( shortcode_atts( array(
    ‘color’ => ‘blue’
    ), $atts ) );
    return ‘<p>’ . $content . ‘</p>’;
    }

    add_shortcode( ‘button’, ‘abtcore_shortcode_button’ );
    [/php]

    The better way that is now required by WordPress 3.3:

    [php highlight=”7″]
    function abtcore_shortcode_button( $atts, $content = null ) {
    extract( shortcode_atts( array(
    ‘color’ => ‘blue’
    ), $atts ) );
    return ‘<p>’ . $content . ‘</p>’;
    }
    add_action(‘init’, ‘abtcore_register_my_shortcodes’, 100);
    function abtcore_register_my_shortcodes() {
    add_shortcode( ‘button’, ‘abtcore_shortcode_button’ );
    }
    [/php]

    Notice the add_action() call on the ‘init’ on line 7. This will properly register your shortcode function when WordPress initiates.

    I hope this helps.

  • How to add custom fields to Drupal 7 breadcrumb

    Breadcrumbs in Drupal 7 are normally based on the menu title.  However, what if you wanted different breadcrumb text than what appears in the menu?  For example, you have a small space and long titles, and would rather use abbreviations in your breadcrumb to save space (usability concerns aside).
    I’m aware of modules like Custom Breadcrumb, but I wasn’t able to find anything that allowed me to:

    1. Create a custom field on a node
    2. Optionally use that field (if populated) instead of the menu title in the breadcrumb list

    So, add the following to your template.php file after creating a node field field_breadcrumb. If you have a better idea, let me know in the comments!

    Based on digging through hook_menu_breadcrumb_alter and menu_get_active_breadcrumb.
    [php]

    /**
    * Reconfigure the breadcrumb trail to use each parent’s custom field
    * @see hook_menu_breadcrumb_alter
    * @see menu_get_active_breadcrumb
    *
    * @param array $active_trail the current page active trail
    * @param whatever $item the current trail item
    */
    function YOURTHEME_menu_breadcrumb_alter(&amp;$active_trail, $item) {

    // must step through each menu item, check to see if it has the ‘custom breadcrumb’ field
    foreach( $active_trail as &amp;$crumb ) :
    $node_id = str_replace(‘node/’, ”, $crumb[‘link_path’]);
    if( $node_id ) :
    // get the node to find the field
    $node = node_load($node_id);
    // best…function…ever
    $crumb_text = field_get_items(‘node’, $node, ‘field_breadcrumb’);

    // replace existing text if we should
    if( $crumb_text ) :
    $crumb[‘link_title’] = $crumb_text[0][‘safe_value’];
    $crumb[‘title’] = $crumb_text[0][‘safe_value’];
    endif;

    endif;
    endforeach;

    // add a sacrificial final item, since that gets removed later on
    $active_trail []= $crumb;

    }//– fn YOURTHEME_menu_breadcrumb_alter

    /**
    * Return a themed breadcrumb trail.
    *
    * Implements Zen theme `zen_breadcrumb`. Paired with XYZ_menu_breadcrumb_alter, which appended a sacrificial duplicate
    *
    *
    * @param $variables
    * – title: An optional string to be used as a navigational heading to give
    * context for breadcrumb links to screen-reader users.
    * – title_attributes_array: Array of HTML attributes for the title. It is
    * flattened into a string within the theme function.
    * – breadcrumb: An array containing the breadcrumb links.
    * @return
    * A string containing the breadcrumb output.
    */
    function YOURTHEME_breadcrumb($variables) {
    if( isset( $variables[‘breadcrumb’]) &amp;&amp; !empty( $variables[‘breadcrumb’] )) :
    // Don’t show a link to the current page in the breadcrumb trail.
    // this should automatically take into account theme settings…
    $last_key = end( array_keys( $variables[‘breadcrumb’] ) );
    $end = end( $variables[‘breadcrumb’] );
    $current_path = url(request_path(), array(‘absolute’ =&gt; false));
    if ( false !== strpos($end, $current_path) ) {
    $variables[‘breadcrumb’][$last_key] = strip_tags( $end );
    }
    endif;
    // business as usual
    return zen_breadcrumb($variables);
    }//– fn YOURTHEME_breadcrumb
    [/php]
    Todo: make this a module…