src/Services/Offer/OfferCacheService.php line 173

Open in your IDE?
  1. <?php
  2. namespace Slivki\Services\Offer;
  3. use Doctrine\Common\Collections\ArrayCollection;
  4. use Doctrine\ORM\EntityManagerInterface;
  5. use Slivki\Entity\BankCurrency;
  6. use Slivki\Entity\Category;
  7. use Slivki\Entity\GeoLocation;
  8. use Slivki\Entity\Media;
  9. use Slivki\Entity\Media\OfferTeaserMedia;
  10. use Slivki\Entity\MediaType;
  11. use Slivki\Entity\Offer;
  12. use Slivki\Entity\OfferExtension;
  13. use Slivki\Entity\PhoneNumber;
  14. use Slivki\Entity\Seo;
  15. use Slivki\Repository\SeoRepository;
  16. use Slivki\Services\CacheService;
  17. use Slivki\Services\TextCacheService;
  18. use Slivki\Util\Logger;
  19. use Slivki\Util\TarantoolCache;
  20. use Symfony\Component\Serializer\Encoder\JsonEncoder;
  21. use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
  22. use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
  23. use Symfony\Component\Serializer\Serializer;
  24. class OfferCacheService extends CacheService {
  25.     const SPACE_NAME 'offer';
  26.     const PHONE_SPACE_NAME 'phoneNumber';
  27.     const EXTENSION_SPACE_NAME 'offerExtension';
  28.     const PHONE_2_LOCATION_SPACE_NAME 'phoneNumber2geoLocation';
  29.     private $entityManager;
  30.     public function __construct(EntityManagerInterface $entityManagerTextCacheService $textCacheService) {
  31.         $this->entityManager $entityManager;
  32.         $this->textCacheService $textCacheService;
  33.     }
  34.     public function reloadOfferCache($offerID$reloadMemcache true) {
  35.         /** @var Offer $offer */
  36.         $offer null;
  37.         $offerID = (int)$offerID;
  38.         if ($reloadMemcache) {
  39.             $offer $this->entityManager->getRepository(Offer::class)->reloadCacheForOneOffer($offerID'OfferCacheService::reloadOfferCache');
  40.         } else {
  41.             $offer $this->entityManager->getRepository(Offer::class)->findCached($offerID);
  42.         }
  43.         $tarantool = new TarantoolCache(self::SPACE_NAME);
  44.         if (!$offer) {
  45.             $this->deleteOffer($offerID);
  46.             return false;
  47.         }
  48.         foreach ($offer->getCategories() as $category) {
  49.             if ($category->getTypeID() == Category::SUPPLIER_CATEGORY_TYPE) {
  50.                 $categoryData = [
  51.                     'name' => $category->getName(),
  52.                     'url' => $this->entityManager->getRepository(Seo::class)->getByEntity(SeoRepository::RESOURCE_URL_OFFER_CATEGORY$category->getID())->getMainAlias()
  53.                 ];
  54.                 $offer->setSupplierCategoryData($categoryData);
  55.             }
  56.         }
  57.         $teaserMediaID $offer->getTeaserMedia() ? $offer->getTeaserMedia()->getID() : null;
  58.         $mediaTarantool = new TarantoolCache(self::MEDIA_SPACE_NAME);
  59.         if ($teaserMediaID) {
  60.             $medias $mediaTarantool->callFunction('getMedias', [OfferTeaserMedia::TYPE0$offerID]);
  61.             if ($medias) {
  62.                 foreach ($medias as $media) {
  63.                     if ($media[0] != $teaserMediaID) {
  64.                         $mediaTarantool->delete($media[0]);
  65.                     }
  66.                 }
  67.             }
  68.         }
  69.         $shopMedias $this->getMediaList($offerID0MediaType::TYPE_OFFER_SHOP_PHOTO_ID);
  70.         foreach ($shopMedias as $tarantoolMedia) {
  71.             $found false;
  72.             foreach ($offer->getShopMedias() as $media) {
  73.                 if ($tarantoolMedia->getID() == $media->getID()) {
  74.                     $found true;
  75.                     break;
  76.                 }
  77.             }
  78.             if (!$found) {
  79.                 $tarantool->delete($tarantoolMedia->getID());
  80.             }
  81.         }
  82.         $tarantool->set($offerID, [$offerIDjson_encode($offer)]);
  83.         $this->cacheMedias([$offer->getTeaserMedia()]);
  84.         $this->cacheMedias([$offer->getMobileTeaserMedia()]);
  85.         $this->cacheMedias($offer->getDetailMedias());
  86.         $this->cacheMedias($offer->getShopMedias());
  87.         $this->cacheMedias([$offer->getAppTeaserMedia()]);
  88.         $medias $mediaTarantool->callFunction('getMedias', [Media\OfferTopBlockMedia::TYPE0$offerID]);
  89.         $mediaID $offer->getTopBlockMedia() ? $offer->getTopBlockMedia()->getID() : 0;
  90.         if ($medias) {
  91.             foreach ($medias as $media) {
  92.                 if ($media[0] != $mediaID) {
  93.                     $mediaTarantool->delete($media[0]);
  94.                 }
  95.             }
  96.         }
  97.         $medias $mediaTarantool->callFunction('getMedias', [Media\OfferTopBlockMobileMedia::TYPE0$offerID]);
  98.         $mediaID $offer->getTopBlockMobileMedia() ? $offer->getTopBlockMobileMedia()->getID() : 0;
  99.         if ($medias) {
  100.             foreach ($medias as $media) {
  101.                 if ($media[0] != $mediaID) {
  102.                     $mediaTarantool->delete($media[0]);
  103.                 }
  104.             }
  105.         }
  106.         $this->cacheMedias([$offer->getTopBlockMedia()]);
  107.         $this->cacheMedias([$offer->getTopBlockMobileMedia()]);
  108.         $medias $mediaTarantool->callFunction('getMedias', [Media\OfferMapLogoMedia::TYPE0$offerID]);
  109.         $mapLogoMedia $offer->getMapLogoMedia();
  110.         $mediaId null === $mapLogoMedia $mapLogoMedia->getID();
  111.         foreach ($medias as $media) {
  112.             if ($media[0] !== $mediaId) {
  113.                 $mediaTarantool->delete($media[0]);
  114.             }
  115.         }
  116.         $this->cacheMedias($offer->getMapLogoMedias()->toArray());
  117.         $medias $mediaTarantool->callFunction('getMedias', [Media\OfferDeliveryZoneMedia::TYPE0$offerID]);
  118.         $deliveryZoneMedia $offer->getDeliveryZoneMedia();
  119.         $mediaId null === $deliveryZoneMedia $deliveryZoneMedia->getID();
  120.         foreach ($medias as $media) {
  121.             if ($media[0] !== $mediaId) {
  122.                 $mediaTarantool->delete($media[0]);
  123.             }
  124.         }
  125.         $this->cacheMedias($offer->getDeliveryZoneMedias()->toArray());
  126.         $medias $mediaTarantool->callFunction('getMedias', [Media\OnlineOrderPopupLogoMedia::TYPE0$offerID]);
  127.         $onlineOrderPopupLogoMedia $offer->getOnlineOrderPopupLogoMedia();
  128.         $mediaId null === $onlineOrderPopupLogoMedia $onlineOrderPopupLogoMedia->getID();
  129.         foreach ($medias as $media) {
  130.             if ($media[0] !== $mediaId) {
  131.                 $mediaTarantool->delete($media[0]);
  132.             }
  133.         }
  134.         $this->cacheMedias($offer->getOnlineOrderPopupLogoMedias()->toArray());
  135.         if ($offer->getSupplierPhotoMedias()) {
  136.             $this->cacheMedias($offer->getSupplierPhotoMedias()->toArray());
  137.         }
  138.         $this->cacheEntityDescriptions($offer->getDescriptions()->toArray());
  139.         if ($offer->getGeoLocations()) {
  140.             $this->cacheGeoLocations($offerID$offer->getGeoLocations()->toArray());
  141.         }
  142.         $this->cachePhoneNumbers($offerID$offer->getPhoneNumbers()->toArray());
  143.         $this->cacheExtensions($offerID$offer->getExtensions()->toArray());
  144.         return $offer;
  145.     }
  146.     public function cacheOffer(Offer $offer) {
  147.         $offerID $offer->getID();
  148.         $this->entityManager->getRepository(Offer::class)->putOfferToCache($offer);
  149.         $tarantool = new TarantoolCache(self::SPACE_NAME);
  150.         $tarantool->set($offerID, [$offerIDjson_encode($offer)]);
  151.     }
  152.     /**
  153.      * @return Offer|bool
  154.      */
  155.     public function getOffer($offerID$withTeaserMedia false$allData false) {
  156.         $offerID = (int)$offerID;
  157.         $tarantool = new TarantoolCache(self::SPACE_NAME);
  158.         $data $tarantool->get($offerID);
  159.         if (!$data) {
  160.             $logger Logger::instance('DEBUG');
  161.             $logger->info($offerID ' offer not found in tarantool');
  162.             return $this->entityManager->getRepository(Offer::class)->findCached($offerID);
  163.         }
  164.         return $this->getSerializedOffer($data$withTeaserMedia$allData);
  165.     }
  166.     private function getSerializedOffer($data$withTeaserMedia false$allData false) {
  167.         $offerID $data[0][0];
  168.         $normalizer = new ObjectNormalizer();
  169.         //$normalizer->setIgnoredAttributes(['bankCurrency']);
  170.         $serializer = new Serializer([$normalizer], [new JsonEncoder()]);
  171.         /** @var Offer $offer */
  172.         $offer $serializer->deserialize($data[0][1], Offer::class, 'json', [AbstractNormalizer::IGNORED_ATTRIBUTES => ['bankCurrency''onlineOrderSettings']]);
  173.         $dataDecoded json_decode($data[0][1]);
  174.         $offer->fromJSON($dataDecoded);
  175.         if ($withTeaserMedia) {
  176.             $medias $this->getMediaList($offerIDOfferTeaserMedia::TYPE0);
  177.             if (count($medias) > 0) {
  178.                 $offer->setTeaserMedias(new ArrayCollection($medias));
  179.             }
  180.         }
  181.         if ($allData) {
  182.             $offer->setDetailMeidas($this->getMediaList($offerID0MediaType::TYPE_OFFER_DETAIL_PHOTO_ID));
  183.             $offer->setShopMedias($this->getMediaList($offerID0MediaType::TYPE_OFFER_SHOP_PHOTO_ID));
  184.             $offer->setDescriptions($this->getEntityDescriptionList($offerID));
  185.             $offer->setMapLogoMedias(new ArrayCollection($this->getMediaList($offerIDMedia\OfferMapLogoMedia::TYPE0)));
  186.             $offer->setDeliveryZoneMedias(new ArrayCollection($this->getMediaList($offerIDMedia\OfferDeliveryZoneMedia::TYPE0)));
  187.             $phones2Locations $this->getPhones2Locations($offerID);
  188.             $geoLocations $this->getGeoLocations(GeoLocation::TYPEGeoLocation::class, $offerID);
  189.             $phoneNumbers $this->getPhoneNumbers($offerID);
  190.             /** @var GeoLocation $geoLocation */
  191.             foreach ($geoLocations as $geoLocation) {
  192.                 foreach ($phoneNumbers as $phoneNumber) {
  193.                     if (in_array(json_encode([$phoneNumber->getID(), $geoLocation->getID()]), $phones2Locations)) {
  194.                         $geoLocation->addPhoneNumber($phoneNumber);
  195.                     }
  196.                 }
  197.             }
  198.             $offer->setGeoLocation($geoLocations);
  199.             $offer->setPhoneNumbers($phoneNumbers);
  200.             $offer->setExtensions($this->getExtensions($offerID));
  201.             if ($offer->isActiveCurrencyCalculator()) {
  202.                 $offer->setBankCurrency(BankCurrency::fromJSON($dataDecoded->bankCurrency));
  203.             }
  204.             $offer->setSupplierPhotoMedias($this->getMediaList($offerID,MediaType::TYPE_OFFER_SUPPLIER_PHOTO_ID0));
  205.             $medias $this->getMediaList($offerIDMedia\OfferAppTeaserMedia::TYPE0);
  206.             if (count($medias) > 0) {
  207.                 $offer->setAppTeaserMedias(new ArrayCollection($medias));
  208.             }
  209.             $medias $this->getMediaList($offerIDMedia\OfferTopBlockMedia::TYPE0);
  210.             if (count($medias) > 0) {
  211.                 $offer->setTopBlockMedias(new ArrayCollection($medias));
  212.             }
  213.             $medias $this->getMediaList($offerIDMedia\OfferTopBlockMobileMedia::TYPE0);
  214.             if (count($medias) > 0) {
  215.                 $offer->setTopBlockMobileMedias(new ArrayCollection($medias));
  216.             }
  217.             $medias $this->getMediaList($offerIDMedia\OnlineOrderPopupLogoMedia::TYPE0);
  218.             if (count($medias) > 0) {
  219.                 $offer->setOnlineOrderPopupLogoMedias(new ArrayCollection($medias));
  220.             }
  221.         }
  222.         return $offer;
  223.     }
  224.     public function deleteOffer($offerID) {
  225.         $tarantool = new TarantoolCache(self::SPACE_NAME);
  226.         $tarantool->callFunction('deleteOffer', [$offerID]);
  227.     }
  228.     private function getPhoneNumbers($offerID) {
  229.         $tarantool = new TarantoolCache(self::PHONE_SPACE_NAME);
  230.         $result $tarantool->select([$offerID],'byEntity');
  231.         $phoneNumbers = new ArrayCollection();
  232.         foreach ($result as $item) {
  233.             $phoneNumbers->add(PhoneNumber::fromJSON(json_decode($item[2])));
  234.         }
  235.         return $phoneNumbers;
  236.     }
  237.     private function getPhones2Locations($offerID) {
  238.         $tarantool = new TarantoolCache(self::PHONE_2_LOCATION_SPACE_NAME);
  239.         $result $tarantool->select([$offerID],'byOfferID');
  240.         $phones2Locations = [];
  241.         foreach ($result as $item) {
  242.             $phones2Locations[] = json_encode([$item[0], $item[1]]);
  243.         }
  244.         return $phones2Locations;
  245.     }
  246.     private function cachePhoneNumbers($offerID, array $phoneNumbers) {
  247.         $tarantool = new TarantoolCache(self::PHONE_SPACE_NAME);
  248.         $tarantoolPhone2Location = new TarantoolCache(self::PHONE_2_LOCATION_SPACE_NAME);
  249.         $phone2Locations = [];
  250.         foreach ($phoneNumbers as $number) {
  251.             $tarantool->set($number->getID(), [$number->getID(), $offerIDjson_encode($number)]);
  252.             foreach ($number->getGeoLocations() as $geoLocation) {
  253.                 $tarantoolPhone2Location->set([$number->getID(), $geoLocation->getID()], [$number->getID(), $geoLocation->getID(), $offerID]);
  254.                 $phone2Locations[] = json_encode([$number->getID(), $geoLocation->getID()]);
  255.             }
  256.         }
  257.         foreach ($tarantoolPhone2Location->select([$offerID], 'byOfferID') as $phone2Location) {
  258.             if (!in_array(json_encode([$phone2Location[0], $phone2Location[1]]), $phone2Locations)) {
  259.                 $tarantool->callFunction('deletePhoneNumber2geoLocation', [(int)$phone2Location[0], (int)$phone2Location[1]]);
  260.             }
  261.         }
  262.     }
  263.     public function deletePhoneNumber($phoneNumberID) {
  264.         $tarantool = new TarantoolCache(self::PHONE_SPACE_NAME);
  265.         $tarantool->delete($phoneNumberID);
  266.     }
  267.     public function getExtensions($offerID) {
  268.         $tarantool = new TarantoolCache(self::EXTENSION_SPACE_NAME);
  269.         $result $tarantool->select([$offerID], 'byEntityID');
  270.         $extensions = new ArrayCollection();
  271.         foreach ($result as $item) {
  272.             $class OfferExtension::getExtensionClass($item[1]);
  273.             $extensions->add($class::fromJSON(json_decode($item[3])));
  274.         }
  275.         return $extensions;
  276.     }
  277.     private function cacheExtensions($offerID, array $extensions) {
  278.         $tarantool = new TarantoolCache(self::EXTENSION_SPACE_NAME);
  279.         foreach ($extensions as $extension) {
  280.             $tarantool->set($extension->getID(), [$extension->getID(), $extension->getType(), $offerIDjson_encode($extension)]);
  281.         }
  282.     }
  283.     public function deleteExtension($extensionID) {
  284.         $tarantool = new TarantoolCache(self::EXTENSION_SPACE_NAME);
  285.         $tarantool->delete($extensionID);
  286.     }
  287.     public function checkState() {
  288.         $tarantool = new TarantoolCache('');
  289.         $tarantool->callFunction('deletePastOffers', []);
  290.     }
  291.     public function getOffers(array $offerIDs$withTeaserMedia false$allData false) {
  292.         $tarantool = new TarantoolCache();
  293.         $offers = [];
  294.         $offersData $tarantool->callFunction('getOffers', [$offerIDs]);
  295.         if (!isset($offersData[0][0])) {
  296.             return $offers;
  297.         }
  298.         foreach ($offersData[0][0] as $data) {
  299.             if (empty($data)) {
  300.                 continue;
  301.             }
  302.             $offer $this->getSerializedOffer($data$withTeaserMedia$allData);
  303.             $offers[$offer->getID()] = $offer;
  304.         }
  305.         return $offers;
  306.     }
  307.     public function findOfferJson(int $offerId): ?Object
  308.     {
  309.         $tarantool = new TarantoolCache(self::SPACE_NAME);
  310.         $offerData $tarantool->getById($offerId);
  311.         if (null === $offerData) {
  312.             return null;
  313.         }
  314.         return json_decode($offerData[1]);
  315.     }
  316.     public function saveOfferJson(Object $offerJson): void {
  317.         $tarantool = new TarantoolCache(self::SPACE_NAME);
  318.         $tarantool->set($offerJson->ID, [$offerJson->IDjson_encode($offerJson)]);
  319.     }
  320. }