Benutzerregistrierung und Datum

Hi,

ich habe eine Benutzertabelle erstellt und über gii Model und Controller erstellt.

Wenn ich nun einen neuen Benutzer anlegen will, dann erscheinen auch die Felder Registrierungsdatum sowie letzter Login. Diese kann ich im Template entfernen und in den Validierungsregeln. Im Controller steht sowas :




if(isset($_POST['User']))

{

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

  if($model->save())

	$this->redirect(array('view','id'=>$model->id));

}



Wie kann ich erreichen, das die Spalte Registrierungsdatum beim Speichern mit dem aktuellen Datum ausgefüllt wird?

Schau dir mal CTimeStampBehavior an - einfach als Behavior im Model definieren, deine Spaltennamen konfigurieren, fertig.

Hi Mike,

das geht super. Habe aber da noch ein Problem. Ich will das Passwort verschlüsseln und wenn ich im Model die untere Funktion mit drin habe, dann wird mir das Datum nicht mehr eingetragen. Entferne ich beforeSave(), dann geht es wieder. Könntest du mir noch nen Tip geben?




public function behaviors() {

    return array(

        'CTimestampBehavior' => array(

            'class' => 'zii.behaviors.CTimestampBehavior',

            'createAttribute' => 'registrierungsdatum',

            'updateAttribute' => 'letzter_login',

         )

    );

}


public function beforeSave() {

    if ($this->isNewRecord)

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

    return true;

}



Du musst in deiner beforeSave() Funktion noch irgendwo parent::beforeSave() aufrufen, sonst wird das Event für die Behavoirs nicht ausgelöst.

Hi,

du bist gut :slight_smile: so hier klappt es.




public function beforeSave() {

    parent::beforeSave();

        

    if ($this->isNewRecord)

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

    return true;

}



eine "Kleinigkeit" hätte ich noch, und zwar das Update des Passwortes. Der Wert (*****) wird nicht mehr angezeigt mit folgender Zeile:




$form->passwordField($model,'passwort',array('size'=>45,'maxlength'=>45,'id'=>'passwort', 'value'=>''))



Nun würde aber bei jedem Update ein leeres Passwort gespeichert bzw. ist es ein Pflichtfeld und man muss bei jedem Update das Passwort angeben. Gib es dafür eine einfache Lösung? Wenn man den Wert erneut anzeigt, wird doch das schon verschlüsselte Passwort erneut verschlüsselt.

Jo, die Standardmethode, die ich dafür verwende: Definiere ein zusätzliches "virtuelles" Attribut in deinem Model (das es in der DB nicht gibt). Dieses Attribut verwendest du als Formularfeld. Das "richtige" DB-Attribut ("passwort" in deinem Fall) zeigst du gar nicht mehr an. Nur wenn dann in dieses virtuelle Attribut ein Wert eingetragen wurde, verschüsselst du das Passwort:




public $displayPw;  // Enthält das Klartextpasswort oder ist leer, falls keins eingetragen wurde

public function beforeSave()

{

    if (!empty($this->displayPw))

        $this->passwort=sha1($this->displayPw);

    ...

}

Nicht vergessen: Eine Regel in rules() für displayPw definieren, sonst wird der Wert beim Abschicken nicht übernommen.

Das Passwortfeld ist ja ein Pflichtfeld, und wenn ich es leer lasse kommt ja die Fehlermeldung. Zumindest sollte es ja beim Anlegen des Datensatzes ein Pflichtfeld sein. Wie kann ich das Feld dann beim Update leer lassen?

Das würd ich jetzt pragmatisch auch in beforeSave() lösen und die required rule wegmachen:




if ($this->isNewRecord && empty($this->displayPw))

{

  $this->addError('displayPw', 'Bitte ausfüllen!');

  return false;

}

Oh, mir fällt grad ein, wir ham ja auch noch das Szenario ‘create’. Du könntest also Alternativ auch ‘on’=>‘create’ zu deiner required Regel hinzufügen, sollte auch klappen.

Hi,

also mit ‘on’=>‘create’ ging es irgendwie nicht, aber ich habe selber ein scenario hinzugefügt (register) und das konnte ich angeben.

ich habe jetzt mal das zusätzliche Feld eingebaut, auch in den rules angegeben, aber wenn ich mir in der beforeSave-Methode den WErt ausgeben lasse, ist der immer leer, auch wenn ich in das Feld etwas eingegeben habe

Hi Mike,

deine Methode mit dem virtuellen Attribut funktioniert nun :slight_smile:

warum ‘on’=> ‘create’ nicht geht weiß ich noch nicht.




// CONTROLLER

$model->scenario = 'register';


//MODEL:

public passwordField


// rules

public function rules() {

        

        return array(

            array('passwordField', 'safe'),

            array('passwordField', 'required', 'on'=>'register'),

            //usw...

        );

    }


public function beforeSave() {

        

        parent::beforeSave();

        

        if (!empty($this->passwordField)){

            $this->passwort = sha1($this->passwordField);

        }

        

        return true;

    }


// TEMPLATE:

$form->passwordField($model,'passwordField',array('size'=>45,'maxlength'=>45,'id'=>'passwort'));




Wenn man auf Update geht, dann ist das Passwortfeld leer und wenn nix eingegeben wurde, wird das alte Passwort behalten. Treten bei einem Create Fehler auf, dann wird der Wert im Passwortfeld beibehalten. Warum das so ist, ist mir noch nicht so klar, da ja beim Update das FEld auch leer ist.

nach diesem Aufruf




array('passwordField', 'safe'),



wurde dann der Wert übernommen.

Bei einem Update wird das Model mit Daten aus der DB befüllt, darum ist passwordField leer, weil das in der DB nicht vorhanden ist. Beim Erstellen/Updaten bleibt der eingegebene Wert hingegen so lange erhalten, bis das Model erfolgreich gespeichert/geupdated wurde. Du übernimmst ja die abgesendeten Formulardaten jedesmal ins Model, und damit auch den Wert für passwordField.

Hi,

ok, danke für die Erklärung. Jedenfalls funktioniert es jetzt so wie es soll dank deiner Hinweise :slight_smile: