I have a trouble while uploading image. The error says: include(CUploadFile.php): failed to open stream: No such file or directory.
I have a table in my db, tbl_barang (id_barang, nama_barang, id_merk, harga, foto, deskripsi)
This is my model, Barang.php
<?php
class Barang extends CActiveRecord {
public static function model($className=__CLASS__) {
return parent::model($className);
}
public function tableName() {
return 'tbl_barang';
}
public function rules() {
return array(
array('nama_barang, id_merk, harga, foto, deskripsi', 'required'),
array('harga', 'numerical', 'integerOnly'=>true),
array('nama_barang', 'length', 'max'=>50),
array('id_merk', 'length', 'max'=>3),
array('foto', 'file', 'types'=>'jpg, gif, png', 'allowEmpty'=>true,), //menentukan file, tipe file, dan boleh empty pada validasi upload foto
array('id_barang, nama_barang, id_merk, harga, foto, deskripsi', 'safe', 'on'=>'search'),
);
}
public function relations() {
return array();
}
public function attributeLabels() {
return array(
'id_barang' => 'Id Barang',
'nama_barang' => 'Nama Barang',
'id_merk' => 'Id Merk',
'harga' => 'Harga',
'foto' => 'Foto',
'deskripsi' => 'Deskripsi',
);
}
public function search() {
$criteria=new CDbCriteria;
$criteria->compare('id_barang',$this->id_barang);
$criteria->compare('nama_barang',$this->nama_barang,true);
$criteria->compare('id_merk',$this->id_merk,true);
$criteria->compare('harga',$this->harga);
$criteria->compare('foto',$this->foto,true);
$criteria->compare('deskripsi',$this->deskripsi,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
}
Then my controller, BarangController.php
class BarangController extends Controller {
/**
* #var string the default layout for the views. Defaults to '//layouts/column2', meaning
* using two-column layout. See 'protected/views/layouts/column2.php'.
*/
//menentukan layout
public $layout='//layouts/column2';
//menentukan folder tempat penyimpanan
const URLUPLOAD='/../images/barang';
/**
* #return array action filters
*/
public function filters() {
return array(
'accessControl', // perform access control for CRUD operations
'postOnly + delete', // we only allow deletion via POST request
);
}
/**
* Specifies the access control rules.
* This method is used by the 'accessControl' filter.
* #return array access control rules
*/
public function accessRules() {
return array(
array('allow', // allow all users to perform 'index' and 'view' actions
'actions'=>array('index','view'),
'users'=>array('*'),
),
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'actions'=>array('create','update'),
'users'=>array('#'),
),
array('allow', // allow admin user to perform 'admin' and 'delete' actions
'actions'=>array('admin','delete'),
'users'=>array('admin'),
),
array('deny', // deny all users
'users'=>array('*'),
),
);
}
/**
* Displays a particular model.
* #param integer $id the ID of the model to be displayed
*/
public function actionView($id) {
$this->render('view',array(
'model'=>$this->loadModel($id),
));
}
/**
* Creates a new model.
* If creation is successful, the browser will be redirected to the 'view' page.
*/
public function actionCreate() {
$model=new Barang; //panggil model Barang
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['Barang'])) { //jika data dikirim
//cek file
$cekfile = $model->image=CUploadFile::getInstance($model, 'foto');
if(empty($cekfile)) { //jika file kosong
//ambil data yang diinput
$model->attributes=$_POST['Barang'];
$model->save();
} else { //jika file tidak kosong
//ambil data yang diinput
$model->attributes=$_POST['Barang'];
//ambil file
$model->image = CUploadFile::getInstance($model, 'foto');
if($model->save()) { //jika data disimpan
//upload image ke folder
$model->image->saveAs(Yii::app()->basePath.self::URLUPLOAD.$model->image.'');
//alihkan ke halaman index/function actionIndex()
$this->redirect(array('view','id'=>$model->id_barang));
}
}
}
$this->render('create',array(
'model'=>$model,
));
}
/**
* Updates a particular model.
* If update is successful, the browser will be redirected to the 'view' page.
* #param integer $id the ID of the model to be updated
*/
public function actionUpdate($id) {
$model=$this->loadModel($id);
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['Barang'])) {
$model->attributes=$_POST['Barang'];
if($model->save())
$this->redirect(array('view','id'=>$model->id_barang));
}
$this->render('update',array(
'model'=>$model,
));
}
/**
* Deletes a particular model.
* If deletion is successful, the browser will be redirected to the 'admin' page.
* #param integer $id the ID of the model to be deleted
*/
public function actionDelete($id) {
$this->loadModel($id)->delete();
// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
if(!isset($_GET['ajax']))
$this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('admin'));
}
/**
* Lists all models.
*/
public function actionIndex() {
$dataProvider=new CActiveDataProvider('Barang');
$this->render('index',array(
'dataProvider'=>$dataProvider,
));
}
/**
* Manages all models.
*/
public function actionAdmin() {
$model=new Barang('search');
$model->unsetAttributes(); // clear any default values
if(isset($_GET['Barang']))
$model->attributes=$_GET['Barang'];
$this->render('admin',array(
'model'=>$model,
));
}
/**
* Returns the data model based on the primary key given in the GET variable.
* If the data model is not found, an HTTP exception will be raised.
* #param integer the ID of the model to be loaded
*/
public function loadModel($id) {
$model=Barang::model()->findByPk($id);
if($model===null)
throw new CHttpException(404,'The requested page does not exist.');
return $model;
}
/**
* Performs the AJAX validation.
* #param CModel the model to be validated
*/
protected function performAjaxValidation($model) {
if(isset($_POST['ajax']) && $_POST['ajax']==='barang-form') {
echo CActiveForm::validate($model);
Yii::app()->end();
}
}
}
In _form.php I just changed the textfiled into filefield in the foto's row. I really confused why it cannot uploaded. I hope anyone can help me and teach me how to fix it. Thank you
In your form you should have this type of code regarding to image foto file.
<div class="row">
<?php echo $form->labelEx($model,'foto'); ?>
<?php echo $form->fileField($model,'foto'); ?>
<php echo $form->error($model,'foto'); ?>
</div>
Now you need to edit your controller file.
Now in your controller file. You need to changes the below method.
It is your controller, i try to remove errors from this controller. you first try this.
public function actionCreate()
{
$model=new Barang;
if(isset($_POST['Barang'])) //jika data dikirim
{
$cekfile = $model->foto=CUploadFile::getInstance($model, 'foto');
if(empty($cekfile)){ //jika file kosong
$model->attributes=$_POST['Barang'];
$model->save();
}
else{ //jika file tidak kosong
$model->attributes=$_POST['Barang'];
$model->foto= CUploadFile::getInstance($model, 'foto');
if($model->save()){ //jika data disimpan
$model->foto->saveAs(Yii::app()->basePath.self::URLUPLOAD.$model->foto.'');
$this->redirect(array('view','id'=>$model->id_barang));
}
}
}
$this->render('create',array(
'model'=>$model,
));
}
if above method giving error too. then you try below method.
public function actionCreate()
{
$model=new Barang;
if(isset($_POST['Barang']))
{
$model->attributes = $_POST['Barang'];
$model->foto = CUploadedFile::getInstance($model,'foto');
if(empty($model->foto)){
$model->save();
}
else
{
if($model->save())
// i have made a folder on root->media and create folder, its name is images.
// so you create your folder first to for uploading your images.
$fullImgSource = Yii::getPathOfAlias('webroot').'/media/images/'.$model->foto;
$model->foto->saveAs($fullImgSource);
$this->redirect(array('view','id'=>$model->id_barang));
}
}
$this->render('create',array('model'=>$model,));
}
I hope, it will help you.
thanks.
Try this;
Instead of
$model->image = CUploadFile::getInstance($model, 'foto');
try
$model->image = CUploadedFile::getInstance($model, 'foto');
Please try this way
$cekfile = CUploadFile::getInstance($model, 'foto'); // for getting
image instance.
$model->foto = $cekfile->name; // assigning foto name to model
attribute.
$cekfile->saveAs(Yii::app()->basePath.self::URLUPLOAD.$model->image.'');
//for uploading image in folder
Also check whether the image upload path is correct.
Thanks
Related
i have problems with duplication of pk, and only users model is saved then the rest will 0 value,
need help guys. thanks in advance
Model: Student [edited]
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('studentid', 'required'),
array('studentid', 'unique'),
array('studentid, year, cellphonenumber', 'numerical', 'integerOnly'=>true),
array('lastname, firstname, middlename, course, email', 'length', 'max'=>32),
// The following rule is used by search().
// #todo Please remove those attributes that should not be searched.
array('studentid, lastname, firstname, middlename, course, year, cellphonenumber, email', 'safe', 'on'=>'search'),
);
}
/**
* #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.
return array(
);
}
/**
* #return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'studentid' => 'Studentid',
'lastname' => 'Lastname',
'firstname' => 'Firstname',
'middlename' => 'Middlename',
'course' => 'Course',
'year' => 'Year',
'cellphonenumber' => 'Cellphonenumber',
'email' => 'Email',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
*
* Typical usecase:
* - Initialize the model fields with values from filter form.
* - Execute this method to get CActiveDataProvider instance which will filter
* models according to data in model fields.
* - Pass data provider to CGridView, CListView or any similar widget.
*
* #return CActiveDataProvider the data provider that can return the models
* based on the search/filter conditions.
*/
public function search()
{
// #todo Please modify the following code to remove attributes that should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('studentid',$this->studentid);
$criteria->compare('lastname',$this->lastname,true);
$criteria->compare('firstname',$this->firstname,true);
$criteria->compare('middlename',$this->middlename,true);
$criteria->compare('course',$this->course,true);
$criteria->compare('year',$this->year);
$criteria->compare('cellphonenumber',$this->cellphonenumber);
$criteria->compare('email',$this->email,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
/**
* Returns the static model of the specified AR class.
* Please note that you should have this exact method in all your CActiveRecord descendants!
* #param string $className active record class name.
* #return Student the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
}
Controller:
public function actionCreateUsers()
{
$vm = (object) array();
$vm->Users=new Users;
$vm->Student=new Student;
$vm->Instructor=new Instructor;
$holder;
// $model=new Users;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['Users']))
{
$vm->Users->attributes=$_POST['Users'];
$vm->Users->save();
if(isset($_POST['Student']))
{
$vm->Student->attributes=$_POST['Student'];
$vm->Student->studentid = $vm->Users->username;
if($vm->Student->save())
$vm->Student->unsetAttributes();
}
if(isset($_POST['Instructor']))
{
$vm->Instructor->attributes=$_POST['Instructor'];
$vm->Instructor->instructorid = $vm->Users->username;
if($vm->Instructor->save())
$vm->Instructor->unsetAttributes();
}
else {
return false;
}
}
// echo 'saved';
// $this->redirect(array('view','id'=>$model->username));
$vm->Users->unsetAttributes();
$vm->Student->unsetAttributes();
$vm->Instructor->unsetAttributes();
$this->render('users',array(
'vm'=>$vm,
));
}
View:
Hi Please provide the code
As you said that one model is saving but others are not. This may be the issue of rules define in model.
Try to getErrors() if model doesn't save
$vm = (object) array();
$vm->Users=new Users;
$vm->Student=new Student;
$vm->Instructor=new Instructor;
$holder;
// $model=new Users;
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['Users']))
{
$vm->Users->attributes=$_POST['Users'];
$vm->Users->save();
if(isset($_POST['Student']))
{
$vm->Student->attributes=$_POST['Student'];
$vm->Student->studentid = $vm->Users->username;
if($vm->Student->save())
$vm->Student->unsetAttributes();
else{
print_r($vm->Student->getErrors());die;// to get errors
}
}
if(isset($_POST['Instructor']))
{
$vm->Instructor->attributes=$_POST['Instructor'];
$vm->Instructor->instructorid = $vm->Users->username;
if($vm->Instructor->save())
$vm->Instructor->unsetAttributes();
else{
print_r($vm->Instructor->getErrors());die;// to get errors
}
}
else {
return false;
}
}
// echo 'saved';
// $this->redirect(array('view','id'=>$model->username));
$vm->Users->unsetAttributes();
$vm->Student->unsetAttributes();
$vm->Instructor->unsetAttributes();
$this->render('users',array(
'vm'=>$vm,
));
}
In order to debug, remember you can add:
if($vm->Student->save()) {
$vm->Student->unsetAttributes();
} else {
var_dump($vm->getErrors());
die;
}
Same for instructors. Hope it helps
I have some project in Yii. First it was a form with two text fields: Name and Subject (subject is list of subjects separated by comma). Now I need to replace subject text field with list of checkboxes, which will add the same string separated by comma.
<!--<?php echo $form->labelEx($model,'Subjects'); ?>
<?php echo $form->textField($model,'Subjects',array('size'=>60,'maxlength'=>255)); ?>
<?php echo $form->error($model,'Subjects'); ?>-->
<?php echo $form->labelEx($model,'Subjects'); ?>
<?php echo $form->checkBoxList($model,'Subjects',$this->listOfSubjects()); ?>
<?php echo $form->error($model,'Subjects'); ?>
List of subjects is a controller method that returns array required for checkboxlist in Yii, something like:
array(
'1'=>'Something',
'2'=>'Anotherthing'
);
Also here is code of my action create. It's rather standart:
public function actionCreate()
{
$model=new CrdTeachers;
if(isset($_POST['CrdTeachers']))
{
$model->attributes=$_POST['CrdTeachers'];
if($model->save())
$this->redirect(array('view','id'=>$model->Teacher_ID));
}
$this->render('create',array(
'model'=>$model,
));
}
This code worked fine when there was just two text fields. Now when I'm using create action it says that mistake:
mb_strlen() expects parameter 1 to be string, array given
I can't find where can I process it's data to make it string. Any experts of Yii here? What should I look for?
UPDATE:
Here is CRDTeachers model class
class CrdTeachers extends CActiveRecord
{
/**
* Returns the static model of the specified AR class.
* #param string $className active record class name.
* #return CrdTeachers 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 'crd_teachers';
}
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('Name, Subjects', 'required'),
array('Name, Subjects', 'length', 'max'=>255),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('Teacher_ID, Name, Subjects', 'safe', 'on'=>'search'),
);
}
/**
* #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.
return array(
//'rSubjects'=>array(self::HAS_MANY, 'CrdSubjects', 'Subject_ID'),
//'categories'=>array(self::MANY_MANY, 'CrdTeachers', '{{CrdSubjects}}(Subject_ID, Subject_Name)'),
);
}
public function behaviors()
{
return array(
'DMultiplyListBehavior'=>array(
'class'=>'DMultiplyListBehavior',
'attribute'=>'categoriesArray',
'relation'=>'categories',
'relationPk'=>'id',
),
);
}
protected function afterSave()
{
//$this->refreshCategories();
parent::afterSave();
}
protected function refreshCategories()
{
$categories = $this->categoriesArray;
CrdTeachers::model()->deleteAllByAttributes(array('Subject_ID'=>$this->id));
if (is_array($categories))
{
foreach ($categories as $id)
{
if (Category::model()->exists('id=:id', array(':id'=>$id)))
{
$postCat = new CrdTeachers();
$postCat->post_id = $this->id;
$postCat->category_id = $id;
$postCat->save();
}
}
}
}
/**
* #return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'Teacher_ID' => 'Teacher',
'Name' => 'Name',
'Subjects' => 'Subjects',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* #return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
*/
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('Teacher_ID',$this->Teacher_ID);
$criteria->compare('Name',$this->Name,true);
$criteria->compare('Subjects',$this->Subjects,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
/*
* Возвращает список по ID
*/
public function getParentTypeById($id) {
$title = $this->model()->findByPk($id)->Name;
return $title;
}
}
You may use this method in your model.
public function beforeValidate()
{
if (is_array($this->Subjects)) {
$this->Subjects = implode(', ', $this->Subjects);
}
return parent::beforeValidate();
}
You can process the input before validation with the beforeValidate function in the model. Make sure that you run the parent method and return true if want validation to continue. Usually it is done like this:
public function beforeValidate()
{
// do stuff to transform the array into the string
return parent::beforeValidate();
}
I have created login form in yii using authenticate functionality.
After submit the login form with out enter username and password, it directly goes to the redirect url.
It doesn't show the error message. I am not familiar in yii. So I couldn't find the solution for this.
Here is my controller code for login form
public function actionIndex()
{
$this->layout = 'layout10';
$model = new LoginForm;
//exit;
// if it is ajax validation request
if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
// collect user input data
if(isset($_POST['LoginForm']))
{
$model->attributes=$_POST['LoginForm'];
// validate user input and redirect to the previous page if valid
if($model->validate() && $model->login($_POST['LoginForm']))
$url = Yii::app()->getBaseUrl()."/admin/product_name";
Yii::app()->getRequest()->redirect($url);
//$this->redirect(Yii::app()->user->returnUrl);
}
$this->render('index',array('model'=>$model));
}
Here is the model page for login
class LoginForm extends CActiveRecord
{
/**
* Returns the static model of the specified AR class.
* #return Users the static model class
*/
private $_identity;
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* #return string the associated database table name
*/
public function tableName()
{
return 'tbl_user';
}
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array(' password, username,' , 'required', 'on'=>'login' ),
);
}
/**
* #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.
return array(
);
}
public function login( $id, $password = "" )
{
$this->_identity = new UserIdentity($username = $id ,$password);
$this->_identity->authenticate();
//Yii::app()->user->login($this->_identity,3600*24*30);
if(Yii::app()->user->login($this->_identity,0*0*0))
{
//echo $this->_identity->errorMessage;
return true;
}
else
{
Yii::app()->user->setState('error', $this->_identity->errorMessage);
return false;
}
}
/**
* #return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'username' => 'User',
'password' => 'Last Name',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* #return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
*/
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id,true);
$criteria->compare('password',$this->password,true);
$criteria->compare('username',$this->username,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
}
Here is the useridentity in components
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$record=LoginForm::model()->find(array(
'condition'=>'username =:username',
'params'=>array(':username'=>$this->username)
));
if($record===null)
{
$this->_id='user Null';
$this->errorCode=self::ERROR_USERNAME_INVALID;
}
else if($record->E_PASSWORD!==$this->password) // here I compare db password with passwod field
{
$this->_id=$this->username;
$this->errorCode=self::ERROR_PASSWORD_INVALID;
}
else
{
$this->_id=$record['username'];
$this->setState('title', $record['username']);
$this->errorCode=self::ERROR_NONE;
}
return !$this->errorCode;
}
public function getId() // override Id
{
return $this->_id;
}
}
Here is the view page for login
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'login-form',
'enableClientValidation'=>false,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
)); ?>
<fieldset>
<div class="input-group input-group-lg">
<span class="input-group-addon"><i class="glyphicon glyphicon-user red"></i></span>
<?php echo $form->textField($model,'username',array('id'=>'example-username2','class'=>'form-control','placeholder'=>'Username')); ?>
</div><?php echo $form->error($model,'username'); ?>
<div class="clearfix"></div><br>
<div class="input-group input-group-lg">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock red"></i></span>
<?php echo $form->passwordField($model,'password',array('id'=>'example-username2','class'=>'form-control','placeholder'=>'Password')); ?>
</div><?php echo $form->error($model,'password'); ?>
<div class="clearfix"></div>
<div class="clearfix"></div>
<p class="center col-md-5">
<button type="submit" class="btn btn-primary">Login</button>
</p>
</fieldset>
<?php $this->endWidget(); ?>
Please tell How to validate the form in model. Now no error message displayed.
for watching errors also you can use:
var_dump($model->getErrors());
and next
$model->login($_POST['LoginForm']);
I think you don't need the pass POST variable because model already have this params
maybe you just change the login method like this:
public function login()
{
$this->_identity = new UserIdentity($this->id ,$this->password);
$this->_identity->authenticate();
//Yii::app()->user->login($this->_identity,3600*24*30);
if(Yii::app()->user->login($this->_identity,0*0*0))
{
//echo $this->_identity->errorMessage;
return true;
}
else
{
Yii::app()->user->setState('error', $this->_identity->errorMessage);
return false;
}
}
We have integrated the yii authenticate acceess rules. In the login page, after submit the
form, it displays the following error message shows
Fatal error: Call to undefined method LoginForm::model() in D:\wamp\www\onlinetest\protected\components\UserIdentity.php on line 13
Here is the controller code
public function actionLogin()
{
$model=new LoginForm;
// if it is ajax validation request
if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
// collect user input data
if(isset($_POST['LoginForm']))
{
$model->attributes=$_POST['LoginForm'];
// validate user input and redirect to the previous page if valid
if($model->validate() && $model->login())
$this->redirect(Yii::app()->user->returnUrl);
}
// display the login form
$this->render('login',array('model'=>$model));
}
Here is the login form model
class LoginForm extends CFormModel
{
public $username;
public $password;
public $rememberMe;
private $_identity;
public function tableName()
{
return 'tbl_login';
}
public function authenticate($attribute,$params)
{
if(!$this->hasErrors()) // we only want to authenticate when no input errors
{
$identity=new UserIdentity($this->username,$this->password);
$identity->authenticate();
switch($identity->errorCode)
{
case UserIdentity::ERROR_NONE:
Yii::app()->user->login($identity);
break;
case UserIdentity::ERROR_USERNAME_INVALID:
$this->addError('username','Username is incorrect.');
break;
default: // UserIdentity::ERROR_PASSWORD_INVALID
$this->addError('password','Password is incorrect.');
break;
}
}
}
public function login()
{
if($this->_identity===null)
{
$this->_identity=new UserIdentity($this->username,$this->password);
$this->_identity->authenticate();
}
if($this->_identity->errorCode===UserIdentity::ERROR_NONE)
{
$duration=$this->rememberMe ? 3600*24*30 : 0; // 30 days
Yii::app()->user->login($this->_identity,$duration);
return true;
}
else
return false;
}
}
Here is the useridentity.php in components
class UserIdentity extends CUserIdentity
{
private $_id;
public function authenticate()
{
$record=LoginForm::model()->findByAttributes(array('VarUser_type'=>$this->username)); // here I use Email as user name which comes from database
if($record===null)
{
$this->_id='user Null';
$this->errorCode=self::ERROR_USERNAME_INVALID;
}
else if($record->E_PASSWORD!==$this->password) // here I compare db password with passwod field
{ $this->_id=$this->username;
$this->errorCode=self::ERROR_PASSWORD_INVALID;
}
else
{
$this->_id=$record['VarUser_type'];
$this->setState('title', $record['VarUser_type']);
$this->errorCode=self::ERROR_NONE;
}
return !$this->errorCode;
}
public function getId() // override Id
{
return $this->_id;
}
}
How can I fix this issue? If you know help me
you can njot use
$record=LoginForm::model()->findByAttributes(array('VarUser_type'=>$this->username));
because LoginForm extends CFormModel
for database retrival it should extends CActiveRecord
see this
see this
your model should be like this
class Users extends CActiveRecord
{
/**
* Returns the static model of the specified AR class.
* #return Users the static model class
*/
private $_identity;
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* #return string the associated database table name
*/
public function tableName()
{
return 'users';
}
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array(' password, user_name,' , 'required', 'on'=>'login' ),
array('user_id, last_name, first_name, address1, address2, city, pincode, state_id, country_id, phone, fax, email, created_date, updated_date, last_login, company_name, tour_id, password, user_name, last_login_from, gender, is_session_on, status, memo, cell, role_type_id, group_contract_template_id, group_policy_id, billing_contact, billing_phone, billing_address, billing_email, after_hours_phone', 'safe', 'on'=>'search'),
);
}
/**
* #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.
return array(
);
}
public function login( $id, $password = "" )
{
$this->_identity = new UserIdentity($username = $id ,$password);
$this->_identity->authenticate();
//Yii::app()->user->login($this->_identity,3600*24*30);
if(Yii::app()->user->login($this->_identity,0*0*0))
{
//echo $this->_identity->errorMessage;
return true;
}
else
{
Yii::app()->user->setState('error', $this->_identity->errorMessage);
return false;
}
}
/**
* #return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'user_id' => 'User',
'last_name' => 'Last Name',
'first_name' => 'First Name',
'address1' => 'Address1',
'email' => 'Email',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* #return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
*/
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('user_id',$this->user_id,true);
$criteria->compare('last_name',$this->last_name,true);
$criteria->compare('first_name',$this->first_name,true);
$criteria->compare('email',$this->billing_address,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
}
you don't have included the code for model method
public static function model($className=__CLASS__)
{
return parent::model($className);
}
in your model class
Your UserIdentity class method authenticate is incorrect.. Refer to the code below to see how.
public function authenticate()
{
$record=YourUserModel::model()->find(array(
'condition'=>'VarUser_type =:username',
'params'=>array(':username'=>$this->username)
));
if($record===null)
{
$this->_id='user Null';
$this->errorCode=self::ERROR_USERNAME_INVALID;
}
else if($record->E_PASSWORD!==$this->password) // here I compare db password with passwod field
{ $this->_id=$this->username;
$this->errorCode=self::ERROR_PASSWORD_INVALID;
}
else
{
$this->_id=$record['VarUser_type'];
$this->setState('title', $record['VarUser_type']);
$this->errorCode=self::ERROR_NONE;
}
return !$this->errorCode;
}
in my site if email is registered in my database I would add a error
$this->addError('email' ,'This Email already registered');
but in Update form I do not want see this error
What is a simple way to solve my problem?
this is my users model:
<?php
/**
* This is the model class for table "users".
class Users extends CActiveRecord
{
// public $captcha;
/**
* #return string the associated database table name
*/
public function tableName()
{
return 'users';
}
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('username, email,password', 'required'),
array('roles_id', 'numerical', 'integerOnly'=>true),
array('username, password',
'length',
'max'=>255,
'min'=>4
),
array('email', 'comp_email'),
array('username', 'comp_username'),
array('DataCreated, LastUpdated', 'safe'),
// The following rule is used by search().
// #todo Please remove those attributes that should not be searched.
array('id, username, password, DataCreated, LastUpdated, roles_id', 'safe', 'on'=>'search'),
);
}
/**
* #return array relational rules.
*/
/**
* #return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'id' => 'ID',
'email'=>'Email',
'username' => 'Username',
'password' => 'Password',
'DataCreated' => 'Data Created',
'LastUpdated' => 'Last Updated',
'roles_id' => 'Roles',
);
}
public function search()
{
// #todo Please modify the following code to remove attributes that should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
$criteria->compare('username',$this->username,true);
$criteria->compare('password',$this->password,true);
$criteria->compare('DataCreated',$this->DataCreated,true);
$criteria->compare('LastUpdated',$this->LastUpdated,true);
$criteria->compare('roles_id',$this->roles_id);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
/**
* Returns the static model of the specified AR class.
* Please note that you should have this exact method in all your CActiveRecord descendants!
* #param string $className active record class name.
* #return Users the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function comp_username($attributes , $params)
{
$username = Yii::app()->db->createCommand()
->select('username')
->from('users')
->queryAll();
$y = (count($username));
for ($x=0;$x<$y;$x++)
{
$usernameE[$x] = $username[$x]['username'];
}
foreach ($usernameE as $u)
{
if($this->username == $u)
{
$this->addError('username' ,'This Username already registered');
break;
}
}
}
public function comp_email($attributes , $params)
{
$email = Yii::app()->db->createCommand()
->select('email')
->from('users')
->queryAll();
$y = (count($email));
for ($x=0;$x<$y;$x++)
{
$emailE[$x] = $email[$x]['email'];
}
foreach ($emailE as $u)
{
if($this->email == $u)
{
$this->addError('email' ,'This Email already registered');
break;
}
}
}
public function getUsernameEmail($id)
{
$emailUsername = Yii::app()->db->createCommand()
->select('*')
->from('users')
->where('id=:id', array(':id'=>$id))
->queryAll();
return $emailUsername;
}
}
and this is my action Update in my controller:
public function actionUpdate($id)
{
$model=$this->loadModel($id);
// Uncomment the following line if AJAX validation is needed
$this->performAjaxValidation($model);
if(isset($_POST['Users']))
{
$model->attributes=$_POST['Users'];
$id=$model->id;
$useremail = Users::model()->getUsernameEmail($id);
$useremailX= $useremail[0]['username'];
$model->username=$useremailX;
$useremailX= $useremail[0]['email'];
$model->email=$useremailX;
$model->password= crypt($model->password,'salt');
if($model->save())
$this->redirect(array('view','id'=>$model->id));
}
$this->render('update',array(
'model'=>$model,
));
}
You can achieve this by applying specific scenarios to your rules.
The Yii WIKI topic on the subject is a good reference.
In your rules, you can specify which scenarios to apply the rule to.
array('email', 'unique','message'=>'Email already exists!', 'on'=>'insert')
Please note that Yii automatically injects specific scenarios, depending on how the object is created.
insert
update
search
You can specify your own custom scenario.
$model = Customer::model()->findByPK($customerID);
$model->scenario = 'purchase';
this is how to validate, you can set error message to be empty.
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
//First parameter is your field name of table which has email value
array('email', 'email','message'=>"The email isn't correct"),
array('email', 'unique','message'=>'Email already exists!'),
);
}
https://stackoverflow.com/a/12778419/1727357
or you can make your own validator:
public function uniqueEmail($attribute, $params)
{
// Set $emailExist variable true or false by using your custom query on checking in database table if email exist or not.
// You can user $this->{$attribute} to get attribute value.
$emailExist = true;
if($emailExist)
{
//do what your want
$this->addError('email','Email already exists');
}
}
User this validation method in rules:
array('email', 'uniqueEmail','message'=>'Email already exists!'),