1

I'm using the Apple News plugin to try and display a tweet that's been added as a JSON asset in a matrix field. The JSON looks something like this

{
    "title": "https://twitter.com/TehseenLadha/status/1291773476877959169",
    "description": null,
    "url": "https://twitter.com/TehseenLadha/status/1291773476877959169",
    ...
}

According to the Apple News Publisher docs, all you need is the tweet's URL. I'm trying to get it by converting the JSON file to a string with file_get_contents and then using json_decode, but it's not working. This is what I have in MyNewsArticle.php:

case 'tweet':
  $asset = $block->tweet->one()->getUrl();
  $string = file_get_contents($asset);
  $jsonArr = json_decode($string, true);
  $tweetUrl = $jsonArr['url'];

  if ($tweetUrl) {
    $components[] = [
      'role' => 'tweet',
      'layout' => 'tweetLayout',
      'URL' => $tweetUrl,
    ];
  }
break;

It's grabbing the correct URL of the asset, but fails with failed to open stream: Operation timed out on the $string = file_get_contents($asset); line. Apparently this is something to do with IPv4 vs IPv6? I'm not certain how to get around it though.

1
  • I’m voting to close this question because it isn't Craft specific. Stack Overflow might be a better place to ask. Oct 13 '20 at 6:16
2
+50

I assume that $block->tweet->one() returns an Asset element in your matrix block called tweet. I suggest that you use the getContents() method on Craft's Asset element type to retrieve the string content of the actual file. Your code block would look something like this:

case 'tweet':
  $tweetFileContent = $block->tweet->one()->getContents();
  $tweetJson = json_decode($tweetFileContent, true);
  $tweetUrl = $tweetJson['url'];

  if ($tweetUrl) {
    $components[] = [
      'role' => 'tweet',
      'layout' => 'tweetLayout',
      'URL' => $tweetUrl,
    ];
  }
break;

However, I would recommend extending your code as follows to address empty state and potential exception:

case 'tweet':
  if (empty($block->tweet)) {
    // return early or do something else
  }
  try {
    $tweetFileContent = $block->tweet->one()->getContents();
    $tweetJson = json_decode($tweetFileContent, true);
    $tweetUrl = $tweetJson['url'];

    if ($tweetUrl) {
      $components[] = [
        'role' => 'tweet',
        'layout' => 'tweetLayout',
        'URL' => $tweetUrl,
      ];
    }
  } catch ($e) {
    // getContents() throws 
    // InvalidConfigException if [[volumeId]] is missing or invalid,
    // AssetException if a stream could not be created
  }
break;
1
  • This did it! Thanks so much 🙌
    – Bryce
    Oct 19 '20 at 17:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.