Completed
Push — remove-phpcr-context ( 64497c )
by Kamil
33:54 queued 13:21
created

AddressExampleFactory::create()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 29
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 29
rs 8.8571
c 0
b 0
f 0
cc 2
eloc 20
nc 2
nop 1
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
namespace Sylius\Bundle\CoreBundle\Fixture\Factory;
13
14
use Sylius\Bundle\CoreBundle\Fixture\OptionsResolver\LazyOption;
15
use Sylius\Component\Addressing\Model\ProvinceInterface;
16
use Sylius\Component\Core\Model\AddressInterface;
17
use Sylius\Component\Core\Model\CustomerInterface;
18
use Sylius\Component\Resource\Factory\FactoryInterface;
19
use Sylius\Component\Resource\Repository\RepositoryInterface;
20
use Symfony\Component\OptionsResolver\Options;
21
use Symfony\Component\OptionsResolver\OptionsResolver;
22
use Webmozart\Assert\Assert;
23
24
/**
25
 * @author Jan Góralski <[email protected]>
26
 */
27
class AddressExampleFactory extends AbstractExampleFactory implements ExampleFactoryInterface
28
{
29
    /**
30
     * @var FactoryInterface
31
     */
32
    private $addressFactory;
33
34
    /**
35
     * @var RepositoryInterface
36
     */
37
    private $countryRepository;
38
39
    /**
40
     * @var RepositoryInterface
41
     */
42
    private $customerRepository;
43
44
    /**
45
     * @var \Faker\Generator
46
     */
47
    private $faker;
48
49
    /**
50
     * @var OptionsResolver
51
     */
52
    private $optionsResolver;
53
54
    /**
55
     * @param FactoryInterface $addressFactory
56
     * @param RepositoryInterface $countryRepository
57
     * @param RepositoryInterface $customerRepository
58
     */
59
    public function __construct(
60
        FactoryInterface $addressFactory,
61
        RepositoryInterface $countryRepository,
62
        RepositoryInterface $customerRepository
63
    ) {
64
        $this->addressFactory = $addressFactory;
65
        $this->countryRepository = $countryRepository;
66
        $this->customerRepository = $customerRepository;
67
68
        $this->faker = \Faker\Factory::create();
69
        $this->optionsResolver = new OptionsResolver();
70
71
        $this->configureOptions($this->optionsResolver);
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77
    protected function configureOptions(OptionsResolver $resolver)
78
    {
79
        $resolver
80
            ->setDefault('first_name', function (Options $options) {
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
81
                return $this->faker->firstName;
82
            })
83
            ->setDefault('last_name', function (Options $options) {
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
84
                return $this->faker->lastName;
85
            })
86
            ->setDefault('phone_number', function (Options $options) {
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
87
                return mt_rand(1, 100) > 50 ? $this->faker->phoneNumber : null;
88
            })
89
            ->setDefault('company', function (Options $options) {
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
90
                return mt_rand(1, 100) > 50 ? $this->faker->company : null;
91
            })
92
            ->setDefault('street', function (Options $options) {
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
93
                return $this->faker->streetAddress;
94
            })
95
            ->setDefault('city', function (Options $options) {
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
96
                return $this->faker->city;
97
            })
98
            ->setDefault('postcode', function (Options $options) {
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
99
                return $this->faker->postcode;
100
            })
101
            ->setDefault('country_code', function (Options $options) {
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
102
                $countries = $this->countryRepository->findAll();
103
                shuffle($countries);
104
105
                return array_pop($countries)->getCode();
106
            })
107
            ->setAllowedTypes('country_code', ['string'])
108
            ->setDefault('province_name', null)
109
            ->setAllowedTypes('province_name', ['null', 'string'])
110
            ->setDefault('province_code', null)
111
            ->setAllowedTypes('province_code', ['null', 'string'])
112
            ->setDefault('customer', LazyOption::randomOne($this->customerRepository))
113
            ->setAllowedTypes('customer', ['string', CustomerInterface::class])
114
            ->setNormalizer('customer', LazyOption::findOneBy($this->customerRepository, 'email'))
115
        ;
116
    }
117
118
    /**
119
     * {@inheritdoc}
120
     */
121
    public function create(array $options = [])
122
    {
123
        $options = $this->optionsResolver->resolve($options);
124
125
        /** @var AddressInterface $address */
126
        $address = $this->addressFactory->createNew();
127
        $address->setFirstName($options['first_name']);
128
        $address->setLastName($options['last_name']);
129
        $address->setPhoneNumber($options['phone_number']);
130
        $address->setCompany($options['company']);
131
        $address->setStreet($options['street']);
132
        $address->setCity($options['city']);
133
        $address->setPostcode($options['postcode']);
134
135
        $this->assertCountryCodeIsValid($options['country_code']);
136
        $address->setCountryCode($options['country_code']);
137
138
        if (null !== $options['province_code']) {
139
            $this->assertProvinceCodeIsValid($options['province_code'], $options['country_code']);
140
            $address->setProvinceCode($options['province_code']);
141
        } else {
142
            $this->assertCountryHasNoProvinces($options['country_code']);
143
            $address->setProvinceName($options['province_name']);
144
        }
145
146
        $options['customer']->addAddress($address);
147
148
        return $address;
149
    }
150
151
    /**
152
     * @param string $code
153
     */
154
    private function assertCountryCodeIsValid($code)
155
    {
156
        $country = $this->countryRepository->findOneBy(['code' => $code]);
157
        Assert::notNull($country);
158
    }
159
160
    /**
161
     * @param string $provinceCode
162
     * @param string $countryCode
163
     */
164
    private function assertProvinceCodeIsValid($provinceCode, $countryCode)
165
    {
166
        $country = $this->countryRepository->findOneBy(['code' => $countryCode]);
167
168
        /** @var ProvinceInterface $province */
169
        foreach ($country->getProvinces() as $province) {
170
            if ($province->getCode() === $provinceCode) {
171
                return;
172
            }
173
        }
174
        throw new \InvalidArgumentException('Provided province code is not valid for "%s"', $country->getName());
175
    }
176
177
    /**
178
     * @param string $countryCode
179
     */
180
    private function assertCountryHasNoProvinces($countryCode)
181
    {
182
        $country = $this->countryRepository->findOneBy(['code' => $countryCode]);
183
        Assert::allIsEmpty($country->getProvinces());
184
    }
185
}
186