[Php + AngularJs] En finir avec les messages TRY CATCH une bonne fois pour toute .

angularjs-300x300

Introduction :

Quand une requête SQL est en erreur dans le back end PHP PDO, on peut vouloir voir le message d’erreur SQL s’afficher en direct dans l’application  FRONT END angularJs.

Ce problème est insupportable si l’on gère différement les retours des requêtes $http à chaque fois, il faut donc  etre  géré toujours de la meme manière .
En fait , il s’agit d’un design pattern.

Comment faire :

Etape 1 :Activer l’affichage des erreurs de la connexion PDO : exemple :


$this->bdd = new PDO('mysql:host=' . self::DB_HOST . ';port='. self::PORT . ' ;dbname=' . self::DB_NAME , self::LOGIN , self::PWD);

$this->bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Note : c’est la 2 ème ligne qui importe .

Etape 2 : Créer une fonction avec un try catch dans une classe PHP, exemple :


  protected function Update($table, $tab_value, $id) {

        try {
			$sql = 'UPDATE ' . $table . ' SET ';

            //  LES NOMS DE CHAMPS ET LEUR VALEUR
            if($tab_value) {
                foreach($tab_value as $i=>$v){
                    $sql .= $i.'= :'.$i.', ';
                }
            } else {
                $tab_value = array();
            }

            //  ENLEVER LA DERNIERE VIRGULE
            $sql = substr($sql, 0, -2);
            $sql .= ' WHERE id_'.$table.' = '.$id;

            $req = $this->bdd->prepare($sql);

            $req->execute($tab_value);

        } catch(PDOException  $e) {
			die('Erreur : '.$e->getMessage());
		}
		return true;
	}

Note : ici , on remarque qu’elle retourne TRUE, seulement à la fin, mais que le CATCH annulera le TRUE si la requête SQL est en erreur, et que le message d’erreur PDO parviendra bien au FRONT END .

Etape 3 :

Appeler la fonction dans le WEB SERVICE en PHP comme ceci (Exemple):

echo json_encode($user ->Update($table, $tab_value, $id));

Etape 4 : Dans le front end , Gérer l’erreur dans AngularJS :

$http.post(webServicesUrl+'?action=UpdateUser',this.utilisateur)
    .then(function (response, status, headers, config) { // return true or the PDO error
	
	if (response.data == "true") {
			 Notification.error({message: 'ok cest bien TRUE', delay: 5000});
			
	} else { 
		 
		 Notification.error({message: response.data, delay: 5000});
		

	}


	 
}.bind(this));

Note : On remarque que TRUE est un string, et que toute autre réponse que TRUE provenant du back end provoque l’affichage de l’erreur dans le FRONT END .

Conclusion :

