Twitter rappresenta un ottimo esempio di una piattaforma che fornisce API per l'interazione con i plugin di WordPress. In questo capitolo vedremo come estrarre dati da Twitter utilizzando queste interfacce per la programmazione.
Le API di Twitter
Per descrivere il nostro progetto si può cominciare dal sito ufficiale per gli sviluppatori di Twitter. Quello che bisogna capire da subito è che le API di Twitter funzionano solo tramite autenticazione. Occorre infatti creare un'app e ottenere così le credenziali di accesso per poter usare le API (sezione "Keys and Access Tokens" di ogni app).
Un'app può avere diversi permessi: lettura, scrittura o entrambi. Un'app in sola lettura potrà leggere i tweet di un utente, effettuare ricerche, visualizzare i trend del giorno ma non postare un tweet mentre, al contrario, un'app con permessi di scrittura potrà effettuare anche quest'ultima operazione.
Ovviamente la pubblicazione dei tweet potrà avvenire unicamente tramite l'account Twitter che possiede l'app creata attraverso di esso. Per gli esempi mostrati in questo capitolo sarà sufficiente un'app in sola lettura.
Librerie PHP per Twitter
L'approccio migliore per lavorare con le API è quello di utilizzare una libreria PHP esistente che andrà poi ad integrare nella nostra implementazione.
Per Twitter possiamo usare la libreria TwitterOauth di Ricardo Pereira. Questa libreria supporta sia il metodo GET che POST, quindi è adatta sia per app in lettura che in scrittura.
Reperire i tweet da Twitter
Per reperire i tweet di un account Twitter dobbiamo utilizzare l'endpoint statuses/user_timeline
delle API. Creiamo una classe per questo scopo e per prima cosa includiamo la libreria TwitterOauth:
require_once( 'TwitterOauth.php' );
Quindi definiamo la struttura della classe:
class My_Twitter {
private $_connection;
public function __construct() {
$settings = array(
'oauth_token' => 'tuotoken',
'oauth_token_secret' => 'tuotokensecret',
'consumer_key' => 'tuaconsumerkey',
'consumer_secret' => 'tuoconsumersecret',
'output_format' => 'text'
);
$this->_connection = new TwitterOauth( $settings );
}
//…
}
Ora la proprietà privata _connection
contiene un'istanza della classe TwitterOauth. A questo punto ci servono due metodi privati per altrettanti compiti specifici:
- formattare le date di Twitter nel formato “… fa”;
- trasformare gli hashtags e gli URL in link HTML.
I metodi di riferimento saranno quindi i seguenti:
private function _relativeTime( $t ) {
$new_tweet_time = strtotime( $t );
return human_time_diff( $new_tweet_time, current_time( 'timestamp' ) );
}
private function _format( $tweet ) {
$tweet_text = $tweet->text;
$tweet_entities = array();
foreach( $tweet->entities->urls as $url ) {
$tweet_entities[] = array (
'type' => 'url',
'curText' => substr( $tweet_text, $url->indices[0], ( $url->indices[1] - $url->indices[0] ) ),
'newText' => '<a href=“' . $url->expanded_url . '”>' . $url->display_url . '</a>'
);
}
foreach ( $tweet->entities->user_mentions as $mention ) {
$string = substr( $tweet_text, $mention->indices[0], ( $mention->indices[1] - $mention->indices[0] ) );
$tweet_entities[] = array (
'type' => 'mention',
'curText' => substr( $tweet_text, $mention->indices[0], ( $mention->indices[1] - $mention->indices[0] ) ),
'newText' => '<a href=“https://twitter.com/' . $mention->screen_name . '”>' . $string . '</a>'
);
}
foreach ( $tweet->entities->hashtags as $tag ) {
$string = substr( $tweet_text, $tag->indices[0], ( $tag->indices[1] - $tag->indices[0] ) );
$tweet_entities[] = array (
'type' => 'hashtag',
'curText' => substr( $tweet_text, $tag->indices[0], ( $tag->indices[1] - $tag->indices[0] ) ),
'newText' => '<a href=“https://twitter.com/search?q=%23' . $tag->text . '&src=hash”>' . $string . '</a>'
);
}
foreach ( $tweet_entities as $entity ) {
$tweet_text = str_replace( $entity['curText'], $entity['newText'], $tweet_text );
}
return $tweet_text;
}
Ora dobbiamo definire il metodo principale, stavolta pubblico, per reperire i tweet utilizzando il metodo TwitterOauth::get()
:
public function fetch() {
$params = array(
'screen_name' => 'gabromanato',
'count' => 3,
'exclude_replies' => true
);
$html = '<div id=“twitter-feed”>';
$resp = $this->_connection->get( 'statuses/user_timeline', $params );
$tweets = json_decode( $resp );
foreach( $tweets as $tweet ) {
$html .= '<div class=“tweet”>';
$html .= '<time class=“tweet-date”>' . $this->_relativeTime( $tweet->created_at ) . '</time>';
$html .= '<div class=“tweet-body”>' . $this->_format( $tweet ) . '</div>';
$html .= '</div>';
}
$html .= '</div>';
return $html;
}
Seguendo il design di WordPress, concluderemo la nostra implementazione definendo una funzione che utilizzerà la classe appena creata, impedendo così che una classe venga usata direttamente.
C'è un potenziale problema di performance nel nostro codice: troppe richieste GET potrebbero rappresentare un bottleneck per un sito. Fortunatamente WordPress dispone delle Transients API che ci permettono di creare un sistema di caching di durata personalizzabile. Quindi scriveremo:
require_once( 'My_Twitter.php' );
function my_get_tweets( $echo = false ) {
$html = '';
if ( false === ( $feed = get_transient( 'my-tweets' ) ) ) {
$twitter_getter = new My_Twitter();
$html = $twitter_getter->fetch();
set_transient( 'my-tweets', $html, 5 * MINUTE_IN_SECONDS );
} else {
$html = get_transient( 'my-tweets' );
}
if( $echo ) {
echo $html;
} else {
return $html;
}
}
Nel caso specifico dell'esempio proposto il codice metterà in cache per 5 minuti i risultati ottenuti da Twitter, solo dopo questo intervallo di tempo verrà effettuata nuovamente una richiesta GET.