Issues (655)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

tests/Twig/Extension/SonataAdminExtensionTest.php (22 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
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\AdminBundle\Tests\Twig\Extension;
15
16
use PHPUnit\Framework\TestCase;
17
use Sonata\AdminBundle\Admin\AbstractAdmin;
18
use Sonata\AdminBundle\Admin\AdminInterface;
19
use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
20
use Sonata\AdminBundle\Admin\Pool;
21
use Sonata\AdminBundle\Exception\NoValueException;
22
use Sonata\AdminBundle\Templating\TemplateRegistry;
23
use Sonata\AdminBundle\Templating\TemplateRegistryInterface;
24
use Sonata\AdminBundle\Tests\Fixtures\Entity\FooToString;
25
use Sonata\AdminBundle\Twig\Extension\SonataAdminExtension;
26
use Symfony\Bridge\Twig\AppVariable;
27
use Symfony\Bridge\Twig\Extension\RoutingExtension;
28
use Symfony\Bridge\Twig\Extension\TranslationExtension;
29
use Symfony\Component\Config\FileLocator;
30
use Symfony\Component\DependencyInjection\ContainerInterface;
31
use Symfony\Component\HttpFoundation\Request;
32
use Symfony\Component\Routing\Generator\UrlGenerator;
33
use Symfony\Component\Routing\Loader\XmlFileLoader;
34
use Symfony\Component\Routing\RequestContext;
35
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
36
use Symfony\Component\Translation\Loader\XliffFileLoader;
37
use Symfony\Component\Translation\Translator;
38
use Symfony\Contracts\Translation\TranslatorInterface;
39
use Twig\Environment;
40
use Twig\Extra\String\StringExtension;
41
use Twig\Loader\FilesystemLoader;
42
43
/**
44
 * Test for SonataAdminExtension.
45
 *
46
 * @author Andrej Hudec <[email protected]>
47
 */
48
class SonataAdminExtensionTest extends TestCase
49
{
50
    /**
51
     * @var SonataAdminExtension
52
     */
53
    private $twigExtension;
54
55
    /**
56
     * @var Environment
57
     */
58
    private $environment;
59
60
    /**
61
     * @var AdminInterface
62
     */
63
    private $admin;
64
65
    /**
66
     * @var AdminInterface
67
     */
68
    private $adminBar;
69
70
    /**
71
     * @var FieldDescriptionInterface
72
     */
73
    private $fieldDescription;
74
75
    /**
76
     * @var \stdClass
77
     */
78
    private $object;
79
80
    /**
81
     * @var Pool
82
     */
83
    private $pool;
84
85
    /**
86
     * @var string[]
87
     */
88
    private $xEditableTypeMapping;
89
90
    /**
91
     * @var TranslatorInterface
92
     */
93
    private $translator;
94
95
    /**
96
     * @var ContainerInterface
97
     */
98
    private $container;
99
100
    /**
101
     * @var TemplateRegistryInterface
102
     */
103
    private $templateRegistry;
104
105
    /**
106
     * @var AuthorizationCheckerInterface
107
     */
108
    private $securityChecker;
109
110
    protected function setUp(): void
111
    {
112
        date_default_timezone_set('Europe/London');
113
114
        $container = $this->createMock(ContainerInterface::class);
115
116
        $this->pool = new Pool($container, '', '');
117
        $this->pool->setAdminServiceIds(['sonata_admin_foo_service']);
118
        $this->pool->setAdminClasses(['fooClass' => ['sonata_admin_foo_service']]);
119
120
        $this->xEditableTypeMapping = [
0 ignored issues
show
Documentation Bug introduced by
It seems like array('choice' => 'selec...umber', 'url' => 'url') of type array<string,string,{"ch...tring","url":"string"}> is incompatible with the declared type array<integer,string> of property $xEditableTypeMapping.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
121
            'choice' => 'select',
122
            'boolean' => 'select',
123
            'text' => 'text',
124
            'textarea' => 'textarea',
125
            'html' => 'textarea',
126
            'email' => 'email',
127
            'string' => 'text',
128
            'smallint' => 'text',
129
            'bigint' => 'text',
130
            'integer' => 'number',
131
            'decimal' => 'number',
132
            'currency' => 'number',
133
            'percent' => 'number',
134
            'url' => 'url',
135
        ];
136
137
        // translation extension
138
        $translator = new Translator('en');
139
        $translator->addLoader('xlf', new XliffFileLoader());
140
        $translator->addResource(
141
            'xlf',
142
            sprintf('%s/../../../src/Resources/translations/SonataAdminBundle.en.xliff', __DIR__),
143
            'en',
144
            'SonataAdminBundle'
145
        );
146
147
        $this->translator = $translator;
148
149
        $this->templateRegistry = new TemplateRegistry();
150
        $this->container = $this->createMock(ContainerInterface::class);
151
        $this->container
152
            ->method('get')
153
            ->with('sonata_admin_foo_service.template_registry')
154
            ->willReturn($this->templateRegistry);
155
156
        $this->securityChecker = $this->createMock(AuthorizationCheckerInterface::class);
157
        $this->securityChecker->method('isGranted')->willReturn(true);
158
159
        $this->twigExtension = new SonataAdminExtension(
160
            $this->pool,
161
            $this->translator,
162
            $this->container,
163
            $this->securityChecker
164
        );
165
        $this->twigExtension->setXEditableTypeMapping($this->xEditableTypeMapping);
166
167
        $request = $this->createMock(Request::class);
168
        $request->method('get')->with('_sonata_admin')->willReturn('sonata_admin_foo_service');
169
170
        $loader = new FilesystemLoader([
171
            __DIR__.'/../../../src/Resources/views/CRUD',
172
            __DIR__.'/../../Fixtures/Resources/views/CRUD',
173
        ]);
174
        $loader->addPath(__DIR__.'/../../../src/Resources/views/', 'SonataAdmin');
175
        $loader->addPath(__DIR__.'/../../Fixtures/Resources/views/', 'App');
176
177
        $this->environment = new Environment($loader, [
178
            'strict_variables' => true,
179
            'cache' => false,
180
            'autoescape' => 'html',
181
            'optimizations' => 0,
182
        ]);
183
        $this->environment->addExtension($this->twigExtension);
184
        $this->environment->addExtension(new TranslationExtension($translator));
185
        $this->environment->addExtension(new FakeTemplateRegistryExtension());
186
187
        // routing extension
188
        $xmlFileLoader = new XmlFileLoader(new FileLocator([sprintf('%s/../../../src/Resources/config/routing', __DIR__)]));
189
        $routeCollection = $xmlFileLoader->load('sonata_admin.xml');
190
191
        $xmlFileLoader = new XmlFileLoader(new FileLocator([sprintf('%s/../../Fixtures/Resources/config/routing', __DIR__)]));
192
        $testRouteCollection = $xmlFileLoader->load('routing.xml');
193
194
        $routeCollection->addCollection($testRouteCollection);
0 ignored issues
show
$testRouteCollection is of type object<Symfony\Component\Routing\RouteCollection>, but the function expects a object<self>.

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...
195
        $requestContext = new RequestContext();
196
        $urlGenerator = new UrlGenerator($routeCollection, $requestContext);
197
        $this->environment->addExtension(new RoutingExtension($urlGenerator));
198
        $this->environment->addExtension(new StringExtension());
199
200
        // initialize object
201
        $this->object = new \stdClass();
202
203
        // initialize admin
204
        $this->admin = $this->createMock(AbstractAdmin::class);
205
206
        $this->admin
207
            ->method('getCode')
208
            ->willReturn('sonata_admin_foo_service');
209
210
        $this->admin
211
            ->method('id')
212
            ->with($this->equalTo($this->object))
213
            ->willReturn('12345');
214
215
        $this->admin
216
            ->method('getNormalizedIdentifier')
217
            ->with($this->equalTo($this->object))
218
            ->willReturn('12345');
219
220
        $this->adminBar = $this->createMock(AbstractAdmin::class);
221
        $this->adminBar
222
            ->method('hasAccess')
223
            ->willReturn(true);
224
        $this->adminBar
225
            ->method('getNormalizedIdentifier')
226
            ->with($this->equalTo($this->object))
227
            ->willReturn('12345');
228
229
        $container
230
            ->method('get')
231
            ->willReturnCallback(function (string $id) {
232
                if ('sonata_admin_foo_service' === $id) {
233
                    return $this->admin;
234
                }
235
236
                if ('sonata_admin_bar_service' === $id) {
237
                    return $this->adminBar;
238
                }
239
            });
240
241
        // initialize field description
242
        $this->fieldDescription = $this->getMockForAbstractClass(FieldDescriptionInterface::class);
243
244
        $this->fieldDescription
245
            ->method('getName')
246
            ->willReturn('fd_name');
247
248
        $this->fieldDescription
249
            ->method('getAdmin')
250
            ->willReturn($this->admin);
251
252
        $this->fieldDescription
253
            ->method('getLabel')
254
            ->willReturn('Data');
255
    }
256
257
    public function getRenderListElementTests()
258
    {
259
        return [
260
            [
261
                '<td class="sonata-ba-list-field sonata-ba-list-field-string" objectId="12345"> Example </td>',
262
                'string',
263
                'Example',
264
                [],
265
            ],
266
            [
267
                '<td class="sonata-ba-list-field sonata-ba-list-field-string" objectId="12345"> </td>',
268
                'string',
269
                null,
270
                [],
271
            ],
272
            [
273
                '<td class="sonata-ba-list-field sonata-ba-list-field-text" objectId="12345"> Example </td>',
274
                'text',
275
                'Example',
276
                [],
277
            ],
278
            [
279
                '<td class="sonata-ba-list-field sonata-ba-list-field-text" objectId="12345"> </td>',
280
                'text',
281
                null,
282
                [],
283
            ],
284
            [
285
                '<td class="sonata-ba-list-field sonata-ba-list-field-textarea" objectId="12345"> Example </td>',
286
                'textarea',
287
                'Example',
288
                [],
289
            ],
290
            [
291
                '<td class="sonata-ba-list-field sonata-ba-list-field-textarea" objectId="12345"> </td>',
292
                'textarea',
293
                null,
294
                [],
295
            ],
296
            'datetime field' => [
297
                '<td class="sonata-ba-list-field sonata-ba-list-field-datetime" objectId="12345">
298
                    <time datetime="2013-12-24T10:11:12+00:00" title="2013-12-24T10:11:12+00:00">
299
                        December 24, 2013 10:11
300
                    </time>
301
                </td>',
302
                'datetime',
303
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')),
304
                [],
305
            ],
306
            [
307
                '<td class="sonata-ba-list-field sonata-ba-list-field-datetime" objectId="12345">
308
                    <time datetime="2013-12-24T10:11:12+00:00" title="2013-12-24T10:11:12+00:00">
309
                        December 24, 2013 18:11
310
                    </time>
311
                </td>',
312
                'datetime',
313
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('UTC')),
314
                ['timezone' => 'Asia/Hong_Kong'],
315
            ],
316
            [
317
                '<td class="sonata-ba-list-field sonata-ba-list-field-datetime" objectId="12345"> &nbsp; </td>',
318
                'datetime',
319
                null,
320
                [],
321
            ],
322
            [
323
                '<td class="sonata-ba-list-field sonata-ba-list-field-datetime" objectId="12345">
324
                    <time datetime="2013-12-24T10:11:12+00:00" title="2013-12-24T10:11:12+00:00">
325
                        24.12.2013 10:11:12
326
                    </time>
327
                </td>',
328
                'datetime',
329
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')),
330
                ['format' => 'd.m.Y H:i:s'],
331
            ],
332
            [
333
                '<td class="sonata-ba-list-field sonata-ba-list-field-datetime" objectId="12345"> &nbsp; </td>',
334
                'datetime',
335
                null,
336
                ['format' => 'd.m.Y H:i:s'],
337
            ],
338
            [
339
                '<td class="sonata-ba-list-field sonata-ba-list-field-datetime" objectId="12345">
340
                    <time datetime="2013-12-24T10:11:12+00:00" title="2013-12-24T10:11:12+00:00">
341
                        24.12.2013 18:11:12
342
                    </time>
343
                </td>',
344
                'datetime',
345
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('UTC')),
346
                ['format' => 'd.m.Y H:i:s', 'timezone' => 'Asia/Hong_Kong'],
347
            ],
348
            [
349
                '<td class="sonata-ba-list-field sonata-ba-list-field-datetime" objectId="12345"> &nbsp; </td>',
350
                'datetime',
351
                null,
352
                ['format' => 'd.m.Y H:i:s', 'timezone' => 'Asia/Hong_Kong'],
353
            ],
354
            [
355
                '<td class="sonata-ba-list-field sonata-ba-list-field-date" objectId="12345">
356
                    <time datetime="2013-12-24" title="2013-12-24">
357
                        December 24, 2013
358
                    </time>
359
                </td>',
360
                'date',
361
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')),
362
                [],
363
            ],
364
            [
365
                '<td class="sonata-ba-list-field sonata-ba-list-field-date" objectId="12345"> &nbsp; </td>',
366
                'date',
367
                null,
368
                [],
369
            ],
370
            [
371
                '<td class="sonata-ba-list-field sonata-ba-list-field-date" objectId="12345">
372
                    <time datetime="2013-12-24" title="2013-12-24">
373
                        24.12.2013
374
                    </time>
375
                </td>',
376
                'date',
377
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')),
378
                ['format' => 'd.m.Y'],
379
            ],
380
            [
381
                '<td class="sonata-ba-list-field sonata-ba-list-field-date" objectId="12345"> &nbsp; </td>',
382
                'date',
383
                null,
384
                ['format' => 'd.m.Y'],
385
            ],
386
            [
387
                '<td class="sonata-ba-list-field sonata-ba-list-field-time" objectId="12345">
388
                    <time datetime="10:11:12+00:00" title="10:11:12+00:00">
389
                        10:11:12
390
                    </time>
391
                </td>',
392
                'time',
393
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')),
394
                [],
395
            ],
396
            [
397
                '<td class="sonata-ba-list-field sonata-ba-list-field-time" objectId="12345">
398
                    <time datetime="10:11:12+00:00" title="10:11:12+00:00">
399
                        18:11:12
400
                    </time>
401
                </td>',
402
                'time',
403
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('UTC')),
404
                ['timezone' => 'Asia/Hong_Kong'],
405
            ],
406
            [
407
                '<td class="sonata-ba-list-field sonata-ba-list-field-time" objectId="12345"> &nbsp; </td>',
408
                'time',
409
                null,
410
                [],
411
            ],
412
            [
413
                '<td class="sonata-ba-list-field sonata-ba-list-field-number" objectId="12345"> 10.746135 </td>',
414
                'number', 10.746135,
415
                [],
416
            ],
417
            [
418
                '<td class="sonata-ba-list-field sonata-ba-list-field-number" objectId="12345"> </td>',
419
                'number',
420
                null,
421
                [],
422
            ],
423
            [
424
                '<td class="sonata-ba-list-field sonata-ba-list-field-integer" objectId="12345"> 5678 </td>',
425
                'integer',
426
                5678,
427
                [],
428
            ],
429
            [
430
                '<td class="sonata-ba-list-field sonata-ba-list-field-integer" objectId="12345"> </td>',
431
                'integer',
432
                null,
433
                [],
434
            ],
435
            [
436
                '<td class="sonata-ba-list-field sonata-ba-list-field-percent" objectId="12345"> 1074.6135 % </td>',
437
                'percent',
438
                10.746135,
439
                [],
440
            ],
441
            [
442
                '<td class="sonata-ba-list-field sonata-ba-list-field-percent" objectId="12345"> 0 % </td>',
443
                'percent',
444
                null,
445
                [],
446
            ],
447
            [
448
                '<td class="sonata-ba-list-field sonata-ba-list-field-currency" objectId="12345"> EUR 10.746135 </td>',
449
                'currency',
450
                10.746135,
451
                ['currency' => 'EUR'],
452
            ],
453
            [
454
                '<td class="sonata-ba-list-field sonata-ba-list-field-currency" objectId="12345"> </td>',
455
                'currency',
456
                null,
457
                ['currency' => 'EUR'],
458
            ],
459
            [
460
                '<td class="sonata-ba-list-field sonata-ba-list-field-currency" objectId="12345"> GBP 51.23456 </td>',
461
                'currency',
462
                51.23456,
463
                ['currency' => 'GBP'],
464
            ],
465
            [
466
                '<td class="sonata-ba-list-field sonata-ba-list-field-currency" objectId="12345"> </td>',
467
                'currency',
468
                null,
469
                ['currency' => 'GBP'],
470
            ],
471
            [
472
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345"> &nbsp; </td>',
473
                'email',
474
                null,
475
                [],
476
            ],
477
            [
478
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345"> <a href="mailto:[email protected]">[email protected]</a> </td>',
479
                'email',
480
                '[email protected]',
481
                [],
482
            ],
483
            [
484
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345">
485
                    <a href="mailto:[email protected]">[email protected]</a> </td>',
486
                'email',
487
                '[email protected]',
488
                ['as_string' => false],
489
            ],
490
            [
491
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345"> [email protected] </td>',
492
                'email',
493
                '[email protected]',
494
                ['as_string' => true],
495
            ],
496
            [
497
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345">
498
                    <a href="mailto:[email protected]?'.$this->buildTwigLikeUrl(['subject' => 'Main Theme', 'body' => 'Message Body']).'">[email protected]</a>  </td>',
499
                'email',
500
                '[email protected]',
501
                ['subject' => 'Main Theme', 'body' => 'Message Body'],
502
            ],
503
            [
504
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345">
505
                    <a href="mailto:[email protected]?'.$this->buildTwigLikeUrl(['subject' => 'Main Theme']).'">[email protected]</a>  </td>',
506
                'email',
507
                '[email protected]',
508
                ['subject' => 'Main Theme'],
509
            ],
510
            [
511
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345">
512
                    <a href="mailto:[email protected]?'.$this->buildTwigLikeUrl(['body' => 'Message Body']).'">[email protected]</a>  </td>',
513
                'email',
514
                '[email protected]',
515
                ['body' => 'Message Body'],
516
            ],
517
            [
518
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345"> [email protected] </td>',
519
                'email',
520
                '[email protected]',
521
                ['as_string' => true, 'subject' => 'Main Theme', 'body' => 'Message Body'],
522
            ],
523
            [
524
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345"> [email protected] </td>',
525
                'email',
526
                '[email protected]',
527
                ['as_string' => true, 'body' => 'Message Body'],
528
            ],
529
            [
530
                '<td class="sonata-ba-list-field sonata-ba-list-field-email" objectId="12345"> [email protected] </td>',
531
                'email',
532
                '[email protected]',
533
                ['as_string' => true, 'subject' => 'Main Theme'],
534
            ],
535
            [
536
                '<td class="sonata-ba-list-field sonata-ba-list-field-array" objectId="12345">
537
                    [1&nbsp;=>&nbsp;First, 2&nbsp;=>&nbsp;Second]
538
                </td>',
539
                'array',
540
                [1 => 'First', 2 => 'Second'],
541
                [],
542
            ],
543
            [
544
                '<td class="sonata-ba-list-field sonata-ba-list-field-array" objectId="12345"> [] </td>',
545
                'array',
546
                null,
547
                [],
548
            ],
549
            [
550
                '<td class="sonata-ba-list-field sonata-ba-list-field-boolean" objectId="12345">
551
                    <span class="label label-success">yes</span>
552
                </td>',
553
                'boolean',
554
                true,
555
                ['editable' => false],
556
            ],
557
            [
558
                '<td class="sonata-ba-list-field sonata-ba-list-field-boolean" objectId="12345">
559
                    <span class="label label-danger">no</span>
560
                </td>',
561
                'boolean',
562
                false,
563
                ['editable' => false],
564
            ],
565
            [
566
                '<td class="sonata-ba-list-field sonata-ba-list-field-boolean" objectId="12345">
567
                    <span class="label label-danger">no</span>
568
                </td>',
569
                'boolean',
570
                null,
571
                ['editable' => false],
572
            ],
573
            [
574
                <<<'EOT'
575
<td class="sonata-ba-list-field sonata-ba-list-field-boolean" objectId="12345">
576
    <span
577
        class="x-editable"
578
        data-type="select"
579
        data-value="1"
580
        data-title="Data"
581
        data-pk="12345"
582
        data-url="/core/set-object-field-value?context=list&amp;field=fd_name&amp;objectId=12345&amp;code=sonata_admin_foo_service"
583
        data-source="[{value: 0, text: 'no'},{value: 1, text: 'yes'}]"
584
    >
585
        <span class="label label-success">yes</span>
586
    </span>
587
</td>
588
EOT
589
            ,
590
                'boolean',
591
                true,
592
                ['editable' => true],
593
            ],
594
            [
595
                <<<'EOT'
596
<td class="sonata-ba-list-field sonata-ba-list-field-boolean" objectId="12345">
597
    <span
598
        class="x-editable"
599
        data-type="select"
600
        data-value="0"
601
        data-title="Data"
602
        data-pk="12345"
603
        data-url="/core/set-object-field-value?context=list&amp;field=fd_name&amp;objectId=12345&amp;code=sonata_admin_foo_service"
604
        data-source="[{value: 0, text: 'no'},{value: 1, text: 'yes'}]"
605
    >
606
    <span class="label label-danger">no</span> </span>
607
</td>
608
EOT
609
                ,
610
                'boolean',
611
                false,
612
                ['editable' => true],
613
            ],
614
            [
615
                <<<'EOT'
616
<td class="sonata-ba-list-field sonata-ba-list-field-boolean" objectId="12345">
617
    <span
618
        class="x-editable"
619
        data-type="select"
620
        data-value="0"
621
        data-title="Data"
622
        data-pk="12345"
623
        data-url="/core/set-object-field-value?context=list&amp;field=fd_name&amp;objectId=12345&amp;code=sonata_admin_foo_service"
624
        data-source="[{value: 0, text: 'no'},{value: 1, text: 'yes'}]" >
625
        <span class="label label-danger">no</span> </span>
626
</td>
627
EOT
628
                ,
629
                'boolean',
630
                null,
631
                ['editable' => true],
632
            ],
633
            [
634
                '<td class="sonata-ba-list-field sonata-ba-list-field-trans" objectId="12345"> Delete </td>',
635
                'trans',
636
                'action_delete',
637
                ['catalogue' => 'SonataAdminBundle'],
638
            ],
639
            [
640
                '<td class="sonata-ba-list-field sonata-ba-list-field-trans" objectId="12345"> </td>',
641
                'trans',
642
                null,
643
                ['catalogue' => 'SonataAdminBundle'],
644
            ],
645
            [
646
                '<td class="sonata-ba-list-field sonata-ba-list-field-trans" objectId="12345"> Delete </td>',
647
                'trans',
648
                'action_delete',
649
                ['format' => '%s', 'catalogue' => 'SonataAdminBundle'],
650
            ],
651
            [
652
                '<td class="sonata-ba-list-field sonata-ba-list-field-trans" objectId="12345">
653
                action.action_delete
654
                </td>',
655
                'trans',
656
                'action_delete',
657
                ['format' => 'action.%s'],
658
            ],
659
            [
660
                '<td class="sonata-ba-list-field sonata-ba-list-field-trans" objectId="12345">
661
                action.action_delete
662
                </td>',
663
                'trans',
664
                'action_delete',
665
                ['format' => 'action.%s', 'catalogue' => 'SonataAdminBundle'],
666
            ],
667
            [
668
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345"> Status1 </td>',
669
                'choice',
670
                'Status1',
671
                [],
672
            ],
673
            [
674
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345"> Status1 </td>',
675
                'choice',
676
                ['Status1'],
677
                ['choices' => [], 'multiple' => true],
678
            ],
679
            [
680
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345"> Alias1 </td>',
681
                'choice',
682
                'Status1',
683
                ['choices' => ['Status1' => 'Alias1', 'Status2' => 'Alias2', 'Status3' => 'Alias3']],
684
            ],
685
            [
686
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345"> </td>',
687
                'choice',
688
                null,
689
                ['choices' => ['Status1' => 'Alias1', 'Status2' => 'Alias2', 'Status3' => 'Alias3']],
690
            ],
691
            [
692
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
693
                NoValidKeyInChoices
694
                </td>',
695
                'choice',
696
                'NoValidKeyInChoices',
697
                ['choices' => ['Status1' => 'Alias1', 'Status2' => 'Alias2', 'Status3' => 'Alias3']],
698
            ],
699
            [
700
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345"> Delete </td>',
701
                'choice',
702
                'Foo',
703
                ['catalogue' => 'SonataAdminBundle', 'choices' => [
704
                    'Foo' => 'action_delete',
705
                    'Status2' => 'Alias2',
706
                    'Status3' => 'Alias3',
707
                ]],
708
            ],
709
            [
710
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345"> Alias1, Alias3 </td>',
711
                'choice',
712
                ['Status1', 'Status3'],
713
                ['choices' => [
714
                    'Status1' => 'Alias1',
715
                    'Status2' => 'Alias2',
716
                    'Status3' => 'Alias3',
717
                ], 'multiple' => true], ],
718
            [
719
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345"> Alias1 | Alias3 </td>',
720
                'choice',
721
                ['Status1', 'Status3'],
722
                ['choices' => [
723
                    'Status1' => 'Alias1',
724
                    'Status2' => 'Alias2',
725
                    'Status3' => 'Alias3',
726
                ], 'multiple' => true, 'delimiter' => ' | '], ],
727
            [
728
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345"> </td>',
729
                'choice',
730
                null,
731
                ['choices' => [
732
                    'Status1' => 'Alias1',
733
                    'Status2' => 'Alias2',
734
                    'Status3' => 'Alias3',
735
                ], 'multiple' => true],
736
            ],
737
            [
738
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
739
                NoValidKeyInChoices
740
                </td>',
741
                'choice',
742
                ['NoValidKeyInChoices'],
743
                ['choices' => [
744
                    'Status1' => 'Alias1',
745
                    'Status2' => 'Alias2',
746
                    'Status3' => 'Alias3',
747
                ], 'multiple' => true],
748
            ],
749
            [
750
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
751
                NoValidKeyInChoices, Alias2
752
                </td>',
753
                'choice',
754
                ['NoValidKeyInChoices', 'Status2'],
755
                ['choices' => [
756
                    'Status1' => 'Alias1',
757
                    'Status2' => 'Alias2',
758
                    'Status3' => 'Alias3',
759
                ], 'multiple' => true],
760
            ],
761
            [
762
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345"> Delete, Alias3 </td>',
763
                'choice',
764
                ['Foo', 'Status3'],
765
                ['catalogue' => 'SonataAdminBundle', 'choices' => [
766
                    'Foo' => 'action_delete',
767
                    'Status2' => 'Alias2',
768
                    'Status3' => 'Alias3',
769
                ], 'multiple' => true],
770
            ],
771
            [
772
                '<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
773
                &lt;b&gt;Alias1&lt;/b&gt;, &lt;b&gt;Alias3&lt;/b&gt;
774
            </td>',
775
                'choice',
776
                ['Status1', 'Status3'],
777
                ['choices' => [
778
                    'Status1' => '<b>Alias1</b>',
779
                    'Status2' => '<b>Alias2</b>',
780
                    'Status3' => '<b>Alias3</b>',
781
                ], 'multiple' => true], ],
782
            [
783
                <<<'EOT'
784
<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
785
    <span
786
        class="x-editable"
787
        data-type="select"
788
        data-value="Status1"
789
        data-title="Data"
790
        data-pk="12345"
791
        data-url="/core/set-object-field-value?context=list&amp;field=fd_name&amp;objectId=12345&amp;code=sonata_admin_foo_service"
792
        data-source="[]"
793
    >
794
        Status1
795
    </span>
796
</td>
797
EOT
798
                ,
799
                'choice',
800
                'Status1',
801
                ['editable' => true],
802
            ],
803
            [
804
                <<<'EOT'
805
<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
806
    <span
807
        class="x-editable"
808
        data-type="select"
809
        data-value="Status1"
810
        data-title="Data"
811
        data-pk="12345"
812
        data-url="/core/set-object-field-value?context=list&amp;field=fd_name&amp;objectId=12345&amp;code=sonata_admin_foo_service"
813
        data-source="[{&quot;value&quot;:&quot;Status1&quot;,&quot;text&quot;:&quot;Alias1&quot;},{&quot;value&quot;:&quot;Status2&quot;,&quot;text&quot;:&quot;Alias2&quot;},{&quot;value&quot;:&quot;Status3&quot;,&quot;text&quot;:&quot;Alias3&quot;}]" >
814
        Alias1 </span>
815
</td>
816
EOT
817
                ,
818
                'choice',
819
                'Status1',
820
                [
821
                    'editable' => true,
822
                    'choices' => [
823
                        'Status1' => 'Alias1',
824
                        'Status2' => 'Alias2',
825
                        'Status3' => 'Alias3',
826
                    ],
827
                ],
828
            ],
829
            [
830
                <<<'EOT'
831
<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
832
    <span
833
        class="x-editable"
834
        data-type="select"
835
        data-value=""
836
        data-title="Data"
837
        data-pk="12345"
838
        data-url="/core/set-object-field-value?context=list&amp;field=fd_name&amp;objectId=12345&amp;code=sonata_admin_foo_service"
839
        data-source="[{&quot;value&quot;:&quot;Status1&quot;,&quot;text&quot;:&quot;Alias1&quot;},{&quot;value&quot;:&quot;Status2&quot;,&quot;text&quot;:&quot;Alias2&quot;},{&quot;value&quot;:&quot;Status3&quot;,&quot;text&quot;:&quot;Alias3&quot;}]" >
840
841
    </span>
842
</td>
843
EOT
844
                ,
845
                'choice',
846
                null,
847
                [
848
                    'editable' => true,
849
                    'choices' => [
850
                        'Status1' => 'Alias1',
851
                        'Status2' => 'Alias2',
852
                        'Status3' => 'Alias3',
853
                    ],
854
                ],
855
            ],
856
            [
857
                <<<'EOT'
858
<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
859
    <span
860
        class="x-editable"
861
        data-type="select"
862
        data-value="NoValidKeyInChoices"
863
        data-title="Data" data-pk="12345"
864
        data-url="/core/set-object-field-value?context=list&amp;field=fd_name&amp;objectId=12345&amp;code=sonata_admin_foo_service"
865
        data-source="[{&quot;value&quot;:&quot;Status1&quot;,&quot;text&quot;:&quot;Alias1&quot;},{&quot;value&quot;:&quot;Status2&quot;,&quot;text&quot;:&quot;Alias2&quot;},{&quot;value&quot;:&quot;Status3&quot;,&quot;text&quot;:&quot;Alias3&quot;}]" >
866
        NoValidKeyInChoices
867
    </span>
868
</td>
869
EOT
870
                ,
871
                'choice',
872
                'NoValidKeyInChoices',
873
                [
874
                    'editable' => true,
875
                    'choices' => [
876
                        'Status1' => 'Alias1',
877
                        'Status2' => 'Alias2',
878
                        'Status3' => 'Alias3',
879
                    ],
880
                ],
881
            ],
882
            [
883
                <<<'EOT'
884
<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
885
    <span
886
        class="x-editable"
887
        data-type="select"
888
        data-value="Foo"
889
        data-title="Data"
890
        data-pk="12345"
891
        data-url="/core/set-object-field-value?context=list&amp;field=fd_name&amp;objectId=12345&amp;code=sonata_admin_foo_service"
892
        data-source="[{&quot;value&quot;:&quot;Foo&quot;,&quot;text&quot;:&quot;Delete&quot;},{&quot;value&quot;:&quot;Status2&quot;,&quot;text&quot;:&quot;Alias2&quot;},{&quot;value&quot;:&quot;Status3&quot;,&quot;text&quot;:&quot;Alias3&quot;}]" >
893
         Delete
894
    </span>
895
</td>
896
EOT
897
                ,
898
                'choice',
899
                'Foo',
900
                [
901
                    'editable' => true,
902
                    'catalogue' => 'SonataAdminBundle',
903
                    'choices' => [
904
                        'Foo' => 'action_delete',
905
                        'Status2' => 'Alias2',
906
                        'Status3' => 'Alias3',
907
                    ],
908
                ],
909
            ],
910
            [
911
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345"> &nbsp; </td>',
912
                'url',
913
                null,
914
                [],
915
            ],
916
            [
917
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345"> &nbsp; </td>',
918
                'url',
919
                null,
920
                ['url' => 'http://example.com'],
921
            ],
922
            [
923
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345"> &nbsp; </td>',
924
                'url',
925
                null,
926
                ['route' => ['name' => 'sonata_admin_foo']],
927
            ],
928
            [
929
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
930
                <a href="http://example.com">http://example.com</a>
931
                </td>',
932
                'url',
933
                'http://example.com',
934
                [],
935
            ],
936
            [
937
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
938
                <a href="https://example.com">https://example.com</a>
939
                </td>',
940
                'url',
941
                'https://example.com',
942
                [],
943
            ],
944
            [
945
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
946
                <a href="https://example.com" target="_blank">https://example.com</a>
947
                </td>',
948
                'url',
949
                'https://example.com',
950
                ['attributes' => ['target' => '_blank']],
951
            ],
952
            [
953
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
954
                <a href="https://example.com" target="_blank" class="fooLink">https://example.com</a>
955
                </td>',
956
                'url',
957
                'https://example.com',
958
                ['attributes' => ['target' => '_blank', 'class' => 'fooLink']],
959
            ],
960
            [
961
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
962
                <a href="http://example.com">example.com</a>
963
                </td>',
964
                'url',
965
                'http://example.com',
966
                ['hide_protocol' => true],
967
            ],
968
            [
969
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
970
                <a href="https://example.com">example.com</a>
971
                </td>',
972
                'url',
973
                'https://example.com',
974
                ['hide_protocol' => true],
975
            ],
976
            [
977
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
978
                <a href="http://example.com">http://example.com</a>
979
                </td>',
980
                'url',
981
                'http://example.com',
982
                ['hide_protocol' => false],
983
            ],
984
            [
985
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
986
                <a href="https://example.com">https://example.com</a>
987
                </td>',
988
                'url',
989
                'https://example.com',
990
                ['hide_protocol' => false],
991
            ],
992
            [
993
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
994
                <a href="http://example.com">Foo</a>
995
                </td>',
996
                'url',
997
                'Foo',
998
                ['url' => 'http://example.com'],
999
            ],
1000
            [
1001
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
1002
                <a href="http://example.com">&lt;b&gt;Foo&lt;/b&gt;</a>
1003
                </td>',
1004
                'url',
1005
                '<b>Foo</b>',
1006
                ['url' => 'http://example.com'],
1007
            ],
1008
            [
1009
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
1010
                <a href="/foo">Foo</a>
1011
                </td>',
1012
                'url',
1013
                'Foo',
1014
                ['route' => ['name' => 'sonata_admin_foo']],
1015
            ],
1016
            [
1017
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
1018
                <a href="http://localhost/foo">Foo</a>
1019
                </td>',
1020
                'url',
1021
                'Foo',
1022
                ['route' => ['name' => 'sonata_admin_foo', 'absolute' => true]],
1023
            ],
1024
            [
1025
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
1026
                <a href="/foo">foo/bar?a=b&amp;c=123456789</a>
1027
                </td>',
1028
                'url',
1029
                'http://foo/bar?a=b&c=123456789',
1030
                ['route' => ['name' => 'sonata_admin_foo'],
1031
                'hide_protocol' => true, ],
1032
            ],
1033
            [
1034
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
1035
                <a href="http://localhost/foo">foo/bar?a=b&amp;c=123456789</a>
1036
                </td>',
1037
                'url',
1038
                'http://foo/bar?a=b&c=123456789',
1039
                [
1040
                    'route' => ['name' => 'sonata_admin_foo', 'absolute' => true],
1041
                    'hide_protocol' => true,
1042
                ],
1043
            ],
1044
            [
1045
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
1046
                <a href="/foo/abcd/efgh?param3=ijkl">Foo</a>
1047
                </td>',
1048
                'url',
1049
                'Foo',
1050
                [
1051
                    'route' => ['name' => 'sonata_admin_foo_param',
1052
                    'parameters' => ['param1' => 'abcd', 'param2' => 'efgh', 'param3' => 'ijkl'], ],
1053
                ],
1054
            ],
1055
            [
1056
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
1057
                <a href="http://localhost/foo/abcd/efgh?param3=ijkl">Foo</a>
1058
                </td>',
1059
                'url',
1060
                'Foo',
1061
                [
1062
                    'route' => ['name' => 'sonata_admin_foo_param',
1063
                    'absolute' => true,
1064
                    'parameters' => ['param1' => 'abcd', 'param2' => 'efgh', 'param3' => 'ijkl'], ],
1065
                ],
1066
            ],
1067
            [
1068
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
1069
                <a href="/foo/obj/abcd/12345/efgh?param3=ijkl">Foo</a>
1070
                </td>',
1071
                'url',
1072
                'Foo',
1073
                [
1074
                    'route' => ['name' => 'sonata_admin_foo_object',
1075
                    'parameters' => ['param1' => 'abcd', 'param2' => 'efgh', 'param3' => 'ijkl'],
1076
                    'identifier_parameter_name' => 'barId', ],
1077
                ],
1078
            ],
1079
            [
1080
                '<td class="sonata-ba-list-field sonata-ba-list-field-url" objectId="12345">
1081
                <a href="http://localhost/foo/obj/abcd/12345/efgh?param3=ijkl">Foo</a>
1082
                </td>',
1083
                'url',
1084
                'Foo',
1085
                [
1086
                    'route' => ['name' => 'sonata_admin_foo_object',
1087
                    'absolute' => true,
1088
                    'parameters' => ['param1' => 'abcd', 'param2' => 'efgh', 'param3' => 'ijkl'],
1089
                    'identifier_parameter_name' => 'barId', ],
1090
                ],
1091
            ],
1092
            [
1093
                '<td class="sonata-ba-list-field sonata-ba-list-field-html" objectId="12345">
1094
                <p><strong>Creating a Template for the Field</strong> and form</p>
1095
                </td>',
1096
                'html',
1097
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1098
                [],
1099
            ],
1100
            [
1101
                '<td class="sonata-ba-list-field sonata-ba-list-field-html" objectId="12345">
1102
                Creating a Template for the Field and form
1103
                </td>',
1104
                'html',
1105
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1106
                ['strip' => true],
1107
            ],
1108
            [
1109
                '<td class="sonata-ba-list-field sonata-ba-list-field-html" objectId="12345">
1110
                Creating a Template for the...
1111
                </td>',
1112
                'html',
1113
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1114
                ['truncate' => true],
1115
            ],
1116
            [
1117
                '<td class="sonata-ba-list-field sonata-ba-list-field-html" objectId="12345"> Creatin... </td>',
1118
                'html',
1119
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1120
                ['truncate' => ['length' => 10]],
1121
            ],
1122
            [
1123
                '<td class="sonata-ba-list-field sonata-ba-list-field-html" objectId="12345">
1124
                Creating a Template for the Field...
1125
                </td>',
1126
                'html',
1127
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1128
                ['truncate' => ['cut' => false]],
1129
            ],
1130
            [
1131
                '<td class="sonata-ba-list-field sonata-ba-list-field-html" objectId="12345">
1132
                Creating a Template for t etc.
1133
                </td>',
1134
                'html',
1135
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1136
                ['truncate' => ['ellipsis' => ' etc.']],
1137
            ],
1138
            [
1139
                '<td class="sonata-ba-list-field sonata-ba-list-field-html" objectId="12345">
1140
                Creating a Template[...]
1141
                </td>',
1142
                'html',
1143
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1144
                [
1145
                    'truncate' => [
1146
                        'length' => 20,
1147
                        'cut' => false,
1148
                        'ellipsis' => '[...]',
1149
                    ],
1150
                ],
1151
            ],
1152
1153
            [
1154
                <<<'EOT'
1155
<td class="sonata-ba-list-field sonata-ba-list-field-text" objectId="12345">
1156
<div
1157
    class="sonata-readmore"
1158
    data-readmore-height="40"
1159
    data-readmore-more="Read more"
1160
    data-readmore-less="Close">A very long string</div>
1161
</td>
1162
EOT
1163
                ,
1164
                'text',
1165
                'A very long string',
1166
                [
1167
                    'collapse' => true,
1168
                ],
1169
            ],
1170
            [
1171
                <<<'EOT'
1172
<td class="sonata-ba-list-field sonata-ba-list-field-text" objectId="12345">
1173
<div
1174
    class="sonata-readmore"
1175
    data-readmore-height="10"
1176
    data-readmore-more="More"
1177
    data-readmore-less="Less">A very long string</div>
1178
</td>
1179
EOT
1180
                ,
1181
                'text',
1182
                'A very long string',
1183
                [
1184
                    'collapse' => [
1185
                        'height' => 10,
1186
                        'more' => 'More',
1187
                        'less' => 'Less',
1188
                    ],
1189
                ],
1190
            ],
1191
            [
1192
                <<<'EOT'
1193
<td class="sonata-ba-list-field sonata-ba-list-field-choice" objectId="12345">
1194
    <span
1195
        class="x-editable"
1196
        data-type="checklist"
1197
        data-value="[&quot;Status1&quot;,&quot;Status2&quot;]"
1198
        data-title="Data"
1199
        data-pk="12345"
1200
        data-url="/core/set-object-field-value?context=list&amp;field=fd_name&amp;objectId=12345&amp;code=sonata_admin_foo_service"
1201
        data-source="[{&quot;value&quot;:&quot;Status1&quot;,&quot;text&quot;:&quot;Delete&quot;},{&quot;value&quot;:&quot;Status2&quot;,&quot;text&quot;:&quot;Alias2&quot;},{&quot;value&quot;:&quot;Status3&quot;,&quot;text&quot;:&quot;Alias3&quot;}]" >
1202
         Delete, Alias2
1203
    </span>
1204
</td>
1205
EOT
1206
                ,
1207
                'choice',
1208
                [
1209
                    'Status1',
1210
                    'Status2',
1211
                ],
1212
                [
1213
                    'editable' => true,
1214
                    'multiple' => true,
1215
                    'catalogue' => 'SonataAdminBundle',
1216
                    'choices' => [
1217
                        'Status1' => 'action_delete',
1218
                        'Status2' => 'Alias2',
1219
                        'Status3' => 'Alias3',
1220
                    ],
1221
                ],
1222
            ],
1223
        ];
