2 /***************************************************************
5 * (c) 2010 Sebastian Kurfürst <sebastian@typo3.org>
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
29 * Ext Direct API Generator
31 * @author Sebastian Kurfürst <sebastian@typo3.org>
32 * @author Stefan Galinski <stefan.galinski@gmail.com>
35 class t3lib_extjs_ExtDirectApi
{
39 protected $settings = array();
42 * Constructs this object.
44 public function __construct() {
45 if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect']) && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect'])) {
46 $this->settings
= $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect'];
51 * Parses the ExtDirect configuration array "$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect']"
52 * and feeds the given typo3ajax instance with the resulting information. The get parameter
53 * "namespace" will be used to filter the configuration.
55 * This method makes usage of the reflection mechanism to fetch the methods inside the
56 * defined classes together with their amount of parameters. This information are building
57 * the API and are required by ExtDirect. The result is cached to improve the overall
60 * @param array $ajaxParams ajax parameters
61 * @param TYPO3AJAX $ajaxObj typo3ajax instance
64 public function getAPI($ajaxParams, TYPO3AJAX
$ajaxObj) {
65 $filterNamespace = t3lib_div
::_GET('namespace');
67 // Check GET-parameter no_cache and extCache setting
68 $extCache = isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['extCache']) && (
69 $GLOBALS['TYPO3_CONF_VARS']['SYS']['extCache'] === 0 ||
70 $GLOBALS['TYPO3_CONF_VARS']['SYS']['extCache'] === '0'
72 $noCache = t3lib_div
::_GET('no_cache') ?
TRUE : $extCache;
74 // look up into the cache
75 $cacheIdentifier = 'ExtDirectApi';
76 $cacheHash = md5($cacheIdentifier . $filterNamespace .
77 serialize($this->settings
) . TYPO3_MODE
);
79 // with no_cache always generate the javascript content
80 $cacheContent = $noCache ?
'' : t3lib_pageSelect
::getHash($cacheHash);
82 // generate the javascript content if it wasn't found inside the cache and cache it!
84 $javascriptNamespaces = $this->generateAPI($filterNamespace);
85 if (!empty($javascriptNamespaces)) {
86 t3lib_pageSelect
::storeHash(
88 serialize($javascriptNamespaces),
93 $javascriptNamespaces = unserialize($cacheContent);
96 // return the generated javascript API configuration
97 if (count($javascriptNamespaces)) {
99 if (typeof Ext.app.ExtDirectAPI !== "object") {
100 Ext.app.ExtDirectAPI = {};
103 if (typeof Object.extend !== "function") {
104 Object.extend = function(destination, source) {
105 for (var property in source) {
106 destination[property] = source[property];
113 $ajaxObj->setContent($javascriptNamespaces);
114 $ajaxObj->setContentFormat('javascript');
115 $ajaxObj->setJavascriptCallbackWrap(
116 $setup . 'Ext.app.ExtDirectAPI = Object.extend(Ext.app.ExtDirectAPI, |);'
119 if ($filterNamespace) {
121 $errorMessage = sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:ExtDirect.namespaceError'),
122 __CLASS__
, $filterNamespace
126 // no namespace given
127 $errorMessage = sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:ExtDirect.noNamespace'),
131 // make js multiline message
132 $msg = t3lib_div
::trimExplode(LF
, str_replace('"', '\"', $errorMessage), TRUE);
134 foreach ($msg as $line) {
135 $errorMessage .= '"' . $line . '" + ' . LF
;
137 $errorMessage = substr(trim($errorMessage), 0, -1);
138 //generate the javascript
139 $ajaxObj->setContentFormat('javascript');
140 $ajaxObj->setJavascriptCallbackWrap('
141 errorMessage = ' . $errorMessage . ';
142 if (typeof console === "object") {
143 console.log(errorMessage);
152 * Generates the API that is configured inside the ExtDirect configuration
153 * array "$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect']".
155 * @param string $filerNamespace namespace that should be loaded like TYPO3.Backend
156 * @return array javascript API configuration
158 protected function generateAPI($filterNamespace) {
159 $javascriptNamespaces = array();
160 if (is_array($this->settings
)) {
161 foreach ($this->settings
as $javascriptName => $className) {
162 $splittedJavascriptName = explode('.', $javascriptName);
163 $javascriptObjectName = array_pop($splittedJavascriptName);
164 $javascriptNamespace = implode('.', $splittedJavascriptName);
166 // only items inside the wanted namespace
167 if (strpos($javascriptNamespace, $filterNamespace) !== 0) {
171 if (!isset($javascriptNamespaces[$javascriptNamespace])) {
172 $javascriptNamespaces[$javascriptNamespace] = array(
173 'url' => $this->getRoutingUrl($javascriptNamespace),
174 'type' => 'remoting',
175 'actions' => array(),
176 'namespace' => $javascriptNamespace
180 $serverObject = t3lib_div
::getUserObj($className, FALSE);
181 $javascriptNamespaces[$javascriptNamespace]['actions'][$javascriptObjectName] = array();
182 foreach (get_class_methods($serverObject) as $methodName) {
183 $reflectionMethod = new ReflectionMethod($serverObject, $methodName);
184 $numberOfParameters = $reflectionMethod->getNumberOfParameters();
185 $docHeader = $reflectionMethod->getDocComment();
186 $formHandler = (strpos($docHeader, '@formHandler') !== FALSE);
188 $javascriptNamespaces[$javascriptNamespace]['actions'][$javascriptObjectName][] = array(
189 'name' => $methodName,
190 'len' => $numberOfParameters,
191 'formHandler' => $formHandler
197 return $javascriptNamespaces;
201 * Returns the convenient path for the routing Urls based on the TYPO3 mode.
203 * @param string $namespace
206 public function getRoutingUrl($namespace) {
208 if (TYPO3_MODE
=== 'FE') {
209 $url = t3lib_div
::locationHeaderUrl('?eID=ExtDirect&action=route&namespace=');
211 $url = t3lib_div
::locationHeaderUrl('ajax.php?ajaxID=ExtDirect::route&namespace=');
213 $url .= rawurlencode($namespace);
219 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE
]['XCLASS']['t3lib/extjs/class.t3lib_extjs_extdirectapi.php']) {
220 include_once($TYPO3_CONF_VARS[TYPO3_MODE
]['XCLASS']['t3lib/extjs/class.t3lib_extjs_extdirectapi.php']);