Created
June 25, 2012 21:09
-
-
Save jjbohn/2991258 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace OpenSky\Bundle\MainBundle\Controller; | |
use OpenSky\Bundle\MainBundle\Document\Sellable\Sellable; | |
use OpenSky\Bundle\MainBundle\Document\Seller\Category; | |
use OpenSky\Bundle\MainBundle\Document\User; | |
use OpenSky\Component\Date\DateRange; | |
use Symfony\Component\HttpFoundation\Request; | |
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | |
use Symfony\Component\HttpKernel\HttpKernelInterface; | |
class BrowseController extends FrontendController | |
{ | |
const SELLABLE_PAGE_SIZE = 24; // 24 is good for responsive design: divisible by 1,2,3,4,6,12. | |
const SELLER_PAGE_SIZE = 12; | |
const CLEARANCE_SHOP = '4f553a915c175d3e6d000043'; | |
const COLLECTION_PAGE_SIZE = 4; | |
public function browseSellablesAction($slug = null, $page = 1) | |
{ | |
if ($slug !== null) { | |
$taxon = $this->getDocumentRepository('MainBundle:Taxonomy\Taxon')->findOneBySlug($slug, true); | |
if ($taxon === null) { | |
throw new NotFoundHttpException(); | |
} | |
return $this->render('MainBundle:Browse:products.html.twig', array( | |
'page' => $page, | |
'slug' => $slug, | |
'taxon' => $taxon, | |
)); | |
} | |
return $this->render('MainBundle:Browse:products.html.twig', array( | |
'page' => $page, | |
'slug' => $slug, | |
)); | |
} | |
/** | |
* TODO - This implementation is temporary while a new clearance implementation is being built | |
* @param int $page | |
*/ | |
public function browseClearanceAction($page = 1) | |
{ | |
return $this->render('MainBundle:Browse:products.html.twig', array( | |
'page' => $page, | |
'slug' => 'clearance', | |
)); | |
} | |
public function browseSellersAction($slug = null, $page = 1) | |
{ | |
$taxon = null; | |
if ($slug !== null) { | |
$taxon = $this->getDocumentRepository('MainBundle:Taxonomy\Taxon')->findOneBySlug($slug, true); | |
} | |
return $this->render('MainBundle:Browse:sellers.html.twig', array( | |
'page' => $page, | |
'taxon' => $taxon, | |
)); | |
} | |
// internal | |
public function renderCategorySellablesAction(Request $request, $isLoggedIn = false) | |
{ | |
$page = $request->get('page', 1); | |
$slug = $request->get('slug'); | |
// only trust the current user on master requests | |
if (HttpKernelInterface::MASTER_REQUEST === $request->attributes->get('_type') && $user = $this->getLoggedInUser()) { | |
$isLoggedIn = true; | |
} | |
$taxon = $this->getDocumentRepository('MainBundle:Taxonomy\Taxon')->findOneBySlug($slug, true); | |
$categoryFlashes = $this->getDocumentRepository('MainBundle:Sellable\CategoryFlash') | |
->findFlashes(DateRange::getTodaysDateRange(), $taxon) | |
->toArray(); | |
$this->getPrimer()->prime($categoryFlashes, 'sellable'); | |
$categoryFlashSellables = array(); | |
$categoryFlashSellableIds = array(); | |
foreach ($categoryFlashes as $flash) { | |
$categoryFlashSellables[] = $flash->getSellable(); | |
$categoryFlashSellableIds[] = $flash->getSellable()->getId(); | |
} | |
$categoryFlashCount = count($categoryFlashSellableIds); | |
if ($page == 1) { | |
$sellableSkip = self::SELLABLE_PAGE_SIZE * ($page - 1); | |
$sellableLimit = self::SELLABLE_PAGE_SIZE - $categoryFlashCount; | |
$collectionSkip = self::COLLECTION_PAGE_SIZE * ($page - 1); | |
$collectionLimit = self::COLLECTION_PAGE_SIZE; | |
} else { | |
$sellableSkip = (self::SELLABLE_PAGE_SIZE * 2 * ($page - 1)) - self::SELLABLE_PAGE_SIZE - $categoryFlashCount; | |
$sellableLimit = self::SELLABLE_PAGE_SIZE * 2; | |
$collectionSkip = (self::COLLECTION_PAGE_SIZE * 2 * ($page - 1)) - self::COLLECTION_PAGE_SIZE; | |
$collectionLimit = self::COLLECTION_PAGE_SIZE * 2; | |
} | |
$category = $this->getDocumentRepository('MainBundle:Seller\Category')->findOneBySlug($slug, true); | |
$sellables = $this->getObjectsForCategory('MainBundle:Sellable\Sellable', $sellableSkip, $sellableLimit, $category); | |
$collections = $this->getObjectsForCategory('MainBundle:SellableCollection', $collectionSkip, $collectionLimit, $category); | |
$this->getPrimer()->prime($sellables, 'product'); | |
// Filter sold out sellables, do this second so we only prime products where necessary | |
$inventoryManager = $this->container->get('inventory.manager'); | |
$inventoryManager->primeSellables($sellables); | |
$sellables = array_filter($sellables, function(Sellable $sellable) use ($inventoryManager) { | |
return $inventoryManager->isInStock($sellable); | |
}); | |
if ($page == 1) { | |
$sellables = array_merge($categoryFlashSellables, $sellables); | |
} | |
$response = $this->render('MainBundle:Browse:_category_products.html.twig', array( | |
'page' => $page, | |
'slug' => $slug, | |
'category' => $category, | |
'sellables' => $sellables, | |
'collections' => $collections, | |
'isLoggedIn' => $isLoggedIn, | |
)); | |
if (HttpKernelInterface::SUB_REQUEST === $request->attributes->get('_type')) { | |
$response->setPublic(); | |
$response->setExpires(new \DateTime(sprintf('%d seconds', 300 - time() % 300))); | |
} | |
return $response; | |
} | |
/** | |
* TODO - This implementation is temporary while a new clearance implementation is being built | |
*/ | |
public function renderClearanceSellablesAction(Request $request, $isLoggedIn = false) | |
{ | |
$page = $request->get('page', 1); | |
// only trust the current user on master requests | |
if (HttpKernelInterface::MASTER_REQUEST === $request->attributes->get('_type') && $user = $this->getLoggedInUser()) { | |
$isLoggedIn = true; | |
} | |
if ($page == 1) { | |
$skip = self::SELLABLE_PAGE_SIZE * ($page - 1); | |
$limit = self::SELLABLE_PAGE_SIZE; | |
} else { | |
$skip = (self::SELLABLE_PAGE_SIZE * 2 * ($page - 1)) - self::SELLABLE_PAGE_SIZE; | |
$limit = self::SELLABLE_PAGE_SIZE * 2; | |
} | |
$qb = $this->getDocumentRepository('MainBundle:Sellable\Sellable')->createActiveQueryBuilder() | |
->field('liveDate')->lte(new \DateTime()) | |
->sort('lastActivityDate', 'desc') | |
->skip($skip) | |
->limit($limit) | |
->slaveOkay(true); | |
// Temporary until we finish the new clearance functionality | |
$qb->field('seller.$id')->equals(new \MongoId(self::CLEARANCE_SHOP)); | |
$sellables = $qb->getQuery()->execute()->toArray(); | |
$this->getPrimer()->prime($sellables, 'seller'); | |
// Filter sellables for active sellers | |
$sellables = array_filter($sellables, function(Sellable $sellable) { | |
return $sellable->getSeller()->isActive(); | |
}); | |
$this->getPrimer()->prime($sellables, 'product'); | |
// Filter sold out sellables, do this second so we only prime products where necessary | |
$inventoryManager = $this->container->get('inventory.manager'); | |
$inventoryManager->primeSellables($sellables); | |
$sellables = array_filter($sellables, function(Sellable $sellable) use ($inventoryManager) { | |
return $inventoryManager->isInStock($sellable); | |
}); | |
$response = $this->render('MainBundle:Browse:_category_products.html.twig', array( | |
'page' => $page, | |
'slug' => 'clearance', | |
'sellables' => $sellables, | |
'isLoggedIn' => $isLoggedIn, | |
)); | |
if (HttpKernelInterface::SUB_REQUEST === $request->attributes->get('_type')) { | |
$response->setPublic(); | |
$response->setExpires(new \DateTime(sprintf('%d seconds', 300 - time() % 300))); | |
} | |
return $response; | |
} | |
/** | |
* Get active Sellable or SellableCollection for a given categorySlug | |
* | |
* @return array | |
*/ | |
private function getObjectsForCategory($type, $skip, $limit, Category $category = null) | |
{ | |
if (!in_array($type, array('MainBundle:Sellable\Sellable', 'MainBundle:SellableCollection'))) { | |
throw new \RuntimeException(sprintf('Cannot handle %s', $type)); | |
} | |
$qb = $this->getDocumentRepository($type)->createActiveQueryBuilder() | |
->sort('lastActivityDate', 'desc') | |
->skip($skip) | |
->limit($limit) | |
->slaveOkay(true) | |
; | |
if ($category) { | |
$qb->field('categories')->references($category); | |
} else { | |
$privateId = $this->container->getParameter('opensky.private_category.id'); | |
$qb->field('categories.$id')->notEqual(new \MongoId($privateId)); | |
} | |
$qb->field('liveDate')->lte(new \DateTime()); | |
$objects = $qb->getQuery()->execute()->toArray(); | |
return $objects; | |
} | |
public function renderCategorySellersAction(Request $request) | |
{ | |
$page = $request->get('page', 1); | |
$slug = $request->get('slug'); | |
// only trust the current user on master requests | |
if (HttpKernelInterface::MASTER_REQUEST === $request->attributes->get('_type') && $user = $this->getLoggedInUser()) { | |
$sellerSlugs = $user->getSellerSlugs(); | |
} else { | |
$sellerSlugs = $request->get('sellerSlugs', array()); | |
} | |
if ($page == 1) { | |
$skip = self::SELLER_PAGE_SIZE * ($page - 1); | |
$limit = self::SELLER_PAGE_SIZE; | |
} else { | |
$skip = (self::SELLER_PAGE_SIZE * 2 * ($page - 1)) - self::SELLER_PAGE_SIZE; | |
$limit = self::SELLER_PAGE_SIZE * 2; | |
} | |
$qb = $this->getDocumentRepository('MainBundle:Seller') | |
->createActiveQueryBuilder() | |
->sort('firstName', 'asc') | |
->skip($skip) | |
->limit($limit) | |
->slaveOkay(true) | |
; | |
if ($taxon = $this->getDocumentRepository('MainBundle:Taxonomy\Taxon')->findOneBySlug($slug, true)) { | |
$qb->field('taxonomy.$id')->equals(new \MongoId($taxon->getId())); | |
} | |
$sellers = $qb->getQuery()->execute()->toArray(); | |
$this->getPrimer()->prime($sellers, 'mostRecentSellables'); | |
$response = $this->render('MainBundle:Browse:_category_sellers.html.twig', array( | |
'taxon' => $taxon, | |
'sellers' => $sellers, | |
'sellerSlugs' => $sellerSlugs, | |
'page' => $page, | |
)); | |
if (HttpKernelInterface::SUB_REQUEST === $request->attributes->get('_type')) { | |
$response->setPublic(); | |
$response->setExpires(new \DateTime(sprintf('+%d seconds', 300 - time() % 300))); | |
} | |
return $response; | |
} | |
// private | |
/** | |
* @return OpenSky\Bundle\MainBundle\ODM\UnitOfWorkPrimer | |
*/ | |
private function getPrimer() | |
{ | |
return $this->get('odm.unitofworkprimer'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment