Completed
Push — master ( abb41b...f9ba0c )
by Kamil
32:48 queued 08:44
created

CoreContext   F

Complexity

Total Complexity 103

Size/Duplication

Total Lines 805
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 22

Importance

Changes 4
Bugs 1 Features 0
Metric Value
wmc 103
c 4
b 1
f 0
lcom 1
cbo 22
dl 0
loc 805
rs 1.263

38 Methods

Rating   Name   Duplication   Size   Complexity  
A iAmLoggedInAsAuthorizationRole() 0 4 1
A iAmLoggedInUser() 0 4 1
A iAmNotLoggedIn() 0 4 1
B storeHasDefaultConfiguration() 0 28 1
B thereAreOrders() 0 53 4
B thereAreFollowingUsers() 0 18 9
B thereAreFollowingCustomers() 0 14 7
A thereAreGroups() 0 14 2
A theFollowingAddressesExist() 0 16 2
A thereIsUser() 0 16 3
A thereIsCustomer() 0 16 3
B productHasTheFollowingVolumeBasedPricing() 0 31 3
A productHasTheFollowingGroupBasedPricing() 0 20 2
A thereAreTaxRates() 0 8 3
A thereIsTaxRate() 0 20 2
B thereAreShippingMethods() 0 15 5
B thereIsShippingMethod() 0 25 4
A thereIsDisabledShippingMethod() 0 4 1
B thereAreLocales() 0 34 6
A thereAreLocalesAssignedToDefaultChannel() 0 15 2
A productIsAvailableInAllVariations() 0 9 1
A allProductsAreAvailableInAllVariations() 0 12 3
B orderHasFollowingItems() 0 31 2
A theCustomerWithEmailShouldHaveUsername() 0 8 2
A theCustomerWithEmailShouldBeEnabled() 0 8 2
A createAddress() 0 16 1
A processAddress() 0 7 1
A createPayment() 0 12 2
A createShipment() 0 20 3
A iAmLoggedInAsRole() 0 15 1
A assignGroups() 0 8 3
A assignAuthorizationRoles() 0 13 3
B createCustomer() 0 17 5
A createUser() 0 21 3
A createAuthorizationRole() 0 9 1
A generateProductVariations() 0 10 2
A prepareSessionIfNeeded() 0 12 3
A getUserWithEmail() 0 14 3

How to fix   Complexity   

Complex Class

