[Yii 1] Salvare Lo Stato Della Sessione

Salve,

come bisogna fare per salvare la sessione dell’ utente?

Mi spiego meglio. Se un utente sta compilando un form o svolgendo altre operazioni nell’ applicazione e il browser si blocca o si chiude accidentalmente come posso fare per far si che l’ utente riparta da dove era arrivato?

Se avete un link (o un’ esempio) che possa tornarmi utile per imparare mi fa piacere!!!

Per avere la certezza di non perdere gli step intermedi di compilazione hai un solo modo: salvare su db.

In caso di chiusure o crash accidentali del browser perdi la sessione, quindi puoi far poco per ripristinare.

Concettualmente potresti salvare sui cookie, ma sono fatti per piccole informazioni, non per storare dati complessi.

Grazie della risposta. Non è possibile salvale la sessione dell’ utente e ricarla, dal punto dove era rimasto (se non è stato validato il form) in caso si disconnetta? L’ ho visto fare in un sito, per questo chiedo informazioni. Praticamente la sessione aveva una durata…se tu iniziavi a compilare il form (mettiamo sia in 3 step) e arrivavi al secondo step, poi non continuavi a compilare per 5 minuti, la sessione scadeva. Se ti riloggavi ripartivi dal punto in cui eri rimasto.

Da come hai descritto il procedimento mi puzza di salvataggio su db… se tutto venisse gestito in sessione non sarebbe necessario riloggarsi per fare il retrieve dello step, credo.

Il problema principale non è tanto sapere a quale step l’utente è arrivato (quello si potrebbe fare anche tramite un cookie), quanto salvare i dati degli step precedenti. Per essere consistente ti serve salvare tutto su un db. Già che fai questo, ti salvi anche l’ultimo step cui l’utente è arrivato.

Tutto questo as far as I know, magari altri utenti del forum sanno darti un’alternativa.

:)

Grazie della risposta SomethingWicked .

Potresti spiegarmi il procedimenti con un piccolo esempio? :)

Se vuoi ti incollo il codice dell’ actionCreate cosi vedi come ho strutturato la action.

Non capisco come salvare lo step.

Ti incollo il codice che uso nel controlle all’ actionCreate cosi de hai tempo ci dai uno sguardo.




public function actionCreate()

	{

		$model=new Ps;

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

		{

  $this->redirect(array('index'));

} elseif (isset($_POST['step2'])) 

{

  $this->setPageState('step1',$_POST['Ps']);

  $model=new Ps('step1');

  

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

  if ($model->validate())

  $this->render('form2',array('model'=>$model));


  else {

    $this->render('form1',array('model'=>$model));

 

   }

}

elseif(isset($_POST['finish'])) 

{

  $model=new Ps('finish');

  $model->attributes = $this->getPageState('step1',array()); 

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

  //Inserisco data e ora

			$model->time=new CDbExpression('NOW()');

			$model->date=new CDbExpression('NOW()');

			//Genero tracking univoco

			$id = $model->id; 

                        $codiceABarre = sprintf('%010d', 1009790000 + $id); 

			//fine generatore tracking univoco

			$model->totale = $model->prezzo + $model->diritti;

  if ($model->save())

    $this->redirect(array('index'));

	else 

	{

    $this->render('form2',array('model'=>$model));

} }else { 

  $model=new Ps('new');

  $this->render('form1',array('model'=>$model));

		}

	}



Cosa dovrei aggiungere?

Non mi è molto chiaro. Stai salvando tutti i tuoi dati post dentro uno state, in modo da portarti appresso tutti gli input dell’utente?

Quello che suggerivo io era di separare gli step e il salvataggio dei dati ad ogni cambio: al primo si fa una insert, dal secondo in poi una update dello stesso record.

Tu invece stai usando il metodo save() solo nello step finish.

Insisto sulla mia linea perché anche se tu riuscissi a far funzionare il form stateful come stai cercando di fare, ti rimane comunque il problema della sessione.

Oppure non ho capito bene io quali sono i tuoi termini.

