<?php
namespace Bidcoz\Bundle\FrontendBundle\Controller\Auction;
use Bidcoz\Bundle\CoreBundle\Controller\CoreController;
use Bidcoz\Bundle\CoreBundle\Entity\Auction\Auction;
use Bidcoz\Bundle\CoreBundle\Entity\Auction\FundANeed;
use Bidcoz\Bundle\CoreBundle\Entity\Auction\Item;
use Bidcoz\Bundle\CoreBundle\Entity\Auction\Shop;
use Bidcoz\Bundle\CoreBundle\Entity\Campaign;
use Bidcoz\Bundle\CoreBundle\Entity\Organization;
use Bidcoz\Bundle\CoreBundle\Entity\Proxy\ItemPurchaseProxy;
use Bidcoz\Bundle\FrontendBundle\Form\Type\ItemBidType;
use Bidcoz\Bundle\FrontendBundle\Form\Type\ItemBuyType;
use Bidcoz\Bundle\FrontendBundle\Form\Type\ItemDonationType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
/**
* @Route("/{orgSlug}/{campaignSlug}")
*
* @IsGranted("VIEW", subject="organization")
* @IsGranted("FRONT_END", subject="campaign")
*/
class ItemController extends CoreController
{
/**
* @Route("/auction/item/{itemId}", name="auction_item", methods={"GET"})
*
* @Cache(maxage="0", smaxage="0", expires="now", public="false")
*
* @Entity("item", class="Bidcoz\Bundle\CoreBundle\Entity\Auction\Item", options={"id" = "itemId"}, expr="repository.findHydrated(itemId)")
*
* @IsGranted("VIEW", subject="item")
*/
public function viewAuctionItemAction(Organization $organization, Campaign $campaign, Auction $auction, Item $item)
{
return $this->viewItem($organization, $campaign, $auction, $item);
}
/**
* @Route("/shop/item/{itemId}", name="shop_item", methods={"GET"})
*
* @Cache(maxage="0", smaxage="0", expires="now", public="false")
*
* @Entity("item", class="Bidcoz\Bundle\CoreBundle\Entity\Auction\Item", options={"id" = "itemId"}, expr="repository.findHydrated(itemId)")
*
* @IsGranted("VIEW", subject="item")
*/
public function viewShopItemAction(Organization $organization, Campaign $campaign, Shop $shop, Item $item)
{
return $this->viewItem($organization, $campaign, $shop, $item);
}
/**
* @Route("/fund-a-need/item/{itemId}", name="fund_a_need_item", methods={"GET"})
*
* @Cache(maxage="0", smaxage="0", expires="now", public="false")
*
* @Entity("item", class="Bidcoz\Bundle\CoreBundle\Entity\Auction\Item", options={"id" = "itemId"}, expr="repository.findHydrated(itemId)")
*
* @IsGranted("VIEW", subject="item")
*/
public function viewFundANeedItemAction(Organization $organization, Campaign $campaign, FundANeed $fundANeed, Item $item)
{
return $this->viewItem($organization, $campaign, $fundANeed, $item);
}
private function viewItem(Organization $organization, Campaign $campaign, Auction $auction, Item $item)
{
[$proxy, $bidForm, $buyForm, $donationForm, $showBidForm, $showBuyForm, $showDonationForm] = $this->getItemVars($item);
$internalUsers = null;
if ($auction instanceof Shop) {
$type = 'shop';
$internalUsers = $this->getRepository('InternalUser')->findByOrganization($organization);
} elseif ($auction instanceof FundANeed) {
$type = 'fund-a-need';
} else {
$type = 'auction';
}
$auctionItems = $this->getPagination($this->getRepository('Auction\Item')->getAuctionQueryBuilder($auction, true, false));
$params = [
'organization' => $organization,
'campaign' => $campaign,
'auction' => $auction,
'item' => $item,
'bidForm' => $bidForm->createView(),
'buyForm' => $buyForm->createView(),
'donationForm' => $donationForm->createView(),
'showBidForm' => $showBidForm,
'showBuyForm' => $showBuyForm,
'showDonationForm' => $showDonationForm,
'requireCC' => !$this->isGranted('WITH_CC', $campaign),
'type' => $type,
'auctionItems' => $auctionItems,
'internalUsers' => $internalUsers,
];
return $this->render('@BidcozFrontend/Auction/item.html.twig', $params);
}
/**
* @Route("/auction/item/{itemId}/bid", name="item_bid")
*
* @Entity("item", class="Bidcoz\Bundle\CoreBundle\Entity\Auction\Item", options={"id" = "itemId"}, expr="repository.findHydrated(itemId)")
*
* @IsGranted("VIEW", subject="item")
*/
public function bidItemAction(Request $request, Organization $organization, Campaign $campaign, Auction $auction, Item $item)
{
$user = $this->getUser();
if (!$user) {
$this->messageAccessDeniedException('You must login or create an account to place a bid');
}
if ('POST' !== $request->getMethod() || !$this->isItemBiddable($item)) {
return $this->redirectToRoute('auction_item', [
'orgSlug' => $organization->getSlug(),
'campaignSlug' => $campaign->getSlug(),
'itemId' => $item->getId(),
]);
}
[$proxy, $bidForm, $buyForm, $donationForm, $showBidForm, $showBuyForm, $showDonationForm] = $this->getItemVars($item);
if (!$this->isGranted('WITH_CC', $campaign)) {
$params = [
'organization' => $organization,
'campaign' => $campaign,
'auction' => $auction,
'item' => $item,
'bidForm' => $bidForm->createView(),
'buyForm' => $buyForm->createView(),
'donationForm' => $donationForm->createView(),
'showBidForm' => $showBidForm,
'showBuyForm' => $showBuyForm,
'showDonationForm' => $showDonationForm,
'ccRequiredWarning' => true,
'requireCC' => true,
'type' => 'auction',
];
return $this->render('@BidcozFrontend/Auction/item.html.twig', $params);
}
$bidForm->handleRequest($request);
if ($bidForm->isValid()) {
try {
$this->getBidManager()->createBid($user, $proxy);
$this->getEntityManager()->flush();
} catch (\Exception $e) {
$this->addFlash('danger', $e->getMessage());
}
return $this->redirectToRoute('auction_item', [
'orgSlug' => $organization->getSlug(),
'campaignSlug' => $campaign->getSlug(),
'itemId' => $item->getId(),
]);
} else {
$this->addFlash('warning', 'There was an error placing your bid, please try again');
}
$params = [
'organization' => $organization,
'campaign' => $campaign,
'auction' => $auction,
'item' => $item,
'bidForm' => $bidForm->createView(),
'buyForm' => $buyForm->createView(),
'donationForm' => $donationForm->createView(),
'showBidForm' => $showBidForm,
'showBuyForm' => $showBuyForm,
'showDonationForm' => $showDonationForm,
'requireCC' => false,
'type' => 'auction',
];
return $this->render('@BidcozFrontend/Auction/item.html.twig', $params);
}
/**
* @Route("/auction/item/{itemId}/buy", name="auction_item_buy")
*
* @Entity("item", class="Bidcoz\Bundle\CoreBundle\Entity\Auction\Item", options={"id" = "itemId"}, expr="repository.findHydrated(itemId)")
*
* @IsGranted("VIEW", subject="item")
*/
public function buyAuctionItemAction(Request $request, Organization $organization, Campaign $campaign, Auction $auction, Item $item)
{
return $this->buyItem($request, $organization, $campaign, $auction, $item);
}
/**
* @Route("/shop/item/{itemId}/buy", name="shop_item_buy")
* @Route("/shop/item/{itemId}/donation", name="shop_item_donation")
*
* @Entity("item", class="Bidcoz\Bundle\CoreBundle\Entity\Auction\Item", options={"id" = "itemId"}, expr="repository.findHydrated(itemId)")
*
* @IsGranted("VIEW", subject="item")
*/
public function buyShopItemAction(Request $request, Organization $organization, Campaign $campaign, Shop $shop, Item $item)
{
return $this->buyItem($request, $organization, $campaign, $shop, $item);
}
/**
* @Route("/fund-a-need/item/{itemId}/buy", name="fund_a_need_item_buy")
* @Route("/fund-a-need/item/{itemId}/donation", name="fund_a_need_item_donation")
*
* @Entity("item", class="Bidcoz\Bundle\CoreBundle\Entity\Auction\Item", options={"id" = "itemId"}, expr="repository.findHydrated(itemId)")
*
* @IsGranted("VIEW", subject="item")
*/
public function buyFundANeedItemAction(Request $request, Organization $organization, Campaign $campaign, FundANeed $fundANeed, Item $item)
{
return $this->buyItem($request, $organization, $campaign, $fundANeed, $item);
}
private function buyItem(Request $request, Organization $organization, Campaign $campaign, Auction $auction, Item $item)
{
$user = $this->getUser();
if (!$user) {
$this->messageAccessDeniedException('You must login or create an account to purchase an item');
}
if ('POST' !== $request->getMethod() || !($this->isItemBuyitNow($item) || $this->isItemDonation($item))) {
return $this->redirectToRoute('auction_item', [
'orgSlug' => $organization->getSlug(),
'campaignSlug' => $campaign->getSlug(),
'itemId' => $item->getId(),
]);
}
[$proxy, $bidForm, $buyForm, $donationForm, $showBidForm, $showBuyForm, $showDonationForm] = $this->getItemVars($item);
if ($auction instanceof Shop) {
$type = 'shop';
} elseif ($auction instanceof FundANeed) {
$type = 'fund-a-need';
} else {
$type = 'auction';
}
if (!$this->isGranted('WITH_CC', $campaign)) {
$params = [
'organization' => $organization,
'campaign' => $campaign,
'auction' => $auction,
'item' => $item,
'bidForm' => $bidForm->createView(),
'buyForm' => $buyForm->createView(),
'donationForm' => $donationForm->createView(),
'showBidForm' => $showBidForm,
'showBuyForm' => $showBuyForm,
'showDonationForm' => $showDonationForm,
'ccRequiredWarning' => true,
'requireCC' => true,
'type' => $type,
];
return $this->render('@BidcozFrontend/Auction/item.html.twig', $params);
}
if ($showBuyForm) {
$buyForm->handleRequest($request);
if ($buyForm->isValid()) {
try {
$holdInCart = $campaign->getHoldItemsInCart();
$expirationDate = $holdInCart
? null
: new \DateTime('+15 minutes');
$this->getPurchaseManager()->createBuyItNowItemPurchase($user, $proxy, $campaign->getHoldItemsInCart(), $expirationDate);
if ('auction' == $type) {
$this->getWatchListManager()->createWatchListItem($user, $proxy->getItem());
}
$this->getEntityManager()->flush();
} catch (\Exception $e) {
$this->addFlash('warning', $e->getMessage());
}
return $this->redirectToRoute('account_campaign_purchases', [
'orgSlug' => $organization->getSlug(),
'campaignSlug' => $campaign->getSlug(),
]);
} else {
$this->addFlash('warning', 'There was an error purchasing this item, please try again');
}
} elseif ($showDonationForm) {
$donationForm->handleRequest($request);
if ($donationForm->isValid()) {
try {
$this->getPurchaseManager()->createDonationItemPurchase($user, $proxy);
$this->getEntityManager()->flush();
} catch (\Exception $e) {
$this->addFlash('warning', $e->getMessage());
}
return $this->redirectToRoute('account_campaign_purchases', [
'orgSlug' => $organization->getSlug(),
'campaignSlug' => $campaign->getSlug(),
]);
} else {
$this->addFlash('warning', 'There was an error making this purchase, please try again');
}
}
$params = [
'organization' => $organization,
'campaign' => $campaign,
'auction' => $auction,
'item' => $item,
'bidForm' => $bidForm->createView(),
'buyForm' => $buyForm->createView(),
'donationForm' => $donationForm->createView(),
'showBidForm' => $showBidForm,
'showBuyForm' => $showBuyForm,
'showDonationForm' => $showDonationForm,
'requireCC' => false,
'type' => $auction instanceof Shop ? 'shop' : 'auction',
];
return $this->render('@BidcozFrontend/Auction/item.html.twig', $params);
}
/**
* @Route("/auction/item/{itemId}/max-bid", name="item_max_bid")
*
* @Entity("item", class="Bidcoz\Bundle\CoreBundle\Entity\Auction\Item", options={"id" = "itemId"}, expr="repository.findHydrated(itemId)")
*
* @IsGranted("VIEW", subject="item")
*/
public function updateMaxBidAction(Request $request, Organization $organization, Campaign $campaign, Auction $auction, Item $item)
{
$user = $this->getUser();
if (!$user) {
$this->messageAccessDeniedException('You must login or create an account to place a bid');
}
if ('POST' !== $request->getMethod() || !$this->isItemBiddable($item)) {
return $this->redirectToRoute('auction_item', [
'orgSlug' => $organization->getSlug(),
'campaignSlug' => $campaign->getSlug(),
'itemId' => $item->getId(),
]);
}
if (!$this->isGranted('WITH_CC', $campaign)) {
[$proxy, $bidForm, $buyForm, $donationForm, $showBidForm, $showBuyForm, $showDonationForm] = $this->getItemVars($item);
$params = [
'organization' => $organization,
'campaign' => $campaign,
'auction' => $auction,
'item' => $item,
'bidForm' => $bidForm->createView(),
'buyForm' => $buyForm->createView(),
'donationForm' => $donationForm->createView(),
'showBidForm' => $showBidForm,
'showBuyForm' => $showBuyForm,
'showDonationForm' => $showDonationForm,
'ccRequiredWarning' => true,
'requireCC' => true,
'type' => 'auction',
];
return $this->render('@BidcozFrontend/Auction/item.html.twig', $params);
}
try {
$amount = $request->request->get('amount', 0);
$cancelBid = (bool) $request->request->get('_cancel', false);
$this->getBidManager()->setMaxBid($user, $item, $amount, $cancelBid);
$this->getEntityManager()->flush();
} catch (\Exception $e) {
$this->addFlash('warning', $e->getMessage());
}
return $this->redirectToRoute('auction_item', [
'orgSlug' => $organization->getSlug(),
'campaignSlug' => $campaign->getSlug(),
'itemId' => $item->getId(),
]);
}
protected function isItemBiddable(Item $item)
{
return $this->getItemManager()->isItemBiddable($item);
}
protected function isItemBuyitNow(Item $item)
{
return $this->getItemManager()->isItemBuyitNow($item);
}
protected function isItemDonation(Item $item)
{
return $this->getItemManager()->isItemDonation($item);
}
protected function createItemPurchaseProxy(Item $item)
{
return new ItemPurchaseProxy($item);
}
protected function getBidForm(ItemPurchaseProxy $proxy)
{
$item = $proxy->getItem();
if ($item->isAuctionType()) {
$itemMinimumBid = $this->getBidManager()->getItemMinimumBid($item);
$proxy->setAmount($itemMinimumBid);
}
$form = $this->createForm(ItemBidType::class, $proxy);
return $form;
}
protected function getBuyForm(ItemPurchaseProxy $proxy)
{
$item = $proxy->getItem();
$form = $this->createForm(ItemBuyType::class, $proxy, [
'item' => $item,
]);
if ($item->isFixedPrice()) {
$form->get('quantity')->setData(1);
}
return $form;
}
protected function getDonationForm(ItemPurchaseProxy $proxy)
{
$item = $proxy->getItem();
return $this->createForm(ItemDonationType::class, $proxy, [
'item' => $item,
]);
}
protected function getItemVars(Item $item)
{
$proxy = $this->createItemPurchaseProxy($item);
$bidForm = $this->getBidForm($proxy);
$buyForm = $this->getBuyForm($proxy);
$donationForm = $this->getDonationForm($proxy);
$showBidForm = $this->getItemManager()->isItemBiddable($item);
$showBuyForm = $this->getItemManager()->isItemBuyitNow($item);
$showDonationForm = $this->getItemManager()->isItemDonation($item);
return [$proxy, $bidForm, $buyForm, $donationForm, $showBidForm, $showBuyForm, $showDonationForm];
}
}