Advertisement
Plugins

Communicating With the WordPress.org Plugin API

by

Over the last few weeks I have been wondering on how to possibly pull data about my plugins hosted on WordPress.org and display it on my website. The first thing that came to mind was "Web Scrapping" but quite frankly this is a lot of work, feels like going back in time, and is not something a good web citizen should do. In some cases, it could be illegal.

I then came across a plugin called "I Make Plugins", developed by Mark Jaquith, which did just want I wanted by fetching data from the readme.txt file of a plugin. It works great but since WordPress allows us to search for plugins directly from the backend and also to see our favorite plugins, I knew there was a better way (or The WordPress Way) and further searching led me to the WordPress.org API. No detailed documentation on this page, but enough to get started knowing there is an API to do this more efficiently.


WordPress.org Plugins API

The URL where all plugin search / update related calls are made is http://api.wordpress.org/plugins/info/1.0/. To get a quick idea of how this works, open this link in a browser and add your plugin slug at the end, e.g. http://api.wordpress.org/plugins/info/1.0/custom-favicon/ and see what is returned.

This browser-based GET request displayed all plugin information for the plugin "Custom Favicon" in the format below. By replacing the last path of the URL with the slug of your plugin you would be able to see details specific to your plugin.

O:8:"stdClass":20:{s:4:"name";s:14:"Custom Favicon";s:4:"slug";s:14:"custom-favicon";s:7:"version";s:3:"1.0";s:6:"author";s:80:"<a href="http://www.dreamsonline.net/wordpress-themes/">Dreams Online Themes</a>";s:14:"author_profile";s:38:"http://profiles.wordpress.org/hchouhan";s:12:"contributors";a:3:{s:8:"hchouhan";s:38:"http://profiles.wordpress.org/hchouhan";s:12:"dreamsonline";s:42:"http://profiles.wordpress.org/dreamsonline";s:11:"dreamsmedia";s:41:"http://profiles.wordpress.org/dreamsmedia";}s:8:"requires";s:3:"3.5";s:6:"tested";s:5:"3.5.2";s:13:"compatibility";a:2:{s:5:"3.5.1";a:1:{s:3:"1.0";a:3:{i:0;i:100;i:1;i:5;i:2;i:5;}}s:3:"3.6";a:1:{s:3:"1.0";a:3:{i:0;i:100;i:1;i:1;i:2;i:1;}}}s:6:"rating";d:100;s:11:"num_ratings";i:3;s:10:"downloaded";i:1995;s:12:"last_updated";s:10:"2013-05-27";s:5:"added";s:10:"2013-05-27";s:8:"homepage";s:61:"http://www.dreamsonline.net/wordpress-plugins/custom-favicon/";s:8:"sections";a:4:{s:11:"description";s:594:"<p>Now easily upload a favicon and apple touch icon for your WordPress website and dashboard.</p></pre>
<p>Please report any bugs you find via <a href="http://www.dreamsonline.net/wordpress-plugins/custom-favicon/" rel="nofollow">http://www.dreamsonline.net/wordpress-plugins/custom-favicon/</a></p>

<h4>My Links</h4>

<ul>

<li>Twitter @<a href="https://twitter.com/dreams_media">harishchouhan</a></li>

<li>Google+ <a href="https://plus.google.com/u/0/103138475844539274387/">Harish Chouhan</a></li>

</ul>

Not very presentable, but hey, at least this is a good start to test if the API delivers plugin information quickly, which we can then display the way we like.

Until this point, most of what I was doing was just based on random trials. The only resource I could find was http://dd32.id.au/projects/wordpressorg-plugin-information-api-docs/ which tries to explain the various options and arguments that can be used when communicating with this API.

So How Does This Work?

To communicate with http://api.wordpress.org/plugins/info/1.0/ and retrive information you need to make a $POST request with 2 things:

  1. Post Action - such as, $_POST['action']
  2. Post Body - such as, $_POST['body'], which has to be a serialized object

The returned data from the API is an Object in all cases (except when visiting the API link from a browser). Even in case of an error, the returned data is still an object but with a single property, an error string.

My first attempt to retrive plugin information was something like this below example:

Example of Retriving Plugin Information Using wp_remote_post HTTP API

<?php

	$args = (object) array( 'slug' => 'custom-favicon' );

	$request = array( 'action' => 'plugin_information', 'timeout' => 15, 'request' => serialize( $args) );

	$url = 'http://api.wordpress.org/plugins/info/1.0/';

	$response = wp_remote_post( $url, array( 'body' => $request ) );

	$plugin_info = unserialize( $response['body'] );

	echo '<pre>' . print_r( $plugin_info, true ) . '</pre>';

?>

We will explain the code later but for now the above example code will return information about our plugin in the format shown below, in the event that everything works as intended:

stdClass Object
(
    [name] => Custom Favicon
    [slug] => custom-favicon
    [version] => 1.0
    [author] => Dreams Online Themes
    [author_profile] => http://profiles.wordpress.org/hchouhan
    [contributors] => Array
        (
            [hchouhan] => http://profiles.wordpress.org/hchouhan
            [dreamsonline] => http://profiles.wordpress.org/dreamsonline
            [dreamsmedia] => http://profiles.wordpress.org/dreamsmedia
        )

    [requires] => 3.5
    [tested] => 3.5.2
    [compatibility] => Array
        (
            [3.6] => Array
                (
                    [1.0] => Array
                        (
                            [0] => 100
                            [1] => 1
                            [2] => 1
                        )

                )

        )

    [rating] => 100
    [num_ratings] => 3
    [downloaded] => 2008
    [last_updated] => 2013-05-27
    [added] => 2013-05-27
    [homepage] => http://www.dreamsonline.net/wordpress-plugins/custom-favicon/
    [sections] => Array
        (
            [description] =>
Now easily upload a favicon and apple touch icon for your WordPress website and dashboard.



Please report any bugs you find via http://www.dreamsonline.net/wordpress-plugins/custom-favicon/



My Links




Twitter @harishchouhan

Google+ Harish Chouhan



If you love the plugin, please consider rating it and clicking on "it works" button.


            [installation] =>

Upload the directory /custom-favicon/ to the /wp-content/plugins/ directory

Activate the plugin through the 'Plugins' menu in WordPress

Click on "Custom Favicon" sub menu under the Settings menu and upload your favicon


            [changelog] =>
= 1.0.0
* This is the first version


            [faq] =>
Take a look at the official "Custom Favicon" FAQ.



You can also visit the support center and start a discussion if needed.


        )

    [download_link] => http://downloads.wordpress.org/plugin/custom-favicon.zip
    [tags] => Array
        (
            [admin] => admin
            [apple-touch] => apple touch
            [apple-touch-icon] => apple touch icon
            [blog] => blog
            [favicon] => favicon
            [icon] => icon
            [iphone] => iphone
            [theme] => theme
            [upload] => upload
            [wordpress] => wordpress
        )

    [donate_link] => http://www.dreamsonline.net
)

If you just wanted to display the download count, you could add like this:

echo '<p>Downloaded: ' . print_r( $plugin_info->downloaded, true ) . ' times</p>';

Note: This is just a test example and not intended to be used in actual projects as there is no error checking. If the slug is wrong or the connection to WordPress.org does not take place, the above code will display errors.

We can continue extending this example with error checking but is there a better way? And the answer is yes, with the plugins_api function.


The plugins_api Function

The plugins_api function is defined in wp-admin/includes/plugin_install.php.

<?php

function plugins_api($action, $args = null) {

	if ( is_array($args) )
		$args = (object)$args;

	if ( !isset($args->per_page) )
		$args->per_page = 24;

	// Allows a plugin to override the WordPress.org API entirely.
	// Use the filter 'plugins_api_result' to merely add results.
	// Please ensure that a object is returned from the following filters.
	$args = apply_filters('plugins_api_args', $args, $action);
	$res = apply_filters('plugins_api', false, $action, $args);

	if ( false === $res ) {
		$url = 'http://api.wordpress.org/plugins/info/1.0/';
		if ( wp_http_supports( array( 'ssl' ) ) )
			$url = set_url_scheme( $url, 'https' );

		$request = wp_remote_post( $url, array(
			'timeout' => 15,
			'body' => array(
				'action' => $action,
				'request' => serialize( $args )
			)
		) );

		if ( is_wp_error($request) ) {
			$res = new WP_Error('plugins_api_failed', __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="http://wordpress.org/support/">support forums</a>.' ), $request->get_error_message() );
		} else {
			$res = maybe_unserialize( wp_remote_retrieve_body( $request ) );
			if ( ! is_object( $res ) && ! is_array( $res ) )
				$res = new WP_Error('plugins_api_failed', __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="http://wordpress.org/support/">support forums</a>.' ), wp_remote_retrieve_body( $request ) );
		}
	} elseif ( !is_wp_error($res) ) {
		$res->external = true;
	}

	return apply_filters('plugins_api_result', $res, $action, $args);
}

?>

Parameters

The plugins_api function accepts 2 parameters: $action and $args:

1. The $action Parameter

Which can be any one of these 3 options below:

  1. query_plugins
  2. plugin_information
  3. hot_tags

2. The $args Parameter

Arguments are optional, and if set, have to be a serialized object. Arguments for each action are different and are explained in detail later in this article.

Data Returned

The data returned depends on the action chosen. The action "plugin_information" returns a single object whereas the other two actions return an array of objects. In case of an error such as the absence of an action or slug parameter, the plugin_api function also returns an object with a single property "error" and a value (string) "Slug not provided" or "action not implemented".

An Example of Using plugins_api Function

We will now try the same example we used earlier but using the plugins_api function instead of wp_remote_post from the HTTP API.

<?php

	/** Prepare our query */
	$call_api = plugins_api( 'plugin_information', array( 'slug' => 'custom-favicon' ) );

	/** Check for Errors & Display the results */
	if ( is_wp_error( $call_api ) ) {

		echo '<pre>' . print_r( $call_api->get_error_message(), true ) . '</pre>';

	} else {

		echo '<pre>' . print_r( $call_api, true ) . '</pre>';

		if ( ! empty( $call_api->downloaded ) ) {

			echo '<p>Downloaded: ' . print_r( $call_api->downloaded, true ) . ' times.</p>';

		}

	}

?>

The above code will return the data in the same way our previous example had. As you can see, this requires a few lines of code and a connection to the WordPress.org Plugin API, unserializing the returned object and initial error checking is all handled by the plugins_api function.

In both the examples above, we only used the "plugin_information" action and a slug with no other arguments as our intention was just to retrieve all possible information about our plugin.

2.1 Arguments for query_plugins

2.1.1. browse

It displays the list similar to http://wordpress.org/plugins/browse/popular/. The possible values are:

  • popular
  • new
  • updated
  • top-rated

2.1.2. search

The term to search for.

2.1.3. tag

Search plugins by a tag.

2.1.4. author

Search plugins from an author.

Note: Between browse, search, tag and author only one argument can be used at a time.

2.1.5. page (optional)

The page number of the results.

2.1.6. per_page (optional)

The number of results to display per page.

2.1.7. fields (optional)

Similar to plugin_information fields listed below.

Example of a query for the most popular plugins:

	$call_api = plugins_api( 'query_plugins',
		array(
			'browse' => 'top-rated',
			'page' => '1',
			'per_page' => '5',
			'fields' => array(
				'downloaded' => false,
				'rating' => false,
				'description' => false,
				'short_description' => false,
				'donate_link' => false,
				'tags' => false,
				'sections' => false,
				'homepage' => false,
				'added' => false,
				'last_updated' => false,
				'compatibility' => false,
				'tested' => false,
				'requires' => false,
				'downloadlink' => true,
			)
		)
	);

Returns an array of objects similar to what plugin_information returns.

2.2 Arguments for plugin_information

2.2.1. slug

The slug of the plugin for which we need to return information.

2.2.2. fields (optional)

By default all the fields from the readme.txt are displayed along with some additional fields such as the total number of downloads, rating and download link. However if you only need to retrieve just a few fields you can override this by sending in an array of key / value pairs, where the field is the key and true / false as the value depending on whether you wish the field to be returned or not.

Example of overriding fields:

	/** Prepare our query */
	$call_api = plugins_api( 'plugin_information',
		array(
			'slug' => 'custom-favicon',
			'fields' => array(
				'downloaded' => false,
				'rating' => false,
			)
		)
	);

The fields that can be overridden are:

  • added
  • compatibility
  • downloadlink (Note: that the actual key is "download_link" but to not return this data, we need to set the field as “downloadlink”)
  • donate_link
  • homepage
  • last_updated
  • rating
  • require
  • sections
  • tags
  • tested

2.3 Arguments for hot_tags

2.3.1. number

The number of tags to return. The default is 100.

hot_tags action example:

	/** Prepare our query */
	$call_api = plugins_api( 'hot_tags',
		array(
			'number' => '50',
		)
	);

This will return an array of objects with the key being the tag slug and each object would contain:

  • Tag Name
  • Tag Slug
  • Count - The Number of plugins marked with this tag

Summary

Internally WordPress core uses the plugins_api function to display a list of plugins based on the keyword used for search, to retrieve your favorite plugins and also to display information about any specific plugin. By changing the action parameter, you can use the function to perform different tasks.

Information about the WordPress.org API is not widely available and the reason could possibly be to avoid abuse of the system, hence make sure your requests to WordPress.org API are limited and done in the right way. Use Transients to cache the data so you do not have to make a request on every page load.

In a future tutorial we will create a plugin with a shortcode to display your plugin download count.

Related Posts
  • Code
    Plugins
    Distributing Your Plugins in GitHub with Automatic UpdatesSensorsthumbnail
    This article will teach you that, with a little creative coding, you can host your own WordPress plugins in GitHub while still retaining the automatic update feature.Read More…
  • Code
    Creative Coding
    Using WordPress for Web Application Development: Features: Custom Queries with WP_QueryApplication foundation 400
    We've been looking at how WordPress can be used as a foundation for application development, but one of the things that we've yet to cover that most modern frameworks offer is how to query the database to retrieve results for any given view. Specifically, we haven't talked about how to get information out of the database and insert it into our pages.Read More…
  • Code
    PHP
    Creating a Photo Tag Wall With Twilio Picture Messaging & PHPProcedural to oop php retina preview
    Twilio's recently announced Picture Messaging has vastly opened up what we can do with text messaging, now we can attach photos to our text messages and have them get used in different ways. In our case, we are going to build a Photo Tag Wall, which will contain photos linked to tags that will be displayed on a website.Read More…
  • Code
    Plugins
    Using HighCharts in WP-AdminHighcharts 400
    Charts are a great way to present data. They make data more digestible by making it visually appealing. In WordPress, there is no built-in method for getting posts and pages data in a graphical form. Although, there are certain plugins available which integrate Google Analytics with WordPress, but they are overkill if you want to get only a portion of that data. Also, nothing should keep you from learning new techniques and to dive straight into the subject is the best way to learn.Read More…
  • Code
    Plugins
    Displaying Information of a WordPress.org Plugin on Your WebsiteWordpressdotorg plugin api border 400
    In the first part of this article, we discussed how to use built-in functions to communicate with WordPress.org and retrieve plugin details. In this tutorial we will put the theory in action to create a simple plugin which will allow us to display details of any plugin hosted on WordPress.org on our WordPress website using shortcodes.Read More…
  • Code
    Creative Coding
    Interacting with WordPress' Plug-in & Theme APIInteractingwithwordpressapi
    The WordPress Repository API is the API used to fetch plug-in and theme information for use on your admin pages. For instance it displays the latest plug-ins on the dashboard, allows you to view themes on your theme tab and allows you to search for, and install, plug-ins straight from the repository. In this tutorial we're going to look at how this API works and how it can be used to access information such as your plug-in's rating, how many times it's been downloaded, or even its ReadMe sections. Using this API, for instance, you can host a link on your website that will always point to the latest version of your plug-in or theme.Read More…