[TASK] Create own response instance in controller actions
[Packages/TYPO3.CMS.git] / typo3 / sysext / t3editor / Classes / CodeCompletion.php
1 <?php
2 namespace TYPO3\CMS\T3editor;
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 use Psr\Http\Message\ResponseInterface;
17 use Psr\Http\Message\ServerRequestInterface;
18 use TYPO3\CMS\Core\Http\HtmlResponse;
19 use TYPO3\CMS\Core\Http\JsonResponse;
20
21 /**
22 * Code completion for t3editor
23 */
24 class CodeCompletion
25 {
26 /**
27 * @var \TYPO3\CMS\Core\Http\AjaxRequestHandler
28 */
29 protected $ajaxObj;
30
31 /**
32 * Default constructor
33 */
34 public function __construct()
35 {
36 $GLOBALS['LANG']->includeLLFile('EXT:t3editor/Resources/Private/Language/locallang.xlf');
37 }
38
39 /**
40 * General processor for AJAX requests.
41 * Called by AjaxRequestHandler
42 *
43 * @param ServerRequestInterface $request
44 * @return ResponseInterface
45 */
46 public function processAjaxRequest(ServerRequestInterface $request): ResponseInterface
47 {
48 $pageId = (int)($request->getParsedBody()['pageId'] ?? $request->getQueryParams()['pageId']);
49 return $this->loadTemplates($pageId);
50 }
51
52 /**
53 * Loads all templates up to a given page id (walking the rootline) and
54 * cleans parts that are not required for the t3editor codecompletion.
55 *
56 * @param int $pageId ID of the page
57 * @return ResponseInterface
58 */
59 protected function loadTemplates($pageId): ResponseInterface
60 {
61 // Check whether access is granted (only admin have access to sys_template records):
62 if ($GLOBALS['BE_USER']->isAdmin()) {
63 // Check whether there is a pageId given:
64 if ($pageId) {
65 return (new JsonResponse())->setPayload($this->getMergedTemplates($pageId));
66 }
67 return new HtmlResponse($GLOBALS['LANG']->getLL('pageIDInteger'), 500);
68 }
69 return new HtmlResponse($GLOBALS['LANG']->getLL('noPermission'), 500);
70 }
71
72 /**
73 * Gets merged templates by walking the rootline to a given page id.
74 *
75 * @todo oliver@typo3.org: Refactor this method and comment what's going on there
76 * @param int $pageId
77 * @return array Setup part of merged template records
78 */
79 protected function getMergedTemplates($pageId)
80 {
81 /** @var $tsParser \TYPO3\CMS\Core\TypoScript\ExtendedTemplateService */
82 $tsParser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\TypoScript\ExtendedTemplateService::class);
83 $tsParser->init();
84 // Gets the rootLine
85 $page = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\Page\PageRepository::class);
86 $rootLine = $page->getRootLine($pageId);
87 // This generates the constants/config + hierarchy info for the template.
88 $tsParser->runThroughTemplates($rootLine);
89 // ts-setup & ts-constants of the currently edited template should not be included
90 // therefor we have to delete the last template from the stack
91 array_pop($tsParser->config);
92 array_pop($tsParser->constants);
93 $tsParser->linkObjects = true;
94 $tsParser->ext_regLinenumbers = false;
95 $tsParser->generateConfig();
96 $result = $this->treeWalkCleanup($tsParser->setup);
97 return $result;
98 }
99
100 /**
101 * Walks through a tree of TypoScript configuration an cleans it up.
102 *
103 * @TODO oliver@typo3.org: Define and comment why this is necessary and exactly happens below
104 * @param array $treeBranch TypoScript configuration or sub branch of it
105 * @return array Cleaned TypoScript branch
106 */
107 private function treeWalkCleanup(array $treeBranch)
108 {
109 $cleanedTreeBranch = [];
110 foreach ($treeBranch as $key => $value) {
111 $dotCount = substr_count($key, '.');
112 //type definition or value-assignment
113 if ($dotCount == 0) {
114 if ($value != '') {
115 if (strlen($value) > 20) {
116 $value = substr($value, 0, 20);
117 }
118 if (!isset($cleanedTreeBranch[$key])) {
119 $cleanedTreeBranch[$key] = [];
120 }
121 $cleanedTreeBranch[$key]['v'] = $value;
122 }
123 } elseif ($dotCount == 1) {
124 // subtree (definition of properties)
125 $subBranch = $this->treeWalkCleanup($value);
126 if ($subBranch) {
127 $key = str_replace('.', '', $key);
128 if (!isset($cleanedTreeBranch[$key])) {
129 $cleanedTreeBranch[$key] = [];
130 }
131 $cleanedTreeBranch[$key]['c'] = $subBranch;
132 }
133 }
134 }
135 return $cleanedTreeBranch;
136 }
137 }