0 follower

Skapa utvidgning

DÄ en utvidgning Àr tÀnkt att anvÀndas av tredjepartsutvecklare, krÀvs lite extra anstrÀngning nÀr den skapas. Följande Àr nÄgra generella riktlinjer:

  • En utvidgning skall vara komplett och oberoende. Det innebĂ€r att dess externa beroenden mĂ„ste vara minimala. Det skulle vara en pina för dess anvĂ€ndare om en utvidgning skulle krĂ€va installation av ytterligare programpaket, klasser eller resursfiler.

  • Filer som tillhör en utvidgning bör organiseras under en katalog med samma namn som utvidgningen.

  • Klasser i en utvidgning bör ges ett (alfabetiskt) namnprefix för undvikande av namnkonflikt med klasser i andra utvidgningar.

  • En utvidgning bör Ă„tföljas av detaljerad installations- och API-dokumentation. Detta hĂ„ller nere den tid och möda som krĂ€vs av andra utvecklare nĂ€r de anvĂ€nder sig av utvidgningen.

  • En utvidgning bör anvĂ€nda sig av en relevant licensmodell. Om utvidgningen Ă€r tĂ€nkt att kunna anvĂ€ndas i projekt med öppen kĂ€llkod sĂ„vĂ€l som sĂ„dana med proprietĂ€r kod, bör licenser som BSD, MIT etc. men inte GPL, övervĂ€gas, dĂ„ den senare krĂ€ver att Ă€ven resulterande arbeten dĂ€r den ingĂ„r mĂ„ste göras tillgĂ€nglig som öppen kĂ€llkod.

I det följande beskrivs hur en ny utvidgning skapas, enligt respektive kategorier, beskrivna i översikt. Dessa beskrivningar Àr Àven applicerbara pÄ komponenter som skapas huvudsakligen för anvÀndning i egna projekt.

1. Applikationskomponent ¶

En applikationskomponent skall implementera grÀnssnittet IApplicationComponent eller Àrva frÄn och utvidga CApplicationComponent. Den viktigaste metoden att implementera Àr IApplicationComponent::init i vilken komponenten utför sina initialiseringar. Denna metod anropas nÀr komponenten skapats och initiala propertyvÀrden (specificerade i applikationskonfiguration) har applicerats.

Som standard skapas och initialiseras en applikationskomponent endast nÀr den anropas för första gÄngen i samband med hantering av anvÀndarens request. Om en applikationskomponent behöver skapas direkt efter instansiering av applikationen, bör den stÀlla kravet pÄ anvÀndaren att dess ID listas i propertyn CApplication::preload.

2. Behavior ¶

För att skapa en behavior, mĂ„ste man implementera ett IBehavior interface. För bekvĂ€mlighets skull innehĂ„ller Yii en basklass CBehavior som redan implementerar detta interface och dessutom tillhandahĂ„ller fler passande metoder. Ärvda klasser behöver i huvudsak implementera de extra metoder som de avser att göra tillgĂ€ngliga för komponenterna de skall kopplas till.

Vid utveckling av behavior för CModel och CActiveRecord kan man Àven utöka CModelBehavior respektive CActiveRecordBehavior. Dessa basklasser erbjuder ytterligare finesser speciellt Àmnade för CModel och CActiveRecord. Till exempel, klassen CActiveRecordBehavior implementerar en uppsÀttning metoder som svarar pÄ hÀndelser som ett ActiveRecord-objekt signalerar under sin livscykel. En Àrvd klass kan dÀrmed ÄsidosÀtta dessa metoder och tillföra anpassad kod som kommer att utgöra en del av AR-objektets livscykel.

Följande kod visar ett exempel pÄ en ActiveRecord behavior. NÀr denna behavior har kopplats till ett AR-objekt och AR-objektet sparas genom anrop till save(), förser den automatiskt create_time- och update_time-attributen med en aktuell tidstÀmpel.

class TimestampBehavior extends CActiveRecordBehavior
{
    public function beforeSave($event)
    {
        if($this->owner->isNewRecord)
            $this->owner->create_time=time();
        else
            $this->owner->update_time=time();
    }
}

3. Widget ¶

En widget skall Àrva och utvidga CWidget eller nedÀrvd klass.

Det enklaste sÀttet att skapa en ny widget Àr genom arv och utvidgning av en existerande widget med ÄsidosÀttande av dess metoder eller Àndring av dess standardpropertyvÀrden. Till exempel, om en mer estetiskt tilltalande CSS-style önskas för CTabView, kan dess CTabView::cssFile-property konfigureras nÀr denna widget anvÀnds. Det gÄr Àven att Àrva frÄn och utvidga CTabView enligt följande sÄ att propertyn inte behöver konfigureras.

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();
    }
}

I ovanstÄende, Àrvs och utvidgas metoden CWidget::init sÄ att den tilldelar CTabView::cssFile URL:en till vÄr nya standard CSS-style, förutsatt att propertyn inte getts ett vÀrde. Den nya filen som innehÄller CSS-style placeras under samma katalog som innehÄller klassfilen för MyTabView, sÄ att de kan paketeras som en utvidgning. DÄ filen med CSS-style inte Àr tillgÀnglig för webbanvÀndare behöver den publiceras som en asset.

