[TASK] Deprecate MenuViewHelperTrait
[Packages/TYPO3.CMS.git] / typo3 / sysext / fluid_styled_content / Classes / ViewHelpers / Menu / KeywordsViewHelper.php
1 <?php
2 namespace TYPO3\CMS\FluidStyledContent\ViewHelpers\Menu;
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 TYPO3\CMS\Core\Database\DatabaseConnection;
17
18 /**
19 * A view helper which returns pages with one of the same keywords as the given pages
20 *
21 * Search default starts at the root of the current page tree.
22 * With entryLevel this can be adjusted.
23 *
24 * = Example =
25 *
26 * <code title="Pages with the similar keyword(s) of page uid = 1 and uid = 2">
27 * <ce:menu.keywords pageUids="{0: 1, 1: 2}" as="pages">
28 * <f:for each="{pages}" as="page">
29 * {page.title}
30 * </f:for>
31 * </ce:menu.keywords>
32 * </code>
33 *
34 * <output>
35 * Page with the keywords "typo3" and "fluid"
36 * Page with the keyword "fluid"
37 * Page with the keyword "typo3"
38 * </output>
39 */
40 class KeywordsViewHelper extends AbstractMenuViewHelper
41 {
42
43 /**
44 * Output escaping is disabled as child content contains HTML by default
45 *
46 * @var bool
47 */
48 protected $escapeOutput = false;
49
50 /**
51 * Initialize ViewHelper arguments
52 *
53 * @return void
54 */
55 public function initializeArguments()
56 {
57 $this->registerArgument('as', 'string', 'Name of template variable which will contain selected pages', true);
58 $this->registerArgument('entryLevel', 'integer', 'The entry level', false, 0);
59 $this->registerArgument('pageUids', 'array', 'Page UIDs of pages to fetch the keywords from', false, array());
60 $this->registerArgument('keywords', 'array', 'Keywords for which to search', false, array());
61 $this->registerArgument('includeNotInMenu', 'boolean', 'Include pages that are marked "hide in menu"?', false, false);
62 $this->registerArgument('includeMenuSeparator', 'boolean', 'Include pages of the type "Menu separator"?', false, false);
63 $this->registerArgument('excludeNoSearchPages', 'boolean', 'Exclude pages that are NOT marked "include in search"?', false, true);
64 }
65
66 /**
67 * Render the view helper
68 *
69 * @return string
70 */
71 public function render()
72 {
73 $typoScriptFrontendController = $this->getTypoScriptFrontendController();
74 $as = (string)$this->arguments['as'];
75 $entryLevel = (int)$this->arguments['entryLevel'];
76 $pageUids = (array)$this->arguments['pageUids'];
77 $keywords = (array)$this->arguments['keywords'];
78 $includeNotInMenu = (bool)$this->arguments['includeNotInMenu'];
79 $includeMenuSeparator = (bool)$this->arguments['includeMenuSeparator'];
80 $excludeNoSearchPages = (bool)$this->arguments['excludeNoSearchPages'];
81
82 // If no pages have been defined, use the current page
83 if (empty($pageUids)) {
84 $pageUids = array($typoScriptFrontendController->page['uid']);
85 }
86
87 // Transform the keywords list into an array
88 if (!is_array($keywords)) {
89 $unfilteredKeywords = $this->keywordsToArray($keywords);
90 } else {
91 $unfilteredKeywords = $keywords;
92 }
93
94 // Use the keywords of the page when none has been given
95 if (empty($keywords)) {
96 foreach ($pageUids as $pageUid) {
97 $page = $typoScriptFrontendController->sys_page->getPage($pageUid);
98 $unfilteredKeywords = array_merge(
99 $unfilteredKeywords,
100 $this->keywordsToArray($page['keywords'])
101 );
102 }
103 }
104 $filteredKeywords = array_unique($unfilteredKeywords);
105
106 $constraints = $this->getPageConstraints($includeNotInMenu, $includeMenuSeparator);
107 if ($excludeNoSearchPages) {
108 $constraints .= ' AND no_search = 0';
109 }
110
111 $keywordConstraints = array();
112 if ($filteredKeywords) {
113 $db = $this->getDatabaseConnection();
114 foreach ($filteredKeywords as $keyword) {
115 $keyword = $db->fullQuoteStr('%' . $db->escapeStrForLike($keyword, 'pages') . '%', 'pages');
116 $keywordConstraints[] = 'keywords LIKE ' . $keyword;
117 }
118 $constraints .= ' AND (' . implode(' OR ', $keywordConstraints) . ')';
119 }
120
121 // Start point
122 if ($entryLevel < 0) {
123 $entryLevel = count($typoScriptFrontendController->tmpl->rootLine) - 1 + $entryLevel;
124 }
125 $startUid = $typoScriptFrontendController->tmpl->rootLine[$entryLevel]['uid'];
126 $treePageUids = explode(
127 ',',
128 $typoScriptFrontendController->cObj->getTreeList($startUid, 20)
129 );
130
131 $pages = $typoScriptFrontendController->sys_page->getMenuForPages(
132 array_merge([$startUid], $treePageUids),
133 '*',
134 '',
135 $constraints
136 );
137 return $this->renderChildrenWithVariables(array(
138 $as => $pages
139 ));
140 }
141
142 /**
143 * Get a clean array of keywords
144 *
145 * The list of keywords can have a separator like comma, semicolon or line feed
146 *
147 * @param string $keywords The list of keywords
148 * @return array Cleaned up list
149 */
150 protected function keywordsToArray($keywords)
151 {
152 $keywordList = preg_split('/[,;' . LF . ']/', $keywords);
153
154 return array_filter(array_map('trim', $keywordList));
155 }
156
157 /**
158 * @return DatabaseConnection
159 */
160 protected function getDatabaseConnection()
161 {
162 return $GLOBALS['TYPO3_DB'];
163 }
164 }