ParserBuilder::addModifier()   A
last analyzed

Complexity

Conditions 6
Paths 18

Size

Total Lines 16

Duplication

Lines 16
Ratio 100 %

Code Coverage

Tests 9
CRAP Score 6

Importance

Changes 0
Metric Value
dl 16
loc 16
ccs 9
cts 9
cp 1
rs 9.1111
c 0
b 0
f 0
cc 6
nc 18
nop 3
crap 6
1
<?php
2
3
namespace TreeHouse\IoBundle\Scrape\Parser;
4
5
use Symfony\Component\EventDispatcher\EventDispatcher;
6
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
7
use Symfony\Component\OptionsResolver\OptionsResolver;
8
use TreeHouse\Feeder\Modifier\Data\Transformer\TransformerInterface;
9
use TreeHouse\Feeder\Modifier\Item\Filter\FilterInterface;
10
use TreeHouse\Feeder\Modifier\Item\ModifierInterface;
11
use TreeHouse\Feeder\Modifier\Item\Transformer\DataTransformer;
12
use TreeHouse\Feeder\Modifier\Item\Validator\ValidatorInterface;
13
use TreeHouse\IoBundle\Scrape\Parser\Type\ParserTypeInterface;
14
15
class ParserBuilder implements ParserBuilderInterface
16
{
17
    /**
18
     * @var EventDispatcherInterface
19
     */
20
    protected $eventDispatcher;
21
22
    /**
23
     * @var ModifierInterface[]
24
     */
25
    protected $modifiers = [];
26
27
    /**
28
     * @param EventDispatcherInterface $eventDispatcher
29
     */
30 22
    public function __construct(EventDispatcherInterface $eventDispatcher = null)
31
    {
32 22
        $this->eventDispatcher = $eventDispatcher ?: new EventDispatcher();
33 22
    }
34
35
    /**
36
     * @inheritdoc
37
     */
38
    public function getEventDispatcher()
39
    {
40
        return $this->eventDispatcher;
41
    }
42
43
    /**
44
     * @return ModifierInterface[]
45
     */
46 10
    public function getModifiers()
47
    {
48 10
        return $this->modifiers;
49
    }
50
51
    /**
52
     * @param ModifierInterface $modifier
53
     * @param int               $position Defaults to the next highest position
54
     * @param bool              $continue Will be determined based on modifier type
55
     *
56
     * @throws \InvalidArgumentException If there already is a modifier at the given position
57
     */
58 16 View Code Duplication
    public function addModifier(ModifierInterface $modifier, $position = null, $continue = null)
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...
59
    {
60 16
        if (null === $position) {
61 10
            $position = sizeof($this->modifiers) ? (max(array_keys($this->modifiers)) + 1) : 0;
62
        }
63
64 16
        if (null === $continue) {
65 14
            $continue = (!$modifier instanceof FilterInterface) && (!$modifier instanceof ValidatorInterface);
66
        }
67
68 16
        if (array_key_exists($position, $this->modifiers)) {
69 2
            throw new \InvalidArgumentException(sprintf('There already is a modifier at position %d', $position));
70
        }
71
72 16
        $this->modifiers[$position] = [$modifier, $continue];
73 16
    }
74
75
    /**
76
     * Adds the given modifier between the start and end index, if there is a vacant position.
77
     *
78
     * @param ModifierInterface $modifier
79
     * @param int               $startIndex
80
     * @param int               $endIndex
81
     * @param bool              $continue
82
     *
83
     * @throws \OutOfBoundsException
84
     */
85 View Code Duplication
    public function addModifierBetween(ModifierInterface $modifier, $startIndex, $endIndex, $continue = null)
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...
86
    {
87
        for ($position = $startIndex; $position <= $endIndex; ++$position) {
88
            if (!$this->hasModifierAt($position)) {
89
                $this->addModifier($modifier, $position, $continue);
90
91
                return;
92
            }
93
        }
94
95
        throw new \OutOfBoundsException(sprintf('No position left between %d and %d', $startIndex, $endIndex));
96
    }
97
98
    /**
99
     * Shortcut for adding a field-value transformer.
100
     *
101
     * @param TransformerInterface $transformer
102
     * @param string               $field
103
     * @param int                  $position
104
     * @param bool                 $continue
105
     */
106 2
    public function addTransformer(TransformerInterface $transformer, $field, $position = null, $continue = true)
107
    {
108 2
        $this->addModifier(new DataTransformer($transformer, $field), $position, $continue);
109 2
    }
110
111
    /**
112
     * Adds the given transformer between the start and end index, if there is a vacant position.
113
     *
114
     * @param TransformerInterface $transformer
115
     * @param string               $field
116
     * @param int                  $startIndex
117
     * @param int                  $endIndex
118
     * @param bool                 $continue
119
     *
120
     * @throws \OutOfBoundsException
121
     */
122
    public function addTransformerBetween(TransformerInterface $transformer, $field, $startIndex, $endIndex, $continue = null)
123
    {
124
        $this->addModifierBetween(new DataTransformer($transformer, $field), $startIndex, $endIndex, $continue);
125
    }
126
127
    /**
128
     * @param int $position
129
     *
130
     * @return bool
131
     */
132
    public function hasModifierAt($position)
133
    {
134
        return array_key_exists($position, $this->modifiers);
135
    }
136
137
    /**
138
     * Removes existing modifier.
139
     *
140
     * @param ModifierInterface $modifier
141
     */
142 2 View Code Duplication
    public function removeModifier(ModifierInterface $modifier)
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...
143
    {
144 2
        foreach ($this->modifiers as $position => list($mod)) {
145 2
            if ($mod === $modifier) {
146 2
                unset($this->modifiers[$position]);
147
            }
148
        }
149 2
    }
150
151
    /**
152
     * Removes modifier at an existing position.
153
     *
154
     * @param int $position
155
     *
156
     * @throws \OutOfBoundsException If modifier does not exist
157
     */
158 4 View Code Duplication
    public function removeModifierAt($position)
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...
159
    {
160 4
        if (!array_key_exists($position, $this->modifiers)) {
161 2
            throw new \OutOfBoundsException(sprintf('There is no modifier at position %d', $position));
162
        }
163
164 2
        unset($this->modifiers[$position]);
165 2
    }
166
167
    /**
168
     * @inheritdoc
169
     */
170 6
    public function build(ParserTypeInterface $type, array $options)
171
    {
172 6
        $resolver = $this->getOptionsResolver($type);
173
174 6
        $type->build($this, $resolver->resolve($options));
175
176 6
        $parser = new DefaultParser($this->eventDispatcher);
177 6
        foreach ($this->modifiers as $position => list($modifier, $continue)) {
178 2
            $parser->addModifier($modifier, $position, $continue);
179
        }
180
181 6
        return $parser;
182
    }
183
184
    /**
185
     * @param ParserTypeInterface $type
186
     *
187
     * @return OptionsResolver
188
     */
189 6
    protected function getOptionsResolver(ParserTypeInterface $type)
190
    {
191 6
        $resolver = new OptionsResolver();
192 6
        $type->setOptions($resolver);
193
194 6
        return $resolver;
195
    }
196
}
197