Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to perform additional tasks in Yii2 restful controller?

Here is how my RESTful controller looks like.

<?php

namespace backend\controllers;
use yii\rest\Controller;
use yii;
use yii\web\Response;
use yii\helpers\ArrayHelper;


class UserController extends \yii\rest\ActiveController
{
  public function behaviors()
  {
    return ArrayHelper::merge(parent::behaviors(), [
      [
        'class' => 'yii\filters\ContentNegotiator',
        'only' => ['view', 'index'],  // in a controller
        // if in a module, use the following IDs for user actions
        // 'only' => ['user/view', 'user/index']
        'formats' => [
          'application/json' => Response::FORMAT_JSON,
        ],
        'languages' => [
          'en',
          'de',
        ],
      ],
      [
        'class' => \yii\filters\Cors::className(),
        'cors' => [
          'Origin' => ['*'],
          'Access-Control-Request-Method' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
          'Access-Control-Request-Headers' => ['*'],
          'Access-Control-Allow-Credentials' => true,
          'Access-Control-Max-Age' => 86400,
        ],
      ],


      ]);
    }



    public $modelClass = 'backend\models\User';

    public function actions()
    {

    }


    public function sendMail(){
	//Need to call this function on every create
	//This should also have the information about the newly created user
    }

  }

It works very well with default behavior but it is not very practical that you will just create the user and exit. You need to send email with verification link SMS etc, may be update some other models based on this action.

I do not want to completely override the create method as it works well to save data and return back JSON. I just want to extend its functionality by adding a callback kind of a function which can accept the newly created user and send an email to the person.

like image 263
Viky293 Avatar asked Oct 18 '15 11:10

Viky293


2 Answers

Take a look here: https://github.com/githubjeka/yii2-rest/blob/bf034d26f90faa3023e5831d1eb165854c5c7aaf/rest/versions/v1/controllers/PostController.php

As you can see this is using the prepareDataProvider to change the normal way the index action is using. This is very handy. You can find the definition of prepareDataProvider here: http://www.yiiframework.com/doc-2.0/yii-rest-indexaction.html#prepareDataProvider()-detail

Now as you can see there are 2 additional methods afterRun() and beforeRun() that are also available for the create action. http://www.yiiframework.com/doc-2.0/yii-rest-createaction.html

You may be able to use these 2 functions and declare them similar to prepareDataProvider to do more things like sending an email. I have not tried them myself but I believe that should be the way to go.

like image 121
Mihai P. Avatar answered Nov 12 '22 07:11

Mihai P.


The easiest way would be getting benefit from afterSave() method in your model. This method will be called after each save process.

public function afterSave($insert, $changedAttributes) {
    //calling a send mail function
    return parent::afterSave($insert, $changedAttributes);
}

Another advantage of this method is the data you have stored in your object model. For example accessing email field:

 public function afterSave($insert, $changedAttributes) {
    //calling a send mail function
    \app\helpers\EmailHelper::send($this->email);
    return parent::afterSave($insert, $changedAttributes);
}

the value of $this->email is containing the saving value into database.

Note You can benefit from $this->isNewRecord to detect whether the model is saving new record into database or updating an existing record. Take a look:

public function afterSave($insert, $changedAttributes) {
    if($this->isNewRecord){
        //calling a send mail function
        \app\helpers\EmailHelper::send(**$this->email**);
    }
    return parent::afterSave($insert, $changedAttributes);
}

Now, it only sends mail if new record is being saved into database.

Please note that you can also benefit from Yii2's EVENTS.

As official Yii2's documentation:

This method is called at the end of inserting or updating a record. The default implementation will trigger an EVENT_AFTER_INSERT event when $insert is true, or an EVENT_AFTER_UPDATE event if $insert is false. The event class used is yii\db\AfterSaveEvent. When overriding this method, make sure you call the parent implementation so that the event is triggered.

like image 2
Ali MasudianPour Avatar answered Nov 12 '22 06:11

Ali MasudianPour