简体   繁体   English

CakePhp:Cake Email AfterSend事件

[英]CakePhp: Cake Email AfterSend event

Good morning everybody, 大家早上好,

I'm currently using CakePHP. 我目前正在使用CakePHP。
I would like to setup an event after an email is sent by CakePHP, because I would like to store a log of this email in database with separate columns for the sender, the receiver, the subject and the body. 我希望在CakePHP发送电子邮件后设置一个事件,因为我想在数据库中存储此电子邮件的日志,其中包含发件人,接收者,主题和正文的单独列。
Currently I'm using the native log system (all headers and body of the email in the same place), but is becoming too messy to debug. 目前我正在使用本机日志系统(电子邮件的所有标题和正文在同一个地方),但是调试变得太乱了。

The CakeEmail class doesn't offer callback methods, and I don't find any way to call this kind of event without editing the CakeEmail class. CakeEmail类不提供回调方法,我没有找到任何方法来调用这种事件而不编辑CakeEmail类。
Of course I can create a MyCakeEmail class that extends the native CakeEmail class, but this means changing every new CakeEmail() yet in the code. 当然,我可以创建扩展本地CakeEmail类MyCakeEmail类,但这意味着要改变每一个新CakeEmail(),但在代码中。

What do you suggest? 你有什么建议?
Thank a lot! 非常感谢!

(Sorry for bad english, not my mother tongue) (抱歉英文不好,不是我的母语)

Use a custom logger: 使用自定义记录器:

Implement your own logger with the DB features you want and configure it in bootstrap for the email scope which is the default scope for email logs or change the whole logging in the config of the email class. 使用您想要的数据库功能实现您自己的记录器 ,并在引导程序中为电子邮件范围配置它,这是电子邮件日志的默认范围或更改电子邮件类配置中的整个日志记录。 See this part of the email class. 请参阅电子邮件类的这一部分。

1161:         $contents = $this->transportClass()->send($this);
1162:         if (!empty($this->_config['log'])) {
1163:             $config = array(
1164:                 'level' => LOG_DEBUG,
1165:                 'scope' => 'email'
1166:             );
1167:             if ($this->_config['log'] !== true) {
1168:                 if (!is_array($this->_config['log'])) {
1169:                     $this->_config['log'] = array('level' => $this->_config['log']);
1170:                 }
1171:                 $config = $this->_config['log'] + $config;
1172:             }
1173:             CakeLog::write(
1174:                 $config['level'],
1175:                 PHP_EOL . $contents['headers'] . PHP_EOL . $contents['message'],
1176:                 $config['scope']
1177:             );
1178:         }

Use your own class - but do it right 使用你自己的课 - 但做得对

Of course I can create a MyCakeEmail class that extends the native CakeEmail class, but this means changing every new CakeEmail() yet in the code. 当然我可以创建一个扩展本地CakeEmail类的MyCakeEmail类,但这意味着在代码中更改每个新的CakeEmail()。

Well you can use your own email class. 那么你可以使用自己的电子邮件类。 But doing new SomeClass() everywhere in the code isn't a good hing in any case IMHO. 但是在代码中到处都是new SomeClass()在任何情况下都不是好事。 You just figured out why. 你只知道原因。 Another reason to not do this ease of testing. 另一个不容易测试的原因。

Instead do this in some class in the upper level of the inheritage chain (AppController, AppModel...): 而是在继承链的上层(AppController,AppModel ...)的某些类中执行此操作:

public function getEmailInstance($config = null) {
    return new MyEmailClass($config);
}

This allows you to simply change the class "globally" and to mock the method in tests as well. 这允许您简单地“全局”更改类,并在测试中模拟方法。

If you're using php 5.4 (or 5.5, not sure right now) you can use a trait for that as well and use it only in classes that need that functionality. 如果您使用的是PHP 5.4(或5.5,现在还不确定),您也可以使用它的特性,并仅在需要该功能的类中使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM