TYPO3 API  SVNRelease
class.t3lib_extjs_extdirectapi.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003  *  Copyright notice
00004  *
00005  *  (c) 2010-2011 Sebastian Kurfürst <sebastian@typo3.org>
00006  *  All rights reserved
00007  *
00008  *  This script is part of the TYPO3 project. The TYPO3 project is
00009  *  free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  The GNU General Public License can be found at
00015  *  http://www.gnu.org/copyleft/gpl.html.
00016  *  A copy is found in the textfile GPL.txt and important notices to the license
00017  *  from the author is found in LICENSE.txt distributed with these scripts.
00018  *
00019  *
00020  *  This script is distributed in the hope that it will be useful,
00021  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  *  GNU General Public License for more details.
00024  *
00025  *  This copyright notice MUST APPEAR in all copies of the script!
00026  ***************************************************************/
00027 
00028 /**
00029  * Ext Direct API Generator
00030  *
00031  * @author  Sebastian Kurfürst <sebastian@typo3.org>
00032  * @author  Stefan Galinski <stefan.galinski@gmail.com>
00033  * @package TYPO3
00034  */
00035 class t3lib_extjs_ExtDirectApi {
00036     /**
00037      * @var array
00038      */
00039     protected $settings = array();
00040 
00041     /**
00042      * Constructs this object.
00043      */
00044     public function __construct() {
00045         if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect']) && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect'])) {
00046             $this->settings = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect'];
00047         }
00048     }
00049 
00050     /**
00051      * Parses the ExtDirect configuration array "$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect']"
00052      * and feeds the given typo3ajax instance with the resulting information. The get parameter
00053      * "namespace" will be used to filter the configuration.
00054      *
00055      * This method makes usage of the reflection mechanism to fetch the methods inside the
00056      * defined classes together with their amount of parameters. This information are building
00057      * the API and are required by ExtDirect. The result is cached to improve the overall
00058      * performance.
00059      *
00060      * @param array $ajaxParams ajax parameters
00061      * @param TYPO3AJAX $ajaxObj typo3ajax instance
00062      * @return void
00063      */
00064     public function getAPI($ajaxParams, TYPO3AJAX $ajaxObj) {
00065         $ajaxObj->setContent(array());
00066     }
00067 
00068     /**
00069      * Get the API for a given nameapace
00070      *
00071      * @throws InvalidArgumentException
00072      * @param  array $filterNamespaces
00073      * @return string
00074      */
00075     public function getApiPhp(array $filterNamespaces) {
00076         $javascriptNamespaces = $this->getExtDirectApi($filterNamespaces);
00077             // return the generated javascript API configuration
00078         if (count($javascriptNamespaces)) {
00079             return '
00080                 if (!Ext.isObject(Ext.app.ExtDirectAPI)) {
00081                     Ext.app.ExtDirectAPI = {};
00082                 }
00083                 Ext.apply(Ext.app.ExtDirectAPI, ' .
00084                     json_encode($javascriptNamespaces) . ');
00085             ';
00086         } else {
00087             $errorMessage = $this->getNamespaceError($filterNamespaces);
00088             throw new InvalidArgumentException(
00089                 $errorMessage,
00090                 1297645190
00091             );
00092         }
00093     }
00094 
00095 
00096     /**
00097      * Generates the API that is configured inside the ExtDirect configuration
00098      * array "$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect']".
00099      *
00100      * @param array $filerNamespace namespace that should be loaded like array('TYPO3.Backend')
00101      * @return array javascript API configuration
00102      */
00103     protected function generateAPI(array $filterNamespaces) {
00104         $javascriptNamespaces = array();
00105         if (is_array($this->settings)) {
00106             foreach ($this->settings as $javascriptName => $className) {
00107                 $splittedJavascriptName = explode('.', $javascriptName);
00108                 $javascriptObjectName = array_pop($splittedJavascriptName);
00109                 $javascriptNamespace = implode('.', $splittedJavascriptName);
00110 
00111                     // only items inside the wanted namespace
00112                 if (!$this->findNamespace($javascriptNamespace, $filterNamespaces)) {
00113                     continue;
00114                 }
00115 
00116                 if (!isset($javascriptNamespaces[$javascriptNamespace])) {
00117                     $javascriptNamespaces[$javascriptNamespace] = array(
00118                         'url' => $this->getRoutingUrl($javascriptNamespace),
00119                         'type' => 'remoting',
00120                         'actions' => array(),
00121                         'namespace' => $javascriptNamespace
00122                     );
00123                 }
00124 
00125                 $serverObject = t3lib_div::getUserObj($className, FALSE);
00126                 $javascriptNamespaces[$javascriptNamespace]['actions'][$javascriptObjectName] = array();
00127                 foreach (get_class_methods($serverObject) as $methodName) {
00128                     $reflectionMethod = new ReflectionMethod($serverObject, $methodName);
00129                     $numberOfParameters = $reflectionMethod->getNumberOfParameters();
00130                     $docHeader = $reflectionMethod->getDocComment();
00131                     $formHandler = (strpos($docHeader, '@formHandler') !== FALSE);
00132 
00133                     $javascriptNamespaces[$javascriptNamespace]['actions'][$javascriptObjectName][] = array(
00134                         'name' => $methodName,
00135                         'len' => $numberOfParameters,
00136                         'formHandler' => $formHandler
00137                     );
00138                 }
00139             }
00140         }
00141 
00142         return $javascriptNamespaces;
00143     }
00144 
00145     /**
00146      * Returns the convenient path for the routing Urls based on the TYPO3 mode.
00147      *
00148      * @param string $namespace
00149      * @return string
00150      */
00151     public function getRoutingUrl($namespace) {
00152         $url = '';
00153         if (TYPO3_MODE === 'FE') {
00154             $url = t3lib_div::locationHeaderUrl('?eID=ExtDirect&action=route&namespace=');
00155         } else {
00156             $url = t3lib_div::locationHeaderUrl(
00157                 t3lib_div::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir .
00158                 'ajax.php?ajaxID=ExtDirect::route&namespace='
00159             );
00160         }
00161         $url .= rawurlencode($namespace);
00162 
00163         return $url;
00164     }
00165 
00166     /**
00167      * Generates the API or reads it from cache
00168      *
00169      * @param  array $filterNamespaces
00170      * @param bool $checkGetParam
00171      * @return string $javascriptNamespaces
00172      */
00173     protected function getExtDirectApi(array $filterNamespaces) {
00174             // Check GET-parameter no_cache and extCache setting
00175         $noCache = isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['extCache']) && (
00176                 $GLOBALS['TYPO3_CONF_VARS']['SYS']['extCache'] === 0 ||
00177                 $GLOBALS['TYPO3_CONF_VARS']['SYS']['extCache'] === '0'
00178         );
00179         $noCache = t3lib_div::_GET('no_cache') ? TRUE : $noCache;
00180 
00181             // look up into the cache
00182         $cacheIdentifier = 'ExtDirectApi';
00183         $cacheHash = md5($cacheIdentifier . implode(',', $filterNamespaces) . t3lib_div::getIndpEnv('TYPO3_SSL') .
00184              serialize($this->settings) . TYPO3_MODE . t3lib_div::getIndpEnv('HTTP_HOST'));
00185 
00186             // with no_cache always generate the javascript content
00187         $cacheContent = $noCache ? '' : t3lib_pageSelect::getHash($cacheHash);
00188 
00189             // generate the javascript content if it wasn't found inside the cache and cache it!
00190         if (!$cacheContent) {
00191             $javascriptNamespaces = $this->generateAPI($filterNamespaces);
00192             if (count($javascriptNamespaces)) {
00193                 t3lib_pageSelect::storeHash(
00194                     $cacheHash,
00195                     serialize($javascriptNamespaces),
00196                     $cacheIdentifier
00197                 );
00198             }
00199         } else {
00200             $javascriptNamespaces = unserialize($cacheContent);
00201         }
00202 
00203         return $javascriptNamespaces;
00204     }
00205 
00206     /**
00207      * Generates the error message
00208      *
00209      * @param  array $filterNamespaces
00210      * @return string $errorMessage
00211      */
00212     protected function getNamespaceError(array $filterNamespaces) {
00213         if (count($filterNamespaces)) {
00214                 // namespace error
00215             $errorMessage = sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:ExtDirect.namespaceError'),
00216                                     __CLASS__, implode(',', $filterNamespaces)
00217             );
00218         }
00219         else {
00220                 // no namespace given
00221             $errorMessage = sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:ExtDirect.noNamespace'),
00222                                     __CLASS__
00223             );
00224         }
00225 
00226         return $errorMessage;
00227     }
00228 
00229     /**
00230      * Looks if the given namespace is present in $filterNamespaces
00231      *
00232      * @param  string $namespace
00233      * @param array $filterNamespaces
00234      * @return bool
00235      */
00236     protected function findNamespace($namespace, array $filterNamespaces) {
00237         if ($filterNamespaces === array('TYPO3')) {
00238             return TRUE;
00239         }
00240         $found = FALSE;
00241         foreach ($filterNamespaces as $filter) {
00242             if (t3lib_div::isFirstPartOfStr($filter, $namespace)) {
00243                 $found = TRUE;
00244                 break;
00245             }
00246         }
00247         return $found;
00248     }
00249 }
00250 
00251 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/extjs/class.t3lib_extjs_extdirectapi.php'])) {
00252     include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/extjs/class.t3lib_extjs_extdirectapi.php']);
00253 }
00254 
00255 ?>