ShowBuilder   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 106
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 4
dl 0
loc 106
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getBaseList() 0 4 1
A addField() 0 14 2
B fixFieldDescription() 0 40 10
A getTemplate() 0 23 4
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\DoctrineORMAdminBundle\Builder;
15
16
use Doctrine\ORM\Mapping\ClassMetadata;
17
use Sonata\AdminBundle\Admin\AdminInterface;
18
use Sonata\AdminBundle\Admin\FieldDescriptionCollection;
19
use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
20
use Sonata\AdminBundle\Builder\ShowBuilderInterface;
21
use Sonata\AdminBundle\Guesser\TypeGuesserInterface;
22
use Sonata\DoctrineORMAdminBundle\Guesser\TypeGuesser;
23
24
class ShowBuilder implements ShowBuilderInterface
25
{
26
    /**
27
     * @var TypeGuesserInterface
28
     */
29
    protected $guesser;
30
31
    /**
32
     * @var string[]
33
     */
34
    protected $templates;
35
36
    /**
37
     * @param string[] $templates
38
     */
39
    public function __construct(TypeGuesserInterface $guesser, array $templates)
40
    {
41
        $this->guesser = $guesser;
42
        $this->templates = $templates;
43
    }
44
45
    public function getBaseList(array $options = [])
46
    {
47
        return new FieldDescriptionCollection();
48
    }
49
50
    public function addField(FieldDescriptionCollection $list, $type, FieldDescriptionInterface $fieldDescription, AdminInterface $admin): void
51
    {
52
        if (null === $type) {
53
            $guessType = $this->guesser->guessType($admin->getClass(), $fieldDescription->getName(), $admin->getModelManager());
54
            $fieldDescription->setType($guessType->getType());
55
        } else {
56
            $fieldDescription->setType($type);
57
        }
58
59
        $this->fixFieldDescription($admin, $fieldDescription);
60
        $admin->addShowFieldDescription($fieldDescription->getName(), $fieldDescription);
61
62
        $list->add($fieldDescription);
63
    }
64
65
    public function fixFieldDescription(AdminInterface $admin, FieldDescriptionInterface $fieldDescription): void
66
    {
67
        $fieldDescription->setAdmin($admin);
68
69
        if ($admin->getModelManager()->hasMetadata($admin->getClass())) {
70
            list($metadata, $lastPropertyName, $parentAssociationMappings) = $admin->getModelManager()->getParentMetadataForProperty($admin->getClass(), $fieldDescription->getName());
71
            $fieldDescription->setParentAssociationMappings($parentAssociationMappings);
72
73
            // set the default field mapping
74
            if (isset($metadata->fieldMappings[$lastPropertyName])) {
75
                $fieldDescription->setFieldMapping($metadata->fieldMappings[$lastPropertyName]);
76
            }
77
78
            // set the default association mapping
79
            if (isset($metadata->associationMappings[$lastPropertyName])) {
80
                $fieldDescription->setAssociationMapping($metadata->associationMappings[$lastPropertyName]);
81
            }
82
        }
83
84
        if (!$fieldDescription->getType()) {
85
            throw new \RuntimeException(sprintf('Please define a type for field `%s` in `%s`', $fieldDescription->getName(), \get_class($admin)));
86
        }
87
88
        $fieldDescription->setOption('code', $fieldDescription->getOption('code', $fieldDescription->getName()));
89
        $fieldDescription->setOption('label', $fieldDescription->getOption('label', $fieldDescription->getName()));
90
91
        if (!$fieldDescription->getTemplate()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $fieldDescription->getTemplate() of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
92
            $fieldDescription->setTemplate($this->getTemplate($fieldDescription->getType()));
93
        }
94
95
        switch ($fieldDescription->getMappingType()) {
96
            case ClassMetadata::MANY_TO_ONE:
97
            case ClassMetadata::ONE_TO_ONE:
98
            case ClassMetadata::ONE_TO_MANY:
99
            case ClassMetadata::MANY_TO_MANY:
100
                $admin->attachAdminClass($fieldDescription);
101
102
                break;
103
        }
104
    }
105
106
    private function getTemplate(string $type): ?string
107
    {
108
        if (!isset($this->templates[$type])) {
109
            // NEXT_MAJOR: Remove the check for deprecated type and always return null.
110
            if (isset(TypeGuesser::DEPRECATED_TYPES[$type])) {
111
                return $this->getTemplate(TypeGuesser::DEPRECATED_TYPES[$type]);
112
            }
113
114
            return null;
115
        }
116
117
        // NEXT_MAJOR: Remove the deprecation.
118
        if (isset(TypeGuesser::DEPRECATED_TYPES[$type])) {
119
            @trigger_error(sprintf(
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
120
                'Overriding %s show template is deprecated since sonata-project/doctrine-orm-admin-bundle 3.19.'
121
                .' You should override %s show template instead.',
122
                $type,
123
                TypeGuesser::DEPRECATED_TYPES[$type]
124
            ), E_USER_DEPRECATED);
125
        }
126
127
        return $this->templates[$type];
128
    }
129
}
130