Il faut désormais toujours utiliser ce pattern pour les requêtes. AngularJs attends soit un TRUE, soit autre chose, et rien d’autres (pas des 1 et des 0 , par exemple (booléens). En fait, il faut choisir, soit en prends les booléens, mais alors on ne récupère pas le message d’erreur PDO ; soit on fait comme plus haut.

Apparté :
En cas de problème :
En fait, le code n’est pas exactement celui ça décrit dans ce cas, car il y a

  • Le web Service
  • La classe Users
  • La classe Query qui comprends des méthodes génériques private pour updater automatiquement n’importe quelle table sql .

De ce fait, le code exact est :
Dans le web service :
echo json_encode($user ->UpdateUser($data));
( ou $data est un objet)
Dans la classe Users :
return $this->update(self::TABLE,$tab_value,$id);
ou les paramêtres sont l’objet $data scindé en plusieurs variables, dont un tableau, la classe query le nécessite.
Dans la classe query, c’est identique à expliqué au début.

Publicités

[Sql] Imbriquer des requêtes pour réduire la taille du back end .

index

Introduction
Avec postgreSQl, il faut (à priori) dès que possible imbriquer les requêtes SQL, pour aller plus vite et réduire la taille du back end

Code exemple qui calcule nbVente et nbDevis, puis permet de faire des calculs dans le select initial (calcul non présent):

SELECT nbVentes.nb_vente_entrant,nbDevis.nb_devis FROM
(
SELECT
 COUNT(v.prix_vente) AS nb_vente_entrant
 FROM crm_vente AS v
 LEFT JOIN crm_devis AS d ON v.id_crm_devis = d.id_crm_devis
 WHERE 1=1
 AND d.type_vente = 'Entrant'
 AND date_part('year', v.date_vente) = 2018
 ) AS nbVentes
,
 (
SELECT
 COUNT(*) AS nb_devis
 FROM crm_devis AS c
 WHERE 1=1
 AND date_part('year', c.date_creation) = 2018
 ) AS nbDevis

La requête peut devenir grosse , mais reste cool à gérer, et surtout ça remplit tout le front end d’un seul coup, car après on encode tout ça en JSON : exemple !

SELECT c.numero,c.nom,R.*,K.nb_j_travailles,Z.nbfiches_creees,D.nbdevis_crees,A.nb_argus FROM commerce_mois AS c

LEFT OUTER JOIN

(
	SELECT s.txn_month,s.nb_j_travailles

	   FROM ( SELECT count(distinct(date_trunc('day',calldate))) AS nb_j_travailles,
	   date_part('month'::text,h.calldate) AS txn_month,
	   date_part('year'::text,h.calldate) AS txn_year
			   FROM crm_historique AS H
				WHERE date_part('year'::text,h.calldate) = 2018
				GROUP BY date_part('month'::text, h.calldate), date_part('year'::text,h.calldate)
			 ) s

	  GROUP BY  s.txn_month,s.nb_j_travailles
	  ORDER BY  s.txn_month
  ) K

  ON c.numero = K.txn_month

LEFT OUTER JOIN

(
	SELECT s.txn_month,s.nb_appels

	   FROM ( SELECT count(h.calldate) AS nb_appels,
	   date_part('month'::text,h.calldate) AS txn_month,
	   date_part('year'::text,h.calldate) AS txn_year
			   FROM historique AS H
			   WHERE date_part('year'::text,h.calldate) = 2018
				GROUP BY date_part('month'::text, h.calldate), date_part('year'::text,h.calldate)
			 ) s

	  GROUP BY  s.txn_month,s.nb_appels
	  ORDER BY  s.txn_month
  ) R

  ON c.numero = R.txn_month

LEFT OUTER JOIN

(

SELECT s.txn_month,s.nbfiches_creees

   FROM ( SELECT count(c.date_contact_pdg) AS nbfiches_creees,
   date_part('month'::text,c.date_contact_pdg) AS txn_month,
   date_part('year'::text,c.date_contact_pdg) AS txn_year
		   FROM comptes AS C
		   WHERE date_part('year'::text,c.date_contact_pdg) = 2018
			GROUP BY date_part('month'::text,c.date_contact_pdg), date_part('year'::text,c.date_contact_pdg)
		 ) s

  GROUP BY  s.txn_month,s.nbfiches_creees
  ORDER BY  s.txn_month
 ) Z

 ON c.numero = Z.txn_month

 LEFT OUTER JOIN

(

SELECT s.txn_month,s.nbdevis_crees

   FROM ( SELECT count(c.date_creation) AS nbdevis_crees,
   date_part('month'::text,c.date_creation) AS txn_month,
   date_part('year'::text,c.date_creation) AS txn_year
		   FROM devis AS C
		   WHERE date_part('year'::text,c.date_creation) = 2018
			GROUP BY date_part('month'::text,c.date_creation), date_part('year'::text,c.date_creation)
		 ) s

  GROUP BY  s.txn_month,s.nbdevis_crees
  ORDER BY  s.txn_month
 ) D

 ON c.numero = D.txn_month

LEFT OUTER JOIN

(

SELECT s.txn_month,s.nb_argus

   FROM ( SELECT count(c.date_creation) AS nb_argus,
   date_part('month'::text,c.date_creation) AS txn_month,
   date_part('year'::text,c.date_creation) AS txn_year
		   FROM crm_devis AS C
		    inner join comptes  AS cc ON C.id_comptes = cc.id_crm_comptes
			WHERE cc.contact_pdg LIKE 'Oui'
		   AND date_part('year'::text,c.date_creation) = 2018
			GROUP BY date_part('month'::text,c.date_creation), date_part('year'::text,c.date_creation)
		 ) s

  GROUP BY  s.txn_month,nb_argus
  ORDER BY  s.txn_month
 ) A

 ON c.numero = A.txn_month

[PHP] Créer un objet à partir de plusieurs résultats SQL, puis envoyer ça au front end

Intro :

On peut envoyer soit un array, soit un objet, ici c’est un objet :

Code exemple :

Le web service :


function GetActivite() {
	$filtres 		= json_decode(file_get_contents("php://input")); 
	$suiviPersonnel = new SuiviPersonnel();
	$result		 	= $suiviPersonnel->GetActivite($filtres);
	if($result){
		echo(json_encode($result));  
	}
}

La méthode qui retourne un objet à partir de résultats SQL



/**
 * Fenetre Activité de la vue suivi_activite
 * @param $filtres => mois | annee| id_user
 * @return array | false
 */
public function GetActivite($filtres)
	{
	try
		{
		$total = new stdClass(); // Cet objet va contenir tous les resultats puis on l'envoit à la fin au front end angularjs

		// $total->property = 'Here we go'; // Exemple d'injection de resultat dans l'objet ...
		// PHASE 1 : CALCUL DU TEMPS DAPPEL TOTAL

		$sql = "
                  SELECT
                  TO_CHAR((SUM(duration) || ' second')::interval, 'HH24:MI:SS') AS temps_appel
                  FROM " . self::TABLE . "
                  WHERE 1=1
                   ";
		if ($filtres->mois)
			{
			$sql.= " AND EXTRACT(MONTH FROM calldate) = " . $filtres->mois;
			}

		if ($filtres->annee)
			{
			$sql.= " AND EXTRACT(YEAR FROM calldate) = " . $filtres->annee;
			}

		if ($filtres->id_utilisateurs)
			{
			$sql.= " AND id_utilisateurs = " . $filtres->id_utilisateurs;
			}

		$req = $this->bdd->prepare($sql);
		$req->execute($tab_value);
		$result = $req->Fetch(PDO::FETCH_ASSOC);
		$req->closeCursor();
		$total->temps_appel = $result[temps_appel];

		// PHASE 2 : CALCUL DU NOMBRE APPEL MOYEN PAR HEURES

		$sql = "
                SELECT
              AVG(*) AS nombre_appels_moyen
              FROM " . self::TABLE . "
             WHERE 1=1
                ";
		if ($filtres->mois)
			{
			$sql.= " AND EXTRACT(MONTH FROM calldate) = " . $filtres->mois;
			}

		if ($filtres->annee)
			{
			$sql.= " AND EXTRACT(YEAR FROM calldate) = " . $filtres->annee;
			}

		if ($filtres->id_utilisateurs)
			{
			$sql.= " AND id_utilisateurs = " . $filtres->id_utilisateurs;
			}

		$req = $this->bdd->prepare($sql);
		$req->execute($tab_value);
		$result2 = $req->Fetch(PDO::FETCH_ASSOC);
		$req->closeCursor();
		$total->nombre_appels_moyen = $result2[nombre_appels_moyen];

		// PHASE 3 : CALCUL DU NOMBRE DE FICHES TRAITEES

		$sql = "
                SELECT
                COUNT(*) AS fiches_traitees
                FROM " . self::TABLE . "
                WHERE 1=1
                ";
		if ($filtres->mois)
			{
			$sql.= " AND EXTRACT(MONTH FROM calldate) = " . $filtres->mois;
			}

		if ($filtres->annee)
			{
			$sql.= " AND EXTRACT(YEAR FROM calldate) = " . $filtres->annee;
			}

		if ($filtres->id_utilisateurs)
			{
			$sql.= " AND id_utilisateurs = " . $filtres->id_utilisateurs;
			}

		$req = $this->bdd->prepare($sql);
		$req->execute($tab_value);
		$result3 = $req->Fetch(PDO::FETCH_ASSOC);
		$req->closeCursor();
		$total->fiches_traitees = $result3[fiches_traitees];

		// PHASE 4 : CALCUL DU NOMBRE DE CONTACTS

		$sql = "
                SELECT
                DISTINCT(COUNT('appeler')) AS nb_contacts
               FROM " . self::TABLE . "
               WHERE 1=1
                ";
		if ($filtres->mois)
			{
			$sql.= " AND EXTRACT(MONTH FROM calldate) = " . $filtres->mois;
			}

		if ($filtres->annee)
			{
			$sql.= " AND EXTRACT(YEAR FROM calldate) = " . $filtres->annee;
			}

		if ($filtres->id_utilisateurs)
			{
			$sql.= " AND id_utilisateurs = " . $filtres->id_utilisateurs;
			}

		$req = $this->bdd->prepare($sql);
		$req->execute($tab_value);
		$result4 = $req->Fetch(PDO::FETCH_ASSOC);
		$req->closeCursor();
		$total->nb_contacts = $result4[nb_contacts];

		// PHASE 5 : CALCUL DU NOMBRE APPEL TOTAL

		$sql = "
                SELECT
                 COUNT(*) AS nombre_appels
                 FROM " . self::TABLE . "
                WHERE 1=1
                ";
		if ($filtres->mois)
			{
			$sql.= " AND EXTRACT(MONTH FROM calldate) = " . $filtres->mois;
			}

		if ($filtres->annee)
			{
			$sql.= " AND EXTRACT(YEAR FROM calldate) = " . $filtres->annee;
			}

		if ($filtres->id_utilisateurs)
			{
			$sql.= " AND id_utilisateurs = " . $filtres->id_utilisateurs;
			}

		$req = $this->bdd->prepare($sql);
		$req->execute($tab_value);
		$result5 = $req->Fetch(PDO::FETCH_ASSOC);
		$req->closeCursor();
		$total->nombre_appels = $result5[nombre_appels];
		return $total;
		}

	catch(Exception $e)
		{
		die('Erreur : ' . $e->getMessage());
		}
	}


 

Puis, si on veut condenser les filtres dans une fonction :

	 public function GetActivite($filtres) {
        
		try {
			
			$total = new stdClass(); // Cet objet va contenir tous les resultats puis on l'envoit à la fin au front end angularjs
			// $total->property = 'Here we go'; // Exemple d'injection de resultat dans l'objet ...
			
			//  CALCUL DU TEMPS DAPPEL TOTAL 
			$sql  = "
				SELECT 
				TO_CHAR((SUM(duration) || ' second')::interval, 'HH24:MI:SS')  AS temps_appel 
				FROM " . self::TABLE . "
				WHERE 1=1 
			";
			
			$sql = $this->addFiltres($filtres,$sql);
			
			$req = $this->bdd->prepare($sql);
            $req->execute($tab_value);
            $result = $req->Fetch(PDO::FETCH_ASSOC);
            $req->closeCursor();
			
			$total->temps_appel = $result[temps_appel] ; 
			
			// CALCUL DU DUREE MOYENNE PAR APPEL
			 $sql  = "
				 SELECT 
				 ROUND(AVG(duration),2) AS duree_appel_moyen  
				 FROM " . self::TABLE . "
				 WHERE 1=1 
			 ";
			 $sql = $this->addFiltres($filtres,$sql);
			
			 $req = $this->bdd->prepare($sql);
             $req->execute($tab_value);
             $result = $req->Fetch(PDO::FETCH_ASSOC);
             $req->closeCursor();
			
			$total->duree_appel_moyen = $result[duree_appel_moyen]; 
			
			
			// CALCUL DU NOMBRE APPEL MOYEN PAR HEURES
			 $sql  = "
				 SELECT 
				 AVG(duration) AS nombre_appels_moyen_heure  
				 FROM " . self::TABLE . "
				 WHERE 1=1 
			 ";
			 $sql = $this->addFiltres($filtres,$sql);
			
			 $req = $this->bdd->prepare($sql);
             $req->execute($tab_value);
             $result = $req->Fetch(PDO::FETCH_ASSOC);
             $req->closeCursor();
			
			$total->nombre_appels_moyen_heure = $result[nombre_appels_moyen_heure]; 
			
			// CALCUL DU NOMBRE DE FICHES TRAITEES 
			$sql  = "
				SELECT 
				COUNT(*)  AS fiches_traitees 
				FROM " . self::TABLE . "
				WHERE 1=1 
			";
			$sql = $this->addFiltres($filtres,$sql);
			
			$req = $this->bdd->prepare($sql);
            $req->execute($tab_value);
            $result = $req->Fetch(PDO::FETCH_ASSOC);
            $req->closeCursor();
			
			$total->fiches_traitees = $result[fiches_traitees]; 
            
			//  CALCUL DU NOMBRE DE CONTACTS 
			$sql  = "
				SELECT 
				DISTINCT(COUNT('appeler'))  AS nb_contacts 
				FROM " . self::TABLE . "
				WHERE 1=1 
			";
			$sql = $this->addFiltres($filtres,$sql);
			
			$req = $this->bdd->prepare($sql);
            $req->execute($tab_value);
            $result = $req->Fetch(PDO::FETCH_ASSOC);
            $req->closeCursor();
			
			$total->nb_contacts  = $result[nb_contacts]; 
			
			
			// CALCUL DU NOMBRE APPEL TOTAL
			$sql  = "
				SELECT 
				COUNT(*) AS nombre_appels 
				FROM " . self::TABLE . "
				WHERE 1=1 
			";
			$sql = $this->addFiltres($filtres,$sql);
			
			$req = $this->bdd->prepare($sql);
            $req->execute($tab_value);
            $result = $req->Fetch(PDO::FETCH_ASSOC);
            $req->closeCursor();
			
			$total->nombre_appels = $result[nombre_appels]; 
			
			
			
			
			return $total; 
			
        } catch(Exception $e) {
            die('Erreur : '.$e->getMessage());
        }
    }
    }

