Yii 2: Return Errors for Unsafe Attributes

In Yii 2 your models can have safe and unsafe attributes for example:


class User extends Model
{
  public $name;
  public $passwordHash;

  public function rules()
  {
    return [
      [['name'], 'safe']
    ];
  }
}

In the above example $name is safe and $passwordHash is unsafe. If you don’t know the difference basically when you load() the attributes into the model from the user, $passwordHash is removed and not saved to the database. This is important because if the user passed in a password hash to their account it would probably be an incorrect hash and they could no longer log into the site.

This is great and I’m grateful for this behavior however I would like to let the user know that they passed in an unsafe or invalid attribute. Yii has provided us with a great method we can override to give us this functionality. To do this I’ve created a global Model
namespace common\base;

use yii\base\Model as YiiModel;
use Yii;

class Model extends YiiModel {
  public function onUnsafeAttribute($name, $value)
  {
    parent::onUnsafeAttribute($name, $value);

    $this->addError(
      $name,
      Yii::t(‘app’, ‘Unknown parameter `{name}`’, [‘name’ => $name])
    );
  }
}

So this works great but there are some caveats. For example, the function validate() clears error messages so when you run validate() you would need to run validate(null, false). Another example is if you’re using the ActiveRecord model provided by Yii. When you save() it will automatically run validate() which will remove the errors so you would have to run save(false) and make sure you do your own validation ahead of time.

Another solution to the error messages getting erased that I use is I override the behavior of the clearErrors() function. I haven’t run into issues yet with this work around that’s probably because I don’t validate my forms more than once. I can see the following causing issues for others. Here’s what my clearErrors() function looks like inside of Model class:


public function clearErrors($attribute = null)
{
  if (!$attribute || !isset($this->attributes[$attribute])) {
    return;
  }

  parent::clearErrors($attribute);
}

I've always worked as an innovative programmer. My insights and creative thinking result in superior products and customer satisfaction. Working full time as a senior web architect I've used lots of exciting technologies (i.e., Ember, Backbone, Handlebars, etc) and developed a lot of exciting sites. In my spare time I hope to develop even more exciting and new technologies. I've been programming professionally for 9 years in everything from desktop applications to web applications to mobile applications.

Posted in Uncategorized

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

About the Author

  • Chris LondonSenior Web ArchitectPartners In Leadership

    I've always worked as an innovative programmer. My insights and creative thinking result in superior products and customer satisfaction. Working full time as a senior web architect I've used lots of exciting technologies (i.e., Ember, Backbone, Handlebars, etc) and developed a lot of exciting sites. In my spare time I hope to develop even more exciting and new technologies. I've been programming professionally for 9 years in everything from desktop applications to web applications to mobile applications.

    Web: https://plus.google.com/116403409191372324375