Project

General

Profile

Feature #17970 » 20080107_ajax_interface.patch

Administrator Admin, 2008-01-07 12:11

View differences:

t3lib/config_default.php (working copy)
'flexFormXMLincludeDiffBase' => TRUE, // If set, an additional tag with index "vXX.vDEFbase" is created for translations in flexforms holding the value of the default language when translation was changed. Used to show diff of value. This setting will change whether the system thinks flexform XML looks clean. For example when FALSE XX.vDEFbase fields will be removed in cleaning while accepted if TRUE (of course)
'compactFlexFormXML' => 0, // If set, the flexform XML will not contain indentation spaces making XML more compact
'elementVersioningOnly' => FALSE, // If true, only element versioning is allowed in the backend. This is recommended for new installations of TYPO3 4.2+ since "page" and "branch" versioning types are known for the drawbacks of loosing ids and "element" type versions supports moving now.
'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.
'pagetreeExpandCollapse' => 'typo3/alt_db_navframe.php:SC_alt_db_navframe->ajaxExpandCollapse',
),
),
'FE' => Array( // Configuration for the TypoScript frontend (FE). Nothing here relates to the administration backend!
'png_to_gif' => 0, // Boolean. Enables conversion back to gif of all png-files generated in the frontend libraries. Notice that this leaves an increased number of temporary files in typo3temp/
t3lib/class.t3lib_div.php (working copy)
* @param mixed Reference to be passed along (typically "$this" - being a reference to the calling object) (REFERENCE!)
* @param string Required prefix of class or function name
* @param boolean If set, no debug() error message is shown if class/function is not present.
* @return mixed Content from method/function call
* @return mixed Content from method/function call or false if the class/method/function was not found
* @see getUserObj()
*/
function callUserFunction($funcName,&$params,&$ref,$checkPrefix='user_',$silent=0) {
global $TYPO3_CONF_VARS;
$content = false;
// Check persistent object and if found, call directly and exit.
if (is_array($GLOBALS['T3_VAR']['callUserFunction'][$funcName])) {
typo3/class.webpagetree.php (working copy)
$PM = t3lib_div::_GP('PM');
if(($PMpos = strpos($PM, '#')) !== false) { $PM = substr($PM, 0, $PMpos); }
$PM = explode('_', $PM);
if(($isAjaxCall = t3lib_div::_GP('ajax')) && is_array($PM) && count($PM)==4) {
if(TYPO3_AJAX && is_array($PM) && count($PM)==4) {
if($PM[1]) {
$expandedPageUid = $PM[2];
$ajaxOutput = '';
typo3/tree.js (working copy)
var Tree = {
thisScript: null,
thisScript: top.TS.PATH_typo3 + 'ajax.php',
frameSetModule: null,
activateDragDrop: true,
highlightClass: 'active',
......
new Ajax.Request(this.thisScript, {
method: 'get',
parameters: 'ajax=1&PM=' + params,
onComplete: function(xhr, status) {
// if this is not a valid ajax response, the whole page gets refreshed
if (!status) return this.refresh();
parameters: 'ajaxID=pagetreeExpandCollapse&PM=' + params,
onComplete: function(xhr) {
// the parent node needs to be overwritten, not the object
$(obj.parentNode).replace(xhr.responseText);
this.registerDragDropHandlers();
this.reSelectActiveItem();
filter($('_livesearch').value);
}.bind(this),
onT3Error: function(xhr) {
// if this is not a valid ajax response, the whole page gets refreshed
this.refresh();
}.bind(this)
});
},
typo3/js/common.js (revision 0)
/***************************************************************
*
* javascript functions regarding the TYPO3 wrapper
* for the javascript library "prototype".
*
* Copyright notice
*
* (c) 2008 Benjamin Mack <www.xnos.org>
* All rights reserved
*
* This script is part of the TYPO3 backend provided by
* Kasper Skaarhoj <kasper@typo3.com> together with TYPO3
*
* Released under GNU/GPL (see license file in /typo3/)
*
* 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.
*
* This copyright notice MUST APPEAR in all copies of this script
*
***************************************************************/
// Please make sure that prototype.js is loaded before loading this
// file in your script, the responder is only added if prototype was loaded
if (Prototype) {
// adding generic a responder to use when a AJAX request is done
Ajax.Responders.register({
onCreate: function(request, transport) {
// if the TYPO3 AJAX backend is used,
// the onSuccess & onComplete callbacks are hooked
if (request.url.indexOf("ajax.php") == -1) {
return;
}
var origSuccess = request.options.onSuccess, origComplete = request.options.onComplete;
// hooking "onSuccess"
if (origSuccess) {
request.options.onSuccess = function(xhr, json) {
if (!json) {
T3AJAX.showError(xhr);
} else {
origSuccess(xhr);
}
}
}
// hooking "onComplete", using T3Error handler if available
if (origComplete) {
request.options.onComplete = function(xhr, json) {
if (!json && request.options.onT3Error) {
request.options.onT3Error(xhr);
} else if (!json) {
T3AJAX.showError(xhr);
} else {
origComplete(xhr);
}
}
}
}
});
}
var T3AJAX = new Object();
T3AJAX.showError = function(xhr) {
alert(xhr.responseText);
}
typo3/classes/class.typo3ajax.php (revision 0)
<?php
/***************************************************************
* Copyright notice
*
* (c) 2008 Benjamin Mack <mack@xnos.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!
***************************************************************/
/**
* class to hold the information about an AJAX call
*
* @author Benjamin Mack <mack@xnos.org>
* @package TYPO3
* @subpackage core
*/
class TYPO3AJAX {
private $id;
private $errorMessage;
private $isError;
private $content;
/**
* constructor with the ajaxID
*
* @return void
*/
public function __construct() {
$this->id = null;
$this->content = null;
$this->isError = false;
$this->errorMessage = null;
}
/**
* sets the ID for the AJAX call
*
* @param string the AJAX id
* @return void
*/
public function setID($id) {
$this->id = $id;
}
/**
* returns the ID for the AJAX call
*
* @return string the AJAX id
*/
public function getID() {
return $this->id;
}
/**
* overwrites the existing content with the first parameter
*
* @param string the new Content
* @return string the old content
*/
public function setContent($content) {
$oldcontent = $this->content;
$this->content = $content;
return $oldcontent;
}
/**
* adds new content to the existing content
*
* @param string the new content to add
* @return string the old content
*/
public function addContent($content) {
$oldcontent = $this->content;
$this->content .= $content;
return $oldcontent;
}
/**
* returns the content for the ajax call
*
* @return string the content
*/
public function getContent() {
return $this->content;
}
/**
* sets an error message and the error flag
*
* @param string the error message
* @return void
*/
public function setError($errorMsg = '') {
$this->errorMessage = $errorMsg;
$this->isError = true;
}
/**
* checks whether an error occured during the execution or not
*
* @return boolean whether this AJAX call
*/
public function isError() {
return $this->isError;
}
/**
* renders the AJAX call and exits the request
*
* @return void
*/
public function output() {
if ($this->isError) {
header('X-JSON: false');
die('<t3err>'.$this->errorMessage.'</t3err>');
} else {
header('X-JSON: true');
echo $this->content;
exit;
}
}
}
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/classes/class.typo3ajax.php']) {
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/classes/class.typo3ajax.php']);
}
?>
typo3/template.php (working copy)
// The backend language engine is started (ext: "lang")
// ******************************************************
require_once(PATH_typo3.'sysext/lang/lang.php');
$LANG = t3lib_div::makeInstance('language');
$LANG->init($BE_USER->uc['lang']);
$GLOBALS['LANG'] = t3lib_div::makeInstance('language');
$GLOBALS['LANG']->init($BE_USER->uc['lang']);
// ******************************
// The template is loaded
// ******************************
$TBE_TEMPLATE = t3lib_div::makeInstance('template');
$GLOBALS['TBE_TEMPLATE'] = t3lib_div::makeInstance('template');
?>
typo3/alt_db_navframe.php (working copy)
$BACK_PATH = '';
require('init.php');
require_once('init.php');
require('template.php');
require_once('class.webpagetree.php');
......
var $backPath;
// Internal, static: GPvar:
var $ajax; // Is set, if an AJAX call should be handled.
var $currentSubScript;
var $cMR;
var $setTempDBmount; // If not '' (blank) then it will clear (0) or set (>0) Temporary DB mount.
/**
* Initialiation of the class
*
......
$this->backPath = $BACK_PATH;
// Setting GPvars:
$this->ajax = t3lib_div::_GP('ajax');
$this->cMR = t3lib_div::_GP('cMR');
$this->currentSubScript = t3lib_div::_GP('currentSubScript');
$this->setTempDBmount = t3lib_div::_GP('setTempDBmount');
......
// Temporary DB mounts:
$this->initializeTemporaryDBmount();
}
// Use template rendering only if this is a non-AJAX call:
if (!$this->ajax) {
// Setting highlight mode:
$this->doHighlight = !$BE_USER->getTSConfigVal('options.pageTree.disableTitleHighlight');
// If highlighting is active, define the CSS class for the active item depending on the workspace
if ($this->doHighlight) {
if ($BE_USER->workspace === 0) $hlClass = 'active';
else $hlClass = 'active active-ws wsver'.$BE_USER->workspace;
}
/**
* function that renders the page for the pagetree, this is only for setting
* up the display options for the page
* Using only when it's not an AJAX call
*
* @return void
*/
public function initPage() {
global $BE_USER;
// Create template object:
$this->doc = t3lib_div::makeInstance('template');
$this->doc->backPath = $BACK_PATH;
$this->doc->docType = 'xhtml_trans';
// Setting highlight mode:
$this->doHighlight = !$BE_USER->getTSConfigVal('options.pageTree.disableTitleHighlight');
// Adding javascript code for AJAX (prototype), drag&drop and the pagetree
$this->doc->loadJavascriptLib('contrib/prototype/prototype.js');
$this->doc->loadJavascriptLib('tree.js');
// If highlighting is active, define the CSS class for the active item depending on the workspace
if ($this->doHighlight) {
$hlClass = ($BE_USER->workspace === 0 ? 'active' : 'active active-ws wsver'.$BE_USER->workspace);
}
$this->doc->JScode .= $this->doc->wrapScriptTags(
($this->currentSubScript?'top.currentSubScript=unescape("'.rawurlencode($this->currentSubScript).'");':'').'
// setting prefs for pagetree and drag & drop
Tree.thisScript = "'.$this->pagetree->thisScript.'";
'.($this->doHighlight ? 'Tree.highlightClass = "'.$hlClass.'";' : '').'
DragDrop.changeURL = "'.$this->backPath.'alt_clickmenu.php";
DragDrop.backPath = "'.t3lib_div::shortMD5(''.'|'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']).'";
DragDrop.table = "pages";
// Create template object:
$this->doc = t3lib_div::makeInstance('template');
$this->doc->backPath = $BACK_PATH;
$this->doc->docType = 'xhtml_trans';
// Function, loading the list frame from navigation tree:
function jumpTo(id, linkObj, highlightID, bank) { //
var theUrl = top.TS.PATH_typo3 + top.currentSubScript + "?id=" + id;
top.fsMod.currentBank = bank;
if (top.condensedMode) top.content.location.href = theUrl;
else parent.list_frame.location.href=theUrl;
// Adding javascript code for AJAX (prototype), drag&drop and the pagetree
$this->doc->loadJavascriptLib('contrib/prototype/prototype.js');
$this->doc->loadJavascriptLib('js/common.js');
$this->doc->loadJavascriptLib('tree.js');
'.($this->doHighlight ? 'Tree.highlightActiveItem("web", highlightID + "_" + bank);' : '').'
'.(!$GLOBALS['CLIENT']['FORMSTYLE'] ? '' : 'if (linkObj) linkObj.blur(); ').'
return false;
}
'.($this->cMR?"jumpTo(top.fsMod.recentIds['web'],'');":'').'
');
// Click menu code is added:
$this->doc->getContextMenuCode();
$this->doc->bodyTagId = 'bodyTag';
$this->doc->JScode .= $this->doc->wrapScriptTags(
($this->currentSubScript?'top.currentSubScript=unescape("'.rawurlencode($this->currentSubScript).'");':'').'
// setting prefs for pagetree and drag & drop
'.($this->doHighlight ? 'Tree.highlightClass = "'.$hlClass.'";' : '').'
DragDrop.changeURL = "'.$this->backPath.'alt_clickmenu.php";
DragDrop.backPath = "'.t3lib_div::shortMD5(''.'|'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']).'";
DragDrop.table = "pages";
// Function, loading the list frame from navigation tree:
function jumpTo(id, linkObj, highlightID, bank) { //
var theUrl = top.TS.PATH_typo3 + top.currentSubScript + "?id=" + id;
top.fsMod.currentBank = bank;
if (top.condensedMode) top.content.location.href = theUrl;
else parent.list_frame.location.href=theUrl;
'.($this->doHighlight ? 'Tree.highlightActiveItem("web", highlightID + "_" + bank);' : '').'
'.(!$GLOBALS['CLIENT']['FORMSTYLE'] ? '' : 'if (linkObj) linkObj.blur(); ').'
return false;
}
'.($this->cMR?"jumpTo(top.fsMod.recentIds['web'],'');":'').'
');
// Click menu code is added:
$this->doc->getContextMenuCode();
$this->doc->bodyTagId = 'bodyTag';
}
/**
* Main function, rendering the browsable page tree
*
......
// Produce browse-tree:
$tree = $this->pagetree->getBrowsableTree();
// Output only the tree if this is an AJAX call:
if ($this->ajax) {
$this->content = $LANG->csConvObj->utf8_encode($tree, $LANG->charSet);
return;
}
// Start page:
$this->content = $this->doc->startPage('TYPO3 Page Tree');
......
* @return void
*/
function printContent() {
// If we handle an AJAX call, send headers:
if ($this->ajax) {
header('X-JSON: ('.($this->pagetree->ajaxStatus?'true':'false').')');
header('Content-type: text/html; charset=utf-8');
// If it's the regular call to fully output the tree:
} else {
$this->content.= $this->doc->endPage();
$this->content = $this->doc->insertStylesAndJS($this->content);
}
$this->content.= $this->doc->endPage();
$this->content = $this->doc->insertStylesAndJS($this->content);
echo $this->content;
}
......
* @return void
*/
function settingTemporaryMountPoint($pageId) {
global $BE_USER;
$GLOBALS['BE_USER']->setAndSaveSessionData('pageTree_temporaryMountPoint',intval($pageId));
}
// Setting temporary mount point ID:
$BE_USER->setAndSaveSessionData('pageTree_temporaryMountPoint',intval($pageId));
/**********************************
*
* AJAX Calls
*
**********************************/
/**
* Makes the AJAX call to expand or collapse the pagetree.
* Called by typo3/ajax.php
*
* @param array additional parameters (not used here)
* @param object the TYPO3AJAX object of this request
*/
public function ajaxExpandCollapse($params, &$ajaxObj) {
global $LANG;
$this->init();
$this->initPage();
$tree = $this->pagetree->getBrowsableTree();
$content = $LANG->csConvObj->utf8_encode($tree, $LANG->charSet);
if (!$this->pagetree->ajaxStatus) {
$ajaxObj->setError($content);
} else {
$ajaxObj->setContent($content);
}
}
}
......
}
// Make instance if it is not an AJAX call
if (!TYPO3_AJAX) {
$SOBE = t3lib_div::makeInstance('SC_alt_db_navframe');
$SOBE->init();
$SOBE->initPage();
$SOBE->main();
$SOBE->printContent();
}
// Make instance:
$SOBE = t3lib_div::makeInstance('SC_alt_db_navframe');
$SOBE->init();
$SOBE->main();
$SOBE->printContent();
?>
typo3/ajax.php (revision 0)
<?php
/***************************************************************
* Copyright notice
*
* (c) 2007-2008 Benjamin Mack
* 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!
***************************************************************/
/**
* AJAX dispatcher
* @author Benjamin Mack <mack@xnos.org>
* @package TYPO3
*/
define('TYPO3_AJAX', true);
require('init.php');
require('classes/class.typo3ajax.php');
// setting the charset
header('Content-type: text/html; charset='.($TYPO3_CONF_VARS['BE']['forceCharset'] ? $TYPO3_CONF_VARS['BE']['forceCharset'] : 'utf-8'));
// finding the script path from the variable
$ajaxID = (string) t3lib_div::_GP('ajaxID');
$ajaxScript = $TYPO3_CONF_VARS['BE']['AJAX'][$ajaxID];
// instantiating the AJAX object
$ajaxObj =& t3lib_div::makeInstance('TYPO3AJAX');
$ajaxParams = array();
// evaluating the arguments and calling the AJAX method/function
if (empty($ajaxID)) {
$ajaxObj->setError('No valid ajaxID parameter given.');
} else if (empty($ajaxScript)) {
$ajaxObj->setError('Registered backend function for ajaxID "'.$ajaxID.'" was not found.');
} else {
$ajaxObj->setID($ajaxID);
$ret = t3lib_div::callUserFunction($ajaxScript, $ajaxParams, $ajaxObj, false, true);
if ($ret === false) {
$ajaxObj->setError('Registered backend function for ajaxID "'.$ajaxID.'" was not found.');
}
}
// outputting the content (and setting the X-JSON-Header)
$ajaxObj->output();
?>
typo3/init.php (working copy)
*/
}
// *****************************
// Check if it is an AJAX call
// *****************************
if (!defined('TYPO3_AJAX')) {
define('TYPO3_AJAX', false);
}
// *************************
// Connect to the database
// *************************
(1-1/6)