DefaultFeedType   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 332
Duplicated Lines 36.75 %

Coupling/Cohesion

Components 1
Dependencies 21

Test Coverage

Coverage 81.58%

Importance

Changes 0
Metric Value
wmc 28
lcom 1
cbo 21
dl 122
loc 332
ccs 93
cts 114
cp 0.8158
rs 10
c 0
b 0
f 0

17 Methods

Rating   Name   Duplication   Size   Complexity  
getMapping() 0 1 ?
getAssociationMapping() 0 1 ?
getFieldMapping() 0 1 ?
getEntityFields() 0 1 ?
A __construct() 0 6 1
A build() 0 24 1
A addCustomModifiers() 0 3 1
A getUnmappedFields() 0 4 1
A getExtraMappedFields() 0 4 1
A getForeignMapping() 0 4 1
A addFinalModifiers() 8 8 1
A getEntityManager() 0 4 1
A getMappedFields() 23 23 1
A addEntityModifiers() 21 21 4
A addAssociationModifiers() 15 15 2
A addFieldModifiers() 4 19 2
C addFieldTypeModifiers() 51 66 11

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace TreeHouse\IoBundle\Import\Feed\Type;
4
5
use Doctrine\Common\Persistence\ManagerRegistry;
6
use Doctrine\ORM\EntityManagerInterface;
7
use Doctrine\ORM\Mapping\ClassMetadataInfo;
8
use Symfony\Component\HttpFoundation\ParameterBag;
9
use TreeHouse\Feeder\Modifier\Data\Transformer\DateTimeToIso8601Transformer;
10
use TreeHouse\Feeder\Modifier\Data\Transformer\EmptyValueToNullTransformer;
11
use TreeHouse\Feeder\Modifier\Data\Transformer\NodeToStringTransformer;
12
use TreeHouse\Feeder\Modifier\Data\Transformer\StringToBooleanTransformer;
13
use TreeHouse\Feeder\Modifier\Data\Transformer\TraversingTransformer;
14
use TreeHouse\Feeder\Modifier\Item\Mapper\PathMapper;
15
use TreeHouse\Feeder\Modifier\Item\Transformer\ObsoleteFieldsTransformer;
16
use TreeHouse\Feeder\Modifier\Item\Transformer\UnderscoreKeysTransformer;
17
use TreeHouse\IoBundle\Import\Feed\FeedBuilderInterface;
18
use TreeHouse\IoBundle\Item\Modifier\Data\Transformer\DutchStringToDateTimeTransformer;
19
use TreeHouse\IoBundle\Item\Modifier\Data\Transformer\EntityToIdTransformer;
20
use TreeHouse\IoBundle\Item\Modifier\Data\Transformer\ForeignMappingTransformer;
21
use TreeHouse\IoBundle\Item\Modifier\Data\Transformer\LocalizedStringToNumberTransformer;
22
use TreeHouse\IoBundle\Item\Modifier\Data\Transformer\MultiLineToSingleLineTransformer;
23
use TreeHouse\IoBundle\Item\Modifier\Data\Transformer\MultiSpaceToSingleSpaceTransformer;
24
use TreeHouse\IoBundle\Item\Modifier\Data\Transformer\NormalizedStringTransformer;
25
use TreeHouse\IoBundle\Item\Modifier\Data\Transformer\StringToDateTimeTransformer;
26
use TreeHouse\IoBundle\Item\Modifier\Item\Transformer\DefaultValuesTransformer;
27
use TreeHouse\IoBundle\Source\Manager\CachedSourceManager;
28
29
abstract class DefaultFeedType extends AbstractFeedType
30
{
31
    /**
32
     * @var ManagerRegistry
33
     */
34
    protected $doctrine;
35
36
    /**
37
     * @var array
38
     */
39
    protected $options;
40
41
    /**
42
     * @param ManagerRegistry     $doctrine
43
     * @param CachedSourceManager $sourceManager
44
     */
45 4
    public function __construct(ManagerRegistry $doctrine, CachedSourceManager $sourceManager)
46
    {
47 4
        $this->doctrine = $doctrine;
48
49 4
        parent::__construct($sourceManager);
50 4
    }
51
52
    /**
53
     * @return array
54
     */
55
    abstract public function getMapping();
56
57
    /**
58
     * @inheritdoc
59
     */
60 4
    public function build(FeedBuilderInterface $builder, array $options)
61
    {
62 4
        parent::build($builder, $options);
63
64 4
        $this->options = $options;
65
66
        // 2000-3000: map paths
67 4
        $builder->addModifier(new PathMapper($this->getMapping()), 2000);
68
69
        // 3000-3500: transform specific fields
70
71
        // 3500-4000: feed-type specific: reserved for field transformers before the regular transformers
72
73
        // 4000-5000: reserved for transformers added automatically based on entity field mapping
74 4
        $this->addEntityModifiers($builder, 4000, 5000);
75
76
        // 5000-6000: feed-type specific: reserved for field transformers after the regular transformers
77
78
        // 6000-7000: reserved for modifiers after all other modifiers are done
79 4
        $this->addFinalModifiers($builder, 6000, 7000);
80
81
        // give extending feed type a method for custom modifiers
82 4
        $this->addCustomModifiers($builder, $options);
83 4
    }
84
85
    /**
86
     * Returns mapping for an association, or null if it does not exist.
87
     *
88
     * @param string $association
89
     *
90
     * @return array|null
91
     */
92
    abstract protected function getAssociationMapping($association);
93
94
    /**
95
     * Returns mapping for a field, or null if it does not exist.
96
     *
97
     * @param string $field
98
     *
99
     * @return array|null
100
     */
101
    abstract protected function getFieldMapping($field);
102
103
    /**
104
     * Returns an array with all the field/association names for
105
     * the entity that is imported.
106
     *
107
     * @return array
108
     */
109
    abstract protected function getEntityFields();
110
111
    /**
112
     * Override this method to add custom modifiers to the feed.
113
     *
114
     * @param FeedBuilderInterface $builder
115
     * @param array                $options
116
     */
117
    protected function addCustomModifiers(FeedBuilderInterface $builder, array $options)
0 ignored issues
show
Unused Code introduced by
The parameter $builder 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...
Unused Code introduced by
The parameter $options 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...
118
    {
119
    }
120
121
    /**
122
     * Returns the names of all mapped and extra mapped fields. These are the
123
     * fields that are allowed in the resulting item. The fields are
124
     * normalized to be lowercased and underscored (instead of dashes).
125
     *
126
     * @return array
127
     */
128 6 View Code Duplication
    protected function getMappedFields()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
129
    {
130 6
        $fields = array_diff(
131 6
            array_unique(
132 6
                array_merge(
133 6
                    array_values($this->getEntityFields()),
134 6
                    array_values($this->getExtraMappedFields()),
135 6
                    array_values($this->getMapping())
136
                )
137
            ),
138 6
            $this->getUnmappedFields()
139
        );
140
141 6
        $fields = new ParameterBag(array_flip($fields));
142
143
        // make sure id is not in it
144 6
        $fields->remove('id');
145
146 6
        $transformer = new UnderscoreKeysTransformer();
147 6
        $transformer->transform($fields);
148
149 6
        return $fields->keys();
150
    }
151
152
    /**
153
     * Specify fields here that are explicitly not mapped.
154
     *
155
     * @return array
156
     */
157 4
    protected function getUnmappedFields()
158
    {
159 4
        return [];
160
    }
161
162
    /**
163
     * Specify fields here that are not mapped directly, but need to stay in the resulting item.
164
     *
165
     * @return array
166
     */
167 4
    protected function getExtraMappedFields()
168
    {
169 4
        return [];
170
    }
171
172
    /**
173
     * Specify a mapping here from foreign configuration to our configuration.
174
     *
175
     * @return array
176
     */
177 4
    protected function getForeignMapping()
178
    {
179 4
        return [];
180
    }
181
182
    /**
183
     * Automatically adds modifiers based on entity field/association mapping.
184
     *
185
     * @param FeedBuilderInterface $builder
186
     * @param int                  $startIndex
187
     * @param int                  $endIndex
188
     */
189 View Code Duplication
    protected function addEntityModifiers(FeedBuilderInterface $builder, $startIndex, $endIndex)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
190
    {
191
        // skip id
192 4
        $mappedFields = array_filter($this->getMappedFields(), function ($value) {
193 4
            return $value !== 'id';
194 4
        });
195
196 4
        foreach ($mappedFields as $key) {
197
            // see if association is in meta
198 4
            if (null !== $mapping = $this->getAssociationMapping($key)) {
199 4
                $this->addAssociationModifiers($builder, $key, $mapping, $startIndex, $endIndex);
200 4
                continue;
201
            }
202
203
            // see if field is in meta
204 4
            if (null !== $mapping = $this->getFieldMapping($key)) {
205 4
                $this->addFieldModifiers($builder, $key, $mapping, $startIndex, $endIndex);
206 4
                continue;
207
            }
208
        }
209 4
    }
210
211
    /**
212
     * @param FeedBuilderInterface $builder
213
     * @param string               $association The association name
214
     * @param array                $mapping     The association mapping
215
     * @param int                  $startIndex
216
     * @param int                  $endIndex
217
     *
218
     * @return int The updated index
219
     */
220 4 View Code Duplication
    protected function addAssociationModifiers(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
221
        FeedBuilderInterface $builder,
222
        $association,
223
        array $mapping,
224
        $startIndex,
225
        $endIndex
226
    ) {
227 4
        $transformer = new EntityToIdTransformer($this->getEntityManager());
228
229 4
        if ($mapping['type'] & ClassMetadataInfo::TO_MANY) {
230 4
            $transformer = new TraversingTransformer($transformer);
231
        }
232
233 4
        $this->addTransformerBetween($builder, $transformer, $association, $startIndex, $endIndex);
234 4
    }
235
236
    /**
237
     * @param FeedBuilderInterface $builder
238
     * @param string               $field      The field name
239
     * @param array                $mapping    The field mapping
240
     * @param int                  $startIndex
241
     * @param int                  $endIndex
242
     */
243 4
    protected function addFieldModifiers(
244
        FeedBuilderInterface $builder,
245
        $field,
246
        array $mapping,
247
        $startIndex,
248
        $endIndex
249
    ) {
250
        // always transform node text values
251 4
        $this->addTransformerBetween($builder, new NodeToStringTransformer(), $field, $startIndex, $endIndex);
252
253
        // see if we need to translate it using foreign mapping
254 4
        $foreignMapping = $this->getForeignMapping();
255 4 View Code Duplication
        if (array_key_exists($field, $foreignMapping)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
256
            $transformer = new ForeignMappingTransformer($field, $foreignMapping[$field]);
257
            $this->addTransformerBetween($builder, $transformer, $field, $startIndex, $endIndex);
258
        }
259
260 4
        $this->addFieldTypeModifiers($builder, $field, $mapping, $startIndex, $endIndex);
261 4
    }
262
263
    /**
264
     * @param FeedBuilderInterface $builder
265
     * @param string               $field      The field name
266
     * @param array                $mapping    The field mapping
267
     * @param int                  $startIndex
268
     * @param int                  $endIndex
269
     */
270 4
    protected function addFieldTypeModifiers(FeedBuilderInterface $builder, $field, array $mapping, $startIndex, $endIndex)
271
    {
272
        // try to cast types
273 4
        switch ($mapping['type']) {
274 4 View Code Duplication
            case 'string':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
275 4
                $this->addTransformerBetween($builder, new MultiLineToSingleLineTransformer(), $field, $startIndex, $endIndex);
276 4
                $this->addTransformerBetween($builder, new MultiSpaceToSingleSpaceTransformer(), $field, $startIndex, $endIndex);
277 4
                $this->addTransformerBetween($builder, new NormalizedStringTransformer(), $field, $startIndex, $endIndex);
278 4
                break;
279 4 View Code Duplication
            case 'text':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
280 4
                $this->addTransformerBetween($builder, new MultiSpaceToSingleSpaceTransformer(), $field, $startIndex, $endIndex);
281 4
                $this->addTransformerBetween($builder, new NormalizedStringTransformer(), $field, $startIndex, $endIndex);
282 4
                break;
283
284 4
            case 'integer':
285 4 View Code Duplication
            case 'smallint':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
286 4
                $this->addTransformerBetween(
287 4
                    $builder,
288 4
                    new LocalizedStringToNumberTransformer($this->options['number_locale'], 0, true, null),
289 4
                    $field,
290 4
                    $startIndex,
291 4
                    $endIndex
292
                );
293 4
                break;
294 4 View Code Duplication
            case 'decimal':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
295
                $this->addTransformerBetween(
296
                    $builder,
297
                    new LocalizedStringToNumberTransformer($this->options['number_locale'], $mapping['scale'], true, null),
298
                    $field,
299
                    $startIndex,
300
                    $endIndex
301
                );
302
                break;
303
304 4 View Code Duplication
            case 'boolean':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
305
                $this->addTransformerBetween(
306
                    $builder,
307
                    new StringToBooleanTransformer(['ja', 'j', 'y'], ['nee', 'n']),
308
                    $field,
309
                    $startIndex,
310
                    $endIndex
311
                );
312
                break;
313
314 4
            case 'date':
315 4 View Code Duplication
            case 'datetime':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
316 4
                switch ($this->options['date_locale']) {
317 4
                    case 'nl':
318
                        $transformer = new DutchStringToDateTimeTransformer();
319
                        break;
320
321
                    default:
322 4
                        $transformer = new StringToDateTimeTransformer();
323
324 4
                        break;
325
                }
326
327 4
                $this->addTransformerBetween($builder, $transformer, $field, $startIndex, $endIndex);
328 4
                $this->addTransformerBetween($builder, new DateTimeToIso8601Transformer(), $field, $startIndex, $endIndex);
329 4
                break;
330
        }
331
332 4
        if ($mapping['nullable']) {
333
            $this->addTransformerBetween($builder, new EmptyValueToNullTransformer(), $field, $startIndex, $endIndex);
334
        }
335 4
    }
336
337
    /**
338
     * @param FeedBuilderInterface $builder
339
     * @param int                  $startStartIndex
340
     * @param int                  $endIndex
341
     *
342
     * @internal param int $index The index to start adding modifiers with
343
     */
344 4 View Code Duplication
    protected function addFinalModifiers(FeedBuilderInterface $builder, $startStartIndex, $endIndex)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
345
    {
346
        // set default values
347 4
        $this->addModifierBetween($builder, new DefaultValuesTransformer($this->options['default_values']), $startStartIndex, $endIndex);
348
349
        // scrub obsolete fields
350 4
        $this->addModifierBetween($builder, new ObsoleteFieldsTransformer($this->getMappedFields()), $startStartIndex, $endIndex);
351 4
    }
352
353
    /**
354
     * @return EntityManagerInterface
355
     */
356 4
    protected function getEntityManager()
357
    {
358 4
        return $this->doctrine->getManager();
359
    }
360
}
361