Test Failed
Branch master (7b1793)
by Tymoteusz
15:35
created

GraphicalMenuContentObject::makeGifs()   F

Complexity

Conditions 52
Paths > 20000

Size

Total Lines 187
Code Lines 135

Duplication

Lines 69
Ratio 36.9 %

Importance

Changes 0
Metric Value
cc 52
eloc 135
nc 25301250
nop 2
dl 69
loc 187
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace TYPO3\CMS\Frontend\ContentObject\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
17
use TYPO3\CMS\Core\TypoScript\TypoScriptService;
18
use TYPO3\CMS\Core\Utility\GeneralUtility;
19
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
20
use TYPO3\CMS\Frontend\Imaging\GifBuilder;
21
22
/**
23
 * Extension class creating graphic based menus (PNG or GIF files)
24
 */
25
class GraphicalMenuContentObject extends AbstractMenuContentObject
26
{
27
    /**
28
     * Calls procesItemStates() so that the common configuration for the menu items are resolved into individual configuration per item.
29
     * Calls makeGifs() for all "normal" items and if configured for, also the "rollover" items.
30
     *
31
     * @see AbstractMenuContentObject::procesItemStates(), makeGifs()
32
     */
33
    public function generate()
34
    {
35
        $splitCount = count($this->menuArr);
36
        if ($splitCount) {
37
            list($NOconf, $ROconf) = $this->procesItemStates($splitCount);
38
            //store initial count value
39
            $tsfe = $this->getTypoScriptFrontendController();
40
            $temp_HMENU_MENUOBJ = $tsfe->register['count_HMENU_MENUOBJ'];
41
            $temp_MENUOBJ = $tsfe->register['count_MENUOBJ'];
42
            // Now we generate the giffiles:
43
            $this->makeGifs($NOconf, 'NO');
44
            // store count from NO obj
45
            $tempcnt_HMENU_MENUOBJ = $tsfe->register['count_HMENU_MENUOBJ'];
46
            $tempcnt_MENUOBJ = $tsfe->register['count_MENUOBJ'];
47
            if ($this->mconf['debugItemConf']) {
48
                echo '<h3>$NOconf:</h3>';
49
                debug($NOconf);
50
            }
51
            // RollOver
52
            if ($ROconf) {
53
                // Start recount for rollover with initial values
54
                $tsfe->register['count_HMENU_MENUOBJ'] = $temp_HMENU_MENUOBJ;
55
                $tsfe->register['count_MENUOBJ'] = $temp_MENUOBJ;
56
                $this->makeGifs($ROconf, 'RO');
57
                if ($this->mconf['debugItemConf']) {
58
                    echo '<h3>$ROconf:</h3>';
59
                    debug($ROconf);
60
                }
61
            }
62
            // Use count from NO obj
63
            $tsfe->register['count_HMENU_MENUOBJ'] = $tempcnt_HMENU_MENUOBJ;
64
            $tsfe->register['count_MENUOBJ'] = $tempcnt_MENUOBJ;
65
        }
66
    }
67
68
    /**
69
     * Will traverse input array with configuration per-item and create corresponding GIF files for the menu.
70
     * The data of the files are stored in $this->result
71
     *
72
     * @param array $conf Array with configuration for each item.
73
     * @param string $resKey Type of images: normal ("NO") or rollover ("RO"). Valid values are "NO" and "RO
74
     * @internal
75
     * @see generate()
76
     */
77
    public function makeGifs($conf, $resKey)
78
    {
79
        $isGD = $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'];
80
        if (!is_array($conf)) {
81
            $conf = [];
82
        }
83
        $totalWH = [];
84
        $items = count($conf);
85
        $minDim = 0;
86
        $maxDim = 0;
87
        $Hcounter = 0;
88
        $Wcounter = 0;
89
        $Hobjs = [];
90
        $Wobjs = [];
91
        if ($isGD) {
92
            // Generate the gif-files. the $menuArr is filled with some values like output_w, output_h, output_file
93
            $Hobjs = $this->mconf['applyTotalH'];
94
            if ($Hobjs) {
95
                $Hobjs = GeneralUtility::intExplode(',', $Hobjs);
96
            }
97
            $Wobjs = $this->mconf['applyTotalW'];
98
            if ($Wobjs) {
99
                $Wobjs = GeneralUtility::intExplode(',', $Wobjs);
100
            }
101
            $minDim = $this->mconf['min'];
102
            if ($minDim) {
103
                $minDim = $this->parent_cObj->calcIntExplode(',', $minDim . ',');
104
            }
105
            $maxDim = $this->mconf['max'];
106
            if ($maxDim) {
107
                $maxDim = $this->parent_cObj->calcIntExplode(',', $maxDim . ',');
108
            }
109
            if ($minDim) {
110
                $conf[$items] = $conf[$items - 1];
111
                $this->menuArr[$items] = [];
112
                $items = count($conf);
113
            }
114
            // TOTAL width
115
            if ($this->mconf['useLargestItemX'] || $this->mconf['useLargestItemY'] || $this->mconf['distributeX'] || $this->mconf['distributeY']) {
116
                $totalWH = $this->findLargestDims($conf, $items, $Hobjs, $Wobjs, $minDim, $maxDim);
117
            }
118
        }
119
        $c = 0;
120
        $maxFlag = 0;
121
        $distributeAccu = ['H' => 0, 'W' => 0];
122
        foreach ($conf as $key => $val) {
123
            $this->getTypoScriptFrontendController()->register['count_HMENU_MENUOBJ']++;
124
            $this->getTypoScriptFrontendController()->register['count_MENUOBJ']++;
125 View Code Duplication
            if ($items === $c + 1 && $minDim) {
126
                $Lobjs = $this->mconf['removeObjectsOfDummy'];
127
                if ($Lobjs) {
128
                    $Lobjs = GeneralUtility::intExplode(',', $Lobjs);
129
                    foreach ($Lobjs as $remItem) {
130
                        unset($val[$remItem]);
131
                        unset($val[$remItem . '.']);
132
                    }
133
                }
134
                $flag = 0;
135
                $tempXY = explode(',', $val['XY']);
136
                if ($Wcounter < $minDim[0]) {
137
                    $tempXY[0] = $minDim[0] - $Wcounter;
138
                    $flag = 1;
139
                }
140
                if ($Hcounter < $minDim[1]) {
141
                    $tempXY[1] = $minDim[1] - $Hcounter;
142
                    $flag = 1;
143
                }
144
                $val['XY'] = implode(',', $tempXY);
145
                if (!$flag) {
146
                    break;
147
                }
148
            }
149
            $c++;
150
            $gifCreator = null;
151
            if ($isGD) {
152
                // Pre-working the item
153
                $gifCreator = GeneralUtility::makeInstance(GifBuilder::class);
154
                $gifCreator->init();
155
                $gifCreator->start($val, $this->menuArr[$key]);
156
                // If useLargestItemH/W is specified
157
                if (!empty($totalWH) && ($this->mconf['useLargestItemX'] || $this->mconf['useLargestItemY'])) {
158
                    $tempXY = explode(',', $gifCreator->setup['XY']);
159
                    if ($this->mconf['useLargestItemX']) {
160
                        $tempXY[0] = max($totalWH['W']);
161
                    }
162
                    if ($this->mconf['useLargestItemY']) {
163
                        $tempXY[1] = max($totalWH['H']);
164
                    }
165
                    // Regenerate the new values...
166
                    $val['XY'] = implode(',', $tempXY);
167
                    $gifCreator = GeneralUtility::makeInstance(GifBuilder::class);
168
                    $gifCreator->init();
169
                    $gifCreator->start($val, $this->menuArr[$key]);
170
                }
171
                // If distributeH/W is specified
172
                if (!empty($totalWH) && ($this->mconf['distributeX'] || $this->mconf['distributeY'])) {
173
                    $tempXY = explode(',', $gifCreator->setup['XY']);
174 View Code Duplication
                    if ($this->mconf['distributeX']) {
175
                        $diff = $this->mconf['distributeX'] - $totalWH['W_total'] - $distributeAccu['W'];
176
                        $compensate = round($diff / ($items - $c + 1));
177
                        $distributeAccu['W'] += $compensate;
178
                        $tempXY[0] = $totalWH['W'][$key] + $compensate;
179
                    }
180 View Code Duplication
                    if ($this->mconf['distributeY']) {
181
                        $diff = $this->mconf['distributeY'] - $totalWH['H_total'] - $distributeAccu['H'];
182
                        $compensate = round($diff / ($items - $c + 1));
183
                        $distributeAccu['H'] += $compensate;
184
                        $tempXY[1] = $totalWH['H'][$key] + $compensate;
185
                    }
186
                    // Regenerate the new values...
187
                    $val['XY'] = implode(',', $tempXY);
188
                    $gifCreator = GeneralUtility::makeInstance(GifBuilder::class);
189
                    $gifCreator->init();
190
                    $gifCreator->start($val, $this->menuArr[$key]);
191
                }
192
                // If max dimensions are specified
193 View Code Duplication
                if ($maxDim) {
194
                    $tempXY = explode(',', $val['XY']);
195
                    if ($maxDim[0] && $Wcounter + $gifCreator->XY[0] >= $maxDim[0]) {
196
                        $tempXY[0] = $maxDim[0] - $Wcounter;
197
                        $maxFlag = 1;
198
                    }
199
                    if ($maxDim[1] && $Hcounter + $gifCreator->XY[1] >= $maxDim[1]) {
200
                        $tempXY[1] = $maxDim[1] - $Hcounter;
201
                        $maxFlag = 1;
202
                    }
203
                    if ($maxFlag) {
204
                        $val['XY'] = implode(',', $tempXY);
205
                        $gifCreator = GeneralUtility::makeInstance(GifBuilder::class);
206
                        $gifCreator->init();
207
                        $gifCreator->start($val, $this->menuArr[$key]);
208
                    }
209
                }
210
                // displace
211 View Code Duplication
                if ($Hobjs) {
212
                    foreach ($Hobjs as $index) {
213
                        if ($gifCreator->setup[$index] && $gifCreator->setup[$index . '.']) {
214
                            $oldOffset = explode(',', $gifCreator->setup[$index . '.']['offset']);
215
                            $gifCreator->setup[$index . '.']['offset'] = implode(',', $gifCreator->applyOffset($oldOffset, [0, -$Hcounter]));
216
                        }
217
                    }
218
                }
219 View Code Duplication
                if ($Wobjs) {
220
                    foreach ($Wobjs as $index) {
221
                        if ($gifCreator->setup[$index] && $gifCreator->setup[$index . '.']) {
222
                            $oldOffset = explode(',', $gifCreator->setup[$index . '.']['offset']);
223
                            $gifCreator->setup[$index . '.']['offset'] = implode(',', $gifCreator->applyOffset($oldOffset, [-$Wcounter, 0]));
224
                        }
225
                    }
226
                }
227
            }
228
            // Finding alternative GIF names if any (by altImgResource)
229
            $gifFileName = '';
230
            if ($conf[$key]['altImgResource'] || is_array($conf[$key]['altImgResource.'])) {
231
                $cObj = GeneralUtility::makeInstance(ContentObjectRenderer::class);
232
                $cObj->start($this->menuArr[$key], 'pages');
233
                $altImgInfo = $cObj->getImgResource($conf[$key]['altImgResource'], $conf[$key]['altImgResource.']);
234
                $gifFileName = $altImgInfo[3];
235
            }
236
            // If an alternative name was NOT given, find the GIFBUILDER name.
237
            if (!$gifFileName && $isGD) {
238
                GeneralUtility::mkdir_deep(PATH_site . 'typo3temp/assets/menu/');
239
                $gifFileName = $gifCreator->fileName('assets/menu/');
240
            }
241
            $this->result[$resKey][$key] = $conf[$key];
242
            // Generation of image file:
243
            // File exists
244
            if (file_exists($gifFileName)) {
245
                $info = @getimagesize($gifFileName);
246
                $this->result[$resKey][$key]['output_w'] = (int)$info[0];
247
                $this->result[$resKey][$key]['output_h'] = (int)$info[1];
248
                $this->result[$resKey][$key]['output_file'] = $gifFileName;
249
            } elseif ($isGD) {
250
                // file is generated
251
                $gifCreator->make();
252
                $this->result[$resKey][$key]['output_w'] = $gifCreator->w;
253
                $this->result[$resKey][$key]['output_h'] = $gifCreator->h;
254
                $this->result[$resKey][$key]['output_file'] = $gifFileName;
255
                $gifCreator->output($this->result[$resKey][$key]['output_file']);
256
                $gifCreator->destroy();
257
            }
258
            // counter is increased
259
            $Hcounter += $this->result[$resKey][$key]['output_h'];
260
            // counter is increased
261
            $Wcounter += $this->result[$resKey][$key]['output_w'];
262
            if ($maxFlag) {
263
                break;
264
            }
265
        }
266
    }
267
268
    /**
269
     * Function searching for the largest width and height of the menu items to be generated.
270
     * Uses some of the same code as makeGifs and even instantiates some gifbuilder objects BUT does not render the images - only reading out which width they would have.
271
     * Remember to upgrade the code in here if the makeGifs function is updated.
272
     *
273
     * @param array $conf Same configuration array as passed to makeGifs()
274
     * @param int $items The number of menu items
275
     * @param array $Hobjs Array with "applyTotalH" numbers (unused)
276
     * @param array $Wobjs Array with "applyTotalW" numbers (unused)
277
     * @param array $minDim Array with "min" x/y
278
     * @param array $maxDim Array with "max" x/y
279
     * @return array Array with keys "H" and "W" which are in themselves arrays with the heights and widths of menu items inside. This can be used to find the max/min size of the menu items.
280
     * @internal
281
     * @see makeGifs()
282
     */
283
    public function findLargestDims($conf, $items, $Hobjs, $Wobjs, $minDim, $maxDim)
0 ignored issues
show
Unused Code introduced by
The parameter $Wobjs is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

283
    public function findLargestDims($conf, $items, $Hobjs, /** @scrutinizer ignore-unused */ $Wobjs, $minDim, $maxDim)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $Hobjs is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

283
    public function findLargestDims($conf, $items, /** @scrutinizer ignore-unused */ $Hobjs, $Wobjs, $minDim, $maxDim)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
284
    {
285
        $items = (int)$items;
286
        $totalWH = [
287
            'W' => [],
288
            'H' => [],
289
            'W_total' => 0,
290
            'H_total' => 0
291
        ];
292
        $Hcounter = 0;
293
        $Wcounter = 0;
294
        $c = 0;
295
        $maxFlag = 0;
296
        foreach ($conf as $key => $val) {
297
            // SAME CODE AS makeGifs()! BEGIN
298 View Code Duplication
            if ($items === $c + 1 && $minDim) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $minDim of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
299
                $Lobjs = $this->mconf['removeObjectsOfDummy'];
300
                if ($Lobjs) {
301
                    $Lobjs = GeneralUtility::intExplode(',', $Lobjs);
302
                    foreach ($Lobjs as $remItem) {
303
                        unset($val[$remItem]);
304
                        unset($val[$remItem . '.']);
305
                    }
306
                }
307
                $flag = 0;
308
                $tempXY = explode(',', $val['XY']);
309
                if ($Wcounter < $minDim[0]) {
310
                    $tempXY[0] = $minDim[0] - $Wcounter;
311
                    $flag = 1;
312
                }
313
                if ($Hcounter < $minDim[1]) {
314
                    $tempXY[1] = $minDim[1] - $Hcounter;
315
                    $flag = 1;
316
                }
317
                $val['XY'] = implode(',', $tempXY);
318
                if (!$flag) {
319
                    break;
320
                }
321
            }
322
            $c++;
323
            $gifCreator = GeneralUtility::makeInstance(GifBuilder::class);
324
            $gifCreator->init();
325
            $gifCreator->start($val, $this->menuArr[$key]);
326 View Code Duplication
            if ($maxDim) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $maxDim of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
327
                $tempXY = explode(',', $val['XY']);
328
                if ($maxDim[0] && $Wcounter + $gifCreator->XY[0] >= $maxDim[0]) {
329
                    $tempXY[0] = $maxDim[0] - $Wcounter;
330
                    $maxFlag = 1;
331
                }
332
                if ($maxDim[1] && $Hcounter + $gifCreator->XY[1] >= $maxDim[1]) {
333
                    $tempXY[1] = $maxDim[1] - $Hcounter;
334
                    $maxFlag = 1;
335
                }
336
                if ($maxFlag) {
337
                    $val['XY'] = implode(',', $tempXY);
338
                    $gifCreator = GeneralUtility::makeInstance(GifBuilder::class);
339
                    $gifCreator->init();
340
                    $gifCreator->start($val, $this->menuArr[$key]);
341
                }
342
            }
343
            // SAME CODE AS makeGifs()! END
344
            // Setting the width/height
345
            $totalWH['W'][$key] = $gifCreator->XY[0];
346
            $totalWH['H'][$key] = $gifCreator->XY[1];
347
            $totalWH['W_total'] += $gifCreator->XY[0];
348
            $totalWH['H_total'] += $gifCreator->XY[1];
349
            // counter is increased
350
            $Hcounter += $gifCreator->XY[1];
351
            // counter is increased
352
            $Wcounter += $gifCreator->XY[0];
353
            if ($maxFlag) {
354
                break;
355
            }
356
        }
