Project

General

Profile

Feature #22000 » extDirectApi.patch

Administrator Admin, 2010-01-20 20:49

View differences:

t3lib/config_default.php (working copy)
'BackendLogin::isTimedOut' => 'typo3/classes/class.ajaxlogin.php:AjaxLogin->isTimedOut',
'BackendLogin::getChallenge' => 'typo3/classes/class.ajaxlogin.php:AjaxLogin->getChallenge',
'WorkspaceMenu::toggleWorkspacePreview' => 'typo3/classes/class.workspaceselector.php:WorkspaceSelector->toggleWorkspacePreview',
'WorkspaceMenu::setWorkspace' => 'typo3/classes/class.workspaceselector.php:WorkspaceSelector->setWorkspace'
'WorkspaceMenu::setWorkspace' => 'typo3/classes/class.workspaceselector.php:WorkspaceSelector->setWorkspace',
'ExtDirect::getAPI' => 't3lib/extjs/class.t3lib_extjs_extdirectapi.php:t3lib_extjs_ExtDirectAPI->getAPI',
'ExtDirect::route' => 't3lib/extjs/class.t3lib_extjs_extdirectrouter.php:t3lib_extjs_ExtDirectRouter->route',
),
'ExtDirect' => array(), // array of key value pairs (provider -> location:className) that holds the classes for the ExtDirect functionality
'XCLASS' => array(), // See 'Inside TYPO3' document for more information.
),
'FE' => array( // Configuration for the TypoScript frontend (FE). Nothing here relates to the administration backend!
t3lib/class.t3lib_pagerenderer.php (working copy)
/**
* Adds Ext.onready code, which will be wrapped in Ext.onReady(function() {...});
*
* @param string $block
* @param string $block javascript code
* @param string $position position of the javascript code (TOP or BOTTOM; last one is the default)
* @return void
*/
public function addExtOnReadyCode($block) {
public function addExtOnReadyCode($block, $position = 'BOTTOM') {
if (!in_array($block, $this->extOnReadyCode)) {
$this->extOnReadyCode[] = $block;
if ($position == 'TOP') {
array_unshift($this->extOnReadyCode, $block);
} else {
$this->extOnReadyCode[] = $block;
}
}
}
t3lib/extjs/class.t3lib_extjs_extdirectrouter.php (revision 0)
<?php
/***************************************************************
* Copyright notice
*
* (c) 2010 Sebastian Kurfuerst <sebastian@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!
***************************************************************/
/**
* Ext Direct Router
*
* @author Sebastian Kurfuerst <sebastian@typo3.org>
* @package TYPO3
*/
class t3lib_extjs_ExtDirectRouter {
/**
* Dispatches the incoming calls to methods about the ExtDirect API.
*
* @param aray $ajaxParams ajax parameters
* @param TYPO3AJAX $ajaxObj typo3ajax instance
* @return void
*/
public function route($ajaxParams, TYPO3AJAX $ajaxObj) {
try {
$isForm = false;
$isUpload = false;
$rawPostData = file_get_contents('php://input');
$namespace = t3lib_div::_GET('namespace');
if (!empty($rawPostData)) {
$ajaxObj->setContentFormat('jsonbody');
$request = json_decode($rawPostData);
} else {
throw new t3lib_error_Exception('ExtDirect: Missing Parameters!');
}
$response = null;
if (is_array($request)) {
$response = array();
foreach ($request as $singleRequest) {
$response[] = $this->processRpc($singleRequest, $namespace);
}
} else {
$response = $this->processRpc($request, $namespace);
}
} catch (t3lib_error_Exception $exception) {
$response = array(
'type' => 'exception',
'message' => $exception->getMessage(),
'where' => $exception->getTraceAsString()
);
}
$ajaxObj->setContent($response);
}
/**
* Processes an incoming extDirect call by executing the defined method. The configuration
* array "$GLOBALS['TYPO3_CONF_VARS']['BE']['ExtDirect']" is taken to find the class/method
* information.
*
* @param object $singleRequest request object from extJS
* @param string $namespace namespace like TYPO3.Backend
* @return mixed return value of the called method
*/
protected function processRpc($singleRequest, $namespace) {
try {
$endpointName = $namespace . '.' . $singleRequest->action;
// theoretically this can never happen, because of an javascript error on
// the client side due the missing namespace/endpoint
if (!isset($GLOBALS['TYPO3_CONF_VARS']['BE']['ExtDirect'][$endpointName])) {
throw new t3lib_error_Exception('ExtDirect: Call to undefined endpoint: ' . $endpointName);
}
$response = array(
'type' => 'rpc',
'tid' => $singleRequest->tid,
'action' => $singleRequest->action,
'method' => $singleRequest->method
);
$endpointObject = t3lib_div::getUserObj(
$GLOBALS['TYPO3_CONF_VARS']['BE']['ExtDirect'][$endpointName],
FALSE
);
$response['result'] = call_user_func_array(
array($endpointObject, $singleRequest->method),
is_array($singleRequest->data) ? $singleRequest->data : array()
);
} catch (t3lib_error_Exception $exception) {
$response = array(
'type' => 'exception',
'message' => $exception->getMessage(),
'where' => $exception->getTraceAsString()
);
}
return $response;
}
}
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_extjs_extdirectrouter.php']) {
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_extjs_extdirectrouter.php']);
}
?>
t3lib/extjs/class.t3lib_extjs_extdirectapi.php (revision 0)
<?php
/***************************************************************
* Copyright notice
*
* (c) 2010 Sebastian Kurfuerst <sebastian@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!
***************************************************************/
/**
* Ext Direct API Generator
*
* @author Sebastian Kurfuerst <sebastian@typo3.org>
* @author Stefan Galinski <stefan.galinski@gmail.com>
* @package TYPO3
*/
class t3lib_extjs_ExtDirectAPI {
/**
* Parses the ExtDirect configuration array "$GLOBALS['TYPO3_CONF_VARS']['BE']['ExtDirect']"
* and feeds the given typo3ajax instance with the resulting informations. The get parameter
* "namespace" will be used to filter the configuration.
*
* This method makes usage of the reflection mechanism to fetch the methods inside the
* defined classes together with their amount of parameters. This informations are building
* the API and are required by ExtDirect.
*
* @param array $ajaxParams ajax parameters
* @param TYPO3AJAX $ajaxObj typo3ajax instance
* @return void
*/
public function getAPI($ajaxParams, TYPO3AJAX $ajaxObj) {
$filterNamespace = t3lib_div::_GET('namespace');
$javascriptNamespaces = array();
if (is_array($GLOBALS['TYPO3_CONF_VARS']['BE']['ExtDirect'])) {
foreach ($GLOBALS['TYPO3_CONF_VARS']['BE']['ExtDirect'] as $javascriptName => $className) {
$splittedJavascriptName = explode('.', $javascriptName);
$javascriptObjectName = array_pop($splittedJavascriptName);
$javascriptNamespace = implode('.', $splittedJavascriptName);
// only items inside the wanted namespace
if (strpos($javascriptNamespace, $filterNamespace) !== 0) {
continue;
}
if (!isset($javascriptNamespaces[$javascriptNamespace])) {
$javascriptNamespaces[$javascriptNamespace] = array(
'url' => 'ajax.php?ajaxID=ExtDirect::route&namespace=' . rawurlencode($javascriptNamespace),
'type' => 'remoting',
'actions' => array(),
'namespace' => $javascriptNamespace
);
}
$serverObject = t3lib_div::getUserObj($className, FALSE);
$javascriptNamespaces[$javascriptNamespace]['actions'][$javascriptObjectName] = array();
foreach (get_class_methods($serverObject) as $methodName) {
$reflectionMethod = new ReflectionMethod($serverObject, $methodName);
$numberOfParameters = $reflectionMethod->getNumberOfParameters();
$javascriptNamespaces[$javascriptNamespace]['actions'][$javascriptObjectName][] = array(
'name' => $methodName,
'len' => $numberOfParameters
);
}
}
}
if (count($javascriptNamespaces)) {
$setup = '
if (typeof Ext.app.ExtDirectAPI != "object") {
Ext.app.ExtDirectAPI = {};
}
';
$ajaxObj->setContent($javascriptNamespaces);
$ajaxObj->setContentFormat('javascript');
$ajaxObj->setJavascriptCallbackWrap($setup . 'Ext.app.ExtDirectAPI = Object.extend(Ext.app.ExtDirectAPI, |);');
}
}
}
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_extjs_extdirectapi.php']) {
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_extjs_extdirectapi.php']);
}
?>
typo3/classes/class.typo3ajax.php (working copy)
protected $contentFormat = 'plain';
protected $charset = 'utf-8';
protected $requestCharset = 'utf-8';
protected $javascriptCallbackWrap = '
<script type="text/javascript">
/*<![CDATA[*/
response = |;
/*]]>*/
</script>
';
/**
* sets the charset and the ID for the AJAX call
......
/**
* sets the content format for the ajax call
*
* @param string can be one of 'plain' (default), 'xml', 'json', 'jsonbody' or 'jsonhead'
* @param string can be one of 'plain' (default), 'xml', 'json', 'javascript', 'jsonbody' or 'jsonhead'
* @return void
*/
public function setContentFormat($format) {
......
}
}
/**
* Specifies the wrap to be used if contentFormat is "javascript".
* The wrap used by default stores the results in a variable "response" and
* adds <script>-Tags around it.
*
* @param string $javascriptCallbackWrap the javascript callback wrap to be used
* @return void
*/
public function setJavascriptCallbackWrap($javascriptCallbackWrap) {
$this->javascriptCallbackWrap = $javascriptCallbackWrap;
}
/**
* sets an error message and the error flag
......
$GLOBALS['LANG']->csConvObj->convArray($this->content, $this->charset, $this->requestCharset);
}
$content = '<script type="text/javascript">
/*<![CDATA[*/
$content = str_replace('|', json_encode($this->content), $this->javascriptCallbackWrap);
response = ' . json_encode($this->content) . ';
/*]]>*/
</script>';
header('Content-type: text/html; charset=' . $this->requestCharset);
echo $content;
}
typo3/backend.php (working copy)
protected $jsFiles;
protected $jsFilesAfterInline;
protected $toolbarItems;
protected $extOnReady;
private $menuWidthDefault = 160; // intentionally private as nobody should modify defaults
protected $menuWidth;
......
'js/modulemenu.js',
'js/iecompatibility.js',
'js/flashupload.js',
'../t3lib/jsfunc.evalfield.js'
'../t3lib/jsfunc.evalfield.js',
'ajax.php?ajaxID=ExtDirect::getAPI&namespace=TYPO3.Backend'
);
$this->jsFilesAfterInline = array(
'js/backend.js',
'js/loginrefresh.js',
'js/loginrefresh.js',
);
// add default BE css
$this->css = '';
......
$pageRenderer->loadScriptaculous('builder,effects,controls,dragdrop');
$pageRenderer->loadExtJS();
// register the extDirect API providers
// Note: we need to iterate thru the object, because the addProvider method
// does this only with multiple arguments
$pageRenderer->addExtOnReadyCode(
'for (var api in Ext.app.ExtDirectAPI) {
Ext.Direct.addProvider(Ext.app.ExtDirectAPI[api]);
}',
'TOP'
);
// remove duplicate entries
$this->jsFiles = array_unique($this->jsFiles);
(1-1/6)