phpimageyiiuploadregistration

yii user: upload image on registration form


I want to upload profile picture in yii user. By so much digging, i came to know that i need to make a profilefield, which i did and called "picture" and then in view of modules/user/registrtaion i need to write this code, given below is my registration view file.

<?php 
        $profileFields=$profile->getFields();
        if ($profileFields) {
            foreach($profileFields as $field) {
            ?>
    <div class="row">
        <?php 
        if ($widgetEdit = $field->widgetEdit($profile)) {
            echo $widgetEdit;
        } elseif ($field->range) {
            echo $form->dropDownListControlGroup($profile,$field->varname,Profile::range($field->range));
        } elseif ($field->field_type=="TEXT") {
            echo$form->textArea($profile,$field->varname,array('rows'=>6, 'cols'=>50));
        } 
// I added this below elseif for picture upload
 elseif ($field->field_type=="VARCHAR" && $field->field_size=="500") {
            echo$form->fileField($profile,$field->varname,array('rows'=>6, 'cols'=>50));
        }else {
            echo $form->textFieldControlGroup($profile,$field->varname,array('size'=>60,'maxlength'=>(($field->field_size)?$field->field_size:255)));
        }
         ?> 

and i am hanlding this profile picture in modules/model/registration.php like this. Given below is the code.

<?php

class RegistrationForm extends User {
    public $verifyPassword;
    public $verifyCode;


    public function rules() {
        $rules = array(
            array('username, password, verifyPassword, email', 'required'),
            array('username', 'length', 'max'=>20, 'min' => 3,'message' => UserModule::t("Incorrect username (length between 3 and 20 characters).")),
            array('password', 'length', 'max'=>128, 'min' => 4,'message' => UserModule::t("Incorrect password (minimal length 4 symbols).")),
            array('email', 'email'),
            array('username', 'unique', 'message' => UserModule::t("This user's name already exists.")),
            array('email', 'unique', 'message' => UserModule::t("This user's email address already exists.")),
            //array('verifyPassword', 'compare', 'compareAttribute'=>'password', 'message' => UserModule::t("Retype Password is incorrect.")),
            array('username', 'match', 'pattern' => '/^[A-Za-z0-9_]+$/u','message' => UserModule::t("Incorrect symbols (A-z0-9).")),
        // adding this liine
 array('picture', 'file','types'=>'jpg, gif, png', 'allowEmpty'=>true, 'on'=>'update'), // 
                    );
        if (!(isset($_POST['ajax']) && $_POST['ajax']==='registration-form')) {
            array_push($rules,array('verifyCode', 'captcha', 'allowEmpty'=>!UserModule::doCaptcha('registration')));
        }

        array_push($rules,array('verifyPassword', 'compare', 'compareAttribute'=>'password', 'message' => UserModule::t("Retype Password is incorrect.")));
        return $rules;
    }

}

and finally in the controller i handle the picture like this given below is the code.

<?php

class RegistrationController extends Controller
{
    public $defaultAction = 'registration';

    /**
     * Declares class-based actions.
     */
    public function actions()
    {
        return array(
            'captcha'=>array(
                'class'=>'CCaptchaAction',
                'backColor'=>0xFFFFFF,
            ),
        );
    }
    /**
     * Registration user
     */
    public function actionRegistration() {
            $model = new RegistrationForm;
            $profile=new Profile;
            $profile->regMode = true;

            // ajax validator
            if(isset($_POST['ajax']) && $_POST['ajax']==='registration-form')
            {
                echo UActiveForm::validate(array($model,$profile));
                Yii::app()->end();
            }

            if (Yii::app()->user->id) {
                $this->redirect(Yii::app()->controller->module->profileUrl);
            } else {
                                        if(isset($_POST['RegistrationForm'])) {
                     // handling picture 
                    $rnd = rand(0, 9999);  // generate random number between 0-9999

                    $model->attributes = $_POST['RegistrationForm'];

                    $uploadedFile = CUploadedFile::getInstance($model, 'picture');
                    $fileName = "{$rnd}-{$uploadedFile}";  // random number + file name
                    $model->picture = $fileName;
                    if ($model->save()) {
                    $uploadedFile->saveAs(Yii::app()->basePath . '/../img/' . $fileName);
                    $this->redirect(array('view', 'id' => $model->id));
                    }
                  // hanlding picture ends                       
                      $profile->attributes=((isset($_POST['Profile'])?$_POST['Profile']:array()));
                    if($model->validate()&&$profile->validate())
                    {
                        $soucePassword = $model->password;
                        $model->activkey=UserModule::encrypting(microtime().$model->password);
                        $model->password=UserModule::encrypting($model->password);
                        $model->verifyPassword=UserModule::encrypting($model->verifyPassword);
                        $model->superuser=0;
                        $model->status=((Yii::app()->controller->module->activeAfterRegister)?User::STATUS_ACTIVE:User::STATUS_NOACTIVE);

                        if ($model->save()) {
                            $profile->user_id=$model->id;
                            $profile->save();
                            if (Yii::app()->controller->module->sendActivationMail) {
                                $activation_url = $this->createAbsoluteUrl('/user/activation/activation',array("activkey" => $model->activkey, "email" => $model->email));
                                UserModule::sendMail($model->email,UserModule::t("You registered from {site_name}",array('{site_name}'=>Yii::app()->name)),UserModule::t("Please activate you account go to {activation_url}",array('{activation_url}'=>$activation_url)));
                            }

                            if ((Yii::app()->controller->module->loginNotActiv||(Yii::app()->controller->module->activeAfterRegister&&Yii::app()->controller->module->sendActivationMail==false))&&Yii::app()->controller->module->autoLogin) {
                                    $identity=new UserIdentity($model->username,$soucePassword);
                                    $identity->authenticate();
                                    Yii::app()->user->login($identity,0);
                                    $this->redirect(Yii::app()->controller->module->returnUrl);
                            } else {
                                if (!Yii::app()->controller->module->activeAfterRegister&&!Yii::app()->controller->module->sendActivationMail) {
                                    Yii::app()->user->setFlash('registration',UserModule::t("Thank you for your registration. Contact Admin to activate your account."));
                                } elseif(Yii::app()->controller->module->activeAfterRegister&&Yii::app()->controller->module->sendActivationMail==false) {
                                    Yii::app()->user->setFlash('registration',UserModule::t("Thank you for your registration. Please {{login}}.",array('{{login}}'=>CHtml::link(UserModule::t('Login'),Yii::app()->controller->module->loginUrl))));
                                } elseif(Yii::app()->controller->module->loginNotActiv) {
                                    Yii::app()->user->setFlash('registration',UserModule::t("Thank you for your registration. Please check your email or login."));
                                } else {
                                    Yii::app()->user->setFlash('registration',UserModule::t("Thank you for your registration. Please check your email."));
                                }
                                $this->refresh();
                            }
                        }
                    } else $profile->validate();
                }
                $this->render('/user/registration',array('model'=>$model,'profile'=>$profile));
            }
    }
}

so the problem is,, when i enter the details on registraion form and upload a picture i get this error Property "RegistrationForm.picture" is not defined. The problem lies in controller line number 45 which is

 $model->picture = $fileName;

I already have picture field in "profiles" table. But the thing is i am totally confused, and neither at yii framework forum nor at stackoverflow i found a proper documentation over this thing. Please help.

My profile.php (model) code

    <?php

    class Profile extends UActiveRecord
    {
        /**
         * The followings are the available columns in table 'profiles':
         * @var integer $user_id
         * @var boolean $regMode
         */
        public $regMode = false;

        private $_model;
        private $_modelReg;
        private $_rules = array();

        /**
         * Returns the static model of the specified AR class.
         * @return CActiveRecord the static model class
         */
        public static function model($className=__CLASS__)
        {
            return parent::model($className);
        }

        /**
         * @return string the associated database table name
         */
        public function tableName()
        {
            return Yii::app()->getModule('user')->tableProfiles;
        }

        /**
         * @return array validation rules for model attributes.
         */
        public function rules()
        {
            if (!$this->_rules) {
                $required = array();
                $numerical = array();
                $float = array();       
                $decimal = array();
                $rules = array();

                $model=$this->getFields();

                foreach ($model as $field) {
                    $field_rule = array();
                    if ($field->required==ProfileField::REQUIRED_YES_NOT_SHOW_REG||$field->required==ProfileField::REQUIRED_YES_SHOW_REG)
                        array_push($required,$field->varname);
                    if ($field->field_type=='FLOAT')
                        array_push($float,$field->varname);
                    if ($field->field_type=='DECIMAL')
                        array_push($decimal,$field->varname);
                    if ($field->field_type=='INTEGER')
                        array_push($numerical,$field->varname);
                    if ($field->field_type=='VARCHAR'||$field->field_type=='TEXT') {
                        $field_rule = array($field->varname, 'length', 'max'=>$field->field_size, 'min' => $field->field_size_min);
                        if ($field->error_message) $field_rule['message'] = UserModule::t($field->error_message);
                        array_push($rules,$field_rule);
                    }
                    if ($field->other_validator) {
                        if (strpos($field->other_validator,'{')===0) {
                            $validator = (array)CJavaScript::jsonDecode($field->other_validator);
                            foreach ($validator as $name=>$val) {
                                $field_rule = array($field->varname, $name);
                                $field_rule = array_merge($field_rule,(array)$validator[$name]);
                                if ($field->error_message) $field_rule['message'] = UserModule::t($field->error_message);
                                array_push($rules,$field_rule);
                            }
                        } else {
                            $field_rule = array($field->varname, $field->other_validator);
                            if ($field->error_message) $field_rule['message'] = UserModule::t($field->error_message);
                            array_push($rules,$field_rule);
                        }
                    } elseif ($field->field_type=='DATE') {
                        $field_rule = array($field->varname, 'type', 'type' => 'date', 'dateFormat' => 'yyyy-mm-dd', 'allowEmpty'=>true);
                        if ($field->error_message) $field_rule['message'] = UserModule::t($field->error_message);
                        array_push($rules,$field_rule);
                    }
                    if ($field->match) {
                        $field_rule = array($field->varname, 'match', 'pattern' => $field->match);
                        if ($field->error_message) $field_rule['message'] = UserModule::t($field->error_message);
                        array_push($rules,$field_rule);
                    }
                    if ($field->range) {
                        $field_rule = array($field->varname, 'in', 'range' => self::rangeRules($field->range));
                        if ($field->error_message) $field_rule['message'] = UserModule::t($field->error_message);
                        array_push($rules,$field_rule);
                    }
                }

                array_push($rules,array(implode(',',$required), 'required'));
                array_push($rules,array(implode(',',$numerical), 'numerical', 'integerOnly'=>true));
                array_push($rules,array(implode(',',$float), 'type', 'type'=>'float'));
                array_push($rules,array(implode(',',$decimal), 'match', 'pattern' => '/^\s*[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?\s*$/'));
                $this->_rules = $rules;
            }
            return $this->_rules;
        }

        /**
         * @return array relational rules.
         */
        public function relations()
        {
            // NOTE: you may need to adjust the relation name and the related
            // class name for the relations automatically generated below.
            $relations = array(
                'user'=>array(self::HAS_ONE, 'User', 'id'),
            );
            if (isset(Yii::app()->getModule('user')->profileRelations)) $relations = array_merge($relations,Yii::app()->getModule('user')->profileRelations);
            return $relations;
        }

        /**
         * @return array customized attribute labels (name=>label)
         */
        public function attributeLabels()
        {
            $labels = array(
                'user_id' => UserModule::t('User ID'),
            );
            $model=$this->getFields();

            foreach ($model as $field)
                $labels[$field->varname] = ((Yii::app()->getModule('user')->fieldsMessage)?UserModule::t($field->title,array(),Yii::app()->getModule('user')->fieldsMessage):UserModule::t($field->title));

            return $labels;
        }

        private function rangeRules($str) {
            $rules = explode(';',$str);
            for ($i=0;$i<count($rules);$i++)
                $rules[$i] = current(explode("==",$rules[$i]));
            return $rules;
        }

        static public function range($str,$fieldValue=NULL) {
            $rules = explode(';',$str);
            $array = array();
            for ($i=0;$i<count($rules);$i++) {
                $item = explode("==",$rules[$i]);
                if (isset($item[0])) $array[$item[0]] = ((isset($item[1]))?$item[1]:$item[0]);
            }
            if (isset($fieldValue)) 
                if (isset($array[$fieldValue])) return $array[$fieldValue]; else return '';
            else
                return $array;
        }

        public function widgetAttributes() {
            $data = array();
            $model=$this->getFields();

            foreach ($model as $field) {
                if ($field->widget) $data[$field->varname]=$field->widget;
            }
            return $data;
        }

        public function widgetParams($fieldName) {
            $data = array();
            $model=$this->getFields();

            foreach ($model as $field) {
                if ($field->widget) $data[$field->varname]=$field->widgetparams;
            }
            return $data[$fieldName];
        }

        public function getFields() {
            if ($this->regMode) {
                if (!$this->_modelReg)


$this->_modelReg=ProfileField::model()->forRegistration()->findAll();
            return $this->_modelReg;
        } else {
            if (!$this->_model)
                $this->_model=ProfileField::model()->forOwner()->findAll();
            return $this->_model;
        }
    }
}

Solution

  • Your registration form model extends user class. Your field picture is not the attribute of any of them.

    It will be the attribute of profile model. You should move your rule to profile model.

    Edit: In your profile model put this line

    array_push($rules,array('picture', 'file','types'=>'jpg, gif, png', 'allowEmpty'=>true, 'on'=>'update'));
    

    before the line

    $this->_rules = $rules;
    

    this code is not tested but it should work.