[Application 53] « TrouveTonFilm » AngularJs + Php-Mysql + Template Sb Admin 2- Mixte Desktop-Tél Mobile

Introductionlogo


Exercice sur 2 semaines d’une application de gestion de films, en partant de zéro .

J’utilise AngularJs en Front end, l’application est mixte desktop et téléphones mobile avec un back-end à base de données relationnelle en Php-Mysql.

L’exercice se concentre sur les clefs étrangères, la gestion des transactions SQL, et la gestion du template sb admin 2. Pas de gestion de stock, mais c’est évolutif.

L’exercice se concentre aussi sur la création de directives AngularJS pour les fonctionnalités « bateau » du type « Recherche », « Filtrage », « Commande » etc …

Pour tester l’application c’est ici

Photo de l’app :


app53

Explication Fonctionnelle :


L’utilisateur recherche un film après avoir choisi la catégorie dans un menu déroulant.

Des cases à cocher permettent d’ajouter des critères de recherche comme « +18ans » ou « mauvaises notes »

Il peut ensuite en voir les acteurs et l’histoire puis noter les films et donner ses impressions. Les notes seront attribuées par des jQuery Knob, c’est très esthétique.

L’admin peut créer les films, des catégories et uploader les images. Tout est pris en compte automatiquement ensuite.

Des statistiques graphiques sur les nombres de films et les notes des utilisateurs sont générés à partir d’appels Sql Back-end.

Journal :


Jour 1 : Mise en place du Framework et de la Bdd Mysql, première vue des films :(4h code)

Jour 2 : Possibilité d’ajouter des impressions sur les films  (3h code)

Jour 3 : Mise en place de l’administration, table des dernières impressions enregistrées, possibilité d’ajouter un film(Pas encore l’image) (4h code) avec un multiSelect sur les acteurs. En cours   : le Chat.
<

Jour 4 : Activation du Chat, Posibilité d’ajouter un acteur, ajout de mysql_escape_string, Ajout de catégories. Durée : 3h30

Jour 5 : Activation du calendrier des Impressions, modification du comportement lors de l’ajout d’une note, Création d’un menu d’administration. Durée : 3h00 . Problèmes : Lazy Loading du calendar ne se lance pas après appui sur F5, les appels $http ne sont pas dans un service mais pour l’instant c’est fait exprès (lab), Lorsque l »on bouge le calendrier par mois, le modèle n’est pas gardé. Il faut desactiver la fonction $interval du chat lorsque l’on change de vue.calendar

Jour 6 :
VUE tableau de bord :
.Toujours sur le debbuging du behavior des données dans le calendrier, il sera multifonction.
.Requête Nombre de films

VUE »films » :
.Ajout de la lib Angular.Js Knowb pour les statistiques,
.Remodeling léger du système de notes

VUE « Gérer les données » :
.Testing d’un crud automatisé PHP avec http://www.phpscaffold.com(Il y en a de bien plus beaux et qui trient) inclus dans une balise iFrame.

Durée 3h30

Jour 7:
. Activation de 2 sources de données différentes dans le calendrier, sur dropdown
. Mise en place de la moyenne des notes
. Ajouts de trailers des films(Pas encore dans le form)

Durée 3h00

Jour 8:
. Ajout d’une connexion à l’API IDBC
. Ajout d’une traduction sommaire ( L’api translate de google est demi payante, je ne peux donc pas l’utiliser)
. Ajout de premieres stats graphiques ( Problèmes d’affichage sur mobile 5 pouces)
. Gros problème concernant le dropdown sur mobile 5 pouces, le keyboard s’affiche ! Je vais le remplacer par ddSlick.
. Création des directives pour la recherche, les filtres la commande, la fiche d’un film, c’est pratique.

Durée 6h00
En prévision :
. Débugguer le lazy loading du calendrier
.Finaliser le formulaire de commandes
.Ajouter la carte des visiteurs
. Développer le système d’importation de films provenant de l’API IDBC vers la base MYSQL
. Débugger les \ dans mysql et élaborer les trucs anti hacking
. Activer le filtrage RANGE de recherche par date de production du film.
. Activer l’infinte scvrolling définitif
.Activer les menus supérieurs.
. Faire du testing de clefs étrangères et des transactions rollback lors d’une commande.
. .Placer les les accès $http dans des services.

Jour 9:
. Développement d’un système de filtrage par date de production du film. Du coup, les requêtes Sql sont additives dans le script PHP en fonction de ce que dis la requête angularJS. J’avoue que ça a compliqué notamment le code angularJs et qu’il y a probablement moyen d’écrire ça beaucoup plus clair quand je mettrais les accès $http dans le service. Ce qui est embétant c’est que les rqts différent si l’utilisateur utilise ou nom le choix par catégories.
. Commencement du dispatching des fonctionalités dans des directives(Recherche, Commande, Recherche ombd) , reste à passer la div d’un film au format directive AngularJs, le code sera très clair comme cela.
(Durée 3h30.)

Jour 10:
.Hacking non autorisé de imdb pour obtenir les photos des films.
.Mise en place de autocomplete avec l’api wikipedia
. Activation du infinite scroll
. Activation de la MAJ de la liste des acteur lords de l’ajout d’un acteur

Système :


file-page1

Notes :


La Bdd relationelle est donc beaucoup moins flexible et pratique que Firebase et le noSql. Mysql implique un retard de 85 % de perte de temps en dev Backend par rapport à Firebase, mais il faut savoir le faire quand même. Pour faire simple, avec Firebase, quand il faut ajouter des champs à l’application, il n’y a rien à faire sur le back end, tout est automatique, alors qu’avec mySql, il faut sans arrêt rajouter des champs dans la base de données, se re-taper le back end etc… C’est super lourd. L’avantage est que les bases SQL sont bien connues par beaucoup de monde et peuvent être placées ou on veut. Et puis … Firebase, c’est le Cloud… Avec tout ce que cela implique, mais c’est beau de rêver à des apps tournant la dessus…

Phases de développement :


Phase 1 : Création de la Base de données (Durée entre 45 minutes et 1 heure)

