[Application 60]»EvalueResto » : Une miniApp avec AngularJs-Php-Mysql-BootstrapCss et du scaffolding php.

evalue

Introduction


Une petite micro application qui permet à des intervenants de noter des restaurants par étoiles, éventuellement sur leurs portables.
L’administrateur ajoute les restaurants et les intervenants, par l’intermédiaire de pages soumises à mot de passes.

Le front end est du angularjs 1.5, le back end est du Php-Mysql, le style est Bootstrap.css.

Cependant, dans cet exercice j’ai principalement étudié :

  • Le scaffolding pour la création des tables SQL .
  • Les clefs étrangères .

Durée de l’exercice : A peu près 1 jour et demi.

Pour tester, c’est ici 

Le mot de passe du scaffolding est user:admin pass:pass

Bien sur, cette application est modifiable à l’infini.

Photo de l’exercice au jour 1


photo1.jpg

Quest ce que le scaffodling Php-Mysql?


Le scaffolding PHP est incroyable, cela permet de générer automatiquement le code PHP pour requêter sur une table SQL, ou même sur tout une base de données. Ce code est de type CRUD (créer lire mettre à jour supprimer), et crée un site WEB permettant de gérer toute notre base de données automatiquement, bien sur on peut inclure ce site web dans une application.

En d’autres termes, on crée la table SQL qui nous vient à l’esprit, ( Par exemple dans le cadre d’un projet UML), puis on fait un dump de cette table, on la soumets au logiciel Php de scaffolding, qui crée automatiquement tout le site web qui nous permettra de consulter ces tables. Pour voir à quoi ressemble un Dump de tables SQL, voir la fin de ce post.

Il en existe plusieurs types, du plus simple, pour une seule table, aux plus complexes qui gèrent l’insertion d’un dump complet de base de données et permettent également les jointures, et le tri :

  1. http://www.phpscaffold.com : permet la création dun site mais pas le tri des tables dans le site web généré.
  2. phpscaffold-master , qui permet le tri et la recherche dans le site web généré, c’est celui que j’utilise dans ce projet. Il permet aussi l’authentification et accepte les dumps complets de base de données.
  3. http://xcrud.com/demos/ est plus évolué et utilise Jquery, il permet surtout la jointure entre les  tables.
  4. http://www.grocerycrud.com/bootstrap-theme est vraiment super, par contre il faut utiliser le framework codeigniter pour l’installer.

Voici Grocery Crud en action, par exemple :

grocerycrud.jpg

Note :  JAVA permet également d’aller plus vite avec des technologies de ce type et avec JPA.

Note 2 : Il existe également du scaffoolding pour les apps MEAN avec node.js, mais c’est assez compliqué c’est avec Yeoman.

Mais c’est un peu nul de tout faire automatiquement … Le site WEB créé n’a donc pas de personnalité ?


L’idée, est de ce servir du générateur sur les tables simples, pour que l’admin puisse peupler l’application WEB, pour aller beaucoup plus vite… Mais lorsqu’il va falloir faire des jointures sur les tables pour les parties complexes de l’application, alors, je coderais moi même les requêtes les plus compliquées, et le code angularJS.

La conception et le code… au jour 1 .


La base de donnée :

Tout d’abord, je réalise sur le papier mes tables SQL en fonction du projet, je m’inspire de Uml  (Durée : 15 minutes).

Le projet mets en relation

  • Les intervenants : Ce sont les personnes qui, comme dans le film ‘L’aile ou la cuisse’ vont aller évaluer les restaurants tous les midi.
  • Les restaurants : Ce sont les restaurants à évaluer.
  • Les évaluations … C’est la liste de toutes les évaluations par restaurant, et par intervenant.

On peut déterminer que :

  • Si un intervenant est supprimé, alors ces évaluations doivent être supprimées (En sql, on appelle cela la cascade)
  • Si un restaurant est supprimé, alors ces évaluations doivent être supprimées en cascade.
  • De ce fait, la réciproque est également vraie, si un intervenant ou un restaurant est présent, alors, ses évaluations ne peuvent pas être supprimées.

Je crée donc les clefs étrangères et les contraintes d’intégrité en conséquence. Je mets également en place, bien sur sur les clefs primaires, Not Null etc … (Pas encore fait au jour 1, on peut le faire après)

J’obtiens ainsi mon MCD.

