Project

General

Profile

Feature #20203 » 10718_tcefile_ajax.patch

Administrator Admin, 2009-03-18 12:32

View differences:

t3lib/config_default.php (Arbeitskopie)
'AJAX' => array( // array of key-value pairs for a unified use of AJAX calls in the TYPO3 backend. Keys are the unique ajaxIDs where the value will be resolved to call a method in an object. See ajax.php and the classes/class.typo3ajax.php for more information.
'SC_alt_db_navframe::expandCollapse' => 'typo3/alt_db_navframe.php:SC_alt_db_navframe->ajaxExpandCollapse',
'SC_alt_file_navframe::expandCollapse' => 'typo3/alt_file_navframe.php:SC_alt_file_navframe->ajaxExpandCollapse',
'tcefile::process' => 'typo3/classes/class.typo3_tcefile.php:TYPO3_tcefile->processAjaxRequest',
't3lib_TCEforms_inline::createNewRecord' => 't3lib/class.t3lib_tceforms_inline.php:t3lib_TCEforms_inline->processAjaxRequest',
't3lib_TCEforms_inline::synchronizeLocalizeRecords' => 't3lib/class.t3lib_tceforms_inline.php:t3lib_TCEforms_inline->processAjaxRequest',
't3lib_TCEforms_inline::setExpandedCollapsedState' => 't3lib/class.t3lib_tceforms_inline.php:t3lib_TCEforms_inline->processAjaxRequest',
t3lib/class.t3lib_extfilefunc.php (Arbeitskopie)
/***************************************************************
* Copyright notice
*
* (c) 1999-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
* (c) 1999-2008 Kasper Skaarhoj (kasperYYYY@typo3.com)
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
......
/**
* Processing the command array in $this->fileCmdMap
*
* @return void
* @return mixed false, if the file functions were not initialized
* otherwise returns an array of all the results that are returned
* from each command, separated in each action.
*/
function processData() {
if (!$this->isInit) return FALSE;
function processData() {
$result = array();
if (!$this->isInit) {
return false;
}
if (is_array($this->fileCmdMap)) {
if (is_array($this->fileCmdMap)) {
// Check if there were uploads expected, but no one made
if ($this->fileCmdMap['upload']) {
if ($this->fileCmdMap['upload']) {
$uploads = $this->fileCmdMap['upload'];
foreach ($uploads as $arr) {
if (!$_FILES['upload_'.$arr['data']]['name']) {
unset($this->fileCmdMap['upload'][$arr['data']]);
foreach ($uploads as $upload) {
if (!$_FILES['upload_' . $upload['data']]['name']) {
unset($this->fileCmdMap['upload'][$upload['data']]);
}
}
if (count($this->fileCmdMap['upload']) == 0) {
......
}
// Traverse each set of actions
foreach($this->fileCmdMap as $action => $actionData) {
foreach ($this->fileCmdMap as $action => $actionData) {
// Traverse all action data. More than one file might be affected at the same time.
if (is_array($actionData)) {
foreach($actionData as $cmdArr) {
if (is_array($actionData)) {
$result[$action] = array();
foreach ($actionData as $cmdArr) {
// Clear file stats
clearstatcache();
// Branch out based on command:
switch ($action) {
switch ($action) {
case 'delete':
$this->func_delete($cmdArr);
$result[$action][] = $this->func_delete($cmdArr);
break;
case 'copy':
$this->func_copy($cmdArr);
$result[$action][] = $this->func_copy($cmdArr);
break;
case 'move':
$this->func_move($cmdArr);
$result[$action][] = $this->func_move($cmdArr);
break;
case 'rename':
$this->func_rename($cmdArr);
$result[$action][] = $this->func_rename($cmdArr);
break;
case 'newfolder':
$this->func_newfolder($cmdArr);
$result[$action][] = $this->func_newfolder($cmdArr);
break;
case 'newfile':
$this->func_newfile($cmdArr);
$result[$action][] = $this->func_newfile($cmdArr);
break;
case 'editfile':
$this->func_edit($cmdArr);
$result[$action][] = $this->func_edit($cmdArr);
break;
case 'upload':
$this->func_upload($cmdArr);
$result[$action][] = $this->func_upload($cmdArr);
break;
case 'unzip':
$this->func_unzip($cmdArr);
$result[$action][] = $this->func_unzip($cmdArr);
break;
}
}
}
}
}
return $result;
}
/**
......
* @param string Redirect URL (for creating link in message)
* @return void (Will exit on error)
*/
function printLogErrorMessages($redirect='') {
function printLogErrorMessages($redirect = '') {
// fetch the error messages from the DB
$errorMessages = $this->getErrorMessages();
$res_log = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'*',
'sys_log',
'type=2 AND userid='.intval($GLOBALS['BE_USER']->user['uid']).' AND tstamp='.intval($GLOBALS['EXEC_TIME']).' AND error!=0'
);
$errorJS = array();
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res_log)) {
$log_data = unserialize($row['log_data']);
$errorJS[] = $row[error].': '.sprintf($row['details'], $log_data[0],$log_data[1],$log_data[2],$log_data[3],$log_data[4]);
}
// only print error messages if there is an error
if (count($errorMessages)) {
$errorDoc = t3lib_div::makeInstance('template');
$errorDoc->backPath = '';
if (count($errorJS)) {
$error_doc = t3lib_div::makeInstance('template');
$error_doc->backPath = '';
$content = $errorDoc->startPage('tce_db.php Error output');
$content.= $error_doc->startPage('tce_db.php Error output');
$lines[] = '
<tr class="bgColor5">
<td colspan="2" align="center"><strong>Errors:</strong></td>
</tr>';
foreach($errorJS as $line) {
foreach ($errorMessages as $line) {
$lines[] = '
<tr class="bgColor4">
<td valign="top"><img'.t3lib_iconWorks::skinImg('','gfx/icon_fatalerror.gif','width="18" height="16"').' alt="" /></td>
<td>'.htmlspecialchars($line).'</td>
<td valign="top"><img' . t3lib_iconWorks::skinImg('', 'gfx/icon_fatalerror.gif', 'width="18" height="16"') . ' alt="" /></td>
<td>' . htmlspecialchars($line) . '</td>
</tr>';
}
$lines[] = '
<tr>
<td colspan="2" align="center"><br />'.
'<form action=""><input type="submit" value="Continue" onclick="'.htmlspecialchars('window.location.href=\''.$redirect.'\';return false;').'" /></form>'.
'<form action=""><input type="submit" value="Continue" onclick="'.htmlspecialchars('window.location.href=\'' . $redirect . '\';return false;').'" /></form>'.
'</td>
</tr>';
$content.= '
$content .= '
<br /><br />
<table border="0" cellpadding="1" cellspacing="1" width="300" align="center">
'.implode('',$lines).'
' . implode('', $lines) . '
</table>';
$content.= $error_doc->endPage();
echo $content;
exit;
$content .= $errorDoc->endPage();
die($content);
}
}
/**
* Returns log error messages from the previous file operations of this script instance
*
* @return array all errorMessages as a numerical array
*/
function getErrorMessages() {
$errorMessages = array();
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'*',
'sys_log',
'type = 2 AND userid = ' . intval($GLOBALS['BE_USER']->user['uid'])
. ' AND tstamp=' . intval($GLOBALS['EXEC_TIME'])
. ' AND error != 0'
);
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
$logData = unserialize($row['log_data']);
$errorMessages[] = $row['error'] . ': ' . sprintf($row['details'], $logData[0], $logData[1], $logData[2], $logData[3], $logData[4]);
}
return $errorMessages;
}
/**
* Goes back in the path and checks in each directory if a folder named $this->recyclerFN (usually '_recycler_') is present.
* If a folder in the tree happens to be a _recycler_-folder (which means that we're deleting something inside a _recycler_-folder) this is ignored
*
......
/**
* Upload of files (action=1)
*
* @param array $cmds['data'] is the ID-number (points to the global var that holds the filename-ref ($_FILES['upload_'.$id]['name']). $cmds['target'] is the target directory
* @param array $cmds['data'] is the ID-number (points to the global var that holds the filename-ref ($_FILES['upload_'.$id]['name']). $cmds['target'] is the target directory, $cmds['charset'] is the the character set of the file name (utf-8 is needed for JS-interaction)
* @return string Returns the new filename upon success
*/
function func_upload($cmds) {
......
if ($_FILES['upload_'.$id]['name']) {
$theFile = $_FILES['upload_'.$id]['tmp_name']; // filename of the uploaded file
$theFileSize = $_FILES['upload_'.$id]['size']; // filesize of the uploaded file
$theName = $this->cleanFileName(stripslashes($_FILES['upload_'.$id]['name'])); // The original filename
$theName = $this->cleanFileName(stripslashes($_FILES['upload_'.$id]['name']), (isset($cmds['charset']) ? $cmds['charset'] : '')); // The original filename
if (is_uploaded_file($theFile) && $theName) { // Check the file
if ($this->actionPerms['uploadFile']) {
if ($theFileSize<($this->maxUploadFileSize*1024)) {
typo3/tce_file.php (Arbeitskopie)
/**
* Gateway for TCE (TYPO3 Core Engine) file-handling through POST forms.
* This script serves as the fileadministration part of the TYPO3 Core Engine.
* Basically it includes two libraries which are used to manipulate files on the server.
*
* For syntax and API information, see the document 'TYPO3 Core APIs'
*
* For TYPO3 4.3 the class in this file was extracted to typo3/classes/class.typo3_tcefile.php
* in order to separate the actual script call from the core class, and to make use
* of the class in a separate context (mainly AJAX)
*
* $Id$
* Revised for TYPO3 3.6 July/2003 by Kasper Skaarhoj
* Revised for TYPO3 4.3 Mar/2009 by Benjamin Mack
*
* @author Kasper Skaarhoj <kasperYYYY@typo3.com>
*/
/**
* [CLASS/FUNCTION INDEX of SCRIPT]
*
*
*
* 77: class SC_tce_file
* 97: function init()
* 117: function initClipboard()
* 138: function main()
* 164: function finish()
*
* TOTAL FUNCTIONS: 4
* (This index is automatically created/updated by the extension "extdeveval")
*
*/
require('init.php');
require('template.php');
require_once(PATH_t3lib . 'class.t3lib_basicfilefunc.php');
require_once(PATH_t3lib . 'class.t3lib_extfilefunc.php');
require_once('init.php');
require_once('classes/class.typo3_tcefile.php');
/**
* Script Class, handling the calling of methods in the file admin classes.
*
* @author Kasper Skaarhoj <kasperYYYY@typo3.com>
* @package TYPO3
* @subpackage core
*/
class SC_tce_file {
// Internal, static: GPvar:
var $file; // Array of file-operations.
var $redirect; // Redirect URL
var $CB; // Clipboard operations array
var $overwriteExistingFiles; // If existing files should be overridden.
var $vC; // VeriCode - a hash of server specific value and other things which identifies if a submission is OK. (see $BE_USER->veriCode())
// Internal, dynamic:
var $include_once = array(); // Used to set the classes to include after the init() function is called.
var $fileProcessor; // File processor object
/**
* Registering Incoming data
*
* @return void
*/
function init() {
// GPvars:
$this->file = t3lib_div::_GP('file');
$this->redirect = t3lib_div::_GP('redirect');
$this->CB = t3lib_div::_GP('CB');
$this->overwriteExistingFiles = t3lib_div::_GP('overwriteExistingFiles');
$this->vC = t3lib_div::_GP('vC');
// If clipboard is set, then include the clipboard class:
if (is_array($this->CB)) {
$this->include_once[] = PATH_t3lib . 'class.t3lib_clipboard.php';
}
}
/**
* Initialize the Clipboard. This will fetch the data about files to paste/delete if such an action has been sent.
*
* @return void
*/
function initClipboard() {
if (is_array($this->CB)) {
$clipObj = t3lib_div::makeInstance('t3lib_clipboard');
$clipObj->initializeClipboard();
if ($this->CB['paste']) {
$clipObj->setCurrentPad($this->CB['pad']);
$this->file = $clipObj->makePasteCmdArray_file($this->CB['paste'], $this->file);
}
if ($this->CB['delete']) {
$clipObj->setCurrentPad($this->CB['pad']);
$this->file = $clipObj->makeDeleteCmdArray_file($this->file);
}
}
}
/**
* Performing the file admin action:
* Initializes the objects, setting permissions, sending data to object.
*
* @return void
*/
function main() {
global $FILEMOUNTS,$TYPO3_CONF_VARS,$BE_USER;
// Initializing:
$this->fileProcessor = t3lib_div::makeInstance('t3lib_extFileFunctions');
$this->fileProcessor->init($GLOBALS['FILEMOUNTS'], $GLOBALS['TYPO3_CONF_VARS']['BE']['fileExtensions']);
$this->fileProcessor->init_actionPerms($GLOBALS['BE_USER']->getFileoperationPermissions());
$this->fileProcessor->dontCheckForUnique = $this->overwriteExistingFiles ? 1 : 0;
// Checking referer / executing:
$refInfo = parse_url(t3lib_div::getIndpEnv('HTTP_REFERER'));
$httpHost = t3lib_div::getIndpEnv('TYPO3_HOST_ONLY');
if ($httpHost != $refInfo['host'] && $this->vC != $GLOBALS['BE_USER']->veriCode() && !$GLOBALS['TYPO3_CONF_VARS']['SYS']['doNotCheckReferer']) {
$this->fileProcessor->writeLog(0, 2, 1, 'Referer host "%s" and server host "%s" did not match!', array($refInfo['host'], $httpHost));
} else {
$this->fileProcessor->start($this->file);
$this->fileProcessor->processData();
}
}
/**
* Redirecting the user after the processing has been done.
* Might also display error messages directly, if any.
*
* @return void
*/
function finish() {
// Prints errors, if...
$this->fileProcessor->printLogErrorMessages($this->redirect);
t3lib_BEfunc::getSetUpdateSignal('updateFolderTree');
if ($this->redirect) {
Header('Location: '.t3lib_div::locationHeaderUrl($this->redirect));
}
}
}
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/tce_file.php']) {
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/tce_file.php']);
}
// Make instance:
$SOBE = t3lib_div::makeInstance('SC_tce_file');
$SOBE = t3lib_div::makeInstance('TYPO3_tcefile');
$SOBE->init();
// Include files?
foreach ($SOBE->include_once as $INC_FILE) {
include_once($INC_FILE);
}
$SOBE->initClipboard();
$SOBE->main();
$SOBE->finish();
typo3/classes/class.typo3_tcefile.php (Revision 0)
<?php
/***************************************************************
* Copyright notice
*
* (c) 1999-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
* (c) 2009 Benjamin Mack (benni.typo3.org)
* 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!
***************************************************************/
/**
* Gateway for TCE (TYPO3 Core Engine) file-handling through POST forms.
* This script serves as the fileadministration part of the TYPO3 Core Engine.
* Basically it includes two libraries which are used to manipulate files on the server.
* Before TYPO3 4.3, it was located in typo3/tce_file.php and redirected back to a
* $redirectURL. Since 4.3 this class is also used for accessing via AJAX
*
*
* For syntax and API information, see the document 'TYPO3 Core APIs'
*
* Revised for TYPO3 3.6 July/2003 by Kasper Skaarhoj
* Revised for TYPO3 4.3 Mar/2009 by Benjamin Mack
*
* @author Kasper Skaarhoj <kasperYYYY@typo3.com>
*/
require_once(PATH_typo3 . 'template.php');
require_once(PATH_t3lib . 'class.t3lib_basicfilefunc.php');
require_once(PATH_t3lib . 'class.t3lib_extfilefunc.php');
require_once(PATH_t3lib . 'class.t3lib_clipboard.php');
/**
* Script Class, handling the calling of methods in the file admin classes.
*
* @author Kasper Skaarhoj <kasperYYYY@typo3.com>
* @package TYPO3
* @subpackage core
*/
class TYPO3_tcefile {
// Internal, static: GPvar:
// Array of file-operations.
protected $file;
// Clipboard operations array
protected $CB;
// If existing files should be overridden.
protected $overwriteExistingFiles;
// VeriCode - a hash of server specific value and other things which
// identifies if a submission is OK. (see $BE_USER->veriCode())
protected $vC;
// the page where the user should be redirected after everything is done
protected $redirect;
// Internal, dynamic:
// File processor object
protected $fileProcessor;
// the result array from the file processor
protected $fileData;
/**
* Registering incoming data
*
* @return void
*/
public function init() {
// set the GPvars from outside
$this->file = t3lib_div::_GP('file');
$this->CB = t3lib_div::_GP('CB');
$this->overwriteExistingFiles = t3lib_div::_GP('overwriteExistingFiles');
$this->vC = t3lib_div::_GP('vC');
$this->redirect = t3lib_div::_GP('redirect');
$this->initClipboard();
}
/**
* Initialize the Clipboard. This will fetch the data about files to paste/delete if such an action has been sent.
*
* @return void
*/
public function initClipboard() {
if (is_array($this->CB)) {
$clipObj = t3lib_div::makeInstance('t3lib_clipboard');
$clipObj->initializeClipboard();
if ($this->CB['paste']) {
$clipObj->setCurrentPad($this->CB['pad']);
$this->file = $clipObj->makePasteCmdArray_file($this->CB['paste'], $this->file);
}
if ($this->CB['delete']) {
$clipObj->setCurrentPad($this->CB['pad']);
$this->file = $clipObj->makeDeleteCmdArray_file($this->file);
}
}
}
/**
* Performing the file admin action:
* Initializes the objects, setting permissions, sending data to object.
*
* @return void
*/
public function main() {
// Initializing:
$this->fileProcessor = t3lib_div::makeInstance('t3lib_extFileFunctions');
$this->fileProcessor->init($GLOBALS['FILEMOUNTS'], $GLOBALS['TYPO3_CONF_VARS']['BE']['fileExtensions']);
$this->fileProcessor->init_actionPerms($GLOBALS['BE_USER']->getFileoperationPermissions());
$this->fileProcessor->dontCheckForUnique = ($this->overwriteExistingFiles ? 1 : 0);
// Checking referer / executing:
$refInfo = parse_url(t3lib_div::getIndpEnv('HTTP_REFERER'));
$httpHost = t3lib_div::getIndpEnv('TYPO3_HOST_ONLY');
if ($httpHost != $refInfo['host']
&& $this->vC != $GLOBALS['BE_USER']->veriCode()
&& !$GLOBALS['TYPO3_CONF_VARS']['SYS']['doNotCheckReferer']
&& $GLOBALS['CLIENT']['BROWSER'] != 'flash') {
$this->fileProcessor->writeLog(0, 2, 1, 'Referer host "%s" and server host "%s" did not match!', array($refInfo['host'], $httpHost));
} else {
$this->fileProcessor->start($this->file);
$this->fileData = $this->fileProcessor->processData();
}
}
/**
* Redirecting the user after the processing has been done.
* Might also display error messages directly, if any.
*
* @return void
*/
public function finish() {
// Prints errors, if there are any
$this->fileProcessor->printLogErrorMessages($this->redirect);
t3lib_BEfunc::getSetUpdateSignal('updateFolderTree');
if ($this->redirect) {
header('Location: ' . t3lib_div::locationHeaderUrl($this->redirect));
}
}
/**
* Handles the actual process from within the ajaxExec function
* therefore, it does exactly the same as the real typo3/tce_file.php
* but without calling the "finish" method, thus makes it simpler to deal with the
* actual return value
*
*
* @param string $params always empty.
* @param string $ajaxObj The Ajax object used to return content and set content types
* @return void
*/
public function processAjaxRequest($params = array(), TYPO3AJAX &$ajaxObj = null) {
$this->init();
$this->main();
$errors = $this->fileProcessor->getErrorMessages();
if (count($errors)) {
$ajaxObj->setError(implode(',', $errors));
} else {
$ajaxObj->addContent('result', $this->fileData);
if ($this->redirect) {
$ajaxObj->addContent('redirect', $this->redirect);
}
$ajaxObj->setContentFormat('json');
}
}
}
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/classes/class.typo3_tcefile.php']) {
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/classes/class.typo3_tcefile.php']);
}
?>
(1-1/2)