如何使用CakePHP中的模型中的电子邮件组件?

时间:2008-11-23 19:29:43

标签: php cakephp

我有一个非常简单的模型。我想在模型的方法上添加一个发送电子邮件例程:

$this->Email->delivery = 'smtp';
$this->Email->template = 'default';
$this->Email->sendAs = 'text';     
$this->Email->from    = 'email';
$this->Email->to      = 'email';
$this->Email->subject = 'Error';

我试过把

App::import('Component', 'Email');
在顶部,无济于事。我得到的错误是:

  

致命错误:在第23行的E:\ xampp \ htdocs8080 \ app \ models \ debug.php中调用未定义的方法stdClass :: send()

有什么想法吗?

我正在运行CakePHP 1.2

8 个答案:

答案 0 :(得分:19)

即使这不是最佳实践,您实际上可以在模型中使用EmailComponent,但您需要实例化它(在模型中没有自动组件加载)并且您需要将其传递给控制器​​。 EmailComponent依赖于Controller,因为它需要与视图连接,用于呈现电子邮件模板和布局。

在模型中使用这样的方法

function sendEmail(&$controller) {
    App::import('Component', 'Email');
    $email = new EmailComponent();
    $email->startup($controller);
}

您可以在控制器中使用它,如下所示:

$这 - >模型 - > sendEmail($此);

(如果您使用的是PHP5,请省略方法签名中的&

答案 1 :(得分:10)

嗯,你这样做错了。您应该在AppController中放置电子邮件发送例程:

function _sendMail($to,$subject,$template) {
    $this->Email->to = $to;
    // $this->Email->bcc = array('secret@example.com'); // copies
    $this->Email->subject = $subject;
    $this->Email->replyTo = 'noreply@domain.com';
    $this->Email->from = 'MyName <noreply@domain.com>';
    $this->Email->template = $template;
    $this->Email->sendAs = 'text'; //Send as 'html', 'text' or 'both' (default is 'text')
    $this->Email->send();
}

然后从任何控制器中使用它,如下所示:

$this->_sendMail($this->data['User']['email'],'Thanks for registering!','register');

不要忘记放置

var $components = array('Email');

在控制器中,您正在使用_sendMail函数。

答案 2 :(得分:7)

CakePHP 2.0拥有可在任何地方使用的新CakeEmail类:

http://book.cakephp.org/2.0/en/core-utility-libraries/email.html

答案 3 :(得分:2)

组件应该用于控制器,而不是模型。

在您的控制器中使用

var $components = array('Email');

无需使用App :: import();

在不知道您的应用程序以及想要在模型中使用它的原因的情况下,我可能会建议您重新考虑您的系统架构并将此逻辑移至您的控制器。

如果您在模式中确实需要它,您的代码包括类似......

$this->Email->delivery = ...

您是否已创建组件的新实例并将其设置为名为Email的模型属性? (不知道这是否会起作用。)

您得到的错误是因为您在stdClass对象上调用send()方法,即不是EmailComponent的实例。

答案 4 :(得分:2)

好的,在模型中使用组件并不好。我的问题是我不想在我的控制器中写一百万次电子邮件块:

  

$ this-&gt;电子邮件 - &gt; delivery ='smtp';

     

$ this-&gt;电子邮件 - &gt;模板= $模板;

     

$ this-&gt;电子邮件 - &gt; sendAs ='text';

     

$ this-&gt; Email-&gt; from = $ from;

     

$ this-&gt; Email-&gt; to = $ to;

     

$ this-&gt;电子邮件 - &gt; subject = $ subject;

     

$这 - &GT;的电子邮件 - &gt;置于();

如果我在控制器中使用这5次,几乎不会干。所以我创建了一个名为Wrapper的组件,并添加了一个sendEmail例程,所以我可以写:

  

$这 - &GT; Wrapper-&GT; sendEmail($从,$到,$主题,$模板,$体);

答案 5 :(得分:2)

我和你在一起贾斯汀。

我有一系列模型可以根据某些操作触发电子邮件,这些操作可能来自用户,管理员和shell脚本,用于自动化流程。

在模型中集中电子邮件响应(比如订单记录被“取消”)比在多个位置重写电子邮件更容易。

此外,我在模型中有自动化流程,处理一些核心“逻辑”,这些逻辑与其他hasOne,belongsTo或hasMany模型是级联规则。

例如,一个crontabbed shell脚本调用Offer-&gt; expire()来“过期”商品,然后调用Offer-&gt; make()来制作另一个商品,但如果不能,则调用Request- &gt; expire()使原始请求“过期”。必须将电子邮件发送给第一个过期的要约收件人,任何新的要约收件人和/或请求者(如果过期)。这些可以由crontabbed shell或用户或可以手动管理请求和提供的管理员调用。全部使用不同的控制器或接口。

这就是我所做的,可以在模型和控制器中调用它:

if(empty($this->MailsController)) {
    App::import('Controller','Mails');
    $this->MailsController = new MailsController();
    $this->MailsController->constructClasses();
    $this->MailsController->Email->startup($this->MailsController);
}

现在我可以从几乎任何地方调用它,并集中所有逻辑,以查找要查找的数据(),生成什么电子邮件,将其发送给谁,等等,通过以下模型内部调用:

$this->MailsController->orderMail($user_id,$this->id,$mode);

由于所有的电子邮件逻辑基本上是通过MailsController由模型调用的,所以我将尝试给rscherer的代码。

希望这有帮助, oh4real

答案 6 :(得分:0)

我有一个应用程序,我向模型(model1)添加一行。然后该模型将条目触发到另一个模型(model2)。 model1 hasmany model2。我想只在成功插入model2时发送电子邮件。因此,我希望每次将model1成功插入到model2中时都会发送模型。

此时重构系统架构的时间过长。

我的解决方案?当我执行Model1-&gt; addRecord时,它会执行model2-> addRecord()。我有model1跟踪model2-> addRecord的每个失败或成功。从model1-&gt; addRecord然后我将一个成功/失败数组返回给调用控制器(model1_controller)。然后我会让model1_controller发出电子邮件。

因此可以正确地执行此操作,而无需完全重写架构。只需将Model1中的更多信息返回给控制器,然后让控制器(正确)发送电子邮件。

对于有些不清楚的帖子感到抱歉。我的大脑现在处于代码模式。

答案 7 :(得分:0)

查看名为Eventful

的插件

它将允许您广播和收听自定义事件。对于我下面的海报:你可以播放Model1Saved事件,在model2中监听它,然后执行第二次保存,然后将成功事件广播回到model1,甚至是控制器。从那里你可以发送你的电子邮件。