diff --git a/TextformatterVideoEmbed.module b/TextformatterVideoEmbed.module index 43224d4..7ae4959 100644 --- a/TextformatterVideoEmbed.module +++ b/TextformatterVideoEmbed.module @@ -5,7 +5,7 @@ * * Looks for Youtube or Vimeo URLs and automatically converts them to embeds * - * Copyright (C) 2021 by Ryan Cramer + * Copyright (C) 2021 by Ryan Cramer * Licensed under MPL 2.0 * https://processwire.com * @@ -20,7 +20,14 @@ * @property string $aspectRatio * @property int $failAction * @property int|bool $noCookies - * + * @property int|bool $getConsent + * @property string $consentInfo + * @property string $consentButtonLabel + * @property string $consentPrivacyUrl + * @property int $consentPrivacyPage + * @property string $consentCheckboxesLabel + * @property string $consentPrivacyLabel + * * @method array getAspectRatios() * @method array getVideoSizes() * @method string wrapEmbedCode($embedCode, array $data) @@ -32,13 +39,13 @@ class TextformatterVideoEmbed extends Textformatter implements ConfigurableModul public static function getModuleInfo() { return array( - 'title' => 'Video embed for YouTube (and Vimeo)', - 'version' => 202, - 'summary' => 'Enter a full YouTube (or Vimeo) URL by itself in any paragraph (example: https://youtu.be/Wl4XiYadV_k) and this will automatically convert it to an embedded video. This formatter is intended to be run on trusted input. Recommended for use with CKEditor textarea fields.', + 'title' => 'Video embed for YouTube (and Vimeo)', + 'version' => 202, + 'summary' => 'Enter a full YouTube (or Vimeo) URL by itself in any paragraph (example: https://youtu.be/Wl4XiYadV_k) and this will automatically convert it to an embedded video. This formatter is intended to be run on trusted input. Recommended for use with CKEditor textarea fields.', 'author' => 'Ryan Cramer', 'href' => 'https://processwire.com/modules/textformatter-video-embed/', 'requires' => 'ProcessWire>=3.0.148', - ); + ); } const dbTableName = 'textformatter_video_embed'; @@ -46,26 +53,33 @@ class TextformatterVideoEmbed extends Textformatter implements ConfigurableModul /** * Default configuration values - * + * * @var array - * + * */ protected $configDefaults = array( 'maxSize' => '720p', 'wrapStyles' => 'position:relative;margin:1em 0;padding-bottom:{pct}%;height:0;overflow:hidden;', - 'frameStyles' => 'position:absolute;top:0;left:0;width:100%;height:100%;', - 'refreshDays' => 0, + 'frameStyles' => 'position:absolute;top:0;left:0;width:100%;height:100%;', + 'refreshDays' => 0, 'lastMaint' => 0, - 'failAction' => 0, + 'failAction' => 0, 'aspectRatio' => '0', - 'noCookies' => 0, + 'noCookies' => 0, + 'getConsent' => 0, + 'consentInfo' => '(i) Click on this will load data from an external video service:', + 'consentButtonLabel' => 'Fine, lets load this video!', + 'consentPrivacyUrl' => '', + 'consentPrivacyPage' => 0, + 'consentCheckboxesLabel' => 'Remember my decision for ', + 'consentPrivacyLabel' => 'See: %1$s' ); /** * Verbose embed data defaults - * + * * @var array - * + * */ protected $verboseDataDefaults = array( 'valid' => false, @@ -81,22 +95,22 @@ class TextformatterVideoEmbed extends Textformatter implements ConfigurableModul 'thumbnail_height' => '', 'thumbnail_width' => '', 'thumbnail_url' => '', - 'embed_code' => '', - 'video_url' => '', + 'embed_code' => '', + 'video_url' => '', 'page_id' => 0, 'field' => '', ); /** * Video sizes - * + * * @var array - * + * */ protected $videoSizes = array( '240p' => array( - 'width' => 426, - 'height' => 240, + 'width' => 426, + 'height' => 240, 'label' => 'Minimum YouTube size' ), '360p' => array( @@ -139,23 +153,23 @@ class TextformatterVideoEmbed extends Textformatter implements ConfigurableModul /** * Last used HTTP GET URL - * + * * @var string - * + * */ protected $lastHttpGetVideoID = ''; /** * Last Page passed to format() - * + * * @var int - * + * */ protected $lastPageId = 0; /** * Name of last Field passed to format() - * + * * @var string * */ @@ -168,18 +182,18 @@ class TextformatterVideoEmbed extends Textformatter implements ConfigurableModul public function __construct() { parent::__construct(); foreach($this->configDefaults as $key => $value) { - $this->set($key, $value); + $this->set($key, $value); } } /** * Run daily maintenance - * + * * @return bool|int Return false if not yet time to run, int with quantity of deleted items when run - * + * */ protected function maintenance() { - + if($this->refreshDays < 1) return false; if($this->lastMaint >= (time() - 86400)) return false; @@ -190,74 +204,74 @@ class TextformatterVideoEmbed extends Textformatter implements ConfigurableModul $rowCount = $query->rowCount(); $this->lastMaint = time(); $this->wire()->modules->saveConfig($this, 'lastMaint', $this->lastMaint); - if($rowCount) $this->log("$rowCount videos older than $this->refreshDays days cleared for maintenance"); - + if($rowCount) $this->log("$rowCount videos older than $this->refreshDays days cleared for maintenance"); + return $rowCount; } - + /** * Given a service oembed URL and video ID, return the corresponding embed code. * - * A cached version of the embed code will be used if possible. When not possible, - * it will be retrieved from the service's oembed URL, and then cached. - * + * A cached version of the embed code will be used if possible. When not possible, + * it will be retrieved from the service's oembed URL, and then cached. + * * @param string $oembedURL * @param string $videoID * @param string $videoURL - * @param bool $verbose Get verbose array of data rather than just embed code? + * @param bool $verbose Get verbose array of data rather than just embed code? * @return string|int|array Returns embed code (string) or HTTP error code (int) * */ protected function getEmbedCode($oembedURL, $videoID, $videoURL, $verbose = true) { - + $this->maintenance(); - + $database = $this->wire()->database; $table = self::dbTableName; $data = array(); - + $query = $database->prepare("SELECT * FROM $table WHERE video_id=:video_id"); $query->bindValue(":video_id", $videoID); $query->execute(); - + if($query->rowCount()) { - $row = $query->fetch(\PDO::FETCH_ASSOC); + $row = $query->fetch(\PDO::FETCH_ASSOC); $data = empty($row['data']) ? array() : json_decode($row['data'], true); $data = is_array($data) ? array_merge($this->verboseDataDefaults, $data) : $this->verboseDataDefaults; $data['created'] = $row['created']; $data['embed_code'] = ctype_digit($row['embed_code']) ? (int) $row['embed_code'] : $row['embed_code']; $data['valid'] = is_string($data['embed_code']); } - + $query->closeCursor(); if(empty($data)) { - $data = $this->getNewEmbedCode($oembedURL, $videoID, $videoURL, $verbose); + $data = $this->getNewEmbedCode($oembedURL, $videoID, $videoURL, $verbose); } - return $data; + return $data; } /** * Get new embed code now from HTTP - * + * * @param string $oembedURL * @param string $videoID * @param string $videoURL * @param bool $verbose * @return array|int|string * @throws WireException - * + * */ protected function getNewEmbedCode($oembedURL, $videoID, $videoURL, $verbose = true) { - + $database = $this->wire()->database; $table = self::dbTableName; $httpErrorCode = 0; $maxTries = 3; $retry = 0; $oembedURL = $this->oembedURL($oembedURL, $videoURL, $videoID); - + $http = new WireHttp(); $this->wire($http); $this->lastHttpGetVideoID = $videoID; @@ -295,7 +309,7 @@ class TextformatterVideoEmbed extends Textformatter implements ConfigurableModul $data['valid'] = false; $embedCode = $httpErrorCode; } - + do { try { $sql = "INSERT INTO $table SET video_id=:videoID, embed_code=:embedCode, created=NOW(), data=:data"; @@ -317,22 +331,22 @@ class TextformatterVideoEmbed extends Textformatter implements ConfigurableModul } else { $this->log("Retrieved embed for: $videoURL"); } - + if($verbose) { $data['embed_code'] = $embedCode; } - + return $verbose ? $data : $embedCode; } /** * Apply replacements and additions to oembed URL - * + * * @param $oembedURL * @param $videoURL * @param $videoID * @return string - * + * */ protected function oembedURL($oembedURL, $videoURL, $videoID) { $oembedURL = str_replace( @@ -353,19 +367,19 @@ class TextformatterVideoEmbed extends Textformatter implements ConfigurableModul /** * Wrap video embed code with responsive div - * + * * @param string $embedCode * @param array $data * @return string * */ protected function ___wrapEmbedCode($embedCode, array $data) { - + $sanitizer = $this->wire()->sanitizer; $frameStyles = $sanitizer->entities($this->frameStyles); $wrapStyles = $sanitizer->entities($this->wrapStyles); $pct = $this->aspectRatio === '0' ? 0 : (float) $this->aspectRatio; - + if($pct === 0) { // auto aspect ratio if(!empty($data['height']) && !empty($data['width'])) { @@ -375,22 +389,104 @@ class TextformatterVideoEmbed extends Textformatter implements ConfigurableModul $pct = '56.25'; // 16:9 } } - + if($frameStyles) { $frameStyles = str_replace(array('{pct}%', '{pct}', '{percent}%', '{percent}'), "$pct%", $frameStyles); $embedCode = str_ireplace('