Acest tutorial face parte din programul Build Your Startup With PHP pe Tuts +. În această serie, vă conduc prin lansarea unei lansări de la concept la realitate utilizând aplicația mea Planificator de întâlniri ca exemplu de viață reală. Fiecare pas de-a lungul drumului, vom lansa codul Planificatorului de întâlniri ca exemple de sursă deschisă pe care le puteți învăța. Vom aborda, de asemenea, problemele de afaceri legate de pornire în momentul în care apar.
În acest tutorial, vom construi domenii cheie în jurul datelor personale ale utilizatorului pentru o utilizare mai largă prin intermediul aplicației:
Întregul cod pentru Planificatorul întâlnirilor este scris în cadrul Yii2 Framework for PHP, care are suport integrat pentru I18n. Dacă doriți să aflați mai multe despre Yii2, consultați seria noastră paralelă Programming With Yii2 de la Tuts+.
Doar un memento, eu particip la comentariile de mai jos. Sunt interesat în special dacă aveți abordări diferite, idei suplimentare sau doriți să sugerați subiecte pentru tutoriale viitoare.
Scopul detaliilor de contact este de a permite utilizatorilor să furnizeze numere de telefon și adrese de conferințe video pentru întâlniri virtuale. Numărul de telefon este util și înainte și după întâlnire.
Construcția acestei caracteristici este relativ simplă. Așa cum am făcut și în tutoriile anterioare, am folosit generatorul de cod Yii, Gii, pentru a construi modelul pentru fișierele UserContact și CRUD.
De asemenea, am actualizat bara de navigare pentru a include o legătură către funcția de contact utilizator. În frontend / views / layouts / main.php:
$ menuItems [] = ['label' => 'Cont', 'items' => [['label' => Yii :: t ('frontend' '], [' label '=> Yii :: t (' frontend ',' Informații de contact '),' url ' : '(' frontend ',' Settings '),' url '=> [' / user-setting '], (')', 'Url' => ['/ site / logout'], 'linkOptions' => [' post'] ], ], ]; echo Nav :: widget (['opțiuni' => ['class' => 'navbar-nav navbar-right'], 'items' => $ menuItems,]);
De asemenea, puteți vedea o legătură de mai sus la funcția Setări utilizator care va fi descrisă mai jos.
Adăugarea unei meniuri de selecție pentru tipuri este o extensie comună a modelului pe care o folosim pentru a face ca formularele să fie mai prietenoase. Consultați Tip de contact mai jos:
Iată definițiile tipului de model și metodele de ajutor pentru a permite dropdown-uri prietenoase pentru serviciile de tip contact:
class UserContact extinde \ 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; ... funcția publică getUserContactType ($ data) $ options = $ this-> getUserContactTypeOptions (); returneaza optiunile $ [$ data]; funcția publică getUserContactTypeOptions () return array (auto :: TYPE_PHONE => 'Telefon', self :: TYPE_SKYPE => 'Skype', self :: TYPE_OTHER = , auto :: TYPE_GOOGLE => 'Google Talk', auto :: TYPE_MSN => 'MSN Messenger', self :: TYPE_AIM => 'AIM', self :: TYPE_YAHOO = > 'ICQ', auto :: TYPE_JABBER => 'Jabber', auto :: TYPE_QQ => 'QQ', auto :: TYPE_GADU => 'Gadu-Gadu';);
Iată dropdown-ul implementat în forma:
= $form->câmp ($ model, contact_type) -> dropDownList ($ model-> getUserContactTypeOptions (), ['prompt' => Yii :: t ('frontend' eticheta (Yii :: t ('frontend', 'Tip de contact'))?Acești ajutători de tip sunt construiți în comun prin Planificatorul de întâlniri.
Acum, să trecem la setările utilizatorului.
Setarile utilizatorului
Ca planificator de întâlniri crește în funcționalitate, va fi important să permiteți utilizatorilor să personalizeze funcționalitatea cu un set de preferințe. Construim un sub-sistem de setări pentru a gestiona aceste preferințe în cadrul aplicației.
Tabelul UserSetting este puțin diferit de alte modele în care fiecare utilizator are doar o singură înregistrare, iar fiecare înregistrare are mai multe câmpuri care reprezintă setările unui anumit utilizator. Acest lucru este diferit de momentul în care utilizatorii adaugă intrări de contacte, în care fiecare utilizator are mai multe înregistrări, fiecare reprezentând o intrare de contact.
Când utilizatorii își modifică setările, actualizăm înregistrarea setărilor individuale. De asemenea, putem extinde câmpurile mesei în timp pentru a susține opțiuni suplimentare.
Va trebui să creăm funcții de ajutor care să încarce setările unui utilizator și să creeze o înregistrare implicită pentru ele dacă acestea nu există.
De asemenea, trebuie să creați un formular pentru a face configurarea setărilor un proces ușor. Putem folosi schemele Bootstrap și extensiile widget Yii2.
Alegerea setărilor primului nostru utilizator
În timp ce numărul de setări va crește în timp, să examinăm câteva dintre cele pe care dorim să le începem:
- Fotografia profilului utilizatorului (calea spre un fișier pe care îl vor încărca)
- Primirea mementourilor cu o zi înainte de o întâlnire
- Primirea memento-urilor în zilele care au condus la o întâlnire
- Partajați detaliile de contact cu participanții la întâlnire
- Blocați toate e-mailurile din sistem
Putem crea tabelul User Setting cu o migrare activă a înregistrărilor și să le extindem ulterior cu migrările actualizate.
./ yii migrați / creați create_user_setting_tableIată migrarea cu câmpuri pentru setările noastre - rețineți relația cu tabelul Utilizator:
db-> driverName === 'mysql') $ tableOptions = 'SETAREA CHARACTERULUI utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB'; $ this-> createTable ('% user_setting', ['id' => Schema :: TYPE_PK, 'user_id' => Schema :: TYPE_BIGINT. TYPE_STRING "NOT NULL ',' avatar '=> Schema :: TYPE_STRING.' NOT NULL ',' reminder_eve '=> Schema :: TYPE_SMALLINT' NOT NULL ',' reminder_hours '=> Schema :: TYPE_INTEGER. ',' no_email '=> Schema :: TYPE_SMALLINT.' NOT NULL ',' created_at '=> Schema :: TYPE_SMALLINT. => Schema :: TYPE_INTEGER. 'NOT NULL',], $ tableOptions); $ this-> addForeignKey ('fk_user_setting_user_id', '% user_setting', 'user_id', 'user%', 'id', 'CASCADE', 'CASCADE'); funcția publică jos () $ this-> dropForeignKey ('fk_user_setting_user_id', '% user_setting'); $ This-> dropTable ( '% user_setting');Rulați migrarea:
./ yii migrați / up Instrument de migrare Yii (bazat pe Yii v2.0.2) Se va aplica un total de 1 migrare nou: m150124_003721_create_user_setting_table Aplicați migrarea de mai sus? (da: nu): da *** aplicând m150124_003721_create_user_setting_table> creați tabelul % user_setting ... done (time: 0.017s)> adăugați cheie străină fk_user_setting_user_id: user_setting % user (id) ... făcut (timpul: 0.009s) *** aplicat m150124_003721_create_user_setting_table (time: 0.031s) Migrat cu succes.Scrierea codului
Putem folosi Gii pentru a genera fișierele model și CRUD pentru noi. Desigur, va trebui să modificăm CRUD-ul pentru a afișa numai înregistrarea curentă a utilizatorului.
Iată setările pentru generatorul de modele:
Iată setările pentru controlerul CRUD:
Când utilizatorul dă clic pe Setări din bara de navigare, dorim să afișăm pagina de setări de actualizare. Să construim niște ajutoare pentru verificarea înregistrării setărilor utilizatorului și crearea acestuia dacă acesta nu există.
Iată redirecționarea indexului la acțiunea de actualizare:
/ ** * Calea implicită - redirecționarea la actualizare * @return mixt * / public function actionIndex () // returnează ID-ul înregistrării nu user_id $ id = UserSetting :: inițializa (Yii :: $ app-> user-> getId ); returnați $ this-> redirect (['update', 'id' => $ id]);Metoda Initialize creează o înregistrare pentru utilizatorul activ și stabilește toate setările implicite:
funcția statică publică inițializează ($ user_id) $ us = UserSetting :: find () -> unde (['user_id' => $ user_id]) -> one (); dacă (is_null ($ us)) $ us = setare nouă de utilizator; $ us-> user_id = $ user_id; $ us-> nume fișier = "; $ us-> avatar ="; $ us-> reminder_eve = auto :: SETTING_YES; $ us-> no_email = auto :: SETTING_NO; $ us-> contact_share = auto :: SETTING_YES; $ us-> reminder_hours = 48; $ Noi-> Salvare (); return $ us-> id;Personalizarea Formularului de setări
Trebuie să înlocuim o parte din codul de formular generat automat pentru a include casetele de selectare și o altă listă drop-down (așa cum am făcut-o și cu tipul UserContact de mai sus). Îmi place funcția căsuței de validare a Yii include posibilitatea de a specifica valori setate și dezactivate. În mod tipic, casetele de casetă din formularul web returnează un element gol (există) pentru adevărat sau nu se returnează (nu există) pentru false.
= $form->câmpul ($ model, 'reminder_eve') -> checkbox (['label' => Yii :: t ('frontend' , "verificat" => $ model :: SETTING_YES]); ?> = $form->câmp ($ model, reminder_hours) -> dropDownList ($ model-> getEarlyReminderOptions (), ['prompt' => Yii :: t (' > etichetă (Yii :: t ('frontend', 'Early reminder'))> = $form->câmpul ('model', 'contact_share') -> (<'label' => Yii :: t ('frontend' 'check' => $ model :: SETTING_YES]); ?> = $form->câmpul ('model', 'no_email') -> bifați caseta de validare ('label' => Yii :: t (' => modelul modelului :: SETTING_YES]); ?>Iată rezultatul final:
Să mergem mai departe și să extindem UserSetting pentru a sprijini fotografiile de profil.
Imagini de profil
Pentru a afișa fotografiile utilizatorilor pe paginile de întâlnire, trebuie să sprijinim utilizatorii care încarcă o fotografie (în majoritatea cazurilor). Alternativ, cel puțin în mod prestabilit, putem folosi serviciul Gravatar care asociază o fotografie de profil prin adresa de e-mail a utilizatorului. Încărcarea și salvarea fișierelor pe un server este întotdeauna o sarcină de dezvoltare web detaliată și delicată pe care o vom trece în scurt timp.
Configurarea filelor Bootstrap
În primul rând, să începem prin adăugarea filelor în formatul de setări pentru utilizatori, care va separa setările generale de imaginile de profil. Folosind definițiile de stil Bootstrap nav-tab, vină cu acest lucru:
- Setări
- Încarcă fotografie
= $form->câmpul ($ model, 'reminder_eve') -> checkbox (['label' => Yii :: t ('frontend' , "verificat" => $ model :: SETTING_YES]); ?> = $form->câmp ($ model, reminder_hours) -> dropDownList ($ model-> getEarlyReminderOptions (), ['prompt' => Yii :: t (' > etichetă (Yii :: t ('frontend', 'Early reminder'))> = $form->câmpul ('model', 'contact_share') -> (<'label' => Yii :: t ('frontend' 'check' => $ model :: SETTING_YES]); ?> = $form->câmpul ('model', 'no_email') -> bifați caseta de validare ('label' => Yii :: t (' => modelul modelului :: SETTING_YES]); ?>= $form->câmp ($ model, 'imagine') -> widget ('FileFilter' => ['jpg', 'gif', 'png']],]); ?>Se pare ca aceasta:
În mod implicit, dacă nu există nicio imagine încărcată, vom încerca să afișăm Gravatar-ul utilizatorului.
Extensii utile Yii2 pentru imaginile de profil
Există patru extensii Yii2 pe care vreau să le includ pentru suportul imaginilor de profil:
- Gravatarul lui Carsten Brandt va afișa gravatare
- Intrare fișier Kartik Visweswaran pentru a susține încărcarea fișierelor imagine
- Yii Imaginați-vă pentru a scala imagini la diferite dimensiuni
- 2Amigos Resource Manager pentru suport ulterior pentru stocarea Amazon S3
Visweswaran și 2 Amigo au produs o serie de extensii Yii2 care sunt super utile și oferă, în general, o documentație solidă.
Deci, adăugați aceste extensii la fișierul composer.json:
"cebe / yii2-gravatar": "*", "kartik-v / yii2-widget-fileinput": "*", "yiisoft / yii2-imagine": "*", "2 amigos/yii2-switch-widget": "0.1. *", "2 amigos/yii2-resource-manager-component": "0.1. *"Și actualizați compozitorul:
compozitorUtilizarea imaginilor Gravatar
Dacă nu există nicio imagine de profil configurată, vom afișa gravatarul utilizatorului. Serviciul Gravatar se referă la adresa de e-mail a utilizatorului înregistrat. Iată codul pentru a afișa Gravatar:
echo \ Cebe \ gravatar \ Gravatar :: widget ([ 'email' => modele \ Common \ utilizator :: găsi () -> în cazul în care ([ 'id' => Yii :: $ app-> user-> getId () ]) -> unul () -> e-mail, 'opţiuni' => [ 'clasa' => 'profil-image', 'alt' => modele \ Common \ utilizator :: găsi () -> în cazul în care ([ 'id „=> Yii :: $ app-> user-> getId ()]) -> unul () -> numele de utilizator,], 'size' => 128]);Va arăta așa. Dacă utilizatorul a configurat un Gravatar, veți vedea imaginea aleasă.
Încărcarea unei imagini de profil
Pentru încărcarea imaginilor, vom folosi widgetul excelent de introducere a fișierelor de la Kartik. De asemenea, el oferă un explicator foarte frumos cu privire la modul de utilizare a acestuia.
Iată codul pentru formularul de actualizare care afișează widgetul din panoul Încărcare fotografie:
= $form->câmp ($ model, 'imagine') -> widget ('FileFilter' => ['jpg', 'gif', 'png']],]); ?>În partea de sus a formularului se află enctype pentru date formate din mai multe părți:
[ 'Enctype' => 'multipart / form-data']]); // important?>Formularul arată astfel:
De asemenea, adăugăm reguli la modelul UserSetting pentru a restricționa încărcarea în jpg, gif și png și pentru a limita dimensiunea încărcării la 100kb.
normele funcției publice () return [[[ 'user_id',], 'necesară'], [[,], 'unic'], [[], 'în condiții de siguranță'], [[ 'image 'image' 'USER_ID' '],' ['fișier', 'fișier', 'fișier', 'extensii' => 'jpg, gif, png' '],' string ',' max '=> 255], [[' user_id ',' reminder_eve ',' reminder_hours ',' contact_share ',' no_email ',' created_at ',' updated_at '],' integer '] ,];Apropo, validatorii Yii2 au o lățime uimitoare de capabilități pentru multe operațiuni obișnuite pe care dezvoltatorii web le pot construi în mod obișnuit. Voi încerca să explorez acest lucru într-un program viitor de programare cu Yii2.
Iată codul care gestionează postarea din formularul de actualizare. În general, probabil că este o idee bună să redimensionați mai mult acest cod în metode de model și să reduceți complexitatea controlorilor.
dacă ($ model-> încărcați (Yii :: $ app-> request-> post ())) $ image = ÎncărcatFile :: getInstance ($ model, 'imagine'); dacă ! is_null ($ image)) // salvați cu imaginea // stocați numele fișierului sursă $ model-> nume fișier = $ image-> name; $ ext = end ((explode (".", $ image-> nume)); // genera un nume unic de fișier pentru a preveni nume de fișiere duplicat $ Model-> Avatar = Yii :: $ app-> securitate-> generateRandomString () "$ ext.".; // calea de salvare a fișierului, puteți seta un uploadPath // în Yii :: $ app-> params (așa cum este folosit în exemplul de mai jos) Yii :: $ app-> params ['uploadPath'] = Yii :: $ app -> bazaPath. '/ Web / încărcări / avatar /'; $ path = Yii :: $ app-> params ['uploadPath']. $ Model-> avatar; $ model-> user_id = Yii :: $ app-> user-> getId (); dacă ($ model-> update ()) $ image-> saveAs (calea $);Imaginile trebuie să fie stocate unde pot fi vizualizate de serverul web. Am creat un director de upload / avatar în arborele / frontend / web.
Scalarea imaginilor cu imagine
De fapt, dorim să stocăm imaginea în trei dimensiuni: dimensiune completă, un mic pătrat pentru afișarea în bara de navigare sau vizualizările de listă și un pătrat de dimensiuni medii pentru paginile de întâlnire.
Vom folosi extensia Yii2 Imagine pentru a scala imaginile; extinde biblioteca de manipulare imagine Imagine pentru PHP.
Iată codul care salvează și salvează dimensiunile suplimentare ale imaginilor:
$ Image-> SAVEAS (calea $); Imagine :: miniatură (Yii :: $ app-> params ['uploadPath']. $ Model-> avatar, 120, 120) -> salvează (Yii :: $ app-> params ['uploadPath' $ model-> avatar, ['calitate' => 50]); Imagine :: miniatură (Yii :: $ app-> params ['uploadPath']. $ Model-> avatar, 30, 30) -> salvează (Yii :: $ app-> params ['uploadPath' $ model-> avatar, ['calitate' => 50]);Iată formularul finalizat care afișează imaginea pătrată pe pagina de profil a utilizatorului:
Curățarea imaginilor neutilizate
Când utilizatorii încarcă o nouă fotografie, trebuie să ștergem vechea imagine și copiile asociate acesteia. Vom extinde controlerul pentru a apela o nouă metodă de ștergere:
$ image = IncarcatFile :: getInstance ($ model, 'imagine'); dacă is_null ($ image)) // cale spre imaginea existentă pentru post-delete $ image_delete = $ model-> avatar; ... $ model-> deleteImage (Yii :: $ app-> params ['uploadPath' $ image_delete);Iată metoda deleteImage în UserSetting:
funcția publică deleteImage ($ path, $ filename) $ file = array (); $ fișier [] = $ cale $ filename; fișierul $ [] = $ path.'sqr _ '. $ filename; fișierul $ [] = $ path.'sm _ '. $ filename; foreach (fișier $ ca $ f) // verifica dacă există fișiere pe serverul în cazul în care (gol ($ f) && file_exists ($ f)!) // sterge unlink fișier ($ f);Utilizarea Amazon S3 pentru a stoca imaginile
Stocarea imaginilor încărcate de utilizatori pe serverul nostru web poate crea complexități. Înseamnă că, în plus față de copierea de rezervă a MySQL, trebuie întotdeauna să facem o copie a unei părți a sistemului de fișiere. Poate complica operațiile de restaurare a serverului și migrațiile. De asemenea, pune o sarcină pe stivă LAMP ori de câte ori sunt încărcate imagini.
Utilizarea Amazon S3 separă această sarcină de serverul dvs. principal de web și poate îmbunătăți performanța și simplifica gestionarea serverului în timp, în special în ceea ce privește portabilitatea, scalabilitatea și upgrade-urile. Voi revizui încărcarea și accesarea fișierelor de pe Amazon S3 într-un tutorial viitor.
Ce urmeaza?
Sper că ați învățat câteva aspecte aplicate ale Yii, ActiveRecord, Bootstrap, formulare, încărcarea fișierelor și manipularea imaginilor. Mi-a plăcut să lucrez cu unele dintre widgeturile noi JQuery disponibile ca extensii Yii. Uita-te pentru tutoriale viitoare în construirea dvs. de pornire cu seria PHP-există o mulțime de caracteristici distractive vine. De fapt, ne apropiem de posibilitatea de a ne programa prima întâlnire!
Vă rugăm să nu adăugați întrebările și comentariile de mai jos; În general, particip la discuții. Puteți să mă contactați și pe Twitter @reifman sau să mă trimiteți direct prin e-mail.
Link-uri conexe
- Programarea cu Yii2: Noțiuni de bază
- Introducere în Cadrul Yii
- Yii2 Developer Exchange, site-ul autorilor pentru Yii2