1224
    }
1225
1226
    /**
1227
     * @dataProvider getRenderViewElementTests
1228
     */
1229
    public function testRenderViewElement(string $expected, string $type, $value, array $options): void
1230
    {
1231
        $this->fieldDescription
0 ignored issues
show
The method method() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
1232
            ->method('getValue')
1233
            ->willReturn($value);
1234
1235
        $this->fieldDescription
0 ignored issues
show
The method method() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
1236
            ->method('getType')
1237
            ->willReturn($type);
1238
1239
        $this->fieldDescription
0 ignored issues
show
The method method() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
1240
            ->method('getOptions')
1241
            ->willReturn($options);
1242
1243
        $this->fieldDescription
0 ignored issues
show
The method method() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
1244
            ->method('getTemplate')
1245
            ->willReturnCallback(static function () use ($type): ?string {
1246
                switch ($type) {
1247
                    case 'boolean':
1248
                        return '@SonataAdmin/CRUD/show_boolean.html.twig';
1249
                    case 'datetime':
1250
                        return '@SonataAdmin/CRUD/show_datetime.html.twig';
1251
                    case 'date':
1252
                        return '@SonataAdmin/CRUD/show_date.html.twig';
1253
                    case 'time':
1254
                        return '@SonataAdmin/CRUD/show_time.html.twig';
1255
                    case 'currency':
1256
                        return '@SonataAdmin/CRUD/show_currency.html.twig';
1257
                    case 'percent':
1258
                        return '@SonataAdmin/CRUD/show_percent.html.twig';
1259
                    case 'email':
1260
                        return '@SonataAdmin/CRUD/show_email.html.twig';
1261
                    case 'choice':
1262
                        return '@SonataAdmin/CRUD/show_choice.html.twig';
1263
                    case 'array':
1264
                        return '@SonataAdmin/CRUD/show_array.html.twig';
1265
                    case 'trans':
1266
                        return '@SonataAdmin/CRUD/show_trans.html.twig';
1267
                    case 'url':
1268
                        return '@SonataAdmin/CRUD/show_url.html.twig';
1269
                    case 'html':
1270
                        return '@SonataAdmin/CRUD/show_html.html.twig';
1271
                    default:
1272
                        return null;
1273
                }
1274
            });
1275
1276
        $this->assertSame(
1277
            $this->removeExtraWhitespace($expected),
1278
            $this->removeExtraWhitespace(
1279
                $this->twigExtension->renderViewElement(
1280
                    $this->environment,
1281
                    $this->fieldDescription,
1282
                    $this->object
1283
                )
1284
            )
1285
        );
1286
    }
