Modélisation évenementielle d'enchainement d'écrans

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

11 janv. 2013, 17:48

La méthode M3e
--------------------
Cette méthode permet de planifier les événements déclencheurs de l'enchainement des écrans d'une application interactive ainsi que les actions procédurales exécutées suite à ces événements. Cette conception sera détaillée dans un modèle de diagrammes nommé "M3e" (m : modèle, e : événementiel, e : enchainement, e: écrans).

Chaque diagramme d'un écran interactif, décrit d'une manière détaillée, son contenu en données (E/S), les commandes événementielles déclencheurs d'actions et le circuit de navigation par rapport à l'environnement de l'écran (écran précédent, écran suivant, bouclage, sortie d'arrêt du programme, événements en entrée asynchrone). Ce diagramme sera appelé "Diagramme événementiel d'écran".

En programmation, on codera le modèle M3e selon les règles du langage de programmation événementielle. Ou bien, si l'environnement de programmation n'est pas événementiel à proprement parler (donc : à exécution séquentielle ou interprétée comme le Web) on peut utiliser la méthode de programmation suivante qui traduit le M3e:
  • 0. afficher l'écran de démarrage.
    1. traiter l’événement déclenché par l'utilisateur de l’écran actuel et qui est déjà planifié par le M3e dans le diagramme de l'écran. Pour chaque événement X on exécute une action X et on décide de l'écran suivant à afficher.
    2. afficher l'écran suivant.
    3. Refaire le cycle à partir de l'étape 1.
C'est une boucle de traitement d’événements décrits dans le M3e écran par écran, en vue d'afficher à chaque fois un écran et en traiter les actions, jusqu'à la fin du programme demandée par l'utilisateur.

Voici un modèle objet écrit en PHP permettant de construire le moteur M3e pour animer les écrans (page web) d'une application front-end web:

Modèle de classes définissant : l'écran, la collection des écrans et le modèle d'enchainement de ces écrans.

class.m3e.php
<?php
# Ce programme est réalise par Sadeq pour publication dans forum.phpfrance.com
# Date : 11/01/2013
#
# Voici un modèle objet écrit en PHP permettant de construire le moteur M3e  
# pour animer les écrans (page web) d'une application front-end web
#
# Ce modèle de classes définit : L'écran, la collection des écrans 
# et le modèle d'enchainement des écrans.
#

#################
#  CLASSE ECRAN #
#################  
#  Un écran est défini par :
#  Code : identifiant unique.
#  Source : fichier externe du contenu de l'écran (PHP,HTML,AUDIO/VIDEO,PDF,...).
#  Dossier_source : dossier ou répertoire dans lequel se situe le fichier source de l'écran.
#  Precedent : code de l'écran précédant cet écran dans l'enchainement (si connu à l'avance).
#  Suivant : code de l'écran suivant cet écran dans l'enchainement (si connu à l'avance).
#  Liste_actions : liste contenant les actions événements pouvant être déclenchés par 
#                 l'utilisateur de l'écran et leurs procédures (voir la classe objet action).
#  Fonction afficher : affiche l'écran à partir de son fichier source.
#  Fonction traiter : traiter les actions prévues listées dans Liste_actions
#################
class ecran {
	public $code = null;
	public $source = null;
	public $dossier_source = 'ecrans/';
	public $precedent = null;
	public $suivant = null;
	public $liste_actions = array();
	#
	public function __construct(){
		$this->liste_actions = array();
	}
	public function afficher(){
		if ($this->source!=null && file_exists($this->dossier_source.'/'.$this->source)) include($this->dossier_source.'/'.$this->source);
	}
	public function traiter($action=null){
		#debug($this->code,'Ecran traité');debug($action,'Action');	
		$action = $action!=null?$action:null;
		if($action!=null && is_array($this->liste_actions))
		foreach($this->liste_actions as $a){
			if ($a->code==$action) {
				if ($a->source_procedure!=null && file_exists($a->dossier_source.'/'.$a->source_procedure)) include($a->dossier_source.'/'.$a->source_procedure);
				$this->suivant = $a->ecran_suivant;
				break;
			}
		}
	}
}
##################
#  CLASSE ACTION #
##################  
#  Une action est définie par :
#  Code : code de l'action (exemple: enregistrer_membre)
#  Source_procedure : fichier externe contenant le programme de traitement de l'action
#  Dossier_source : dossier ou répertoire dans lequel se situe le fichier source du programme de traitement.
#  Ecran_suivant : code de l'écran suivant à afficher après cette action
##################
class action {
	public $code = null;
	public $source_procedure = null;
	public $dossier_source = 'actions/';
	public $ecran_suivant = null;
	#
	public function __construct($code, $source_procedure, $ecran_suivant){
		$this->code = $code;
		$this->source_procedure = $source_procedure;
		$this->ecran_suivant = $ecran_suivant;
	}
}
###############################
#  CLASSE COLLECTION D'ECRANS #
###############################  
#  Une collection est définie par :
#  Contenu : liste des objets écrans enregistrés dans la collection
#  Fonction ajouter : ajouter un objet écran à la collection
#  Fonction getEcran : trouver et retourner un objet écran par son code
###############################
class collection_ecrans {
	public $contenu = array();
	#
	public function ajouter($listeEcrans=array()){
		$listeEcrans = is_array($listeEcrans)?$listeEcrans:array($listeEcrans);
		foreach($listeEcrans as $e){
			$this->contenu[] = $e;
		}
	}
	public function getEcran($code_ecran){
		foreach($this->contenu as $e){
			if ($e->code == $code_ecran) { return $e; }
		}
		return null;
	}
}
###############
#  CLASSE M3E #
###############  
#  Le Modèle m3e est celui qui décrit l'enchainement des écrans de l'application, pour cela il faut :
#  Collection_ecrans : liste des objets écrans dument construits et enregistrés dans la collection
#  EcranParDefaut : code de l'écran de démarrage de l'application (un des écrans de la collection)
#  Fonction executer : animer l'enchainement des écrans dont le principe est simple: 
#     1. Traiter l'écran déjà affiché (s'il y eu déjà affichage)
#     2. Afficher l'écran suivant l'écran déjà traité ou bien l'écran par défaut si démarrage.
###############
class m3e {
	public $collection_ecrans;
	public $ecranParDefaut = null;
	public $ecran_actuel = null;
	public function __construct(){
		$this->collection_ecrans = new collection_ecrans();
	}
	public function executer(){
		#Traiter l'écran déjà affiché (s'il y eu déjà affichage)
		$code_ecran_actuel = isset($_GET['code_ecran_actuel'])?$_GET['code_ecran_actuel']:null;
		$ecran_actuel = $this->collection_ecrans->getEcran($code_ecran_actuel);
		if ($ecran_actuel!=null) {
			#debug($ecran_actuel,'Ecran Actuel');
			$action = isset($_GET['action'])?$_GET['action']:(isset($_POST['action'])?$_POST['action']:null);
			$ecran_actuel->traiter($action);
		}
		#Afficher l'écran suivant l'écran déjà traité ou bien l'écran par défaut si démarrage.
		$code_ecran_suivant = $ecran_actuel!=null?$ecran_actuel->suivant:$this->ecranParDefaut;
		$ecran_suivant = $this->collection_ecrans->getEcran($code_ecran_suivant);
		$ecran_suivant = $ecran_suivant!=null?$ecran_suivant:$this->collection_ecrans->getEcran($this->ecranParDefaut);
		$ecran_suivant->precedent = $ecran_actuel!=null?$ecran_actuel->code:$this->ecranParDefaut;
		#debug($ecran_suivant,'Ecran Suivant');	
		$ecran_suivant->afficher();
	}
}
###########################
#  FONCTION POUR LE DEBUG #
###########################
function debug($var,$titre=null){ echo('<pre><h3>'.$titre.':</h3><ul>');print_r($var);echo('</ul></pre>'); }
?>
Le programme objet de construction de l'application écran par écran en utilisant le modèle M3e précédent est le suivant:

