Files
yii/docs/guide/it/extension.create.txt
2012-01-01 03:05:53 +00:00

238 lines
9.3 KiB
Plaintext

Creare estensioni
===================
Quanto segue, sono le linee guida per lo sviluppo di estensioni per Yii.
* Bisogna cercare di rendere le estensioni indipendenti da altro codice. La dipendenza da altre classi, estensioni o pacchetti, potrebbe rendere difficoltosa la loro installazione per gli utenti che desiderano utilizzarle.
* Tutti i file di una stessa estensione, dovrebbero essere organizzati sotto la stessa cartella al fine di mantenere il codice il più ordinato possibile.
* Le classi in una estensione dovrebbero avere lo stesso prefisso onde evitare conflitti con i nomi di classi di altre estensioni.
* È importante fornire l'estensione di una corretta documentazione. Questo serve a ridurre il tempo necessario agli altri sviluppatori per usare questa estensione.
* Un'estensione deve usare una licenza appropriata. Se vuoi rendere la tua estensione utilizzabile sia in progetti open-source che in progetti closed-source. Puoi considerare di usare la licenza BSD, MIT, etc. Ma non la licenza GPL che richiede che i progetti derivati siano open-source a loro volta.
Di seguito, si descrive come creare una nuova estensione, secondo le linee guida
che si possono leggere nell'[overview](/doc/guide/extension.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.
Component dell'applicazione
---------------------
Un [component dell'applicazione](/doc/guide/basics.application#application-component)
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](/doc/guide/basics.application#application-configuration))
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].
Behavior
--------
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.
~~~
[php]
class TimestampBehavior extends CActiveRecordBehavior
{
public function beforeSave($event)
{
if($this->owner->isNewRecord)
$this->owner->create_time=time();
else
$this->owner->update_time=time();
}
}
~~~
Widget
------
Un [widget](/doc/guide/basics.view#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.
~~~
[php]
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](http://us3.php.net/manual/en/book.outcontrol.php)
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]:
~~~
[php]
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.
Action
------
Una [action](/doc/guide/basics.controller#action) può estendere la classe [CAction]
oppure una sua classe figlia. Il metodo principale che deve essere implementato per
una azione è [IAction::run].
Filter
------
Un [filter](/doc/guide/basics.controller#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.
~~~
[php]
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.
Controller
----------
Un [controller](/doc/guide/basics.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.
Validator
---------
Un variatore può estendere la classe [CValidator] ed implementare il suo metodo
[CValidator::validateAttribute].
~~~
[php]
class MyValidator extends CValidator
{
protected function validateAttribute($model,$attribute)
{
$value=$model->$attribute;
if($value has error)
$model->addError($attribute,$errorMessage);
}
}
~~~
Console Command
---------------
Un [console command](/doc/guide/topics.console) 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.
~~~
[php]
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';
}
}
~~~
Modulo
------
Fate riferimento alla sezione [moduli](/doc/guide/basics.module#creating-module).
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.
Component generico
-----------------
Sviluppare un component generico è come scrivere una classe. Il component,
può anche essere indipendente ed usato anche da altri sviluppatori.
<div class="revision">$Id: extension.create.txt 1423 2009-09-28 01:54:38Z qiang.xue $</div>