‪TYPO3CMS  11.5
TypoLinkGeneratorTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
28 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerFactory;
29 use TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Scenario\DataHandlerWriter;
30 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\Internal\AbstractInstruction;
31 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\Internal\ArrayValueInstruction;
32 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\Internal\TypoScriptInstruction;
33 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalRequest;
34 use TYPO3\TestingFramework\Core\Functional\Framework\Frontend\InternalResponse;
35 
40 {
42  'typo3/sysext/backend/Resources/Public/Images/Logo.png' => 'fileadmin/logo.png',
43  ];
44 
45  protected function ‪setUp(): void
46  {
47  parent::setUp();
48 
50  'acme-com',
51  $this->‪buildSiteConfiguration(1000, 'https://acme.com/'),
52  [
53  $this->‪buildDefaultLanguageConfiguration('EN', 'https://acme.us/'),
54  $this->‪buildLanguageConfiguration('FR', 'https://acme.fr/', ['EN']),
55  $this->‪buildLanguageConfiguration('FR-CA', 'https://acme.ca/', ['FR', 'EN']),
56  ]
57  );
58 
59  $this->withDatabaseSnapshot(function () {
60  $this->‪setUpDatabase();
61  });
62  }
63 
64  protected function ‪setUpDatabase(): void
65  {
66  $backendUser = $this->setUpBackendUserFromFixture(1);
68 
69  $scenarioFile = __DIR__ . '/Fixtures/TypoLinkScenario.yaml';
70  $factory = DataHandlerFactory::fromYamlFile($scenarioFile);
71  $writer = DataHandlerWriter::withBackendUser($backendUser);
72  $writer->invokeFactory($factory);
73  static::failIfArrayIsNotEmpty(
74  $writer->getErrors()
75  );
76 
77  // @todo Provide functionality of assigning TSconfig to Testing Framework
78  $connection = GeneralUtility::makeInstance(ConnectionPool::class)
79  ->getConnectionForTable('pages');
80  $connection->update(
81  'pages',
82  ['TSconfig' => implode(chr(10), [
83  'TCEMAIN.linkHandler.content {',
84  ' configuration.table = tt_content',
85  '}',
86  ])],
87  ['uid' => 1000]
88  );
89 
90  $this->‪setUpFileStorage();
91  $this->setUpFrontendRootPage(
92  1000,
93  [
94  'typo3/sysext/frontend/Tests/Functional/SiteHandling/Fixtures/LinkGenerator.typoscript',
95  ],
96  [
97  'title' => 'ACME Root',
98  ]
99  );
100  }
101 
105  private function ‪setUpFileStorage(): void
106  {
107  $storageRepository = GeneralUtility::makeInstance(StorageRepository::class);
108  $storageId = $storageRepository->createLocalStorage(
109  'fileadmin',
110  'fileadmin/',
111  'relative',
112  'Default storage created in TypoLinkTest',
113  true
114  );
115  $storage = $storageRepository->findByUid($storageId);
116  (new ‪Indexer($storage))->processChangesInStorages();
117  }
118 
122  public function ‪linkIsGeneratedDataProvider(): array
123  {
124  $instructions = [
125  [
126  't3://email?email=mailto:user@example.org&other=other#other',
127  '<a href="mailto:user@example.org">user@example.org</a>',
128  ],
129  [
130  't3://email?email=user@example.org&other=other#other',
131  '<a href="mailto:user@example.org">user@example.org</a>',
132  ],
133  [
134  't3://email?email=user@example.org?subject=Hello%20World#other',
135  '<a href="mailto:user@example.org?subject=Hello World">user@example.org?subject=Hello World</a>',
136  ],
137  [
138  't3://file?uid=1&type=1&other=other#other',
139  '<a href="/fileadmin/logo.png#other">/fileadmin/logo.png</a>',
140  ],
141  [
142  't3://file?identifier=1:/logo.png&other=other#other',
143  '<a href="/fileadmin/logo.png#other">/fileadmin/logo.png</a>',
144  ],
145  [
146  't3://file?identifier=fileadmin/logo.png&other=other#other',
147  '<a href="/fileadmin/logo.png#other">/fileadmin/logo.png</a>',
148  ],
149  [
150  't3://folder?identifier=fileadmin&other=other#other',
151  '<a href="/fileadmin/#other">/fileadmin/</a>',
152  ],
153  [
154  't3://page?uid=1200&type=1&param-a=a&param-b=b#fragment',
155  '<a href="/features?param-a=a&amp;param-b=b&amp;type=1&amp;cHash=92aa5284d0ad18f7934fe94b52f6c1a5#fragment">EN: Features</a>',
156  ],
157  [
158  't3://page?uid=1300&additional=1&param-a=a#fragment',
159  '<a href="http://typo3.org">Go to TYPO3.org</a>',
160  ],
161  [
162  't3://record?identifier=content&uid=400&other=other#fragment',
163  '<a href="/features#c400">EN: Features</a>',
164  ],
165  'Non-existent record' => [
166  't3://record?identifier=content&uid=400000',
167  '',
168  ],
169  'Translated record on default language page' => [
170  't3://record?identifier=content&uid=402',
171  '<a href="/features#c402">EN: Features</a>',
172  ],
173  'Record with language ALL on default language page' => [
174  't3://record?identifier=content&uid=410',
175  '<a href="/features#c410">EN: Features</a>',
176  ],
177  [
178  't3://url?url=https://typo3.org%3f%26param-a=a%26param-b=b&other=other#other',
179  '<a href="https://typo3.org?&amp;param-a=a&amp;param-b=b">https://typo3.org?&amp;param-a=a&amp;param-b=b</a>',
180  ],
181  [
182  '1200,1 target class title &param-a=a',
183  '<a href="/features?param-a=a&amp;type=1&amp;cHash=62ac35c73f425af5e13cfff14c04424e" title="title" target="target" class="class">EN: Features</a>',
184  ],
185  [
186  'user@example.org target class title &other=other',
187  '<a href="mailto:user@example.org" title="title" target="target" class="class">user@example.org</a>',
188  ],
189  // check link with language parameters
190  [
191  't3://page?uid=1200&L=0',
192  '<a href="/features">EN: Features</a>',
193  ],
194  [
195  't3://page?uid=1200&_language=0',
196  '<a href="/features">EN: Features</a>',
197  ],
198  [
199  't3://page?uid=1200&L=1',
200  '<a href="https://acme.fr/features-fr">FR: Features</a>',
201  ],
202  [
203  't3://page?uid=1200&_language=1',
204  '<a href="https://acme.fr/features-fr">FR: Features</a>',
205  ],
206  [
207  't3://page?uid=1201&L=1',
208  '<a href="https://acme.fr/features-fr">FR: Features</a>',
209  ],
210  [
211  't3://page?uid=1201&_language=1',
212  '<a href="https://acme.fr/features-fr">FR: Features</a>',
213  ],
214  // localized page language overrule language arguments (new and old).
215  // This has also test coverage through SlugGeneratorTests.
216  [
217  't3://page?uid=1202&L=1',
218  '<a href="https://acme.ca/features-ca">FR-CA: Features</a>',
219  ],
220  [
221  't3://page?uid=1202&_language=1',
222  '<a href="https://acme.ca/features-ca">FR-CA: Features</a>',
223  ],
224  // check precedence order correctness if old and modern are provided
225  [
226  't3://page?uid=1200&L=2&_language=1',
227  '<a href="https://acme.fr/features-fr">FR: Features</a>',
228  ],
229  [
230  't3://page?uid=1200&_language=1&L=2',
231  '<a href="https://acme.fr/features-fr">FR: Features</a>',
232  ],
233  [
234  't3://page?uid=1200&L=1&_language=2',
235  '<a href="https://acme.ca/features-ca">FR-CA: Features</a>',
236  ],
237  [
238  't3://page?uid=1200&_language=2&L=1',
239  '<a href="https://acme.ca/features-ca">FR-CA: Features</a>',
240  ],
241  ];
242  return $this->‪keysFromTemplate($instructions, '%1$s;');
243  }
244 
252  public function ‪linkIsGenerated(string $parameter, string $expectation): void
253  {
254  $response = $this->‪invokeTypoLink($parameter);
255  self::assertSame($expectation, (string)$response->getBody());
256  }
257 
259  {
260  return [
261  'No ATag Params' => [
262  [
263  'ATagParams' => '',
264  ],
265  '',
266  'text',
267  '<a href="/welcome">text</a>',
268  ],
269  'specific ATagParams' => [
270  [
271  'ATagParams' => 'data-any="where"',
272  ],
273  '',
274  'text',
275  '<a href="/welcome" data-any="where">text</a>',
276  ],
277  'specific ATagParams with a target' => [
278  [
279  'ATagParams' => 'data-any="where" target="from-a-tags"',
280  ],
281  '',
282  'text',
283  '<a href="/welcome" data-any="where" target="from-a-tags">text</a>',
284  ],
285  'specific ATagParams with target in parameter' => [
286  [
287  'parameter' => '1100 from-parameter',
288  'ATagParams' => 'data-any="where"',
289  ],
290  '',
291  'text',
292  '<a href="/welcome" target="from-parameter" data-any="where">text</a>',
293  ],
294  'specific ATagParams with a target and target in parameter' => [
295  [
296  'parameter' => '1100 from-parameter',
297  'ATagParams' => 'data-any="where" target="from-a-tags"',
298  ],
299  '',
300  'text',
301  '<a href="/welcome" target="from-a-tags" data-any="where">text</a>',
302  ],
303  'specific ATagParams with a target and target as option' => [
304  [
305  'parameter' => '1100 from-parameter',
306  'ATagParams' => 'data-any="where" target="from-a-tags"',
307  'target' => 'from-option',
308  ],
309  '',
310  'text',
311  '<a href="/welcome" target="from-a-tags" data-any="where">text</a>',
312  ],
313  'specific ATagParams with a target and target in parameter and global attributes' => [
314  [
315  'parameter' => '1100 from-parameter',
316  'ATagParams' => 'data-any="where" target="from-a-tags"',
317  ],
318  'tabindex="from-global"',
319  'text',
320  '<a href="/welcome" target="from-a-tags" tabindex="from-global" data-any="where">text</a>',
321  ],
322  'specific ATagParams with global attributes and local ATagParams overridden mixed, and href removed' => [
323  [
324  'ATagParams' => 'data-any="where" target="from-a-tags"',
325  ],
326  'tabindex="from-global" target="_blank" data-any="global" data-global="1" href="#"',
327  'text',
328  '<a href="/welcome" tabindex="from-global" target="from-a-tags" data-any="where" data-global="1">text</a>',
329  ],
340  ];
341  }
342 
347  public function ‪ATagParamsAreAddedInOrder(array $instructions, string $globalATagParams, string $linkText, string $expectation): void
348  {
349  $sourcePageId = 1100;
350  $instructions['parameter'] = $instructions['parameter'] ?? $sourcePageId;
351  $request = (new InternalRequest('https://acme.us/'))
352  ->withPageId($sourcePageId)
353  ->withInstructions(
354  [
355  $this->‪createTypoLinkInstruction($instructions, $linkText),
356  (new TypoScriptInstruction(TemplateService::class))
357  ->withTypoScript([
358  'config.' => [
359  'ATagParams' => $globalATagParams,
360  ],
361  ]),
362  ],
363  );
364  $response = $this->executeFrontendSubRequest($request);
365  self::assertSame($expectation, (string)$response->getBody());
366  }
367 
371  public function ‪linkIsEncodedDataProvider(): array
372  {
373  $instructions = [
374  [
375  't3://email?email=mailto:<bad>thing(1)</bad>',
376  '<a href="mailto:&lt;bad&gt;thing(1)&lt;/bad&gt;">&lt;bad&gt;thing(1)&lt;/bad&gt;</a>',
377  ],
378  [
379  't3://email?email=mailto:<good%20a="a/"%20b="thing(1)">',
380  '<a href="mailto:&lt;good a=&quot;a/&quot; b=&quot;thing(1)&quot;&gt;">&lt;good a=&quot;a/&quot; b=&quot;thing(1)&quot;&gt;</a>',
381  ],
382  [
383  't3://email?email=<bad>thing(1)</bad>',
384  '<a href="mailto:&lt;bad&gt;thing(1)&lt;/bad&gt;">&lt;bad&gt;thing(1)&lt;/bad&gt;</a>',
385  ],
386  [
387  't3://email?email=<good%20a="a/"%20b="thing(1)">',
388  '<a href="mailto:&lt;good a=&quot;a/&quot; b=&quot;thing(1)&quot;&gt;">&lt;good a=&quot;a/&quot; b=&quot;thing(1)&quot;&gt;</a>',
389  ],
390  [
391  't3://folder?identifier=<any>',
392  '',
393  ],
394  [
395  't3://page?uid=<any>',
396  '',
397  ],
398  [
399  't3://record?identifier=content&uid=<any>',
400  '',
401  ],
402  [
403  't3://url?url=<bad>thing(1)</bad>',
404  '<a href="http://&lt;bad&gt;thing(1)&lt;/bad&gt;">http://&lt;bad&gt;thing(1)&lt;/bad&gt;</a>',
405  ],
406  [
407  't3://url?url=<good%20a="a/"%20b="thing(1)">',
408  '<a href="http://&lt;good a=&quot;a/&quot; b=&quot;thing(1)&quot;&gt;">http://&lt;good a=&quot;a/&quot; b=&quot;thing(1)&quot;&gt;</a>',
409  ],
410  [
411  't3://url?url=javascript:good()',
412  '<a ></a>',
413  ],
414  [
415  "t3://url?url=java\tscript:good()",
416  '<a href="http://java_script:good()">http://java_script:good()</a>',
417  ],
418  [
419  't3://url?url=java&#09;script:good()',
420  '<a href="http://java">http://java</a>',
421  ],
422  [
423  't3://url?url=javascript&colon;good()',
424  '<a href="http://javascript">http://javascript</a>',
425  ],
426  [
427  't3://url?url=data:text/html,<good>',
428  '<a ></a>',
429  ],
430  [
431  "t3://url?url=da\tsta:text/html,<good>",
432  '<a href="http://da_sta:text/html,&lt;good&gt;">http://da_sta:text/html,&lt;good&gt;</a>',
433  ],
434  [
435  't3://url?url=da&#09;ta:text/html,<good>',
436  '<a href="http://da">http://da</a>',
437  ],
438  [
439  't3://url?url=data&colon;text/html,<good>',
440  '<a href="http://data">http://data</a>',
441  ],
442  [
443  't3://url?url=%26%23106%3B%26%2397%3B%26%23118%3B%26%2397%3B%26%23115%3B%26%2399%3B%26%23114%3B%26%23105%3B%26%23112%3B%26%23116%3B%26%2358%3B%26%23103%3B%26%23111%3B%26%23111%3B%26%23100%3B%26%2340%3B%26%2341%3B',
444  '<a href="http://&amp;#106;&amp;#97;&amp;#118;&amp;#97;&amp;#115;&amp;#99;&amp;#114;&amp;#105;&amp;#112;&amp;#116;&amp;#58;&amp;#103;&amp;#111;&amp;#111;&amp;#100;&amp;#40;&amp;#41;">http://&amp;#106;&amp;#97;&amp;#118;&amp;#97;&amp;#115;&amp;#99;&amp;#114;&amp;#105;&amp;#112;&amp;#116;&amp;#58;&amp;#103;&amp;#111;&amp;#111;&amp;#100;&amp;#40;&amp;#41;</a>',
445  ],
446  [
447  '<bad>thing(1)</bad>',
448  '<a href="/&lt;bad&gt;thing(1)&lt;/bad&gt;">&lt;bad&gt;thing(1)&lt;/bad&gt;</a>',
449  ],
450  [
451  '<good%20a="a/"%20b="thing(1)">',
452  '<a href="/&lt;good%20a=&quot;a/&quot;%20b=&quot;thing(1)&quot;&gt;">&lt;good a=&quot;a/&quot; b=&quot;thing(1)&quot;&gt;</a>',
453  ],
454  [
455  '<good/a="a/"/b="thing(1)"> target class title &other=other',
456  '<a href="/&lt;good/a=&quot;a/&quot;/b=&quot;thing(1)&quot;&gt;" title="title" target="target" class="class">&lt;good/a=&quot;a/&quot;/b=&quot;thing(1)&quot;&gt;</a>',
457  ],
458  [
459  'javascript:good()',
460  '',
461  ],
462  [
463  "java\tscript:good()",
464  '',
465  ],
466  [
467  'java&#09;script:good()',
468  '<a href="java&amp;#09;script:good()"></a>',
469  ],
470  [
471  'javascript&colon;good()',
472  '',
473  ],
474  [
475  'data:text/html,<good>',
476  '',
477  ],
478  [
479  "da\tta:text/html,<good>",
480  '',
481  ],
482  [
483  'da&#09;ta:text/html,<good>',
484  '<a href="da&amp;#09;ta:text/html,&lt;good&gt;"></a>',
485  ],
486  [
487  'data&colon;text/html,<good>',
488  '<a href="/data&amp;colon;text/html,&lt;good&gt;">data&amp;colon;text/html,&lt;good&gt;</a>',
489  ],
490  [
491  '%26%23106%3B%26%2397%3B%26%23118%3B%26%2397%3B%26%23115%3B%26%2399%3B%26%23114%3B%26%23105%3B%26%23112%3B%26%23116%3B%26%2358%3B%26%23103%3B%26%23111%3B%26%23111%3B%26%23100%3B%26%2340%3B%26%2341%3B',
492  '',
493  ],
494  [
495  '</> <"> <"> <">',
496  '<a href="/&lt;/&gt;" title="&lt;&quot;&gt;" target="&lt;&quot;&gt;" class="&lt;&quot;&gt;">&lt;/&gt;</a>',
497  ],
498  ];
499  return $this->‪keysFromTemplate($instructions, '%1$s;');
500  }
501 
509  public function ‪linkIsEncodedPerDefault(string $parameter, string $expectation): void
510  {
511  $response = $this->‪invokeTypoLink($parameter);
512  self::assertSame($expectation, (string)$response->getBody());
513  }
514 
522  public function ‪linkIsEncodedHavingParseFunc(string $parameter, string $expectation): void
523  {
524  $response = $this->‪invokeTypoLink($parameter, $this->‪createParseFuncInstruction([
525  'allowTags' => 'good',
526  'denyTags' => '*',
527  'nonTypoTagStdWrap.' => [
528  'HTMLparser.' => [
529  'tags.' => [
530  'good.' => [
531  'allowedAttribs' => 0,
532  ],
533  ],
534  ],
535  ],
536  ]));
537  self::assertSame($expectation, (string)$response->getBody());
538  }
539 
543  public function ‪linkToPageIsProcessedDataProvider(): array
544  {
545  return [
546  [
547  't3://page?uid=9911',
548  '<a href="/test/good">&lt;good&gt;</a>',
549  false,
550  ],
551  [
552  't3://page?uid=9911',
553  '<a href="/test/good"><good></good></a>', // expanded from `<good>` to `<good></good>`
554  true,
555  ],
556  [
557  't3://page?uid=9912',
558  '<a href="/test/good-a-b-spaced">&lt;good a=&quot;a/&quot; b=&quot;thing(1)&quot;&gt;</a>',
559  false,
560  ],
561  [
562  't3://page?uid=9912',
563  '<a href="/test/good-a-b-spaced"><good></good></a>', // expanded from `<good>` to `<good></good>`
564  true,
565  ],
566  [
567  't3://page?uid=9913',
568  '<a href="/test/good-a-b-enc-a">&lt;good%20a=&quot;a/&quot;%20b=&quot;thing(1)&quot;&gt;</a>',
569  false,
570  ],
571  [
572  't3://page?uid=9913',
573  '<a href="/test/good-a-b-enc-a">&lt;good%20a="a/"%20b="thing(1)"&gt;</a>',
574  true,
575  ],
576  [
577  't3://page?uid=9914',
578  '<a href="/test/good-a-b-enc-b">&lt;good/a=&quot;a/&quot;/b=&quot;thing(1)&quot;&gt;</a>',
579  false,
580  ],
581  [
582  't3://page?uid=9914',
583  '<a href="/test/good-a-b-enc-b">&lt;good/a="a/"/b="thing(1)"&gt;</a>',
584  true,
585  ],
586  [
587  't3://page?uid=9921',
588  '<a href="/test/bad">&lt;bad&gt;</a>',
589  false,
590  ],
591  [
592  't3://page?uid=9921',
593  '<a href="/test/bad">&lt;bad&gt;</a>',
594  true,
595  ],
596  ];
597  }
598 
607  public function ‪linkToPageIsProcessed(string $parameter, string $expectation, bool $parseFuncEnabled): void
608  {
609  $instructions = [];
610  if ($parseFuncEnabled) {
611  $instructions[] = $this->‪createParseFuncInstruction([
612  'allowTags' => 'good',
613  'denyTags' => '*',
614  'nonTypoTagStdWrap.' => [
615  'HTMLparser.' => [
616  'tags.' => [
617  'good.' => [
618  'allowedAttribs' => 0,
619  ],
620  ],
621  ],
622  ],
623  'htmlSanitize' => true,
624  'htmlSanitize.' => [
625  'build' => TestSanitizerBuilder::class,
626  ],
627  ]);
628  }
629  $response = $this->‪invokeTypoLink($parameter, ...$instructions);
630  self::assertSame($expectation, (string)$response->getBody());
631  }
632 
634  {
635  return [
636  'empty parameter does not create a link' => [
637  [
638  'parameter' => '',
639  ],
640  'no link',
641  'no link',
642  ],
643  'empty parameter with additional ATagParams does not create a link' => [
644  [
645  'parameter' => '',
646  'ATagParams' => 'data-any="where"',
647  ],
648  'no link',
649  'no link',
650  ],
651  'empty parameter with additional ATagParams with id creates a link' => [
652  [
653  'parameter' => '',
654  'ATagParams' => 'id="c13" data-any="where"',
655  ],
656  'a link',
657  '<a id="c13" data-any="where">a link</a>',
658  ],
659  'empty parameter with additional ATagParams with id creates a link and adds title' => [
660  [
661  'parameter' => '',
662  'ATagParams' => 'id="c13" data-any="where"',
663  'title' => 'custom title',
664  ],
665  'a link',
666  '<a title="custom title" id="c13" data-any="where">a link</a>',
667  ],
668  ];
669  }
670 
675  public function ‪linkWithoutAnchorIsGenerated(array $instructions, string $linkText, string $expectation): void
676  {
677  $sourcePageId = 1100;
678  $request = (new InternalRequest('https://acme.us/'))
679  ->withPageId($sourcePageId)
680  ->withInstructions(
681  [
682  $this->‪createTypoLinkInstruction($instructions, $linkText),
683  ]
684  );
685  $response = $this->executeFrontendSubRequest($request);
686  self::assertSame($expectation, (string)$response->getBody());
687  }
688 
694  private function ‪invokeTypoLink(string $parameter, AbstractInstruction ...$instructions): InternalResponse
695  {
696  $sourcePageId = 1100;
697 
698  $request = (new InternalRequest('https://acme.us/'))
699  ->withPageId($sourcePageId)
700  ->withInstructions(
701  [
703  'parameter.' => [
704  'data' => 'field:pid',
705  ],
706  'section.' => [
707  'data' => 'field:uid',
708  'wrap' => 'c|',
709  ],
710  ]),
712  'parameter' => $parameter,
713  ]),
714  ]
715  );
716 
717  if (count($instructions) > 0) {
718  $request = $this->‪applyInstructions($request, ...$instructions);
719  }
720 
721  return $this->executeFrontendSubRequest($request);
722  }
723 
729  private function ‪createTypoLinkInstruction(array $typoLink, ?string $linkText = null): ArrayValueInstruction
730  {
731  return (new ArrayValueInstruction(LinkHandlingController::class))
732  ->withArray([
733  '10' => 'TEXT',
734  '10.' => array_merge([
735  'typolink.' => $typoLink,
736  ], ($linkText ? ['value' => $linkText] : [])),
737  ]);
738  }
739 
744  private function ‪createRecordLinksInstruction(array $typoLink): TypoScriptInstruction
745  {
746  return (new TypoScriptInstruction(TemplateService::class))
747  ->withTypoScript([
748  'config.' => [
749  'recordLinks.' => [
750  'content.' => [
751  'typolink.' => $typoLink,
752  ],
753  ],
754  ],
755  ]);
756  }
757 
762  private function ‪createParseFuncInstruction(array $parseFunc): TypoScriptInstruction
763  {
764  return (new TypoScriptInstruction(TemplateService::class))
765  ->withTypoScript([
766  'lib.' => [
767  'parseFunc.' => array_replace_recursive(
768  [
769  'makelinks' => 1,
770  'makelinks.' => [
771  'http.' => [
772  'keep' => 'path',
773  'extTarget' => '_blank',
774  ],
775  'mailto.' => [
776  'keep' => 'path',
777  ],
778  ],
779  'allowTags' => '',
780  'denyTags' => '',
781  'constants' => 1,
782  'nonTypoTagStdWrap.' => [
783  'HTMLparser' => 1,
784  'HTMLparser.' => [
785  'keepNonMatchedTags' => 1,
786  'htmlSpecialChars' => 2,
787  ],
788  ],
789  ],
790  $parseFunc
791  ),
792  ],
793  ]);
794  }
795 }
‪TYPO3\CMS\Core\Resource\Index\Indexer
Definition: Indexer.php:34
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildLanguageConfiguration
‪array buildLanguageConfiguration(string $identifier, string $base, array $fallbackIdentifiers=[], string $fallbackType=null)
Definition: SiteBasedTestTrait.php:144
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\writeSiteConfiguration
‪writeSiteConfiguration(string $identifier, array $site=[], array $languages=[], array $errorHandling=[])
Definition: SiteBasedTestTrait.php:58
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\AbstractTestCase\keysFromTemplate
‪array keysFromTemplate(array $array, string $template, callable $callback=null)
Definition: AbstractTestCase.php:102
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\AbstractTestCase
Definition: AbstractTestCase.php:29
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildDefaultLanguageConfiguration
‪array buildDefaultLanguageConfiguration(string $identifier, string $base)
Definition: SiteBasedTestTrait.php:126
‪TYPO3\CMS\Core\Core\Bootstrap\initializeLanguageObject
‪static initializeLanguageObject()
Definition: Bootstrap.php:598
‪TYPO3\CMS\Core\Resource\StorageRepository
Definition: StorageRepository.php:38
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling\Fixtures\TestSanitizerBuilder
Definition: TestSanitizerBuilder.php:24
‪TYPO3\CMS\Core\TypoScript\TemplateService
Definition: TemplateService.php:46
‪TYPO3\CMS\Frontend\Tests\Functional\SiteHandling
Definition: AbstractTestCase.php:18
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\applyInstructions
‪InternalRequest applyInstructions(InternalRequest $request, AbstractInstruction ... $instructions)
Definition: SiteBasedTestTrait.php:254
‪TYPO3\CMS\Core\Core\Bootstrap
Definition: Bootstrap.php:70
‪TYPO3\CMS\Core\Tests\Functional\SiteHandling\SiteBasedTestTrait\buildSiteConfiguration
‪array buildSiteConfiguration(int $rootPageId, string $base='')
Definition: SiteBasedTestTrait.php:111
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50