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) { |
|
|
|
|
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
|
|
|
|
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.