/**
  * @param Eshop $eshop
  * @param Category $category
  * @return Category[]
  */
 public function findCategories(Eshop $eshop, Category $category = null)
 {
     $query = ['$and' => [[CategoryMeta::ESHOP_ID => $eshop->getId()]]];
     if ($category === null) {
         $query['$and'][] = [CategoryMeta::PATH => ['$size' => 0]];
     } else {
         $query['$and'][] = [CategoryMeta::PATH => $category->getId()];
         $query['$and'][] = [CategoryMeta::PATH => ['$size' => count($category->getPath()) + 1]];
     }
     return $this->find($query, [], ["sort" => [CategoryMeta::NAME => 1]]);
 }
 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);
 }