V4 Pr. Licenta Bajnok Tamas [302781]
UNIVERSITATEA DIN ORADEA
FACULTATEA DE INGINERIE ELECTRICĂ ȘI
TEHNOLOGIA INFORMAȚIEI
PROGRAMUL DE STUDIU CALCULATOARE
FORMA DE ÎNVĂȚĂMÂNT ZI
Proiect de diplomă
COORDONATOR ȘTIINȚIFIC
Prof. dr.ing. Ștefan VÁRI-KAKAS
ABSOLVENT: [anonimizat]
2018
UNIVERSITATEA DIN ORADEA
FACULTATEA DE INGINERIE ELECTRICĂ ȘI
TEHNOLOGIA INFORMAȚIEI
PROGRAMUL DE STUDIU CALCULATOARE
FORMA DE ÎNVĂȚĂMÂNT ZI
Proiectarea și implementarea unei aplicații pentru teste și chestionare auto
COORDONATOR ȘTIINȚIFIC
Prof. dr.ing. Ștefan VÁRI-KAKAS
ABSOLVENT: [anonimizat]
2018
[anonimizat], [anonimizat], ci sunt un copil care are puterea de a demonstra ca nimic nu e imposibil. [anonimizat]. Aplicația ,,Școala auto” [anonimizat]. Acum câțiva ani am fost și eu în postura de a [anonimizat], dar, [anonimizat], erori, [anonimizat].
Aplicația ,,Scoala auto” dezvoltată în cadrul proiectului oferă diverse funcționalități:
[anonimizat]:
HTML – [anonimizat]: tag-uri, elemente, [anonimizat], componente, [anonimizat] – [anonimizat], [anonimizat] – folosit pentu baza de date
Scopul aplicației este de a înștiința, [anonimizat]-o continuă dezvoltare spre a avea o experiență cât mai plăcută.
Capitolul I. Concepte teoretice
În procesul de dezvoltare a aplicației, [anonimizat] o [anonimizat].
PHP este unul dintre cele mai populare limbaje de programare actuale ( 82% [anonimizat] ) [anonimizat] 7, l-a făcut să fie și mai stabil decât versiunile anterioare.
De ce merită să lucrăm cu un framework și nu doar cu PHP simplu?
un framework ne facilitează munca de programator
întreținerea codului devine mai ușoară
modelul MVC ajută la implementare
din punct de vedere a [anonimizat], [anonimizat]:
Symfony – [anonimizat]-source web application. Prima lansare a avut loc în data de 22 octombrie 2005 [8]. [anonimizat]. Symfony pune la dispoziție zeci de componente pregătite pentru implementare. API-[anonimizat], [anonimizat], cum este de de exemplu și AngularJS [45]. Foarte multe proiecte mari au la bază Symfony, cum este și Drupal-ul sau phpBB-ul; de asemenea, cel mai popular framework PHP, Laravel-ul folosește Symfony ca și fundație [7].
Laravel – este unul dinte cele mai populare framework-uri actuale de PHP. Prima versiune a apărut în iunie, 2011, iar în mai 2015 s-a anunțat versiunea 5.1 care are suport pe termen lung (2 ani). Multe dintre companiile de hosting favorizează aplicațiile scrie în Laravel [7].
Yii – Yii a fost creat de Qiang Xue în anul 2008. Este un framework securizat de mare performanță pe piața aplicațiilor web. Yii folosește Composer-ul [46] pentru a instala și a gestina componentele și plugin-urile PHP. Este unul dintre cele mai rapide framework-uri, din cauza tehnicii de lazy-loading. Un alt beneficiu al lui Yii este jQuery-ul, care este implicit integrat în el. Similar cu Symfony, Yii se bazează pe componente pentru a suporta implementarea rapidă al aplicațiilor [54].
Analizând opțiunile de mai sus se observă că fiecare framework are propriile avantaje sau dezavantaje; în final am hotărât să folosesc Symfony, deoacere acesta este utilizat ca fundament și în alte framework-uri și, în ultimele versiuni prezintă îmbunătățiri majore de performantă față de versiunile anterioare. Symfony e implementat de compania franceză SensioLabs, care deja are 7 birouri în Franța, Germania și Marea Britanie. Scopul lor la dezvoltarea framework-ului era crearea unui produs de calitate și de mare performanță pentru dezvoltarea aplicațiilor web [9].
I.1. Framework-ul Symfony
„Symfony este un set de componente PHP, un framework Web Application, o filozofie, și o comunitate – toate acestea funcționând împreună în armonie.” [9]
Acest framework (Figura I.1) este între liderii din această categorie și a fost puternic inspirat de Spring Framework la începutul aniilor 2000 [8]. Folosește un set de componente PHP reutilizabile și lucreză cu modelul MVC. Aceste componente, biblioteci PHP sine stătătoare menționate mai înainte au devenit fundamentul standard pe care sunt construite cele mai bune, cele mai mari aplicații, de ex. Drupal-ul [11]. Avantajele Symfony-ului sunt următoarele:
Reputația
După 13 ani experiență în domeniu, Symfony în zilele noastre este un framework stabil, cunoscut, dar și recunoscut pe plan internațional. Acesta este dovedit de numărul referințelor care a crescut exponențial cu timpul. Symfony are de asemenea o comunitate activă din mii de dezvoltatori și alți contribuabili. Această comunitate uriașă participă la continuă dezvoltare al framework-ului [12].
Performanța
În spatele produsului Symfony, există o companie: SensioLabs, care are pe piață deja peste 18 ani de experiență. Având în vedere nevoile companiei, echipele de dezvoltare folosesc tot Symfony pentru realizarea proiectelor clienților.
Dezvoltatorul Symfony-ului, compania SensioLabs oferă întotdeauna sprijin al framework-ului pe termen lung. În afară de acest sprijin, există la dispoziție un întreg ecosistem care a crescut cu timpul în jurul Symfony-ului: comunitatea.
În vederea dezvoltării durabile, Symfony este distribuită sub licența MIT cu licență Open Source [12].
Referințe
Mii de site-uri de toate dimensiunile și de toate tipurile au încredere deja în Symfony: site-uri publice importante, rețele sociale, site-uri comunitare, aplicații de gestionare, etc. De exemplu: phpBB, Drupal, Yahoo! [12].
Inovație
Viteză, flexibilitate, componente reutilizabile, etc. Acestea sunt lucrurile ce așteptăm de la un framework. Symfony a dezvoltat un sentiment de curiozitate care merge dincolo de PHP, căutând idei în altă parte și apoi adoptându-le la PHP – cum ar fi injecția de dependență din limbajul Java [12].
Resurse
În spatele framework-ului există un sprijin comunitar mare; de asemenea compania SensioLabs asigură un support continuu. Astfel, pornind de la principiul că "o linie nedocumentată este o linie care nu există", de asemenea stau la dispoziție zeci de proiecte făcute pentru exemplificare, constituind resurse de unde putem să ne inspirăm [12].
Interoperabilitate
Un principiu important a lui Symfony este acela că nu se limitează în interiorul său. Deși Symfony folosește standardele obișnuite, este permisă utilizarea și altor piese ale blocurilor de software (injector de dependență, gestionarea traducerilor, gestionarea formularelor, etc.). Mai mult, Symfony este atât de interoperabil că folosește el însăși blocuri de software externe (ORM Doctrine, Swiftmailer, etc.) [12].
În Symfony, avem peste 30 de componente la îndemână [12] pe care, cu ajutorul tool-ului, numit composer, putem să le instalăm / actualizăm / stergem individual, toate fiind independente [11].
Dintre aceste zeci de componente există câteva care sunt mai importante față de celealte și merită menționate:
Componenta Asset
Această componentă joacă un rol important în framework-ul Symfony și facilitând dezvoltarea. Gestionează generarea URL-urilor și versiunilor asset-urilor, cum ar fi fișiserele de stil CSS, fișiserele JavaScript și imagini [14].
Componenta BrowserKit
Simulează comportamentul unui web browser [14].
Componenta Cache
Implementează mecanismele de caching pentru PSR-6 și PSR-16 și oferă adaptoare pentru backend-urile cache populare (Redis, Memcache, APCu etc.) [14].
Componenta Config
Ajută la găsirea, încărcarea, combinarea, completarea automată și validarea valorilor de configurare [14].
Componenta Templating
Oferă toate instrumentele necesare pentru a construi orice tip de template. [14]
Componenta Form
Această componentă ne asigură facilitatea de a crea, procesa și a reutiliza formulare în Symfony. În acest framework formularele sunt decorate cu obiecte și aceste obiecte sunt construite cu ajutorul formFactory-ului [16].
Componenta Validation
Această componentă este legată de componenta descrisă mai înainte, deoarece validarea se referă la validarea formularului. Deși se leagă unul de altul, nu este obligatoriu să fie folosite împreună. De exemplu, dacă vrem să folosim componenta Form, nu suntem obligați să folosim și beneficiile componentei Validation, dar în acest caz trebuie să găsim o altă soluție echivalentă pentru a gestiona greșelile introduse într-un formular [16] [17].
Componenta Routing
Din punctul meu de vedere această componentă este poate cea mai importantă și mai utilă din Symfony, asigurând mecanismul de rutare a cererilor. Poate fi utilizată în două moduri: varianta mai veche, definind calea fiecărei acțiuni într-un fișier numit routing.yml, sau varianta mai nouă, mai des folosită în ultima perioadă bazată pe metoda adnotării (annotation). Acesta constă din definirea path-ului în controller înainte de metode, deci folosind acestă variantă știm exact în care funcție vom ajunge în urma apelului cu la calea definită. Adnotările se folosesc astfel: [18]
/**rile
* @Route("/category/{name}", name="route1")
*/
public function category()
{
// …
} [18]
Componenta Translation
În cazul în care dorim să creăm un proiect mai mare pentru lansarea pe piața internațională probabil că va fi nevoie de o implementare bilinguală. Symfony ne ajută și din acest punct de vedere și prin folosirea componentei de translatare prin intermediul căreia ne asigură metode de a internaționaliza ușor proiectul.
Constructorul clasei Translator așteaptă un argument, și anume parametrul locale:
use Symfony\Component\Translation\Translator;
$translator = new Translator('fr_FR'); [19]
Prin trimiterea acestei parametru practic îi transmitem în ce limbă dorim să traducem site-ul [19].
I.1.1. Modelul MVC în Symfony
Conceptul de MVC provine din cuvintele Model-View-Controller și indică, pur și simplu, că fragmentele de cod pe baza cărora se genereză pagina, sunt localizate în diferite fișiere în funcție de natura acestora. MVC este un șablon arhitectural care stă la baza multor framework-uri utilizate în prezent, inclusiv Symfony (Figura I.2). Astfel:
codul care se referă la manipularea datelor independente de o pagină, trebuie localizat în model [23]
codul care se referă la prezentarea către utilizator, trebuie localizat în secțiunea view; în Symfony, stratul de vizualizare se bazează pe template-uri și fișiere de configurare [23]
codul destinat legării între model și vizualizare și implementează întreaga logică a site-ului în vechiul PHP, este localizat în controler; în Symfony controler-ul pentru o anumită pagină se numește acțiune [23]
Figura I.2. – Diagrama de interacțiuni într-un MVC [24]
I.1.2. Arhitectura Symfony 3.2
Versiunea de Symfony, 3.2, aduce noutăți, fie pe partea de core a framework-ului (cu anumite procese rescrise / regândite), fie pe partea arhitecturală. Astfel, structura unui proiect Symfony implică următoarele directoare:
app/
Aici se găsesc configurațiile proiectului, template-urile și translatările. Este punctul principal de intrare al configurației aplicației.
bin/
Conține fișierele executabile (de exemplu bin/console).
src/
Conține codul PHP al proiectului.
tests/
Aici se găsesc anumite teste automate ale proiectului (de exemplu Unit tests).
var/
Conține fișierele generate de proiect (cum sunt fișierele cache, log, etc).
vendor/
Conține fișierele third-party, respectiv ”core”-ul framework-ului.
web/
Aici sunt stocate toate fișierele publice, respective statice, cum sunt imaginile, fișierele de stil, fișierele JavaScript ale proiectului. Mai mult – aici se găsește fișierul care gestionează toate request-urile (app.php / app_dev.php) care ajung la proiect. Controller-ul este cel care ascultă cererea ajunsă la el, creând apoi un obiect Request, utilizând variabilele globale de PHP, pe care îl transmite către kernel. Acest pas este urmat de trimiterea conținutul răspunsului returnat de kernel înapoi la utlizator [31].
Figura I.3. – Fluxul de lucru în Symfony
Fluxul de lucru al unui proiect Symfony este ilustrat în Figura I.3. constă din următorii pași: [25]
utilizatorul trimite un request la aplicație prin browser
browser-ul va trimite un request la web server – Apache web server
web server-ul va redirecționa, bazându-se pe PHP, care la rândul său o trimite la framework-ul Symfony
HttpKernel este componenta principal a lui Symfony. HttpKernel rezolvă controlerul cereii date, utilizând componenta Routing și transmite cererea către controlerul țintă.
toată logica de business se așează în controller-ul țintă
controller-ul va interacționa cu modelul, care la rândul său interacționează cu Datasource prin intermediul Doctrine ORM
Odată ce controllerul finalizează procesul, sau generează răspunsul propriu-zis, sau prin View Engine și îl trimite înapoi la serverul web.
în ultimul pas răspunsul va fi trimis de web server către browser
Una dintre cele mai bune și utile caracteristici ale Symfony-ului este sistemul de bundle-uri. Bundle-ul este un fel de plugin în alt software, iar în Symfony practic totul este sub formă bundle, de la core framework până la codul scris de utilizator pentru aplicație. Tot codul scris de utilizator este structurat în bundle-uri. Practic, putem spune că ”un bundle este un set de fișiere structurate care implementează o singură caracteristică și care poate să fie ușor de împărtășit cu alți dezvoltatori” [31].
Symfony ne stă la dispoziție cu un bundle inițial (numit AppBundle ), pe care-l putem folosi pentru a începe dezvoltarea aplicației, iar în cazul în care vrem să divizăm aplicația pe componente reutilizabile, putem crea bundle-urile noastre proprii [31].
Relația dintre componente, bundle-uri și aplicația Symfony este ilustrată în Figura I.4:
Figura I.4. – Relația dintre componente, bundle-uri și aplicația Symfony [25]
Există o destul de mare diferență de arhitectură este între versiunea 3 și 4. În versiunea 4 de exemplu nu există folder web, ci avem un nou director numit public în care vom avea următoarele directoare: css (eventual și scss), font, images, js dar și fișierul index.php, de unde pornește tot încărcarea a paginilor.
I.1.3. Template-uri în Symfony. Template-engine-ul Twig
Deși Symfony este un framework de PHP, utilizarea template-urilor nu implică neapărat PHP pentru a construi aspectul vizual bazat pe datele preparate în controller. În versiunile anterioare, după apariția Symfony-ul PHP era utilizat și în template-uri în felul următor:
<?php // aici vine codul PHP ?>
Începând din octombire 2009 există un template engine specific pentru framework-uri PHP, numit Twig. Cum este și Symfony-ul, și Twig este dezvoltat de echipa SensioLabs și este un produs open-source. Versiunea 2 al framework-ului Symfony a fost lansată prima dată cu suport pentru acest template engine-ul Twig [20].
Din punct de vedere al sintaxei Twig-ul ne stă la dispoziție cu trei tipuri de delimitatori [20]:
{{ … }} – pentru a afișa conținutul unei variabile
{# … #} – pentru a adăuga comentarii în template. Aceste rânduri nu vor fi incluse în codul paginii redate
{% … %} – pentru a executa condiții / bucle
{% set a = ‘apple’ %} – pentru a asigna valori unei variabile
{% if a > b and b < c %} … {% endif %} – pentru a executa condiții
{% for i in 0..10 %} … {% endfor %} – pentru a executa o buclă
Pentru evitarea redundanței a codului în Twig, a fost introdus conceptul de moștenire la nivel de template. Acesta înseamnă că într-un fișier de bază base, putem defini toate părțile de cod din template ca și blocuri reutilizabile apoi in fișierele care extind template-ul de bază. În practică acesta funcționează în felul următor:
base.html.twig
{% block header %}
{# aici vine continutul header-ului #}
{% endblock %}
{% block body %}
{# aici vine continutul body-ului #}
{% endblock %}
{% block footer %}
{# aici vine codul footer-ului #}
{% endblock %}
index.html.twig
{% extends “base.html.twig” %}
{% block body %}
{# aici vine codul block-ului suprascris #}
{% endblock %}
Astfel, fișierul index.html.twig extinde fișierul de bază base.html.twig-ul, în consecință toate blocurile definite în template-ul părinte se moștenesc și codul se aplică și în template-ul fiu, în afară de blocuri care sunt suprascrise (de exemplu, blocul body) [20] [21]. Twig-ul în sine se instalează cum se instalează o componentă, cu Composer.
În timpul fiecărei cereri (request), Symfony setează în mod implicit o variabilă globală numită ”app” atât pentru template engine-ul Twig, dar atât și pentru modul obișnuit de PHP. Acestă variabilă este o instanță AppVariable și ne dă acces la anumite variabile specifice aplicației, și anume: [22]
app.user – reprezintă utilizatorul curent logat. În caz contrar vom avea în variabilă valoare null.
app.request – reprezintă cererea (request-ul) curentă
app.session – reprezintă sesiunea utilizatorului curent logat sau null în cazul în care nu este niciun utilizator logat
app.environment – numele mediului (dev / prod)
app.debug – true dacă suntem în mod debug, în caz contrar false
Aceste variabile sunt foarte utile în procesul de dezvoltare; de exemplu, atunci când vrem să afișăm anumite informații din obiectul userului curent logat, aceste date nu trebuiesc pregătite în controller ca apoi să le putem afișa în template, ci există acces direct la ele din Twig.
I.2. Bootstrap
După cum Symfony este alcătuit din componente independente de PHP, framework-urile frontend sunt alcătuite din componente reutilizabile de HTML, CSS și JavaScript. În general aceste framework-uri sunt open-source și cu ajutorul lor se pot crea aplicații mobile-friendly care sunt responsive. Există la ora actuală o serie de variante de framework de frontend care pot fi utilizate împreună cu Symfony, și anume:
Bootstrap – este liderul indiscutabil în cadrul framework-urilor frontend în zilele noastre. Având în vedere popularitatea sa, care crește zi de zi, putem fi siguri că acest framework va fi o alegere bună [32].
Foundation – este dezvoltat de compania ZURB, și este al doilea cel mai mare concurent pe piața framework-urilor frontend. Deși este doar al doilea pe piață, Foundation este folosit pe multe site-uri mari, de exemplu: Facebook, Mozilla, Ebay, Yahoo!, National Geographic, etc [32].
Semantic UI – dezvoltatorului lui depune un efort continuu de a crea site-uri cu conținut semantic. Folosește principiile limbajului natural, făcând codul mult mai ușor de citit și mai ușor de înțeles [32].
Pure – este un frontend framework dezvoltalt de Yahoo!. Au scris în CSS pur, și include componente care pot fi utilizate împreună sau separat în funcție de nevoie. Prima versiune a fost lansată în 2013 [32].
Uikit – dezvoltatorul este YOOtheme și este compus din componente ușor de utilizat și ușor de personalizat. Nu este atât de popular cum sunt concurenții săi, oferă același nivel de calitate. Cum e și în cazul lui Pure, prima versiune a lui Uikit a fost lansată tot în anul 2013 [32].
Bootstrap nu neaparat oferă fucționalități mult mai diferite față de competitori, dar are ca avantaj popularitatea ( are peste 121 de mii de stele pe GitHub [30] ). În cazul framework-urilor frontend este important să avem la îndemână cât mai multe resurse în procesul de dezvoltare (articole, blog-uri, tutoriale, etc.).
Bootstrap-ul este cel mai popular framework de frontend (Figura I.5) în prezent dezvoltat pentru construirea aplicațiilor web. Este gratuit și open-source. Bootstrap conține șabloane de HTML, CSS pentru tipografii, formulare, butoane, navigație și multe alte componente de interfață, precum și extensii JavaScript opționale [30].
Prima versiune a Bootstrap-ului a fost lansată în vara anului 2011 sub numele Twitter Blueprint, dezvoltat de Mark Otto și Jacob Thornton de la Twitter, ca un framework pentru a încuraja coerența între structurile interne. Înainte de Bootstrap, au fost folosite diferite biblioteci pentru dezvoltarea interfeței, ceea ce a dus la inconsecvențe și la o mari probleme de mentenanță [30].
După lansarea primei versiuni a urmat o perioadă în care o mică echipă a continuat dezvoltarea, cu conducerea lui Otto și Thornton, iar până la începutul anului 2012 s-a finalizat versiunea 2, care avea deja schimbări radicale, cum sunt: sistemul responsive de grid layout cu 12 coloane, suport pentru Glyphicons și multe alte componente [30].
A treia versiune a apărut în mijlocul anului 2013, dar conține schimbări mari: a apărut designul plat și primele principii de abordare mobilă [30].
Bazându-se pe Bootstrap, site-ul rezultat va fi unul responsive și mobile-friendly, ceea ce înseamnă că codul trebuie implementat doar o singură dată, într-un singur loc, folosind structurile predefinite de Bootstrap, iar rezultatul va fi compatibil și cu dispozitivele desktop, și cu dispozitivele mobile (atât tablete cât și telefoane mobile). Se ajustă dinamic în funcție de mărimea ecranului pe care apare aplicația. Această însușire de responsabilitate în zilele noastre este indispensabil. [30]
În prezent, versiunea actuală este Bootstrap 4, care este o rescriere radicală față de versiunea 3, cu schimbări semnificative, dintre care cea mai importantă este reprezentată de schimbarea de la limbajul style-sheet Less la Sass [28].
Există un tag meta foarte important în bootstrap, cu ajutorul căruia se obțin aplicații responsive, un element important în aplicațiile web și mobile actuale. Acesta trebuie pus în sectiunea <head> al paginii:
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
I.3. Limbajul SASS
Prescurtarea SASS (Figura I.6) vine din Syntactically Awesome Style Sheets. A apărut prima data în noiembrie 2006, și este un limbaj de scripting prepocesor care este interpretat sau compilat în foi de stil (CSS) [26][27].
Foile de stil cu timpul devin din ce în ce mai mari, complexe și devin greu de întreținut. Pentru a evita acestă problemă ne stă la dispoziție SASS-ul, care are caracteristici adiționale față de CSS-ul obișnuit: variabile, ierarhizare, mixin-uri, moștenire, etc. SASS-ul lucrează cu tipuri de fișiere .scss. Acesta înseamnă că codul în sine vom scrie în fișierul cu extensia .scss, și ulterior îl vom compila în .css.
Dupa instalarea SASS, exista mai multe metode care pot fi utilizate pentru a genera fisierele CSS. Metoda obișnuită este folosirea comenzii sass din linia de comandă. Trebuie să specificăm care fișier vrem să fie convertit în versiunea CSS. Un exemplu concret: sass main.scss style.css.
Folosirea variabilelor are o mare importanță în principiul SASS. Putem stoca numere, string-uri, coduri de culori, boolean-e în ele dacă vrem să le mai refolosim oriunde în CSS. Cum este si în PHP, și în SCSS cu $ se definesc variabilele. [27] De exemplu:
$background-color: #fff;
$default-font-size: 16px;
body {
background-color: $background-color;
font-size: $default-font-size: 16px;
}
După compilare, în fișierul CSS va apărea următorul conținut:
body {
background-color: #fff;
font-size: 16px;
}
Principiul de ierarhizare (numit ”nesting” în engleză) funcționează în felul următor:
nav {
li {
width: 100%;
background: $secondary-color;
}
a {
color: $default-font-color;
}
}
Rezultatul obținut în fișierul CSS compilat este unul de felul următor:
nav li {
width: 100%;
background: #000;
}
nav a {
color: #fff;
}
Dacă vrem să structurăm și mai bine fișierele noastre de SCSS putem crea așa numitele parțiale. De exemplu un parțial separat pentru definirea variabilelor, care fișier ulterior va fi importat în fișierul în care voi scrie codul în sine. În CSS operațiile matematice sau buclele nu sunt posibile (deși ar ajuta în anumite situații), dar în acest sens ne stă la dispoziție SASS-ul.
I.4. DropzoneJS
DropzoneJS (Figura I.7) este o librărie de JavaScript open-source care furnizează funcționalitate de upload drag’n’drop cu previzualizarea imaginilor. Avantajul acestei librării este că nu depinde de nicio altă bibliotecă (de exemplu de jQuery), și este foarte ușor de personalizat [33].
Sunt mai multe metode pentru a configura Dropzone-ul. Modul cel mai evident este de a trimite un obiect cu opțiuni atunci când instanțiem un Dropzone, dar dacă avem doar elemente HTML cu clasa .dropzone, atunci nu instanțiăm programatic obiectele. În acest caz trebuie să stocăm configurația undeva, astfel încât Dropzone-ul să știe cum să configureze zonele când se instanțiază [33]. Această setare se face prin obiectul Dropzone.options:
// "myAwesomeDropzone" is the camelized version of the HTML element's ID
Dropzone.options.myAwesomeDropzone = {
paramName: "file", // The name that will be used to transfer the file
maxFilesize: 2, // MB
accept: function(file, done) {
if (file.name == "justinbieber.jpg") {
done("Naha, you don't.");
}
else { done(); }
}
}; [34]
Există foarte multe opțiuni pentru configurarea Dropzone-ului. De exemplu:
putem permite multiple/single upload-ul
putem specifica dimensiunea fizică maximă acceptată la upload
putem seta rezoluția minimă acceptată al imaginii încărcate
putem specifica extensiile acceptate a fișierelor
putem defini scala de redimensionare a pozelor
etc.
Din punct de vedere al utilizabilității, DropzoneJS este foarte bine gândit, designul implicit fiind ușor de personalizat. De asemenea, toate animațiile și afișările realizate sunt sugestive. De exemplu, în cazul in care fișierul pe care vrem să-l încărcăm nu se potrivește cerințelor noastre setate, pe thumbnail-ul imaginii apare un X mare împreună cu un mesaj de eroare.
Dropzone va găsi toate elementele de tip form cu clasa ”dropzone”. Se va atașa automat la ea și va încărca fișierele introduse în ea la atributul de acțiune specificat. Fișierele încărcate pot fi gestionate cum form-ul care ar fi un input HTML simplu: <input type="file" name="file" />
I.5. Plugin-ul Highcharts
Acest plugin (Figura I.8) este unul recunoscut în ”lumea diagramelor” fiind extrem de utilizat pentru crearea de diferite tipuri de diagrame. Sute de site-uri mari îl folosesc (de exemplu: Facebook, Twitter, Yahoo!, Visa, Groupon, Nokia, MasterCard, Yandex, BR Petrobras, etc.) pentru că ne ușurează foarte mult munca dacă vrem să creăm o pagină de statistici la zi. Pune la dispoziție o mulțime de tipuri de diagrame profesionale pentru orice domeniu, grupate în 4 categorii mari: Highcharts, Highstock, Highmaps și Highcharts Cloud [35].
Din punct de vedere a compatibilității plugin-ul este compatibil aproape cu toate browserele: Safari 4.0 +, Firefox 2.0 +, Internet Explorer 6.0 +, dar și cu browserul lui Android, care are versiune mai mare de 2.0 + [36].
Exista trei abordări care pot fi utilizate pentru instalarea plugin-ului: instalare cu bower, cu npm, sau pur și simplu instalare prin includerea fișierului JS furnizat de dezvoltator. Crearea primei diagrame este foarte simplă, necesită doar definirea div-ului aferent afișării: [35]
<div id="container" style="width:100%; height:400px;"></div>
, apoi se instanțiază folosind următorul jQuery script care se rulează când pagina este cu statusul onReady și prepopulăm cu date: [35]
$(function () {
var myChart = Highcharts.chart('container', {
chart: {
type: 'bar'
},
title: {
text: 'Fruit Consumption'
},
xAxis: {
categories: ['Apples', 'Bananas', 'Oranges']
},
yAxis: {
title: {
text: 'Fruit eaten'
}
},
series: [{
name: 'Jane',
data: [1, 0, 4]
}, {
name: 'John',
data: [5, 7, 3]
}]
});
});
I.6. jQuery
jQuery (Figura I.9) este o librărie JavaScript cross-platform, dezvoltată pentru a facilita dezvoltarea client-side a HTML-ului. Syntaxa acestui limbaj este creată pentru a ajuta navigarea în document, selectarea elementelor DOM, crearea de animații, gestionarea de evenimente și dezvoltarea de aplicații Ajax. Prima dată a fost lansată în ianuarie 2006 de John Resig în New York, sub influența librăriei cssQuery, scris de Dean Edward [38].
jQuery este o bibliotecă de manipulare a DOM- ului (Document Object Model). DOM-ul este reprezentarea structurată a tuturor elementelor unei pagini web iar jQuery simplifică sintaxa pentru găsirea, selectarea și manipularea acestor elemente. jQuery include următoarele caracteristici: [38]
selecțiile elementului DOM utilizând selectorul de surse cu mai multe versiune de browser
manipularea DOM bazată pe selectori CSS care utilizează numele și atributele elementelor
efecte și animații
evenimente
Ajax
parsare JSON
extensibilitatea prin plug-inuri
posibilitate de controlare asincronă
utilitare, cum ar fi detectarea caracteristicilor
metode de compatibilitate disponibile în browserele moderne, dar trebuie să se întoarcă pentru cele mai vechi, cum sunt inArray() și each()
suport multi-browser
Utilizarea jQuery-ului se poate realiza în următoarele variante: [38]
prin funcția $, care este o metodă factory pentru obiectul jQuery. Aceste funcții numite adesea comenzi, pot fi înlănțuite deorece toate returnează obiecte jQuery.
prin funția cu prefix $. – acestea sunt funcții utilitare care nu acționează direct asupra obiectului jQuery.
jQuery oferă de asemenea capabilități dezvoltatorilor de a crea plugin-uri proprii. Acest lucru îi permite dezvoltatorilor să creeze abstracții pentru interacțiune și animație la nivel scăzut, efecte avansate și widget-uri la nivel înalt, care pot fi modelate. Abordarea modulară a bibliotecii jQuery permite crearea de pagini web dinamice puternice și aplicații web. [38]
I.7. Google Maps Geolocation API
Google Maps Geolocation API (Figura I.10) este un web service care, pe baza datelor trimise către server returnează o locație pentru utilizator (sau mai multe locații și distanțe de la punctul start în funcție de parametrile trimise la API).
Serviciile Google Maps API reprezintă o interfață pentru solicitarea datelor Maps API de la servicii externe și utilizarea datelor din aplicațiile externe.
Acest serviciu furnizat de Google este foarte util în cazul în care se vrea construirea unei funcționalități în care este nevoie de coordonate GPS ( în cazul unui site de cazări, această opțiune este foarte importantă când într-o locație nu se găsesc cazări și se vrea recomandarea altor cazări din apropierea localității căutate într-o rază specificată). Comunicarea se face prin HTTPS folosind POST-uri. Atât cererea, cât și răspunsul sunt în format JSON, iar tipul de conținut al ambelor este application/json [39].
Pentru a putea folosi Geolocation API-ul, este nevoie de un API key ce trebuie inițializat în contul utilizatorului de Google, iar apoi requestul către API se trimite cu un POST prin URL-ul următor:
https://maps.googleapis.com/maps/api/geocode/outputFormat?key=[API_KEY] [39]
După cum se observă din exemplul de mai sus, API KEY-ul este specificat în request link. Această cheie este un hash unic pe baza căruia se face identificarea cererii (request-ului), respectiv se face legătura între cerere și contul utilizatorului în scopul administrării a consumului de credite din cont. Parametrul ”outputFormat” poate să fie sau json sau xml, și în funcție de acesta rezultatul returnat va fi afișat în acest format.
În afară de parametrul cheie mai trebuie să trimitem la API cel puțin un parametru, și anume adresa, care va fi convertită în coordonate GPS ( de exemplu din: ” Primariei 45, Oradea, Bihor ” în latitudine 47.056524, și longitudine 21.919036 ) și apoi returnate ca și rezultat. Aceste coordonate apoi le putem folosi pentru a pune markere pe hartă.
Indiferent de rezultatul construit, API-ul ne returnează întotdeauna și un status, atașat la răspuns, și anume, aceste răspunsuri posibile sunt: [39]
OK – indică că nu au fost erori sesizate și cel puțin un geocode a fost returnat
ZERO_RESULTS – indică faptul că deși geocoding-ul a fost executat cu succes, nu au fost rezultate găsite
OVER_QUERY_LIMIT – ne avertizează că suntem peste cota noastră admisă
REQUEST_DENIED – indică că cererea a fost respinsă
INVALID_REQUEST – indică lispa unei parametru obligatoriu
UNKNOWN_ERROR – ne avertizează că cererea nu a fost procesată cu succes din cauza unei erori de sistem
Există și o posibilitate de a face conversie în direcție inversă, ceea ce înseamnă că API-u,l pe baza coordonatelor GPS, ne returnează o adresă.
I.8. Google Maps Distance Matrix API
La fel ca Google Maps Geolocation API, și Distance Matrix API (Figura I.11) este un service suportat de Google, care oferă distanța și timpul de deplasare pentru o matrice de origini și destinații, pe baza traseului recomandat între punctele de început și sfârșit [40].
Metoda de utilizare al acestui API este foarte asemănător cu cel prezentat pentru Google Maps Geolocation API. Prin HTTPS cu URL-ul construit accesăm API-ul, care conține cel puțin parametrile: punctul de start, punctul de sfârșit și API key-ul, iar răspunsul returnat iarăși poate să fie sau în format JSON, sau în XML. De exemplu dacă încercăm exemplul dat de furnizor: [40]
https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins=Washington,DC&destinations=New+York+City,NY&key=YOUR_API_KEY
rezultatul returnat va fi următorul:
{
"destination_addresses" : [ "New York, NY, USA" ],
"origin_addresses" : [ "Washington, DC, USA" ],
"rows" : [
{
"elements" : [
{
"distance" : {
"text" : "225 mi",
"value" : 361715
},
"duration" : {
"text" : "3 hours 49 mins",
"value" : 13725
},
"status" : "OK"
}
]
}
],
"status" : "OK"
}
După cum se vede, durata este returnată și în secunde (value), și în formatul care poate fi citit ușor de oameni (text). Pe baza parametrilor, distanța am primit în formatul milă (field-ul distance.text) ce depinde de setarea ”units”, iar în câmpul distance.value avem distanța în metri. Dacă facem câteve calcule rapide, putem observa că distanța care apare în text, este o valoare rotunjită, pentru că 361715 de metri este echivalent doar cu 224.75 de mile. Ca și în cazul Geolocation API-ului, serviciul returnează de asemenea un status.
I.9. Editorul de text TinyMCE
TinyMCE (Figura I.12) este unul dintre cele mai populare, sau poate chiar cel mai popular și folosit editor de text pentru aplicații web. Prescurtarea numelui TinyMCE vine din Tiny Moxiecode Content Editor. Este un editor independent de platformă, bazat pe browser WYSIWYG ( what you see is what you get ), scris în JavaScript, cărui versiune 1.0 a fost lansat în primăvara anului 2004 ca și un plugin open-source. Abilitatea lui principală este convertirea textelor HTML sau a altor elemente HTML în editor de text. TinyMCE este în așa fel implementat încât este ușor de integrat în site-uri personalizate, dar și în CMS-uri ( content management system ), cum ar fi Django, Drupal, Joomla!, WordPress, etc [41].
Plugin-ul are o versiune premium, dar și versiunea standard oferă opțiuni în general suficiente pentru cerințele generale ale unui proiect. Instalarea lui se poate face în două moduri: prin descărcarea plugin-ului și despachetarea lui în proiectul în care va fi utilizat, urmat de includerea resurselor în locurile necesare sau printr-o secvență similară cu următorul exemplu [42]:
<!DOCTYPE html>
<html>
<head>
<script src="https://cloud.tinymce.com/stable/tinymce.min.js"></script>
<script>tinymce.init({ selector:'textarea' });</script>
</head>
<body>
<textarea>Next, get a free Cloud API key!</textarea>
</body>
</html>
Practic a fost inclus scriptul plugin-ului și apoi atașat TinyMCE-ul la elementul dorit. Rezultatul va fi un editor de text asemănător cu următoarea imagine:
Figura I.13 – Ilustrație TinyMCE editor [41]
Editorul pune la dispoziție o mulțime de opțiuni, similare cu cele din editoarele cunscute, de exemplu (Figura I.13):
inserarea imagilor, link-urilor, tabelurilor, bucăților de cod stilizate
formatarea textului (mărimea, culoarea, culoarea lui de fundal, etc.)
alinierea textului
activarea verificării a corectitudinii a textului
crearea listelor
etc.
Deci, deoarece plugin TinyMCE-ul este foarte ușor de integrat și oferă o mulțime de posibilități este utilizat în prezent cadrul a milioane de site-uri, printre care Microsoft, WordPress, Atlassian, IBM, LinkedIn, etc. [42].
I.10. MySQL
MySQL (Figura I.14) este un sistem relațional de gestionare a bazelor de date, open-source apărut în mai 1995, care este în continuă dezvoltare de comania Oracle Corporation. La început MySQL a fost creat de compania suedeză MySQL AB, fondat de Allan Larsson, Michael Widenius și David Axmark. [47]. Numele sistemului vine din numele fiicei fondatorului Michael, ”My”, respectiv din prescurtarea limbajului Structured Query Language [47]. MySQL este o componentă centrală al LAMP-ului [48] (LAMP [48] este prescurtarea din ”Linux, Apache, MySQL, Perl/PHP/Python”), care este un pachet de aplicații web open-source. Acest sistem, în zilele noastre este folosit în milioane de aplicații, între ele și site-uri de dimensiuni uriașe, cum sunt: Google (deși Google nu folosește MySQL pentru căutări), Facebook, Twitter, YouTube, Flickr, etc [51].
Sistemul MySQL este scris în limbajul C și C++ și este compatibil cu multe platforme, de exemplu: Symbian, Oracle Solaris, Linux, MacOS, Microsoft Windows, OpenBSD, SunOS, SCO OpenServer, etc [51].
Ce este o tabelă SQL?
O bază de date poate să fie compusă din mai multe tabele, iar o tabelă este compusă din mai multe rânduri și coloane care formează o grilă. Dacă imaginăm tabela în așa fel cum arată o tablă de șah, în primul rând apar denumirile datelor ce se vrea să stocheze în coloana respectivă (de ex.: Name, Age, Gender, Eye Color, etc. – Figura I.15). Toate celelalte rânduri sunt informații stocate din tabelă. Fiecare rând reprezintă o înregistrare separată care conține datele aceluiași persoane ( în cazul de exemplu ) [52].
Ce este o bază de date relațională?
O bază de date relațională ne permite să ”facem legătura” între tabele. De exemplu dacă se vrea implementarea unei baze de date pentru un dealer auto, toate datele mașinilor care se vând se pot stoca într-o singură tabelă, iar de exemplu datele de contact pentru un furnizor poate să fie stocat doar într-un singur loc [50]. Această legătură necesită crearea unei noi tabele, de exemplu cu numele providers, în care se va stoca datele furnizorilor (nume, adresă, număr de telefon, etc), iar după aceea se poate face legătura între tabele cu ajutorul unui ID unic din tabela a doua [52].
Tipurile de date SQL
Fiecare coloană poate conține doar un singur tip de date ce trebuie definit la crearea tabelei. De exemplu coloanal age va fi de tip number. Cele mai folosite tipuri de date sunt următoarele [52]:
INTEGER – poate stoca doar numere (și negative, și pozitive)
FLOAT – stochează doar numere când este nevoie să se folosească decimale
DATETIME – stochează dată și timp în format YYYY-MM-DD HH:MM:SS
VARCHAR – poate stoca texte cu lungimi limitate sau un singur caracter.
BLOB – stochează dată binară
I.11 Doctrine
Doctrine (Figura I.16) este un set de biblioteci PHP, care sunt axate în principal pe furnizarea serviciilor de persistență și de funcționalități relaționale. Unul dintre cele mai importante caracteristici al Doctrine-ului este posibilitatea de utilizare a limbajului Doctrine Query Language ( DQL ), care este un dialect SQL orientat pe obiecte [44]. În esență, DQL oferă capabilități puternice de interogare asupra modelului de obiecte. Se poate imagina că toate obiectele sunt în jurul unor stocări (de ex. o bază de date), iar la scrierea unei interogări DQL se interogează acel spațiu de stocare pentru a alege un anumit subset al obiectelor [53].
DQL-ul, ca limbaj de interogare are constructe SELECT, UPDATE și DELETE care se potrivesc cu tipurile de instrucțiuni SQL corespunzătoare. Instrucțiunile INSERT nu sunt permise în limbajul DQL, din cauza că entitățile și relațiile lor trebuie introduse în contextul persistenței prin EntityManage, persist() pentru a asigura coerența modelului de obiect [53].
Instrucțiunile SELECT din DQL reprezintă modalitatea puternică de a prelua părți din model. În plus ele permit preluarea entităților și asociațiile acestora într-o singură instrucțiune SQL select, care poate face o diferență mare în performană în comparația cu utilizarea mai multor interogări [53].
Instrucțiunile UPDATE și DELETE oferă modalitatea de a efectua modificări pe entități [53].
În următorul exemplu se poate vedea un SELECT care scoate toate mașinile care au vârstă mai mare de 14 ani:
<?php
$query = $em->createQuery('SELECT c FROM MyProject\Model\Car c WHERE c.manufacture < 2004');
$users = $query->getResult();
Acest query:
c este numit identificator / alias care referă la clasa MyProject\Model\Car. Dacă face parte acest alias din SELECT, se specific că se vrea toate instanțele clasei Car care satisface cererile interogării
cuvântul FROM întotdeauna este urmat de numele clasei care trebuie să fie instanțiată
expresia c.manufacture din clauza WHERE este o expresie a căii. Expresiile de acest tip sunt ușor de identificat, deoarece se utilizează operatorul ”.”, care este utilizat pentru construirea căilor. Deci, expresia c.manufacture se referă la câmpul manufacture din clasa Car.
Un mare avantaj al DQL-ului este viteza ridicată de procesare față de tehnologiile mai vechi (sau de exemplu față de SQL).
Capitolul II – Aplicația Bestcazări.ro
Aplicația este destinată persoanelor care-și caută cazare pentru a le oferi un serviciu de bună calitate în vederea găsirii cazării perfecte.
Aplicația Bestcazări.ro oferă următoarele funcționalități:
posibilitate de a adăuga anunț de cazare pentru priprietari de cazări
posibilitate de a administra / edita cazările încărcate în contul proprietarului de cazare
posibilitate de a căuta cazări și de a contacta proprietarul cazării prin formularul de contact
posibilitate de evaluare a cazărilor unde individul deja a fost cazat
posibilitate de a vedea statisticile pentru administratori
posibilitate de a edita cazările / cliențile / utilizatorile din interfața de administrator
Pe partea de backend aplicația este implementată în framework-ul Symfony, utilizând PHP, iar pentru aspectul vizual este responsabil framework-ul Bootstrap. Pentru a oferi un serviciu complet, ușor de folosit și corect s-au folosit mai multe plugin-uri / tehnologii la implementare:
SASS – pentru generarea dinamică a fișierelor CSS
DropzoneJS – este folosit la încărcarea imaginilor
Highcharts – pe pagina de statistici pentru administratori
jQuery – pentru a face site-ul mai dinamic, cu acțiuni instante
Google Geolocation API – pentru scoaterea coordonatelor GPS
Google Distance Matrix API – la recomandarea cazărilor în apropiere
TinyMCE – editor de texte, folosit pe pagina de editarea a cazărilor
DQL – limbaj de interogare folosit împreună cu Symfony
II.1 Structura aplicației
Proiectul pe partea de backend a fost organizat pe componente separate, numite bundle-uri. Proiectul Bestcazări.ro este structurat pe două bundle-uri, și anume AdminBundle, respectiv AppBundle (Figura II.1). În folderul AdminBundle se găsesc clasele de controller care sunt responsabili pentru interfața de administrator, respectiv în folderul AppBundle se găsesc toate celelalte controllere care gestionează funcționarea paginilor destinate pentru clienți și utilizatori.
Din punct de vedere al frontend-ului datorită faptului că proiectul se bazează pe modelul MVC, template-urile sunt structurate într-un director separat de controllere. După cum se vede pe Figura II.2, controllerele sunt următoarele:
AdminBundle:
AccomodationController
ClientController
UserController
DashboardController – este responsabil pentru toate statisticile vizibile pe interfața de administrator
AppBundle:
ChangePasswordController
DashboardController – în această clasă se găsesc metodele dashboardAction – care este executat la încărcarea interfeței de administrare a contului – respectiv acțiunea care se execută la apăsarea butonului de adăugare o nouă unitate de cazare
DefaultController – în acest controller se găsesc câteva funcții comune, ce pot fi folosite în tot proiectul unde este nevoie (de ex.: funcția generateRandomString($length) ) și câteva variabile constante care sunt statice în tot proiectul
DetailController – conține metoda care este responsabil pentru pregătirea datelor ce vor fi afișate pe pagina de detaliu a cazărilor
EditAccomodationController – aici se găsesc toate metodele care sunt folosite de clienți pe pagina de editare a cazărilor (de ex.: autosaveAction(), deleteImageAction(), uploadImageAction(), checkMandatoryFieldsAction(), etc.)
HomeController – este responsabil pentru pregătirea datelor necesare ce apar pe pagina principală
MessageController – conține metodele care afișează pagina de mesaje, respectiv pagina de chat ( de pe care se poate trimite răspuns clientului / utilizatorului )
ProfileChangeController
RatingController – aici ce găsește metoda care salvează evaluările introduse de utilizator
RegistrationController
SearchController – nu numai pagina de căutare depinde de acest controler, ci și funcționalitatea de autocomplete de pe pagina principală, deoarece în afară de metodele folosite pe pagina de căutare, și metoda autocompleteAction() aici se găsește, care este apelată cu Ajax la fiecare apăsare de tastă în câmpul de căutare.
SecurityController
Figura II. 3. – Structura aplicației pe parte de frontend ( client / utilizator )
Arhitectura aplicației este structurată în foldere cu nume specific fiecărei pagini al aplicației (Figura II.3). La fel, este denumit fiecare clasă, corespunzător, pentru a exista o corelație între numele ei și ceea ce reprezină ea pentru pagina respectivă.
Funcționalitățile majore care conferă aplicației dezvoltate avantaje față de celelalte aplicații similare existente sunt următoarele:
o pagină de detaliu a cazărilor cu un design modern și sugestiv cu formular de rezervare
posibilitate de a face rezervare și fără cont creat (dacă vrea aplicantul se crează un cont de utilizator în momentul rezervării)
interfată de administrare pentru proprietarii de cazări, pe care poate să facă următoarele operațiuni:
să adauge / modifice / șteargă o cazare
să vadă rezervările făcute la cazările lor
să vadă mesajurile primite și trimise în legătură cu rezervările făcute și poate să și răspundă la acestea
să-și modifice setările contului
interfață de administrare pentru utilizatori, pe care poate să facă următoarele operațiuni:
să vadă rezervările făcute de el
să vadă mesajurile trimise și primite în legătură cu rezervările făcute și poate să și continue conversația în legătură cu rezervare
să-și modifice setările contului
sistem de mesaje, care este accesibil din interfața de administrare al utilizatorului sau a proprietarului de cazare
interfață de statistici și de administrare pentru administratorul site-ului. Administratorul are dreptul de a vedea statisticile site-ului pe o perioadă selectată, poate vedea setările utilizatorilor și a cazărilor, și are posibilitatea de a le edita în caz de nevoie.
Din punctul de vedere al rolurilor, structura este una destul de simplă cu doar 4 tipuri de utilizatori, și accesul paginilor se bazează pe baza rolului utilizatorilor. Aceste roluri sunt următoarele (Figura II.4):
client – aceea persoană care are un cont creat pe site și este proprietarul unei cazări. Cu un astfel de tip de cont se pot adăuga cazări pe site
utilizator – aceea personă care are un cont creat pe site și își caută să rezerve cazare. Acest tip de utilizator poate să facă doar rezervare la cazările existente
vizitator neautentificat – aceea persoană care navighează pe site fără să fie autentificat
administrator – moderatorul site-ului, care supraveghează acțiunile efectuate, și le șterge/modifică în caz de nevoie
Figura II.4 – Ierarhia rolurilor
În funcție de rolul utilizatorilor, paginile accesibile sunt ilustrate în Figura II.5:
Figura II.5 – Paginile utilizatorilor în funcție de roluri
II.2 Baza de date
Baza de date MySQL folosită include în total 13 tabele (Figura II.6) pentru a stoca toate datele necesare pentru aplicație.
Figura II.6. – Structura bazei de date
Componența bazei de date include următoarele tabele:
tabelul accomodations – datele unităților de cazare, adăugate de clienți ( acesta este cea mai importantă tabelă. Aproape fiecare tabelă are legătură directă cu accomodations )
tabelul accomodation_types – conține tipurile posibile de cazări (ex. Pensiune, Hotel, etc.)
tabelul conversations – conține conversațiile făcute între utilizatori ( între proprietarul cazării și persoana interesată în legătură cu cazarea )
tabelul county – conține toate județele din România
tabelul image – stochează imaginile încărcate pentru cazări
tabelul location – conține toate locațiile din România care pot fi selectate ca locație unde se găsește cazarea / unde se caută cazare
tabelul phone_shows – conține numărul click-urilor pe textul numarul de telefon / cazare / zi pentru a avea statistici
tabelul price_form – conține metode de stabilire a prețurilor
tabelul rating – stochează randamentele (descrierile pozitive și negative, respectiv evaluările date de utilizatori într-un interval între 1 și 10)
tabelul region – conține toate regiunile din România
tabelul reservations – stochează datele rezervărilor făcute de utilizatori
tabelul user – stochează toate conturile create
tabelul view – conține numărul de vizualizări per cazare / zi
Comunicarea cu baza de date în interiorul proiectului se face cu ajutorul DQL-ului [42]. Cel mai semnificativ avantaj al acestui limbaj de interogare este performanța și viteza. De exemplu o interogare foarte rapidă din tabela accommodations:
$accomodation = $this->getDoctrine()
->getRepository('AppBundle:accomodations')
->findOneById($accomodation_id);
Capitolul III. Funcționalitățile aplicației
III.1 Pagina principală a aplicației
Din punct de vedere al importanței SEO ( Search Engine Optimization ) pagina principală este probabil cea mai seminificativă, deoarece aici se decide dacă informațiile furnizate de site sunt relevante pentru utilizator. În cazul acestul proiect, prima pagină este una dintre paginile la care fiecare utilizator are acces, fără restricții. Această pagină nu necesită autentificare, și conținutul ei nu este influențat dacă utilizatorul este autentificat sau nu.
După cum se vede pe Figura III.1, pe partea de sus a paginii principale se găsește meniul principal, care în fază neautentificată conține doar 3 opțiuni:
Înregistrare,
Autentificare,
și un link special pentru proprietari de cazări
Aceste link-uri se schimbă în cazul în care ne înregistrăm, și cu stat-usul logat avem următoarele opțiuni:
Link spre pagina de administrare
Delogare
și link-ul destinat pentru proprietari de cazări
Figura III.1 – Meniul principal al aplicației
Meniul principal este urmat de un antet care este în focus când se încarcă pagina, deoarece aici este plasat cel mai important element pentru un utilizator care își caută cazare, un câmp cu autocomplete, care servește la căutarea rapidă a cazărilor (Figura III.2).
Figura III.2 – Antetul paginii principale și autocomplete-ul
Figura III.3 – Autocomplete-ul în funcțiune, respectiv secțiunea cu cazări promovate
În spatele autocomplete-ului din Figura III.3 rulează un jQuery autocomplete [41] personalizat, care este apelat la fiecare apăsare de tastă când în câmpul de căutare am introdus cel puțin o literă. Această apelare este făcută cu ajutorul Ajax-ului, care apelează metoda autocompleteAction() din controller. Pe baza string-ului introdus în input, în baza de date se face o căutare MySql de tip LIKE (se scot toate înregistrările care conțin acel string introdus) după nume de locații, după nume de cazări, după nume de județ, respectiv nume de regiune. În plus la această condiție s-a mai adăugat o condiție prin care se iau în considerare doar acelea rezultate unde se găsește cel puțin o cazare (valabil doar în cazul locației, județului și a regiunii). Rezultatele obținute sunt fi returnate în format JSON ce va fi gestionat de jQuery pentru corectitudinea afișării.
Un exemplu concret în acest sens este prezentat în Figura III.3: deși în câmpul de căutare s-a introdus string-ul ”ar”, la rezultate nu apare județul Arad, deoarece deocamdată nu se găsesc cazări în acest județ. De asemenea, în secțiunea Cazări promovate apar doar acele cazări care sunt marcate cu un fanion în baza de date. Această setare poate să modifice doar administratorul site-ului din interfața de administrare.
Figura III.4 – secțiunea ”Cele mai noi cazări”, respectiv lista cu locațiile și regiunile cele mai populare
În secțiunea ”Cele mai noi cazări” (Figura III.4) sunt afișate cazările cel mai recent adăugate pe pagină în ordine cronologică descrescătoare. Aici nu există niciun fel de restricție în ceea ce privește vizualizarea cazărilor. Acestea doar trebuie să fie active și acceptate de administrator.
Secțiunea ”Cele mai populare” conține acele 6 locații, respectiv acele 6 regiuni în care se găsesc cele mai multe cazări ( grupate pe locații și regiuni).
III.2 Înregistrarea și autentificarea utilizatorilor
În pagina de înregistrare se poate ajunge din meniul principal, atunci când utilizatorul nu este încă autentificat.
Pentru înregistrare primul pas este alegerea tipului de cont ( client / utilizator ). În pasul al doilea trebuie completate cele 3 câmpuri ( e-mail, parolă și confirmarea parolei ), iar la sfârșit este necesar acceptul pentru termenii și condițiile impuse de site (Figura III.5).
Figura III.5 – formularul de înregistrare
Design-ul paginii de autentificare este foarte asemănător cu design-ul paginii de înregistrare. Pentru a autentifica utilizatorul se folosește FOSUser-ul core-ului din Symfony prin intermediul metodelor predefinite pentru a executa această acțiune. Apelarea acestei acțiuni necesită în prealabil setare în fișierul de config a proiectului. În cazul în care s-au introdus corect credențialele și nu se returnează nicio eroare, utilizatorul va fi redirectat pe pagina principal cu statusul autentificat (Figura III.6).
Figura III. 6 – formularul de autentificare
În cazul în care un utilizator / client își uită parola, există posibilitatea de a o recupera. Formularul din pagina de recuperare a parolei (Figura III.7) funcționează în așa fel încât, când s-a introdus o adresă de e-mail în câmpul din formular și s-a dat click pe butonul de trimitere, se trimite un e-mail pe adresa respectivă cu indicațiile suplimentare pentru a schimba parola.
Figura III. 7 – formularul de recuperare a parolei
Accesând pagina de setare a contului, ambele tipuri de utilizatori pot să-și modifice datele personale din contul propriu (Figura III.8).
Parola poate fi de asemenea schimbată prin formularul de pe pagina de schimbare a parolei (Figura III.9):
Figura III. 9 – formularul de schimbare a parolei
III.3 Căutarea cazărilor
Pagina de căutare este pagina unde se pot face căutări de cazări detaliate în vederea obținerii rezultatelor mai relevante pentru utilizator. Au fost implementate diverse de filtre prin care putem elimina cazările nerelevante pentru utilizator, printre care:
filtrare după județ
filtrare după o regiune
filtrare după tipul cazării
filtrare în funcție de intervalul de preț
filtrare după serviciile oferite de cazare
filtrare după numărul maxim al locurilor disponibile
În afară de aceste filtre, în antetul paginii este disponibil același autocomplete care este folosit și pe pagina principală. Cu ajutorul se poate căuta direct după locații sau o anumită cazare. În spatele autocomplete-ului funcționează același logică ca și pe pagina principală și printr-un ajax call este apelată metoda autocompleteAction() din searchController.
O altă opțiune importantă este ordonarea rezultatelor. Pe partea de mijloc – dreapta a imaginii din Figura III.10 se observă un dropdown cu câteva opțiuni. Cu ajutorul acestui dropdown rezultatele pot fi ordonate după:
recomandarea noastră
preț crescător
preț descrescător
numărul de locuri disponibile crescător
numărul de locuri disponibile descrescător
Figura III. 10 – partea de sus a paginii de căutare fără filtre aplicate
Pentru aplicarea filtrelor instant (Figura III.11, III.12, III.13, III.14), s-a creat o metoda jQuery, care ascultă fiecare click făcut pe checkbox-urile filtrelor. În momentul apăsării click-ului, în primii doi pași se apelează două funcții getUrlParameterValue respectiv getUrlParameters:
function getUrlParameterValue(sParam) {
var sPageURL = decodeURIComponent(window.location.search.substring(1)),
sURLVariables = sPageURL.split('&'),
sParameterName,
i;
for (i = 0; i < sURLVariables.length; i++) {
sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] === sParam) {
return sParameterName[1] === undefined ? true : sParameterName[1];
}
}
};
function getUrlParameters() {
var sPageURL = decodeURIComponent(window.location.search.substring(1)),
sURLVariables = sPageURL.split('&');
return sURLVariables;
}
Aceste funcții iau din linia de URL actual toate valorile a parametrilor, respectiv numele parametrilor. Valorile se pun în tablouri jQuery care apoi vor fi parcurse, și în funcție de tipul filtrului (dacă poate să fie multiple sau nu ) se adaugă sau se șterge din lista de parametri. Pe baza acestei parcurgeri se construiește un nou URL, și pagina actuală va fi redirectată pe acel link.
O funcționalitate utilă și importantă este reprezentată de ștergerea filtrelor aplicate. Această acțiune poate fi executate în două moduri: prima variantă implică ștergerea tuturor filtrelor deodată, sau individual ( în caz exemplului din Figura III.15: Tipul cazării / Servicii / Județ ).
Figura. III.15 – partea de sus a paginii de căutare cu filtre aplicate
Tot pe pagina de căutare s-a implementat și o paginare (Figura III.16) care folosește core-ul framework-ului Symphony pentru a construi aceste pagini. Ca și funcționalitate, acesta este o paginare obișnuită, dar funcționarea ei necesită instalarea unui plugin, numit KnpPaginator:
/**
* @var $paginator \Knp\Component\Pager\Paginator
*/
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$query,
$request->query->getInt('page', 1),
$request->query->getInt('limit', DefaultController::LIST_LIMIT_ON_SEARCH)
);
Primul parametru este query-ul construit pe baza filtrelor aplicate ( parametrul $query ), al doilea parametru este numarul paginii pe care vrem să o afișăm la încărcare, respectiv definirea limitei maxime de cazări cât pot apărea pe o pagină. Opțiunea de paginare trebuie inclusă și în template-ul twig al paginii:
{{ knp_pagination_render(pagination) }}
Această linie afișează atât opțiunile pentru a merge pe pagina următoare sau anterioară, dar se și crează automat un design frumos pentru ea, cum se poate vedea și pe Figura III.16:
Figura. III. 16 – rezultatul paginării
Listarea cazărilor (Figura III.17) se face prin parcurgerea variabilei $pagination, după ce acesta a fost pregătită în controller și conține detaliile despre cazări care trebuiesc afișate pe această pagină.
Figura III.17 – listarea cazărilor
Pagina de detaliu este una dintre cel mai importante pagini, deoarece în cazul unui site de rezervări pe această pagină poate să contacteze utilizatorul proprietarul cazării, respectiv această pagină conține informațiile detaliate despre cazări ( ex. imagini, descrieri, preturi, servicii, rating-uri, detalii de contact, etc. ).
În vederea utilizării ușoare a paginii, pe partea de sus s-a implementat un floating bar de informații de contact care rămâne fix și când utilizatorul dă scroll la pagină. Cum se sugerează și numele ei, această bară conține un link care redirectează utilizatorul către formularul de contact, respectiv un link care afișează numărul de telefon a proprietarului cazării. Când se dă un click pe butonul ”Număr de telefon”, se apelează un Ajax call, care incrementează în baza de date numărul click-urilor date pe acest buton / cazare / zi.
Sub meniul principal este plasată o ”navigare de search” care arată unde este utilizatorul pe site. În cazul exemplului de mai jos: Cazări / județul Bihor / Oradea / Hotel Impero. Pe lângă această navigare se mai găsesc imaginile cazării, adresa exactă al acestuia ( eventual și coordonatele GPS ), o scurtă descriere despre unitatea de cazare, prețurile, respectiv un buton numit ”Rezervare”, care de fapt funcționează la fel cum funcționează și butonul ”E-mail” din bara de informații de contact ( redirectează utilizatorul la formularul de contact ) (Figura III.18).
Figura III.18 – Bara de informații de contact, respectiv partea de sus a paginii de detaliu
Pe partea stânga sus al imaginii se poate observa acel cerc care este vizibil și pe pagina de listare. Sensul lui este același, și anume arată evaluarea medie a cazării al utilizatorilor.
Partea de mijloc a paginii conține următoarele bucăți (Figura III.19):
Pe partea stânga:
formularul de rezervare
Pe partea dreapta:
facilitățile, respectiv
serviciile oferite de cazare
Figura III.19 – formularul de contact, respectiv blocurile ”Facilități” și ”Serviciile cazării”
Formularul de rezervare conține o serie de câmpuri necesare introducerii de informații necesare rezervării. Acest formular în spate folosește un form construit cu Symfony.
În momentul apăsării butonului de trimitere, în cazul în care nu sunt erori la trimiterea formularului, se crează un cont utilizator ( dacă încă nu există ), se salvează datele de rezervare în baza de date ( în tabelele ”reservation” și ”conversation” ), respectiv se trimite un e-mail către proprietarul cazării.
Ultima secțiune a paginii de detaliu conține descrierile cazărilor pe partea stânga, respectiv evaluările medii pe fiecare categorie în parte, și evaluarea globală pe baza evaluărilor pe categorii. Sub aceste valori se afișează ultimile trei opinii despre cazarea curentă (Figura III.20).
Opinia și evaluarea poate să fie adăugată doar de persoane care au făcut deja rezervare la cazarea respectivă. Link-ul pe care pot adăuga evaluarea va fi trimis în e-mail după 3 zile de la data plecării de la cazare.
Figura III.20 – secțiunea de descrieri, respectiv secțiunea de evaluări
III.4 Interfața de administrare
Interfața de administrare este prima pagină care poate să fie accesată doar de clienți / utilizatori autentificați. Pactic această interfață este ”pagina principală al utilizatorului autentificat” și de aici se poate ajunge la pe celelalte pagini care necesită autentificare, și anume pe paginile (Figura III.21):
mesaje
rezervări
setări de parole
schimbarea parolei
editare a cazărilor ( numai în cazul tipurilor de cont client )
În meniu în dreptul opțiunilor ”Mesaje” și ”Rezervări” se pot observa două numere. Acestea indică numărul total al mesajelor primite, respectiv rezervărilor primite sau trimise de către clienți sau utilizatori.
Acestă pagină este foarte asemănătoare și pentru clienți, dar și pentru utilizatori. Diferența semnificativă este prima secțiune a paginii, care conține cazările adăugate de client și din acest motiv apare doar pentru acest tip de utilizator. Din această secțiune poate să-și adauge utilizatorul o nouă cazare, să le editeze sau să le activeze / deactiveze (Figura III.22).
Figura III.22 – prima secțiune – secțiunea de cazări de pe pagina de interfață
Pentru evitarea adăugărilor greșite de cazare, după apăsarea butonului ”Adaugă o nouă cazare” apare un pop-up de confirmare pentru a întreba clientul dacă chiar vrea să-și adauge o nouă cazare, sau a apăsat butonul doar din greșeală. Dacă confirmarea este pozitivă se crează o nouă cazare și clientul automat va fi redirectat către pagina de editarea a cazării.
În momentul apăsării textului status printr-un Ajax call se apelează o metodă care pornește un request de activare / deactivare a cazării selectate pe baza statusului anterior.
Secțiunea comună a paginii este secțiunea de rezervări. În acest box al paginii sunt enumerate ultimile 3 rezervări făcute de utilizator / făcute la cazările clientului. În cazul unui cont client această secțiune arată astfel (Figura III.23):
Figura III.23 – secțiunea de rezervări
Dacă se dă click pe link-ul ”detalii / răspunde la mesaj” utilizatorul / clientul va fi redirectat către pagina de mesaje, unde poate vedea detaliile rezervării, respectiv mesajul primit atașat la rezervare. În cazul unui click pe butonul „Vizualizați toate rezervările” clientul / utilizatorul va fi redirectat către o altă pagină care listează toate rezervările făcute până în momentul dat.
III.5 Transmiterea de mesaje
Pagina de mesaje este cea mai importantă din punct de vedere a legăturii între clienți și utilizatori (Figura III.24).
În momentul în care un utilizator face o rezervare la o anumită cazare, datele rezervării se salvează în baza de date în tabela ”reservation”, iar primul mesaj atașat rezervării, în tabela ”conversation”. Apoi aceste date vor fi afișate pe pagina de mesaj în următorul fel:
Figura III.24 – datele unei cazări, respective formularul de trimitere mesaj
Datorită sistemului de mesaje, conversația între cele două părți ( client – utilizator ), poate fi făcută în cadrul aplicației. Mesajele sunt salvate în baza de date; în plus, se trimite și un e-mail de notificare către celălalt membru a conversației (Figura III.25).
Figura III.25 – trimiterea mesajului
III.6 Editarea cazărilor
Pagina de editare a cazării este pagina pe care clientul ( proprietarul cazării ) poate să modifice sau să adauge datele (inclusiv poze) unei unități de cazare. Pagina a fost implementată în așa fel încât datele și descrierile introduse în câmpurile formularului la focus-out se salvează automat, prin trimiterea datelor din câmpul editat cu ajutorul unei apelări Ajax la metoda de salvare din controller. Rezultatul salvării este marcat cu un pop-up, care apare pe partea de jos a paginii timp de 5 secunde (temporizatorul este realizat cu funcția setTimeOut() din Javascript) (Figura III.26, III.27).
Figura III.26 – partea de sus a paginii de editare a cazării
Deși salvarea datelor se face automat la fiecare focus-out, din motive de securitate a funcționării, pe pagină se găsește și un buton de salvare, care face același lucru ca și salvarea automată, doar că această metodă salvează toate datele deodată. Acest buton a fost adăugat pentru a evita în care nu se încarcă bine un script Javascript sau salvarea automată nu poate să facă salvarea datelor.
Pentru a face publica cazarea proprietarul trebuie să completeze cel puțin următoarele câmpuri:
numele cazării
tipul cazării
județul
locația
regiunea
adresa
numărul camerelor
numărul băilor
numărul maxim disponibil
prețul cazării
metoda de stabilire a prețului
numele și prenumele a persoanei de contact
adresa de e-mail a persoanei de contact
numărul de telefon a persoanei de contact
scurtă descriere a cazării
descrierea detaliată
+ să încarcă cel puțin o poză despre cazare
În momentul în care județul, locația sau adresa este modificată în afară de salvarea automată se mai apelează și o metodă prin Ajax call care trimite datele din câmpurile enumerate mai înaine către API-ul Geolocation a lui Google. Acest API returnează coordonatele GPS pe baza adresei, care în acel moment sunt salvate în baza de date. Aceste coordonate vor fi folosite mai târziu pe pagina de rezultate, unde sistemul oferă utilizatorilor și alte cazări într-o rază specificată de la locația căutată.
La fiecare salvare automată se verifică dacă aceste câmpuri enumerate mai sus, sunt completate. Dacă funcția care verifică acest lucru returnează true, butonul de ”Publică cazarea” devine activ și dând click pe el, se trimite un request către administrator pentru moderare, respectiv pentru publicare.
Figura III.27 – partea de mijloc a paginii cu secțiunile de prețuri și datele de contact
Clientul poate să-și șteargă cazările pe care le-a introdus; astfel, acestea devine inactive (nu vor mai fi disponibile în lista de căutare și nici accesibile de către utilizatori ). Ștergerea este marcată în baza de date prin câmpul ”is_deleted” la 1, ce înseamnă că cazarea nu va mai fi vizibil în interfața de administrare a clientului dar din baza de date nu se șterge fizic pentru a o putea reactiva în caz de nevoie, respectiv pentru statistici.
Cum se vede și pe Figura III.28, pentru adăugarea descrierii detaliate a fost integrat editorul de texte TinyMCE.
Figura III. 28 – secțiunea de descrieri
Figura III.29 – secțiunea de servicii
Figura III.30 – secțiunea de încărcare al imaginilor
La încărcarea imaginilor unei anumite cazări este folosit plugin-ul DropzoneJS. Acest plugin permite clienților să ”arunce” unul sau mai multe fișiere deodată în secțiunea marcată cu chenar albastru, iar încărcarea și salvarea imaginilor se face instant și automat. În box-ul de încărcare va apărea un mic thumbnail – împreună cu o iconiță de success / eroare – ( Figura III.31) cu imaginea pe care vrea să o încarce clientul, iar după încarcarea executată cu succes imaginea va apărea și sub box-ul de încărcare ( Figura III.30 ). Metoda de salvare se apelează și aici automat cu ajutorul unui apel Ajax, iar ca răspuns se returnează toate imaginile cazării – bucată de cod care este injectat exact sub boxul de upload ( Figura III.30 ).
Figura III.31 – thumbnail-ul imaginii încărcate cu o iconiță de succes pe ea
III.7 Interfața de administrare pentru administratori
Administratorul are funcția de moderator asupra site-ului și corectează greșelile introduse de clienți sau de utilizatori. În plus, acesta poate:
să vadă statisticile site-ului
să vadă, să editeze, respectiv să activeze / deactiveze cazările
să vadă și să editeze conturile clienților și ale utilizatorilor
Paginile implementate doar pentru administrator au fost implementate cu scopul de a da posibilitatea de moderare pentru ei pe o interfață separată, fără obligarea administratorului să se autentifice în contul fiecărei client sau utilizator pentru a modifica ceva.
III.8 Vizualizarea statisticilor
Pagina de statistici are funcția de interfață pe care administratorul poate vedea toate acțiunile făcute pe site într-o perioadă selectată. Perioada dorită se selectează pe partea de sus a paginii, folosind 2 controale de de tip datepicker create pe baza datepickerului de la jQuery. În funcție de intervalul selectat, pot fi generate diferite tipuri de statistici (figurile III.32, III.33, III.34, III.35, III.36, III.37, III.38, III.39, III.40). Pentru generarea acestora s-au utilizat 4 diferite tipuri de diagrame, pe baza plugin-ului JavaScript, Highcharts. Aceste diagrame sunt de tipul coloană, linie, zonă și cerc.
Figura III.32 – Cele 2 datepickere și prima diagramă cu statistica de rezervări
Figura III.33 – Statisticile de rezervări pe județe
Figura III.34 – Statistici pe locații dintr-un județ
Figura III.35 – Statistici de vizualizări de cazări
Figura III.36 – Statistici de vizualizări pe județe
Figura III.37 – Statistici de noi cazări
Figura III.38 – Statistici de cazări în total (pe site)
Figura III.39 – Statistici numărul total de cazări pe județe
Figura III.40 – Numărul cazărilor actualizate pe site
III.9 Editarea, activarea și deactivarea cazărilor
Pagina de listare a cazărilor (Figura III.41) este accesibilă doar pentru administratori. Aici se găsesc toate cazările de pe site, iar folosind filtrele din partea dreapta, se poate găsi ușor cazarea căutată. Exista posibilitate de filtrare după:
ID-ul cazării
numele cazării
tipul cazării
locație
județ
regiune
dacă cazarea este activă sau inactivă
dacă necesită moderare
dacă este șters
după e-mail-ul de contact
sau după numărul de telefon al persoanei de contact
Figura III.41 – Pagina de listare a cazărilor, respectiv pe partea dreaptă filtrele
Bulina de lângă fiecare cazare poate să fie de 4 tipuri, și anume acestea pot fi:
bulină verde – semnifică că cazarea este activă
bulină protocalie – seminifică că cazarea necesită moderare și dacă totul este în regulă trebuie activat
bulină gri – cazarea este inactivă
bulină roșie – cazarea este ștersă
Patru din titlurile tabelei sunt scrise cu culoare albastră ( ID, Nume, Județ, Regiune ). Acesta înseamnă că pe respectivele titluri se poate da click, acesta fiind legat cu acțiunea de ordonare crescătoare / descrescătoare. Această facilitate de ordonare este predefinită în Symfony.
Pagina de editare a cazărilor (Figura III.42) este foarte asemănătoare cu pagina de editare făcută pentru clienți. În plus, administratorul mai pe o secțiune separată pentru a putea activa / deactiva, șterge, promova cazările. Modificările și aici sunt realizate cu salvări automate prin apelarea metodei de salvare cu un Ajax-call.
Figura III.42 – Secțiunea de activare / deactivare
III.9 Editarea clienților și a utilizatorilor
Pentru editarea clienților și a utilizatorilor (Figura III.43, III.44) s-au implementat două pagini simple de listare de unde se poate ajunge pe pagina de editare a datelor.
Figura III.43 – Pagina de listare de clienți
Figura III.44 – pagina de listare a utilizatorilor
După cum se observa in figurile III.43 și III.44, pe ambele pagini avem 3 filtre minime (ID, adresă de e-mail, număr de telefon) cu ajutorul cărora putem restrânge căutarea. În cazul în care se completează un filtru, aceea valoare se trimite ca și parametru la metoda de interogare, iar valoarea din parametru se adaugă în query pentru a obține rezultatele relevante.
Capitolul IV – Concluzii
Aplicația Bestcazări realizată este un proiect complex, cu funcționalități multiple, care rezolvă o problemă importantă în domeniul rezervărilor de cazare. A fost implementată într-o variantă de implementare flexibilă și extensibilă.
Implementarea realizată are la bază tehnologii de ultimă ora, și anumte framework-ul PHP, Symfony 3.2 pentru back-end, Bootstrap pentru frontend, extinse cu 3 plugin-uri ( DropzoneJS, Highcharts, TinyMCE ) și utilizând API-uri externe ( Google Geolocation API, Google Distance Matrix API ) pentru a îmbunătăți relevanța rezultatelor, respectiv a ușura uzabilitatea de către clienți și utilizatori.
Întreaga implementare a reprezentat o provocare pentru mine deoarece până la începerea proiectului Bestcazări.ro n-am lucrat în versiunea 3.2 a Symfony-ului, respectiv n-am lucrat nici cu plugin-urile DropzoneJS, Highcharts, Google Geolocation API și Google Distance Matrix API.
Avantajul aplicației este, că din punct de vedere a uzabilității, față de mulți concurenți a devenit un site simplificat, cu multe acțiuni instante, ușor de folosit, atât pentru clienți cât și pentru utilizatori.
Deși aplicația, în acest stadiu, poate funcționa și poate deservi cererile utilizatorilor fără probleme, aceasta poate fi îmbunătățită ulterior cu următoarele funcționalități:
Îmbunătățiri generale:
În autocomplete-ul de pe pagina principală să apară toate locațiile relevante, și în cazul în care nu sunt cazări în locația respectivă. În acest caz pe pagina de căutare vor fi oferite alte cazări din împrejurime ( îmbunătățire de uzabilitate )
Filtrare după limba vorbită pe pagina de căutare
Filtrare după rating-ul minim pe pagina de căturare
Îmbunătățiri pentru clienți:
Pagină de statistici pentru cazările lui ( asemănător cu statisticile pentru administratori, doar acelea care sunt relevante pentru el )
Îmbunătățiri pentru utilizatori:
Posibilitate de a salva căutare între favorite
Posibilitate de a salva cazarea între favorite
Pagină pentru căutările și cazările salvate între favorite ( în interfața de administrare pentru utilizatori )
Îmbunătățiri pentru administratori:
Pagină de facturi + generare facturi în format PDF / CSV.
Bibliografie
PHP and MySQL Web Development – Luke Welling and Laura Thomson, 4th Edition, 2009
HTML and CSS – Virginia DeBolt, 2005
Web Development with jQuery – Richard York, 2015
Learning PHP Design Patterns – William Sanders, 2013
https://en.wikipedia.org/wiki/Zend_Framework
https://en.wikipedia.org/wiki/AngularJS
https://en.wikipedia.org/wiki/Laravel
https://en.wikipedia.org/wiki/Symfony
https://symfony.com/what-is-symfony
https://sensiolabs.com/en/join_us/about_us.html
https://symfony.com/
https://symfony.com/six-good-reasons
https://getcomposer.org/doc/00-intro.md
https://symfony.com/components
https://symfony.com/doc/current/components/asset.html
https://symfony.com/doc/3.2/components/form.html
https://symfony.com/doc/3.2/components/validator.html
https://symfony.com/doc/current/components/routing.html
https://symfony.com/doc/current/components/translation.html
https://en.wikipedia.org/wiki/Twig_(template_engine)
https://twig.symfony.com/
https://symfony.com/doc/3.2/templating/app_variable.html
https://symfony.com/legacy/doc/askeet/1_0/en/3
https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
https://www.tutorialspoint.com/symfony/symfony_architecture.htm
https://en.wikipedia.org/wiki/Sass_(stylesheet_language)
https://sass-lang.com/guide
https://sass-lang.com/
http://getbootstrap.com/
https://en.wikipedia.org/wiki/Bootstrap_(front-end_framework)
https://symfony.com/doc/3.2/quick_tour/the_architecture.html
https://www.sitepoint.com/most-popular-frontend-frameworks-compared/
http://www.dropzonejs.com/
http://www.dropzonejs.com/#configuration
https://www.highcharts.com/
https://www.highcharts.com/docs/getting-started/system-requirements
https://www.highcharts.com/docs/getting-started/your-first-chart
https://en.wikipedia.org/wiki/JQuery
https://developers.google.com/maps/documentation/geolocation/intro
https://developers.google.com/maps/documentation/distance-matrix/start
https://en.wikipedia.org/wiki/TinyMCE
https://www.tinymce.com/
https://en.wikipedia.org/wiki/Doctrine_(PHP)
https://angularjs.org/
https://getcomposer.org/
https://en.wikipedia.org/wiki/SQL
https://en.wikipedia.org/wiki/LAMP_(software_bundle)
https://en.wikipedia.org/wiki/Oracle_Corporation
https://www.mysql.com/
https://en.wikipedia.org/wiki/MySQL
https://www.thoughtco.com/understanding-how-sql-databases-work-2693878
https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/dql-doctrine-query-language.html
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: V4 Pr. Licenta Bajnok Tamas [302781] (ID: 302781)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
