[TASK] Remove compat layer for backend module
[Packages/TYPO3.CMS.git] / typo3 / sysext / workspaces / Classes / Service / GridDataService.php
1 <?php
2 namespace TYPO3\CMS\Workspaces\Service;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2010-2013 Workspaces Team (http://forge.typo3.org/projects/show/typo3v4-workspaces)
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the textfile GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
20 *
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29 /**
30 * Grid data service
31 *
32 * @author Workspaces Team (http://forge.typo3.org/projects/show/typo3v4-workspaces)
33 */
34 class GridDataService {
35
36 const SIGNAL_GenerateDataArray_BeforeCaching = 'generateDataArray.beforeCaching';
37 const SIGNAL_GenerateDataArray_PostProcesss = 'generateDataArray.postProcess';
38 const SIGNAL_GetDataArray_PostProcesss = 'getDataArray.postProcess';
39 const SIGNAL_SortDataArray_PostProcesss = 'sortDataArray.postProcess';
40 /**
41 * Id of the current active workspace.
42 *
43 * @var integer
44 */
45 protected $currentWorkspace = NULL;
46
47 /**
48 * Version record information (filtered, sorted and limited)
49 *
50 * @var array
51 */
52 protected $dataArray = array();
53
54 /**
55 * Name of the field used for sorting.
56 *
57 * @var string
58 */
59 protected $sort = '';
60
61 /**
62 * Direction used for sorting (ASC, DESC).
63 *
64 * @var string
65 */
66 protected $sortDir = '';
67
68 /**
69 * @var \TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
70 */
71 protected $workspacesCache = NULL;
72
73 /**
74 * @var array
75 */
76 protected $systemLanguages;
77
78 /**
79 * @var \TYPO3\CMS\Workspaces\Service\IntegrityService
80 */
81 protected $integrityService;
82
83 /**
84 * Generates grid list array from given versions.
85 *
86 * @param array $versions All records uids etc. First key is table name, second key incremental integer. Records are associative arrays with uid and t3ver_oid fields. The pid of the online record is found as "livepid" the pid of the offline record is found in "wspid
87 * @param object $parameter Parameters as submitted by JavaScript component
88 * @param integer $currentWorkspace The current workspace
89 * @return array Version record information (filtered, sorted and limited)
90 * @throws \InvalidArgumentException
91 */
92 public function generateGridListFromVersions($versions, $parameter, $currentWorkspace) {
93 // Read the given parameters from grid. If the parameter is not set use default values.
94 $filterTxt = isset($parameter->filterTxt) ? $parameter->filterTxt : '';
95 $start = isset($parameter->start) ? intval($parameter->start) : 0;
96 $limit = isset($parameter->limit) ? intval($parameter->limit) : 30;
97 $this->sort = isset($parameter->sort) ? $parameter->sort : 't3ver_oid';
98 $this->sortDir = isset($parameter->dir) ? $parameter->dir : 'ASC';
99 if (is_int($currentWorkspace)) {
100 $this->currentWorkspace = $currentWorkspace;
101 } else {
102 throw new \InvalidArgumentException('No such workspace defined');
103 }
104 $data = array();
105 $data['data'] = array();
106 $this->generateDataArray($versions, $filterTxt);
107 $data['total'] = count($this->dataArray);
108 $data['data'] = $this->getDataArray($start, $limit);
109 return $data;
110 }
111
112 /**
113 * Generates grid list array from given versions.
114 *
115 * @param array $versions All available version records
116 * @param string $filterTxt Text to be used to filter record result
117 * @return void
118 */
119 protected function generateDataArray(array $versions, $filterTxt) {
120 $workspaceAccess = $GLOBALS['BE_USER']->checkWorkspace($GLOBALS['BE_USER']->workspace);
121 $swapStage = $workspaceAccess['publish_access'] & 1 ? \TYPO3\CMS\Workspaces\Service\StagesService::STAGE_PUBLISH_ID : 0;
122 $swapAccess = $GLOBALS['BE_USER']->workspacePublishAccess($GLOBALS['BE_USER']->workspace) && $GLOBALS['BE_USER']->workspaceSwapAccess();
123 $this->initializeWorkspacesCachingFramework();
124 // check for dataArray in cache
125 if ($this->getDataArrayFromCache($versions, $filterTxt) === FALSE) {
126 /** @var $stagesObj \TYPO3\CMS\Workspaces\Service\StagesService */
127 $stagesObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Workspaces\\Service\\StagesService');
128 foreach ($versions as $table => $records) {
129 $versionArray = array('table' => $table);
130 $hiddenField = $this->getTcaEnableColumnsFieldName($table, 'disabled');
131 $isRecordTypeAllowedToModify = $GLOBALS['BE_USER']->check('tables_modify', $table);
132
133 foreach ($records as $record) {
134 $origRecord = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecord($table, $record['t3ver_oid']);
135 $versionRecord = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecord($table, $record['uid']);
136 $combinedRecord = \TYPO3\CMS\Workspaces\Domain\Model\CombinedRecord::createFromArrays($table, $origRecord, $versionRecord);
137 $this->getIntegrityService()->checkElement($combinedRecord);
138
139 if ($hiddenField !== NULL) {
140 $recordState = $this->workspaceState($versionRecord['t3ver_state'], $origRecord[$hiddenField], $versionRecord[$hiddenField]);
141 } else {
142 $recordState = $this->workspaceState($versionRecord['t3ver_state']);
143 }
144
145 $isDeletedPage = $table == 'pages' && $recordState == 'deleted';
146 $viewUrl = \TYPO3\CMS\Workspaces\Service\WorkspaceService::viewSingleRecord($table, $record['uid'], $origRecord, $versionRecord);
147 $versionArray['id'] = $table . ':' . $record['uid'];
148 $versionArray['uid'] = $record['uid'];
149 $versionArray['workspace'] = $versionRecord['t3ver_id'];
150 $versionArray['label_Workspace'] = htmlspecialchars(\TYPO3\CMS\Backend\Utility\BackendUtility::getRecordTitle($table, $versionRecord));
151 $versionArray['label_Live'] = htmlspecialchars(\TYPO3\CMS\Backend\Utility\BackendUtility::getRecordTitle($table, $origRecord));
152 $versionArray['label_Stage'] = htmlspecialchars($stagesObj->getStageTitle($versionRecord['t3ver_stage']));
153 $tempStage = $stagesObj->getNextStage($versionRecord['t3ver_stage']);
154 $versionArray['label_nextStage'] = htmlspecialchars($stagesObj->getStageTitle($tempStage['uid']));
155 $tempStage = $stagesObj->getPrevStage($versionRecord['t3ver_stage']);
156 $versionArray['label_prevStage'] = htmlspecialchars($stagesObj->getStageTitle($tempStage['uid']));
157 $versionArray['path_Live'] = htmlspecialchars(\TYPO3\CMS\Backend\Utility\BackendUtility::getRecordPath($record['livepid'], '', 999));
158 $versionArray['path_Workspace'] = htmlspecialchars(\TYPO3\CMS\Backend\Utility\BackendUtility::getRecordPath($record['wspid'], '', 999));
159 $versionArray['workspace_Title'] = htmlspecialchars(\TYPO3\CMS\Workspaces\Service\WorkspaceService::getWorkspaceTitle($versionRecord['t3ver_wsid']));
160 $versionArray['workspace_Tstamp'] = $versionRecord['tstamp'];
161 $versionArray['workspace_Formated_Tstamp'] = \TYPO3\CMS\Backend\Utility\BackendUtility::datetime($versionRecord['tstamp']);
162 $versionArray['t3ver_oid'] = $record['t3ver_oid'];
163 $versionArray['livepid'] = $record['livepid'];
164 $versionArray['stage'] = $versionRecord['t3ver_stage'];
165 $versionArray['icon_Live'] = \TYPO3\CMS\Backend\Utility\IconUtility::mapRecordTypeToSpriteIconClass($table, $origRecord);
166 $versionArray['icon_Workspace'] = \TYPO3\CMS\Backend\Utility\IconUtility::mapRecordTypeToSpriteIconClass($table, $versionRecord);
167 $languageValue = $this->getLanguageValue($table, $versionRecord);
168 $versionArray['languageValue'] = $languageValue;
169 $versionArray['language'] = array(
170 'cls' => \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconClasses($this->getSystemLanguageValue($languageValue, 'flagIcon')),
171 'title' => htmlspecialchars($this->getSystemLanguageValue($languageValue, 'title'))
172 );
173 $versionArray['allowedAction_nextStage'] = $isRecordTypeAllowedToModify && $stagesObj->isNextStageAllowedForUser($versionRecord['t3ver_stage']);
174 $versionArray['allowedAction_prevStage'] = $isRecordTypeAllowedToModify && $stagesObj->isPrevStageAllowedForUser($versionRecord['t3ver_stage']);
175 if ($swapAccess && $swapStage != 0 && $versionRecord['t3ver_stage'] == $swapStage) {
176 $versionArray['allowedAction_swap'] = $isRecordTypeAllowedToModify && $stagesObj->isNextStageAllowedForUser($swapStage);
177 } elseif ($swapAccess && $swapStage == 0) {
178 $versionArray['allowedAction_swap'] = $isRecordTypeAllowedToModify;
179 } else {
180 $versionArray['allowedAction_swap'] = FALSE;
181 }
182 $versionArray['allowedAction_delete'] = $isRecordTypeAllowedToModify;
183 // preview and editing of a deleted page won't work ;)
184 $versionArray['allowedAction_view'] = !$isDeletedPage && $viewUrl;
185 $versionArray['allowedAction_edit'] = $isRecordTypeAllowedToModify && !$isDeletedPage;
186 $versionArray['allowedAction_editVersionedPage'] = $isRecordTypeAllowedToModify && !$isDeletedPage;
187 $versionArray['state_Workspace'] = $recordState;
188 if ($filterTxt == '' || $this->isFilterTextInVisibleColumns($filterTxt, $versionArray)) {
189 $this->dataArray[] = $versionArray;
190 }
191 }
192 }
193 // Suggested slot method:
194 // methodName(Tx_Workspaces_Service_GridData $gridData, array &$dataArray, array $versions)
195 $this->emitSignal(self::SIGNAL_GenerateDataArray_BeforeCaching, $this->dataArray, $versions);
196 // Enrich elements after everything has been processed:
197 foreach ($this->dataArray as &$element) {
198 $identifier = $element['table'] . ':' . $element['t3ver_oid'];
199 $element['integrity'] = array(
200 'status' => $this->getIntegrityService()->getStatusRepresentation($identifier),
201 'messages' => htmlspecialchars($this->getIntegrityService()->getIssueMessages($identifier, TRUE))
202 );
203 }
204 $this->setDataArrayIntoCache($versions, $filterTxt);
205 }
206 // Suggested slot method:
207 // methodName(Tx_Workspaces_Service_GridData $gridData, array &$dataArray, array $versions)
208 $this->emitSignal(self::SIGNAL_GenerateDataArray_PostProcesss, $this->dataArray, $versions);
209 $this->sortDataArray();
210 }
211
212 /**
213 * Gets the data array by considering the page to be shown in the grid view.
214 *
215 * @param integer $start
216 * @param integer $limit
217 * @return array
218 */
219 protected function getDataArray($start, $limit) {
220 $dataArrayPart = array();
221 $end = $start + $limit < count($this->dataArray) ? $start + $limit : count($this->dataArray);
222 for ($i = $start; $i < $end; $i++) {
223 $dataArrayPart[] = $this->dataArray[$i];
224 }
225 // Suggested slot method:
226 // methodName(Tx_Workspaces_Service_GridData $gridData, array &$dataArray, $start, $limit)
227 $this->emitSignal(self::SIGNAL_GetDataArray_PostProcesss, $this->dataArray, $start, $limit);
228 return $dataArrayPart;
229 }
230
231 /**
232 * Initializes the workspace cache
233 *
234 * @return void
235 */
236 protected function initializeWorkspacesCachingFramework() {
237 $this->workspacesCache = $GLOBALS['typo3CacheManager']->getCache('workspaces_cache');
238 }
239
240 /**
241 * Puts the generated dataArray into the workspace cache.
242 *
243 * @param array $versions All records uids etc. First key is table name, second key incremental integer. Records are associative arrays with uid and t3ver_oid fields. The pid of the online record is found as "livepid" the pid of the offline record is found in "wspid
244 * @param string $filterTxt The given filter text from the grid.
245 */
246 protected function setDataArrayIntoCache(array $versions, $filterTxt) {
247 $hash = $this->calculateHash($versions, $filterTxt);
248 $this->workspacesCache->set($hash, $this->dataArray, array($this->currentWorkspace, 'user_' . $GLOBALS['BE_USER']->user['uid']));
249 }
250
251 /**
252 * Checks if a cache entry is given for given versions and filter text and tries to load the data array from cache.
253 *
254 * @param array $versions All records uids etc. First key is table name, second key incremental integer. Records are associative arrays with uid and t3ver_oid fields. The pid of the online record is found as "livepid" the pid of the offline record is found in "wspid
255 * @param string $filterTxt The given filter text from the grid.
256 * @return boolean TRUE if cache entry was successfully fetched from cache and content put to $this->dataArray
257 */
258 protected function getDataArrayFromCache(array $versions, $filterTxt) {
259 $cacheEntry = FALSE;
260 $hash = $this->calculateHash($versions, $filterTxt);
261 $content = $this->workspacesCache->get($hash);
262 if ($content !== FALSE) {
263 $this->dataArray = $content;
264 $cacheEntry = TRUE;
265 }
266 return $cacheEntry;
267 }
268
269 /**
270 * Calculates the hash value of the used workspace, the user id, the versions array, the filter text, the sorting attribute, the workspace selected in grid and the sorting direction.
271 *
272 * @param array $versions All records uids etc. First key is table name, second key incremental integer. Records are associative arrays with uid and t3ver_oid fields. The pid of the online record is found as "livepid" the pid of the offline record is found in "wspid
273 * @param string $filterTxt The given filter text from the grid.
274 * @return string
275 */
276 protected function calculateHash(array $versions, $filterTxt) {
277 $hashArray = array(
278 $GLOBALS['BE_USER']->workspace,
279 $GLOBALS['BE_USER']->user['uid'],
280 $versions,
281 $filterTxt,
282 $this->sort,
283 $this->sortDir,
284 $this->currentWorkspace
285 );
286 $hash = md5(serialize($hashArray));
287 return $hash;
288 }
289
290 /**
291 * Performs sorting on the data array accordant to the
292 * selected column in the grid view to be used for sorting.
293 *
294 * @return void
295 */
296 protected function sortDataArray() {
297 if (is_array($this->dataArray)) {
298 switch ($this->sort) {
299 case 'uid':
300
301 case 'change':
302
303 case 'workspace_Tstamp':
304
305 case 't3ver_oid':
306
307 case 'liveid':
308
309 case 'livepid':
310
311 case 'languageValue':
312 usort($this->dataArray, array($this, 'intSort'));
313 break;
314 case 'label_Workspace':
315
316 case 'label_Live':
317
318 case 'label_Stage':
319
320 case 'workspace_Title':
321
322 case 'path_Live':
323 // case 'path_Workspace': This is the first sorting attribute
324 usort($this->dataArray, array($this, 'stringSort'));
325 break;
326 }
327 } else {
328 \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog('Try to sort "' . $this->sort . '" in "TYPO3\\CMS\\Workspaces\\Service\\GridDataService::sortDataArray" but $this->dataArray is empty! This might be the Bug #26422 which could not reproduced yet.', 3);
329 }
330 // Suggested slot method:
331 // methodName(Tx_Workspaces_Service_GridData $gridData, array &$dataArray, $sortColumn, $sortDirection)
332 $this->emitSignal(self::SIGNAL_SortDataArray_PostProcesss, $this->dataArray, $this->sort, $this->sortDir);
333 }
334
335 /**
336 * Implements individual sorting for columns based on integer comparison.
337 *
338 * @param array $a First value
339 * @param array $b Second value
340 * @return integer
341 */
342 protected function intSort(array $a, array $b) {
343 // First sort by using the page-path in current workspace
344 $path_cmp = strcasecmp($a['path_Workspace'], $b['path_Workspace']);
345 if ($path_cmp < 0) {
346 return $path_cmp;
347 } elseif ($path_cmp == 0) {
348 if ($a[$this->sort] == $b[$this->sort]) {
349 return 0;
350 }
351 if ($this->sortDir == 'ASC') {
352 return $a[$this->sort] < $b[$this->sort] ? -1 : 1;
353 } elseif ($this->sortDir == 'DESC') {
354 return $a[$this->sort] > $b[$this->sort] ? -1 : 1;
355 }
356 } elseif ($path_cmp > 0) {
357 return $path_cmp;
358 }
359 return 0;
360 }
361
362 /**
363 * Implements individual sorting for columns based on string comparison.
364 *
365 * @param string $a First value
366 * @param string $b Second value
367 * @return integer
368 */
369 protected function stringSort($a, $b) {
370 $path_cmp = strcasecmp($a['path_Workspace'], $b['path_Workspace']);
371 if ($path_cmp < 0) {
372 return $path_cmp;
373 } elseif ($path_cmp == 0) {
374 if ($a[$this->sort] == $b[$this->sort]) {
375 return 0;
376 }
377 if ($this->sortDir == 'ASC') {
378 return strcasecmp($a[$this->sort], $b[$this->sort]);
379 } elseif ($this->sortDir == 'DESC') {
380 return strcasecmp($a[$this->sort], $b[$this->sort]) * -1;
381 }
382 } elseif ($path_cmp > 0) {
383 return $path_cmp;
384 }
385 return 0;
386 }
387
388 /**
389 * Determines whether the text used to filter the results is part of
390 * a column that is visible in the grid view.
391 *
392 * @param string $filterText
393 * @param array $versionArray
394 * @return boolean
395 */
396 protected function isFilterTextInVisibleColumns($filterText, array $versionArray) {
397 if (is_array($GLOBALS['BE_USER']->uc['moduleData']['Workspaces'][$GLOBALS['BE_USER']->workspace]['columns'])) {
398 foreach ($GLOBALS['BE_USER']->uc['moduleData']['Workspaces'][$GLOBALS['BE_USER']->workspace]['columns'] as $column => $value) {
399 if (isset($value['hidden']) && isset($column) && isset($versionArray[$column])) {
400 if ($value['hidden'] == 0) {
401 switch ($column) {
402 case 'workspace_Tstamp':
403 if (stripos($versionArray['workspace_Formated_Tstamp'], $filterText) !== FALSE) {
404 return TRUE;
405 }
406 break;
407 case 'change':
408 if (stripos(strval($versionArray[$column]), str_replace('%', '', $filterText)) !== FALSE) {
409 return TRUE;
410 }
411 break;
412 default:
413 if (stripos(strval($versionArray[$column]), $filterText) !== FALSE) {
414 return TRUE;
415 }
416 }
417 }
418 }
419 }
420 }
421 return FALSE;
422 }
423
424 /**
425 * Gets the state of a given state value.
426 *
427 * @param integer $stateId stateId of offline record
428 * @param boolean $hiddenOnline hidden status of online record
429 * @param boolean $hiddenOffline hidden status of offline record
430 * @return string
431 */
432 protected function workspaceState($stateId, $hiddenOnline = FALSE, $hiddenOffline = FALSE) {
433 switch ($stateId) {
434 case -1:
435 $state = 'new';
436 break;
437 case 1:
438
439 case 2:
440 $state = 'deleted';
441 break;
442 case 4:
443 $state = 'moved';
444 break;
445 default:
446 $state = 'modified';
447 }
448 if ($hiddenOnline == 0 && $hiddenOffline == 1) {
449 $state = 'hidden';
450 } elseif ($hiddenOnline == 1 && $hiddenOffline == 0) {
451 $state = 'unhidden';
452 }
453 return $state;
454 }
455
456 /**
457 * Gets the field name of the enable-columns as defined in $TCA.
458 *
459 * @param string $table Name of the table
460 * @param string $type Type to be fetches (e.g. 'disabled', 'starttime', 'endtime', 'fe_group)
461 * @return string|NULL The accordant field name or NULL if not defined
462 */
463 protected function getTcaEnableColumnsFieldName($table, $type) {
464 $fieldName = NULL;
465
466 if (!(empty($GLOBALS['TCA'][$table]['ctrl']['enablecolumns'][$type]))) {
467 $fieldName = $GLOBALS['TCA'][$table]['ctrl']['enablecolumns'][$type];
468 }
469
470 return $fieldName;
471 }
472
473 /**
474 * Gets the used language value (sys_language.uid) of
475 * a given database record.
476 *
477 * @param string $table Name of the table
478 * @param array $record Database record
479 * @return integer
480 */
481 protected function getLanguageValue($table, array $record) {
482 $languageValue = 0;
483 if (\TYPO3\CMS\Backend\Utility\BackendUtility::isTableLocalizable($table)) {
484 $languageField = $GLOBALS['TCA'][$table]['ctrl']['languageField'];
485 if (!empty($record[$languageField])) {
486 $languageValue = $record[$languageField];
487 }
488 }
489 return $languageValue;
490 }
491
492 /**
493 * Gets a named value of the available sys_language elements.
494 *
495 * @param integer $id sys_language uid
496 * @param string $key Name of the value to be fetched (e.g. title)
497 * @return string|NULL
498 * @see getSystemLanguages
499 */
500 protected function getSystemLanguageValue($id, $key) {
501 $value = NULL;
502 $systemLanguages = $this->getSystemLanguages();
503 if (!empty($systemLanguages[$id][$key])) {
504 $value = $systemLanguages[$id][$key];
505 }
506 return $value;
507 }
508
509 /**
510 * Gets all available system languages.
511 *
512 * @return array
513 * @see \TYPO3\CMS\Backend\Configuration\TranslationConfigurationProvider::getSystemLanguages
514 */
515 public function getSystemLanguages() {
516 if (!isset($this->systemLanguages)) {
517 /** @var $translateTools \TYPO3\CMS\Backend\Configuration\TranslationConfigurationProvider */
518 $translateTools = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Configuration\\TranslationConfigurationProvider');
519 $this->systemLanguages = $translateTools->getSystemLanguages();
520 }
521 return $this->systemLanguages;
522 }
523
524 /**
525 * Gets an instance of the integrity service.
526 *
527 * @return \TYPO3\CMS\Workspaces\Service\IntegrityService
528 */
529 protected function getIntegrityService() {
530 if (!isset($this->integrityService)) {
531 $this->integrityService = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Workspaces\\Service\\IntegrityService');
532 }
533 return $this->integrityService;
534 }
535
536 /**
537 * Emits a signal to be handled by any registered slots.
538 *
539 * @param string $signalName Name of the signal
540 * @return void
541 */
542 protected function emitSignal($signalName) {
543 // Arguments are always ($this, [method argument], [method argument], ...)
544 $signalArguments = array_merge(array($this), array_slice(func_get_args(), 1));
545 $this->getSignalSlotDispatcher()->dispatch('TYPO3\\CMS\\Workspaces\\Service\\GridDataService', $signalName, $signalArguments);
546 }
547
548 /**
549 * @return \TYPO3\CMS\Extbase\SignalSlot\Dispatcher
550 */
551 protected function getSignalSlotDispatcher() {
552 return $this->getObjectManager()->get('TYPO3\\CMS\\Extbase\\SignalSlot\\Dispatcher');
553 }
554
555 /**
556 * @return \TYPO3\CMS\Extbase\Object\ObjectManagerException
557 */
558 protected function getObjectManager() {
559 return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManagerException');
560 }
561
562 }
563
564
565 ?>