Problém se stránkováním v modelu

ForestCZE
Člen | 209
+
0
-

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>
    &nbsp;|&nbsp;
    <a class="link" n:href="Searching: page => $page-1">Předchozí</a>
    &nbsp;|&nbsp;
{/if}

Strana {$page} z {$lastPage == 0 ? 1 : $lastPage}

{if $page < $lastPage}
    &nbsp;|&nbsp;
    <a class="link" n:href="Searching: page => $page+1">Další</a>
    &nbsp;|&nbsp;
    <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 | 762
+
0
-

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

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

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

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 | 762
+
+1
-

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

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#L397

takž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 | 762
+
0
-

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)