myApp.php:
<?php
# Ce programme est réalise par Sadeq pour publication dans forum.phpfrance.com
# Date : 11/01/2013
#
# Voici un modèle objet écrit en PHP permettant de construire le moteur M3e  
# pour animer les écrans (page web) d'une application front-end web
#
###########################
# Extension du Modèle M3e #
###########################
require_once('class.m3e.php');
#
# Ici on va décrire les écrans de l'application un par un
#
########################
# ECRAN MENU PRINCIPAL #
########################
class e_menu extends ecran {
	public function __construct(){
		$this->code = 'e_menu';
		$this->source = 'e_menu.php';
		$this->precedent = null;
		$this->suivant = null;
		$this->liste_actions = array(
			new action('accueil',null,'e_accueil'),
			new action('contact',null,'e_contact')
		);
	}
}
#################
# ECRAN ACCUEIL #
#################
class e_accueil extends ecran {
	public function __construct(){
		$this->code = 'e_accueil';
		$this->source = 'e_accueil.php';
		$this->precedent = null;
		$this->suivant = null;
		$this->liste_actions = array(
			new action('menu',null,'e_menu')
		);
	}
}
########################
# ECRAN CONTACTEZ-NOUS #
########################
class e_contact extends ecran {
	public function __construct(){
		$this->code = 'e_contact';
		$this->source = 'e_contact.php';
		$this->precedent = null;
		$this->suivant = null;
		$this->liste_actions = array(
			new action('menu',null,'e_menu'),
			new action('enregistrer','e_contact_enregistrer.php','e_contact')
			
		);
	}
}
#############################
# CREATION DE L'APPLICATION #
#############################
#debug($_GET,'GET'); debug($_SESSION,'SESSION');
$myApp = new m3e();
$myApp->collection_ecrans->ajouter(array(
	new e_menu(),
	new e_accueil(),
	new e_contact() 
));
$myApp->ecranParDefaut = 'e_menu';
$myApp->executer();
?>
Ce qui fait que on a les fichiers suivants dans notre dossier de l'application web:
  • 1. class.m3e.php
    2. myApp.php
    puis 2 dossiers: "ecrans/" et "actions/"
Le dossier "ecrans/" qui doit contenir les fichiers sources des écrans. Dans notre exemple il s'agit de 3 écrans:

1. e_menu.php
<?php 
# ici votre code d'initialisation de l'écran
?>
<h1>Menu principal</h1>
<a href="?code_ecran_actuel=e_menu&action=accueil">Accueil</a>
<a href="?code_ecran_actuel=e_menu&action=contact">Contactez-nous</a>
2. e_accueil.php
<?php 
# ici votre code d'initialisation de l'écran
?>
<h1>Page d'accueil</h1>
<a href="?code_ecran_actuel=e_accueil&action=menu">Menu</a>
3. e_contact.php
<?php 
# ici votre code d'initialisation de l'écran

$nom = isset($_GET['nom'])?$_GET['nom']:(isset($_POST['nom'])?$_POST['nom']:null);
$prenom = isset($_GET['prenom'])?$_GET['prenom']:(isset($_POST['prenom'])?$_POST['prenom']:null);
?>
<h1>Page de contact</h1>
<a href="?code_ecran_actuel=e_contact&action=menu">Menu</a>

<form method="get">
<h2>Nom <input type="text" name="nom" value="<?php echo isset($nom)?$nom:null; ?>" /></h2>
<h2>Prénom <input type="text" name="prenom" value="<?php echo isset($prenom)?$prenom:null; ?>" /></h2>