Les filtres sont désormais contenus dans cette function :

private function addFiltres($filtres,$sql){
		
		if ($filtres->mois) {
			$sql  .= " AND EXTRACT(MONTH FROM  calldate) = 	".$filtres->mois ; 
		} 	

		if ($filtres->annee) {
			$sql  .= " AND EXTRACT(YEAR FROM  calldate) = 	".$filtres->annee; 
		} 
		
		if ($filtres->id_utilisateurs) {
			$sql  .= " AND id_utilisateurs = ".$filtres->id_utilisateurs;
		}
		
		return $sql;
		
	}

[PHP] Serializer un objet JSON dans PostGres sur INSERT puis deserialiser sur SELECT

php_1_

Intro

Revient constamment ;
On stocke carrément des objets ou même des arrays JSON dans des BDD relationelles ! A la punk ! HI HI

Lire la suite

[www.openode.io] Enfin, un bon hébergeur pour publier ULTRA facilement des applications NODE.JS

nodeeeeee

Introduction


Avant 2018, on pouvait créer nos applications NODE.JS assez facilement en LOCAL .

Mais lorsque venait le moment de publier notre application en ligne, c’était assez la galère,il fallait soit acheter un serveur dédié assez cher, soit effectuer des méthodes complexes avec cloudant ou autres Aws pour arriver à placer son app en ligne .

Openode.io : Une seule commande, cela fonctionne de suite !


Depuis 2018, openode.io est arrivé, et enfin, ça marche et c’est facile !! Depuis le temps qu’on attendait ça !!

On s’inscrit sur openode.io, on a de suite un environnement prêt, suffit juste de lui donner un nom, c’est vraiment TROP SIMPLE ! Cette société serait basée au Texas.

En local, dans notre pc, on se rends dans le répertoire de notre site node.js .

Ensuite, on télécharge avec GIT leur programme de gestion hyper simple qui nous donne quelques commandes supplémentaires dans CMD(La ligne de commande Windows).

Une fois qu’on a installé leur programme, il suffit de taper dans notre répertoire :

openode deploy

pour envoyer l’intégralité de notre site en ligne, ça marche de suite !

Voici un exemple de moi, qui envoie mon application node.js en ligne :

deploy.jpg

Le programme deploy surveille que notre fichier package.json contient de bonnes versions de librairies :

Exemple :

{
"name": "socket-chat-example",
"version": "0.0.1",
"description": "my first socket.io app",
"dependencies": {
"express": "^4.15.2",
"mysql": "^2.16.0",
"mongoose": "^5.2.6",
"morgan": "^1.1.1"

},
"scripts": {
"start": "node index.js"
}
}

