Quanto segue, sono le linee guida per lo sviluppo di estensioni per Yii.
Di seguito, si descrive come creare una nuova estensione, secondo le linee guida che si possono leggere nell'overview. È consigliato seguire le linee guida anche nei propri progetti, quando i componenti che si vanno a creare non vengono pubblicati sul sito di Yii.
Un component dell'applicazione può implementare l'interfaccia IApplicationComponent oppure estendere la classe CApplicationComponent. Il metodo principale da implementare è il metodo IApplicationComponent::init nel quale il componente esegue il suo lavoro di inizializzazione. Questo metodo viene invocato dopo che il componente è stato creato ed i valori iniziali (come spiegato nella configurazione dell'applicazione) sono applicati.
Di default, un component dell'applicazione è creato ed inizializzato solo quando viene caricato la prima volta. Se un component dell'applicazione necessita di essere caricato prima dell'istanziazione dell'applicazione, si può indicare il suo ID nella proprietà CApplication::preload.
Per creare un behavior, bisogna implementare l'interfaccia IBehavior. Per convenienza, Yii fornisce una classe base chiamata CBehavior che implementa già questa interfaccia e fornisce alcuni metodi aggiuntivi che possono farci comodo.
Quando si sviluppa un behavior per CModel o CActiveRecord, si può anche estendere CModelBehavior o CActiveRecordBehavior. Queste classi base offrono caratteristiche aggiuntive che sono specificatamente create per CModel e CActiveRecord. Per esempio, la classe CActiveRecordBehavior implementa un set di metodi per rispondere al ciclo di vita degli eventi scatenati da un oggetto ActiveRecord. Una classe figlia può sovrascrivere questi metodi per inserire del codice personalizzato.
Il codice seguente mostra un esempio di un behavior ActiveRecord. Quando questo behavior è collegato ad un oggetto ActiveRecord e quando questo oggetto salva utilizzando il metodo save, questo behavior esegue delle azioni automaticamente.
class TimestampBehavior extends CActiveRecordBehavior
{
public function beforeSave($event)
{
if($this->owner->isNewRecord)
$this->owner->create_time=time();
else
$this->owner->update_time=time();
}
}
Un widget può estendere dalla classe CWidget o da sue classi figlie.
Il metodo più semplice di creare un nuovo widget è quello di estendere un Widget già esistente sovraccaricando i suoi metodi o cambiando le sue proprietà di default. Per esempio se si vuole usare un CSS differente per CTabView si può configurare la sua proprietà CTabView::cssFile. Si può anche estendere CTabView come mostrato di seguito, così da non aver bisogno di configurare la proprietà usando il widget.
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();
}
}
Nel codice precedente, vine sovrascritto il metodo CWidget::init ed assegnato alla proprietà CTabView::cssFile l'indirizzo del nostro nuovo foglio di stile (se la proprietà non è già stata impostata). Mettiamo il nuovo css nella stessa directory che contiene la classe MyTabView, in questo modo possono essere pacchettizzate come una estensione. Siccome il css non è accessibile al web, abbiamo bisogno di pubblicarlo dentro ad un asset.
Per creare un nuovo widget da zero, abbiamo principalmente bisogno di implementare
due metodi:
CWidget::init e CWidget::run. Il primo è chiamato quando noi usiamo
$this->beginWidget
. Il secondo quando viene chiamato $this->endWidget
.
Se vogliamo catturare e processare il contenuto mostrato tra l'invocazione di
questi due metodi, possiamo iniziare l'output buffering
dentro a CWidget::init e recuperare l'output bufferizzato dentro al metodo CWidget::run.
Un widget spesso include un css, del codice javascript ed altre risorse. Chiamiamo questi file assets perché loro stanno tutti raccolti con la classe del widget e solitamente non sono accessibili all'utente web. Per rendere questi file accessibili al web, abbiamo bisogno di pubblicarli usando CWebApplication::assetManager. Come mostrato nello snippet di codice, per registrare uno script dobbiamo utilizzare CClientScript:
class MyWidget extends CWidget
{
protected function registerClientScript()
{
// ...publish CSS or JavaScript file here...
$cs=Yii::app()->clientScript;
$cs->registerCssFile($cssFile);
$cs->registerScriptFile($jsFile);
}
}
Un widget può anche avere un proprio file view. Se deve essere così, è necessario
creare una directory chiamata views
dentro alla directory contenente la classe
del widget. Nella classe del widget, per renderizzare la view, bisogna utilizzare
il metodo $this->render('ViewNamÈ)
che è simile a quello che viene utilizzato in
un controller.
Una action può estendere la classe CAction oppure una sua classe figlia. Il metodo principale che deve essere implementato per una azione è IAction::run.
Un filter può estendere la classe CFilter o una sua classe figlia. Il metodo principale che deve essere implementato per un filter è CFilter::preFilter e CFilter::postFilter. Il primo viene invocato prima che l'action sia eseguita. Il secondo dopo.
class MyFilter extends CFilter
{
protected function preFilter($filterChain)
{
// logica che viene applicata prima che l'action venga eseguita
return true; // false qualora l'action non debba essere eseguita
}
protected function postFilter($filterChain)
{
// logica che viene applicata dopo che l'action venga eseguita
}
}
Il parametro $filterChain
è di tipo CFilterChain che contiene informazioni
riguardo l'action che è filtrata in questo momento.
Un controller distribuito come una estensione è
un'estensione che può estendere CExtController, invece che CController. La
ragione principale sta nel fatto che CController considera come file di view
i file posizionati sotto la cartella application.views.ControllerID
, mentre
CExtController considera le view che si trovano sotto la cartella views
che
è una sottodirectory che contiene la classe del controller. In questo modo è
facile ridistribuire il controller insieme ai suoi file view.
Un variatore può estendere la classe CValidator ed implementare il suo metodo CValidator::validateAttribute.
class MyValidator extends CValidator
{
protected function validateAttribute($model,$attribute)
{
$value=$model->$attribute;
if($value has error)
$model->addError($attribute,$errorMessage);
}
}
Un console command può estendere la classe CConsoleCommand ed implementare il suo metodo CConsoleCommand::run. Opzionalmente, possiamo sovraccaricare anche il metodo CConsoleCommand::getHelp per fornire alcune informazioni di aiuto del comando.
class MyCommand extends CConsoleCommand
{
public function run($args)
{
// $args gives an array of the command-line arguments for this command
}
public function getHelp()
{
return 'Usage: how to use this command';
}
}
Fate riferimento alla sezione moduli.
Una linea guida generale per sviluppare un modulo è che dovrebbe essere autosufficiente. I file di risorsa (come CSS, Javascript ed immagini) che sono usati da un modulo dovrebbero essere distribuiti insieme al modulo. Ed il modulo dovrebbe pubblicarli in modo tale che siano accessibili via web.
Sviluppare un component generico è come scrivere una classe. Il component, può anche essere indipendente ed usato anche da altri sviluppatori.
Found a typo or you think this page needs improvement?
Edit it on github !
Signup or Login in order to comment.