Ce tutoriel fait partie de la série Construire son démarrage avec PHP sur Tuts +. Dans cette série, je vous guide dans le lancement d'une startup du concept à la réalité en utilisant mon application Meeting Planner comme exemple concret. À chaque étape, nous publierons le code de Meeting Planner sous forme d’exemples open source à partir desquels vous pourrez apprendre. Nous aborderons également les problèmes commerciaux liés au démarrage à mesure qu'ils surviennent..
Dans ce tutoriel, nous allons créer des zones clés autour des données propres à l'utilisateur pour une utilisation plus large via l'application:
Tout le code de Meeting Planner est écrit dans le framework Yii2 pour PHP, qui prend en charge I18n de manière intégrée. Si vous souhaitez en savoir plus sur Yii2, consultez notre série parallèle Programmer avec Yii2 chez Tuts+.
Juste un rappel, je participe aux commentaires ci-dessous. Je suis particulièrement intéressé si vous avez des approches différentes, des idées supplémentaires ou si vous souhaitez suggérer des sujets pour de futurs tutoriels..
Les informations de contact ont pour but de permettre aux utilisateurs de fournir des numéros de téléphone et des adresses de vidéoconférence pour des réunions virtuelles. Le numéro de téléphone est également utile avant et après la réunion.
Construire cette fonctionnalité est relativement simple. Comme dans les tutoriels précédents, nous avons utilisé le générateur de code de Yii, Gii, pour construire le modèle des fichiers UserContact et CRUD..
Nous avons également mis à jour la barre de navigation pour inclure un lien vers la fonction Contact utilisateur. Dans frontend / views / layouts / main.php:
$ menuItems [] = ['label' => 'Compte', 'items' => [['label' => Yii :: t ('interface', 'Amis'), 'url' => ['/ ami '],], [' label '=> Yii :: t (' interface ',' Informations de contact '),' url '=> [' / user-contact '],], [' label '=> Yii: : t ('frontend', 'Settings'), 'url' => ['/ user-setting'],], ['label' => Yii :: t ('frontend', 'Logout'). ' ('. Yii :: $ app-> utilisateur-> identité-> nom d'utilisateur.') ',' Url '=> [' / site / logout '],' linkOptions '=> [' data-method '=>' post ']],],]; echo Nav :: widget (['options' => ['class' => 'navbar-nav navbar-right'], 'items' => $ menuItems,]);
Vous pouvez également voir un lien ci-dessus vers la fonctionnalité Paramètres utilisateur qui sera décrite plus en détail ci-dessous.
L'ajout d'un menu déroulant de sélection pour les types est une extension de modèle courante que nous utilisons pour rendre les formulaires plus conviviaux. Voir le Type de contact menu déroulant ci-dessous:
Voici les définitions de type de modèle et les méthodes d'assistance permettant des menus déroulants conviviaux pour les services de type de contact:
la classe UserContact s étend \ yii \ db \ ActiveRecord const TYPE_OTHER = 0; const TYPE_PHONE = 10; const TYPE_SKYPE = 20; const TYPE_FACEBOOK = 30; const TYPE_GOOGLE = 40; const TYPE_MSN = 50; const TYPE_AIM = 60; const TYPE_YAHOO = 70; const TYPE_ICQ = 80; const TYPE_JABBER = 90; const TYPE_QQ = 100; const TYPE_GADU = 110;… fonction publique getUserContactType ($ data) $ options = $ this-> getUserContactTypeOptions (); retourne $ options [$ data]; fonction publique getUserContactTypeOptions () return array (self :: TYPE_PHONE => 'Phone', self :: TYPE_SKYPE => 'Skype', self :: TYPE_OTHER => 'Autre', self :: TYPE_FACEBOOK => 'Facebook Messenger' , auto :: TYPE_GOOGLE => 'Google Talk', auto :: TYPE_MSN => 'MSN Messenger', auto :: TYPE_AIM => 'AIM', auto :: TYPE_YAHOO => 'Yahoo! Messenger', auto :: TYPE_ICQ = > 'ICQ', self :: TYPE_JABBER => 'Jabber', self :: TYPE_QQ => 'QQ', self :: TYPE_GADU => 'Gadu-Gadu',);
Voici la liste déroulante implémentée sous la forme:
= $form->field ($ model, 'contact_type') -> dropDownList ($ model-> getUserContactTypeOptions (), ['prompt' => Yii :: t ('frontend', 'Quel type de contact est-ce?')]) -) label (Yii :: t ('frontend', 'Type de contact'))?>Ces assistants de type sont des constructions courantes dans Meeting Planner..
Passons maintenant aux paramètres de l'utilisateur.
Paramètres utilisateur
À mesure que la fonctionnalité de Meeting Planner augmente, il sera important de permettre aux utilisateurs de personnaliser les fonctionnalités avec un ensemble de préférences. Nous construisons un sous-système de paramètres utilisateur pour gérer ces préférences dans l'application.
La table UserSetting est un peu différente des autres modèles en ce que chaque utilisateur n'a qu'un seul enregistrement et chaque enregistrement possède de nombreux champs qui représentent les paramètres d'un utilisateur particulier. Ceci est différent de lorsque les utilisateurs ajoutent des entrées de contact, chaque utilisateur ayant plusieurs enregistrements représentant chacun une entrée de contact..
Lorsque les utilisateurs modifient leurs paramètres, nous mettons à jour leurs enregistrements de paramètres individuels. Nous pouvons également étendre les champs de la table au fil du temps pour prendre en charge des options supplémentaires.
Nous devrons créer des fonctions d'assistance qui chargent les paramètres d'un utilisateur et créer un enregistrement par défaut pour eux s'ils n'existent pas..
Nous devons également créer un formulaire pour faciliter la configuration des paramètres. Nous pouvons utiliser les dispositions de Bootstrap et les extensions de widget Yii2.
Choisir nos premiers paramètres d'utilisateur
Bien que le nombre de paramètres augmente avec le temps, examinons quelques-uns de ceux avec lesquels nous voulons commencer:
- Photo de profil de l'utilisateur (chemin d'accès au fichier qu'il téléchargera)
- Recevoir des rappels la veille d'une réunion
- Recevoir des rappels dans les jours précédant une réunion
- Partager les détails de contact avec les participants à la réunion
- Bloquer tous les courriels du système
Nous pouvons créer la table de configuration de l'utilisateur avec une migration active d'enregistrement et l'étendre ultérieurement avec les migrations mises à jour..
./ yii migrate / create create_user_setting_tableVoici la migration avec des champs pour nos paramètres - notez la relation avec la table User:
db-> nomDuPort === 'mysql') $ tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB'; $ this-> createTable ('% user_setting', ['id' => Schema :: TYPE_PK, 'user_id' => Schema :: TYPE_BIGINT. 'NOT NULL', 'nom du fichier' => Schema :: TYPE_STRING. 'NOT NULL', 'avatar' => Schéma :: TYPE_STRING. 'NOT NULL', 'reminder_eve' => Schéma :: TYPE_SMALLINT. 'NON NULL', 'reminder_hours' => Schéma :: TYPE_INTEGER. 'NON NULL ',' contact_share '=> Schema :: TYPE_SMALLINT.' NOT NULL ',' no_email '=> Schema :: TYPE_SMALLINT.' NOT NULL ',' created_at '=> Schéma :: TYPE_INTEGER.' NOT NULL ',' updated_at ' => Schema :: TYPE_INTEGER. 'NOT NULL',], $ tableOptions); $ this-> addForeignKey ('fk_user_setting_user_id', '% user_setting', 'id_utilisateur', '% user', 'id', 'CASCADE', 'CASCADE'); public function down () $ this-> dropForeignKey ('fk_user_setting_user_id', '% user_setting'); $ this-> dropTable ('% user_setting');Exécutez la migration:
./ yii migrate / up Yii Outil de migration (basé sur Yii v2.0.2) Total 1 nouvelle migration à appliquer: m150124_003721_create_user_setting_table Appliquer la migration ci-dessus? (yes | no) [no]: yes *** application de m150124_003721_create_user_setting_table> créer une table % user_setting… done (heure: 0.017s)> ajouter une clé étrangère fk_user_setting_user_id: % user_setting (user_id) (user_id) % user (id)… terminé (heure: 0,009s) *** appliqué m150124_003721_create_user_setting_table (heure: 0,031s) Migration réussie.Écrire le code
Nous pouvons utiliser Gii pour générer les fichiers de modèle et CRUD pour nous. Bien sûr, nous devrons modifier le CRUD pour afficher uniquement l'enregistrement de l'utilisateur actuel.
Voici les paramètres du générateur de modèle:
Voici les paramètres du contrôleur CRUD:
Lorsque l'utilisateur clique sur Paramètres dans la barre de navigation, nous souhaitons afficher la page des paramètres de mise à jour. Construisons des aides pour vérifier l'enregistrement des paramètres de l'utilisateur et le créer s'il n'existe pas.
Voici la redirection d'index vers l'action de mise à jour:
/ ** * chemin par défaut - redirection vers la mise à jour * @return mixed * / public function actionIndex () // retourne l'id de l'enregistrement et non l'id de l'utilisateur $ id = UserSetting :: initialize (Yii :: $ app-> user-> getId () ) return $ this-> redirect (['update', 'id' => $ id]);La méthode Initialize crée un enregistrement pour l'utilisateur actif et définit tous les paramètres par défaut:
fonction statique publique initialize ($ user_id) $ us = UserSetting :: find () -> where (['user_id' => $ user_id]) -> one (); if (is_null ($ us)) $ us = new UserSetting; $ us-> user_id = $ user_id; $ us-> nom_fichier = "; $ us-> avatar ="; $ us-> reminder_eve = self :: SETTING_YES; $ us-> no_email = self :: SETTING_NO; $ us-> contact_share = self :: SETTING_YES; $ us-> reminder_hours = 48; $ us-> save (); return $ us-> id;Personnalisation du formulaire de configuration
Nous devons remplacer une partie du code de formulaire généré automatiquement pour inclure des cases à cocher et une autre liste déroulante (comme nous l'avons fait avec le type UserContact ci-dessus). J'aime que la fonctionnalité de case à cocher de Yii inclut la possibilité de spécifier des valeurs définies et non définies. En règle générale, les cases à cocher de formulaire Web renvoient un élément vide (existe) pour true ou ne renvoie pas (n'existe pas) pour false.
= $form->field ($ model, 'reminder_eve') -> checkBox (['label' => Yii :: t ('frontend', 'Envoyer le dernier rappel la veille'), 'décocher' => $ model :: SETTING_NO , 'vérifié' => $ modèle :: SETTING_YES]); ?> = $form->field ($ model, 'reminder_hours') -> dropDownList ($ model-> getEarlyReminderOptions (), ['prompt' => Yii :: t ('frontend', 'Quand voudriez-vous avoir votre premier rappel?')]) - > label (Yii :: t ('frontend', 'Early Rappels'))?> = $form->champ ($ model, 'contact_share') -> case à cocher (['label' => Yii :: t ('frontend', 'Partager mes informations de contact avec les participants à la réunion')), 'décocher' => $ model :: SETTING_NO, 'vérifié' => $ modèle :: SETTING_YES]); ?> = $form->field ($ model, 'no_email') -> case à cocher (['label' => Yii :: t ('frontend', 'Désactiver tous les emails'), 'décocher' => $ model :: SETTING_NO, 'coché' => $ model :: SETTING_YES]); ?>Voici le résultat final:
Continuons et étendons UserSetting pour prendre en charge les photos de profil..
Images de profil
Pour afficher les photos des utilisateurs sur les pages de réunion, nous devons aider les utilisateurs à télécharger une photo (dans la plupart des cas). Sinon, au moins par défaut, nous pouvons utiliser le service Gravatar qui associe une photo de profil à l'adresse électronique de l'utilisateur. Le téléchargement et la sauvegarde de fichiers sur un serveur constituent toujours une tâche de développement Web détaillée et délicate, que nous allons parcourir rapidement..
Configuration des onglets d'amorçage
Tout d’abord, commençons par ajouter des onglets au formulaire de paramètres d’utilisateur, qui sépareront les paramètres généraux des images de profil. En utilisant les définitions de style de l'onglet de navigation Bootstrap, nous obtenons ceci:
- Réglages
- Envoyer la photo
= $form->field ($ model, 'reminder_eve') -> checkBox (['label' => Yii :: t ('frontend', 'Envoyer le dernier rappel la veille'), 'décocher' => $ model :: SETTING_NO , 'vérifié' => $ modèle :: SETTING_YES]); ?> = $form->field ($ model, 'reminder_hours') -> dropDownList ($ model-> getEarlyReminderOptions (), ['prompt' => Yii :: t ('frontend', 'Quand voudriez-vous avoir votre premier rappel?')]) - > label (Yii :: t ('frontend', 'Early Rappels'))?> = $form->champ ($ model, 'contact_share') -> case à cocher (['label' => Yii :: t ('frontend', 'Partager mes informations de contact avec les participants à la réunion')), 'décocher' => $ model :: SETTING_NO, 'vérifié' => $ modèle :: SETTING_YES]); ?> = $form->field ($ model, 'no_email') -> case à cocher (['label' => Yii :: t ('frontend', 'Désactiver tous les emails'), 'décocher' => $ model :: SETTING_NO, 'coché' => $ model :: SETTING_YES]); ?>= $form->field ($ model, 'image') -> widget (FileInput :: classname (), ['options' => ['accepter' => 'image / *'], 'pluginOptions' => ['allowedFileExtensions' => ['jpg', 'gif', 'png']],]); ?>Cela ressemble à ceci:
Par défaut, s'il n'y a pas d'image téléchargée, nous essaierons d'afficher le Gravatar de l'utilisateur..
Extensions Yii2 utiles pour les images de profil
Je souhaite inclure quatre extensions Yii2 pour la prise en charge des images de profil:
- Le gravatar de Carsten Brandt pour afficher les gravatars
- Entrée de fichier Kartik Visweswaran pour prendre en charge le téléchargement de fichiers image
- Yii Imagine pour redimensionner les images à différentes tailles
- 2Amigos Resource Manager pour une prise en charge ultérieure du stockage Amazon S3
Visweswaran et 2Amigos ont produit un certain nombre d’extensions Yii2 qui sont super utiles et fournissent généralement une documentation solide..
Ajoutez donc ces extensions à votre fichier composer.json:
"cebe / yii2-gravatar": "*", "kartik-v / yii2-widget-fileinput": "*", "yiisoft / yii2-imagine": "*", "il y a 2 heures": "0.1. *", "2 amigos/yii2-resource-manager-component": "0.1. *"Et mettre à jour le compositeur:
mise à jour du compositeurUtiliser des images Gravatar
Si aucune image de profil n'est configurée, nous afficherons le gravatar de l'utilisateur. Le service Gravatar fait référence à l'adresse électronique de l'utilisateur enregistré. Voici le code pour afficher le Gravatar:
echo \ cebe \ gravatar \ Gravatar :: widget (['email' => commun \ modèles \ Utilisateur :: find () -> où (['id' => Yii :: $ app-> user-> getId () ]) -> one () -> email, 'options' => ['class' => 'image_profil', 'alt' => commun \ modèles \ Utilisateur :: find () -> où (['id '=> Yii :: $ app-> user-> getId ()]) -> one () -> nom d'utilisateur,],' size '=> 128,]);Cela ressemblera à quelque chose comme ça. Si l'utilisateur a configuré un Gravatar, vous verrez l'image choisie.
Télécharger une image de profil
Pour télécharger des images, nous utiliserons l'excellent widget de saisie de fichiers de Kartik. Il offre également un très bon explicateur sur la façon de l'utiliser.
Voici le code de notre formulaire de mise à jour qui affiche le widget dans le volet Télécharger une photo:
= $form->field ($ model, 'image') -> widget (FileInput :: classname (), ['options' => ['accepter' => 'image / *'], 'pluginOptions' => ['allowedFileExtensions' => ['jpg', 'gif', 'png']],]); ?>Le haut du formulaire inclut un enctype pour les données de formulaire en plusieurs parties:
['enctype' => 'multipart / form-data']]); // important?>Le formulaire ressemble à ceci:
Nous ajoutons également des règles au modèle UserSetting pour limiter les envois au format jpg, gif et png, ainsi que la taille de l'envoi à 100 Ko..
règles de fonction publique () return [[['user_id',], 'required'], [['user_id',], 'unique'], [['image'], 'safe'], [['image '],' file ',' extensions '=>' jpg, gif, png '], [[' 'image'], 'file', 'maxSize' => '100000'], [['nomfichier', 'avatar '],' string ',' max '=> 255], [[' user_id ',' reminder_eve ',' reminder_hours ',' contact_share ',' no_email ',' created_at ',' updated_at '],' entier '] ,];En passant, les validateurs Yii2 disposent d’un nombre impressionnant de fonctionnalités pour la plupart des opérations courantes que les développeurs Web pourraient créer manuellement. Je vais essayer d'explorer cela dans un futur tutoriel sur la programmation avec Yii2.
Voici le code qui gère la publication à partir du formulaire de mise à jour. En général, c'est probablement une bonne idée de retravailler davantage de ce code dans des méthodes de modèle et de réduire la complexité des contrôleurs..
if ($ model-> load (Yii :: $ app-> request-> post ())) $ image = UploadedFile :: getInstance ($ model, 'image'); if (! is_null ($ image)) // enregistrer avec image // stocker le nom du fichier source $ model-> nom_fichier = $ image-> nom; $ ext = end ((explode (".", $ image-> nom))); // génère un nom de fichier unique pour éviter les noms de fichiers en double $ model-> avatar = Yii :: $ app-> security-> generateRandomString (). ". $ ext"; // le chemin pour enregistrer le fichier, vous pouvez définir un uploadPath // dans Yii :: $ app-> params (comme utilisé dans l'exemple ci-dessous) Yii :: $ app-> params ['uploadPath'] = Yii :: $ app -> basePath. '/ web / uploads / avatar /'; $ path = Yii :: $ app-> params ['uploadPath']. $ model-> avatar; $ model-> user_id = Yii :: $ app-> user-> getId (); if ($ model-> update ()) $ image-> saveAs ($ path);Les images doivent être stockées à un endroit où elles peuvent être visualisées par le serveur Web. J'ai créé un répertoire uploads / avatar dans l'arborescence / frontend / web.
Mise à l'échelle d'images avec Imagine
En fait, nous souhaitons stocker l'image en trois tailles: taille réelle, un petit carré à afficher dans la barre de navigation ou la liste, et un carré de taille moyenne pour les pages de réunion..
Nous utiliserons l'extension Yii2 Imagine pour redimensionner des images. il étend la bibliothèque de manipulation d'images Imagine pour PHP.
Voici le code qui redimensionne et enregistre les tailles d'image supplémentaires:
$ image-> saveAs ($ path); Image :: thumbnail (Yii :: $ app-> params ['uploadPath']. $ Model-> avatar, 120, 120) -> enregistrer (Yii :: $ app-> params ['uploadPath']. 'Sqr_' . $ modèle-> avatar, ['qualité' => 50]); Image :: thumbnail (Yii :: $ app-> params ['uploadPath']. $ Model-> avatar, 30, 30) -> enregistrer (Yii :: $ app-> params ['uploadPath']. 'Sm_' . $ modèle-> avatar, ['qualité' => 50]);Voici le formulaire terminé affichant l'image carrée sur la page de profil de l'utilisateur:
Nettoyage des images inutilisées
Lorsque les utilisateurs téléchargent une nouvelle photo, nous devons supprimer l'ancienne image et les copies à l'échelle qui l'accompagnent. Nous allons développer le contrôleur pour appeler une nouvelle méthode de suppression:
$ image = UploadedFile :: getInstance ($ model, 'image'); if (! is_null ($ image)) // chemin d'accès à l'image existante pour post-suppression $ image_delete = $ modèle-> avatar;… $ modèle-> deleteImage (Yii :: $ app-> params ['uploadPath'], $ image_delete);Voici la méthode deleteImage dans UserSetting:
fonction publique deleteImage ($ path, $ filename) $ file = array (); $ file [] = $ path. $ filename; $ file [] = $ path.'sqr _ '. $ filename; $ file [] = $ path.'sm _ '. $ filename; foreach ($ file as $ f) // vérifie si le fichier existe sur le serveur if (! empty ($ f) && file_exists ($ f)) // delete file unlink ($ f);Utilisation d'Amazon S3 pour stocker des images
Le stockage des images téléchargées par les utilisateurs sur notre serveur Web peut créer des complexités. Cela signifie qu'en plus de la sauvegarde de MySQL, nous devons également sauvegarder une partie du système de fichiers. Cela peut compliquer les opérations de restauration du serveur et les migrations. Il met également une charge sur notre pile LAMP lorsque des images sont chargées.
L'utilisation d'Amazon S3 sépare cette tâche de votre serveur Web principal et peut améliorer les performances et simplifier la gestion du serveur au fil du temps, notamment en ce qui concerne la portabilité, l'évolutivité et les mises à niveau. Je passerai en revue le téléchargement et l'accès aux fichiers d'Amazon S3 dans un futur tutoriel.
Et après?
J'espère que vous avez appris certains aspects appliqués de Yii, ActiveRecord, Bootstrap, les formulaires, le téléchargement de fichiers et la manipulation d'images. J'ai aimé travailler avec certains des nouveaux widgets JQuery disponibles en tant qu'extensions Yii. Surveillez les prochains tutoriels dans notre rubrique Construire votre démarrage. Avec la série PHP, de nombreuses fonctionnalités amusantes sont à venir. En fait, nous nous rapprochons de la possibilité de planifier notre première réunion!
N'hésitez pas à ajouter vos questions et commentaires ci-dessous; Je participe généralement aux discussions. Vous pouvez également me joindre sur Twitter @reifman ou m'envoyer un email directement.
Liens connexes
- Programmation avec Yii2: Mise en route
- Introduction au framework Yii
- Yii2 Developer Exchange, le site de conseils de l'auteur pour Yii2