1287
1288
    public function getRenderViewElementTests()
1289
    {
1290
        return [
1291
            ['<th>Data</th> <td>Example</td>', 'string', 'Example', ['safe' => false]],
1292
            ['<th>Data</th> <td>Example</td>', 'text', 'Example', ['safe' => false]],
1293
            ['<th>Data</th> <td>Example</td>', 'textarea', 'Example', ['safe' => false]],
1294
            [
1295
                '<th>Data</th> <td><time datetime="2013-12-24T10:11:12+00:00" title="2013-12-24T10:11:12+00:00"> December 24, 2013 10:11 </time></td>',
1296
                'datetime',
1297
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')), [],
1298
            ],
1299
            [
1300
                '<th>Data</th> <td><time datetime="2013-12-24T10:11:12+00:00" title="2013-12-24T10:11:12+00:00"> 24.12.2013 10:11:12 </time></td>',
1301
                'datetime',
1302
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')),
1303
                ['format' => 'd.m.Y H:i:s'],
1304
            ],
1305
            [
1306
                '<th>Data</th> <td><time datetime="2013-12-24T10:11:12+00:00" title="2013-12-24T10:11:12+00:00"> December 24, 2013 18:11 </time></td>',
1307
                'datetime',
1308
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('UTC')),
1309
                ['timezone' => 'Asia/Hong_Kong'],
1310
            ],
1311
            [
1312
                '<th>Data</th> <td><time datetime="2013-12-24" title="2013-12-24"> December 24, 2013 </time></td>',
1313
                'date',
1314
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')),
1315
                [],
1316
            ],
1317
            [
1318
                '<th>Data</th> <td><time datetime="2013-12-24" title="2013-12-24"> 24.12.2013 </time></td>',
1319
                'date',
1320
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')),
1321
                ['format' => 'd.m.Y'],
1322
            ],
1323
            [
1324
                '<th>Data</th> <td><time datetime="10:11:12+00:00" title="10:11:12+00:00"> 10:11:12 </time></td>',
1325
                'time',
1326
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('Europe/London')),
1327
                [],
1328
            ],
