Search Results

Entries tagged with “php” from Trendrr Developer Portal

July 27, 2009 10:17 AM

This example demonstrates how to grab data from the Internet source of your choice and utilize the api/account/my_graphs and api/account/start_tracking API functions. The program below utilizes Twitter's search API to get the latest trends and automatically creates Trendrr graphs for the phrases returned.


The structure provided is quite linear in nature, though a more robust and abstract class system was created to automate graph creation for multiple sources. The more advanced version is available for download, but I thought it would be easier to comprehend the API flow linearly to start. Don't worry, I'm an advanced PHP5 developer normally :-) Let's begin at the top.


index.php


require_once 'TrendrrRequest.php';


$datasource_id = 115; // Twitter Search
$feed = 'http://search.twitter.com/trends.json';


// Get JSON object of Twitter trends
$twitter_obj = getTwitterTrends($feed);


...



TrendrrRequest is a class I created to handle the low level calls to the API. The source code is included in the advanced download. Two other things I will need ahead of time are the source of information (The url to Twitter's Trends) and the ID of the Trendrr data source I will be using to create a graph. All of the data source IDs can be found here or by using the api/account/data_sources call. Next, I call a function I defined to get information from Twitter and save it as an object. Let's take a look at this function.


getTwitterTrends()

function getTwitterTrends($feed) {


  $curl_obj = curl_init($feed);
  if ($curl_obj === false) { return false; }


  curl_setopt($curl_obj, CURLOPT_RETURNTRANSFER, 1);
  $source = curl_exec($curl_obj);
  curl_close($curl_obj);


  if ($source === false) { return false; }
  return json_decode($source);
}



The function utilizes a cURL session to make the Twitter API request. It will return false if the process fails at any point. If everything works, it will decode the response into a JSON object for the return value. Now, for the rest of the main source code.


index.php

...
if ($twitter_obj !== false) {


  // Get the array of trends from the JSON return
  $trends_array = $twitter_obj->trends;


  if (!empty($trends_array)) {


    // Make a graph for each trend if it doesn't already exist
    foreach ($trends_array as $trend) {


      // Search for existing graph
      if (!graphExistsFor($trend->name, null, $datasource_id)) {


        // Start tracking the new trend
        $request = startTracking(
          $datasource_id,
          createTagArray($trend->name),
          $trend->name
        );


        // Display the result
        echo $request->getResultMessage(),"\n";
      }
    }
  }
}



Ok, there are a few things here, but it would be more confusing to split it up. The first thing is to make sure that a JSON object was actually created and that the function didn't return false. From there, I save 'trends' from the JSON object which is actually an array of the trends. And as long as that array is not empty, we are going to make a graph for each trend (hence a foreach loop).


In order to avoid numerous duplicate and repetitive graphs, I'll be using the api/account/my_graphs function in the Trendrr API to see if a phrase is already being tracked within my own graphs. Let's take a closer look at the graphExistsFor() function which I use in the code above.


graphExistsFor()

function graphExistsFor($input1, $datasource_id) {


  $api_string = 'api/account/my_graphs?'.
    'input1='.urlencode($input1).
    '&datasource_id='.$datasource_id;


  $request = new TrendrrRequest($api_string);


  if ($request != null) {
    $graph_number = $request->getNumberOfElementsByTagName('graph');
    return ($graph_number !== 0);
  }
  return false;
}



api/account/my_graphs actually doesn't require any parameters, but you can refine a search (instead of returns all of your graphs) using input1, input2, and a datasource_id. In this example, I'm using the Twitter trend as input1 and twitter search datasource_id. Note that I do not have to limit the graphs I create to the Twitter Search data source, but it is the most logical. I could have used Twitter's API to get the trends and then create graphs that track these phrases on different blogging or video sites. A TrendrrRequest object handles the call and then I check if there are any graph tags in the response XML. If none exist, then we need to track this trend!


You'll notice that if a graph doesn't exist, another function (which I defined) is called; startTracking(). This takes the data source id, an array of tags, and the actual trending phrase as arguments. Don't worry too much about createTagArray(). All this does is take the input and explode it so each word in the input becomes an element in the array of tags. Plus, it's in the download if you really want to check it out. A closer look at the tracking function:


startTracking()

function startTracking($datasource_id, $tags_array, $input1) {
  $api_string = 'api/account/start_tracking?'.
    'input1='.urlencode($input1).
    '&datasource_id='.$datasource_id;


  // TAGS
  $tag_string = null;
  if (!empty($tags_array)) {
    $tag_string .= '&tags=';
    foreach ($tags_array as $key => $tag) {
      if ($key != 0) { $tag_string .= '+'; }
      $tag_string .= urlencode(trim($tag));
    }
  }
  $api_string .= $tag_string;


  // Make the request
  return new TrendrrRequest($api_string);
}



api/account/start_tracking has three required parameters. You could have probably guessed that these are at least one input, a set of tags, and a data source ID. The first thing is to set up the values for these parameters into a string for the API call. You'll notice that I have multiple tags, so I add pluses in between to distinguish them from one another. After that, I just need to send the request. If all was successful, my Twitter Search graphs using the Twitter Trends should be in my Trendrr account.


There's a bit more you can add to this code, which I have included in the advanced version that's supposed to be run on the command line. It will also include functions to check response codes and echo more response messages. I suggest you take a look once you grab the basics here. Also take a look at my TrendrrRequest class to see how I handle the API communication.


And an important note: make sure to always have your inputs URL encoded!


Download advanced version

June 30, 2008 12:20 PM

This is another example of how to use a custom data source. In this case, the graph information will be coming from my Folding@Home statistics. Before writing any code, I logged into Trendrr.com and went to Start Tracking»Add Custom Data Set. My data source input key is given once the form is filled out appropriately. Now for the custom development. First, I will show the entire PHP file I use in order to retrieve Folding@Home data and then explain each piece.



<?php


include('foldingStats.php');


// Only submit data if accessed by cron
if ($_SERVER['argv'][1] == 'cron') {


  // Get score, rank, and WUs for a specific user
  if ($folding_stats = getFoldingStats('jbulava')) {


    $api_url = 'http://www.trendrr.com/api/import/timeseries?';
    $dataset_key = '<API Key>';
    $score = $folding_stats['score'];


    // Send value to your custom data source
    $ch = curl_init($api_url.'dataset_key='.$dataset_key.'&value='.$score);
    curl_exec($ch);
    curl_close($ch);
  }
}
else {
  echo 'Folding@Home data sent only when accessed by cron.';
}


?>



The included foldingStats.php file does the data-mining magic; we'll get back to that. As in my Facebook API example, a cron job has been set up on my server to call this file on a periodical basis. Here's the definition I used.



0 * * * * php -f /<some directory>/datasources/folding/index.php cron



If the command line argument 'cron' is present, which is used to avoid non-uniform data points via accessing the file through a browser, the 'getFoldingStats' method is called from the included file. All we need to know right now is that it will return the 'score,' 'rank,' and 'work_units' of the given Folding@Home user as an associative array with these words as the key values. If the results are returned successfully, three important variables are set; the API URL, the data set key that was obtained when adding a new data source, and my Folding@Home score using the returned associative array. Now cURL can be used to piece together the full RESTful URL and submit a data point to Trendrr.


The actual process to obtain the statistics is less about using our API, but can be a valuable example as to how you may obtain data. cURL is used to make an HTTP request and the source code is stored as a string. As long as there is no statistic update in progress, this string is then parsed to obtain the numbers for rank, score, and number of work units.



<?php


/**
 * Filename: foldingStats.php
 * Created: Jun 24, 2008
 * @author: jbulava
 * @version: 1.0
 *
 * Library to access and retrieve Folding@Home stats.
*/


/**
* Retrieves score, rank, and work units for the given username.
*/
function getFoldingStats($username) {


  if ($username == null)
    return false;


  // Grab page source with stats
  $statsPage = curl_init('http://fah-web.stanford.edu/cgi-bin/main.py?qtype=userpage&username='.$username);
  curl_setopt($statsPage, CURLOPT_RETURNTRANSFER, 1);
  $pageSource = curl_exec($statsPage);
  curl_close($statsPage);
  $pageSource = strip_tags($pageSource);


  // Check for unavailable server due to updates since this happens a lot
  if (stristr($pageSource, 'Stats update in progress'))
    return false;


  // Isolate stats
  $username = strtolower($username);
  $statsStartPos = strpos($pageSource, 'Donator') + 8;
  $statsEndPos = strpos($pageSource, 'Detailed listing', $statsStartPos);
  $stats = substr($pageSource, $statsStartPos, ($statsEndPos - $statsStartPos) );
  $stats = str_replace("\n", "", $stats);
  $stats = str_replace("\t", "", $stats);


  // Get total score
  $strStart = strpos($stats, 'Score') + 6;
  $strEnd = strpos($stats, '(certificate)', $strStart);
  $score = trim(substr($stats, $strStart, ($strEnd - $strStart) ));


  // Get overall rank
  $strStart = strpos($stats, 'Donator Rank') + 13;
  $strEnd = strpos($stats, 'of', $strStart);
  $rank = trim(substr($stats, $strStart, ($strEnd - $strStart) ));


  // Get total work units
  $strStart = strpos($stats, 'WU') + 3;
  $strEnd = strpos($stats, '(certificate)', $strStart);
  $units = trim(substr($stats, $strStart, ($strEnd - $strStart) ));


  return array(
    'score' => $score,
    'rank' => $rank,
    'work_units' => $units
    );
}


?>

June 19, 2008 2:56 PM

Here is an example which connects the Trendrr API to the Facebook API, allowing statistical analysis of social data. The RSVP statuses of a specific event are collected and graphed (i.e. users who have accepted, declined, or are unsure of the invitation). In return, the Facebook markup language (FBML) is refreshed to show the latest graph for this application on both the user profile and canvas pages. First, three Custom Data Sets, one for each RSVP status, are created via Start Tracking»Add Custom Data Set on Trendrr. The API keys provided for each data set will be necessary to submit the number of users in each category.

The Facebook API can only be used within a Facebook application and, therefore, one has been created for this example. Those new to Facebook development can find out more on the Facebook developer wiki. The main components of the application will be located within one index.php file described below in detail, one section at a time.

The beginning of this PHP file initializes the typical Facebook information and should look familiar to those who have developed applications for the site. This piece also establishes a user and session key for a scheduled cron job to update the graph data every hour. The implementation of a cron job will be discussed later. For additional information on this technique, visit Infinite Session Howto on the developer wiki site.

require_once 'facebook.php';

$appapikey = '<Your Facebook API key>';
$appsecret = '<Your Facebook secret key>';
$facebook = new Facebook($appapikey, $appsecret);

// Set up user with infinite key (for cron access)
$user = '<user id>';
$key = '<user's session key>';
$facebook->set_user($user, $key);

// Callback url
$appcallbackurl = '<your callback url>';

// Catch the exception that gets thrown if the cookie has an invalid session_key in it
try {
  if (!$facebook->api_client->users_isAppAdded()) {
    $facebook->redirect($facebook->get_add_url());
  }
} catch (Exception $ex) {
  //this will clear cookies for your application and redirect them to a login prompt
  $facebook->set_user(null, null);
  $facebook->redirect($appcallbackurl);
}

Secondly, we need to gather all the appropriate information in order to upload statistics to Trendrr. Given an event id, the Facebook API is used to return all users that have been invited to this event. The numbers for each RSVP category can then be calculated and stored. The last three lines define the API keys for the data sets previously set up on Trendrr. These keys can be found on your My Graphs»my data page.

// Get event members
$event_id = 8414464684; //Pillow Fight NYC 2008
$event_members = $facebook->api_client->events_getMembers($event_id);

// Get RSVP numbers
$attending = sizeof($event_members['attending']);
$notsure   = sizeof($event_members['unsure']);
$declined  = sizeof($event_members['declined']);

// API keys for Trendrr
$attending_key = '<api key for data set>';
$notsure_key   = '<api key for data set>';
$declined_key  = '<api key for data set>';

The URL syntax defined in the Trendrr API is utilized to retrieve the RSVP data. The curl functions in PHP allow this page to access these URLs and provide values.

// Send information to Trendrr (if accessed by cron job)
if ($_SERVER['argv'][1] == 'cron') {
    $a = curl_init("http://www.trendrr.com/api/import/timeseries?dataset_key=" . $attending_key . "&value=" . $attending);
    curl_exec($a); curl_close($a);
    $n = curl_init("http://www.trendrr.com/api/import/timeseries?dataset_key=" . $notsure_key . "&value=" . $notsure);
    curl_exec($n); curl_close($n);
    $d = curl_init("http://www.trendrr.com/api/import/timeseries?dataset_key=" . $declined_key . "&value=" . $declined);
    curl_exec($d); curl_close($d);
}

Notice that the curl statements are located within an if statement looking for the argument string 'cron.' To automatically post data, a cron job has been defined on our UNIX server to access this Facebook application every hour. Requiring the 'cron' argument for this block of code ensures that data points are not added to Trendrr when the page is accessed manually in a browser. The line for the cron job is shown below. We realize that not everyone will have the ability or access to generate their own automated jobs, and therefore we recommend webcron.org, a web service for creating such automated tasks.

0 * * * * php -f /<some directory>/index.php cron

Displaying the latest results is the final step for this Facebook page. The 'embed_img' URL is the Trendrr defined embedding code on the graph's customization page. This graph, however, is not one of the above data sets, but rather all three as one. Within Trendrr, multiple data sets can be combined and then this new graph can be accessed for display.

The embedded image URL will return the latest graph as an image. Facebook automatically caches application images, thus an API call to refresh the image is necessary due to the graph's dynamic nature. A Cascading Style Sheet (CSS) is included to display the canvas and profile pages in different styles, but is not necessary. The FBML is then displayed on the canvas page and passed to 'profile_setFBML' to update the user's profile.

// Refresh the graph image and set the FBML
$embed_img = 'http://www.trendrr.com/public/graphs/369161';
$facebook->api_client->fbml_refreshImgSrc($embed_img);
$fbml = '<img width="380" height="285" src="'.$embed_img.'" />';

// Include style, display FBML for the canvas page, and set the FBML for the profile page
include_once 'lib/main.css';
echo '<div id="canvas">'.$fbml.'</div>';
$facebook->api_client->profile_setFBML('<div id="profile">'.$fbml.'</div>', $user);

Manually visiting this page on Facebook, either on the canvas or profile page, will display the latest results for the graph which combines all three data sets. When the cron job accesses the page, the curl functions will execute the API defined URLs to send the event information back to Trendrr.