public function findProducts(ListingFilter $filter)
 {
     $must = [];
     if ($filter->getEshop() !== null) {
         $must[] = ["term" => [ProductMeta::ESHOP_ID => (string) $filter->getEshop()->getId()]];
     }
     if ($filter->getCategory() !== null) {
         /** @var Category[] $childrenCategories */
         $childrenCategories = $this->categoryRepository->find([CategoryMeta::PATH => $filter->getCategory()->getId()]);
         $must[] = ["terms" => [ProductMeta::CATEGORY_IDS => array_merge([(string) $filter->getCategory()->getId()], array_map(function (Category $category) {
             return (string) $category->getId();
         }, $childrenCategories))]];
     }
     $body = ["query" => ["filtered" => ["filter" => ["bool" => ["must" => $must]]]], "from" => $filter->getOffset(), "size" => $filter->getLimit(), "sort" => ["_score" => "desc"]];
     if ($filter->getQ() !== null) {
         $body["query"]["filtered"]["query"] = ["multi_match" => ["query" => $filter->getQ(), "fields" => [ProductMeta::NAME . "^5", ProductMeta::LONG_NAME . "^5", ProductMeta::DESCRIPTION, ProductMeta::MANUFACTURER . "^2", ProductMeta::BRAND . "^2", ProductMeta::ESHOP . "." . EshopMeta::NAME . "^2"]]];
     }
     //		if (empty($body["query"]["filtered"]["filter"]["bool"]["must"])) {
     //			unset($body["query"]["filtered"]["filter"]);
     //		}
     $response = $this->elasticsearch->search(["index" => $this->catalogIndexAliasName, "type" => ProductMeta::SHORT_NAME, "body" => $body]);
     if (!isset($response["hits"]["hits"])) {
         throw new \RuntimeException("Response does not have hits->hits. Got: " . json_encode($response));
     }
     $products = [];
     foreach ($response["hits"]["hits"] as $hit) {
         $products[] = ProductMeta::fromArray($hit["_source"], "json:");
     }
     return $products;
 }
 public function eshopDetailAction(Request $request)
 {
     /** @var Eshop $eshop */
     $eshop = $this->eshopRepository->findOne([EshopMeta::SLUG => $request->attributes->get("eshop")]);
     $category = null;
     if ($request->attributes->has("category")) {
         /** @var Category $category */
         $category = $this->categoryRepository->findOneById($request->attributes->get("category"));
     }
     return $this->render("CC15Bundle:Eshop:eshopDetail.html.twig", ["eshop" => $eshop, "category" => $category, "categories" => $this->categoryRepository->findCategories($eshop, $category), "products" => $this->listingService->findProducts(ListingFilter::create()->setEshop($eshop)->setCategory($category))]);
 }
 public function handleMessage(Change $change, Message $message, Channel $channel)
 {
     if (!$change->getProduct()) {
         throw new \InvalidArgumentException("Badly routed message '{$message->content}' with routing key '{$message->routingKey}'.");
     }
     $product = $change->getProduct();
     /** @var Eshop $eshop */
     $eshop = $this->eshopRepository->getOneById($product->getEshopId());
     $product->setEshop($eshop);
     $categoryIds = $product->getCategoryIds();
     if (!empty($categoryIds)) {
         $product->setCategories($this->categoryRepository->find(["_id" => ['$in' => $product->getCategoryIds()]]));
     }
     if (!$this->elasticsearch->indices()->existsAlias(["name" => $this->catalogIndexAliasName])) {
         $this->initIndex();
     }
     $response = $this->elasticsearch->index(["index" => $this->catalogIndexAliasName, "type" => ProductMeta::SHORT_NAME, "id" => (string) $product->getId(), "version" => $product->getV(), "version_type" => "external_gte", "body" => ProductMeta::toObject($product, "json:")]);
     $this->log->info("Indexed Product#{$product->getId()} (v={$product->getV()}, created=" . json_encode($response["created"]) . ").");
     $channel->ack($message);
 }
 private function fillCategoryIds(Product $product)
 {
     $categoryTexts = $product->getCategoryTexts();
     $categoryIds = $product->getCategoryIds();
     for ($i = 0, $l = count($categoryTexts); $i < $l; ++$i) {
         if (isset($categoryIds[$i])) {
             continue;
         }
         $tree = preg_split("/\\s*[|>\\/]\\s*/", $categoryTexts[$i]);
         if (strncasecmp($tree[0], "heureka", 7) === 0) {
             array_shift($tree);
         }
         $tree = array_filter($tree, function ($name) {
             $name = trim($name);
             return !empty($name);
         });
         if (empty($tree)) {
             $categoryIds[$i] = null;
             continue;
         }
         $hash = md5(implode(" | ", $tree));
         /** @var Category $category */
         $category = $this->categoryRepository->findOne([CategoryMeta::ESHOP_ID => $product->getEshopId(), CategoryMeta::HASH => $hash], ["_id" => 1]);
         if ($category) {
             $categoryIds[$i] = $category->getId();
             continue;
         }
         $path = [];
         for ($j = 0, $m = count($tree); $j < $m; ++$j) {
             $treeHash = md5(implode(" | ", array_slice($tree, 0, $j + 1)));
             $treeCategory = new Category();
             $treeCategory->setEshopId($product->getEshopId())->setHash($treeHash)->setName($tree[$j])->setPath($path);
             /** @var Category $savedTreeCategory */
             $savedTreeCategory = $this->categoryRepository->findAndModify([CategoryMeta::ESHOP_ID => $treeCategory->getEshopId(), CategoryMeta::HASH => $treeCategory->getHash()], CategoryMeta::toArray($treeCategory), ["_id" => 1], ["upsert" => true, "new" => true]);
             $this->changeProducer->publish(Change::create()->setCategory($savedTreeCategory), RoutingKeys::CHANGE_CATEGORY_UPDATE);
             $path[$j] = $savedTreeCategory->getId();
         }
         $categoryIds[$i] = $path[count($tree) - 1];
     }
     $product->setCategoryIds($categoryIds);
 }