1329
            [
1330
                '<th>Data</th> <td><time datetime="10:11:12+00:00" title="10:11:12+00:00"> 18:11:12 </time></td>',
1331
                'time',
1332
                new \DateTime('2013-12-24 10:11:12', new \DateTimeZone('UTC')),
1333
                ['timezone' => 'Asia/Hong_Kong'],
1334
            ],
1335
            ['<th>Data</th> <td>10.746135</td>', 'number', 10.746135, ['safe' => false]],
1336
            ['<th>Data</th> <td>5678</td>', 'integer', 5678, ['safe' => false]],
1337
            ['<th>Data</th> <td> 1074.6135 % </td>', 'percent', 10.746135, []],
1338
            ['<th>Data</th> <td> EUR 10.746135 </td>', 'currency', 10.746135, ['currency' => 'EUR']],
1339
            ['<th>Data</th> <td> GBP 51.23456 </td>', 'currency', 51.23456, ['currency' => 'GBP']],
1340
            [
1341
                '<th>Data</th> <td> <ul><li>1&nbsp;=>&nbsp;First</li><li>2&nbsp;=>&nbsp;Second</li></ul> </td>',
1342
                'array',
1343
                [1 => 'First', 2 => 'Second'],
1344
                ['safe' => false],
1345
            ],