Je crée toutes mes tables à l’aide du logiciel Mysql Workbench.

Le scaffolding Php Mysql: 

Durée : 5 minutes
Je peux voir que la table restos et la table intervenants peuvent être modifiées telles quelles dans l’application, l’administrateur aura besoin de faire du CRUD directement dessus…

Evidemment, je ne vais pas m’embéter à créer tout le code back end et front end pour cela alors qu’un générateur Php peut le faire pour moi.

Je fais donc un DUMP de mes 2 tables dans mysqlWorkench(cliquer surServer/DataExport)

Ensuite, j’ai 2 choix soit, je copie -colle le dump dans ce site WEB : http://www.phpscaffold.com puis je récupère tous les fichiers qui vont me permettre de gérer ma BDD dans mon appliciation web.

Le problème avec ce site, c’est que les pages générées ne permettent pas ni le tri, ni la pagination, je choisis donc d’utiliser phpscaffold-master qui est plus évolué mais fonctionne de même sauf qu’il faut le télécharger sur son serveur localhost.

Je passe sur les détails pour faire fonctionner phpscaffold-Master, hormis qu’il faut le traduire en français dans le code.

Pour faire simple, phpscaffoldmaster génére des fichiers que je place dans le répertoire de mon application web dans un sous répertoire nommé CRUD.

L’arborescence de l’app:

arbv

La logique Technique :

Voici la logique technique exprimée par un graphique, sauf que dans notre cas, il n’y a qu’une seule vue, un seul controleur, et pas de routing de vues…

file-page1

La page index.html

La page index.html comprends comme d’habitude le chargement des librairies en début de pages(Que l’on a téléchargé dans notre site avec BOWER), puis un menu, qui pointe sur :

  • Les templates qui ont été générés par phpscaffold-master
  • Un template personnel html, bati avec angularJs et un controleur, qui pointera sur un back end perso…

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Neutre</title>
	<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">

		<!-- CHARGEMENT DES LIBRAIRIES -->

		<!-- JQUERY ET BOOTSRAP -->
		<script src="bower_components/jquery/dist/jquery.min.js"></script>
		<script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
		<link rel="stylesheet" type="text/css" href="bower_components/bootstrap/dist/css/bootstrap.min.css">

		<!-- ANGULARJS -->
		<script src='bower_components/angular/angular.min.js'></script>
		<script src="bower_components/angular-locale_fr-fr/angular-locale_fr-fr.js"></script>
		<!-- UI BOOTSTRAP -->
		<script src="bower_components/ui-bootstrap/src/ui-bootstrap-tpls-0.14.3.min.js"></script>
		<!-- PERSO -->
		<script src="js/app.js"></script>  			<!-- Chargement des modules AngularJs et du routing de vues -->
		<script src="js/generalCtrl.js"></script>  	<!-- Chargement  du controleur -->
		<link rel="stylesheet" type="text/css" href="css/style.css">

		<!-- FIN DE CHARGEMENT DES LIBRAIRIES -->
</head>
z
<body ng-app="neutre" ng-controller="generalCtrl">

<!--  MENU -->
<div class="row">
	<div class="col-sm-2">
		<ul class="nav nav-tabs nav-stacked nav-pills" role="tablist">
			<li ng-class="{'active': view_tab == 'tab1'}">
				<a class="btn-lg" ng-click="changeTab('tab1')" href=""><span class="glyphicon glyphicon-glass" aria-hidden="true"></span> Restos</a>
			</li>
			</li>
			 <li ng-class="{'active': view_tab == 'tab5'}">
				<a class="btn-lg" ng-click="changeTab('tab5')" href=""><span class="glyphicon glyphicon-user" aria-hidden="true"></span> Intervenants</a>
			</li>
			<li ng-class="{'active': view_tab == 'tab6'}">
				<a class="btn-lg" ng-click="changeTab('tab6')" href=""><span class="glyphicon glyphicon-star-empty" aria-hidden="true"></span> Evaluer un Resto</a>
			</li>

		</ul>
	</div>
	<div class="col-sm-9">
		<div >
			<div class="tab-pane" ng-show="view_tab == 'tab1'">
				<iframe class="table" style="min-height:600px;" ng-src="{{'crud/restos/index.php'}}"></iframe>
			</div>

			</div>
			<div class="tab-pane" ng-show="view_tab == 'tab5'">
				<iframe class="table" style="min-height:700px;" ng-src="{{'crud/intervenants/index.php'}}"></iframe>
			</div>
			<div class="tab-pane" ng-show="view_tab == 'tab6'">
				<div ng-include="'vues/evaluer.html'"></div>
			</div>

		</div>
	</div>
