Manipulação De Formulário De Alteração

Bom dia pessoal.

Estou montando um sistema de gerenciamento empresarial para minha empresa e estou como dúvidas, pois sou iniciante no Yii.

É o seguinte eu tenho uma tabela no BD chamada: usuario, onde estão cadastrados os usuários que podem se logar ao sistema.

Ao se logar no sistema o usuário pode entrar no menu PERFIL e alterar alguns dados de sua conta.

Segue em anexo uma imagem da tela de alteração de usuário para vocês entenderem melhor minhas dúvidas.

Minhas dúvidas são as seguintes:

1 - Ao alterar o campo LOGIN, como eu posso fazer antes uma consulta para ver se o login digitado já existe e bloquear a alteração caso exista?

2 - No campo Senha, como eu faço para o textfield vir vazio, pois eu estou usando a encriptação SHA1 para senha ai vem um código louco no textfield.

3 - Como eu faço para criar um outro campo textfield para conferencia da nova senha digitada, EX: SENHA/CONFIRMAR SENHA.

Volto a dizer eu sou iniciante no Yii e peço que vocês expliquem com exemplos ou me mostrem um caminho para que eu possa estudar.

Obrigado.

Freelancer,

  1. Existe uma função que você pode adicionar no seu Model, que ele faz as execuções antes da validação, o nome é beforeValidate(). Dentro do beforeValidate(), você faz a consulta com o login digitado.

Exemplo:




public function beforeValidate() {

	$login = self::model()->find('login = :login', array(':login' => $this->login));

	if(!is_null($login)) {

		$this->addError('login', 'Este login já está sendo usado.');

		

	return parent::beforeValidate();

}



  1. Usa o afterValidate com afterFind();



class Model extends CActiveRecord


	public $old_password;

	

	public function beforeValidate(){


		/*Se a senha não for digitada, a ação é não recriar uma nova senha */

		if(!empty($this->password) && $this->password != $this->old_password)

			$this->password = sha1($this->password);

			

		return parent::beforeValidate();

	}

	public function afterFind() {

		$this->old_password = $this->password; //Atribuindo a senha atual a uma nova variavel, caso ele mude a senha, você pode comparar com a senha digitada

		$this->password = '';

			

		return parent::afterFind();

	}

	

}



  1. Segue o exemplo



class Model extends CActiveRecord {


    public $confirmPassword;

	

    public function rules() {

        return array(

            array('password, confirmPassword', 'length', 'max' => 40, 'min' => 5),

            array('confirmPassword', 'compare', 'compareAttribute' => 'password'),

        );

    }

}



Opa, Newerton Valeu pelas dicas.

Estou com umas dúvidas na implementação desses códigos que você me passou.

PROBLEMAS:

1 - A função beforeValidate() funcionou corretamente, ao digitar um login que já existe no Banco de dados ele lança um erro informando que o login já existe, como já esperado. Só que ao digitar um login diferente ocorre que o mesmo não é atualizado no banco de dados ao lançar o formulário. Eu acredito que ele não está conseguindo executar a função actionUpdate() do UsuarioController, pois a página não é redirecionada para o View do usuario alterado.

2 - Com relação a senha toda a interação de erros está funcionando corretamente:

  • está exigindo que a senha tenha no mínimo 5 caracteres e no máximo 10, tanto no textfield senha como no textfield confirmar senha.

  • está exigindo que o campo senha seja idêntico ao campo confirmar senha

Só que também não ta executando a alteração junto ao banco de dados. e quando eu consegui fazer com que alterasse, ao deslogar e tentar relogar ficava informando que o a senha ou o usuário estavam incorretos no momento do login.

3 - Percebi também que estas funções interferiram tanto no login como em todas as ações que precisam acessar o banco de dados para fazer alterações ou cadastros.

Ex: como descrevi no problema 2 o login parou de funcionar após tentar alterar senha e a actionLogout() do SiteController que eu havia implementado para alterar o banco de dados com informações de lastlogintime antes de deslogar parou de funcionar também.

Segue abaixo o textfield que criei no _form.php:




<div class="row">

		<?php echo $form->labelEx($model,'confirmPassword'); ?> 

		<?php echo $form->textField($model,'confirmPassword',array('size'=>15,'maxlength'=>10)); ?>

		<?php echo $form->error($model,'confirmPassword'); ?>

</div>



Segue abaixo meu MODEL - usuario, já com a implementação que você passou.




<?php


/**

 * This is the model class for table "usuario".

 *

 * The followings are the available columns in table 'usuario':

 * @property integer $id_user

 * @property string $nm_user

 * @property string $psw_user

 * @property string $email_user

 * @property string $dt_acesso_user

 * @property string $hr_acesso_user

 * @property integer $tp_sistema_user

 * @property string $dt_criacao_user

 */

class Usuario extends CActiveRecord

{

	public $old_password;

	public $confirmPassword;

	

	

	//FUNÇÃO QUE CONFERE SE O LOGIN DIGITADO NA ALTERAÇÃO OU NO CADASTRO JÁ EXISTE.

	public function beforeValidate() {

        $login = self::model()->find('nm_user = :nm_user', array(':nm_user' => $this->nm_user));

        if(!is_null($login)) {

			$this->addError('nm_user', 'Este login já está sendo usado.');

			return parent::beforeValidate();

		}

		//Se a senha não for digitada, a ação é não recriar uma nova senha

		if(!empty($this->psw_user) && $this->psw_user != $this->old_password)

			$this->psw_user = sha1($this->psw_user);

			return parent::beforeValidate();

	}

	

