Add your plugins search ranking to your dashboard (Plugin Developer Stats Part 4)

Inspired by Iain Poulson’s service Plugin Rank I wanted to see this metrics in my personal dashboard. He offers a great tool but I didn’t want to check another service, so I’m going to add this feature to my own metabase dashboard right now.

If you haven’t read part 2 and part 3 of this post series please go back to these articles because in part 2 we created ans populated a SQLite database which is necessary for this chapter and in part 3 we used this database as a data source in metabase. This part extends both of them.

Search WordPress plugins via API

Using the same API we already used in part 2 we can’t just get plugins by author but also find them by a search term. This is the way the plugin search in WordPress backend works. In my opinion this search is at least as important for WordPress plugins as Google is.

http://api.wordpress.org/plugins/info/1.2/

Instead of the author parameter we used in part 2 we use the parameter search now.

our search request in Postman

In our use case we search for “email template”.

Get Plugin Search Ranking via PHP script

Our API call looks like this:

$result = callAPI( 'GET', 'http://api.wordpress.org/plugins/info/1.1/',[
                  'action' => 'query_plugins',
                  'timeout' => 15,
                  'request' => [
                     'per_page' => 250, // 250 is the max allowed
                     'search' => $searchterm,
                     'fields' => [
                              'sections'      => false,
                              'description'   => false,
                              'homepage'      => false,
                              'ratings'       => false,
                              'requires'      => false,
                              'downloaded'    => false,
                              'tags'          => false,
                              'last_updated'   => false,
                              'active_installs'=> false
                     ]
               ]
         ]   
      );

We can pass a variable $searchterm and filter the results afterwards to get the ranking of our plugin. The API allows us to get up to 250 search results per page which is enough for me. If my plugin is not within these 250 plugins I just return 250 as result instead of going through the following pages. But you should know this limitation because it could impact your statistics.

Here’s the full script:

<?php
function callAPI($method, $url, $data){
   $curl = curl_init();

   switch ($method){
      case "POST":
         curl_setopt($curl, CURLOPT_POST, 1);
         if ($data)
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
         break;
      case "PUT":
         curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
         if ($data)
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);			 					
         break;
      default:
         if ($data)
            $url = sprintf("%s?%s", $url, http_build_query($data));
   }

   // OPTIONS:
   curl_setopt($curl, CURLOPT_URL, $url);
   curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);

   // EXECUTE:
   $result = curl_exec($curl);
   if(!$result){die("Connection Failure");}
   curl_close($curl);
   return $result;
}

function getRanking($searchterm,$slug){
   $result = callAPI( 'GET', 'http://api.wordpress.org/plugins/info/1.1/',[
                  'action' => 'query_plugins',
                  'timeout' => 15,
                  'request' => [
                     'per_page' => 250, // 250 is the max allowed
                     'search' => $searchterm,
                     'fields' => [
                              'sections'      => false,
                              'description'   => false,
                              'homepage'      => false,
                              'ratings'       => false,
                              'requires'      => false,
                              'downloaded'    => false,
                              'tags'          => false,
                              'last_updated'   => false,
                              'active_installs'=> false
                     ]
               ]
         ]   
      );
   $result = json_decode($result);
   $plugins = $result->plugins;

   foreach( $plugins as $index => $plugin ){
      if( $plugin->slug == $slug )
         return $index+1;
   }

   return 250;
}



function maybe_create_database_table( $db ){
    $sql = "
            CREATE TABLE IF NOT EXISTS searchranking
            (
               ID INTEGER PRIMARY KEY AUTOINCREMENT,
               slug        CHAR(100)    NOT NULL,
               searchterm  CHAR(255)    NOT NULL,
               ranking     INTEGER,
               TIMESTAMP DATETIME DEFAULT CURRENT_TIMESTAMP
            );
        ";
    $db->exec($sql);
}



$plugins = [
      'wp-html-mail' => [
         'email template',
         'email design',
         'mail designer',
         'email',
         'woocommerce email',
         'woocommerce mail'
      ],
      'cleverreach' => [
         'cleverreach',
         'newsletter'
      ]
   ];
require( 'db.php' ); 
$db = new CQDashboardDB();
if($db) {
   maybe_create_database_table( $db );
   
   foreach( $plugins as $slug => $searchterms ){
      foreach( $searchterms as $searchterm ){
         $ranking = getRanking($searchterm, $slug);
         echo "$slug, $searchterm: " . $ranking ."\n";
         $sql = "
            INSERT INTO searchranking( slug, searchterm, ranking )
            VALUES( '$slug', '$searchterm', $ranking );
         ";
         $db->exec($sql);
      }
   }
}

It uses the SQLite database connection we created in part 2 and an array of plugin slugs and search terms. Copy the code above and paste it to a new file wordpressorg-search-ranking.php next to the files db.php and wordpressorg.php created in part 2.

Afterwards replace the $plugins variable with your plugins slug and search terms.

Open a terminal, navigate to the directory where you saved this script and run

php wordpressorg-search-ranking.php

If everything works fine you just have to schedule future executions of your script using cron. In part 2 we created a bash script run-hourly.sh. For the search ranking it should be enough to run it once a day/night so I’m using a script run-nightly.sh to execute this php script:

#!/bin/sh
current_path="${0%/*}"
cd "$current_path"
php wordpressorg-search-ranking.php

To trigger this script type crontab -e and add this line:

0 1 * * * /home/YOUR-PATH/run-nightly.sh

Refresh your data source in Metabase

We have modified the structure of our data source by adding an additional database table. In Metabase it could take some time until it refreshes the table structure. If you want to speed up this process navigate to

Admin -> Databases -> WordPress.org Plugin Data

There’s a button to sync the database schema.

Show wordpress.org plugin search ranking in your Metabase dashboard

As we already did in Part 3 we click the button “Ask a question“.
Then we choose Simple Question and select our new database table.
We use a line chart and filter by one single plugin and add a graph per search term. (see screenshot below for settings)

The chart looks a little bit boring at the moment but I promise, it’s getting more interesting over time when our cron job fetches new data every day.

You can create another chart like this for each of you plugins.

In part 5 we are going to add our PayPal balance to the dashboard.