[YII 2] Password Validation - repeat

Ciao a tutti,

è tutto il giorno che sto impazzendo sulla validazione della password.

In pratica ho due campi per inserire la password: password_hash e password_hash_repeat

Il form funziona ma anzichè salvare mi da errore BAD REQUEST #400 Missing required parameters: id

Vi posto il codice :

_form.php




<?php


use yii\helpers\Html;

use yii\widgets\ActiveForm;


/* @var $this yii\web\View */

/* @var $model backend\models\lista_clienti */

/* @var $form yii\widgets\ActiveForm */

?>


<div class="lista-clienti-form">


    <?php $form = ActiveForm::begin(); ?>


    <?= $form->field($model, 'username')->textInput(['maxlength' => 30]) ?>


    <?= $form->field($model, 'firstname')->textInput(['maxlength' => 120]) ?>


    <?= $form->field($model, 'lastname')->textInput(['maxlength' => 120]) ?>


    <!--<?= $form->field($model, 'auth_key')->textInput(['maxlength' => 32]) ?>-->


    <?= $form->field($model, 'password_hash')->textInput(['maxlength' => 30]) ?>


    <?= $form->field($model, 'password_hash_repeat' )->textInput(['maxlength' => 30]) ?>


    <?= $form->field($model, 'email')->textInput(['maxlength' => 255]) ?>


 <!--   <?= $form->field($model, 'status')->textInput() ?> 


    <?= $form->field($model, 'created_at')->textInput() ?>


    <?= $form->field($model, 'updated_at')->textInput() ?>-->


    <div class="form-group">

        <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>

    </div>


    <?php ActiveForm::end(); ?>


</div>




MODEL - lista-clienti




<?php


namespace backend\models;


use Yii;

//aggiunte

use common\models\User;

use yii\base\Model;

/**

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

 *

 * @property integer $id

 * @property string $username

 * @property string $firstname

 * @property string $lastname

 * @property string $auth_key

 * @property string $password_hash

 * @property string $password_reset_token

 * @property string $email

 * @property integer $status

 * @property integer $created_at

 * @property integer $updated_at

 */

class lista_clienti extends \yii\db\ActiveRecord

{

	public $password_hash_repeat;	

    /**

     * @inheritdoc

     */

    public static function tableName()

    {

        return 'user';

    }


    /**

     * @inheritdoc

     */

    public function rules()

    {

		

        return [

			['username', 'filter', 'filter' => 'trim'],

            ['username', 'required', 'message'=> 'Inserire un username'],

            ['username', 'unique', 'targetClass' => '\common\models\User', 'message' => 'Username già usato'],

            ['username', 'string', 'min' => 5, 'max' => 20, 'tooShort'=> 'Minimo 5 caratteri', 'tooLong' => 'Massimo 20 caratteri alfanumerici'],

			

			[['firstname', 'lastname'], 'required', 'message' => ' Campo obbligatorio'],

            [['firstname', 'lastname'], 'string', 'min'=>3, 'max' => 120, 'tooShort'=> ' Minimo 3 caratteri'],

			

			//['password_hash_repeat', 'message' => 'Inserire una password'],

            

			['password_hash', 'required'],

			['password_hash', 'string', 'min' => 6, 'tooShort' => 'Minimo 6 caratteri alfanumerici'],            

			//['password_hash_repeat', 'required', 'message' => ' Ripetere la password'],

			['password_hash_repeat', 'required', 'message' => ' Ripetere la password'],

			[['password_hash_repeat'], 'compare', 'compareAttribute' => 'password_hash'],     

            

			

			

			

			

			

	        //['password_hash', 'compare'],//password_repeat

			//['password_hash_repeat','safe'],

			

			['email', 'filter', 'filter' => 'trim'],

            ['email', 'required', 'message' => ' Inserire una email valida'],

            ['email', 'email', 'message' =>'Email non valida'],

            ['email', 'unique', 'targetClass' => '\common\models\User', 'message' => 'Email già usata'],

        ];

    }


    /**

     * @inheritdoc

     */

    public function attributeLabels()

    {

        return [

            'id' => 'ID',

            'username' => 'Username',

            'firstname' => 'Nome',

            'lastname' => 'Cognome',

            'password_hash' => 'Password',

			'password_hash_repeat' => 'Ripeti Password ',

            'email' => 'Email',

       

        ];

    }

}



CONTROLLER - ListaClientiControllers




<?php


namespace backend\controllers;


use Yii;

use backend\models\lista_clienti;

use backend\models\ListaClientiSearch;

use yii\web\Controller;

use yii\web\NotFoundHttpException;

use yii\filters\VerbFilter;

//aggiunte

use yii\base\InvalidParamException;

use yii\web\BadRequestHttpException;

use yii\filters\AccessControl;




/**

 * ListaClientiController implements the CRUD actions for lista_clienti model.

 */

class ListaClientiController extends Controller

{

    public function behaviors()

    {

        return [

            'verbs' => [

                'class' => VerbFilter::className(),

                'actions' => [

                    'delete' => ['post'],

                ],

            ],

        ];

    }