Ici , je charge la lib mongoose pour pouvoir me connecter à un base de données MONGODB et la lib mysql pour pouvoir aussi me connecter à une base de données MYSQL, tout cela en JS (le langage le plus coool et flexiiible!).

Et oui, cela veut dire qu’on peut désormais coder tout en JS, aborder des bdd relationnelles quand même, et déployer de façon ultra simple, c’est carrément TROP COOL !

Voici les 2 autres fichiers de mon app, just pour info (On voit que j’exécute des requêtes SQL dans le Javascript …)  :

index.js :


 var app = require('express')();
 var http = require('http').Server(app);
 var port = process.env.PORT || 3000;
 var mongoose = require('mongoose');
 var mysql = require('mysql');
 var morgan = require('morgan'); // log requests to the console (express4)</code>

 var connection = mysql.createConnection({
     host: 'sql.free.fr',
     user: 'nicolas.huleux',
     password: 'xxxxxxx',
     database: 'nicolas_huleux'
 });

 connection.connect(function(err) {
     // connected! (unless `err` is set)

 });

 connection.query('SELECT * from acteurs', function(err, rows, fields) {
     if (!err)
         console.log('The solution is: ', rows);
     else
         console.log('Error while performing Query.');
 });

 app.get('/', function(req, res) {
     res.sendFile(__dirname + '/index.html');
 });

 http.listen(port, function() {
     console.log('listening on *:' + port);
 });

Et là, index.html, un formulaire bateau, pas encore fonctionnel

<!doctype html>
<html>
  <head>
    <title>form</title>

  </head>
  <body>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
    <script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
    <script src="https://code.jquery.com/jquery-1.11.1.js"></script>
	
	 <form action="action_page.php">
		  <div class="imgcontainer">
			<img src="img_avatar2.png" alt="Avatar" class="avatar">
		  </div>

		  <div class="container">
			<label for="uname"><b>Username</b></label>
			<input type="text" placeholder="Enter Username" name="uname" required>

			<label for="psw"><b>Password</b></label>
			<input type="password" placeholder="Enter Password" name="psw" required>

			<button type="submit">Login</button>
			<label>
			  <input type="checkbox" checked="checked" name="remember"> Remember me
			</label>
		  </div>

		  <div class="container" style="background-color:#f1f1f1">
			<button type="button" class="cancelbtn">Cancel</button>
			<span class="psw">Forgot <a href="#">password?</a></span>
		  </div>
		</form> 

  </body>
</html>

Conclusion :
On peut désormais coder tout en NODE.JS et publier des démos sur son blog super facilement, sans acheter une serveur dédié, c’est TROP BIEN . Si on veut, plus besoin d’utiliser PHP en back end il existe des tas de libs qui permette à node de se connecter aux bases relationnelles, y compris sans faire de SQL avec par exemple KNEX.JS (https://stackoverflow.com/questions/5818312/mysql-with-node-js) :

KNEX.JS

KnexJs can be used as an SQL query builder in both Node.JS and the browser. I find it easy to use. Let try it – Knex.js

$ npm install knex--save# Then add one of the following(adding a--save) flag:
  $ npm install pg
$ npm install sqlite3
$ npm install mysql
$ npm install mysql2
$ npm install mariasql
$ npm install strong - oracle
$ npm install oracle
$ npm install mssql


var knex = require('knex')({
    client: 'mysql',
    connection: {
        host: '127.0.0.1',
        user: 'your_database_user',
        password: 'your_database_password',
        database: 'myapp_test'
    }
});

You can use it like this

knex.select('*').from('users')

or

knex('users').where({
    first_name: 'Test',
    last_name: 'User'
}).select('id')

Traitement Back-end PHP Try Catch avec réception et traitement Front-end AngularJs 1.6.5

INTRODUCTION :


Gérer les TRY CATCH dans les web service PHP, et communiquer le message contenu dans un THROW directement au FRONT END ANGULARJS

Le système de try catch PHP est puissant et pratique à utiliser, en particulier pour les problèmes de droits par exemple mais cela peut être pour n’importe quoi d’autre !!

Seulement, il faut savoir le faire communiquer avec le FRONT END !!

DETAIL


Pour info, voici le look d’une méthode de ma classe, dans le BACKEND PHP, fichier backend.php , qui enregistre les permissions, on peut voir un test de permission avant l’exécution  de la requête qui enregistre un tableau d’objets JSON décomposé grâce au foreach, l’important ici est de regarder le THROW et son message STRING ( Les contrôles de sécurité ne sont pas affichés dans cet exemple):

    /**
     * Update Permissions after front end management
     * 
     * Required Permission : $_SESSION['auth'] = true | UPDATE_PERMISSIONS
     * 
     * @return true
     * 
     * 
     */
    public function updatePermissions($jsonArray)
    {

        // Check User Permissions
        if (!$this->has_permission('UPDATE_PERMISSIONS', $_SESSION['permissions'])) {
            throw new Exception("Error : You are restricted to do this.");
        };


        foreach ($jsonArray as $index => $row) {
            $row                      = $this->escape_data_object($row);
            $id                       = $row['id'];
            $name                     = $row['name'];
            $permissions              = strval($row['permissions']);
           

            $sql = "UPDATE Job SET name='$name',permissions='$permissions' WHERE id = '$id'";
            $this->conn->query($sql);

        }

        mysqli_close($this->conn);
        return true;
    }

Le Web Service en PHP qui catche une éventuelle erreur de permission et renvoie le message d’erreur STRING du THROW pour pouvoir l’afficher directement dans le front end, (json_encode() permet de créer du JSON, compréhensible par angularJs, ou vue.js, ou angular 5 …) :

 if(!empty($_POST["updatePermissions"]) AND $_SESSION['auth']) {

    $jsonArray = $_POST["updatePermissions"];
    $jsonArray = json_decode($jsonArray,true); 
    $status = 200;

    try{
        $db->updatePermissions($jsonArray);
    } 
    catch(Exception $e){
         echo json_encode(array("response"=>$e->getMessage()));
         exit();
    } 

    echo json_encode(array("response"=>$status));

} 

Et enfin le FRONT END en ANGULARJS 1.6.5 qui traite le message d’erreur dans le .then() et affiche le STRING du THROW originel directement dans le FRONT END (Remarquez que la requête POST ajax s’adressait bien à mon WEBSERVICE en php ):

//~ AJAX CALL -> Sending whole $scope.permissions array of json objects
        $http.post(wsUrl, {updatePermissions: JSON.stringify($scope.permissions)})
            .then(function(data, headers, config) {
                console.log(data.data);

                $scope.ajaxCall = false;
                $scope.record_button_disable = false;

                // Errors management Responses
                if (data.data.response == 200) {
                    Notification.success($translate.instant('REQUESTSUCCESS'));
                    console.log("Réponse Serveur: " + data.data);

                }
                if (data.data.response != 200) {
                    Notification.error(data.data.response);
                }
            })
        }

