TYPO3 CMS  TYPO3_8-7
ExtDirectApi.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
22 
27 {
31  protected $settings = [];
32 
36  public function __construct()
37  {
38  if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect']) && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect'])) {
39  $this->settings = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect'];
40  }
41  }
42 
57  public function getAPI(ServerRequestInterface $request, ResponseInterface $response)
58  {
59  $response->getBody()->write(json_encode([]));
60  return $response;
61  }
62 
70  public function getApiPhp(array $filterNamespaces)
71  {
72  $javascriptNamespaces = $this->getExtDirectApi($filterNamespaces);
73  // Return the generated javascript API configuration
74  if (!empty($javascriptNamespaces)) {
75  return '
76  if (!Ext.isObject(Ext.app.ExtDirectAPI)) {
77  Ext.app.ExtDirectAPI = {};
78  }
79  Ext.apply(Ext.app.ExtDirectAPI, ' . json_encode($javascriptNamespaces) . ');
80  ';
81  }
82  $errorMessage = $this->getNamespaceError($filterNamespaces);
83  throw new \InvalidArgumentException($errorMessage, 1297645190);
84  }
85 
93  protected function generateAPI(array $filterNamespaces)
94  {
95  $javascriptNamespaces = [];
96  if (is_array($this->settings)) {
97  foreach ($this->settings as $javascriptName => $configuration) {
98  $splittedJavascriptName = explode('.', $javascriptName);
99  $javascriptObjectName = array_pop($splittedJavascriptName);
100  $javascriptNamespace = implode('.', $splittedJavascriptName);
101  // Only items inside the wanted namespace
102  if (!$this->findNamespace($javascriptNamespace, $filterNamespaces)) {
103  continue;
104  }
105  if (!isset($javascriptNamespaces[$javascriptNamespace])) {
106  $javascriptNamespaces[$javascriptNamespace] = [
107  'url' => $this->getRoutingUrl($javascriptNamespace),
108  'type' => 'remoting',
109  'actions' => [],
110  'namespace' => $javascriptNamespace
111  ];
112  }
113  if (is_array($configuration)) {
114  $className = $configuration['callbackClass'];
115  $serverObject = GeneralUtility::getUserObj($className);
116  $javascriptNamespaces[$javascriptNamespace]['actions'][$javascriptObjectName] = [];
117  foreach (get_class_methods($serverObject) as $methodName) {
118  $reflectionMethod = new \ReflectionMethod($serverObject, $methodName);
119  $numberOfParameters = $reflectionMethod->getNumberOfParameters();
120  $docHeader = $reflectionMethod->getDocComment();
121  $formHandler = strpos($docHeader, '@formHandler') !== false;
122  $javascriptNamespaces[$javascriptNamespace]['actions'][$javascriptObjectName][] = [
123  'name' => $methodName,
124  'len' => $numberOfParameters,
125  'formHandler' => $formHandler
126  ];
127  }
128  }
129  }
130  }
131  return $javascriptNamespaces;
132  }
133 
140  public function getRoutingUrl($namespace)
141  {
142  if (TYPO3_MODE === 'FE') {
143  $url = GeneralUtility::locationHeaderUrl('?eID=ExtDirect&action=route&namespace=' . rawurlencode($namespace));
144  } else {
146  $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
147  $url = (string)$uriBuilder->buildUriFromRoute('ajax_ext_direct_route', ['namespace' => $namespace]);
148  }
149  return $url;
150  }
151 
158  protected function getExtDirectApi(array $filterNamespaces)
159  {
160  $noCache = (bool)GeneralUtility::_GET('no_cache');
161  // Look up into the cache
162  $cacheTag = 'ExtDirectApi';
163  $cacheIdentifier = md5($cacheTag . implode(',', $filterNamespaces) . GeneralUtility::getIndpEnv('TYPO3_SSL') . serialize($this->settings) . TYPO3_MODE . GeneralUtility::getIndpEnv('HTTP_HOST'));
164  // With no_cache always generate the javascript content
165  // Generate the javascript content if it wasn't found inside the cache and cache it!
167  $cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_hash');
168  if ($noCache || !is_array(($javascriptNamespaces = $cache->get($cacheIdentifier)))) {
169  $javascriptNamespaces = $this->generateAPI($filterNamespaces);
170  if (!empty($javascriptNamespaces)) {
171  $cache->set($cacheIdentifier, $javascriptNamespaces, [$cacheTag]);
172  }
173  }
174  return $javascriptNamespaces;
175  }
176 
183  protected function getNamespaceError(array $filterNamespaces)
184  {
185  if (!empty($filterNamespaces)) {
186  // Namespace error
187  $errorMessage = sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:ExtDirect.namespaceError'), __CLASS__, implode(',', $filterNamespaces));
188  } else {
189  // No namespace given
190  $errorMessage = sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:ExtDirect.noNamespace'), __CLASS__);
191  }
192  return $errorMessage;
193  }
194 
202  protected function findNamespace($namespace, array $filterNamespaces)
203  {
204  if ($filterNamespaces === ['TYPO3']) {
205  return true;
206  }
207  $found = false;
208  foreach ($filterNamespaces as $filter) {
209  if (GeneralUtility::isFirstPartOfStr($filter, $namespace)) {
210  $found = true;
211  break;
212  }
213  }
214  return $found;
215  }
216 }
static isFirstPartOfStr($str, $partStr)
getAPI(ServerRequestInterface $request, ResponseInterface $response)
getApiPhp(array $filterNamespaces)
getNamespaceError(array $filterNamespaces)
static makeInstance($className,... $constructorArguments)
generateAPI(array $filterNamespaces)
findNamespace($namespace, array $filterNamespaces)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']