You are here

public function TwitterFeedBlock::build in Twitter_Feed 8

Builds and returns the renderable array for this block plugin.

If a block should not be rendered because it has no content, then this method must also ensure to return no content: it must then only return an empty array, or an empty array with #cache set (with cacheability metadata indicating the circumstances for it being empty).

Return value

array A renderable array representing the content of the block.

Overrides BlockPluginInterface::build

See also

\Drupal\block\BlockViewBuilder

File

src/Plugin/Block/TwitterFeedBlock.php, line 119

Class

TwitterFeedBlock
Provides a 'TwitterFeedBlock' block.

Namespace

Drupal\twitter_feed\Plugin\Block

Code

public function build() {
  $config = \Drupal::config('twitter_feed.settings');

  // https://dev.twitter.com/oauth/application-only
  $api_key = rawurlencode($config
    ->get('twitter_feed_api_key'));
  $api_secret = rawurlencode($config
    ->get('twitter_feed_api_secret'));
  if (!$api_key || !$api_secret) {
    return [
      '#markup' => $this
        ->t('API Key or Secret missing for Twitter Feed.'),
    ];
  }
  $encoded_key = base64_encode("{$api_key}:{$api_secret}");
  $headers = [
    'Authorization' => "Basic {$encoded_key}",
    'Content-Type' => 'application/x-www-form-urlencoded',
  ];
  $options = [
    'headers' => $headers,
    'timeout' => 10,
    'form_params' => [
      'grant_type' => 'client_credentials',
    ],
    'referer' => TRUE,
    'allow_redirects' => TRUE,
    'decode_content' => 'gzip',
  ];
  try {

    // Get the access token first.
    // https://dev.twitter.com/oauth/reference/post/oauth2/token
    $res = $this->httpClient
      ->post('https://api.twitter.com/oauth2/token', $options);
    $body = json_decode($res
      ->getBody());
    $access_token = $body->access_token;

    // Now get the tweets.
    // https://dev.twitter.com/rest/reference/get/statuses/user_timeline
    $username = $this->configuration['username'];
    $num_tweets = $this->configuration['number_of_tweets'];
    $options['headers']['Authorization'] = "{$body->token_type} {$access_token}";
    unset($options['headers']['Content-Length']);
    unset($options['form_params']);
    $query = http_build_query([
      'screen_name' => $username,
      'count' => $num_tweets,
      'tweet_mode' => 'extended',
    ]);

    // Fetches the tweets.
    $res = $this->httpClient
      ->get("https://api.twitter.com/1.1/statuses/user_timeline.json?{$query}", $options);
  } catch (RequestException $e) {
    return [
      '#markup' => $this
        ->t('Error fetching tweets:') . $e
        ->getMessage(),
    ];
  }
  $renderable_tweets = [];
  foreach (json_decode($res
    ->getBody()) as $tweet_object) {
    $renderable_tweet = [
      '#theme' => 'twitter_feed_item',
      '#tweet' => $tweet_object,
    ];
    $language = \Drupal::config('twitter_feed.settings')
      ->get('twitter_feed_jquery_timeago_locale');
    $renderable_tweet['#attached']['library'][] = 'twitter_feed/timeago';
    if ($language) {
      $renderable_tweet['#attached']['library'][] = 'twitter_feed/timeago_' . $language;
    }
    $renderable_tweets[] = $renderable_tweet;
  }
  if (empty($renderable_tweets)) {
    return [
      '#markup' => $this
        ->t('Error fetching or rendering tweets.'),
    ];
  }
  $item_list = [
    '#items' => $renderable_tweets,
    '#type' => 'ul',
    '#theme' => 'item_list',
    '#attributes' => [
      'class' => 'twitter-feed',
    ],
  ];
  $build['twitter_feed_list'] = $item_list;
  $build['#cache']['keys'] = [
    'twitter_feed',
    $username,
    "count:{$num_tweets}",
  ];

  // Cache block for 1 hour by default.
  // TODO set per-block cache time.
  $build['#cache']['max-age'] = 3600;
  return $build;
}