<?php
namespace App\Application\Twig;
use App\Admin\Document\Category;
use App\Admin\Document\Config;
use App\Admin\Document\Product;
use App\Admin\Document\ProductProperty;
use App\Admin\Document\Property;
use App\Admin\Document\PropertyValue;
use App\Application\Controller\CatalogController;
use Doctrine\ODM\MongoDB\DocumentManager;
use Symfony\Component\HttpFoundation\Request;
class GlobalLoader
{
/**
* @var DocumentManager
*/
private $documentManager;
/**
* @var Config
*/
private $config;
public function __construct(DocumentManager $documentManager)
{
$this->documentManager = $documentManager;
}
/**
* @return object|null|Config
* @throws \Exception
*/
public function getConfig()
{
if (!$this->config) {
$this->config = $this->documentManager->getRepository(Config::class)->findOneBy([]);
if (!$this->config) {
throw new \Exception('Config not found');
}
}
return $this->config;
}
private $menu;
public function getMenu() {
if (!isset($this->menu)) {
$this->menu = $this->documentManager->getRepository(Category::class)->findBy(
['active' => true, 'parent' => null], ['orderNumber' => 'asc', 'name' => 'asc']);
}
return $this->menu;
}
private $propertyMap = [];
/**
* @param $id
* @return ProductProperty
*/
public function getProperty(\App\Admin\Document\Embedded\Property $property) {
$result = false;
if ($property->getValueId() !== null) {
$key = $property->getId() . '_' . $property->getValueId();
if (isset($this->propertyMap[$key])) {
return $this->propertyMap[$key];
}
/**
* @var ProductProperty $productProperty
*/
$productProperty = $this->documentManager->getRepository(ProductProperty::class)->findOneBy([
'id1C' => $property->getId(),
'active' => true
]);
if ($productProperty) {
$value = $this->getPropertyValue($property->getValueId());
if ($value) {
$productProperty->setValue($value);
$result = $productProperty;
}
}
$this->propertyMap[$key] = $result;
}
return $result;
}
private $propertyValueMap = [];
private function getPropertyValue($id) {
if (isset($this->propertyValueMap[$id])) {
return $this->propertyValueMap[$id];
}
$value = $this->documentManager->getRepository(PropertyValue::class)->findOneBy(['id1C' => $id]);
if (!$value) {
$value = new PropertyValue();
$value->setId1C($id);
$value->setName($id);
}
$this->propertyValueMap[$id] = $value;
return $value;
}
/**
* Получить отсортированные свойства товара с учетом orderNumber
*/
public function getSortedProperties(Product $product) {
$properties = $product->getProperties1C();
$sortedProperties = [];
foreach ($properties as $property) {
$productProperty = $this->getProperty($property);
if ($productProperty) {
$sortedProperties[] = $productProperty;
}
}
// Сортировка: сначала по orderNumber (если есть), затем в текущем порядке
usort($sortedProperties, function($a, $b) {
$orderA = $a->getOrderNumber();
$orderB = $b->getOrderNumber();
// Если у обеих есть orderNumber - сортируем по нему
if ($orderA !== null && $orderB !== null) {
return $orderA <=> $orderB;
}
// Если только у одной есть orderNumber - она идет первой
if ($orderA !== null && $orderB === null) {
return -1;
}
if ($orderA === null && $orderB !== null) {
return 1;
}
// Если у обеих orderNumber = null - оставляем текущий порядок
return 0;
});
return $sortedProperties;
}
private $watchedProducts = null;
public function getRecentlyWatchedProducts($excludeProductId = null) {
if ($this->watchedProducts === null) {
$request = Request::createFromGlobals();
$ids = explode(';', $request->cookies->get(CatalogController::RECENTLY_WATCHED_PRODUCTS_COOKIE_NAME, ''));
$productIds = [];
foreach ($ids as $id) {
if ($id) {
$productIds[] = new \MongoId($id);
}
}
$this->watchedProducts = $this->documentManager->getRepository(Product::class)->findBy(
[
'_id' => ['$in' => $productIds],
]
);
usort($this->watchedProducts, function (Product $a, Product $b) use ($productIds) {
return array_search($a->getId(), $productIds) - array_search($b->getId(), $productIds);
});
}
$result = [];
/**
* @var Product $product
*/
foreach ($this->watchedProducts as $product) {
if ($product->getId() != $excludeProductId && $product->getActive()) {
$result[] = $product;
}
}
return $result;
}
}