Completed
Push — master ( ca9035...17598f )
by Tim
15:18
created

Classes/Xclass/ContentObjectRenderer.php (6 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * ContentObjectRenderer
4
 */
5
6
namespace FRUIT\Popup\Xclass;
7
8
use TYPO3\CMS\Core\Utility\GeneralUtility;
9
use TYPO3\CMS\Frontend\Plugin\AbstractPlugin;
10
11
/**
12
 * ContentObjectRenderer
13
 */
14
class ContentObjectRenderer extends \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
15
{
16
17
18
    /**
19
     * Implements the "typolink" property of stdWrap (and others)
20
     * Basically the input string, $linktext, is (typically) wrapped in a <a>-tag linking to some page, email address, file or URL based on a parameter defined by the configuration array $conf.
21
     * This function is best used from internal functions as is. There are some API functions defined after this function which is more suited for general usage in external applications.
22
     * Generally the concept "typolink" should be used in your own applications as an API for making links to pages with parameters and more. The reason for this is that you will then automatically make links compatible with all the centralized functions for URL simulation and manipulation of parameters into hashes and more.
23
     * For many more details on the parameters and how they are intepreted, please see the link to TSref below.
24
     *
25
     * @param    string        The string (text) to link
26
     * @param    array        TypoScript configuration (see link below)
27
     * @return    string        A link-wrapped string.
28
     * @see stdWrap(), tslib_pibase::pi_linkTP()
29
     * @link http://typo3.org/doc.0.html?&tx_extrepmgm_pi1[extUid]=270&tx_extrepmgm_pi1[tocEl]=321&cHash=59bd727a5e
30
     */
31
    public function typoLink($linktxt, $conf)
32
    {
33
        $LD = [];
34
        $finalTagParts = [];
35
        $finalTagParts['aTagParams'] = $this->getATagParams($conf);
36
37
        $link_param = trim($this->stdWrap($conf['parameter'], $conf['parameter.']));
38
39
        $sectionMark = trim($this->stdWrap($conf['section'], $conf['section.']));
40
        $sectionMark = $sectionMark ? (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($sectionMark) ? '#c' : '#') . $sectionMark : '';
41
        $initP = '?id=' . $GLOBALS['TSFE']->id . '&type=' . $GLOBALS['TSFE']->type;
42
        $this->lastTypoLinkUrl = '';
43
        $this->lastTypoLinkTarget = '';
44
        if ($link_param) {
45
            $enableLinksAcrossDomains = $GLOBALS['TSFE']->config['config']['typolinkEnableLinksAcrossDomains'];
46
            $link_paramA = GeneralUtility::unQuoteFilenames($link_param, true);
47
48
            // Check for link-handler keyword:
49
            list($linkHandlerKeyword, $linkHandlerValue) = explode(':', trim($link_paramA[0]), 2);
50
            if ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['typolinkLinkHandler'][$linkHandlerKeyword] && strcmp(
51
                $linkHandlerValue,
52
                ''
53
            )
54
            ) {
55
                $linkHandlerObj = GeneralUtility::getUserObj($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['typolinkLinkHandler'][$linkHandlerKeyword]);
56
57
                if (method_exists($linkHandlerObj, 'main')) {
58
                    return $linkHandlerObj->main(
59
                        $linktxt,
60
                        $conf,
61
                        $linkHandlerKeyword,
62
                        $linkHandlerValue,
63
                        $link_param,
64
                        $this
65
                    );
66
                }
67
            }
68
69
            $link_param = trim($link_paramA[0]);    // Link parameter value
70
            $linkClass = trim($link_paramA[2]);        // Link class
71
            if ($linkClass == '-') {
72
                $linkClass = '';
73
            }    // The '-' character means 'no class'. Necessary in order to specify a title as fourth parameter without setting the target or class!
74
            $forceTarget = trim($link_paramA[1]);    // Target value
75
            $forceTitle = trim($link_paramA[3]);    // Title value
76
            if ($forceTarget == '-') {
77
                $forceTarget = '';
78
            }    // The '-' character means 'no target'. Necessary in order to specify a class as third parameter without setting the target!
79
            // Check, if the target is coded as a JS open window link:
80
            $JSwindowParts = [];
81
            $JSwindowParams = '';
82
            $onClick = '';
0 ignored issues
show
$onClick is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
83
            if ($forceTarget && preg_match('/^([0-9]+)x([0-9]+)(:(.*)|.*)$/', $forceTarget, $JSwindowParts)) {
84
                // Take all pre-configured and inserted parameters and compile parameter list, including width+height:
85
                $JSwindow_tempParamsArr = GeneralUtility::trimExplode(
86
                    ',',
87
                    strtolower($conf['JSwindow_params'] . ',' . $JSwindowParts[4]),
88
                    1
0 ignored issues
show
1 is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
89
                );
90
                $JSwindow_paramsArr = [];
91
                foreach ($JSwindow_tempParamsArr as $JSv) {
92
                    list($JSp, $JSv) = explode('=', $JSv);
93
                    $JSwindow_paramsArr[$JSp] = $JSp . '=' . $JSv;
94
                }
95
                // Add width/height:
96
                $JSwindow_paramsArr['width'] = 'width=' . $JSwindowParts[1];
97
                $JSwindow_paramsArr['height'] = 'height=' . $JSwindowParts[2];
98
                // Imploding into string:
99
                $JSwindowParams = implode(',', $JSwindow_paramsArr);
100
                $forceTarget = '';    // Resetting the target since we will use onClick.
101
            }
102
103
            // Internal target:
104
            $target = isset($conf['target']) ? $conf['target'] : $GLOBALS['TSFE']->intTarget;
105
            if ($conf['target.']) {
106
                $target = $this->stdWrap($target, $conf['target.']);
107
            }
108
109
            // Title tag
110
            $title = $conf['title'];
111
            if ($conf['title.']) {
112
                $title = $this->stdWrap($title, $conf['title.']);
113
            }
114
115
            // Parse URL:
116
            $pU = parse_url($link_param);
117
118
            // Detecting kind of link:
119
            if (strstr(
120
                $link_param,
121
                '@'
122
            ) && (!$pU['scheme'] || $pU['scheme'] == 'mailto')
123
            ) {        // If it's a mail address:
124
                $link_param = preg_replace('/^mailto:/i', '', $link_param);
125
                list($this->lastTypoLinkUrl, $linktxt) = $this->getMailTo($link_param, $linktxt, $initP);
0 ignored issues
show
The call to ContentObjectRenderer::getMailTo() has too many arguments starting with $initP.

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.

Loading history...
126
                $finalTagParts['url'] = $this->lastTypoLinkUrl;
127
                $finalTagParts['TYPE'] = 'mailto';
128
            } else {
129
                $isLocalFile = 0;
130
                $fileChar = intval(strpos($link_param, '/'));
131
                $urlChar = intval(strpos($link_param, '.'));
132
133
                // Firsts, test if $link_param is numeric and page with such id exists. If yes, do not attempt to link to file
134
                if (!\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($link_param) || count($GLOBALS['TSFE']->sys_page->getPage_noCheck($link_param)) == 0) {
135
                    // Detects if a file is found in site-root (or is a 'virtual' simulateStaticDocument file!) and if so it will be treated like a normal file.
136
                    list($rootFileDat) = explode('?', rawurldecode($link_param));
137
                    $containsSlash = strstr($rootFileDat, '/');
138
                    $rFD_fI = pathinfo($rootFileDat);
139
                    if (trim($rootFileDat) && !$containsSlash && (@is_file(PATH_site . $rootFileDat) || GeneralUtility::inList(
140
                        'php,html,htm',
141
                        strtolower($rFD_fI['extension'])
142
                    ))
143
                    ) {
144
                        $isLocalFile = 1;
145
                    } elseif ($containsSlash) {
146
                        $isLocalFile = 2;        // Adding this so realurl directories are linked right (non-existing).
147
                    }
148
                }
149
150
                if ($pU['scheme'] || ($isLocalFile != 1 && $urlChar && (!$containsSlash || $urlChar < $fileChar))) {    // url (external): If doubleSlash or if a '.' comes before a '/'.
151
                    $target = isset($conf['extTarget']) ? $conf['extTarget'] : $GLOBALS['TSFE']->extTarget;
152
                    if ($conf['extTarget.']) {
153
                        $target = $this->stdWrap($target, $conf['extTarget.']);
154
                    }
155
                    if ($forceTarget) {
156
                        $target = $forceTarget;
157
                    }
158
                    if ($linktxt == '') {
159
                        $linktxt = $link_param;
160
                    }
161
                    if (!$pU['scheme']) {
162
                        $scheme = 'http://';
163
                    } else {
164
                        $scheme = '';
165
                    }
166
                    if ($GLOBALS['TSFE']->config['config']['jumpurl_enable']) {
167
                        $this->lastTypoLinkUrl = $GLOBALS['TSFE']->absRefPrefix . $GLOBALS['TSFE']->config['mainScript'] . $initP . '&jumpurl=' . rawurlencode($scheme . $link_param) . $GLOBALS['TSFE']->getMethodUrlIdToken;
168
                    } else {
169
                        $this->lastTypoLinkUrl = $scheme . $link_param;
170
                    }
171
                    $this->lastTypoLinkTarget = $target;
172
                    $finalTagParts['url'] = $this->lastTypoLinkUrl;
173
                    $finalTagParts['targetParams'] = $target ? ' target="' . $target . '"' : '';
174
                    $finalTagParts['TYPE'] = 'url';
175
                    $finalTagParts['aTagParams'] .= $this->extLinkATagParams(
176
                        $finalTagParts['url'],
177
                        $finalTagParts['TYPE']
178
                    );
179
                } elseif ($containsSlash || $isLocalFile) {    // file (internal)
0 ignored issues
show
The variable $containsSlash 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

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
180
                    $splitLinkParam = explode('?', $link_param);
181
                    if (file_exists(rawurldecode($splitLinkParam[0])) || $isLocalFile) {
182
                        if ($linktxt == '') {
183
                            $linktxt = rawurldecode($link_param);
184
                        }
185
                        if ($GLOBALS['TSFE']->config['config']['jumpurl_enable']) {
186
                            $this->lastTypoLinkUrl = $GLOBALS['TSFE']->absRefPrefix . $GLOBALS['TSFE']->config['mainScript'] . $initP . '&jumpurl=' . rawurlencode($link_param) . $GLOBALS['TSFE']->getMethodUrlIdToken;
187
                        } else {
188
                            $this->lastTypoLinkUrl = $GLOBALS['TSFE']->absRefPrefix . $link_param;
189
                        }
190
                        $target = isset($conf['fileTarget']) ? $conf['fileTarget'] : $GLOBALS['TSFE']->fileTarget;
191
                        if ($conf['fileTarget.']) {
192
                            $target = $this->stdWrap($target, $conf['fileTarget.']);
193
                        }
194
                        if ($forceTarget) {
195
                            $target = $forceTarget;
196
                        }
197
                        $this->lastTypoLinkTarget = $target;
198
199
                        $finalTagParts['url'] = $this->lastTypoLinkUrl;
200
                        $finalTagParts['targetParams'] = $target ? ' target="' . $target . '"' : '';
201
                        $finalTagParts['TYPE'] = 'file';
202
                        $finalTagParts['aTagParams'] .= $this->extLinkATagParams(
203
                            $finalTagParts['url'],
204
                            $finalTagParts['TYPE']
205
                        );
206
                    } else {
207
                        $GLOBALS['TT']->setTSlogMessage(
208
                            "typolink(): File '" . $splitLinkParam[0] . "' did not exist, so '" . $linktxt . "' was not linked.",
209
                            1
210
                        );
211
                        return $linktxt;
212
                    }
213
                } else {    // integer or alias (alias is without slashes or periods or commas, that is 'nospace,alphanum_x,lower,unique' according to definition in $TCA!)
214
                    if ($conf['no_cache.']) {
215
                        $conf['no_cache'] = $this->stdWrap($conf['no_cache'], $conf['no_cache.']);
216
                    }
217
                    $link_params_parts = explode('#', $link_param);
218
                    $link_param = trim($link_params_parts[0]);        // Link-data del
219
                    if (!strcmp($link_param, '')) {
220
                        $link_param = $GLOBALS['TSFE']->id;
221
                    }    // If no id or alias is given
222
                    if ($link_params_parts[1] && !$sectionMark) {
223
                        $sectionMark = trim($link_params_parts[1]);
224
                        $sectionMark = (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($sectionMark) ? '#c' : '#') . $sectionMark;
225
                    }
226
                    // Splitting the parameter by ',' and if the array counts more than 1 element it's a id/type/? pair
227
                    unset($theTypeP);
228
                    $pairParts = GeneralUtility::trimExplode(',', $link_param);
229
                    if (count($pairParts) > 1) {
230
                        $link_param = $pairParts[0];
231
                        $theTypeP = isset($pairParts[1]) ? $pairParts[1] : 0;        // Overruling 'type'
232
                        $conf['additionalParams'] .= isset($pairParts[2]) ? $pairParts[2] : '';
233
                    }
234
                    // Checking if the id-parameter is an alias.
235
                    if (!\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($link_param)) {
236
                        $link_param = $GLOBALS['TSFE']->sys_page->getPageIdFromAlias($link_param);
237
                    }
238
239
                    // Link to page even if access is missing?
240
                    if (strlen($conf['linkAccessRestrictedPages'])) {
241
                        $disableGroupAccessCheck = ($conf['linkAccessRestrictedPages'] ? true : false);
242
                    } else {
243
                        $disableGroupAccessCheck = ($GLOBALS['TSFE']->config['config']['typolinkLinkAccessRestrictedPages'] ? true : false);
244
                    }
245
246
                    // Looking up the page record to verify its existence:
247
                    $page = $GLOBALS['TSFE']->sys_page->getPage($link_param, $disableGroupAccessCheck);
248
249
                    if (count($page)) {
250
                        // MointPoints, look for closest MPvar:
251
                        $MPvarAcc = [];
252
                        if (!$GLOBALS['TSFE']->config['config']['MP_disableTypolinkClosestMPvalue']) {
253
                            $temp_MP = $this->getClosestMPvalueForPage($page['uid'], true);
254
                            if ($temp_MP) {
255
                                $MPvarAcc['closest'] = $temp_MP;
256
                            }
257
                        }
258
                        // Look for overlay Mount Point:
259
                        $mount_info = $GLOBALS['TSFE']->sys_page->getMountPointInfo($page['uid'], $page);
260
                        if (is_array($mount_info) && $mount_info['overlay']) {
261
                            $page = $GLOBALS['TSFE']->sys_page->getPage(
262
                                $mount_info['mount_pid'],
263
                                $disableGroupAccessCheck
264
                            );
265
                            if (!count($page)) {
266
                                $GLOBALS['TT']->setTSlogMessage(
267
                                    "typolink(): Mount point '" . $mount_info['mount_pid'] . "' was not available, so '" . $linktxt . "' was not linked.",
268
                                    1
269
                                );
270
                                return $linktxt;
271
                            }
272
                            $MPvarAcc['re-map'] = $mount_info['MPvar'];
273
                        }
274
275
276
                        // -----------------------
277
                        // Popup Hook
278
                        // -----------------------
279
                        $popup = AbstractPlugin::pi_getRecord('pages', $page['uid']);
280
                        $popup_configuration = $popup['tx_popup_configuration'];
281
282
283
                        // Setting title if blank value to link:
284
                        if ($linktxt == '') {
285
                            $linktxt = $page['title'];
286
                        }
287
288
                        // Query Params:
289
                        $addQueryParams = $conf['addQueryString'] ? $this->getQueryArguments($conf['addQueryString.']) : '';
290
                        $addQueryParams .= trim($this->stdWrap($conf['additionalParams'], $conf['additionalParams.']));
291
                        if (substr($addQueryParams, 0, 1) != '&') {
292
                            $addQueryParams = '';
293
                        } elseif ($conf['useCacheHash']) {    // cache hashing:
294
                            // Added '.$this->linkVars' dec 2003: The need for adding the linkVars is that they will be included in the link, but not the cHash. Thus the linkVars will always be the problem that prevents the cHash from working. I cannot see what negative implications in terms of incompatibilities this could bring, but for now I hope there are none. So here we go... (- kasper);
295
                            $addQueryParams .= '&cHash=' . GeneralUtility::generateCHash($addQueryParams . $GLOBALS['TSFE']->linkVars);
0 ignored issues
show
The method generateCHash() does not seem to exist on object<TYPO3\CMS\Core\Utility\GeneralUtility>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
296
                        }
297
298
                        $tCR_domain = '';
299
                        // Mount pages are always local and never link to another domain
300
                        if (count($MPvarAcc)) {
301
                            // Add "&MP" var:
302
                            $addQueryParams .= '&MP=' . rawurlencode(implode(',', $MPvarAcc));
303
                        } elseif (strpos(
304
                            $addQueryParams,
305
                            '&MP='
306
                        ) === false && $GLOBALS['TSFE']->config['config']['typolinkCheckRootline']
307
                        ) {
308
                            // We do not come here if additionalParams had '&MP='. This happens when typoLink is called from
309
                            // menu. Mount points always work in the content of the current domain and we must not change
310
                            // domain if MP variables exist.
311
312
                            // If we link across domains and page is free type shortcut, we must resolve the shortcut first!
313
                            // If we do not do it, TYPO3 will fail to (1) link proper page in RealURL/CoolURI because
314
                            // they return relative links and (2) show proper page if no RealURL/CoolURI exists when link is clicked
315
                            if ($enableLinksAcrossDomains && $page['doktype'] == 4 && $page['shortcut_mode'] == 0) {
316
                                $page2 = $page;    // Save in case of broken destination or endless loop
317
                                $maxLoopCount = 20;    // Same as in RealURL, seems enough
318
                                while ($maxLoopCount && is_array($page) && $page['doktype'] == 4 && $page['shortcut_mode'] == 0) {
319
                                    $page = $GLOBALS['TSFE']->sys_page->getPage(
320
                                        $page['shortcut'],
321
                                        $disableGroupAccessCheck
322
                                    );
323
                                    $maxLoopCount--;
324
                                }
325
                                if (count($page) == 0 || $maxLoopCount == 0) {
326
                                    // We revert if shortcut is broken or maximum number of loops is exceeded (indicates endless loop)
327
                                    $page = $page2;
328
                                }
329
                            }
330
331
                            // This checks if the linked id is in the rootline of this site and if not it will find the domain for that ID and prefix it:
332
                            $tCR_rootline = $GLOBALS['TSFE']->sys_page->getRootLine($page['uid']);    // Gets rootline of linked-to page
333
                            $tCR_flag = 0;
334
                            foreach ($tCR_rootline as $tCR_data) {
335
                                if ($tCR_data['uid'] == $GLOBALS['TSFE']->tmpl->rootLine[0]['uid']) {
336
                                    $tCR_flag = 1;    // OK, it was in rootline!
337
                                    break;
338
                                }
339
                                if ($tCR_data['is_siteroot']) {
340
                                    // Possibly subdomain inside main domain. In any case we must stop now because site root is reached.
341
                                    break;
342
                                }
343
                            }
344
                            if (!$tCR_flag) {
345
                                foreach ($tCR_rootline as $tCR_data) {
346
                                    $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
347
                                        'domainName',
348
                                        'sys_domain',
349
                                        'pid=' . intval($tCR_data['uid']) . ' AND redirectTo=\'\'' . $this->enableFields('sys_domain'),
350
                                        '',
351
                                        'sorting'
352
                                    );
353
                                    $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
354
                                    $GLOBALS['TYPO3_DB']->sql_free_result($res);
355
                                    if ($row) {
356
                                        $tCR_domain = preg_replace('/\/$/', '', $row['domainName']);
357
                                        break;
358
                                    }
359
                                }
360
                            }
361
                        }
362
                        // If other domain, overwrite
363
                        if (strlen($tCR_domain) && !$enableLinksAcrossDomains) {
364
                            $target = isset($conf['extTarget']) ? $conf['extTarget'] : $GLOBALS['TSFE']->extTarget;
365
                            if ($conf['extTarget.']) {
366
                                $target = $this->stdWrap($target, $conf['extTarget.']);
367
                            }
368
                            if ($forceTarget) {
369
                                $target = $forceTarget;
370
                            }
371
                            $LD['target'] = $target;
372
                            $this->lastTypoLinkUrl = $this->URLqMark(
373
                                'http://' . $tCR_domain . '/index.php?id=' . $page['uid'],
374
                                $addQueryParams
375
                            ) . $sectionMark;
376
                        } else {    // Internal link:
377
                            if ($forceTarget) {
378
                                $target = $forceTarget;
379
                            }
380
                            $LD = $GLOBALS['TSFE']->tmpl->linkData(
381
                                $page,
382
                                $target,
383
                                $conf['no_cache'],
384
                                '',
385
                                '',
386
                                $addQueryParams,
387
                                $theTypeP,
0 ignored issues
show
The variable $theTypeP 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

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
388
                                $tCR_domain
389
                            );
390
                            if (strlen($tCR_domain)) {
391
                                // We will add domain only if URL does not have it already.
392
393
                                if ($enableLinksAcrossDomains) {
394
                                    // Get rid of the absRefPrefix if necessary. absRefPrefix is applicable only
395
                                    // to the current web site. If we have domain here it means we link across
396
                                    // domains. absRefPrefix can contain domain name, which will screw up
397
                                    // the link to the external domain.
398
                                    $prefixLength = strlen($GLOBALS['TSFE']->config['config']['absRefPrefix']);
399
                                    if (substr(
400
                                        $LD['totalURL'],
401
                                        0,
402
                                        $prefixLength
403
                                    ) == $GLOBALS['TSFE']->config['config']['absRefPrefix']
404
                                    ) {
405
                                        $LD['totalURL'] = substr($LD['totalURL'], $prefixLength);
406
                                    }
407
                                }
408
                                $urlParts = parse_url($LD['totalURL']);
409
                                if ($urlParts['host'] == '') {
410
                                    $LD['totalURL'] = 'http://' . $tCR_domain . ($LD['totalURL']{0} == '/' ? '' : '/') . $LD['totalURL'];
411
                                }
412
                            }
413
                            $this->lastTypoLinkUrl = $this->URLqMark($LD['totalURL'], '') . $sectionMark;
414
                        }
415
416
                        $this->lastTypoLinkTarget = $LD['target'];
417
                        $targetPart = $LD['target'] ? ' target="' . $LD['target'] . '"' : '';
418
419
                        // If sectionMark is set, there is no baseURL AND the current page is the page the link is to, check if there are any additional parameters and is not, drop the url.
420
                        if ($sectionMark && !trim($addQueryParams) && $page['uid'] == $GLOBALS['TSFE']->id && !$GLOBALS['TSFE']->config['config']['baseURL']) {
421
                            list(, $URLparams) = explode('?', $this->lastTypoLinkUrl);
422
                            list($URLparams) = explode('#', $URLparams);
423
                            parse_str($URLparams . $LD['orig_type'], $URLparamsArray);
424
                            if (intval($URLparamsArray['type']) == $GLOBALS['TSFE']->type) {    // type nums must match as well as page ids
425
                                unset($URLparamsArray['id']);
426
                                unset($URLparamsArray['type']);
427
                                if (!count($URLparamsArray)) {    // If there are no parameters left.... set the new url.
428
                                    $this->lastTypoLinkUrl = $sectionMark;
429
                                }
430
                            }
431
                        }
432
433
                        // If link is to a access restricted page which should be redirected, then find new URL:
434
                        if ($GLOBALS['TSFE']->config['config']['typolinkLinkAccessRestrictedPages'] &&
435
                            $GLOBALS['TSFE']->config['config']['typolinkLinkAccessRestrictedPages'] !== 'NONE' &&
436
                            !$GLOBALS['TSFE']->checkPageGroupAccess($page)
437
                        ) {
438
                            $thePage = $GLOBALS['TSFE']->sys_page->getPage($GLOBALS['TSFE']->config['config']['typolinkLinkAccessRestrictedPages']);
439
440
                            $addParams = $GLOBALS['TSFE']->config['config']['typolinkLinkAccessRestrictedPages_addParams'];
441
                            $addParams = str_replace(
442
                                '###RETURN_URL###',
443
                                rawurlencode($this->lastTypoLinkUrl),
444
                                $addParams
445
                            );
446
                            $addParams = str_replace('###PAGE_ID###', $page['uid'], $addParams);
447
                            $this->lastTypoLinkUrl = $this->getTypoLink_URL(
448
                                $thePage['uid'] . ($theTypeP ? ',' . $theTypeP : ''),
449
                                $addParams,
450
                                $target
451
                            );
452
                            $LD = $this->lastTypoLinkLD;
453
                        }
454
455
                        // Rendering the tag.
456
                        $finalTagParts['url'] = $this->lastTypoLinkUrl;
457
                        $finalTagParts['targetParams'] = $targetPart;
458
                        $finalTagParts['TYPE'] = 'page';
459
                    } else {
460
                        $GLOBALS['TT']->setTSlogMessage(
461
                            "typolink(): Page id '" . $link_param . "' was not found, so '" . $linktxt . "' was not linked.",
462
                            1
463
                        );
464
                        return $linktxt;
465
                    }
466
                }
467
            }
468
469
            $this->lastTypoLinkLD = $LD;
470
471
            if ($forceTitle) {
472
                $title = $forceTitle;
473
            }
474
475
            if ($JSwindowParams) {
476
                // Create TARGET-attribute only if the right doctype is used
477
                if (!GeneralUtility::inList('xhtml_strict,xhtml_11,xhtml_2', $GLOBALS['TSFE']->xhtmlDoctype)) {
478
                    $target = ' target="FEopenLink"';
479
                } else {
480
                    $target = '';
481
                }
482
483
                $onClick = "vHWin=window.open('" . $GLOBALS['TSFE']->baseUrlWrap($finalTagParts['url']) . "','FEopenLink','" . $JSwindowParams . "');vHWin.focus();return false;";
484
                $res = '<a href="' . htmlspecialchars($finalTagParts['url']) . '"' . $target . ' onclick="' . htmlspecialchars($onClick) . '"' . ($title ? ' title="' . $title . '"' : '') . ($linkClass ? ' class="' . $linkClass . '"' : '') . $finalTagParts['aTagParams'] . '>';
485
            } else {
486
                if ($GLOBALS['TSFE']->spamProtectEmailAddresses === 'ascii' && $finalTagParts['TYPE'] === 'mailto') {
487
                    $res = '<a href="' . $finalTagParts['url'] . '"' . ($title ? ' title="' . $title . '"' : '') . $finalTagParts['targetParams'] . ($linkClass ? ' class="' . $linkClass . '"' : '') . $finalTagParts['aTagParams'] . '>';
488
                } else {
489
                    // -----------------------
490
                    // Popup Hook
491
                    // -----------------------
492
                    if (isset($popup_configuration) && strlen($popup_configuration)) {
493
                        $popup = GeneralUtility::makeInstance('FRUIT\\Popup\\Popup');
494
                        $popup_configuration = $popup->convertCfg2Js($popup_configuration);
495
                        $res = '<a href="' . htmlspecialchars($finalTagParts['url']) . '"' . ($title ? ' title="' . $title . '"' : '') . $finalTagParts['targetParams'] . ($linkClass ? ' class="' . $linkClass . '"' : '') . $finalTagParts['aTagParams'] . ' onclick="window.open(this.href,\'\',\'' . $popup_configuration . '\'); return false;">';
496
                    } else {
497
                        $res = '<a href="' . htmlspecialchars($finalTagParts['url']) . '"' . ($title ? ' title="' . $title . '"' : '') . $finalTagParts['targetParams'] . ($linkClass ? ' class="' . $linkClass . '"' : '') . $finalTagParts['aTagParams'] . '>';
498
                    }
499
                }
500
            }
501
502
            // Call user function:
503
            if ($conf['userFunc']) {
504
                $finalTagParts['TAG'] = $res;
505
                $res = $this->callUserFunction($conf['userFunc'], $conf['userFunc.'], $finalTagParts);
506
            }
507
508
            // Hook: Call post processing function for link rendering:
509
            if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['typoLink_PostProc']) && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['typoLink_PostProc'])) {
510
                $_params = [
511
                    'conf' => &$conf,
512
                    'linktxt' => &$linktxt,
513
                    'finalTag' => &$res,
514
                    'finalTagParts' => &$finalTagParts,
515
                ];
516
                foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['typoLink_PostProc'] as $_funcRef) {
517
                    GeneralUtility::callUserFunction($_funcRef, $_params, $this);
518
                }
519
            }
520
521
            // If flag "returnLastTypoLinkUrl" set, then just return the latest URL made:
522
            if ($conf['returnLast']) {
523
                switch ($conf['returnLast']) {
524
                    case 'url':
525
                        return $this->lastTypoLinkUrl;
526
                        break;
527
                    case 'target':
528
                        return $this->lastTypoLinkTarget;
529
                        break;
530
                }
531
            }
532
533
            if ($conf['ATagBeforeWrap']) {
534
                return $res . $this->wrap($linktxt, $conf['wrap']) . '</a>';
535
            } else {
536
                return $this->wrap($res . $linktxt . '</a>', $conf['wrap']);
537
            }
538
        } else {
539
            return $linktxt;
540
        }
541
    }
542
}
543