</div>		

</body>
</html>

Explication du code :

Certains onglets ouvrent des IFRAMES qui affichent les pages web générées par phpScaffold, il n’y a rien à faire du tout !
Par contre, pour l’application en elle même on affiche une vue appelée evaluer.html, qui va tourner avec angularJs.

La vue Evaluer.html

c’est donc la vue qui va nous permettre d’évaluer nos restaurants… elle tourne en adéquation avec le controleur angularJs appelée generalCtrl, et elle lance des appels au back end PHP, qui est un fichier nommé crud.php. Cette vue nécessite des jointures SQL, voici pourquoi on ne peut pas utiliser de générateur scaffold pour la réaliser.

<br>
<div class="row">

	<div class="col-lg-6">
		<div  class="panel panel-primary ">
			<div class="panel-heading">
				<span class="glyphicon glyphicon-user" aria-hidden="true"></span><h3 class="panel-title"> Votre identité</h3>
			</div>

			<div class="panel-body" style="min-height:600px"><br>
				<div class="form-group" >
					<select class="form-control col-xs-5" ng-model="intervenants.selected" title="Selectionner le film " ng-options="intervenant.nom for intervenant in intervenants | orderBy:'intervenant.nom'" ng-change="getEvaluations()" required>
						<option value="" >---Sélectionnez votre nom---</option>
					</select>
				</div>

				<img src = "img-intervenants/{{intervenants.selected.photo}}" class = "" style ="width : 200px; height:200px;" ng-show="intervenants.selected.photo"></img>
				<br> {{intervenants.selected.prenom}} <b>{{intervenants.selected.nom}}</b><br> 

				<h3 class="panel-title">LISTE DE VOS EVALUATIONS:</h3>
				<div style="height:200px;overflow:auto" >
					<div ng-repeat="evaluation in evaluations">
						<button class="btn btn-block" ng-click="chargeEvaluation(evaluation)">Resto :{{evaluation.nom}}, Note Globale: {{evaluation.noteglobale}} , idevaluation {{evaluation.idevaluation}}<br>
					</div>
				</div>
			</div>

			<div class="panel-footer text-right">
				!
			</div>
		</div>
	</div>

	<div class="col-lg-6">
		<div class="panel panel-warning ">

			<div class="panel-heading">
				<span class="glyphicon glyphicon-star-empty" aria-hidden="true"></span><h3 class="panel-title"> Votre évaluation</h3>
			</div>

			<form name="myForm">
			<div class="panel-body" style="min-height:600px"><br>
				<select ng-show="montreBtnSelectResto" class="form-control col-xs-5" ng-model="restos.selected" title="Selectionner le film " ng-options="resto.nom for resto in restos | orderBy:'resto.nom'"  ng-required="actionBouttonValider=='new'">
					<option value="" >---Sélectionnez le resto---</option>
				</select>
				<b>
				{{restos.selected.nom}}
				{{restos.selected.adresse}}<b>
				<br><br><br>
				<div class="form-group input-group g">
					<span class="input-group-addon"> <img src = "img-app/global.png" class = "" style ="width : 30px; height:30px;"></img>  Note globale</span>
				<rating ng-model="nouvelleEvaluation.noteglobale" 	  max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = 0" required></rating>
				</div>	

				<div class="form-group input-group g">
					<span class="input-group-addon"> <img src = "img-app/service.jpg" class = "" style ="width : 30px; height:30px;"></img> Service </span>
				<rating ng-model="nouvelleEvaluation.service" 	 max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>
				</div>	

				<div class="form-group input-group g ">
					<span class="input-group-addon"> <img src = "img-app/ambiance.png" class = "" style ="width : 30px; height:30px;"></img> Ambiance</span>
				<rating ng-model="nouvelleEvaluation.ambiance" 	 max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>
				</div>
				<div class="form-group input-group g">
					<span class="input-group-addon"> <img src = "img-app/attente.png" class = "" style ="width : 30px; height:30px;"></img> Attente</span>
				<rating ng-model="nouvelleEvaluation.attente" 	 max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>
				</div>
				<div class="form-group input-group g">
					<span class="input-group-addon"> <img src = "img-app/caisses.png" class = "" style ="width : 30px; height:30px;"></img> Caisses  </span>
				<rating ng-model="nouvelleEvaluation.caisses" 	 max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>
				</div>
				<div class="form-group input-group g">
					<span class="input-group-addon"> <img src = "img-app/cuisine.jpg" class = "" style ="width : 30px; height:30px;"></img>Cuisines</span>
				<rating ng-model="nouvelleEvaluation.cuisines" 	 max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>
				</div>
				<div class="form-group input-group g">
					<span class="input-group-addon"> <img src = "img-app/toilettes.png" class = "" style ="width : 30px; height:30px;"> Toilettes</span>
				<rating ng-model="nouvelleEvaluation.toilettes" 	 max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>
				</div>
			</div>

			<div class="panel-footer text-right">
			<button class= "btn " ng-click="newEvaluation()">Nouveau</button>
				<button class= "btn" ng-click="myForm.$valid && check(action())">Valider</button></form>
				<div  ng-show="alertMsg.show"  class="alert alert-success " role="alert" ><strong>Bien Joué</strong> Opération enregistrée. </div>
			</div>
		</div>

	</div>
