/lib/wiki-plugins/wikiplugin_preview.php
PHP | 242 lines | 181 code | 37 blank | 24 comment | 27 complexity | 5595f72b7b41157dbb82e74b4c9cf36c MD5 | raw file
- <?php
- // (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
- //
- // All Rights Reserved. See copyright.txt for details and a complete list of authors.
- // Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
- // $Id$
- use Tiki\Lib\Alchemy\AlchemyLib;
- /**
- * Plugin definition for preview
- *
- * @return array
- */
- function wikiplugin_preview_info()
- {
- return [
- 'name' => tr('Preview Files'),
- 'documentation' => 'PluginPreviewFiles',
- 'description' => tr('Enabled to generate preview of images or video files'),
- 'prefs' => ['wikiplugin_preview'],
- 'iconname' => 'file',
- 'introduced' => 18,
- 'tags' => ['experimental'],
- 'packages_required' => ['media-alchemyst/media-alchemyst' => 'MediaAlchemyst\Alchemyst'],
- 'format' => 'html',
- 'params' => [
- 'fileId' => [
- 'required' => true,
- 'name' => tr('fileId'),
- 'description' => tr('Id of the file in the file gallery'),
- 'since' => '18.0',
- 'filter' => 'int',
- ],
- 'animation' => [
- 'required' => false,
- 'name' => tr('Animation'),
- 'description' => tr('Output should be a static image (<code>0</code>) or an animation (<code>1</code>)'),
- 'since' => '18.0',
- 'filter' => 'int',
- ],
- 'width' => [
- 'required' => false,
- 'name' => tr('Width'),
- 'description' => tr('Width of the result in pixels'),
- 'since' => '18.0',
- 'filter' => 'int',
- ],
- 'height' => [
- 'required' => false,
- 'name' => tr('Height'),
- 'description' => tr('Height of the result in pixels'),
- 'since' => '18.0',
- 'filter' => 'int',
- ],
- 'download' => [
- 'required' => false,
- 'name' => tr('Download'),
- 'description' => tr('Show download link to the original file'),
- 'since' => '19.0',
- 'filter' => 'int',
- ],
- 'range' => [
- 'required' => false,
- 'name' => tr('Range'),
- 'description' => tr('Page range preview in the format <integer>-<integer>. Example for the preview page from 2 to 4: "2-4"'),
- 'since' => '21.0',
- ],
- ],
- ];
- }
- /**
- * Plugin definition for Preview
- *
- * @param $data
- * @param $params
- * @return string|void
- */
- function wikiplugin_preview($data, $params)
- {
- global $user, $prefs, $tikipath, $tikidomain;
- if (! AlchemyLib::isLibraryAvailable()) {
- return;
- }
- $fileId = isset($params['fileId']) ? (int)$params['fileId'] : 0;
- $animation = isset($params['animation']) ? (int)$params['animation'] : 0;
- $width = isset($params['width']) ? (int)$params['width'] : null;
- $height = isset($params['height']) ? (int)$params['height'] : null;
- $range = isset($params['range']) ? $params['range'] : null;
- $smartyLib = TikiLib::lib('smarty');
- $fileGalleryLib = TikiLib::lib('filegal');
- $userLib = TikiLib::lib('user');
- $file = \Tiki\FileGallery\File::id($fileId);
- if (! $file->exists() || ! $userLib->user_has_perm_on_object($user, $file->fileId, 'file', 'tiki_p_download_files')) {
- return;
- }
- $requestUniqueIdentifier = md5(serialize([$data, $params]));
- if (! isset($_REQUEST[$requestUniqueIdentifier])) {
- // generate the html output
- $urlParts = parse_url($_SERVER['REQUEST_URI']);
- $path = isset($urlParts['path']) ? $urlParts['path'] : '/';
- if (isset($urlParts['query'])) {
- parse_str($urlParts['query'], $pageParams);
- } else {
- $pageParams = [];
- }
- if (isset($_GET['page'])) {
- $pageParams['page'] = $_GET['page'];
- }
- $pageParams[$requestUniqueIdentifier] = '1';
- $pageParamStr = http_build_query($pageParams, null, '&');
- $fileLink = $path . '?' . $pageParamStr;
- $smartyLib->assign('param', $params);
- $files = [];
- if (! empty($range)) {
- $rangeFormat = preg_match("/^\d+\-\d+$/", $range);
- if ($rangeFormat !== 1) {
- Feedback::error(tr('File ID %0 preview contains an invalid range parameter.', $fileId));
- } else {
- $pageIterator = explode('-', $range)[0];
- $lastPage = explode('-', $range)[1];
- while ($pageIterator <= $lastPage) {
- $files[] = $fileLink . "&previewPage=" . $pageIterator;
- $pageIterator++;
- }
- }
- } else {
- $files[] = $fileLink;
- }
- $smartyLib->assign('files', $files);
- if ((isset($params['download']) && $params['download'] === 1)) {
- $tikilib = TikiLib::lib('tiki');
- $smartyLib->assign('original_file_download_link', $tikilib->tikiUrl() . 'tiki-download_file.php?fileId=' . $fileId, true);
- }
- return $smartyLib->fetch('wiki-plugins/wikiplugin_preview.tpl');
- }
- $filePath = $file->getWrapper()->getReadableFile();
- $fileMd5 = $file->getWrapper()->getChecksum();
- while (ob_get_level() > 1) {
- ob_end_clean();
- } // Be sure output buffering is turned off
- /** @var Cachelib $cacheLib */
- $cacheLib = TikiLib::lib('cache');
- $cacheName = $fileMd5 . $requestUniqueIdentifier;
- $previewPage = isset($_GET['previewPage']) ? $_GET['previewPage'] : null;
- if ($previewPage) {
- $cacheName .= "_" . $previewPage;
- }
- $cacheType = 'wp_preview_' . $fileId . '_';
- $buildContent = true;
- $content = null;
- $contentType = null;
- $content_temp = $cacheLib->getCached($cacheName, $cacheType);
- if ($content_temp && $content_temp !== serialize(false) && $content_temp != "") {
- $buildContent = false;
- $pos = strpos($content_temp, ';');
- $contentType = substr($content_temp, 0, $pos);
- $content = substr($content_temp, $pos + 1);
- }
- unset($content_temp);
- if ($buildContent) {
- $newFileExtension = $animation ? '.gif' : '.png';
- $newFilePath = $tikipath . DIRECTORY_SEPARATOR
- . 'temp' . DIRECTORY_SEPARATOR
- . 'cache' . DIRECTORY_SEPARATOR
- . $tikidomain . DIRECTORY_SEPARATOR
- . 'target_' . $cacheType . $cacheName . $newFileExtension;
- // This will allow apps executed by Alchemy (like when converting doc to pdf) to have a writable home
- // save existing ENV
- $envHomeDefined = isset($_ENV) && array_key_exists('HOME', $_ENV);
- if ($envHomeDefined) {
- $envHomeCopy = $_ENV['HOME'];
- }
- // set a proper home folder
- $_ENV['HOME'] = $tikipath . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . $tikidomain;
- AlchemyLib::hintMimeTypeByFilePath($filePath, $file->filetype);
- $alchemy = new AlchemyLib();
- $contentType = $alchemy->convertToImage($filePath, $newFilePath, $width, $height, $animation, $previewPage);
- // Restore the environment
- if ($envHomeDefined) {
- $_ENV['HOME'] = $envHomeCopy;
- } else {
- unset($_ENV['HOME']);
- }
- if (file_exists($newFilePath)) {
- $content = file_get_contents($newFilePath);
- }
- unlink($newFilePath);
- if (empty($content)) {
- exit;
- }
- $cacheLib->cacheItem($cacheName, $contentType . ';' . $content, $cacheType);
- }
- session_write_close(); // close the session in case of large transcode/downloads to enable further browsing
- // Compression of the stream may corrupt files on windows
- ini_set('zlib.output_compression', 'Off');
- header("Expires: 0");
- header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
- header("Cache-Control: private", false);
- header('Content-Length: ' . strlen($content));
- header('Content-Type: ' . $contentType);
- header('Content-Disposition: inline; filename="' . $fileMd5 . '";');
- header('Connection: close');
- header('Content-Transfer-Encoding: binary');
- echo $content;
- exit;
- }