357
        return $totalWH;
358
    }
359
360
    /**
361
     * Traverses the ->result['NO'] array of menu items configuration (made by ->generate()) and renders the HTML of each item (the images themselves was made with makeGifs() before this. See ->generate())
362
     * During the execution of this function many internal methods prefixed "extProc_" from this class is called and many of these are for now dummy functions. But they can be used for processing as they are used by the GMENU_LAYERS
363
     *
364
     * @return string The HTML for the menu (returns result through $this->extProc_finish(); )
365
     */
366
    public function writeMenu()
367
    {
368
        if (!is_array($this->menuArr) || empty($this->result) || !is_array($this->result['NO'])) {
369
            return '';
370
        }
371
        $this->WMresult = '';
372
        $this->INPfixMD5 = substr(md5(microtime() . $this->GMENU_fixKey), 0, 4);
0 ignored issues
show
Documentation Bug introduced by
It seems like substr(md5(microtime() ....s->GMENU_fixKey), 0, 4) can also be of type false. However, the property $INPfixMD5 is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
373
        $this->WMmenuItems = count($this->result['NO']);
374
        $typoScriptService = GeneralUtility::makeInstance(TypoScriptService::class);
375
        $this->WMsubmenuObjSuffixes = $typoScriptService->explodeConfigurationForOptionSplit(['sOSuffix' => $this->mconf['submenuObjSuffixes']], $this->WMmenuItems);
376
        $this->extProc_init();
377
        $tsfe = $this->getTypoScriptFrontendController();
378
        if (!isset($tsfe->additionalJavaScript['JSImgCode'])) {
379
            $tsfe->additionalJavaScript['JSImgCode'] = '';
380
        }
381
        for ($key = 0; $key < $this->WMmenuItems; $key++) {
382
            if ($this->result['NO'][$key]['output_file']) {
383
                // Initialize the cObj with the page record of the menu item
384
                $this->WMcObj->start($this->menuArr[$key], 'pages');
385
                $this->I = [];
386
                $this->I['key'] = $key;
387
                $this->I['INPfix'] = ($this->imgNameNotRandom ? '' : '_' . $this->INPfixMD5) . '_' . $key;
0 ignored issues
show
Bug introduced by
Are you sure $this->INPfixMD5 of type false|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

387
                $this->I['INPfix'] = ($this->imgNameNotRandom ? '' : '_' . /** @scrutinizer ignore-type */ $this->INPfixMD5) . '_' . $key;
Loading history...
388
                $this->I['val'] = $this->result['NO'][$key];
389
                $this->I['title'] = $this->getPageTitle($this->menuArr[$key]['title'], $this->menuArr[$key]['nav_title']);
390
                $this->I['uid'] = $this->menuArr[$key]['uid'];
391
                $this->I['mount_pid'] = $this->menuArr[$key]['mount_pid'];
392
                $this->I['pid'] = $this->menuArr[$key]['pid'];
393
                $this->I['spacer'] = $this->menuArr[$key]['isSpacer'];
394
                if (!$this->I['uid'] && !$this->menuArr[$key]['_OVERRIDE_HREF']) {
395
                    $this->I['spacer'] = 1;
396
                }
397
                $this->I['noLink'] = $this->I['spacer'] || $this->I['val']['noLink'] || empty($this->menuArr[$key]);
398
                // !count($this->menuArr[$key]) means that this item is a dummyItem
399
                $this->I['name'] = '';
400
                // Set access key
401 View Code Duplication
                if ($this->mconf['accessKey']) {
402
                    $this->I['accessKey'] = $this->accessKey($this->I['title']);
403
                } else {
404
                    $this->I['accessKey'] = [];
405
                }
406
                // Make link tag
407
                $this->I['val']['ATagParams'] = $this->WMcObj->getATagParams($this->I['val']);
408 View Code Duplication
                if (isset($this->I['val']['additionalParams.'])) {
409
                    $this->I['val']['additionalParams'] = $this->WMcObj->stdWrap($this->I['val']['additionalParams'], $this->I['val']['additionalParams.']);
410
                }
411
                $this->I['linkHREF'] = $this->link($key, $this->I['val']['altTarget'], $this->mconf['forceTypeValue']);
412
                // Title attribute of links:
413
                $titleAttrValue = isset($this->I['val']['ATagTitle.']) ? $this->WMcObj->stdWrap($this->I['val']['ATagTitle'], $this->I['val']['ATagTitle.']) . $this->I['accessKey']['alt'] : $this->I['val']['ATagTitle'] . $this->I['accessKey']['alt'];
414
                if ($titleAttrValue !== '') {
415
                    $this->I['linkHREF']['title'] = $titleAttrValue;
416
                }
417
                // Set rollover
418
                if ($this->result['RO'][$key] && !$this->I['noLink']) {
419
                    $this->I['theName'] = $this->imgNamePrefix . $this->I['uid'] . $this->I['INPfix'];
420
                    $this->I['name'] = ' ' . $this->nameAttribute . '="' . $this->I['theName'] . '"';
421
                    $this->I['linkHREF']['onMouseover'] = $this->WMfreezePrefix . 'over(' . GeneralUtility::quoteJSvalue($this->I['theName']) . ');';
422
                    $this->I['linkHREF']['onMouseout'] = $this->WMfreezePrefix . 'out(' . GeneralUtility::quoteJSvalue($this->I['theName']) . ');';
423
                    $tsfe->additionalJavaScript['JSImgCode'] .= LF . $this->I['theName'] . '_n=new Image(); ' . $this->I['theName'] . '_n.src = ' . GeneralUtility::quoteJSvalue($tsfe->absRefPrefix . $this->I['val']['output_file']) . '; ';
424
                    $tsfe->additionalJavaScript['JSImgCode'] .= LF . $this->I['theName'] . '_h=new Image(); ' . $this->I['theName'] . '_h.src = ' . GeneralUtility::quoteJSvalue($tsfe->absRefPrefix . $this->result['RO'][$key]['output_file']) . '; ';
425
                    $tsfe->imagesOnPage[] = $this->result['RO'][$key]['output_file'];
426
                    $tsfe->setJS('mouseOver');
427
                    $this->extProc_RO($key);
428
                }
429
                // Set altText
430
                $this->I['altText'] = $this->I['title'] . $this->I['accessKey']['alt'];
431
                // Calling extra processing function
432
                $this->extProc_beforeLinking($key);
433
                // Set linking
434
                if (!$this->I['noLink']) {
435
                    $this->setATagParts();
436
                } else {
437
                    $this->I['A1'] = '';
438
                    $this->I['A2'] = '';
439
                }
440
                $this->I['IMG'] = '<img src="' . $tsfe->absRefPrefix . $this->I['val']['output_file'] . '" width="' . $this->I['val']['output_w'] . '" height="' . $this->I['val']['output_h'] . '" ' . $this->parent_cObj->getBorderAttr('border="0"') . ($this->mconf['disableAltText'] ? '' : ' alt="' . htmlspecialchars($this->I['altText']) . '"') . $this->I['name'] . ($this->I['val']['imgParams'] ? ' ' . $this->I['val']['imgParams'] : '') . ' />';
441
                // Make before, middle and after parts
442
                $this->I['parts'] = [];
443
                $this->I['parts']['ATag_begin'] = $this->I['A1'];
444
                $this->I['parts']['image'] = $this->I['IMG'];
445
                $this->I['parts']['ATag_end'] = $this->I['A2'];
446
                // Passing I to a user function
447
                if ($this->mconf['IProcFunc']) {
448
                    $this->I = $this->userProcess('IProcFunc', $this->I);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->userProcess('IProcFunc', $this->I) can also be of type string. However, the property $I is declared as type array<mixed,mixed>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
449
                }
450
                // Putting the item together.
451
                // Merge parts + beforeAllWrap
452
                $this->I['theItem'] = implode('', $this->I['parts']);
453
                $this->I['theItem'] = $this->extProc_beforeAllWrap($this->I['theItem'], $key);
454
                // wrap:
455
                $this->I['theItem'] = $this->WMcObj->wrap($this->I['theItem'], $this->I['val']['wrap']);
456
                // allWrap:
457
                $allWrap = isset($this->I['val']['allWrap.']) ? $this->WMcObj->stdWrap($this->I['val']['allWrap'], $this->I['val']['allWrap.']) : $this->I['val']['allWrap'];
458
                $this->I['theItem'] = $this->WMcObj->wrap($this->I['theItem'], $allWrap);
459 View Code Duplication
                if ($this->I['val']['subst_elementUid']) {
460
                    $this->I['theItem'] = str_replace('{elementUid}', $this->I['uid'], $this->I['theItem']);
461
                }
462
                // allStdWrap:
463 View Code Duplication
                if (is_array($this->I['val']['allStdWrap.'])) {
464
                    $this->I['theItem'] = $this->WMcObj->stdWrap($this->I['theItem'], $this->I['val']['allStdWrap.']);
465
                }
466
                $tsfe->imagesOnPage[] = $this->I['val']['output_file'];
467
                $this->extProc_afterLinking($key);
468
            }
469
        }
470
        return $this->extProc_finish();
471
    }