<input type="hidden" name="code_ecran_actuel" value="e_contact"/>
<input type="submit" name="action" value="enregistrer" />
</form>
Le dossier "actions/" quant à lui, doit contenir les fichiers sources des procédures de traitement des actions prévues pour les écrans. Dans notre exemple il s'agit de la procédure "e_contact_enregistrer.php" déclenchée par l'action "enregistrer" de l'écran "e_contact".

e_contact_enregistrer.php:
<?php
# ici votre code de traitement de l'action
debug($_GET,'Données form contact');
echo "Contact enregistré.";
?>
Téléchargez les sources ici : http://dl.free.fr/nLWomIgcO
Bonne lecture :-)
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

12 janv. 2013, 23:46

Et c'est pas fini,

Voici une nouvelle version du modèle M3e que j'ai présenté. J'ai ajouté un générateur automatique qui crée dans des fichiers sources les maquettes préliminaires des écrans définis par le modèle M3e de l'application.

Voici donc les fichiers de la nouvelle version : http://dl.free.fr/r6rwCWL4K

Pour générer l'application d'exemple, voici l'URL à utiliser : http://localhost/m3e/genererApp.php
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

14 janv. 2013, 01:15

Troisième mise à jour:

Ce n'est pas encore fini, j'ai ajouté une méthode qui permet de charger la description des écrans (diagrammes d'écrans) à partir d'un fichier XML.
Cette méthode est importante car elle sépare les modèles d'écrans de la classe M3e de génération des maquettes sources de l'application selon l’enchaînement décrit dans les diagrammes XML.

Voici un exemple du fichier XML correspondant aux écrans de mon exemple d'application sur lequel j'ai travaillé depuis le début de ce tuto.

Fichier: diagramme des ecrans.xml
<?xml version = '1.0' encoding="UTF8"?> 
<!--  Ici on va décrire les écrans de l'application un par un -->
<collection_ecrans>
	<!-- ECRAN MENU PRINCIPAL -->
	<ecran>
		<code>e_menu</code>
		<titre>Menu principal</titre>
		<source>e_menu.php</source>
		<precedent></precedent>
		<suivant></suivant>
		<action>
			<code>afficher_accueil</code>
			<titre>Afficher la page Accueil</titre>
			<source_procedure></source_procedure>
			<ecran_suivant>e_accueil</ecran_suivant>
		</action>
		<action>
			<code>afficher_contact</code>
			<titre>Afficher la page Contactez-nous</titre>
			<source_procedure></source_procedure>
			<ecran_suivant>e_contact</ecran_suivant>
		</action>
	</ecran>
	<!-- ECRAN ACCUEIL -->
	<ecran>
		<code>e_accueil</code>
		<titre>Accueil</titre>
		<source>e_accueil.php</source>
		<precedent></precedent>
		<suivant></suivant>
		<action>
			<code>retourner_menu</code>
			<titre>Retour au menu</titre>
			<source_procedure></source_procedure>
			<ecran_suivant>e_menu</ecran_suivant>
		</action>
	</ecran>
	<!-- ECRAN CONTACTEZ-NOUS -->
	<ecran>
		<code>e_contact</code>
		<titre>Contactez-nous</titre>
		<source>e_contact.php</source>
		<precedent></precedent>
		<suivant></suivant>
		<action>
			<code>retourner_menu</code>
			<titre>Retour au menu</titre>
			<source_procedure></source_procedure>
			<ecran_suivant>e_menu</ecran_suivant>
		</action>
		<action>
			<code>enregistrer_contact</code>
			<titre>Enregistrer le message de contact</titre>
			<source_procedure>e_contact_enregistrer.php</source_procedure>
			<ecran_suivant>e_contact</ecran_suivant>
		</action>
	</ecran>
</collection_ecrans>
Voici la méthode (fonction) qui a été ajoutée au modèle M3e permettant de charger la collection d'écran à partir du fichier XML:
	public function chargerXML($source_xml){ 
		#ouvrir le fichier xml
		if (!file_exists($source_xml)) return false;
		$xml = simplexml_load_file($source_xml); 
		#print_r($xml);
		foreach($xml as $e){
			#remplir un ecran
			$objet_ecran = new ecran();
			$objet_ecran->code = "$e->code";
			$objet_ecran->titre = "$e->titre";
			$objet_ecran->source = "$e->source";
			#remplir les actions de l'ecran
			foreach($e->action as $a){
				$objet_ecran->ajouter_action(new action(
					"$a->code",
					"$a->titre",
					"$a->source_procedure",
					"$a->ecran_suivant"));
			}
			#ajouter l'ecran dans la collection
			$this->ajouter($objet_ecran);
		}
		#print_r($this);
		return true;
	}
Et voici comment on l'appelerait dans le programme d'exemple qui crée une application d'exemple (myAPP):
<?php
# Ce programme est réalise par Sadeq pour publication dans forum.phpfrance.com
# Date : 11/01/2013
#
# Voici un modèle objet écrit en PHP permettant de construire le moteur M3e  
# pour animer les écrans (page web) d'une application frontend web
#
###########################
# Extension du Modèle M3e #
###########################
require_once('class.m3e.php');
#
# Ici les descriptions des écrans de l'application sont dans un fichier XML
#
#############################
# CREATION DE L'APPLICATION #
#############################
#debug($_GET,'GET'); debug($_SESSION,'SESSION');
$myApp = new m3e();

# Charger la collection d'écrans à partir d'un fichier XML
$myApp->collection_ecrans->chargerXML('diagramme des ecrans.xml');
#
if (count($myApp->collection_ecrans->contenu)>0){
	# Déclarer l'écran de démarrage de l'application
	$myApp->ecranParDefaut = 'e_menu';

	# Définir les dossiers de génération des fichiers des maquettes écrans+actions
	$myApp->dossier_ecrans = 'ecrans/';
	$myApp->dossier_actions = 'actions/';

	# Si le générateur doit se baser sur des modèles de maquettes écrans+actions
	$myApp->fichier_modele_ecran = 'modele_ecran.txt'; $myApp->creerModeleEcran();
	$myApp->fichier_modele_action = 'modele_action.txt'; $myApp->creerModeleAction();

	# Générer les sources de l'application
	$myApp->generer();

	# Démarrer l'application
	$myApp->executer();
}
else { echo "Désolé, aucun écran n'a été défini"; }
Et voici les sources de cette nouvelle version : http://dl.free.fr/kspjAgoer

La prochaine étape serait de pouvoir utiliser un Concepteur de diagrammes d'écrans qui permet créer le fichier "diagramme des ecrans.xml" automatiquement à partir de dessins d'écrans et des actions les reliant.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

18 janv. 2013, 03:09

La prochaine étape serait de pouvoir utiliser un Concepteur de diagrammes d'écrans qui permet créer le fichier "diagramme des ecrans.xml" automatiquement à partir de dessins d'écrans et des actions les reliant.
Quatrième version donc, cette étape est désormais achevée, j'ai réussi à trouver un logiciel dessinateur d'écrans qui traduit les dessins en XML (c'est juste un premier choix pour l'instant qu'il faudrait approfondir son nom se trouve dans les comment du programme). J'ai adapté donc le générateur d'application basé sur la classe M3e pour qu'il se base sur les fichiers XML générés par le dessinateur d'écrans (les diagrammes des ecrans) pour créer donc les écrans de l'application en les codant en PHP/HTML. C'est testé et c'est concluant.

Voici la dernière nouvelle version : http://dl.free.fr/gUCAiPOQt
J'explique le fonctionnement de cette version:
Dans le dossier : diagrammes_ecrans
On trouve les fichiers XML des écrans dessinés par le logiciel de dessin d'écrans ( e_accueil.xml, e_contact.xml et e_menu.xml) selon notre exemple d'application.
Le programme genererApp.php a été adapté ainsi que le module de classes class.m3e.php pour lire les fichiers xml et générer automatiquement la traduction des écrans en PHP/HTML (résultat dans le dossier "ecrans" : e_accueil.php, e_contact.php et e_menu.php). Bien sur, l'application se construit maintenant sous forme d'objets écrans. Objectif atteint, cette étape est terminée alors.

Ce qui reste maintenant c'est de modéliser les enchainements des écrans (et donc les actions qui permettent la navigation entre les écrans de l'application) ça doit être fait de la même façon sous forme de dessin traduisible en XML que le générateur M3e peut traduire par la suite en codage PHP/JS/HTML. Les questions stratégiques qui se posent à ce niveau sont nombreuses et notamment la gestion des actions selon leurs catégories (simple lien, postage de données (form ou ajax), actions procédurales, ...) ??? à suivre ...
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

21 janv. 2013, 01:26

Ce qui reste maintenant c'est de modéliser les enchainements des écrans (et donc les actions qui permettent la navigation entre les écrans de l'application) ça doit être fait de la même façon sous forme de dessin traduisible en XML que le générateur M3e peut traduire par la suite en codage PHP/JS/HTML. Les questions stratégiques qui se posent à ce niveau sont nombreuses et notamment la gestion des actions selon leurs catégories (simple lien, postage de données (form ou ajax), actions procédurales, ...) ??? à suivre ...
Bonjour, c'est maintenant chose faite.