1346
            [
1347
                '<th>Data</th> <td> [1&nbsp;=>&nbsp;First, 2&nbsp;=>&nbsp;Second] </td>',
1348
                'array',
1349
                [1 => 'First', 2 => 'Second'],
1350
                ['safe' => false, 'inline' => true],
1351
            ],
1352
            [
1353
                '<th>Data</th> <td><span class="label label-success">yes</span></td>',
1354
                'boolean',
1355
                true,
1356
                [],
1357
            ],
1358
            [
1359
                '<th>Data</th> <td><span class="label label-danger">yes</span></td>',
1360
                'boolean',
1361
                true,
1362
                ['inverse' => true],
1363
            ],
1364
            ['<th>Data</th> <td><span class="label label-danger">no</span></td>', 'boolean', false, []],
1365
            [
1366
                '<th>Data</th> <td><span class="label label-success">no</span></td>',
1367
                'boolean',
1368
                false,
1369
                ['inverse' => true],
1370
            ],
1371
            [
1372
                '<th>Data</th> <td> Delete </td>',
1373
                'trans',
1374
                'action_delete',
1375
                ['safe' => false, 'catalogue' => 'SonataAdminBundle'],
1376
            ],
1377
            [
1378
                '<th>Data</th> <td> Delete </td>',
1379
                'trans',
1380
                'delete',
1381
                ['safe' => false, 'catalogue' => 'SonataAdminBundle', 'format' => 'action_%s'],
1382
            ],
1383
            ['<th>Data</th> <td>Status1</td>', 'choice', 'Status1', ['safe' => false]],
1384
            [
1385
                '<th>Data</th> <td>Alias1</td>',
1386
                'choice',
1387
                'Status1',
1388
                ['safe' => false, 'choices' => [
1389
                    'Status1' => 'Alias1',
1390
                    'Status2' => 'Alias2',
1391
                    'Status3' => 'Alias3',
1392
                ]],
1393
            ],
1394
            [
1395
                '<th>Data</th> <td>NoValidKeyInChoices</td>',
1396
                'choice',
1397
                'NoValidKeyInChoices',
1398
                ['safe' => false, 'choices' => [
1399
                    'Status1' => 'Alias1',
1400
                    'Status2' => 'Alias2',
1401
                    'Status3' => 'Alias3',
1402
                ]],
1403
            ],
1404
            [
1405
                '<th>Data</th> <td>Delete</td>',
1406
                'choice',
1407
                'Foo',
1408
                ['safe' => false, 'catalogue' => 'SonataAdminBundle', 'choices' => [
1409
                    'Foo' => 'action_delete',
1410
                    'Status2' => 'Alias2',
1411
                    'Status3' => 'Alias3',
1412
                ]],
1413
            ],
1414
            [
1415
                '<th>Data</th> <td>NoValidKeyInChoices</td>',
1416
                'choice',
1417
                ['NoValidKeyInChoices'],
1418
                ['safe' => false, 'choices' => [
1419
                    'Status1' => 'Alias1',
1420
                    'Status2' => 'Alias2',
1421
                    'Status3' => 'Alias3',
1422
                ], 'multiple' => true],
1423
            ],
1424
            [
1425
                '<th>Data</th> <td>NoValidKeyInChoices, Alias2</td>',
1426
                'choice',
1427
                ['NoValidKeyInChoices', 'Status2'],
1428
                ['safe' => false, 'choices' => [
1429
                    'Status1' => 'Alias1',
1430
                    'Status2' => 'Alias2',
1431
                    'Status3' => 'Alias3',
1432
                ], 'multiple' => true],
1433
            ],
1434
            [
1435
                '<th>Data</th> <td>Alias1, Alias3</td>',
1436
                'choice',
1437
                ['Status1', 'Status3'],
1438
                ['safe' => false, 'choices' => [
1439
                    'Status1' => 'Alias1',
1440
                    'Status2' => 'Alias2',
1441
                    'Status3' => 'Alias3',
1442
                ], 'multiple' => true],
1443
            ],
1444
            [
1445
                '<th>Data</th> <td>Alias1 | Alias3</td>',
1446
                'choice',
1447
                ['Status1', 'Status3'], ['safe' => false, 'choices' => [
1448
                    'Status1' => 'Alias1',
1449
                    'Status2' => 'Alias2',
1450
                    'Status3' => 'Alias3',
1451
                ], 'multiple' => true, 'delimiter' => ' | '],
1452
            ],
1453
            [
1454
                '<th>Data</th> <td>Delete, Alias3</td>',
1455
                'choice',
1456
                ['Foo', 'Status3'],
1457
                ['safe' => false, 'catalogue' => 'SonataAdminBundle', 'choices' => [
1458
                    'Foo' => 'action_delete',
1459
                    'Status2' => 'Alias2',
1460
                    'Status3' => 'Alias3',
1461
                ], 'multiple' => true],
1462
            ],
1463
            [
1464
                '<th>Data</th> <td><b>Alias1</b>, <b>Alias3</b></td>',
1465
                'choice',
1466
                ['Status1', 'Status3'],
1467
                ['safe' => true, 'choices' => [
1468
                    'Status1' => '<b>Alias1</b>',
1469
                    'Status2' => '<b>Alias2</b>',
1470
                    'Status3' => '<b>Alias3</b>',
1471
                ], 'multiple' => true],
1472
            ],
1473
            [
1474
                '<th>Data</th> <td>&lt;b&gt;Alias1&lt;/b&gt;, &lt;b&gt;Alias3&lt;/b&gt;</td>',
1475
                'choice',
1476
                ['Status1', 'Status3'],
1477
                ['safe' => false, 'choices' => [
1478
                    'Status1' => '<b>Alias1</b>',
1479
                    'Status2' => '<b>Alias2</b>',
1480
                    'Status3' => '<b>Alias3</b>',
1481
                ], 'multiple' => true],
1482
            ],
1483
            [
1484
                '<th>Data</th> <td><a href="http://example.com">http://example.com</a></td>',
1485
                'url',
1486
                'http://example.com',
1487
                ['safe' => false],
1488
            ],
1489
            [
1490
                '<th>Data</th> <td><a href="http://example.com" target="_blank">http://example.com</a></td>',
1491
                'url',
1492
                'http://example.com',
1493
                ['safe' => false, 'attributes' => ['target' => '_blank']],
1494
            ],
1495
            [
1496
                '<th>Data</th> <td><a href="http://example.com" target="_blank" class="fooLink">http://example.com</a></td>',
1497
                'url',
1498
                'http://example.com',
1499
                ['safe' => false, 'attributes' => ['target' => '_blank', 'class' => 'fooLink']],
1500
            ],
1501
            [
1502
                '<th>Data</th> <td><a href="https://example.com">https://example.com</a></td>',
1503
                'url',
1504
                'https://example.com',
1505
                ['safe' => false],
1506
            ],
1507
            [
1508
                '<th>Data</th> <td><a href="http://example.com">example.com</a></td>',
1509
                'url',
1510
                'http://example.com',
1511
                ['safe' => false, 'hide_protocol' => true],
1512
            ],
1513
            [
1514
                '<th>Data</th> <td><a href="https://example.com">example.com</a></td>',
1515
                'url',
1516
                'https://example.com',
1517
                ['safe' => false, 'hide_protocol' => true],
1518
            ],
1519
            [
1520
                '<th>Data</th> <td><a href="http://example.com">http://example.com</a></td>',
1521
                'url',
1522
                'http://example.com',
1523
                ['safe' => false, 'hide_protocol' => false],
1524
            ],
1525
            [
1526
                '<th>Data</th> <td><a href="https://example.com">https://example.com</a></td>',
1527
                'url',
1528
                'https://example.com',
1529
                ['safe' => false,
1530
                'hide_protocol' => false, ],
1531
            ],
1532
            [
1533
                '<th>Data</th> <td><a href="http://example.com">Foo</a></td>',
1534
                'url',
1535
                'Foo',
1536
                ['safe' => false, 'url' => 'http://example.com'],
1537
            ],
1538
            [
1539
                '<th>Data</th> <td><a href="http://example.com">&lt;b&gt;Foo&lt;/b&gt;</a></td>',
1540
                'url',
1541
                '<b>Foo</b>',
1542
                ['safe' => false, 'url' => 'http://example.com'],
1543
            ],
1544
            [
1545
                '<th>Data</th> <td><a href="http://example.com"><b>Foo</b></a></td>',
1546
                'url',
1547
                '<b>Foo</b>',
1548
                ['safe' => true, 'url' => 'http://example.com'],
1549
            ],
1550
            [
1551
                '<th>Data</th> <td><a href="/foo">Foo</a></td>',
1552
                'url',
1553
                'Foo',
1554
                ['safe' => false, 'route' => ['name' => 'sonata_admin_foo']],
1555
            ],
1556
            [
1557
                '<th>Data</th> <td><a href="http://localhost/foo">Foo</a></td>',
1558
                'url',
1559
                'Foo',
1560
                ['safe' => false, 'route' => [
1561
                    'name' => 'sonata_admin_foo',
1562
                    'absolute' => true,
1563
                ]],
1564
            ],
1565
            [
1566
                '<th>Data</th> <td><a href="/foo">foo/bar?a=b&amp;c=123456789</a></td>',
1567
                'url',
1568
                'http://foo/bar?a=b&c=123456789',
1569
                [
1570
                    'safe' => false,
1571
                    'route' => ['name' => 'sonata_admin_foo'],
1572
                    'hide_protocol' => true,
1573
                ],
1574
            ],
1575
            [
1576
                '<th>Data</th> <td><a href="http://localhost/foo">foo/bar?a=b&amp;c=123456789</a></td>',
1577
                'url',
1578
                'http://foo/bar?a=b&c=123456789',
1579
                ['safe' => false, 'route' => [
1580
                    'name' => 'sonata_admin_foo',
1581
                    'absolute' => true,
1582
                ], 'hide_protocol' => true],
1583
            ],