</div>

general.js

Voici ensuite le controleur AngularJs general.js qui lance des appels à crud.php, en fonction de ce que demande la vue evaluer.html :

/* CONTROLEUR DE LA VUE ACCUEIL */
app.controller('generalCtrl', function($scope,$http, $timeout) {	

$scope.max = 10; // notation max par étoiles
$scope.nouvelleEvaluation = {}; // va contenir toutes les notes des évaluations.

/* Gère le clic sur les onglets */
$scope.changeTab = function(tab) {
    $scope.view_tab = tab;
}

/* Gère le clic sur le bouton Valider (il a des actions differentes)*/
$scope.check = function(){

	if($scope.actionBouttonValider=='maj'){
		majEvaluation();
	}
	else if($scope.actionBouttonValider=='new'){
		insertEvaluation();
	}
	else {

	}
}

/*Charger une evaluation  unique existante*/
$scope.chargeEvaluation = function(evaluation){
	$scope.actionBouttonValider = 'maj';
	$scope.montreBtnSelectResto = false;
	$scope.nouvelleEvaluation = evaluation;

}

/* Créer une nouvelle evalution */
$scope.newEvaluation = function(){
	$scope.actionBouttonValider = 'new';
	$scope.montreBtnSelectResto = true;
	$scope.nouvelleEvaluation = {};
}

 /* Montrer un message Bootstrap sur click. */
 $scope.alertMsg = {
        show: false,
        text:"Alert message is ::show"
    };
    $scope.showAlert =function(){
         $scope.alertMsg.show = true;
        $timeout(function(){
            $scope.alertMsg.show = false;
        }, 2000);
    }

/* ------------------------------------------TOUT LE CRUD----------------------------------------------- */

/* Charger les intervenants dans le menu déroulant */
$http.get('crud.php?action=get_intervenants').success(function(data){
            $scope.intervenants = data;
			console.log(data);
    }).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});

/* Charger les restaurants dans le menu déroulant */
	$http.get('crud.php?action=get_restos').success(function(data){
				$scope.restos = data;
		}).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});

/* Get les évaluation d un intervenant*/
$scope.getEvaluations = function(){
	var k = angular.copy($scope.intervenants.selected.id);
	/* Charger la liste des evaluations déjà faites */
	$http.post('crud.php?action=get_evaluations',{'idintervenant':k}).success(function(data){
				$scope.evaluations = data;
				console.log(data);
	   }).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});
}

/* Enregistrer l evaluation d un restaurant faite par un intervenant */
function insertEvaluation() {

	/* Préciser de qui et de quel resto est l evaluation */
	$scope.nouvelleEvaluation.idintervenant = parseInt($scope.intervenants.selected.id);
	$scope.nouvelleEvaluation.idresto 		= parseInt($scope.restos.selected.id);

	/* Insérer l évaluation */
	if($scope.intervenants.selected.id){
	$http.post('crud.php?action=insert_evaluation',$scope.nouvelleEvaluation).success(function(data){
		console.log(data);
		$scope.showAlert();
	   }).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});
	}
	else{
		alert('erreur');
	}
}

