0

I have been playing with Yii2 and I am stuck at rules. The functionality I am trying to achieve:

User is presented with a form where he can add points to different statistics. However, he has only limited amount of points he can add. Same like in almost any role-playing game, where you can increase some stats when you level up.

For example we have these stats: strength, agility, vitality and the user can add up to 3 points. How do I make the rules, so they allow adding max of 3 points, but once the 3 points are used, they refuse adding any more?

So if he adds 3 points to strength the max for agility and vitality is 0. Or if he adds 2 points to strength, the max for agility and vitality is 1, but once he adds the one point the rest goes to 0?

Edit: I am currently playing with something like:

["strength", "integer", "min" => 0 , "max" => $free_points, "when" => function($model) {
 return $model->vitality == 0 && $model->agility == 0}],

Currently my problem is making it into a version that would adapt to the number of free points.

Edit2: I am trying to write a custom validator. What I can't find is how to get the value from the form... My non-working code (some variables are named just to show what I am trying to achieve):

public function validatePoints($attribute, $params)
{
    $free_points = Technology::findOne(Yii::$app->user->identity->technology)->free_points;
    $used_points = 0;

    foreach($params as $value){
        $used_points += $value;
    }
    if(($assigned_points + $used_points) > $free_points){
        $this->addError($attribute, Yii::t('user', "You can not use more points than you have free points."));
        return false;
    }
    return true;
}
Chris Illusion
  • 277
  • 2
  • 5
  • 18
  • You should simply write your own validator for this – soju Mar 10 '15 at 17:13
  • @soju Looks like I'll have to. I thought there would be some in-built function or a trick. Anyway, I am building a function based on [this answer](http://stackoverflow.com/a/19073394/1871244). Will update when I get some results. – Chris Illusion Mar 10 '15 at 18:22

1 Answers1

1

You wrote this in the model, so this function already knows about it's object. To access the entered $strength you just have to use $this->strength etc.

Now you have a lot of things like $parameter that I have no idea what it is so you will have to work that out yourself.

If I understand properly you can do something like

foreach(['vitality', 'agility', 'strength'] as $parameter){
        $used_points += $this->{$parameter};
    }

Again no idea where $assigned_points is coming from, you might have to use $this->assigned_points if it is a property of the model.

arogachev
  • 33,150
  • 7
  • 114
  • 117
Mihai P.
  • 9,307
  • 3
  • 38
  • 49
  • Thank you very much! Just a quick question, why do I have to use {} brackets in $this->{$parameter} ? Also, the `$parameter` was supposed to be `$params`. Fixing it in question now. – Chris Illusion Mar 11 '15 at 10:25
  • It might work without brackets, but I like to put them anyway as it makes it easier to read (for me anyway). I can easily see the difference between $this->parameter that is a property of the object and $this->{$parameter} that is the name of property contained in the $parameter string. I am not sure if the brackets are required or not. Also my $parameter has nothing to do with your $params. – Mihai P. Mar 11 '15 at 20:51