O extensie cere un efort in plus din partea programatorului, deoarece o extensie are scopul de a fi folosita de catre alti programatori. In cele ce urmeaza, avem cateva principii generale:
In cele ce urmeaza, vom descrie cum sa cream o extensie noua, pornind de la categorisirea facuta in generalitati despre extensii. Aceste descrieri sunt valabile si in cazul in care cream o componenta folosita in special in propriile noastre proiecte.
O componenta de aplicatie trebuie sa implementeze interfata IApplicationComponent sau sa fie derivata din clasa CApplicationComponent. Pricipala metoda care trebuie implementata este IApplicationComponent::init in care se fac initializarile componentei. Aceasta metoda este apelata dupa ce componenta este creata si dupa ce sunt initializate proprietatile clasei cu valorile initiale specificate in configurarea aplicatiei.
Implicit, o componenta a aplicatiei este creata si initializata doar atunci cand este accesata prima data in timpul tratarii unei cereri de la utilizatorul web. Daca o componenta a aplicatiei trebuie sa fie creata imediat dupa ce este creata instanta aplicatiei insasi, va trebui sa ii adaugam ID-ul in proprietatea CApplication::preload.
Un widget trebuie sa fie derivat din clasa CWidget sau dintr-o clasa derivata.
Cel mai usor mod de a crea un nou widget este sa il derivam dintr-un widget existent si sa ii suprascriem metodele sau sa ii schimbam valorile sale initiale. De exemplu, daca vrem sa folosim un alt stil CSS pentru CTabView, ar putem sa configuram proprietatea sa CTabView::cssFile. Putem de asemenea deriva CTabView dupa cum urmeaza, ca sa nu mai fie nevoie sa configuram proprietatea de fiecare data cand folosim widget-ul.
class MyTabView extends CTabView
{
public function init()
{
if($this->cssFile===null)
{
$file=dirname(__FILE__).DIRECTORY_SEPARATOR.'tabview.css';
$this->cssFile=Yii::app()->getAssetManager()->publish($file);
}
parent::init();
}
}
In codul de mai sus, suprascriem metoda CWidget::init si atribuim proprietatii
CTabView::cssFile URL-ul cu noul stil CSS. Punem apoi fisierul cu noul stil CSS
in acelasi director care contine fisierul clasei MyTabView
pentru a putea fi impachetate intr-o
extensie. Deoarece fisierul cu stilul CSS nu este accesibil utilizatorilor Web, trebuie sa il publicam
ca fiind un asset.
Pentru a crea un nou widget de la zero, in principal trebuie sa implementam doua metode:
CWidget::init si CWidget::run. Prima metoda este apelata atunci cand folosim
$this->beginWidget
pentru a insera un widget intr-un view. A doua metoda este apelata atunci cand
apelam $this->endWidget
. Daca vrem sa capturam si sa procesam continutul afisat intre aceste doua
apeluri de metode, putem porni output buffering
in CWidget::init si in CWidget::run sa extragem output-ul memorat pentru procesare ulterioara.
Cand folosim un widget, de obicei trebuie sa includem CSS-ul, javascript-ul sau alte fisiere in pagina care foloseste widget-ul. Denumim aceste fisiere assets pentru ca ele stau impreuna cu fisierul clasei widget-ului si nu sunt accesibile in mod normal utilizatorilor Web. Pentru a face accesibile aceste fisiere, trebuie sa le publicam folosind CWebApplication::assetManager, dupa cum am aratat in snippet-ul de mai sus. In plus, daca vrem sa includem un fisier CSS sau javascript in pagina curenta, trebuie sa inregistram fisierul folosind CClientScript:
class MyWidget extends CWidget
{
protected function registerClientScript()
{
// ...publicam fisiere CSS sau JavaScript aici...
$cs=Yii::app()->clientScript;
$cs->registerCssFile($cssFile);
$cs->registerScriptFile($jsFile);
}
}
Un widget poate de asemenea sa aiba propriile sale fisiere view. In cazul acesta,
cream un directorul cu numele views
in interiorul directorului care contine fisierul clasei
widget-ului, si punem acolo toate fisierele view. In clasa widget-ului, pentru a procesa
un view al widget-ului, folosim $this->render('ViewName')
, la fel ca in cazul unui controller.
Un action trebuie sa fie derivat din clasa CAction sau una din clasele sale derivate. Principala metoda care trebuie implementata pentru un action este IAction::run.
Un filtru trebuie sa fie derivat din clasa CFilter sau una din clasele sale derivate. Principalele metode care trebuie implementate pentru un filtru sunt CFilter::preFilter si CFilter::postFilter. CFilter::preFilter este apelat inainte ca action-ul sa fie executat. CFilter::postFilter este apelat dupa ce action-ul a fost executat.
class MyFilter extends CFilter
{
protected function preFilter($filterChain)
{
// lucruri de aplicat inainte ca action-ul sa fie executat
return true; // false daca action-ul NU ar trebui sa fie executat
}
protected function postFilter($filterChain)
{
// lucruri de aplicat dupa ce action-ul a fost executat
}
}
Parametrul $filterChain
este de tip CFilterChain care contine informatii despre action-ul
care este filtrat in acest moment.
Un controller distribuit ca extensie
ar trebui sa fie derivat din clasa CExtController, in loc de CController. Motivul
principal este ca CController presupune ca fisierele view ale controller-ului sunt localizate
in application.views.ControllerID
, in timp ce CExtController presupune ca fisierele view
sunt localizate in interiorul directorului views
care este un subdirector al directorului care contine
fisierul clasei controller-ului. De aceea, este mai usor sa redistribuim controller-ul
din moment ce fisierele sale view stau impreuna cu fisierul clasei controller-ului.
Un validator ar trebui sa fie derivat din CValidator si sa implementeze metoda CValidator::validateAttribute.
class MyValidator extends CValidator
{
protected function validateAttribute($model,$attribute)
{
$value=$model->$attribute;
if($value has error)
$model->addError($attribute,$errorMessage);
}
}
console command ar trebui sa fie derivata din clasa CConsoleCommand si sa implementeze metoda CConsoleCommand::run. Optional, putem suprascrie CConsoleCommand::getHelp pentru a pune la dispozitie informatii despre comanda.
class MyCommand extends CConsoleCommand
{
public function run($args)
{
// $args gives an array of the command-line arguments for this command
}
public function getHelp()
{
return 'Folosire: cum folosim aceasta comanda';
}
}
Pentru a crea un modul, trebuie vazuta sectiunea despre module.
Un principiu general pentru dezvoltarea unui modul este ca ar trebui sa fie de sine statator. Fisierele cu resursele lui (CSS, JavaScript, imagini) ar trebui sa fie distribuite impreuna cu modulul. In acelasi timp, modului trebuie sa le publice pentru a fi accesibile utilizatorilor Web.
Dezvoltarea unei extensii de componenta generica este la fel ca scrierea unei clase. Din nou, ar trebui sa fie de sine statatoare pentru a fi usor de folosit de alti programatori.
Signup or Login in order to comment.