PageRenderTime 61ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/fr/core-libraries/components/pagination.rst

https://gitlab.com/albertkeba/docs
ReStructuredText | 376 lines | 296 code | 80 blank | 0 comment | 0 complexity | bfebaeb17b9f30831e5105ad1478ac4f MD5 | raw file
  1. Pagination
  2. ##########
  3. .. php:class:: PaginatorComponent(ComponentCollection $collection, array $settings = array())
  4. Un des principaux obstacles à la création d'une application flexible et
  5. ergonomique est le design et une interface utilisateur intuitive.
  6. De nombreuses applications ont tendance à augmenter en taille et en complexité
  7. rapidement, et les designers ainsi que les programmeurs trouvent même qu'ils
  8. sont incapables de faire face a l'affichage des centaines ou des milliers
  9. d'enregistrements. Réécrire prend du temps, et les performances et la
  10. satisfaction des utilisateurs peut en pâtir.
  11. Afficher un nombre raisonnable d'enregistrements par page a toujours été
  12. une partie critique dans toutes les applications et cause régulièrement
  13. de nombreux maux de tête aux développeurs. CakePHP allège le fardeau
  14. des développeurs en fournissant un moyen rapide et facile de paginer
  15. les données.
  16. La pagination dans CakePHP est offerte par un Component dans le controller,
  17. pour rendre la création des requêtes de pagination plus facile.
  18. Dans la Vue, :php:class:`PaginatorHelper` est utilisé pour rendre la
  19. génération de la pagination, des liens et des boutons simples.
  20. Paramétrage des requêtes
  21. ========================
  22. Dans le controller, nous commençons par définir les conditions de la requête de
  23. pagination qui seront utilisées par défaut dans la variable ``$paginate`` du
  24. controller.
  25. Ces conditions, vont servir de base à vos requêtes de pagination. Elles sont
  26. complétées par le tri, la direction, la limitation et les paramètres de page
  27. passés depuis l'URL. Ici, il est important de noter que l'ordre des clés
  28. doit être défini dans une structure en tableau comme ci-dessous::
  29. class PostsController extends AppController {
  30. public $components = array('Paginator');
  31. public $paginate = array(
  32. 'limit' => 25,
  33. 'order' => array(
  34. 'Post.title' => 'asc'
  35. )
  36. );
  37. }
  38. Vous pouvez aussi inclure d'autres options :php:meth:`~Model::find()`,
  39. comme ``fields``::
  40. class PostsController extends AppController {
  41. public $components = array('Paginator');
  42. public $paginate = array(
  43. 'fields' => array('Post.id', 'Post.created'),
  44. 'limit' => 25,
  45. 'order' => array(
  46. 'Post.title' => 'asc'
  47. )
  48. );
  49. }
  50. D'autres clés qui peuvent être introduites dans le tableau ``$paginate``
  51. sont similaires aux paramètres de la méthode ``Model->find('all')``,
  52. qui sont: ``conditions``, ``fields``, ``order``, ``limit``, ``page``,
  53. ``contain``,``joins``, et ``recursive``. En plus des touches mentionnées
  54. ci dessus, chacune des clés peut aussi être passé à la méthode find du
  55. model. Ça devient alors très simple d'utiliser les component comme
  56. :php:class:`ContainableBehavior` avec la pagination::
  57. class RecipesController extends AppController {
  58. public $components = array('Paginator');
  59. public $paginate = array(
  60. 'limit' => 25,
  61. 'contain' => array('Article')
  62. );
  63. }
  64. En plus de définir des valeurs de pagination générales, vous pouvez définir
  65. plus d'un jeu de pagination par défaut dans votre controller, vous avez juste
  66. à nommer les clés du tableau d'après le model que vous souhaitez configurer::
  67. class PostsController extends AppController {
  68. public $paginate = array(
  69. 'Post' => array (...),
  70. 'Author' => array (...)
  71. );
  72. }
  73. Les valeurs des clés ``Post`` et ``Author`` pourraient contenir toutes
  74. les propriétés qu'un model/clé sans ``$paginate`` pourraient contenir.
  75. Une fois que la variable ``$paginate`` à été définie, nous pouvons
  76. utiliser la méthode ``paginate()`` du :php:class:`PaginatorComponent` de
  77. l'action de notre controller. Ceci retournera les résultats du ``find()``
  78. depuis le model. Il définit également quelques paramètres de pagination
  79. supplémentaires, qui sont ajoutés à l'objet request. L'information
  80. supplémentaire est définie dans ``$this->request->params['paging']``, et est
  81. utilisée par :php:class:`PaginatorHelper` pour la création des liens.
  82. :php:meth:`PaginatorComponent::paginate()` ajoute aussi
  83. :php:class:`PaginatorHelper` à la liste des helpers dans votre controller, si
  84. il n'a pas déjà été ajouté::
  85. public function list_recipes() {
  86. $this->Paginator->settings = $this->paginate;
  87. // similaire à un findAll(), mais récupère les résultats paginés
  88. $data = $this->Paginator->paginate('Recipe');
  89. $this->set('data', $data);
  90. }
  91. Vous pouvez filtrer les enregistrements en passant des conditions
  92. en second paramètre à la fonction ``paginate()``::
  93. $data = $this->Paginator->paginate(
  94. 'Recipe',
  95. array('Recipe.title LIKE' => 'a%')
  96. );
  97. Ou vous pouvez aussi définir des ``conditions`` et d'autres tableaux de
  98. configuration de pagination à l'intérieur de votre action::
  99. public function list_recipes() {
  100. $this->Paginator->settings = array(
  101. 'conditions' => array('Recipe.title LIKE' => 'a%'),
  102. 'limit' => 10
  103. );
  104. $data = $this->Paginator->paginate('Recipe');
  105. $this->set(compact('data'));
  106. }
  107. Personnalisation des requêtes de pagination
  108. ===========================================
  109. Si vous n'êtes pas prêts à utiliser les options standards du find pour créer
  110. la requête d'affichage de vos données, il y a quelques options.
  111. Vous pouvez utiliser :ref:`custom find type <model-custom-find>`.
  112. Vous pouvez aussi implémenter les méthodes ``paginate()`` et ``paginateCount()``
  113. sur votre model, ou les inclure dans un behavior attaché à votre model.
  114. Les behaviors qui implémentent ``paginate`` et/ou ``paginateCount`` devraient
  115. implémenter les signatures de méthode définies ci-dessous avec le premier
  116. paramètre normal supplémentaire de ``$model``::
  117. // paginate et paginateCount implémentés dans le behavior.
  118. public function paginate(Model $model, $conditions, $fields, $order, $limit,
  119. $page = 1, $recursive = null, $extra = array()) {
  120. // contenu de la méthode
  121. }
  122. public function paginateCount(Model $model, $conditions = null,
  123. $recursive = 0, $extra = array()) {
  124. // corps (body) de la méthode
  125. }
  126. C'est rare d'avoir besoin d'implémenter paginate() et paginateCount(). vous
  127. devriez vous assurer que vous ne pouvez pas atteindre votre but avec les
  128. méthodes du noyau du model, ou avec un finder personnalisé. Pour paginer avec
  129. un type de find personnalisé, vous devez définir le ``0``'ème element, ou la
  130. clé ``findType`` depuis la version 2.3::
  131. public $paginate = array(
  132. 'popular'
  133. );
  134. Puisque le 0ème index est difficile à gérer, dans 2.3 l'option ``findType`` a
  135. été ajoutée::
  136. public $paginate = array(
  137. 'findType' => 'popular'
  138. );
  139. La méthode ``paginate()`` devrait implémenter les signatures de méthode
  140. suivantes. Pour utiliser vos propres méthodes/logiques, surchargez les
  141. dans le model dans lequel vous voulez récupérer des données::
  142. /**
  143. * Surcharge de la méthode paginate - groupée par week, away_team_id et home_team_id
  144. */
  145. public function paginate($conditions, $fields, $order, $limit, $page = 1,
  146. $recursive = null, $extra = array()) {
  147. $recursive = -1;
  148. $group = $fields = array('week', 'away_team_id', 'home_team_id');
  149. return $this->find('all', compact('conditions', 'fields', 'order',
  150. 'limit', 'page', 'recursive', 'group'));
  151. }
  152. Vous aurez aussi besoin de surcharger le ``paginateCount()`` du noyau,
  153. cette méthode s'attend aux mêmes arguments que ``Model::find('count')``.
  154. L'exemple ci-dessous utilise quelques fonctionnalités Postgres spécifiques,
  155. Veuillez ajuster en conséquence en fonction de la base de données que vous
  156. utilisez::
  157. /**
  158. * Surcharge de la méthode paginateCount
  159. */
  160. public function paginateCount($conditions = null, $recursive = 0,
  161. $extra = array()) {
  162. $sql = "SELECT
  163. DISTINCT ON(
  164. week, home_team_id, away_team_id
  165. )
  166. week, home_team_id, away_team_id
  167. FROM
  168. games";
  169. $this->recursive = $recursive;
  170. $results = $this->query($sql);
  171. return count($results);
  172. }
  173. Le lecteur attentif aura noté que la méthode paginate que nous avons
  174. définie n'était pas réellement nécessaire - Tout ce que vous avez à
  175. faire est d'ajouter le mot clé dans la variable de classe
  176. ``$paginate`` du controller::
  177. /**
  178. * Ajout d'une clause GROUP BY
  179. */
  180. public $paginate = array(
  181. 'MyModel' => array(
  182. 'limit' => 20,
  183. 'order' => array('week' => 'desc'),
  184. 'group' => array('week', 'home_team_id', 'away_team_id')
  185. )
  186. );
  187. /**
  188. * Ou à la volée depuis l'intérieur de l'action
  189. */
  190. public function index() {
  191. $this->Paginator->settings = array(
  192. 'MyModel' => array(
  193. 'limit' => 20,
  194. 'order' => array('week' => 'desc'),
  195. 'group' => array('week', 'home_team_id', 'away_team_id')
  196. )
  197. );
  198. }
  199. Dans CakePHP 2.0, vous n'avez plus besoin d'implémenter ``paginateCount()``
  200. quand vous utilisez des clauses de groupe. Le ``find('count')`` du groupe
  201. comptera correctement le nombre total de lignes.
  202. Contrôle du champ à utiliser pour ordonner
  203. ==========================================
  204. Par défaut le classement peut être effectué pour n'importe quelle colonne dans
  205. un model. C'est parfois indésirable comme permettre aux utilisateurs de trier
  206. des colonnes non indexées, ou des champs virtuels ce qui peut être coûteux en
  207. temps de calculs. Vous pouvez utiliser le 3ème paramètre de
  208. ``PaginatorComponent::paginate()`` pour restreindre les colonnes à trier
  209. en faisant ceci::
  210. $this->Paginator->paginate('Post', array(), array('title', 'slug'));
  211. Ceci permettrait le tri uniquement sur les colonnes title et slug.
  212. Un utilisateur qui paramètre le tri à d'autres valeurs sera ignoré.
  213. Limitation du nombre maximum de lignes qui peuvent être recherchées
  214. ===================================================================
  215. Le nombre de résultats qui sont retournés à l'utilisateur est représenté
  216. par le paramètre ``limit``. Il est généralement indésirable de permettre
  217. à l'utilisateur de retourner toutes les lignes dans un ensemble paginé.
  218. Par défaut CAKEPHP limite le nombre de lignes retournées à 100. Si cette
  219. valeur par défaut n'est pas appropriée pour votre application, vous pouvez
  220. l'ajuster dans une partie des options de pagination::
  221. public $paginate = array(
  222. // d'autre clés ici.
  223. 'maxLimit' => 10
  224. );
  225. Si le paramètre de limitation de la requête est supérieur à cette valeur,
  226. il sera réduit à la valeur de ``maxLimit``.
  227. .. _pagination-with-get:
  228. Pagination avec des paramètres GET
  229. ==================================
  230. Dans les versions précédentes de CAKEPHP vous ne pouviez générer des liens
  231. de pagination qu'en utilisant des paramètres nommés. Mais si les pages étaient
  232. recherchées avec des paramètres GET elle continueraient à fonctionner.
  233. Pour la version 2.0, nous avons décidés de rendre la façon de générer les
  234. paramètres de pagination plus contrôlable et plus cohérente. Vous pouvez
  235. choisir d'utiliser une chaîne de requête ou bien des paramètre nommés dans le
  236. component. Les requêtes entrantes devront accepter le type choisi, et
  237. :php:class:`PaginatorHelper` générera les liens avec les paramètres choisis::
  238. public $paginate = array(
  239. 'paramType' => 'querystring'
  240. );
  241. Ce qui est au-dessus permet à un paramètre de recherche sous forme de chaîne de
  242. caractères, d'être parsé et d'être généré. Vous pouvez aussi modifier les
  243. propriétés de ``$settings`` du Component Paginator (PaginatorComponent)::
  244. $this->Paginator->settings['paramType'] = 'querystring';
  245. Par défaut tous les paramètres de pagination typiques seront convertis en
  246. arguments GET.
  247. .. note::
  248. Vous pouvez rentrer dans une situation assigner une valeur dans une
  249. propriété inexistante retournera des erreurs::
  250. $this->paginate['limit'] = 10;
  251. Retournera l'erreur "Notice: Indirect modification of overloaded property
  252. $paginate has no effect." ("Notice: Une modification indirect d'une surcharge de
  253. la propriété $paginate n'a aucun effet."). En assignant une valeur initiale à la
  254. propriété, cela résout le problème::
  255. $this->paginate = array();
  256. $this->paginate['limit'] = 10;
  257. //ou
  258. $this->paginate = array('limit' => 10);
  259. Ou juste en déclarant la propriété dans la classe du controller ::
  260. class PostsController {
  261. public $paginate = array();
  262. }
  263. Ou en utilisant ``$this->Paginator->setting = array('limit' => 10);``
  264. Assurez-vous d'avoir ajouté le component Paginator dans votre tableau
  265. $components si vous voulez modifier la propriété ``$settings`` du
  266. Component Paginator.
  267. L'une ou l'autre de ces approches résoudra les erreurs rencontrés.
  268. Requêtes en dehors des clous
  269. ============================
  270. Depuis la version 2.3, PaginatorComponent va lancer une `NotFoundException`
  271. quand il essaiera d'accéder à une page qui n'existe pas, par ex le nombre
  272. de la page requêtée est plus grand que le total du nombre de pages.
  273. Ainsi vous pouvez soit laisser la page d'erreur normal être rendu ou bien
  274. vous pouvez utiliser un block try catch et renvoyer vers l'action appropriée
  275. quand une exception `NotFoundException` est attrapée::
  276. public function index() {
  277. try {
  278. $this->Paginator->paginate();
  279. } catch (NotFoundException $e) {
  280. //Faire quelque chose ici comme rediriger à la première ou dernière page.
  281. //$this->request->params['paging'] va vous donner l'info nécessaire.
  282. }
  283. }
  284. Pagination AJAX
  285. ===============
  286. C'est très simple d'incorporer les fonctionnalités AJAX dans la pagination.
  287. en utilisant :php:class:`JsHelper` et :php:class:`RequestHandlerComponent`
  288. vous pouvez facilement ajouter des paginations AJAX à votre application.
  289. Voir :ref:`ajax-pagination` pour plus d'information.
  290. Pagination dans la vue
  291. ======================
  292. Regardez la documentation du :php:class:`PaginatorHelper` pour voir comment
  293. créer des liens de navigation paginés.
  294. .. meta::
  295. :title lang=fr: Pagination
  296. :keywords lang=fr: order array,query conditions,php class,web applications,headaches,obstacles,complexity,programmers,parameters,paginate,designers,cakephp,satisfaction,developers