Page 1 sur 1

Un bloc de pagination classe en PHP

Posté : 19 févr. 2008, 19:32
par Gofromiel
Aujourd'hui je vous propose une petite classe très pratique et très adaptable pour générer des blocs de pagination en HTML.
class WdPager
{
    public $add_arrows = true;
    public $reverse_arrows = false;
    public $separator = '<span class="separator">,</span>';
    public $gap = '<span class="gap"> ... </span>';
    public $base_url = '?page=';
    
    private $count;
    private $limit;
    private $on_page;
    
    public function __construct($count, $limit=5, $on_page=0)
    {
        $this->count = $count;
        $this->limit = $limit;
        $this->on_page = $on_page;
    }

    public function getURL($n)
    {
        return $this->base_url . $n;
    }
    
    public function getLink($n, $label=NULL, $class=NULL)
    {
        $rc = '<a href="' . $this->getURL($n) . '"';
        
        if ($class)
        {
            $rc .= ' class="' . $class . '"';
        }
        
        $rc .= '>';
        
        $rc .= $label ? $label : ($n + 1);
        
        $rc .= '</a>';
        
        return $rc;
    }
    
    public function getPosition($n)
    {
        return '<strong>' . $n . '</strong>';
    }

    public function __toString()
    {
        $pages = ceil($this->count / $this->limit);
    
        if ($pages == 1)
        {
            return;
        }

        $on_page = $this->on_page + 1;
    
        $rc = NULL;
        
        if ($pages > 10)
        {
            $init_page_max = min($pages, 3);
    
            for ($i = 1 ; $i < $init_page_max + 1 ; $i++)
            {
                if ($i == $on_page)
                {
                    $rc .= $this->getPosition($i);
                }
                else
                {
                    $rc .= $this->getLink($i - 1);
                }
    
                if ($i < $init_page_max)
                {
                    $rc .= $this->separator;
                }
            }
    
            if ($pages > 3)
            {
                if (($on_page > 1) && ($on_page < $pages))
                {
                    $rc .= ($on_page > 5) ? $this->gap : $this->separator;
    
                    $init_page_min = ($on_page > 4) ? $on_page : 5;
                    $init_page_max = ($on_page < $pages - 4) ? $on_page : $pages - 4;
    
                    for ($i = $init_page_min - 1; $i < $init_page_max + 2; $i++)
                    {
                        $rc .= ($i == $on_page) ? $this->getPosition($i) : $this->getLink($i - 1);

                        if ($i < $init_page_max + 1)
                        {
                            $rc .= $this->separator;
                        }
                    }
    
                    $rc .= ($on_page < $pages - 4) ? $this->gap : $this->separator;
                }
                else
                {
                    $rc .= $this->gap;
                }
    
                for($i = $pages - 2 ; $i < $pages + 1 ; $i++)
                {
                    $rc .= ($i == $on_page) ? $this->getPosition($i) : $this->getLink($i - 1);
                    
                    if ($i < $pages)
                    {
                        $rc .= $this->separator;
                    }
                }
            }
        }
        else
        {
            for ($i = 1 ; $i < $pages + 1 ; $i++)
            {
                $rc .= ($i == $on_page) ? $this->getPosition($i) : $this->getLink($i - 1);
                
                if ($i < $pages)
                {
                    $rc .= $this->separator;
                }
            }
        }
    
        if ($this->add_arrows)
        {
            #
            # add next (>) link
            #
        
            if ($this->reverse_arrows ? ($on_page > 1) : ($on_page < $pages))
            {
                $rc .= $this->getLink($this->reverse_arrows ? $on_page - 2 : $on_page, '>', 'next');
            }
            
            #
            # add prev (<) link
            #
        
            if ($this->reverse_arrows ? ($on_page < $pages) : ($on_page > 1))
            {
                $rc = $this->getLink($this->reverse_arrows ? $on_page : $on_page - 2, '<', 'previous') . $rc;
            }
        }
    
        return $rc;
    }
}
Exemple

Imaginons un blog avec 30 messages. Ce serait très pénible pour le visiteur que tous les messages soient affichés sur une même page. On décide donc de n'afficher que 5 messages par page et on va utiliser la classe WdPager pour nous créer notre bloc de pagination :
$pager = new WdPager(30, 5);

echo $pager
En savoir plus...

Posté : 20 févr. 2008, 11:01
par agité
Merci, pourrais tu poster un exemple du rendu ?