472
473
    /**
474
     * Called right before the traversing of $this->result begins.
475
     * Can be used for various initialization
476
     *
477
     * @internal
478
     * @see writeMenu()
479
     */
480
    public function extProc_init()
481
    {
482
    }
483
484
    /**
485
     * Called after all processing for RollOver of an element has been done.
486
     *
487
     * @param int $key Pointer to $this->menuArr[$key] where the current menu element record is found OR $this->result['RO'][$key] where the configuration for that elements RO version is found!
488
     * @internal
489
     * @see writeMenu()
490
     */
491
    public function extProc_RO($key)
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

491
    public function extProc_RO(/** @scrutinizer ignore-unused */ $key)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
492
    {
493
    }
494
495
    /**
496
     * Called right before the creation of the link for the menu item
497
     *
498
     * @param int $key Pointer to $this->menuArr[$key] where the current menu element record is found
499
     * @internal
500
     * @see writeMenu()
501
     */
502
    public function extProc_beforeLinking($key)
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

502
    public function extProc_beforeLinking(/** @scrutinizer ignore-unused */ $key)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
503
    {
504
    }
505
506
    /**
507
     * Called right after the creation of links for the menu item. This is also the last function call before the
508
     * for-loop traversing menu items goes to the next item.
509
     * This function MUST set $this->WMresult.=[HTML for menu item] to add the generated menu item to the internal accumulation of items.
510
     * Further this calls the subMenu function in the parent class to create any submenu there might be.
511
     *
512
     * @param int $key Pointer to $this->menuArr[$key] where the current menu element record is found
513
     * @internal
514
     * @see writeMenu(), AbstractMenuContentObject::subMenu()
515
     */
