Problém se stránkováním v modelu
- ForestCZE
- Člen | 209
Ahoj, mám následující kód:
Model:
public function getFoundUsers(int $page, int $lastPage, ?string $username): Selection
{
if(!$username)
return $this->database->getUsers()->where('deleted', false)->order('id DESC')->page($page, 20, $lastPage);
return $this->database->getUsers()->where('username LIKE ? AND deleted = ?', '%' . $username . '%', false);
}
Presenter:
private $usersFound;
private $lastPage = 0;
public function actionDefault($search, $page = 1): void
{
$this->usersFound = $this->userManager->getFoundUsers($page, $this->lastPage, $search);
}
public function renderDefault($page = 1): void
{
$this->template->usersFound = $this->usersFound;
$this->template->roles = UserManager::$roles;
$this->template->page = $page;
$this->template->lastPage = $this->lastPage;
if($this->isAjax())
$this->redrawControl('usersfound');
}
Latte:
{snippet usersfound}
<table class="records">
<tr>
<th>ID</th>
<th>Nick</th>
<th>Jméno</th>
<th>E-mail</th>
<th>Role</th>
</tr>
{foreach $usersFound as $userf}
<tr>
<td>{$userf->id}</td>
<td><a class="link" n:href="User: id => $userf->id, tab => 'profile'" target="_blank">{$userf->username}</a></td>
<td>{$userf->real_name ? $userf->real_name : 'Nevyplněno'}</td>
<td>
{ifset $isSuperAdmin}
{$userf->email|replace:'@':'(at)'}
{else}
<i class="fas fa-eye-slash"></i>
{/ifset}
</td>
<td>{$roles[$userf->role]}</td>
</tr>
{/foreach}
</table>
{/snippet}
<br>
{if $page > 1}
<a class="link" n:href="Searching: page => 1">První</a>
|
<a class="link" n:href="Searching: page => $page-1">Předchozí</a>
|
{/if}
Strana {$page} z {$lastPage == 0 ? 1 : $lastPage}
{if $page < $lastPage}
|
<a class="link" n:href="Searching: page => $page+1">Další</a>
|
<a class="link" n:href="Searching: page => $lastPage">Poslední</a>
{/if}
Normálně používám to stránkování v presenteru, ale v tomto případě je to v modelu, protože chci stránkovat pouze pokud to nic nehledá a je to ve výchozím stavu. Nevím proč, ale neukazuje mi to stránky. Je tam 1 z 1 a to je v DB 600+ záznamů. Co mám špatně? Děkuji předem za pomoc.
- Kamil Valenta
- Člen | 822
Ta logika je nějaká divoká, ale v principu je problém, že v presteru lastPage je 0 a nikde se nemění. Takže pak v šabloně bude podmínka {$lastPage == 0 ? 1 : $lastPage} vždy vracet tu jedničku…
- ForestCZE
- Člen | 209
Kamil Valenta napsal(a):
Ta logika je nějaká divoká, ale v principu je problém, že v presteru lastPage je 0 a nikde se nemění. Takže pak v šabloně bude podmínka {$lastPage == 0 ? 1 : $lastPage} vždy vracet tu jedničku…
Děkuju za snahu, ale v tom to není. To $lastPage
se mění
nějak vnitřně díky té metodě page
, která je na
Selection
, viz zde.
Editoval ForestCZE (17. 3. 2021 0:55)
- Kamil Valenta
- Člen | 822
A jsi si tím jist? Ano, z odkazovaného examplu to vyplývá, ale v API dokumentaci není zmínka, že by se tam předávala reference a IMHO by takový side-efect byl dost nečekaný. Nevím, tu metodu nepoužívám, ale zkusil bych si to dumpnout, zda je to skutečně tak, jak píšeš…
O to víc, když máš lastPage private…
- ForestCZE
- Člen | 209
Kamil Valenta napsal(a):
A jsi si tím jist? Ano, z odkazovaného examplu to vyplývá, ale v API dokumentaci není zmínka, že by se tam předávala reference a IMHO by takový side-efect byl dost nečekaný. Nevím, tu metodu nepoužívám, ale zkusil bych si to dumpnout, zda je to skutečně tak, jak píšeš…
O to víc, když máš lastPage private…
Ano jsem si jist, mám to použito na několika místech v presenterech a
funguje to. Jenom tady je problém, když je ta metoda page
volána
z modelu.
- Kamil Valenta
- Člen | 822
Ale vždyť to je ten rozdíl.
Pokud teda metoda page() má tento side-effect, tak ovlivní int $lastPage,
která je na stacku prostředí getFoundUsers().
O existenci private $lastPage v prostředí classy presenteru vůbec
„neví“.
public function getFoundUsers(int $page, int &$lastPage, ?string $username): Selection
nepomůže?
Ale je to krok o 10 let zpátky :(
--
EDIT: jo, je tam reference, která v api není vidět:
https://github.com/…election.php#L397
takže si myslím, že platí výše uvedené
Editoval Kamil Valenta (17. 3. 2021 3:36)
- ForestCZE
- Člen | 209
Kamil Valenta napsal(a):
Ale vždyť to je ten rozdíl.
Pokud teda metoda page() má tento side-effect, tak ovlivní int $lastPage, která je na stacku prostředí getFoundUsers().
O existenci private $lastPage v prostředí classy presenteru vůbec „neví“.public function getFoundUsers(int $page, int &$lastPage, ?string $username): Selection
nepomůže?
Ale je to krok o 10 let zpátky :(
--
EDIT: jo, je tam reference, která v api není vidět:
https://github.com/…election.php#L397takže si myslím, že platí výše uvedené
A můžu to teda použít, když je to „krok o 10 let zpátky“?
EDIT: Funguje to, ale zajímá mě, jestli je to šalamounské řešení nebo je
to teda v pořádku.
Editoval ForestCZE (17. 3. 2021 3:42)
- Kamil Valenta
- Člen | 822
Pokud už používáš metodu page(), tak klidně použij &$lastPage, je
to naprosto na stejné rovině.
Z pohledu jazyka je to v pořádku.
A debata, zda programovat s vedlejším efektem nebo ne, by byla
částečně akademická. Některé věci se tak prostě dají udělat snáz,
zároveň to však do kódu vnáší jistou nepřehlednost, nečekanost a
v důsledku i chybovost. Proto se od referencí upouští (teda statistiku
nemám, takže to ber jen jako můj osobní názor).
Pokud jsi ale na page() zvyklý, bude to pro Tebe akceptovatelné…
P.S. mně by teda žralo, že mi „něco“ přepíše private atribut. Divím se, že php nevykopne exceptionu a povoluje private atribut předat referencí…
P.S.2 ale zas abych nebyl příkrej, najdou se příklady, kdy bude referencování efektivní, třeba u datově velkých struktur
Editoval Kamil Valenta (17. 3. 2021 4:14)