Voici la version finale qui clôture ce module et met en place donc l'enchainement des écrans et le traitement des actions déclenchées sur chaque écran avec transmission de données suite à certaines actions qui l’exigent. Le tout est généré automatiquement à partir des diagrammes d'écrans rédigés en XML. Moi j'ai utilisé le logiciel Balsamiq Mockups pour dessiner les écrans et leurs contenus (label, zones de texte, menus, liens hypertextes, boutons submit, combobox, ...) puis je les ai exporté en XML. Les diagrammes d'écrans sont situés dans le dossier "diagrammes_ecrans" du projet.

Une fois les diagrammes XML créé, le module M3e permet de générer l'application correspondante en traduisant les sources XML des écrans en pages PHP/HTML et d'exécuter l'application web à partir de l'écran qui a été spécifié comme page de démarrage.

Voici les source de la version finale : http://dl.free.fr/nsoyrMrAx (màj du 21/01/2013 à 11:00)

Bonne lecture.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

30 janv. 2013, 04:18

Nouvelle mise à jour. Le modèle est stable. Je travaille actuellement sur la construction de mon propre dessinateur d'écrans avec la boite à outils des objets graphiques, la collection des écrans à dessiner avec leurs propriétés métiers (métadonnées et actions : c'est à dire liaisons avec les données de la base et les requêtes SQL). Sans oublier bien sûr le dessin de l'enchainement des écrans.
En principe, tous les résultats de ce dessinateur seront enregistrés dans des fichiers XML pour jouer le rôle de "diagrammes d'écrans". Et c'est cette partie objectif finale que j'ai commencé à réaliser en premier et tout est OK. L'application se génère automatiquement à partir de ces modèles XML et l'exécution des cas d'utilisation de mon exemple est concluante (Navigation entre écrans, postage de données, exécution de procédures SQL, ... tout est OK)

Voici la dernière version : http://dl.free.fr/kBLFbBjNX (Mise à jour le 01/02/2013)

La base de données d'exemple se trouve dans le dossier "diagrammes_ecrans" et se nomme "test.sql"

L'url de départ est : http://localhost/m3e/genererApp.php?recreer=true
L'application d'exemple sera créée dans une session où il tournera en autonomie. Tout changement dans les diagrammes d'écrans XML exige de recréer l'application c'est normal car ces diagrammes sont les structures de conception des écrans avec leurs données et actions qui permettent leurs enchainement et donc leur interaction avec l'utilisateur, le système et la base de données.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

01 févr. 2013, 15:57

Dernière mise à jour du 01/02/2013 : http://dl.free.fr/lB7Na30QV
Récap:
=====
1. Le dossier "diagrammes_ecrans" doit contenir les fichiers XML de chaque diagramme écran chacun portant le nom de son écran + le fichier XML du diagramme général (diagramme des ecrans.xml). Voici des exemples de ces fichiers :