516 View Code Duplication
    public function extProc_afterLinking($key)
517
    {
518
        // Add part to the accumulated result + fetch submenus
519
        if (!$this->I['spacer']) {
520
            $this->I['theItem'] .= $this->subMenu($this->I['uid'], $this->WMsubmenuObjSuffixes[$key]['sOSuffix']);
521
        }
522
        $part = isset($this->I['val']['wrapItemAndSub.']) ? $this->WMcObj->stdWrap($this->I['val']['wrapItemAndSub'], $this->I['val']['wrapItemAndSub.']) : $this->I['val']['wrapItemAndSub'];
523
        $this->WMresult .= $part ? $this->WMcObj->wrap($this->I['theItem'], $part) : $this->I['theItem'];
524
    }
525
526
    /**
527
     * Called before the "wrap" happens on the menu item.
528
     *
529
     * @param string $item The current content of the menu item, $this->I['theItem'], passed along.
530
     * @param int $key Pointer to $this->menuArr[$key] where the current menu element record is found (unused)
531
     * @return string The modified version of $item, going back into $this->I['theItem']
532
     * @internal
533
     * @see writeMenu()
534
     */
535
    public function extProc_beforeAllWrap($item, $key)
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

535
    public function extProc_beforeAllWrap($item, /** @scrutinizer ignore-unused */ $key)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
536
    {
537
        return $item;
538
    }
539
540
    /**
541
     * Called before the writeMenu() function returns (only if a menu was generated)
542
     *
543
     * @return string The total menu content should be returned by this function
544
     * @internal
545
     * @see writeMenu()
546
     */
547 View Code Duplication
    public function extProc_finish()
548
    {
549
        // stdWrap:
550
        if (is_array($this->mconf['stdWrap.'])) {
551
            $this->WMresult = $this->WMcObj->stdWrap($this->WMresult, $this->mconf['stdWrap.']);
552
        }
553
        return $this->WMcObj->wrap($this->WMresult, $this->mconf['wrap']) . $this->WMextraScript;
554
    }
555
}
556