This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace AOE\Languagevisibility; |
||
4 | |||
5 | /*************************************************************** |
||
6 | * Copyright notice |
||
7 | * |
||
8 | * (c) 2014 AOE GmbH <[email protected]> |
||
9 | * |
||
10 | * All rights reserved |
||
11 | * |
||
12 | * This script is part of the TYPO3 project. The TYPO3 project is |
||
13 | * free software; you can redistribute it and/or modify |
||
14 | * it under the terms of the GNU General Public License as published by |
||
15 | * the Free Software Foundation; either version 3 of the License, or |
||
16 | * (at your option) any later version. |
||
17 | * |
||
18 | * The GNU General Public License can be found at |
||
19 | * http://www.gnu.org/copyleft/gpl.html. |
||
20 | * |
||
21 | * This script is distributed in the hope that it will be useful, |
||
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
24 | * GNU General Public License for more details. |
||
25 | * |
||
26 | * This copyright notice MUST APPEAR in all copies of the script! |
||
27 | ***************************************************************/ |
||
28 | |||
29 | use AOE\Languagevisibility\Dao\DaoCommon; |
||
30 | use AOE\Languagevisibility\Services\FeServices; |
||
31 | use TYPO3\CMS\Core\Utility\GeneralUtility; |
||
32 | |||
33 | /** |
||
34 | * Class \AOE\Languagevisibility\ElementFactory |
||
35 | */ |
||
36 | class ElementFactory { |
||
37 | |||
38 | /** |
||
39 | * @var DaoCommon |
||
40 | */ |
||
41 | protected $dao; |
||
42 | |||
43 | /** |
||
44 | * Dependency is injected, this object needs a simple Data Access Object (can be replaced in testcase) |
||
45 | */ |
||
46 | public function __construct($dao) { |
||
47 | $this->dao = $dao; |
||
48 | } |
||
49 | |||
50 | /** |
||
51 | * Returns ready initialised "element" object. Depending on the element the correct element class is used. (e.g. page/content/fce) |
||
52 | * |
||
53 | * @param string $table table |
||
54 | * @param int $uid identifier |
||
55 | * @param bool $overlay_ids boolean parameter to overlay uids if the user is in workspace context |
||
56 | * @throws \UnexpectedValueException |
||
57 | * @return Element |
||
58 | */ |
||
59 | public function getElementForTable($table, $uid, $overlay_ids = TRUE) { |
||
60 | if (!FeServices::isSupportedTable($table)) { |
||
61 | throw new \UnexpectedValueException($table . ' not supported ', 1195039394); |
||
62 | } |
||
63 | |||
64 | if (!is_numeric($uid) || (intval($uid) === 0)) { |
||
65 | // no uid => maybe NEW element in BE |
||
66 | $row = array(); |
||
67 | } else { |
||
68 | if (is_object($GLOBALS['BE_USER']) && $GLOBALS['BE_USER']->workspace != 0 && $overlay_ids) { |
||
69 | $row = $this->getWorkspaceOverlay($table, $uid); |
||
70 | } else { |
||
71 | $row = $this->dao->getRecord($uid, $table); |
||
72 | } |
||
73 | } |
||
74 | |||
75 | /** @var Element $element */ |
||
76 | switch ($table) { |
||
77 | case 'pages': |
||
78 | $element = GeneralUtility::makeInstance('AOE\\Languagevisibility\\PageElement', $row, $table); |
||
79 | break; |
||
80 | case 'tt_news': |
||
81 | $element = GeneralUtility::makeInstance('AOE\\Languagevisibility\\TtnewsElement', $row, $table); |
||
82 | break; |
||
83 | case 'tt_content': |
||
84 | if ($row['CType'] == 'templavoila_pi1') { |
||
85 | // read DS: |
||
86 | $srcPointer = $row['tx_templavoila_ds']; |
||
87 | $DS = $this->_getTVDS($srcPointer); |
||
88 | if (is_array($DS)) { |
||
89 | if ($DS['meta']['langDisable'] == 1 && $DS['meta']['langDatabaseOverlay'] == 1) { |
||
90 | // handle as special FCE with normal tt_content overlay: |
||
91 | $element = GeneralUtility::makeInstance('AOE\\Languagevisibility\\FceOverlayElement', $row); |
||
92 | } else { |
||
93 | $element = GeneralUtility::makeInstance('AOE\\Languagevisibility\\FceElement', $row, $DS); |
||
94 | } |
||
95 | } else { |
||
96 | throw new \UnexpectedValueException($table . ' uid:' . $row['uid'] . ' has no valid Datastructure ', 1195039394); |
||
97 | } |
||
98 | } else { |
||
99 | $element = GeneralUtility::makeInstance('AOE\\Languagevisibility\\CElement', $row, $table); |
||
100 | } |
||
101 | break; |
||
102 | default: |
||
103 | if (isset ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['languagevisibility']['getElementForTable'][$table])) { |
||
104 | $hookObj = GeneralUtility::getUserObj($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['languagevisibility']['getElementForTable'][$table]); |
||
105 | if (method_exists($hookObj, 'getElementForTable')) { |
||
106 | $element = $hookObj->getElementForTable($table, $uid, $row, $overlay_ids); |
||
107 | } |
||
108 | } elseif (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['languagevisibility']['recordElementSupportedTables'][$table])) { |
||
109 | $element = $this->getElementInstance('AOE\\Languagevisibility\\RecordElement', $row, $table); |
||
0 ignored issues
–
show
|
|||
110 | } else { |
||
111 | throw new \UnexpectedValueException($table . ' not supported ', 1195039394); |
||
112 | } |
||
113 | break; |
||
114 | } |
||
115 | |||
116 | $element->setTable($table); |
||
0 ignored issues
–
show
The variable
$element does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
117 | |||
118 | return $element; |
||
119 | } |
||
120 | |||
121 | /** |
||
122 | * Get workspace overlay for a record. |
||
123 | * |
||
124 | * @param string $table Table name |
||
125 | * @param integer $uid Record UID |
||
126 | * @return array |
||
127 | */ |
||
128 | protected function getWorkspaceOverlay($table, $uid) { |
||
129 | $row = $this->dao->getRecord($uid, $table); |
||
130 | |||
131 | if (is_array($row)) { |
||
132 | if (is_object($GLOBALS['TSFE'])) { |
||
133 | $GLOBALS['TSFE']->sys_page->versionOL($table, $row); |
||
134 | } else { |
||
135 | \TYPO3\CMS\Backend\Utility\BackendUtility::workspaceOL($table, $row); |
||
136 | } |
||
137 | } |
||
138 | // the overlay row might be FALSE if the record is hidden |
||
139 | // or deleted in workspace. In this case we return an empty array. |
||
140 | if (!is_array($row)) { |
||
141 | $row = array(); |
||
142 | } |
||
143 | |||
144 | return $row; |
||
145 | } |
||
146 | |||
147 | /** |
||
148 | * This method is used to retrieve all parent elements (an parent elements needs to |
||
149 | * have the flag 'tx_languagevisibility_inheritanceflag_original' or |
||
150 | * needs to be orverlayed with a record, that has the field 'tx_languagevisibility_inheritanceflag_overlayed' |
||
151 | * configured or is the first element of the rootline |
||
152 | * |
||
153 | * @param tx_languagevisibility_element $element |
||
154 | * @param $language |
||
155 | * @return array $elements (collection of tx_languagevisibility_element) |
||
156 | */ |
||
157 | public function getParentElementsFromElement(Element $element, $language) { |
||
158 | $elements = array(); |
||
159 | |||
160 | if ($element instanceof PageElement) { |
||
161 | $rootline = $this->getOverlayedRootLine($element->getUid(), $language->getUid()); |
||
162 | |||
163 | if (is_array($rootline)) { |
||
164 | foreach ($rootline as $rootlineElement) { |
||
165 | if ($rootlineElement['tx_languagevisibility_inheritanceflag_original'] == 1 || |
||
166 | $rootlineElement['tx_languagevisibility_inheritanceflag_overlayed'] == 1 |
||
167 | ) { |
||
168 | $elements[] = self::getElementForTable('pages', $rootlineElement['uid']); |
||
169 | } |
||
170 | } |
||
171 | |||
172 | if (sizeof($elements) == 0) { |
||
173 | $root = end($rootline); |
||
174 | $elements[] = self::getElementForTable('pages', $root['uid']); |
||
175 | } |
||
176 | } |
||
177 | } else { |
||
178 | $parentPage = $this->getElementForTable('pages', $element->getUid()); |
||
179 | $elements = $this->getParentElementsFromElement($parentPage, $language); |
||
180 | } |
||
181 | |||
182 | return $elements; |
||
183 | } |
||
184 | |||
185 | /** |
||
186 | * This method is needed because the getRootline method from \TYPO3\CMS\Frontend\Page\PageRepository causes an error when |
||
187 | * getRootline is called be cause getRootline internally uses languagevisibility to determine the |
||
188 | * visibility during the rootline calculation. This results in an unlimited recursion. |
||
189 | * |
||
190 | * @todo The rooline can be build in a smarter way, once the rootline for a page has been created |
||
191 | * same parts of the rootline not have to be calculated twice. |
||
192 | * @param $uid |
||
193 | * @param $languageid |
||
194 | * @return array |
||
195 | * @internal param \The $integer page uid for which to seek back to the page tree root. |
||
196 | * @see tslib_fe::getPageAndRootline() |
||
197 | */ |
||
198 | protected function getOverlayedRootLine($uid, $languageid) { |
||
199 | $cacheManager = CacheManager::getInstance(); |
||
200 | |||
201 | $cacheData = $cacheManager->get('overlayedRootline'); |
||
202 | $isCacheEnabled = $cacheManager->isCacheEnabled(); |
||
203 | |||
204 | if (!$isCacheEnabled || !isset($cacheData[$uid][$languageid])) { |
||
205 | $sys_page = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Page\\PageRepository'); |
||
206 | $sys_page->sys_language_uid = $languageid; |
||
207 | |||
208 | $uid = intval($uid); |
||
209 | |||
210 | $loopCheck = 0; |
||
211 | $theRowArray = Array(); |
||
212 | |||
213 | while ($uid != 0 && $loopCheck < 20) { // Max 20 levels in the page tree. |
||
214 | |||
215 | $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'pages', 'uid=' . intval($uid) . ' AND pages.deleted=0 AND pages.doktype!=255'); |
||
216 | $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res); |
||
217 | $GLOBALS['TYPO3_DB']->sql_free_result($res); |
||
218 | |||
219 | if ($row) { |
||
220 | $sys_page->versionOL('pages', $row, FALSE, TRUE); |
||
221 | $sys_page->fixVersioningPid('pages', $row); |
||
222 | |||
223 | if (is_array($row)) { |
||
224 | // Mount Point page types are allowed ONLY a) if they are the outermost record in rootline and b) if the overlay flag is not set: |
||
225 | $uid = $row['pid']; // Next uid |
||
226 | } |
||
227 | // Add row to rootline with language overlaid: |
||
228 | $langvisHook = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getPageOverlay']['languagevisility']; |
||
229 | unset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getPageOverlay']['languagevisility']); |
||
230 | $theRowArray[] = $sys_page->getPageOverlay($row, $languageid); |
||
231 | $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_page.php']['getPageOverlay']['languagevisility'] = $langvisHook; |
||
232 | } else { |
||
233 | return array(); // broken rootline. |
||
234 | } |
||
235 | |||
236 | $loopCheck++; |
||
237 | } |
||
238 | |||
239 | // Create output array (with reversed order of numeric keys): |
||
240 | $output = Array(); |
||
241 | $c = count($theRowArray); |
||
242 | foreach ($theRowArray as $key => $val) { |
||
243 | $c--; |
||
244 | $output[$c] = $val; |
||
245 | } |
||
246 | |||
247 | $cacheData[$uid][$languageid] = $output; |
||
248 | $cacheManager->set('overlayedRootline', $cacheData); |
||
249 | } |
||
250 | |||
251 | return $cacheData[$uid][$languageid]; |
||
252 | } |
||
253 | |||
254 | /** |
||
255 | * Determines the dataStructure from a given sourcePointer. |
||
256 | * |
||
257 | * @param $srcPointer |
||
258 | * @return array |
||
259 | */ |
||
260 | protected function _getTVDS($srcPointer) { |
||
261 | $cacheManager = CacheManager::getInstance(); |
||
262 | |||
263 | $cacheData = $cacheManager->get('dataStructureCache'); |
||
264 | $isCacheEnabled = $cacheManager->isCacheEnabled(); |
||
265 | |||
266 | if (!$isCacheEnabled || !isset($cacheData[$srcPointer])) { |
||
267 | $DS = array(); |
||
268 | $srcPointerIsInteger = \TYPO3\CMS\Core\Utility\MathUtility::convertToPositiveInteger($srcPointer); |
||
269 | if ($srcPointerIsInteger) { // If integer, then its a record we will look up: |
||
270 | $sys_page = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Page\\PageRepository'); |
||
271 | $DSrec = $sys_page->getRawRecord('tx_templavoila_datastructure', $srcPointer, 'dataprot'); |
||
272 | $DS = GeneralUtility::xml2array($DSrec['dataprot']); |
||
273 | } else { // Otherwise expect it to be a file: |
||
274 | $file = GeneralUtility::getFileAbsFileName($srcPointer); |
||
275 | if ($file && @is_file($file)) { |
||
276 | $DS = GeneralUtility::xml2array(GeneralUtility::getUrl($file)); |
||
277 | } |
||
278 | } |
||
279 | |||
280 | $cacheData[$srcPointer] = $DS; |
||
281 | $cacheManager->set('dataStructureCache', $cacheData); |
||
282 | } |
||
283 | |||
284 | return $cacheData[$srcPointer]; |
||
285 | } |
||
286 | |||
287 | /** |
||
288 | * Gets instance depending on TYPO3 version |
||
289 | * @param $name name of the class |
||
290 | * @param array $row row that is used to initialaze element instance |
||
291 | * @return tx_languagevisibility_element |
||
292 | */ |
||
293 | private function getElementInstance($name, $row) { |
||
294 | return GeneralUtility::makeInstance($name, $row); |
||
295 | } |
||
296 | } |
||
297 |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.