diff --git a/README.md b/README.md
index 2883f24..9037d3a 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,10 @@ docker run -p 8080:80 \
rezozero/mixedfeed
```
+or use `docker-compose`: copy `docker-compose.yml` to `docker-compose.test.yml` and fill your provider credentials in
+it. Then execute `docker-compose -f docker-compose.test.yml up -d --force-recreate`, *Mixedfeed* will be available at
+http://localhost:8080
+
### Available environment variables
| Name | Default value | Multiple? (comma separated) |
@@ -41,8 +45,6 @@ docker run -p 8080:80 \
| MF_FACEBOOK_ACCESS_TOKEN | | |
| MF_FACEBOOK_FIELDS | from,link,picture,full_picture,message,story,type,created_time,source,status_type | ✅ |
| MF_FACEBOOK_ENDPOINT | https://graph.facebook.com/v2.12/ | |
-| MF_INSTAGRAM_USER_ID | | ✅ |
-| MF_INSTAGRAM_ACCESS_TOKEN | | |
| MF_GRAPH_INSTAGRAM_USER_ID | | ✅ |
| MF_GRAPH_INSTAGRAM_ACCESS_TOKEN | | ✅ |
| MF_GITHUB_RELEASES_REPOSITORY | | ✅ |
@@ -145,7 +147,7 @@ return $feed->getAsyncCanonicalItems(12);
## Combine feeds
-*mixedfeed* can combine multiple social feeds so you can loop over them and use some common data fields such as `feedItemPlatform`, `normalizedDate` and `canonicalMessage`. *mixedfeed* will sort all your feed items by *descending* `normalizedDate`, but you can configure it to sort *ascending*:
+*mixedfeed* can combine multiple social feeds so you can loop over them and use some common data fields such as `feedItemPlatform`, `normalizedDate` and `canonicalMessage`. *mixedfeed* will sort all your feed items by *descending* `normalizedDate`, but you can configure it to sort *ascending*:
```php
new MixedFeed([…], MixedFeed::ASC);
@@ -181,11 +183,12 @@ object with essential data: `RZ\MixedFeed\Canonical\FeedItem`. *FeedItem* will p
- likeCount `int|null`
- shareCount `int|null`: Share, comments or retweet count depending on platform.
- images `Image[]`
- - url `string`
- - width `integer`
- - height `integer`
+ - url `string`
+ - width `integer`
+ - height `integer`
- dateTime `DateTime`
- tags `array` (only used with `MediumFeed`)
+- raw `stdClass` to access raw API object if canonical item fields are not enough
When FeedItem has images, `FeedItem::$images` will hold an array of `RZ\MixedFeed\Canonical\Image` objects to
have better access to its `url`, `width` and `height` if they're available.
@@ -221,12 +224,12 @@ There are plenty of APIs on the internet, and this tool won’t be able to handl
But this is not a problem, you can easily create your own feed provider in *mixedfeed*. You just have to create a new *class* that
will inherit from `RZ\MixedFeed\AbstractFeedProvider`. Then you will have to implement some methods from `FeedProviderInterface`:
-* `getRequests($count = 5): \Generator` method which return a *Guzzle* `Request` generator to be transformed to a response. This is
+* `getRequests($count = 5): \Generator` method which return a *Guzzle* `Request` generator to be transformed to a response. This is
the best option as it will enable **async request pooling**.
* `supportsRequestPool(): bool` method should return if your provider can be pooled to enhance performances. If you are using a third party library to fetch your data (such as some platform SDK), you should set it to `false`.
* `createFeedItemFromObject($item)` method which transform a raw feed object into a canonical `RZ\MixedFeed\Canonical\FeedItem` and `RZ\MixedFeed\Canonical\Image`
* `getDateTime` method to look for the critical datetime field in your feed.
-* `getFeed` method to consume your API endpoint with a count limit and take care of caching your responses.
+* `getFeed` method to consume your API endpoint with a count limit and take care of caching your responses.
This method **must convert your own feed items into `\stdClass` objects, not arrays.**
* `getCanonicalMessage` method to look for the important text content in your feed items.
* `getFeedPlatform` method to get a global text identifier for your feed items.
@@ -255,7 +258,7 @@ protected function getFeed($count = 5)
$object = new \stdClass();
$object->native = $article;
return $object;
- },
+ },
$this->entityManager->getRepository(Article::class)->findBy(
[],
['datetime' => 'DESC'],
@@ -270,13 +273,13 @@ protected function createFeedItemFromObject($item)
$feedItem->setDateTime($this->getDateTime($item));
$feedItem->setMessage($this->getCanonicalMessage($item));
$feedItem->setPlatform($this->getFeedPlatform());
-
+
for ($item->images as $image) {
$feedItemImage = new RZ\MixedFeed\Canonical\Image();
$feedItemImage->setUrl($image->url);
$feedItem->addImage($feedItemImage);
}
-
+
return $feedItem;
}
```
@@ -299,7 +302,7 @@ public function getDateTime($item)
/**
* @inheritDoc
*/
-public function getCanonicalMessage($item)
+public function getCanonicalMessage(stdClass $item)
{
if ($item->native instanceof Article) {
return $item->native->getExcerpt();
diff --git a/composer.json b/composer.json
index 862f634..17cfd07 100644
--- a/composer.json
+++ b/composer.json
@@ -1,8 +1,15 @@
{
"name": "rezozero/mixedfeed",
+ "type": "library",
"description": "A PHP library to get social networks feeds and merge them",
+ "keywords": [
+ "feed",
+ "social",
+ "social networks",
+ "aggregator",
+ "rezo zero"
+ ],
"license": "MIT",
- "type": "library",
"authors": [
{
"name": "Ambroise Maupate",
@@ -11,28 +18,29 @@
"role": "Lead developer"
}
],
- "keywords": [
- "feed",
- "social",
- "social networks",
- "aggregator",
- "rezo zero"
- ],
"require": {
- "php": ">=7.2",
- "abraham/twitteroauth": "^2.0.0",
- "doctrine/cache": "^1.6.2",
- "guzzlehttp/guzzle": "~6.0 || ~7.0",
- "ext-json": "*"
- },
- "autoload": {
- "psr-4": {"RZ\\MixedFeed\\": "src/"}
+ "php": "^7.4 || ^8.0",
+ "ext-json": "*",
+ "abraham/twitteroauth": "^3.0",
+ "guzzlehttp/guzzle": "^7.0",
+ "guzzlehttp/promises": "^1.5",
+ "guzzlehttp/psr7": "^2.1",
+ "psr/cache": "^1.0 || ^2.0 || ^3.0"
},
"require-dev": {
- "squizlabs/php_codesniffer": "^3.3",
"jms/serializer": "^2.1 || ^3.5",
- "symfony/stopwatch": ">=4.2",
- "symfony/dotenv": ">=4.2",
- "phpstan/phpstan": "^0.12.14"
+ "phpstan/phpstan": "^1.0",
+ "squizlabs/php_codesniffer": "^3.3",
+ "symfony/cache": "^5.0",
+ "symfony/dotenv": "^5.0",
+ "symfony/stopwatch": "^5.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "RZ\\MixedFeed\\": "src/"
+ }
+ },
+ "scripts": {
+ "analyze": "vendor/bin/phpstan"
}
}
diff --git a/docker-compose.yml b/docker-compose.yml
index 9e60327..133bdc4 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -9,8 +9,8 @@ services:
# MF_FACEBOOK_ACCESS_TOKEN: ""
# MF_FACEBOOK_FIELDS: "from,picture,full_picture,message,story,created_time,status_type,message_tags,shares,permalink_url"
# MF_FACEBOOK_ENDPOINT: "https://graph.facebook.com/v2.12/"
- # MF_INSTAGRAM_USER_ID: ""
- # MF_INSTAGRAM_ACCESS_TOKEN: ""
+ # MF_GRAPH_INSTAGRAM_USER_ID: ""
+ # MF_GRAPH_INSTAGRAM_ACCESS_TOKEN: ""
# MF_GITHUB_RELEASES_REPOSITORY: ""
# MF_GITHUB_COMMITS_REPOSITORY: ""
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
index af9a6a1..cea2e73 100644
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -8,9 +8,10 @@
-
+
+
src/
*/node_modules
diff --git a/phpstan.neon b/phpstan.neon
index 12f3e15..4a91d60 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -1,12 +1,5 @@
parameters:
- level: 3
+ level: 8
+ checkMissingIterableValueType: false
paths:
- src
- excludes_analyse:
- - */node_modules/*
- - */bower_components/*
- - */static/*
- reportUnmatchedIgnoredErrors: false
- checkMissingIterableValueType: false
- checkGenericClassInNonGenericObjectType: false
- treatPhpDocTypesAsCertain: false
diff --git a/src/AbstractFeedProvider.php b/src/AbstractFeedProvider.php
index d82ec4c..9408874 100644
--- a/src/AbstractFeedProvider.php
+++ b/src/AbstractFeedProvider.php
@@ -1,187 +1,153 @@
cacheProvider = $cacheProvider;
}
- /**
- * @inheritDoc
- */
public function addError(string $reason): FeedProviderInterface
{
$this->errors[] = $reason;
+
return $this;
}
- /**
- * @param int $count
- * @return mixed
- */
- protected function getFeed($count = 5)
+ public function isCacheHit(int $count = 5): bool
{
- $rawFeed = $this->getRawFeed($count);
- if ($this->isValid($rawFeed)) {
- return $rawFeed;
+ if (!$this->cacheProvider) {
+ return false;
}
- return [];
- }
- abstract protected function getCacheKey(): string;
+ $countKey = $this->getCacheKey() . $count;
+
+ return $this->cacheProvider->getItem($countKey)->isHit();
+ }
/**
- * @param int $count
- *
- * @return bool
+ * @param string $rawFeed
*/
- public function isCacheHit($count = 5): bool
+ public function setRawFeed(string $rawFeed): AbstractFeedProvider
{
- return null !== $this->cacheProvider &&
- $this->cacheProvider->contains($this->getCacheKey() . $count);
+ $this->rawFeed = Utils::jsonDecode($rawFeed);
+
+ return $this;
}
/**
- * @param string|array $rawFeed
- * @param bool $json
- *
- * @return AbstractFeedProvider
+ * @return mixed
*/
- public function setRawFeed($rawFeed, $json = true): AbstractFeedProvider
+ protected function getFeed(int $count = 5)
{
- if ($json === true) {
- $rawFeed = json_decode($rawFeed);
- if ('No error' !== $jsonError = json_last_error_msg()) {
- throw new \RuntimeException($jsonError);
- }
+ $rawFeed = $this->getCachedRawFeed($count);
+
+ if ($this->isValid($rawFeed)) {
+ return $rawFeed;
}
- $this->rawFeed = $rawFeed;
- return $this;
+
+ return [];
}
/**
- * @param int $count
- *
* @return mixed
+ *
* @throws FeedProviderErrorException
*/
- protected function getRawFeed($count = 5)
+ protected function getRawFeed(int $count = 5)
{
- $countKey = $this->getCacheKey() . $count;
-
if (null !== $this->rawFeed) {
- if (null !== $this->cacheProvider &&
- !$this->cacheProvider->contains($countKey)) {
- $this->cacheProvider->save(
- $countKey,
- $this->rawFeed,
- $this->ttl
- );
- }
return $this->rawFeed;
}
try {
- if (null !== $this->cacheProvider &&
- $this->cacheProvider->contains($countKey)) {
- return $this->cacheProvider->fetch($countKey);
- }
-
$client = new Client([
'http_errors' => true,
]);
$response = $client->send($this->getRequests($count)->current());
- $body = json_decode($response->getBody()->getContents());
- if ('No error' !== $jsonError = json_last_error_msg()) {
- throw new FeedProviderErrorException($this->getFeedPlatform(), $jsonError);
- }
- if (null !== $this->cacheProvider) {
- $this->cacheProvider->save(
- $countKey,
- $body,
- $this->ttl
- );
- }
- return $body;
+ return Utils::jsonDecode($response->getBody()->getContents());
} catch (GuzzleException $e) {
throw new FeedProviderErrorException($this->getFeedPlatform(), $e->getMessage(), $e);
}
}
/**
- * {@inheritdoc}
+ * @return mixed
+ *
+ * @throws FeedProviderErrorException
*/
- public function getItems($count = 5)
+ protected function getCachedRawFeed(int $count = 5)
{
- $list = $this->getFeed($count);
- /*
- * Need to inject feed item platform, normalizedDate and canonicalMessage
- * to be able to merge them with other types
- */
- foreach ($list as $index => $item) {
- if (is_object($item)) {
- $item->feedItemPlatform = $this->getFeedPlatform();
- $item->normalizedDate = $this->getDateTime($item);
- $item->canonicalMessage = $this->getCanonicalMessage($item);
- } else {
- unset($list[$index]);
- }
+ if (!$this->cacheProvider) {
+ return $this->getRawFeed($count);
+ }
+
+ $countKey = $this->getCacheKey() . $count;
+ $item = $this->cacheProvider->getItem($countKey);
+
+ if ($item->isHit()) {
+ return $item->get();
}
- return $list;
+
+ $feed = $this->getRawFeed($count);
+ $item->set($feed);
+ $item->expiresAfter($this->ttl);
+
+ $this->cacheProvider->save($item);
+
+ return $feed;
}
/**
* {@inheritdoc}
*/
- public function getCanonicalItems($count = 5)
+ public function getCanonicalItems(int $count = 5): array
{
$items = [];
- foreach ($this->getFeed($count) as $index => $item) {
- if (is_object($item)) {
+
+ foreach ($this->getFeed($count) as $item) {
+ if ($item instanceof stdClass) {
$items[] = $this->createFeedItemFromObject($item);
}
}
+
return $items;
}
/**
* Gets the value of ttl.
- *
- * @return integer
*/
- public function getTtl()
+ public function getTtl(): ?int
{
return $this->ttl;
}
@@ -189,34 +155,26 @@ public function getTtl()
/**
* Sets the value of ttl.
*
- * @param integer $ttl the ttl
- *
- * @return self
+ * @param int $ttl the ttl
*/
- public function setTtl($ttl)
+ public function setTtl(?int $ttl): AbstractFeedProvider
{
$this->ttl = $ttl;
return $this;
}
- /**
- * @param \stdClass $item
- *
- * @return FeedItem
- */
- protected function createFeedItemFromObject($item): FeedItem
+ protected function createFeedItemFromObject(stdClass $item): FeedItem
{
$feedItem = new FeedItem();
+ $feedItem->setRaw($item);
$feedItem->setDateTime($this->getDateTime($item));
$feedItem->setMessage($this->getCanonicalMessage($item));
$feedItem->setPlatform($this->getFeedPlatform());
+
return $feedItem;
}
- /**
- * @inheritDoc
- */
public function supportsRequestPool(): bool
{
return true;
@@ -225,24 +183,12 @@ public function supportsRequestPool(): bool
/**
* {@inheritdoc}
*/
- public function isValid($feed)
+ public function isValid($feed): bool
{
- if (count($this->errors) > 0) {
- throw new FeedProviderErrorException($this->getFeedPlatform(), implode(', ', $this->errors));
+ if (\count($this->errors) > 0) {
+ throw new FeedProviderErrorException($this->getFeedPlatform(), \implode(', ', $this->errors));
}
- return null !== $feed && is_iterable($feed->items);
- }
- /**
- * Get errors details.
- *
- * @param mixed $feed
- *
- * @return string
- * @deprecated Catch FeedProviderErrorException for errors details.
- */
- public function getErrors($feed)
- {
- return $feed['error'];
+ return null !== $feed && \is_iterable($feed->items);
}
}
diff --git a/src/AbstractFeedProvider/AbstractTwitterFeed.php b/src/AbstractFeedProvider/AbstractTwitterFeed.php
index f46fa99..8ab395f 100644
--- a/src/AbstractFeedProvider/AbstractTwitterFeed.php
+++ b/src/AbstractFeedProvider/AbstractTwitterFeed.php
@@ -1,13 +1,17 @@
accessToken = $accessToken;
- if (null === $accessToken ||
- false === $accessToken ||
- empty($accessToken)) {
- throw new CredentialsException("TwitterSearchFeed needs a valid access token.", 1);
+ if (empty($accessToken)) {
+ throw new CredentialsException('TwitterSearchFeed needs a valid access token.', 1);
}
- if (null === $accessTokenSecret ||
- false === $accessTokenSecret ||
- empty($accessTokenSecret)) {
- throw new CredentialsException("TwitterSearchFeed needs a valid access token secret.", 1);
+ if (empty($accessTokenSecret)) {
+ throw new CredentialsException('TwitterSearchFeed needs a valid access token secret.', 1);
}
- if (null === $consumerKey ||
- false === $consumerKey ||
- empty($consumerKey)) {
- throw new CredentialsException("TwitterSearchFeed needs a valid consumer key.", 1);
+ if (empty($consumerKey)) {
+ throw new CredentialsException('TwitterSearchFeed needs a valid consumer key.', 1);
}
- if (null === $consumerSecret ||
- false === $consumerSecret ||
- empty($consumerSecret)) {
- throw new CredentialsException("TwitterSearchFeed needs a valid consumer secret.", 1);
+ if (empty($consumerSecret)) {
+ throw new CredentialsException('TwitterSearchFeed needs a valid consumer secret.', 1);
}
$this->twitterConnection = new TwitterOAuth(
@@ -82,17 +64,15 @@ public function __construct(
/**
* {@inheritdoc}
*/
- public function getDateTime($item)
+ public function getDateTime($item): DateTime
{
- $date = new \DateTime();
- $date->setTimestamp(strtotime($item->created_at));
- return $date;
+ return new DateTime('@' . \strtotime($item->created_at));
}
/**
* {@inheritdoc}
*/
- public function getCanonicalMessage($item)
+ public function getCanonicalMessage(stdClass $item): string
{
if (isset($item->text)) {
return $item->text;
@@ -101,12 +81,7 @@ public function getCanonicalMessage($item)
return $item->full_text;
}
- /**
- * @param int $count
- *
- * @return \Generator
- */
- public function getRequests($count = 5): \Generator
+ public function getRequests(int $count = 5): Generator
{
throw new \RuntimeException('Twitter cannot be used in async mode');
}
@@ -114,7 +89,7 @@ public function getRequests($count = 5): \Generator
/**
* {@inheritdoc}
*/
- public function getFeedPlatform()
+ public function getFeedPlatform(): string
{
return 'twitter';
}
@@ -122,35 +97,19 @@ public function getFeedPlatform()
/**
* {@inheritdoc}
*/
- public function isValid($feed)
- {
- if (count($this->errors) > 0) {
- throw new FeedProviderErrorException($this->getFeedPlatform(), implode(', ', $this->errors));
- }
- return null !== $feed && is_array($feed);
- }
-
- /**
- * {@inheritdoc}
- */
- public function getErrors($feed)
+ public function isValid($feed): bool
{
- $errors = "";
-
- if (null !== $feed && null !== $feed->errors && !empty($feed->errors)) {
- foreach ($feed->errors as $error) {
- $errors .= "[" . $error->code . "] ";
- $errors .= $error->message . PHP_EOL;
- }
+ if (\count($this->errors) > 0) {
+ throw new FeedProviderErrorException($this->getFeedPlatform(), \implode(', ', $this->errors));
}
- return $errors;
+ return null !== $feed && \is_array($feed);
}
/**
* @inheritDoc
*/
- protected function createFeedItemFromObject($item): FeedItem
+ protected function createFeedItemFromObject(stdClass $item): FeedItem
{
$feedItem = parent::createFeedItemFromObject($item);
$feedItem->setId($item->id_str);
@@ -168,8 +127,8 @@ protected function createFeedItemFromObject($item): FeedItem
if (isset($item->entities->hashtags)) {
foreach ($item->entities->hashtags as $hashtag) {
- $feedItem->setTags(array_merge($feedItem->getTags(), [
- $hashtag->text
+ $feedItem->setTags(\array_merge($feedItem->getTags(), [
+ $hashtag->text,
]));
}
}
diff --git a/src/AbstractFeedProvider/AbstractYoutubeVideoFeed.php b/src/AbstractFeedProvider/AbstractYoutubeVideoFeed.php
index 1d6f64b..fc459e6 100644
--- a/src/AbstractFeedProvider/AbstractYoutubeVideoFeed.php
+++ b/src/AbstractFeedProvider/AbstractYoutubeVideoFeed.php
@@ -1,80 +1,80 @@
apiKey = $apiKey;
- if (null === $this->apiKey ||
- false === $this->apiKey ||
- empty($this->apiKey)) {
- throw new CredentialsException("YoutubeVideoFeed needs a valid apiKey.", 1);
+ if (empty($this->apiKey)) {
+ throw new CredentialsException('YoutubeVideoFeed needs a valid apiKey.', 1);
}
}
- protected function getFeed($count = 5)
+ protected function getFeed(int $count = 5)
{
- $rawFeed = $this->getRawFeed($count);
+ $rawFeed = $this->getCachedRawFeed($count);
if ($this->isValid($rawFeed)) {
return $rawFeed->items;
}
+
return [];
}
/**
* {@inheritdoc}
*/
- public function getDateTime($item)
+ public function getDateTime($item): ?DateTime
{
if (isset($item->snippet->publishedAt)) {
- return new \DateTime($item->snippet->publishedAt);
+ return new DateTime($item->snippet->publishedAt);
}
+
return null;
}
/**
* {@inheritdoc}
*/
- public function getCanonicalMessage($item)
+ public function getCanonicalMessage(stdClass $item): string
{
if (isset($item->snippet->title)) {
return $item->snippet->title;
}
- return "";
+ return '';
}
/**
* @inheritDoc
*/
- protected function createFeedItemFromObject($item): FeedItem
+ protected function createFeedItemFromObject(stdClass $item): FeedItem
{
$feedItem = parent::createFeedItemFromObject($item);
$feedItem->setId($item->id);
- $feedItem->setLink('https://www.youtube.com/watch?v=' . $item->id);
+ $feedItem->setLink(\sprintf(self::YOUTUBE_URL_FORMAT, $item->id));
$feedItem->setTitle($item->snippet->title);
$feedItem->setMessage($item->snippet->description);
$feedItem->setAuthor($item->snippet->channelTitle);
@@ -90,6 +90,7 @@ protected function createFeedItemFromObject($item): FeedItem
$feedItemImage->setHeight($item->snippet->thumbnails->maxres->height);
$feedItem->addImage($feedItemImage);
}
+
return $feedItem;
}
}
diff --git a/src/Canonical/FeedItem.php b/src/Canonical/FeedItem.php
index e863d1d..74653a0 100644
--- a/src/Canonical/FeedItem.php
+++ b/src/Canonical/FeedItem.php
@@ -1,281 +1,192 @@
id;
}
- /**
- * @param string $id
- *
- * @return FeedItem
- */
- public function setId($id)
+ public function setId(string $id): FeedItem
{
$this->id = $id;
return $this;
}
- /**
- * @return string
- */
- public function getPlatform()
+ public function getRaw(): ?stdClass
+ {
+ return $this->raw;
+ }
+
+ public function setRaw(stdClass $object): FeedItem
+ {
+ $this->raw = $object;
+
+ return $this;
+ }
+
+ public function getPlatform(): string
{
return $this->platform;
}
- /**
- * @param string $platform
- *
- * @return FeedItem
- */
- public function setPlatform($platform)
+ public function setPlatform(string $platform): FeedItem
{
$this->platform = $platform;
return $this;
}
- /**
- * @return string
- */
- public function getAuthor()
+ public function getAuthor(): string
{
return $this->author;
}
- /**
- * @param string $author
- *
- * @return FeedItem
- */
- public function setAuthor($author)
+ public function setAuthor(string $author): FeedItem
{
$this->author = $author;
return $this;
}
- /**
- * @return string
- */
- public function getTitle()
+ public function getTitle(): string
{
return $this->title;
}
- /**
- * @param string $title
- *
- * @return FeedItem
- */
- public function setTitle($title)
+ public function setTitle(string $title): FeedItem
{
$this->title = $title;
return $this;
}
- /**
- * @return Image[]
- */
- public function getImages()
+ /** @return Image[] */
+ public function getImages(): array
{
return $this->images;
}
- /**
- * @param Image[] $images
- *
- * @return FeedItem
- */
- public function setImages($images)
+ /** @param Image[] $images */
+ public function setImages(array $images): FeedItem
{
$this->images = $images;
return $this;
}
- /**
- * @param Image $image
- *
- * @return FeedItem
- */
- public function addImage(Image $image)
+ public function addImage(Image $image): FeedItem
{
$this->images[] = $image;
+
return $this;
}
- /**
- * @return string
- */
- public function getMessage()
+ public function getMessage(): string
{
return $this->message;
}
- /**
- * @param string $message
- *
- * @return FeedItem
- */
- public function setMessage($message)
+ public function setMessage(string $message): FeedItem
{
$this->message = $message;
return $this;
}
- /**
- * @return \DateTime
- */
- public function getDateTime()
+ public function getDateTime(): ?DateTime
{
return $this->dateTime;
}
- /**
- * @param \DateTime $dateTime
- *
- * @return FeedItem
- */
- public function setDateTime($dateTime)
+ public function setDateTime(?DateTime $dateTime): FeedItem
{
$this->dateTime = $dateTime;
return $this;
}
- /**
- * @return string
- */
- public function getLink()
+ public function getLink(): string
{
return $this->link;
}
- /**
- * @param string $link
- *
- * @return FeedItem
- */
- public function setLink($link)
+ public function setLink(string $link): FeedItem
{
$this->link = $link;
return $this;
}
- /**
- * @return array
- */
- public function getTags()
+ /** @return string[] */
+ public function getTags(): array
{
return $this->tags;
}
- /**
- * @param array $tags
- *
- * @return FeedItem
- */
- public function setTags(array $tags)
+ /** @param string[] $tags */
+ public function setTags(array $tags): FeedItem
{
$this->tags = $tags;
return $this;
}
- /**
- * @return int|null
- */
public function getLikeCount(): ?int
{
return $this->likeCount;
}
- /**
- * @param int $likeCount
- *
- * @return FeedItem
- */
- public function setLikeCount(int $likeCount)
+ public function setLikeCount(int $likeCount): FeedItem
{
$this->likeCount = $likeCount;
return $this;
}
- /**
- * @return int|null
- */
public function getShareCount(): ?int
{
return $this->shareCount;
}
- /**
- * @param int $shareCount
- *
- * @return FeedItem
- */
- public function setShareCount(int $shareCount)
+ public function setShareCount(int $shareCount): FeedItem
{
$this->shareCount = $shareCount;
diff --git a/src/Canonical/Image.php b/src/Canonical/Image.php
index 21d546d..3174aac 100644
--- a/src/Canonical/Image.php
+++ b/src/Canonical/Image.php
@@ -1,75 +1,45 @@
url;
}
- /**
- * @param string $url
- *
- * @return Image
- */
- public function setUrl($url)
+ public function setUrl(string $url): Image
{
$this->url = $url;
return $this;
}
- /**
- * @return int
- */
- public function getWidth()
+ public function getWidth(): int
{
return $this->width;
}
- /**
- * @param int $width
- *
- * @return Image
- */
- public function setWidth($width)
+ public function setWidth(int $width): Image
{
$this->width = $width;
return $this;
}
- /**
- * @return int
- */
- public function getHeight()
+ public function getHeight(): int
{
return $this->height;
}
- /**
- * @param int $height
- *
- * @return Image
- */
- public function setHeight($height)
+ public function setHeight(int $height): Image
{
$this->height = $height;
diff --git a/src/Env/CacheResolver.php b/src/Env/CacheResolver.php
index 8b98ea9..94de636 100644
--- a/src/Env/CacheResolver.php
+++ b/src/Env/CacheResolver.php
@@ -1,29 +1,27 @@
*
- * @return FeedProviderInterface[]
- * @throws \RZ\MixedFeed\Exception\CredentialsException
+ * @throws CredentialsException
*/
- public static function parseFromEnvironment(CacheProvider $cache = null)
+ public static function parseFromEnvironment(?CacheItemPoolInterface $cache = null): array
{
$feedProviders = [];
- if (false !== $facebookPageIds = getenv('MF_FACEBOOK_PAGE_ID')) {
- $facebookPageIds = explode(',', $facebookPageIds);
+
+ if (false !== $facebookPageIds = $_ENV['MF_FACEBOOK_PAGE_ID'] ?? false) {
+ $facebookPageIds = \explode(',', $facebookPageIds);
+
foreach ($facebookPageIds as $facebookPageId) {
$facebookProvider = new FacebookPageFeed(
$facebookPageId,
- getenv('MF_FACEBOOK_ACCESS_TOKEN'),
+ $_ENV['MF_FACEBOOK_ACCESS_TOKEN'] ?? '',
$cache,
- getenv('MF_FACEBOOK_FIELDS') ?
- explode(',', getenv('MF_FACEBOOK_FIELDS')):
+ isset($_ENV['MF_FACEBOOK_FIELDS']) ?
+ \explode(',', $_ENV['MF_FACEBOOK_FIELDS']) :
[],
- getenv('MF_FACEBOOK_ENDPOINT')
+ $_ENV['MF_FACEBOOK_ENDPOINT'] ?? null
);
- array_push($feedProviders, $facebookProvider);
+ \array_push($feedProviders, $facebookProvider);
}
}
+
/*
* Youtube playlist
*/
- if (false !== $youtubePlaylistIds = getenv('MF_YOUTUBE_PLAYLIST_ID')) {
- $youtubePlaylistIds = explode(',', $youtubePlaylistIds);
+ if (false !== $youtubePlaylistIds = \getenv('MF_YOUTUBE_PLAYLIST_ID')) {
+ $youtubePlaylistIds = \explode(',', $youtubePlaylistIds);
+
foreach ($youtubePlaylistIds as $youtubePlaylistId) {
$youtubePlaylistProvider = new YoutubePlaylistItemFeed(
$youtubePlaylistId,
- getenv('MF_YOUTUBE_API_KEY'),
+ $_ENV['MF_YOUTUBE_API_KEY'] ?? '',
$cache
);
- array_push($feedProviders, $youtubePlaylistProvider);
+ \array_push($feedProviders, $youtubePlaylistProvider);
}
}
+
/*
* Former Instagram API
*/
- if (false !== $instagramUserIds = getenv('MF_INSTAGRAM_USER_ID')) {
- $instagramUserIds = explode(',', $instagramUserIds);
+ if (isset($_ENV['MF_INSTAGRAM_USER_ID'])) {
+ $instagramUserIds = \explode(',', $_ENV['MF_INSTAGRAM_USER_ID']);
+
foreach ($instagramUserIds as $instagramUserId) {
$instagramProvider = new InstagramFeed(
$instagramUserId,
- getenv('MF_INSTAGRAM_ACCESS_TOKEN'),
+ $_ENV['MF_INSTAGRAM_ACCESS_TOKEN'] ?? '',
$cache
);
- array_push($feedProviders, $instagramProvider);
+ \array_push($feedProviders, $instagramProvider);
}
}
+
/*
* Graph instagram
*/
- $instagramUserIds = getenv('MF_GRAPH_INSTAGRAM_USER_ID');
- $instagramAccessTokens = getenv('MF_GRAPH_INSTAGRAM_ACCESS_TOKEN');
- if (false !== $instagramUserIds && false !== $instagramAccessTokens) {
- $instagramUserIds = explode(',', $instagramUserIds);
- $instagramAccessTokens = explode(',', $instagramAccessTokens);
+ $instagramUserIds = $_ENV['MF_GRAPH_INSTAGRAM_USER_ID'] ?? null;
+ $instagramAccessTokens = $_ENV['MF_GRAPH_INSTAGRAM_ACCESS_TOKEN'] ?? null;
+
+ if ($instagramUserIds && $instagramAccessTokens) {
+ $instagramUserIds = \explode(',', $instagramUserIds);
+ $instagramAccessTokens = \explode(',', $instagramAccessTokens);
+
foreach ($instagramUserIds as $i => $instagramUserId) {
- if (isset($instagramAccessTokens[$i])) {
- $instagramProvider = new GraphInstagramFeed(
- $instagramUserId,
- $instagramAccessTokens[$i],
- $cache
- );
- array_push($feedProviders, $instagramProvider);
+ if (!isset($instagramAccessTokens[$i])) {
+ continue;
}
+
+ $instagramProvider = new GraphInstagramFeed($instagramUserId, $instagramAccessTokens[$i], $cache);
+ \array_push($feedProviders, $instagramProvider);
}
}
- if (false !== $instagramOEmbedId = getenv('MF_INSTAGRAM_OEMBED_ID')) {
+
+ if (isset($_ENV['MF_INSTAGRAM_OEMBED_ID'])) {
$instagramOEmbedProvider = new InstagramOEmbedFeed(
- explode(',', $instagramOEmbedId),
- $cache
+ \explode(',', $_ENV['MF_INSTAGRAM_OEMBED_ID']),
+ $cache,
);
- array_push($feedProviders, $instagramOEmbedProvider);
+ \array_push($feedProviders, $instagramOEmbedProvider);
}
- if (false !== $mediumUserNames = getenv('MF_MEDIUM_USERNAME')) {
- $mediumUserNames = explode(',', $mediumUserNames);
- if (false !== $mediumUserIds = getenv('MF_MEDIUM_USER_ID')) {
- $mediumUserIds = explode(',', $mediumUserIds);
- } else {
- $mediumUserIds = [];
- }
+
+ if (isset($_ENV['MF_MEDIUM_USERNAME'])) {
+ $mediumUserNames = \explode(',', $_ENV['MF_MEDIUM_USERNAME']);
+
+ $mediumUserIds = $_ENV['MF_MEDIUM_USER_ID'];
+ $mediumUserIds = \explode(',', $mediumUserIds);
foreach ($mediumUserNames as $i => $mediumUserName) {
$mediumUserId = null;
+
if (!empty($mediumUserIds[$i])) {
$mediumUserId = $mediumUserIds[$i];
}
- $mediumProvider = new MediumFeed(
- $mediumUserName,
- $cache,
- $mediumUserId
- );
- array_push($feedProviders, $mediumProvider);
+
+ $mediumProvider = new MediumFeed($mediumUserName, $cache, $mediumUserId);
+ \array_push($feedProviders, $mediumProvider);
}
}
- if (false !== $pinterestBoardIds = getenv('MF_PINTEREST_BOARD_ID')) {
- $pinterestBoardIds = explode(',', $pinterestBoardIds);
+
+ if (isset($_ENV['MF_PINTEREST_BOARD_ID'])) {
+ $pinterestBoardIds = \explode(',', $_ENV['MF_PINTEREST_BOARD_ID']);
+
foreach ($pinterestBoardIds as $pinterestBoardId) {
$pinterestProvider = new PinterestBoardFeed(
$pinterestBoardId,
- getenv('MF_PINTEREST_ACCESS_TOKEN'),
+ $_ENV['MF_PINTEREST_ACCESS_TOKEN'] ?? '',
$cache
);
- array_push($feedProviders, $pinterestProvider);
+ \array_push($feedProviders, $pinterestProvider);
}
}
- if (false !== $githubReleasesRepos = getenv('MF_GITHUB_RELEASES_REPOSITORY')) {
- $githubReleasesRepos = explode(',', $githubReleasesRepos);
+
+ if (isset($_ENV['MF_GITHUB_RELEASES_REPOSITORY'])) {
+ $githubReleasesRepos = \explode(',', $_ENV['MF_GITHUB_RELEASES_REPOSITORY']);
+
foreach ($githubReleasesRepos as $githubReleasesRepo) {
$githubReleasesProvider = new GithubReleasesFeed(
$githubReleasesRepo,
- getenv('MF_GITHUB_ACCESS_TOKEN'),
+ $_ENV['MF_GITHUB_ACCESS_TOKEN'] ?? '',
$cache
);
- array_push($feedProviders, $githubReleasesProvider);
+ \array_push($feedProviders, $githubReleasesProvider);
}
}
- if (false !== $githubCommitsRepos = getenv('MF_GITHUB_COMMITS_REPOSITORY')) {
- $githubCommitsRepos = explode(',', $githubCommitsRepos);
+
+ if (isset($_ENV['MF_GITHUB_COMMITS_REPOSITORY'])) {
+ $githubCommitsRepos = \explode(',', $_ENV['MF_GITHUB_COMMITS_REPOSITORY']);
+
foreach ($githubCommitsRepos as $githubCommitsRepo) {
$githubCommitsProvider = new GithubCommitsFeed(
$githubCommitsRepo,
- getenv('MF_GITHUB_ACCESS_TOKEN'),
+ $_ENV['MF_GITHUB_ACCESS_TOKEN'] ?? '',
$cache
);
- array_push($feedProviders, $githubCommitsProvider);
+ \array_push($feedProviders, $githubCommitsProvider);
}
}
- if (false !== $twitterUserIds = getenv('MF_TWITTER_USER_ID')) {
- $twitterUserIds = explode(',', $twitterUserIds);
+
+ if (isset($_ENV['MF_TWITTER_USER_ID'])) {
+ $twitterUserIds = \explode(',', $_ENV['MF_TWITTER_USER_ID']);
+
foreach ($twitterUserIds as $twitterUserId) {
$twitterProvider = new TwitterFeed(
$twitterUserId,
- getenv('MF_TWITTER_CONSUMER_KEY'),
- getenv('MF_TWITTER_CONSUMER_SECRET'),
- getenv('MF_TWITTER_ACCESS_TOKEN'),
- getenv('MF_TWITTER_ACCESS_TOKEN_SECRET'),
+ $_ENV['MF_TWITTER_CONSUMER_KEY'] ?? '',
+ $_ENV['MF_TWITTER_CONSUMER_SECRET'] ?? '',
+ $_ENV['MF_TWITTER_ACCESS_TOKEN'] ?? '',
+ $_ENV['MF_TWITTER_ACCESS_TOKEN_SECRET'] ?? '',
$cache,
true,
false,
- (bool) getenv('MF_TWITTER_EXTENDED_MODE')
+ (bool) ($_ENV['MF_TWITTER_EXTENDED_MODE'] ?? false)
);
- array_push($feedProviders, $twitterProvider);
+ \array_push($feedProviders, $twitterProvider);
}
}
- if (false !== $twitterSearch = getenv('MF_TWITTER_SEARCH_QUERY')) {
- parse_str($twitterSearch, $searchParams);
+
+ if (isset($_ENV['MF_TWITTER_SEARCH_QUERY'])) {
+ \parse_str($_ENV['MF_TWITTER_SEARCH_QUERY'], $searchParams);
$twitterSearchProvider = new TwitterSearchFeed(
$searchParams,
- getenv('MF_TWITTER_CONSUMER_KEY'),
- getenv('MF_TWITTER_CONSUMER_SECRET'),
- getenv('MF_TWITTER_ACCESS_TOKEN'),
- getenv('MF_TWITTER_ACCESS_TOKEN_SECRET'),
+ $_ENV['MF_TWITTER_CONSUMER_KEY'] ?? '',
+ $_ENV['MF_TWITTER_CONSUMER_SECRET'] ?? '',
+ $_ENV['MF_TWITTER_ACCESS_TOKEN'] ?? '',
+ $_ENV['MF_TWITTER_ACCESS_TOKEN_SECRET'] ?? '',
$cache,
- (bool) getenv('MF_TWITTER_EXTENDED_MODE')
+ (bool) ($_ENV['MF_TWITTER_EXTENDED_MODE'] ?? false)
);
- array_push($feedProviders, $twitterSearchProvider);
+ \array_push($feedProviders, $twitterSearchProvider);
}
return $feedProviders;
diff --git a/src/Exception/CredentialsException.php b/src/Exception/CredentialsException.php
index d2902e4..5d0d42c 100644
--- a/src/Exception/CredentialsException.php
+++ b/src/Exception/CredentialsException.php
@@ -1,12 +1,17 @@
pageId = $pageId;
@@ -61,15 +54,13 @@ public function __construct(
'status_type',
'message_tags',
'shares',
- 'permalink_url'
+ 'permalink_url',
];
- $this->fields = array_unique(array_merge($this->fields, $fields));
+ $this->fields = \array_unique(\array_merge($this->fields, $fields));
$this->apiBaseUrl = $apiBaseUrl ?: $this->apiBaseUrl;
- if (null === $this->accessToken ||
- false === $this->accessToken ||
- empty($this->accessToken)) {
- throw new CredentialsException("FacebookPageFeed needs a valid App access token.", 1);
+ if (empty($this->accessToken)) {
+ throw new CredentialsException('FacebookPageFeed needs a valid App access token.', 1);
}
}
@@ -81,54 +72,57 @@ protected function getCacheKey(): string
/**
* @inheritDoc
*/
- public function getRequests($count = 5): \Generator
+ public function getRequests(int $count = 5): Generator
{
$params = [
'access_token' => $this->accessToken,
- 'limit' => $count,
- 'fields' => implode(',', $this->fields),
+ 'limit' => $count,
+ 'fields' => \implode(',', $this->fields),
];
/*
* Filter by date range
*/
- if (null !== $this->since &&
- $this->since instanceof \Datetime) {
+ if (
+ null !== $this->since &&
+ $this->since instanceof DateTime
+ ) {
$params['since'] = $this->since->getTimestamp();
}
- if (null !== $this->until &&
- $this->until instanceof \Datetime) {
+ if (
+ null !== $this->until &&
+ $this->until instanceof DateTime
+ ) {
$params['until'] = $this->until->getTimestamp();
}
- $value = http_build_query($params, null, '&', PHP_QUERY_RFC3986);
+ $value = \http_build_query($params, '', '&', PHP_QUERY_RFC3986);
yield new Request(
'GET',
- $this->apiBaseUrl . $this->pageId . '/posts?'.$value
+ $this->apiBaseUrl . $this->pageId . '/posts?' . $value
);
}
- protected function getFeed($count = 5)
+ protected function getFeed(int $count = 5)
{
- $rawFeed = $this->getRawFeed($count);
- if (is_array($rawFeed) && isset($rawFeed['error'])) {
+ $rawFeed = $this->getCachedRawFeed($count);
+ if (\is_array($rawFeed) && isset($rawFeed['error'])) {
return $rawFeed;
}
+
return $rawFeed->data;
}
/**
* {@inheritdoc}
*/
- public function getDateTime($item)
+ public function getDateTime($item): ?DateTime
{
- $date = new \DateTime();
- $date->setTimestamp(strtotime($item->created_time));
- return $date;
+ return new DateTime('@' . \strtotime($item->created_time));
}
/**
* {@inheritdoc}
*/
- public function getCanonicalMessage($item)
+ public function getCanonicalMessage(stdClass $item): string
{
return isset($item->message) ? $item->message : '';
}
@@ -136,17 +130,15 @@ public function getCanonicalMessage($item)
/**
* {@inheritdoc}
*/
- public function getFeedPlatform()
+ public function getFeedPlatform(): string
{
return 'facebook_page';
}
/**
* Gets the value of since.
- *
- * @return \Datetime
*/
- public function getSince()
+ public function getSince(): ?DateTime
{
return $this->since;
}
@@ -154,11 +146,9 @@ public function getSince()
/**
* Sets the value of since.
*
- * @param \Datetime $since the since
- *
- * @return self
+ * @param DateTime $since the since
*/
- public function setSince(\Datetime $since)
+ public function setSince(?DateTime $since): AbstractFeedProvider
{
$this->since = $since;
@@ -167,10 +157,8 @@ public function setSince(\Datetime $since)
/**
* Gets the value of until.
- *
- * @return \Datetime
*/
- public function getUntil()
+ public function getUntil(): ?DateTime
{
return $this->until;
}
@@ -178,11 +166,9 @@ public function getUntil()
/**
* Sets the value of until.
*
- * @param \Datetime $until the until
- *
- * @return self
+ * @param DateTime $until the until
*/
- public function setUntil(\Datetime $until)
+ public function setUntil(?DateTime $until): AbstractFeedProvider
{
$this->until = $until;
@@ -192,7 +178,7 @@ public function setUntil(\Datetime $until)
/**
* @inheritDoc
*/
- protected function createFeedItemFromObject($item): FeedItem
+ protected function createFeedItemFromObject(stdClass $item): FeedItem
{
$feedItem = parent::createFeedItemFromObject($item);
$feedItem->setId($item->id);
@@ -211,7 +197,7 @@ protected function createFeedItemFromObject($item): FeedItem
}
if (isset($item->message_tags)) {
- $feedItem->setTags(array_map(function ($messageTag) {
+ $feedItem->setTags(\array_map(function ($messageTag) {
return $messageTag->name;
}, $item->message_tags));
}
@@ -225,22 +211,20 @@ protected function createFeedItemFromObject($item): FeedItem
return $feedItem;
}
- /**
- * @return array
- */
+ /** @return string[] */
public function getFields(): array
{
return $this->fields;
}
/**
- * @param array $fields
+ * @param string[] $fields
*
* @return FacebookPageFeed
*/
public function setFields(array $fields)
{
- $this->fields = array_unique($fields);
+ $this->fields = \array_unique($fields);
return $this;
}
diff --git a/src/FeedProviderInterface.php b/src/FeedProviderInterface.php
index 5a17a2f..7093c67 100644
--- a/src/FeedProviderInterface.php
+++ b/src/FeedProviderInterface.php
@@ -1,6 +1,7 @@
*/
+ public function getRequests(int $count = 5): Generator;
/**
* Get the social platform name.
- *
- * @return string
*/
- public function getFeedPlatform();
- /**
- *
- * Get item method must return the direct
- * feed array and must inject two parameters in each item:
- *
- * * feedItemPlatform (string)
- * * normalizedDate (\DateTime)
- *
- * @param integer $count
- * @return array
- * @throws FeedProviderErrorException
- * @deprecated Use getCanonicalItems method
- */
- public function getItems($count = 5);
+ public function getFeedPlatform(): string;
/**
* Get item method must return a normalized array of FeedItem.
*
- * @param int $count
+ * @return FeedItem[]
*
- * @return mixed
* @throws FeedProviderErrorException
*/
- public function getCanonicalItems($count = 5);
+ public function getCanonicalItems(int $count = 5): array;
/**
- * Get a \DateTime object from a social feed item.
+ * Get a DateTime object from a social feed item.
*
* @param \stdClass $item
- * @return \DateTime|null
*/
- public function getDateTime($item);
+ public function getDateTime($item): ?DateTime;
/**
* Check if the feed provider has succeded to
* contact API.
*
* @param mixed $feed
- *
- * @return boolean
*/
- public function isValid($feed);
+ public function isValid($feed): bool;
/**
- * @param string $reason
- *
* @return $this
*/
public function addError(string $reason): FeedProviderInterface;
/**
* Get a canonical message from current feed item.
- *
- * @param \stdClass $item
- * @return string
*/
- public function getCanonicalMessage($item);
+ public function getCanonicalMessage(stdClass $item): string;
- /**
- * @return bool
- */
public function supportsRequestPool(): bool;
}
diff --git a/src/GithubCommitsFeed.php b/src/GithubCommitsFeed.php
index dc98330..47e8e86 100644
--- a/src/GithubCommitsFeed.php
+++ b/src/GithubCommitsFeed.php
@@ -1,55 +1,48 @@
repository = $repository;
$this->accessToken = $accessToken;
$this->page = $page;
- if (null === $repository ||
- false === $repository ||
- empty($repository)) {
- throw new CredentialsException("GithubCommitsFeed needs a valid repository name.", 1);
+ if (empty($repository)) {
+ throw new CredentialsException('GithubCommitsFeed needs a valid repository name.', 1);
}
- if (0 === preg_match('#([a-zA-Z\-\_0-9\.]+)/([a-zA-Z\-\_0-9\.]+)#', $repository)) {
- throw new CredentialsException("GithubCommitsFeed needs a valid repository name “user/project”.", 1);
+ if (0 === \preg_match('#([a-zA-Z\-\_0-9\.]+)/([a-zA-Z\-\_0-9\.]+)#', $repository)) {
+ throw new CredentialsException('GithubCommitsFeed needs a valid repository name “user/project”.', 1);
}
- if (null === $accessToken ||
- false === $accessToken ||
- empty($accessToken)) {
- throw new CredentialsException("GithubCommitsFeed needs a valid access token.", 1);
+ if (empty($accessToken)) {
+ throw new CredentialsException('GithubCommitsFeed needs a valid access token.', 1);
}
}
@@ -61,34 +54,32 @@ protected function getCacheKey(): string
/**
* @inheritDoc
*/
- public function getRequests($count = 5): \Generator
+ public function getRequests(int $count = 5): Generator
{
- $value = http_build_query([
+ $value = \http_build_query([
'access_token' => $this->accessToken,
- 'per_page' => $count,
- 'token_type' => 'bearer',
- 'page' => $this->page,
- ], null, '&', PHP_QUERY_RFC3986);
+ 'per_page' => $count,
+ 'token_type' => 'bearer',
+ 'page' => $this->page,
+ ], '', '&', PHP_QUERY_RFC3986);
yield new Request(
'GET',
- 'https://api.github.com/repos/' . $this->repository . '/commits?'.$value
+ 'https://api.github.com/repos/' . $this->repository . '/commits?' . $value
);
}
/**
* {@inheritdoc}
*/
- public function getDateTime($item)
+ public function getDateTime($item): ?DateTime
{
- $date = new \DateTime();
- $date->setTimestamp(strtotime($item->commit->author->date));
- return $date;
+ return new DateTime('@' . \strtotime($item->commit->author->date));
}
/**
* {@inheritdoc}
*/
- public function getCanonicalMessage($item)
+ public function getCanonicalMessage(stdClass $item): string
{
return $item->commit->message;
}
@@ -96,7 +87,7 @@ public function getCanonicalMessage($item)
/**
* {@inheritdoc}
*/
- public function getFeedPlatform()
+ public function getFeedPlatform(): string
{
return 'github_commit';
}
@@ -104,12 +95,13 @@ public function getFeedPlatform()
/**
* @inheritDoc
*/
- protected function createFeedItemFromObject($item): FeedItem
+ protected function createFeedItemFromObject(stdClass $item): FeedItem
{
$feedItem = parent::createFeedItemFromObject($item);
$feedItem->setId($item->sha);
$feedItem->setAuthor($item->commit->author->name);
$feedItem->setLink($item->html_url);
+
return $feedItem;
}
}
diff --git a/src/GithubReleasesFeed.php b/src/GithubReleasesFeed.php
index 4e17664..cc472b0 100644
--- a/src/GithubReleasesFeed.php
+++ b/src/GithubReleasesFeed.php
@@ -1,56 +1,48 @@
repository = $repository;
$this->accessToken = $accessToken;
$this->page = $page;
- if (null === $repository ||
- false === $repository ||
- empty($repository)) {
- throw new CredentialsException("GithubReleasesFeed needs a valid repository name.", 1);
+ if (empty($repository)) {
+ throw new CredentialsException('GithubReleasesFeed needs a valid repository name.', 1);
}
- if (0 === preg_match('#([a-zA-Z\-\_0-9\.]+)/([a-zA-Z\-\_0-9\.]+)#', $repository)) {
- throw new CredentialsException("GithubReleasesFeed needs a valid repository name “user/project”.", 1);
+ if (0 === \preg_match('#([a-zA-Z\-\_0-9\.]+)/([a-zA-Z\-\_0-9\.]+)#', $repository)) {
+ throw new CredentialsException('GithubReleasesFeed needs a valid repository name “user/project”.', 1);
}
- if (null === $accessToken ||
- false === $accessToken ||
- empty($accessToken)) {
- throw new CredentialsException("GithubReleasesFeed needs a valid access token.", 1);
+ if (empty($accessToken)) {
+ throw new CredentialsException('GithubReleasesFeed needs a valid access token.', 1);
}
}
@@ -62,34 +54,32 @@ protected function getCacheKey(): string
/**
* @inheritDoc
*/
- public function getRequests($count = 5): \Generator
+ public function getRequests(int $count = 5): Generator
{
- $value = http_build_query([
+ $value = \http_build_query([
'access_token' => $this->accessToken,
- 'per_page' => $count,
- 'token_type' => 'bearer',
- 'page' => $this->page,
- ], null, '&', PHP_QUERY_RFC3986);
+ 'per_page' => $count,
+ 'token_type' => 'bearer',
+ 'page' => $this->page,
+ ], '', '&', PHP_QUERY_RFC3986);
yield new Request(
'GET',
- 'https://api.github.com/repos/' . $this->repository . '/releases?'.$value
+ 'https://api.github.com/repos/' . $this->repository . '/releases?' . $value
);
}
/**
* {@inheritdoc}
*/
- public function getDateTime($item)
+ public function getDateTime($item): ?DateTime
{
- $date = new \DateTime();
- $date->setTimestamp(strtotime($item->created_at));
- return $date;
+ return new DateTime('@' . \strtotime($item->created_at));
}
/**
* {@inheritdoc}
*/
- public function getCanonicalMessage($item)
+ public function getCanonicalMessage(stdClass $item): string
{
return $item->name;
}
@@ -97,7 +87,7 @@ public function getCanonicalMessage($item)
/**
* {@inheritdoc}
*/
- public function getFeedPlatform()
+ public function getFeedPlatform(): string
{
return 'github_release';
}
@@ -105,7 +95,7 @@ public function getFeedPlatform()
/**
* @inheritDoc
*/
- protected function createFeedItemFromObject($item): FeedItem
+ protected function createFeedItemFromObject(stdClass $item): FeedItem
{
$feedItem = parent::createFeedItemFromObject($item);
$feedItem->setId($item->id);
@@ -113,6 +103,7 @@ protected function createFeedItemFromObject($item): FeedItem
$feedItem->setLink($item->html_url);
$feedItem->setTitle($item->name);
$feedItem->setMessage($item->body);
+
return $feedItem;
}
}
diff --git a/src/Graph/AccessToken.php b/src/Graph/AccessToken.php
index 9746191..eae1080 100644
--- a/src/Graph/AccessToken.php
+++ b/src/Graph/AccessToken.php
@@ -1,29 +1,16 @@
accessToken = $accessToken;
$this->tokenType = $tokenType;
@@ -31,8 +18,6 @@ final public function __construct(string $accessToken, string $tokenType = "", i
}
/**
- * @param array $payload
- *
* @return static
*/
public static function fromArray(array $payload)
@@ -49,25 +34,16 @@ public function __toString()
return $this->accessToken;
}
- /**
- * @return string
- */
public function getAccessToken(): string
{
return $this->accessToken;
}
- /**
- * @return string
- */
public function getTokenType(): string
{
return $this->tokenType;
}
- /**
- * @return int
- */
public function getExpiresIn(): int
{
return $this->expiresIn;
diff --git a/src/Graph/RefreshInstagramAccessToken.php b/src/Graph/RefreshInstagramAccessToken.php
index 43a19c3..cf5eedf 100644
--- a/src/Graph/RefreshInstagramAccessToken.php
+++ b/src/Graph/RefreshInstagramAccessToken.php
@@ -1,40 +1,29 @@
accessToken = $accessToken;
}
- /**
- * @throws FeedProviderErrorException
- */
+ /** @throws FeedProviderErrorException */
public function getRefreshedAccessToken(): AccessToken
{
$value = \http_build_query([
- 'grant_type' => static::$grantType,
+ 'grant_type' => self::$grantType,
'access_token' => $this->accessToken,
]);
@@ -44,9 +33,12 @@ public function getRefreshedAccessToken(): AccessToken
]);
$response = $client->send(new Request(
'GET',
- 'https://graph.instagram.com/refresh_access_token?'.$value
+ 'https://graph.instagram.com/refresh_access_token?' . $value
));
- return AccessToken::fromArray(json_decode($response->getBody()->getContents(), true));
+
+ $body = GuzzleUtils::jsonDecode($response->getBody()->getContents(), true);
+
+ return AccessToken::fromArray((array) $body);
} catch (GuzzleException $e) {
throw new FeedProviderErrorException(RefreshInstagramAccessToken::class, $e->getMessage(), $e);
}
diff --git a/src/GraphInstagramFeed.php b/src/GraphInstagramFeed.php
index e05223d..02fd83d 100644
--- a/src/GraphInstagramFeed.php
+++ b/src/GraphInstagramFeed.php
@@ -1,54 +1,56 @@
userId = $userId;
$this->accessToken = $accessToken;
- if (count($fields) > 0) {
- $this->fields = $fields;
- } else {
- $this->fields = [
+
+ $this->fields = \count($fields) > 0
+ ? $fields
+ : [
'id',
'username',
'caption',
@@ -60,101 +62,94 @@ public function __construct($userId, $accessToken, CacheProvider $cacheProvider
'like_count',
'comments_count',
];
- }
- if (null === $this->accessToken ||
- false === $this->accessToken ||
- empty($this->accessToken)) {
- throw new CredentialsException("GraphInstagramFeed needs a valid access token.", 1);
+ if (empty($this->accessToken)) {
+ throw new CredentialsException('GraphInstagramFeed needs a valid access token.', 1);
}
}
- protected function getCacheKey(): string
+ /** @inheritDoc */
+ public function getRequests(int $count = 5): Generator
{
- return $this->getFeedPlatform() . $this->userId;
+ $value = \http_build_query([
+ 'fields' => \implode(',', $this->fields),
+ 'access_token' => $this->accessToken,
+ 'limit' => $count,
+ ], '', '&', PHP_QUERY_RFC3986);
+
+ yield new Request('GET', 'https://graph.instagram.com/' . $this->userId . '/media?' . $value);
}
- /**
- * @inheritDoc
- */
- public function getRequests($count = 5): \Generator
+ protected function getCacheKey(): string
{
- $value = http_build_query([
- 'fields' => implode(',', $this->fields),
- 'access_token' => $this->accessToken,
- 'limit' => $count,
- ], null, '&', PHP_QUERY_RFC3986);
- yield new Request(
- 'GET',
- 'https://graph.instagram.com/' . $this->userId . '/media?'.$value
- );
+ return $this->getFeedPlatform() . $this->userId;
}
- protected function getFeed($count = 5)
+ protected function getFeed(int $count = 5)
{
- $rawFeed = $this->getRawFeed($count);
+ $rawFeed = $this->getCachedRawFeed($count);
+
if ($this->isValid($rawFeed)) {
return $rawFeed->data;
}
+
return [];
}
/**
* {@inheritdoc}
*/
- public function isValid($feed)
+ public function isValid($feed): bool
{
- if (count($this->errors) > 0) {
- throw new FeedProviderErrorException($this->getFeedPlatform(), implode(', ', $this->errors));
+ if (\count($this->errors) > 0) {
+ throw new FeedProviderErrorException($this->getFeedPlatform(), \implode(', ', $this->errors));
}
- return isset($feed->data) && is_iterable($feed->data);
+
+ return isset($feed->data) && \is_iterable($feed->data);
}
/**
* {@inheritdoc}
*/
- public function getDateTime($item)
+ public function getDateTime($item): DateTime
{
- return new \DateTime($item->timestamp);
+ return new DateTime($item->timestamp);
}
/**
* {@inheritdoc}
*/
- public function getCanonicalMessage($item)
+ public function getCanonicalMessage(stdClass $item): string
{
if (null !== $item->caption) {
return $item->caption;
}
- return "";
+ return '';
}
- /**
- * {@inheritdoc}
- */
- public function getFeedPlatform()
+ public function getFeedPlatform(): string
{
return 'instagram';
}
- /**
- * @inheritDoc
- */
- protected function createFeedItemFromObject($item): FeedItem
+ /** @inheritDoc */
+ protected function createFeedItemFromObject(stdClass $item): FeedItem
{
$feedItem = parent::createFeedItemFromObject($item);
$feedItem->setId($item->id);
$feedItem->setAuthor($item->username);
$feedItem->setLink($item->permalink);
+
if (isset($item->like_count)) {
$feedItem->setLikeCount($item->like_count);
}
+
if (isset($item->comments_count)) {
$feedItem->setShareCount($item->comments_count);
}
- if ($item->media_type === static::TYPE_VIDEO && !empty($item->thumbnail_url)) {
+ if (self::TYPE_VIDEO === $item->media_type && !empty($item->thumbnail_url)) {
$feedItemImage = new Image();
$feedItemImage->setUrl($item->thumbnail_url);
$feedItem->addImage($feedItemImage);
diff --git a/src/InstagramFeed.php b/src/InstagramFeed.php
index f6ed374..58cc45b 100644
--- a/src/InstagramFeed.php
+++ b/src/InstagramFeed.php
@@ -1,42 +1,40 @@
userId = $userId;
$this->accessToken = $accessToken;
- if (null === $this->accessToken ||
- false === $this->accessToken ||
- empty($this->accessToken)) {
- throw new CredentialsException("InstagramFeed needs a valid access token.", 1);
+ if (empty($this->accessToken)) {
+ throw new CredentialsException('InstagramFeed needs a valid access token.', 1);
}
}
@@ -48,64 +46,64 @@ protected function getCacheKey(): string
/**
* @inheritDoc
*/
- public function getRequests($count = 5): \Generator
+ public function getRequests(int $count = 5): Generator
{
- $value = http_build_query([
+ $value = \http_build_query([
'access_token' => $this->accessToken,
- 'count' => $count,
- ], null, '&', PHP_QUERY_RFC3986);
+ 'count' => $count,
+ ], '', '&', PHP_QUERY_RFC3986);
yield new Request(
'GET',
- 'https://api.instagram.com/v1/users/' . $this->userId . '/media/recent/?'.$value
+ 'https://api.instagram.com/v1/users/' . $this->userId . '/media/recent/?' . $value
);
}
- protected function getFeed($count = 5)
+ protected function getFeed(int $count = 5)
{
- $rawFeed = $this->getRawFeed($count);
+ $rawFeed = $this->getCachedRawFeed($count);
if ($this->isValid($rawFeed)) {
return $rawFeed->data;
}
+
return [];
}
/**
* {@inheritdoc}
*/
- public function isValid($feed)
+ public function isValid($feed): bool
{
- if (count($this->errors) > 0) {
- throw new FeedProviderErrorException($this->getFeedPlatform(), implode(', ', $this->errors));
+ if (\count($this->errors) > 0) {
+ throw new FeedProviderErrorException($this->getFeedPlatform(), \implode(', ', $this->errors));
}
- return isset($feed->data) && is_iterable($feed->data);
+
+ return isset($feed->data) && \is_iterable($feed->data);
}
/**
* {@inheritdoc}
*/
- public function getDateTime($item)
+ public function getDateTime($item): DateTime
{
- $date = new \DateTime();
- $date->setTimestamp($item->created_time);
- return $date;
+ return new DateTime('@' . $item->created_time);
}
/**
* {@inheritdoc}
*/
- public function getCanonicalMessage($item)
+ public function getCanonicalMessage(stdClass $item): string
{
if (null !== $item->caption) {
return $item->caption->text;
}
- return "";
+ return '';
}
/**
* {@inheritdoc}
*/
- public function getFeedPlatform()
+ public function getFeedPlatform(): string
{
return 'instagram';
}
@@ -113,7 +111,7 @@ public function getFeedPlatform()
/**
* @inheritDoc
*/
- protected function createFeedItemFromObject($item): FeedItem
+ protected function createFeedItemFromObject(stdClass $item): FeedItem
{
$feedItem = parent::createFeedItemFromObject($item);
$feedItem->setId($item->id);
@@ -127,6 +125,7 @@ protected function createFeedItemFromObject($item): FeedItem
$feedItemImage->setWidth($item->images->standard_resolution->width);
$feedItemImage->setHeight($item->images->standard_resolution->height);
$feedItem->addImage($feedItemImage);
+
return $feedItem;
}
}
diff --git a/src/InstagramOEmbedFeed.php b/src/InstagramOEmbedFeed.php
index 95b1a47..fd67e84 100644
--- a/src/InstagramOEmbedFeed.php
+++ b/src/InstagramOEmbedFeed.php
@@ -1,30 +1,33 @@
$url) {
- if (0 === preg_match('#^https?:\/\/www\.instagram\.com\/p\/#', $url)) {
+ if (0 === \preg_match('#^https?:\/\/www\.instagram\.com\/p\/#', $url)) {
$embedUrls[$i] = 'https://www.instagram.com/p/' . $url;
}
}
@@ -33,23 +36,18 @@ public function __construct($embedUrls, CacheProvider $cacheProvider = null)
protected function getCacheKey(): string
{
- return $this->getFeedPlatform() . serialize($this->embedUrls);
+ return $this->getFeedPlatform() . \serialize($this->embedUrls);
}
- /**
- * @param int $count
- *
- * @return \Generator
- */
- public function getRequests($count = 5): \Generator
+ public function getRequests(int $count = 5): Generator
{
foreach ($this->embedUrls as $embedUrl) {
- $value = http_build_query([
+ $value = \http_build_query([
'url' => $embedUrl,
- ], null, '&', PHP_QUERY_RFC3986);
+ ], '', '&', PHP_QUERY_RFC3986);
yield new Request(
'GET',
- 'https://api.instagram.com/oembed?'.$value
+ 'https://api.instagram.com/oembed?' . $value
);
}
}
@@ -57,51 +55,32 @@ public function getRequests($count = 5): \Generator
/**
* @param mixed $rawFeed
* @param bool $json
- *
- * @return AbstractFeedProvider
*/
public function setRawFeed($rawFeed, $json = true): AbstractFeedProvider
{
if (null === $this->rawFeed) {
$this->rawFeed = [];
}
- if ($json === true) {
- $rawFeed = json_decode($rawFeed);
- if ('No error' !== $jsonError = json_last_error_msg()) {
- throw new \RuntimeException($jsonError);
- }
+ if (true === $json && \is_string($rawFeed)) {
+ GuzzleUtils::jsonDecode($rawFeed, true);
}
- array_push($this->rawFeed, $rawFeed);
+ \array_push($this->rawFeed, $rawFeed);
+
return $this;
}
/**
- * @param int $count
- *
* @return array
+ *
* @throws FeedProviderErrorException
*/
- protected function getRawFeed($count = 5)
+ protected function getRawFeed(int $count = 5)
{
- $countKey = $this->getCacheKey() . $count;
-
if (null !== $this->rawFeed) {
- if (null !== $this->cacheProvider &&
- !$this->cacheProvider->contains($countKey)) {
- $this->cacheProvider->save(
- $countKey,
- $this->rawFeed,
- $this->ttl
- );
- }
return $this->rawFeed;
}
try {
- if (null !== $this->cacheProvider &&
- $this->cacheProvider->contains($countKey)) {
- return $this->cacheProvider->fetch($countKey);
- }
$body = [];
$promises = [];
$client = new \GuzzleHttp\Client();
@@ -109,28 +88,17 @@ protected function getRawFeed($count = 5)
// Initiate each request but do not block
$promises[] = $client->sendAsync($request);
}
- $responses = \GuzzleHttp\Promise\settle($promises)->wait();
+ /** @var array $responses */
+ $responses = Promise\Utils::settle($promises)->wait();
- /** @var array $response */
foreach ($responses as $response) {
- if ($response['state'] !== 'rejected') {
- array_push($body, json_decode($response['value']->getBody()->getContents()));
- if ('No error' !== $jsonError = json_last_error_msg()) {
- throw new \RuntimeException($jsonError);
- }
+ if ('rejected' !== $response['state']) {
+ \array_push($body, GuzzleUtils::jsonDecode($response['value']->getBody()->getContents()));
} else {
throw $response['reason'];
}
}
- if (null !== $this->cacheProvider) {
- $this->cacheProvider->save(
- $countKey,
- $body,
- $this->ttl
- );
- }
-
return $body;
} catch (ClientException $e) {
throw new FeedProviderErrorException($this->getFeedPlatform(), $e->getMessage(), $e);
@@ -140,7 +108,7 @@ protected function getRawFeed($count = 5)
/**
* {@inheritdoc}
*/
- public function getFeedPlatform()
+ public function getFeedPlatform(): string
{
return 'instagram_oembed';
}
@@ -148,10 +116,10 @@ public function getFeedPlatform()
/**
* {@inheritdoc}
*/
- public function isValid($feed)
+ public function isValid($feed): bool
{
- if (count($this->errors) > 0) {
- throw new FeedProviderErrorException($this->getFeedPlatform(), implode(', ', $this->errors));
+ if (\count($this->errors) > 0) {
+ throw new FeedProviderErrorException($this->getFeedPlatform(), \implode(', ', $this->errors));
}
// OEmbed response is not iterable because there is only one item
return null !== $feed;
@@ -160,30 +128,31 @@ public function isValid($feed)
/**
* {@inheritdoc}
*/
- public function getDateTime($item)
+ public function getDateTime($item): ?DateTime
{
- if (false !== preg_match("#datetime=\\\"([^\"]+)\\\"#", $item->html, $matches)) {
- return new \DateTime($matches[1]);
+ if (false !== \preg_match('#datetime=\\"([^"]+)\\"#', $item->html, $matches)) {
+ return new DateTime('@' . $matches[1]);
}
+
return null;
}
/**
* {@inheritdoc}
*/
- public function getCanonicalMessage($item)
+ public function getCanonicalMessage(stdClass $item): string
{
if (isset($item->title)) {
return $item->title;
}
- return "";
+ return '';
}
/**
* @inheritDoc
*/
- protected function createFeedItemFromObject($item): FeedItem
+ protected function createFeedItemFromObject(stdClass $item): FeedItem
{
$feedItem = parent::createFeedItemFromObject($item);
$feedItem->setId($item->media_id);
@@ -194,6 +163,7 @@ protected function createFeedItemFromObject($item): FeedItem
$feedItemImage->setWidth($item->thumbnail_width);
$feedItemImage->setHeight($item->thumbnail_height);
$feedItem->addImage($feedItemImage);
+
return $feedItem;
}
}
diff --git a/src/MediumFeed.php b/src/MediumFeed.php
index e01cd2b..e5db64b 100644
--- a/src/MediumFeed.php
+++ b/src/MediumFeed.php
@@ -1,50 +1,46 @@
username = $username;
$this->cacheProvider = $cacheProvider;
$this->userId = $userId;
- if ($this->userId !== null) {
+ if (null !== $this->userId) {
/*
* If userId is available, use the profile/stream endpoint instead for better consistency
* between calls.
@@ -63,14 +59,14 @@ protected function getCacheKey(): string
/**
* @inheritDoc
*/
- public function getRequests($count = 5): \Generator
+ public function getRequests(int $count = 5): Generator
{
- $value = http_build_query([
- 'format' => 'json',
- 'limit' => $count,
+ $value = \http_build_query([
+ 'format' => 'json',
+ 'limit' => $count,
'collectionId' => null,
- 'source' => 'latest',
- ], null, '&', PHP_QUERY_RFC3986);
+ 'source' => 'latest',
+ ], '', '&', PHP_QUERY_RFC3986);
yield new Request(
'GET',
$this->url . '?' . $value
@@ -80,57 +76,27 @@ public function getRequests($count = 5): \Generator
/**
* @inheritDoc
*/
- public function setRawFeed($rawFeed, $json = true): AbstractFeedProvider
+ public function setRawFeed(string $rawFeed): AbstractFeedProvider
{
- if ($json === true) {
- $rawFeed = str_replace('])}while(1);', '', $rawFeed);
- $rawFeed = json_decode($rawFeed);
- if ('No error' !== $jsonError = json_last_error_msg()) {
- throw new \RuntimeException($jsonError);
- }
- }
+ $rawFeed = \str_replace('])}while(1);', '', $rawFeed);
+ $rawFeed = Utils::jsonDecode($rawFeed, true);
$this->rawFeed = $rawFeed;
+
return $this;
}
-
- protected function getRawFeed($count = 5)
+ protected function getRawFeed(int $count = 5)
{
- $countKey = $this->getCacheKey() . $count;
-
if (null !== $this->rawFeed) {
- if (null !== $this->cacheProvider &&
- !$this->cacheProvider->contains($countKey)) {
- $this->cacheProvider->save(
- $countKey,
- $this->rawFeed,
- $this->ttl
- );
- }
return $this->rawFeed;
}
- try {
- if (null !== $this->cacheProvider &&
- $this->cacheProvider->contains($countKey)) {
- return $this->cacheProvider->fetch($countKey);
- }
+ try {
$client = new Client();
$response = $client->send($this->getRequests($count)->current());
$raw = $response->getBody()->getContents();
- $raw = str_replace('])}while(1);', '', $raw);
- $body = json_decode($raw);
- if ('No error' !== $jsonError = json_last_error_msg()) {
- throw new \RuntimeException($jsonError);
- }
-
- if (null !== $this->cacheProvider) {
- $this->cacheProvider->save(
- $countKey,
- $body,
- $this->ttl
- );
- }
+ $raw = \str_replace('])}while(1);', '', $raw);
+ $body = Utils::jsonDecode($raw);
return $body;
} catch (ClientException $e) {
@@ -141,28 +107,31 @@ protected function getRawFeed($count = 5)
/**
* @inheritDoc
*/
- protected function getFeed($count = 5): array
+ protected function getFeed(int $count = 5): array
{
- return $this->getTypedFeed($this->getRawFeed($count));
+ return $this->getTypedFeed($this->getCachedRawFeed($count));
}
-
/**
* @param object $body
*
* @return array
+ *
* @throws \Exception
*/
protected function getTypedFeed($body)
{
$feed = [];
+ if (!isset($body->payload)) {
+ return $feed;
+ }
if (isset($body->payload->user)) {
$this->name = $body->payload->user->name;
}
foreach ($body->payload->streamItems as $item) {
- if ($item->itemType === 'postPreview') {
+ if ('postPreview' === $item->itemType) {
$id = $item->postPreview->postId;
- $createdAt = new \DateTime();
+ $createdAt = new DateTime();
$createdAt->setTimestamp($item->createdAt);
if (isset($body->payload->references->Post->$id)) {
@@ -177,7 +146,7 @@ protected function getTypedFeed($body)
/**
* {@inheritdoc}
*/
- public function getFeedPlatform()
+ public function getFeedPlatform(): string
{
return 'medium';
}
@@ -185,38 +154,34 @@ public function getFeedPlatform()
/**
* {@inheritdoc}
*/
- public function getDateTime($item)
+ public function getDateTime($item): ?DateTime
{
- $createdAt = new \DateTime();
- if ($this->isUsingLatestPublicationDate()) {
- $createdAt->setTimestamp($item->latestPublishedAt/1000);
- } else {
- $createdAt->setTimestamp($item->firstPublishedAt/1000);
- }
- return $createdAt;
+ $createdAt = $this->isUsingLatestPublicationDate() ? $item->latestPublishedAt / 1000 : $item->firstPublishedAt / 1000;
+
+ return new DateTime('@' . $createdAt);
}
/**
* {@inheritdoc}
*/
- public function getCanonicalMessage($item)
+ public function getCanonicalMessage(stdClass $item): string
{
if (isset($item->title)) {
return $item->title;
}
- return "";
+ return '';
}
/**
* @inheritDoc
*/
- protected function createFeedItemFromObject($item): FeedItem
+ protected function createFeedItemFromObject(stdClass $item): FeedItem
{
$feedItem = parent::createFeedItemFromObject($item);
$feedItem->setId($item->uniqueSlug);
$feedItem->setAuthor($this->name);
- $feedItem->setLink('https://medium.com/'.$this->username.'/'.$item->uniqueSlug);
+ $feedItem->setLink('https://medium.com/' . $this->username . '/' . $item->uniqueSlug);
$feedItem->setTitle($item->title);
$feedItem->setTags($item->virtuals->tags);
if (isset($item->content) && isset($item->content->subtitle)) {
@@ -228,7 +193,7 @@ protected function createFeedItemFromObject($item): FeedItem
/*
* 4 seems to be an image type
*/
- if ($paragraph->type === 4 && isset($paragraph->metadata)) {
+ if (4 === $paragraph->type && isset($paragraph->metadata)) {
$feedItemImage = new Image();
$feedItemImage->setUrl('https://miro.medium.com/' . $paragraph->metadata->id);
$feedItemImage->setWidth($paragraph->metadata->originalWidth);
@@ -237,6 +202,7 @@ protected function createFeedItemFromObject($item): FeedItem
}
}
}
+
return $feedItem;
}
@@ -248,19 +214,11 @@ public function getName()
return $this->name;
}
- /**
- * @return bool
- */
public function isUsingLatestPublicationDate(): bool
{
return $this->useLatestPublicationDate;
}
- /**
- * @param bool $useLatestPublicationDate
- *
- * @return MediumFeed
- */
public function setUseLatestPublicationDate(bool $useLatestPublicationDate): MediumFeed
{
$this->useLatestPublicationDate = $useLatestPublicationDate;
diff --git a/src/MixedFeed.php b/src/MixedFeed.php
index 226f093..3d8adc6 100644
--- a/src/MixedFeed.php
+++ b/src/MixedFeed.php
@@ -1,48 +1,41 @@
providers) > 0) {
- $perProviderCount = floor($count / count($this->providers));
-
- /** @var FeedProviderInterface $provider */
- foreach ($this->providers as $provider) {
- try {
- $list = array_merge($list, $provider->getItems($perProviderCount));
- } catch (FeedProviderErrorException $e) {
- $list = array_merge($list, [
- new ErroredFeedItem($e->getMessage(), $provider->getFeedPlatform()),
- ]);
- }
- }
- }
-
- return $this->sortFeedObjects($list);
- }
-
- /**
- * @inheritDoc
+ * @return FeedItem[]
*/
- public function getCanonicalItems($count = 5)
+ public function getCanonicalItems(int $count = 5): array
{
$list = [];
- if (count($this->providers) > 0) {
- $perProviderCount = floor($count / count($this->providers));
+ if (\count($this->providers) > 0) {
+ $perProviderCount = (int) \floor($count / \count($this->providers));
/** @var FeedProviderInterface $provider */
foreach ($this->providers as $provider) {
try {
- $list = array_merge($list, $provider->getCanonicalItems($perProviderCount));
+ /** @var FeedItem[] $list */
+ $list = \array_merge($list, $provider->getCanonicalItems($perProviderCount));
} catch (FeedProviderErrorException $e) {
$errorItem = new FeedItem();
$errorItem->setMessage($e->getMessage());
$errorItem->setPlatform($provider->getFeedPlatform() . ' [errored]');
- $errorItem->setDateTime(new \DateTime());
- $list = array_merge($list, [
- $errorItem
+ $errorItem->setDateTime(new DateTime());
+ $list = \array_merge($list, [
+ $errorItem,
]);
}
}
}
+
return $this->sortFeedItems($list);
}
/**
* @param FeedItem[] $feedItems
*
- * @return array
+ * @return FeedItem[] $feedItems
*/
protected function sortFeedItems(array $feedItems): array
{
- usort($feedItems, function (FeedItem $a, FeedItem $b) {
+ \usort($feedItems, function (FeedItem $a, FeedItem $b) {
$aDT = $a->getDateTime();
$bDT = $b->getDateTime();
@@ -122,92 +93,19 @@ protected function sortFeedItems(array $feedItems): array
// DESC sorting
return ($aDT > $bDT) ? -1 : 1;
});
- return $feedItems;
- }
-
- /**
- * @param \stdClass[] $items
- *
- * @return array
- */
- protected function sortFeedObjects(array $items)
- {
- usort($items, function (\stdClass $a, \stdClass $b) {
- $aDT = $a->normalizedDate;
- $bDT = $b->normalizedDate;
-
- if ($aDT == $bDT) {
- return 0;
- }
- // ASC sorting
- if ($this->sortDirection === static::ASC) {
- return ($aDT > $bDT) ? 1 : -1;
- }
- // DESC sorting
- return ($aDT > $bDT) ? -1 : 1;
- });
-
- return $items;
- }
-
- /**
- * {@inheritdoc}
- */
- public function getFeedPlatform()
- {
- return 'mixed';
- }
-
- /**
- * {@inheritdoc}
- */
- public function getDateTime($item)
- {
- return new \DateTime('now');
- }
-
- /**
- * {@inheritdoc}
- */
- public function getCanonicalMessage($item)
- {
- return "";
- }
-
- /**
- * {@inheritdoc}
- */
- public function isValid($feed)
- {
- return true;
- }
- /**
- * {@inheritdoc}
- */
- public function getErrors($feed)
- {
- return '';
- }
-
- /**
- * @inheritDoc
- */
- protected function getFeed($count = 5): array
- {
- trigger_error('getFeed method must not be called in MixedFeed.', E_USER_ERROR);
- return [];
+ return $feedItems;
}
/**
- * @inheritDoc
+ * @return FeedItem[]
*/
- public function getAsyncCanonicalItems($count = 5): array
+ public function getAsyncCanonicalItems(int $count = 5): array
{
- if (count($this->providers) === 0) {
+ if (0 === \count($this->providers)) {
throw new \RuntimeException('No provider were registered');
}
- $perProviderCount = floor($count / count($this->providers));
+ $perProviderCount = (int) \floor($count / \count($this->providers));
$list = [];
$requests = [];
/** @var FeedProviderInterface $provider */
@@ -223,22 +121,25 @@ public function getAsyncCanonicalItems($count = 5): array
$client = new Client();
$pool = new Pool($client, $requests, [
'concurrency' => 6,
- 'fulfilled' => function ($response, $index) {
- list($providerIdx, $i) = explode('.', $index);
+ 'fulfilled' => function (Response $response, $index) {
+ list($providerIdx, $i) = \explode('.', $index);
$provider = $this->providers[$providerIdx];
- if ($provider instanceof AbstractFeedProvider &&
- $response instanceof Response &&
- $response->getStatusCode() === 200) {
+ if (
+ 200 === $response->getStatusCode()
+ && $provider instanceof AbstractFeedProvider
+ && $response instanceof Response
+ ) {
$provider->setRawFeed($response->getBody()->getContents());
} else {
$provider->addError($response->getReasonPhrase());
}
},
- 'rejected' => function ($reason, $index) {
- list($providerIdx, $i) = explode('.', $index);
+ 'rejected' => function (RequestException $reason, $index) {
+ list($providerIdx, $i) = \explode('.', $index);
$provider = $this->providers[$providerIdx];
- if ($provider instanceof AbstractFeedProvider &&
- method_exists($reason, 'getMessage')) {
+ if (
+ $provider instanceof AbstractFeedProvider
+ ) {
$provider->addError($reason->getMessage());
}
},
@@ -253,37 +154,19 @@ public function getAsyncCanonicalItems($count = 5): array
* For providers which already have a cached response
*/
try {
- $list = array_merge($list, $provider->getCanonicalItems($perProviderCount));
+ /** @var FeedItem[] $list */
+ $list = \array_merge($list, $provider->getCanonicalItems($perProviderCount));
} catch (FeedProviderErrorException $e) {
$errorItem = new FeedItem();
$errorItem->setMessage($e->getMessage());
$errorItem->setPlatform($provider->getFeedPlatform() . ' [errored]');
- $errorItem->setDateTime(new \DateTime());
- $list = array_merge($list, [
- $errorItem
+ $errorItem->setDateTime(new DateTime());
+ $list = \array_merge($list, [
+ $errorItem,
]);
}
}
return $this->sortFeedItems($list);
}
-
- /**
- * @param int $count
- *
- * @return \Generator
- */
- public function getRequests($count = 5): \Generator
- {
- if (count($this->providers) === 0) {
- throw new \RuntimeException('No provider were registered');
- }
-
- $perProviderCount = floor($count / count($this->providers));
-
- /** @var FeedProviderInterface $provider */
- foreach ($this->providers as $provider) {
- yield iterator_to_array($provider->getRequests($perProviderCount));
- }
- }
}
diff --git a/src/MockObject/ErroredFeedItem.php b/src/MockObject/ErroredFeedItem.php
deleted file mode 100644
index 0c65499..0000000
--- a/src/MockObject/ErroredFeedItem.php
+++ /dev/null
@@ -1,34 +0,0 @@
-message = $message;
- $this->feedItemPlatform = $feedItemPlatform . '[errored]';
- $this->normalizedDate = new \Datetime('now');
- $this->canonicalMessage = $message;
- }
-}
diff --git a/src/PinterestBoardFeed.php b/src/PinterestBoardFeed.php
index 2ed8c8e..138f2ad 100644
--- a/src/PinterestBoardFeed.php
+++ b/src/PinterestBoardFeed.php
@@ -1,12 +1,16 @@
boardId = $boardId;
$this->accessToken = $accessToken;
- if (null === $this->accessToken ||
- false === $this->accessToken ||
- empty($this->accessToken)) {
- throw new CredentialsException("PinterestBoardFeed needs a valid access token.", 1);
+ if (empty($this->accessToken)) {
+ throw new CredentialsException('PinterestBoardFeed needs a valid access token.', 1);
}
}
@@ -50,58 +49,58 @@ protected function getCacheKey(): string
/**
* @inheritDoc
*/
- public function getRequests($count = 5): \Generator
+ public function getRequests(int $count = 5): Generator
{
- $value = http_build_query([
+ $value = \http_build_query([
'access_token' => $this->accessToken,
- 'limit' => $count,
- 'fields' => 'id,color,created_at,creator,media,image[original],note,link,url',
- ], null, '&', PHP_QUERY_RFC3986);
+ 'limit' => $count,
+ 'fields' => 'id,color,created_at,creator,media,image[original],note,link,url',
+ ], '', '&', PHP_QUERY_RFC3986);
yield new Request(
'GET',
- 'https://api.pinterest.com/v1/boards/' . $this->boardId . '/pins?'.$value
+ 'https://api.pinterest.com/v1/boards/' . $this->boardId . '/pins?' . $value
);
}
/**
* {@inheritdoc}
*/
- public function isValid($feed)
+ public function isValid($feed): bool
{
- if (count($this->errors) > 0) {
- throw new FeedProviderErrorException($this->getFeedPlatform(), implode(', ', $this->errors));
+ if (\count($this->errors) > 0) {
+ throw new FeedProviderErrorException($this->getFeedPlatform(), \implode(', ', $this->errors));
}
- return isset($feed->data) && is_iterable($feed->data);
+
+ return isset($feed->data) && \is_iterable($feed->data);
}
/**
- * @param int $count
* @return mixed
+ *
* @throws FeedProviderErrorException
*/
- protected function getFeed($count = 5)
+ protected function getFeed(int $count = 5)
{
- $rawFeed = $this->getRawFeed($count);
+ $rawFeed = $this->getCachedRawFeed($count);
if ($this->isValid($rawFeed)) {
return $rawFeed->data;
}
+
return [];
}
/**
* {@inheritdoc}
*/
- public function getDateTime($item)
+ public function getDateTime($item): DateTime
{
- $date = new \DateTime();
- $date->setTimestamp(strtotime($item->created_at));
- return $date;
+ return new DateTime('@' . \strtotime($item->created_at));
}
/**
* {@inheritdoc}
*/
- public function getCanonicalMessage($item)
+ public function getCanonicalMessage(stdClass $item): string
{
return $item->note;
}
@@ -109,7 +108,7 @@ public function getCanonicalMessage($item)
/**
* {@inheritdoc}
*/
- public function getFeedPlatform()
+ public function getFeedPlatform(): string
{
return 'pinterest_pin';
}
@@ -117,7 +116,7 @@ public function getFeedPlatform()
/**
* @inheritDoc
*/
- protected function createFeedItemFromObject($item): FeedItem
+ protected function createFeedItemFromObject(stdClass $item): FeedItem
{
$feedItem = parent::createFeedItemFromObject($item);
$feedItem->setId($item->id);
@@ -131,6 +130,7 @@ protected function createFeedItemFromObject($item): FeedItem
$feedItemImage->setHeight($item->image->original->height);
$feedItem->addImage($feedItemImage);
}
+
return $feedItem;
}
}
diff --git a/src/Response/FeedItemResponse.php b/src/Response/FeedItemResponse.php
index d831556..cca542d 100644
--- a/src/Response/FeedItemResponse.php
+++ b/src/Response/FeedItemResponse.php
@@ -1,21 +1,20 @@
meta = $meta;
}
- /**
- * @return array
- */
+ /** @return FeedItem[] */
public function getItems(): array
{
return $this->items;
}
- /**
- * @param array $items
- *
- * @return FeedItemResponse
- */
+ /** @param FeedItem[] $items */
public function setItems(array $items): FeedItemResponse
{
$this->items = $items;
@@ -43,19 +36,13 @@ public function setItems(array $items): FeedItemResponse
return $this;
}
- /**
- * @return array
- */
+ /** @return mixed[] */
public function getMeta(): array
{
return $this->meta;
}
- /**
- * @param array $meta
- *
- * @return FeedItemResponse
- */
+ /** @param mixed[] $meta */
public function setMeta(array $meta): FeedItemResponse
{
$this->meta = $meta;
diff --git a/src/TwitterFeed.php b/src/TwitterFeed.php
index d299b83..4a3e6f6 100644
--- a/src/TwitterFeed.php
+++ b/src/TwitterFeed.php
@@ -1,8 +1,10 @@
getFeedPlatform() . $this->userId;
}
- protected function getFeed($count = 5)
+ protected function getRawFeed(int $count = 5)
{
- $countKey = $this->getCacheKey() . $count;
-
try {
- if (null !== $this->cacheProvider &&
- $this->cacheProvider->contains($countKey)) {
- return $this->cacheProvider->fetch($countKey);
- }
- $body = $this->twitterConnection->get("statuses/user_timeline", [
- "user_id" => $this->userId,
- "count" => $count,
- "exclude_replies" => $this->excludeReplies,
- 'include_rts' => $this->includeRts,
- 'tweet_mode' => ($this->extended ? 'extended' : '')
+ $body = $this->twitterConnection->get('statuses/user_timeline', [
+ 'user_id' => $this->userId,
+ 'count' => $count,
+ 'exclude_replies' => $this->excludeReplies,
+ 'include_rts' => $this->includeRts,
+ 'tweet_mode' => ($this->extended ? 'extended' : ''),
]);
- if (null !== $this->cacheProvider) {
- $this->cacheProvider->save(
- $countKey,
- $body,
- $this->ttl
- );
- }
+
return $body;
} catch (TwitterOAuthException $e) {
throw new FeedProviderErrorException($this->getFeedPlatform(), $e->getMessage(), $e);
diff --git a/src/TwitterSearchFeed.php b/src/TwitterSearchFeed.php
index fabe06b..f3ba405 100644
--- a/src/TwitterSearchFeed.php
+++ b/src/TwitterSearchFeed.php
@@ -1,8 +1,9 @@
queryParams = array_filter($queryParams);
+ $this->queryParams = \array_filter($queryParams);
$this->extended = $extended;
}
protected function getCacheKey(): string
{
- return $this->getFeedPlatform() . md5(serialize($this->queryParams));
+ return $this->getFeedPlatform() . \md5(\serialize($this->queryParams));
}
- /**
- * @return string
- */
- protected function formatQueryParams()
+ protected function formatQueryParams(): string
{
$inlineParams = [];
foreach ($this->queryParams as $key => $value) {
- if (is_numeric($key)) {
+ if (\is_numeric($key)) {
$inlineParams[] = $value;
} else {
$inlineParams[] = $key . ':' . $value;
}
}
- return implode(' ', $inlineParams);
+ return \implode(' ', $inlineParams);
}
- protected function getFeed($count = 5)
+ protected function getRawFeed(int $count = 5)
{
- $countKey = $this->getCacheKey() . $count;
-
try {
- if (null !== $this->cacheProvider &&
- $this->cacheProvider->contains($countKey)) {
- return $this->cacheProvider->fetch($countKey);
- }
-
- if ($this->includeRetweets === false) {
+ if (false === $this->includeRetweets) {
$this->queryParams['-filter'] = 'retweets';
}
$params = [
- "q" => $this->formatQueryParams(),
- "count" => $count,
- "result_type" => $this->resultType,
+ 'q' => $this->formatQueryParams(),
+ 'count' => $count,
+ 'result_type' => $this->resultType,
];
if ($this->extended) {
$params['tweet_mode'] = 'extended';
}
/** @var object $body */
- $body = $this->twitterConnection->get("search/tweets", $params);
-
- if (null !== $this->cacheProvider) {
- $this->cacheProvider->save(
- $countKey,
- $body->statuses,
- $this->ttl
- );
- }
- return $body->statuses;
+ $body = $this->twitterConnection->get('search/tweets', $params);
+
+ return isset($body->statuses) ? $body->statuses : [];
} catch (TwitterOAuthException $e) {
throw new FeedProviderErrorException($this->getFeedPlatform(), $e->getMessage(), $e);
}
}
- /**
- * @return bool
- */
- public function isIncludeRetweets()
+ public function isIncludeRetweets(): bool
{
return $this->includeRetweets;
}
/**
- * @param bool $includeRetweets
* @return TwitterSearchFeed
*/
- public function setIncludeRetweets($includeRetweets)
+ public function setIncludeRetweets(bool $includeRetweets): AbstractFeedProvider
{
$this->includeRetweets = $includeRetweets;
+
return $this;
}
- /**
- * @return string
- */
- public function getResultType()
+ public function getResultType(): string
{
return $this->resultType;
}
@@ -158,12 +115,12 @@ public function getResultType()
* recent : return only the most recent results in the response
* popular : return only the most popular results in the response.
*
- * @param string $resultType
* @return TwitterSearchFeed
*/
- public function setResultType($resultType)
+ public function setResultType(string $resultType): AbstractFeedProvider
{
$this->resultType = $resultType;
+
return $this;
}
}
diff --git a/src/YoutubeMostPopularFeed.php b/src/YoutubeMostPopularFeed.php
index 68ae182..84d7bab 100644
--- a/src/YoutubeMostPopularFeed.php
+++ b/src/YoutubeMostPopularFeed.php
@@ -1,6 +1,8 @@
getFeedPlatform() . serialize($this->apiKey);
+ return $this->getFeedPlatform() . \serialize($this->apiKey);
}
- /**
- * @param int $count
- *
- * @return \Generator
- */
- public function getRequests($count = 5): \Generator
+ public function getRequests(int $count = 5): Generator
{
- $value = http_build_query([
- 'part' => 'snippet,contentDetails',
- 'key' => $this->apiKey,
- 'chart' => 'mostPopular',
- 'maxResults' => $count
+ $value = \http_build_query([
+ 'part' => 'snippet,contentDetails',
+ 'key' => $this->apiKey,
+ 'chart' => 'mostPopular',
+ 'maxResults' => $count,
]);
- yield new Request(
- 'GET',
- 'https://www.googleapis.com/youtube/v3/videos?'.$value
- );
+
+ yield new Request('GET', 'https://www.googleapis.com/youtube/v3/videos?' . $value);
}
- /**
- * {@inheritdoc}
- */
- public function getFeedPlatform()
+ public function getFeedPlatform(): string
{
return 'youtube_video';
}
diff --git a/src/YoutubePlaylistItemFeed.php b/src/YoutubePlaylistItemFeed.php
index 843f76c..0e19a66 100644
--- a/src/YoutubePlaylistItemFeed.php
+++ b/src/YoutubePlaylistItemFeed.php
@@ -1,12 +1,13 @@
getFeedPlatform() . serialize($this->playlistId);
+ return $this->getFeedPlatform() . \serialize($this->playlistId);
}
- /**
- * @param int $count
- *
- * @return \Generator
- */
- public function getRequests($count = 5): \Generator
+ public function getRequests(int $count = 5): Generator
{
- $value = http_build_query([
- 'part' => 'snippet,contentDetails',
- 'key' => $this->apiKey,
+ $value = \http_build_query([
+ 'part' => 'snippet,contentDetails',
+ 'key' => $this->apiKey,
'playlistId' => $this->playlistId,
'maxResults' => $count,
]);
yield new Request(
'GET',
- 'https://www.googleapis.com/youtube/v3/playlistItems?'.$value
+ 'https://www.googleapis.com/youtube/v3/playlistItems?' . $value
);
}
/**
* {@inheritdoc}
*/
- public function getFeedPlatform()
+ public function getFeedPlatform(): string
{
return 'youtube_playlist_items';
}
@@ -64,7 +56,7 @@ public function getFeedPlatform()
/**
* @inheritDoc
*/
- protected function createFeedItemFromObject($item): FeedItem
+ protected function createFeedItemFromObject(stdClass $item): FeedItem
{
$feedItem = parent::createFeedItemFromObject($item);
$feedItem->setId($item->snippet->resourceId->videoId);
diff --git a/web/dev.php b/web/dev.php
index c1fe5ee..cb3cabb 100644
--- a/web/dev.php
+++ b/web/dev.php
@@ -1,4 +1,5 @@
loadEnv(dirname(__DIR__) . '/.env');
+(new Dotenv())->usePutenv()->loadEnv(dirname(__DIR__).'/.env');
try {
$sw = new Stopwatch();
@@ -28,13 +29,13 @@
$feedItems = $feed->getAsyncCanonicalItems((int) getenv('MF_FEED_LENGTH'));
$event = $sw->stop('fetch');
$feedItemResponse = new FeedItemResponse($feedItems, [
- 'time' => $event->getDuration(),
+ 'time' => $event->getDuration(),
'memory' => $event->getMemory(),
- 'count' => count($feedItems),
+ 'count' => count($feedItems),
]);
echo $serializer->serialize($feedItemResponse, 'json');
} catch (\RuntimeException $exception) {
- header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
+ header($_SERVER['SERVER_PROTOCOL'].' 500 Internal Server Error', true, 500);
echo json_encode([
'message' => $exception->getMessage(),
]);
diff --git a/web/index.php b/web/index.php
index 4224465..4517166 100644
--- a/web/index.php
+++ b/web/index.php
@@ -1,4 +1,5 @@
loadEnv(dirname(__DIR__) . '/.env');
+(new Dotenv())->usePutenv()->loadEnv(dirname(__DIR__).'/.env');
try {
$sw = new Stopwatch();
@@ -29,12 +30,12 @@
$feedItems = $feed->getAsyncCanonicalItems((int) getenv('MF_FEED_LENGTH'));
$event = $sw->stop('fetch');
$feedItemResponse = new FeedItemResponse($feedItems, [
- 'time' => $event->getDuration(),
+ 'time' => $event->getDuration(),
'count' => count($feedItems),
]);
echo $serializer->serialize($feedItemResponse, 'json');
} catch (\RuntimeException $exception) {
- header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500);
+ header($_SERVER['SERVER_PROTOCOL'].' 500 Internal Server Error', true, 500);
echo json_encode([
'message' => $exception->getMessage(),
]);
diff --git a/web/test.sample.php b/web/test.sample.php
index fc4d75f..2c38a3e 100644
--- a/web/test.sample.php
+++ b/web/test.sample.php
@@ -1,20 +1,19 @@
getAsyncCanonicalItems(20);
$event = $sw->stop('fetch');
$feedItemResponse = new FeedItemResponse($feedItems, [
- 'time' => $event->getDuration(),
+ 'time' => $event->getDuration(),
'memory' => $event->getMemory(),
]);
$jsonContent = $serializer->serialize($feedItemResponse, 'json');