Plugin based architecute for Yii application

I am looking to build an open source application in PHP and today came across YII framework.

I came to know that YII supports plugin/components based coding. But what I would like to know is, is there any inbuild support for function hooks to extend the application further by other users?

For example, Wordpress is an open source application and users can extend its functionality as they wish using plugin.

Any help or comments from this community? It would help me to decide on learning YII further.

@Purus, you could use “events” which is basically what you’re talking about anyway when you talk about function hooks. Users would then extend functionality by writing event handlers and registering them. In addition to the built-in events, you could of course raise your own where ever you wanted to allow users to add other handlers. Just search on events and/or component events for further info.

Thanks Bglee for the reply. I will see and try to understand that.

@Purus, I don’t know if you’ve seen the new extension called Extensionloader, but it looks like it would make your task a bit easier.

@Purus & @bglee.

Yes that extension is meant to do exactly that, to allow users hook into your application from inside extensions, just like wordpress does. Basically when you create a wp plugin, inside the plugin folder, you have a file named just like the folder, which is basically the plugin init file. Now because we’re using a more oop approach, my extension will require a ExtensionFolderNameInit.php class file, which will be used to init the extension and hook into defined events by defining event handlers in the ExtensionFolderNameInit.php class file.

Beside the fact the extension already defines some cool events, you can add your own easily, like:




//controller file

	public function actionCreate()

	{

	    $model=new Model();

        

            if($this->hasEventHandler('onCreateAction'))

            {

              $event=new ControllerEvent($this);

              $event->params['model']=$model;

              $this->onCreateAction($event);

            }

            // continue here

	}


        public function actionUpdate($id)

	{

            $model=$this->loadModel($id);


            if($this->hasEventHandler('onUpdateAction'))

            {

              $event=new ControllerEvent($this);

              $event->params['model']=$model;

              $this->onUpdateAction($event);

            }

            // continue here

	}

	

    public function onUpdateAction($event)

    {

        $this->raiseEvent('onUpdateAction', $event);

    }

    

    public function onCreateAction($event)

    {

        $this->raiseEvent('onCreateAction', $event);

    }



Then users could hook into your update/create action from your extension, something like:




class ExampleExtensionInit extends ExtensionInit{


    public function run()

    {

        //we hook only in mycontroller controller

        if(ControllerHelper::isController('mycontroller'))

            $this->controller->attachEventHandler('onUpdateAction',array($this,'runOnUpdate'));

    }

	

	public function runOnUpdate($event)

	{

	   $model=$event->params['model'];

	    if($model instanceof Model)

	    {

	       // do whatever you want with $model here.

	    }

	}

}



More than this, you can extend the functionality to be used in behaviors too.

There is a ControllerBevahior class, which you can extend and include these two events:




class MyControllerBehavior extends ControllerBehavior {

    

    public function events()

    {

        return array_merge(parent::events(), array(

            'onUpdateAction'=>'updateAction',

            'onCreateAction'=>'createAction',

        ));

    }

    

    /**

     * Responds to onUpdateAction event.

     * Overrides this method if you want to handle the corresponding event of the {@link CBehavior::owner owner}.

     * @param ControllerEvent $event event parameter

     */

    public function updateAction($event)

    {

    }

    

    /**

     * Responds to onCreateAction event.

     * Overrides this method if you want to handle the corresponding event of the {@link CBehavior::owner owner}.

     * @param ControllerEvent $event event parameter

     */

    public function createAction($event)

    {

    }

        

}



Then, future behaviors will extend the MyControllerBehavior class and they can hook into updateAction()/createAction() to alter the model:




class ExampleBehavior extends MyControllerBehavior{

    

    public function updateAction($event)

    {

        parent::updateAction($event);

	$model=$event->params['model'];

        if($model instanceof Model)

	{

           // alter $model as you want here.

	}

    }


}



As you see, using this extension gives you a real plugin based architecture :)