diagramme des ecrans.xml
<?xml version = '1.0' encoding="UTF8"?> 
<!--  Ici on va décrire les écrans de l'application un par un -->
<collection_ecrans>
	<!-- ECRAN ACCUEIL -->
	<ecran>
		<code>e_accueil</code>
		<titre>Accueil</titre>
		<ecran_par_defaut>1</ecran_par_defaut>
		<fichier_source>e_accueil.php</fichier_source>
		<fichier_contenu_xml>e_accueil.xml</fichier_contenu_xml>
		<action>
			<code>afficher_contact</code>
			<titre>Contactez-nous</titre>
			<fichier_source_procedure></fichier_source_procedure>
			<ecran_suivant>e_contact</ecran_suivant>
		</action>
		<action>
			<code>afficher_services</code>
			<titre>Nos Services</titre>
			<fichier_source_procedure></fichier_source_procedure>
			<ecran_suivant>e_services</ecran_suivant>
		</action>
		<action>
			<code>afficher_produits</code>
			<titre>Produits</titre>
			<fichier_source_procedure></fichier_source_procedure>
			<ecran_suivant>e_produits</ecran_suivant>
		</action>
		<champ>
			<type>sortie</type>
			<id>titre</id>
			<valeur></valeur>
		</champ>
		<champ>
			<type>sortie</type>
			<id>texte_accueil</id>
			<valeur></valeur>
		</champ>
		<champ>
			<type>sortie</type>
			<id>barre_etat</id>
			<valeur></valeur>
		</champ>
	</ecran>
	<!-- ECRAN CONTACTEZ-NOUS -->
	<ecran>
		<code>e_contact</code>
		<titre>Contactez-nous</titre>
		<ecran_par_defaut>0</ecran_par_defaut>
		<fichier_source>e_contact.php</fichier_source>
		<fichier_contenu_xml>e_contact.xml</fichier_contenu_xml>
		<action>
			<code>afficher_accueil</code>
			<titre>Accueil</titre>
			<fichier_source_procedure></fichier_source_procedure>
			<ecran_suivant>e_accueil</ecran_suivant>
		</action>
		<action>
			<code>afficher_services</code>
			<titre>Nos Services</titre>
			<fichier_source_procedure></fichier_source_procedure>
			<ecran_suivant>e_services</ecran_suivant>
		</action>
		<action>
			<code>afficher_produits</code>
			<titre>Produits</titre>
			<fichier_source_procedure></fichier_source_procedure>
			<ecran_suivant>e_produits</ecran_suivant>
		</action>
		<action>
			<code>enregistrer_contact</code>
			<titre>Enregistrer</titre>
			<fichier_source_procedure>enregistrer_contact.php</fichier_source_procedure>
			<ecran_suivant>e_contact</ecran_suivant>
			<postData>email,nom,prenom,message,cp_ville,pays,tel</postData>
			<postMethod>GET</postMethod>
			<sql>
				<type>insert</type>
				<source_name>t_contacts</source_name>
				<db_name>test</db_name>
				<db_host>localhost</db_host>
				<db_user_id>root</db_user_id>
				<db_user_pwd></db_user_pwd>
				<champs>email,nom,prenom,message,cp_ville,pays,tel</champs>
			</sql>
		</action>
		<action>
			<code>modifier_contact</code>
			<titre>Modifier</titre>
			<fichier_source_procedure>modifier_contact.php</fichier_source_procedure>
			<ecran_suivant>e_contact</ecran_suivant>
			<postData>email,nom,prenom,message,cp_ville,pays,tel</postData>
			<postMethod>GET</postMethod>
			<sql>
				<type>update</type>
				<source_name>t_contacts</source_name>
				<db_name>test</db_name>
				<db_host>localhost</db_host>
				<db_user_id>root</db_user_id>
				<db_user_pwd></db_user_pwd>
				<condition>email=%email%</condition>	
				<champs>nom,prenom,message,cp_ville,pays,tel</champs>
			</sql>
		</action>
		<action>
			<code>afficher_contact</code>
			<titre>Afficher</titre>
			<fichier_source_procedure>afficher_contact.php</fichier_source_procedure>
			<data_entree_sortie>email</data_entree_sortie>
			<ecran_suivant>e_contact</ecran_suivant>
			<postData>email</postData>
			<postMethod>GET</postMethod>
			<sql>
				<type>select</type>
				<source_name>t_contacts</source_name>
				<db_name>test</db_name>
				<db_host>localhost</db_host>
				<db_user_id>root</db_user_id>
				<db_user_pwd></db_user_pwd>
				<champs>email,nom,prenom,message,cp_ville,pays,tel</champs>
				<condition>email=%email%</condition>
				<tri></tri>
			</sql>
		</action>
		<action>
			<code>supprimer_contact</code>
			<titre>Supprimer</titre>
			<fichier_source_procedure>supprimer_contact.php</fichier_source_procedure>
			<ecran_suivant>e_contact</ecran_suivant>
			<postData>email</postData>
			<postMethod>GET</postMethod>
			<sql>
				<type>delete</type>
				<source_name>t_contacts</source_name>
				<db_name>test</db_name>
				<db_host>localhost</db_host>
				<db_user_id>root</db_user_id>
				<db_user_pwd></db_user_pwd>
				<condition>email=%email%</condition>
			</sql>
		</action>
		<champ>
			<type>entree_sortie</type>
			<id>email</id>
			<label>Email</label>
			<requis>true</requis>
			<valid_si></valid_si>
			<dataType>text</dataType>
			<masque>email</masque>
			<valeur></valeur>
			<dataset_source>t_contacts_dataset1</dataset_source>
			<link_field>email</link_field>
			<display_fields>email</display_fields>
			<form_parent></form_parent>
			<plugin>jquery.recherche(email)</plugin>
		</champ>
		<champ>
			<type>entree_sortie</type>
			<id>nom</id>
			<label>Nom</label>
			<requis>true</requis>
			<valid_si></valid_si>
			<dataType>text</dataType>
			<masque></masque>
			<valeur></valeur>
			<dataset_source>t_contacts_dataset1</dataset_source>
			<link_field>nom</link_field>
			<display_fields>nom</display_fields>
			<form_parent></form_parent>
		</champ>
		<champ>
			<type>entree_sortie</type>
			<id>prenom</id>
			<label>prenom</label>
			<requis>true</requis>
			<valid_si></valid_si>
			<dataType>text</dataType>
			<masque></masque>
			<valeur></valeur>
			<dataset_source>t_contacts_dataset1</dataset_source>
			<link_field>prenom</link_field>
			<display_fields>prenom</display_fields>
			<form_parent></form_parent>
		</champ>
		<champ>
			<type>entree_sortie</type>
			<multilignes>true</multilignes>
			<id>message</id>
			<label>message</label>
			<requis>true</requis>
			<valid_si></valid_si>
			<dataType>text</dataType>
			<masque></masque>
			<valeur></valeur>
			<dataset_source>t_contacts_dataset1</dataset_source>
			<link_field>message</link_field>
			<display_fields>message</display_fields>
			<form_parent></form_parent>
		</champ>
		<champ>
			<type>entree_sortie</type>
			<id>cp_ville</id>
			<label>cp_ville</label>
			<requis>true</requis>
			<valid_si></valid_si>
			<dataType>text</dataType>
			<masque></masque>
			<valeur></valeur>
			<dataset_source>t_contacts_dataset1</dataset_source>
			<link_field>cp_ville</link_field>
			<display_fields>cp_ville</display_fields>
			<form_parent></form_parent>
			<table>
				<multiple>false</multiple>
				<selectedValue></selectedValue>
				<cols>2</cols>
				<header>cp_ville,pays</header>
				<footer></footer>
				<row>'72000, Le Mans',France</row>
				<row>'53000, Laval',France</row>
				<row_event>
					<type>onclick</type>
					<procedure>selectedValue=this.col[0]</procedure>
				</row_event>
				<row_source>
					<db_name>test</db_name>
					<db_host>localhost</db_host>
					<db_user_name>root</db_user_name>
					<db_user_pwd></db_user_pwd>
					<source_sql>select cp_ville, pays from t_villes order by pays,cp_ville</source_sql>
					<row_value_field>cp_ville</row_value_field>
					<row_text_field>cp_ville,pays</row_text_field>
				</row_source>
			</table>
		</champ>
		<champ>
			<type>entree_sortie</type>
			<id>pays</id>
			<label>pays</label>
			<requis>true</requis>
			<valid_si>in list</valid_si>
			<dataType>text</dataType>
			<masque></masque>
			<valeur></valeur>
			<dataset_source>t_contacts_dataset1</dataset_source>
			<link_field>pays</link_field>
			<display_fields>pays</display_fields>
			<form_parent></form_parent>
			<list>
				<multiple>false</multiple>
				<selectedValue></selectedValue>
				<row>
					<value>France</value>
					<text>France</text>
				</row>
				<row>
					<value>Espagne</value>
					<text>Espagne</text>
				</row>
				<row_source>
					<db_name>test</db_name>
					<db_host>localhost</db_host>
					<db_user_name>root</db_user_name>
					<db_user_pwd></db_user_pwd>
					<source_sql>select distinct pays from t_villes order by pays</source_sql>
					<row_value_field>pays</row_value_field>
					<row_text_field>pays</row_text_field>
				</row_source>
			</list>
		</champ>
		<champ>
			<type>entree_sortie</type>
			<id>tel</id>
			<label>Tel.</label>
			<requis>true</requis>
			<valid_si></valid_si>
			<dataType>alphanumeric</dataType>
			<masque>tel</masque>
			<valeur></valeur>
			<dataset_source>t_contacts_dataset1</dataset_source>
			<link_field>tel</link_field>
			<display_fields>tel</display_fields>
			<form_parent></form_parent>
		</champ>
		<champ>
			<type>sortie</type>
			<id>barre_etat</id>
			<valeur></valeur>
		</champ>
		<champ>
			<type>sortie</type>
			<id>titre</id>
			<valeur>Formulaire de contact</valeur>
		</champ>
		<dataset>
			<id>t_contacts_dataset1</id>
			<source_name>t_contacts</source_name>
			<db_name>test</db_name>
			<db_host>localhost</db_host>
			<db_user_id>root</db_user_id>
			<db_user_pwd></db_user_pwd>
			<champs>email,nom,prenom,message,cp_ville,pays,tel</champs>
			<condition>email=%email%</condition>
			<tri></tri>
		</dataset>
	</ecran>