/* Mettre à jour l evaluation d un intervenant */
function majEvaluation() {

	$http.post('crud.php?action=maj_evaluation',$scope.nouvelleEvaluation).success(function(data){
		console.log(data);
		$scope.showAlert();
	   }).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});

}

/* FIN DU CONTROLEUR */
})

crud.php

Et puis finalement, le plus sympa, le fichier PHP qui requête Mysql… On remarque que le switch en début de script route les demandes du controleur Angular… Chaque résultat obtenu est ensuite renvoyé au format JSON, puis récupéré dans la fonction de rappel des fonctions $http du controleur AngularJS. Comme d’hab on fait du mapping objet-relationnel. EDIT : J’utilise désormais mysql_fetch_assoc() qui permet de récupérer une table SQL en un rien de temps, sans rien écrire ! Merci Sabotage sur developpez.com. Les injections SQL ne sont pas encore traitées. L’insertion d’une nouvelle évaluation (insert_evaluation()) est désormais auto adaptative, ce qui signifie que si le FRONT END envoye plus de données, si l’on rajoute des champs dans la vue par exemple, et bien il n’y a plus besoin de remanier le Back end, par contre il faudra ajouter les nouvelles colonnes dans la table SQL bien sur . J’ai également rendu la requête UPDATE dynamique.


<?php

include('connexionConfig.php'); 
mysql_set_charset('utf-8');  /// très important
/* header( 'content-type: text/html; charset=utf-8' );  */
error_reporting(E_ALL ^ E_NOTICE); // important pour ne pas afficher les notice PHP sans cela le script ne marche pas.
 
/**  Switch Case pour récupérer la l'action demandée par le controleur  Angular **/
  
switch($_GET['action'])  {
    case 'get_intervenants' :	get_intervenants();
    break;
	case 'get_restos' :			get_restos();
    break;
	case 'get_evaluations' :	get_evaluations();
    break;
    case 'insert_evaluation' :	insert_evaluation();
    break;
	case 'maj_evaluation' :		maj_evaluation();
    break;
}
 
/*Function qui récupère les catégories: */
 function get_intervenants() {  
     
    /* SQL. */
    $q = "SELECT * from intervenants ORDER BY nom"; 
    $qry = mysql_query($q);
      
     /* Mets le resultat  dans un tableau . */
     while($row = mysql_fetch_assoc($qry))
        {
        $tab[]= $row;
        }
    /* Convertit en JSON  */    
    print_r(json_encode($tab));
    exit();     
         
}
 
 /*Function qui récupère les restos: */
 function get_restos() {  
     
    /* SQL. */
    $q = "SELECT * from restos ORDER BY nom"; 
    $qry = mysql_query($q);
      
     /* Mets le resultat  dans un tableau . */
      while($row = mysql_fetch_assoc($qry))
        {
        $tab[]= $row;
        }
    /* Convertit en JSON  */    
    print_r(json_encode($tab));
    exit();     
         
}
 
 /*Function qui récupère les evaluations dun intervenant: */
 function get_evaluations() {  
  $data = json_decode(file_get_contents("php://input"));   


$idintervenant   	= $data->idintervenant;   

	
 /* SQL. */
 $q = "SELECT evaluations.*,restos.nom from evaluations inner join restos on evaluations.idresto=restos.id  WHERE  idintervenant='".$idintervenant."'"; //marche 

$qry = mysql_query($q);
      
    
    /* Mets le resultat  dans un tableau . */
      while($row = mysql_fetch_assoc($qry))
        {
        $tab[]= $row;
        }
         
    print_r(json_encode($tab));
    exit();     
         
}

/*Function qui insère les notes d un resto (elle est auto adaptative on peut envoyer plus de données si on veut dans de nouvelles colonnes il n'y a rien à modifier): */
 function insert_evaluation() {  

/* Récupération des données POST */
 $data = json_decode(file_get_contents("php://input"), true); 

/* ELABORATION DE LA REQUETE DINSERTION DYNAMIQUE  */
$columns = implode(",",array_keys($data));

$escaped_values = array_map('intval', array_values($data));
$values  = implode(",", $escaped_values);

/* SQL. */
$q = "INSERT INTO evaluations (idevaluation,".$columns.") VALUES (null,".$values.")";

$qry = mysql_query($q);
      
 if ($qry) {
        $arr = array('msg' => "Impression enregistree avec succès!!!", 'error' => '');
        $jsn = json_encode($arr);
        // print_r($jsn);
    } else {
        $arr = array('msg' => "", 'error' => 'Erreur dans la mise à jour de l enregistrement');
        $jsn = json_encode($arr);
        // print_r($jsn);
    }
    exit();  
         
}

