These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of the Sylius package. |
||
5 | * |
||
6 | * (c) Paweł Jędrzejewski |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | declare(strict_types=1); |
||
13 | |||
14 | namespace Sylius\Bundle\CoreBundle\Fixture\Factory; |
||
15 | |||
16 | use Doctrine\Common\Collections\Collection; |
||
17 | use Sylius\Bundle\CoreBundle\Fixture\OptionsResolver\LazyOption; |
||
18 | use Sylius\Component\Addressing\Model\Country; |
||
19 | use Sylius\Component\Addressing\Model\ProvinceInterface; |
||
20 | use Sylius\Component\Core\Model\AddressInterface; |
||
21 | use Sylius\Component\Core\Model\CustomerInterface; |
||
22 | use Sylius\Component\Resource\Factory\FactoryInterface; |
||
23 | use Sylius\Component\Resource\Repository\RepositoryInterface; |
||
24 | use Symfony\Component\OptionsResolver\Options; |
||
25 | use Symfony\Component\OptionsResolver\OptionsResolver; |
||
26 | use Webmozart\Assert\Assert; |
||
27 | |||
28 | class AddressExampleFactory extends AbstractExampleFactory |
||
29 | { |
||
30 | /** |
||
31 | * @var FactoryInterface |
||
32 | */ |
||
33 | private $addressFactory; |
||
34 | |||
35 | /** |
||
36 | * @var RepositoryInterface |
||
37 | */ |
||
38 | private $countryRepository; |
||
39 | |||
40 | /** |
||
41 | * @var RepositoryInterface |
||
42 | */ |
||
43 | private $customerRepository; |
||
44 | |||
45 | /** |
||
46 | * @var \Faker\Generator |
||
47 | */ |
||
48 | private $faker; |
||
49 | |||
50 | /** |
||
51 | * @var OptionsResolver |
||
52 | */ |
||
53 | private $optionsResolver; |
||
54 | |||
55 | /** |
||
56 | * @param FactoryInterface $addressFactory |
||
57 | * @param RepositoryInterface $countryRepository |
||
58 | * @param RepositoryInterface $customerRepository |
||
59 | */ |
||
60 | public function __construct( |
||
61 | FactoryInterface $addressFactory, |
||
62 | RepositoryInterface $countryRepository, |
||
63 | RepositoryInterface $customerRepository |
||
64 | ) { |
||
65 | $this->addressFactory = $addressFactory; |
||
66 | $this->countryRepository = $countryRepository; |
||
67 | $this->customerRepository = $customerRepository; |
||
68 | |||
69 | $this->faker = \Faker\Factory::create(); |
||
70 | $this->optionsResolver = new OptionsResolver(); |
||
71 | |||
72 | $this->configureOptions($this->optionsResolver); |
||
73 | } |
||
74 | |||
75 | /** |
||
76 | * {@inheritdoc} |
||
77 | */ |
||
78 | protected function configureOptions(OptionsResolver $resolver): void |
||
79 | { |
||
80 | $resolver |
||
81 | ->setDefault('first_name', function (Options $options): string { |
||
82 | return $this->faker->firstName; |
||
83 | }) |
||
84 | ->setDefault('last_name', function (Options $options): string { |
||
85 | return $this->faker->lastName; |
||
86 | }) |
||
87 | ->setDefault('phone_number', function (Options $options): ?string { |
||
88 | return random_int(1, 100) > 50 ? $this->faker->phoneNumber : null; |
||
89 | }) |
||
90 | ->setDefault('company', function (Options $options): ?string { |
||
91 | return random_int(1, 100) > 50 ? $this->faker->company : null; |
||
92 | }) |
||
93 | ->setDefault('street', function (Options $options): string { |
||
94 | return $this->faker->streetAddress; |
||
95 | }) |
||
96 | ->setDefault('city', function (Options $options): string { |
||
97 | return $this->faker->city; |
||
98 | }) |
||
99 | ->setDefault('postcode', function (Options $options): string { |
||
100 | return $this->faker->postcode; |
||
101 | }) |
||
102 | ->setDefault('country_code', function (Options $options): string { |
||
103 | $countries = $this->countryRepository->findAll(); |
||
104 | shuffle($countries); |
||
105 | |||
106 | return array_pop($countries)->getCode(); |
||
107 | }) |
||
108 | ->setAllowedTypes('country_code', ['string']) |
||
109 | ->setDefault('province_name', null) |
||
110 | ->setAllowedTypes('province_name', ['null', 'string']) |
||
111 | ->setDefault('province_code', null) |
||
112 | ->setAllowedTypes('province_code', ['null', 'string']) |
||
113 | ->setDefault('customer', LazyOption::randomOne($this->customerRepository)) |
||
114 | ->setAllowedTypes('customer', ['string', CustomerInterface::class, 'null']) |
||
115 | ->setNormalizer('customer', LazyOption::findOneBy($this->customerRepository, 'email')) |
||
116 | ; |
||
117 | } |
||
118 | |||
119 | /** |
||
120 | * {@inheritdoc} |
||
121 | */ |
||
122 | public function create(array $options = []): AddressInterface |
||
123 | { |
||
124 | $options = $this->optionsResolver->resolve($options); |
||
125 | |||
126 | /** @var AddressInterface $address */ |
||
127 | $address = $this->addressFactory->createNew(); |
||
128 | $address->setFirstName($options['first_name']); |
||
129 | $address->setLastName($options['last_name']); |
||
130 | $address->setPhoneNumber($options['phone_number']); |
||
131 | $address->setCompany($options['company']); |
||
132 | $address->setStreet($options['street']); |
||
133 | $address->setCity($options['city']); |
||
134 | $address->setPostcode($options['postcode']); |
||
135 | |||
136 | $this->assertCountryCodeIsValid($options['country_code']); |
||
137 | $address->setCountryCode($options['country_code']); |
||
138 | |||
139 | $this->resolveCountryProvince($options, $address); |
||
140 | |||
141 | if (isset($options['customer'])) { |
||
142 | $options['customer']->addAddress($address); |
||
143 | } |
||
144 | |||
145 | return $address; |
||
146 | } |
||
147 | |||
148 | /** |
||
149 | * @param string $code |
||
150 | * |
||
151 | * @throws \InvalidArgumentException |
||
152 | */ |
||
153 | private function assertCountryCodeIsValid(string $code): void |
||
154 | { |
||
155 | $country = $this->countryRepository->findOneBy(['code' => $code]); |
||
156 | Assert::notNull($country); |
||
157 | } |
||
158 | |||
159 | /** |
||
160 | * @param string $provinceCode |
||
161 | * @param string $countryCode |
||
162 | * |
||
163 | * @throws \InvalidArgumentException |
||
164 | */ |
||
165 | private function assertProvinceCodeIsValid(string $provinceCode, string $countryCode): void |
||
166 | { |
||
167 | $country = $this->countryRepository->findOneBy(['code' => $countryCode]); |
||
168 | |||
169 | /** @var ProvinceInterface $province */ |
||
170 | foreach ($country->getProvinces() as $province) { |
||
171 | if ($province->getCode() === $provinceCode) { |
||
172 | return; |
||
173 | } |
||
174 | } |
||
175 | |||
176 | throw new \InvalidArgumentException(sprintf('Provided province code is not valid for "%s"', $country->getName())); |
||
177 | } |
||
178 | |||
179 | /** |
||
180 | * @param array $options |
||
181 | * @param AddressInterface $address |
||
182 | */ |
||
183 | private function provideProvince(array $options, AddressInterface $address): void |
||
184 | { |
||
185 | /** @var Country $country */ |
||
186 | $country = $this->countryRepository->findOneBy(['code' => $options['country_code']]); |
||
187 | |||
188 | if ($country->hasProvinces()) { |
||
189 | $address->setProvinceCode($this->getProvinceCode($country->getProvinces(), $options['province_name'])); |
||
0 ignored issues
–
show
|
|||
190 | |||
191 | return; |
||
192 | } |
||
193 | |||
194 | $address->setProvinceName($options['province_name']); |
||
195 | } |
||
196 | |||
197 | /** |
||
198 | * @param Collection $provinces |
||
199 | * @param string $provinceName |
||
200 | * |
||
201 | * @return string |
||
202 | * |
||
203 | * @throws \InvalidArgumentException |
||
204 | */ |
||
205 | private function getProvinceCode(Collection $provinces, string $provinceName): string |
||
206 | { |
||
207 | /** @var ProvinceInterface $province */ |
||
208 | foreach ($provinces as $province) { |
||
209 | if ($province->getName() === $provinceName) { |
||
210 | return $province->getCode(); |
||
211 | } |
||
212 | } |
||
213 | |||
214 | throw new \InvalidArgumentException(sprintf('Country has defined provinces, but %s is not one of them', $provinceName)); |
||
215 | } |
||
216 | |||
217 | /** |
||
218 | * @param array $options |
||
219 | * @param AddressInterface $address |
||
220 | */ |
||
221 | private function resolveCountryProvince(array $options, AddressInterface $address): void |
||
222 | { |
||
223 | if (null !== $options['province_code']) { |
||
224 | $this->assertProvinceCodeIsValid($options['province_code'], $options['country_code']); |
||
225 | $address->setProvinceCode($options['province_code']); |
||
226 | |||
227 | return; |
||
228 | } |
||
229 | |||
230 | if (null !== $options['province_name']) { |
||
231 | $this->provideProvince($options, $address); |
||
232 | } |
||
233 | } |
||
234 | } |
||
235 |
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.