</collection_ecrans>
Et voici les fichiers xml décrivant le contenu des écrans :
Pour l'écran d'accueil : e_accueil.xml
<ecran id="e_accueil" version="1.0" skin="windows" font="verdana" size="10" width="100%" height="100%">
    <champ id="menubar1" displayOrder="0" type="MenuBar" position="absolute" x="0" y="0" width="414" height="30" zindex="0" isInGroup="-1"  cssClass="">
		<align>left</align>
        <color>#182080</color>
		<backcolor></backcolor>
		<size>12</size>
		<actions>afficher_contact,afficher_services,afficher_produits</actions>
    </champ>
	<champ id="label_titre" displayOrder="1" type="Label" position="" x="11" y="39" width="414" height="50" zindex="0" locked="false" isInGroup="-1"  cssClass="">
        <align>left</align>
		<size>24</size>
		<bold>true</bold>
        <color>#182080</color>
        <value>Bienvenue</value>
    </champ>
    <champ id="texte_accueil" displayOrder="2" type="Label" position="" x="11" y="120" width="399" height="369" zindex="0" locked="false" isInGroup="-1"  cssClass="">
		<align>left</align>
        <color>#182080</color>
		<size>12</size>
        <value>Puisqu%27une%20page%20d%27accueil%20c%27est%20l%27image%20du%20site%20tout%20entier%2C%20le%20design%20doit%20jouer%20une%20place%20consid%E9rable.%20Quand%20on%20parle%20de%20design%2C%20on%20n%27%E9voque%20pas%20forc%E9ment%20la%20multiplication%20d%27images%20surdimensionn%E9es.%20Il%20s%27agit%20de%20trouver%20un%20juste%20%E9quilibre%2C%20et%20de%20mesurer%20cet%20%E9quilibre%20en%20fonction%20du%20type%20de%20site.Il%20est%20en%20tout%20cas%20%E9vident%20qu%27une%20page%20d%27accueil%20doit%20%EAtre%20visuellement%20plus%20tape%20%E0%20l%27oeil%20qu%27une%20page%20interne%20de%20contenu.%20Avant%20tout%2C%20elle%20doit%20donner%20envie.%20Et%20cette%20envie%20d%E9coule%20d%27une%20exp%E9rience%20globale%2C%20r%E9sultat%20de%20contenus%20incitatifs%20mais%20aussi%20d%27un%20design%20%E9tudi%E9.Le%20rapport%20entre%20design%20et%20ergonomie%20doit%20%EAtre%20consid%E9r%E9%20de%20telle%20sorte%20que%20le%20design%20serve%20l%27utilisabilit%E9%20de%20la%20page%20d%27accueil%2C%20en%20appuyant%20certains%20contenus%2C%20en%20mettant%20en%20valeur%20des%20groupes%20d%27informations%2C%20en%20soulignant%20la%20hi%E9rarchie%20d%27importance%20des%20%E9l%E9ments%20par%20leur%20apparence%2C%20etc.De%20nombreuses%20pages%20d%27accueil%20incluent%20des%20%E9l%E9ments%20anim%E9s%20%28mettons%20de%20c%F4t%E9%20les%20sites%20enti%E8rement%20construits%20en%20flash%29.%20Concernant%20l%27ad%E9quation%20d%27une%20animation%2C%20la%20question%20n%27est%20pas%20forc%E9ment%20de%20se%20demander%20si%20l%27on%20doit%20en%20int%E9grerou%20pas%2C%20mais%20plut%F4t%20de%20savoir%20si%20sa%20pr%E9sence%20apporterait%20une%20plus-value%20%E0%20la%20page%20d%27accueil.%20Il%20est%20aussi%20recommand%E9%20de%20d%E9tecter%20si%20le%20syst%E8me%20de%20l%27utilisateur%20dispose%20du%20plug-in%20n%E9cessaire.%20Si%20ce%20n%27est%20pas%20le%20cas%2C%20on%20peut%20lui%20afficher%20une%20image%20statique%20%E0%20la%20place%20de%20l%27animation.%20</value>
    </champ>  
    <champ id="barre_etat" displayOrder="18" type="Label" position="" x="11" y="424" width="429" height="30" zindex="0" isInGroup="-1"  cssClass="">
		<align>left</align>
        <color>#404630</color>
		<size>12</size>
		<italic>true</italic>
        <value/>
    </champ>
</ecran>
Pour l'écran de contact : e_contact.xml
<ecran id="e_contact" version="1.0" skin="windows" font="verdana" size="10" width="100%" height="100%">
    <champ id="menubar1" displayOrder="0" type="MenuBar" position="absolute" x="0" y="0" width="414" height="30" zindex="0" isInGroup="-1"  cssClass="">
		<align>left</align>
        <color>#182080</color>
		<backcolor></backcolor>
		<size>12</size>
		<actions>afficher_accueil,afficher_services,afficher_produits</actions>
    </champ>
	<champ id="label_titre" displayOrder="1" type="Label" position="" x="11" y="39" width="414" height="50" zindex="0" locked="false" isInGroup="-1"  cssClass="">
        <align>left</align>
		<size>24</size>
		<bold>true</bold>
        <color>#182080</color>
        <value>Fiche contact</value>
    </champ>
    <champ id="label_email" displayOrder="2" type="Label" position="" x="11" y="120" width="36" height="21" zindex="0" locked="false" isInGroup="-1"  cssClass="">
		<align>left</align>
        <color>#182080</color>
		<size>12</size>
		<bold>true</bold>
        <value>Email</value>
    </champ>
    <champ id="email" displayOrder="3" type="TextInput" position="" x="92" y="117" width="216" height="27" zindex="6" locked="false" isInGroup="-1"  cssClass="">
        <align>left</align>
        <color>#182080</color>
		<size>12</size>
        <value/>
		<tabindex>2</tabindex>
    </champ>
    <champ id="afficher_contact" displayOrder="4" type="Button" position="" x="315" y="117" width="105" height="27" zindex="0" locked="false"  isInGroup="-1"  cssClass="">
        <align>center</align>
        <color>#182080</color>
		<size>10</size>
		<value>Afficher</value>
		<tabindex>3</tabindex>
    </champ>	
    <champ id="Label_nom" displayOrder="5" type="Label" position="" x="11" y="155" width="32" height="21" zindex="0" locked="false" isInGroup="-1"  cssClass="">
        <align>left</align>
        <color>#182080</color>
		<size>12</size>
		<bold>true</bold>
		<value>Nom</value>
    </champ>
    <champ id="nom" displayOrder="6" type="TextInput" position="" x="92" y="152" width="216" height="27" zindex="0" locked="false" isInGroup="-1"  cssClass="">
        <align>left</align>
        <color>#182080</color>
		<size>12</size>
        <value/>
		<tabindex>4</tabindex>
    </champ>	
    <champ id="Label_prenom" displayOrder="7" type="Label" position="" x="11" y="189" width="51" height="21" zindex="0" locked="false" isInGroup="-1"  cssClass="">
		<align>left</align>
        <color>#182080</color>
		<size>12</size>
		<bold>true</bold>
        <value>Prenom</value>
    </champ>
    <champ id="prenom" displayOrder="8" type="TextInput" position="" x="92" y="188" width="216" height="27" zindex="0" locked="false" isInGroup="-1"  cssClass="">
        <align>left</align>
        <color>#182080</color>
		<size>12</size>
        <value/>
		<tabindex>5</tabindex>
    </champ>	
    <champ id="Label_message" displayOrder="9" type="Label" position="" x="11" y="222" width="57" height="21" zindex="0" locked="false" isInGroup="-1"  cssClass="">
		<align>left</align>
        <color>#182080</color>
		<size>12</size>
		<bold>true</bold>
        <value>Message</value>
    </champ>
    <champ id="message" displayOrder="10" type="TextArea" position="" x="92" y="222" width="216" height="140" zindex="0" locked="false" isInGroup="-1"  cssClass="">
        <align>left</align>
        <color>#182080</color>
		<size>12</size>
        <value/>
		<tabindex>6</tabindex>
    </champ>
    <champ id="Label_cp_ville" displayOrder="11" type="Label" position="" x="11" y="369" width="48" height="21" zindex="0" locked="false" isInGroup="-1"  cssClass="">
		<align>left</align>
        <color>#182080</color>
		<size>12</size>
		<bold>true</bold>
        <value>CP_Ville</value>
    </champ>
    <champ id="cp_ville" displayOrder="12" type="TextInput" position="" x="92" y="369" width="216" height="27" zindex="0" locked="false" isInGroup="-1"  cssClass="">
        <align>left</align>
        <color>#182080</color>
		<size>12</size>
        <value/>
		<tabindex>7</tabindex>
    </champ>
    <champ id="Label_pays" displayOrder="13" type="Label" position="" x="11" y="403" width="33" height="21" zindex="0" locked="false" isInGroup="-1"  cssClass="">
		<align>left</align>
        <color>#182080</color>
		<size>12</size>
		<bold>true</bold>
        <value>Pays</value>
    </champ>
    <champ id="pays" displayOrder="14" type="ComboBox" position="" x="92" y="403" width="216" height="24" zindex="0" locked="false" isInGroup="-1"  cssClass="">
        <align>left</align>
        <color>#182080</color>
		<size>12</size>
        <value/>
		<data>Espagne,France</data>
		<tabindex>8</tabindex>
    </champ>
     <champ id="Label_tel" displayOrder="15" type="Label" position="" x="11" y="434" width="29" height="21" zindex="0" locked="false" isInGroup="-1"  cssClass="">
		<align>left</align>
        <color>#182080</color>
		<size>12</size>
		<bold>true</bold>
        <value>Tel.</value>
    </champ>
    <champ id="tel" displayOrder="16" type="TextInput" position="" x="92" y="434" width="216" height="27" zindex="0" locked="false" isInGroup="-1"  cssClass="">
        <align>left</align>
        <color>#182080</color>
		<size>12</size>
        <value/>
		<tabindex>9</tabindex>
    </champ>
    <champ id="enregistrer_contact" displayOrder="17" type="Button" position="" x="92" y="468" width="105" height="27" zindex="0" locked="false"  isInGroup="-1"  cssClass="">
        <align>left</align>
        <color>#182080</color>
		<size>10</size>
		<action>enregistrer_contact</action>
		<value>Enregistrer</value>
		<tabindex>10</tabindex>
    </champ>	
   <champ id="barre_etat" displayOrder="18" type="Label" position="" x="11" y="502" width="429" height="30" zindex="0" isInGroup="-1"  cssClass="">
		<align>left</align>
        <color>#404630</color>
		<size>12</size>
		<italic>true</italic>
        <value/>
    </champ>