1584
            [
1585
                '<th>Data</th> <td><a href="/foo/abcd/efgh?param3=ijkl">Foo</a></td>',
1586
                'url',
1587
                'Foo',
1588
                ['safe' => false, 'route' => [
1589
                    'name' => 'sonata_admin_foo_param',
1590
                    'parameters' => ['param1' => 'abcd', 'param2' => 'efgh', 'param3' => 'ijkl'],
1591
                ]],
1592
            ],
1593
            [
1594
                '<th>Data</th> <td><a href="http://localhost/foo/abcd/efgh?param3=ijkl">Foo</a></td>',
1595
                'url',
1596
                'Foo',
1597
                ['safe' => false, 'route' => [
1598
                    'name' => 'sonata_admin_foo_param',
1599
                    'absolute' => true,
1600
                    'parameters' => [
1601
                        'param1' => 'abcd',
1602
                        'param2' => 'efgh',
1603
                        'param3' => 'ijkl',
1604
                    ],
1605
                ]],
1606
            ],
1607
            [
1608
                '<th>Data</th> <td><a href="/foo/obj/abcd/12345/efgh?param3=ijkl">Foo</a></td>',
1609
                'url',
1610
                'Foo',
1611
                ['safe' => false, 'route' => [
1612
                    'name' => 'sonata_admin_foo_object',
1613
                    'parameters' => [
1614
                        'param1' => 'abcd',
1615
                        'param2' => 'efgh',
1616
                        'param3' => 'ijkl',
1617
                    ],
1618
                    'identifier_parameter_name' => 'barId',
1619
                ]],
1620
            ],
1621
            [
1622
                '<th>Data</th> <td><a href="http://localhost/foo/obj/abcd/12345/efgh?param3=ijkl">Foo</a></td>',
1623
                'url',
1624
                'Foo',
1625
                ['safe' => false, 'route' => [
1626
                    'name' => 'sonata_admin_foo_object',
1627
                    'absolute' => true,
1628
                    'parameters' => [
1629
                        'param1' => 'abcd',
1630
                        'param2' => 'efgh',
1631
                        'param3' => 'ijkl',
1632
                    ],
1633
                    'identifier_parameter_name' => 'barId',
1634
                ]],
1635
            ],
1636
            [
1637
                '<th>Data</th> <td> &nbsp;</td>',
1638
                'email',
1639
                null,
1640
                [],
1641
            ],
1642
            [
1643
                '<th>Data</th> <td> <a href="mailto:[email protected]">[email protected]</a></td>',
1644
                'email',
1645
                '[email protected]',
1646
                [],
1647
            ],
1648
            [
1649
                '<th>Data</th> <td> <a href="mailto:[email protected]?'.$this->buildTwigLikeUrl(['subject' => 'Main Theme', 'body' => 'Message Body']).'">[email protected]</a></td>',
1650
                'email',
1651
                '[email protected]',
1652
                ['subject' => 'Main Theme', 'body' => 'Message Body'],
1653
            ],
1654
            [
1655
                '<th>Data</th> <td> <a href="mailto:[email protected]?'.$this->buildTwigLikeUrl(['subject' => 'Main Theme']).'">[email protected]</a></td>',
1656
                'email',
1657
                '[email protected]',
1658
                ['subject' => 'Main Theme'],
1659
            ],
1660
            [
1661
                '<th>Data</th> <td> <a href="mailto:[email protected]?'.$this->buildTwigLikeUrl(['body' => 'Message Body']).'">[email protected]</a></td>',
1662
                'email',
1663
                '[email protected]',
1664
                ['body' => 'Message Body'],
1665
            ],
1666
            [
1667
                '<th>Data</th> <td> [email protected]</td>',
1668
                'email',
1669
                '[email protected]',
1670
                ['as_string' => true, 'subject' => 'Main Theme', 'body' => 'Message Body'],
1671
            ],
1672
            [
1673
                '<th>Data</th> <td> [email protected]</td>',
1674
                'email',
1675
                '[email protected]',
1676
                ['as_string' => true, 'subject' => 'Main Theme'],
1677
            ],
1678
            [
1679
                '<th>Data</th> <td> [email protected]</td>',
1680
                'email',
1681
                '[email protected]',
1682
                ['as_string' => true, 'body' => 'Message Body'],
1683
            ],
1684
            [
1685
                '<th>Data</th> <td> <a href="mailto:[email protected]">[email protected]</a></td>',
1686
                'email',
1687
                '[email protected]',
1688
                ['as_string' => false],
1689
            ],
1690
            [
1691
                '<th>Data</th> <td> [email protected]</td>',
1692
                'email',
1693
                '[email protected]',
1694
                ['as_string' => true],
1695
            ],
1696
            [
1697
                '<th>Data</th> <td><p><strong>Creating a Template for the Field</strong> and form</p> </td>',
1698
                'html',
1699
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1700
                [],
1701
            ],
1702
            [
1703
                '<th>Data</th> <td>Creating a Template for the Field and form </td>',
1704
                'html',
1705
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1706
                ['strip' => true],
1707
            ],
1708
            [
1709
                '<th>Data</th> <td> Creating a Template for the... </td>',
1710
                'html',
1711
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1712
                ['truncate' => true],
1713
            ],
1714
            [
1715
                '<th>Data</th> <td> Creatin... </td>',
1716
                'html',
1717
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1718
                ['truncate' => ['length' => 10]],
1719
            ],
1720
            [
1721
                '<th>Data</th> <td> Creating a Template for the Field... </td>',
1722
                'html',
1723
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1724
                ['truncate' => ['cut' => false]],
1725
            ],
1726
            [
1727
                '<th>Data</th> <td> Creating a Template for t etc. </td>',
1728
                'html',
1729
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1730
                ['truncate' => ['ellipsis' => ' etc.']],
1731
            ],
1732
            [
1733
                '<th>Data</th> <td> Creating a Template[...] </td>',
1734
                'html',
1735
                '<p><strong>Creating a Template for the Field</strong> and form</p>',
1736
                [
1737
                    'truncate' => [
1738
                        'length' => 20,
1739
                        'cut' => false,
1740
                        'ellipsis' => '[...]',
1741
                    ],
1742
                ],
1743
            ],
1744
            [
1745
                <<<'EOT'
1746
<th>Data</th> <td><div
1747
        class="sonata-readmore"
1748
        data-readmore-height="40"
1749
        data-readmore-more="Read more"
1750
        data-readmore-less="Close">
1751
            A very long string
1752
</div></td>
1753
EOT
1754
                ,
1755
                'text',
1756
                ' A very long string ',
1757
                [
1758
                    'collapse' => true,
1759
                    'safe' => false,
1760
                ],
1761
            ],
1762
            [
1763
                <<<'EOT'
1764
<th>Data</th> <td><div
1765
        class="sonata-readmore"
1766
        data-readmore-height="10"
1767
        data-readmore-more="More"
1768
        data-readmore-less="Less">
1769
            A very long string
1770
</div></td>
1771
EOT
1772
                ,
1773
                'text',
1774
                ' A very long string ',
1775
                [
1776
                    'collapse' => [
1777
                        'height' => 10,
1778
                        'more' => 'More',
1779
                        'less' => 'Less',
1780
                    ],
1781
                    'safe' => false,
1782
                ],
1783
            ],
1784
        ];
1785
    }
1786
1787
    public function getRenderViewElementWithNoValueTests(): iterable
1788
    {
1789
        return [
1790
            // NoValueException
1791
            ['<th>Data</th> <td></td>', 'string', ['safe' => false]],
1792
            ['<th>Data</th> <td></td>', 'text', ['safe' => false]],
1793
            ['<th>Data</th> <td></td>', 'textarea', ['safe' => false]],
1794
            ['<th>Data</th> <td>&nbsp;</td>', 'datetime', []],
1795
            [
1796
                '<th>Data</th> <td>&nbsp;</td>',
1797
                'datetime',
1798
                ['format' => 'd.m.Y H:i:s'],
1799
            ],
1800
            ['<th>Data</th> <td>&nbsp;</td>', 'date', []],
1801
            ['<th>Data</th> <td>&nbsp;</td>', 'date', ['format' => 'd.m.Y']],
1802
            ['<th>Data</th> <td>&nbsp;</td>', 'time', []],
1803
            ['<th>Data</th> <td></td>', 'number', ['safe' => false]],
1804
            ['<th>Data</th> <td></td>', 'integer', ['safe' => false]],
1805
            ['<th>Data</th> <td> 0 % </td>', 'percent', []],
1806
            ['<th>Data</th> <td> </td>', 'currency', ['currency' => 'EUR']],
1807
            ['<th>Data</th> <td> </td>', 'currency', ['currency' => 'GBP']],
1808
            ['<th>Data</th> <td> <ul></ul> </td>', 'array', ['safe' => false]],
1809
            [
1810
                '<th>Data</th> <td><span class="label label-danger">no</span></td>',
1811
                'boolean',
1812
                [],
1813
            ],
1814
            [
1815
                '<th>Data</th> <td> </td>',
1816
                'trans',
1817
                ['safe' => false, 'catalogue' => 'SonataAdminBundle'],
1818
            ],
1819
            [
1820
                '<th>Data</th> <td></td>',
1821
                'choice',
1822
                ['safe' => false, 'choices' => []],
1823
            ],
1824
            [
1825
                '<th>Data</th> <td></td>',
1826
                'choice',
1827
                ['safe' => false, 'choices' => [], 'multiple' => true],
1828
            ],
1829
            ['<th>Data</th> <td>&nbsp;</td>', 'url', []],
1830
            [
1831
                '<th>Data</th> <td>&nbsp;</td>',
1832
                'url',
1833
                ['url' => 'http://example.com'],
1834
            ],
1835
            [
1836
                '<th>Data</th> <td>&nbsp;</td>',
1837
                'url',
1838
                ['route' => ['name' => 'sonata_admin_foo']],
1839
            ],
1840
        ];
1841
    }
1842
1843
    public function testGetValueFromFieldDescriptionWithNoValueException(): void
1844
    {
1845
        $object = new \stdClass();
1846
        $fieldDescription = $this->getMockForAbstractClass(FieldDescriptionInterface::class);
1847
1848
        $fieldDescription
1849
            ->method('getValue')
1850
            ->willReturnCallback(static function (): void {
1851
                throw new NoValueException();
1852
            });
1853
1854
        $fieldDescription
1855
            ->method('hasAssociationAdmin')
1856
            ->willReturn(false);
1857
1858
        $this->assertNull(
1859
            $this->getMethodAsPublic('getValueFromFieldDescription')->invoke(
1860
                $this->twigExtension,
1861
                $object,
1862
                $fieldDescription
1863
            )
1864
        );
1865
    }
1866
1867
    public function testRenderRelationElementNoObject(): void
1868
    {
1869
        $this->assertSame('foo', $this->twigExtension->renderRelationElement('foo', $this->fieldDescription));
1870
    }
1871
1872
    public function testRenderRelationElementToString(): void
1873
    {
1874
        $this->fieldDescription->expects($this->exactly(1))
0 ignored issues
show
The method expects() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
1875
            ->method('getOption')
1876
            ->willReturnCallback(static function ($value, $default = null) {
1877
                if ('associated_property' === $value) {
1878
                    return $default;
1879
                }
1880
            });
1881
1882
        $element = new FooToString();
1883
        $this->assertSame('salut', $this->twigExtension->renderRelationElement($element, $this->fieldDescription));
1884
    }
1885
1886
    public function testRenderRelationElementCustomToString(): void
1887
    {
1888
        $this->fieldDescription->expects($this->exactly(1))
0 ignored issues
show
The method expects() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
1889
            ->method('getOption')
1890
            ->willReturnCallback(static function ($value, $default = null) {
0 ignored issues
show
The parameter $default is not used and could be removed.

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

Loading history...
1891
                if ('associated_property' === $value) {
1892
                    return 'customToString';
1893
                }
1894
            });
1895
1896
        $element = $this->getMockBuilder(\stdClass::class)
1897
            ->setMethods(['customToString'])
1898
            ->getMock();
1899
        $element
1900
            ->method('customToString')
1901
            ->willReturn('fooBar');
1902
1903
        $this->assertSame('fooBar', $this->twigExtension->renderRelationElement($element, $this->fieldDescription));
1904
    }
