Jonathon Posted March 10, 2013 Share Posted March 10, 2013 Hi Larry and all, I've got a small function in my user controller that just confirms an email address and activation code, I then use this to activate a user. // Start of function code is $x and $ y valid etc User::model()->activateUser($x, $y); } else { Yii::app()->user->setFlash('error','Bad activation length'); $this->render('verify'); } } else { Yii::app()->user->setFlash('error','Bad email format'); $this->render('verify'); } So in short, if $x or $y are invalid I set the flash message which works fine. However, I call this function (in bold) to update my User model. public function activateUser($x, $y) { $model = User::model()->findByAttributes(array('email'=>$x, 'active'=>$y)); if($model === NULL) { throw new CDbException('These credentials, didn\'t match any records on file'); } else { // Record returned validate new record if($model->validate()) { $model->active = NULL; if($model->save()) { return 'ACTIVATED'; } So I wasn't sure how I pass a database error in a tidy way, like a flash message to say to the user "These credentials didn't match anything on file." This just provides the detailed error report. Because you can't use $this-> render() from inside the model()??? In the same way I couldn't figure out how to go about passing a success 'Activated' message either. Thanks Jonathon Link to comment Share on other sites More sharing options...
Larry Posted March 11, 2013 Share Posted March 11, 2013 Yeah, you don't render from inside models. I would just have the function return a Boolean indicating success and then use the results of that function call in the controller to know whether to set a good/bad flash message. 2 Link to comment Share on other sites More sharing options...
Antonio Conte Posted March 11, 2013 Share Posted March 11, 2013 I would go for custom exceptions. Definetly the cleanest approach I can think of. try { User::model()->activateUser($x, $y); } catch ( InvalidActivationException $iae ) { Yii::app()->user->setFlash('error',$iee->getMessage()); } // Render $this->render('verify'); Just add the exceptions to your model. class Model .... { public function activateUser($x, $y) { $model = User::model()->findByAttributes(array('email'=>$x, 'active'=>$y)); if($model === NULL) { throw new InvalidActivationException("Something bad happened"); } ... } } /** * InvalidActivationException */ class InvalidActivationException extends Exception { public function __construct($message) { parent::__construct($message); } } Hope that helps man. 1 Link to comment Share on other sites More sharing options...
Jonathon Posted March 11, 2013 Author Share Posted March 11, 2013 Thanks gents, What a handy piece to the jigsaw puzzle. Link to comment Share on other sites More sharing options...
Jonathon Posted March 11, 2013 Author Share Posted March 11, 2013 What I went for was: Controller // rest of $_GET checks try{ // try to activate the user User::model()->activateUser($x, $y); } catch (InvalidActivationException $invalidActivationMessage) { // Set error message Yii::app()->user->setFlash('error',$invalidActivationMessage->getMessage()); // render view $this->render('verify'); } } else { // Set error message Yii::app()->user->setFlash('error','Bad activation length'); // render view $this->render('verify'); } } else { // Set error message Yii::app()->user->setFlash('error','Bad email format'); // render view $this->render('verify'); } } I put in my own custom exception like Antonio said Model.php was public function activateUser($x, $y) { $model = User::model()->findByAttributes(array('email'=>$x, 'active'=>$y)); if($model === NULL) { // No records returned throw error throw new InvalidActivationException("Something bad happened"); } else { // Record returned, validate new record if($model->validate()) { $model->active = NULL; if($model->save()) { } } } } I wasn't sure exactly how to link the Model and controller when returning the boolean value. I'm sure it's pretty straight forward but today it's not happening for me. Link to comment Share on other sites More sharing options...
Jonathon Posted March 21, 2013 Author Share Posted March 21, 2013 How I went about this was this for those interested: Model public function activateUser($x, $y) { $model = User::model()->findByAttributes(array('email'=>$x, 'active'=>$y)); if($model === NULL) { // No records returned throw error throw new InvalidActivationException("Something bad happened"); } else { // Record returned, validate new record if($model->validate()) { $model->active = NULL; if($model->save()) { return true; } } } } And in the controller: Controller // rest of $_GET checks try{ // try to activate the user $register_success = User::model()->activateUser($x, $y); if($register_success == true) { // Set success message Yii::app()->user->setFlash('success','You have now been registered!'); // render view $this->render('verify'); } } catch (InvalidActivationException $invalidActivationMessage) { // Set error message Yii::app()->user->setFlash('error',$invalidActivationMessage->getMessage()); // render view $this->render('verify'); } } else { // Set error message Yii::app()->user->setFlash('error','Bad activation length'); // render view $this->render('verify'); } } else { // Set error message Yii::app()->user->setFlash('error','Bad email format'); // render view $this->render('verify'); } } Link to comment Share on other sites More sharing options...
Antonio Conte Posted March 21, 2013 Share Posted March 21, 2013 That looks pretty clean to me. Some good code you've written there, Jonathan. Link to comment Share on other sites More sharing options...
Jonathon Posted March 21, 2013 Author Share Posted March 21, 2013 Thanks Thomas, You know I actually was half way through writing my ideas down in a private message to help me fix the last part. And whilst trying to explain my thoughts (as I haven't looked at this for a good few days). I thought i'd just try to see how my ideas got on and it worked. I'm sure I tried something very similar before, must have just missed something out and it was failing. Rubber ducking as Larry calls it! Thanks Thomas for your help Link to comment Share on other sites More sharing options...
Recommended Posts