I'm using a Data Mapper / Gateway design pattern.
So I have a:
Mapper;
Gateway;
Domain Object (mainly with getters and setters);
A controller;
A view.
My question is: where should I instantiate the Zend Mail ?
I believe the view is obviously out of question, and the gateway is, as well, not to be considered.
The controller should be kept clean, so:
Mapper our Domain Object ?
If our form will have some select box that will retrieve data from the database, then, perhaps the Mapper will be the most appropriate place to instantiate Zend Mail ?
Thanks
Hmmmm? Well with Zend you can configure your Zend_Mail in your bootstrap or by using the application.ini file or some other config file. That's how I configure mine right now. For dev, I'll write the mails to a file and for testing I'll do mail over an actual mail server.
I instantiate my Zend_Mail instance in a class that I call Mail_Service. This mail service class will create a Zend_Mail instance internally when it needs to send a mail and will use an existing Zend_Mail instance if one has been created and more mails need to be sent.
It has methods that will send predefined mails for me. For example,
Mail_Service->sendWelcomeEmail( $userInfo )
OR
Mail_Service->sendActivationEmail( $userInfo )
Say for example my controller gets a request to create a new user, then the over all flow of my code will be like this
//in the controller
//process form from browser somehow
UserAccountService->createNewUser( $userInfo );
/////////////////
/// Within the user account service
public function createNewUser( $userInfo )
{
$userMapper->createNewUser( $userInfo );
$preferencesMapper->createDefaultPreferencesForUser( $userInfo );
MailService->sendWelcomeEmail( $userInfo );
}
I don't know if this is the best way to do it, but this way my service have function
names that are relevant to the service and capture a whole work flow instead of being atomic operations that just forward calls to other objects.
Hope this helps.
I always keep code that sends mail in my controllers.
Model - database/business logic
View - html / presentation layer
Controller - The code that does stuff.
Related
I would like to switch my application to a configuration where email isn't actually send, but instead saved to a log file.
This way I can test my application normally without being afraid of accidentally emailing to hundreds of users and without spamming myself.
I figured something with EmailTransports could be a solution. For instance, when using the DebugTransport the emails aren't send at all, the mail content is instead only returned by the ->send() function.
The downside of this transport is than I have to modify controller code in order to display the content, which I would like to avoid.
So is there a configuration such that email is stored to files instead of being sent, e.g.:
[root]
logs/
emails/
2019-10-01_15:32_email#example.com.txt
2019-10-01_16:54_another_recipient#example.com.txt
...
There is no such built-in configuration, no, but you can easily create your own custom transport that logs emails to files instead of sending them.
Here's a very basic example transport that extends the debug transport, and writes the data to a custom logging scope:
namespace App\Mailer\Transport;
use Cake\Log\LogTrait;
use Cake\Mailer\Email;
use Cake\Mailer\Transport\DebugTransport;
use Psr\Log\LogLevel;
class TestTransport extends DebugTransport
{
use LogTrait;
public function send(Email $email)
{
$data = parent::send($email);
$this->log(json_encode($data), LogLevel::DEBUG, ['scope' => ['emails']]);
return $data;
}
}
See also
Cookbook > Email > Using Transports > Creating Custom Transports
I'm making by a requirement a code able to send an E-mail to an specific list of E-mails, due the fact that I must to include the attachments of the record I decided to use an apex class instead an e-mail alert. This object (A custom object ) must populate some fields in an email template with some of the record´s fields. I implemented the following code
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddresses(lista);
mail.setTemplateId('00X21000000QR22');
//mail.setWhatId(idMinuta);
mail.setTargetObjectId('005d0000005NMIx');
mail.setSaveAsActivity(false);
List<Messaging.Emailfileattachment> fileAttachments = new List<Messaging.Emailfileattachment>();
for (ContentVersion document: documents)
{
Messaging.Emailfileattachment efa = new Messaging.Emailfileattachment();
efa.setFileName(document.Title);
efa.setBody(document.VersionData);
fileAttachments.add(efa);
}
mail.setFileAttachments(fileAttachments);
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
I understood that to make the fields merge it´s necesary to use the WhatId method. In the related code, I have commented it because It generates an error (INVALID_ID_FIELD, WhatId is not available for sending emails to UserIds.)
My question is, if is it possible to do this with a custom object. I´m a little confuse with salesforce documentation beacuse it looks like the method supports a custom object, or maybe If I am forggeting something to include in the code.
If i keep the WhatID line commented, effectively the email is sent with the attachments and the Template but it is not populated.
I really need this kind of solution because the org have in this object at least 20 email templates, for me will be easier just to pass the Id of the template instead of makig a code with 20 different html codes for each situation
Thanks a lot
Please publish this question at Salesforce StackExcahnge https://salesforce.stackexchange.com/
I'm new to magento and I'm trying to create a module for an email form.
In classic MVC I would send the request to the Controller, but in Magento a controller is only responsible for one URL. So when I want to put my email form on the productpage I cant use the controller, is that right?
I inlcude my block element via layout xml in the productpage. So I have to validate my form und send the email in the class of my block element? Or would I have to write one or more helpers for that?
What is the magento way?
Thanks a lot. Sorry if my question is lame, but I'm a beginner and I want to learn the right way and I have seen so much tutorials with the wrong one.
Just while submitting the form give action to controller like:
<?php echo Mage::getUrl()?>bpartner/index/mailbpartner
bpartner your module name
Index your controller name
mailbpartner your function in INDEX NAMED CONTROLLER FILE.
Get all details through POST and send mail like below + redirect with success
$to = "abc#abc.com";
$dt = date('d-m-Y');
$subject = "Become A Partner Details on date $dt";
$mail = new Zend_Mail('utf-8');
$mail->setBodyHtml($message)
->setFrom($data['email'], $data['firstname'])
->addTo($to, 'Site Admin')
->setSubject($subject);
try {
$mail->send();
Mage::getSingleton('core/session')->addSuccess('Mail sent successfully. We will contact you shortly');
}
catch(Exception $e) {
Mage::getSingleton('core/session')->addError('Unable to send email.');
}
$this->_redirect('bpartner');
Some above data are POST DATA which is self understandable
Can anyone give me a rough idea or link to instructions on how to create custom symfony swift mailer spool? I currently have the basic Doctrine spool which sends messages and deletes queue item.
I would like to do following:
Have a field with status (Sent, Unsent, Failed, Email does not exist, etc)
Update status field instead of deleting queue item on send
I've never done such functionality myself, but it seems like you can create your own spool class:
<?php
class Swift_MySpool extends Swift_DoctrineSpool {}
Have a field with status (Sent, Unsent, Failed, Email does not exist, etc)
The Swift_DoctrineSpool class supports an option called model, where you can pass a name of class to store your mail at. So, just creating your custom model will take effect.
Update status field instead of deleting queue item on send
Override queueMessage() and flushQueue() methods in your class and refer to Swift_DoctrineSpool at symfony API.
Hope this will help.
We built an app in Zend Framework (v1) and have not worked a lot in setting up error reporting and logging. Is there any way we could get some level or error reporting without too much change in the code? Is there a ErrorHandler plugin available?
The basic requirement is to log errors that happens within the controller, missing controllers, malformed URLs, etc.
I also want to be able to log errors within my controllers. Will using error controller here, help me identify and log errors within my controllers? How best to do this with minimal changes?
I would use Zend_Log and use the following strategy.
If you are using Zend_Application in your app, there is a resource for logging. You can read more about the resource here
My advice would be to choose between writing to a db or log file stream. Write your log to a db if you plan on having some sort of web interface to it, if not a flat file will do just fine.
You can setup the logging to a file with this simple example
resources.log.stream.writerName = "Stream"
resources.log.stream.writerParams.stream = APPLICATION_PATH "/../data/logs/application.log"
resources.log.stream.writerParams.mode = "a"
resources.log.stream.filterName = "Priority"
resources.log.stream.filterParams.priority = 4
Also, I would suggest sending Critical errors to an email account that is checked regularly by your development team. The company I work for sends them to errors#companyname.com and that forwards to all of the developers from production sites.
From what I understand, you can't setup a Mail writer via a factory, so the resource won't do you any good, but you can probably set it up in your ErrorController or Bootstrap.
$mail = new Zend_Mail();
$mail->setFrom('errors#example.org')
->addTo('project_developers#example.org');
$writer = new Zend_Log_Writer_Mail($mail);
// Set subject text for use; summary of number of errors is appended to the
// subject line before sending the message.
$writer->setSubjectPrependText('Errors with script foo.php');
// Only email warning level entries and higher.
$writer->addFilter(Zend_Log::WARN);
$log = new Zend_Log();
$log->addWriter($writer);
// Something bad happened!
$log->error('unable to connect to database');
// On writer shutdown, Zend_Mail::send() is triggered to send an email with
// all log entries at or above the Zend_Log filter level.
You will need to do a little work to the above example but the optimal solution would be to grab the log resource in your bootstrap file, and add the email writer to it, instead of creating a second log instance.
You can use Zend_Controller_Plugin_ErrorHandler . As you can see on the documentation page there is an example that checks for missing controller/action and shows you how to set the appropriate headers.
You can then use Zend_Log to log your error messages to disk/db/mail.