/*Function qui maj les notes d un resto: */
 function maj_evaluation() {  
 
	/* Récupération des données POST POUR USAGE IMMEDIAT AVEC SYNTAXE DU STYLE $dataFull->idevaluation  */
	 $dataFull = json_decode(file_get_contents("php://input"));

	/* Récupération des données POST POUR MANIPULATION PHP*/
	$data = json_decode(file_get_contents("php://input"), true);    

	 /* CONVERSION DES DONNES EN TABLEAUX PHP POUR INSERTION DYNAMIQUE DANS LA BOUCLE FOR  */
	$columns = array_map('strval',array_keys($data));
	$escaped_values = array_map('intval', array_values($data));


	/* Oblige de supprimer idevaluation des arrays parce que il ne peux pas être mis a jour dans un update cest la clef primaire. */
	array_shift($columns);
	array_shift($escaped_values);

	for($i=0;$i<sizeof($columns);$i++){
		$q = "UPDATE test.evaluations SET ".$columns[$i]." = ".$escaped_values[$i]." WHERE  idevaluation=".$dataFull->idevaluation." ";
		$qry = mysql_query($q);
		echo($q); 
		if ($qry) {
			$arr = array('msg' => "Impression enregistree avec succès!!!", 'error' => '');
			$jsn = json_encode($arr);
			print_r($jsn);
		} else {
			$arr = array('msg' => "", 'error' => 'Erreur dans la mise à jour de l enregistrement');
			$jsn = json_encode($arr);
			print_r($jsn);
		}        
	}
}


/* ANCIENNE REQUETE NON DYNAMiQUE */

/* $q = "UPDATE test.evaluations SET noteglobale='".$data->noteglobale."',service='".$data->service."',ambiance='".$data->ambiance."',attente='".$data->attente."',caisses='".$data->caisses."',cuisines='".$data->cuisines."',toilettes='".$data->toilettes."' WHERE  idevaluation='".$data->idevaluation."' "; 

$qry = mysql_query($q); */
      

?>

Pour info, voici le dump SQL qui m’a permit de créer automatiquement les pages Restos et Intervenants de mon application (C’est cela qu’il faut copié coller dans le site http://www.phpscaffold.com pour obtenir des pages HTML qui fonctionnent … :

-- MySQL dump 10.13  Distrib 5.7.12, for Win32 (AMD64)
--
-- Host: 127.0.0.1    Database: test
-- ------------------------------------------------------
-- Server version	5.7.13

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `intervenants`
--

DROP TABLE IF EXISTS `intervenants`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `intervenants` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nom` varchar(45) DEFAULT NULL,
  `prenom` varchar(45) DEFAULT NULL,
  `photo` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `intervenants`
--

LOCK TABLES `intervenants` WRITE;
/*!40000 ALTER TABLE `intervenants` DISABLE KEYS */;
INSERT INTO `intervenants` VALUES (1,'Jobert','Philippe','1.jpg'),(2,'Andre','Dupont','2.jpg'),(3,'Aziz','Benhammed','3.jpg');
/*!40000 ALTER TABLE `intervenants` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `restos`
--

DROP TABLE IF EXISTS `restos`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `restos` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nom` varchar(45) DEFAULT NULL,
  `adresse` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `restos`
--

LOCK TABLES `restos` WRITE;
/*!40000 ALTER TABLE `restos` DISABLE KEYS */;
INSERT INTO `restos` VALUES (2,'Chez Dubois','fezfez'),(3,'La Taverne','rehreh'),(4,'Le clocher','12 rue de lilas'),(5,'Chez Laurent','12 Rue des lis');
/*!40000 ALTER TABLE `restos` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2016-08-01  3:11:47

Mais, moi je voudrais que les intervenants puissent ajouter l ‘évaluation de leur choix et la nommer, avec un bouton +

Nous verrons au jour 2 comment modifier la table évaluations et le code angularjs afin de faire cela( Il y aura un ng-repeat sur les ratings).

Publicités