Passing data to model functions from controllers

Up until now I have been doing all operations in the controller, but recently I’ve come to realise that I would be better off employing the “thin controller / fat model” approach, especially as I’ve been repeating blocks of code in my controllers.

So I’m going to attempt to re-jig my code. First off, I have an EnquiryController action, as follows:




public function actionSubmit()

{

	$model=new Enquiry;

	$user=new User;


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

	{

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

			

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

				

		if($user->validate() & $model->validate())

		{

			// create the user record

			$user->password=md5($user->password);

			$user->register_date=date('Y-m-d H:i:00');

			$user->type=2;

			$user->enabled=1;

			

			if($user->save(false))

			{

				// send a welcome email to the user

				$subject='Welcome to '.Yii::app()->name;

				$body=$this->render('//mail/userRegistration', array('user'=>$user), true);

				$headers="From: ".Yii::app()->params['adminEmailFromName']." <".Yii::app()->params['adminEmailFromAddress'].">\r\n";

				@mail($user->email, $subject, $body, $headers);

				

				// create the enquiry record

				$model->user_id=$user->id;

				$model->enquiry_date=date('Y-m-d H:i:s');

				$model->enquiry_ref=mt_rand(1000000000, 9999999999);

				

				if($model->save(false))

				{

					// send conf email to user

					$subject='Your Enquiry Ref: '.$model->enquiry_ref;

					$body=$this->render('//mail/quoteRequest', array('model'=>$model, 'user'=>$user), true);

					$headers="From: ".Yii::app()->params['adminEmailFromName']." <".Yii::app()->params['adminEmailFromAddress'].">\r\n";

					@mail($user->email, $subject, $body, $headers);

										

					Yii::app()->user->setFlash('confirm', 'Thank you, your enquiry has been sent.');

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

				}

			}

		}

	}

}



Now, there are 4 ‘operations’ defined in the code above:

  1. create the user record

  2. send a welcome email to the user

  3. create the enquiry record

  4. send conf email to user

My questions are:

  1. What model functions do I need to create, which operations need to go in them and what would the method signatures be?

  2. The last two lines of the code ( setFlash() and redirect() ) should stay in the controller. I assume I need to ensure that the model functions have executed without any errors before these two lines of code are run? (How?)

I think a controller is a right place for sending email (or you can create a method/component for this purpose).

But operations like these I always put into model’s beforeSave() method:




protected function beforeSave()

{

    if (parent::beforeSave())

    {

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

        $this->register_date=date('Y-m-d H:i:00');

        // next properties probably depend on the model's scenario.

        $this->type=2;

        $this->enabled=1;


        return true;

    }

}