Oznámení
Lean Mapper – výchozí řazení v proměnné typu m:belongsToMany
před 6 lety
- svezij
- Člen | 69
Ahojte, nerad přidávám příspěvky do vlákna Lean
Mapper – tenké ORM nad dibi, protože mi přijde, že se tam řeší
důležité věci ohledně Lean Mapperu a nechci tam obtěžovat takovými
maličkostmi. Proto se omlouvám, měl-li bych tento dotaz vložit právě
tam.
Mám entitu výrobku, která obsahuje obrázky výrobku:
/**
* @property int $id
* ...
* @property ProductImage[] $images m:belongsToMany(:product_images)
* ...
*/
class Product extends \LeanMapper\Entity
{
}
Všechno funguje tak, jak má, ale tabulka product_images
obsahuje sloupec sequence
, který je typu „integer“ a udává
řazení obrázků. Jak Lean Mapper „donutit“, aby mi obrázky z tabulky
product_images
stahoval do proměnné $images
v pořadí ORDER BY sequence ASC
? Tzn.:
Tabulka:
id | product | filename | sequence
----------------------------------
1 | 1 | obr1.jpg | 1
2 | 1 | obr2.jpg | 3
3 | 1 | obr3.jpg | 2
Kód:
$repository = getProductRepository();
$product = $repository->find(1);
foreach ($product->images as $image) {
echo $image->file . '<br />';
}
Chtěl bych, aby vypsalo:
obr1.jpg
obr3.jpg
obr2.jpg
ale samozřejmě vypíše:
obr1.jpg
obr2.jpg
obr3.jpg
Jak to mám vyřešit? Děkuji :-).
před 6 lety
- svezij
- Člen | 69
Tak zatím jsem to „zvládl“ přes vlastní getter.
/**
* Getter of images
*
* @return ProductImage[]
*/
public function getImages()
{
$value = array();
foreach ($this->row->referencing('product_images', 'product_id') as $row) {
$value[] = new ProductImage($row->referenced('product_images', 'id'));
}
usort($value, function($a, $b) {
return (($a->sequence == $b->sequence) ? 0 : (($a->sequence < $b->sequence) ? -1 : 1));
});
return $value;
}
Je to správné řešení, nebo existuje jiné, lepší?
před 6 lety
- Casper
- Člen | 253
Použij filtr.
Entita:
/**
* @property ProductImage[] $images m:belongsToMany(:product_images) m:filter(sortImages)
*/
class Product extends \LeanMapper\Entity{}
config.neon
services:
myFilter: Model\Filter\MyFilter
connection:
class: LeanMapper\Connection(%database%)
setup:
- registerFilter('sortImages', [@myFilter, 'sortImages'])
Filtr:
class MyFilter {
public function sortImages(\LeanMapper\Fluent $statement){
$statement->orderBy("sequence ASC");
}
}
před 6 lety
- Tharos
- Člen | 1042
Použití filtru je best practice.
Ke Casperovo odpovědi jenom dodám, že filtr může být i obecnější (a univerzálnější) s „natvrdo“ vepsaným parametrem v anotaci, což bych zde asi volil:
/**
* @property ProductImage[] $images m:belongsToMany(:product_images) m:filter(sort#sequence)
*/
class Product extends \LeanMapper\Entity
{
}
$connection->registerFilter('sort', function(Fluent $statement, $column) {
$statement->orderBy($column);
});
před 6 lety
- svezij
- Člen | 69
Ahojte, mockrát děkuji za odpověď, chtěl jsem to takto provést, ale nevím, kde registrovat ten filter. Zkoušel jsem ho registrovat v konstruktoru repozitáře, ale laděnka píše:
Filter with name 'sort' was already registered.
Systém s LeanMapperem spojuji v bootstrap.php
:
// LeanMapper connection registration
$configurator->onCompile[] = function($configurator, Nette\Config\Compiler $compiler) {
$compiler->addExtension('dibi', new LeanMapperConnectionExtension());
};
a třída LeanMapperConnectionExtension
se liší od
DibiNette20Extension
tím, že volám:
$connection = $container->addDefinition($this->prefix('connection'))
->setClass('LeanMapper\Connection', array($config));
místo:
$connection = $container->addDefinition($this->prefix('connection'))
->setClass('DibiConnection', array($config));
Kde mám tedy zavolat
$connection->registerFilter('sort', function(Fluent $statement, $column) {
$statement->orderBy($column);
});
?
Ještě jednou moc děkuji.
před 5 lety
- medhi
- Bronze Partner | 189
Také bych se přimlouval za odpověď. Jak v Nette registrovat takový filtr, pokud mám Lean Mapper v configu jako extension?
Díky
Editoval medhi (29. 8. 2014 16:22)
před 5 lety
- Tharos
- Člen | 1042
Ahoj,
já poslední dobou registruji filtry následovně:
<?php
namespace SomeProject\LeanMapper\DI;
use LeanMapper\Connection;
use Nette\DI\CompilerExtension;
use Nette\PhpGenerator\ClassType;
use SomeProject\LeanMapper\IFiltersConfigurator;
/**
* @author Vojtěch Kohout
*/
class LeanMapperExtension extends CompilerExtension
{
public function loadConfiguration()
{
$container = $this->getContainerBuilder();
$config = $this->getConfig();
$useProfiler = isset($config['profiler'])
? $config['profiler']
: class_exists('Tracy\Debugger') && $container->parameters['debugMode'];
unset($config['profiler']);
if (isset($config['flags'])) {
$flags = 0;
foreach ((array) $config['flags'] as $flag) {
$flags |= constant($flag);
}
$config['flags'] = $flags;
}
$connection = $container->addDefinition($this->prefix('connection'))
->setClass('LeanMapper\Connection', [$config]);
if ($useProfiler) {
$panel = $container->addDefinition($this->prefix('panel'))
->setClass('Dibi\Bridges\Tracy\Panel');
$connection->addSetup([$panel, 'register'], [$connection]);
}
}
/**
* @param ClassType $class
*/
public function afterCompile(ClassType $class)
{
$initialize = $class->methods['initialize'];
$initialize->addBody('$this->getByType("' . IFiltersConfigurator::class . '")->setUpFilters($this->getByType("' . Connection::class . '"));');
}
}
<?php
namespace SomeProject\LeanMapper;
use LeanMapper\Connection;
/**
* @author Vojtěch Kohout
*/
interface IFiltersConfigurator
{
function setUpFilters(Connection $connection);
}
<?php
namespace SomeProject\LeanMapper;
use SomeProject\LeanMapper\Query\IQuery;
use SomeProject\LeanMapper\Query\QueryUsingEntityReflection;
use LeanMapper\Connection;
use LeanMapper\Exception\InvalidArgumentException;
use LeanMapper\Fluent;
use LeanMapper\IMapper;
use LeanMapper\Reflection\Property;
/**
* @author Vojtěch Kohout
*/
class FiltersConfigurator implements IFiltersConfigurator
{
/**
* @param Connection $connection
*/
public function setUpFilters(Connection $connection)
{
$connection->registerFilter(...);
}
}
Možností je vážně celá řada. Mně se líbí, když existuje nějaký
konfigurátor (FiltersConfigurator
) a v extenzi, která
Lean Mapper integruje do projektu, se dá velmi pohodlně využít.
Editoval Tharos (2. 9. 2014 23:31)