*/ ?>
Création d'une liste dynamique

Dans ce tutoriel, vous allez apprendre à créer une liste dynamique.

Contexte du tutoriel:

Les articles que vous commercialisez sont stockés dans une base et sont classés par catégories.
L'application doit présenter une liste des catégories.
Lorsque l'utilisateur sélectionne une entrée de cette liste, l'application doit afficher une liste des articles de cette catégorie.

Prérequis

Pour faire fonctionner l'exemple de ce tutoriel, vous devez disposer d'un serveur web, du langage php et d'une base de données MySQL. Des compétences minimales en php et sql sont nécessaires.

Moyennant quelques adaptations, vous pouvez tester cet exemple avec une autre base et/ou un autre langage: la seule contrainte est de produire des documents XML conformes aux spécifications AppMobile.

Si vous n'avez pas de serveur à disposition, des offres d'essai gratuites existent chez de nombreux hébergeurs - une simple recherche du type "hébergement gratuit mysql php" sur votre moteur de recherche préféré suffira à vous apporter une solution.

Premier niveau: liste d'articles

Les données

Toutes les tables des tutoriels de la doc AppMobile seront préfixées "amdoc_" pour ne pas risquer d'écraser des tables existantes de votre base.

Les catégories sont stockées dans une table "amdoc_categories" contenant les champs "name", "pic" et "id" (clé primaire).

