問題描述
大家早上好,
我目前正在使用 CakePHP.
我想在 CakePHP 發送電子郵件后設置一個事件,因為我想將這封電子郵件的日志存儲在數據庫中,并為發件人、收件人、主題和正文提供單獨的列.
目前我正在使用本機日志系統(電子郵件的所有標題和正文都在同一位置),但是變得太混亂而無法調試.
CakeEmail 類不提供回調方法,而且我找不到任何方法在不編輯 CakeEmail 類的情況下調用這種事件.
當然,我可以創建一個 MyCakeEmail 類來擴展本地 CakeEmail 類,但這意味著更改代碼中的每個 new CakeEmail().
你有什么建議?
非常感謝!
(抱歉英語不好,不是我的母語)
使用自定義記錄器:
實現你自己的記錄器 使用您想要的數據庫功能,并在引導程序中為電子郵件范圍配置它,這是電子郵件日志的默認范圍,或者在電子郵件類的配置中更改整個日志記錄.查看電子郵件類的這一部分.
1161: $contents = $this->transportClass()->send($this);1162:如果(!空($this->_config['log'])){1163:$config = 數組(1164:級別"=>日志調試,1165:范圍"=>'電子郵件'第1166話1167: 如果 ($this->_config['log'] !== true) {1168:如果(!is_array($this->_config['log'])){1169: $this->_config['log'] = array('level' => $this->_config['log']);1170:}1171: $config = $this->_config['log'] + $config;1172:}1173:CakeLog::寫(1174: $config['level'],1175: PHP_EOL .$contents['headers'] .PHP_EOL .$contents['message'],1176: $config['scope']第1177話1178:}
使用您自己的課程 - 但要正確使用
<塊引用>當然,我可以創建一個 MyCakeEmail 類來擴展本地 CakeEmail 類,但這意味著更改代碼中的每個新 CakeEmail().
好吧,您可以使用自己的電子郵件課程.但是在任何情況下恕我直言,在代碼中的任何地方都執行 new SomeClass()
并不是一個好主意.你才知道為什么.不進行這種輕松測試的另一個原因.
而是在繼承鏈上層的某個類(AppController、AppModel...)中執行此操作:
public function getEmailInstance($config = null) {返回新的 MyEmailClass($config);}
這允許您簡單地全局"更改類并在測試中模擬該方法.
如果您使用的是 php 5.4(或 5.5,現在不確定),您也可以為此使用 trait,并且僅在需要該功能的類中使用它.
Good morning everybody,
I'm currently using 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.
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.
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.
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.
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. 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...):
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.
這篇關于CakePhp:蛋糕電子郵件 AfterSend 事件的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!