Ask your Symfony questions! Pay money and get answers fast! (more info)

Submitting forms without using the view Symfony

  • SOLVED

So, this requires a bit of back-knowledge of the way my app handles emails, then I will be on to my specific question.

I have an emailMessage in my schema, corresponding forms (doctrine generated and customized by me), and a module to handle CRUD and sending.

My application has 3 main ways emails are send:
1) A rep sends an email to an individual customer from the admin front-end with the emailMessage form
2) A rep sends a batch of emails to multiple customers from the admin front end
3) Some action a rep does (update a value, for instance), or a task called by cron, triggers an email to be sent

Now, in 3 of the above scenarios, templates are loaded and parsed (sometimes, a template is not loaded and a customer is sent a custom email, but that only happens in scenario 1). Once the email is loaded, it is *always* inserted into the database, and then emailed off.

Here is a snippet of how this works:

apps/myapp/modules/emailmsg/actions/actions.class.php

class emailmsgActions extends sfActions
{
protected function processForm(sfWebRequest $request, sfForm $form)
{
$form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));
if ($form->isValid())
{
$email_message = $form->save();
$this->executeSend($email_message);
$this->redirect($this->getRequest()->getReferer());
}
}

public function executeSend($email_message)
{
// blah blah code to send email
}


<em>Now, for the actual question I am looking to have answered...</em>
Now, for scenario 3, when I need to call it via a task or some backend action without using the standard access form from view and then post, how would I call the processForm action on the emailMessage?

I know I can set it up in an action to do something like

$this->emailForm = new EmailMessageForm(
new EmailMessage(),
array(
'subject'=>'hello',
'body_html'=>'here is your email'
));


But from there, I don't know how to post it / process it / and send it.

Answers (3)

2010-07-07

Arturo Linares answers:

I wouldn't use the form in tasks. I would better create manually the new EmailMessage and send it. I would refactor the send function in another class so you can access it in the task and in the actions.


webguy comments:

I wasn't really happy with my original idea either.

Would I be able to do something like...


$email_message = new EmailMessage(),
array(
'subject'=>'hello',
'body_html'=>'here is your email'
);
$email_message->save();


Would save() work to save it in the database just as if it were submitted via the form? It is crucial that these get saved to the database properly.

And then send it using something like,

$myMailer = new myMailer();
$myMailer->send($email_message);


Could you sketch out a brief bit of code to illustrate what you're saying if this isn't what you're talking about?


Arturo Linares comments:

Sure. A note: You won't have the form validators, so you have to update the object with clean data.


$email_message = new EmailMessage();
$email_message->setSubject('hello');
$email_message->setBodyHtml('here is your meial');

$email_message->save();


$myMailer = new myMailer();
$myMailer->send($email_message);

2010-07-07

Jakub Zalas answers:

The advantage of using forms in both your actions and task is that you'd have validation in one place (alternatively you could use doctrine validation).

What stops you from using form in a task? Try code below (i didn't test it):


class mailTask extends sfBaseTask
{
protected function configure()
{
// usual stuff
}

protected function execute($arguments = array(), $options = array())
{
$databaseManager = new sfDatabaseManager($this->configuration);
$connection = $databaseManager->getDatabase($options['connection'])->getDoctrineConnection();

$emailForm = new EmailMessageForm(new EmailMessage());
$data = array($emailForm->getName() => array(
'subject' => 'hello',
'body_html '=> 'here is your email'
));

$emailForm->bind($data);

if ($form->isValid())
{
$emailMessage = $form->save();
$this->sendMessage($emailMessage);
$this->log('E-mail sent');
}
else
{
$this->log('Could not send an e-mail');
}
}

protected function sendMessage(EmailMessage $emailMessage)
{
// send your mail
}
}


2010-07-08

JuG answers:

Hi,

Even in a task, there is a request ! Just use it to execute your action :


// in "yourTask::execute() "function :

// get the request for context
$request = sfContext::getInstance()->getRequest();

// configure it
$request->setParameter( 'your_form_name', array(
'foo' => 'bar',
'zip' => 123,
//... pass your form parameters here
));

$request->setMethod('post'); // or put ?

// Create your action
$action = new emailmsgActions;

// and execute it as the front web controller would do it in a "normal/web" navigation
$action->executeSend( $request );


Bye...