/** * Get the cropped image by File Object * * @param FileInterface $file * @param string $ratio * * @return string The new filename */ public function getCroppedImageSrcByFile(FileInterface $file, $ratio) { $absoluteImageName = GeneralUtility::getFileAbsFileName($file->getPublicUrl()); $focusPointX = MathUtility::forceIntegerInRange((int) $file->getProperty('focus_point_x'), -100, 100, 0); $focusPointY = MathUtility::forceIntegerInRange((int) $file->getProperty('focus_point_y'), -100, 100, 0); $tempImageFolder = 'typo3temp/focuscrop/'; $tempImageName = $tempImageFolder . $file->getSha1() . '-' . str_replace(':', '-', $ratio) . '-' . $focusPointX . '-' . $focusPointY . '.' . $file->getExtension(); $absoluteTempImageName = GeneralUtility::getFileAbsFileName($tempImageName); if (is_file($absoluteTempImageName)) { return $tempImageName; } $absoluteTempImageFolder = GeneralUtility::getFileAbsFileName($tempImageFolder); if (!is_dir($absoluteTempImageFolder)) { GeneralUtility::mkdir_deep($absoluteTempImageFolder); } $this->graphicalFunctions = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Imaging\\GraphicalFunctions'); $imageSizeInformation = getimagesize($absoluteImageName); $width = $imageSizeInformation[0]; $height = $imageSizeInformation[1]; // dimensions /** @var \HDNET\Focuspoint\Service\DimensionService $service */ $dimensionService = GeneralUtility::makeInstance('HDNET\\Focuspoint\\Service\\DimensionService'); list($focusWidth, $focusHeight) = $dimensionService->getFocusWidthAndHeight($width, $height, $ratio); $cropMode = $dimensionService->getCropMode($width, $height, $ratio); list($sourceX, $sourceY) = $dimensionService->calculateSourcePosition($cropMode, $width, $height, $focusWidth, $focusHeight, $focusPointX, $focusPointY); // generate image $sourceImage = $this->graphicalFunctions->imageCreateFromFile($absoluteImageName); $destinationImage = imagecreatetruecolor($focusWidth, $focusHeight); $this->graphicalFunctions->imagecopyresized($destinationImage, $sourceImage, 0, 0, $sourceX, $sourceY, $focusWidth, $focusHeight, $focusWidth, $focusHeight); $this->graphicalFunctions->ImageWrite($destinationImage, $absoluteTempImageName, $GLOBALS['TYPO3_CONF_VARS']['GFX']['jpg_quality']); return $tempImageName; }
/** * When retrieving the height or width for a media file * a possible cropping needs to be taken into account. * * @param FileInterface $fileObject * @param string $dimensionalProperty 'width' or 'height' * @return int */ protected function getCroppedProperty(FileInterface $fileObject, $dimensionalProperty) { if (!$fileObject->hasProperty('crop') || empty($fileObject->getProperty('crop'))) { return $fileObject->getProperty($dimensionalProperty); } $croppingConfiguration = json_decode($fileObject->getProperty('crop'), true); return (int) $croppingConfiguration[$dimensionalProperty]; }
/** * When retrieving the width for a media file * a possible cropping needs to be taken into account. * * @param FileInterface $fileObject * @return int */ protected function getCroppedWidth(FileInterface $fileObject) { if (!$fileObject->hasProperty('crop') || empty($fileObject->getProperty('crop'))) { return $fileObject->getProperty('width'); } $croppingConfiguration = json_decode($fileObject->getProperty('crop'), true); return (int) $croppingConfiguration['width']; }
/** * Render for given File(Reference) HTML output * * @param FileInterface $file * @param int|string $width TYPO3 known format; examples: 220, 200m or 200c * @param int|string $height TYPO3 known format; examples: 220, 200m or 200c * @param array $options controls = TRUE/FALSE (default TRUE), autoplay = TRUE/FALSE (default FALSE), loop = TRUE/FALSE (default FALSE) * @param bool $usedPathsRelativeToCurrentScript See $file->getPublicUrl() * @return string */ public function render(FileInterface $file, $width, $height, array $options = [], $usedPathsRelativeToCurrentScript = false) { // If autoplay isn't set manually check if $file is a FileReference take autoplay from there if (!isset($options['autoplay']) && $file instanceof FileReference) { $autoplay = $file->getProperty('autoplay'); if ($autoplay !== null) { $options['autoplay'] = $autoplay; } } $attributes = []; if ((int) $width > 0) { $attributes[] = 'width="' . (int) $width . '"'; } if ((int) $height > 0) { $attributes[] = 'height="' . (int) $height . '"'; } if (!isset($options['controls']) || !empty($options['controls'])) { $attributes[] = 'controls'; } if (!empty($options['autoplay'])) { $attributes[] = 'autoplay'; } if (!empty($options['muted'])) { $attributes[] = 'muted'; } if (!empty($options['loop'])) { $attributes[] = 'loop'; } foreach (['class', 'dir', 'id', 'lang', 'style', 'title', 'accesskey', 'tabindex', 'onclick'] as $key) { if (!empty($options[$key])) { $attributes[] = $key . '="' . htmlspecialchars($options[$key]) . '"'; } } return sprintf('<video%s><source src="%s" type="%s"></video>', empty($attributes) ? '' : ' ' . implode(' ', $attributes), htmlspecialchars($file->getPublicUrl($usedPathsRelativeToCurrentScript)), $file->getMimeType()); }
/** * Fetch, cache and return the number of references of a file * * @return int */ public function getReferenceCount() { $uid = (int) $this->resource->getProperty('uid'); if ($uid <= 0) { return 0; } if (!isset(static::$referenceCounts[$uid])) { $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_refindex'); $count = $queryBuilder->count('*')->from('sys_refindex')->where($queryBuilder->expr()->eq('ref_table', $queryBuilder->quote('sys_file')))->andWhere($queryBuilder->expr()->eq('ref_uid', (int) $this->resource->getProperty('uid')))->andWhere($queryBuilder->expr()->neq('tablename', $queryBuilder->quote('sys_file_metadata')))->execute()->fetchColumn(); static::$referenceCounts[$uid] = $count; } return static::$referenceCounts[$uid]; }
/** * Fetch, cache and return the number of references of a file * * @return int */ public function getReferenceCount() { $uid = (int) $this->resource->getProperty('uid'); if ($uid <= 0) { return 0; } if (!isset(static::$referenceCounts[$uid])) { $count = $this->getDatabaseConnection()->exec_SELECTcountRows('*', 'sys_refindex', 'ref_table=\'sys_file\'' . ' AND ref_uid=' . (int) $this->resource->getProperty('uid') . ' AND deleted=0' . ' AND tablename != \'sys_file_metadata\''); if (!is_int($count)) { $count = 0; } static::$referenceCounts[$uid] = $count; } return static::$referenceCounts[$uid]; }
/** * Returns a (local copy of) a file for processing it. When changing the * file, you have to take care of replacing the current version yourself! * * @param \TYPO3\CMS\Core\Resource\FileInterface $file * @param bool $writable Set this to FALSE if you only need the file for read operations. This might speed up things, e.g. by using a cached local version. Never modify the file if you have set this flag! * @return string The path to the file on the local disk */ public function getFileForLocalProcessing(\TYPO3\CMS\Core\Resource\FileInterface $file, $writable = true) { error_log('FAL DRIVER: ' . __FUNCTION__); if (!$file->isIndexed() || !$file->getProperty('yagItem') instanceof \Tx_Yag_Domain_Model_Item) { $identifier = $file->getIdentifier(); $fileInfo = $this->getFileInfoByIdentifier($identifier); $sourceUri = $this->yagFileSystemDiv->makePathAbsolute($fileInfo['sourceUri']); } else { $item = $file->getProperty('yagItem'); $sourceUri = $this->yagFileSystemDiv->makePathAbsolute($item->getSourceuri()); } return $sourceUri; }
/** * Render for given File(Reference) html output * * @param FileInterface $file * @param int|string $width TYPO3 known format; examples: 220, 200m or 200c * @param int|string $height TYPO3 known format; examples: 220, 200m or 200c * @param array $options * @param bool $usedPathsRelativeToCurrentScript See $file->getPublicUrl() * @return string */ public function render(FileInterface $file, $width, $height, array $options = null, $usedPathsRelativeToCurrentScript = false) { if ($file instanceof FileReference) { $autoplay = $file->getProperty('autoplay'); if ($autoplay !== null) { $options['autoplay'] = $autoplay; } } $urlParams = array(); if (!empty($options['autoplay'])) { $urlParams[] = 'autoplay=1'; } if (!empty($options['loop'])) { $urlParams[] = 'loop=1'; } $urlParams[] = 'title=' . (int) (!empty($options['showinfo'])); $urlParams[] = 'byline=' . (int) (!empty($options['showinfo'])); $urlParams[] = 'portrait=0'; if ($file instanceof FileReference) { $orgFile = $file->getOriginalFile(); } else { $orgFile = $file; } $videoId = $this->getOnlineMediaHelper($file)->getOnlineMediaId($orgFile); $src = sprintf('//player.vimeo.com/video/%s?%s', $videoId, implode('&', $urlParams)); $attributes = array('allowfullscreen'); if ((int) $width > 0) { $attributes[] = 'width="' . (int) $width . '"'; } if ((int) $height > 0) { $attributes[] = 'height="' . (int) $height . '"'; } if (is_object($GLOBALS['TSFE']) && $GLOBALS['TSFE']->config['config']['doctype'] !== 'html5') { $attributes[] = 'frameborder="0"'; } foreach (array('class', 'dir', 'id', 'lang', 'style', 'title', 'accesskey', 'tabindex', 'onclick') as $key) { if (!empty($options[$key])) { $attributes[] = $key . '="' . htmlspecialchars($options[$key]) . '"'; } } return sprintf('<iframe src="%s"%s></iframe>', $src, empty($attributes) ? '' : ' ' . implode(' ', $attributes)); }
/** * Render for given File(Reference) html output * * @param FileInterface $file * @param int|string $width TYPO3 known format; examples: 220, 200m or 200c * @param int|string $height TYPO3 known format; examples: 220, 200m or 200c * @param array $options * @param bool $usedPathsRelativeToCurrentScript See $file->getPublicUrl() * @return string */ public function render(FileInterface $file, $width, $height, array $options = null, $usedPathsRelativeToCurrentScript = false) { if ($file instanceof FileReference) { $autoplay = $file->getProperty('autoplay'); if ($autoplay !== null) { $options['autoplay'] = $autoplay; } } $urlParams = array(); if (!empty($options['autoplay'])) { $urlParams[] = 'auto_play=1'; } if ($file instanceof FileReference) { $orgFile = $file->getOriginalFile(); } else { $orgFile = $file; } $soundCloudId = $this->getOnlineMediaHelper($file)->getOnlineMediaId($orgFile); $src = sprintf('//w.soundcloud.com/player/?url=%s?%s', urlencode('https://api.soundcloud.com/tracks/' . $soundCloudId), implode('&', $urlParams)); foreach (['class', 'dir', 'id', 'lang', 'style', 'title', 'accesskey', 'tabindex', 'onclick'] as $key) { if (!empty($options[$key])) { $attributes[] = $key . '="' . htmlspecialchars($options[$key]) . '"'; } } return sprintf('<iframe src="%s"%s></iframe>', $src, empty($attributes) ? '' : ' ' . implode(' ', $attributes)); }
/** * Calculate new dimensions for SVG image * No cropping, if cropped info present image is scaled down * * @param Resource\FileInterface $file * @param array $configuration * @param array $options * @param GifBuilder $gifBuilder * @return array width,height */ protected function getNewSvgDimensions($file, array $configuration, array $options, GifBuilder $gifBuilder) { $info = array($file->getProperty('width'), $file->getProperty('height')); $data = $gifBuilder->getImageScale($info, $configuration['width'], $configuration['height'], $options); // Turn cropScaling into scaling if ($data['crs']) { if (!$data['origW']) { $data['origW'] = $data[0]; } if (!$data['origH']) { $data['origH'] = $data[1]; } if ($data[0] > $data['origW']) { $data[1] = (int) ($data['origW'] * $data[1] / $data[0]); $data[0] = $data['origW']; } else { $data[0] = (int) ($data['origH'] * $data[0] / $data[1]); $data[1] = $data['origH']; } } return array('width' => $data[0], 'height' => $data[1]); }
/** * Render for given File(Reference) html output * * @param FileInterface $file * @param int|string $width TYPO3 known format; examples: 220, 200m or 200c * @param int|string $height TYPO3 known format; examples: 220, 200m or 200c * @param array $options * @param bool $usedPathsRelativeToCurrentScript See $file->getPublicUrl() * @return string */ public function render(FileInterface $file, $width, $height, array $options = null, $usedPathsRelativeToCurrentScript = false) { if ($file instanceof FileReference) { $autoplay = $file->getProperty('autoplay'); if ($autoplay !== null) { $options['autoplay'] = $autoplay; } } $urlParams = array('autohide=1'); if (!isset($options['controls']) || !empty($options['controls'])) { $urlParams[] = 'controls=2'; } if (!empty($options['autoplay'])) { $urlParams[] = 'autoplay=1'; } if (!empty($options['loop'])) { $urlParams[] = 'loop=1'; } if (!isset($options['enablejsapi']) || !empty($options['enablejsapi'])) { $urlParams[] = 'enablejsapi=1&origin=' . GeneralUtility::getIndpEnv('HTTP_HOST'); } $urlParams[] = 'showinfo=' . (int) (!empty($options['showinfo'])); if ($file instanceof FileReference) { $orgFile = $file->getOriginalFile(); } else { $orgFile = $file; } $videoId = $this->getOnlineMediaHelper($file)->getOnlineMediaId($orgFile); $src = sprintf('//www.youtube%s.com/embed/%s?%s', !empty($options['no-cookie']) ? '-nocookie' : '', $videoId, implode('&', $urlParams)); $attributes = ['allowfullscreen']; if ((int) $width > 0) { $attributes[] = 'width="' . (int) $width . '"'; } if ((int) $height > 0) { $attributes[] = 'height="' . (int) $height . '"'; } if (is_object($GLOBALS['TSFE']) && $GLOBALS['TSFE']->config['config']['doctype'] !== 'html5') { $attributes[] = 'frameborder="0"'; } foreach (['class', 'dir', 'id', 'lang', 'style', 'title', 'accesskey', 'tabindex', 'onclick', 'poster', 'preload'] as $key) { if (!empty($options[$key])) { $attributes[] = $key . '="' . htmlspecialchars($options[$key]) . '"'; } } return sprintf('<iframe src="%s"%s></iframe>', $src, empty($attributes) ? '' : ' ' . implode(' ', $attributes)); }
/** * Render img tag * * @param FileInterface $image * @param string $width * @param string $height * @return string Rendered img tag */ protected function renderImage(FileInterface $image, $width, $height) { $crop = $image instanceof FileReference ? $image->getProperty('crop') : null; $processingInstructions = ['width' => $width, 'height' => $height, 'crop' => $crop]; $imageService = $this->getImageService(); $processedImage = $imageService->applyProcessingInstructions($image, $processingInstructions); $imageUri = $imageService->getImageUri($processedImage); $this->tag->addAttribute('src', $imageUri); $this->tag->addAttribute('width', $processedImage->getProperty('width')); $this->tag->addAttribute('height', $processedImage->getProperty('height')); $alt = $image->getProperty('alternative'); $title = $image->getProperty('title'); // The alt-attribute is mandatory to have valid html-code, therefore add it even if it is empty if (empty($this->arguments['alt'])) { $this->tag->addAttribute('alt', $alt); } if (empty($this->arguments['title']) && $title) { $this->tag->addAttribute('title', $title); } return $this->tag->render(); }
/** * @param FileInterface $file * @param int|string $width TYPO3 known format; examples: 220, 200m or 200c * @param int|string $height TYPO3 known format; examples: 220, 200m or 200c * @param array $options * @param bool $usedPathsRelativeToCurrentScript See $file->getPublicUrl() * @return string */ public function render(FileInterface $file, $width, $height, array $options = array(), $usedPathsRelativeToCurrentScript = false) { $data = $srcset = $sizes = []; if ($file instanceof FileReference) { $originalFile = $file->getOriginalFile(); } else { $originalFile = $file; } try { $defaultProcessConfiguration = []; $defaultProcessConfiguration['width'] = (int) $width; $defaultProcessConfiguration['crop'] = $file->getProperty('crop'); } catch (\InvalidArgumentException $e) { $defaultProcessConfiguration['crop'] = ''; } foreach ($this->settings['sourceCollection'] as $configuration) { try { if (!is_array($configuration)) { throw new \RuntimeException(); } if (isset($configuration['sizes'])) { $sizes[] = trim($configuration['sizes'], ' ,'); } if ((int) $configuration['width'] > (int) $width) { throw new \RuntimeException(); } $localProcessingConfiguration = $defaultProcessConfiguration; $localProcessingConfiguration['width'] = $configuration['width']; $processedFile = $originalFile->process(ProcessedFile::CONTEXT_IMAGECROPSCALEMASK, $localProcessingConfiguration); $url = $this->absRefPrefix . $processedFile->getPublicUrl(); $data['data-' . $configuration['dataKey']] = $url; $srcset[] = $url . rtrim(' ' . $configuration['srcset'] ?: ''); } catch (\Exception $ignoredException) { continue; } } $src = $originalFile->process(ProcessedFile::CONTEXT_IMAGECROPSCALEMASK, $defaultProcessConfiguration)->getPublicUrl(); $this->tagBuilder->reset(); $this->tagBuilder->setTagName('img'); $this->tagBuilder->addAttribute('src', $src); $this->tagBuilder->addAttribute('alt', $file->getProperty('alternative')); $this->tagBuilder->addAttribute('title', $file->getProperty('title')); switch ($this->settings['layoutKey']) { case 'srcset': if (!empty($srcset)) { $this->tagBuilder->addAttribute('srcset', implode(', ', $srcset)); } $this->tagBuilder->addAttribute('sizes', implode(', ', $sizes)); break; case 'data': if (!empty($data)) { foreach ($data as $key => $value) { $this->tagBuilder->addAttribute($key, $value); } } break; default: $this->tagBuilder->addAttributes(['width' => (int) $width, 'height' => (int) $height]); break; } return $this->tagBuilder->render(); }
/** * Get the cropped image by File Object * * @param FileInterface $file * @param string $ratio * * @return string The new filename */ public function getCroppedImageSrcByFile(FileInterface $file, $ratio) { return $this->getCroppedImageSrcBySrc($file->getPublicUrl(), $ratio, $file->getProperty('focus_point_x'), $file->getProperty('focus_point_y')); }
/** * @param string $src * @param FileInterface $file * @param array $options * * @return string */ protected function buildImageTag($src, FileInterface $file, array $options) { $tagBuilder = $this->getTagBuilder(); $configuration = $this->getConfiguration(); $tagBuilder->reset(); $tagBuilder->setTagName('img'); try { $alt = trim($file->getProperty('alternative')); if (empty($alt)) { throw new \LogicException(); } } catch (\Exception $e) { $alt = isset($options['alt']) && !empty($options['alt']) ? $options['alt'] : ''; } try { $title = trim($file->getProperty('title')); if (empty($title)) { throw new \LogicException(); } } catch (\Exception $e) { $title = isset($options['title']) && !empty($options['title']) ? $options['title'] : ''; } $tagBuilder->addAttribute('src', $src); $tagBuilder->addAttribute('alt', $alt); $tagBuilder->addAttribute('title', $title); switch ($configuration->getLayoutKey()) { case 'srcset': if (!empty($this->srcset)) { $tagBuilder->addAttribute('srcset', implode(', ', $this->srcset)); if (!empty($this->sizes)) { $tagBuilder->addAttribute('sizes', implode(', ', $this->sizes)); } } break; case 'data': if (!empty($this->data)) { foreach ($this->data as $key => $value) { $tagBuilder->addAttribute($key, $value); } } break; default: $tagBuilder->addAttributes(['width' => (int) $this->defaultWidth, 'height' => (int) $this->defaultHeight]); break; } if (isset($options['data']) && is_array($options['data'])) { foreach ($options['data'] as $dataAttributeKey => $dataAttributeValue) { $tagBuilder->addAttribute('data-' . $dataAttributeKey, $dataAttributeValue); } } foreach ($configuration->getGenericTagAttributes() as $attributeName) { if (isset($options[$attributeName]) && $options[$attributeName] !== '') { $tagBuilder->addAttribute($attributeName, $options[$attributeName]); } } if (isset($options['additionalAttributes']) && is_array($options['additionalAttributes'])) { $tagBuilder->addAttributes($options['additionalAttributes']); } return $tagBuilder->render(); }