Completed
Pull Request — master (#8)
by Arnaud
02:50
created

ActionFactory::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 1 Features 0
Metric Value
c 4
b 1
f 0
dl 0
loc 10
rs 9.4285
cc 1
eloc 7
nc 1
nop 3
1
<?php
2
3
namespace LAG\AdminBundle\Admin\Factory;
4
5
use Exception;
6
use LAG\AdminBundle\Admin\Action;
7
use LAG\AdminBundle\Admin\Admin;
8
use LAG\AdminBundle\Admin\AdminInterface;
9
use LAG\AdminBundle\Admin\Configuration\ActionConfiguration;
10
use LAG\AdminBundle\Admin\Configuration\ApplicationConfiguration;
11
use LAG\AdminBundle\Field\Factory\FieldFactory;
12
use Symfony\Component\OptionsResolver\Options;
13
use Symfony\Component\OptionsResolver\OptionsResolver;
14
15
class ActionFactory
16
{
17
    /**
18
     * @var FieldFactory
19
     */
20
    protected $fieldFactory;
21
22
    /**
23
     * @var FilterFactory
24
     */
25
    protected $filterFactory;
26
27
    /**
28
     * @var ApplicationConfiguration
29
     */
30
    protected $configuration;
31
32
    public function __construct(
33
        FieldFactory $fieldFactory,
34
        FilterFactory $filterFactory,
35
        ApplicationConfiguration $configuration
36
    )
37
    {
38
        $this->fieldFactory = $fieldFactory;
39
        $this->filterFactory = $filterFactory;
40
        $this->configuration = $configuration;
41
    }
42
43
    /**
44
     * Create an Action from configuration values.
45
     *
46
     * @param string $actionName
47
     * @param array $actionConfiguration
48
     * @param AdminInterface $admin
49
     *
50
     * @return Action
51
     */
52
    public function create($actionName, array $actionConfiguration, AdminInterface $admin)
53
    {
54
        // resolving default options
55
        $resolver = new OptionsResolver();
56
        $this->configureOptionsResolver($resolver, $actionName, $admin);
57
        $actionConfiguration = $resolver->resolve($actionConfiguration);
58
59
        // creating action object from configuration
60
        $action = $this->createActionFromConfiguration($actionConfiguration, $actionName);
61
62
        // creating actions linked to current action
63
        foreach ($actionConfiguration['actions'] as $customActionName => $customActionConfiguration) {
64
            // resolve configuration
65
            $customActionConfiguration = $resolver->resolve($customActionConfiguration);
66
            // create action
67
            $customAction = $this->createActionFromConfiguration($customActionConfiguration, $customActionName);
68
            // add to the main action
69
            $action->addAction($customAction);
70
        }
71
72
        // adding fields items to actions
73
        foreach ($actionConfiguration['fields'] as $fieldName => $fieldConfiguration) {
74
            $field = $this
75
                ->fieldFactory
76
                ->create($fieldName, $fieldConfiguration);
77
            $action->addField($field);
78
        }
79
80
        // adding filters to the action
81
        foreach ($actionConfiguration['filters'] as $fieldName => $filterConfiguration) {
82
            $filter = $this
83
                ->filterFactory
84
                ->create($fieldName, $filterConfiguration);
85
            $action->addFilter($filter);
86
        }
87
        return $action;
88
    }
89
90
    /**
91
     * Create an action and its configuration object from configuration values
92
     *
93
     * @param array $actionConfiguration
94
     * @param $actionName
95
     * @return Action
96
     */
97
    protected function createActionFromConfiguration(array $actionConfiguration, $actionName)
98
    {
99
        $configuration = new ActionConfiguration($actionConfiguration);
100
        $action = new Action($actionName, $actionConfiguration, $configuration);
101
102
        return $action;
103
    }
104
105
    /**
106
     * Return action configuration resolver
107
     *
108
     * @param OptionsResolver $resolver
109
     * @param $actionName
110
     * @param AdminInterface|null $admin
111
     */
112
    protected function configureOptionsResolver(OptionsResolver $resolver, $actionName, AdminInterface $admin = null)
113
    {
114
        $defaultCriteria = [];
115
        $defaultLoadStrategy = Admin::LOAD_STRATEGY_UNIQUE;
116
117
        if ($actionName == 'edit') {
118
            $defaultCriteria = [
119
                'id'
120
            ];
121
        } else if ($actionName == 'delete') {
122
            $defaultCriteria = [
123
                'id'
124
            ];
125
        } else if ($actionName == 'create') {
126
            $defaultLoadStrategy = Admin::LOAD_STRATEGY_NONE;
127
        }
128
129
        $resolver
130
            ->setDefaults([
131
                'title' => null,
132
                'fields' => [
133
                    'id' => [],
134
                ],
135
                'permissions' => [
136
                    'ROLE_ADMIN'
137
                ],
138
                'export' => [
139
                    'json',
140
                    'html',
141
                    'csv',
142
                    'xls'
143
                ],
144
                'order' => [],
145
                'actions' => [],
146
                'submit_actions' => [],
147
                'target' => '_self',
148
                'route' => '',
149
                'parameters' => [],
150
                'icon' => null,
151
                'filters' => [],
152
                'batch' => [],
153
                'load_strategy' => $defaultLoadStrategy,
154
                'pager' => 'pagerfanta',
155
                'criteria' => $defaultCriteria
156
            ])
157
            ->setAllowedValues('pager', [
158
                null,
159
                'pagerfanta',
160
            ])
161
            ->setAllowedValues('load_strategy', [
162
                Admin::LOAD_STRATEGY_NONE,
163
                Admin::LOAD_STRATEGY_UNIQUE,
164
                Admin::LOAD_STRATEGY_MULTIPLE,
165
            ])
166
            ->setAllowedTypes('actions', 'array')
167
            ->setNormalizer('route', function (Options $options, $value) use ($admin, $actionName) {
168
                if (!$value) {
169
                    // if no route was provided, it should be linked to an Admin
170
                    if (!$admin) {
171
                        throw new Exception('No route was provided for action : ' . $actionName);
172
                    }
173
                    return $admin
174
                        ->generateRouteName($actionName);
175
                }
176
                return $value;
177
            })
178
            ->setNormalizer('title', function (Options $options, $value) use ($admin, $actionName) {
179
                if (!$value) {
180
                    $adminKey = '';
181
                    // if an Admin is linked to this action, we use its name in translation key
182
                    if ($admin) {
183
                        $adminKey = $admin->getName();
184
                    }
185
                    return $this->configuration->getTranslationKey($actionName, $adminKey);
186
                }
187
                return $value;
188
            })
189
            ->setNormalizer('batch', function (Options $options, $value) use ($admin, $actionName) {
190
                if ($value) {
191
                    if (!is_array($value)) {
192
                        $value = [$value];
193
                    }
194
                    foreach ($value as $key => $title) {
195
                        if (!$title) {
196
                            $adminKey = '';
197
                            // if an Admin is linked to this action, we use its name in translation key
198
                            if ($admin) {
199
                                $adminKey = $admin->getName();
200
                            }
201
                            $value[$key] = $this->configuration->getTranslationKey('batch.' . $key, $adminKey);
202
                        }
203
                    }
204
                }
205
                return $value;
206
            })
207
        ;
208
    }
209
}
210