Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
692 lines (458 sloc) 16.8 KB
<?php
/*
* TwitterDarValor.php
*
* Copyright 2013 Miguel Rafael Esteban Martín (www.logicaalternativa.com) <miguel.esteban@logicaalternativa.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
require_once dirname(__FILE__).DIRECTORY_SEPARATOR."TwitterAPIExchange.php";
/*
* Clase que da valor a los tweet. Calcula el grado de interés la
* audiencia y el grado de difusión de los tweet
**/
class TwitterDarValor {
/* ATRIBUTOS PÚBLICOS */
/*
* Url del api de twitterr
* */
var $urlApi = "https://api.twitter.com/1.1/";
/*
* Factor que da valor a los reteweet a la hora de calcular el grado
* de interés. Número mayor que 1
* */
var $factorRetweet = 33; // (3 Retweet por 100 seguidores) darían un grado de interes del 2.5 => la mitad
/*
* Factor que da valor a los favoritos a la hora de calcular el grado
* de interés. Número mayor que 1
* */
var $factorFavoritos = 16; // (6 favoritos por 100 seguidores = 25) darían un grado de interes del 2.5 => la mitad
/*
* Número de tweets de los que se listan de los que se
* obtiene la audiencia
* */
var $maxRegistrosCalcularAudiencia = 15;
/*
* Array de acceso que es necesario para la clase TwitterAPIExchange
* Para más información ver:
* https://github.com/J7mbo/twitter-api-php/blob/master/README.md
* */
private $settings = array(
'oauth_access_token' => "",
'oauth_access_token_secret' => "",
'consumer_key' => "",
'consumer_secret' => ""
);
/* Contador interno que sirve para llevar la cuenta de las
* audiencias que ya se han calculado
* */
private $contInternoTweetAudiencia = 0;
/*
* Clase privada de TwitterAPIExchange
* Para más información ver:
* https://github.com/J7mbo/twitter-api-php/blob/master/README.md
* */
private $twitterAPIExchange;
/*
* Constructor
* */
function __construct( $settings = null ) {
if ( ! is_null( $settings ) ) {
$this->settings = $settings; // Se carga los "settings" para la conexión
}
// Se crea la instancia de la clase
$this->twitterAPIExchange = new TwitterAPIExchange( $this->settings );
}
/*MÉTODOS PÚBLICOS*/
/*
* Obtiene el time line (la parte pública) del usuario validado en
* los settings
* Se puede pasar el número de tweets que se quieren obtener y
* si se desea obtener la audiencia y el grado de difusión
* */
public function obtenerTimeLine( $numeroTweets = 8, $obtenerAudiencia = false ) {
$this->_inicializarContadorTweetInternoAudiencia();
$resultadoTwitter = $this->_obtenerTimeLineTwitter( $numeroTweets );
return $this->_procesarTimeLine( $resultadoTwitter, $obtenerAudiencia );
}
/*
* Obtiene el home time line (la parte privada) del usuario validado
* en los settings
* Se puede pasar el número de tweets que se quieren obtener y
* si se desea obtener la audiencia y el grado de difusión
* */
public function obtenerHomeTimeLine( $numeroTweets = 8, $obtenerAudiencia = false ) {
$this->_inicializarContadorTweetInternoAudiencia();
$resultadoTwitter = $this->_obtenerHomeTimeLineTwitter( $numeroTweets );
return $this->_procesarTimeLine( $resultadoTwitter, $obtenerAudiencia );
}
/*MÉTODOS PRIVADOS*/
/*
* Obtiene el home time line haciendo una llamada REST al API de
* Twitter
* Se pasa por argumento el número de tweets que se quiere devolver
* */
private function _obtenerHomeTimeLineTwitter( $numeroTweets ){
$url = "{$this->urlApi}statuses/home_timeline.json";
$camposGet = "?count=$numeroTweets";
$metodo = "GET";
$request = $this->twitterAPIExchange->setGetfield($camposGet )
->buildOauth($url, $metodo)
->performRequest();
$res = json_decode( $request ) ;
// Traza
//~ var_dump( $res );
//~ exit;
// Fin de traza
return $res;
}
/*
* Obtiene el time line haciendo una llamada REST al API de
* Twitter
* Se pasa por argumento el número de tweets que se quiere devolver
* */
private function _obtenerTimeLineTwitter( /*$usuario, */$numeroTweets ){
$url = "{$this->urlApi}statuses/user_timeline.json";
//~ $camposGet = "?screen_name=$usuario&count=$numeroTweets";
$camposGet = "?count=$numeroTweets";
$metodo = "GET";
$request = $this->twitterAPIExchange->setGetfield($camposGet )
->buildOauth($url, $metodo)
->performRequest();
$res = json_decode( $request ) ;
// Traza
//~ var_dump( $res );
//~ exit;
// Fin de traza
return $res;
}
/*
* Si el mensaje que se está procesado es un retweet, se obtiene
* la fecha, el nombre y el perfil del que lo ha hecho
* */
private function _obtenerDatosRetweet( $registroProcesado, $reg ){
if ( ! isset ( $registroProcesado["es_retweet"] ) || $registroProcesado["es_retweet"] != 1) {
return $registroProcesado;
}
$registroProcesado["retweet_fecha_unix"] = strtotime( $reg->created_at );
// Se obtiene la clase usuario del tweet
$tweetUsuario = $reg->user;
if ( isset( $tweetUsuario) ) {
$registroProcesado["retweet_nombre" ] = $tweetUsuario->name;
$registroProcesado ["retweet_perfil" ] = $tweetUsuario->screen_name;
}
return $registroProcesado;
}
/*
* Inicializa el contador interno de audiencia
* */
private function _inicializarContadorTweetInternoAudiencia(){
$this->contInternoTweetAudiencia = 0;
}
/*
* Procesa el registro que nos devueleve el api REST para devolver
* los datos que nos son interesantes
* Devuelve una lista con los datos procesados y que nos son
* interesantes de cada registro que nos devuelve el API REST
* */
private function _procesarTimeLine( $res, $obtenerAudiencia ) {
$resProcesado = array();
foreach ( $res as $registro ) {
$registroProcesado = array();
// Obtiene la clase según es retweet o no
$registroProcesado["es_retweet"] = isset ($registro->retweeted_status) ? 1 : 0;
$registroProcesado = $this->_obtenerDatosRetweet( $registroProcesado, $registro ) ;
$registroProcesado = $this->_cargarDatosTweet( $registroProcesado, $registro ) ;
$registroProcesado = $this->_obtenerGradoInteres( $registroProcesado );
if ( $obtenerAudiencia ) {
if ( $this->contInternoTweetAudiencia < $this->maxRegistrosCalcularAudiencia ) {
$registroProcesado = $this->_obtenerAudiencia( $registroProcesado );
$registroProcesado = $this->_obtenerGradoDifusion( $registroProcesado );
$this->contInternoTweetAudiencia ++;
}
}
//~ // Traza
// var_dump( $registroProcesado);
//~ var_dump( $tweet->entities);
// exit;
//~ // Fin de traza
$resProcesado[] = $registroProcesado;
}
return $resProcesado;
}
/*
* Carga los datos del tweetcomo la fecha, el texto, el número de
* retweet,...
* */
private function _cargarDatosTweet( $registroProcesado, $registro ){
$tweet = $registroProcesado["es_retweet"] == 1 ? $registro->retweeted_status : $registro;
$registroProcesado[ "fecha_unix"] = strtotime ( $tweet->created_at ) ;
//~ $registroProcesado[ "fecha"] = $this->_calcularFecha( $registroProcesado[ "fecha_unix"] );
$registroProcesado[ "texto"] = $tweet->text;
$registroProcesado[ "textoHtml"] = $this->_obtenerTextoHtml( $tweet->text, $tweet->entities );
$registroProcesado[ "num_retweet"] = $tweet->retweet_count;
$registroProcesado[ "num_favoritos"] = $tweet->favorite_count;
$registroProcesado[ "id"] = $tweet->id_str;
// Traza
/*
var_dump( $registroProcesado);
var_dump( $tweet->id_str );
exit;
*/
//~ // Fin de traza
// Se obtienen los datos del usuario
$registroProcesado = $this->_obtenerDatosAutorTweet( $registroProcesado, $tweet );
return $registroProcesado;
}
/*
* Obtiene el grado de difusión.
* Es la proporción de seguidores con repespecto a la audiencia total
* Se eleva al cuadrado para dar más importancia a las proporciones
* altas
* Es un número normalizado, del 0 (peor) al 5 (mejor)
* */
private function _obtenerGradoDifusion( $registroProcesado ){
if ( ! isset ( $registroProcesado["audiencia"] ) ){
return $registroProcesado;
}
$coeficiente = 1 - ( $registroProcesado["autor_seguridores"] / $registroProcesado["audiencia"] ) ;
$coeficiente = $coeficiente * $coeficiente;
$coeficiente = $coeficiente * 5;
$registroProcesado["grado_difusion"] =$this->_redondear( $coeficiente, 0.5 );
return $registroProcesado;
}
/*
* Obtiene la audiencia del tweet suma los seguidores de los
* últimos 100 retweet.
* Si el tweet tiene más de 100 retweet se hace una estimación con
* el número calculado.
* */
private function _obtenerAudiencia( $registroProcesado ) {
$numeroSeguidores = 0;
if ( isset( $registroProcesado[ "num_retweet"] )
&& $registroProcesado[ "num_retweet"] > 0) {
$numeroSeguidores = $this->_obtenerSumaSeguidores( $registroProcesado[ "id"], $registroProcesado[ "num_retweet"] );
if ( isset( $numeroSeguidores ) && $registroProcesado[ "num_retweet"] > 100) { // Se hace una estimación
$numeroSeguidores = round ( $numeroSeguidores * $registroProcesado[ "num_retweet"] / 100 );
$numeroSeguidores = $numeroSeguidores + $registroProcesado[ "autor_seguridores" ];
$registroProcesado["audiencia"] = $this->_redondearCifrasSignificativas( $numeroSeguidores, 4 );
return $registroProcesado;
}
}
// Traza
//~ var_dump( $registroProcesado[ "num_retweet"] );
//~ var_dump( $numeroSeguidores );
//~ exit;
// Fin de traza
$registroProcesado["audiencia"] = isset ( $numeroSeguidores )
? ( $registroProcesado[ "autor_seguridores" ] + $numeroSeguidores )
: null;
return $registroProcesado;
}
/*
* Para la estimación redondea a las cifras significativas
* que se pasan como argumento
* */
private function _redondearCifrasSignificativas( $valor, $cifrasSignificativas ){
$res = $valor;
$i = 0;
while ( $res > 1 ) {
$res = $res / 10;
$i++;
}
if ( $i <= $cifrasSignificativas ) {
return $valor;
}
$res = round ( $res * pow( 10, $cifrasSignificativas ) ) / pow( 10, $cifrasSignificativas );
$res = $res *pow( 10, $i);
// Traza
/*
var_dump( $valor );
var_dump( $res );
exit();
*/
// Fin de traza
return $res;
}
/*
* Obtiene la suma de los seguidores de los últimos 100 retweet
* del tweet que se pasa como argumento
* */
private function _obtenerSumaSeguidores( $id, $numero ){
$res = $this->_obtenerRetweets( $id, $numero ) ;
$numeroSeguidores = 0;
if ( !isset( $res ) || ! is_array( $res ) ) {
return null ;
}
foreach ( $res as $registro ) {
$tweetUsuario = $registro->user;
if ( isset( $tweetUsuario ) ) {
// Traza
//~ var_dump( $tweetUsuario->name.": ".$tweetUsuario->followers_count);
// Fin de traza
$num = $tweetUsuario->followers_count;
if ( isset( $numeroSeguidores ) ) {
$numeroSeguidores += $num;
}
}
}
return $numeroSeguidores;
}
/*
* Obtiene el número de retweets del id que se pasa haciendo una
* llamada al API Rest de Twitter
* El número está limitado a 100
* */
private function _obtenerRetweets( $id, $numero ) {
$url = "{$this->urlApi}statuses/retweets/{$id}.json";
$count = $numero > 100 ? 100 : $numero;
$camposGet = "?count=$count";
$metodo = "GET";
$request = $this->twitterAPIExchange->setGetfield($camposGet )
->buildOauth($url, $metodo)
->performRequest();
$res = json_decode( $request ) ;
// Traza
//~ var_dump( $res );
//~ exit;
// Fin de Traza
return $res;
}
/*
* Redondea un número con la precisión requerida
* */
private function _redondear( $avalor, $precision ) {
$valor = ( $avalor + ( $precision / 2 ) ) / $precision;
// Taza
/*
var_dump( $avalor );
var_dump( $valor );
var_dump( floor( $valor ) * $precision );
*/
// Fin de traza
return floor( $valor ) * $precision;
}
/*
* Obtiene el grado de interés.
* Se obtiene el valor resultante de la suma de multiplicar el
* número de retwet y de favoritos por sus respectivos factores.
* Después se obtiene que proporción es con respecto a sus seguidores
* Se normaliza a un número de 0 (peor) a 5 (mejor) con una precisión
* de 0.5
* */
private function _obtenerGradoInteres( $registroProcesado ) {
$coeficienteRetweet = ( $this->factorRetweet * $registroProcesado["num_retweet"] ) + ( $this->factorFavoritos * $registroProcesado["num_favoritos"] );
$coeficiente = $coeficienteRetweet / ( $coeficienteRetweet + $registroProcesado["autor_seguridores"] );
// Se normaliza a un valor entre 0,5 y 5 con precision de 0,5
$coeficiente = 5 * $coeficiente;
$registroProcesado["grado_interes"] = $this->_redondear( $coeficiente, 0.5 );
// Traza
//~ $registroProcesado["coeficienteRetweet"] = $coeficienteRetweet;
//~ $registroProcesado["coeficiente"] = $coeficiente;
//~ var_dump( $coeficienteRetweet );
//~ var_dump( $coeficiente );
//~ exit;
// Fin de traza
return $registroProcesado;
}
/*
* Obtiene los datos del autor del Tweet
* */
private function _obtenerDatosAutorTweet( $registroProcesado, $tweet ) {
$tweetUsuario = $tweet->user;
// Traza
//~ var_dump( $tweetUsuario);
// Fin de traza
$registroProcesado ["autor_imagen"] = $tweetUsuario->profile_image_url;
$registroProcesado ["autor_nombre" ] = $tweetUsuario->name;
$registroProcesado ["autor_perfil" ] = $tweetUsuario->screen_name;
$registroProcesado ["autor_seguridores" ] = $tweetUsuario->followers_count;
// Traza
//~ var_dump( $registroProcesado);
//~ exit;
// Fin de traza
return $registroProcesado;
}
/*
* Procesa las urls para mostarlas en html
* */
private function _procesarUrls( $texto, $urls ) {
if ( ! isset ( $urls ) || ! is_array( $urls ) ) {
return $texto;
}
// Traza
//~ var_dump( $urls);
//~ exit;
//~ // Fin de traza
foreach ( $urls as $reg ) {
$texto = str_replace( $reg->url, "<a href=\"{$reg->expanded_url}\" target=\"_blank\">{$reg->display_url}</a>", $texto );
}
return $texto;
}
/*
* Procesa el texto del tweet como HTML, procesa los Hashtag,
* los usuarios y las URLs
* */
private function _obtenerTextoHtml( $texto, $entities) {
$texto = $this->_procesarUrls( $texto, $entities->urls );
if ( isset( $entities->media ) ) {
$texto = $this->_procesarUrls( $texto, $entities->media );
}
$texto = $this->_procesarEnlaceHtmlHashtag( $texto );
$texto = $this->_procesarEnlaceHtmlPerfil( $texto );
// Traza
//~ var_dump($texto);
//~ exit;
// Fin de Traza
return nl2br( $texto );
}
/*
* Procesa un Hashtag para mostrar su enlace HTML
* */
private function _procesarEnlaceHtmlHashtag( $texto ) {
$patron = '/(^|[ "\n\r\'])(#([a-zA-Z0-9_-]+))/i';
$url = "https://twitter.com/search?q=%23";
return $this->_procesarEnlacesHtmlRegExp( $texto, $patron, $url );
}
/*
* Procesa un nombre de usuario para mostrar su enlace HTML
* */
private function _procesarEnlaceHtmlPerfil( $texto ) {
$patron = '/(^|[ "\n\r\'])(@([a-zA-Z0-9_-]+))/i';
$url = "https://twitter.com/";
return $this->_procesarEnlacesHtmlRegExp( $texto, $patron, $url );
}
/*
* Procesa el texto con la empresión regular para obtener enlace
* del código html
* */
private function _procesarEnlacesHtmlRegExp( $texto, $patron, $url ) {
$match = array();
$resultado = preg_match_all( $patron, $texto , $match, PREG_SET_ORDER );
foreach ( $match as $coincidencias ) {
// Traza
// print_r($match);
// exit;
// Fin de Traza
if ( isset ( $coincidencias[2] ) && isset( $coincidencias[3] ) ){
$paramEncode = urlencode( $coincidencias[3] );
$valor = $coincidencias[2];
$texto = str_replace( $valor, "<a href=\"{$url}{$paramEncode}\" target=\"_blank\">${valor}</a>", $texto );
}
}
return trim( $texto );
}
}
You can’t perform that action at this time.