src/Controller/MagazineController.php line 24

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