Passed
Pull Request — master (#175)
by Arnaud
08:30 queued 02:17
created

MenuItemConfiguration::configureOptions()   D

Complexity

Conditions 19
Paths 1

Size

Total Lines 105
Code Lines 61

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 380

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 19
eloc 61
nc 1
nop 1
dl 0
loc 105
ccs 0
cts 56
cp 0
crap 380
rs 4.5166
c 1
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
3
namespace LAG\AdminBundle\Configuration;
4
5
use JK\Configuration\Configuration;
6
use LAG\AdminBundle\Routing\Resolver\RoutingResolverInterface;
7
use LAG\Component\StringUtils\StringUtils;
8
use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException;
9
use Symfony\Component\OptionsResolver\Options;
10
use Symfony\Component\OptionsResolver\OptionsResolver;
11
12
class MenuItemConfiguration extends Configuration
13
{
14
    /**
15
     * @var string
16
     */
17
    private $itemName;
18
19
    /**
20
     * @var RoutingResolverInterface
21
     */
22
    private $routingResolver;
23
24
    /**
25
     * @var string
26
     */
27
    private $menuName;
28
29
    /**
30
     * @var string
31
     */
32
    private $adminName;
33
34
    public function __construct(
35
        string $itemName,
36
        string $menuName,
37
        RoutingResolverInterface $routingResolver,
38
        ?string $adminName = null
39
    ) {
40
        $this->itemName = $itemName;
41
        $this->routingResolver = $routingResolver;
42
        $this->menuName = $menuName;
43
        $this->adminName = $adminName;
44
        parent::__construct();
45
    }
46
47
    /**
48
     * Define allowed parameters and values for this configuration, using optionsResolver component.
49
     */
50
    public function configureOptions(OptionsResolver $resolver)
51
    {
52
        // user can defined an admin name
53
        $resolver
54
            ->setDefaults([
55
                'admin' => $this->adminName,
56
                'action' => null,
57
                'route' => null,
58
                'routeParameters' => [],
59
                'uri' => null,
60
                'attributes' => [],
61
                'linkAttributes' => [],
62
                'label' => null,
63
                'icon' => null,
64
                'text' => null,
65
                'children' => [],
66
                //'allow_safe_labels' => true,
67
                'extras' => ['safe_label' => true],
68
            ])
69
            ->setNormalizer('route', function (Options $options, $route) {
70
                if ($options->offsetGet('uri')) {
71
                    return $route;
72
                }
73
74
                if (!$route) {
75
                    $route = $this->routingResolver->resolve($options->offsetGet('admin'), $options->offsetGet('action'));
76
                }
77
78
                return $route;
79
            })
80
            ->setNormalizer('admin', function (Options $options, $adminName) {
81
                // user has to defined either an admin name and an action name, or a route name with optional
82
                // parameters, or an url
83
                if (null === $adminName
84
                    && null === $options->offsetGet('route')
85
                    && null === $options->offsetGet('uri')
86
                ) {
87
                    throw new InvalidOptionsException('You should either defined an admin name, or route name or an uri');
88
                }
89
90
                return $adminName;
91
            })
92
            // if an admin name is set, an action name can provided. This action will be the menu link
93
            ->setNormalizer('action', function (Options $options, $action) {
94
                // if an action name is provided, an admin name should be defined too
95
                if (null !== $action && null === $options->offsetGet('admin')) {
96
                    throw new InvalidOptionsException('You should provide an admin name for this action '.$action);
97
                }
98
99
                // default to list action
100
                if (null !== $options->offsetGet('admin') && null === $action) {
101
                    $action = 'list';
102
                }
103
104
                return $action;
105
            })
106
            ->setNormalizer('children', function (Options $options, $items) {
107
                if (!is_array($items)) {
108
                    $items = [];
109
                }
110
                $resolver = new OptionsResolver();
111
                $resolvedItems = [];
112
113
                foreach ($items as $name => $item) {
114
                    $itemConfiguration = new MenuItemConfiguration($name, $this->menuName, $this->routingResolver, $this->adminName);
115
                    $itemConfiguration->configureOptions($resolver);
116
                    $itemConfiguration->setParameters($resolver->resolve($item));
117
                    $resolver->clear();
118
119
                    $resolvedItems[$name] = $itemConfiguration;
120
                }
121
122
                return $resolvedItems;
123
            })
124
            ->setNormalizer('text', function (Options $options, $text) {
125
                if ($text) {
126
                    return $text;
127
                }
128
129
                if ($options->offsetGet('admin')) {
130
                    $text = ucfirst($options->offsetGet('admin'));
131
132
                    if (StringUtils::endsWith($text, 'y')) {
133
                        $text = substr($text, 0, strlen($text) - 1).'ie';
134
                    }
135
136
                    if (!StringUtils::endsWith($text, 's')) {
137
                        $text .= 's';
138
                    }
139
140
                    return $text;
141
                }
142
143
                return $text;
144
            })
145
            ->setNormalizer('linkAttributes', function (Options $options, $linkAttributes) {
146
                if (!$linkAttributes) {
147
                    $linkAttributes = [];
148
                }
149
150
                if ('left' === $this->menuName && empty($linkAttributes)) {
151
                    $linkAttributes = ['class' => 'list-group-item list-group-item-action'];
152
                }
153
154
                return $linkAttributes;
155
            })
156
        ;
157
    }
158
}
159