Completed
Push — master ( ed38e4...34da6d )
by Arnaud
19s queued 10s
created

LinkField::render()   A

Complexity

Conditions 6
Paths 12

Size

Total Lines 30
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 6
eloc 18
c 2
b 0
f 1
nc 12
nop 1
dl 0
loc 30
rs 9.0444
1
<?php
2
3
namespace LAG\AdminBundle\Field;
4
5
use LAG\AdminBundle\Configuration\ActionConfiguration;
6
use LAG\AdminBundle\Field\Traits\EntityAwareTrait;
7
use LAG\AdminBundle\Field\Traits\TwigAwareTrait;
8
use LAG\AdminBundle\Routing\RoutingLoader;
9
use LAG\AdminBundle\Utils\TranslationUtils;
10
use LAG\Component\StringUtils\StringUtils;
11
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
12
use Symfony\Component\OptionsResolver\Options;
13
use Symfony\Component\OptionsResolver\OptionsResolver;
14
use Symfony\Component\PropertyAccess\PropertyAccess;
15
16
class LinkField extends StringField implements TwigAwareFieldInterface, EntityAwareFieldInterface
17
{
18
    use TwigAwareTrait;
19
    use EntityAwareTrait;
20
21
    /**
22
     * @var ActionConfiguration
23
     */
24
    protected $actionConfiguration;
25
26
    public function isSortable(): bool
27
    {
28
        return false;
29
    }
30
31
    public function configureOptions(OptionsResolver $resolver, ActionConfiguration $actionConfiguration)
32
    {
33
        parent::configureOptions($resolver, $actionConfiguration);
34
35
        $this->actionConfiguration = $actionConfiguration;
36
37
        $resolver
38
            ->setDefaults([
39
                'template' => '@LAGAdmin/Field/link.html.twig',
40
                'title' => '',
41
                'icon' => '',
42
                'target' => '_self',
43
                'route' => '',
44
                'parameters' => [],
45
                'url' => '',
46
                'text' => '',
47
                'admin' => null,
48
                'action' => null,
49
                'class' => '',
50
            ])
51
            ->setAllowedTypes('route', 'string')
52
            ->setAllowedTypes('parameters', 'array')
53
            ->setAllowedTypes('length', 'integer')
54
            ->setAllowedTypes('url', 'string')
55
            ->setAllowedValues('target', [
56
                '_self',
57
                '_blank',
58
            ])
59
            ->setNormalizer('route', function (Options $options, $value) use ($actionConfiguration) {
60
                // route or url should be defined
61
                if (!$value && !$options->offsetGet('url') && !$options->offsetGet('admin')) {
62
                    throw new InvalidOptionsException(
63
                        'Either an url or a route should be defined'
64
                    );
65
                }
66
67
                if ($options->offsetGet('admin')) {
68
                    $value = RoutingLoader::generateRouteName(
69
                        $options->offsetGet('admin'),
70
                        $options->offsetGet('action'),
71
                        $actionConfiguration->getAdminConfiguration()->getParameter('routing_name_pattern')
72
                    );
73
                }
74
75
                return $value;
76
            })
77
            ->setNormalizer('admin', function (Options $options, $value) {
78
                // if a Admin is defined, an Action should be defined too
79
                if ($value && !$options->offsetGet('action')) {
80
                    throw new InvalidOptionsException(
81
                        'An Action should be provided if an Admin is provided'
82
                    );
83
                }
84
85
                return $value;
86
            })
87
            ->setNormalizer('parameters', function (Options $options, $values) {
88
                $cleanedValues = [];
89
90
                foreach ($values as $name => $method) {
91
                    if (null === $method) {
92
                        $method = $name;
93
                    }
94
                    $cleanedValues[$name] = $method;
95
                }
96
97
                return $cleanedValues;
98
            })
99
            ->setNormalizer('text', function (Options $options, $value) use ($actionConfiguration) {
100
                if ($value) {
101
                    return $value;
102
                }
103
104
                if ($options->offsetGet('action')) {
105
                    return $this
106
                        ->translator
107
                        ->trans(TranslationUtils::getActionTranslationKey(
108
                            $actionConfiguration->getAdminConfiguration()->get('translation_pattern'),
109
                            $actionConfiguration->getAdminName(),
110
                            $options->offsetGet('action')
111
                        ));
112
                }
113
114
                return $options->offsetGet('route');
115
            })
116
        ;
117
    }
118
119
    public function render($value = null): string
120
    {
121
        $value = parent::render($value);
122
        $accessor = PropertyAccess::createPropertyAccessor();
123
        $options = $this->options;
124
125
        foreach ($options['parameters'] as $name => $method) {
126
            // Allow static values by prefixing it with an underscore
127
            if (StringUtils::startsWith($method, '_')) {
128
                $options['parameters'][$name] = StringUtils::end($method, -1);
129
            } else {
130
                $options['parameters'][$name] = $accessor->getValue($this->entity, $method);
131
            }
132
        }
133
134
        if ($value) {
135
            $options['text'] = $value;
136
        }
137
138
        if ('' === $options['text'] && $options['action']) {
139
            $translationKey = TranslationUtils::getActionTranslationKey(
140
                $this->actionConfiguration->getAdminConfiguration()->get('translation_pattern'),
141
                $this->actionConfiguration->getAdminName(),
142
                $options['action']
143
            );
144
            $options['text'] = $this->translator->trans($translationKey);
145
        }
146
147
        return $this->twig->render($this->options['template'], [
148
            'options' => $options,
149
        ]);
150
    }
151
}
152