Création de la base de données, des clefs primaires, index et clefs étrangères dans MYSQL en mode InnoDb( Pour les futures gestion de transaction:

mysql1

Explications :

  • Les clefs étrangères permettent par exemple d’éviter qu’une catégorie puisse être supprimée tant qu’il y a des films qui font référence à cette catégorie.
  • Les tables avec un underscore_ sont des tables permettant la liaison de 2 tables avec une relation n à n. Par exemple, un film pouvant avoir plusieurs notes données par plusieurs utilisateurs, il faut une table entre les deux tables films et notefilm qui permet la liaison entre les deux tables. Voici à quoi ressemble une table « intermédiaire » film_notefilm :myslql2
  • Les transactions permettent d’annuler une transaction non finalilsée de commande en cas de coupure d’électricité par exemple.
  • Quelques études de verrous éventuellement.

Phase 2 : Upload du template sur le serveur et programmation Front-end avec AngularJs / et Back End avec Php/Mysql (Durée 4h):

Le code :


On est dans un template, il y a donc des vues différentes. Le premier jours, on a une seule vue, home.html.
Attention, il faut exclusivement utiliser les classes CSS du template, c’est du Bootstrap 3.
Là, ma vue pointe sur des directives, c’est pratique pour modifier telle ou telle directive en fonction de sa fonctionalité.
:

<div class="row">
     	
	<!-- DIRECTIVE RECHERCHE -->
	 <recherche></recherche> 
	
	<!-- DIRECTIVE RECHERCHE SUR OMDB-->
	<rechercheomdb></rechercheomdb>

	<!-- DIRECTIVE COMMANDE -->
	<commande></commande>
		
</div>	
	
	<!-- AFFICHE LES FILMS OMDB -->
	<omdb></omdb>
	<!-- DIRECTIVE QUI AFFICHE LES FILMS -->
	<films></films>

<footer id="footer" >
	<div class="row">
	</div>
</footer>
	

Un exemple de directive, la directive de recherche :


<div class="col-lg-6">
	<div class="panel panel-warning">
		
		<div class="panel-heading"><i class="glyphicon glyphicon-search"></i>
			Choisis le film dans ta base de données: {{nomsFilms.length}} 
		</div>
		
		<div class="panel-body">
			<div class="form-group">
				
				<angucomplete-alt id="ex1"placeholder="Tape un nom de film" pause="100" selected-object="filmSelectionne" local-data="listeNomsFilms" search-fields="nom" title-field="nom" minlength="1"input-class="form-control form-control-small"  match-class="highlight" ></angucomplete-alt><br>

				<ui-select id="jojo" type="text" ng-model="CategorieSelect.selected" ng-change="rechercheParCategorie()" >
					<ui-select-match placeholder="Selectionner une catégorie">
						<img ng-src="img-app/{{ $select.selected.image }}" style ="width:20px;"/> {{$select.selected.nom}}</ui-select-match>
					<ui-select-choices repeat="categorie in listeCategorie" >
						<img ng-src="img-app/{{ categorie.image }}" style ="width:50px;"/>
						<div ng-bind-html="categorie.nom" style="display: inline"></div>
					</ui-select-choices>
				</ui-select>
					
			</div>
			 
			 <div class="form-group" ng-if="afficheMenuFilm">
				<select class="form-control col-xs-5" ng-model="films.selected" title="Selectionner le film " ng-options="film.nom for film in nomsFilms | orderBy:'film.nom'" ng-change="selectionnerFilm(films.selected.idFilm)"> 
					<option value="" >---Sélectionnez le Film---</option>
				</select>
			</div>
		</div>
		
		<div class="panel-footer text-right">
			Filtrer par date de production :
			<select  ng-model="filtres.dateDebut" title="année Début">
				<option ng-repeat="annee in annees track by $index" value="{{annees[$index]}}">{{annees[$index]}}</option>
			</select> ->
			<select ng-model="filtres.dateFin" title="année Fin">
				<option ng-repeat="annee in annees track by $index" value="{{annees[$index]}}">{{annees[$index]}}</option>
			</select>
			
			
			<!-- <button ng-click="afficher2Suivants()" class="btn">Charger les 2 Suivants</button> -->
		</div>
	</div>
</div>
		
	
	

Le controleur AngularJs de la vue des films, comme on peut remarquer, j’ai mis les accès $http dans le controleur, mais normalement il faut créer de préférence des services.:

'use strict';
angular.module('sbAdminApp')

.controller('MainCtrl', function($scope,$position,$http,$httpParamSerializerJQLike) {
	
	/* INITIALISATIONS */
	var d = new Date();
	$scope.CategorieSelect 		= {}; 	// CONTIENT LA CATEGORIE SELECTIONNEE
	$scope.nouvelleImpression 	= {}; 	// CONTIENT L IMPRESSION D UNE PERSONNE A PROPOS D UN FILM
	$scope.commandes 			= []; 	// CONTIENT LES COMMANDES
	$scope.debutRecherche 		= 0; 	// POUR L INFINITE SCROLLING
	$scope.filtres 				= {}; 	// CONTIENT LES FILTRES DE RECHERCHE
	$scope.annees				= [1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,
									1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,
									2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020,2021];
	window.filtrerRange = false; /* Active le filtrage ou non*/
	 
	 /* SURVEILLE SI L UTILISATEUR VEUT FILTRER LES FILMS PAR DATES */
	 $scope.$watch('filtres', function() {
        // faire quelque chose
		if ($scope.filtres.dateDebut && $scope.filtres.dateFin ){
			if($scope.filtres.dateDebut < $scope.filtres.dateFin ){
				window.filtrerRange = true;
				$scope.debutRecherche = 0;
				$scope.rechercheParCategorie();
			}
			else{
				window.filtrerRange = false;
				alert('La date de début doit être infénieure à la date de fin')
			}
		}
    }, true);
	
	
	/* CHARGEMENT DE LA LISTE DES NOMS DES FILMS POUR L AUTOCOMPLETE: */
	$http.get('filtrer.php?action=autocomplete_noms_films').success(function(data){
			$scope.listeNomsFilms = data; 
	}).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});
	
	/* RECUPERE L ID DU FILM A PARTIR DE L AUTOCOMPLETE PUIS LANCE LA FONCTION DE RECUPERATION DU FILM */
	$scope.filmSelectionne = function (selectionne) {
		console.log(selectionne.originalObject.idFilm); 
		$scope.selectionnerFilm(selectionne.originalObject.idFilm);
	};
	
	/* CHARGEMENT DES LISTE DEROULANTES */
	$http.get('filtrer.php?action=get_categories').success(function(data){
		$scope.listeCategorie = data; 
	}).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});
	
	
	
	 /* TROUVER LES FILMS PAR CATEGORIE */
	$scope.rechercheParCategorie = function(){
		
		if(window.filtrerRange==true){
			if (!$scope.CategorieSelect.selected){
				$scope.CategorieSelect.selected = {};
				$scope.CategorieSelect.selected.idCategorie = "pasDeCategorie";
			}
			
			$http.post('filtrer.php?action=get_films',{'idCategorie':$scope.CategorieSelect.selected.idCategorie,'debutRecherche':$scope.debutRecherche,'dateDebut':$scope.filtres.dateDebut,'dateFin':$scope.filtres.dateFin},{header : {'Content-Type' : 'application/json; charset=UTF-8'}
					}).success(function(data){
				   $scope.films = data;  
				   
			}).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});
			
		}
		else{
			$scope.debutRecherche = 0;
			$http.post('filtrer.php?action=get_films',{'idCategorie':$scope.CategorieSelect.selected.idCategorie,'debutRecherche':$scope.debutRecherche},{header : {'Content-Type' : 'application/json; charset=UTF-8'}
					}).success(function(data){
				   
				   $scope.films = data;  
				   $scope.afficheMenuFilm = true;	
				   getNomsFilms();
				   
			}).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});
		}
		$scope.showInfinite = true;
		
	}
	
	/* REMPLIR LE SELECT CONTENANT LA LISTE DES FILMS EN FONCTION DE LA CATEGORIE */
	function getNomsFilms(){
		$http.post('filtrer.php?action=get_noms_films',{'idCategorie':$scope.CategorieSelect.selected.idCategorie},{header : {'Content-Type' : 'application/json; charset=UTF-8'}
				}).success(function(data){
					$scope.nomsFilms = data;  
		}).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});
		
	}
	
	/* SELECTIONNER UN FILM UNIQUE SUR MYSQL */
	$scope.selectionnerFilm = function(idFilm){
		
		$http.post('filtrer.php?action=get_unique_film',{'idFilm':idFilm},{header : {'Content-Type' : 'application/json; charset=UTF-8'}
				}).success(function(data){
					$scope.films = data;  
		}).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});
		$scope.showInfinite = false;
	}
	
	/* UN PSEUDO AJOUTE UNE NOTE A UN FILM */
	$scope.ajouterNote = function(idFilm){
		if($scope.nouvelleImpression.pseudo && $scope.nouvelleImpression.impression && $scope.nouvelleImpression.note){
			$http.post('filtrer.php?action=post_note',{'pseudo':$scope.nouvelleImpression.pseudo,'impression':$scope.nouvelleImpression.impression,'note':$scope.nouvelleImpression.note,'idFilm':idFilm,'date':d}).success(function(data){
				/* UN AJOUT EN ANGULARJS Supplémentaire POUR L AFFICHAGE TEMPS REEL */
				var x = 0;
				for(x=0;x<$scope.films.length;x++){
					if ($scope.films[x].idFilm == idFilm){
						$scope.films[x].notes.push({'pseudo':$scope.nouvelleImpression.pseudo,'impression':$scope.nouvelleImpression.impression,'note':$scope.nouvelleImpression.note,'idFilm':idFilm,'date':d});
					}
				}
			}).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});
		}
		else{
			alert('tous les champs ne sont pas remplis');
		}
	};
	
	/* DEBUT DE LA FONCTIONNALITE DE COMMANDES */
	$scope.ajouterCommande = function(film){
		$scope.commandes.push({'nom':film.nom});
		
	}
	
	/* FONCTIONNALITE INFINITE SCROLL */
	$scope.afficher2Suivants = function(){
		$scope.debutRecherche = $scope.debutRecherche + 4 ; // On modifie la recherche sur mysql dès que la div infinte scroll a été mouse hover
		
		if(window.filtrerRange == true){
			if (!$scope.CategorieSelect.selected){
					$scope.CategorieSelect.selected = {};
					$scope.CategorieSelect.selected.idCategorie = "pasDeCategorie";
				}
				
				/* APPEL AU SCRIPT PHP AVEC UN ARGUMENT $scope.CategorieSelect.selected.idCategorie */
				$http.post('filtrer.php?action=get_films',{'idCategorie':$scope.CategorieSelect.selected.idCategorie,'debutRecherche':$scope.debutRecherche,'dateDebut':$scope.filtres.dateDebut,'dateFin':$scope.filtres.dateFin},{header : {'Content-Type' : 'application/json; charset=UTF-8'}
						}).success(function(data){
					    var x;
						   for(x=0;x<data.length;x++){
							$scope.films.push(data[x]);  
						   }
				}).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});
		
		
		}
		else{
			$http.post('filtrer.php?action=get_films',{'idCategorie':$scope.CategorieSelect.selected.idCategorie,'debutRecherche':$scope.debutRecherche},{header : {'Content-Type' : 'application/json; charset=UTF-8'}
				}).success(function(data){
			   var x;
			   for(x=0;x<data.length;x++){
				$scope.films.push(data[x]);  
			   }
		}).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});
			
			
		}
	}
	
	
	/* PARAMETRAGE DE L ASPECT GRAPHIQUE DES KNOBS */
	$scope.options = {
		  unit: "%",
		  size:150,
		  skin :{ type: 'simple', width: 10, color: 'rgba(255,0,0,.5)', spaceWidth: 5 },
		  readOnly: true,
		  subText: {
			enabled: true,
			text: 'Note Moyenne',
			color: 'gray',
			font: 'auto'
		  },
		  trackWidth: 20,
		  barWidth: 15,
		  trackColor: '#656D7F',
		  barColor: '#2CC185'
		};
		
	$scope.options2 = {
		  unit: "%",
		   size:150,
		  readOnly: true,
		  subText: {
			enabled: true,
			text: 'Commandes',
			color: 'gray',
			font: 'auto'
		  },
		  trackWidth: 20,
		  barWidth: 15,
		  trackColor: '#656D7F',
		  barColor: '#d60bc9'
		};

		
/* RECHERCHE SUR OMDB	 */	
$scope.$watch('search', function() {
    /* fetch(); */ 
	dropDown();
    });

    $scope.search = "";

    function fetch() {
      $http.get("http://www.omdbapi.com/?t=" + $scope.search + "&tomatoes=true&plot=full")
        .then(function(response) {
			
		if(response.data.Response=='False'){	
				$scope.affOk='';
			}
		else{
			$scope.affOk=true;
			$scope.details = response.data;
			$http.post('filtrer.php?action=telecharge_image_imdb',{'url':$scope.details.Poster,"nomFilm":$scope.details.Title+'.jpg'}).success(function(data){
					   $scope.setup = $scope.details.Title;
				}).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});
			console.log("details "+$scope.details.Poster);
		}
		  console.log(response)
        });
    }

    $scope.update = function(movie) {
      $scope.search = movie.Title;
    };

    $scope.select = function() {
      this.setSelectionRange(0, this.value.length);
    }
		
	function dropDown(){
		var url = "http://imdb.wemakesites.net/api/search?s=all&q="+$scope.search+"&callback=JSON_CALLBACK";
		$http({
			method: 'jsonp',
			url: url,
			responseType: "json"
		}).then(function(response) {
			console.log(response);
          $scope.filmsDropdown = response ; 
        }); 
	}
		
	$scope.setFilm = function(titre){
		$scope.search = titre;
		fetch();
	} 	
		
/* FIN DU CONTROLLEUR */

$scope.myPagingFunction = function(){
	alert('test');
	
}
})


/* ACTIVATION DES TABS */
 jQuery(function () {
    jQuery('#myTab a:last').tab('show');

}) 



Le controleur AngularJs du Tableau de Bord:

angular.module('sbAdminApp')

  .controller('tableauDeBordCtrl', function($scope,$position,$http,$interval) {
   
   /* INITIALISATION */

	var d = new Date();
   /* CHARGEMENT DU NB DE FILMSs */
	$http.get('filtrer.php?action=get_nb_films_total').success(function(data){
			$scope.nbFilmsTotal = data.DECOMPTE;});
   
	/* CHARGEMENT DES 5 DERNIERES IMPRESSIONS */
	$http.get('filtrer.php?action=get_5_dernieres_impressions',
    {header : {'Content-Type' : 'application/json; charset=UTF-8'}}).success(function(data){
					console.log(data);
					$scope.derImpressions = data;
			}).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});
			
	/* AJOUTER UN MESSAGE DANS LE CHAT */
	$scope.ajouterMessage = function(){
		
		if($scope.pseudo && $scope.message){
			$http.post('filtrer.php?action=ajouter_message',{'pseudo':$scope.pseudo,'message':$scope.message,'date':d}).success(function(data){
				$scope.getMessages();
				 $scope.message = "";
			}).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});	
		}
		else 
		{
			alert('Tous les champs ne sont pas remplis');
		}	
	}
	
	/* OBTENIR LA LISTE DES MESSAGES DU CHAT */
	function getMessages(){
		$http.get('filtrer.php?action=get_chat_messages').success(function(data){
					$scope.listeMessages = data;  
					console.log($scope.listeMessages);
					
			}).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});	
		
	}
	
	/* TOUTE LA GESTION DU CALENDRIER */
	
	/* CHOIX DU MODELE DE DONNEES A INSERER DANS LE CALENDRIER */
	$scope.choixDonneesCalendrier = function(choixDonnees){
		switch (choixDonnees)
			{
			   case 'impressions': getImpressions();
			   break;
			   
			   case 'ajouts': getAjouts();
			   break;
			
			}
	}
	
	/* CHARGEMENT DES IMPRESSIONS DANS LE CALENDRIER */
	function getImpressions(){
		$http.get('filtrer.php?action=get_impressions').success(function(data){
			/* Suppression des events anciens. */
			$scope.events.splice(0,$scope.events.length); 
			/* Insertion des Impressions dans le calendrier */
			var x ;
			for (x=0;x<data.length;x++){
				$scope.events.push({'title':data[x].pseudo+' : '+data[x].impression,'type':'gms','start':data[x].date,stick: true})
			}   
			}).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});	
	}
	
	
	/* CHARGEMENT DES FILMS AJOUTES DANS LE CALENDRIER */
	function getAjouts(){
			
		$http.get('filtrer.php?action=get_ajouts').success(function(data){
			/* Suppression des events anciens. */
			$scope.events.splice(0,$scope.events.length); 
			var x ;
			for (x=0;x<data.length;x++){
				$scope.events.push({'title':data[x].nom,'start':data[x].dateAjout,stick: true})
			}   
			}).error(function(data){ $scope.infos = " Pas de données ou pb de connexion"});	
	}
	
	
	
	
	/* PARAMETRAGE DU CALENDRIER */
		
	/* Tableau de Tous les évenements du calendrier, modifiable en temps réel, c'est une tableau d'objets JSON */
	
	/* FORMAT DES EVENTS */
	$scope.events = [
	 /*   {
			title: 'Visite chez le docteur',
			type   : 'gms',
			start  : '2016-03-03 09:00:00',
			end    : '2016-03-03 10:00:00',
			allDay : false
		},
		{
			title: 'Visite chez le docteur',
			type   : 'gms',
			start  : '2016-04-08T11:47:30.910Z',
			end    : '2016-04-08T14:47:30.910Z',
			allDay : false
		} */
		
	  
	]; 

	 /* alert on eventClick */
	$scope.alertOnEventClick = function( date, jsEvent, view){
		alert(date.title + ' was clicked ');
	};
	
	/* Nécessaire pour l'interpretation du calendrier */
	$scope.eventSources = [$scope.events];
	
	  /* configuration du look de l'agenda */
	$scope.uiConfig = {
	  calendar:{
		height: 450,
		selectable: true,
		editable: true,
		
		 defaultView: 'basicWeek',
		header:{
		  left: 'month basicWeek basicDay agendaWeek agendaDay',
		  center: 'title',
		  right: 'today prev,next'
		},
		dayClick: dayClick,
		eventDrop: $scope.alertOnDrop,
		eventResize: $scope.alertOnResize,
		eventClick: $scope.alertOnEventClick
	  }
	};
	 
	function dayClick(date){
		alert(date);
	};
	  
	$scope.alertEventOnClick = function(date) {
		alert('test');
	// change the border color just for fun
	   $(this).css('border-color', 'red'); 
	};
	
	/* alerte sur eventClick */
	$scope.alertOnEventClick = function( date, jsEvent, view){
		$scope.alertMessage = (date.title + ' was clicked ');
	};
	
	/* INITITIALISATION DU CHAT ET DU CALENDRIER */
	getMessages();
	getImpressions(); 
	
	/* RAFRAICHISSEMENT DU CHAT  */
	$interval(function() {
      getMessages();
    }, 10000);
	
	
	
	
	
	
	
})
 

Le fichier PHP qui gère tous les accès MYSQL, c’est très pratique parce que tout est centralisé, du coup on se repère très facilement dans les fonctions avec le switch du début:




<?php


<?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_login' :
            get_login();
            break;
	case 'get_categories' :
			get_categories();
			break;
	case 'get_films' :
			get_films();
			break;
	case 'get_noms_films' :
			get_noms_films();
			break;		
	case 'get_unique_film' :
			get_unique_film();
			break;		
	case 'get_acteurs' :
			get_acteurs();
			break;
	case 'post_note' :
			post_note();
			break;
	case 'get_5_dernieres_impressions' :
			get_5_dernieres_impressions();
			break;
	case 'ajouter_film' :
			ajouter_film();
			break;
	case 'ajouter_acteurs_du_film' :
			ajouter_acteurs_du_film();
			break;
	case 'get_maxIdFilms' :
			get_maxIdFilms();
			break;	
	case 'ajouter_message' :
			ajouter_message();
			break;
	case 'get_chat_messages' :
			get_chat_messages();
			break;			
	case 'ajouter_acteur' :
			ajouter_acteur();
			break;	
	case 'get_nb_films_total' :
			get_nb_films_total();
			break;	
	case 'get_impressions' :
			get_impressions();
			break;			
	case 'get_ajouts' :
			get_ajouts();
			break;
	case 'stats_nb_films_par_categorie' :
			stats_nb_films_par_categorie();
			break;	
	case 'stats_classement_films_par_notes' :
			stats_classement_films_par_notes();
			break;
	case 'autocomplete_noms_films' :
			autocomplete_noms_films();
			break;	
	case 'telecharge_image_imdb' :
			telecharge_image_imdb();
			break;		
	}

/*Function qui teste le login: */
 function get_login() {  
	
	/* Reception des données login a tester en base de donnée */
	$data 				= json_decode(file_get_contents("php://input"));     
    $email 				= $data->email;
	$motdepasseATester 	= $data->motdepasseATester;
	$email  			= mysql_real_escape_string($email );
	$motdepasseATester  = mysql_real_escape_string($motdepasseATester );
	
	/* Recherche de l'email en base de données. */
	$q = "SELECT * from utilisateurs3 WHERE utilisateurs3.email = '" .$email."'"; 
	$qry = mysql_query($q);
	 
	 /* Mets le resultat du Login dans un tableau (On recupère l id de l utilisateur). */
	 while($rows = mysql_fetch_array($qry))
		{
			
		$tab= array(
					"id"      	=> $rows['id'],
					"email"     => $rows['email'],
					"motDePasse"=> $rows['motDePasse'],
					"nom"     	=> $rows['nom'],
					"prenom"	=> $rows['prenom']
					);
		}
		
	  /*  Teste si le password écrit par l'utilisateur est egal au password dans la base de données. */
        if($motdepasseATester==$tab[motDePasse]){
			/* renvoie les variables id et email et mot de passe de l'utilisateur au script angularJs*/
			print_r(json_encode($tab));
		}
         
        else {
             /* Afficher false au script angularJs qui va afficher une erreur de login */
            echo('false');
		}
	exit();	
		
}

/*Function qui récupère les catégories: */
 function get_categories() {  
	
	/* SQL. */
	$q = "SELECT * from categories ORDER BY nom"; 
	$qry = mysql_query($q);
	 
	 /* Mets le resultat du Login dans un tableau . */
	 while($rows = mysql_fetch_array($qry))
		{
		$tab[]= array(
					"idCategorie"   => $rows['idCategorie'],
					"nom"     		=> $rows['nom'],
					"desc"			=> $rows['desc'],
					"image"			=> $rows['image']
					);
		}
		
	print_r(json_encode($tab));
	 exit();	 
		
}



/*Function qui récupère les films et l'intégralité des données: */
  function get_films() {  
	
    $data = json_decode(file_get_contents("php://input"));     
    $idCategorie 		= 	$data->idCategorie;  
	// Paramétrage de Infinite scrolling 
	$debutRecherche		=	$data->debutRecherche;
	$etendueRecherche	=	4;
	// Paramétrage du filtrage par date
	$dateDebut 			= 	$data->dateDebut;
	$dateFin 			= 	$data->dateFin;
	
/* 	$dateDebut			=	intval($dateDebut);
	$dateFin			=	intval(dateFin); */
	
	mysql_query("SET NAMES UTF8");
	
    /* ATTENTION LA REQUETE EST EVOLUTIVE EN FONCTION DES DONNEES RECUES PAR LE CONTROLEUR ANGULARJS */
   $q = "SELECT * FROM films";  
   
  /*  TESTE SI UNE CATEGORIE A ETE CHOISIE OU PAS */
   if($idCategorie!="pasDeCategorie"){
		$q = $q . ' ' .  "WHERE idCategorie = ".$idCategorie."" ;
	}
    
	/* SI LUTILISATEUR NA PAS CHOISI DE CATEGORIE ALORS ON BALANCE CETTE REQUETE */
	if($idCategorie=="pasDeCategorie"){
		$q = $q . ' ' .  "WHERE dateSortie BETWEEN '".$dateDebut."' AND '".$dateFin."'";
	} 
	
	/* TESTE SI LUTILISATEUR FILTRE PAR DATE DE DEBUT ET DE FIN ET A CHOISI UNE CATEGORIE*/
	if($dateDebut&&$dateFin&&$idCategorie!=="pasDeCategorie"){
		$q = $q . ' ' . "AND dateSortie BETWEEN '".$dateDebut."' AND '".$dateFin."'";
	} 
	
	/* AJOUTE LE PARAMETRAGE DE LINFINITE SCROLLING QUI TELECHARGE PLUS OU MOINS DE FILMS POUR OPTIMISER L AFFICHAGE */
	$q = $q . ' ' . "LIMIT ".$debutRecherche.",".$etendueRecherche."";
	


   $qry = mysql_query($q);
    $data = array();
    
	while($rows = mysql_fetch_array($qry)){	
		
		
		/* TROUVE LES ACTEURS DUN FILM */
		$acteurs = array();
		$q2 = "select *  from acteurs 
				INNER JOIN film_acteur on film_acteur.idActeur = acteurs.idActeur
				INNER JOIN films on films.idFilm = film_acteur.idFilm 
				WHERE films.idFilm =".$rows['idFilm'];
		$qry2 = mysql_query($q2);
		while($rows2 = mysql_fetch_array($qry2)){
			$acteurs[] = array(
				"idActeur"    	=> $rows2['idActeur'],
				"prenom"      	=> $rows2['prenom'],
				"nom"      		=> $rows2['nomActeur'],
				"biographie"    => $rows2['biographie'],
				"image"    		=> $rows2['imageActeur']
				);
		
		}; 
		
		/* TROUVE LES NOTES DUN FILM */
		$notes = array();
		$q3 = "
			SELECT *
			FROM notefilm
			WHERE notefilm.idFilm =
		".$rows['idFilm'];
		$qry3 = mysql_query($q3);
		while($rows3 = mysql_fetch_array($qry3)){
			$notes[] = array(
				"idNoteFilm"    => $rows3['idNoteFilm'],
				"pseudo"      	=> $rows3['pseudo'],
				"note"      	=> $rows3['note'],
				"impression"    => $rows3['impression'],
				"date"     		=> $rows3['date'],
				);
		
		}; 
		
		/* TROUVE LA MOYENNE DES NOTES D UN FILM */
		
		
		$q4 = "
			SELECT AVG(note) AS moyenne
			FROM notefilm
			WHERE notefilm.idFilm =
		".$rows['idFilm'];
		$qry4 = mysql_query($q4);
		$moyenne = mysql_fetch_object($qry4);
		
		
		/* TROUVE LA CATEGORIE DUN FILM */
		$q5 = "
			SELECT categories.nom AS categorie
			FROM films
			INNER JOIN categories ON films.idCategorie = categories.idCategorie WHERE films.idFilm = 
		".$rows['idFilm'];
		$qry5 = mysql_query($q5);
		$categorie = mysql_fetch_object($qry5);
		
		
		
		/* INSERE TOUTES LES DONNEES DU FILM */
        $data[] = array(
                    "idFilm"    	=> $rows['idFilm'],
                    "nom"      		=> $rows['nom'],
                    "histoire"      => $rows['histoire'], 
					"prix"      	=> $rows['prix'],
					"image"      	=> $rows['image'],
					"idCategorie"	=> $rows['idCategorie'],
					"trailer"		=> $rows['trailer'],
					"dateSortie"	=> $rows['dateSortie'],
					"categorie"		=> $categorie,
					"acteurs"		=> $acteurs,
					"notes"			=> $notes,
					"moyenne"		=> $moyenne
					
                    );
    }
	
	error_reporting(E_ALL ^ E_NOTICE); 
    print_r(json_encode($data));
	exit();	 
};  


/*Function qui récupère les noms des films et leurs id en fonction de la catégorie: */
  function get_noms_films() {  
	
    $data = json_decode(file_get_contents("php://input"));     
    $idCategorie 		= 	$data->idCategorie;  
	mysql_query("SET NAMES UTF8"); 
     
    $q = "SELECT * from films  WHERE idCategorie = ".$idCategorie."" ; 
    $qry = mysql_query($q);
    $data = array();
    
	while($rows = mysql_fetch_array($qry)){	
		
		
		/* INSERE TOUTES LES DONNEES DU FILM */
        $data[] = array(
                    "idFilm"    	=> $rows['idFilm'],
                    "nom"      		=> $rows['nom'],
		);
    }
	
	error_reporting(E_ALL ^ E_NOTICE); 
    print_r(json_encode($data));
	exit();	 
};  

/*Function qui récupère un film en fonction de son id: */
  function get_unique_film() {  
	
    $data = json_decode(file_get_contents("php://input"));     
    $idFilm 		= 	$data->idFilm;  
	mysql_query("SET NAMES UTF8"); 
     
    $q = "SELECT * from films  WHERE idFilm = ".$idFilm."" ; 
    $qry = mysql_query($q);
    $data = array();
    while($rows = mysql_fetch_array($qry)){	
		
		
		/* TROUVE LES ACTEURS DUN FILM */
		$acteurs = array();
		$q2 = "select *  from acteurs 
				INNER JOIN film_acteur on film_acteur.idActeur = acteurs.idActeur
				INNER JOIN films on films.idFilm = film_acteur.idFilm 
				WHERE films.idFilm =".$rows['idFilm'];
		$qry2 = mysql_query($q2);
		while($rows2 = mysql_fetch_array($qry2)){
			$acteurs[] = array(
				"idActeur"    	=> $rows2['idActeur'],
				"prenom"      	=> $rows2['prenom'],
				"nom"      		=> $rows2['nomActeur'],
				"biographie"    => $rows2['biographie'],
				"image"    		=> $rows2['imageActeur']
				);
		
		}; 
		
		/* TROUVE LES NOTES DUN FILM */
		$notes = array();
		$q3 = "
			SELECT *
			FROM notefilm
			WHERE notefilm.idFilm =
		".$rows['idFilm'];
		$qry3 = mysql_query($q3);
		while($rows3 = mysql_fetch_array($qry3)){
			$notes[] = array(
				"idNoteFilm"    => $rows3['idNoteFilm'],
				"pseudo"      	=> $rows3['pseudo'],
				"note"      	=> $rows3['note'],
				"impression"    => $rows3['impression'],
				"date"     		=> $rows3['date'],
				);
		
		}; 
		
		/* TROUVE LA MOYENNE DES NOTES D UN FILM */
		
		
		$q4 = "
			SELECT AVG(note) AS moyenne
			FROM notefilm
			WHERE notefilm.idFilm =
		".$rows['idFilm'];
		$qry4 = mysql_query($q4);
		$moyenne = mysql_fetch_object($qry4);
		
		
		
		
		
		
		
		/* INSERE TOUTES LES DONNEES DU FILM */
        $data[] = array(
                    "idFilm"    	=> $rows['idFilm'],
                    "nom"      		=> $rows['nom'],
                    "histoire"      => $rows['histoire'], 
					"prix"      	=> $rows['prix'],
					"image"      	=> $rows['image'],
					"idCategorie"	=> $rows['idCategorie'],
					"trailer"		=> $rows['trailer'],
					"dateSortie"	=> $rows['dateSortie'],
					"acteurs"		=> $acteurs,
					"notes"			=> $notes,
					"moyenne"		=> $moyenne
					
                    );
    }
	
	error_reporting(E_ALL ^ E_NOTICE); 
    print_r(json_encode($data));
	exit();	 

	
	
};  






/*Function qui enregistre les notes: */
 function post_note() {  
	
	$data 			= json_decode(file_get_contents("php://input"));     
    $pseudo 		= $data->pseudo; 
	$impression 	= $data->impression; 
	$note 			= $data->note;
	$idFilm			= $data->idFilm;
	$date			= $data->date;
	
	$impression = addslashes($impression);
	$impression = mysql_real_escape_string($impression);
	
	mysql_query("SET NAMES UTF8"); 
	$qry = "INSERT INTO notefilm VALUES ('','".$pseudo."','".$note."','".$impression."','".$idFilm."','".$date."')"; 
	$qry_res = mysql_query($qry);
    if ($qry_res) {
        $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();
		
}


/* Fonction qui retourne les 5 dernières impressions des films */

function get_5_dernieres_impressions(){
	 
	/* SQL. */
	mysql_query("SET NAMES UTF8"); 
	$q = "SELECT notefilm . * , films.nom, max( idNoteFilm ) AS maxi
			FROM notefilm
			INNER JOIN films ON notefilm.idfilm = films.idfilm
			GROUP BY idNoteFilm
			ORDER BY maxi DESC
			LIMIT 5 "; 
	$qry = mysql_query($q);
	 
	 /* Mets le resultat dans un tableau . */
	 while($rows = mysql_fetch_array($qry))
		{
		$tab[]= array(
					"idNoteFilm"   	=> $rows['idNoteFilm'],
					"pseudo"     	=> $rows['pseudo'],
					"note"			=> $rows['note'],
					"impression"	=> $rows['impression'],
					"idFilm"		=> $rows['idFilm'],
					"nom"			=> $rows['nom'],
					"date"			=> $rows['date'],
		);
		}
	print_r(json_encode($tab));
	exit();	 
}



/*Function qui récupère les acteurs: */
 function get_acteurs() {  
	
	/* SQL. */
	mysql_query("SET NAMES UTF8"); 
	$q = "SELECT * from acteurs ORDER BY nomActeur" ; 
	$qry = mysql_query($q);
	 
	 /* Mets le resultat  dans un tableau . */
	 while($rows = mysql_fetch_array($qry))
		{
		$tab[]= array(
					"idActeur"   	=> $rows['idActeur'],
					"nomActeur"     => $rows['nomActeur'],
					"prenom"		=> $rows['prenom'],
					"desc"			=> $rows['desc']
					);
		}
		
	print_r(json_encode($tab));
	exit();	 
		
}

/*Function qui ajoute un film: */
 function ajouter_film() {  
	
	$data 				= json_decode(file_get_contents("php://input"));     
    $nom 				= $data->nom; 
	$histoire 			= $data->histoire; 
	$idCategorie 		= $data->idCategorie;
	$noteRedaction		= $data->noteRedaction;
	$image				= $data->image; 
	$dateAjout			= $data->dateAjout; 
	$dateSortie			= $data->dateSortie; 
	
	$idActeurs		= $data->idActeurs; 

	$histoire = addslashes($histoire);
	$histoire = mysql_real_escape_string($histoire);
	/* $nom  = addslashes($nom); */
	$nom  = mysql_real_escape_string($nom);
	
	mysql_query("SET NAMES UTF8"); 
	$qry = "INSERT INTO films VALUES ('','".$nom."','".$histoire."','','".$image."','".$idCategorie."','".$noteRedaction."','".$dateAjout."','".$dateSortie."','')";  
	$qry_res = mysql_query($qry);
    
	
	
	/* for($i=0; $i<count($idActeurs['id']); $i++) {
		$z = $idActeurs['id'][$i];
			$qry2 = "INSERT INTO film_acteur VALUES ('1','1')";  
	mysql_query($qry2);
	} */
	
	/* IL FAUDRAIT FAIRE COMME CA POUR INSERER LES ACTEURS DU FILM  
	$sql = array(); 
		foreach( $data as $row ) {
			$sql[] = '("'.mysql_real_escape_string($row['text']).'", '.$row['category_id'].')';
		}
		mysql_query('INSERT INTO table (text, category) VALUES '.implode(',', $sql)); */
	
	if ($qry_res) {
        $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 ajoute des acteurs au film: */
 function ajouter_acteurs_du_film() {  
	
	$data 			= json_decode(file_get_contents("php://input"));     
	$idActeur		= $data->idActeur; 
	$idFilm			= $data->idFilm; 

	mysql_query("SET NAMES UTF8"); 
	$qry = "INSERT INTO film_acteur VALUES ('".$idFilm	."','".$idActeur."')";  
	$qry_res = mysql_query($qry);
	 
	
	
	
	if ($qry_res) {
        $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 récupère lune valeur unique : Max(idFilm) */
 function get_maxIdFilms() {  
	
	/* SQL. */
	mysql_query("SET NAMES UTF8"); 
	$req1="SELECT max( idFilm ) as mf FROM films"; 
	$res1=mysql_query($req1); 
	$value = mysql_fetch_object($res1);
	
	print_r(json_encode($value));
	exit();	 
}


/* Fonction qui ajoute un message dans le chat */
function ajouter_message() {
	
	$data 			= json_decode(file_get_contents("php://input"));     
	$pseudo			= $data->pseudo; 
	$message		= $data->message;
	$date			= $data->date;
	
	$message 		= addslashes($message);
	$message 		= mysql_real_escape_string($message);
	
	mysql_query("SET NAMES UTF8"); 
	$qry = "INSERT INTO chat VALUES ('','".$pseudo	."','".$message."','".$date."')";  
	$qry_res = mysql_query($qry);
	
	if ($qry_res) {
        $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 get_chat_messages(){
	 
	/* SQL. */
	mysql_query("SET NAMES UTF8"); 
	$q = "SELECT chat. * , max( id ) AS maxi
			FROM chat
			GROUP BY id
			ORDER BY maxi DESC
			LIMIT 50 "; 
	$qry = mysql_query($q);
	 
	 /* Mets le resultat  dans un tableau . */
	 while($rows = mysql_fetch_array($qry))
		{
		$tab[]= array(
					"id"   	=> $rows['id'],
					"pseudo"     	=> $rows['pseudo'],
					"message"		=> $rows['message'],
					"date"			=> $rows['date']
		);
		}
	print_r(json_encode($tab));
	exit();	 
}

/* Fonction qui ajoute un acteur*/
function ajouter_acteur() {
	
	$data 			= json_decode(file_get_contents("php://input"));     
	$prenom			= $data->prenom; 
	$nom			= $data->nom;
	$biographie		= $data->biographie;
	$image 			= $data->image;
	
	$nom 		= mysql_real_escape_string($nom);
	$biographie	 =mysql_real_escape_string($biographie);
	
	mysql_query("SET NAMES UTF8"); 
	$qry = "INSERT INTO acteurs VALUES ('','".$nom."','".$prenom	."','".$biographie."','".$image."')";  
	$qry_res = mysql_query($qry);
	
	if ($qry_res) {
        $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 get_nb_films_total(){
	mysql_query("SET NAMES UTF8"); 
	$qry = "SELECT COUNT(*) AS DECOMPTE FROM films";  
	$qry_res = mysql_query($qry);
	$value = mysql_fetch_object($qry_res);
	print_r(json_encode($value));
	exit();	 
}

function get_impressions(){
	 
	/* SQL. */
	mysql_query("SET NAMES UTF8"); 
	$q = "SELECT notefilm . * , films.nom, max( idNoteFilm ) AS maxi
			FROM notefilm
			INNER JOIN films ON notefilm.idfilm = films.idfilm
			GROUP BY idNoteFilm
			ORDER BY maxi DESC
			
			
			 "; 
	$qry = mysql_query($q);
	 
	 /* Mets le resultat dans un tableau . */
	 while($rows = mysql_fetch_array($qry))
		{
		$tab[]= array(
					"idNoteFilm"   	=> $rows['idNoteFilm'],
					"pseudo"     	=> $rows['pseudo'],
					"note"			=> $rows['note'],
					"impression"	=> $rows['impression'],
					"idFilm"		=> $rows['idFilm'],
					"nom"			=> $rows['nom'],
					"date"			=> $rows['date'],
		);
		}
	print_r(json_encode($tab));
	exit();	 
}

function get_ajouts(){
	 
	/* SQL. */
	mysql_query("SET NAMES UTF8"); 
	$q = "SELECT * FROM films ORDER BY dateAjout "; 
	$qry = mysql_query($q);
	 
	 /* Mets le resultat dans un tableau . */
	 while($rows = mysql_fetch_array($qry))
		{
		$tab[]= array(
					"idFilm"   		=> $rows['idFilm'],
					"nom"     		=> $rows['nom'],
					"dateAjout"		=> $rows['dateAjout'],
				);
		}
	print_r(json_encode($tab));
	exit();	 
}


function stats_nb_films_par_categorie(){
	 
	/* SQL. */
	mysql_query("SET NAMES UTF8"); 
	$q = "SELECT COUNT( * ) AS decompte, categories.nom
		FROM films
		INNER JOIN categories ON films.idCategorie = categories.idCategorie
		GROUP BY films.idCategorie"; 
	$qry = mysql_query($q);
	 
	 /* Mets le resultat dans un tableau . */
	 while($rows = mysql_fetch_array($qry))
		{
		$tab[]= array(
					"decompte"   	=> $rows['decompte'],
					"nom"     		=> $rows['nom']
				);
		}
	print_r(json_encode($tab));
	exit();	 
}

function stats_classement_films_par_notes(){
	 
	/* SQL. */
	mysql_query("SET NAMES UTF8"); 
	$q = "SELECT films.nom, notefilm.idFilm, SUM( notefilm.note ) / count( notefilm.note ) AS moyenne
			FROM notefilm
			INNER JOIN films ON films.idFilm = notefilm.idFilm
			GROUP BY idFilm
			ORDER BY moyenne
			DESC LIMIT 5
			"; 
	$qry = mysql_query($q);
	 
	 /* Mets le resultat dans un tableau . */
	 while($rows = mysql_fetch_array($qry))
		{
		$tab[]= array(
					"nom"   	=> $rows['nom'],
					"idFilm"    => $rows['idFilm'],
					"moyenne"   => $rows['moyenne']
				);
		}
	print_r(json_encode($tab));
	exit();	 
}



function autocomplete_noms_films(){
	 
	/* SQL. */
	mysql_query("SET NAMES UTF8"); 
	$q = "SELECT films.nom,films.idFilm FROM films"; 
	$qry = mysql_query($q);
	 
	 /* Mets le resultat dans un tableau . */
	 while($rows = mysql_fetch_array($qry))
		{
		$tab[]= array(
					"nom"   	=> $rows['nom'],
					"idFilm"    => $rows['idFilm']
				);
		}
	print_r(json_encode($tab));
	exit();	 
}

function telecharge_image_imdb(){
	
	$data 	= json_decode(file_get_contents("php://input"));     
	$url	= $data->url; 
	$nomFilm= $data->nomFilm;
	$chemin = 'img-films';
	$filepath = $chemin . DIRECTORY_SEPARATOR . $nomFilm;
	$copy = copy($url, $filepath); 
	if ($copy) {echo 'OK';} else {echo 'FAIL';}  
	
	
}


 
?>

Le fichier App.js qui gère le routing et le lazy loading des librairies et des directives, il est très pratique et relativement simple

'use strict';
/**
 * @ngdoc overview
 * @name sbAdminApp
 * @description
 * # sbAdminApp
 *
 * Main module of the application.
 */
angular
  .module('sbAdminApp', [
    'oc.lazyLoad',
    'ui.router',
    'ui.bootstrap',
    'angular-loading-bar',
	'ui.select', 
	'ngSanitize',
	'angular-input-stars',
	'angularjs-dropdown-multiselect',
	'yaru22.angular-timeago',
	'ui.knob',
	'angucomplete-alt',
	'pascalprecht.translate'
  ]).config(function($sceDelegateProvider) {
  $sceDelegateProvider.resourceUrlWhitelist([
    'self',
    'https://www.youtube.com/**',
	'http://ia.media-imdb.com/**',
	'http://imdb.wemakesites.net/api/**',
	'http://imdb.wemakesites.net/**'
  ]);
})
  .config(['$stateProvider','$urlRouterProvider','$ocLazyLoadProvider',function ($stateProvider,$urlRouterProvider,$ocLazyLoadProvider) {
    
    $ocLazyLoadProvider.config({
      debug:false,
      events:true,
    });

    $urlRouterProvider.otherwise('/dashboard/home');

    $stateProvider
      .state('dashboard', {
        url:'/dashboard',
        templateUrl: 'views/dashboard/main.html',
        resolve: {
            loadMyDirectives:function($ocLazyLoad){
                return $ocLazyLoad.load(
                {	
                    name:'sbAdminApp',
                    files:[
                    'scripts/directives/header/header.js',
                    'scripts/directives/header/header-notification/header-notification.js',
                    'scripts/directives/sidebar/sidebar.js',
                    'scripts/directives/sidebar/sidebar-search/sidebar-search.js'
                    ]
                }),
                $ocLazyLoad.load(
                {
                   name:'toggle-switch',
                   files:["bower_components/angular-toggle-switch/angular-toggle-switch.min.js",
                          "bower_components/angular-toggle-switch/angular-toggle-switch.css"
                      ]
                }),
                $ocLazyLoad.load(
                {
                  name:'ngAnimate',
                  files:['bower_components/angular-animate/angular-animate.js']
                })
                $ocLazyLoad.load(
                {
                  name:'ngCookies',
                  files:['bower_components/angular-cookies/angular-cookies.js']
                })
                $ocLazyLoad.load(
                {
                  name:'ngResource',
                  files:['bower_components/angular-resource/angular-resource.js']
                })
                $ocLazyLoad.load(
                {
                  name:'ngSanitize',
                  files:['bower_components/angular-sanitize/angular-sanitize.js']
                })
                $ocLazyLoad.load(
                {
                  name:'ngTouch',
                  files:['bower_components/angular-touch/angular-touch.js']
                })
            }
        }
    })
      .state('dashboard.home',{
        url:'/home',
        controller: 'MainCtrl',
        templateUrl:'views/dashboard/home.html',
        resolve: {
          loadMyFiles:function($ocLazyLoad) {
            return $ocLazyLoad.load({
              name:'sbAdminApp',
              files:[
              'scripts/controllers/main.js',
			  'scripts/directives/timeline/timeline.js',
              'scripts/directives/notifications/notifications.js',
              'scripts/directives/chat/chat.js',
              'scripts/directives/dashboard/stats/stats.js',
			  'scripts/directives/perso/recherche.js',
			  'scripts/directives/perso/rechercheomdb.js',
			  'scripts/directives/perso/commande.js',
			   
			  'scripts/directives/perso/films.js',
			  'scripts/directives/perso/omdb.js'
			   
              ]
            })
          }
        }
      })

      .state('dashboard.chart',{
        templateUrl:'views/chart.html',
        url:'/chart',
        controller:'ChartCtrl',
        resolve: {
          loadMyFile:function($ocLazyLoad) {
            return $ocLazyLoad.load({
              name:'chart.js',
              files:[
                'bower_components/angular-chart.js/dist/angular-chart.min.js',
                'bower_components/angular-chart.js/dist/angular-chart.css'
              ]
            }),
            $ocLazyLoad.load({
                name:'sbAdminApp',
                files:['scripts/controllers/chartContoller.js']
            })
          }
        }
    })

    .state('dashboard.tableauDeBord',{
       templateUrl:'views/persos/tableauDeBord.html',
	   controller: 'tableauDeBordCtrl',
       url:'/tableauDeBord',
	    resolve: {
          loadMyFiles:function($ocLazyLoad) {
            return $ocLazyLoad.load({
              name:'ui.calendar',
			  reconfig: true,
              files:[
				'bower_components/angular-ui-calendar/src/calendar.js',
				'bower_components/fullcalendar/dist/fullcalendar.min.js',
				'bower_components/fullcalendar/dist/lang/fr.js',
				'bower_components/fullcalendar/dist/gcal.js',
				'bower_components/fullcalendar/dist/fullcalendar.css'
			
				],
                    serie: true
            }),$ocLazyLoad.load({
              name:'sbAdminApp',
              files:[
              'scripts/controllers/tableauDeBord.js',
			  'scripts/directives/timeline/timeline.js',
              'scripts/directives/notifications/notifications.js',
              'scripts/directives/chat/chat.js',
              'scripts/directives/dashboard/stats/stats.js'
				

              ]
            })
		}}
   })
    .state('dashboard.crud',{
       templateUrl:'views/persos/crud.html',
	   controller: 'crudCtrl',
       url:'/crud',
	    resolve: {
          loadMyFiles:function($ocLazyLoad) {
            
			return $ocLazyLoad.load({
                name:'sbAdminApp',
                files:[
				'scripts/controllers/crud.js',
				'scripts/factories/api.js'
				
				]
            })
		}}
   })
   
   
   
   
   
   
   
  }]);

    



#ddd, #footer

Publicités