1905
1906
    public function testRenderRelationElementMethodNotExist(): void
1907
    {
1908
        $element = new \stdClass();
1909
        $this->expectException(\RuntimeException::class);
1910
        $this->expectExceptionMessage('You must define an `associated_property` option or create a `stdClass::__toString');
1911
1912
        $this->twigExtension->renderRelationElement($element, $this->fieldDescription);
1913
    }
1914
1915
    public function testRenderRelationElementWithPropertyPath(): void
1916
    {
1917
        $this->fieldDescription->expects($this->once())
0 ignored issues
show
The method expects() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
1918
            ->method('getOption')
1919
1920
            ->willReturnCallback(static function ($value, $default = null) {
0 ignored issues
show
The parameter $default is not used and could be removed.

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

Loading history...
1921
                if ('associated_property' === $value) {
1922
                    return 'foo';
1923
                }
1924
            });
1925
1926
        $element = new \stdClass();
1927
        $element->foo = 'bar';
1928
1929
        $this->assertSame('bar', $this->twigExtension->renderRelationElement($element, $this->fieldDescription));
1930
    }
1931
1932
    public function testRenderRelationElementWithClosure(): void
1933
    {
1934
        $this->fieldDescription->expects($this->once())
0 ignored issues
show
The method expects() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
1935
            ->method('getOption')
1936
1937
            ->willReturnCallback(static function ($value, $default = null) {
0 ignored issues
show
The parameter $default is not used and could be removed.

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

Loading history...
1938
                if ('associated_property' === $value) {
1939
                    return static function ($element): string {
1940
                        return sprintf('closure %s', $element->foo);
1941
                    };
1942
                }
1943
            });
1944
1945
        $element = new \stdClass();
1946
        $element->foo = 'bar';
1947
1948
        $this->assertSame(
1949
            'closure bar',
1950
            $this->twigExtension->renderRelationElement($element, $this->fieldDescription)
1951
        );
1952
    }
1953
1954
    public function testGetUrlsafeIdentifier(): void
1955
    {
1956
        $model = new \stdClass();
1957
1958
        // set admin to pool
1959
        $this->pool->setAdminServiceIds(['sonata_admin_foo_service']);
1960
        $this->pool->setAdminClasses([\stdClass::class => ['sonata_admin_foo_service']]);
1961
1962
        $this->admin->expects($this->once())
0 ignored issues
show
The method expects() does not seem to exist on object<Sonata\AdminBundle\Admin\AdminInterface>.

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...
1963
            ->method('getUrlSafeIdentifier')
1964
            ->with($this->equalTo($model))
1965
            ->willReturn('1234567');
1966
1967
        $this->assertSame('1234567', $this->twigExtension->getUrlSafeIdentifier($model));
1968
    }
1969
1970
    public function testGetUrlsafeIdentifier_GivenAdmin_Foo(): void
1971
    {
1972
        $model = new \stdClass();
1973
1974
        // set admin to pool
1975
        $this->pool->setAdminServiceIds([
1976
            'sonata_admin_foo_service',
1977
            'sonata_admin_bar_service',
1978
        ]);
1979
        $this->pool->setAdminClasses([\stdClass::class => [
1980
            'sonata_admin_foo_service',
1981
            'sonata_admin_bar_service',
1982
        ]]);
1983
1984
        $this->admin->expects($this->once())
0 ignored issues
show
The method expects() does not seem to exist on object<Sonata\AdminBundle\Admin\AdminInterface>.

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...
1985
            ->method('getUrlSafeIdentifier')
1986
            ->with($this->equalTo($model))
1987
            ->willReturn('1234567');
1988
1989
        $this->adminBar->expects($this->never())
0 ignored issues
show
The method expects() does not seem to exist on object<Sonata\AdminBundle\Admin\AdminInterface>.

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...
1990
            ->method('getUrlSafeIdentifier');
1991
1992
        $this->assertSame('1234567', $this->twigExtension->getUrlSafeIdentifier($model, $this->admin));
1993
    }
1994
1995
    public function testGetUrlsafeIdentifier_GivenAdmin_Bar(): void
1996
    {
1997
        $model = new \stdClass();
1998
1999
        // set admin to pool
2000
        $this->pool->setAdminServiceIds(['sonata_admin_foo_service', 'sonata_admin_bar_service']);
2001
        $this->pool->setAdminClasses([\stdClass::class => [
2002
            'sonata_admin_foo_service',
2003
            'sonata_admin_bar_service',
2004
        ]]);
2005
2006
        $this->admin->expects($this->never())
0 ignored issues
show
The method expects() does not seem to exist on object<Sonata\AdminBundle\Admin\AdminInterface>.

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...
2007
            ->method('getUrlSafeIdentifier');
2008
2009
        $this->adminBar->expects($this->once())
0 ignored issues
show
The method expects() does not seem to exist on object<Sonata\AdminBundle\Admin\AdminInterface>.

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...
2010
            ->method('getUrlSafeIdentifier')
2011
            ->with($this->equalTo($model))
2012
            ->willReturn('1234567');
2013
2014
        $this->assertSame('1234567', $this->twigExtension->getUrlSafeIdentifier($model, $this->adminBar));
2015
    }
2016
2017
    public function xEditableChoicesProvider()
2018
    {
2019
        return [
2020
            'needs processing' => [
2021
                ['choices' => ['Status1' => 'Alias1', 'Status2' => 'Alias2']],
2022
                [
2023
                    ['value' => 'Status1', 'text' => 'Alias1'],
2024
                    ['value' => 'Status2', 'text' => 'Alias2'],
2025
                ],
2026
            ],
2027
            'already processed' => [
2028
                ['choices' => [
2029
                    ['value' => 'Status1', 'text' => 'Alias1'],
2030
                    ['value' => 'Status2', 'text' => 'Alias2'],
2031
                ]],
2032
                [
2033
                    ['value' => 'Status1', 'text' => 'Alias1'],
2034
                    ['value' => 'Status2', 'text' => 'Alias2'],
2035
                ],
2036
            ],
2037
            'not required' => [
2038
                [
2039
                    'required' => false,
2040
                    'choices' => ['' => '', 'Status1' => 'Alias1', 'Status2' => 'Alias2'],
2041
                ],
2042
                [
2043
                    ['value' => '', 'text' => ''],
2044
                    ['value' => 'Status1', 'text' => 'Alias1'],
2045
                    ['value' => 'Status2', 'text' => 'Alias2'],
2046
                ],
2047
            ],
2048
            'not required multiple' => [
2049
                [
2050
                    'required' => false,
2051
                    'multiple' => true,
2052
                    'choices' => ['Status1' => 'Alias1', 'Status2' => 'Alias2'],
2053
                ],
2054
                [
2055
                    ['value' => 'Status1', 'text' => 'Alias1'],
2056
                    ['value' => 'Status2', 'text' => 'Alias2'],
2057
                ],
2058
            ],
2059
        ];
2060
    }
2061
2062
    /**
2063
     * @dataProvider xEditablechoicesProvider
2064
     */
2065
    public function testGetXEditableChoicesIsIdempotent(array $options, array $expectedChoices): void
2066
    {
2067
        $fieldDescription = $this->getMockForAbstractClass(FieldDescriptionInterface::class);
2068
        $fieldDescription
2069
            ->method('getOption')
2070
            ->withConsecutive(
2071
                ['choices', []],
2072
                ['catalogue'],
2073
                ['required'],
2074
                ['multiple']
2075
            )
2076
            ->will($this->onConsecutiveCalls(
2077
                $options['choices'],
2078
                'MyCatalogue',
2079
                $options['multiple'] ?? null
2080
            ));
2081
2082
        $this->assertSame($expectedChoices, $this->twigExtension->getXEditableChoices($fieldDescription));
2083
    }
2084
2085
    public function select2LocalesProvider()
2086
    {
2087
        return [
2088
            ['ar', 'ar'],
2089
            ['az', 'az'],
2090
            ['bg', 'bg'],
2091
            ['ca', 'ca'],
2092
            ['cs', 'cs'],
2093
            ['da', 'da'],
2094
            ['de', 'de'],
2095
            ['el', 'el'],
2096
            [null, 'en'],
2097
            ['es', 'es'],
2098
            ['et', 'et'],
2099
            ['eu', 'eu'],
2100
            ['fa', 'fa'],
2101
            ['fi', 'fi'],
2102
            ['fr', 'fr'],
2103
            ['gl', 'gl'],
2104
            ['he', 'he'],
2105
            ['hr', 'hr'],
2106
            ['hu', 'hu'],
2107
            ['id', 'id'],
2108
            ['is', 'is'],
2109
            ['it', 'it'],
2110
            ['ja', 'ja'],
2111
            ['ka', 'ka'],
2112
            ['ko', 'ko'],
2113
            ['lt', 'lt'],
2114
            ['lv', 'lv'],
2115
            ['mk', 'mk'],
2116
            ['ms', 'ms'],
2117
            ['nb', 'nb'],
2118
            ['nl', 'nl'],
2119
            ['pl', 'pl'],
2120
            ['pt-PT', 'pt'],
2121
            ['pt-BR', 'pt-BR'],
2122
            ['pt-PT', 'pt-PT'],
2123
            ['ro', 'ro'],
2124
            ['rs', 'rs'],
2125
            ['ru', 'ru'],
2126
            ['sk', 'sk'],
2127
            ['sv', 'sv'],
2128
            ['th', 'th'],
2129
            ['tr', 'tr'],
2130
            ['ug-CN', 'ug'],
2131
            ['ug-CN', 'ug-CN'],
2132
            ['uk', 'uk'],
2133
            ['vi', 'vi'],
2134
            ['zh-CN', 'zh'],
2135
            ['zh-CN', 'zh-CN'],
2136
            ['zh-TW', 'zh-TW'],
2137
        ];
2138
    }
2139
2140
    /**
2141
     * @dataProvider select2LocalesProvider
2142
     */
2143
    public function testCanonicalizedLocaleForSelect2(?string $expected, string $original): void
2144
    {
2145
        $this->assertSame($expected, $this->twigExtension->getCanonicalizedLocaleForSelect2($this->mockExtensionContext($original)));
2146
    }
2147
2148
    public function momentLocalesProvider(): array
