Commit 1a2ff0cd authored by sgalinsk's avatar sgalinsk

added refactored pmkshadowbox version


git-svn-id: https://svn.typo3.org/TYPO3v4/Extensions/pmkshadowbox/trunk@33461 735d13b6-9817-0410-8766-e36946ffe9aa
parent dbd8a27c
### README ###
The generation of the shadowbox script has changed dramatically, because the script is build on
runtime now. The configuration is very easy and mostly backwards compatible. See the notes
below for a list of specific configuration changes. The build functionality is completely
convered by unit tests!
## General Notes:
- Dropped support for TYPO3 below 4.3, because this should be a new major release (3.0)
- Some default values changed to fit the new shadowbox defaults
- tt_products is completely untested
## Values for the "iframeScrolling" configuration option
- yes -> always show the scrollbars
- no -> never show the scrollbars
- auto -> autodetection if the scrollbars are needed
- dynamic -> scrollbars will be enabled/disabled while resizing
-> only useful in some cases and far way from perfection
- dynamic_noScrollFallback -> same as dynamic, but IE6/7 won't display the scrollbars anymore
## Added non-shadowbox options:
- useSizzle moved from shadowbox to non-shadowbox option
- players moved from shadowbox to non-shadowbox option
- adapter moved from shadowbox to non-shadowbox option
- preserveAspectWhileResizing - enable old resizing behaviour by default (the new one is extremely annoying)
- skinModificationDirectory -> more flexible approach than the skinPath variable
- flashPlayer -> option to change the default flash player
- flashExpressInstallScript -> option to change the default flash express install script
## Removed non-shadowbox options:
- jsFramework -> The user is responsible to include his framework himself now! An administrator
should know how he can fulfill this condition.
- skipSetup -> moved to the shadowbox option with the same name (but reversed the default)
- iframeScrolling -> can be used as a rel attribute only now
-> the global solution didn't made much sense
- skinPath -> replaced by the more flexible skinModification configuration variable
## Removed shadowbox configuration options:
- flvPlayer -> autoloaded by naming convention (player.swf inside the build path)
- flashBgColor -> replaced by the more general flashParams option
- autoDimensions -> no replacement
- handleException -> no replacement
- gdoc player doesn't exists anymore
## Added shadowbox configuration options:
Some were mentioned with background informations already before this section.
- troubleElements
- flashVars
- flashParams
- flashVersion
- skipSetup
### TODO ###
Any issues that are still open after the release should be moved to forge!
Reintegration:
- reintegration of the different skins
- classicWithSave
- dropShadow
- savefile.php integration
Others:
- rewrite/update of the manual
<?php
/***************************************************************
* Copyright notice
*
* (c) 2010 Peter Klein (pmk@io.dk)
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
* A copy is found in the textfile GPL.txt and important notices to the license
* from the author is found in LICENSE.txt distributed with these scripts.
*
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
define('TYPO3_MODE','BE');
define('TYPO3_cliMode', TRUE);
define('TYPO3_OS', stristr(PHP_OS,'win')&&!stristr(PHP_OS,'darwin')?'WIN':'');
define('PATH_thisScript',str_replace('//','/', str_replace('\\','/', (php_sapi_name()=='cgi'||php_sapi_name()=='isapi' ||php_sapi_name()=='cgi-fcgi')&&($_SERVER['ORIG_PATH_TRANSLATED']?$_SERVER['ORIG_PATH_TRANSLATED']:$_SERVER['PATH_TRANSLATED'])? ($_SERVER['ORIG_PATH_TRANSLATED']?$_SERVER['ORIG_PATH_TRANSLATED']:$_SERVER['PATH_TRANSLATED']):($_SERVER['ORIG_SCRIPT_FILENAME']?$_SERVER['ORIG_SCRIPT_FILENAME']:$_SERVER['SCRIPT_FILENAME']))));
define('PATH_site', ereg_replace('[^/]*.[^/]*$','',dirname(dirname(PATH_thisScript))));
define('PATH_typo3', PATH_site.'typo3/');
define('PATH_typo3conf', PATH_site.'typo3conf/');
define('PATH_t3lib', PATH_site.'t3lib/');
require_once(PATH_t3lib.'class.t3lib_div.php');
require_once(PATH_typo3conf.'localconf.php');
$image = t3lib_div::_GET('image');
//first check if the requested file has an valid image file extension, not the nicest security feature but at least it prevents from downloading php files like localconf.php.
$allowedExtensions = t3lib_div::trimExplode(',', (strlen($TYPO3_CONF_VARS['GFX']['imagefile_ext']) > 0 ? $TYPO3_CONF_VARS['GFX']['imagefile_ext'] : 'gif,jpg,jpeg,tif,bmp,pcx,tga,png,pdf,ai'), 1);
$imageInfo = pathinfo($image);
if(!in_array(strtolower($imageInfo['extension']), $allowedExtensions)) { die('You are trying to download a file, which you don\'t have access to'); }
switch (t3lib_div::_GET('mode')) {
case 'print':
print_image($image);
break;
case 'save':
force_download($image);
break;
default:
break;
}
exit;
function print_image($filename) {
echo '<html>
<head>
<title>Print</title>
<script type="text/javascript">
function printit(){
try {
window.print();
}
catch(err) {
return;
}
window.close();
}
window.onload = printit;
</script>
</head>
<body style="margin:0;padding:0;">
<img src="'.$filename.'" style="border:none;cursor:pointer;" onclick="self.close()">
</body>
</html>';
}
function force_download ($filename, $mimetype='') {
$filename = str_replace(t3lib_div::getIndpEnv('TYPO3_SITE_URL'),PATH_site,$filename);
if (!file_exists($filename)) return false;
// Mimetype not set?
if (empty($mimetype)) {
$file_extension = strtolower(substr(strrchr($filename,"."),1));
switch( $file_extension ) {
case "pdf": $mimetype="application/pdf"; break;
case "exe": $mimetype="application/octet-stream"; break;
case "zip": $mimetype="application/zip"; break;
case "doc": $mimetype="application/msword"; break;
case "xls": $mimetype="application/vnd.ms-excel"; break;
case "ppt": $mimetype="application/vnd.ms-powerpoint"; break;
case "gif": $mimetype="image/gif"; break;
case "png": $mimetype="image/png"; break;
case "jpeg":
case "jpg": $mimetype="image/jpg"; break;
default: $mimetype="application/force-download";
}
}
// Make sure there's nothing else left
ob_clean_all();
// Start sending headers
header('Pragma: public'); // required
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private',false); // required for certain browsers
header('Content-Transfer-Encoding: binary');
header('Content-Type: ' . $mimetype);
header('Content-Length: ' . filesize($filename));
header('Content-Disposition: attachment; filename="' . basename($filename) . '";' );
// Send data
readfile($filename);
exit;
}
function ob_clean_all () {
$ob_active = ob_get_length () !== false;
while($ob_active) {
ob_end_clean();
$ob_active = ob_get_length () !== false;
}
return true;
}
?>
\ No newline at end of file
<?php
/***************************************************************
* Copyright notice
*
* (c) 2010 Stefan Galinski (stefan.galinski@gmail.com)
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
* A copy is found in the textfile GPL.txt and important notices to the license
* from the author is found in LICENSE.txt distributed with these scripts.
*
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
// unfortunately not automatically loaded
require_once(PATH_typo3 . 'contrib/jsmin/jsmin.php');
/**
* This class contains methods for building up the shadowbox script.
*
* @author Stefan Galinski <stefan.galinski@gmail.com>
*/
class tx_pmkshadowbox_build {
/**
* Content Object for Typoscript Operations
*
* @param tslib_cObj
* @var tslib_cObj
*/
public $cObj = null;
/**
* Cache Handler
*
* @property tx_pmkshadowbox_cache
* @var tx_pmkshadowbox_cache
*/
protected $cacheHandler = null;
/**
* Extension Configuration
*
* @var array
*/
protected $extensionConfiguration = array();
/**
* Path to the Source Directory
*
* @var string
*/
protected $sourceDirectory = '';
/**
* Constructor
*
* Note: If no cache handler parameter is given, the method will create a new one!
*
* @param tx_pmkshadowbox_cache $cacheHandler
* @return void
*/
public function __construct($cacheHandler = NULL) {
$this->cObj = t3lib_div::makeInstance('tslib_cObj');
$this->sourceDirectory = t3lib_extMgm::siteRelPath('pmkshadowbox') .
'resources/shadowbox/source/';
$this->extensionConfiguration = unserialize(
$GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['pmkshadowbox']
);
if ($cacheHandler === NULL) {
try {
$this->cacheHandler = t3lib_div::makeInstance(
'tx_pmkshadowbox_cache',
'typo3temp/pmkshadowbox/'
);
} catch (Exception $exception) {
t3lib_div::sysLog(
$exception->getMessage(),
'pmkshadowbox',
t3lib_div::SYSLOG_SEVERITY_ERROR
);
throw $exception;
}
} else {
$this->cacheHandler = $cacheHandler;
}
}
/**
* Destructor
*
* @return void
*/
public function __destruct() {
unset($this->cacheHandler, $this->cObj);
}
/**
* Returns the cache handler
*
* @return tx_pmkshadowbox_cache
*/
public function getCacheHandler() {
return $this->cacheHandler;
}
/**
* Applies the stdWrap typoscript property on all entries of the given array that
* are suffixed with a dot. The primitive value without a dot is overriden in this case.
*
* @parameters array $configuration typoscript configuration
* @return array normalized typoscript configuration
*/
protected function applyStdWrapOn(array $configuration) {
$newConfiguration = array();
foreach ($configuration as $label => $value) {
if (!is_array($value)) {
$newConfiguration[$label] = $value;
continue;
}
$labelWithoutDot = rtrim($label, '.');
$newConfiguration[$labelWithoutDot] = $this->cObj->stdWrap('', $value);
}
return $newConfiguration;
}
/**
* Checks the availability of the adapter and returns the given value or 'base' as an
* harcoded fallback value. It's returned as a relative path to the adapter based upon
* the TYPO3 root.
*
* @param string $adapter
* @return string
*/
protected function getAdapter($adapter) {
$adapter = $this->sourceDirectory . 'adapters/' . $adapter . '.js';
if (!file_exists(PATH_site . $adapter)) {
$adapter = $this->sourceDirectory . 'adapters/base.js';
}
return $adapter;
}
/**
* Checks the availability of the given language. The second parameter is used
* as a fallback, but the hardcoded fallback will be 'en' in any case. The method
* returns the relative path to the language based upon the TYPO3 root.
*
* Note: The language 'de' is translated into 'de-DE' to simplify the usage in the
* typoscript configuration code.
*
* @param string $language
* @param string $languageFallback
* @return string
*/
protected function getLanguage($language, $languageFallback) {
$language = ($language === 'de' ? 'de-DE' : $language);
$language = $this->sourceDirectory . 'languages/' . $language . '.js';
if (!file_exists(PATH_site . $language)) {
$languageFallback = ($languageFallback === 'de' ? 'de-DE' : $languageFallback);
$language = $this->sourceDirectory . 'languages/' .
$languageFallback . '.js';
if (!file_exists(PATH_site . $language)) {
$language = $this->sourceDirectory . 'languages/en.js';
}
}
return $language;
}
/**
* Checks the availability of the given players and returns an array with all
* available ones. The values are prefixed with the relative directory based upon
* the TYPO3 root.
*
* @param array $wantedPlayers wanted players
* @return array available players
*/
protected function getPlayers(array $wantedPlayers) {
$availablePlayers = array();
foreach ($wantedPlayers as $player) {
$player = $this->sourceDirectory . 'players/' . trim($player) . '.js';
if (file_exists(PATH_site . $player)) {
$availablePlayers[] = $player;
}
}
return $availablePlayers;
}
/**
* Checks the given typoscript configuration variable and returns the relative path
* to the sizzle javascript file based on the TYPO3 root directory. Otherwise an blank
* string will be returned.
*
* @param mixed $useSizzle see method description
* @return string
*/
protected function getCssSelectorSupport($useSizzle) {
$sizzle = '';
if ($useSizzle == 1) {
$sizzle = $this->sourceDirectory . 'find.js';
}
return $sizzle;
}
/**
* Checks the availability of the skin modification and returns the normalized, relative
* path based on the TYPO3 root directory. If the file doesn't exists a blank string is
* returned.
*
* @param string $skinModification TYPO3 path to a skin modification directory
* @return string
*/
protected function getSkinModificationDirectory($typo3SkinModificationDirectory) {
$skinModificationDirectory = t3lib_div::getFileAbsFileName($typo3SkinModificationDirectory);
if (is_dir($skinModificationDirectory)) {
$skinModificationDirectory = str_replace(PATH_site, '', $skinModificationDirectory);
} else {
$skinModificationDirectory = '';
}
return $skinModificationDirectory;
}
/**
* Checks the availability of the given flash player and returns the normalized, relative
* path based on the TYPO3 root directory. If the file doesn't exists a blank string is
* returned.
*
* @param string $flashPlayer relative path to a flash player script
* @return string
*/
protected function getFlashPlayer($flashPlayer) {
$flashPlayer = t3lib_div::getFileAbsFileName($flashPlayer);
if (file_exists($flashPlayer)) {
$flashPlayer = str_replace(PATH_site, '', $flashPlayer);
} else {
$flashPlayer = '';
}
return $flashPlayer;
}
/**
* Checks the availability of the given express install script and returns the normalized,
* relative path based on the TYPO3 root directory. If the file doesn't exists a blank
* string is returned.
*
* @param string $flashExpressInstallScript relative path to the script
* @return string
*/
protected function getFlashExpressInstallScript($flashExpressInstallScript) {
$flashExpressInstallScript = t3lib_div::getFileAbsFileName($flashExpressInstallScript);
if (file_exists($flashExpressInstallScript)) {
$flashExpressInstallScript = str_replace(PATH_site, '', $flashExpressInstallScript);
} else {
$flashExpressInstallScript = '';
}
return $flashExpressInstallScript;
}
/**
* Returns the skin modification javascript if it's exists!
*
* @param string $skinModificationDirectory
* @return string
*/
protected function getSkinModificationJavaScript($skinModificationDirectory) {
$skinModificationJavaScript = '';
if ($skinModificationDirectory !== '' &&
file_exists(PATH_site . $skinModificationDirectory . 'skin.js')
) {
$skinModificationJavaScript = $skinModificationDirectory . 'skin.js';
}
return $skinModificationJavaScript;
}
/**
* Checks the players array for the values 'flv' and 'swf'. If the match is
* positive we are returning a relative path to the flash script based on the TYPO3 root.
* Otherwise an emptry string will be returned.
*
* @param array $players
* @return string
*/
protected function needsFlash(array $players) {
$flash = '';
$playerNames = array_map('basename', $players);
if (in_array('flv.js', $playerNames) || in_array('swf.js', $playerNames)) {
$flash = $this->sourceDirectory . 'flash.js';
}
return $flash;
}
/**
* Returns the file name without the file extension from a normal path string.
*
* @param string $filePath
* @return string
*/
protected function getFileNameWithoutExtension($filePath) {
$fileName = basename($filePath);
return substr($fileName, 0, strrpos($fileName, '.'));
}
/**
* Creates the scriptfile with the name "$scriptname" based upon the array in
* "$scripts" and their defined order.
*
* @param array $scripts
* @throws Exception if a file could not be read or written
* @return string relative path to the cache file
*/
protected function createScriptFile(array $scripts) {
$scriptContent = '';
foreach ($scripts as $script) {
if (($content = file_get_contents(PATH_site . $script)) === FALSE) {
$message = 'Could not read the source file: ' . PATH_site . $script;
t3lib_div::sysLog($message, 'pmkshadowbox', t3lib_div::SYSLOG_SEVERITY_ERROR);
throw new Exception($message);
}
$scriptContent .= $content;
}
if (!t3lib_extMgm::isLoaded('scriptmerger')) {
$scriptContent = JSMin::minify($scriptContent);
}
return $this->cacheHandler->writeCacheFile('shadowbox.js', $scriptContent);
}
/**
* Copies the resources of the shadowbox source folder inside the build directory. If a
* skin modification directory is passed and the folder contains a "resources" directory,
* we copy the contents inside the build directory. This can be used to override the default
* resources of the shadowbox.
*
* @param string $skinModificationDirectory
* @return void
*/
protected function copySkinResources($skinModificationDirectory) {
// copy the default resources
$absoluteSourceDirectory = PATH_site . $this->sourceDirectory . 'resources/';
$directoryHandler = new DirectoryIterator($absoluteSourceDirectory);
$allowedFileExtensions = array('png', 'gif', 'jpg', 'css');
foreach ($directoryHandler as $fileInfo) {
if ($fileInfo->isFile()) {
$fileName = $fileInfo->getFilename();
$fileExtension = substr($fileName, strrpos($fileName, '.') + 1);
if (!in_array($fileExtension, $allowedFileExtensions)) {
continue;
}
$this->cacheHandler->copyResourceFile($fileInfo->getPathname());
}
}
// copy the skin modification resources if available
$resourceFolder = PATH_site . $skinModificationDirectory . 'resources/';
if (is_dir($resourceFolder)) {
$directoryHandler = new DirectoryIterator($resourceFolder);
foreach ($directoryHandler as $fileInfo) {
if ($fileInfo->isDot() || $fileInfo->isDir()) {
continue;
}
$this->cacheHandler->copyResourceFile($fileInfo->getPathname());
}
}
}
/**
* Copies the flash player resources to the build directory
*
* Note: The two parameters can be used to override the default resource
*
* @param string $flashPlayer relative path to an alternative flash player (default: blank)
* @param string $expressInstallScript relative path to an express install script (default: blank)
* @return void
*/
protected function copyFlashResources($flashPlayer = '', $expressInstallScript = '') {
if ($flashPlayer === '') {
$flashPlayer = $this->sourceDirectory . 'resources/player.swf';
}
$this->cacheHandler->copyResourceFile(PATH_site . $flashPlayer, 'player.swf');
if ($expressInstallScript === '') {
$expressInstallScript = $this->sourceDirectory . 'resources/expressInstall.swf';
}
$this->cacheHandler->copyResourceFile(PATH_site . $expressInstallScript, 'expressInstall.swf');
}
/**
* Returns the name of the build directory based upon the given configuration.
*
* @param array $configuration
* @return string
*/
protected function getNameOfBuildDirectory(array $configuration) {
$playerNames = array_map(
array($this, 'getFileNameWithoutExtension'),
$configuration['players']
);
$playerNames = implode('-', $playerNames);
$flashPlayerName = '';
if ($configuration['flashPlayer'] !== '') {
$flashPlayerName = '-' . $this->getFileNameWithoutExtension($configuration['flashPlayer']);
}
$flashExpressInstallScriptName = '';
if ($configuration['flashExpressInstallScript'] !== '') {
$flashExpressInstallScriptName = '-' . $this->
getFileNameWithoutExtension($configuration['flashExpressInstallScript']);
}
$buildDirectory = $this->getFileNameWithoutExtension($configuration['adapter']) . '-' .
$this->getFileNameWithoutExtension($configuration['language']);
$buildDirectory .= ($playerNames !== '' ? '-' . $playerNames : '');
$buildDirectory .= ($configuration['useSizzle'] !== '' ? '-sizzle' : '');
$buildDirectory .= ($configuration['skinModificationDirectory'] !== '' ? '-' .
basename($configuration['skinModificationDirectory']) : '');
$buildDirectory .= $flashPlayerName . $flashExpressInstallScriptName;
$buildDirectory .= '/';
return $buildDirectory;
}
/**
* Returns an array with the shadowbox source javascripts and modifications in the
* needed order.
*
* @param array $configuration
* @return array
*/
protected function getOrderedScripts(array $configuration) {
$scripts = array_merge(
array(
$this->sourceDirectory . 'intro.js',
$this->sourceDirectory . 'core.js',
$this->sourceDirectory . 'util.js',
$configuration['adapter'],
$this->sourceDirectory . 'load.js',
$this->sourceDirectory . 'plugins.js',
$this->sourceDirectory . 'cache.js',
$configuration['useSizzle'], $configuration['useFlash'], $configuration['language']
), $configuration['players'], array(
$this->sourceDirectory . 'skin.js',
$this->getSkinModificationJavaScript($configuration['skinModificationDirectory']),
$this->sourceDirectory . 'outro.js'
)
);
return t3lib_div::removeArrayEntryByValue($scripts, '');
}
/**
* This function builds a new shadowbox directory from the sources based upon the
* selected configuration. The new directory is saved inside "typo3temp/pmkshadowbox".