3 namespace Drupal\media_entity_instagram;
5 use Drupal\Component\Serialization\Json;
6 use Drupal\Core\Cache\CacheBackendInterface;
7 use Drupal\Component\Utility\UrlHelper;
8 use Drupal\Core\Logger\LoggerChannelFactoryInterface;
9 use Drupal\Core\Utility\Error;
10 use GuzzleHttp\Client;
11 use GuzzleHttp\Exception\RequestException;
14 * Fetches instagram post via oembed.
16 * Fetches (and caches) instagram post data from free to use Instagram's oEmbed
19 class InstagramEmbedFetcher implements InstagramEmbedFetcherInterface {
21 const INSTAGRAM_URL = 'http://instagr.am/p/';
23 const INSTAGRAM_API = 'http://api.instagram.com/oembed';
26 * The optional cache backend.
28 * @var \Drupal\Core\Cache\CacheBackendInterface
35 * @var \GuzzleHttp\Client
37 protected $httpClient;
42 * @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
44 protected $loggerFactory;
47 * InstagramEmbedFetcher constructor.
49 * @param \GuzzleHttp\Client $client
51 * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $loggerFactory
53 * @param \Drupal\Core\Cache\CacheBackendInterface|null $cache
54 * (optional) A cache bin for storing fetched instagram posts.
56 public function __construct(Client $client, LoggerChannelFactoryInterface $loggerFactory, CacheBackendInterface $cache = NULL) {
57 $this->httpClient = $client;
58 $this->loggerFactory = $loggerFactory;
59 $this->cache = $cache;
65 public function fetchInstagramEmbed($shortcode, $hidecaption = FALSE, $maxWidth = NULL) {
68 'url' => self::INSTAGRAM_URL . $shortcode . '/',
69 'hidecaption' => (int) $hidecaption,
74 $options['maxwidth'] = $maxWidth;
77 // Tweets don't change much, so pull it out of the cache (if we have one)
78 // if this one has already been fetched.
79 $cacheKey = md5(serialize($options));
80 if ($this->cache && $cached_instagram_post = $this->cache->get($cacheKey)) {
81 return $cached_instagram_post->data;
84 $queryParameter = UrlHelper::buildQuery($options);
87 $response = $this->httpClient->request(
89 self::INSTAGRAM_API . '?' . $queryParameter,
92 if ($response->getStatusCode() === 200) {
93 $data = Json::decode($response->getBody()->getContents());
96 catch (RequestException $e) {
97 $this->loggerFactory->get('media_entity_instagram')->error("Could not retrieve Instagram post $shortcode.", Error::decodeException($e));
100 // If we got data from Instagram oEmbed request, return data.
103 // If we have a cache, store the response for future use.
105 // Instagram posts don't change often, so the response should expire
106 // from the cache on its own in 90 days.
107 $this->cache->set($cacheKey, $data, time() + (86400 * 90));