Bonjour,

J'ai un petit nouveau bug de changement d'affichage de menu de mon projet USSD (ce que j'appelle: "PAGINATION") qui pourtant fonctionnait avant que je ne fasse des modifications dans une autre partie de mon projet. Comme vous pouvez le voir sur la capture d'écran suivante: https://img-19.ccm2.net/AcbRLW9lzyH4kQCnO17-5OAu724=/72c28289d94048d49ee92ec9dcc95b4a/ccm-ugc/USSD_MENU.png .

function toString(){
        $objectString='';
        $items=$this->children;
        $bufferLimit=(count($items)==0)?1:$this->getBufferLimit()+1;

        echo "<pre>";
        echo $this->getBufferLimit()+1;
        echo "</pre>";

        do{
            $bufferLimit-=1;
            $objectString=$this->recurseMenu($items,$bufferLimit);
        }while(strlen($objectString>160));
        $this->index=$bufferLimit;

        /* echo "<pre>";
        echo $this->index;
        echo "</pre>"; */

        /* echo "<pre>";
        echo $objectString;
        echo "</pre>"; */
        return $objectString;
    }

    function getBufferLimit() {
        $len=count($this->children);
        $margin=$len-$this->index;

        if($margin<5)
            return $this->index+$margin;
        else
            return $this->index+5; //Permet de définir le Nombre de Menu à afficher au niveau de l'index "/ussd/receiver.php" dont le Menu est "/ussd/MyTree.php".
    }

    function recurseMenu($items,$bufferLimit) {
        $objectString="<strong>". $this->getTitle() . "</strong>" . PHP_EOL;
        $lastMenu=false;
        if(count($items)>0) {
            foreach ($items as $i => $item) {
                if ($i >= $bufferLimit){
                    break;
                }
                $num = $i + 1;
                //get node by name
                $userSessions = $_SESSION['userSessions'];
                $currUserSession = $userSessions[$this->address];
                $node = $currUserSession->getNode($item);
                $title = $node->getTitle();
                $objectString .= PHP_EOL . $num . '. ' . $title;
            }
        } else {
            $objectString=$objectString.PHP_EOL . 'NO DATA AVAILABLE, TRY AGAIN LATER';
        }
        $lastMenu=$bufferLimit==count($items);
        $objectString=$objectString . PHP_EOL . PHP_EOL . "<strong>0. Exit</strong>";
        if($this->getParent() != '0'){
            $objectString=$objectString . PHP_EOL . "<strong>#. Back</strong>";

        }
        if($lastMenu===false){
            $rem=count($items)-$this->index;
            $objectString=$objectString . PHP_EOL . "<strong>99. Next (".$rem.")</strong>";
        }
        return $objectString;
    }

Ce que je veux

Comme vous pouvez le constater sur la capture d'écran que je viens de vous envoyer, la Page suivante (7 à 12) sélectionnée en bleu sur cette capture d'écran, du Menu apparait juste en dessous de l'index alors que quand on envoie le message "99" qui actionne l'option "Next", la 1ère liste de Menu de l'index par défaut (1 à 6) devrait disparaître et laisser place à la liste de Menus suivante (7 à 12).

Ce que j'obtiens

Quand je cherche à débuguer "$this->getBufferLimit()+1" dans la fonction "toString" ci-dessus comme ceci:

echo "<pre>"; 
echo $this->getBufferLimit()+1; 
echo "</pre>";
  • La 1ère entrée de "99. Next", me retourne 6.
  • La 2ème entrée de "99. Next", me retourne 11.
  • La 3ème entrée de "99. Next", me retourne 13.

Je précise qu'il y actuellement 12 Menus en tout que je cherche à afficher par lot de 5 à chaque fois que j'actionne le "99. Next".

Comment donc modifier le "return $this->index+5" dans ma fonction "getBufferLimit" pour qu'il affiche SEULEMENT les 6 prochaines liste de Menu même quand on clique sur l'action "99. Next" au lieu de les afficher en dessous des précédents comme on le voit actuellement sur la capture d'écran ci-dessus sachant qu'elle est également utilisé dans la fonction "toString" ci-dessous ???

Merci de m'aider s'il vous plaît.

6 réponses


Je pense que la solution que tu cherches désespérément est un modulo 5 (Tu sais, le $currentIndex % 5).
Tu n'auras qu'à véfier la première fois que t'as un 0 en réponse avant de faire ta "pagination" pour ne pas rajouter de page à ce moment là

Bonjour.

Je ne vous suit pas. Il n'y a pas de variable $currentIndex dans mon code. Dans quelle fonction devrais-je la mettre et pouvez-vous me donner un exemple de code ???
Ça m'aiderait très certainement à mieux comprendre.

Etant donné que l'indice principal ne suffit pas, je vais aller un poil plus en profondeur.

Ce dont tu as besoin pour faire une pagination :

  • le nombre d'élément par page (ici, 5, nommons ça $nbrElementParPage)
  • la page actuelle (nommons ça $pageActuelle)
  • le nombre de pages au total (ceil(count($items) / 5);) - Tu prends ton nombre d'objets que tu divises par ton nombre d'éléments dans ton tableau et tu prends l'entier supérieur : 4 / 5 = 0.8, tu prends l'entier supérieur, tu as donc 1 page. 21 / 5 = 4.2 => entier supérieur 5, tu as 5 page, ...
  • le premier index à afficher ( $currentIndex = ($pageActuelle * $nbrElementParPage) - $nbrElementParPage;) : Ca te permettra de boucler sur tes éléments plus facilement

Donc, pour ton next (ta var $rem), tu auras la valeur de ta page actuelle +1 (et pour le précédent, ça sera -1). Fait attention à ne pas dépasser ton nombre de page ou à passer à une page négative

Pour l'affichage de tes éléments, tu récupères tes éléments à partir de ton premier élément à afficher, tu boucles $nbrElementParPage fois

for ($i = 0 ; $i < $nbrElementParPage; $i++) {
    $item = $items[$i + $currentIndex];
    // Ton affichage
}

Sinon, le modulo 5 t'aurais permis, assez simplement, de savoir quand tu es sur une nouvelle page.
Petit exemple :

foreach ($items as $currentIndex => $item)
{
    if ($currentIndex != 0 && $curentIndex % 5 == 0){
        // On est à une nouvelle page, on casse la boucle.
        break;
    }
}

Le soucis du foreach, est qu'il va toujours boucler à partir du premier index, d'où le for dans l'exemple précédent. Tu peux outre-passer ça en mettant un continue en fonction du premier index à afficher, je te le déconseille, surtout niveau performance

Si tu aimes vraiment le foreach (je peux comprendre), hésite pas à regarder les méthodes array_chunk (si tu veux suivre la petite partie que je t'ai donné) et array_slice (si tu veux garder ton système de prochain index à afficher)

Edit :
Et un petit exemple de array_chunk et arraySlice, à toi d'adapter pour ton code, si tu veux utiliser ça :

<?php
// J'ai mis des espaces au niveau des pages)
$arr = [1,2,3,4,5, 6,7,8,9,10, 11,12,13,14,15, 16,17,18,19];

$nbrElementParPage = 5;
$pageActuelle = 2;
$nbrPage = ceil(count($arr) / $nbrElementParPage);

// On empêche d'être à une page nagative
if ($page < 1) $page = 1;
// On empêche d'être au delà du nombre de page
if ($page > $nbrElementParPage) $page = $nbrElementParPage;

echo "Pages : ${$pageActuelle} / ${nbrPage} - Eléments par page : ${$nbrElementParPage}<br>";

echo "Chunks : <br>";
$arrChunks = array_chunk($arr, $nbrElementParPage);
foreach($arrChunks[$pageActuelle - 1] as $item) {
    echo "- ${item}<br>";
}
echo "<br>";

echo "Splice : <br>";
$arrSlice = array_slice($arr, ($pageActuelle - 1) * $nbrElementParPage, $nbrElementParPage);
foreach($arrSlice as $item) {
    echo "- ${item}<br>";
}

Bonjour et grand merci pour le temps accordé pour toutes ces explications. Mais je me demande juste dans laquelle de mes fonctions fonctions devrais-je appliquer ceci ???
Est-ce vraiment dans la fonction "getBufferLimit" car c'est elle qui se charge normalement de retourner la variable $this->index+5 (qui indique le nombre de liste de menus à afficher) pour être plus tard utilisé dans ma fonction toString().
Si oui, comment pourrais-je l'adapter en remplacement à $this->index+5 ?
Si non, comment l'adapter (array_slice dans mon cas pour paginer ou scinder l'affichage des menus par 5 à chaque entrée de la touche "99. Next") à la fonction concernée dans mes trois fonction (toString(), getBufferLimit et recurseMenu ) ci-dessus ???

En fait, je suis vraiment confus.

Mon autre inquiétude est:
Pourquoi dans le dernier code d'exemple contenant le foreach avec array_chunks et array_slice, donner 2 comme valeur à la variable $pageActuelle au lieu de la 1 (puisqu'on commence par la toute première page) ???