Posté : 20 févr. 2008, 13:10
par Cyrano
Ce qui serait appréciable aussi, c'est que le code soit commenté. Je l'ai toujours systématiquement fait dans les tutos que j'ai pu poster, mais visiblement l'exemple n'est pas suivi.

Je ne sais pas pour les autres, mais quand je vois ce type de code sans la moindre ligne de commentaire, même si le code est proprement indenté comme ici, je ne m'attarde pas : devoir me farcir de lire le code dans les détails pour en comprendre le fonctionnement va me prendre quasiment autant de temps que de le ré-écrire moi-même. Et même pour toi, si tu veux y revenir dans six mois ou dans deux ans, il te faudra un certain temps de reprise en main avant d'y ajouter ou modifier la moindre ligne de code. :-k

cf ma signature ;)

Posté : 21 févr. 2008, 12:26
par Hywan
+10.

Quand Cyrano m'a dit de commenter mon code, je lui ai dis : « tu vois je le fais », et il m'a dit : « une documentation qui explique le fonctionnement etc., et pas simplement une description de la méthode (l'arité, son nom et son retour). ». Je me disais : « dans 6 mois, je reprends le code, pas de soucis, je le connais pas coeur ». En effet, je le connais par coeur, et quand je le lis, je n'ai aucun mal à le comprendre, mais pour retrouver toutes les subtilités que j'y avais placé, ou ne serait-ce que le fonctionnement général, je suis obligé d'aller jeter un oeil dans mon laboratoire où il y a tous mes tests pour me rappeler. Et imaginons quelqu'un qui n'ait pas écrit le code, c'est encore pire.
Moralité, ne pas prendre Cyrano pour un c** quand il rabâche qu'il faut commenter le code. Et même si on commente en 2 lignes, ça ne suffit pas. Il ne faut pas écrire des romans, on s'entend (euh ... on se lit ;-)), mais expliquer son fonctionnement général, et après son utilisation de manière précise et complète. C'est un réflexe à prendre, et tout le monde sera content.
Autre moralité, ne pas me prendre pour un c** quand je dis d'écouter Cyrano :lol:.

Posté : 28 févr. 2008, 00:45
par Gofromiel
Désolé pour le manque de commentaires, c'est vrai que c'est une vilaine habitude. J'avoue que quand j'écris des petites classes toutes simples en un quart d'heure, je n'est pas ce réflexe. Par contre je donne des exemples simples et pratiques sur mon blog.

Je promets de faire attention la prochaine fois :oops:

Posté : 28 févr. 2008, 03:53
par Nagol
personnellement je préfère un code non commenté. si le code est propre et écrit logiquement la lecture se fait comme du français, en revanche mettre des commentaires dans du bon code en gêne la lecture (du moins pour moi).

Posté : 28 févr. 2008, 07:30
par Cyrano
personnellement je préfère un code non commenté. si le code est propre et écrit logiquement la lecture se fait comme du français, en revanche mettre des commentaires dans du bon code en gêne la lecture (du moins pour moi).
C'est peut-être une question de goûts, mais je ne suis pas d'accord, d'autant moins qu'on peut utiliser un éditeur permettant de "replier" les commentaires.

Posté : 28 févr. 2008, 18:22
par AB
ça part d'un bon sentiment.

J'ai été voir sur ton blog :

Pour ceux qui cherchent à apprendre ou à se perfectionner, le manque de commentaires leur fera cruellement défaut.

Pour ceux qui sont un plus expérimentés, je rejoindrai Cyrano : "devoir me farcir de lire le code dans les détails pour en comprendre le fonctionnement va me prendre quasiment autant de temps que de le ré-écrire moi-même".

Et si l'on considère que c'est un bloc de code prêt à l'emploi, la mise en oeuvre n'est pas très compréhensible pour un débutant car il manque un exemple concret d'application.

Un petit effort dans un sens ou dans l'autre (ou dans les deux) et ton code pourra être utile à beaucoup plus de monde :wink:

Posté : 28 févr. 2008, 18:53
par Gofromiel
Ben si cette classe vous intéresse et que vous avez des questions, je suis votre serviteur. :love:

Posté : 19 avr. 2008, 21:52
par flotix
Sympatique class au niveau de la customisation pour le rewrite merci!
Et aussi poue ceux dont le debut d'enregistrement commence à 0 et non pas à 1 comme 90% des class de pagination! :lol:

Posté : 19 avr. 2008, 23:43
par Hywan
Mais toujours pas de commentaire :roll:.