Práva v dotazu nad výběrem položek (stránkování)
- double
- Člen | 14
Zdravím,
měl bych dotaz, resp. prosbu o radu. Mám ACl, které jde až na úroveň
řádku v databázi. Nad každým řádkém na stránce se pak provede
callback, zda uživatel má právo na danné id, nebo ne. potud vše funguje
v pořádku.
Problém je, že data se vytáhnou z modelu všechny (tam ani práva
nepatří), předají se do presenteru všechny a ten rozhoduje pomocí ACL zda
zobrazit nebo ne.
Pak ale nefunguje stránkování, kdy práva na řádek z datbáze může být
ve skutečnosti až na 50 straně a do té doby mám jen prázdné stránky
pak mám tedy
Model
function getAll($offset = 0,$limit = 1000)
{
// vrátí stránkované data
return ...SELECt id, name FROM test LIMIT $offset, $limit
}
Presenter
public function renderDefault() {
$vp = new VisualPaginator($this, 'vp');
$paginator = $vp->getPaginator();
$this->template->xxx = ...getAll($paginator->offset, $paginator->itemsPerPage);
}
A až teprve v šabloně rozhoduji, zda se zobrazí nebo ne
Šablona
.....{if $user->isAllowed(new Resource('Item',$company))}
Přijde mi zbytečné, procházet pole 2× v presenteru a šabloně. Výsledek je pak samozřejmě jedna položka na 50 straně.
Editoval double (16. 11. 2011 15:23)
- Patrik Votoček
- Člen | 2221
Tohle už je z principu celé špatně! Ty máš dostupnost pro danného uživatele řešit už v modelové části a né v šabloně.
- double
- Člen | 14
Ahoj,
ale jak? Vždyť přece v modelu není acl dostupné, přes this se
nedostanu k autorizátoru. Další věc je, že někdy teprve v presenteru
dostaneš všechny data potřebné k rozhodnutí.
Např. společnost a smlouvy – teprve až na smlouvě se dozvíš, jestli má
právo na společnosti něco vidět.
- double
- Člen | 14
Tak se s tím docela peru.
Když si předám acl, jak vyřešit metodu getAll()?
dejme tomu, že
user může vidět jen svoje
vedoucí může vidět svoje a usera pod ním
admin může vidět všechno
Přece nebudu psát tři dotazy, vždyť tím bych přebral celou zodpovědnost authentifikátoru a dělal bych to za něj.
- Filip Procházka
- Moderator | 4668
Co takto?
public function getAll()
{
if ($this->acl->isAllowed(self::RESOURCE, 'see:all')) {
return $this->db->query("dotaz na všechny");
} elseif ($this->acl->isAllowed(self::RESOURCE, 'see:owned')) {
return $this->db->query("dotaz na ty, které vlastní", $this->user->identity->id);
}
return NULL;
}
- pawouk
- Člen | 172
No ono tohle je opravdu těžko řešitelné. Pokud máš jen pár rolí tak to jde vyřešit jednoduše, ale když máš hodně rolí a práv, je nutné to zahrnout do SQL dotazu, jinak budeš vždycky tahat z db nesmyslná data a čím bude databáze větší, tím váce nesmyslných dat budeš tahat. Bohužel z toho vznikají občas opravdu dlouhé SQL dotazy, ale je to jediný způsob jak dosáhnout efektivního výsledku a funkčního stránkování…