Et enfin… Juste pour info, la petite fonction privée PHP has_permission() du cru qui permet d’ejecter les gars qui tentent de faire un truc alors qu’ils n’ont pas la permission dans leur array de permissions (séparé par ;), par le back end, hi hi . Par ecemple si il na pas la permission DISPLAY_USERS, le back end throw une erreur, et angularjs(ou vue.js) affiche le message d’erreur:

/**
	 * This function is looking for the permission inside user PHP SESSION permissions variables, if the permission is not present, then it returns false !
	 * 

	 * @return false|true
	 * 

	 */

	private function has_permission($permission, $permissions)
	{

		$permissions = explode(";", $permissions);

		if (in_array($permission, $permissions)) {
			return true;
		}

		return false;
	}

 

240px-Sheep_Shaf_Mouton.JPG‘Bhee, t »es un ouf pourquoi t’utilises pas que Php pour simplifier plutôt que de faire tout ça bhee?’

Parce que AngularJs et Javascript disposent de l’atout temps réel, d’énormément de librairies et sont très puissants, voir par exemple le jeux LARA CROFT http://xproger.info/projects/OpenLara/ avec une lib dédiée graphique js , voir Three.js, ou alors ne serait ce que D3.JS qui permet une modélisation innovante pour analyse de données, bon courage pour faire ça avec php !!!

[AngularJs + Php MYSQL ] Une table Html infinite scroll simple, sur base de donnée

angularjsphp_1_

Introduction


Avec Angularjs 1.6 , on ne télécharge pas tout un modèle de données lorsqu’il est très grand. Par exemple, pour, afficher toute une table de log de 150 MO, évidemment, on ne charge pas toute la table d’un seul coup dans la mémoire vive, ce serait bien trop couteux. Dans d’autres cas, dans le cadre d’une vue spéciale dans une application, on peut envisager de télécharger tout le modèle de données ( Par exemple, 500 utilisateurs)

NOTE CETTE DOC EST OBSOLETE VOICI LA NOUVELLE DOC
https://nicolashcodes.wordpress.com/2018/10/30/angularjs-php-un-infinite-scroll-sur-une-table-html/

L’idée de l’infinite Scroll sur base de donnée


L’idée étant d’afficher les 20 premiers enregistrements de la table, puis ensuite, lorsque l’on atteints le bas de la page, charger les 20 suivants, puis ainsi de suite, de cette manière, l’utilisateur a la sensation d’être en temps réel.

Le problème


Lire la suite