Author Archives: J.D. Grimes

BuddyPress: Query Users by xProfile Data

Today I had a needed to query BuddyPress users by their extended profile data. I couldn’t find any functions in BuddyPress core that facilitate this, so I wrote my own. Here it is for anyone else who is looking for it:

/**
 * Get users by BuddyPress xprofile data.
 *
 * @param int    $field_id The ID of the field to search in.
 * @param string $value    The value to search for.
 * 
 * @return int[] The IDs of the users matching the search.
 */
function my_bp_get_users_by_xprofile( $field_id, $value ) {

	global $wpdb;

    $user_ids = $wpdb->get_col(
    	$wpdb->prepare(
    		"
    			SELECT `user_id`
    			FROM `{$wpdb->prefix}bp_xprofile_data`
    			WHERE `field_id` = %d
    				AND `value` = %s
    		"
    		, $field_id
    		, $value
    	)
    );
}

Usage:

$user_ids = my_bp_get_users_by_xprofile( 5, 'find me' );

If you need to get the field ID, you can use xprofile_get_field_id_from_name( 'field name' ).

Enjoy!

WordPress Documentation Lookup Within TextWrangler

I use TextWrangler as my code editor. This is one reason why.

Sometimes you want to look up something in the WordPress documentation, straight from your code editor. And with WordPress, that might be a function, a filter, or an action. It’s easy to add that feature to TextWrangler, just by adding an AppleScript file to the scripts folder (~/Library/Application Support/TextWrangler/Scripts/). Then you can access it from the scripts menu, which is the one with the little script icon. (To open the scripts folder, click on “Open Scripts Folder” under the scripts menu).

Here’s what you can put in the file to look up a function on the WordPress codex:

[applescript]
tell application "TextWrangler"
set function to selection of window 1 as string
if function = "" then
set function to text returned of (display dialog "WordPress Function:" default answer "")
end if

if function is not "" then
set target_URL to "http://codex.wordpress.org/Function_Reference/" & function
open location target_URL
end if
end tell
[/applescript]

Simple, huh?

This will open a dialog prompt for you to type whatever function you want to look up, or if you have already selected the function’s name on the page, it will use that. Either way, the codex page for that function will open in your favorite browser.

You can easily customize this script to look up anything you want anywhere you want. Just change the target URL and dialog text accordingly.

Here’s a zip of my folder which includes filter and action look-up in addition to the function look-up. You can copy the entire folder to TextWrangler’s scripts folder, and it will create a new menu item named WordPress.

Quick Lookup with Browser Bookmarks

I’m a DRY person. I try not to repeat myself, or do tasks over and over manually when they could be automated. So I’ve started to create different bookmarks in my browser that automate different common tasks using JavaScript. I thought I’d share a few of these that can be used to look up WordPress related stuff in various references. Their usage is simple. Once you have bookmarked one of them in your browser, clicking on the bookmark will bring up a JavaScript prompt dialog box where you can enter whatever you are searching for. If you have already highlighted the text to search for on the page, then the prompt will be skipped.

It’s not hard to roll these, and you can make some yourself. Here’s an example. Just make a few changes and strip out the white space.

javascript:
	q = document.getSelection();

	if ( q.rangeCount < 1 )
		void( q = prompt( 'WP%20Seek:', '' ) );

	void( q = escape( q ) );

	if ( q && q != 'null' ) 
		location.href = 'http://wpseek.com/' + q

Programmatically‎ Creating a WordPress Widget Instance

Occasionally in WordPress development one finds the need to create an instance of a widget programmatically‎. I found a need for this when writing some unit tests for my WordPoints plugin. The code that you can use to do this is below. It shouldn’t be hard to understand its use.

/**
 * Programmatically save a new widget instance.
 *
 * Based on wp_ajax_save_widget().
 *
 * @param string $id_base    The base ID for instances of this widget.
 * @param array  $settings   The settings for this widget instance. Optional.
 * @param string $sidebar_id The ID of the sidebar to add the widget to. Optional.
 *
 * @return bool Whether the widget was saved successfully.
 */
function my_add_widget( $id_base, array $settings = array(), $sidebar_id = null ) {

	global $wp_registered_widget_updates;
	static $multi_number = 0;
	$multi_number++;

	$sidebars = wp_get_sidebars_widgets();

	if ( isset( $sidebar_id ) ) {

		$sidebar = ( isset( $sidebars[ $sidebar_id ] ) ) ? $sidebars[ $sidebar_id ] : array();

	} else {

		$sidebar_id = key( $sidebars );
		$sidebar = array_shift( $sidebars );
	}

	$sidebar[] = $id_base . '-' . $multi_number;

	$_POST['sidebar'] = $sidebar_id;
	$_POST[ "widget-{$id_base}" ] = array( $multi_number => $settings );
	$_POST['widget-id'] = $sidebar;

	if (
		! isset( $wp_registered_widget_updates[ $id_base ] )
		|| ! is_callable( $wp_registered_widget_updates[ $id_base ]['callback'] )
	) {

		return false;
	}

	$control = $wp_registered_widget_updates[ $id_base ];

	return call_user_func_array( $control['callback'], $control['params'] );
}

Example usage:

my_add_widget( 
	'rss'
	,array( 
		'title' => 'Test Widget', 
		'items' => 5, 
		'url'   => 'https://codesymphony.co/feed/' 
	)
	,'sidebar-1'
);

Enjoy!

WordPress Unit Testing: Deprecated Functions

A new feature has just been introduced into the WordPress test suite: the @expectedDeprecated notation. This notation is modeled after PHPUnit’s built-in @expectedException notation, and allows you to test for the use of deprecated functions or function arguments in your test suites. (You do have a suite of unit tests for your plugin, don’t you?)

This new feature comes as the result of a charge to clean up the WordPress unit tests, lead by @wonderboymusic. I’m really glad to see this happen, because the tests, like any WordPress development environment, really should be run with WP_DEBUG on, and when I tried that a few weeks ago I encountered plenty of notices. Many of those notices were about the use of deprecated functions in the test suite. The use of these functions is intentional, and is meant to test for backward compatibility. The new notation provides a way to test deprecated functions, and at the same time test that the proper deprecated notices are given. Also as a result of this, any time a deprecated function is used in a suite and it hasn’t been @expectedDeprecated, the test will fail. Tests which expect deprecated notices and don’t get them will also fail.

The usage of this new annotation is simple enough. If you have a test case that uses a deprecated function or argument, then add an @expectedDeprecated to the docblock for the test function where the deprecated function or function argument is used. In the below example, we’ll test one of your project’s functions that has been deprecated, and another that has a deprecated argument:

<?php

/**
 * A test case.
 *
 * In case we fail, we test.
 */
class My_Deprecated_Function_Test extends WP_UnitTestCase {

	/**
	 * Test these this deprecated functions are backward compatible.
	 *
	 * They have to give deprecated notices too, or else this won't pass.
	 *
	 * @expectedDeprecated my_deprecated_function
	 * @expectedDeprecated function_with_deprecated_arg
	 */
	public function test_my_deprecated_function() {
	
		$this->assertTrue( my_deprecated_function() );
		$this->assertEquals( 4, function_with_deprecated_arg( 'deprecated' ) );
	}
}

You can also use this when testing for backward compatibility with older versions of WordPress, by marking any deprecated WordPress functions used as @expectedDeprecated.

The notation can also be used in the class docblock, if all of your tests in a test case class will be using the deprecated function.