0

I'm using Yii MongoDbSuite. I need to create form field for password repeat validation, which shouldn't appear in MongoDB. Because of I'm using yii forms, all fields which i want to add in view i should declare as public in my model. But my model extend MongoDocument, so all decleared public fields after save() appear in MongoDb. How can i declare field, wich would appear in model, but doesn't appear in Mongo.

Mesbah Gueffaf
  • 518
  • 1
  • 7
  • 21
user1279525
  • 539
  • 1
  • 6
  • 12

3 Answers3

0

In a CActiveRecord model, you can add a property that is not a database column. And it will be treated almost the same as other database backed properties.

public $new_password;
public $new_password_confirm;
...
return array(
    array('E_NAME, E_EMAIL, new_password, new_password_confirm', 'required'),
    array('new_password', 'compare', 'compareAttribute'=>'new_password_confirm'),
...
<div class="row">
    <?php echo $form->labelEx($model, 'new_password'); ?>
    <?php echo $form->passwordField($model, 'new_password'); ?>
    <?php echo $form->error($model,'new_password'); ?>
</div>

<div class="row">
    <?php echo $form->labelEx($model, 'new_password_confirm'); ?>
    <?php echo $form->passwordField($model, 'new_password_confirm'); ?>
    <?php echo $form->error($model,'new_password_confirm'); ?>
</div>

Also a CFormModel model is a model that has no database backed properties.

Nikos Tsirakis
  • 709
  • 4
  • 8
0

Unfortunately, due to the way YiiMongoDBSuite works, Nikos' answer won't work completely.

YiiMongoDBSuite saves in a weird way to accomodate the schemaless design of MongoDB by reflecting all public attributes into database attributes.

It starts (in the update function) calling toArray: https://github.com/canni/YiiMongoDbSuite/blob/master/EMongoDocument.php#L593 and then finishs in _toArrray with setting all public attributes as databse properties: https://github.com/canni/YiiMongoDbSuite/blob/master/EMongoEmbeddedDocument.php#L304.

What you can do is set some protected attributes in your model. This should make them not go to the database and be saved, i.e.

class MyAwesomeModel{
    public $somedbvar;
    protected $somenotdbvar;
}

You can then use that protected property the same way that Nikos' shows.

Sammaye
  • 43,242
  • 7
  • 104
  • 146
  • yes, i was thinkig about this. But when i creating protected fields and trying to add it into view i'v get error of undefined variable. – user1279525 Nov 27 '12 at 09:30
  • @user1279525 Dang...hmm this is why I use my own and not YiiMongoDBSuite, cos it sucked...I can't think of any easy way around this honestly. You could recode ther library to make it go from the _attributes array which I think should work. – Sammaye Nov 27 '12 at 09:36
0

To improve on @Sammaye 's answer, it is correct, YMDS does assign attributes from class variables.

Although this is not the problem here. The problem here imo, is lazy coding.

Example on how I would tackle the problem

User Model (based on the suit's example)

class User extends EMongoDocument
{

    public $username;
    public $email;
    public $password;

    public function getCollectionName()
    {
        return 'users';
    }

    public function rules() {
        return array(
            array('username, email, password', 'required'),
        );
    }

    public function attributeLabels()
    {
        return array(
            'username'                   => 'UserName',
            'email'                      => 'Email',
            'password'                   => 'Password',
        );
    }

    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }

    public function getForm()
    {
        $form = new UserForm();
        $form->userid = $this->primaryKey();
        return $form;
    }
}

Form Model :

<?php

class UserForm extends CFormModel
{
    public $userid; //something to refer back to your User model on save, you might need this as a hidden field
    public $username;
    public $email;
    public $password;
    public $password_again;

    public function rules()
    {
        return array(
            array('username, email, password, password_again', 'required'),
            array('password', 'compare', 'compareAttribute'=>'password_again', 'strict'=>true),
        );
    }

    public function attributeLabels()
    {
        return array(
            'password_again'=>'Re-type Password',
        );
    }

    public function save()
    {
        if($this->validate())
        {
            $user = User::findByPk($this->userid);
            $user->username = $this->username;
            $user->email = $this->email;
            $user->password = hash('sha512',$this->password);
            if($user->save())
            {
                //do stuff
            }
        }
    }


}

And in the view:

<?php
$model = $model->form;
$form = $this->beginWidget('CActiveForm', array(
    'id'=>'user-form',
    'enableAjaxValidation'=>true,
    'enableClientValidation'=>true,
    'focus'=>array($model,'firstName'),
)); 

Ofcourse this is just an example on how to solve your problem without running into problem after problem

(a lazy way that would work btw, is simply declaring an attribute unsafe and never it would never be saved)

DarkMukke
  • 2,469
  • 1
  • 23
  • 31