    /**

     * Lists all lista_clienti models.

     * @return mixed

     */

    public function actionIndex()

    {

        $searchModel = new ListaClientiSearch();

        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);


        return $this->render('index', [

            'searchModel' => $searchModel,

            'dataProvider' => $dataProvider,

        ]);

    }


    /**

     * Displays a single lista_clienti model.

     * @param integer $id

     * @return mixed

     */

    public function actionView($id)

    {

        return $this->render('view', [

            'model' => $this->findModel($id),

        ]);

    }


    /**

     * Creates a new lista_clienti model.

     * If creation is successful, the browser will be redirected to the 'view' page.

     * @return mixed

     */

    public function actionCreate()

    {

        $model = new lista_clienti();

		

	

        if ($model->load(Yii::$app->request->post()) && $model->validate()) {

			$model->status = 10;

			$model->created_at = date('d-m-Y');

			$hash = Yii::$app->getSecurity()->generatePasswordHash($model->password_hash);

			$model->password_hash = $hash;			

			$model->save();

			

            return $this->redirect(['view', 'id' => $model->id]);

        } else {

            return $this->render('create', [

                'model' => $model,

            ]);

        }

    }


    /**

     * Updates an existing lista_clienti model.

     * If update is successful, the browser will be redirected to the 'view' page.

     * @param integer $id

     * @return mixed

     */

    public function actionUpdate($id)

    {

        $model = $this->findModel($id);


        if ($model->load(Yii::$app->request->post())) {

			$model->password_hash = md5($this->password_hash);

			$model->save();

            return $this->redirect(['view', 'id' => $model->id]);

        } else {

            return $this->render('update', [

                'model' => $model,

            ]);

        }

    }


    /**

     * Deletes an existing lista_clienti model.

     * If deletion is successful, the browser will be redirected to the 'index' page.

     * @param integer $id

     * @return mixed

     */

    public function actionDelete($id)

    {

        $this->findModel($id)->delete();


        return $this->redirect(['index']);

    }


    /**

     * Finds the lista_clienti model based on its primary key value.

     * If the model is not found, a 404 HTTP exception will be thrown.

     * @param integer $id

     * @return lista_clienti the loaded model

     * @throws NotFoundHttpException if the model cannot be found

     */

    protected function findModel($id)

    {

        if (($model = lista_clienti::findOne($id)) !== null) {

            return $model;

        } else {

            throw new NotFoundHttpException('The requested page does not exist.');

        }

    }

}



Dove sbaglio ???

Grazie a tutti in anticipo!!!

:smiley:

Intervengo solo per chiederti la cortesia di modificare il titolo inserendo [Yii 2] all’inizio, giusto per tenere in ordine i titoli.

Nessun sa nulla ? :unsure:

Possibile mai ?

mi viene il dubbio che nel db il campo id sia impostato come NOT NULL ma non autoincrement, il che farebbe fallire il salvataggio. Però se così fosse, quando gii ha creato il model lo avrebbe messo required.

Verifica però. Mi scoccia abbandonarti, ma a dispetto dei 26 mesi su yii 1, ho girato pochissime ore con yii 2

Allora … guarda la tua actionCreate

sappiamo per certo che model->save non va a buon fine

qui model->id è nullo

per cui il redirect fa una chiamata verso una action che ha un parametro id, che però non gli viene fornito.

quindi yii dice che la richiesta è errara, perchè manca il parametro id

L’errore a video è spiegato da questo, ma la causa è più a monte, la causa vera è che qualche errore di validazione impedisce al modello di essere salvato a db.

Ora che sappiamo dove cercare l’errore, prima del redirect (o al posto del redirect), fai un dump dei model->errors (se ci sono anche in yii 2, ma mi sembra di si), perchè di sicuro se non va a buon fine il save il model ha degli errori di validazione.

A quel punto saprai e lo sapremo anche noi dove intervenire. Insieme vedremo COME farlo.

Dimmi che mi sono spiegato bene, è l’1 di notte…

Eccomi.

Grazie x avermi risposto.

Mi da quest’errore solo quando vado ad implementare il “compare” sulla password. Cosa che poi vorrei fare anche con l’email.

Se tolgo la ripetizione dellimmissione della pwd va tutto in modo corretto.

Ho creato il modulo e il crud con il gii ed il database è quello base dell’installazione di Yii2.

Dove si inserisce il model->errors ???

nell’actionCreate

sostitusici




return $this->redirect(['view', 'id' => $model->id]);



con l’equivalente, che atualmente non ricordo, di yii 2 di questo:




CVarDumper::dump($model->errors, 2,true);



Così vedi qual’è l’errore dal punto di vista di yii, e cerchiamo di capire meglio insieme

Non sono riuscito a trovare lo steso codice per Yii2.

Ho letto che è un problema di codice nel modulo

Se metto $model->save(false) mi registra il record e non ho nessun errore.

In teoria è solo una cosa momentanea il "false" … serve per capire se tutto va a buon fine ma non è una cosa da mantenere a regime. Ho capito bene ?

Il problema è nel trovare il codice corretto nel model lista_clienti.php

