Práva v dotazu nad výběrem položek (stránkování)

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
double
Člen | 14
+
0
-

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
+
0
-

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
+
0
-

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.

Filip Procházka
Moderator | 4668
+
0
-

To je jednoduché, znáš Dependency Injection?

double
Člen | 14
+
0
-

aaa, jasně, to mi nedošlo. Díky za nakopnutí

double
Člen | 14
+
0
-

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
+
0
-

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
+
0
-

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í…