2014-05-26 00:30:46 +02:00
< ? php
2016-08-10 11:00:40 +02:00
class TwitterBridge extends BridgeAbstract {
2016-08-27 21:03:26 +02:00
public $name = 'Twitter Bridge' ;
public $uri = 'https://twitter.com' ;
public $description = 'returns tweets' ;
public $parameters = array (
'global' => array (
'nopic' => array (
'name' => 'Hide profile pictures' ,
'type' => 'checkbox' ,
'title' => 'Activate to hide profile pictures in content'
)
),
'By keyword or hashtag' => array (
'q' => array (
'name' => 'Keyword or #hashtag' ,
'required' => true ,
'exampleValue' => 'rss-bridge, #rss-bridge' ,
'title' => 'Insert a keyword or hashtag'
)
),
'By username' => array (
'u' => array (
'name' => 'username' ,
'required' => true ,
'exampleValue' => 'sebsauvage' ,
'title' => 'Insert a user name'
),
'norep' => array (
'name' => 'Without replies' ,
'type' => 'checkbox' ,
'title' => 'Only return initial tweets'
)
)
);
2015-11-05 16:50:18 +01:00
2016-08-25 01:49:30 +02:00
public function getName (){
switch ( $this -> queriedContext ){
case 'By keyword or hashtag' :
$specific = 'search ' ;
$param = 'q' ;
break ;
case 'By username' :
$specific = '@' ;
$param = 'u' ;
break ;
}
return 'Twitter ' . $specific
. $this -> parameters [ $this -> queriedContext ][ $param ][ 'value' ];
}
public function getURI (){
$params = $this -> parameters [ $this -> queriedContext ];
switch ( $this -> queriedContext ){
case 'By keyword or hashtag' :
return $this -> uri . 'search?q=' . urlencode ( $params [ 'q' ][ 'value' ]);
case 'By username' :
return $this -> uri . urlencode ( $params [ 'u' ][ 'value' ]) .
( isset ( $params [ 'norep' ][ 'value' ]) ? '' : '/with_replies' );
}
}
2016-08-25 01:24:53 +02:00
public function collectData (){
$param = $this -> parameters [ $this -> queriedContext ];
2016-07-08 19:06:35 +02:00
$html = '' ;
2016-08-25 01:24:53 +02:00
if ( isset ( $param [ 'q' ][ 'value' ])) { /* keyword search mode */
$html = $this -> getSimpleHTMLDOM ( 'https://twitter.com/search?q=' . urlencode ( $param [ 'q' ][ 'value' ]) . '&f=tweets' ) or $this -> returnServerError ( 'No results for this query.' );
2014-05-26 00:30:46 +02:00
}
2016-08-25 01:24:53 +02:00
elseif ( isset ( $param [ 'u' ][ 'value' ])) { /* user timeline mode */
$html = $this -> getSimpleHTMLDOM ( 'https://twitter.com/' . urlencode ( $param [ 'u' ][ 'value' ]) . ( isset ( $param [ 'norep' ][ 'value' ]) ? '' : '/with_replies' )) or $this -> returnServerError ( 'Requested username can\'t be found.' );
2014-05-26 00:30:46 +02:00
}
else {
2016-08-17 14:45:08 +02:00
$this -> returnClientError ( 'You must specify a keyword (?q=...) or a Twitter username (?u=...).' );
2014-05-26 00:30:46 +02:00
}
2016-08-10 10:44:23 +02:00
$hidePictures = false ;
2016-08-25 01:24:53 +02:00
if ( isset ( $param [ 'nopic' ][ 'value' ]))
2016-08-25 17:07:37 +02:00
$hidePictures = $param [ 'nopic' ][ 'value' ];
2016-08-10 10:44:23 +02:00
2014-05-26 00:30:46 +02:00
foreach ( $html -> find ( 'div.js-stream-tweet' ) as $tweet ) {
2016-08-22 18:55:59 +02:00
$item = array ();
2014-05-26 00:30:46 +02:00
// extract username and sanitize
2016-08-22 18:55:59 +02:00
$item [ 'username' ] = $tweet -> getAttribute ( 'data-screen-name' );
2014-05-26 00:30:46 +02:00
// extract fullname (pseudonym)
2016-08-22 18:55:59 +02:00
$item [ 'fullname' ] = $tweet -> getAttribute ( 'data-name' );
2016-08-10 10:26:29 +02:00
// get author
2016-08-22 18:55:59 +02:00
$item [ 'author' ] = $item [ 'fullname' ] . ' (@' . $item [ 'username' ] . ')' ;
2014-05-26 00:30:46 +02:00
// get avatar link
2016-08-22 18:55:59 +02:00
$item [ 'avatar' ] = $tweet -> find ( 'img' , 0 ) -> src ;
2014-05-26 00:30:46 +02:00
// get TweetID
2016-08-22 18:55:59 +02:00
$item [ 'id' ] = $tweet -> getAttribute ( 'data-tweet-id' );
2016-07-08 19:06:35 +02:00
// get tweet link
2016-08-22 18:55:59 +02:00
$item [ 'uri' ] = 'https://twitter.com' . $tweet -> find ( 'a.js-permalink' , 0 ) -> getAttribute ( 'href' );
2014-05-26 00:30:46 +02:00
// extract tweet timestamp
2016-08-22 18:55:59 +02:00
$item [ 'timestamp' ] = $tweet -> find ( 'span.js-short-timestamp' , 0 ) -> getAttribute ( 'data-time' );
2016-08-10 10:26:29 +02:00
// generate the title
2016-08-22 18:55:59 +02:00
$item [ 'title' ] = strip_tags ( html_entity_decode ( $tweet -> find ( 'p.js-tweet-text' , 0 ) -> innertext , ENT_QUOTES , 'UTF-8' ));
2016-07-08 19:06:35 +02:00
2014-05-26 00:30:46 +02:00
// processing content links
foreach ( $tweet -> find ( 'a' ) as $link ) {
if ( $link -> hasAttribute ( 'data-expanded-url' ) ) {
$link -> href = $link -> getAttribute ( 'data-expanded-url' );
}
$link -> removeAttribute ( 'data-expanded-url' );
$link -> removeAttribute ( 'data-query-source' );
$link -> removeAttribute ( 'rel' );
$link -> removeAttribute ( 'class' );
$link -> removeAttribute ( 'target' );
$link -> removeAttribute ( 'title' );
}
2016-08-09 21:59:55 +02:00
// process emojis (reduce size)
foreach ( $tweet -> find ( 'img.Emoji' ) as $img ){
$img -> style .= ' height: 1em;' ;
}
2016-08-09 21:47:29 +02:00
2016-08-09 21:59:55 +02:00
// get tweet text
2016-08-09 21:47:29 +02:00
$cleanedTweet = str_replace ( 'href="/' , 'href="https://twitter.com/' , $tweet -> find ( 'p.js-tweet-text' , 0 ) -> innertext );
2016-08-10 10:44:23 +02:00
// Add picture to content
$picture_html = '' ;
if ( ! $hidePictures ){
$picture_html = <<< EOD
2016-08-22 18:55:59 +02:00
< a href = " https://twitter.com/ { $item [ 'username' ] } " >< img style = " align: top; width:75 px; border: 1px solid black; " alt = " { $item [ 'username' ] } " src = " { $item [ 'avatar' ] } " title = " { $item [ 'fullname' ] } " /></ a >
2016-08-10 10:44:23 +02:00
EOD ;
}
// add content
2016-08-22 18:55:59 +02:00
$item [ 'content' ] = <<< EOD
2016-08-09 22:05:42 +02:00
< div style = " display: inline-block; vertical-align: top; " >
2016-08-10 10:44:23 +02:00
{ $picture_html }
2016-08-09 22:05:42 +02:00
</ div >
< div style = " display: inline-block; vertical-align: top; " >
< blockquote > { $cleanedTweet } </ blockquote >
</ div >
2016-08-09 21:47:29 +02:00
EOD ;
2014-05-26 00:30:46 +02:00
// put out
$this -> items [] = $item ;
}
}
public function getCacheDuration (){
return 300 ; // 5 minutes
}
}