custom/plugins/EconsorAmity/src/Services/AmityPosts/AmityPostService.php line 113

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Econsor\Amity\Services\AmityPosts;
  4. use Econsor\Amity\Models\AmityPostLikes\AmityPostLikesEntity;
  5. use Econsor\Amity\Services\Helpers\AmityRepositoryHelper;
  6. use Econsor\Amity\Services\Stream\StreamProcessor;
  7. use Econsor\Amity\Services\Stream\StreamSorter;
  8. use Econsor\Amity\Services\Stream\StreamUtilities;
  9. use Exception;
  10. use Shopware\Core\Content\Product\ProductEntity;
  11. use Shopware\Core\Framework\Context;
  12. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  14. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
  16. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  17. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter;
  18. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
  19. use Econsor\Amity\Services\AmityPosts\LocalPostService;
  20. use Shopware\Core\Content\Product\Aggregate\ProductMedia\ProductMediaCollection;
  21. /**
  22.  * Class AmityPostService
  23.  * @package Econsor\Amity\Services\AmityPosts
  24.  */
  25. class AmityPostService
  26. {
  27.     const STREAM_LIMIT 100;
  28.     const STREAM_OFFSET 10;
  29.     public function __construct(
  30.         protected StreamProcessor $streamProcessor,
  31.         protected StreamSorter $streamSorter,
  32.         protected StreamUtilities $utilities,
  33.         protected AmityRepositoryHelper $repositoryHelper,
  34.         protected LocalPostService $localPostService
  35.     ) {}
  36.     /**
  37.      * @throws Exception
  38.      */
  39.     public function fetchCustomerStats(string $customerIdSalesChannelContext $context): array
  40.     {
  41.         return [
  42.             'totalLikes' => $this->repositoryHelper->queryLikes($this->streamProcessor->getCriteriaLikeCount($customerId), $context->getContext())->count(),
  43.             'totalFollowers' => $this->repositoryHelper->queryFollowed($this->streamProcessor->getFollowing($customerId), $context->getContext())->count(),
  44.             'totalFollowings' => $this->repositoryHelper->queryFollowed($this->streamProcessor->getFollowed($customerId), $context->getContext())->count(),
  45.             'isFollowed' => $this->repositoryHelper->queryFollowed($this->streamProcessor->getFollowing($customerId)->addFilter(new EqualsFilter('customerId'$context->getCustomerId())), $context->getContext())->count() > 0,
  46.             'postCount' => $this->repositoryHelper->queryTotalPost($this->streamProcessor->getCriteriaPostCount($customerId), $context->getContext())->count(),
  47.         ];
  48.     }
  49.     /**
  50.      * @throws Exception
  51.      */
  52.     public function fetchStream(
  53.         ?string $customerId,
  54.         SalesChannelContext $context,
  55.         string $mode 'tags'// tags|liked|uploaded
  56.         ?string $productId null,
  57.         ?string $postId null,
  58.         $page 1,
  59.         $limit 100
  60.     ): array {
  61.         $customerTags = !empty($customerId) ? $this->utilities->getCustomerTags($customerId$context->getContext())?->get('tags')?->getElements() : [];
  62.         if (empty($customerTags)) {
  63.             $customerTags $this->utilities->getAllTags($context->getContext())->getElements();
  64.         }
  65.         $result = match ($mode) {
  66.             'tags' => $this->buildNormalStream($customerTags$customerId$context$productId$postId$page$limit),
  67.             'liked' => !empty($customerId) ? $this->buildLikedStream($customerTags$customerId$context) : [],
  68.             'uploaded' => !empty($customerId) ? $this->buildUploadedStream($customerTags$customerId$context) : [],
  69.             'saved' => !empty($customerId) ? $this->buildSavedStream($customerTags$customerId$context) : [],
  70.             'details' => !empty($productId) ? $this->buildDetailStream($productId$customerId$context) : [],
  71.             default => throw new Exception('Stream Mode not recognized - try "tags", "details", "liked" or "uploaded"'),
  72.         };
  73.         $likedPostIds = [];
  74.         $savedPostIds = [];
  75.         $followedIds = [];
  76.         if (!empty($customerId)) {
  77.             foreach ($this->repositoryHelper->queryLikes($this->streamProcessor->getCriteriaLiked($customerId499), $context->getContext())->getIterator() as $like) {
  78.                 /** @var AmityPostLikesEntity $like */
  79.                 $likedPostIds[] = $like->getPostId();
  80.             }
  81.             foreach ($this->repositoryHelper->querySaved($this->streamProcessor->getSaved($customerId499), $context->getContext())->getIterator() as $saved) {
  82.                 $savedPostIds[] = $saved->getPostId();
  83.             }
  84.             foreach ($this->repositoryHelper->queryFollowed($this->streamProcessor->getFollowed($customerId), $context->getContext())->getIterator() as $followed) {
  85.                 $followedIds[] = $followed->followerId;
  86.             }
  87.         }
  88.         foreach ($result as &$post) {
  89.             /** @var AmityPostLikesEntity $post */
  90.             $post->addArrayExtension('stats', [
  91.                 'liked' => in_array($post->getId(), $likedPostIds),
  92.                 'saved' => in_array($post->getId(), $savedPostIds),
  93.                 'followed' => in_array($post->postUser$followedIds),
  94.             ]);
  95.             $post $this->convertVideoKey($post);
  96.         }
  97.         return $result;
  98.     }
  99.     public function buildNormalStream($customerTags, ?string $customerIdSalesChannelContext $context, ?string $productId null, ?string $postId null$page 1$limit): array
  100.     {
  101.         $viewedVideos = !empty($customerId) ? $this->utilities->getViewedVideos($customerId$context->getContext()) : [];
  102.         $viewedResults $restResults $latest null;
  103.         $mainResults $this->repositoryHelper->queryPosts2(
  104.             $this->streamProcessor->getCriteriaMain($customerTags$viewedVideos$limit$productId$customerId),
  105.             $context,
  106.             $postId,
  107.             $page,
  108.         );
  109.         //        /*
  110.         //         * If the total Stream amount doesn't reach the 100 video cap, add videos from viewed.
  111.         //         */
  112.         //        if(($total = $mainResults->getTotal()) < $limit)
  113.         //        {
  114.         //            $limit = $limit - $total;
  115.         //
  116.         //            $viewedResults =  $this->repositoryHelper->queryPosts2(
  117.         //                $this->streamProcessor->getCriteriaViewed($viewedVideos, $limit),
  118.         //                $context,
  119.         //                false,
  120.         //                !empty($productId),
  121.         //            );
  122.         //
  123.         //            /*
  124.         //            * If the total Stream amount STILL doesn't reach the 100 video cap, add videos from all tags.
  125.         //            */
  126.         //            if(($total += $viewedResults->getTotal()) < $limit)
  127.         //            {
  128.         //                /*
  129.         //                * Update for not duplicate videos
  130.         //                */
  131.         //                $viewedIds = [];
  132.         //                foreach ($viewedResults as $result)
  133.         //                {
  134.         //                    $viewedIds[] = $result->getId();
  135.         //                }
  136.         //                $limit = $limit - $total;
  137.         //
  138.         //                $restResults = $this->repositoryHelper->queryPosts2(
  139.         //                    $this->streamProcessor->getCriteriaRest($customerTags, $viewedIds, 100),
  140.         //                    $context,
  141.         //                    false,
  142.         //                    !empty($productId),
  143.         //                );
  144.         //                $restResults = $restResults->slice(0, 2);
  145.         //            }
  146.         //
  147.         //            $latest = $viewedResults->first();
  148.         //        }
  149.         //
  150.         //        // Get the latest watched video
  151.         //        if(!$latest && !empty($customerId))
  152.         //        {
  153.         //            $latest = $this->getLatestViewed($customerId, $context);
  154.         //        }
  155.         //
  156.         //        if(!empty($productId))
  157.         //        {
  158.         //            $latest = null;
  159.         //        }
  160.         return $this->streamSorter->sort(
  161.             $this->grabWeights($customerTags$customerId$context),
  162.             $mainResults,
  163.             $viewedResults,
  164.             $restResults,
  165.             $latest
  166.         );
  167.     }
  168.     public function buildUploadedStream($customerTagsstring $customerIdSalesChannelContext $context): array
  169.     {
  170.         return $this->streamSorter->sort(
  171.             $this->grabWeights($customerTags$customerId$context),
  172. //            $this->repositoryHelper->queryPosts2($this->streamProcessor->getUploadedCriteria($customerId, 499), $context, null, 1, 'uploaded')
  173.             $this->repositoryHelper->queryPosts($this->streamProcessor->getUploadedCriteria($customerId499), $contexttrue)
  174.         );
  175.     }
  176.     public function buildLikedStream($customerTagsstring $customerIdSalesChannelContext $context): array
  177.     {
  178.         $ids = [];
  179.         foreach ($this->repositoryHelper->queryLikes($this->streamProcessor->getCriteriaLiked($customerId499), $context->getContext())->getIterator() as $like) {
  180.             /** @var AmityPostLikesEntity $like */
  181.             $ids[] = $like->getPostId();
  182.         }
  183.         if (empty($ids)) {
  184.             return [];
  185.         }
  186.         return $this->streamSorter->sort(
  187.             $this->grabWeights($customerTags$customerId$context),
  188.             $this->repositoryHelper->queryPosts2($this->streamProcessor->getIdCriteria($ids100$customerId), $contextnull1'liked')
  189.         );
  190.     }
  191.     public function buildSavedStream($customerTagsstring $customerIdSalesChannelContext $context): array
  192.     {
  193.         $ids = [];
  194.         foreach ($this->repositoryHelper->querySaved($this->streamProcessor->getSaved($customerId499), $context->getContext())->getIterator() as $saved) {
  195.             /** @var AmityPostLikesEntity $saved */
  196.             $ids[] = $saved->getPostId();
  197.         }
  198.         if (empty($ids)) {
  199.             return [];
  200.         }
  201.         return $this->streamSorter->sort(
  202.             $this->grabWeights($customerTags$customerId$context),
  203.             $this->repositoryHelper->queryPosts2($this->streamProcessor->getIdCriteria($ids100$customerId), $contextnull1'saved')
  204.         );
  205.     }
  206.     public function getLatestViewed(string $customerIdSalesChannelContext $context)
  207.     {
  208.         $latest $this->repositoryHelper->queryPosts(
  209.             $this->utilities->getLastViewedCriteria($customerId$context->getContext()),
  210.             $context
  211.         );
  212.         return $latest->getTotal() ? $latest->first() : null;
  213.     }
  214.     public function grabWeights($customerTags, ?string $customerIdSalesChannelContext $context): array
  215.     {
  216.         return [
  217.             'viewTime'  =>  !empty($customerId) ? $this->utilities->getViewTimeWeights($customerTags$customerId$context->getContext()) : null,
  218.             'orders'    =>  !empty($customerId) ? $this->utilities->getOrderWeights($customerTags$customerId$context->getContext()) : null,
  219.             'social'    =>  !empty($customerId) ? $this->utilities->getSocialGraphWeights($customerId$context->getContext()) : null,
  220.         ];
  221.     }
  222.     /**
  223.      * @param ProductEntity $product
  224.      * @param SalesChannelContext $context
  225.      * @param string|null $type
  226.      * @return array
  227.      */
  228.     public function fetchPostsByEAN(ProductEntity $productSalesChannelContext $context, ?string $type null): array
  229.     {
  230.         $EANs = [$product->getEan()];
  231.         if (
  232.             array_key_exists('amityEANs'$product->getCustomFields())
  233.             && $product->getCustomFields()['amityEANs']
  234.         ) {
  235.             $EANs array_merge($EANsexplode(','$product->getCustomFields()['amityEANs']));
  236.         }
  237.         $filters = [];
  238.         foreach ($EANs as $EAN) {
  239.             $filters[] = (new EqualsFilter('ean'$EAN));
  240.         }
  241.         $criteria = (new Criteria())
  242.             ->addFilter(new MultiFilter('OR'$filters))
  243.             ->addAssociation('postChildren');
  244.         if ($type) {
  245.             $criteria->addFilter(new EqualsFilter('type'$type));
  246.         }
  247.         return $this->repositoryHelper->queryPosts(
  248.             $criteria,
  249.             $context
  250.         )->getElements();
  251.     }
  252.     public function buildDetailStream(string $productId$customerIdSalesChannelContext $context): array
  253.     {
  254.         $ids = [];
  255.         foreach ($this->repositoryHelper->queryDetailPost($this->streamProcessor->getCriteriaDetail($productId$customerId100), $context->getContext())->getIterator() as $post) {
  256.             $ids[] = $post->getId();
  257.         }
  258.         if (empty($ids)) {
  259.             return [];
  260.         }
  261.         return $this->streamSorter->sort(
  262.             $this->grabWeights([], $customerId$context),
  263.             $this->repositoryHelper->queryPosts($this->streamProcessor->getIdCriteria($ids10$customerId), $contexttrue)
  264.         );
  265.     }
  266.     public function convertVideoKey($post)
  267.     {
  268.         if (!empty($post->getCustomer())) {
  269.                 if (!empty($post->getCustomer()?->getCustomFields())) {
  270.                     $postCustomerCustomFields $post->getCustomer()?->getCustomFields();
  271.                     if (!empty($postCustomerCustomFields['emailListInvited'])) {
  272.                         $postCustomerCustomFields['emailListInvited'] = [];
  273.                     }
  274.                     if (!empty($postCustomerCustomFields['emailsInvited'])) {
  275.                         $postCustomerCustomFields['emailsInvited'] = [];
  276.                     }
  277.                     $post->getCustomer()?->setCustomFields($postCustomerCustomFields);
  278.                 }
  279.             }
  280.             if (!empty($post->getProduct())) {
  281.                 if (!empty($post->getProduct()?->getMedia())) {
  282.                     $post->getProduct()?->setMedia(new ProductMediaCollection([]));
  283.                 }
  284.                 if (!empty($post->getProduct()?->getCustomFields())) {
  285.                     $post->getProduct()?->setCustomFields([]);
  286.                 }
  287.                 if (!empty($post->getProduct()?->getTranslated())) {
  288.                     $postProductCustomFields $post->getProduct()?->getTranslated();
  289.                     if (!empty($postProductCustomFields['customFields'])) {
  290.                         $postProductCustomFields['customFields'] = [];
  291.                     }
  292.                     $post->getProduct()->setTranslated($postProductCustomFields);
  293.                 }
  294.             }
  295.             if (!empty($post->getAmityObject())) {
  296.                 $post->setAmityObject([]);
  297.             }
  298.             if (!empty($post->getPostChildren())) {
  299.                 foreach ($post->getPostChildren() as $postChild) {
  300.                     if (!empty($postChild->getAmityObject())) {
  301.                         $postChild->setAmityObject([]);
  302.                     }
  303.                     if (!empty($postChild->getFile()) && !empty($postChild->getFile()->{'fileObject'})) {
  304.                         $postChild->getFile()->{'fileObject'} = [];
  305.                     }
  306.                 }
  307.             }
  308.             return $post;
  309.     }
  310. }