src/Gh/FrontBundle/Controller/CardController.php line 354

Open in your IDE?
  1. <?php
  2. namespace Gh\FrontBundle\Controller;
  3. use Gh\FrontBundle\Classes\Sidebar\SidebarAuthor;
  4. use Gh\FrontBundle\Classes\Sidebar\SidebarBuy;
  5. use Gh\FrontBundle\Classes\Sidebar\SidebarCard;
  6. use Gh\FrontBundle\Controller\GhController,
  7.     Symfony\Component\Routing\Annotation\Route,
  8.     Sensio\Bundle\FrameworkExtraBundle\Configuration\Template,
  9.     Symfony\Component\HttpFoundation\RedirectResponse,
  10.     Gh\DatabaseBundle\Entity\GhCard,
  11.     Gh\DatabaseBundle\Entity\GhDownload,
  12.     Gh\DatabaseBundle\Entity\GhNews,
  13.     Gh\FrontBundle\Classes\TitleClass,
  14.     Gh\CommonBundle\Classes\Meta\MetaClass,
  15.     Gh\FrontBundle\Classes\BreadcrumbClass,
  16.     Gh\FrontBundle\Classes\UtilClass,
  17.     Gh\FrontBundle\Classes\InternalClass,
  18.     Gh\FrontBundle\Classes\ShopClass,
  19.     Gh\FrontBundle\Classes\MenuActiveClass,
  20.     Gh\FrontBundle\Classes\ListValues\ConsoleClass,
  21.     Gh\FrontBundle\Classes\ListValues\SectionTypeClass,
  22.     Gh\FrontBundle\Classes\ListValues\WorkflowStateClass,
  23.     Gh\FrontBundle\Classes\Helpers\PaginatorHelper,
  24.     Gh\FrontBundle\Classes\Helpers\MovieHelper,
  25.     Gh\FrontBundle\Classes\Sidebar\SidebarClass,
  26.     Gh\FrontBundle\Classes\Sidebar\SidebarSimilarCards;
  27. class CardController extends GhController
  28. {
  29.     const ARTICLE_TYPE_REVIEW 'review';
  30.     const ARTICLE_TYPE_PREVIEW 'preview';
  31.     /**
  32.      * This component manages the card layout header.
  33.      * @Template()
  34.      * @param GhCard $card
  35.      * @param string $route
  36.      * @return array
  37.      */
  38.     public function dynamicCardLayoutHeaderAction($card$route)
  39.     {
  40.         // Get the also available consoles (the current card is at first position)
  41.         $em $this->getDoctrine()->getManager();
  42.         $alsoAvailableCards $em->getRepository('GhDatabaseBundle:GhCard')->getAlsoAvailableCards($cardtrue);
  43.         array_unshift($alsoAvailableCards$card);
  44.         // Get the shop links
  45.         $shopLinks = array(
  46.             'amazon' => ShopClass::getAmazonLink($card),
  47.             'priceminister' => ShopClass::getPriceMinisterLink($card),
  48.             'ebay' => ShopClass::getEbayLink($card),
  49.             'boulanger' => ShopClass::getBoulangerLink($card)
  50.         );
  51.         // Get review
  52.         $cardReviews $em->getRepository('GhDatabaseBundle:GhReview')->getReviewsByCardId($card->getId());
  53.         if ($cardReviews != null) {
  54.             $cardReview $cardReviews[0];
  55.         } else {
  56.             $cardReview null;
  57.         }
  58.         // Increment view counters (total and daily)
  59.         $card->setCounter($card->getCounter() + 1);
  60.         $card->setCounterdaily($card->getCounterdaily() + 1);
  61.         $em->flush();
  62.         // Push the block Similar games
  63.         // GH-78 : do not display similar cards for companies and material
  64.         if(!in_array($card->getType(), array(GhCard::CARD_TYPE_COMPANYGhCard::CARD_TYPE_MATERIAL))) {
  65.             SidebarClass::getInstance()->push('similarCards', new SidebarSimilarCards($card), -1);
  66.         }
  67.         // Push the Buy sidebar
  68.         SidebarClass::getInstance()->push('buy', new SidebarBuy($card$shopLinks), -1);
  69.         // Push the About card sidebar
  70.         SidebarClass::getInstance()->push('card', new SidebarCard($alsoAvailableCards), -1);
  71.         return array(
  72.             'card' => $card,
  73.             'alsoAvailableCards' => $alsoAvailableCards,
  74.             'review' => $cardReview,
  75.             'route' => $route
  76.         );
  77.     }
  78.     /**
  79.      * @Route(
  80.      *      "/{console}/{cardId}-{slug}/",
  81.      *      name="GhFrontBundle_Card_card",
  82.      *      requirements={"console" = "([0-9a-zA-Z]+)", "cardId" = "([0-9]+)", "slug" = "([0-9a-zA-Z_-]+)"}
  83.      * )
  84.      * @Template()
  85.      */
  86.     public function cardAction($console$cardId$slug)
  87.     {   
  88.         $em $this->getDoctrine()->getManager();
  89.         $card $em->getRepository('GhDatabaseBundle:GhCard')->getCardAndCompanies($cardId);
  90.         
  91.         if ($card === null) {
  92.             // Throw a 404 error if no card found
  93.             throw $this->createNotFoundException('Aucune fiche n\'a été trouvée');
  94.         }
  95.         
  96.         // Generate title
  97.         TitleClass::getInstance()->setTitle($card->getTitle().' - '.$card->getDisplayConsole());
  98.         
  99.         // Generate breadcrumb
  100.         $breadcrumb BreadcrumbClass::getInstance();
  101.         $breadcrumb->addPath(ConsoleClass::getInstance()->getLongFromCode($card->getConsole()), $this->get('router'), 'GhFrontBundle_Page_homepageDefault', array('console' => ConsoleClass::getInstance()->getShortFromCode($card->getConsole())));
  102.         $breadcrumb->addPath($card->getTitle());
  103.         
  104.         // Generate meta
  105.         $meta MetaClass::getInstance();
  106.         $meta->setMetaCard($card);
  107.         $description '';
  108.         // Depending on card type, generate an appropriated description
  109.         switch ($card->getType()) {
  110.             case GhCard::CARD_TYPE_GAME:
  111.                 $description 'Toutes les dernières infos sur le jeu vidéo '.$card->getTitle().' sur '.$card->getDisplayConsole().' sur GameHope : tests, previews, news, reportages, vidéos, astuces, téléchargements.';
  112.                 break;
  113.             case GhCard::CARD_TYPE_EVENT:
  114.                 $description 'Toutes les dernières infos sur l\'événement '.$card->getTitle().' sur GameHope : news, reportages, vidéos, premières impressions.';
  115.                 break;
  116.             case GhCard::CARD_TYPE_COMPANY:
  117.                 $description 'Toutes les dernières infos sur la société '.$card->getTitle().' sur GameHope : tests, previews, news, news, reportages, vidéos.';
  118.                 break;
  119.             case GhCard::CARD_TYPE_MATERIAL:
  120.                 $description 'Toutes les dernières infos sur l\'accessoire '.$card->getTitle().' sur GameHope : tests, previews, news, news, reportages, vidéos.';
  121.                 break;
  122.         }
  123.         $meta->addMeta('description'$description);
  124.         $meta->addMeta('keywords''jeux vidéo, '.$card->getTitle().', '.$card->getDisplayConsole());
  125.         
  126.         // Generate canonical URL
  127.         $this->updateCanonicalUrl($card);
  128.         
  129.         // Get data for block "Gallery"
  130.         $latestPictures $em->getRepository('GhDatabaseBundle:GhGallery')->getGalleryByCardId(
  131.             $cardId
  132.             0
  133.             $this->container->getParameter('card_limit_show_images_block_gallery')
  134.         );
  135.         
  136.         // Get data for block "Fil d'actualité"
  137.         $latestArticles $em->getRepository('GhDatabaseBundle:FakeArticle')->getLatestArticlesForCard($cardId$this->container);
  138.         
  139.         // Get data for blocks "Review", "Preview", "Dossier"
  140.         $cardReviews $em->getRepository('GhDatabaseBundle:GhReview')->getReviewsByCardId($cardId);
  141.         $cardPreviews $em->getRepository('GhDatabaseBundle:GhPreview')->getPreviewsByCardId($cardId);
  142.         $cardDossiers $em->getRepository('GhDatabaseBundle:GhDossier')->getDossiersByCardId($cardId);
  143.         
  144.         // Get data for block "Opinion"
  145.         $cardOpinions $em->getRepository('GhDatabaseBundle:GhNews')->getNewsListByCardIdAndSubsectionId($cardIdGhNews::NEWS_TYPE_OPINION);
  146.         // Get data for published/developed games (company only)
  147.         $publishedGames null;
  148.         $developedGames null;
  149.         if ($card->getType() == GhCard::CARD_TYPE_COMPANY) {
  150.             $publishedGames $em->getRepository('GhDatabaseBundle:GhCard')->getPublishedOrDevelopedCards(
  151.                 $card
  152.                 GhCard::CARD_COMPANY_PUBLISHER,
  153.                 0,
  154.                 $this->container->getParameter('card_company_published_max_list')
  155.             );
  156.             
  157.             $developedGames $em->getRepository('GhDatabaseBundle:GhCard')->getPublishedOrDevelopedCards(
  158.                 $card
  159.                 GhCard::CARD_COMPANY_DEVELOPER,
  160.                 0,
  161.                 $this->container->getParameter('card_company_published_max_list')
  162.             );
  163.         }
  164.         
  165.         // Get data for compatible games (material only)
  166.         $compatibleGames null;
  167.         if ($card->getType() == GhCard::CARD_TYPE_MATERIAL) {
  168.             $compatibleGames $em->getRepository('GhDatabaseBundle:GhCardMaterial')->getCompatibleCards(
  169.                 $card
  170.             );
  171.         }
  172.         
  173.         return array(
  174.             'card' => $card
  175.             'latestArticles' => $latestArticles,
  176.             'latestPictures' => $latestPictures,
  177.             'cardReviews' => $cardReviews,
  178.             'cardPreviews' => $cardPreviews,
  179.             'cardDossiers' => $cardDossiers,
  180.             'cardOpinions' => $cardOpinions,
  181.             'publishedGames' => $publishedGames,
  182.             'developedGames' => $developedGames,
  183.             'compatibleGames' => $compatibleGames
  184.         );
  185.     }
  186.     
  187.     /**
  188.      * This private method is used to factorize the code between review and preview pages, which
  189.      * are quite similar.
  190.      * 
  191.      * @param int $cardId Card identifier (from GhCard entity).
  192.      * @param int $articleId Article identifier (from GhReview or GhPreview entities).
  193.      * @param string $type CardController::ARTICLE_TYPE_REVIEW or CardController::ARTICLE_TYPE_PREVIEW.
  194.      * @return array/RedirectResponse Array with the following keys: 'card', 'article'.
  195.      *      If an error is thrown, RedirectResponse is sent.
  196.      */
  197.     private function reviewPreviewAction($cardId$articleId$type)
  198.     {
  199.         $em $this->getDoctrine()->getManager();
  200.         $card $em->getRepository('GhDatabaseBundle:GhCard')->getCardAndCompanies($cardId);
  201.         
  202.         if ($card === null) {
  203.             // Throw a 404 error if no card found
  204.             throw $this->createNotFoundException('Aucune fiche n\'a été trouvée');
  205.         }
  206.         
  207.         if ($type == self::ARTICLE_TYPE_REVIEW) {
  208.             $article $em->getRepository('GhDatabaseBundle:GhReview')->findOneById($articleId);
  209.         } elseif ($type == self::ARTICLE_TYPE_PREVIEW) {
  210.             $article $em->getRepository('GhDatabaseBundle:GhPreview')->findOneById($articleId);
  211.         }
  212.         
  213.         if ($article === null) {
  214.             // Throw a 404 error if no article found
  215.             throw $this->createNotFoundException('Aucun article n\'a été trouvé');
  216.         }
  217.         
  218.         // Increment view counter
  219.         $article->setCounter($article->getCounter() + 1);
  220.         $em->flush();
  221.         
  222.         // Generate title
  223.         if ($type == self::ARTICLE_TYPE_REVIEW) {
  224.             $title 'Test';
  225.         } elseif ($type == self::ARTICLE_TYPE_PREVIEW) {
  226.             $title 'Preview';
  227.         }
  228.         $title .= ' '.$card->getTitle().' - '.$card->getDisplayConsole();
  229.         TitleClass::getInstance()->setTitle($title);
  230.         
  231.         // Generate breadcrumb
  232.         $breadcrumb BreadcrumbClass::getInstance();
  233.         $breadcrumb->addPath(ConsoleClass::getInstance()->getLongFromCode($card->getConsole()), $this->get('router'), 'GhFrontBundle_Page_homepageDefault', array('console' => ConsoleClass::getInstance()->getShortFromCode($card->getConsole())));
  234.         $breadcrumb->addPath($card->getTitle(), $this->get('router'), 'GhFrontBundle_Card_card', array('card' => $card));
  235.         $breadcrumb->addPath(SectionTypeClass::getInstance()->getLabelById($type$article->getType()));
  236.         
  237.         // Generate meta
  238.         $meta MetaClass::getInstance();
  239.         $meta->setMetaCard($card);
  240.         $meta->addMeta('description'SectionTypeClass::getInstance()->getLabelById($type$article->getType()).' du jeu vidéo '.$card->getTitle().' sur '.$card->getDisplayConsole().' sur GameHope.');
  241.         $meta->addMeta('og:type''article');
  242.         $meta->addMeta('og:description'$article->getCatcherfacebook());
  243.         
  244.         // Prevent indexation of not published articles
  245.         if ($article->getWorkflowstate() != WorkflowStateClass::PUBLISHED) {
  246.             $meta->setMeta('robots''noindex, nofollow');
  247.         }
  248.         
  249.         // Generate canonical URL
  250.         if ($type == self::ARTICLE_TYPE_REVIEW) {
  251.             $this->updateCanonicalUrl($card, array('reviewId' => $articleId));
  252.         } elseif ($type == self::ARTICLE_TYPE_PREVIEW) {
  253.             $this->updateCanonicalUrl($card, array('previewId' => $articleId));
  254.         }
  255.         
  256.         $canonicalUrl UtilClass::getCanonicalUrlFromMeta();
  257.         // Push the sidebar Author
  258.         $member $em->getRepository('GhDatabaseBundle:GhTeam')->findOneByName($article->getAuthor());
  259.         SidebarClass::getInstance()->push('author', new SidebarAuthor($member), -1);
  260.         
  261.         return array(
  262.             'card' => $card,
  263.             'article' => $article,
  264.             'canonicalUrl' => $canonicalUrl
  265.         );
  266.     }
  267.     
  268.     /**
  269.      * $previewMode: If true, all articles can be opened. If false, only published articles can be opened.
  270.      * 
  271.      * @Route(
  272.      *      "/{console}/{cardId}-{slug}/test_{reviewId}.html",
  273.      *      name="GhFrontBundle_Card_review",
  274.      *      requirements={"console" = "([0-9a-zA-Z]+)", "cardId" = "([0-9]+)", "slug" = "([0-9a-zA-Z_-]+)", "reviewId" = "([0-9]+)"}
  275.      * )
  276.      * @Template()
  277.      */
  278.     public function reviewAction($console$cardId$slug$reviewId$previewMode false)
  279.     {
  280.         $array $this->reviewPreviewAction($cardId$reviewIdself::ARTICLE_TYPE_REVIEW);
  281.         // If an error is thrown, RedirectResponse is sent
  282.         if ($array instanceof RedirectResponse) {
  283.             return $array;
  284.         }
  285.         
  286.         $meta MetaClass::getInstance();
  287.         $meta->addMeta('keywords''jeux vidéo, '.$array['card']->getTitle().', '.$array['card']->getDisplayConsole().', test, '.SectionTypeClass::getInstance()->getLabelById('review'$array['article']->getType()));
  288.         
  289.         // Set menu active
  290.         MenuActiveClass::getInstance()->setMenuActive('review');
  291.         
  292.         return array(
  293.             'card' => $array['card'],
  294.             'article' => $array['article'],
  295.             'canonicalUrl' => $array['canonicalUrl']
  296.         );
  297.     }
  298.     
  299.     /**
  300.      * Route used by GameHope V4 and V5.
  301.      * 
  302.      * @Route(
  303.      *      "/test.articles/{reviewId}.html",
  304.      *      name="GhFrontBundle_Card_reviewOldRoute",
  305.      *      requirements={"reviewId" = "([0-9]+)"}
  306.      * )
  307.      */
  308.     public function reviewOldRouteAction($reviewId)
  309.     {
  310.         // Find the associated review
  311.         $em $this->getDoctrine()->getManager();
  312.         $article $em->getRepository('GhDatabaseBundle:GhReview')->findOneById($reviewId);
  313.         
  314.         // Throw a 404 error if no article found
  315.         if ($article === null) {
  316.             throw $this->createNotFoundException('Aucun article n\'a été trouvé');
  317.         }
  318.         
  319.         $routeParams UtilClass::getRouteParamsFromCard($article->getCardid());
  320.         return $this->redirect($this->generateUrl(
  321.                 'GhFrontBundle_Card_review',
  322.                 array_merge($routeParams, array('reviewId' => $reviewId))
  323.             ), 
  324.             301
  325.         );
  326.     }
  327.     
  328.     /**
  329.      * $previewMode: If true, all articles can be opened. If false, only published articles can be opened.
  330.      * 
  331.      * @Route(
  332.      *      "/{console}/{cardId}-{slug}/preview_{previewId}.html",
  333.      *      name="GhFrontBundle_Card_preview",
  334.      *      requirements={"console" = "([0-9a-zA-Z]+)", "cardId" = "([0-9]+)", "slug" = "([0-9a-zA-Z_-]+)", "previewId" = "([0-9]+)"}
  335.      * )
  336.      * @Template()
  337.      */
  338.     public function previewAction($console$cardId$slug$previewId$previewMode false)
  339.     {
  340.         $array $this->reviewPreviewAction($cardId$previewIdself::ARTICLE_TYPE_PREVIEW);
  341.         // If an error is thrown, RedirectResponse is sent
  342.         if ($array instanceof RedirectResponse) {
  343.             return $array;
  344.         }
  345.         
  346.         // Generate meta
  347.         $meta MetaClass::getInstance();
  348.         $meta->addMeta('keywords''jeux vidéo, '.$array['card']->getTitle().', '.$array['card']->getDisplayConsole().', preview, '.SectionTypeClass::getInstance()->getLabelById('preview'$array['article']->getType()));
  349.         
  350.         // Set menu active
  351.         MenuActiveClass::getInstance()->setMenuActive('preview');
  352.         
  353.         return array(
  354.             'card' => $array['card'],
  355.             'article' => $array['article'],
  356.             'canonicalUrl' => $array['canonicalUrl']
  357.         );
  358.     }
  359.     
  360.     /**
  361.      * @Route(
  362.      *      "/{console}/{cardId}-{slug}/galerie-{page}.html",
  363.      *      name="GhFrontBundle_Card_gallery",
  364.      *      requirements={"console" = "([0-9a-zA-Z]+)", "cardId" = "([0-9]+)", "slug" = "([0-9a-zA-Z_-]+)", "page" = "([0-9]+)"}
  365.      * )
  366.      * @Template()
  367.      */
  368.     public function galleryAction($console$cardId$slug$page)
  369.     {      
  370.         $em $this->getDoctrine()->getManager();
  371.         $card $em->getRepository('GhDatabaseBundle:GhCard')->getCardAndCompanies($cardId);
  372.         
  373.         // Throw a 404 error if no card found
  374.         if ($card === null) {
  375.             throw $this->createNotFoundException('Aucun article n\'a été trouvé');
  376.         }
  377.         
  378.         // Generate title
  379.         TitleClass::getInstance()->setTitle($card->getTitle().' - '.$card->getDisplayConsole().' : la galerie d\'images');
  380.         
  381.         // Generate breadcrumb
  382.         $breadcrumb BreadcrumbClass::getInstance();
  383.         $breadcrumb->addPath(ConsoleClass::getInstance()->getLongFromCode($card->getConsole()), $this->get('router'), 'GhFrontBundle_Page_homepageDefault', array('console' => ConsoleClass::getInstance()->getShortFromCode($card->getConsole())));
  384.         $breadcrumb->addPath($card->getTitle(), $this->get('router'), 'GhFrontBundle_Card_card', array('card' => $card));
  385.         $breadcrumb->addPath('Galerie'$this->get('router'), 'GhFrontBundle_Card_gallery', array('card' => $card'page' => 1));
  386.         if ($page != 1) {
  387.             $breadcrumb->addPath('Page '.$page);
  388.         }
  389.         
  390.         // Generate meta
  391.         $meta MetaClass::getInstance();
  392.         $meta->setMetaCard($card);
  393.         $meta->addMeta('description''Découvrez toutes les images du jeu vidéo '.$card->getTitle().' sur '.$card->getDisplayConsole().' : screenshots, captures d\'écran, artworks, wallpapers.');
  394.         $meta->addMeta('keywords''jeux vidéo, '.$card->getTitle().', '.$card->getDisplayConsole());
  395.         
  396.         // Generate canonical URL
  397.         $this->updateCanonicalUrl($card, array('page' => $page));
  398.         
  399.         // Set menu active
  400.         MenuActiveClass::getInstance()->setMenuActive('gallery');
  401.         
  402.         // Pagination
  403.         $paginator = new PaginatorHelper(
  404.             $em->getRepository('GhDatabaseBundle:GhGallery')->countGalleryByCardId($cardId), 
  405.             $page
  406.             $this->container->getParameter('gallery_images_per_page')
  407.         );
  408.         $paginator->setSfLinkedController($this);
  409.         $paginator->setRouter($this->get('router'));
  410.         $paginator->setSfUrlParameters(UtilClass::getRouteParamsFromCard($card));
  411.         $paginator->setPageParameterName('page');
  412.         $paginator->setPaginationStep($this->container->getParameter('gallery_pagination_step'));
  413.         
  414.         // Get pictures list
  415.     $associatedGalleries $em->getRepository('GhDatabaseBundle:GhGallery')->getGalleryByCardId($cardId$paginator->getOffset(), $paginator->getLimit());
  416.         
  417.         // Throw a 404 error if no picture found
  418.         if (count($associatedGalleries) == 0) {
  419.             throw $this->createNotFoundException('Aucune image n\'a été trouvée');
  420.         }
  421.         
  422.         // Determine the date limit to highlight the screenshots
  423.         $newInterval $this->container->getParameter('gallery_new_interval');
  424.         $newDateLimit time() - ($newInterval 3600 24);
  425.         
  426.         return array(
  427.             'card' => $card
  428.             'page' => $page
  429.             'associatedGalleries' => $associatedGalleries
  430.             'paginator' => $paginator
  431.             'imagesPerLine' => $this->container->getParameter('gallery_images_per_line'),
  432.             'newDateLimit' => $newDateLimit
  433.         );
  434.     }
  435.     
  436.     /**
  437.      * @Route(
  438.      *      "/{console}/{cardId}-{slug}/galerie.html",
  439.      *      name="GhFrontBundle_Card_galleryDefault",
  440.      *      requirements={"console" = "([0-9a-zA-Z]+)", "cardId" = "([0-9]+)", "slug" = "([0-9a-zA-Z_-]+)"}
  441.      * )
  442.      */
  443.     public function galleryDefaultAction($console$cardId$slug)
  444.     {
  445.         return $this->redirect(
  446.             $this->generateUrl(
  447.                 'GhFrontBundle_Card_gallery',
  448.                 array('console' => $console'cardId' => $cardId'slug' => $slug'page' => 1)
  449.             ), 
  450.             301
  451.         );
  452.     }
  453.     
  454.     /**
  455.      * @Route(
  456.      *      "/{console}/{cardId}-{slug}/videos.html",
  457.      *      name="GhFrontBundle_Card_movie",
  458.      *      requirements={"console" = "([0-9a-zA-Z]+)", "cardId" = "([0-9]+)", "slug" = "([0-9a-zA-Z_-]+)"}
  459.      * )
  460.      * @Template()
  461.      */
  462.     public function movieAction($console$cardId$slug)
  463.     {      
  464.         $type NULL;
  465.         $request $this->getRequest();
  466.         if ($request->query->get('type')) {
  467.             $type $request->query->get('type');
  468.         }
  469.         
  470.         return $this->movieFactorized($cardId0$type);
  471.     }
  472.     
  473.     /**
  474.      * @Route(
  475.      *      "/{console}/{cardId}-{slug}/video-{movieId}.html",
  476.      *      name="GhFrontBundle_Card_movieView",
  477.      *      requirements={"console" = "([0-9a-zA-Z]+)", "cardId" = "([0-9]+)", "slug" = "([0-9a-zA-Z_-]+)", "movieId" = "([0-9]+)"}
  478.      * )
  479.      * @Template("@GhFront/card/movie.html.twig")
  480.      */
  481.     public function movieViewAction($console$cardId$slug$movieId)
  482.     {
  483.         return $this->movieFactorized($cardId$movieId);
  484.     }
  485.    
  486.     
  487.     /**
  488.      * This private method is called by both GhFrontBundle_Card_movie and GhFrontBundle_Card_movieView routes.
  489.      * 
  490.      * @param integer $cardId
  491.      * @param integer $movieId By default, set to 0 (no movie selected).
  492.      * @param integer $type By default, set to NULL (no category selected).
  493.      * @return array() 
  494.      */
  495.     private function movieFactorized($cardId$movieId 0$type NULL)
  496.     {
  497.         $em $this->getDoctrine()->getManager();
  498.         $card $em->getRepository('GhDatabaseBundle:GhCard')->getCardAndCompanies($cardId);
  499.         
  500.         // Select the movies
  501.         $associatedMovies $em->getRepository('GhDatabaseBundle:GhMovie')->getMovieByCardIdAndType($cardId$type);
  502.         
  503.         if (count($associatedMovies) == 0) {
  504.             // Throw a 404 error if no movie found
  505.             throw $this->createNotFoundException('Aucune vidéo n\'a été trouvée');
  506.         }
  507.         // Extract all categories
  508.         if ($type !== NULL) {
  509.             $associatedMoviesForCategories $em->getRepository('GhDatabaseBundle:GhMovie')->getMovieByCardIdAndType($cardId);
  510.         } else {
  511.             $associatedMoviesForCategories $associatedMovies;
  512.         }
  513.         $categoriesList = array();
  514.         foreach ($associatedMoviesForCategories as $movie) {
  515.             if (!in_array($movie->getType(), $categoriesList)) {
  516.                 $categoriesList[] = $movie->getType();
  517.             }
  518.         }
  519.         sort($categoriesList);
  520.         
  521.         // Get the movie to display
  522.         $selectedMovie null;
  523.         if ($movieId == 0) {
  524.             // When no movie is selected, choose one by default
  525.             if (count($associatedMovies) > 0) {
  526.                 $selectedMovie $associatedMovies[0];
  527.             }
  528.             // Exclude current video
  529.             array_shift($associatedMovies);
  530.         } else {
  531.             // When a movie is selected, choose it, and remove it from the list
  532.             for ($i 0$i count($associatedMovies); $i++) {
  533.                 if ($associatedMovies[$i]->getId() == $movieId) {
  534.                     $selectedMovie $associatedMovies[$i];
  535.                     unset($associatedMovies[$i]);
  536.                 }
  537.             }
  538.         }
  539.         
  540.         if ($selectedMovie === null) {
  541.             // Throw a 404 error if no movie found
  542.             throw $this->createNotFoundException('Aucune vidéo n\'a été trouvée');
  543.         }
  544.         
  545.         // Increment view counter
  546.         if ($selectedMovie) {
  547.             $selectedMovie->setCounter($selectedMovie->getCounter() + 1);
  548.             $em->flush();
  549.         }
  550.         
  551.         // Determine the date limit to highlight the movies
  552.         $newInterval $this->container->getParameter('movie_new_interval');
  553.         $newDateLimit time() - ($newInterval 3600 24);
  554.         
  555.         // Generate title
  556.         $title $card->getTitle().' - '.$card->getDisplayConsole().' : vidéo';
  557.         if ($selectedMovie && mb_strtolower($selectedMovie->getTitle(), 'UTF-8') != mb_strtolower($card->getTitle(), 'UTF-8')) {
  558.             $title .= ' '.$selectedMovie->getTitle().' ('.SectionTypeClass::getInstance()->getLabelById('movie'$selectedMovie->getType()).')';
  559.         }
  560.         TitleClass::getInstance()->setTitle($title);
  561.         
  562.         // Generate breadcrumb
  563.         $breadcrumb BreadcrumbClass::getInstance();
  564.         $breadcrumb->addPath(ConsoleClass::getInstance()->getLongFromCode($card->getConsole()), $this->get('router'), 'GhFrontBundle_Page_homepageDefault', array('console' => ConsoleClass::getInstance()->getShortFromCode($card->getConsole())));
  565.         $breadcrumb->addPath($card->getTitle(), $this->get('router'), 'GhFrontBundle_Card_card', array('card' => $card));
  566.         $breadcrumb->addPath('Vidéos'$this->get('router'), 'GhFrontBundle_Card_movie', array('card' => $card));
  567.         if ($type !== NULL) {
  568.             $breadcrumb->addPath(SectionTypeClass::getInstance()->getLabelById('movie'$type), $this->get('router'), 'GhFrontBundle_Card_movie', array('card' => $card'type' => $type));
  569.         }
  570.         if ($movieId != 0) {
  571.             $breadcrumb->addPath($selectedMovie->getTitle());
  572.         }
  573.         
  574.         // Generate meta
  575.         $meta MetaClass::getInstance();
  576.         $meta->setMetaCard($card);
  577.         $meta->addMeta('description''Découvrez toutes les vidéos du jeu vidéo '.$card->getTitle().' sur '.$card->getDisplayConsole().' sur GameHope : trailers, bande annonces, reportages, interviews.');
  578.         $meta->addMeta('keywords''jeux vidéo, '.$card->getTitle().', '.$card->getDisplayConsole().', vidéos');
  579.         $meta->addMeta('og:type''video.movie');
  580.         $meta->addMeta('og:image'$this->container->getParameter('base_url_absolute').MovieHelper::displayMovieThumb($this->container$selectedMovie));
  581.         
  582.         // Generate canonical URL
  583.         $this->updateCanonicalUrl($card, array('movieId' => $selectedMovie->getId()), '''GhFrontBundle_Card_movieView');
  584.         $canonicalUrl UtilClass::getCanonicalUrlFromMeta();
  585.         
  586.         // Set menu active
  587.         MenuActiveClass::getInstance()->setMenuActive('movie');
  588.         
  589.         return array(
  590.             'card' => $card,
  591.             'associatedMovies' => $associatedMovies,
  592.             'movie' => $selectedMovie,
  593.             'movieId' => $movieId,
  594.             'selectedType' => $type,
  595.             'newDateLimit' => $newDateLimit,
  596.             'categoriesList' => $categoriesList,
  597.             'canonicalUrl' => $canonicalUrl
  598.         );
  599.     }
  600.     
  601.     /**
  602.      * @Route(
  603.      *      "/{console}/{cardId}-{slug}/presse.html",
  604.      *      name="GhFrontBundle_Card_pressReview",
  605.      *      requirements={"console" = "([0-9a-zA-Z]+)", "cardId" = "([0-9]+)", "slug" = "([0-9a-zA-Z_-]+)"}
  606.      * )
  607.      * @Template()
  608.      */
  609.     public function pressReviewAction($console$cardId$slug)
  610.     {
  611.         $em $this->getDoctrine()->getManager();
  612.         $associatedPressReviews $em->getRepository('GhDatabaseBundle:GhPressReview')->getPressReviewsByCardId($cardId);
  613.         $card $em->getRepository('GhDatabaseBundle:GhCard')->getCardAndCompanies($cardId);
  614.         
  615.         // Throw a 404 error if no card found
  616.         if ($card === null) {
  617.             throw $this->createNotFoundException('Aucune fiche n\'a été trouvée');
  618.         }
  619.         
  620.         // Throw a 404 error if no press review found
  621.         if (count($associatedPressReviews) == 0) {
  622.             throw $this->createNotFoundException('Aucune revue de presse n\'a été trouvée');
  623.         }
  624.         
  625.         // Generate title
  626.         TitleClass::getInstance()->setTitle($card->getTitle().' - '.$card->getDisplayConsole().' : la revue de presse');
  627.         
  628.         // Generate breadcrumb
  629.         $breadcrumb BreadcrumbClass::getInstance();
  630.         $breadcrumb->addPath(ConsoleClass::getInstance()->getLongFromCode($card->getConsole()), $this->get('router'), 'GhFrontBundle_Page_homepageDefault', array('console' => ConsoleClass::getInstance()->getShortFromCode($card->getConsole())));
  631.         $breadcrumb->addPath($card->getTitle(), $this->get('router'), 'GhFrontBundle_Card_card', array('card' => $card));
  632.         $breadcrumb->addPath('Revue de presse');
  633.         
  634.         // Generate meta
  635.         $meta MetaClass::getInstance();
  636.         $meta->setMetaCard($card);
  637.         $meta->addMeta('description''Découvrez toutes les revues de presse du jeu vidéo '.$card->getTitle().' sur '.$card->getDisplayConsole().' sur GameHope.');
  638.         $meta->addMeta('keywords''jeux vidéo, '.$card->getTitle().', '.$card->getDisplayConsole().', revue de presse');
  639.         
  640.         // Generate canonical URL
  641.         $this->updateCanonicalUrl($card);
  642.         
  643.         return array(
  644.             'card' => $card
  645.             'associatedPressReviews' => $associatedPressReviews
  646.         );
  647.     }
  648.     
  649.     /**
  650.      * @Route(
  651.      *      "/{console}/{cardId}-{slug}/astuces.html",
  652.      *      name="GhFrontBundle_Card_hint",
  653.      *      requirements={"console" = "([0-9a-zA-Z]+)", "cardId" = "([0-9]+)", "slug" = "([0-9a-zA-Z_-]+)"}
  654.      * )
  655.      * @Template()
  656.      */
  657.     public function hintAction($console$cardId$slug)
  658.     {
  659.         $em $this->getDoctrine()->getManager();
  660.         $card $em->getRepository('GhDatabaseBundle:GhCard')->getCardAndCompanies($cardId);
  661.         
  662.         // Throw a 404 error if no card found
  663.         if ($card === null) {
  664.             throw $this->createNotFoundException('Aucune fiche n\'a été trouvée');
  665.         }
  666.         
  667.     $associatedHints $em->getRepository('GhDatabaseBundle:GhHint')->getHintByCardId($cardId);
  668.         
  669.         // Throw a 404 error if no hint found
  670.         if (count($associatedHints) == 0) {
  671.             throw $this->createNotFoundException('Aucune astuce n\'a été trouvée');
  672.         }
  673.         // Generate title
  674.         TitleClass::getInstance()->setTitle($card->getTitle().' - '.$card->getDisplayConsole().' : astuces, cheat codes, solution');
  675.         
  676.         // Generate breadcrumb
  677.         $breadcrumb BreadcrumbClass::getInstance();
  678.         $breadcrumb->addPath(ConsoleClass::getInstance()->getLongFromCode($card->getConsole()), $this->get('router'), 'GhFrontBundle_Page_homepageDefault', array('console' => ConsoleClass::getInstance()->getShortFromCode($card->getConsole())));
  679.         $breadcrumb->addPath($card->getTitle(), $this->get('router'), 'GhFrontBundle_Card_card', array('card' => $card));
  680.         $breadcrumb->addPath('Astuces');
  681.         
  682.         // Generate meta
  683.         $meta MetaClass::getInstance();
  684.         $meta->setMetaCard($card);
  685.         $meta->addMeta('description''Découvrez toutes les astuces, cheat codes, triches du jeu vidéo '.$card->getTitle().' sur '.$card->getDisplayConsole().' sur GameHope.');
  686.         $meta->addMeta('keywords''jeux vidéo, '.$card->getTitle().', '.$card->getDisplayConsole().', cheat codes, astuces, triche, solution, soluce');
  687.         
  688.         // Generate canonical URL
  689.         $this->updateCanonicalUrl($card);
  690.         $canonicalUrl UtilClass::getCanonicalUrlFromMeta();
  691.         
  692.         // Set menu active
  693.         MenuActiveClass::getInstance()->setMenuActive('hint');
  694.         
  695.         return array(
  696.             'card' => $card
  697.             'associatedHints' => $associatedHints,
  698.             'canonicalUrl' => $canonicalUrl
  699.         );
  700.     }
  701.     
  702.     /**
  703.      * Route used by GameHope V4 and V5.
  704.      * 
  705.      * @Route(
  706.      *      "/astuce.articles/{hintId}.html",
  707.      *      name="GhFrontBundle_Card_hintOldRoute",
  708.      *      requirements={"hintId" = "([0-9]+)"}
  709.      * )
  710.      */
  711.     public function hintOldRouteAction($hintId)
  712.     {
  713.         // Find the associated hint
  714.         $em $this->getDoctrine()->getManager();
  715.         $article $em->getRepository('GhDatabaseBundle:GhHint')->findOneById($hintId);
  716.         
  717.         // Throw a 404 error if no article found
  718.         if ($article === null) {
  719.             throw $this->createNotFoundException('Aucun article n\'a été trouvé');
  720.         }
  721.         
  722.         $routeParams UtilClass::getRouteParamsFromCard($article->getCardid());
  723.         return $this->redirect($this->generateUrl(
  724.                 'GhFrontBundle_Card_hint',
  725.                 $routeParams
  726.             ), 
  727.             301
  728.         );
  729.     }
  730.     
  731.     /**
  732.      * @Route(
  733.      *      "/{console}/{cardId}-{slug}/telecharger.html",
  734.      *      name="GhFrontBundle_Card_download",
  735.      *      requirements={"console" = "([0-9a-zA-Z]+)", "cardId" = "([0-9]+)", "slug" = "([0-9a-zA-Z_-]+)"}
  736.      * )
  737.      * @Template()
  738.      */
  739.     public function downloadAction($console$cardId$slug)
  740.     {
  741.         return $this->downloadFactorized($cardId);
  742.     }
  743.     
  744.     /**
  745.      * @Route(
  746.      *      "/{console}/{cardId}-{slug}/demos-jouables.html",
  747.      *      name="GhFrontBundle_Card_downloadDemo",
  748.      *      requirements={"console" = "([0-9a-zA-Z]+)", "cardId" = "([0-9]+)", "slug" = "([0-9a-zA-Z_-]+)"}
  749.      * )
  750.      * @Template("@GhFront/card/download.html.twig")
  751.      */
  752.     public function downloadDemoAction($console$cardId$slug)
  753.     {
  754.         return $this->downloadFactorized($cardIdGhDownload::DOWNLOAD_TYPE_DEMO);
  755.     }
  756.     
  757.     /**
  758.      * @Route(
  759.      *      "/{console}/{cardId}-{slug}/patches.html",
  760.      *      name="GhFrontBundle_Card_downloadPatch",
  761.      *      requirements={"console" = "([0-9a-zA-Z]+)", "cardId" = "([0-9]+)", "slug" = "([0-9a-zA-Z_-]+)"}
  762.      * )
  763.      * @Template("@GhFront/card/download.html.twig")
  764.      */
  765.     public function downloadPatchAction($console$cardId$slug)
  766.     {
  767.         return $this->downloadFactorized($cardIdGhDownload::DOWNLOAD_TYPE_PATCH);
  768.     }
  769.     
  770.     /**
  771.      * @Route(
  772.      *      "/{console}/{cardId}-{slug}/videos-telecharger.html",
  773.      *      name="GhFrontBundle_Card_downloadMovie",
  774.      *      requirements={"console" = "([0-9a-zA-Z]+)", "cardId" = "([0-9]+)", "slug" = "([0-9a-zA-Z_-]+)"}
  775.      * )
  776.      * @Template("@GhFront/card/download.html.twig")
  777.      */
  778.     public function downloadMovieAction($console$cardId$slug)
  779.     {
  780.         return $this->downloadFactorized($cardIdGhDownload::DOWNLOAD_TYPE_MOVIE);
  781.     }
  782.     
  783.     /**
  784.      * @Route(
  785.      *      "/{console}/{cardId}-{slug}/jeu-complet.html",
  786.      *      name="GhFrontBundle_Card_downloadFullGame",
  787.      *      requirements={"console" = "([0-9a-zA-Z]+)", "cardId" = "([0-9]+)", "slug" = "([0-9a-zA-Z_-]+)"}
  788.      * )
  789.      * @Template("@GhFront/card/download.html.twig")
  790.      */
  791.     public function downloadFullGameAction($console$cardId$slug)
  792.     {
  793.         return $this->downloadFactorized($cardIdGhDownload::DOWNLOAD_TYPE_FULL_GAME);
  794.     }
  795.     
  796.     /**
  797.      * @param integer $cardId
  798.      * @param integer $type Type of download. See GhDownload::DOWNLOAD_TYPE_* constants.
  799.      *      By default NULL (all types are returned).
  800.      * @return array(mixed) Values to be sent to Twig template. 
  801.      */
  802.     private function downloadFactorized($cardId$type NULL)
  803.     {
  804.         $em $this->getDoctrine()->getManager();
  805.         $card $em->getRepository('GhDatabaseBundle:GhCard')->getCardAndCompanies($cardId);
  806.         
  807.         // Throw a 404 error if no card found
  808.         if ($card === null) {
  809.             throw $this->createNotFoundException('Aucune fiche n\'a été trouvée');
  810.         }
  811.         
  812.         // Get pagination information
  813.         if ($this->getRequest()->query->get('page')) {
  814.             $page $this->getRequest()->query->get('page');
  815.         } else {
  816.             $page 1;
  817.         }
  818.         
  819.         $paginator = new PaginatorHelper($em->getRepository('GhDatabaseBundle:GhDownload')->countDownloadsByCardIdAndType($cardId$type), $page$this->container->getParameter('downloads_per_page'));
  820.         $paginator->setSfLinkedController($this);
  821.         $paginator->setRouter($this->get('router'));
  822.         $paginator->setSfUrlParameters(array_merge(UtilClass::getRouteParamsFromCard($card), array('page' => $page)));
  823.         $paginator->setPageParameterName('page');
  824.         $paginator->setPaginationStep($this->container->getParameter('downloads_pagination_step'));
  825.         
  826.         $associatedDownloads $em->getRepository('GhDatabaseBundle:GhDownload')->getDownloadsByCardIdAndType($cardId$type$paginator->getOffset(), $paginator->getLimit());
  827.         
  828.         // Throw a 404 error if no download found
  829.         if (count($associatedDownloads) == 0) {
  830.             throw $this->createNotFoundException('Aucun téléchargement n\'a été trouvé');
  831.         }
  832.         
  833.         // Extract all categories
  834.         $associatedDownloadsForCategories $em->getRepository('GhDatabaseBundle:GhDownload')->getDownloadsByCardIdAndType($cardId);
  835.         $categoriesList = array();
  836.         foreach ($associatedDownloadsForCategories as $download) {
  837.             if (!in_array($download->getType(), $categoriesList)) {
  838.                 $categoriesList[] = $download->getType();
  839.             }
  840.         }
  841.         sort($categoriesList);
  842.         
  843.         // Get the gallery, in order to illustrate the page
  844.         $gallery $em->getRepository('GhDatabaseBundle:GhGallery')->getGalleryByCardId($cardId0count($associatedDownloads));
  845.         
  846.         // Generate title
  847.         $title $card->getTitle().' - '.$card->getDisplayConsole().' : téléchargements';
  848.         if ($type !== NULL) {
  849.             $title .= ' ('.SectionTypeClass::getInstance()->getLabelById('download'$typefalse).')';
  850.         }
  851.         TitleClass::getInstance()->setTitle($title);
  852.         
  853.         // Generate breadcrumb
  854.         $breadcrumb BreadcrumbClass::getInstance();
  855.         $breadcrumb->addPath(ConsoleClass::getInstance()->getLongFromCode($card->getConsole()), $this->get('router'), 'GhFrontBundle_Page_homepageDefault', array('console' => ConsoleClass::getInstance()->getShortFromCode($card->getConsole())));
  856.         $breadcrumb->addPath($card->getTitle(), $this->get('router'), 'GhFrontBundle_Card_card', array('card' => $card));
  857.         $breadcrumb->addPath('Téléchargements'$this->get('router'), 'GhFrontBundle_Card_download', array('card' => $card));
  858.         if ($type !== NULL) {
  859.             $route GhDownload::translateRoute($type);
  860.             $breadcrumb->addPath(SectionTypeClass::getInstance()->getLabelById('download'$typefalse), $this->get('router'), $route, array('card' => $card));
  861.         }
  862.         if ($page != 1) {
  863.             $breadcrumb->addPath('Page '.$page);
  864.         }
  865.         
  866.         // Generate meta
  867.         $meta MetaClass::getInstance();
  868.         $meta->setMetaCard($card);
  869.         $meta->addMeta('description''Découvrez tous les téléchargements du jeu vidéo '.$card->getTitle().' sur '.$card->getDisplayConsole().' sur GameHope : démos jouables, patches, vidéos, jeux complets.');
  870.         $meta->addMeta('keywords''jeux vidéo, '.$card->getTitle().', '.$card->getDisplayConsole().', téléchargements, downloads');
  871.         
  872.         // Generate canonical URL
  873.         $canonicalParam '';
  874.         if ($page != 1) {
  875.             $canonicalParam '?page='.$page;
  876.         }
  877.         $this->updateCanonicalUrl($card, array(), $canonicalParam);
  878.         
  879.         // Set menu active
  880.         MenuActiveClass::getInstance()->setMenuActive('download');
  881.         
  882.         return array(
  883.             'card' => $card
  884.             'associatedDownloads' => $associatedDownloads,
  885.             'paginator' => $paginator,
  886.             'gallery' => $gallery,
  887.             'categoriesList' => $categoriesList,
  888.             'selectedType' => ($type === NULL ? -$type)
  889.         );
  890.     }
  891.     
  892.     /**
  893.      * @Route(
  894.      *      "/{console}/{cardId}-{slug}/acheter.html",
  895.      *      name="GhFrontBundle_Card_buy",
  896.      *      requirements={"console" = "([0-9a-zA-Z]+)", "cardId" = "([0-9]+)", "slug" = "([0-9a-zA-Z_-]+)"}
  897.      * )
  898.      * @Template()
  899.      */
  900.     public function buyAction($console$cardId$slug)
  901.     {
  902.         $em $this->getDoctrine()->getManager();
  903.         $card $em->getRepository('GhDatabaseBundle:GhCard')->getCardAndCompanies($cardId);
  904.         
  905.         // Throw a 404 error if no card found
  906.         if ($card === null) {
  907.             throw $this->createNotFoundException('Aucune fiche n\'a été trouvée');
  908.         }
  909.         
  910.         // Generate title
  911.         TitleClass::getInstance()->setTitle($card->getTitle().' - '.$card->getDisplayConsole().' : acheter au meilleur prix');
  912.         
  913.         // Generate breadcrumb
  914.         $breadcrumb BreadcrumbClass::getInstance();
  915.         $breadcrumb->addPath(ConsoleClass::getInstance()->getLongFromCode($card->getConsole()), $this->get('router'), 'GhFrontBundle_Page_homepageDefault', array('console' => ConsoleClass::getInstance()->getShortFromCode($card->getConsole())));
  916.         $breadcrumb->addPath($card->getTitle(), $this->get('router'), 'GhFrontBundle_Card_card', array('card' => $card));
  917.         $breadcrumb->addPath('Acheter');
  918.         
  919.         // Generate meta
  920.         $meta MetaClass::getInstance();
  921.         $meta->setMetaCard($card);
  922.         $meta->addMeta('description''Achetez '.$card->getTitle().' sur '.$card->getDisplayConsole().' sur GameHope.');
  923.         $meta->addMeta('keywords''jeux vidéo, '.$card->getTitle().', '.$card->getDisplayConsole());
  924.         
  925.         // Generate canonical URL
  926.         $this->updateCanonicalUrl($card);
  927.         
  928.         // Get the shop links
  929.         $shopLinks = array(
  930.             'amazon' => ShopClass::getAmazonLink($card),
  931.             'priceminister' => ShopClass::getPriceMinisterLink($card),
  932.             'ebay' => ShopClass::getEbayLink($card),
  933.             'boulanger' => ShopClass::getBoulangerLink($card)
  934.         );
  935.         
  936.         return array(
  937.             'card' => $card,
  938.             'shopLinks' => $shopLinks
  939.         );
  940.     }
  941.     
  942.     /**
  943.      * @Route(
  944.      *      "/{console}/{cardId}-{slug}/news-{page}.html",
  945.      *      name="GhFrontBundle_Card_news",
  946.      *      requirements={"console" = "([0-9a-zA-Z]+)", "cardId" = "([0-9]+)", "slug" = "([0-9a-zA-Z_-]+)", "page" = "([0-9]+)"}
  947.      * )
  948.      * @Template()
  949.      */
  950.     public function newsAction($console$cardId$slug$page)
  951.     {      
  952.         $em $this->getDoctrine()->getManager();
  953.         $card $em->getRepository('GhDatabaseBundle:GhCard')->getCardAndCompanies($cardId);
  954.         
  955.         // Throw a 404 error if no card found
  956.         if ($card === null) {
  957.             throw $this->createNotFoundException('Aucune fiche n\'a été trouvée');
  958.         }
  959.         
  960.         // Generate title
  961.         TitleClass::getInstance()->setTitle($card->getTitle().' - '.$card->getDisplayConsole().' : toutes les news du jeu vidéo');
  962.         
  963.         // Generate breadcrumb
  964.         $breadcrumb BreadcrumbClass::getInstance();
  965.         $breadcrumb->addPath(ConsoleClass::getInstance()->getLongFromCode($card->getConsole()), $this->get('router'), 'GhFrontBundle_Page_homepageDefault', array('console' => ConsoleClass::getInstance()->getShortFromCode($card->getConsole())));
  966.         $breadcrumb->addPath($card->getTitle(), $this->get('router'), 'GhFrontBundle_Card_card', array('card' => $card));
  967.         $breadcrumb->addPath('News'$this->get('router'), 'GhFrontBundle_Card_news', array('card' => $card'page' => 1));
  968.         if ($page != 1) {
  969.             $breadcrumb->addPath('Page '.$page);
  970.         }
  971.         
  972.         // Generate meta
  973.         $meta MetaClass::getInstance();
  974.         $meta->setMetaCard($card);
  975.         $meta->addMeta('description''Découvrez toute l\'actualité du jeu vidéo '.$card->getTitle().' sur '.$card->getDisplayConsole().' sur GameHope : news, infos, reportages, rumeurs, plannings.');
  976.         $meta->addMeta('keywords''jeux vidéo, '.$card->getTitle().', '.$card->getDisplayConsole());
  977.         
  978.         // Set menu active
  979.         MenuActiveClass::getInstance()->setMenuActive('daily');
  980.         
  981.         // Compute pagination
  982.         $paginator = new PaginatorHelper($em->getRepository('GhDatabaseBundle:GhNewsCard')->countNewsCardByCardId($cardId), $page$this->container->getParameter('news_per_page'));
  983.         $paginator->setSfLinkedController($this);
  984.         $paginator->setRouter($this->get('router'));
  985.         $paginator->setSfUrlParameters(array_merge(UtilClass::getRouteParamsFromCard($card), array('page' => $page)));
  986.         $paginator->setPageParameterName('page');
  987.         $paginator->setPaginationStep($this->container->getParameter('news_pagination_step'));
  988.         
  989.         // Get the list of news
  990.     $associatedNews $em->getRepository('GhDatabaseBundle:GhNewsCard')->getNewsCardByCardId($cardId$paginator->getOffset(), $paginator->getLimit());
  991.         
  992.         // Generate canonical URL
  993.         $this->updateCanonicalUrl($card, array('page' => $page));
  994.         return array(
  995.             'card' => $card
  996.             'associatedNews' => $associatedNews
  997.             'paginator' => $paginator
  998.         );
  999.     }
  1000.     
  1001.     /**
  1002.      * @Route(
  1003.      *      "/{console}/{cardId}-{slug}/news.html",
  1004.      *      name="GhFrontBundle_Card_newsDefault",
  1005.      *      requirements={"console" = "([0-9a-zA-Z]+)", "cardId" = "([0-9]+)", "slug" = "([0-9a-zA-Z_-]+)"}
  1006.      * )
  1007.      */
  1008.     public function newsDefaultAction($console$cardId$slug)
  1009.     {
  1010.         return $this->redirect($this->generateUrl(
  1011.                 'GhFrontBundle_Card_news',
  1012.                 array('console' => $console'cardId' => $cardId'slug' => $slug'page' => 1)
  1013.             ), 
  1014.             301
  1015.         );
  1016.     }
  1017.     /**
  1018.      * @Route(
  1019.      *      "/{console}/{cardId}-{slug}/{type}-{page}.html",
  1020.      *      name="GhFrontBundle_Card_companyGames",
  1021.      *      requirements={"console" = "([0-9a-zA-Z]+)", "cardId" = "([0-9]+)", "slug" = "([0-9a-zA-Z_-]+)", "type" = "(editeur|developpeur)", "page" = "([0-9]+)"}
  1022.      * )
  1023.      * @Template()
  1024.      */
  1025.     public function companyGamesAction($console$cardId$slug$type$page)
  1026.     {
  1027.         switch ($type) {
  1028.             case 'editeur':
  1029.                 $filterType GhCard::CARD_COMPANY_PUBLISHER;
  1030.                 break;
  1031.             case 'developpeur':
  1032.                 $filterType GhCard::CARD_COMPANY_DEVELOPER;
  1033.                 break;
  1034.             default:
  1035.                 throw $this->createNotFoundException('Le type est invalide');
  1036.         }
  1037.         
  1038.         $em $this->getDoctrine()->getManager();
  1039.         $card $em->getRepository('GhDatabaseBundle:GhCard')->getCardAndCompanies($cardId);
  1040.         
  1041.         // Throw a 404 error if no card found
  1042.         if ($card === null) {
  1043.             throw $this->createNotFoundException('Aucun article n\'a été trouvé');
  1044.         }
  1045.         
  1046.         // Generate title
  1047.         if ($filterType == GhCard::CARD_COMPANY_PUBLISHER) {
  1048.             TitleClass::getInstance()->setTitle('Les jeux édités par '.$card->getTitle());
  1049.         } else {
  1050.             TitleClass::getInstance()->setTitle('Les jeux développés par '.$card->getTitle());
  1051.         }
  1052.         
  1053.         // Generate breadcrumb
  1054.         $breadcrumb BreadcrumbClass::getInstance();
  1055.         $breadcrumb->addPath(ConsoleClass::getInstance()->getLongFromCode($card->getConsole()), $this->get('router'), 'GhFrontBundle_Page_homepageDefault', array('console' => ConsoleClass::getInstance()->getShortFromCode($card->getConsole())));
  1056.         $breadcrumb->addPath($card->getTitle(), $this->get('router'), 'GhFrontBundle_Card_card', array('card' => $card));
  1057.         if ($filterType == GhCard::CARD_COMPANY_PUBLISHER) {
  1058.             $breadcrumb->addPath('Jeux édités'$this->get('router'), 'GhFrontBundle_Card_companyGames', array('card' => $card'type' => $type'page' => 1));
  1059.             $descriptionLabel 'édités';
  1060.         } else {
  1061.             $breadcrumb->addPath('Jeux développés'$this->get('router'), 'GhFrontBundle_Card_companyGames', array('card' => $card'type' => $type'page' => 1));
  1062.             $descriptionLabel 'développés';
  1063.         }
  1064.         if ($page != 1) {
  1065.             $breadcrumb->addPath('Page '.$page);
  1066.         }
  1067.         
  1068.         // Generate meta
  1069.         $meta MetaClass::getInstance();
  1070.         $meta->setMetaCard($card);
  1071.         $meta->addMeta('description''Retrouvez tous les jeux '.$descriptionLabel.' par '.$card->getTitle().' sur GameHope : tests, previews, news, reportages, vidéos, astuces, téléchargements.');
  1072.         $meta->addMeta('keywords''jeux vidéo, '.$card->getTitle().', '.$card->getDisplayConsole());
  1073.         
  1074.         // Generate canonical URL
  1075.         $this->updateCanonicalUrl($card, array('page' => $page'type' => $type));
  1076.         
  1077.         // Pagination
  1078.         $paginator = new PaginatorHelper(
  1079.             $em->getRepository('GhDatabaseBundle:GhCard')->countPublishedOrDevelopedCards($card$filterType), 
  1080.             $page
  1081.             $this->container->getParameter('cards_company_per_page')
  1082.         );
  1083.         $paginator->setSfLinkedController($this);
  1084.         $paginator->setRouter($this->get('router'));
  1085.         $paginator->setSfUrlParameters(array_merge(UtilClass::getRouteParamsFromCard($card), array('type' => $type)));
  1086.         $paginator->setPageParameterName('page');
  1087.         $paginator->setPaginationStep($this->container->getParameter('cards_company_pagination_step'));
  1088.         
  1089.         // Get cards list
  1090.     $associatedCards $em->getRepository('GhDatabaseBundle:GhCard')->getPublishedOrDevelopedCards($card$filterType$paginator->getOffset(), $paginator->getLimit());
  1091.         
  1092.         // Throw a 404 error if no card found
  1093.         if (count($associatedCards) == 0) {
  1094.             throw $this->createNotFoundException('Aucune fiche n\'a été trouvée');
  1095.         }
  1096.         
  1097.         return array(
  1098.             'card' => $card
  1099.             'page' => $page
  1100.             'type' => $filterType,
  1101.             'associatedCards' => $associatedCards
  1102.             'paginator' => $paginator
  1103.         );
  1104.     }
  1105.     
  1106.     /**
  1107.      * @Route(
  1108.      *      "/{console}/{cardId}-{slug}/{type}.html",
  1109.      *      name="GhFrontBundle_Card_companyGamesDefault",
  1110.      *      requirements={"console" = "([0-9a-zA-Z]+)", "cardId" = "([0-9]+)", "slug" = "([0-9a-zA-Z_-]+)", "type" = "(editeur|developpeur)"}
  1111.      * )
  1112.      */
  1113.     public function companyGamesDefaultAction($console$cardId$slug$type)
  1114.     {
  1115.         return $this->redirect($this->generateUrl(
  1116.                 'GhFrontBundle_Card_companyGames',
  1117.                 array('console' => $console'cardId' => $cardId'slug' => $slug'type' => $type'page' => 1)
  1118.             ), 
  1119.             301
  1120.         );
  1121.     }
  1122. }