Aussi, le variable $page n'a pas été définie d'avance avant de la passer dans le if ($page < 1). Est-ce normal ???

Je suis vraiment confus à tout ceci.

Comment adapter le array_slice dans mon cas pour paginer ou scinder l'affichage des menus par 5 à chaque entrée de la touche "99. Next" ???
A laquelle de mes trois fonction (toString, getBufferLimit et recurseMenu) ci-dessus devrais-je l'adapter ???

Dans la fonction recurseMenu comme ceci:

function recurseMenu($items,$bufferLimit) {
        $objectString="<strong>". $this->getTitle() . "</strong>" . PHP_EOL;
        $lastMenu=false;
        if(count($items)>0) {
            $nbrElementPerPage = 5;
            $currentPage = 1;
            $nbrPage = ceil(count($items) / $nbrElementPerPage);
            // On empêche d'être à une page nagative
            if ($currentPage < 1) $currentPage = 1;
            // On empêche d'être au delà du nombre de page
            if ($currentPage > $nbrElementPerPage) $currentPage = $nbrElementPerPage;
            $itemSlice = array_slice($items, ($currentPage - 1) * $nbrElementPerPage, $nbrElementPerPage);
            foreach ($itemSlice as $i => $item) {
                if ($i >= $bufferLimit){
                    break;
                }
                $num = $i + 1;
                //get node by name
                $userSessions = $_SESSION['userSessions'];
                $currUserSession = $userSessions[$this->address];
                $node = $currUserSession->getNode($item);
                $title = $node->getTitle();
                $objectString .= PHP_EOL . $num . '. ' . $title;
            }
        } else {
            $objectString=$objectString.PHP_EOL . 'NO DATA AVAILABLE, TRY AGAIN LATER';
        }
        $lastMenu=$bufferLimit==count($items);
        $objectString=$objectString . PHP_EOL . PHP_EOL . "<strong>0. Exit</strong>";
        if($this->getParent() != '0'){
            $objectString=$objectString . PHP_EOL . "<strong>#. Back</strong>";

        }
        if($lastMenu===false){
            $rem=count($items)-$this->index;
            $objectString=$objectString . PHP_EOL . "<strong>99. Next (".$rem.")</strong>";
        }
        return $objectString;
    }

peut-être ???

Mais ça ne bouge pas à la 2ème page quand je clique sur le 99. Next. Ça reste statique sur la 1ère page. Et, j'imagine que c'est parce-que ma variable $currentPage = 1.

Comment donc dynamiser la variable $currentPage pour qu'elle évolue et change de valeur $currentPage = 2 à chaque fois quand on clique sur 99. Next et ainsi de suite ???

Veuillez me corriger si non s'il vous plaît.