File: /var/www/html/wpbiancoarte/wp-content/plugins/custom-twitter-feeds/inc/CTF_Feed.php
<?php
/**
* Class SB_Instagram_Feed
*
* Retrieves data and generates the html for each feed. The
* "display_instagram" function in the if-functions.php file
* is where this class is primarily used.
*
* @since 2.0/4.0
*/
namespace TwitterFeed;
use TwitterFeed\CtfCache;
use TwitterFeed\CTF_Parse;
use TwitterFeed\V2\CtfOauthConnect;
if ( ! defined( 'ABSPATH' ) ) {
die( '-1' );
}
class CTF_Feed
{
/**
* @var string
*/
private $regular_feed_transient_name;
/**
* @var string
*/
private $header_transient_name;
/**
* @var string
*/
private $backup_feed_transient_name;
/**
* @var string
*/
private $backup_header_transient_name;
/**
* @var array
*/
private $post_data;
/**
* @var
*/
private $header_data;
/**
* @var array
*/
private $next_pages;
/**
* @var array
*/
private $transient_atts;
/**
* @var int
*/
private $last_retrieve;
/**
* @var bool
*/
private $should_paginate;
/**
* @var int
*/
private $num_api_calls;
/**
* @var array
*/
private $image_ids_post_set;
/**
* @var bool
*/
private $should_use_backup;
/**
* @var array
*/
private $report;
/**
* @var array
*
* @since 2.1.1/5.2.1
*/
private $resized_images;
/**
* @var array
*
* @since 2.1.3/5.2.3
*/
protected $one_post_found;
private $last_id_data;
/**
* @var CtfCache
*/
protected $cache;
/**
* SB_Instagram_Feed constructor.
*
* @param string $transient_name ID of this feed
* generated in the SB_Instagram_Settings class
*/
public function __construct( $transient_name ) {
$this->regular_feed_transient_name = $transient_name;
$header_transient_name = str_replace( 'ctf_', 'ctf_header_', $transient_name );
$header_transient_name = substr($header_transient_name, 0, 44);
$this->header_transient_name = $header_transient_name;
$this->post_data = array();
$this->next_pages = array();
$this->should_paginate = true;
// this is a count of how many api calls have been made for each feed
// type and term.
// By default the limit is 10
$this->num_api_calls = 0;
$this->max_api_calls = 10;
$this->should_use_backup = false;
// used for errors and the sbi_debug report
$this->report = array();
$this->resized_images = array();
$this->one_post_found = false;
$this->cache = new CtfCache( $transient_name, 600, 1 );
}
public function set_cache( $cache_seconds, $settings ) {
$feed_id = $this->regular_feed_transient_name;
$feed_page = 1;
$this->cache = new CtfCache( $feed_id, $cache_seconds, $feed_page );
}
/**
* @return array
*
* @since 2.0/5.0
*/
public function get_post_data() {
return $this->post_data;
}
/**
* @return array
*
* @since 2.0/5.0
*/
public function set_post_data( $post_data ) {
$this->post_data = $post_data;
}
/**
* @return array
*
* @since 2.1.1/5.2.1
*/
public function set_resized_images( $resized_image_data ) {
$this->resized_images = $resized_image_data;
}
/**
* @return array
*
* @since 2.0/5.0
*/
public function get_next_pages() {
return $this->next_pages;
}
/**
* @return array
*
* @since 2.1.1/5.2.1
*/
public function get_resized_images() {
return $this->resized_images;
}
/**
* Checks the database option related the transient expiration
* to ensure it will be available when the page loads
*
* @return bool
*
* @since 2.0/4.0
*/
public function regular_cache_exists() {
//Check whether the cache transient exists in the database and is available for more than one more minute
if ( strpos( $this->regular_feed_transient_name, 'ctf_!' ) !== false ) {
$this->transient_data = $this->cache->get_transient($this->transient_name);
$transient_exists = $this->cache->get_persistent( $this->regular_feed_transient_name );
} else {
$transient_exists = $this->cache->get_transient( $this->regular_feed_transient_name );
}
return $transient_exists;
}
/**
* Checks the database option related the header transient
* expiration to ensure it will be available when the page loads
*
* @return bool
*
* @since 2.0/5.0
*/
public function regular_header_cache_exists() {
$header_transient = $this->cache->get_transient( $this->header_transient_name );
return $header_transient;
}
/**
* @return bool
*
* @since 2.0/5.0
*/
public function should_use_backup() {
return $this->should_use_backup || empty( $this->post_data );
}
/**
* The header is only displayed when the setting is enabled and
* an account has been connected
*
* Overwritten in the Pro version
*
* @param array $settings settings specific to this feed
* @param array $feed_types_and_terms organized settings related to feed data
* (ex. 'user' => array( 'smashballoon', 'custominstagramfeed' )
*
* @return bool
*
* @since 2.0/5.0
*/
public function need_header( $settings, $feed_types_and_terms ) {
$showheader = ($settings['showheader'] === 'on' || $settings['showheader'] === 'true' || $settings['showheader'] === true);
return ($showheader && isset( $feed_types_and_terms['users'] ));
}
/**
* Use the transient name to retrieve cached data for header
*
* @since 2.0/5.0
*/
public function set_header_data_from_cache() {
$header_cache = $this->cache->get_transient( $this->header_transient_name );
$header_cache = json_decode( $header_cache, true );
if ( ! empty( $header_cache ) ) {
$this->header_data = $header_cache;
}
}
public function set_header_data( $header_data ) {
$this->header_data = $header_data;
}
/**
* @since 2.0/5.0
*/
public function get_header_data() {
return $this->header_data;
}
/**
* Sets the post data, pagination data, shortcode atts used (cron cache),
* and timestamp of last retrieval from transient (cron cache)
*
* @param array $atts available for cron caching
*
* @since 2.0/5.0
*/
public function set_post_data_from_cache( $atts = array() ) {
if ( strpos( $this->regular_feed_transient_name, 'ctf_!' ) !== false ) {
$transient_data = $this->cache->get_persistent( $this->regular_feed_transient_name );
} else {
$transient_data = $this->cache->get_transient( $this->regular_feed_transient_name );
}
$transient_data = json_decode( $transient_data, true );
if ( $transient_data ) {
$post_data = isset( $transient_data['data'] ) ? $transient_data['data'] : array();
if ( empty( $post_data ) ) {
$post_data = isset( $transient_data[0]['id_str'] ) ? $transient_data : array();
}
$this->post_data = $post_data;
$this->next_pages = isset( $transient_data['pagination'] ) ? $transient_data['pagination'] : array();
if ( isset( $transient_data['atts'] ) ) {
$this->transient_atts = $transient_data['atts'];
$this->last_retrieve = $transient_data['last_retrieve'];
}
}
}
/**
* Checks to see if there are enough posts available to create
* the current page of the feed
*
* @param int $num
* @param int $offset
*
* @return bool
*
* @since 2.0/5.0
*/
public function need_posts( $num, $offset = 0 ) {
$num_existing_posts = is_array( $this->post_data ) ? count( $this->post_data ) : 0;
$num_needed_for_page = (int)$num + (int)$offset;
($num_existing_posts < $num_needed_for_page) ? $this->add_report( 'need more posts' ) : $this->add_report( 'have enough posts' );
return ($num_existing_posts < $num_needed_for_page);
}
/**
* Checks to see if there are additional pages available for any of the
* accounts in the feed and that the max conccurrent api request limit
* has not been reached
*
* @return bool
*
* @since 2.0/5.0
*/
public function can_get_more_posts() {
$one_type_and_term_has_more_ages = $this->next_pages !== false;
$max_concurrent_api_calls_not_met = $this->num_api_calls < $this->max_api_calls;
$max_concurrent_api_calls_not_met ? $this->add_report( 'max conccurrent requests not met' ) : $this->add_report( 'max concurrent met' );
$one_type_and_term_has_more_ages ? $this->add_report( 'more pages available' ) : $this->add_report( 'no next page' );
return ($one_type_and_term_has_more_ages && $max_concurrent_api_calls_not_met);
}
/**
* Appends one filtered API request worth of posts for each feed term
*
* @param $settings
* @param array $feed_types_and_terms organized settings related to feed data
* (ex. 'user' => array( 'smashballoon', 'custominstagramfeed' )
* @param array $connected_accounts_for_feed connected account data for the
* feed types and terms
*
* @since 2.0/5.0
* @since 2.0/5.1 added logic to make a second attempt at an API connection
* @since 2.0/5.1.2 remote posts only retrieved if API requests are not
* delayed, terms shuffled if there are more than 5
* @since 2.2/5.3 added logic to refresh the access token for basic display
* accounts if needed before using it in an API request
*/
public function add_remote_posts( $settings, $feed_types_and_terms ) {
$new_post_sets = array();
$next_pages = $this->next_pages;
/**
* Number of posts to retrieve in each API call
*
* @param int Minimum number of posts needed in each API request
* @param array $settings Settings for this feed
*
* @since 2.0/5.0
*/
$num = apply_filters( 'ctf_num_in_request', $settings['apinum'], $settings );
if ( ! $settings['includereplies'] && ! $settings['selfreplies'] ) {
$num = min( 200, $num * 3 );
}
$one_successful_connection = false;
$one_post_found = false;
$next_page_found = false;
$one_api_request_delayed = false;
foreach ( $feed_types_and_terms as $type => $terms ) {
if ( is_array( $terms ) && count( $terms ) > 5 ) {
shuffle( $terms );
}
foreach ( $terms as $term_and_params ) {
$params = array(
'count' => $num
);
$this->add_report( 'num ' . $num );
$term = $term_and_params['term'];
$params = array_merge( $params, $term_and_params['params'] );
if ( ! empty( $next_pages[ $term . '_' . $type ] ) ) {
$params['count'] = min( $params['count'] + 1, 200 );
$params['max_id'] = $next_pages[ $term . '_' . $type ];
}
$params['tweet_mode'] = 'extended';
if ( $type === 'usertimeline' ) {
if ( ! empty ( $term ) ) {
$params['screen_name'] = $term;
}
//if ( $settings['includereplies'] || $settings['selfreplies'] ) {
// $params['exclude_replies'] = 'false';
//} else {
$params['exclude_replies'] = 'true';
//}
}
if ( $type === 'hometimeline' ) {
//if ( $settings['includereplies'] || $settings['selfreplies'] ) {
// $params['exclude_replies'] = 'false';
//} else {
$params['exclude_replies'] = 'true';
//}
}
if ( $type === 'search' || $type === 'hashtag' ) {
$params['q'] = $term;
}
if ( $type === 'lists' ) {
if ( ! empty ( $term ) ) {
$params['list_id'] = $term;
}
}
if ( $type === 'userslookup' ) {
if ( ! empty ( $term ) ) {
$params['screen_name'] = $term;
}
}
// max_id parameter should only be included for the second set of posts
$this->num_api_calls++;
$api_obj = $this->apiConnectionResponse( $params, $type, $settings );
$raw_tweet_data = json_decode( $api_obj->json , $assoc = true );
if ( isset( $raw_tweet_data['errors'][0] ) ) {
if ( empty( $api_obj ) ) {
$api_obj = new \stdClass();
}
$api_obj->api_error_no = $raw_tweet_data['errors'][0]['code'];
$api_obj->api_error_message = $raw_tweet_data['errors'][0]['message'];
$this->add_report( 'error ' . $api_obj->api_error_no . ' ' . $api_obj->api_error_message );
$next_pages[ $term . '_' . $type ] = false;
} else {
if ( isset( $raw_tweet_data['statuses'] ) ) {
$raw_tweet_data = $raw_tweet_data['statuses'];
}
if ( ! empty( $params['max_id'] ) ) {
// remove the first tweet as it was returned in the paginated request
array_shift( $raw_tweet_data );
}
if ( count( $raw_tweet_data ) > 0 ) {
if ( isset( $raw_tweet_data[ count( $raw_tweet_data ) - 1 ] ) ) {
$last_tweet = $raw_tweet_data[ count( $raw_tweet_data ) - 1 ];
$this->add_report( 'normal last tweet' );
} else {
$last_tweet = $raw_tweet_data[0];
$this->add_report( 'backup last tweet' );
}
$working_tweet_set = CTF_Feed::reduceTweetSetData( $raw_tweet_data );
$working_tweet_set = CTF_Feed::filterTweetSet( $working_tweet_set, $settings );
if ( count( $working_tweet_set ) > 1 ) {
$last_tweet = $raw_tweet_data[ count( $working_tweet_set ) - 1 ];
}
$next_pages[ $term . '_' . $type ] = CTF_Parse_Pro::get_tweet_id( $last_tweet );
$new_post_sets[] = $working_tweet_set;
$one_post_found = true;
$next_page_found = true;
} else {
$this->add_report( 'no raw tweet data' );
$this->add_report( $api_obj->json );
$next_pages[ $term . '_' . $type ] = false;
}
}
}
}
$posts = $this->merge_posts( $new_post_sets, $settings );
if ( ! empty( $this->post_data ) && is_array( $this->post_data ) ) {
$posts = array_merge( $this->post_data, $posts );
} elseif ( $one_post_found ) {
$this->one_post_found = true;
}
$this->post_data = $posts;
if ( isset( $next_page_found ) && $next_page_found ) {
$this->next_pages = $next_pages;
} else {
$this->next_pages = false;
}
}
/**
* attempts to connect and retrieve tweets from the Twitter api
*
* @return mixed|string object containing the response
*/
public function apiConnectionResponse( $get_fields, $end_point, $settings ){
// Only can be set in the options page
$request_settings = array(
'consumer_key' => $settings['consumer_key'],
'consumer_secret' => $settings['consumer_secret'],
'access_token' => $settings['access_token'],
'access_token_secret' => $settings['access_token_secret'],
);
// actual connection
$twitter_connect = new CtfOauthConnect( $request_settings, $end_point );
$twitter_connect->setUrlBase();
$twitter_connect->setGetFields( $get_fields );
$twitter_connect->setRequestMethod( $settings['request_method'] );
return $twitter_connect->performRequest();
}
public static function reduceTweetSetData( $tweets ) {
$tweet_count = count( $tweets );
$len = count( $tweets );
$trimmed_tweets = array();
foreach ( $tweets as $tweet ) {
$trimmed_tweet = array();
$trimmed_tweet['user']['name'] = $tweet['user']['name'];
$trimmed_tweet['user']['screen_name'] = $tweet['user']['screen_name'];
$trimmed_tweet['user']['verified'] = $tweet['user']['verified'];
$trimmed_tweet['user']['profile_image_url_https'] = $tweet['user']['profile_image_url_https'];
$trimmed_tweet['user']['utc_offset'] = $tweet['user']['utc_offset'];
$trimmed_tweet['user']['statuses_count'] = $tweet['user']['statuses_count'];
$trimmed_tweet['user']['followers_count'] = $tweet['user']['followers_count'];
$trimmed_tweet['user']['description'] = $tweet['user']['description'];
$trimmed_tweet['text'] = isset( $tweet['text'] ) ? $tweet['text'] : $tweet['full_text'];
$trimmed_tweet['id_str'] = $tweet['id_str'];
$trimmed_tweet['created_at'] = $tweet['created_at'];
$trimmed_tweet['retweet_count'] = $tweet['retweet_count'];
$trimmed_tweet['favorite_count'] = $tweet['favorite_count'];
if ( isset( $tweet['entities']['urls'][0] ) ) {
foreach ( $tweet['entities']['urls'] as $url ) {
$trimmed_tweet['entities']['urls'][] = array(
'url' => $url['url'],
'expanded_url' => $url['expanded_url'],
'display_url' => $url['display_url'],
);
}
}
if ( isset( $tweet['retweeted_status'] ) ) {
$trimmed_tweet['retweeted_status']['user']['name'] = $tweet['retweeted_status']['user']['name'];
$trimmed_tweet['retweeted_status']['user']['screen_name'] = $tweet['retweeted_status']['user']['screen_name'];
$trimmed_tweet['retweeted_status']['user']['verified'] = $tweet['retweeted_status']['user']['verified'];
$trimmed_tweet['retweeted_status']['user']['profile_image_url_https'] = $tweet['retweeted_status']['user']['profile_image_url_https'];
$trimmed_tweet['retweeted_status']['user']['utc_offset'] = $tweet['retweeted_status']['user']['utc_offset'];
$trimmed_tweet['retweeted_status']['text'] = isset( $tweet['retweeted_status']['text'] ) ? $tweet['retweeted_status']['text'] : $tweet['retweeted_status']['full_text'];
$trimmed_tweet['retweeted_status']['id_str'] = $tweet['retweeted_status']['id_str'];
$trimmed_tweet['retweeted_status']['created_at'] = $tweet['retweeted_status']['created_at'];
$trimmed_tweet['retweeted_status']['retweet_count'] = $tweet['retweeted_status']['retweet_count'];
$trimmed_tweet['retweeted_status']['favorite_count'] = $tweet['retweeted_status']['favorite_count'];
if ( isset( $tweet['retweeted_status']['entities']['urls'][0] ) ) {
foreach ( $tweet['retweeted_status']['entities']['urls'] as $url ) {
$trimmed_tweet['retweeted_status']['entities']['urls'][] = array(
'url' => $url['url'],
'expanded_url' => $url['expanded_url'],
'display_url' => $url['display_url'],
);
}
}
if ( isset( $tweet['retweeted_status']['quoted_status'] ) ) {
$trimmed_tweet['retweeted_status']['quoted_status']['user']['name'] = $tweet['retweeted_status']['quoted_status']['user']['name'];
$trimmed_tweet['retweeted_status']['quoted_status']['user']['screen_name'] = $tweet['retweeted_status']['quoted_status']['user']['screen_name'];
$trimmed_tweet['retweeted_status']['quoted_status']['user']['verified'] = $tweet['retweeted_status']['quoted_status']['user']['verified'];
$trimmed_tweet['retweeted_status']['quoted_status']['user']['profile_image_url_https'] = $tweet['retweeted_status']['quoted_status']['user']['profile_image_url_https'];
$trimmed_tweet['retweeted_status']['quoted_status']['text'] = isset( $tweet['retweeted_status']['quoted_status']['text'] ) ? $tweet['retweeted_status']['quoted_status']['text'] : $tweet['retweeted_status']['quoted_status']['full_text'];
$trimmed_tweet['retweeted_status']['quoted_status']['id_str'] = $tweet['retweeted_status']['quoted_status']['id_str'];
$trimmed_tweet['retweeted_status']['quoted_status']['created_at'] = $tweet['retweeted_status']['quoted_status']['created_at'];
if ( isset( $tweet['retweeted_status']['quoted_status']['entities']['urls'][0] ) ) {
foreach ( $tweet['retweeted_status']['quoted_status']['entities']['urls'] as $url ) {
$trimmed_tweet['retweeted_status']['quoted_status']['entities']['urls'][] = array(
'url' => $url['url'],
'expanded_url' => $url['expanded_url'],
'display_url' => $url['display_url'],
);
}
}
}
}
if ( isset( $tweet['quoted_status'] ) ) {
$trimmed_tweet['quoted_status']['user']['name'] = $tweet['quoted_status']['user']['name'];
$trimmed_tweet['quoted_status']['user']['screen_name'] = $tweet['quoted_status']['user']['screen_name'];
$trimmed_tweet['quoted_status']['user']['profile_image_url_https'] = $tweet['quoted_status']['user']['profile_image_url_https'];
$trimmed_tweet['quoted_status']['user']['verified'] = $tweet['quoted_status']['user']['verified'];
$trimmed_tweet['quoted_status']['text'] = isset( $tweet['quoted_status']['text'] ) ? $tweet['quoted_status']['text'] : $tweet['quoted_status']['full_text'];
$trimmed_tweet['quoted_status']['id_str'] = $tweet['quoted_status']['id_str'];
$trimmed_tweet['quoted_status']['created_at'] = $tweet['quoted_status']['created_at'];
if ( isset( $tweet['quoted_status']['entities']['urls'][0] ) ) {
foreach ( $tweet['quoted_status']['entities']['urls'] as $url ) {
$trimmed_tweet['quoted_status']['entities']['urls'][] = array(
'url' => $url['url'],
'expanded_url' => $url['expanded_url'],
'display_url' => $url['display_url'],
);
}
}
}
if ( isset( $tweet['in_reply_to_screen_name'] ) ) {
$trimmed_tweet['in_reply_to_screen_name'] = $tweet['in_reply_to_screen_name'];
$trimmed_tweet['entities']['user_mentions'][0]['name'] = isset( $tweet['entities']['user_mentions'][0]['name'] ) ? $tweet['entities']['user_mentions'][0]['name'] : '';
$trimmed_tweet['in_reply_to_status_id_str'] = $tweet['in_reply_to_status_id_str'];
}
if ( isset( $tweet['extended_entities']['media'] ) ) {
// if there is media, we need to remove the media url from the tweet text
if ( isset( $tweet['extended_entities']['media'][0]['url'] ) ) {
$trimmed_tweet['text'] = CTF_Feed::removeStringFromText( $tweet['extended_entities']['media'][0]['url'], $trimmed_tweet['text'] );
}
$num_media = count( $tweet['extended_entities']['media'] );
for ( $i = 0; $i < $num_media; $i++ ) {
$trimmed_tweet['extended_entities']['media'][$i]['media_url_https'] = $tweet['extended_entities']['media'][$i]['media_url_https'];
$trimmed_tweet['extended_entities']['media'][$i]['type'] = $tweet['extended_entities']['media'][$i]['type'];
if ( isset( $tweet['extended_entities']['media'][$i]['sizes'] ) ) {
$trimmed_tweet['extended_entities']['media'][$i]['sizes'] = $tweet['extended_entities']['media'][$i]['sizes'];
}
if ( $tweet['extended_entities']['media'][$i]['type'] == 'video' || $tweet['extended_entities']['media'][$i]['type'] == 'animated_gif' ) {
$preferred_variant = $tweet['extended_entities']['media'][$i]['video_info']['variants'][0]['url'];
$highest_bitrate = 0;
foreach ( $tweet['extended_entities']['media'][$i]['video_info']['variants'] as $variant ) {
if ( isset( $variant['content_type'] )
&& $variant['content_type'] == 'video/mp4'
&& $variant['bitrate'] > $highest_bitrate ) {
$highest_bitrate = $variant['bitrate'];
$preferred_variant = $variant['url'];
}
}
$trimmed_tweet['extended_entities']['media'][$i]['video_info']['variants'][0]['url'] = $preferred_variant;
$trimmed_tweet['extended_entities']['media'][$i]['video_info']['variants'][0]['bitrate'] = $highest_bitrate;
}
}
} elseif ( isset( $tweet['entities']['media'] ) ) {
// if there is media, we need to remove the media url from the tweet text
if ( isset( $tweet['entities']['media'][0]['url'] ) ) {
$trimmed_tweet['text'] = CTF_Feed::removeStringFromText( $tweet['entities']['media'][0]['url'], $trimmed_tweet['text'] );
}
$num_media = count( $tweet['entities']['media'] );
for ( $i = 0; $i < $num_media; $i++ ) {
$trimmed_tweet['entities']['media'][$i]['media_url_https'] = $tweet['entities']['media'][$i]['media_url_https'];
$trimmed_tweet['entities']['media'][$i]['type'] = $tweet['entities']['media'][$i]['type'];
if ( isset( $tweet['entities']['media'][$i]['sizes'] ) ) {
$trimmed_tweet['entities']['media'][$i]['sizes'] = $tweet['entities']['media'][$i]['sizes'];
}
if ( $tweet['entities']['media'][$i]['type'] == 'video' || $tweet['entities']['media'][$i]['type'] == 'animated_gif' ) {
$preferred_variant = $tweet['entities']['media'][$i]['video_info']['variants'][0]['url'];
$highest_bitrate = 0;
foreach ( $tweet['entities']['media'][$i]['video_info']['variants'] as $variant ) {
if ( isset( $variant['content_type'] )
&& $variant['content_type'] == 'video/mp4'
&& $variant['bitrate'] > $highest_bitrate ) {
$highest_bitrate = $variant['bitrate'];
$preferred_variant = $variant['url'];
}
}
$trimmed_tweet['entities']['media'][$i]['video_info']['variants'][0]['url'] = $preferred_variant;
$trimmed_tweet['entities']['media'][$i]['video_info']['variants'][0]['bitrate'] = $highest_bitrate;
}
}
}
if ( isset( $tweet['retweeted_status']['extended_entities']['media'] ) ) {
// if there is media, we need to remove the media url from the tweet text
$retweeted_text = isset( $tweet['retweeted_status']['full_text'] ) ? $tweet['retweeted_status']['full_text'] : $tweet['retweeted_status']['text'];
if ( isset( $tweet['retweeted_status']['extended_entities']['media'][0]['url'] ) ) {
$trimmed_tweet['retweeted_status']['text'] = CTF_Feed::removeStringFromText( $tweet['retweeted_status']['extended_entities']['media'][0]['url'], $retweeted_text );
}
$num_media = count( $tweet['retweeted_status']['extended_entities']['media'] );
for ( $i = 0; $i < $num_media; $i++ ) {
$trimmed_tweet['retweeted_status']['extended_entities']['media'][$i]['media_url_https'] = $tweet['retweeted_status']['extended_entities']['media'][$i]['media_url_https'];
$trimmed_tweet['retweeted_status']['extended_entities']['media'][$i]['type'] = $tweet['retweeted_status']['extended_entities']['media'][$i]['type'];
if ( isset( $tweet['retweeted_status']['extended_entities']['media'][$i]['sizes'] ) ) {
$trimmed_tweet['retweeted_status']['extended_entities']['media'][$i]['sizes'] = $tweet['retweeted_status']['extended_entities']['media'][$i]['sizes'];
}
if ( $tweet['retweeted_status']['extended_entities']['media'][$i]['type'] == 'video' || $tweet['retweeted_status']['extended_entities']['media'][$i]['type'] == 'animated_gif' ) {
foreach ( $tweet['retweeted_status']['extended_entities']['media'][$i]['video_info']['variants'] as $variant ) {
if ( isset( $variant['content_type'] ) && $variant['content_type'] == 'video/mp4' ) {
$trimmed_tweet['retweeted_status']['extended_entities']['media'][$i]['video_info']['variants'][$i]['url'] = $variant['url'];
}
}
if ( ! isset( $trimmed_tweet['retweeted_status']['extended_entities']['media'][$i]['video_info']['variants'][$i]['url'] ) ) {
$trimmed_tweet['retweeted_status']['extended_entities']['media'][$i]['video_info']['variants'][$i]['url'] = $tweet['retweeted_status']['extended_entities']['media'][$i]['video_info']['variants'][0]['url'];
}
}
}
} elseif ( isset( $tweet['retweeted_status']['entities']['media'] ) ) {
// if there is media, we need to remove the media url from the tweet text
$retweeted_text = isset( $tweet['retweeted_status']['full_text'] ) ? $tweet['retweeted_status']['full_text'] : $tweet['retweeted_status']['text'];
if ( isset( $tweet['retweeted_status']['entities']['media'][0]['url'] ) ) {
$trimmed_tweet['retweeted_status']['text'] = CTF_Feed::removeStringFromText( $tweet['retweeted_status']['entities']['media'][0]['url'], $retweeted_text );
}
$num_media = count( $tweet['retweeted_status']['entities']['media'] );
for( $i = 0; $i < $num_media; $i++ ) {
$trimmed_tweet['retweeted_status']['entities']['media'][$i]['media_url_https'] = $tweet['retweeted_status']['entities']['media'][$i]['media_url_https'];
$trimmed_tweet['retweeted_status']['entities']['media'][$i]['type'] = $tweet['retweeted_status']['entities']['media'][$i]['type'];
if ( isset( $tweet['retweeted_status']['entities']['media'][$i]['sizes'] ) ) {
$trimmed_tweet['retweeted_status']['entities']['media'][$i]['sizes'] = $tweet['retweeted_status']['entities']['media'][$i]['sizes'];
}
if ( $tweet['retweeted_status']['entities']['media'][$i]['type'] == 'video' || $tweet['retweeted_status']['entities']['media'][$i]['type'] == 'animated_gif' ) {
foreach ( $tweet['retweeted_status']['entities']['media'][$i]['video_info']['variants'] as $variant ) {
if ( isset( $variant['content_type'] ) && $variant['content_type'] == 'video/mp4' ) {
$trimmed_tweet['retweeted_status']['entities']['media'][$i]['video_info']['variants'][$i]['url'] = $variant['url'];
}
}
if ( ! isset( $trimmed_tweet['retweeted_status']['entities']['media'][$i]['video_info']['variants'][$i]['url'] ) ) {
$trimmed_tweet['retweeted_status']['entities']['media'][$i]['video_info']['variants'][$i]['url'] = $tweet['retweeted_status']['entities']['media'][$i]['video_info']['variants'][0]['url'];
}
}
}
} elseif ( isset( $tweet['quoted_status']['extended_entities']['media'] ) ) {
// if there is media, we need to remove the media url from the tweet text
$quoted_text = isset( $tweet['quoted_status']['full_text'] ) ? $tweet['quoted_status']['full_text'] : $tweet['quoted_status']['text'];
if ( isset( $tweet['quoted_status']['extended_entities']['media'][0]['url'] ) ) {
$trimmed_tweet['quoted_status']['text'] = CTF_Feed::removeStringFromText( $tweet['quoted_status']['extended_entities']['media'][0]['url'], $quoted_text );
}
$num_media = count( $tweet['quoted_status']['extended_entities']['media'] );
for( $i = 0; $i < $num_media; $i++ ) {
$trimmed_tweet['quoted_status']['extended_entities']['media'][$i]['media_url_https'] = $tweet['quoted_status']['extended_entities']['media'][$i]['media_url_https'];
$trimmed_tweet['quoted_status']['extended_entities']['media'][$i]['type'] = $tweet['quoted_status']['extended_entities']['media'][$i]['type'];
if ( $tweet['quoted_status']['extended_entities']['media'][$i]['type'] == 'video' || $tweet['quoted_status']['extended_entities']['media'][$i]['type'] == 'animated_gif' ) {
foreach ( $tweet['quoted_status']['extended_entities']['media'][$i]['video_info']['variants'] as $variant ) {
if ( isset( $variant['content_type'] ) && $variant['content_type'] == 'video/mp4' ) {
$trimmed_tweet['quoted_status']['extended_entities']['media'][$i]['video_info']['variants'][$i]['url'] = $variant['url'];
}
}
if ( ! isset( $trimmed_tweet['quoted_status']['extended_entities']['media'][$i]['video_info']['variants'][$i]['url'] ) ) {
$trimmed_tweet['quoted_status']['extended_entities']['media'][$i]['video_info']['variants'][$i]['url'] = $tweet['quoted_status']['extended_entities']['media'][$i]['video_info']['variants'][0]['url'];
}
}
}
} elseif ( isset( $tweet['quoted_status']['entities']['media'] ) ) {
// if there is media, we need to remove the media url from the tweet text
$quoted_text = isset( $tweet['quoted_status']['full_text'] ) ? $tweet['quoted_status']['full_text'] : $tweet['quoted_status']['text'];
if ( isset( $tweet['quoted_status']['entities']['media'][0]['url'] ) ) {
$trimmed_tweet['quoted_status']['text'] = CTF_Feed::removeStringFromText( $tweet['quoted_status']['entities']['media'][0]['url'], $quoted_text );
}
$num_media = count( $tweet['quoted_status']['entities']['media'] );
for( $i = 0; $i < $num_media; $i++ ) {
$trimmed_tweet['quoted_status']['entities']['media'][$i]['media_url_https'] = $tweet['quoted_status']['entities']['media'][$i]['media_url_https'];
$trimmed_tweet['quoted_status']['entities']['media'][$i]['type'] = $tweet['quoted_status']['entities']['media'][$i]['type'];
if ( $tweet['quoted_status']['entities']['media'][$i]['type'] == 'video' || $tweet['quoted_status']['entities']['media'][$i]['type'] == 'animated_gif' ) {
foreach ( $tweet['quoted_status']['entities']['media'][$i]['video_info']['variants'] as $variant ) {
if ( isset( $variant['content_type'] ) && $variant['content_type'] == 'video/mp4' ) {
$trimmed_tweet['quoted_status']['entities']['media'][$i]['video_info']['variants'][$i]['url'] = $variant['url'];
}
}
if ( ! isset( $trimmed_tweet['quoted_status']['entities']['media'][$i]['video_info']['variants'][$i]['url'] ) ) {
$trimmed_tweet['quoted_status']['entities']['media'][$i]['video_info']['variants'][$i]['url'] = $tweet['quoted_status']['entities']['media'][$i]['video_info']['variants'][0]['url'];
}
}
}
}
if ( isset( $tweet['retweeted_status']['quoted_status']['extended_entities']['media'] ) ) {
// if there is media, we need to remove the media url from the tweet text
$retweeted_text = isset( $tweet['retweeted_status']['quoted_status']['full_text'] ) ? $tweet['retweeted_status']['quoted_status']['full_text'] : $tweet['retweeted_status']['quoted_status']['text'];
if ( isset( $tweet['retweeted_status']['quoted_status']['extended_entities']['media'][0]['url'] ) ) {
$trimmed_tweet['retweeted_status']['quoted_status']['text'] = CTF_Feed::removeStringFromText( $tweet['retweeted_status']['quoted_status']['extended_entities']['media'][0]['url'], $retweeted_text );
}
$num_media = count( $tweet['retweeted_status']['quoted_status']['extended_entities']['media'] );
for ( $i = 0; $i < $num_media; $i++ ) {
$trimmed_tweet['retweeted_status']['quoted_status']['extended_entities']['media'][$i]['media_url_https'] = $tweet['retweeted_status']['quoted_status']['extended_entities']['media'][$i]['media_url_https'];
$trimmed_tweet['retweeted_status']['quoted_status']['extended_entities']['media'][$i]['type'] = $tweet['retweeted_status']['quoted_status']['extended_entities']['media'][$i]['type'];
if ( isset( $tweet['retweeted_status']['quoted_status']['extended_entities']['media'][$i]['sizes'] ) ) {
$trimmed_tweet['retweeted_status']['quoted_status']['extended_entities']['media'][$i]['sizes'] = $tweet['retweeted_status']['quoted_status']['extended_entities']['media'][$i]['sizes'];
}
if ( $tweet['retweeted_status']['quoted_status']['extended_entities']['media'][$i]['type'] == 'video' || $tweet['retweeted_status']['quoted_status']['extended_entities']['media'][$i]['type'] == 'animated_gif' ) {
foreach ( $tweet['retweeted_status']['quoted_status']['extended_entities']['media'][$i]['video_info']['variants'] as $variant ) {
if ( isset( $variant['content_type'] ) && $variant['content_type'] == 'video/mp4' ) {
$trimmed_tweet['retweeted_status']['quoted_status']['extended_entities']['media'][$i]['video_info']['variants'][$i]['url'] = $variant['url'];
}
}
if ( ! isset( $trimmed_tweet['retweeted_status']['quoted_status']['extended_entities']['media'][$i]['video_info']['variants'][$i]['url'] ) ) {
$trimmed_tweet['retweeted_status']['quoted_status']['extended_entities']['media'][$i]['video_info']['variants'][$i]['url'] = $tweet['retweeted_status']['quoted_status']['extended_entities']['media'][$i]['video_info']['variants'][0]['url'];
}
}
}
} elseif ( isset( $tweet['retweeted_status']['quoted_status']['entities']['media'] ) ) {
// if there is media, we need to remove the media url from the tweet text
$retweeted_text = isset( $tweet['retweeted_status']['quoted_status']['full_text'] ) ? $tweet['retweeted_status']['quoted_status']['full_text'] : $tweet['retweeted_status']['quoted_status']['text'];
if ( isset( $tweet['retweeted_status']['quoted_status']['entities']['media'][0]['url'] ) ) {
$trimmed_tweet['retweeted_status']['quoted_status']['text'] = CTF_Feed::removeStringFromText( $tweet['retweeted_status']['quoted_status']['entities']['media'][0]['url'], $retweeted_text );
}
$num_media = count( $tweet['retweeted_status']['quoted_status']['entities']['media'] );
for( $i = 0; $i < $num_media; $i++ ) {
$trimmed_tweet['retweeted_status']['quoted_status']['entities']['media'][$i]['media_url_https'] = $tweet['retweeted_status']['quoted_status']['entities']['media'][$i]['media_url_https'];
$trimmed_tweet['retweeted_status']['quoted_status']['entities']['media'][$i]['type'] = $tweet['retweeted_status']['quoted_status']['entities']['media'][$i]['type'];
if ( isset( $tweet['retweeted_status']['quoted_status']['entities']['media'][$i]['sizes'] ) ) {
$trimmed_tweet['retweeted_status']['quoted_status']['entities']['media'][$i]['sizes'] = $tweet['retweeted_status']['quoted_status']['entities']['media'][$i]['sizes'];
}
if ( $tweet['retweeted_status']['quoted_status']['entities']['media'][$i]['type'] == 'video' || $tweet['retweeted_status']['quoted_status']['entities']['media'][$i]['type'] == 'animated_gif' ) {
foreach ( $tweet['retweeted_status']['quoted_status']['entities']['media'][$i]['video_info']['variants'] as $variant ) {
if ( isset( $variant['content_type'] ) && $variant['content_type'] == 'video/mp4' ) {
$trimmed_tweet['retweeted_status']['quoted_status']['entities']['media'][$i]['video_info']['variants'][$i]['url'] = $variant['url'];
}
}
if ( ! isset( $trimmed_tweet['retweeted_status']['quoted_status']['entities']['media'][$i]['video_info']['variants'][$i]['url'] ) ) {
$trimmed_tweet['retweeted_status']['quoted_status']['entities']['media'][$i]['video_info']['variants'][$i]['url'] = $tweet['retweeted_status']['quoted_status']['entities']['media'][$i]['video_info']['variants'][0]['url'];
}
}
}
}
//remove the url from the text if it links to a quoted tweet that is already linked to
if ( isset( $tweet['quoted_status'] ) ) {
$maybe_remove_index = count( $tweet['entities']['urls'] ) - 1;
if ( isset( $tweet['entities']['urls'][$maybe_remove_index]['url'] ) ) {
$text = isset( $trimmed_tweet['full_text'] ) ? $trimmed_tweet['full_text'] : $trimmed_tweet['text'];
$trimmed_tweet['text'] = CTF_Feed::removeStringFromText( $tweet['entities']['urls'][$maybe_remove_index]['url'], $text );
}
}
$api_twitter_card = false;
if ( isset( $tweet['card'] ) ) {
$api_twitter_card = self::parse_api_card_data($tweet['card']);
}
// used to generate twitter cards
if ( isset( $tweet['entities']['urls'][0]['expanded_url'] ) ) {
$trimmed_tweet['entities']['urls'][0]['expanded_url'] = $tweet['entities']['urls'][0]['expanded_url'];
$twitter_card = CTF_Feed::maybeGetTwitterCardData( $tweet['entities']['urls'][0]['expanded_url'], $trimmed_tweet['id_str'] );
if ( ! empty( $twitter_card ) ) {
$trimmed_tweet['twitter_card'] = $twitter_card;
$remove_url_from_tweet = apply_filters( 'ctf_should_remove_url_from_text', true );
if ( ! empty( $twitter_card["twitter:card"] ) && isset( $tweet['entities']['urls'][0]['url'] ) && $remove_url_from_tweet ) {
$trimmed_tweet['text'] = CTF_Feed::removeStringFromText( $tweet['entities']['urls'][0]['url'], $trimmed_tweet['text'] );
}
} elseif ( $twitter_card !== false ) {
$trimmed_tweet['twitter_card'] = $twitter_card;
}
}
if ( isset( $tweet['retweeted_status']['entities']['urls'][0]['expanded_url'] ) ) {
$trimmed_tweet['retweeted_status']['entities']['urls'][0]['expanded_url'] = $tweet['retweeted_status']['entities']['urls'][0]['expanded_url'];
$twitter_card = CTF_Feed::maybeGetTwitterCardData( $tweet['retweeted_status']['entities']['urls'][0]['expanded_url'], $trimmed_tweet['retweeted_status']['id_str'] );
if ( ! empty( $twitter_card ) ) {
$trimmed_tweet['retweeted_status']['twitter_card'] = $twitter_card;
$retweeted_text = isset( $tweet['retweeted_status']['full_text'] ) ? $tweet['retweeted_status']['full_text'] : $tweet['retweeted_status']['text'];
$remove_url_from_tweet = apply_filters( 'ctf_should_remove_url_from_text', true );
if ( ! empty( $twitter_card["twitter:card"] ) && isset( $tweet['retweeted_status']['entities']['urls'][0]['url'] ) && $remove_url_from_tweet ) {
$trimmed_tweet['retweeted_status']['text'] = CTF_Feed::removeStringFromText( $tweet['retweeted_status']['entities']['urls'][0]['url'], $retweeted_text );
}
} elseif ( $twitter_card !== false ) {
$trimmed_tweet['twitter_card'] = $twitter_card;
}
}
if ( ! empty( $api_twitter_card ) ) {
$trimmed_tweet['twitter_card'] = $api_twitter_card;
if ( isset( $tweet['entities']['urls'][0]['expanded_url'] ) ) {
$target_one = $tweet['entities']['urls'][0]['expanded_url'];
$target_two = $tweet['entities']['urls'][0]['url'];
$remove_url_from_tweet = apply_filters( 'ctf_should_remove_url_from_text', true );
if ( $remove_url_from_tweet ) {
$trimmed_tweet['text'] = CTF_Feed::removeStringFromText( $target_one, $trimmed_tweet['text'] );
$trimmed_tweet['text'] = CTF_Feed::removeStringFromText( $target_two, $trimmed_tweet['text'] );
}
}
if ( isset( $tweet['retweeted_status']['entities']['urls'][0]['expanded_url'] ) ) {
$target_one = $tweet['retweeted_status']['entities']['urls'][0]['expanded_url'];
$target_two = $tweet['retweeted_status']['entities']['urls'][0]['url'];
$remove_url_from_tweet = apply_filters( 'ctf_should_remove_url_from_text', true );
if ( $remove_url_from_tweet ) {
$trimmed_tweet['retweeted_status']['text'] = CTF_Feed::removeStringFromText( $target_one, $trimmed_tweet['retweeted_status']['text'] );
$trimmed_tweet['retweeted_status']['text'] = CTF_Feed::removeStringFromText( $target_two, $trimmed_tweet['retweeted_status']['text'] );
}
}
}
$trimmed_tweets[] = $trimmed_tweet;
}
return $trimmed_tweets;
}
public static function filterTweetSet( $tweet_set, $settings ){
$tweets_to_remove_strip_ctf = str_replace( 'ctf_', '', $settings['remove_by_id'] );
$ids_of_tweets_to_remove = ! empty( $tweets_to_remove_strip_ctf ) ? explode( ',', str_replace( ' ', '', $tweets_to_remove_strip_ctf ) ) : '';
$tweets_that_pass_filter = array();
foreach ( $tweet_set as $tweet ) {
$retweet_id = isset( $tweet['retweeted_status']['id_str'] ) ? $tweet['retweeted_status']['id_str'] : '';
$keep = true;
if ( ! empty( $retweet_id ) && ! $settings['includeretweets'] ) {
$keep = false;
} elseif ( !$settings['includereplies'] && !$settings['selfreplies'] && isset( $tweet['in_reply_to_screen_name'] ) ) {
$keep = false;
} elseif ( !$settings['includereplies']
&& $settings['selfreplies']
&& isset( $tweet['in_reply_to_screen_name'] )
&& $tweet['in_reply_to_screen_name'] !== $tweet['user']['screen_name']) {
$keep = false;
} elseif ( ! empty( $ids_of_tweets_to_remove ) && in_array( $tweet['id_str'], $ids_of_tweets_to_remove ) ) {
$keep = false;
} elseif ( CTF_Feed::tweetShouldBeRemoved( $tweet, $settings ) ) {
$keep = false;
}
if ( $keep ) {
$tweets_that_pass_filter[] = $tweet;
}
}
return $tweets_that_pass_filter;
}
public static function tweetShouldBeRemoved( $tweet, $settings )
{
$return = false;
$good_text = ! empty( $settings['includewords'] ) ? explode( ',', str_replace( ' ', '', $settings['includewords'] ) ) : '';
$bad_text = ! empty( $settings['excludewords'] ) ? explode( ',', str_replace( ' ', '', $settings['excludewords'] ) ) : '';
$includewords_any_all = $settings['includeanyall'];
$excludewords_any_all = $settings['excludeanyall'];
$filter_and_or = $settings['filterandor'];
if ( isset( $tweet['retweeted_status']['full_text'] ) ) {
$tweet_text = $tweet['retweeted_status']['full_text'];
} elseif ( isset( $tweet['retweeted_status']['text'] ) ) {
$tweet_text = $tweet['retweeted_status']['text'];
} elseif ( isset( $tweet['full_text'] ) ) {
$tweet_text = $tweet['full_text'];
} elseif ( isset( $tweet['text'] ) ) {
$tweet_text = $tweet['text'];
} else {
$tweet_text = '';
}
$tweet_text = ' ' . preg_replace( '/[,.!?:;"]+/', '', $tweet_text ) . ' '; // spaces added so that we can use strpos instead of regex to find words
$tweet_text = strtolower( preg_replace( '/[\n]+/', ' ', $tweet_text ) );
// don't bother with filtering process if both filters are empty
if ( ! empty( $good_text ) || ! empty( $bad_text ) ) {
if ( $filter_and_or == 'and' && ! empty( $good_text ) && ! empty( $bad_text ) ) {
if ( CTF_Feed::hasGoodText( $good_text, $includewords_any_all, $tweet_text, true ) && CTF_Feed::hasNoBadText( $bad_text, 'any', $tweet_text, true ) ) {
$return = false;
} else {
$return = true;
}
} else {
if ( CTF_Feed::hasGoodText( $good_text, $includewords_any_all, $tweet_text, false ) || CTF_Feed::hasNoBadText( $bad_text, $excludewords_any_all, $tweet_text, false ) ) {
$return = false;
} else {
$return = true;
}
}
}
$return = apply_filters( 'ctf_filter_out_tweet', $return, $tweet_text, $tweet );
return $return;
}
public static function hasGoodText( $good_text, $any_or_all, $tweet_text, $default )
{
if ( empty( $good_text ) ) { // don't factor in the includewords if there aren't any
return $default;
} else {
$encoded_text = ' ' . str_replace( array( '+', '%0A' ), ' ', urlencode( str_replace( array( '#', '@' ), array( ' HASHTAG', ' MENTION' ), strtolower( $tweet_text ) ) ) ) . ' ';
if ( $any_or_all == 'any' ) {
// as soon as we find any of the includewords, stop searching and return true
foreach ( $good_text as $good ) {
$converted_includeword = trim( str_replace('+', ' ', urlencode( str_replace( array( '#', '@' ), array( ' HASHTAG', ' MENTION' ), strtolower( $good ) ) ) ) );
if ( preg_match('/\b'.$converted_includeword.'\b/i', $encoded_text, $matches ) ) {
return true;
}
}
// if foreach finishes without finding any matches
return false;
} else {
// to make sure all of the includewords are present, keep a count of
// how many of the words are detected and compare it to the number that's needed
$good_text_matches = 0;
$number_of_good_text_to_look_for = count( $good_text );
foreach ( $good_text as $good ) {
$converted_includeword = trim( str_replace('+', ' ', urlencode( str_replace( array( '#', '@' ), array( ' HASHTAG', ' MENTION' ), strtolower( $good ) ) ) ) );
if ( preg_match('/\b'.$converted_includeword.'\b/i', $encoded_text, $matches ) ) {
$good_text_matches++;
}
}
if ( $good_text_matches >= $number_of_good_text_to_look_for ) {
return true;
} else {
return false;
}
}
}
}
/**
* if a filter is applied to this feed, check and see if this tweet needs to
* or contains the excludewords text
*
* @param $bad_text array words the tweet cannot have to be included in the feed
* @param $any_or_all enum whether any or all of the bad text words need to be included
* @param $tweet_text string content text of the tweet
* @param $default bool the default return type if nothing is set
* @return bool whether the tweet meets the requirements for having no bad text
*/
public static function hasNoBadText( $bad_text, $any_or_all, $tweet_text, $default )
{
if ( empty( $bad_text ) ) { // don't factor in the excludewords if there aren't any
return $default;
} else {
$encoded_text = ' ' . str_replace( array( '+', '%0A' ), ' ', urlencode( str_replace( array( '#', '@' ), array( ' HASHTAG', ' MENTION' ), strtolower( $tweet_text ) ) ) ) . ' ';
if ( $any_or_all == 'any' ) {
// as soon as we find any of the excludewords, stop searching and return false
foreach ( $bad_text as $bad ) {
if ( empty( $bad ) ) {
return true;
}
$converted_excludeword = trim( str_replace('+', ' ', urlencode( str_replace( array( '#', '@' ), array( ' HASHTAG', ' MENTION' ), strtolower( $bad ) ) ) ) );
if ( preg_match('/\b'.$converted_excludeword.'\b/i', $encoded_text, $matches ) ) {
return false;
}
}
// if foreach finishes without finding any matches
return true;
} else {
// under this circumstance, all excludewords need to be present to remove
// the tweet so a count is kept and compared to the number of words
$bad_text_matches = 0;
$number_of_bad_text_to_look_for = count( $bad_text );
foreach ( $bad_text as $bad ) {
$converted_excludeword = trim( str_replace('+', ' ', urlencode( str_replace( '#', 'HASHTAG', strtolower( $bad ) ) ) ) );
if ( preg_match('/\b'.$converted_excludeword.'\b/i', $encoded_text, $matches ) ) {
$bad_text_matches++;
}
}
if ( $bad_text_matches >= $number_of_bad_text_to_look_for ) {
return false;
} else {
return true;
}
}
}
}
public static function removeStringFromText( $string, $text, $expanded_url = '' ) {
$exceptions = array( '://fb.me/' );
if ( $expanded_url !== '' ) {
foreach ( $exceptions as $exception ) {
if ( strpos( $expanded_url, $exception ) !== false ) {
return str_replace( $string, $expanded_url, $text );
}
}
}
return str_replace( $string, '', $text );
}
public static function maybeGetTwitterCardData( $url, $id ) {
if ( ! ctf_is_pro_version() ) {
return false;
}
$url_key = str_replace('&','038',$url);
$url_key = preg_replace( '~[^a-zA-Z0-9]+~', '', $url_key );
$tc_data = get_option( 'ctf_twitter_cards', array() );
$card = false;
if ( isset( $tc_data[ $url_key ] ) ) {
$card = $tc_data[ $url_key ];
} elseif ( isset( $tc_data[ $id ] ) ) {
$card = $tc_data[ $id ];
}
if ( $card && ! isset( $card['local'] ) ) {
$card['local'] = CTF_Twitter_Card_Manager::add_local_image( $card, $id );
}
return $card;
}
public function set_next_pages( $next_pages ) {
$this->next_pages = $next_pages;
}
private function merge_posts( $post_sets, $settings ) {
$merged_posts = array();
$settings['sortby'] = isset( $settings['sortby'] ) ? $settings['sortby'] : 'date';
if ( $settings['sortby'] === 'alternate' ) {
// don't bother merging posts if there is only one post set
if ( isset( $post_sets[1] ) ) {
$min_cycles = max( 1, (int)$settings['num'] );
for( $i = 0; $i <= $min_cycles; $i++ ) {
foreach ( $post_sets as $post_set ) {
if ( isset( $post_set[ $i ] ) && isset( $post_set[ $i ]['id'] ) ) {
$merged_posts[] = $post_set[ $i ];
}
}
}
} else {
$merged_posts = isset( $post_sets[0] ) ? $post_sets[0] : array();
}
} elseif ( $settings['sortby'] === 'api' ) {
if ( isset( $post_sets[0] ) ) {
foreach ( $post_sets as $post_set ) {
$merged_posts = array_merge( $merged_posts, $post_set );
}
}
} else {
// don't bother merging posts if there is only one post set
if ( isset( $post_sets[1] ) ) {
foreach ( $post_sets as $post_set ) {
$merged_posts = array_merge( $merged_posts, $post_set );
}
} else {
$merged_posts = isset( $post_sets[0] ) ? $post_sets[0] : array();
}
}
return $merged_posts;
}
/**
* Connects to the Instagram API and records returned data
*
* @param $settings
* @param array $feed_types_and_terms organized settings related to feed data
* (ex. 'user' => array( 'smashballoon', 'custominstagramfeed' )
* @param array $connected_accounts_for_feed connected account data for the
* feed types and terms
*
* @since 2.0/5.0
* @since 2.2/5.3 added logic to append bio data from the related
* connected account if not available in the API response
*/
public function set_remote_header_data( $settings, $feed_types_and_terms ) {
$this->header_data = false;
$endpoint = 'accountlookup';
if ( $settings['type'] === 'usertimeline' ) {
$endpoint = 'userslookup';
}
// Only can be set in the options page
$request_settings = array(
'consumer_key' => $settings['consumer_key'],
'consumer_secret' => $settings['consumer_secret'],
'access_token' => $settings['access_token'],
'access_token_secret' => $settings['access_token_secret'],
);
$get_fields = $this->setGetFieldsArray( $endpoint, $settings['screenname'], $settings );
// actual connection
$twitter_connect = new CtfOauthConnect( $request_settings, $endpoint );
$twitter_connect->setUrlBase();
$twitter_connect->setGetFields( $get_fields );
$twitter_connect->setRequestMethod( $settings['request_method'] );
$request_results = $twitter_connect->performRequest();
$header_json = isset( $request_results->json ) ? $request_results->json : false;
$header_data = json_decode( $header_json, true );
$this->header_data = $header_data;
}
protected function setGetFieldsArray( $end_point, $feed_term, $settings )
{
$feed_type = $end_point;
$get_fields = array();
$get_fields['tweet_mode'] = 'extended';
if ( $feed_type === 'usertimeline' ) {
if ( ! empty ( $feed_term ) ) {
$get_fields['screen_name'] = $feed_term;
}
if ( $settings['includereplies'] || $settings['selfreplies'] ) {
$get_fields['exclude_replies'] = 'false';
} else {
$get_fields['exclude_replies'] = 'true';
}
}
if ( $feed_type === 'hometimeline' ) {
if ( $settings['includereplies'] || $settings['selfreplies'] ) {
$get_fields['exclude_replies'] = 'false';
} else {
$get_fields['exclude_replies'] = 'true';
}
}
if ( $feed_type === 'search' || $feed_type === 'hashtag' ) {
$get_fields['q'] = $feed_term;
}
if ( $feed_type === 'lists' ) {
if ( ! empty ( $feed_term ) ) {
$get_fields['list_id'] = $feed_term;
}
}
if ( $feed_type === 'userslookup' ) {
if ( ! empty ( $feed_term ) ) {
$get_fields['screen_name'] = $feed_term;
}
}
return $get_fields;
}
/**
* Stores feed data in a transient for a specified time
*
* @param int $cache_time
* @param bool $save_backup
*
* @since 2.0/5.0
* @since 2.0/5.1 duplicate posts removed
*/
public function cache_feed_data( $cache_time, $save_backup = true ) {
if ( ! empty( $this->post_data ) || ! empty( $this->next_pages ) ) {
$this->remove_duplicate_posts();
$this->trim_posts_to_max();
$to_cache = array(
'data' => $this->post_data,
'pagination' => $this->next_pages
);
$this->cache->set_transient( $this->regular_feed_transient_name, wp_json_encode( $to_cache ), $cache_time );
if ( $save_backup ) {
update_option( $this->backup_feed_transient_name, wp_json_encode( $to_cache ), false );
}
} else {
$this->add_report( 'no data not caching' );
}
}
/**
* Stores header data for a specified time as a transient
*
* @param int $cache_time
* @param bool $save_backup
*
* @since 2.0/5.0
*/
public function cache_header_data( $cache_time, $save_backup = true ) {
if ( $this->header_data ) {
$this->cache->set_transient( $this->header_transient_name, wp_json_encode( $this->header_data ), $cache_time );
if ( $save_backup ) {
update_option( $this->backup_header_transient_name, wp_json_encode( $this->header_data ), false );
}
}
}
/**
* Determines if pagination can and should be used based on settings and available feed data
*
* @param array $settings
* @param int $offset
*
* @return bool
*
* @since 2.0/5.0
*/
public function should_use_pagination( $settings, $offset = 0 ) {
if ( $settings['minnum'] < 1 ) {
$this->add_report( 'minnum too small' );
return false;
}
$posts_available = count( $this->post_data ) - ($offset + $settings['minnum']);
$show_loadmore_button_by_settings = ($settings['showbutton'] == 'on' || $settings['showbutton'] == 'true' || $settings['showbutton'] == true ) && $settings['showbutton'] !== 'false';
if ( $show_loadmore_button_by_settings ) {
if ( $posts_available > 0 ) {
$this->add_report( 'do pagination, posts available' );
return true;
}
$pages = $this->next_pages;
if ( $pages && ! $this->should_use_backup() ) {
foreach ( $pages as $page ) {
if ( ! empty( $page ) ) {
return true;
}
}
}
}
$this->add_report( 'no pagination, no posts available' );
return false;
}
/**
* Overwritten in the Pro version
*
* @param $feed_types_and_terms
*
* @return string
*
* @since 2.1/5.2
*/
public function get_first_user( $feed_types_and_terms ) {
if ( isset( $feed_types_and_terms['users'][0] ) ) {
return $feed_types_and_terms['users'][0][1];
} else {
return '';
}
}
/**
* Adds recorded strings to an array
*
* @param $to_add
*
* @since 2.0/5.0
*/
public function add_report( $to_add ) {
$this->report[] = $to_add;
}
/**
* @return array
*
* @since 2.0/5.0
*/
public function get_report() {
return $this->report;
}
/**
* Used for filtering a single API request worth of posts
*
* Overwritten in the Pro version
*
* @param array $post_set a single set of post data from the api
*
* @return mixed|array
*
* @since 2.0/5.0
*/
protected function filter_posts( $post_set, $settings = array() ) {
// array_unique( $post_set, SORT_REGULAR);
return $post_set;
}
protected function handle_no_posts_found( $settings = array(), $feed_types_and_terms = array() ) {
}
protected function remove_duplicate_posts() {
$posts = $this->post_data;
$ids_in_feed = array();
$non_duplicate_posts = array();
$removed = array();
foreach ( $posts as $post ) {
$post_id = CTF_Parse::get_post_id( $post );
if ( ! in_array( $post_id, $ids_in_feed, true ) ) {
$ids_in_feed[] = $post_id;
$non_duplicate_posts[] = $post;
} else {
$removed[] = $post_id;
}
}
$this->add_report( 'removed duplicates: ' . implode(', ', $removed ) );
$this->set_post_data( $non_duplicate_posts );
}
public static function parse_api_card_data( $data ) {
$return = array(
'twitter:title' => '',
'twitter:description' => '',
'twitter:image' => '',
'twitter:site' => '',
'twitter:card' => '',
);
if ( ! empty( $data['name'] ) ) {
$return['twitter:card'] = $data['name'];
}
if ( ! empty( $data['url'] ) ) {
$return['twitter:site'] = $data['url'];
}
if ( ! empty( $data['binding_values']['title']['string_value'] ) ) {
$return['twitter:title'] = $data['binding_values']['title']['string_value'];
}
if ( ! empty( $data['binding_values']['description']['string_value'] ) ) {
$return['twitter:description'] = $data['binding_values']['description']['string_value'];
}
if ( ! empty( $data['binding_values']['thumbnail_image_large']['image_value']['url'] ) ) {
$return['twitter:image'] = $data['binding_values']['thumbnail_image_large']['image_value']['url'];
} elseif ( ! empty( $data['binding_values']['thumbnail_image']['image_value']['url'] ) ) {
$return['twitter:image'] = $data['binding_values']['thumbnail_image']['image_value']['url'];
} elseif ( ! empty( $data['binding_values']['thumbnail_image_small']['image_value']['url'] ) ) {
$return['twitter:image'] = $data['binding_values']['thumbnail_image_small']['image_value']['url'];
}
return $return;
}
}