diff --git a/ChangeLog b/ChangeLog index 99aa5d7531f5b3326226d83e2338ca027e6e12c8..ca7c129afcf23259d034e38bb0de110e677976aa 100755 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-08-23 Steffen Kamper <steffen@typo3.org> + + * Added feature #15513: Log ExtDirect Exceptions in DebugConsole (Thanks to Stefan Galinski) + 2010-08-23 Xavier Perseguers <typo3@perseguers.ch> * Raised DBAL to version 1.2.0alpha1 diff --git a/t3lib/class.t3lib_pagerenderer.php b/t3lib/class.t3lib_pagerenderer.php index 0e647597d32591d4c3d8463c2284aa1e1895c43e..4c594339d4fbc9e7d3228bc29d743a4a273608de 100644 --- a/t3lib/class.t3lib_pagerenderer.php +++ b/t3lib/class.t3lib_pagerenderer.php @@ -873,6 +873,57 @@ class t3lib_PageRenderer implements t3lib_Singleton { } } + /** + * Adds the ExtDirect code + * + * @return void + */ + public function addExtDirectCode() { + // Note: we need to iterate thru the object, because the addProvider method + // does this only with multiple arguments + $this->addExtOnReadyCode( + 'for (var api in Ext.app.ExtDirectAPI) { + Ext.Direct.addProvider(Ext.app.ExtDirectAPI[api]); + } + + var extDirectDebug = function(message, header, group) { + var TYPO3ViewportInstance = null; + + if (top && top.TYPO3 && typeof top.TYPO3.Backend === "object") { + TYPO3ViewportInstance = top.TYPO3.Backend; + } else if (typeof TYPO3 === "object" && typeof TYPO3.Backend === "object") { + TYPO3ViewportInstance = TYPO3.Backend; + } + + if (TYPO3ViewportInstance !== null) { + TYPO3ViewportInstance.DebugConsole.addTab(message, header, group); + } else { + document.write(message); + } + }; + + Ext.Direct.on("exception", function(event) { + extDirectDebug( + "<p>" + event.message + "</p>" + + "<p style=\"margin-top: 20px;\">" + + "<strong>Backtrace:</strong><br />" + + event.where.replace(/#/g, "<br />#") + + "</p>", + event.method, + "ExtDirect - Exception" + ); + }); + + Ext.Direct.on("event", function(event, provider) { + if (typeof event.debug !== "undefined" && event.debug !== "") { + extDirectDebug(event.debug, event.method, "ExtDirect - Debug"); + } + }); + ', + TRUE + ); + } + /* CSS Files */ /** diff --git a/t3lib/core_autoload.php b/t3lib/core_autoload.php index 18fe45a827470f2d303d06a4e80a5e738ab21b8b..ce55bf3260ba9f616bcd390cdfb58f30a65a254b 100644 --- a/t3lib/core_autoload.php +++ b/t3lib/core_autoload.php @@ -137,6 +137,7 @@ $t3libClasses = array( 't3lib_spritemanager_spritegenerator' => PATH_t3lib . 'spritemanager/class.t3lib_spritemanager_spritegenerator.php', 't3lib_spritemanager_spriteicongenerator' => PATH_t3lib . 'interfaces/interface.t3lib_spritemanager_spriteicongenerator.php', 't3lib_spritemanager_simplehandler' => PATH_t3lib . 'spritemanager/class.t3lib_spritemanager_simplehandler.php', + 't3lib_extjs_extdirectdebug' => PATH_t3lib . 'extjs/class.t3lib_extjs_extdirectdebug.php', ); $tslibClasses = require(PATH_typo3 . 'sysext/cms/ext_autoload.php'); diff --git a/t3lib/extjs/class.t3lib_extjs_extdirectdebug.php b/t3lib/extjs/class.t3lib_extjs_extdirectdebug.php new file mode 100644 index 0000000000000000000000000000000000000000..97f4fcfe74703645e24fd281e11a11a9002679ef --- /dev/null +++ b/t3lib/extjs/class.t3lib_extjs_extdirectdebug.php @@ -0,0 +1,67 @@ +<?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! +***************************************************************/ + +/** + * Ext Direct Debug + * + * @author Stefan Galinski <stefan.galinski@gmail.com> + * @package TYPO3 + */ +final class t3lib_extjs_ExtDirectDebug { + /** + * Internal debug message array + * + * @var array + */ + protected static $debugMessages = array(); + + /** + * Adds a new message of any data type to the internal debug message array. + * + * @param mixed $message + * @return void + */ + public static function debug($message) { + self::$debugMessages[] = $message; + } + + /** + * Returns the internal debug messages as a string. + * + * @return string + */ + public static function toString() { + $messagesAsString = ''; + if (count(self::$debugMessages)) { + $messagesAsString = t3lib_div::view_array(self::$debugMessages); + } + + return $messagesAsString; + } +} + +?> \ No newline at end of file diff --git a/t3lib/extjs/class.t3lib_extjs_extdirectrouter.php b/t3lib/extjs/class.t3lib_extjs_extdirectrouter.php index 8956baeded31ca12a29be400d8c32225423d780c..068b5ff60bf046b7cc25f07a6176e723d420f3c9 100644 --- a/t3lib/extjs/class.t3lib_extjs_extdirectrouter.php +++ b/t3lib/extjs/class.t3lib_extjs_extdirectrouter.php @@ -3,6 +3,7 @@ * Copyright notice * * (c) 2010 Sebastian Kurfuerst <sebastian@typo3.org> +* (c) 2010 Stefan Galinski <stefan.galinski@gmail.com> * All rights reserved * * This script is part of the TYPO3 project. The TYPO3 project is @@ -41,56 +42,67 @@ class t3lib_extjs_ExtDirectRouter { * @return void */ public function route($ajaxParams, TYPO3AJAX $ajaxObj) { - try { - $isForm = FALSE; - $isUpload = FALSE; - $rawPostData = file_get_contents('php://input'); - $postParameters = t3lib_div::_POST(); - $namespace = t3lib_div::_GET('namespace'); - - if (!empty($postParameters['extAction'])) { - $isForm = TRUE; - $isUpload = $postParameters['extUpload'] === 'true'; - - $request->action = $postParameters['extAction']; - $request->method = $postParameters['extMethod']; - $request->tid = $postParameters['extTID']; - $request->data = array($_POST + $_FILES); - } elseif (!empty($rawPostData)) { - $request = json_decode($rawPostData); - } else { - throw new t3lib_error_Exception('ExtDirect: Missing Parameters!'); - } + $isForm = FALSE; + $isUpload = FALSE; + $rawPostData = file_get_contents('php://input'); + $postParameters = t3lib_div::_POST(); + $namespace = t3lib_div::_GET('namespace'); + $response = array(); + $request = NULL; + + if (!empty($postParameters['extAction'])) { + $isForm = TRUE; + $isUpload = $postParameters['extUpload'] === 'true'; + + $request = new stdClass; + $request->action = $postParameters['extAction']; + $request->method = $postParameters['extMethod']; + $request->tid = $postParameters['extTID']; + $request->data = array($_POST + $_FILES); + } elseif (!empty($rawPostData)) { + $request = json_decode($rawPostData); + } else { + $response[] = array( + 'type' => 'exception', + 'message' => 'Something went wrong with an ExtDirect call!' + ); + } - $response = NULL; - if (is_array($request)) { - $response = array(); - foreach ($request as $singleRequest) { - $response[] = $this->processRpc($singleRequest, $namespace); - } - } else { - $response = $this->processRpc($request, $namespace); - } + if (!is_array($request)) { + $request = array($request); + } - if ($isForm && $isUpload) { - $ajaxObj->setContentFormat('plain'); - $response = json_encode($response); - $response = preg_replace('/"/', '\\"', $response); - - $response = array( - '<html><body><textarea>' . - $response . - '</textarea></body></html>' - ); - } else { - $ajaxObj->setContentFormat('jsonbody'); + foreach ($request as $index => $singleRequest) { + $response[$index] = array( + 'tid' => $singleRequest->tid, + 'action' => $singleRequest->action, + 'method' => $singleRequest->method + ); + + try { + $response[$index]['type'] = 'rpc'; + $response[$index]['result'] = $this->processRpc($singleRequest, $namespace); + $response[$index]['debug'] = t3lib_extjs_ExtDirectDebug::toString(); + + } catch (Exception $exception) { + $response[$index]['type'] = 'exception'; + $response[$index]['message'] = $exception->getMessage(); + $response[$index]['where'] = $exception->getTraceAsString(); } - } catch (t3lib_error_Exception $exception) { + } + + if ($isForm && $isUpload) { + $ajaxObj->setContentFormat('plain'); + $response = json_encode($response); + $response = preg_replace('/"/', '\\"', $response); + $response = array( - 'type' => 'exception', - 'message' => $exception->getMessage(), - 'where' => $exception->getTraceAsString() + '<html><body><textarea>' . + $response . + '</textarea></body></html>' ); + } else { + $ajaxObj->setContentFormat('jsonbody'); } $ajaxObj->setContent($response); @@ -104,40 +116,27 @@ class t3lib_extjs_ExtDirectRouter { * * @param object $singleRequest request object from extJS * @param string $namespace namespace like TYPO3.Backend + * @throws t3lib_error_exception if the remote method couldn't be found * @return mixed return value of the called method */ protected function processRpc($singleRequest, $namespace) { - try { - $endpointName = $namespace . '.' . $singleRequest->action; + $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']['SC_OPTIONS']['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']['SC_OPTIONS']['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) { - throw $exception; + if (!isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect'][$endpointName])) { + throw new t3lib_error_Exception('ExtDirect: Call to undefined endpoint: ' . $endpointName); } - return $response; + $endpointObject = t3lib_div::getUserObj( + $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect'][$endpointName], + FALSE + ); + + return call_user_func_array( + array($endpointObject, $singleRequest->method), + is_array($singleRequest->data) ? $singleRequest->data : array() + ); } } diff --git a/typo3/backend.php b/typo3/backend.php index 23ee7265021b62801eba01d2ccd5fc61e89f8fe1..c62f75cf51a28aad2c6397bf3e60ec4e0e9d5b2c 100644 --- a/typo3/backend.php +++ b/typo3/backend.php @@ -100,18 +100,12 @@ class TYPO3backend { $this->pageRenderer->loadScriptaculous('builder,effects,controls,dragdrop'); $this->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 $this->pageRenderer->addExtOnReadyCode( - 'for (var api in Ext.app.ExtDirectAPI) { - Ext.Direct.addProvider(Ext.app.ExtDirectAPI[api]); - } - TYPO3.Backend = new TYPO3.Viewport(TYPO3.Viewport.configuration); + 'TYPO3.Backend = new TYPO3.Viewport(TYPO3.Viewport.configuration); ', TRUE ); - + $this->pageRenderer->addExtDirectCode(); // add default BE javascript $this->js = '';