Initial commit
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\TagViewHelperTrait;
|
||||
|
||||
/**
|
||||
* Base class for media related tag based view helpers which mostly
|
||||
* adds HTML5 tag attributes.
|
||||
*
|
||||
* @author Björn Fromme <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media
|
||||
*/
|
||||
abstract class AbstractMediaTagViewHelper extends AbstractMediaViewHelper {
|
||||
|
||||
use TagViewHelperTrait;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
|
||||
|
||||
/**
|
||||
* Base class for media related view helpers
|
||||
*
|
||||
* @author Björn Fromme <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media
|
||||
*/
|
||||
abstract class AbstractMediaViewHelper extends AbstractTagBasedViewHelper {
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $mediaSource;
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerArgument('src', 'mixed', 'Path to the media resource(s). Can contain single or multiple paths for videos/audio (either CSV, array or implementing Traversable).', TRUE);
|
||||
$this->registerArgument('relative', 'boolean', 'If FALSE media URIs are rendered absolute. URIs in backend mode are always absolute.', FALSE, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns a relative source URI into an absolute URL
|
||||
* if required
|
||||
*
|
||||
* @param string $src
|
||||
* @return string
|
||||
*/
|
||||
public function preprocessSourceUri($src) {
|
||||
$src = $GLOBALS['TSFE']->absRefPrefix . GeneralUtility::rawUrlEncodeFP($src);
|
||||
if (FALSE === empty($GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_vhs.']['settings.']['prependPath'])) {
|
||||
$src = $GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_vhs.']['settings.']['prependPath'] . $src;
|
||||
} elseif ('BE' === TYPO3_MODE || FALSE === (boolean) $this->arguments['relative']) {
|
||||
$src = GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . ltrim($src, '/');
|
||||
}
|
||||
return $src;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of sources resolved from src argument
|
||||
* which can be either an array, CSV or implement Traversable
|
||||
* to be consumed by ViewHelpers handling multiple sources.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getSourcesFromArgument() {
|
||||
$src = $this->arguments['src'];
|
||||
if ($src instanceof \Traversable) {
|
||||
$src = iterator_to_array($src);
|
||||
} elseif (TRUE === is_string($src)) {
|
||||
$src = GeneralUtility::trimExplode(',', $src, TRUE);
|
||||
}
|
||||
return $src;
|
||||
}
|
||||
|
||||
}
|
||||
146
typo3conf/ext/vhs/Classes/ViewHelpers/Media/AudioViewHelper.php
Normal file
146
typo3conf/ext/vhs/Classes/ViewHelpers/Media/AudioViewHelper.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\TagViewHelperTrait;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
|
||||
|
||||
/**
|
||||
* Renders HTML code to embed a HTML5 audio player. NOTICE: This is
|
||||
* all HTML5 and won't work on browsers like IE8 and below. Include
|
||||
* some helper library like kolber.github.io/audiojs/ if you need to suport those.
|
||||
* Source can be a single file, a CSV of files or an array of arrays
|
||||
* with multiple sources for different audio formats. In the latter
|
||||
* case provide array keys 'src' and 'type'. Providing an array of
|
||||
* sources (even for a single source) is preferred as you can set
|
||||
* the correct mime type of the audio which is otherwise guessed
|
||||
* from the filename's extension.
|
||||
*
|
||||
* @author Xaver Maierhofer <xaver.maierhofer@xwissen.info>
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media
|
||||
*/
|
||||
class AudioViewHelper extends AbstractMediaViewHelper {
|
||||
|
||||
use TagViewHelperTrait;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tagName = 'audio';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $validTypes = array('mp3', 'ogg', 'oga', 'wav');
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $mimeTypesMap = array('mp3' => 'audio/mpeg', 'ogg' => 'audio/ogg', 'oga' => 'audio/ogg', 'wav' => 'audio/wav');
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $validPreloadModes = array('auto', 'metadata', 'none');
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
parent::initializeArguments();
|
||||
$this->registerUniversalTagAttributes();
|
||||
$this->registerArgument('width', 'integer', 'Sets the width of the audio player in pixels.', TRUE);
|
||||
$this->registerArgument('height', 'integer', 'Sets the height of the audio player in pixels.', TRUE);
|
||||
$this->registerArgument('autoplay', 'boolean', 'Specifies that the audio will start playing as soon as it is ready.', FALSE, FALSE);
|
||||
$this->registerArgument('controls', 'boolean', 'Specifies that audio controls should be displayed (such as a play/pause button etc).', FALSE, FALSE);
|
||||
$this->registerArgument('loop', 'boolean', 'Specifies that the audio will start over again, every time it is finished.', FALSE, FALSE);
|
||||
$this->registerArgument('muted', 'boolean', 'Specifies that the audio output of the audio should be muted.', FALSE, FALSE);
|
||||
$this->registerArgument('poster', 'string', 'Specifies an image to be shown while the audio is downloading, or until the user hits the play button.', FALSE, NULL);
|
||||
$this->registerArgument('preload', 'string', 'Specifies if and how the author thinks the audio should be loaded when the page loads. Can be "auto", "metadata" or "none".', FALSE, 'auto');
|
||||
$this->registerArgument('unsupported', 'string', 'Add a message for old browsers like Internet Explorer 9 without audio support.', FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @throws Exception
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
$sources = $this->getSourcesFromArgument();
|
||||
if (0 === count($sources)) {
|
||||
throw new Exception('No audio sources provided.', 1359382189);
|
||||
}
|
||||
|
||||
foreach ($sources as $source) {
|
||||
if (TRUE === is_string($source)) {
|
||||
if (FALSE !== strpos($source, '//')) {
|
||||
$src = $source;
|
||||
$type = substr($source, strrpos($source, '.') + 1);
|
||||
} else {
|
||||
$src = substr(GeneralUtility::getFileAbsFileName($source), strlen(PATH_site));
|
||||
$type = pathinfo($src, PATHINFO_EXTENSION);
|
||||
}
|
||||
} elseif (TRUE === is_array($source)) {
|
||||
if (FALSE === isset($source['src'])) {
|
||||
throw new Exception('Missing value for "src" in sources array.', 1359381250);
|
||||
}
|
||||
$src = $source['src'];
|
||||
if (FALSE === isset($source['type'])) {
|
||||
throw new Exception('Missing value for "type" in sources array.', 1359381255);
|
||||
}
|
||||
$type = $source['type'];
|
||||
} else {
|
||||
// skip invalid source
|
||||
continue;
|
||||
}
|
||||
$type = strtolower($type);
|
||||
if (FALSE === in_array($type, $this->validTypes)) {
|
||||
throw new Exception('Invalid audio type "' . $type . '".', 1359381260);
|
||||
}
|
||||
$type = $this->mimeTypesMap[$type];
|
||||
$src = $this->preprocessSourceUri($src);
|
||||
$this->renderChildTag('source', array('src' => $src, 'type' => $type), FALSE, 'append');
|
||||
}
|
||||
$tagAttributes = array(
|
||||
'width' => $this->arguments['width'],
|
||||
'height' => $this->arguments['height'],
|
||||
'preload' => 'auto',
|
||||
);
|
||||
if (TRUE === (boolean) $this->arguments['autoplay']) {
|
||||
$tagAttributes['autoplay'] = 'autoplay';
|
||||
}
|
||||
if (TRUE === (boolean) $this->arguments['controls']) {
|
||||
$tagAttributes['controls'] = 'controls';
|
||||
}
|
||||
if (TRUE === (boolean) $this->arguments['loop']) {
|
||||
$tagAttributes['loop'] = 'loop';
|
||||
}
|
||||
if (TRUE === (boolean) $this->arguments['muted']) {
|
||||
$tagAttributes['muted'] = 'muted';
|
||||
}
|
||||
if (TRUE === in_array($this->arguments['preload'], $this->validPreloadModes)) {
|
||||
$tagAttributes['preload'] = 'preload';
|
||||
}
|
||||
if (NULL !== $this->arguments['poster']) {
|
||||
$tagAttributes['poster'] = $this->arguments['poster'];
|
||||
}
|
||||
$this->tag->addAttributes($tagAttributes);
|
||||
if (NULL !== $this->arguments['unsupported']) {
|
||||
$this->tag->setContent($this->tag->getContent() . LF . $this->arguments['unsupported']);
|
||||
}
|
||||
return $this->tag->render();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* File/Directory Exists Condition ViewHelper
|
||||
*
|
||||
* @author Claus Due <claus@namelesscoder.net>
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media
|
||||
*/
|
||||
class ExistsViewHelper extends AbstractConditionViewHelper {
|
||||
|
||||
/**
|
||||
* Initialize arguments
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('file', 'string', 'Filename which must exist to trigger f:then rendering', FALSE);
|
||||
$this->registerArgument('directory', 'string', 'Directory which must exist to trigger f:then rendering', FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
|
||||
$evaluation = static::evaluateCondition($this->arguments);
|
||||
|
||||
if (FALSE !== $evaluation) {
|
||||
return $this->renderThenChild();
|
||||
}
|
||||
return $this->renderElseChild();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method decides if the condition is TRUE or FALSE. It can be overriden in extending viewhelpers to adjust functionality.
|
||||
*
|
||||
* @param array $arguments ViewHelper arguments to evaluate the condition for this ViewHelper, allows for flexiblity in overriding this method.
|
||||
* @return bool
|
||||
*/
|
||||
static protected function evaluateCondition($arguments = NULL) {
|
||||
$file = GeneralUtility::getFileAbsFileName($arguments['file']);
|
||||
$directory = $arguments['directory'];
|
||||
$evaluation = FALSE;
|
||||
if (TRUE === isset($arguments['file'])) {
|
||||
$evaluation = (boolean) ((TRUE === file_exists($file) || TRUE === file_exists(constant('PATH_site') . $file)) && TRUE === is_file($file));
|
||||
} elseif (TRUE === isset($arguments['directory'])) {
|
||||
$evaluation = (boolean) (TRUE === is_dir($directory) || TRUE === is_dir(constant('PATH_site') . $directory));
|
||||
}
|
||||
return $evaluation;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* Returns the extension of the provided file
|
||||
*
|
||||
* @author Björn Fromme <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media
|
||||
*/
|
||||
class ExtensionViewHelper extends AbstractViewHelper {
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerArgument('file', 'string', 'Path to the file to determine extension for.', FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
|
||||
$filePath = $this->arguments['file'];
|
||||
|
||||
if (TRUE === empty($filePath)) {
|
||||
$filePath = $this->renderChildren();
|
||||
|
||||
if (NULL === $filePath) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
$file = GeneralUtility::getFileAbsFileName($filePath);
|
||||
|
||||
$parts = explode('.', basename($file));
|
||||
|
||||
// file has no extension
|
||||
if (1 === count($parts)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$extension = strtolower(array_pop($parts));
|
||||
|
||||
return $extension;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
|
||||
/**
|
||||
* Returns an array of files found in the provided path
|
||||
*
|
||||
* @author Björn Fromme <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media
|
||||
*/
|
||||
class FilesViewHelper extends AbstractViewHelper {
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerArgument('path', 'string', 'Path to the folder containing the files to be listed.', TRUE);
|
||||
$this->registerArgument('extensionList', 'string', 'A comma seperated list of file extensions to pick up.', FALSE, '');
|
||||
$this->registerArgument('prependPath', 'boolean', 'If set to TRUE the path will be prepended to file names.', FALSE, FALSE);
|
||||
$this->registerArgument('order', 'string', 'If set to "mtime" sorts files by modification time or alphabetically otherwise.', FALSE, '');
|
||||
$this->registerArgument('excludePattern', 'string', 'A comma seperated list of filenames to exclude, no wildcards.', FALSE, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function render() {
|
||||
$path = $this->arguments['path'];
|
||||
|
||||
if (NULL === $path) {
|
||||
$path = $this->renderChildren();
|
||||
if (NULL === $path) {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
$extensionList = $this->arguments['extensionList'];
|
||||
$prependPath = $this->arguments['prependPath'];
|
||||
$order = $this->arguments['order'];
|
||||
$excludePattern = $this->arguments['excludePattern'];
|
||||
|
||||
$files = GeneralUtility::getFilesInDir($path, $extensionList, $prependPath, $order, $excludePattern);
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
|
||||
|
||||
/**
|
||||
* Renders Gravatar <img/> tag
|
||||
*
|
||||
* @author Juan Manuel Vergés Solanas <juanmanuel@vergessolanas.es>
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media
|
||||
*/
|
||||
class GravatarViewHelper extends AbstractTagBasedViewHelper {
|
||||
|
||||
/**
|
||||
* Base url
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const GRAVATAR_BASEURL = 'http://www.gravatar.com/avatar/';
|
||||
|
||||
/**
|
||||
* Base secure url
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const GRAVATAR_SECURE_BASEURL = 'https://secure.gravatar.com/avatar/';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tagName = 'img';
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
* Size argument has no default value to prevent the creation of an unnecessary URI parameter.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
parent::initializeArguments();
|
||||
$this->registerUniversalTagAttributes();
|
||||
$this->registerArgument('email', 'string', 'Email address', TRUE);
|
||||
$this->registerArgument('size', 'integer', 'Size in pixels, defaults to 80px [ 1 - 2048 ]', FALSE);
|
||||
$this->registerArgument('imageSet', 'string', 'Default image set to use. Possible values [ 404 | mm | identicon | monsterid | wavatar ] ', FALSE);
|
||||
$this->registerArgument('maximumRating', 'string', 'Maximum rating (inclusive) [ g | pg | r | x ]', FALSE);
|
||||
$this->registerArgument('secure', 'boolean', 'If it is FALSE will return the un secure Gravatar domain (www.gravatar.com)', FALSE, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
$email = $this->arguments['email'];
|
||||
$size = $this->checkArgument('size');
|
||||
$imageSet = $this->checkArgument('imageSet');
|
||||
$maximumRating = $this->checkArgument('maximumRating');
|
||||
$secure = (boolean) $this->arguments['secure'];
|
||||
|
||||
$url = (TRUE === $secure ? self::GRAVATAR_SECURE_BASEURL : self::GRAVATAR_BASEURL);
|
||||
$url .= md5(strtolower(trim($email)));
|
||||
$query = http_build_query(array('s' => $size, 'd' => $imageSet, 'r' => $maximumRating));
|
||||
$url .= (FALSE === empty($query) ? '?' . $query : '');
|
||||
$this->tag->addAttribute('src', $url);
|
||||
$this->tag->forceClosingTag(TRUE);
|
||||
|
||||
return $this->tag->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an argument is passed
|
||||
*
|
||||
* @param $argument
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function checkArgument($argument) {
|
||||
return TRUE === isset($this->arguments[$argument]) ? $this->arguments[$argument] : NULL;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media\Image;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Utility\ResourceUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
|
||||
|
||||
/**
|
||||
* Base class: Media\Image view helpers
|
||||
*
|
||||
* @author Björn Fromme <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media\Image
|
||||
*/
|
||||
abstract class AbstractImageInfoViewHelper extends AbstractViewHelper {
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Core\Resource\ResourceFactory
|
||||
*/
|
||||
protected $resourceFactory;
|
||||
|
||||
/**
|
||||
* Construct resource factory
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->resourceFactory = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\ResourceFactory');
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerArgument('src', 'string', 'Path to or id of the image file to determine info for.', TRUE);
|
||||
$this->registerArgument('treatIdAsUid', 'boolean', 'If TRUE, the path argument is treated as a resource uid.', FALSE, FALSE);
|
||||
$this->registerArgument('treatIdAsReference', 'boolean', 'If TRUE, the path argument is treated as a reference uid and will be resolved to a resource via sys_file_reference.', FALSE, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
* @return array
|
||||
*/
|
||||
public function getInfo() {
|
||||
$src = $this->arguments['src'];
|
||||
$treatIdAsUid = (boolean) $this->arguments['treatIdAsUid'];
|
||||
$treatIdAsReference = (boolean) $this->arguments['treatIdAsReference'];
|
||||
|
||||
if (NULL === $src) {
|
||||
$src = $this->renderChildren();
|
||||
if (NULL === $src) {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
if (TRUE === $treatIdAsUid || TRUE === $treatIdAsReference) {
|
||||
$id = (integer) $src;
|
||||
$info = array();
|
||||
if (TRUE === $treatIdAsUid) {
|
||||
$info = $this->getInfoByUid($id);
|
||||
} elseif (TRUE === $treatIdAsReference) {
|
||||
$info = $this->getInfoByReference($id);
|
||||
}
|
||||
} else {
|
||||
$file = GeneralUtility::getFileAbsFileName($src);
|
||||
if (FALSE === file_exists($file) || TRUE === is_dir($file)) {
|
||||
throw new Exception('Cannot determine info for "' . $file . '". File does not exist or is a directory.', 1357066532);
|
||||
}
|
||||
$imageSize = getimagesize($file);
|
||||
$info = array(
|
||||
'width' => $imageSize[0],
|
||||
'height' => $imageSize[1],
|
||||
'type' => $imageSize['mime'],
|
||||
);
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $id
|
||||
* @return array
|
||||
*/
|
||||
public function getInfoByReference($id) {
|
||||
$fileReference = $this->resourceFactory->getFileReferenceObject($id);
|
||||
$file = $fileReference->getOriginalFile();
|
||||
return ResourceUtility::getFileArray($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $uid
|
||||
* @return array
|
||||
*/
|
||||
public function getInfoByUid($uid) {
|
||||
$file = $this->resourceFactory->getFileObject($uid);
|
||||
return ResourceUtility::getFileArray($file);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media\Image;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\ViewHelpers\Media\AbstractMediaViewHelper;
|
||||
use TYPO3\CMS\Core\Imaging\GraphicalFunctions;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\MathUtility;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
|
||||
|
||||
/**
|
||||
* Base class for image related view helpers adapted from FLUID
|
||||
* original image viewhelper.
|
||||
*
|
||||
* @author Björn Fromme <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media
|
||||
*/
|
||||
abstract class AbstractImageViewHelper extends AbstractMediaViewHelper {
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController contains a backup of the current $GLOBALS['TSFE'] if used in BE mode
|
||||
*/
|
||||
protected $tsfeBackup;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $workingDirectoryBackup;
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
|
||||
*/
|
||||
protected $contentObject;
|
||||
|
||||
/**
|
||||
* @var ConfigurationManagerInterface
|
||||
*/
|
||||
protected $configurationManager;
|
||||
|
||||
/**
|
||||
* Result of \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::getImgResource()
|
||||
* @var array
|
||||
*/
|
||||
protected $imageInfo;
|
||||
|
||||
/**
|
||||
* @param ConfigurationManagerInterface $configurationManager
|
||||
* @return void
|
||||
*/
|
||||
public function injectConfigurationManager(ConfigurationManagerInterface $configurationManager) {
|
||||
$this->configurationManager = $configurationManager;
|
||||
$this->contentObject = $this->configurationManager->getContentObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('width', 'string', 'Width of the image. This can be a numeric value representing the fixed width of the image in pixels. But you can also perform simple calculations by adding "m" or "c" to the value. See imgResource.width for possible options.', FALSE);
|
||||
$this->registerArgument('height', 'string', 'Height of the image. This can be a numeric value representing the fixed height of the image in pixels. But you can also perform simple calculations by adding "m" or "c" to the value. See imgResource.width for possible options.', FALSE);
|
||||
$this->registerArgument('maxW', 'integer', 'Maximum Width of the image. (no upscaling)', FALSE);
|
||||
$this->registerArgument('maxH', 'integer', 'Maximum Height of the image. (no upscaling)', FALSE);
|
||||
$this->registerArgument('minW', 'integer', 'Minimum Width of the image.', FALSE);
|
||||
$this->registerArgument('minH', 'integer', 'Minimum Height of the image.', FALSE);
|
||||
$this->registerArgument('format', 'string', 'Format of the processed file - also determines the target file format. If blank, TYPO3/IM/GM default is taken into account.', FALSE, NULL);
|
||||
$this->registerArgument('quality', 'integer', 'Quality of the processed image. If blank/not present falls back to the default quality defined in install tool.', FALSE, NULL);
|
||||
$this->registerArgument('treatIdAsReference', 'boolean', 'When TRUE treat given src argument as sys_file_reference record. Applies only to TYPO3 6.x and above.', FALSE, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function preprocessImage() {
|
||||
$src = $this->arguments['src'];
|
||||
$width = $this->arguments['width'];
|
||||
$height = $this->arguments['height'];
|
||||
$minW = $this->arguments['minW'];
|
||||
$minH = $this->arguments['minH'];
|
||||
$maxW = $this->arguments['maxW'];
|
||||
$maxH = $this->arguments['maxH'];
|
||||
$format = $this->arguments['format'];
|
||||
$quality = $this->arguments['quality'];
|
||||
$treatIdAsReference = (boolean) $this->arguments['treatIdAsReference'];
|
||||
|
||||
if ('BE' === TYPO3_MODE) {
|
||||
$this->simulateFrontendEnvironment();
|
||||
}
|
||||
$setup = array(
|
||||
'width' => $width,
|
||||
'height' => $height,
|
||||
'minW' => $minW,
|
||||
'minH' => $minH,
|
||||
'maxW' => $maxW,
|
||||
'maxH' => $maxH,
|
||||
'treatIdAsReference' => $treatIdAsReference,
|
||||
);
|
||||
if (FALSE === empty($format)) {
|
||||
$setup['ext'] = $format;
|
||||
}
|
||||
if (0 < intval($quality)) {
|
||||
$quality = MathUtility::forceIntegerInRange($quality, 10, 100, 75);
|
||||
$setup['params'] = '-quality ' . $quality;
|
||||
}
|
||||
if ('BE' === TYPO3_MODE && '../' === substr($src, 0, 3)) {
|
||||
$src = substr($src, 3);
|
||||
}
|
||||
$this->imageInfo = $this->contentObject->getImgResource($src, $setup);
|
||||
$GLOBALS['TSFE']->lastImageInfo = $this->imageInfo;
|
||||
if (FALSE === is_array($this->imageInfo)) {
|
||||
throw new Exception('Could not get image resource for "' . htmlspecialchars($src) . '".', 1253191060);
|
||||
}
|
||||
if ((float) substr(TYPO3_version, 0, 3) < 7.1) {
|
||||
$this->imageInfo[3] = GeneralUtility::png_to_gif_by_imagemagick($this->imageInfo[3]);
|
||||
} else {
|
||||
$this->imageInfo[3] = GraphicalFunctions::pngToGifByImagemagick($this->imageInfo[3]);
|
||||
}
|
||||
$GLOBALS['TSFE']->imagesOnPage[] = $this->imageInfo[3];
|
||||
$publicUrl = rawurldecode($this->imageInfo[3]);
|
||||
$this->mediaSource = GeneralUtility::rawUrlEncodeFP($publicUrl);
|
||||
if ('BE' === TYPO3_MODE) {
|
||||
$this->resetFrontendEnvironment();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares $GLOBALS['TSFE'] for Backend mode
|
||||
* This somewhat hacky work around is currently needed because the
|
||||
* getImgResource() function of \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
|
||||
* relies on those variables to be set
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function simulateFrontendEnvironment() {
|
||||
$this->tsfeBackup = TRUE === isset($GLOBALS['TSFE']) ? $GLOBALS['TSFE'] : NULL;
|
||||
$this->workingDirectoryBackup = getcwd();
|
||||
chdir(constant('PATH_site'));
|
||||
$typoScriptSetup = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT);
|
||||
$GLOBALS['TSFE'] = new \stdClass();
|
||||
$template = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\TypoScript\\TemplateService');
|
||||
$template->tt_track = 0;
|
||||
$template->init();
|
||||
$template->getFileName_backPath = constant('PATH_site');
|
||||
$GLOBALS['TSFE']->tmpl = $template;
|
||||
$GLOBALS['TSFE']->tmpl->setup = $typoScriptSetup;
|
||||
$GLOBALS['TSFE']->config = $typoScriptSetup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets $GLOBALS['TSFE'] if it was previously changed
|
||||
* by simulateFrontendEnvironment()
|
||||
*
|
||||
* @return void
|
||||
* @see simulateFrontendEnvironment()
|
||||
*/
|
||||
protected function resetFrontendEnvironment() {
|
||||
$GLOBALS['TSFE'] = $this->tsfeBackup;
|
||||
chdir($this->workingDirectoryBackup);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media\Image;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the height of the provided image file in pixels
|
||||
*
|
||||
* @author Björn Fromme <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media\Image
|
||||
*/
|
||||
class HeightViewHelper extends AbstractImageInfoViewHelper {
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function render() {
|
||||
$info = $this->getInfo();
|
||||
return (TRUE === isset($info['height']) ? $info['height'] : 0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media\Image;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the mimetype of the provided image file
|
||||
*
|
||||
* @author Björn Fromme <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media\Image
|
||||
*/
|
||||
class MimetypeViewHelper extends AbstractImageInfoViewHelper {
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
$info = $this->getInfo();
|
||||
return TRUE === isset($info['type']) ? $info['type'] : '';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media\Image;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the width of the provided image file in pixels
|
||||
*
|
||||
* @author Björn Fromme <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media\Image
|
||||
*/
|
||||
class WidthViewHelper extends AbstractImageInfoViewHelper {
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function render() {
|
||||
$info = $this->getInfo();
|
||||
return TRUE === isset($info['width']) ? $info['width'] : 0;
|
||||
}
|
||||
|
||||
}
|
||||
101
typo3conf/ext/vhs/Classes/ViewHelpers/Media/ImageViewHelper.php
Normal file
101
typo3conf/ext/vhs/Classes/ViewHelpers/Media/ImageViewHelper.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\ViewHelpers\Media\Image\AbstractImageViewHelper;
|
||||
use FluidTYPO3\Vhs\Traits\SourceSetViewHelperTrait;
|
||||
|
||||
/**
|
||||
* Renders an image tag for the given resource including all valid
|
||||
* HTML5 attributes. Derivates of the original image are rendered
|
||||
* if the provided (optional) dimensions differ.
|
||||
*
|
||||
* ## rendering responsive Images variants
|
||||
*
|
||||
* You can use the srcset argument to generate several differently sized
|
||||
* versions of this image that will be added as a srcset argument to the img tag.
|
||||
* enter a list of widths in the srcset to genereate copies of the same crop +
|
||||
* ratio but in the specified widths. Put the width at the start that you want
|
||||
* to use as a fallback to be shown when no srcset functionality is supported.
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* <v:media.image src="fileadmin/some-image.png" srcset="480,768,992,1200" />
|
||||
*
|
||||
* ### Browser Support
|
||||
*
|
||||
* To have the widest Browser-Support you should consider using a polyfill like:
|
||||
* http://scottjehl.github.io/picturefill/
|
||||
*
|
||||
* @author Björn Fromme <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media
|
||||
*/
|
||||
class ImageViewHelper extends AbstractImageViewHelper {
|
||||
|
||||
use SourceSetViewHelperTrait;
|
||||
|
||||
/**
|
||||
* name of the tag to be created by this view helper
|
||||
*
|
||||
* @var string
|
||||
* @api
|
||||
*/
|
||||
protected $tagName = 'img';
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
parent::initializeArguments();
|
||||
$this->registerUniversalTagAttributes();
|
||||
$this->registerTagAttribute('usemap', 'string', 'A hash-name reference to a map element with which to associate the image.', FALSE);
|
||||
$this->registerTagAttribute('ismap', 'string', 'Specifies that its img element provides access to a server-side image map.', FALSE, '');
|
||||
$this->registerTagAttribute('alt', 'string', 'Equivalent content for those who cannot process images or who have image loading disabled.', TRUE);
|
||||
$this->registerArgument('srcset', 'mixed', 'List of width used for the srcset variants (either CSV, array or implementing Traversable)', FALSE, NULL);
|
||||
$this->registerArgument('srcsetDefault', 'integer', 'Default width to use as a fallback for browsers that don\'t support srcset', FALSE, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
$this->preprocessImage();
|
||||
|
||||
if (FALSE === empty($this->arguments['srcset'])) {
|
||||
$srcSetVariants = $this->addSourceSet($this->tag, $this->mediaSource);
|
||||
}
|
||||
|
||||
if (FALSE === empty($srcSetVariants) && FALSE === empty($this->arguments['srcsetDefault'])) {
|
||||
$srcSetVariantDefault = $srcSetVariants[$this->arguments['srcsetDefault']];
|
||||
$src = $srcSetVariantDefault['src'];
|
||||
$width = $srcSetVariantDefault['width'];
|
||||
$height = $srcSetVariantDefault['height'];
|
||||
} else {
|
||||
$src = $this->preprocessSourceUri($this->mediaSource);
|
||||
$width = $this->imageInfo[0];
|
||||
$height = $this->imageInfo[1];
|
||||
}
|
||||
|
||||
$this->tag->addAttribute('width', $width);
|
||||
$this->tag->addAttribute('height', $height);
|
||||
$this->tag->addAttribute('src', $src);
|
||||
|
||||
if (TRUE === empty($this->arguments['title'])) {
|
||||
$this->tag->addAttribute('title', $this->arguments['alt']);
|
||||
}
|
||||
return $this->tag->render();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Utility\CommandUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Converts the provided PDF file into a PNG thumbnail and renders
|
||||
* the according image tag using Fluid's standard image ViewHelper
|
||||
* thus implementing its arguments. For PDF documents with multiple
|
||||
* pages the first page is rendered by default unless specified.
|
||||
*
|
||||
* @author Björn Fromme <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media
|
||||
*/
|
||||
class PdfThumbnailViewHelper extends ImageViewHelper {
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('path', 'string', 'Path to PDF source file');
|
||||
$this->registerArgument('minWidth', 'integer', 'Minimum width of resulting thumbnail image', FALSE, NULL);
|
||||
$this->registerArgument('minHeight', 'integer', 'Minimum height of resulting thumbnail image', FALSE, NULL);
|
||||
$this->registerArgument('maxWidth', 'integer', 'Maximum width of resulting thumbnail image', FALSE, NULL);
|
||||
$this->registerArgument('maxHeight', 'integer', 'Maximum height of resulting thumbnail image', FALSE, NULL);
|
||||
$this->registerArgument('density', 'integer', 'Canvas resolution for rendering the PDF in dpi (higher means better quality)', FALSE, 100);
|
||||
$this->registerArgument('background', 'string', 'Fill background of resulting image with this color (for transparent source files)', FALSE, NULL);
|
||||
$this->registerArgument('rotate', 'integer', 'Number of degress to rotate resulting image by (caution: very slow if not multiple of 90)', FALSE, 0);
|
||||
$this->registerArgument('page', 'integer', 'Optional page number to render as thumbnail for PDF documents with multiple pages', FALSE, 1);
|
||||
$this->registerArgument('forceOverwrite', 'boolean', 'Forcibly overwrite existing converted PDF files', FALSE, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
$path = GeneralUtility::getFileAbsFileName($this->arguments['path']);
|
||||
if (FALSE === file_exists($path)) {
|
||||
return NULL;
|
||||
}
|
||||
$density = $this->arguments['density'];
|
||||
$rotate = $this->arguments['rotate'];
|
||||
$page = intval($this->arguments['page']);
|
||||
$background = $this->arguments['background'];
|
||||
$forceOverwrite = (boolean) $this->arguments['forceOverwrite'];
|
||||
$width = $this->arguments['width'];
|
||||
$height = $this->arguments['height'];
|
||||
$minWidth = $this->arguments['minWidth'];
|
||||
$minHeight = $this->arguments['minHeight'];
|
||||
$maxWidth = $this->arguments['maxWidth'];
|
||||
$maxHeight = $this->arguments['maxHeight'];
|
||||
$filename = basename($path);
|
||||
$pageArgument = $page > 0 ? $page - 1 : 0;
|
||||
$colorspace = TRUE === isset($GLOBALS['TYPO3_CONF_VARS']['GFX']['colorspace']) ? $GLOBALS['TYPO3_CONF_VARS']['GFX']['colorspace'] : 'RGB';
|
||||
$destination = GeneralUtility::getFileAbsFileName('typo3temp/vhs-pdf-' . $filename . '-page' . $page . '.png');
|
||||
if (FALSE === file_exists($destination) || TRUE === $forceOverwrite) {
|
||||
$arguments = '-colorspace ' . $colorspace;
|
||||
if (0 < intval($density)) {
|
||||
$arguments .= ' -density ' . $density;
|
||||
}
|
||||
if (0 !== intval($rotate)) {
|
||||
$arguments .= ' -rotate ' . $rotate;
|
||||
}
|
||||
$arguments .= ' "' . $path . '"[' . $pageArgument . ']';
|
||||
if (NULL !== $background) {
|
||||
$arguments .= ' -background "' . $background . '" -flatten';
|
||||
}
|
||||
$arguments .= ' "' . $destination . '"';
|
||||
$command = CommandUtility::imageMagickCommand('convert', $arguments);
|
||||
CommandUtility::exec($command);
|
||||
}
|
||||
$image = substr($destination, strlen(PATH_site));
|
||||
return parent::render($image, $width, $height, $minWidth, $minHeight, $maxWidth, $maxHeight);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\TagBuilder;
|
||||
|
||||
/**
|
||||
* Renders a picture element with different images/sources for specific
|
||||
* media breakpoints
|
||||
*
|
||||
* ### Example
|
||||
*
|
||||
* <v:media.picture src="fileadmin/some-image.png" alt="Some Image">
|
||||
* <v:media.source media="(min-width: 1200px)" width="500c" height="500c" />
|
||||
* <v:media.source media="(min-width: 992px)" width="300c" height="300c" />
|
||||
* <v:media.source media="(min-width: 768px)" width="200c" height="200c" />
|
||||
* <v:media.source width="80c" height="80c" />
|
||||
* </v:media.picture>
|
||||
*
|
||||
* ### Browser Support
|
||||
*
|
||||
* To have the widest Browser-Support you should consider using a polyfill like:
|
||||
* http://scottjehl.github.io/picturefill/
|
||||
*
|
||||
* @author Marc Neuhaus <mneuhaus@famelo.com>, famelo
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media
|
||||
*/
|
||||
class PictureViewHelper extends AbstractTagBasedViewHelper {
|
||||
const SCOPE = 'FluidTYPO3\Vhs\ViewHelpers\Media\PictureViewHelper';
|
||||
const SCOPE_VARIABLE_SRC = 'src';
|
||||
const SCOPE_VARIABLE_DEFAULT_SOURCE = 'default-source';
|
||||
|
||||
/**
|
||||
* name of the tag to be created by this view helper
|
||||
*
|
||||
* @var string
|
||||
* @api
|
||||
*/
|
||||
protected $tagName = 'picture';
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('src', 'string', 'Path to the image.', TRUE);
|
||||
$this->registerArgument('alt', 'string', 'Text for the alt tag.', TRUE);
|
||||
$this->registerArgument('title', 'string', 'Text for the alt tag.', FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function render() {
|
||||
$src = $this->arguments['src'];
|
||||
|
||||
$this->viewHelperVariableContainer->addOrUpdate(self::SCOPE, self::SCOPE_VARIABLE_SRC, $src);
|
||||
$content = $this->renderChildren();
|
||||
$this->viewHelperVariableContainer->remove(self::SCOPE, self::SCOPE_VARIABLE_SRC);
|
||||
|
||||
if (FALSE === $this->viewHelperVariableContainer->exists(self::SCOPE, self::SCOPE_VARIABLE_DEFAULT_SOURCE)) {
|
||||
throw new Exception('Please add a source without a media query as a default.', 1438116616);
|
||||
}
|
||||
$defaultSource = $this->viewHelperVariableContainer->get(self::SCOPE, self::SCOPE_VARIABLE_DEFAULT_SOURCE);
|
||||
|
||||
$defaultImage = new TagBuilder('img');
|
||||
$defaultImage->addAttribute('src', $defaultSource);
|
||||
$defaultImage->addAttribute('alt', $this->arguments['alt']);
|
||||
|
||||
if (FALSE === empty($this->arguments['title'])) {
|
||||
$defaultImage->addAttribute('title', $this->arguments['alt']);
|
||||
}
|
||||
$content .= $defaultImage->render();
|
||||
|
||||
$this->tag->setContent($content);
|
||||
return $this->tag->render();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
|
||||
|
||||
/**
|
||||
* Returns the size of the provided file in bytes
|
||||
*
|
||||
* @author Björn Fromme <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media
|
||||
*/
|
||||
class SizeViewHelper extends AbstractViewHelper {
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerArgument('path', 'string', 'Path to the file to determine size for.', FALSE, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
* @return integer
|
||||
*/
|
||||
public function render() {
|
||||
|
||||
$path = $this->arguments['path'];
|
||||
|
||||
if (NULL === $path) {
|
||||
$path = $this->renderChildren();
|
||||
if (NULL === $path) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
$file = GeneralUtility::getFileAbsFileName($path);
|
||||
|
||||
if (FALSE === file_exists($file) || TRUE === is_dir($file)) {
|
||||
throw new Exception('Cannot determine size of "' . $file . '". File does not exist or is a directory.', 1356953963);
|
||||
}
|
||||
|
||||
$size = filesize($file);
|
||||
|
||||
if (FALSE === $size) {
|
||||
throw new Exception('Cannot determine size of "' . $file . '".', 1356954032);
|
||||
}
|
||||
|
||||
return $size;
|
||||
}
|
||||
|
||||
}
|
||||
147
typo3conf/ext/vhs/Classes/ViewHelpers/Media/SourceViewHelper.php
Normal file
147
typo3conf/ext/vhs/Classes/ViewHelpers/Media/SourceViewHelper.php
Normal file
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Utility\FrontendSimulationUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\MathUtility;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
|
||||
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
|
||||
|
||||
/**
|
||||
* Used in conjuntion with the `v:media.PictureViewHelper`.
|
||||
* Please take a look at the `v:media.PictureViewHelper` documentation for more
|
||||
* information.
|
||||
*
|
||||
* @author Marc Neuhaus <mneuhaus@famelo.com>, famelo
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media
|
||||
*/
|
||||
class SourceViewHelper extends AbstractTagBasedViewHelper {
|
||||
|
||||
const SCOPE = 'FluidTYPO3\Vhs\ViewHelpers\Media\PictureViewHelper';
|
||||
const SCOPE_VARIABLE_SRC = 'src';
|
||||
const SCOPE_VARIABLE_DEFAULT_SOURCE = 'default-source';
|
||||
|
||||
/**
|
||||
* name of the tag to be created by this view helper
|
||||
*
|
||||
* @var string
|
||||
* @api
|
||||
*/
|
||||
protected $tagName = 'source';
|
||||
|
||||
/**
|
||||
* @var ContentObjectRenderer
|
||||
*/
|
||||
protected $contentObject;
|
||||
|
||||
/**
|
||||
* @var ConfigurationManagerInterface
|
||||
*/
|
||||
protected $configurationManager;
|
||||
|
||||
/**
|
||||
* @param ConfigurationManagerInterface $configurationManager
|
||||
* @return void
|
||||
*/
|
||||
public function injectConfigurationManager(ConfigurationManagerInterface $configurationManager) {
|
||||
$this->configurationManager = $configurationManager;
|
||||
$this->contentObject = $this->configurationManager->getContentObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
parent::initializeArguments();
|
||||
$this->registerArgument('media', 'string', 'Media query for which breakpoint this sources applies', FALSE, NULL);
|
||||
$this->registerArgument('width', 'string', 'Width of the image. This can be a numeric value representing the fixed width of the image in pixels. But you can also perform simple calculations by adding "m" or "c" to the value. See imgResource.width for possible options.', FALSE);
|
||||
$this->registerArgument('height', 'string', 'Height of the image. This can be a numeric value representing the fixed height of the image in pixels. But you can also perform simple calculations by adding "m" or "c" to the value. See imgResource.width for possible options.', FALSE);
|
||||
$this->registerArgument('maxW', 'integer', 'Maximum Width of the image. (no upscaling)', FALSE);
|
||||
$this->registerArgument('maxH', 'integer', 'Maximum Height of the image. (no upscaling)', FALSE);
|
||||
$this->registerArgument('minW', 'integer', 'Minimum Width of the image.', FALSE);
|
||||
$this->registerArgument('minH', 'integer', 'Minimum Height of the image.', FALSE);
|
||||
$this->registerArgument('format', 'string', 'Format of the processed file - also determines the target file format. If blank, TYPO3/IM/GM default is taken into account.', FALSE, NULL);
|
||||
$this->registerArgument('quality', 'integer', 'Quality of the processed image. If blank/not present falls back to the default quality defined in install tool.', FALSE, NULL);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
$src = $this->viewHelperVariableContainer->get(self::SCOPE, self::SCOPE_VARIABLE_SRC);
|
||||
|
||||
if ('BE' === TYPO3_MODE) {
|
||||
$tsfeBackup = FrontendSimulationUtility::simulateFrontendEnvironment();
|
||||
}
|
||||
|
||||
$setup = array(
|
||||
'width' => $this->arguments['width'],
|
||||
'height' => $this->arguments['height'],
|
||||
'minW' => $this->arguments['minW'],
|
||||
'minH' => $this->arguments['minH'],
|
||||
'maxW' => $this->arguments['maxW'],
|
||||
'maxH' => $this->arguments['maxH']
|
||||
);
|
||||
$quality = $this->arguments['quality'];
|
||||
$format = $this->arguments['format'];
|
||||
|
||||
if (FALSE === empty($format)) {
|
||||
$setup['ext'] = $format;
|
||||
}
|
||||
if (0 < intval($quality)) {
|
||||
$quality = MathUtility::forceIntegerInRange($quality, 10, 100, 75);
|
||||
$setup['params'] .= ' -quality ' . $quality;
|
||||
}
|
||||
|
||||
if ('BE' === TYPO3_MODE && '../' === substr($src, 0, 3)) {
|
||||
$src = substr($src, 3);
|
||||
}
|
||||
$result = $this->contentObject->getImgResource($src, $setup);
|
||||
|
||||
if ('BE' === TYPO3_MODE) {
|
||||
FrontendSimulationUtility::resetFrontendEnvironment($tsfeBackup);
|
||||
}
|
||||
|
||||
$src = $this->preprocessSourceUri(rawurldecode($result[3]));
|
||||
|
||||
if (NULL === $this->arguments['media']) {
|
||||
$this->viewHelperVariableContainer->addOrUpdate(self::SCOPE, self::SCOPE_VARIABLE_DEFAULT_SOURCE, $src);
|
||||
} else {
|
||||
$this->tag->addAttribute('media', $this->arguments['media']);
|
||||
}
|
||||
|
||||
$this->tag->addAttribute('srcset', $src);
|
||||
return $this->tag->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns a relative source URI into an absolute URL
|
||||
* if required
|
||||
*
|
||||
* @param string $src
|
||||
* @return string
|
||||
*/
|
||||
public function preprocessSourceUri($src) {
|
||||
if (FALSE === empty($GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_vhs.']['settings.']['prependPath'])) {
|
||||
$src = $GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_vhs.']['settings.']['prependPath'] . $src;
|
||||
} elseif ('BE' === TYPO3_MODE || FALSE === (boolean) $this->arguments['relative']) {
|
||||
$src = GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . ltrim($src, '/');
|
||||
}
|
||||
return $src;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
|
||||
|
||||
/**
|
||||
* Renders HTML code to embed a Spotify play button
|
||||
*
|
||||
* @author Björn Fromme <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media
|
||||
*/
|
||||
class SpotifyViewHelper extends AbstractTagBasedViewHelper {
|
||||
|
||||
/**
|
||||
* Play button base url
|
||||
*/
|
||||
const SPOTIFY_BASEURL = 'https://embed.spotify.com/';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tagName = 'iframe';
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerArgument('spotifyUri', 'string', 'Spotify URI to create the play button for. Right click any song, album or playlist in Spotify and select Copy Spotify URI.', TRUE);
|
||||
$this->registerArgument('width', 'int', 'Width of the play button in pixels. Defaults to 300', FALSE, 300);
|
||||
$this->registerArgument('height', 'int', 'Height of the play button in pixels. Defaults to 380', FALSE, 380);
|
||||
$this->registerArgument('compact', 'boolean', 'Whether to render the compact button with a fixed height of 80px.', FALSE, FALSE);
|
||||
$this->registerArgument('theme', 'string', 'Theme to use. Can be "black" or "white" and is not available in compact mode. Defaults to "black".', FALSE, 'black');
|
||||
$this->registerArgument('view', 'string', 'View to use. Can be "list" or "coverart" and is not available in compact mode. Defaults to "list".', FALSE, 'list');
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
$spotifyUri = $this->arguments['spotifyUri'];
|
||||
$width = (integer) $this->arguments['width'];
|
||||
$height = (integer) $this->arguments['height'];
|
||||
|
||||
if (TRUE === in_array($this->arguments['theme'], array('black', 'white'))) {
|
||||
$theme = $this->arguments['theme'];
|
||||
} else {
|
||||
$theme = 'black';
|
||||
}
|
||||
|
||||
if (TRUE === in_array($this->arguments['view'], array('coverart', 'list'))) {
|
||||
$view = $this->arguments['view'];
|
||||
} else {
|
||||
$view = 'list';
|
||||
}
|
||||
|
||||
if (TRUE === (boolean) $this->arguments['compact']) {
|
||||
$height = 80;
|
||||
}
|
||||
|
||||
$src = self::SPOTIFY_BASEURL . '?uri=' . $spotifyUri . '&theme=' . $theme . '&view=' . $view;
|
||||
|
||||
$this->tag->forceClosingTag(TRUE);
|
||||
$this->tag->addAttribute('src', $src);
|
||||
$this->tag->addAttribute('width', $width);
|
||||
$this->tag->addAttribute('height', $height);
|
||||
$this->tag->addAttribute('allowtransparancy', 'true');
|
||||
$this->tag->addAttribute('frameborder', 0);
|
||||
|
||||
return $this->tag->render();
|
||||
}
|
||||
|
||||
}
|
||||
144
typo3conf/ext/vhs/Classes/ViewHelpers/Media/VideoViewHelper.php
Normal file
144
typo3conf/ext/vhs/Classes/ViewHelpers/Media/VideoViewHelper.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use FluidTYPO3\Vhs\Traits\TagViewHelperTrait;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\Exception;
|
||||
|
||||
/**
|
||||
* Renders HTML code to embed a HTML5 video player. NOTICE: This is
|
||||
* all HTML5 and won't work on browsers like IE8 and below. Include
|
||||
* some helper library like videojs.com if you need to suport those.
|
||||
* Source can be a single file, a CSV of files or an array of arrays
|
||||
* with multiple sources for different video formats. In the latter
|
||||
* case provide array keys 'src' and 'type'. Providing an array of
|
||||
* sources (even for a single source) is preferred as you can set
|
||||
* the correct mime type of the video which is otherwise guessed
|
||||
* from the filename's extension.
|
||||
*
|
||||
* @author Björn Fromme <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media
|
||||
*/
|
||||
class VideoViewHelper extends AbstractMediaViewHelper {
|
||||
|
||||
use TagViewHelperTrait;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tagName = 'video';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $validTypes = array('mp4', 'webm', 'ogg', 'ogv');
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $mimeTypesMap = array('mp4' => 'video/mp4', 'webm' => 'video/webm', 'ogg' => 'video/ogg', 'ogv' => 'video/ogg');
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $validPreloadModes = array('auto', 'metadata', 'none');
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
parent::initializeArguments();
|
||||
$this->registerUniversalTagAttributes();
|
||||
$this->registerArgument('width', 'integer', 'Sets the width of the video player in pixels.', TRUE);
|
||||
$this->registerArgument('height', 'integer', 'Sets the height of the video player in pixels.', TRUE);
|
||||
$this->registerArgument('autoplay', 'boolean', 'Specifies that the video will start playing as soon as it is ready.', FALSE, FALSE);
|
||||
$this->registerArgument('controls', 'boolean', 'Specifies that video controls should be displayed (such as a play/pause button etc).', FALSE, FALSE);
|
||||
$this->registerArgument('loop', 'boolean', 'Specifies that the video will start over again, every time it is finished.', FALSE, FALSE);
|
||||
$this->registerArgument('muted', 'boolean', 'Specifies that the audio output of the video should be muted.', FALSE, FALSE);
|
||||
$this->registerArgument('poster', 'string', 'Specifies an image to be shown while the video is downloading, or until the user hits the play button.', FALSE, NULL);
|
||||
$this->registerArgument('preload', 'string', 'Specifies if and how the author thinks the video should be loaded when the page loads. Can be "auto", "metadata" or "none".', FALSE, 'auto');
|
||||
$this->registerArgument('unsupported', 'string', 'Add a message for old browsers like Internet Explorer 9 without video support.', FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @throws Exception
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
$sources = $this->getSourcesFromArgument();
|
||||
if (0 === count($sources)) {
|
||||
throw new Exception('No video sources provided.', 1359382189);
|
||||
}
|
||||
foreach ($sources as $source) {
|
||||
if (TRUE === is_string($source)) {
|
||||
if (FALSE !== strpos($source, '//')) {
|
||||
$src = $source;
|
||||
$type = substr($source, strrpos($source, '.') + 1);
|
||||
} else {
|
||||
$src = substr(GeneralUtility::getFileAbsFileName($source), strlen(PATH_site));
|
||||
$type = pathinfo($src, PATHINFO_EXTENSION);
|
||||
}
|
||||
} elseif (TRUE === is_array($source)) {
|
||||
if (FALSE === isset($source['src'])) {
|
||||
throw new Exception('Missing value for "src" in sources array.', 1359381250);
|
||||
}
|
||||
$src = $source['src'];
|
||||
if (FALSE === isset($source['type'])) {
|
||||
throw new Exception('Missing value for "type" in sources array.', 1359381255);
|
||||
}
|
||||
$type = $source['type'];
|
||||
} else {
|
||||
// skip invalid source
|
||||
continue;
|
||||
}
|
||||
if (FALSE === in_array(strtolower($type), $this->validTypes)) {
|
||||
throw new Exception('Invalid video type "' . $type . '".', 1359381260);
|
||||
}
|
||||
$type = $this->mimeTypesMap[$type];
|
||||
$src = $this->preprocessSourceUri($src);
|
||||
$this->renderChildTag('source', array('src' => $src, 'type' => $type), FALSE, 'append');
|
||||
}
|
||||
$tagAttributes = array(
|
||||
'width' => $this->arguments['width'],
|
||||
'height' => $this->arguments['height'],
|
||||
'preload' => 'auto',
|
||||
);
|
||||
if (TRUE === (boolean) $this->arguments['autoplay']) {
|
||||
$tagAttributes['autoplay'] = 'autoplay';
|
||||
}
|
||||
if (TRUE === (boolean) $this->arguments['controls']) {
|
||||
$tagAttributes['controls'] = 'controls';
|
||||
}
|
||||
if (TRUE === (boolean) $this->arguments['loop']) {
|
||||
$tagAttributes['loop'] = 'loop';
|
||||
}
|
||||
if (TRUE === (boolean) $this->arguments['muted']) {
|
||||
$tagAttributes['muted'] = 'muted';
|
||||
}
|
||||
if (TRUE === in_array($this->arguments['preload'], $this->validPreloadModes)) {
|
||||
$tagAttributes['preload'] = 'preload';
|
||||
}
|
||||
if (NULL !== $this->arguments['poster']) {
|
||||
$tagAttributes['poster'] = $this->arguments['poster'];
|
||||
}
|
||||
$this->tag->addAttributes($tagAttributes);
|
||||
if (NULL !== $this->arguments['unsupported']) {
|
||||
$this->tag->setContent($this->tag->getContent() . LF . $this->arguments['unsupported']);
|
||||
}
|
||||
return $this->tag->render();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
|
||||
|
||||
/**
|
||||
* Renders HTML code to embed a video from Vimeo
|
||||
*
|
||||
* @author Björn Fromme <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media
|
||||
*/
|
||||
class VimeoViewHelper extends AbstractTagBasedViewHelper {
|
||||
|
||||
/**
|
||||
* Base URL for Vimeo video player
|
||||
*/
|
||||
const VIMEO_BASEURL = '//player.vimeo.com/video/';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tagName = 'iframe';
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerArgument('videoId', 'string', 'Vimeo ID of the video to embed.', TRUE);
|
||||
$this->registerArgument('width', 'integer', 'Width of the video in pixels. Defaults to 640 for 16:9 content.', FALSE, 640);
|
||||
$this->registerArgument('height', 'integer', 'Height of the video in pixels. Defaults to 360 for 16:9 content.', FALSE, 360);
|
||||
$this->registerArgument('title', 'boolean', 'Show the title on the video. Defaults to TRUE.', FALSE, TRUE);
|
||||
$this->registerArgument('byline', 'boolean', 'Show the user’s byline on the video. Defaults to TRUE.', FALSE, TRUE);
|
||||
$this->registerArgument('portrait', 'boolean', 'Show the user’s portrait on the video. Defaults to TRUE.', FALSE, TRUE);
|
||||
$this->registerArgument('color', 'string', 'Specify the color of the video controls. Defaults to 00adef. Make sure that you don’t include the #.', FALSE, '00adef');
|
||||
$this->registerArgument('autoplay', 'boolean', 'Play the video automatically on load. Defaults to FALSE. Note that this won’t work on some devices.', FALSE, FALSE);
|
||||
$this->registerArgument('loop', 'boolean', 'Play the video again when it reaches the end. Defaults to FALSE.', FALSE, FALSE);
|
||||
$this->registerArgument('api', 'boolean', 'Set to TRUE to enable the Javascript API.', FALSE, FALSE);
|
||||
$this->registerArgument('playerId', 'string', 'An unique id for the player that will be passed back with all Javascript API responses.', FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
$videoId = $this->arguments['videoId'];
|
||||
$width = $this->arguments['width'];
|
||||
$height = $this->arguments['height'];
|
||||
|
||||
$src = self::VIMEO_BASEURL . $videoId . '?';
|
||||
|
||||
$queryParams = array(
|
||||
'title=' . (integer) $this->arguments['title'],
|
||||
'byline=' . (integer) $this->arguments['byline'],
|
||||
'portrait=' . (integer) $this->arguments['portrait'],
|
||||
'color=' . str_replace('#', '', $this->arguments['color']),
|
||||
'autoplay=' . (integer) $this->arguments['autoplay'],
|
||||
'loop=' . (integer) $this->arguments['loop'],
|
||||
'api=' . (integer) $this->arguments['api'],
|
||||
'player_id=' . (integer) $this->arguments['playerId'],
|
||||
);
|
||||
|
||||
$src .= implode('&', $queryParams);
|
||||
|
||||
$this->tag->forceClosingTag(TRUE);
|
||||
$this->tag->addAttribute('src', $src);
|
||||
$this->tag->addAttribute('width', $width);
|
||||
$this->tag->addAttribute('height', $height);
|
||||
$this->tag->addAttribute('frameborder', 0);
|
||||
$this->tag->addAttribute('webkitAllowFullScreen', 'webkitAllowFullScreen');
|
||||
$this->tag->addAttribute('mozAllowFullScreen', 'mozAllowFullScreen');
|
||||
$this->tag->addAttribute('allowFullScreen', 'allowFullScreen');
|
||||
|
||||
return $this->tag->render();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
namespace FluidTYPO3\Vhs\ViewHelpers\Media;
|
||||
|
||||
/*
|
||||
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
|
||||
*
|
||||
* For the full copyright and license information, please read the
|
||||
* LICENSE.md file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
|
||||
|
||||
/**
|
||||
* Renders HTML code to embed a video from YouTube
|
||||
*
|
||||
* @author Björn Fromme <fromme@dreipunktnull.com>, dreipunktnull
|
||||
* @package Vhs
|
||||
* @subpackage ViewHelpers\Media
|
||||
*/
|
||||
class YoutubeViewHelper extends AbstractTagBasedViewHelper {
|
||||
|
||||
/**
|
||||
* Base url
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const YOUTUBE_BASEURL = '//www.youtube.com';
|
||||
|
||||
/**
|
||||
* Base url for extended privacy
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const YOUTUBE_PRIVACY_BASEURL = '//www.youtube-nocookie.com';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $tagName = 'iframe';
|
||||
|
||||
/**
|
||||
* Initialize arguments.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
public function initializeArguments() {
|
||||
$this->registerArgument('videoId', 'string', 'YouTube id of the video to embed.', TRUE);
|
||||
$this->registerArgument('width', 'integer', 'Width of the video in pixels. Defaults to 640 for 16:9 content.', FALSE, 640);
|
||||
$this->registerArgument('height', 'integer', 'Height of the video in pixels. Defaults to 385 for 16:9 content.', FALSE, 385);
|
||||
$this->registerArgument('autoplay', 'boolean', 'Play the video automatically on load. Defaults to FALSE.', FALSE, FALSE);
|
||||
$this->registerArgument('legacyCode', 'boolean', 'Whether to use the legacy flash video code.', FALSE, FALSE);
|
||||
$this->registerArgument('showRelated', 'boolean', 'Whether to show related videos after playing.', FALSE, FALSE);
|
||||
$this->registerArgument('extendedPrivacy', 'boolean', 'Whether to use cookie-less video player.', FALSE, TRUE);
|
||||
$this->registerArgument('hideControl', 'boolean', 'Hide video player\'s control bar.', FALSE, FALSE);
|
||||
$this->registerArgument('hideInfo', 'boolean', 'Hide video player\'s info bar.', FALSE, FALSE);
|
||||
$this->registerArgument('playlist', 'string', 'Comma seperated list of video IDs to be played.', FALSE);
|
||||
$this->registerArgument('loop', 'boolean', 'Play the video in a loop.', FALSE, FALSE);
|
||||
$this->registerArgument('start', 'integer', 'Start playing after seconds.', FALSE);
|
||||
$this->registerArgument('end', 'integer', 'Stop playing after seconds.', FALSE);
|
||||
$this->registerArgument('lightTheme', 'boolean', 'Use the YouTube player\'s light theme.', FALSE, FALSE);
|
||||
$this->registerArgument('videoQuality', 'string', 'Set the YouTube player\'s video quality (hd1080,hd720,highres,large,medium,small).', FALSE);
|
||||
$this->registerArgument('windowMode', 'string', 'Set the Window-Mode of the YouTube player (transparent,opaque). This is necessary for z-index handling in IE10/11.', FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
$videoId = $this->arguments['videoId'];
|
||||
$width = $this->arguments['width'];
|
||||
$height = $this->arguments['height'];
|
||||
|
||||
$this->tag->addAttribute('width', $width);
|
||||
$this->tag->addAttribute('height', $height);
|
||||
|
||||
$src = $this->getSourceUrl($videoId);
|
||||
|
||||
if (FALSE === (boolean) $this->arguments['legacyCode']) {
|
||||
$this->tag->addAttribute('src', $src);
|
||||
$this->tag->addAttribute('frameborder', 0);
|
||||
$this->tag->addAttribute('allowFullScreen', 'allowFullScreen');
|
||||
$this->tag->forceClosingTag(TRUE);
|
||||
} else {
|
||||
$this->tag->setTagName('object');
|
||||
|
||||
$tagContent = '';
|
||||
|
||||
$paramAttributes = array(
|
||||
'movie' => $src,
|
||||
'allowFullScreen' => 'true',
|
||||
'scriptAccess' => 'always',
|
||||
);
|
||||
foreach ($paramAttributes as $name => $value) {
|
||||
$tagContent .= $this->renderChildTag('param', array($name => $value), TRUE);
|
||||
}
|
||||
|
||||
$embedAttributes = array(
|
||||
'src' => $src,
|
||||
'type' => 'application/x-shockwave-flash',
|
||||
'width' => $width,
|
||||
'height' => $height,
|
||||
'allowFullScreen' => 'true',
|
||||
'scriptAccess' => 'always',
|
||||
);
|
||||
$tagContent .= $this->renderChildTag('embed', $embedAttributes, TRUE);
|
||||
|
||||
$this->tag->setContent($tagContent);
|
||||
}
|
||||
|
||||
return $this->tag->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns video source url according to provided arguments
|
||||
*
|
||||
* @param string $videoId
|
||||
* @return string
|
||||
*/
|
||||
private function getSourceUrl($videoId) {
|
||||
$src = (boolean) TRUE === $this->arguments['extendedPrivacy'] ? self::YOUTUBE_PRIVACY_BASEURL : self::YOUTUBE_BASEURL;
|
||||
|
||||
$params = array();
|
||||
|
||||
if (FALSE === (boolean) $this->arguments['showRelated']) {
|
||||
$params[] = 'rel=0';
|
||||
}
|
||||
if (TRUE === (boolean) $this->arguments['autoplay']) {
|
||||
$params[] = 'autoplay=1';
|
||||
}
|
||||
if (TRUE === (boolean) $this->arguments['hideControl']) {
|
||||
$params[] = 'controls=0';
|
||||
}
|
||||
if (TRUE === (boolean) $this->arguments['hideInfo']) {
|
||||
$params[] = 'showinfo=0';
|
||||
}
|
||||
if (FALSE === empty($this->arguments['playlist'])) {
|
||||
$params[] = 'playlist=' . $this->arguments['playlist'];
|
||||
}
|
||||
if (TRUE === (boolean) $this->arguments['loop']) {
|
||||
$params[] = 'loop=1';
|
||||
}
|
||||
if (FALSE === empty($this->arguments['start'])) {
|
||||
$params[] = 'start=' . $this->arguments['start'];
|
||||
}
|
||||
if (FALSE === empty($this->arguments['end'])) {
|
||||
$params[] = 'end=' . $this->arguments['end'];
|
||||
}
|
||||
if (TRUE === (boolean) $this->arguments['lightTheme']) {
|
||||
$params[] = 'theme=light';
|
||||
}
|
||||
if (FALSE === empty($this->arguments['videoQuality'])) {
|
||||
$params[] = 'vq=' . $this->arguments['videoQuality'];
|
||||
}
|
||||
if (FALSE === empty($this->arguments['windowMode'])) {
|
||||
$params[] = 'wmode=' . $this->arguments['windowMode'];
|
||||
}
|
||||
|
||||
if (FALSE === $this->arguments['legacyCode']) {
|
||||
$src .= '/embed/'. $videoId;
|
||||
$seperator = '?';
|
||||
} else {
|
||||
$src .= '/v/' . $videoId . '?version=3';
|
||||
$seperator = '&';
|
||||
}
|
||||
|
||||
if (FALSE === empty($params)) {
|
||||
$src .= $seperator . implode('&', $params);
|
||||
}
|
||||
|
||||
return $src;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the provided tag and its attributes
|
||||
*
|
||||
* @param string $tagName
|
||||
* @param array $attributes
|
||||
* @param boolean $forceClosingTag
|
||||
* @return string
|
||||
*/
|
||||
private function renderChildTag($tagName, $attributes = array(), $forceClosingTag = FALSE) {
|
||||
$tagBuilder = clone $this->tag;
|
||||
$tagBuilder->reset();
|
||||
$tagBuilder->setTagName($tagName);
|
||||
$tagBuilder->addAttributes($attributes);
|
||||
$tagBuilder->forceClosingTag($forceClosingTag);
|
||||
$childTag = $tagBuilder->render();
|
||||
unset($tagBuilder);
|
||||
|
||||
return $childTag;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user