по сути, это типичная уменьшение операция.
несколько различных способов сделать это (однако, остерегайтесь проблемы с запросом n + 1):
// in the product entity class
public function getMinPrice() {
return array_reduce($this->getProductLinks(), function($lowest, $link) {
return min($lowest ?? $link->getPrice(), $link->getPrice());
});
}
вы также можете сделать что-то подобное в ветке (будьте осторожны: только в ветке> = 1,41 или ветке> = 2,10):
product.productLinks|reduce((lowest, link) => min(lowest ?? link.price, link.price))
однако, вероятно, лучше адаптировать свой репозиторий продуктов, чтобы установить самую низкую цену навиртуальное свойство, например, такое, что вы не загружаете все ссылки для всех продуктов в отдельности ...
Если честно, я не совсем уверен, работает ли это
// in ProductRepository
public function getWithMinPrices() {
$qb = $this->createQueryBuilder('product');
$qb
->addSelect('(SELECT MIN(pl.price) FROM product.productLinks pl) as minprice')
// do other query stuff like limiting number of products, searching etc.
$result = $qb->getQuery()->getResult();
// in contrast to normal queries, you now have an array of arrays with
// one object and the minprice
return array_map(function($row) {
$product = $row[0];
$product->minPrice = $row['minprice'];
return $product;
}
}
после этого вы можете получить доступ к этой виртуальной переменной в twig через product.minPrice
, вы также можете комбинировать подходы:
protected $minPrice = null;
// in the product entity class
public function getMinPrice() {
if(!is_null($this->minPrice)) {
$this->minPrice = array_reduce($this->getProductLinks(), function($lowest, $link) {
return min($lowest ?? $link->getPrice(), $link->getPrice());
});
}
return $this->minPrice;
}
public function setMinPrice($minPrice) {
$this->minPrice = $minPrice;
}
затем вам нужно вызвать $product->setMinPrice($row['minprice'])
в функции хранилища.
этот гибридный подход гарантирует, что вы всегда получите минимальную цену, даже если функция хранилища не была вызвана.
в качестве дополнительного примечания: вызовы Reduction всегда можно заменить нацикл:
$min = null;
foreach($this->getProductLinks() as $link) {
$min = min($min ?? $link->getPrice(), $link->getPrice());
}
, который выглядит меньшепугающе и семантически примерно одно и то же ... что-то подобное возможно в ветке, но это ужасно уродливо, но все же может быть достаточно хорошим