2149
    {
2150
        return [
2151
            ['af', 'af'],
2152
            ['ar-dz', 'ar-dz'],
2153
            ['ar', 'ar'],
2154
            ['ar-ly', 'ar-ly'],
2155
            ['ar-ma', 'ar-ma'],
2156
            ['ar-sa', 'ar-sa'],
2157
            ['ar-tn', 'ar-tn'],
2158
            ['az', 'az'],
2159
            ['be', 'be'],
2160
            ['bg', 'bg'],
2161
            ['bn', 'bn'],
2162
            ['bo', 'bo'],
2163
            ['br', 'br'],
2164
            ['bs', 'bs'],
2165
            ['ca', 'ca'],
2166
            ['cs', 'cs'],
2167
            ['cv', 'cv'],
2168
            ['cy', 'cy'],
2169
            ['da', 'da'],
2170
            ['de-at', 'de-at'],
2171
            ['de', 'de'],
2172
            ['de', 'de-de'],
2173
            ['dv', 'dv'],
2174
            ['el', 'el'],
2175
            [null, 'en'],
2176
            [null, 'en-us'],
2177
            ['en-au', 'en-au'],
2178
            ['en-ca', 'en-ca'],
2179
            ['en-gb', 'en-gb'],
2180
            ['en-ie', 'en-ie'],
2181
            ['en-nz', 'en-nz'],
2182
            ['eo', 'eo'],
2183
            ['es-do', 'es-do'],
2184
            ['es', 'es-ar'],
2185
            ['es', 'es-mx'],
2186
            ['es', 'es'],
2187
            ['et', 'et'],
2188
            ['eu', 'eu'],
2189
            ['fa', 'fa'],
2190
            ['fi', 'fi'],
2191
            ['fo', 'fo'],
2192
            ['fr-ca', 'fr-ca'],
2193
            ['fr-ch', 'fr-ch'],
2194
            ['fr', 'fr-fr'],
2195
            ['fr', 'fr'],
2196
            ['fy', 'fy'],
2197
            ['gd', 'gd'],
2198
            ['gl', 'gl'],
2199
            ['he', 'he'],
2200
            ['hi', 'hi'],
2201
            ['hr', 'hr'],
2202
            ['hu', 'hu'],
2203
            ['hy-am', 'hy-am'],
2204
            ['id', 'id'],
2205
            ['is', 'is'],
2206
            ['it', 'it'],
2207
            ['ja', 'ja'],
2208
            ['jv', 'jv'],
2209
            ['ka', 'ka'],
2210
            ['kk', 'kk'],
2211
            ['km', 'km'],
2212
            ['ko', 'ko'],
2213
            ['ky', 'ky'],
2214
            ['lb', 'lb'],
2215
            ['lo', 'lo'],
2216
            ['lt', 'lt'],
2217
            ['lv', 'lv'],
2218
            ['me', 'me'],
2219
            ['mi', 'mi'],
2220
            ['mk', 'mk'],
2221
            ['ml', 'ml'],
2222
            ['mr', 'mr'],
2223
            ['ms', 'ms'],
2224
            ['ms-my', 'ms-my'],
2225
            ['my', 'my'],
2226
            ['nb', 'nb'],
2227
            ['ne', 'ne'],
2228
            ['nl-be', 'nl-be'],
2229
            ['nl', 'nl'],
2230
            ['nl', 'nl-nl'],
2231
            ['nn', 'nn'],
2232
            ['pa-in', 'pa-in'],
2233
            ['pl', 'pl'],
2234
            ['pt-br', 'pt-br'],
2235
            ['pt', 'pt'],
2236
            ['ro', 'ro'],
2237
            ['ru', 'ru'],
2238
            ['se', 'se'],
2239
            ['si', 'si'],
2240
            ['sk', 'sk'],
2241
            ['sl', 'sl'],
2242
            ['sq', 'sq'],
2243
            ['sr-cyrl', 'sr-cyrl'],
2244
            ['sr', 'sr'],
2245
            ['ss', 'ss'],
2246
            ['sv', 'sv'],
2247
            ['sw', 'sw'],
2248
            ['ta', 'ta'],
2249
            ['te', 'te'],
2250
            ['tet', 'tet'],
2251
            ['th', 'th'],
2252
            ['tlh', 'tlh'],
2253
            ['tl-ph', 'tl-ph'],
2254
            ['tr', 'tr'],
2255
            ['tzl', 'tzl'],
2256
            ['tzm', 'tzm'],
2257
            ['tzm-latn', 'tzm-latn'],
2258
            ['uk', 'uk'],
2259
            ['uz', 'uz'],
2260
            ['vi', 'vi'],
2261
            ['x-pseudo', 'x-pseudo'],
2262
            ['yo', 'yo'],
2263
            ['zh-cn', 'zh-cn'],
2264
            ['zh-hk', 'zh-hk'],
2265
            ['zh-tw', 'zh-tw'],
2266
        ];
2267
    }
2268
2269
    /**
2270
     * @dataProvider momentLocalesProvider
2271
     */
2272
    public function testCanonicalizedLocaleForMoment(?string $expected, string $original): void
2273
    {
2274
        $this->assertSame($expected, $this->twigExtension->getCanonicalizedLocaleForMoment($this->mockExtensionContext($original)));
2275
    }
2276
2277
    public function testIsGrantedAffirmative(): void
2278
    {
2279
        $this->assertTrue(
2280
            $this->twigExtension->isGrantedAffirmative(['foo', 'bar'])
2281
        );
2282
        $this->assertTrue($this->twigExtension->isGrantedAffirmative('foo'));
2283
        $this->assertTrue($this->twigExtension->isGrantedAffirmative('bar'));
2284
    }
2285
2286
    /**
2287
     * @dataProvider getRenderViewElementCompareTests
2288
     */
2289
    public function testRenderViewElementCompare(string $expected, string $type, $value, array $options, ?string $objectName = null): void
2290
    {
2291
        $this->fieldDescription
0 ignored issues
show
The method method() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
2292
            ->method('getValue')
2293
            ->willReturn($value);
2294
2295
        $this->fieldDescription
0 ignored issues
show
The method method() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
2296
            ->method('getType')
2297
            ->willReturn($type);
2298
2299
        $this->fieldDescription
0 ignored issues
show
The method method() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
2300
            ->method('getOptions')
2301
            ->willReturn($options);
2302
2303
        $this->fieldDescription
0 ignored issues
show
The method method() does not seem to exist on object<Sonata\AdminBundl...ldDescriptionInterface>.

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...
2304
            ->method('getTemplate')
2305
            ->willReturnCallback(static function () use ($type, $options): ?string {
2306
                if (isset($options['template'])) {
2307
                    return $options['template'];
2308
                }
2309
2310
                switch ($type) {
2311
                    case 'boolean':
2312
                        return '@SonataAdmin/CRUD/show_boolean.html.twig';
2313
                    case 'datetime':
2314
                        return '@SonataAdmin/CRUD/show_datetime.html.twig';
2315
                    case 'date':
2316
                        return '@SonataAdmin/CRUD/show_date.html.twig';
2317
                    case 'time':
2318
                        return '@SonataAdmin/CRUD/show_time.html.twig';
2319
                    case 'currency':
2320
                        return '@SonataAdmin/CRUD/show_currency.html.twig';
2321
                    case 'percent':
2322
                        return '@SonataAdmin/CRUD/show_percent.html.twig';
2323
                    case 'email':
2324
                        return '@SonataAdmin/CRUD/show_email.html.twig';
2325
                    case 'choice':
2326
                        return '@SonataAdmin/CRUD/show_choice.html.twig';
2327
                    case 'array':
2328
                        return '@SonataAdmin/CRUD/show_array.html.twig';
2329
                    case 'trans':
2330
                        return '@SonataAdmin/CRUD/show_trans.html.twig';
2331
                    case 'url':
2332
                        return '@SonataAdmin/CRUD/show_url.html.twig';
2333
                    case 'html':
2334
                        return '@SonataAdmin/CRUD/show_html.html.twig';
2335
                    default:
2336
                        return null;
2337
                }
2338
            });
2339
2340
        $this->object->name = 'SonataAdmin';
2341
2342
        $comparedObject = clone $this->object;
2343
2344
        if (null !== $objectName) {
2345
            $comparedObject->name = $objectName;
2346
        }
2347
2348
        $this->assertSame(
2349
            $this->removeExtraWhitespace($expected),
2350
            $this->removeExtraWhitespace(
2351
                $this->twigExtension->renderViewElementCompare(
2352
                    $this->environment,
2353
                    $this->fieldDescription,
2354
                    $this->object,
2355
                    $comparedObject
2356
                )
2357
            )
2358
        );
2359
    }
2360
2361
    public function getRenderViewElementCompareTests(): iterable
2362
    {
2363
        return [
2364
            ['<th>Data</th> <td>Example</td><td>Example</td>', 'string', 'Example', ['safe' => false]],
2365
            ['<th>Data</th> <td>Example</td><td>Example</td>', 'text', 'Example', ['safe' => false]],
2366
            ['<th>Data</th> <td>Example</td><td>Example</td>', 'textarea', 'Example', ['safe' => false]],
2367
            ['<th>Data</th> <td>SonataAdmin<br/>Example</td><td>SonataAdmin<br/>Example</td>', 'virtual_field', 'Example', ['template' => 'custom_show_field.html.twig', 'safe' => false, 'SonataAdmin']],
2368
            ['<th class="diff">Data</th> <td>SonataAdmin<br/>Example</td><td>SonataAdmin<br/>Example</td>', 'virtual_field', 'Example', ['template' => 'custom_show_field.html.twig', 'safe' => false], 'sonata-project/admin-bundle'],
2369
            [
2370
                '<th>Data</th> <td><time datetime="2020-05-27T09:11:12+00:00" title="2020-05-27T09:11:12+00:00"> May 27, 2020 10:11 </time></td>'
2371
                .'<td><time datetime="2020-05-27T09:11:12+00:00" title="2020-05-27T09:11:12+00:00"> May 27, 2020 10:11 </time></td>',
2372
                'datetime',
2373
                new \DateTime('2020-05-27 10:11:12', new \DateTimeZone('Europe/London')), [],
2374
            ],
2375
            [
2376
                '<th>Data</th> <td><time datetime="2020-05-27T09:11:12+00:00" title="2020-05-27T09:11:12+00:00"> 27.05.2020 10:11:12 </time></td>'
2377
                .'<td><time datetime="2020-05-27T09:11:12+00:00" title="2020-05-27T09:11:12+00:00"> 27.05.2020 10:11:12 </time></td>',
2378
                'datetime',
2379
                new \DateTime('2020-05-27 10:11:12', new \DateTimeZone('Europe/London')),
2380
                ['format' => 'd.m.Y H:i:s'],
2381
            ],
2382
            [
2383
                '<th>Data</th> <td><time datetime="2020-05-27T10:11:12+00:00" title="2020-05-27T10:11:12+00:00"> May 27, 2020 18:11 </time></td>'
2384
                .'<td><time datetime="2020-05-27T10:11:12+00:00" title="2020-05-27T10:11:12+00:00"> May 27, 2020 18:11 </time></td>',
2385
                'datetime',
2386
                new \DateTime('2020-05-27 10:11:12', new \DateTimeZone('UTC')),
2387
                ['timezone' => 'Asia/Hong_Kong'],
2388
            ],
2389
            [
2390
                '<th>Data</th> <td><time datetime="2020-05-27" title="2020-05-27"> May 27, 2020 </time></td>'
2391
                .'<td><time datetime="2020-05-27" title="2020-05-27"> May 27, 2020 </time></td>',
2392
                'date',
2393
                new \DateTime('2020-05-27 10:11:12', new \DateTimeZone('Europe/London')),
2394
                [],
2395
            ],
2396
        ];
2397
    }
2398
2399
    /**
2400
     * This method generates url part for Twig layout.
2401
     */
2402
    private function buildTwigLikeUrl(array $url): string
2403
    {
2404
        return htmlspecialchars(http_build_query($url, '', '&', PHP_QUERY_RFC3986));
2405
    }
2406
2407
    private function getMethodAsPublic($privateMethod): \ReflectionMethod
2408
    {
2409
        $reflection = new \ReflectionMethod('Sonata\AdminBundle\Twig\Extension\SonataAdminExtension', $privateMethod);
2410
        $reflection->setAccessible(true);
2411
2412
        return $reflection;
2413
    }
2414
2415
    private function removeExtraWhitespace(string $string): string
2416
    {
2417
        return trim(preg_replace(
2418
            '/\s+/',
2419
            ' ',
2420
            $string
2421
        ));
2422
    }
2423
2424
    private function mockExtensionContext(string $locale): array
2425
    {
2426
        $request = $this->createMock(Request::class);
2427
        $request->method('getLocale')->willReturn($locale);
2428
        $appVariable = $this->createMock(AppVariable::class);
2429
        $appVariable->method('getRequest')->willReturn($request);
2430
2431
        return ['app' => $appVariable];
2432
    }
2433
}
2434