Skip to content

Commit

Permalink
New: Add ReplaceIframes component
Browse files Browse the repository at this point in the history
  • Loading branch information
jonnitto committed Mar 17, 2023
1 parent 7634d35 commit fbfd3c9
Show file tree
Hide file tree
Showing 4 changed files with 210 additions and 13 deletions.
128 changes: 128 additions & 0 deletions Classes/FusionObjects/ReplaceIframesImplementation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?php

namespace Jonnitto\PrettyEmbedVideoPlatforms\FusionObjects;

use Jonnitto\PrettyEmbedHelper\Service\ApiService;
use Jonnitto\PrettyEmbedHelper\Service\ParseIDService;
use Jonnitto\PrettyEmbedHelper\Service\YoutubeService;
use Jonnitto\PrettyEmbedHelper\Utility\Utility;
use Neos\Flow\Annotations as Flow;
use Neos\Fusion\FusionObjects\AbstractFusionObject;
use function strpos;
use function preg_match_all;
use function str_replace;

/**
* Replace embeded iframes with the video
*/
class ReplaceIframesImplementation extends AbstractFusionObject
{
/**
* @Flow\Inject
* @var YoutubeService
*/
protected $youtubeService;

/**
* @return string
*/
public function getContent(): string
{
return (string) $this->fusionValue('content');
}

/**
* @return string
*/
public function getOrigin(): string
{
return (string) $this->fusionValue('origin');
}

/**
* Render Replace embeded iframes with the pretty embeded markup
*
* @return string
*/
public function evaluate(): string
{
$content = $this->getContent();

if (!strpos($content, '<iframe') && (!strpos($content, 'https://www.youtube.com/embed') || !strpos($content, 'https://www.youtube-nocookie.com/embed') || !strpos($content, 'https://player.vimeo.com/video'))) {
return $content;
}

preg_match_all('/<iframe[^>]*?src=\"(https:\/\/www\.youtube(?:-nocookie)?\.com\/embed\/[^"]*)(?:(?!<\/iframe>).)+<\/iframe>/im', $content, $youtubeIframeMatcher, PREG_SET_ORDER);
preg_match_all('/<iframe[^>]*?src=\"(https:\/\/player\.vimeo\.com\/video\/[^"]*)(?:(?!<\/iframe>).)+<\/iframe>/im', $content, $vimeoIframeMatcher, PREG_SET_ORDER);
$parseID = new ParseIDService();

foreach ($youtubeIframeMatcher as $array) {
$iframe = $array[0] ?? null;
$url = $array[1] ?? null;
if (!$iframe || !$url) {
continue;
}
$videoID = $parseID->youtube($url);
if (!$videoID) {
continue;
}
$type = $this->youtubeService->type($url);
$replacement = $this->buildYoutube($videoID, $type);
$content = str_replace($iframe, $replacement, $content);
}

foreach ($vimeoIframeMatcher as $array) {
$iframe = $array[0] ?? null;
$url = $array[1] ?? null;
if (!$iframe || !$url) {
continue;
}
$videoID = $parseID->vimeo($url);
if (!$videoID) {
continue;
}
$replacement = $this->buildVimeo($videoID);
$content = str_replace($iframe, $replacement, $content);
}

return $content;
}

protected function buildYoutube(string $videoID, string $type): string
{
$data = $this->youtubeService->getBestPossibleYoutubeImage($videoID);
$poster = null;
if (isset($data)) {
$utility = new Utility();
$poster = $utility->removeProtocolFromUrl($data['image'] ?? null);
}
$this->runtime->pushContextArray([
'videoID' => $videoID,
'type' => $type,
'poster' => $poster,
'origin' => $this->getOrigin(),
]);
$html = $this->runtime->render($this->path . '/itemYoutubeRenderer');
$this->runtime->popContext();
return $html;
}

protected function buildVimeo(string $videoID): string
{
$api = new ApiService();
$data = $api->vimeo($videoID);
$poster = null;
if (isset($data)) {
$utility = new Utility();
$poster = $utility->removeProtocolFromUrl($data['thumbnail_url'] ?? null);
}

$this->runtime->pushContextArray([
'videoID' => $videoID,
'poster' => $poster
]);
$html = $this->runtime->render($this->path . '/itemVimeoRenderer');
$this->runtime->popContext();
return $html;
}
}
56 changes: 44 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ Prettier embeds for your Vimeo videos and YouTube videos/playlists in [Neos CMS]