</ecran>

Dans cette version à ce niveau de l'avancement du développement, tous ces fichiers ont été créé manuellement pour définir le contenu de chaque écran (champs et actions) et l'enchaniement entre eux.
L'objectif de la prochaine version est de créer un concepteur d'écrans (un dessinateur à priori en SVG) dont le rôle est de faciliter la génération de ces fichiers XML à partir d'un dessin graphique.

Cette mise à jour, permet de sauvegarder une application générée dans une instance dans la base de données et dans un fichier pour pouvoir l'exécuter à la demande en tant qu'instance (même si l'application est instanciée elle restent dynamique au niveau de la structure, données et traitements php car elle reste liée à ses sources qui sont dans les dossiers "ecrans" et "actions")
Elle permet aussi de générer des feuilles CSS pour les écrans à partir des définitions XML des écrans. Ce qui rend la maintenance des styles CSS des écrans aisées.
Bien sûr, le formalisme XML (balises, attributs, ....) que j'ai choisi pour définir les écrans, leurs champs et les actions, est pour l'instant expérimental, il y a encore des redondances et des structures prévues non utilisées. Pour l'instant le générateur automatique de code fait la traduction XML en PHP/HTML mais l'objectif est le faire évoluer vers une génération multiplateforme (cross-platform screen design). Mais tout cela sera affiné au fil de l'eau.


En attendant la prochaine version majeure, portez vous bien. :wink:
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

02 févr. 2013, 01:44

Nouvelle mise à jour (évolution du formalisme XML et de la génération du CSS) : http://dl.free.fr/kyY0CpFYB :wink:
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Petit nouveau ! | 1 Messages

02 juin 2013, 10:11

Nouvelle mise à jour (évolution du formalisme XML et de la génération du CSS) : dl.free.fr/kyY0CpFYB :wink:
Je suis désolé. "Fichier inexistant."

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

02 juin 2013, 19:48

Merci d'avoir signalé ce lien cassé, voici le nouveau : Dernière Version de l'application M3e
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène