, ,

Créer votre site avec Smarty en MVC – Partie 2 (Suite)

Smarty
Smarty

Créer votre site avec Smarty en MVC – Partie 2

Voici la suite du tutoriel sur comment « Créer votre site avec Smarty en MVC – Partie 1« . Je suis désolé de l’attente de publication pour ce deuxième article mais le voici enfin. Il va vous permettre de peaufiner ce que vous avez appris avec le premier tutoriel et le mettre en pratique au coeur de vos projets.

Dans notre premier article nous avions vu comment créer la config, la connexion à votre base de donnée, créer votre header, footer et votre première page Index.

C’est l’heure maintenant de créer des classes, des controllers pour jouer un peu avec le PHP.Pour rappel notre projet de Tutoriel s’appelle PixyJob et nous aimerions pouvoir lister des offres, en ajouter et en consulter une en particulier. Nous venons donc de définir 3 actions pour le moment possible

Création de notre base de donnée

On va donc créer une base de donnée dans laquelle nous allons stocker des informations dont on ira sauvegarder / lire les informations via les fonctions que nous aurons écrites dans le CORE.

Le nom de la base sera pixyjob comme définit dans nos config.

Notre première table s’appellera donc offers, je choisi de toujours nommer les tables et champs en anglais pour une norme dans mes projets de travail.

A l’intérieur nous allons avoir besoin de plusieurs champs qui sont ceux-ci pour notre exemple :

id : INT, Champ en Auto Increment, automatique qui servira de clé primaire
title : Contiendra le titre de l’annonce, VARCHAR limité à 70 caractères.
descr : Contiendra la description de l’annonce, TEXTE

Pour ceux qui souhaiteraient le code SQL afin de l’importer sous PHPMYADMIN le voici :


CREATE TABLE IF NOT EXISTS `offers` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(70) COLLATE latin1_general_ci NOT NULL,
  `description` text COLLATE latin1_general_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=1 ;

Notre première classe

On va créer un nouveau fichier PHP que l’on va nommer offers.php qui sera enregistré dans le dossier core
A l’intérieur nous allons déclarer une classe que l’on nommera « Offres » dans laquelle nous aurons les différentes fonctions identifier.

Je pars toujours du principe que dans un premier temps on va juste créer la classe avec les arguments, mettre des commentaires à l’intérieur de ce que l’on devra développer pour le faire plus tard. Mais ainsi on évite d’oublier de créer des fonctions que nous avons besoins.En fonction de ce qu’on à déduit au-dessus je vous laisse le soin de créer votre 4 première classe.

Voici mon fichier offers.php

<?php

class Offers
{
    //Récupérer toutes les offres
    public function getAll()
    {
      // Créer la connexion a la base pour récupérer toutes les offres triées de la plus récente a la plus ancienne
    }

    //Récupérer plus d'info sur 1 offre
    public function getOne($id_offer)
    {
      // Créer la connexion a la base pour récupérer toutes les infos liée a 1 offre en particulier
    }

    //Ajoter une offre
    public function Add($data)
    {
      // Créer la connexion a la base + traitement des données + Sauvegarde en BDD
    }
}

?>

Je vous invite donc à coder vos fonctions maintenant qu’on a écrit les grosses lignes pour les définir.

Voici mon fichier avec les fonctions écrites

<?php

class Offers
{
    //Récupérer toutes les offres
    public function getAll()
    {
      //On définit la bdd pour la fonction
      global $bdd;
      $offers = $bdd->query('SELECT * FROM offers')->fetchAll(PDO::FETCH_ASSOC);
      return ($offers);
    }

    //Récupérer plus d'info sur 1 offre
    public function getOne($id_offer)
    {
      global $bdd;
      $offer = $bdd->query('SELECT * FROM offers WHERE offers.id = '.$id_offer.' ')->fetch(PDO::FETCH_ASSOC);
      return ($offer);
    }

