Completed
Pull Request — master (#8491)
by Stefan
18:30 queued 07:04
created

ZoneContext::theStoreHasZones()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
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
declare(strict_types=1);
13
14
namespace Sylius\Behat\Context\Setup;
15
16
use Behat\Behat\Context\Context;
17
use Doctrine\Common\Persistence\ObjectManager;
18
use Sylius\Behat\Service\SharedStorageInterface;
19
use Sylius\Component\Addressing\Factory\ZoneFactoryInterface;
20
use Sylius\Component\Addressing\Model\CountryInterface;
21
use Sylius\Component\Addressing\Model\ProvinceInterface;
22
use Sylius\Component\Addressing\Model\Scope;
23
use Sylius\Component\Addressing\Model\ZoneInterface;
24
use Sylius\Component\Addressing\Model\ZoneMemberInterface;
25
use Sylius\Component\Core\Formatter\StringInflector;
26
use Sylius\Component\Core\Model\ChannelInterface;
27
use Sylius\Component\Resource\Factory\FactoryInterface;
28
use Sylius\Component\Resource\Model\CodeAwareInterface;
29
use Sylius\Component\Resource\Repository\RepositoryInterface;
30
use Symfony\Component\Intl\Intl;
31
32
final class ZoneContext implements Context
33
{
34
    /**
35
     * @var SharedStorageInterface
36
     */
37
    private $sharedStorage;
38
39
    /**
40
     * @var RepositoryInterface
41
     */
42
    private $zoneRepository;
43
44
    /**
45
     * @var ObjectManager
46
     */
47
    private $objectManager;
48
49
    /**
50
     * @var ZoneFactoryInterface
51
     */
52
    private $zoneFactory;
53
54
    /**
55
     * @var FactoryInterface
56
     */
57
    private $zoneMemberFactory;
58
59
    /**
60
     * @param SharedStorageInterface $sharedStorage
61
     * @param RepositoryInterface $zoneRepository
62
     * @param ObjectManager $objectManager
63
     * @param ZoneFactoryInterface $zoneFactory
64
     * @param FactoryInterface $zoneMemberFactory
65
     */
66
    public function __construct(
67
        SharedStorageInterface $sharedStorage,
68
        RepositoryInterface $zoneRepository,
69
        ObjectManager $objectManager,
70
        ZoneFactoryInterface $zoneFactory,
71
        FactoryInterface $zoneMemberFactory
72
    ) {
73
        $this->sharedStorage = $sharedStorage;
74
        $this->zoneRepository = $zoneRepository;
75
        $this->objectManager = $objectManager;
76
        $this->zoneFactory = $zoneFactory;
77
        $this->zoneMemberFactory = $zoneMemberFactory;
78
    }
79
80
    /**
81
     * @Given /^there is a zone "The Rest of the World" containing all other countries$/
82
     */
83
    public function thereIsAZoneTheRestOfTheWorldContainingAllOtherCountries()
84
    {
85
        $restOfWorldCountries = Intl::getRegionBundle()->getCountryNames('en');
86
        unset($restOfWorldCountries['US']);
87
88
        $zone = $this->zoneFactory->createWithMembers(array_keys($restOfWorldCountries));
89
        $zone->setType(ZoneInterface::TYPE_COUNTRY);
90
        $zone->setCode('RoW');
91
        $zone->setName('The Rest of the World');
92
93
        $this->zoneRepository->add($zone);
94
    }
95
96
    /**
97
     * @Given default tax zone is :zone
98
     */
99
    public function defaultTaxZoneIs(ZoneInterface $zone)
100
    {
101
        /** @var ChannelInterface $channel */
102
        $channel = $this->sharedStorage->get('channel');
103
        $channel->setDefaultTaxZone($zone);
104
105
        $this->objectManager->flush();
106
    }
107
108
    /**
109
     * @Given the store does not have any zones defined
110
     */
111
    public function theStoreDoesNotHaveAnyZonesDefined()
112
    {
113
        $zones = $this->zoneRepository->findAll();
114
115
        foreach ($zones as $zone) {
116
            $this->zoneRepository->remove($zone);
117
        }
118
    }
119
120
    /**
121
     * @Given the store has (also) a zone :zoneName
122
     * @Given the store has a zone :zoneName with code :code
123
     * @Given the store also has a zone :zoneName with code :code
124
     */
125
    public function theStoreHasAZoneWithCode(string $zoneName, string $code = null): void
126
    {
127
        $this->saveZone($this->createZone($zoneName, $code, Scope::ALL), 'zone');
128
    }
129
130
    /**
131
     * @Given the store has zones :firstName, :secondName and :thirdName
132
     */
133
    public function theStoreHasZones(string ...$names): void
134
    {
135
        foreach ($names as $name) {
136
            $this->theStoreHasAZoneWithCode($name);
137
        }
138
    }
139
140
    /**
141
     * @Given the store has a :scope zone :zoneName with code :code
142
     */
143
    public function theStoreHasAScopedZoneWithCode($scope, $zoneName, $code)
144
    {
145
        $this->saveZone($this->createZone($zoneName, $code, $scope), $scope . '_zone');
146
    }
147
148
    /**
149
     * @Given /^(it)(?:| also) has the ("([^"]+)" country) member$/
150
     * @Given /^(this zone)(?:| also) has the ("([^"]+)" country) member$/
151
     */
152
    public function itHasTheCountryMemberAndTheCountryMember(
153
        ZoneInterface $zone,
154
        CountryInterface $country
155
    ) {
156
        $zone->setType(ZoneInterface::TYPE_COUNTRY);
157
        $zone->addMember($this->createZoneMember($country));
158
159
        $this->objectManager->flush();
160
    }
161
162
    /**
163
     * @Given /^(it) has the ("[^"]+" province) member$/
164
     * @Given /^(it) also has the ("[^"]+" province) member$/
165
     */
166
    public function itHasTheProvinceMemberAndTheProvinceMember(
167
        ZoneInterface $zone,
168
        ProvinceInterface $province
169
    ) {
170
        $zone->setType(ZoneInterface::TYPE_PROVINCE);
171
        $zone->addMember($this->createZoneMember($province));
172
173
        $this->objectManager->flush();
174
    }
175
176
    /**
177
     * @Given /^(it) has the (zone named "([^"]+)")$/
178
     * @Given /^(it) also has the (zone named "([^"]+)")$/
179
     */
180
    public function itHasTheZoneMemberAndTheZoneMember(
181
        ZoneInterface $parentZone,
182
        ZoneInterface $childZone
183
    ) {
184
        $parentZone->setType(ZoneInterface::TYPE_ZONE);
185
        $parentZone->addMember($this->createZoneMember($childZone));
186
187
        $this->objectManager->flush();
188
    }
189
190
    /**
191
     * @param CodeAwareInterface $zoneMember
192
     *
193
     * @return ZoneMemberInterface
194
     */
195
    private function createZoneMember(CodeAwareInterface $zoneMember)
196
    {
197
        $code = $zoneMember->getCode();
198
        /** @var ZoneMemberInterface $zoneMember */
199
        $zoneMember = $this->zoneMemberFactory->createNew();
200
        $zoneMember->setCode($code);
201
202
        return $zoneMember;
203
    }
204
205
    /**
206
     * @param string $name
207
     * @param string|null $code
208
     * @param string $scope
209
     *
210
     * @return ZoneInterface
211
     */
212
    private function createZone(string $name, ?string $code = null, ?string $scope = Scope::ALL): ZoneInterface
213
    {
214
        $zone = $this->zoneFactory->createTyped(ZoneInterface::TYPE_ZONE);
215
        $zone->setCode($code ?? StringInflector::nameToCode($name));
216
        $zone->setName($name);
217
        $zone->setScope($scope);
218
219
        return $zone;
220
    }
221
222
    /**
223
     * @param ZoneInterface $zone
224
     * @param string $key
225
     */
226
    private function saveZone($zone, $key)
227
    {
228
        $this->sharedStorage->set($key, $zone);
229
        $this->zoneRepository->add($zone);
230
    }
231
}
232