För att skapa en ny widget frÄn grunden, behöver i huvudsak tvÄ metoder implementeras: CWidget::init och CWidget::run. Den första metoden anropas nÀr $this->beginWidget anvÀnds för att sÀtta in en widget i en vy, den andra metoden anropas som en följd av anrop till $this->endWidget. Om det presentationsinnehÄll som genereras mellan anropen till dessa tvÄ metoder behöver fÄngas upp, kan buffring av utmatning startas i CWidget::init och resultatet hÀmtas tillbaka i CWidget::run för fortsatt bearbetning.

En widget involverar ofta CSS, JavaScript eller andra resursfiler i sidan som anvÀnder nÀmnda widget. Dessa filer kallas assets eftersom de förblir placerade tillsammans med widgetens klassfil och vanligtvis inte Àr tillgÀngliga för webbanvÀndare. För att dessa filer skall bli tillgÀngliga frÄn webben behöver de publiceras med hjÀlp av CWebApplication::assetManager, sÄ som framgÄr av ovanstÄende kodsnutt. Vidare, om en CSS- eller JavaScriptfil behöver inkluderas i den aktuella sidan, behöver den registreras med hjÀlp av CClientScript:

class MyWidget extends CWidget
{
    protected function registerClientScript()
    {
        // ...publish CSS or JavaScript file here...
        $cs=Yii::app()->clientScript;
        $cs->registerCssFile($cssFile);
        $cs->registerScriptFile($jsFile);
    }
}

En widget kan Àven ha sina egna vyfiler. Om sÄ Àr fallet, skapa en katalog views under katalogen som innehÄller widgetens klassfil och placera alla vyfiler dÀr. För att rendera en widgetvy, anvÀnd $this->render('ViewName'), snarlikt hur det görs i en kontroller.

4. ÅtgĂ€rd ¶

En ÄtgÀrd skall Àrva frÄn och utvidga CAction eller nedÀrvd klass. Huvudsaklig metod att implementera för en ÄtgÀrd Àr IAction::run.

5. Filter ¶

Ett filter skall Àrva frÄn och utvidga CFilter eller nedÀrvd klass. Huvudsakliga metoder som behöver implementeras för ett filter Àr CFilter::preFilter och CFilter::postFilter. Den förra anropas innan ÄtgÀrden körs, den senare efter.

class MyFilter extends CFilter
{
    protected function preFilter($filterChain)
    {
        // logic being applied before the action is executed
        return true; // false if the action should not be executed
    }
 
    protected function postFilter($filterChain)
    {
        // logic being applied after the action is executed
    }
}

Parametern $filterChain Àr av typen CFilterChain vilken innehÄller information om den ÄtgÀrd som Àr föremÄl för pÄgÄende filtrering.

6. Kontroller ¶

En kontroller distribuerad i form av en utvidgning skall Àrva frÄn och utvidga CExtController istÀllet för CController. Det huvudsakliga skÀlet Àr att CController antar att kontrollerns vyfiler Àr placerade under application.views.ControllerID, medan CExtController antar att vyfilerna Àr placerade i katalogen views, en underkatalog till katalogen innehÄllande kontrollerns klassfil. PÄ det sÀttet blir det lÀttare att vidaredistribuera kontrollern eftersom dess vyfiler förblir placerade i anslutning till kontrollerns klassfil.

7. Validator ¶

En validator skall Àrva frÄn och utvidga CValidator och implementera dess metod CValidator::validateAttribute.

class MyValidator extends CValidator
{
    protected function validateAttribute($model,$attribute)
    {
        $value=$model->$attribute;
        if($value has error)
            $model->addError($attribute,$errorMessage);
    }
}

8. Konsolkommando ¶

Ett konsolkommando skall Àrva frÄn och utvidga CConsoleCommand och implementera dess metod CConsoleCommand::run. Som frivillig komplettering kan CConsoleCommand::getHelp ÄsidosÀttas för att tillhandahÄlla anvÀndbar hjÀlpinformation om kommandot.

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';
    }
}

9. Modul ¶

Se avsnittet om moduler för information om hur man skapar en modul.

En generell riktlinje för utveckling av en modul Àr att den skall vara komplett i sig, samt oberoende. Resursfiler (sÄ som CSS, JavaScript, bilder) som modulen anvÀnder sig av, skall distribueras tillsammans med modulen. Modulen skall Àven publicera dessa sÄ att de blir Ätkomliga för webbanvÀndare.

10. Generell komponent ¶

Utveckling av en generell utvidgningskomponent Ă€r som att skriva en klass. Återigen, komponenten skall Ă€ven vara komplett och oberoende sĂ„ att den med lĂ€tthet kan anvĂ€ndas av andra utvecklare.

Found a typo, or you think this page needs improvement?
Edit it on GitHub !