Skip to content

Commit

Permalink
backport new parser from Craft 4 version
Browse files Browse the repository at this point in the history
  • Loading branch information
kringkaste committed Oct 24, 2022
1 parent 3034438 commit 80014f9
Show file tree
Hide file tree
Showing 9 changed files with 406 additions and 146 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
# Instagram Feed Changelog

## Unreleased
## 1.2.0 - 2022-10-21

### Added

- Set referrer in proxy requests.
- Set plugin version in proxy requests.

### Changed

- Refactored parsers to generalize it more and make it easier to adapt to new structures in the future.

## 1.1.8 - 2022-06-03 [CRITICAL]

> {note} Instagram has changed the data structure on 06/01/2022. Without this update, the plugin will no longer work.
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "codemonauts/craft-instagram-feed",
"description": "Craft CMS plugin to receive Instragram feed data as variable in templates.",
"version": "1.1.8",
"version": "1.2.0",
"type": "craft-plugin",
"keywords": [
"craft",
Expand Down
48 changes: 48 additions & 0 deletions src/parsers/AccountVersion1Parser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace codemonauts\instagramfeed\parsers;

class AccountVersion1Parser extends Parser
{
/**
* @inheritDoc
*/
public function getItems(array $response): array
{
$items = [];

if (!isset($response['data']['user']['edge_owner_to_timeline_media']['edges'])) {
return $items;
}

foreach ($response['data']['user']['edge_owner_to_timeline_media']['edges'] as $media) {
$item['thumbnailSource'] = $this->getBestPicture($media['node']['thumbnail_resources']);
$item['imageSource'] = $media['node']['display_url'];
$item['likes'] = $media['node']['edge_liked_by']['count'] ?? 0;
$item['comments'] = $media['node']['edge_media_to_comment']['count'] ?? 0;
$item['shortcode'] = $media['node']['shortcode'];
$item['timestamp'] = $media['node']['taken_at_timestamp'];
$item['caption'] = $media['node']['edge_media_to_caption']['edges'][0]['node']['text'] ?? '';
$item['isVideo'] = (bool)$media['node']['is_video'];
if ($item['isVideo']) {
$item['hasAudio'] = isset($media['node']['has_audio']) && $media['node']['has_audio'];
$item['video_view_count'] = $media['node']['video_view_count'] ?? 0;
}
$items[] = $item;
}

return $items;
}

/**
* @inheritDoc
*/
protected function getPictureMapping(): array
{
return [
'width' => 'config_width',
'height' => 'config_height',
'url' => 'src',
];
}
}
54 changes: 54 additions & 0 deletions src/parsers/Parser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace codemonauts\instagramfeed\parsers;

use yii\base\Exception;

abstract class Parser
{
/**
* Returns the items from the given response.
*
* @param array $response The response from Instagram.
*
* @return array
*/
abstract public function getItems(array $response): array;

/**
* Returns the picture mapping of the structure.
*
* @return array
*/
abstract protected function getPictureMapping(): array;

/**
* Returns the best picture in size from the Instagram result array.
*
* @param array $pictures The array of pictures to choose the best version from.
*
* @return string
* @throws \yii\base\Exception
*/
final protected function getBestPicture(array $pictures): string
{
$url = '';
$maxPixels = 0;

$mapping = $this->getPictureMapping();

foreach ($pictures as $picture) {
if (!isset($picture[$mapping['width']])) {
throw new Exception('Wrong mapping of width.');
}
$pixels = $picture[$mapping['width']] * $picture[$mapping['height']];
if ($pixels > $maxPixels) {
$url = $picture[$mapping['url']];

$maxPixels = $pixels;
}
}

return $url;
}
}
59 changes: 59 additions & 0 deletions src/parsers/TagVersion1Parser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace codemonauts\instagramfeed\parsers;

class TagVersion1Parser extends Parser
{
/**
* @inheritDoc
*/
public function getItems(array $response): array
{
$items = [];

if (!isset($response['entry_data']['TagPage'][0]['graphql']['hashtag']['edge_hashtag_to_media']['edges'])) {
return $items;
}

$sections = array_slice($response['data']['recent']['sections'], 0, 12);

foreach ($sections as $section) {
foreach ($section['layout_content']['medias'] as $node) {
if ((int)$node['media']['media_type'] === 8) {
if (!isset($node['media']['carousel_media'][0]['image_versions2'])) {
continue;
}
$item['thumbnailSource'] = $this->getBestPicture($node['media']['carousel_media'][0]['image_versions2']['candidates']);
} else {
$item['thumbnailSource'] = $this->getBestPicture($node['media']['image_versions2']['candidates']);
}
$item['imageSource'] = $item['thumbnailSource'];
$item['likes'] = $node['media']['like_count'] ?? 0;
$item['comments'] = $node['media']['comment_count'] ?? 0;
$item['shortcode'] = $node['media']['code'];
$item['timestamp'] = $node['media']['taken_at'];
$item['caption'] = $node['media']['caption']['text'] ?? '';
$item['isVideo'] = (int)$node['media']['media_type'] === 2;
if ($item['isVideo']) {
$item['hasAudio'] = isset($node['media']['has_audio']) && $node['media']['has_audio'];
}
$item['video_view_count'] = $node['media']['video_view_count'] ?? 0;
$items[] = $item;
}
}

return $items;
}

/**
* @inheritDoc
*/
protected function getPictureMapping(): array
{
return [
'width' => 'width',
'height' => 'height',
'url' => 'url',
];
}
}
59 changes: 59 additions & 0 deletions src/parsers/TagVersion2Parser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace codemonauts\instagramfeed\parsers;

class TagVersion2Parser extends Parser
{
/**
* @inheritDoc
*/
public function getItems(array $response): array
{
$items = [];

if (!isset($response['data']['recent']['sections'])) {
return $items;
}

$sections = array_slice($response['data']['recent']['sections'], 0, 8);

foreach ($sections as $section) {
foreach ($section['layout_content']['medias'] as $node) {
if ((int)$node['media']['media_type'] === 8) {
if (!isset($node['media']['carousel_media'][0]['image_versions2'])) {
continue;
}
$item['thumbnailSource'] = $this->getBestPicture($node['media']['carousel_media'][0]['image_versions2']['candidates']);
} else {
$item['thumbnailSource'] = $this->getBestPicture($node['media']['image_versions2']['candidates']);
}
$item['imageSource'] = $item['thumbnailSource'];
$item['likes'] = $node['media']['like_count'] ?? 0;
$item['comments'] = $node['media']['comment_count'] ?? 0;
$item['shortcode'] = $node['media']['code'];
$item['timestamp'] = $node['media']['taken_at'];
$item['caption'] = $node['media']['caption']['text'] ?? '';
$item['isVideo'] = (int)$node['media']['media_type'] === 2;
if ($item['isVideo']) {
$item['hasAudio'] = isset($node['media']['has_audio']) && $node['media']['has_audio'];
$item['video_view_count'] = $node['media']['video_view_count'] ?? 0;
}
$items[] = $item;
}
}

return $items;
}

/**
* @inheritDoc
*/
protected function getPictureMapping(): array
{
return [
'width' => 'width',
'height' => 'height',
'url' => 'url',
];
}
}
50 changes: 50 additions & 0 deletions src/parsers/TagVersion3Parser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace codemonauts\instagramfeed\parsers;

class TagVersion3Parser extends Parser
{
/**
* @inheritDoc
*/
public function getItems(array $response): array
{
$items = [];

if (!isset($response['data']['hashtag']['edge_hashtag_to_media']['edges'])) {
return $items;
}

$medias = array_slice($response['data']['hashtag']['edge_hashtag_to_media']['edges'], 0,24);

foreach ($medias as $media) {
$item['thumbnailSource'] = $this->getBestPicture($media['node']['thumbnail_resources']);
$item['imageSource'] = $media['node']['display_url'];
$item['likes'] = $media['node']['edge_liked_by']['count'] ?? 0;
$item['comments'] = $media['node']['edge_media_to_comment']['count'] ?? 0;
$item['shortcode'] = $media['node']['shortcode'];
$item['timestamp'] = $media['node']['taken_at_timestamp'];
$item['caption'] = $media['node']['edge_media_to_caption']['edges'][0]['node']['text'] ?? '';
$item['isVideo'] = (bool)$media['node']['is_video'];
if ($item['isVideo']) {
$item['hasAudio'] = isset($media['node']['has_audio']) && $media['node']['has_audio'];
$item['video_view_count'] = $media['node']['video_view_count'] ?? 0;
}
$items[] = $item;
}

return $items;
}

/**
* @inheritDoc
*/
protected function getPictureMapping(): array
{
return [
'width' => 'config_width',
'height' => 'config_height',
'url' => 'src',
];
}
}
Loading

0 comments on commit 80014f9

Please sign in to comment.