Se tolgo il "require" al campo "password_hash_repeat" funziona tutto correttamente. ma così non mi fa il raffronto tra le due psw.

Scusami se insisto, ma c’è DAVVERO bisogno di capire dal punto di vista di yii cosa non fa.

A questa pagina della guida ufficiale di Yii 2 viene spiegato come mostrare gli errori




$model = new \app\models\ContactForm;


// populate model attributes with user inputs

$model->attributes = \Yii::$app->request->post('ContactForm');


if ($model->validate()) {

    // all inputs are valid

} else {

    // validation failed: $errors is an array containing error messages

    $errors = $model->errors;

}



E qui c’è spiegato come usare il dump

Quindi una volta che hai ottenuto gli errors devi solo fare





    yii\helpers\BaseVarDumper->dump($errors,2,true)




E copia/incollarci gli errori di validazione.

Non ha alcun senso disattivare la validazione dei campi inserendo quel ‘false’. Tanto più se sai che inserendolo l’errore non si vede piu.

Questo vuol dire che l’errore è solo in fase di validazione, capiamo QUAL’è e sistemiamo il model di conseguenza.

Allora :

ho inserito il codice x vedre gli errori che già avevo fatto prima :smiley:


if ($model->load(Yii::$app->request->post()) && $model->validate()) {

			$model->status = 10;

			$model->created_at = date('Y');

			$hash = Yii::$app->getSecurity()->generatePasswordHash($model->password_hash);

			$model->password_hash = $hash;

			$model->save();

			

            return $this->redirect(['view', 'id' => $model->id]);

			$errors = $model->errors;

			

        } else {

            return $this->render('create', [

                'model' => $model,

            ]);

        }

    }



Poi per visualizzarli non ho capito bene dove inserire il codice o cmq sia dove scrivere la riga di comando che mi hai dato per visualizzari…!!! :blink:

Ottimo, ci siamo quasi

Commenta la riga del redirect




// return $this->redirect(['view', 'id' => $model->id]);



E dopo questa riga




$errors = $model->errors;



aggiungi questa




    yii\helpers\BaseVarDumper->dump($errors,2,true)



Teoricamente dovresti vedere a video un array "colorato" con gli errori.

Ho dato una letta al volo, Bad Request viene restituito quando appunto la richiesta non è valida e non è legato alla validazione del modello, a occhio pare che tu stia chiamando una Action senza passargli il parametro $id richiesto.

es. hai una actionPippo($key) del controller topolino, se tu richiami topolino/pippo senza passargli in _GET la variabile key lui ti da bad request, per non dare errore dovresti quindi chiamare topolino/pippo?key=qualcosa.

Detto questo analizza le chiamate che fa la tua app (tipo con firebug) e vedi se sono corrette per le action che hai dichiarato! ;)

@realtebo = Non sono riuscito ad inserire i codici da te scritti … dove vanno messi di preciso ?

@Nicola = in teoria l’id già dvorebbe prenderselo da solo xè se tolgo il compare della pwd tutto funziona correttamente… non capisco il xè non funziona e cmq sia non penso di essere il primo al quale serve questa cosa su Yii2 … !!! :blink:

Scusa, quota nel messagio la parte che NON capisci, sennò io non capisco COSA non hai capito tu.

Se parli del mio post #11, si riferisce tutto alla actionCreate dentro al tuo controller.

Le mie modifiche si riferiscono a quanto avevi postato tu piu sopra.

A che punto sei col problema? ancora invariato?

Faccio questo




//return $this->redirect(['view', 'id' => $model->id]);

			$errors = $model->errors;

			yii\helpers\BaseVarDumper->dump($errors,2,true)



e mi da una pagina di errore … l’errore sta nella riga yii\helpers…

PHP Parse Error – yii\base\ErrorException

syntax error, unexpected ‘->’ (T_OBJECT_OPERATOR)

Stai richiamando un metodo statico, la sintassi è:




yii\helpers\BaseVarDumper::dump($errors,2,true)



Che poi sarebbe meglio usare VarDumper




yii\helpers\VarDumper::dump($errors,2,true)



Scusatemi, quando gli ho dato il consiglio non lo stavo usando yii 2, ho fatto tutto solo leggendo la guida alle api

cambiando il codice e mettendo i due punti doppi

mi da errore… strano eppure il file esiste

Class ‘Yii\helpers\BaseVarDumper’ not found

Devi studiarti un attimo i namespaces e il meccanismo di autoloading delle classi altrimenti avrai un sacco di problemi a lavorare con Yii2!

Comunque se non dichiari con "use" i namespaces che vai ad utilizzare devi specificare il namespace completo, nel tuo caso la classe che usi è "\yii\helpers\VarDumper" quindi per richiamare un suo metodo dovrai scrivere:




\yii\helpers\VarDumper::dump($var);



Il tutto è case sensitive quindi "yii" e "Yii" sono due cose differenti.

Per queste cose ti è molto utile usare un IDE tipo NetBeans che ti suggerisce i namespace completi e ti avverte se stai usando metodi non dichiarati.

Già l’ho dichiarato…




use yii\helpers\BaseVarDumper;