src/Controller/MagazineController.php line 118

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Service\CanonicalRedirectHelper;
  4. use App\Service\FormHelper;
  5. use App\Service\MagazinHelper;
  6. use Carbon\Carbon;
  7. use Elements\Bundle\HashCashBundle\Service\HashCashService;
  8. use Knp\Component\Pager\PaginatorInterface;
  9. use Pimcore\DataObject\Consent\Service;
  10. use Pimcore\File;
  11. use Pimcore\Mail;
  12. use Pimcore\Model\DataObject;
  13. use Pimcore\Model\DataObject\BlogArticle;
  14. use Pimcore\Model\DataObject\BlogAuthor;
  15. use Pimcore\Model\DataObject\BlogCategory;
  16. use Pimcore\Model\DataObject\BlogSubscriber;
  17. use Pimcore\Model\DataObject\BlogTheme;
  18. use Pimcore\Translation\Translator;
  19. use Symfony\Component\HttpFoundation\Request;
  20. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  21. class MagazineController extends AbstractController
  22. {
  23.     public function portalAction(Request $requestService $consentServiceTranslator $translatorHashCashService $hashCashService) {
  24.         $portal $this->document->getProperty('blogPortal');
  25.         //2 top artikel
  26.         $topArticleListing = new BlogArticle\Listing();
  27.         $topArticleListing->addConditionParam('topArticle = 1 AND portals LIKE :portal', ['portal' => '%,' $portal->getId() . ',%']); //add later, currently there are no top articles
  28.         $topArticleListing->setLimit(2);
  29.         $topArticleListing->addConditionParam('teaserImage IS NOT NULL AND (IFNULL(submitted, 0) = 0 OR IFNULL(verified, 0) = 1)');
  30.         $topArticleListing->setOrderKey('articleDate');
  31.         $topArticleListing->setOrder('DESC');
  32.         //Teaser Grid Articles
  33.         $gridArticleListing = new BlogArticle\Listing();
  34.         //ignore the two top articles
  35.         if ($topArticleListing->count()) {
  36.             $gridArticleListing->addConditionParam('oo_id NOT IN (' implode(',', (clone $topArticleListing)->loadIdList()) . ')');
  37.         }
  38.         $gridArticleListing->addConditionParam('teaserImage IS NOT NULL AND portals LIKE :portal AND (IFNULL(submitted, 0) = 0 OR IFNULL(verified, 0) = 1)', ['portal' => '%,' $portal->getId() . ',%']);
  39.         $gridArticleListing->setOrderKey('articleDate');
  40.         $gridArticleListing->setOrder('DESC');
  41.         $gridArticleListing->setLimit(12);
  42.         $subscribeResult $this->subscriberAction($request$consentService$translator$hashCashService);
  43.         return $this->renderTemplate('Magazine/portal.html.twig', [
  44.             'gridArticles' => $gridArticleListing,
  45.             'topArticles' => $topArticleListing,
  46.             'subscribeSuccess' => $subscribeResult['subscribeSuccess'],
  47.             'errors' => $subscribeResult['errors']
  48.         ]);
  49.     }
  50.     public function topicAction(Request $requestPaginatorInterface $paginatorService $consentServiceTranslator $translatorHashCashService $hashCashService)
  51.     {
  52.         $blogTheme $this->getDocumentEditable('relation''blogTheme')->getElement();
  53.         if ($blogTheme instanceof BlogTheme) {
  54.             $orCondition = [];
  55.             foreach ($blogTheme->getBlogCategories() as $category){
  56.                 $orCondition[] = 'categories LIKE "%,' $category->getId() . ',%"';
  57.             }
  58.             $orCondition[] = 'blogThemes LIKE "%,' $blogTheme->getId() . ',%"';
  59.             if (!empty($orCondition)) {
  60.                 /*//2 top artikel
  61.                 $topArticleListing = new BlogArticle\Listing();
  62.                 $topArticleListing->addConditionParam('topArticle = 1 AND portals LIKE :portal', ['portal' => '%,' . $this->document->getProperty('blogPortal')->getId() . ',%']); //add later, currently there are no top articles
  63.                 $topArticleListing->addConditionParam(implode(' OR ' , $orCondition)); //add later, currently there are no top articles
  64.                 if ($articleRelation = $this->getDocumentEditable('relation', 'mainArticle')->getElement()){
  65.                     $topArticleListing->addConditionParam('oo_id != ' . $articleRelation->getId());
  66.                 }
  67.                 $topArticleListing->setLimit(2);
  68.                 $topArticleListing->addConditionParam('teaserImage IS NOT NULL');
  69.                 $topArticleListing->setOrderKey('articleDate');
  70.                 $topArticleListing->setOrder('DESC');*/
  71.                 $articleListing = new BlogArticle\Listing();
  72.                 $articleListing->addConditionParam(implode(' OR ' $orCondition)); //add later, currently there are no top articles
  73.                 if ($articleRelation $this->getDocumentEditable('relation''mainArticle')->getElement()){
  74.                     $articleListing->addConditionParam('oo_id != ' $articleRelation->getId());
  75.                 }
  76.                 $articleListing->addConditionParam('teaserImage IS NOT NULL AND portals LIKE :portal AND (IFNULL(submitted, 0) = 0 OR IFNULL(verified, 0) = 1)', ['portal' => '%,' $this->document->getProperty('blogPortal')->getId() . ',%']);
  77.                 /*//ignore the two top articles
  78.                 if ($topArticleListing->count()) {
  79.                     $articleListing->addConditionParam('oo_id NOT IN (' . implode(',', (clone $topArticleListing)->loadIdList()) . ')');
  80.                 }*/
  81.                 $articleListing->setOrderKey('articleDate');
  82.                 $articleListing->setOrder('DESC');
  83.                 $pagination $paginator->paginate($articleListing$request->get('page'1), $blogTheme->getArticlesPerPage() ?: 6);
  84.                 $pagination->setPageRange(3);
  85.             }
  86.         }
  87.         if ($request->isXmlHttpRequest()) {
  88.             return $this->json([
  89.                 'success' => true,
  90.                 'html' => $this->renderView('Magazine/Includes/articleTeaserGrid.html.twig', ['paginator' => $pagination'document' => $this->document])
  91.             ]);
  92.         }
  93.         $subscribeResult $this->subscriberAction($request$consentService$translator$hashCashService);
  94.         return $this->renderTemplate('Magazine/topic.html.twig', [
  95.             'blogTheme' => $blogTheme,
  96. //            'topArticles' => $topArticleListing,
  97.             'paginator' => $pagination,
  98.             'subscribeSuccess' => $subscribeResult['subscribeSuccess'],
  99.             'errors' => $subscribeResult['errors']
  100.         ]);
  101.     }
  102.     public function archiveAction(Request $requestTranslator $translatorPaginatorInterface $paginator){
  103.         $articleListing = new BlogArticle\Listing();
  104.         $articleListing->setOrderKey('articleDate');
  105.         $articleListing->setOrder('DESC');
  106.         $currentYear $request->get('timeline') ?: Carbon::today()->format('Y');
  107.         $firstDayOfYear Carbon::createFromFormat("Y-m-d H:i:s"$currentYear."-01-01 00:00:00")->timestamp;
  108.         $lastDayOfYear Carbon::createFromFormat("Y-m-d H:i:s"$currentYear."-12-31 23:59:59")->timestamp;
  109.         $articleListing->addConditionParam('(articleDate < "' $lastDayOfYear '") AND (articleDate > "' $firstDayOfYear '")');
  110.         $articleListing->addConditionParam('teaserImage IS NOT NULL AND portals LIKE :portal AND (IFNULL(submitted, 0) = 0 OR IFNULL(verified, 0) = 1)', ['portal' => '%,' $this->document->getProperty('blogPortal')->getId() . ',%']);
  111.         $paginator $paginator->paginate($articleListing$request->get('page'1), $this->getDocumentEditable('numeric''per_page')->getData() ? $this->getDocumentEditable('numeric''per_page')->getData() : 9);
  112.         $paginator->setPageRange(3);
  113.         if ($request->isXmlHttpRequest()) {
  114.             return $this->json([
  115.                 'success' => true,
  116.                 'html' => $this->renderView('Magazine/Includes/archiveContainer.html.twig', [
  117.                     'paginator' => $paginator,
  118.                     'currentYear' => $currentYear,
  119.                     'document' => $this->document
  120.                 ])
  121.             ]);
  122.         }
  123.         $archiveYears = new BlogArticle\Listing();
  124.         $archiveYears->addConditionParam('teaserImage IS NOT NULL AND portals LIKE :portal AND articleDate != "" AND articleDate IS NOT NULL AND (IFNULL(submitted, 0) = 0 OR IFNULL(verified, 0) = 1)', ['portal' => '%,' $this->document->getProperty('blogPortal')->getId() . ',%']);
  125.         $archiveYears->setOrderKey('articleDate');
  126.         $archiveYears->setOrder('DESC');
  127.         $archiveYears->setGroupBy('YEAR(FROM_UNIXTIME(articleDate))'false);
  128.         return $this->renderTemplate('Magazine/archive.html.twig', [
  129.             'archiveYears' => $archiveYears,
  130.             'currentYear' => $currentYear,
  131.             'paginator' => $paginator
  132.         ]);
  133.     }
  134.     public function searchAction(Request $requestPaginatorInterface $paginator)
  135.     {
  136.         $articleListing = new BlogArticle\Listing();
  137.         $articleListing->addConditionParam('teaserImage IS NOT NULL AND portals LIKE :portal AND (IFNULL(submitted, 0) = 0 OR IFNULL(verified, 0) = 1)', ['portal' => '%,' $this->document->getProperty('blogPortal')->getId() . ',%']);
  138.         if ($request->get('category')){
  139.             $articleListing->addConditionParam("categories LIKE :category", ["category" => "%," .$request->get('category') . ",%"]);
  140.         }
  141.         if ($searchParam $request->get('nav-search')){
  142.             $articleListing->addConditionParam("title LIKE :query OR keywords LIKE :queryComma", ["query" => "%" $searchParam "%""queryComma" => "%" $searchParam ",%"]);
  143.         }
  144.         $articleListing->setOrderKey('articleDate');
  145.         $articleListing->setOrder('DESC');
  146.         $paginator $paginator->paginate($articleListing$request->get('page'1), $this->getDocumentEditable('numeric''per_page')->getData() ? $this->getDocumentEditable('numeric''per_page')->getData() : 9);
  147.         $paginator->setPageRange(3);
  148.         if ($request->isXmlHttpRequest()) {
  149.             return $this->json([
  150.                 'success' => true,
  151.                 'html' => $this->renderView('Magazine/Includes/articleTeaserGrid.html.twig', ['paginator' => $paginator'document' => $this->document])
  152.             ]);
  153.         }
  154.         return $this->renderTemplate('Magazine/search.html.twig', [
  155.             'magazine' => true,
  156.             'paginator' => $paginator,
  157.             'category' => BlogCategory::getById($request->get('category'))
  158.         ]);
  159.     }
  160.     public function detailAction(Request $requestCanonicalRedirectHelper $redirectHelperService $consentServiceTranslator $translatorHashCashService $hashCashService)
  161.     {
  162.         $article BlogArticle::getById($request->get('id',0));
  163.         if (!$article || ($article->getSubmitted() && !$article->getVerified())){
  164.             throw new NotFoundHttpException("the requested object doesn't exist anymore");
  165.         }
  166.         if (CanonicalRedirectHelper::ENABLE_CANONICAL_REDIRECT && $redirect $redirectHelper->canonicalRedirect($article)) {
  167.             return $redirect;
  168.         }
  169.         $subscribeResult $this->subscriberAction($request$consentService$translator$hashCashService);
  170.         return $this->renderTemplate('Magazine/detail.html.twig', [
  171.             'article' => $article,
  172.             'subscribeSuccess' => $subscribeResult['subscribeSuccess'],
  173.             'errors' => $subscribeResult['errors']
  174.         ]);
  175.     }
  176.     public function authorOverviewAction(Request $requestPaginatorInterface $paginator){
  177.         $portalId $this->document->getProperty('blogPortal')->getId();
  178.         $authorListing = new BlogAuthor\Listing();
  179.         $authorListing->addConditionParam('image != "" AND image IS NOT NULL AND name IS NOT NULL AND name != ""');
  180.         $authorListing->addConditionParam('portals LIKE :portal', ['portal' => '%,' $portalId ',%']);
  181.         $authorListing->setOrderKey('name');
  182.         $authorListing->setOrder('ASC');
  183.         $paginator $paginator->paginate($authorListing$request->get('page'1), $this->getDocumentEditable('numeric''per_page')->getData() ? $this->getDocumentEditable('numeric''per_page')->getData() : 6);
  184.         $paginator->setPageRange(3);
  185.         $db \Pimcore\Db::get();
  186.         $sql = <<<EOT
  187. SELECT oo_id,
  188. (SELECT COUNT(*) FROM object_BlogArticle WHERE author__id = object_BlogAuthor.oo_id AND object_BlogArticle.teaserImage IS NOT NULL AND o_published = 1) as counter
  189. FROM object_BlogAuthor WHERE portals LIKE "%,$portalId,%"
  190. EOT;
  191.         $results $db->fetchAll($sql);
  192.         $articleCount = [];
  193.         foreach ($results as $result){
  194.             $articleCount[$result['oo_id']] = $result;
  195.         }
  196.         if ($request->isXmlHttpRequest()) {
  197.             return $this->json([
  198.                 'success' => true,
  199.                 'html' => $this->renderView('Magazine/Includes/authorTeaserGrid.html.twig', [
  200.                     'paginator' => $paginator,
  201.                     'articleCount' => $articleCount,
  202.                     'document' => $this->document
  203.                 ])
  204.             ]);
  205.         }
  206.         return $this->renderTemplate('Magazine/authorOverview.html.twig', [
  207.             'paginator' => $paginator,
  208.             'articleCount' => $articleCount,
  209.         ]);
  210.     }
  211.     public function authorDetailAction(Request $requestPaginatorInterface $paginatorCanonicalRedirectHelper $redirectHelper)
  212.     {
  213.         $author BlogAuthor::getById($request->get('id',0));
  214.         if (!$author){
  215.             throw new NotFoundHttpException("the requested object doesn't exist anymore");
  216.         }
  217.         if (CanonicalRedirectHelper::ENABLE_CANONICAL_REDIRECT && $redirect $redirectHelper->canonicalRedirect($author)) {
  218.             return $redirect;
  219.         }
  220.         $articleListing = new BlogArticle\Listing();
  221.         $articleListing->addConditionParam("author__id = " $author->getId());
  222.         $articleListing->addConditionParam('teaserImage IS NOT NULL AND (IFNULL(submitted, 0) = 0 OR IFNULL(verified, 0) = 1)');
  223.         $articleListing->setOrderKey('articleDate');
  224.         $articleListing->setOrder('DESC');
  225.         $paginator $paginator->paginate($articleListing$request->get('page'1), 6);
  226.         $paginator->setPageRange(3);
  227.         if ($request->isXmlHttpRequest()) {
  228.             return $this->json([
  229.                 'success' => true,
  230.                 'html' => $this->renderView('Magazine/Includes/articleTeaserGrid.html.twig', [
  231.                     'paginator' => $paginator,
  232.                     'notRelative' => true,
  233.                     'document' => $this->document
  234.                 ])
  235.             ]);
  236.         }
  237.         return $this->renderTemplate('Magazine/authorDetail.html.twig', [
  238.             'author' => $author,
  239.             'paginator' => $paginator
  240.         ]);
  241.     }
  242.     public function subscriberAction(Request $requestService $consentServiceTranslator $translatorHashCashService $hashCashService){
  243.         $portal $this->document->getProperty('blogPortal');
  244.         $subscribeSuccess false;
  245.         if ($request->isMethod('POST') && $request->get('subscribeMagazine'false)) {
  246.             if ($hashCashService->validateProcessFrom()) {
  247.                 $email $request->get('email');
  248.                 $errors = [];
  249.                 if ($email == '') {
  250.                     $errors[] = 'email must not be empty';
  251.                 } else {
  252.                     if (!FormHelper::isValidEmailAddress($email)) {
  253.                         $errors[] = 'email must be valid';
  254.                     } else {
  255.                         $subscriber BlogSubscriber::getByEmail($email);
  256.                         $subscriber->addConditionParam('portal__id = :portal', ['portal' => $portal->getId()]);
  257.                         $subscriber->setLimit(1);
  258.                         $subscriber $subscriber->current();
  259.                         if ($subscriber instanceof BlogSubscriber && $subscriber->getConfirmed()) {
  260.                             $errors[] = 'subscriber already exists';
  261.                         }
  262.                     }
  263.                 }
  264.             } else {
  265.                 $errors[] = 'hashcash not valid';
  266.             }
  267.             if (empty($errors)) {
  268.                 if (!$subscriber instanceof BlogSubscriber) {
  269.                     $subscriber = new BlogSubscriber();
  270.                     $subscriber->setKey(File::getValidFilename($email));
  271.                     $subscriber->setPublished(true);
  272.                     $subscriber->setParent(DataObject\Service::createFolderByPath('/Blog/Subscribers/' $portal->getKey()));
  273.                     $subscriber->setEmail($email);
  274.                     $subscriber->setSubscriberLanguage($request->getLocale());
  275.                 }
  276.                 $token md5($portal->getKey() . '_' $email time());
  277.                 $validUntil Carbon::now()->addDays(30);
  278.                 $subscriber->setToken($token);
  279.                 $subscriber->setValidUntil($validUntil);
  280.                 $subscriber->setSubscriberLanguage($request->getLocale());
  281.                 $metaData = [
  282.                     'ip' => $request->getClientIp()
  283.                 ];
  284.                 $subscriber->setPortal($portal);
  285.                 $subscriber->save();
  286.                 $consentService->giveConsent($subscriber'consent'$translator->trans('magazin.subscribe.' $portal->getKey() . '.gdpr'), $metaData);
  287.                 $subscriber->save();
  288.                 if ($mailDoc $this->document->getProperty('blogPortal')->getSubscribeMail()) {
  289.                     $mail = new Mail();
  290.                     $mail->setDocument($mailDoc);
  291.                     $mail->setParams([
  292.                         'email' => $email,
  293.                         'url' => $this->document->getProperty('blogPortal')->getSubscribeConfirmDocument() . '?token=' $token,
  294.                         'token' => $token
  295.                     ]);
  296.                     $mail->addTo($email);
  297.                     $mail->send();
  298.                 }
  299.                 $subscribeSuccess true;
  300.             }
  301.         }
  302.         return [
  303.             'subscribeSuccess' => $subscribeSuccess,
  304.             'errors' => $errors ?? []
  305.         ];
  306.     }
  307.     public function confirmSubscriptionAction(Request $request) {
  308.         $success false;
  309.         $errors = [];
  310.         if (!$this->editmode) {
  311.             $subscriber BlogSubscriber::getByToken($request->get('token'), 1);
  312.             if ($subscriber instanceof BlogSubscriber) {
  313.                 if ($subscriber->getValidUntil() >= Carbon::now()) {
  314.                     $subscriber->setConfirmed(true);
  315.                     $subscriber->setActive(true);
  316.                     $subscriber->setToken('');
  317.                     try {
  318.                         $subscriber->save();
  319.                         $success true;
  320.                     } catch (\Exception $e) {
  321.                         if (\Pimcore::inDebugMode()) {
  322.                             p_r($e);
  323.                         }
  324.                         $errors[] = 'general error';
  325.                     }
  326.                 } else {
  327.                     $errors[] = 'token expired';
  328.                 }
  329.             } else {
  330.                 $errors[] = 'token invalid';
  331.             }
  332.         }
  333.         return $this->renderTemplate('Magazine/confirmSubscription.html.twig', [
  334.             'success' => $success,
  335.             'errors' => $errors,
  336.         ]);
  337.     }
  338.     /**
  339.      * @param Request $request
  340.      * @param string $id
  341.      * @return \Symfony\Component\HttpFoundation\Response
  342.      * @throws \Exception
  343.      */
  344.     public function unsubscribeSubscriptionAction(Request $request) {
  345.         $subscriber BlogSubscriber::getById($request->get('id'));
  346.         $unsubscribed false;
  347.         if ($subscriber instanceof BlogSubscriber && $request->isMethod('POST') && $request->get('pot-number') == '') {
  348.             $subscriber->setActive(false);
  349.             $subscriber->save();
  350.             $unsubscribed true;
  351.         }
  352.         return $this->renderTemplate('Magazine/unsubscribeSubscription.html.twig', [
  353.             'unsubscribed' => $unsubscribed
  354.         ]);
  355.     }
  356. }