	public function afterFind() {

		//Atribuindo a senha atual a uma nova variavel, caso ele mude a senha, você pode comparar com a senha digitada	  

		$this->old_password = $this->psw_user;

		$this->psw_user = '';

				

		return parent::afterFind();

	}	

	

	

	/**

	 * @return string the associated database table name

	 */

	public function tableName()

	{

		return 'usuario';

	}


	/**

	 * @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('nm_user, psw_user, email_user, dt_acesso_user, hr_acesso_user, tp_sistema_user', 'required'),

			array('tp_sistema_user', 'numerical', 'integerOnly'=>true),

			array('nm_user, psw_user, email_user', 'length', 'max'=>255),

			array('dt_criacao_user', 'safe'),

			// The following rule is used by search().

			// @todo Please remove those attributes that should not be searched.

			array('id_user, nm_user, psw_user, email_user, dt_acesso_user, hr_acesso_user, tp_sistema_user, dt_criacao_user', 'safe', 'on'=>'search'),

			

			array('psw_user, confirmPassword', 'length', 'max' => 10, 'min' => 5),

            array('confirmPassword', 'compare', 'compareAttribute' => 'psw_user'),

			

			/* MODELO DE COMO ADICIONAR A DATA DE CRIACAO NO BD AO CRIAR USUARIO

			 array('dt_acesso_user','default',

              'value'=>new CDbExpression('NOW()'),

              'setOnEmpty'=>false,'on'=>'create'),

    		*/

		);

	}


	/**

	 * @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(

			'id_user' => 'Id',

			'nm_user' => 'Login',

			'psw_user' => 'Senha',

			'email_user' => 'E-mail',

			'dt_acesso_user' => 'Data do último Acesso',

			'hr_acesso_user' => 'Hora do último Acesso',

			'tp_sistema_user' => 'Tipo de Sistema',

			'dt_criacao_user' => 'Data da Criação',

			'confirmPassword' => 'Confirmar Senha',

		);

	}


	/**

	 * 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('id_user',$this->id_user);

		$criteria->compare('nm_user',$this->nm_user,true);

		$criteria->compare('psw_user',$this->psw_user,true);

		$criteria->compare('email_user',$this->email_user,true);

		$criteria->compare('dt_acesso_user',$this->dt_acesso_user,true);

		$criteria->compare('hr_acesso_user',$this->hr_acesso_user,true);

		$criteria->compare('tp_sistema_user',$this->tp_sistema_user);

		$criteria->compare('dt_criacao_user',$this->dt_criacao_user,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 Usuario the static model class

	 */

	public static function model($className=__CLASS__)

	{

		return parent::model($className);

	}

	

	

}



Todo código que manipulei esta logo acima, não sei mais o que devo fazer.

Posta seu form, deixa eu ver quais os campos está solicitando.

Ta ocorrendo que alguns campos, são obrigatorio, e não está passando pelo seu controller, no seu controller, tem um $model->validate(), precisa saber quais os outros campos é obrigatório, e criar uma novo cenário.

Pelo seu model, por onde você está gerando a senha?

Em anexo esta uma foto do meu form ao qual o código esta logo abaixo.

Na foto contém a descrição de um erro que esta ocorrendo quando é adicionado ao RULES do usuario o código que você me passou.

Segue abaixo meu _form.php referente ao model usuario:




<?php

/* @var $this UsuarioController */

/* @var $model Usuario */

/* @var $form CActiveForm */

?>


<div class="form">


<?php $form=$this->beginWidget('CActiveForm', array(

	'id'=>'usuario-form',

	// Please note: When you enable ajax validation, make sure the corresponding

	// controller action is handling ajax validation correctly.

	// There is a call to performAjaxValidation() commented in generated controller code.

	// See class documentation of CActiveForm for details on this.

	'enableAjaxValidation'=>false,

)); ?>


	<p class="note">Campos com <span class="required">*</span> são obrigatórios.</p>


	<?php echo $form->errorSummary($model); ?>


	<div class="row">

		<?php echo $form->labelEx($model,'nm_user'); ?>

		<?php echo $form->textField($model,'nm_user',array('size'=>15,'maxlength'=>17)); ?>

		<?php echo $form->error($model,'nm_user'); ?>

	</div>


	<div class="row">

		<?php echo $form->labelEx($model,'psw_user'); ?> 

		<?php echo $form->textField($model,'psw_user',array('size'=>15,'maxlength'=>10)); ?>

		<?php echo $form->error($model,'psw_user'); ?>

	</div>

	

    <div class="row">

		<?php echo $form->labelEx($model,'confirmPassword'); ?> 

		<?php echo $form->textField($model,'confirmPassword',array('size'=>15,'maxlength'=>10)); ?>

		<?php echo $form->error($model,'confirmPassword'); ?>

	</div>

    

	<div class="row">

		<?php echo $form->labelEx($model,'email_user'); ?>

		<?php echo $form->textField($model,'email_user',array('size'=>40,'maxlength'=>50)); ?>

		<?php echo $form->error($model,'email_user'); ?>

	</div>

	

	

	<div class="row_buttons">

		<?php echo CHtml::submitButton($model->isNewRecord ? 'Cadastrar' : 'Alterar'); ?>

	</div>


<?php $this->endWidget(); ?>


</div><!-- form -->



A função abaixo é referente ao SiteController onde eu fiz a edição para salvar a data e hora do LASTLOGINTIME ao deslogar.




public function actionLogout()

	{

		$user=Usuario::model()->find("id_user");		

		$user->dt_acesso_user = date("Y-m-d");

 		$user->hr_acesso_user = date("H:i:s");

		$user->save();

		

		Yii::app()->user->logout();

		//$this->redirect(Yii::app()->homeUrl);

		$this->redirect(array('site/login'));

	}