5

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.

Viky293
  • 1,250
  • 12
  • 18

2 Answers2

3

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.

Mihai P.
  • 9,307
  • 3
  • 38
  • 49
2

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.

Ali MasudianPour
  • 14,329
  • 3
  • 60
  • 62
  • I have added this function in my code but it is not getting called, will I have to write something to override it? – Viky293 Oct 18 '15 at 15:03
  • @Viky293 This is a method in your `Model` class. I mean: `backend\models\User`. You must override it in `backend\models\User` class. – Ali MasudianPour Oct 18 '15 at 15:05
  • Thanks for helping, but I don't want to put the code for sending email inside models. I did tried with afterAction() function, in a similar way as you have explained, but that also I don't find a good solution as afterAction would be called after all the controller actions. – Viky293 Oct 18 '15 at 15:25
  • @Viky293 there is no urgent to put your email code into your model. This is in front of MVC structure. You can call a helper method or similar OOP's solutions. – Ali MasudianPour Oct 18 '15 at 15:27
  • @Viky293 As I have mentioned in my answer, you can benefit from `EVENT_AFTER_INSERT`, so there is no need to put your code into your model. :-) – Ali MasudianPour Oct 18 '15 at 15:28