Bonjour,
Je voudrais faire une pagination intelligente, c'est à dire exactement comme le site de Grafikart
Comme ceci :
Mon code actuel affiche la pagination classique (toute les pages)
Mon contrôleur :
$res = $this->Post->query("SELECT COUNT(id) AS nbPosts FROM posts");
$nbPosts = intval($res[0]->nbPosts);
$perPage = 1;
$nbPages = ceil($nbPosts / $perPage);
if (isset($_GET["p"]) && intval($_GET["p"]) !== 0 && intval($_GET["p"]) <= $nbPages) {
$p = $_GET["p"];
} else {
if ($_SERVER["REQUEST_URI"] !== $this->getRoute("admin.post.index")) {
header("Location: " . $this->getRoute("admin.post.index"));
}
$p = 1;
}
$posts = $this->Post->query("SELECT * FROM posts ORDER BY date DESC LIMIT ".($p-1)*$perPage.",$perPage");
Ma vue :
<?php if ($nbPosts > $perPage) : ?>
<div class="pagination" id="pagination">
<?php for ($i=1; $i < $nbPages+1; $i++) : ?>
<?php if ($i === 1) : ?>
<a href="<?= $this->getRoute("admin.post.index"); ?>"><?= $i; ?></a>
<?php else : ?>
<a href="<?= $this->getRoute("admin.post.index"); ?>?p=<?= $i; ?>"><?= $i; ?></a>
<?php endif; ?>
<?php endfor; ?>
</div>
<?php endif; ?>
Le résultat :
Ton script fonctionne correctement, je l'ai adapté à mon application, cepandant il y a beaucoup de conditions ^^
Ton script manquait quelques vérifications rien de méchant.
S'il y a des choses à changer pour l'optimisation de mon code, dites le moi merci.
Voici mon code :
Contrôleur
public function index() {
// Variables pour la pagination
$res = $this->Post->query("SELECT COUNT(*) AS nbPosts FROM posts", "", true);
$nbPosts = intval($res->nbPosts);
$itemsPerPage = 1;
$nbPages = intval(ceil($nbPosts / $itemsPerPage));
$nbLinks = 9;
// Récupération du numéro de la page courante
if (isset($_GET["p"]) && intval($_GET["p"]) > 0 && intval($_GET["p"]) <= $nbPages) {
$currentPage = $_GET["p"];
} else {
if ($_SERVER["REQUEST_URI"] !== $this->getRoute("admin.post.index")) {
header("Location: ".$this->getRoute("admin.post.index"));
}
$currentPage = 1;
}
// Traitement de la pagination
$halfTotalLinks = floor($nbLinks / 2);
$start = $currentPage - $halfTotalLinks;
$end = $currentPage + $halfTotalLinks;
// Variables renvoyées à la vue
$name = "posts";
$posts = $this->Post->query("SELECT * FROM posts ORDER BY date DESC LIMIT ".($currentPage - 1) * $itemsPerPage.",".$itemsPerPage);
$category = $this->Category;
$pagination = [
"nbPosts" => $nbPosts,
"itemsPerPage" => $itemsPerPage,
"lastPage" => $nbPages,
"currentPage" => $currentPage,
"nbLinks" => $nbLinks,
"start" => $start,
"end" => $end,
"halfTotalLinks" => $halfTotalLinks
];
$this->setTitle("Articles");
$this->render("admin/posts/index", compact("name", "posts", "category", "pagination"), "admin");
}
Vue
<?php if ($pagination["nbPosts"] > $pagination["itemsPerPage"]) : ?>
<ul class="pagination">
<li>
<?php if ($pagination["currentPage"] === 1) : ?>
<a href="<?= $this->getRoute("admin.post.index"); ?>" class="active">1</a>
<?php else: ?>
<a href="<?= $this->getRoute("admin.post.index"); ?>">1</a>
<?php endif; ?>
</li>
<?php if ($pagination["currentPage"] > $pagination["halfTotalLinks"] + 1) : ?>
<li><span class="more">...</span></li>
<?php endif; ?>
<?php for ($i = 1; $i <= $pagination["lastPage"]; $i++) : ?>
<?php if ($pagination["start"] < $i && $i < $pagination["end"]) : ?>
<?php if ($i !== 1 && $i !== $pagination["lastPage"]) : ?>
<li>
<?php if ($pagination["currentPage"] === $i) : ?>
<a href="<?= $this->getRoute("admin.post.index"); ?>?p=<?= $i; ?>" class="active"><?=$i?></a>
<?php else: ?>
<a href="<?= $this->getRoute("admin.post.index"); ?>?p=<?= $i; ?>"><?=$i?></a>
<?php endif; ?>
</li>
<?php endif; ?>
<?php endif; ?>
<?php endfor; ?>
<?php if ($pagination["currentPage"] < $pagination["lastPage"] - ($pagination["halfTotalLinks"] + 1)) : ?>
<li><span class="more">...</span></li>
<?php endif; ?>
<li>
<?php if ($pagination["currentPage"] === $pagination["lastPage"]) : ?>
<a href="<?= $this->getRoute("admin.post.index"); ?>?p=<?= $pagination["lastPage"]; ?>" class="active"><?= $pagination["lastPage"]; ?></a>
<?php else: ?>
<a href="<?= $this->getRoute("admin.post.index"); ?>?p=<?= $pagination["lastPage"]; ?>"><?= $pagination["lastPage"]; ?></a>
<?php endif; ?>
</li>
</ul>
<?php endif; ?>
Il te faut filtrer ça dans la boucle qui génère ta pagination, en n'affichant que les 3 premières et la dernière (par exemple).
<?php if ($nbPosts > $perPage) : ?>
<div class="pagination" id="pagination">
<?php for ($i=1; $i < 4; $i++) : ?>
<?php if ($i === 1) : ?>
<a href="<?= $this->getRoute("admin.post.index"); ?>"><?= $i; ?></a>
<?php else : ?>
<a href="<?= $this->getRoute("admin.post.index"); ?>?p=<?= $i; ?>"><?= $i; ?></a>
<?php endif; ?>
<?php endfor; ?>
<div class="separator">...</div>
<a href="<?= $this->getRoute("admin.post.index"); ?>?p=<?= $nbPosts ; ?>"><?= $nbPosts ; ?></a>
</div>
<?php endif; ?>
C'est la version "sale", je te laisse refactorer ;)
http://stackoverflow.com/questions/28240777/custom-pagination-view-in-laravel-5 regarde la deuxième partie de la première réponse. Certes c'est du blade, mais le blade n'est pas trop compliqué
Edit : finalement, essaye ça :
<?php
// config
$link_limit = 7; // maximum number of links (a little bit inaccurate, but will be ok for now)
$last_page = X;// ton calcul doit trouver la dernière page
$current_page = X;// ton calcul doit trouver la page courrante
if ($last_page > 1):
?>
<ul class="pagination">
<!-- DÉBUT : lien pour la première page -->
<li class="<?= ($current_page == 1) ? ' disabled' : '' ?>">
<a href="/ton/lien/pour/la/premiere/page">First</a>
</li>
<!-- FIN : lien pour la dernière page-->
<!-- DÉBUT : pagination 'intelligente' -->
<?php
for ($i = 1; $i <= $last_page; $i++):
$half_total_links = floor($link_limit / 2);
$from = $current_page - $half_total_links;
$to = $current_page + $half_total_links;
if ($current_page < $half_total_links) {
$to += $half_total_links - $current_page;
}
if ($last_page - $current_page < $half_total_links) {
$from -= $half_total_links - ($last_page - $current_page) - 1;
}
if ($from < $i && $i < $to):
?>
<li class="<?= ($current_page == $i) ? ' active' : '' ?>">
<a href="/ton/lien/pour/la/$i eme/page"><?=$i?></a>
</li>
<?php
endif;
endfor;
?>
<!-- FIN : pagination 'intelligente' -->
<!-- DÉBUT : lien pour la dernière page -->
<li class="<?= ($current_page == $last_page) ? ' disabled' : '' ?>">
<a href="/ton/lien/pour/la/dernière/page">Last</a>
</li>
<!-- FIN : lien pour la dernière page -->
</ul>
<?php
endif;
?>
Je t'ai déjà adapté le code depuis du blade, à toi de le faire pour qu'il corresponde à ton code ;)
Pour compter le nombre de résultats, c'est quoi la solution la plus rapide ?
Une requête SQL :
$res = $this->Post->query("SELECT COUNT(*) AS nbPosts FROM posts", "", true);
$nbPosts = intval($res->nbPosts);
Ou la fonction count de PHP
$nbPosts = count($this->Post->query("SELECT * FROM posts"));
Autre cas :
// Je fait ma requête SQL pour afficher mes articles
$posts = $this->Post->query("SELECT * FROM posts ORDER BY date DESC";
// Pour compter les résultats une 2ème requête SQL ou la fonction count
count($posts);
je dirais le count en SQL, surtout avec un grand nombre de données, avec un petit nombre c'est moins significatif je pense
Mis à part de remplacer ça :
if (isset($_GET["p"]) && intval($_GET["p"]) !== 0 && intval($_GET["p"]) <= $nbPages) {
$p = $_GET["p"];
} else {
if ($_SERVER["REQUEST_URI"] !== $this->getRoute("admin.post.index")) {
header("Location: ".$this->getRoute("admin.post.index"));
}
$p = 1;
}
$currentPage = intval($p);
par ça :
if (isset($_GET["p"]) && intval($_GET["p"]) > 0 && intval($_GET["p"]) <= $nbPages) {
$currentPage = intval($_GET["p"]);
} else {
if ($_SERVER["REQUEST_URI"] !== $this->getRoute("admin.post.index")) {
header("Location: ".$this->getRoute("admin.post.index"));
}
$currentPage = 1;
}
Je pense pas
Oui j'ai zaaper cette variable ^^, j'ai fait la modification
Merci pour vos réponses et votre réactivité