ProductCreate   A
last analyzed

Complexity

Total Complexity 5

Size/Duplication

Total Lines 113
Duplicated Lines 7.08 %

Coupling/Cohesion

Components 0
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 5
lcom 0
cbo 2
dl 8
loc 113
ccs 93
cts 93
cp 1
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
B getConfigTreeBuilder() 8 110 5

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
declare(strict_types=1);
4
5
/*
6
 * This software may be modified and distributed under the terms
7
 * of the MIT license. See the LICENSE file for details.
8
 */
9
10
namespace Shapin\Stripe\Configuration;
11
12
use Shapin\Stripe\Model\Product\Product;
13
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
14
use Symfony\Component\Config\Definition\ConfigurationInterface;
15
16
class ProductCreate implements ConfigurationInterface
17
{
18 8
    public function getConfigTreeBuilder()
19
    {
20 8
        $treeBuilder = new TreeBuilder('shapin_stripe');
21 8
        $rootNode = $treeBuilder->getRootNode();
22
23
        $rootNode
24 8
            ->children()
25 8
                ->scalarNode('id')
26 8
                    ->info('An identifier will be randomly generated by Stripe. You can optionally override this ID, but the ID must be unique across all products in your Stripe account. Applicable to both service and good types.')
27 8
                ->end()
28 8
                ->scalarNode('name')
29 8
                    ->isRequired()
30 8
                    ->info('The product’s name, meant to be displayable to the customer. Applicable to both service and good types.')
31 8
                ->end()
32 8
                ->enumNode('type')
33 8
                    ->isRequired()
34 8
                    ->info('The type of the product. The product is either of type service, which is eligible for use with Subscriptions and Plans or good, which is eligible for use with Orders and SKUs.')
35 8
                    ->values(['service', 'good'])
36 8
                ->end()
37 8
                ->booleanNode('active')
38 8
                    ->info('Whether the product is currently available for purchase. Defaults to true.')
39 8
                ->end()
40 8
                ->arrayNode('attributes')
41 8
                    ->scalarPrototype()->end()
42 8
                    ->info('A list of up to 5 alphanumeric attributes. Applicable to both service and good types.')
43 8
                    ->validate()
44
                        ->ifTrue(function ($c) {
45 1
                            return 5 < \count($c);
46 8
                        })
47 8
                        ->thenInvalid('You can have up to 5 attributes.')
48 8
                    ->end()
49 8
                ->end()
50 8
                ->scalarNode('caption')
51 8
                    ->info('A short one-line description of the product, meant to be displayable to the customer. May only be set if type=good.')
52 8
                ->end()
53 8
                ->arrayNode('deactivate_on')
54 8
                    ->prototype('scalar')->end()
55 8
                    ->info('An array of Connect application names or identifiers that should not be able to order the SKUs for this product. May only be set if type=good.')
56 8
                ->end()
57 8
                ->scalarNode('description')
58 8
                    ->info('The product’s description, meant to be displayable to the customer. May only be set if type=good.')
59 8
                ->end()
60 8
                ->arrayNode('images')
61 8
                    ->scalarPrototype()->end()
62 8
                    ->info('A list of up to 8 URLs of images for this product, meant to be displayable to the customer. May only be set if type=good.')
63 8
                    ->validate()
64
                        ->ifTrue(function ($c) {
65 1
                            return 8 < \count($c);
66 8
                        })
67 8
                        ->thenInvalid('You can have up to 8 images.')
68 8
                    ->end()
69 8
                ->end()
70 8
                ->arrayNode('metadata')
71 8
                    ->scalarPrototype()->end()
72 8
                    ->info('Set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format. Individual keys can be unset by posting an empty value to them. All keys can be unset by posting an empty value to metadata.')
73 8
                ->end()
74 8
                ->arrayNode('package_dimensions')
75 8
                    ->children()
76 8
                        ->floatNode('height')
77 8
                            ->isRequired()
78 8
                            ->info('Height, in inches. Maximum precision is 2 decimal places.')
79 8
                        ->end()
80 8
                        ->floatNode('length')
81 8
                            ->isRequired()
82 8
                            ->info('Length, in inches. Maximum precision is 2 decimal places.')
83 8
                        ->end()
84 8
                        ->floatNode('weight')
85 8
                            ->isRequired()
86 8
                            ->info('Weight, in ounces. Maximum precision is 2 decimal places.')
87 8
                        ->end()
88 8
                        ->floatNode('width')
89 8
                            ->isRequired()
90 8
                            ->info('Width, in inches. Maximum precision is 2 decimal places.')
91 8
                        ->end()
92 8
                    ->end()
93 8
                    ->info('The dimensions of this product for shipping purposes. A SKU associated with this product can override this value by having its own package_dimensions. May only be set if type=good.')
94 8
                ->end()
95 8
                ->booleanNode('shippable')
96 8
                    ->info('Whether this product is shipped (i.e., physical goods). Defaults to true. May only be set if type=good.')
97 8
                ->end()
98 8
                ->scalarNode('url')
99 8
                    ->info('A URL of a publicly-accessible webpage for this product. May only be set if type=good.')
100 8
                ->end()
101 8
            ->end()
102
        ;
103
104
        $rootNode
105 8
            ->validate()
106
                ->always(function ($c) {
107 6
                    if (empty($c['deactivate_on'])) {
108 5
                        unset($c['deactivate_on']);
109
                    }
110
111 6
                    return $c;
112 8
                })
113 8
            ->end()
114
        ;
115
116 8
        $goodOnlyFields = ['caption', 'deactivate_on', 'description', 'package_dimensions', 'shippable', 'url'];
117 8 View Code Duplication
        foreach ($goodOnlyFields as $field) {
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...
118 8
            $rootNode->validate()
119
                ->ifTrue(function ($v) use ($field) {
120 6
                    return isset($v['type']) && Product::TYPE_GOOD !== $v['type'] && isset($v[$field]);
121 8
                })
122 8
                ->thenInvalid("You can only set \"$field\" for \"good\" products.")
123 8
            ->end();
124
        }
125
126 8
        return $treeBuilder;
127
    }
128
}
129