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
This diff is collapsed.
<?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!
***************************************************************/
/**
* This class handles all cache directory operations.
*
* @author Stefan Galinski <stefan.galinski@gmail.com>
*/
class tx_pmkshadowbox_cache {
/**
* Path to the Cache Directory
*
* @var string
*/
protected $cacheDirectory = '';
/**
* Build Directory Name
*
* @var string
*/
protected $buildDirectory = '';
/**
* Constructor
*
* Note: The cache directory is created if it does not already exists!
*
* @param string $cacheDirectory
* @return void
*/
public function __construct($cacheDirectory = 'typo3temp/pmkshadowbox/') {
$this->cacheDirectory = $cacheDirectory;
if (!is_dir(PATH_site . $this->cacheDirectory)) {
if (!t3lib_div::mkdir(PATH_site . $this->cacheDirectory)) {
$message = 'Cache directory "' . PATH_site . $this->cacheDirectory .
'" couldn\'t be created!';
t3lib_div::sysLog($message, 'pmkshadowbox', t3lib_div::SYSLOG_SEVERITY_ERROR);
throw new Exception($message);
}
}
}
/**
* Returns the cache directory
*
* @return string cache directory
*/
public function getCacheDirectory() {
return $this->cacheDirectory;
}
/**
* Sets the build directory name
*
* Note: The directory is immediatly created!
*
* @param string $buildDirectory
* @return void
*/
public function setBuildDirectory($buildDirectory) {
$this->buildDirectory = $buildDirectory;
if (!is_dir(PATH_site . $this->cacheDirectory . $this->buildDirectory)) {
t3lib_div::mkdir(PATH_site . $this->cacheDirectory . $this->buildDirectory);
}
}
/**
* Removes all files and directories inside the cache directory
*
* @throws Exception if a file or directory couldn't be deleted
* @return void
*/
public function clear() {
$cacheDirectoryIterator = new DirectoryIterator(PATH_site . $this->cacheDirectory);
foreach ($cacheDirectoryIterator as $fileInfo) {
if ($fileInfo->isDot() || !$fileInfo->isDir()) {
continue;
}
foreach (new DirectoryIterator($fileInfo->getPathname()) as $cacheFileInfo) {
if ($cacheFileInfo->isDot()) {
continue;
}
if (unlink($cacheFileInfo->getPathname()) === FALSE) {
$message = 'cache->clear(): File "' .
$cacheFileInfo->getPathname() . '" couldn\'t be removed!';
t3lib_div::sysLog($message, 'pmkshadowbox', t3lib_div::SYSLOG_SEVERITY_ERROR);
throw new Exception($message);
}
}
if (rmdir($fileInfo->getPathname()) === FALSE) {
$message = 'cache->clear(): Build directory "' .
$fileInfo->getPathname() . '" couldn\'t be removed!';
t3lib_div::sysLog($message, 'pmkshadowbox', t3lib_div::SYSLOG_SEVERITY_ERROR);
throw new Exception($message);
}
}
}
/**
* Writes the cache file "shadowbox.js" into the given build directory
*
* @param string $scriptName
* @param string $scriptContent
* @throws Exception if the file could not be written
* @return string relative path to the written cache file
*/
public function writeCacheFile($scriptName, $scriptContent) {
$script = $this->cacheDirectory . $this->buildDirectory . $scriptName;
if (t3lib_div::writeFile(PATH_site . $script, $scriptContent) === FALSE) {
$message = 'cache->writeCacheFile: Could not write the script file: ' . $script;
t3lib_div::sysLog($message, 'pmkshadowbox', t3lib_div::SYSLOG_SEVERITY_ERROR);
throw new Exception($message);
}
return $script;
}
/**
* Copies a resource to the build directory and returns the relative path to the
* copied resource.
*
* @param string $resource absolute path to the resource file
* @param string $fileName new name of the resource file (default: name of the resource file)
* @throws Exception if the resource could not be copied
* @return string
*/
public function copyResourceFile($resource, $fileName = '') {
if ($fileName === '') {
$fileName = basename($resource);
}
$destination = $this->cacheDirectory . $this->buildDirectory . $fileName;
if (copy($resource, PATH_site . $destination) === FALSE) {
$message = 'cache->copyResourceFile: Resource "' .
$resource . '" couldn\'t be copied!';
t3lib_div::sysLog($message, 'pmkshadowbox', t3lib_div::SYSLOG_SEVERITY_ERROR);
throw new Exception($message);
}
return $destination;
}
/**
* Returns the relative path to the cache file directory.
*
* @return string
*/
public function getPathToBuildDirectory() {
return $this->getCacheDirectory() . $this->buildDirectory;
}
/**
* Clear cache post processing hook
*
* @param array $parameters
* @param object $parent
* @return void
*/
public function clearCachePostProc($parameters, $parent) {
if ($parameters['cacheCmd'] === 'all') {
$this->clear();
}
}
}
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/pmkshadowbox/classes/class.tx_pmkshadowbox_cache.php']) {
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/pmkshadowbox/classes/class.tx_pmkshadowbox_cache.php']);
}
?>
<?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!
***************************************************************/
require_once (PATH_typo3 . 'interfaces/interface.backend_cacheActionsHook.php');
/**
* Extending class to render the menu for the cache clearing actions,
* and adding Clear Shadowbox Builds option
*
* @author Stefan Galinski <stefan.galinski@gmail.com>
* @package TYPO3
* @subpackage pmkshadowbox
*/
class tx_pmkshadowbox_clearcachemenu implements backend_cacheActionsHook {
/**
* Adds a new entry to the cache menu items array
*
* @param array array Cache menu items
* @param array array of access configuration identifiers (typically used by userTS with options.clearCache.identifier)
* @return void
*/
public function manipulateCacheActions(&$cacheActions, &$optionValues) {
if ($GLOBALS['BE_USER']->isAdmin()) {
$title = $GLOBALS['LANG']->sL('LLL:EXT:pmkshadowbox/locallang.xml:clearCacheTitle');
$cacheActions[] = array (
'id' => 'clearShadowboxBuilds',
'title' => $title,
'href' => $GLOBALS['BACK_PATH'] . 'ajax.php?ajaxID=pmkshadowbox::clearShadowboxBuilds',
'icon' => '<img src="' . t3lib_extMgm::extRelPath('pmkshadowbox') .
'ext_icon.gif" width="16" height="16" title="' . htmlspecialchars($title) . '" alt="" />'
);
$optionValues[] = 'clearShadowboxBuilds';
}
}
}
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/pmkshadowbox/classes/class.tx_pmkshadowbox_clearcachemenu.php']) {
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/pmkshadowbox/classes/class.tx_pmkshadowbox_clearcachemenu.php']);
}
?>
<?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!
***************************************************************/
/**
* This class contains a hook class for modifying the tt_news image markers
* It just add a "IMAGE_NUM_CURRENT" register value, so that pmkshadowbox
* can use navigation on tt_news images.
*
* @author Peter Klein <pmk@io.dk>
*/
class tx_ttnews_imageMarker extends tslib_pibase {
var $prefixId = "tx_ttnews_imageMarkerHook"; // Same as class name
var $scriptRelPath = "class.tx_ttnews_imageMarkerHook.php"; // Path to this script relative to the extension dir.
var $extKey = "tt_news"; // The extension key.
function extraItemMarkerProcessor($parentMarkerArray, $row, $lConf, $tt_news) {
$tt_news->pi_setPiVarDefaults();
$this->pi_loadLL();
$this->conf = &$tt_news->conf;
$this->makeImageMarkers($row,$lConf,$tt_news,$parentMarkerArray);
return $parentMarkerArray;
}
function makeImageMarkers($row,$lConf,$tt_news,&$parentMarkerArray) {
$imageNum = isset($lConf['imageCount']) ? $lConf['imageCount'] : 1;
$imageNum = t3lib_div::intInRange($imageNum, 0, 100);
$theImgCode = '';
$imgs = t3lib_div::trimExplode(',', $row['image'], 1);
$imgsCaptions = explode(chr(10), $row['imagecaption']);
$imgsAltTexts = explode(chr(10), $row['imagealttext']);
$imgsTitleTexts = explode(chr(10), $row['imagetitletext']);
$textRenderObj = $tt_news->theCode;
reset($imgs);
if ($textRenderObj == 'displaySingle' || $textRenderObj == 'SINGLE') {
$parentMarkerArray = $this->getSingleViewImages($lConf, $imgs, $imgsCaptions, $imgsAltTexts, $imgsTitleTexts, $imageNum, $parentMarkerArray,$tt_news);
} else {
$imageMode = (strpos($textRenderObj, 'LATEST') ? $lConf['latestImageMode'] : $lConf['listImageMode']);
$suf = '';
if (is_numeric(substr($lConf['image.']['file.']['maxW'], - 1))) { // 'm' or 'c' not set by TS
if ($imageMode) {
switch ($imageMode) {
case 'resize2max' :
$suf = 'm';
break;
case 'crop' :
$suf = 'c';
break;
case 'resize' :
$suf = '';
break;
}
}
}
// only insert width/height if it is not given by TS and width/height is empty
if ($lConf['image.']['file.']['maxW'] && ! $lConf['image.']['file.']['width']) {
$lConf['image.']['file.']['width'] = $lConf['image.']['file.']['maxW'] . $suf;
unset($lConf['image.']['file.']['maxW']);
}
if ($lConf['image.']['file.']['maxH'] && ! $lConf['image.']['file.']['height']) {
$lConf['image.']['file.']['height'] = $lConf['image.']['file.']['maxH'] . $suf;
unset($lConf['image.']['file.']['maxH']);
}
$cc = 0;
foreach ($imgs as $val) {
if ($cc == $imageNum)
break;
if ($val) {
$lConf['image.']['altText'] = $imgsAltTexts[$cc];
$lConf['image.']['titleText'] = $imgsTitleTexts[$cc];
$lConf['image.']['file'] = 'uploads/pics/' . $val;
$GLOBALS['TSFE']->register['IMAGE_NUM_CURRENT'] = $cc;
$theImgCode .= $tt_news->local_cObj->IMAGE($lConf['image.']) . $tt_news->local_cObj->stdWrap($imgsCaptions[$cc], $lConf['caption_stdWrap.']);
}
$cc++;
}
if ($cc) {
$parentMarkerArray['###NEWS_IMAGE###'] = $tt_news->local_cObj->wrap($theImgCode, $lConf['imageWrapIfAny']);
} else {
$parentMarkerArray['###NEWS_IMAGE###'] = $tt_news->local_cObj->stdWrap($parentMarkerArray['###NEWS_IMAGE###'], $lConf['image.']['noImage_stdWrap.']);
}
}
}
/**
* Fills the image markers for the SINGLE view with data. Supports Optionssplit for some parameters
*
* @param [type] $lConf: ...
* @param [type] $imgs: ...
* @param [type] $imgsCaptions: ...
* @param [type] $imgsAltTexts: ...
* @param [type] $imgsTitleTexts: ...
* @param [type] $imageNum: ...
* @return array $markerArray: filled markerarray
*/
function getSingleViewImages($lConf, $imgs, $imgsCaptions, $imgsAltTexts, $imgsTitleTexts, $imageNum, $markerArray,$tt_news) {
$marker = 'NEWS_IMAGE';
$sViewSplitLConf = array();
$tmpMarkers = array();
$iC = count($imgs);
// remove first img from image array in single view if the TSvar firstImageIsPreview is set
if (($iC > 1 && $tt_news->config['firstImageIsPreview']) || ($iC >= 1 && $tt_news->config['forceFirstImageIsPreview'])) {
array_shift($imgs);
array_shift($imgsCaptions);
array_shift($imgsAltTexts);
array_shift($imgsTitleTexts);
$iC--;
}
if ($iC > $imageNum) {
$iC = $imageNum;
}
// get img array parts for single view pages
if ($tt_news->piVars[$tt_news->config['singleViewPointerName']]) {
$spage = $tt_news->piVars[$tt_news->config['singleViewPointerName']];
$astart = $imageNum * $spage;
$imgs = array_slice($imgs, $astart, $imageNum);
$imgsCaptions = array_slice($imgsCaptions, $astart, $imageNum);
$imgsAltTexts = array_slice($imgsAltTexts, $astart, $imageNum);
$imgsTitleTexts = array_slice($imgsTitleTexts, $astart, $imageNum);
}
if ($tt_news->conf['enableOptionSplit']) {
if ($lConf['imageMarkerOptionSplit']) {
$ostmp = explode('|*|', $lConf['imageMarkerOptionSplit']);
$osCount = count($ostmp);
}
$sViewSplitLConf = $tt_news->processOptionSplit($lConf, $iC);
}
// reset markers for optionSplitted images
for ($m = 1; $m <= $imageNum; $m++) {
$markerArray['###' . $marker . '_' . $m . '###'] = '';
}
$cc = 0;
foreach ($imgs as $val) {
if ($cc == $imageNum)
break;
if ($val) {
if (! empty($sViewSplitLConf[$cc])) {
$lConf = $sViewSplitLConf[$cc];
}
$lConf['image.']['altText'] = $imgsAltTexts[$cc];
$lConf['image.']['titleText'] = $imgsTitleTexts[$cc];
$lConf['image.']['file'] = 'uploads/pics/' . $val;
$GLOBALS['TSFE']->register['IMAGE_NUM_CURRENT'] = $cc;
$imgHtml = $tt_news->local_cObj->IMAGE($lConf['image.']) . $tt_news->local_cObj->stdWrap($imgsCaptions[$cc], $lConf['caption_stdWrap.']);
if ($osCount) {
if ($iC > 1) {
$mName = '###' . $marker . '_' . $lConf['imageMarkerOptionSplit'] . '###';
} else { // fall back to the first image marker if only one image has been found
$mName = '###' . $marker . '_1###';
}
$tmpMarkers[$mName]['html'] .= $imgHtml;
$tmpMarkers[$mName]['wrap'] = $lConf['imageWrapIfAny'];
} else {
$theImgCode .= $imgHtml;
}
}
$cc++;
}
if ($cc) {
if ($osCount) {
foreach ($tmpMarkers as $mName => $res) {
$markerArray[$mName] = $tt_news->local_cObj->wrap($res['html'], $res['wrap']);
}