vendor/pimcore/pimcore/lib/Targeting/Document/DocumentTargetingConfigurator.php line 78

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4.  * Pimcore
  5.  *
  6.  * This source file is available under two different licenses:
  7.  * - GNU General Public License version 3 (GPLv3)
  8.  * - Pimcore Commercial License (PCL)
  9.  * Full copyright and license information is available in
  10.  * LICENSE.md which is distributed with this source code.
  11.  *
  12.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  13.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  14.  */
  15. namespace Pimcore\Targeting\Document;
  16. use Pimcore\Bundle\AdminBundle\Security\User\UserLoader;
  17. use Pimcore\Cache\Core\CoreCacheHandler;
  18. use Pimcore\Http\RequestHelper;
  19. use Pimcore\Model\Document;
  20. use Pimcore\Model\Document\Targeting\TargetingDocumentInterface;
  21. use Pimcore\Model\Tool\Targeting\TargetGroup;
  22. use Pimcore\Targeting\VisitorInfoStorageInterface;
  23. class DocumentTargetingConfigurator
  24. {
  25.     /**
  26.      * @var VisitorInfoStorageInterface
  27.      */
  28.     private $visitorInfoStorage;
  29.     /**
  30.      * @var RequestHelper
  31.      */
  32.     private $requestHelper;
  33.     /**
  34.      * @var UserLoader
  35.      */
  36.     private $userLoader;
  37.     /**
  38.      * @var CoreCacheHandler
  39.      */
  40.     private $cache;
  41.     /**
  42.      * @var array
  43.      */
  44.     private $targetGroupMapping = [];
  45.     /**
  46.      * @var TargetGroup|null
  47.      */
  48.     private $overrideTargetGroup;
  49.     public function __construct(
  50.         VisitorInfoStorageInterface $visitorInfoStorage,
  51.         RequestHelper $requestHelper,
  52.         UserLoader $userLoader,
  53.         CoreCacheHandler $cache
  54.     ) {
  55.         $this->visitorInfoStorage $visitorInfoStorage;
  56.         $this->requestHelper $requestHelper;
  57.         $this->userLoader $userLoader;
  58.         $this->cache $cache;
  59.     }
  60.     /**
  61.      * Configure target group to use on the document by reading the most relevant
  62.      * target group from the visitor info.
  63.      *
  64.      * @param Document $document
  65.      */
  66.     public function configureTargetGroup(Document $document)
  67.     {
  68.         if (!$document instanceof TargetingDocumentInterface) {
  69.             return;
  70.         }
  71.         // already configured
  72.         if (isset($this->targetGroupMapping[$document->getId()])) {
  73.             return;
  74.         }
  75.         if ($this->isConfiguredByAdminParam($document)) {
  76.             return;
  77.         }
  78.         if ($this->isConfiguredByOverride($document)) {
  79.             return;
  80.         }
  81.         $matchingTargetGroups $this->getMatchingTargetGroups($document);
  82.         if (count($matchingTargetGroups) > 0) {
  83.             $targetGroup $matchingTargetGroups[0];
  84.             $this->targetGroupMapping[$document->getId()] = $targetGroup;
  85.             $document->setUseTargetGroup($targetGroup->getId());
  86.         }
  87.     }
  88.     /**
  89.      * Handle _ptg admin param here only if there's a valid user session
  90.      *
  91.      * @param TargetingDocumentInterface $document
  92.      *
  93.      * @return bool
  94.      */
  95.     private function isConfiguredByAdminParam(TargetingDocumentInterface $document): bool
  96.     {
  97.         if (!$this->requestHelper->hasMainRequest()) {
  98.             return false;
  99.         }
  100.         $request $this->requestHelper->getMainRequest();
  101.         if (!$this->requestHelper->isFrontendRequestByAdmin($request)) {
  102.             return false;
  103.         }
  104.         // IMPORTANT: check there is an authenticated admin user before allowing
  105.         // to set target groups via parameter
  106.         $user $this->userLoader->getUser();
  107.         if (!$user) {
  108.             return false;
  109.         }
  110.         // ptg = pimcore target group = will be used from the admin UI to show target specific data
  111.         // in editmode
  112.         if ($ptg $request->get('_ptg')) {
  113.             $targetGroup TargetGroup::getById((int)$ptg);
  114.             if ($targetGroup) {
  115.                 $this->targetGroupMapping[$document->getId()] = $targetGroup;
  116.                 $document->setUseTargetGroup($targetGroup->getId());
  117.                 return true;
  118.             }
  119.         }
  120.         return false;
  121.     }
  122.     private function isConfiguredByOverride(TargetingDocumentInterface $document): bool
  123.     {
  124.         if (null !== $this->overrideTargetGroup) {
  125.             $this->targetGroupMapping[$document->getId()] = $this->overrideTargetGroup;
  126.             $document->setUseTargetGroup($this->overrideTargetGroup->getId());
  127.             return true;
  128.         }
  129.         return false;
  130.     }
  131.     /**
  132.      * @param Document $document
  133.      *
  134.      * @return TargetGroup|null
  135.      */
  136.     public function getConfiguredTargetGroup(Document $document)
  137.     {
  138.         if (isset($this->targetGroupMapping[$document->getId()])) {
  139.             return $this->targetGroupMapping[$document->getId()];
  140.         }
  141.         return null;
  142.     }
  143.     public function getResolvedTargetGroupMapping(): array
  144.     {
  145.         return $this->targetGroupMapping;
  146.     }
  147.     /**
  148.      * Resolve all target groups which were matched and which are valid for
  149.      * the document
  150.      *
  151.      * @param Document $document
  152.      *
  153.      * @return TargetGroup[]
  154.      */
  155.     public function getMatchingTargetGroups(Document $document): array
  156.     {
  157.         if (!$this->visitorInfoStorage->hasVisitorInfo()) {
  158.             return [];
  159.         }
  160.         $configuredTargetGroups $this->getTargetGroupsForDocument($document);
  161.         if (empty($configuredTargetGroups)) {
  162.             return [];
  163.         }
  164.         $visitorInfo $this->visitorInfoStorage->getVisitorInfo();
  165.         $result = [];
  166.         foreach ($visitorInfo->getAssignedTargetGroups() as $targetGroup) {
  167.             if (in_array($targetGroup->getId(), $configuredTargetGroups)) {
  168.                 $result[$targetGroup->getId()] = $targetGroup;
  169.             }
  170.         }
  171.         return array_values($result);
  172.     }
  173.     /**
  174.      * Resolves valid target groups for a document. A target group is seen as valid
  175.      * if it has at least one element configured for that target group.
  176.      *
  177.      * @param Document $document
  178.      *
  179.      * @return array
  180.      */
  181.     public function getTargetGroupsForDocument(Document $document): array
  182.     {
  183.         if (!$document instanceof TargetingDocumentInterface) {
  184.             return [];
  185.         }
  186.         /** @var Document\TargetingDocument $document */
  187.         $cacheKey sprintf('document_target_groups_%d'$document->getId());
  188.         if ($targetGroups $this->cache->load($cacheKey)) {
  189.             return $targetGroups;
  190.         }
  191.         $targetGroups = [];
  192.         foreach ($document->getEditables() as $key => $tag) {
  193.             $pattern '/^' preg_quote(TargetingDocumentInterface::TARGET_GROUP_EDITABLE_PREFIX'/') . '([0-9]+)' preg_quote(TargetingDocumentInterface::TARGET_GROUP_EDITABLE_SUFFIX'/') . '/';
  194.             if (preg_match($pattern, (string) $key$matches)) {
  195.                 $targetGroups[] = (int)$matches[1];
  196.             }
  197.         }
  198.         $targetGroups array_unique($targetGroups);
  199.         $targetGroups array_filter($targetGroups, function ($id) {
  200.             return TargetGroup::isIdActive($id);
  201.         });
  202.         $this->cache->save($cacheKey$targetGroups, [sprintf('document_%d'$document->getId()), 'target_groups']);
  203.         return $targetGroups;
  204.     }
  205.     public function setOverrideTargetGroup(TargetGroup $overrideTargetGroup null)
  206.     {
  207.         $this->overrideTargetGroup $overrideTargetGroup;
  208.     }
  209.     /**
  210.      * @return null|TargetGroup
  211.      */
  212.     public function getOverrideTargetGroup()
  213.     {
  214.         return $this->overrideTargetGroup;
  215.     }
  216. }