| Version | Neos | Maintained |
| ------- | ----------- | :--------: |
| 1.\* | 4.2.\*, > 5 ||
| 2.\* | >= 5.3 ||
| 1.\* | 4.2.\*, > 5 ||
| 2.\* | >= 5.3 ||
| 3.\* | >= 5.3 ||

## Installation

Expand Down Expand Up @@ -53,18 +54,18 @@ Jonnitto:
enableJsApi: true
```
or, if you want to use the youtube-nocookie.com domain you can also edit the entries in your `Settings.yaml` file like this:
per default, the youtube-nocookie.com domain is used for embedding YouTube videos.
```yaml
Jonnitto:
PrettyEmbedVideoPlatforms:
youtube:
playlist:
embed: 'https://www.youtube-nocookie.com/embed/videoseries?list=%id%'
href: 'https://www.youtube-nocookie.com/playlist?list=%id%'
href: 'https://www.youtube.com/playlist?list=%id%'
video:
embed: 'https://www.youtube-nocookie.com/embed/%id%'
href: 'https://www.youtube-nocookie.com/watch?v=%id%'
href: 'https://www.youtube.com/watch?v=%id%'
```
Be aware that you need to provide the placeholder for the ID (`%id%`) of the playlist or video.
Expand Down Expand Up @@ -131,12 +132,8 @@ If you use SCCS in your build pipeline, you can adjust the look and feel of [`Ma
```scss
// Buttons (play / pause)
$prettyembed-button-play-size: 72px !default;
$prettyembed-button-pause-size: round(
$prettyembed-button-play-size / 2
) !default;
$prettyembed-button-pause-margin: round(
$prettyembed-button-pause-size / 2
) !default;
$prettyembed-button-pause-size: calc($prettyembed-button-play-size / 2) !default;
$prettyembed-button-pause-margin: calc($prettyembed-button-pause-size / 2) !default;
$prettyembed-button-opacity: 0.9 !default;
$prettyembed-button-scale: 0.8 !default;
$prettyembed-button-scale-hover: 1 !default;
Expand All @@ -157,6 +154,39 @@ $prettyembed-lightbox-close-size: 30px !default;
$prettyembed-lightbox-close-opacity: 0.65 !default;
$prettyembed-lightbox-close-opacity-hover: 1 !default;
$prettyembed-lightbox-close-color: #fff !default;
$prettyembed-lightbox-backdrop-filter: blur(5px) !default;
// GDPR Message
$prettyembed-gdpr-include: true !default;
$prettyembed-gdpr-color: #fff !default;
$prettyembed-gdpr-font-size-breakpoint: 640px !default;
$prettyembed-gdpr-font-size-mobile: 0.8rem !default;
$prettyembed-gdpr-font-size: 1rem !default;
$prettyembed-gdpr-gap: 1em !default;
$prettyembed-gdpr-padding: 0.5em !default;
$prettyembed-gdpr-explantation-font-size: 0.9em !default;
$prettyembed-gdpr-explantation-max-width: 60ch !default;
$prettyembed-gdpr-button-gap: 1em !default;
$prettyembed-gdpr-button-padding: 0.5em 1em !default;
$prettyembed-gdpr-button-border-radius: 0.25em !default;
$prettyembed-gdpr-button-accept-color: #fff !default;
$prettyembed-gdpr-button-accept-background-color: #16a34a !default;
$prettyembed-gdpr-button-accept-border: 1px solid #16a34a !default;
$prettyembed-gdpr-button-accept-color-hover: #fff !default;
$prettyembed-gdpr-button-accept-background-color-hover: #15803d !default;
$prettyembed-gdpr-button-accept-border-color-hover: #15803d !default;
$prettyembed-gdpr-button-external-color: #fff !default;
$prettyembed-gdpr-button-external-background-color: transparent !default;
$prettyembed-gdpr-button-external-border: 1px solid #fff !default;
$prettyembed-gdpr-button-external-color-hover: #000 !default;
$prettyembed-gdpr-button-external-background-color-hover: #fff !default;
$prettyembed-gdpr-button-external-border-color-hover: false !default;
$prettyembed-gdpr-backdrop-filter: blur(5px) !default;
$prettyembed-gdpr-overlay-color: #0b0b0b !default;
$prettyembed-gdpr-overlay-opacity: 0.8 !default;
```

