Completed
Push — master ( f9ba0c...336b1b )
by Kamil
23:42
created

CoreContext   F

Complexity

Total Complexity 97

Size/Duplication

Total Lines 762
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 21

Importance

Changes 5
Bugs 2 Features 0
Metric Value
wmc 97
c 5
b 2
f 0
lcom 1
cbo 21
dl 0
loc 762
rs 1.263

35 Methods

Rating   Name   Duplication   Size   Complexity  
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 storeHasDefaultConfiguration() 0 28 1
A iAmLoggedInAsAuthorizationRole() 0 4 1
A iAmLoggedInUser() 0 4 1
A iAmNotLoggedIn() 0 4 1
B thereAreOrders() 0 53 4
B orderHasFollowingItems() 0 31 2
B thereAreShippingMethods() 0 16 6
B thereIsShippingMethod() 0 26 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
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

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