Ecco lo sapevo che il mio metodo non era quello esatto ufffff!!! Come posso dividerlo come dici tu? Cioè l’ insert lo dovrei fare con la query? Non so farlo come dici tu…Ho dovuto leggere un bel po di forum e guide per arrivare a fare questo che sto facendo. Yii per me è nuovo. Puoi aiutarmi SomethingWicked? Comunque per ora grazie dei consigli e per aver bloccato i miei tentativi (ovviamente falliti) di arrivare dove voglio arrivare, seguendo la strada sbagliata!!! :) L’ ho detto che ci sto uscendo matto con questo form!!!

Http è stateless quindi da qualche parte bisogna conservare i dati appena inseriti.

Sei sicuro che invece non hai visto qualcosa del genere? In cui veniva rinnovata la sessione? http://www.yiiframework.com/extension/timeout-dialog/

Sono un pochino incasinato in questi giorni. Ti butto giù qualcosa appena possibile ;)

Ti ringrazio :) … io continuo a provare intanto … fosse mai che mi vada di (|) ;D e ci rieesca. In tal caso posto e aggiungo “Risolto” al Post!!!

Io una cosa simile l’avevo fatta salvando gli step nel database come “temporaneo” del modello, mi spiego:

Al completamento del primo step viene creato il record e vengono inseriti i dati richiesti nel primo form, nei successivi step il record viene aggiornato con i dati inseriti nei vari forms.

Per sapere a che punto l’utente è arrivato uso un campo “step” nella tabella che viene incrementato ad ogni passaggio.

Nel mio caso poi ogni record ha anche un campo “autore” e grazie a questo, quando l’utente effettua il login, riesco a sapere se ha dei form da completare.

Se hai un solo form invece, puoi fare il salvataggio temporaneo via Ajax ogni tot secondi o ogni volta che un campo viene modificato, in giro ho visto fare così spesso.

Ciao Nicola e grazie per il tuo intervento.

Il tuo procedimento mi interessa moltissimo e ti sarei grato se mi potessi spiegare come realizzarlo. Il fatto di poter sapere se l’ utente ha o meno ancora il form da convalidare e poterlo far ripartire dal punto preciso dove si trovava mi piace tantissimo. Questo perché nella mia app i form da compilare vanno in base al prodotto che l’ utente sceglie di utilizzare. Mi interessa il tuo procedimento perché vorrei far si che se l’ utente non ha compilato e convalidato il form, del prodotto che sta utilizzando, NON possa iniziare a usare un altro prodotto, quindi a compilare un altro form, finché non ha convalidato il form che stava utilizzando. Non so se mi spiego. Quindi se hai tempo e mi potessi spiegare come fare quei controlli che fai tu e come realizzare la mia action te ne sarei veramente grato. Grazie :)

Il metodo che suggerivo precedentemente è riassumibile in questi termini:

[list=3]

[*]Al primo step, una volta che l’utente clicca sul bottone di salvataggio, nel controller usi il metodo save del tuo model

[*]In sessione ti salvi l’id del record inserito in db, e quest’ultimo lo puoi recuperare così:


  if($model->save()){

        $model->id // eccolo qui

  }

oppure così:


  $insert_id = Yii::app()->db->getLastInsertID();



[*]Negli step successivi utilizzi


  $model = MyModel::model()->findByPk($insert_id);



e procedi con il salvataggio dei campi della form degli step successivi

[/list]

Questo era quello che mi era venuto in mente, compreso il discorso di Nicola sulla gestione degli step.

Forse non è il metodo stilisticamente più ricercato che si potrebbe mettere in atto, però dovrebbe essere sufficientemente solido.

Come alternativa, gestendo tutto lato client prima ancora di salvare in database, puoi provare con l’approccio di questa guida/estensione: http://www.yiiframework.com/extension/wizard-behavior/

Tieni conto che da quanto ho capito però non ti risolve il problema delle sessioni rotte/chiusure non volute del browser. Puoi però provare a sfruttare la parte client, perché mi sembra fatta non male, e fare un merge con la logica server che ti abbiamo suggerito sia io che Nicola.

Ciao