6

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

$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

4

8 回答 8

19

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

在您的模型中使用这样的方法

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

您可以像这样在控制器中使用它:

$this->Model->sendEmail($this);

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

于 2008-12-17T09:42:06.110 回答
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 函数。

于 2009-03-06T04:29:58.513 回答
7

CakePHP 2.0 有一个新的 CakeEmail 类,它可以在任何地方工作:

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

于 2012-01-25T20:26:59.623 回答
2

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

在您的控制器中使用

var $components = array('Email');

无需使用 App::import();

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

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

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

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

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

于 2008-11-24T00:44:50.027 回答
2

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

$this->Email->delivery = 'smtp';

$this->Email->template = $template;

$this->Email->sendAs = '文本';

$this->Email->from = $from;

$this->Email->to = $to;

$this->电子邮件->主题 = $主题;

$this->电子邮件->发送();

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

$this->Wrapper->sendEmail($from,$to,$subject,$template,$body);

于 2008-12-07T16:15:24.977 回答
2

我和你在一起,贾斯汀。

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

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

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

例如,一个 crontabbed 的 shell 脚本调用 Offer->expire() 来“过期”一个 Offer,然后调用 Offer->make() 来制作另一个 Offer,但如果它不能,那么它调用 Request->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

于 2009-04-05T18:23:39.907 回答
0

我有一个应用程序,我在其中将单行添加到模型(model1)。然后该模型触发进入另一个模型 (model2)。模型 1 有许多模型 2。我只想在 model2 插入成功时发送电子邮件。所以我希望model1每次成功插入model2时都会发送电子邮件。

在这一点上,重构系统架构的时间太长了。

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

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

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

于 2009-04-16T18:09:19.697 回答
0

查看一个名为 Eventful 的插件

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

于 2009-08-27T18:43:32.340 回答