Because all variables have the `!default` flag, the variables don't get overwritten if you declare
Expand Down Expand Up @@ -199,6 +229,8 @@ If you want to use the player as a pure component, you can use the [`Jonnitto.Pr

If you want to read the node properties and let the package handle all for you, you should use the [`Jonnitto.PrettyEmbedVideoPlatforms:Content.Video`] prototype. For more comfortable including in your node types, you can disable the content element wrapping with `contentElement = false`. This is useful if you want to create, for example, a text with a video node type.

If you want to parse an existing content with iframes and replace them automatically, you can add [`Jonnitto.PrettyEmbedVideoPlatforms:ReplaceIframes`] with an `@process` like that: `@process.replaceIframes = Jonnitto.PrettyEmbedVideoPlatforms:ReplaceIframes`. The `content` property is per default set to `${value}`.

## Get metadata

To get the metadata, you can run the flow command `./flow prettyembed:metadata`. This command search for nodes with the `VideoID` mixin, and tries to get the metadata. If for some reason, it is not possible to fetch the metadata (Perhaps the video is set to private, or the ID does not exist), you will get a table with the name of the node type, the type, the video ID and the node path.
Expand Down Expand Up @@ -245,7 +277,6 @@ If you install the PrettyEmbedCollection, the video players get grouped into an
[stargazers]: https://github.com/jonnitto/Jonnitto.PrettyEmbedVideoPlatforms/stargazers
[subscription]: https://github.com/jonnitto/Jonnitto.PrettyEmbedVideoPlatforms/subscription
[followers]: https://github.com/jonnitto/followers
[license]: LICENSE
[neos cms]: https://www.neos.io
[prettyembedcollection]: https://github.com/jonnitto/Jonnitto.PrettyembedCollection
[prettyembedvimeo]: https://github.com/jonnitto/Jonnitto.PrettyEmbedVimeo
Expand All @@ -257,5 +288,6 @@ If you install the PrettyEmbedCollection, the video players get grouped into an
[settings.jonnitto.yaml]: Configuration/Settings.Jonnitto.yaml
[`jonnitto.prettyembedvideoplatforms:component.video`]: Resources/Private/Fusion/Component/Video.fusion
[`jonnitto.prettyembedvideoplatforms:content.video`]: Resources/Private/Fusion/Content/Video.fusion
[`jonnitto.prettyembedvideoplatforms:replaceiframes`]: Resources/Private/Fusion/ReplaceIframes.fusion
[sitegeist.slipstream]: https://github.com/sitegeist/Sitegeist.Slipstream
[`main.scss`]: https://github.com/jonnitto/Jonnitto.PrettyEmbedHelper/blob/master/Resources/Private/Assets/Main.scss
37 changes: 37 additions & 0 deletions Resources/Private/Fusion/ReplaceIframes.fusion
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
prototype(Jonnitto.PrettyEmbedVideoPlatforms:ReplaceIframes) {
@class = 'Jonnitto\\PrettyEmbedVideoPlatforms\\FusionObjects\\ReplaceIframesImplementation'

// The content to parse
content = ${value}

origin = Neos.Neos:NodeUri {
node = ${site}
absolute = true
@process.onlyTheDomain = ${String.pregMatch(value, '(https?:\/\/[^\/]+)')[0]}
}

// This property is used internally by `ReplaceIframesImplementation` to render each YouTube iframe.
// It can be modified to change behaviour for all rendered YouTube items.
itemYoutubeRenderer = Jonnitto.PrettyEmbedVideoPlatforms:Component.Video {
type = ${type}
videoID = ${videoID}
platform = 'youtube'
origin = ${origin}
poster = ${poster}

// Set this to replace the preview image
content = null
}

// This property is used internally by `ReplaceIframesImplementation` to render each Vimeo iframe.
// It can be modified to change behaviour for all rendered Vimeo items.
itemVimeoRenderer = Jonnitto.PrettyEmbedVideoPlatforms:Component.Video {
videoID = ${videoID}
type = 'video'
platform = 'vimeo'
poster = ${poster}

// Set this to replace the preview image
content = null
}
}
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
}
],
"require": {
"jonnitto/prettyembedhelper": "^4.2 || dev-master"
"jonnitto/prettyembedhelper": "^4.2.3 || dev-master"
},
"autoload": {
"psr-4": {
Expand Down

0 comments on commit fbfd3c9

Please sign in to comment.