Les articles sont stockés dans une table "amdoc_products" contenant les champs "name", "id" (clé primaire), "price", "description", "pic" et "id_cat" (pointe la catégorie de l'article).

Le code mysql ci-dessous vous permettra de créer rapidement un peu de contenu pour vos essais sur ce tutoriel.

Tables des articles et des catégories d'articles :

-- -------- Structure de la table `amdoc_categories` ----------
CREATE TABLE IF NOT EXISTS `amdoc_categories` (
  `id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(30) NOT NULL,
  `pic` varchar(30) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 ;

-- -------- Contenu de la table `amdoc_categories` ----------
INSERT INTO `amdoc_categories` (`id`, `name`, `pic`) VALUES
(1, 'Pizzas', 'pizza6.jpg'),
(2, 'Sandwichs', 'Sandwichs.jpg'),
(3, 'Salades', 'salade1.jpg'),
(4, 'Flammekueche', 'flam2.jpg'),
(5, 'Boissons', 'orangina.jpg'),
(6, 'Desserts', 'dessert4.jpg');

-- -------- Structure de la table `amdoc_products` ----------
CREATE TABLE IF NOT EXISTS `amdoc_products` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) NOT NULL,
  `descr` varchar(200) NOT NULL,
  `price` float NOT NULL DEFAULT '0',
  `pic` varchar(30) NOT NULL,
  `id_cat` tinyint(3) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;

-- -------- Structure de la table `products` ----------
INSERT INTO `amdoc_products` (`id`, `name`, `descr`, `price`, `pic`, `id_cat`) VALUES
(1, 'Louisiane', 'sauce tomate, mozzarella, champignons frais, oignons frais, poivrons verts et double poulet', 9.8, 'pizza1.jpg', 1),
(2, 'Tartiflette', 'creme fraîche, mozzarella, pommes de terre, lardons et Saint-Nectaire', 11.5, 'pizza2.jpg', 1),
(3, 'Quatre saisons', 'sauce tomate, mozzarella, champignons frais, oignons frais, poivrons verts et tomates fraiches', 8.9, 'pizza3.jpg', 1),
(4, 'Quatre Fromages', 'sauce tomate, mozzarella, cantal, fourme d''Ambert AOC, fromage de chevre', 12.3, 'pizza4.jpg', 1),
(5, 'Montova', 'Tomates, mozzarella, salade, pesto, oignons', 4.9, 'wichpizza1.jpg', 2),
(6, 'Como', 'Poulet, curry, salade', 4.9, 'wichpizza2.jpg', 2),
(7, 'Trento', 'Jambon, fromage, salade, pesto', 4.9, 'wichpizza3.jpg', 2),
(8, 'Cesar', 'Poulet, salade, croûtons, olives, tomate cerise', 5.5, 'salade1.jpg', 3),
(9, 'Rimini', 'Mortadelle, salade, maïs, oignons, olives, champignons', 5.5, 'salade2.jpg', 3),
(10, 'Padova', 'Tomate, mozzarella, salade, oignons, olives', 5.5, 'salade3.jpg', 3),
(11, 'Gratinée', 'Crème fraîche, oignons, fromage', 6.5, 'flam4.jpg', 4),
(12, 'Normale', 'Crème fraîche, oignons', 6.1, 'flam5.jpg', 4),
(13, 'Orangina', 'Orangina, boîte 33 cl.', 1.7, 'orangina.jpg', 5),
(14, 'Munster', 'Crème fraîche, oignons, munster', 7.05, 'flam2.jpg', 4),
(15, 'Framboise / Speculos', 'Crème fraîche, framboise, speculos', 6.9, 'flam3.jpg', 4),
(16, 'Pommes / cannelle', 'Crème fraîche, pomme, cannelle', 6, 'flam1.jpg', 4),
(17, 'Coca Cola', 'Coca Cola, boîte 33 cl.', 1.7, 'coca.jpg', 5);

Création de la liste des articles

Nous allons ici créer un petit script products_list.php qui génère à la volée la liste des articles d'une catégorie donnée. Si des articles sont ajoutés, supprimés ou modifiés, la liste retranscrira l'état de la base en temps réel.

Appel du script / paramètres

Afin de pouvoir afficher la liste des articles de la catégorie choisie par l'utilisateur, il faut passer cette catégorie en paramètre au script. Nous allons passer ce paramètre dans l'adresse (ou paramètre "GET"), ce qui donnera une url de la forme:
http://mon_serveur.com/products_list.php?cat=4

Le paramètre sera récupéré côté php: $cat=$_GET['cat'];

Requête SQL:

La requête est très simple:

SELECT id, name, price, pic from `amdoc_products` where id_cat={selected id}

Attention: nous avons décidé d'utiliser les anciennes fonctions mysql_* dans les scripts de démo, pour une compatibilité plus large. Vous ne devriez PAS les utiliser en production, mais télécharger les scripts des modules téléchargeables à la place (basés sur la librairie PDO, plus complets et plus sûrs).

Sélection des articles d'une catégorie :

<?php
include('config.php');
//récupération du paramètre passé dans l'url et requête sql
$cat=$_GET['cat'];
$req="SELECT id, name, price, pic from `$db_tbl_prod` where id_cat=$cat";

//exécution de la requête mysql: 
$db =  mysql_connect($dbhost, $dbuser, $dbpassword);
mysql_select_db($dbname);
$result = mysql_query($query,$db);
mysql_close($db);
?>

Nota 1: un "select *" aurait fait l'affaire dans notre exemple, mais les bases réelles dans lesquelles vous allez puiser contiendront de nombreux champs sans intérêt pour l'affichage d'une liste des produits.

Nota 2: il manque à ce script une petite touche de gestion des exceptions... cette lacune est corrigée dans les scripts disponibles au téléchargement.

Nota 3: Les paramètres généraux qui seront réutilisés dans les différents scripts du projet (ici les différents tutoriels) sont rassemblés dans le fichier "config.php": URL du site, identifiants de connexion à la base, noms des tables...

config.php :

<?php
    $dbhost='hostName';
    $dbuser='userLogin';
    $dbpassword='password';
    $dbname='DBName';
		
		$db_tbl_prod='amdoc_products';
		$db_tbl_cat='amdoc_categories';
		$db_tbl_ord='amdoc_orders';
		$db_tbl_user='amdoc_users';
		$db_tbl_msg='amdoc_messages';
		
		$urlprefix='http://mysite.com/path/to/folder';
		$emailaddress='yourMailAddress';
 ?>

Création de la liste XML:

Il ne reste plus qu'à mettre en forme les données dans le format XML voulu.
Nota: les spécifications du format XML sont détaillées ici.

Format XML :

<?xml version="1.0" encoding="UTF-8"?>
<items version="1.0" type="1" reload="0">
	<item type="1">
		<img>http://mon_serveur.com/pic/th_pizza1.jpg</img>
		<txt1>Louisiane</txt1>
		<txt2>9,80 €</txt2>
		<txt3></txt3>
		<link type="1" url="http://mon_serveur.com/description.php?id=1"
			title="Détail"/>
		</item>
	<item type="1">
		etc....
	</item>
</items>

Pour ça rien de plus simple, il suffit pour chaque article récupéré dans la base, de coller les valeurs des champs au bon endroit.
Ca donne en quelques lignes de php:

Export XML :

<?php
	header ("Content-Type:text/xml; charset=utf-8");
	echo"<?xml version='1.0' encoding='UTF-8'?>
	<items version='1.0' type='1' reload='0'>";
	while ($l = mysql_fetch_assoc($result)) {
		$id=$l["id"]; $name=$l["name"]; $price=$l["price"]; $pic=$l["pic"];
		echo("
		<item type='1'>
			<img>$urlprefix/pic/$pic</img>
			<txt1>$name</txt1>
			<txt2>$price</txt2>
			<txt3></txt3>
			<link type='1' url='$urlprefix/description.php?id=$id'
				title='Détail'/>
		</item>");
	}
	echo("</items>");
?>

Récapitulatif

La création de la liste, à la volée d'après les données en base au moment de l'appel du script, se résume à un script d'une trentaine de lignes:

Même remarque que ci-dessus: il manque à ce script une petite touche de gestion des exceptions... cette lacune est corrigée dans les scripts disponibles au téléchargement.

art_list.php :

<?php
include('config.php');
//récupération du paramètre passé dans l'url et requête sql
$cat=$_GET['cat'];
$req="SELECT id, name, price, pic from `$db_tbl_prod` where id_cat=$cat";

//exécution de la requête mysql: 
$db =  mysql_connect($dbhost, $dbuser, $dbpassword);
mysql_select_db($dbname);
$result = mysql_query($query,$db);
mysql_close($db);

//exploitation du résultat: export XML 
header ("Content-Type:text/xml; charset=utf-8");
echo"<?xml version='1.0' encoding='UTF-8'?>
<items version='1.0' type='1' reload='0'>";
while ($l = mysql_fetch_assoc($result)) {
	$id=$l["id"]; $name=$l["name"]; $price=$l["price"]; $pic=$l["pic"];
	echo("
	<item type='1'>
		<img>$urlprefix/pic/$pic</img>
		<txt1>$name</txt1>
		<txt2>$price</txt2>
		<txt3></txt3>
		<link type='1' url='$urlprefix/description.php?id=$id'
			title='Détail'/> //lien vers une page HTML (type='1')
	</item>");
}
echo("
</items>");
?>

Il ne reste plus qu'à:

Liste à plusieurs niveaux

Nous voulons maintenant créer une liste à deux niveaux.

Il n'y a plus qu'à créer la liste de premier niveau. Chaque élément de cette liste appellera, pour le second niveau, le script déjà réalisé. L'id de la catégorie voulue sera passé en paramètre (souvenez-vous de notre paramètre "?cat=..." dans l'url du script...):
http://mon_serveur.com/products_list.php?cat=4

La requête pour obtenir les catégories en base est encore plus simple que la précédente:
SELECT id, name, pic FROM amdoc_categories

Sur la méthode, la construction de la liste est identique à la première.
Sur le contenu, la seule différence est l'attribut "type" de l'élément <link>: il aura la valeur "4" pour une sous-liste XML et non plus "1" pour une age HTML (voir les spécifications du format XML):
<link type="4" url="http://mon_serveur.com/products_list.php?cat={id de la categorie}" title="{nom de la catégorie}"/>

Le code du script php pour générer cette liste est le suivant:

art_catlist.php

<?php
include('config.php');
//requête mysql
$req="SELECT id, name, pic FROM `$db_tbl_cat`";

//exécution de la requête mysql: 
$db =  mysql_connect($dbhost, $dbuser, $dbpassword);
mysql_select_db($dbname);
$result = mysql_query($query,$db);
mysql_close($db);

//exploitation du résultat: export XML 
header ("Content-Type:text/xml; charset=utf-8");
echo"<?xml version='1.0' encoding='UTF-8'?>
<items version='1.0' type='1' reload='0'>";
while ($l = mysql_fetch_assoc($result)) {
	$id=$l["id"]; $name=$l["name"]; $pic=$l["pic"];
	echo("
	<item type='1'>
		<img>$urlprefix/pic/$pic</img>
		<txt1>$name</txt1>
		<txt2></txt2>
		<txt3></txt3>
		<link type='4' url='$urlprefix/products_list.php?cat=$id'
			title='$name'/> //lien vers la sous-liste XML (type='4')
	</item>");
}
echo("
</items>");
?>

Pour tester le résultat directement sur votre mobile, saisissez l'url du script sur le portail mvsappmobile.com   .
Le système AppMobile gérera automatiquement la liste, l'affichage des sous-listes (liens <link type="4">), comme celui des pages HTML appelées (liens <link type="1">)

Conseils pratiques

Adaptez vos images:

La vignette qui apparaît dans les listes est une image de largeur 80 px et de hauteur 60 px (format .jpg ou .png).
Inutile d'allonger les temps de téléchargement avec des images de taille supérieure: prévoyez des vignettes de 80 x 60 pixels pour vos listes, et pour vos pages de contenu des images ayant une définition cohérente pour un affichage sur smartphone (largeur = 320px par exemple).

Validez vos XML:

Utilisez notre validateur pour identifier les problèmes dans vos XML:
http://www.mvsappmobile.com/doc/fr/validate/validate.html.