Skip to content

Commit

Permalink
Merge pull request #2 from ThreeSixtyEu/seat-reservation
Browse files Browse the repository at this point in the history
  • Loading branch information
Amunak authored Sep 14, 2016
2 parents 4334758 + be9c7df commit 5e9ded0
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 14 deletions.
27 changes: 16 additions & 11 deletions src/Sylius/Bundle/CartBundle/Controller/CartItemController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Sylius\Bundle\CartBundle\Controller;

use Sylius\Component\Cart\Event\CartEvent;
use Sylius\Component\Cart\Event\CartItemEvent;
use Sylius\Component\Cart\Resolver\ItemResolvingException;
use Sylius\Component\Cart\SyliusCartEvents;
Expand Down Expand Up @@ -51,27 +52,31 @@ class CartItemController extends Controller
public function addAction(Request $request)
{
$cart = $this->getCurrentCart();
$emptyItem = $this->createNew();

$eventDispatcher = $this->getEventDispatcher();

$eventDispatcher->dispatch(SyliusCartEvents::ITEM_ADD_FIRST_INIT, new CartEvent($cart));

try {
$item = $this->getResolver()->resolve($emptyItem, $request);
$iterations = $this->getResolver()->countIterations($request);
for ($i = 0; $i < $iterations; $i++) {
$emptyItem = $this->createNew();
$item = $this->getResolver()->resolve($emptyItem, $request, $i);

$event = new CartItemEvent($cart, $item);
$event->isFresh(true);

// Update models
$eventDispatcher->dispatch(SyliusCartEvents::ITEM_ADD_INITIALIZE, $event);
$eventDispatcher->dispatch(SyliusCartEvents::CART_CHANGE, new GenericEvent($cart));
$eventDispatcher->dispatch(SyliusCartEvents::CART_SAVE_INITIALIZE, $event);
}
} catch (ItemResolvingException $exception) {
// Write flash message
$eventDispatcher->dispatch(SyliusCartEvents::ITEM_ADD_ERROR, new FlashEvent($exception->getMessage()));

return $this->redirectAfterAdd($request);
}

$event = new CartItemEvent($cart, $item);
$event->isFresh(true);

// Update models
$eventDispatcher->dispatch(SyliusCartEvents::ITEM_ADD_INITIALIZE, $event);
$eventDispatcher->dispatch(SyliusCartEvents::CART_CHANGE, new GenericEvent($cart));
$eventDispatcher->dispatch(SyliusCartEvents::CART_SAVE_INITIALIZE, $event);

// Write flash message
$eventDispatcher->dispatch(SyliusCartEvents::ITEM_ADD_COMPLETED, new FlashEvent());

Expand Down
82 changes: 81 additions & 1 deletion src/Sylius/Bundle/CoreBundle/Cart/ItemResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public function __construct(
/**
* {@inheritdoc}
*/
public function resolve(CartItemInterface $item, $data)
public function resolve(CartItemInterface $item, $data, $iteration = 0)
{
$id = $this->resolveItemIdentifier($data);

Expand All @@ -117,6 +117,10 @@ public function resolve(CartItemInterface $item, $data)

// We use forms to easily set the quantity and pick variant but you can do here whatever is required to create the item.
$form = $this->formFactory->create('sylius_cart_item', $item, array('product' => $product));

// When iterating over multiple variants we need to transform each iteration to single item for the form to work
$data = $this->transformIterationToRegularData($data, $iteration);

$form->submit($data);

// If our product has no variants, we simply set the master variant of it.
Expand Down Expand Up @@ -185,4 +189,80 @@ public function resolveItemIdentifier($request)

return $id;
}

/**
* {@inheritdoc}
*/
public function countIterations($request)
{
if (!$request instanceof Request) {
throw new ItemResolvingException('Invalid request data.');
}

if (!$this->isMultipleRequest($request)) {
return 1;
}

$submittedVariants = $request->request->get('sylius_cart_item[variant]', null, true);
if ($submittedVariants === null || !is_array($submittedVariants)) {
throw new ItemResolvingException('Submitted variants missing from request or it has unexpected format.');
}

return count($submittedVariants);
}

/**
* @param Request $data
* @param $iteration
* @return Request
* @throws ItemResolvingException
*/
protected function transformIterationToRegularData(Request $data, $iteration)
{
if (!$this->isMultipleRequest($data)) {
return $data;
}

$submittedVariants = $data->request->get('sylius_cart_item[variant]', null, true);
reset($submittedVariants);
for ($i = 0; $i < $iteration; $i++) {
if (next($submittedVariants) === false) {
throw new ItemResolvingException('There are more iterations than submitted variants.');
}
}

return $this->transformData($data, key($submittedVariants));
}


/**
* Checks whether we will be resolving multiple variants from a request
*
* @param Request $request
* @return bool
*/
protected function isMultipleRequest(Request $request)
{
return $request->request->getAlnum('variant_types', 'default') === 'multiple';
}

/**
* Transforms request with multiple variants to a request with single variant (based on $variantId)
*
* The new request <b>must</b> be cloned first if it changes any value.
*
* @param Request $original the original request
* @param int $variantId
* @return Request
*/
protected function transformData(Request $original, $variantId)
{
$clone = clone $original;
$clone->request->set('sylius_cart_item', array(
'variant' => $variantId,
'quantity' => $original->request->getInt('sylius_cart_item[variant][' . $variantId . '][quantity]', 1, true),
'_token' => $original->request->get('sylius_cart_item[_token]', null, true),
));
return $clone;
}
}
7 changes: 6 additions & 1 deletion src/Sylius/Bundle/CoreBundle/Checkout/Step/FinalizeStep.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Sylius\Bundle\CoreBundle\Checkout\Step;

use Doctrine\ORM\ORMException;
use Sylius\Bundle\FlowBundle\Process\Context\ProcessContextInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\SyliusCheckoutEvents;
Expand Down Expand Up @@ -45,7 +46,11 @@ public function forwardAction(ProcessContextInterface $context)

$order->setUser($this->getUser());

$this->completeOrder($order);
try {
$this->completeOrder($order);
} catch (ORMException $e) {
$this->get('logger')->addWarning(sprintf('%s raised during order completion.', get_class($e)), array('exception' => $e));
}

return $this->complete();
}
Expand Down
13 changes: 12 additions & 1 deletion src/Sylius/Component/Cart/Resolver/ItemResolverInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,21 @@ interface ItemResolverInterface
*
* @param CartItemInterface $item Empty and clean item object as first argument
* @param mixed $data Mixed data from which item identifier is extracted
* @param int $iteration Current iteration count when we are adding multiple variants
*
* @return CartItemInterface
*
* @throws ItemResolvingException
*/
public function resolve(CartItemInterface $item, $data);
public function resolve(CartItemInterface $item, $data, $iteration = 0);

/**
* Returns iteration count - how many times should resolve be called for the specified request.
*
* @param $request
* @return
*
* @throws ItemResolvingException
*/
public function countIterations($request);
}
1 change: 1 addition & 0 deletions src/Sylius/Component/Cart/SyliusCartEvents.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ final class SyliusCartEvents
const CART_SAVE_INITIALIZE = 'sylius.cart_save.initialize';
const CART_SAVE_COMPLETED = 'sylius.cart_save.completed';

const ITEM_ADD_FIRST_INIT = 'sylius.cart_item.add.first_initialize';
const ITEM_ADD_INITIALIZE = 'sylius.cart_item.add.initialize';
const ITEM_ADD_COMPLETED = 'sylius.cart_item.add.completed';
const ITEM_ADD_ERROR = 'sylius.cart_item.add.error';
Expand Down

0 comments on commit 5e9ded0

Please sign in to comment.