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 |
||
| 17 | class FeedBuilder implements FeedBuilderInterface |
||
| 18 | { |
||
| 19 | /** |
||
| 20 | * @var EventDispatcherInterface |
||
| 21 | */ |
||
| 22 | protected $eventDispatcher; |
||
| 23 | |||
| 24 | /** |
||
| 25 | * @var array<ModifierInterface, boolean> |
||
| 26 | */ |
||
| 27 | protected $modifiers = []; |
||
| 28 | |||
| 29 | /** |
||
| 30 | * @param EventDispatcherInterface $eventDispatcher |
||
| 31 | */ |
||
| 32 | 26 | public function __construct(EventDispatcherInterface $eventDispatcher) |
|
| 36 | |||
| 37 | /** |
||
| 38 | * @inheritdoc |
||
| 39 | */ |
||
| 40 | 20 | View Code Duplication | public function addModifier(ModifierInterface $modifier, $position = null, $continue = null) |
|
|
|||
| 41 | { |
||
| 42 | 20 | if (null === $position) { |
|
| 43 | 10 | $position = sizeof($this->modifiers) ? (max(array_keys($this->modifiers)) + 1) : 0; |
|
| 44 | } |
||
| 45 | |||
| 46 | 20 | if (null === $continue) { |
|
| 47 | 18 | $continue = (!$modifier instanceof FilterInterface) && (!$modifier instanceof ValidatorInterface); |
|
| 48 | } |
||
| 49 | |||
| 50 | 20 | if (array_key_exists($position, $this->modifiers)) { |
|
| 51 | 2 | throw new \InvalidArgumentException(sprintf('There already is a modifier at position %d', $position)); |
|
| 52 | } |
||
| 53 | |||
| 54 | 20 | $this->modifiers[$position] = [$modifier, $continue]; |
|
| 55 | 20 | } |
|
| 56 | |||
| 57 | /** |
||
| 58 | * @inheritdoc |
||
| 59 | */ |
||
| 60 | 10 | public function getModifiers() |
|
| 64 | |||
| 65 | /** |
||
| 66 | * @inheritdoc |
||
| 67 | */ |
||
| 68 | 6 | public function addTransformer(TransformerInterface $transformer, $field, $position = null, $continue = true) |
|
| 72 | |||
| 73 | /** |
||
| 74 | * @inheritdoc |
||
| 75 | */ |
||
| 76 | 4 | public function hasModifierAt($position) |
|
| 80 | |||
| 81 | /** |
||
| 82 | * @inheritdoc |
||
| 83 | */ |
||
| 84 | 2 | View Code Duplication | public function removeModifier(ModifierInterface $modifier) |
| 85 | { |
||
| 86 | 2 | foreach ($this->modifiers as $position => list($mod)) { |
|
| 87 | 2 | if ($mod === $modifier) { |
|
| 88 | 2 | unset($this->modifiers[$position]); |
|
| 89 | } |
||
| 90 | } |
||
| 91 | 2 | } |
|
| 92 | |||
| 93 | /** |
||
| 94 | * @inheritdoc |
||
| 95 | */ |
||
| 96 | 4 | View Code Duplication | public function removeModifierAt($position) |
| 104 | |||
| 105 | /** |
||
| 106 | * @inheritdoc |
||
| 107 | */ |
||
| 108 | 10 | public function build(FeedTypeInterface $type, ReaderInterface $reader, array $options = []) |
|
| 109 | { |
||
| 110 | 10 | $resolver = $this->getOptionsResolver($type); |
|
| 111 | 10 | $type->build($this, $resolver->resolve($options)); |
|
| 112 | |||
| 113 | 10 | if (!$itemName = $type->getItemName()) { |
|
| 114 | throw new \LogicException( |
||
| 115 | sprintf('"%s::getItemName()" must return a valid item name', get_class($type)) |
||
| 116 | ); |
||
| 117 | } |
||
| 118 | |||
| 119 | 10 | return $this->createFeed($reader, $this->eventDispatcher, $itemName); |
|
| 120 | } |
||
| 121 | |||
| 122 | /** |
||
| 123 | * @param ReaderInterface $reader |
||
| 124 | * @param EventDispatcherInterface $dispatcher |
||
| 125 | * @param string $itemName |
||
| 126 | * |
||
| 127 | * @return Feed |
||
| 128 | */ |
||
| 129 | 10 | protected function createFeed(ReaderInterface $reader, EventDispatcherInterface $dispatcher, $itemName) |
|
| 130 | { |
||
| 131 | 10 | if ($reader instanceof XmlReader) { |
|
| 132 | 4 | $reader->setNodeCallback($itemName); |
|
| 133 | } |
||
| 134 | |||
| 135 | 10 | $feed = new Feed($reader, $dispatcher); |
|
| 136 | |||
| 137 | /** @var ModifierInterface $modifier */ |
||
| 138 | 10 | foreach ($this->modifiers as $position => list($modifier, $continue)) { |
|
| 139 | 6 | $feed->addModifier($modifier, $position, $continue); |
|
| 140 | } |
||
| 141 | |||
| 142 | 10 | return $feed; |
|
| 143 | } |
||
| 144 | |||
| 145 | /** |
||
| 146 | * @param FeedTypeInterface $type |
||
| 147 | * |
||
| 148 | * @return OptionsResolver |
||
| 149 | */ |
||
| 150 | 10 | protected function getOptionsResolver(FeedTypeInterface $type) |
|
| 157 | } |
||
| 158 |
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.