    //Ajouter une offre
    public function Add($data)
    {
      global $bdd;
      $insert = $bdd->exec('INSERT INTO offers(title, description) VALUES('.$data['title'].', '.$data['description'].')');
      return ($insert);
    }
}

?>

Comme vous pouvez le voir ma fonction Add, pour ajouter une offre, est relativement simple, il vous faudra bien entendu effectuer des tests sur les données entrantes afin de vérifier qu’aucune faille XSS ou SQL n’est possible.

De plus mes fonctions pour récupérer toutes les offres ou une en particulier ne retourne pas d’erreur directement, il vous faudra peut-être gérer ce cas.

Maintenant qu’on à cela , qu’est ce que nous aimerions faire ? Tous simplement listé sur notre page d’accueil toutes les offres. Mais comment-faire ?
Très simple, on va avoir un template constituant le squelette HTML, avec des variables SMARTY, car pas de code PHP dans le template.
Le rôle du controller sera justement d’appeler les fonctions PHP et d’envoyer les données à Smarty pour les afficher.Attaquons donc ce controller

Notre Ami le controller

On va donc crée un fichier php qui devra obligatoirement avoir le même nom que le template, pour notre exemple nous souhaitons avoir toutes les offres sur la home page qui s’appelle index. donc on va créer un index.php qui sera sauvegarder dans le dossier controller, à l’intérieur duquel nous allons appeler notre fonction getAll

Voici le contenu de mon controller index.php

<?php

//On appelle la fonction getAll()
$alloffers = Offers::getAll();
//On transmets les variables à Smarty
$smarty->assign('alloffers', $alloffers);

?>

Dans notre controllers on a créé une variable nommé $alloffers pour l’exemple dans laquelle on va dans la classe Offers appeler la fonction getAll()

Ensuite on transmets cela a Smarty, la fonction $smarty->assign prends en compte deux données, la première est le nom qu’aura cette variable dans la vue (Template) et la deuxième, le nom de la variable du controller. Donc maintenant sous notre vue, on pourra récupérer ces données via la variable smarty alloffers

On va pouvoir maintenant arriver à la concrétisation de tous notre petit travail. Voir les données s’afficher. N’oubliez pas avant de rentrer manuellement via PHPMYADMIN, 3 ou 4 offres dans votre table offers, sinon vous ne verrez jamais rien dans votre vue.

Le Template

On va donc reprendre notre fichier index.tpl qui doit se trouver dans le dossier tpl/pages/

On supprime tout et on repars de zéro.

Nous devrions avoir 3-4 annonces en base donc on va faire une boucle, un foreach, sur les annonces pour les afficher dans des rectangles les un à la suite des autres.
Smarty possède pas mal de fonction, comme le foreach, le truncate et bien d’autres que vous pourrez trouver sur leur site en lien plus bas.

Dans notre vue pour appeler nos variables assignées à smarty on doit le faire entre accolade, donc dans notre controller on a assignée « $smarty->assign(‘alloffers‘, $alloffers); » donc sous smarty on fera {$alloffers}. Ici dans notre exemple $alloffers est un array donc on devra prendre à l’intérieur de celui-ci les informations à afficher.

Voici mon Template index.tpl

{foreach from=$alloffers item=offer}
{$offer.title}

{$offer.description}

Voir plus d'info
{/foreach}

Dans notre boucle le foreach prends deux arguments minimum, le foreach qui défini sur quel array on va effectuer la boucle, et le item où l’on définit le nom de chaque boucle que l’on va utilisé à l’intérieur de ce foreach.

Et ainsi de suite, la suite est logique, si vous avez des questions n’hésitez à les poster. Et si vous voulez, je pourrais vous faire une troisième partie sur Smarty.

Smarty propose une FAQ qui pourra vous aider si vous vous posez des questions sur l’utilisation de quelques variables : www.smarty.net

Lien vers la Partie 1 de ce tutorial

Written by Fredods

Passionné de voyage, nourriture, cocktails. Travaillant dans le monde du e-Commerce et du Digital, je partage mes passions et conseils à travers ce blog.

23 Comments

Leave a Reply
  1. ahh super je l’attendais avec impatience…super boulot.

    Par contre, j’ai un petit problème…lorsqu’il va me chercher les fonctions, j’ai un message m’indiquant que le methode n’est pas static…je ne vois pas pourquoi elle devrait étre au format static…une idée ?

    Sinon encore bien joué, exellent boulot !

    y a – til un moyen par la suite de pouvoir faire de la surcharge ? (on ne sais jamais…^^)

    • Bonjour Matthebest62,

      Pour ton problème, il te suffit de renommer ta fonction « public function » en « public static function ». L’erreur est dû au faites que tu possèdes peut-être une version de PHP avancé pour l’heure comme la 5.4 et qui est plus strict dans les règles de définition des fonctions.

      Qu’appelle tu « faire de la surchage » ?

      Merci pour le Tuto, n’hésite pas à le partager avec tes amis.

      Bonne journée

  2. oui entre temps j’ai su réglé le probleme rassure toi.
    mais merci quand même !

    faire une surcharge du genre :
    -Core
    — mes class.php

    pouvoir créé un peu à la Magento, un dossier « local », avec dedans nos classe de surcharge (de sorte à ne pas avoir à retoucher à celles du Core par la suite simplement…

    Par contre j’ai une toute autre question,
    J’ai deux table :
    la table « client » qui contient
    -id_client
    – nom
    -prenom

    et ma table « adresse » etant comme suit :
    -id
    -id_client
    -adresse
    -ville
    -code_postal

    Mon interet est de créé les classe et les fonction qui vont bien mais pouvoir ressortir sous forme de tableau les adresse correspondant au nom du client. (je ne sais pas si je suis bien clair)…

    En gros dans mon Core, je ne veux pas tout mélanger.
    une classe « Client » qui est en gros ma table « client » sous forme d’objet, et une classe « Adresse » qui idem est ma table adresse sous forme d’objet.

    Comment faire pour ressortir les infos dont j’ai besoin ?

    En tout cas merci de ton aide, sa m’a été très précieux, et désolé pour le dérangement.

    Matthebest62

    • Re bonjour Matthebest62,

      Concernant tes questions, tu peux effectivement si tu le souhaites faire une surcharge pour ne pas avoir à retoucher tes classes.

      Concernant tes tables.

      Tu peux et même tu dois créer une classe par table c’est beaucoup mieux pour la lisibilité de ton projet et pour travailler de façon optimal.

      Je lis que tu veux recevoir sous forme d’objet, tu es donc obligée de codé en PHP5 tes classes en hydratant tes objets avec des getters et setter. Et tu pourras très facilement grâce à un client ressortir une adresse.

      Cependant dans ton modèle, un client peut avoir plusieurs adresses possibles si j’ai bien compris ? Si ce n’est pas le cas il faut tout grouper sur la même table.

  3. En effet,
    mon client peut avoir plusieurs adresse.

    Mais simplifions nous la vie, faisons comme ci que j’avais ma table client, et une table « intervention »…chaque client peut avoir 1 ou plusieurs intervention. (mais le principe est le même).

    Concernant mes getter / setter, ils sont créé…
    mais tu arriverai à me donner un exemple la dessus ?
    (faire en sorte que si je fait un :
    $client = new Client;
    $client->getAdresse();

    je puisse avoir le nom de mon client, son prenom, et son adresse etc…
    (oui je sais c’est la base mais…j’ai un peu de mal dessus).

    De sorte à avoir un template avec un beau petit while qui me ressort tout ça…(désolé de te soliciter à nouveau…je coince un peu…mais comme tout le reste de mon site va se baser dessus, une fois compris sa glissera tout seul).

    Merci pour tes retours chaque fois plus rapide ^^

    • Pour revenir à ta question.

      Dans ton core client, tu as forcément ton objet hydrater à partir d’un id, qui te permet de récupérer toutes les infos clients.

      Imaginons donc que ta variable est

      $client = new Client;

      Puis il faut que ton objet Adresse soit hydrater via un Id client, de ce fait, tu fais tes jointures en fonction de cela, que une adresse correspond à un et un seul client.

      Ainsi en faisant $client->getAdresse();

      Tu pourras récupérer l’adresse de ton client.

      Tout ceci est plus du dév PHP5, j’essayerai de faire un tutoriel là dessus pour expliquer comment créer une classe, l’hydrater, créer des relations 1,1 ou 1,n

      Bonne soirée à toi

  4. Re bonjour,

    merci pour toutes ces infos…j’ai tenté quelques petites chose, et, comme d’hab, je me trouve confronté à plusieurs problèmes…

    lorsque je cherche à étendre ma classe genre :
    class Toto extends Titi {

    public function maFonction();
    etc…
    }

    j’ai une erreur qui remonte m’indiquant que la classe n’a pas été trouvé (sachant que mes deux classes sont dans core sous le nom respectif de « Toto.php » et « Titi.php » (la casse est bonne).

    Pourquoi l’extends ne fonctionne pas ?

    Deuxième question :

    j’ai tenté, dans mon config d’utiliser la fameuse fonction « __autoload($maClass) { include « blabla ».$maClass. ».php »; }

    mais il n’arrive même pas à savoir ce que retourne « $maClass ».

    bref je galère un peu.

    Concernant ta réponse d’hier, j’avais bien compris le principe, mais est ce que tu saurai me donné un exemple plus concret (un morceau de code) ? (oui oui je sais je suis exigeant).

    En fait je vois pas trop quoi écrire dans mes modeles…

    Merci pour ta patience et tes retours chaque fois plus complet.

    (n’hesite pas à me contacter par mail au besoin).

    Et, je ne cesse de le dire, mais encore bien joué pour ton cms !

  5. Bon, il ne faut pas que sa tourne en forum, mais pour ceux qui ont été bloqué tout comme moi avec la fonction __autoload() après moulte recherche, j’ai trouvé la solution :

    il suffit d’inclure smarty avant, et faire comme ceci :

    require(_PATH_ . ‘tools/smarty/Smarty.class.php’);

    /* Autoload */
    function __autoload($className)
    {
    if (!class_exists($className, false))
    require_once(_CORE_.$className.’.php’);
    }

    spl_autoload_register(‘__autoload’);

    La fonction spl_autoload_register est super importante, sans elle sa ne fonctionnera pas.

    En esperant avoir apporté pour une fois mon aide. hihi

  6. re bonjour,

    je voulais savoir si tu allé faire une suite à celà ? de mon coté j’avance bien, mais je me demandé comment tu allé procédé pour les actions ? comment vas tu passé en paramétre ce dont on a besoin ? (par exemple passer en paramétre l’id client pour pouvoir travailler avec etc…?

    désolé du dérangement à nouveau !

    merci de ton aide…

  7. Bonjour,

    j’ai suivis la 1er partie du tuto qui m’intéresse, mais arrive à la fin de la 1er partie je test sur mon navigateur et j’ai cette erreur
    Fatal error: require() [function.require]: Failed opening required ‘C:/wamp/www//web/tools/smarty/Smarty.class.php’ (include_path=’.;C:\php\pear’) in C:\wamp\www\frameMVC\config\config_init.php on line 8

    Pourquoi ?

    Merci d’avance !

    • Bonjour Kevin,

      Comme tu le voies, ton php n’arrive pas à aller charger le fichier de Smarty ici C:/wamp/www//web/tools/smarty/Smarty.class.php

      Car si tu regards bien entre www et web tu as deux //

      Il manque entre les deux le nom du dossier où tu as stocké tes fichiers.

      Il faut que dans ton defines.inc.php à cette ligne

      // Define de la racine du site
      define(‘_PATH_’, $_SERVER[‘DOCUMENT_ROOT’].’/’);

      Tu mettes ton dossier comme ceci

      // Define de la racine du site
      define(‘_PATH_’, $_SERVER[‘DOCUMENT_ROOT’].’/tondossier/’);

      Bonne soirée à toi

  8. Bonjour,

    j’ai trouvé ce tuto vraiment cool. Mais javais une question si j’ai envie de faire un petit back-office comment faire pour créer un dossier admin et créer le lien.

    Encore merci =)

    • Bonjour Lucas,

      Tu peux tout simplement te recréer soit une deuxième structure de ce type que tu places au sein d’un dossier Admin par exemple soit adapté ton index.php pour lui indiquer que tu as une partie des pages/controllers qui ne doit etre visible que par certaines IP ou comptes Loggué

      • Désolé du retard ^^. J’ai fait un systeme d’authtification + j’ai mit la meme structure dans un dossier admin.
        Mais lors de l’authentification impossible de faire la redirection dans le dossier admin.

        Merci

      • Merci pour ta réponse.
        je veux creer un controller de test voici mon config_ini.php

        query(« SET NAMES UTF8 »);
        } catch (Exception $e) {
        echo « Problème de connexion à la base de donnée demo… »;
        die();
        }

        // Initialisation Smarty
        $smarty = new Smarty();?>

        ici le contenu de mon fichier test.tpl
        à l’interieur de ce fichier j’y mets un formulaire qui enverra les donnèes au controller/test.php

        Nom :

        Envoyer votre message

        ici le contenu de mon fichier core/test.php

        juste une classe de test

        et en fin le contenu de mon fichier controller/test.php qui fait appel a la classe crée dans core/test.php

        voici l’erreur que jai

        ( ! ) Fatal error: Class ‘Demo’ not found in /var/www/MediStockWeb/controllers/test.php on line 8

        je ne peu pas faire appell a ma classe dans le controller
        je ne sais pas si c’est lié au path que jai donné dans mon fichier test.tpl pour référencé le controller

        Merci d’avance pour ta réponse

  9. Bonjour!

    Dans la partie 2 vous dite on va créer dans controllers/index.php. Alors, il est déjà créé par la partie 1.
    Ça fait un peu mélange pour un débutant.

    J’ai pas très bien saisie la différence entre CORE et CONTROLLERS.

    Quand mettre dans CORE et quand mettre dans CONTROLLERS.

    Ça aidé de tomber sur ce site. Merci.

    • Bonjour Stephan,

      Merci de ton commentaire, la partie action sert à faire le lien entre les fonctions et le template HTML.

      Grâce à action tu vas appeler des fonctions dont tu vas stocker le résultats dans des variables, et grâce à ces variables, tu pourras les appeler dans ton html 🙂

      Bonne journée

  10. Bonjour Fredods,

    J’ai suivi ton tuto, tout fonctionne, mais je suis bloqué un peu plus loins.

    J’ai créé dans /controllers un autre fichier (cible.php) et donc dans tpl son équivalent.

    Dans ce nouveau fichier, j’essaie d’utiliser Offers::getOne(); mais … dans mes logs php il m’indique qu’il ne trouve pas la classe Offers ! J’ai l’impression qu’avec ce qu’on à la seul le fichier controllers/index.php y a accès par le biais du index.php à la racine ?

    Bref du coup si tu avais la réponse à mon probleme de classe, je suis preneur,

    Cdt

    • En fait pour être plus précis j’essaie de créer dans controllers/index.php un petit formulaire qui renvoie à controllers/cible.php, mais cible.php n’a pas accès à la classe Offers du core, comment je peux faire pour que tous mes fichiers aient l’inclusion des classes qui se trouvent dans core ?

      j’ai essayé de toucher au bout de code juste en dessous qui se trouve dans config_init.php mais je n’ai pas réussi … cdt
      // Chargement du coeur
      $files = scandir(_CORE_);
      print_r($files);
      foreach ($files as $filename)
      {
      echo _CORE_.$filename;
      if (is_file(_CORE_.$filename))
      require_once(_CORE_.$filename);
      }

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

CAPTCHA