Complex classes like CoreContext often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use CoreContext, and based on these observations, apply Extract Interface, too.

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\Behat;
13
14
use Behat\Gherkin\Node\TableNode;
15
use Behat\Mink\Driver\Selenium2Driver;
16
use Sylius\Bundle\ResourceBundle\Behat\DefaultContext;
17
use Sylius\Component\Addressing\Model\AddressInterface;
18
use Sylius\Component\Cart\SyliusCartEvents;
19
use Sylius\Component\Core\Model\ChannelInterface;
20
use Sylius\Component\Core\Model\CustomerInterface;
21
use Sylius\Component\Core\Model\OrderInterface;
22
use Sylius\Component\Core\Model\OrderItemInterface;
23
use Sylius\Component\Core\Model\PaymentInterface;
24
use Sylius\Component\Core\Model\ProductInterface;
25
use Sylius\Component\Core\Model\ProductVariantInterface;
26
use Sylius\Component\Core\Model\ShipmentInterface;
27
use Sylius\Component\Core\Model\ShippingMethodInterface;
28
use Sylius\Component\Core\Model\TaxRateInterface;
29
use Sylius\Component\Core\Model\UserInterface;
30
use Sylius\Component\Core\Pricing\Calculators as PriceCalculators;
31
use Sylius\Component\Currency\Model\CurrencyInterface;
32
use Sylius\Component\Locale\Model\LocaleInterface;
33
use Sylius\Component\Order\OrderTransitions;
34
use Sylius\Component\Payment\Model\PaymentMethodInterface;
35
use Sylius\Component\Rbac\Model\RoleInterface;
36
use Sylius\Component\Shipping\Calculator\DefaultCalculators;
37
use Sylius\Component\Shipping\ShipmentTransitions;
38
use Sylius\Component\User\Model\GroupableInterface;
39
use Symfony\Component\EventDispatcher\GenericEvent;
40
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
41
42
class CoreContext extends DefaultContext
43
{
44
    /**
45
     * Created orders.
46
     *
47
     * @var OrderInterface[]
48
     */
49
    protected $orders = array();
50
51
    /**
52
     * @Given store has default configuration
53
     */
54
    public function storeHasDefaultConfiguration()
55
    {
56
        $manager = $this->getEntityManager();
57
58
        /** @var CurrencyInterface $currency */
59
        $currency = $this->getFactory('currency')->createNew();
60
        $currency->setCode('EUR');
61
        $currency->setExchangeRate(1);
62
        $manager->persist($currency);
63
64
        /** @var LocaleInterface $locale */
65
        $locale = $this->getFactory('locale')->createNew();
66
        $locale->setCode('en_US');
67
        $manager->persist($locale);
68
69
        /* @var ChannelInterface $channel */
70
        $channel = $this->getFactory('channel')->createNew();
71
        $channel->setCode('DEFAULT-WEB');
72
        $channel->setName('Default');
73
        $channel->setUrl('http://example.com');
74
        $channel->addCurrency($currency);
75
        $channel->setDefaultCurrency($currency);
76
        $channel->addLocale($locale);
77
        $channel->setDefaultLocale($locale);
78
        $manager->persist($channel);
79
80
        $manager->flush();
81
    }
82
83
    /**
84
     * @Given I am logged in as :role
85
     */
86
    public function iAmLoggedInAsAuthorizationRole($role)
87
    {
88
        $this->iAmLoggedInAsRole('ROLE_ADMINISTRATION_ACCESS', '[email protected]', array($role));
89
    }
90
91
    /**
92
     * @Given /^I am logged in user$/
93
     * @Given /^I am logged in as user "([^""]*)"$/
94
     */
95
    public function iAmLoggedInUser($email = '[email protected]')
96
    {
97
        $this->iAmLoggedInAsRole('ROLE_USER', $email);
98
    }
99
100
    /**
101
     * @Given /^I am not logged in$/
102
     */
103
    public function iAmNotLoggedIn()
104
    {
105
        $this->getSession()->restart();
106
    }
107
108
    /**
109
     * @Given /^there are following orders:$/
110
     * @Given /^the following orders exist:$/
111
     * @Given /^there are orders:$/
112
     * @Given /^the following orders were placed:$/
113
     */
114
    public function thereAreOrders(TableNode $table)
115
    {
116
        $manager = $this->getEntityManager();
117
        $finite = $this->getService('sm.factory');
118
        $orderFactory = $this->getFactory('order');
119
        $shipmentProcessor = $this->getService('sylius.processor.shipment_processor');
120
121
        /** @var $paymentMethod PaymentMethodInterface */
122
        $paymentMethod = $this->getFactory('payment_method')->createNew();
123
        $paymentMethod->setName('Stripe');
124
        $paymentMethod->setGateway('stripe');
125
        $paymentMethod->setCode('PM100');
126
        $manager->persist($paymentMethod);
127
128
        $currentOrderNumber = 1;
129
        foreach ($table->getHash() as $data) {
130
            $address = $this->createAddress($data['address']);
131
132
            /* @var $order OrderInterface */
133
            $order = $orderFactory->createNew();
134
            $order->setShippingAddress($address);
135
            $order->setBillingAddress($address);
136
137
            $customer = $this->thereIsCustomer($data['customer']);
138
            $customer->addAddress($address);
139
            $order->setCustomer($customer);
140
141
            if (isset($data['shipment']) && '' !== trim($data['shipment'])) {
142
                $order->addShipment($this->createShipment($data['shipment']));
143
            }
144
145
            $order->setNumber(str_pad($currentOrderNumber, 9, 0, STR_PAD_LEFT));
146
147
            $finite->get($order, OrderTransitions::GRAPH)->apply(OrderTransitions::SYLIUS_CREATE);
148
149
            $this->createPayment($order, $paymentMethod);
150
151
            $order->setCurrency('EUR');
152
            $order->setPaymentState(PaymentInterface::STATE_COMPLETED);
153
154
            $order->complete();
155
156
            $shipmentProcessor->updateShipmentStates($order->getShipments(), ShipmentTransitions::SYLIUS_PREPARE);
157
158
            $manager->persist($order);
159
160
            $this->orders[$order->getNumber()] = $order;
161
162
            ++$currentOrderNumber;
163
        }
164
165
        $manager->flush();
166
    }
167
168
    /**
169
     * @Given /^order #(\d+) has following items:$/
170
     */
171
    public function orderHasFollowingItems($number, TableNode $items)
172
    {
173
        $manager = $this->getEntityManager();
174
        $orderItemFactory = $this->getFactory('order_item');
175
        $orderItemQuantityModifier = $this->getService('sylius.order_item_quantity_modifier');
176
177
        $order = $this->orders[$number];
178
179
        foreach ($items->getHash() as $data) {
180
            $product = $this->findOneByName('product', trim($data['product']));
181
182
            /* @var $item OrderItemInterface */
183
            $item = $orderItemFactory->createNew();
184
            $item->setVariant($product->getMasterVariant());
185
            $item->setUnitPrice($product->getMasterVariant()->getPrice());
186
187
            $orderItemQuantityModifier->modify($item, $data['quantity']);
188
189
            $order->addItem($item);
190
        }
191
192
        $order->complete();
193
194
        $this->getService('sylius.order_processing.payment_processor')->createPayment($order);
195
        $this->getService('event_dispatcher')->dispatch(SyliusCartEvents::CART_CHANGE, new GenericEvent($order));
196
197
        $order->setPaymentState(PaymentInterface::STATE_COMPLETED);
198
199
        $manager->persist($order);
200
        $manager->flush();
201
    }
202
203
    /**
204
     * @Given /^there are following users:$/
205
     */
206
    public function thereAreFollowingUsers(TableNode $table)
207
    {
208
        foreach ($table->getHash() as $data) {
209
            $this->thereIsUser(
210
                $data['email'],
211
                isset($data['password']) ? $data['password'] : $this->faker->word(),
212
                'ROLE_USER',
213
                isset($data['enabled']) ? $data['enabled'] : true,
214
                isset($data['address']) && !empty($data['address']) ? $data['address'] : null,
215
                isset($data['groups']) && !empty($data['groups']) ? explode(',', $data['groups']) : array(),
216
                false,
217
                array(),
218
                isset($data['created at']) ? new \DateTime($data['created at']) : null
219
            );
220
        }
221
222
        $this->getEntityManager()->flush();
223
    }
224
225
    /**
226
     * @Given /^there are following customers:$/
227
     * @Given /^the following customers exist:$/
228
     */
229
    public function thereAreFollowingCustomers(TableNode $table)
230
    {
231
        foreach ($table->getHash() as $data) {
232
            $this->thereIsCustomer(
233
                $data['email'],
234
                isset($data['address']) && !empty($data['address']) ? $data['address'] : null,
235
                isset($data['groups']) && !empty($data['groups']) ? explode(',', $data['groups']) : array(),
236
                false,
237
                isset($data['created at']) ? new \DateTime($data['created at']) : null
238
            );
239
        }
240
241
        $this->getEntityManager()->flush();
242
    }
243
244
    /**
245
     * @Given /^there are groups:$/
246
     * @Given /^there are following groups:$/
247
     * @Given /^the following groups exist:$/
248
     */
249
    public function thereAreGroups(TableNode $table)
250
    {
251
        $manager = $this->getEntityManager();
252
        $factory = $this->getFactory('group');
253
254
        foreach ($table->getHash() as $data) {
255
            $group = $factory->createNew();
256
            $group->setName(trim($data['name']));
257
258
            $manager->persist($group);
259
        }
260
261
        $manager->flush();
262
    }
263
264
    /**
265
     * @Given /^the following addresses exist:$/
266
     */
267
    public function theFollowingAddressesExist(TableNode $table)
268
    {
269
        $manager = $this->getEntityManager();
270
271
        foreach ($table->getHash() as $data) {
272
            $address = $this->createAddress($data['address']);
273
274
            $user = $this->thereIsUser($data['user'], 'sylius', 'ROLE_USER', 'yes', null, array());
275
            $user->getCustomer()->addAddress($address);
276
277
            $manager->persist($address);
278
            $manager->persist($user);
279
        }
280
281
        $manager->flush();
282
    }
283
284
    public function thereIsUser($email, $password, $role = null, $enabled = 'yes', $address = null, $groups = array(), $flush = true, array $authorizationRoles = array(), $createdAt = null)
285
    {
286
        if (null !== $user = $this->getRepository('user')->findOneByEmail($email)) {
287
            return $user;
288
        }
289
290
        /* @var $user UserInterface */
291
        $user = $this->createUser($email, $password, $role, $enabled, $address, $groups, $authorizationRoles, $createdAt);
292
293
        $this->getEntityManager()->persist($user);
294
        if ($flush) {
295
            $this->getEntityManager()->flush();
296
        }
297
298
        return $user;
299
    }
300
301
    protected function thereIsCustomer($email, $address = null, $groups = array(), $flush = true, $createdAt = null)
302
    {
303
        if (null !== $customer = $this->getRepository('customer')->findOneByEmail($email)) {
304
            return $customer;
305
        }
306
307
        /* @var $customer CustomerInterface */
308
        $customer = $this->createCustomer($email, $address, $groups, $createdAt);
309
310
        $this->getEntityManager()->persist($customer);
311
        if ($flush) {
312
            $this->getEntityManager()->flush();
313
        }
314
315
        return $customer;
316
    }
317
318
    /**
319
     * @Given /^product "([^""]*)" has the following volume based pricing:$/
320
     */
321
    public function productHasTheFollowingVolumeBasedPricing($productName, TableNode $table)
322
    {
323
        /* @var $product ProductInterface */
324
        $product = $this->findOneByName('product', $productName);
325
        $masterVariant = $product->getMasterVariant();
326
327
        /* @var $masterVariant ProductVariantInterface */
328
        $masterVariant->setPricingCalculator(PriceCalculators::VOLUME_BASED);
329
        $configuration = array();
330
331
        foreach ($table->getHash() as $data) {
332
            if (false !== strpos($data['range'], '+')) {
333
                $min = (int) trim(str_replace('+', '', $data['range']));
334
                $max = null;
335
            } else {
336
                list($min, $max) = array_map(function ($value) { return (int) trim($value); }, explode('-', $data['range']));
337
            }
338
339
            $configuration[] = array(
340
                'min' => $min,
341
                'max' => $max,
342
                'price' => (int) ($data['price'] * 100),
343
            );
344
        }
345
346
        $masterVariant->setPricingConfiguration($configuration);
347
348
        $manager = $this->getEntityManager();
349
        $manager->persist($product);
350
        $manager->flush();
351
    }
352
353
    /**
354
     * @Given /^product "([^""]*)" has the following group based pricing:$/
355
     */
356
    public function productHasTheFollowingGroupBasedPricing($productName, TableNode $table)
357
    {
358
        $product = $this->findOneByName('product', $productName);
359
        $masterVariant = $product->getMasterVariant();
360
361
        /* @var $masterVariant ProductVariantInterface */
362
        $masterVariant->setPricingCalculator(PriceCalculators::GROUP_BASED);
363
        $configuration = array();
364
365
        foreach ($table->getHash() as $data) {
366
            $group = $this->findOneByName('group', trim($data['group']));
367
            $configuration[$group->getId()] = (float) $data['price'] * 100;
368
        }
369
370
        $masterVariant->setPricingConfiguration($configuration);
371
372
        $manager = $this->getEntityManager();
373
        $manager->persist($product);
374
        $manager->flush();
375
    }
376
377
    /**
378
     * @Given /^there are following tax rates:$/
379
     * @Given /^the following tax rates exist:$/
380
     */
381
    public function thereAreTaxRates(TableNode $table)
382
    {
383
        foreach ($table->getHash() as $data) {
384
            $this->thereIsTaxRate($data['amount'], $data['name'], $data['code'], $data['category'], $data['zone'], isset($data['included in price?']) ? $data['included in price?'] : false, false);
385
        }
386
387
        $this->getEntityManager()->flush();
388
    }
389
390
    /**
391
     * @Given /^there is (\d+)% tax "([^""]*)" with code "([^""]*)" for category "([^""]*)" with zone "([^""]*)"$/
392
     * @Given /^I created (\d+)% tax "([^""]*)" with code "([^""]*)" for category "([^""]*)" with zone "([^""]*)"$/
393
     */
394
    public function thereIsTaxRate($amount, $name, $code, $category, $zone, $includedInPrice = false, $flush = true)
395
    {
396
        /* @var $rate TaxRateInterface */
397
        $rate = $this->getFactory('tax_rate')->createNew();
398
        $rate->setName($name);
399
        $rate->setAmount($amount / 100);
400
        $rate->setIncludedInPrice($includedInPrice);
401
        $rate->setCategory($this->findOneByName('tax_category', $category));
402
        $rate->setZone($this->findOneByName('zone', $zone));
403
        $rate->setCalculator('default');
404
        $rate->setCode($code);
405
406
        $manager = $this->getEntityManager();
407
        $manager->persist($rate);
408
        if ($flush) {
409
            $manager->flush();
410
        }
411
412
        return $rate;
413
    }
414
415
    /**
416
     * @Given /^the following shipping methods are configured:$/
417
     * @Given /^the following shipping methods exist:$/
418
     * @Given /^there are shipping methods:$/
419
     */
420
    public function thereAreShippingMethods(TableNode $table)
421
    {
422
        foreach ($table->getHash() as $data) {
423
            $calculator = array_key_exists('calculator', $data) ? str_replace(' ', '_', strtolower($data['calculator'])) : DefaultCalculators::PER_ITEM_RATE;
424
            $configuration = array_key_exists('configuration', $data) ? $this->getConfiguration($data['configuration']) : null;
425
426
            if (!isset($data['enabled'])) {
427
                $data['enabled'] = 'yes';
428
            }
429
430
            $this->thereIsShippingMethod($data['name'], $data['code'], $data['zone'], $calculator, $configuration, 'yes' === $data['enabled'], false);
431
        }
432
433
        $this->getEntityManager()->flush();
434
    }
435
436
    /**
437
     * @Given /^I created shipping method "([^""]*)" with code "([^""]*)" and zone "([^""]*)"$/
438
     * @Given /^There is shipping method "([^""]*)" with code "([^""]*)" and zone "([^""]*)"$/
439
     * @Given /^there is an enabled shipping method "([^""]*)" with code "([^""]*)" and zone "([^""]*)"$/
440
     */
441
    public function thereIsShippingMethod($name, $code, $zoneName, $calculator = DefaultCalculators::PER_ITEM_RATE, array $configuration = null, $enabled = true, $flush = true)
442
    {
443
        $repository = $this->getRepository('shipping_method');
444
        $factory = $this->getFactory('shipping_method');
445
446
        /* @var $method ShippingMethodInterface */
447
        if (null === $method = $repository->findOneBy(array('name' => $name))) {
448
            $method = $factory->createNew();
449
            $method->setName($name);
450
            $method->setCode($code);
451
            $method->setZone($this->findOneByName('zone', $zoneName));
452
            $method->setCalculator($calculator);
453
            $method->setConfiguration($configuration ?: array('amount' => 2500));
454
        };
455
456
        $method->setEnabled($enabled);
457
458
        $manager = $this->getEntityManager();
459
        $manager->persist($method);
460
        if ($flush) {
461
            $manager->flush();
462
        }
463
464
        return $method;
465
    }
466
467
    /**
468
     * @Given /^there is a disabled shipping method "([^""]*)" with code "([^""]*)" and zone "([^""]*)"$/
469
     */
470
    public function thereIsDisabledShippingMethod($name, $code, $zoneName)
471
    {
472
        $this->thereIsShippingMethod($name, $code, $zoneName, DefaultCalculators::PER_ITEM_RATE, null, false);
473
    }
474
475
    /**
476
     * @Given /^the following locales are defined:$/
477
     * @Given /^there are following locales configured:$/
478
     */
479
    public function thereAreLocales(TableNode $table)
480
    {
481
        $repository = $this->getRepository('locale');
482
        $manager = $this->getEntityManager();
483
        $factory = $this->getFactory('locale');
484
485
        $locales = $repository->findAll();
486
        foreach ($locales as $locale) {
487
            $manager->remove($locale);
488
        }
489
490
        $manager->flush();
491
        $manager->clear();
492
493
        foreach ($table->getHash() as $data) {
494
            $locale = $factory->createNew();
495
496
            if (isset($data['code'])) {
497
                $locale->setCode($data['code']);
498
            } elseif (isset($data['name'])) {
499
                $locale->setCode($this->getLocaleCodeByEnglishLocaleName($data['name']));
500
            } else {
501
                throw new \InvalidArgumentException('Locale definition should have either code or name');
502
            }
503
504
            if (isset($data['enabled'])) {
505
                $locale->setEnabled('yes' === $data['enabled']);
506
            }
507
508
            $manager->persist($locale);
509
        }
510
511
        $manager->flush();
512
    }
513
514
    /**
515
     * @Given /^there are following locales configured and assigned to the default channel:$/
516
     */
517
    public function thereAreLocalesAssignedToDefaultChannel(TableNode $table)
518
    {
519
        $this->thereAreLocales($table);
520
521
        /** @var ChannelInterface $defaultChannel */
522
        $defaultChannel = $this->getRepository('channel')->findOneBy(array('code' => 'DEFAULT-WEB'));
523
524
        /** @var LocaleInterface[] $locales */
525
        $locales = $this->getRepository('locale')->findAll();
526
        foreach ($locales as $locale) {
527
            $defaultChannel->addLocale($locale);
528
        }
529
530
        $this->getEntityManager()->flush();
531
    }
532
533
    /**
534
     * @Given /^product "([^""]*)" is available in all variations$/
535
     */
536
    public function productIsAvailableInAllVariations($productName)
537
    {
538
        /** @var ProductInterface $product */
539
        $product = $this->findOneByName('product', $productName);
540
541
        $this->generateProductVariations($product);
542
543
        $this->getEntityManager()->flush();
544
    }
545
546
    /**
547
     * @Given all products are available in all variations
548
     */
549
    public function allProductsAreAvailableInAllVariations()
550
    {
551
        /** @var ProductInterface[] $products */
552
        $products = $this->getRepository('product')->findAll();
553
        foreach ($products as $product) {
554
            if ($product->hasOptions()) {
555
                $this->generateProductVariations($product);
556
            }
557
        }
558
559
        $this->getEntityManager()->flush();
560
    }
561
562
    /**
563
     * @Then the customer with email :email should have username :username
564
     */
565
    public function theCustomerWithEmailShouldHaveUsername($email, $username)
566
    {
567
        $user = $this->getUserWithEmail($email);
568
569
        if ($username !== $user->getUsername()) {
570
            throw new \Exception(sprintf('The username should be %s but is %s', $username, $user->getUsername()));
571
        }
572
    }
573
574
    /**
575
     * @Then the customer with email :email should be enabled
576
     */
577
    public function theCustomerWithEmailShouldBeEnabled($email)
578
    {
579
        $user = $this->getUserWithEmail($email);
580
581
        if (!$user->isEnabled()) {
582
            throw new \Exception('The account is disabled.');
583
        }
584
    }
585
586
    /**
587
     * Create an address instance from string.
588
     *
589
     * @param string $string
590
     *
591
     * @return AddressInterface
592
     */
593
    private function createAddress($string)
594
    {
595
        $addressData = $this->processAddress($string);
596
597
        list($firstname, $lastname) = explode(' ', $addressData[0]);
598
599
        /* @var $address AddressInterface */
600
        $address = $this->getFactory('address')->createNew();
601
        $address->setFirstname(trim($firstname));
602
        $address->setLastname(trim($lastname));
603
        $address->setStreet($addressData[1]);
604
        $address->setPostcode($addressData[2]);
605
        $address->setCity($addressData[3]);
606
        $address->setCountryCode($this->getCountryCodeByEnglishCountryName($addressData[4]));
607
        return $address;
608
    }
609
610
    /**
611
     * @param string $address
612
     *
613
     * @return array
614
     */
615
    protected function processAddress($address)
616
    {
617
        $addressData = explode(',', $address);
618
        $addressData = array_map('trim', $addressData);
619
620
        return $addressData;
621
    }
622
623
    /**
624
     * Create an payment instance.
625
     *
626
     * @param OrderInterface         $order
627
     * @param PaymentMethodInterface $method
628
     */
629
    private function createPayment(OrderInterface $order, PaymentMethodInterface $method)
630
    {
631
        /** @var $payment PaymentInterface */
632
        $payment = $this->getFactory('payment')->createNew();
633
        $payment->setOrder($order);
634
        $payment->setMethod($method);
635
        $payment->setAmount($order->getTotal());
636
        $payment->setCurrency($order->getCurrency() ?: 'EUR');
637
        $payment->setState(PaymentInterface::STATE_COMPLETED);
638
639
        $order->addPayment($payment);
640
    }
641
642
    /**
643
     * Create an shipment instance from string.
644
     *
645
     * @param string $string
646
     *
647
     * @return ShipmentInterface
648
     */
649
    private function createShipment($string)
650
    {
651
        $shipmentData = explode(',', $string);
652
        $shipmentData = array_map('trim', $shipmentData);
653
654
        /* @var $shippingMethod ShippingMethodInterface */
655
        $shippingMethod = $this->getRepository('shipping_method')->findOneBy(array('name' => $shipmentData[0]));
656
657
        /* @var $shipment ShipmentInterface */
658
        $shipment = $this->getFactory('shipment')->createNew();
659
        $shipment->setMethod($shippingMethod);
660
        if (isset($shipmentData[1])) {
661
            $shipment->setState($shipmentData[1]);
662
        }
663
        if (isset($shipmentData[2])) {
664
            $shipment->setTracking($shipmentData[2]);
665
        }
666
667
        return $shipment;
668
    }
669
670
    /**
671
     * Create user and login with given role.
672
     *
673
     * @param string $role
674
     * @param string $email
675
     * @param array  $authorizationRoles
676
     */
677
    private function iAmLoggedInAsRole($role, $email = '[email protected]', array $authorizationRoles = array())
678
    {
679
        $user = $this->thereIsUser($email, 'sylius', $role, 'yes', null, array(), true, $authorizationRoles);
680
681
        $token = new UsernamePasswordToken($user, $user->getPassword(), 'administration', $user->getRoles());
682
683
        $session = $this->getService('session');
684
        $session->set('_security_user', serialize($token));
685
        $session->save();
686
687
        $this->prepareSessionIfNeeded();
688
689
        $this->getSession()->setCookie($session->getName(), $session->getId());
690
        $this->getService('security.token_storage')->setToken($token);
691
    }
692
693
    /**
694
     * @param GroupableInterface $groupableObject
695
     * @param array              $groups
696
     */
697
    protected function assignGroups(GroupableInterface $groupableObject, array $groups)
698
    {
699
        foreach ($groups as $groupName) {
700
            if ($group = $this->findOneByName('group', $groupName)) {
701
                $groupableObject->addGroup($group);
702
            }
703
        }
704
    }
705
706
    /**
707
     * @param array         $authorizationRoles
708
     * @param UserInterface $user
709
     */
710
    protected function assignAuthorizationRoles(UserInterface $user, array $authorizationRoles = array())
711
    {
712
        foreach ($authorizationRoles as $role) {
713
            try {
714
                $authorizationRole = $this->findOneByName('role', $role);
715
            } catch (\InvalidArgumentException $exception) {
716
                $authorizationRole = $this->createAuthorizationRole($role);
717
                $this->getEntityManager()->persist($authorizationRole);
718
            }
719
720
            $user->addAuthorizationRole($authorizationRole);
721
        }
722
    }
723
724
    /**
725
     * @param $email
726
     * @param $address
727
     * @param $groups
728
     * @param $createdAt
729
     *
730
     * @return CustomerInterface
731
     */
732
    protected function createCustomer($email, $address = null, $groups = array(), $createdAt = null)
733
    {
734
        $addressData = $this->processAddress($address);
735
736
        $customer = $this->getFactory('customer')->createNew();
737
        $customer->setFirstname(null === $address ? $this->faker->firstName : $addressData[0]);
738
        $customer->setLastname(null === $address ? $this->faker->lastName : $addressData[1]);
739
        $customer->setEmail($email);
740
        $customer->setEmailCanonical($email);
741
        $customer->setCreatedAt(null === $createdAt ? new \DateTime() : $createdAt);
742
        if (null !== $address) {
743
            $customer->setShippingAddress($this->createAddress($address));
744
        }
745
        $this->assignGroups($customer, $groups);
746
747
        return $customer;
748
    }
749
750
    /**
751
     * @param $email
752
     * @param $password
753
     * @param $role
754
     * @param $enabled
755
     * @param $address
756
     * @param $groups
757
     * @param array $authorizationRoles
758
     * @param $createdAt
759
     *
760
     * @return UserInterface
761
     */
762
    protected function createUser($email, $password, $role = null, $enabled = 'yes', $address = null, array $groups = array(), array $authorizationRoles = array(), $createdAt = null)
763
    {
764
        $user = $this->getFactory('user')->createNew();
765
        $customer = $this->createCustomer($email, $address, $groups, $createdAt);
766
        $user->setCustomer($customer);
767
        $user->setUsername($email);
768
        $user->setEmail($email);
769
        $user->setEnabled('yes' === $enabled);
770
        $user->setCreatedAt(null === $createdAt ? new \DateTime() : $createdAt);
771
        $user->setPlainPassword($password);
772
        $user->setUsernameCanonical($email);
773
        $user->setEmailCanonical($email);
774
        $this->getService('sylius.user.password_updater')->updatePassword($user);
775
776
        if (null !== $role) {
777
            $user->addRole($role);
778
        }
779
        $this->assignAuthorizationRoles($user, $authorizationRoles);
780
781
        return $user;
782
    }
783
784
    /**
785
     * @param string $role
786
     *
787
     * @return RoleInterface
788
     */
789
    protected function createAuthorizationRole($role)
790
    {
791
        $authorizationRole = $this->getFactory('role')->createNew();
792
        $authorizationRole->setCode($role);
793
        $authorizationRole->setName(ucfirst($role));
794
        $authorizationRole->setSecurityRoles(array('ROLE_ADMINISTRATION_ACCESS'));
795
796
        return $authorizationRole;
797
    }
798
799
    /**
800
     * @param ProductInterface $product
801
     */
802
    private function generateProductVariations($product)
803
    {
804
        $this->getService('sylius.generator.product_variant')->generate($product);
805
806
        foreach ($product->getVariants() as $variant) {
807
            $variant->setPrice($product->getMasterVariant()->getPrice());
808
        }
809
810
        $this->getEntityManager()->persist($product);
811
    }
812
813
    private function prepareSessionIfNeeded()
814
    {
815
        if (!$this->getSession()->getDriver() instanceof Selenium2Driver) {
816
            return;
817
        }
818
819
        if (false !== strpos($this->getSession()->getCurrentUrl(), $this->getMinkParameter('base_url'))) {
820
            return;
821
        }
822
823
        $this->visitPath('/');
824
    }
825
826
    /**
827
     * @param $email
828
     *
829
     * @return \Sylius\Component\User\Model\UserInterface
830
     * @throws \Exception
831
     */
832
    private function getUserWithEmail($email)
833
    {
834
        $customer = $this->getRepository('customer')->findOneBy(array('email' => $email));
835
836
        if (null === $customer) {
837
            throw new \Exception(sprintf('Customer with email %s does not exist.', $email));
838
        }
839
840
        if (null === $user = $customer->getUser()) {
841
            throw new \Exception(sprintf('Customer with email %s does not have associated user.', $email));
842
        }
843
844
        return $user;
845
    }
846
}
847