Как использовать компонент электронной почты из модели в CakePHP? - PullRequest
6 голосов
/ 23 ноября 2008

У меня очень простая модель. Я хочу добавить подпрограмму отправки электронной почты в один из методов для модели:

$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');

вверху, безрезультатно. Я получаю ошибку:

Неустранимая ошибка: вызов неопределенного метода stdClass :: send () в E: \ xampp \ htdocs8080 \ app \ models \ debug.php в строке 23

Есть идеи?

Я использую CakePHP 1.2

Ответы [ 8 ]

19 голосов
/ 17 декабря 2008

, даже если это не лучшая практика, вы на самом деле можете использовать EmailComponent в модели, но вам нужно создать его экземпляр (в моделях нет автоматической загрузки компонентов), и вам нужно передать ему контроллер. EmailComponent полагается на контроллер из-за соединения, которое ему нужно для представления, для рендеринга шаблонов и макетов электронной почты.

С помощью такого метода в вашей модели

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

Вы можете использовать его в вашем контроллере следующим образом:

$ this-> Модель-> SendEmail ($ это);

(не указывайте & в сигнатуре метода, если вы используете PHP5)

10 голосов
/ 06 марта 2009

Ну, вы делаете это неправильно. Вы должны поместить процедуру отправки электронной почты в свой 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.

7 голосов
/ 26 января 2012

CakePHP 2.0 имеет новый класс CakeEmail, который работает где угодно:

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

2 голосов
/ 05 апреля 2009

Я с тобой Джастин.

У меня есть серия моделей, которые запускают электронные письма на основе определенных действий, которые могут исходить от пользователей, администраторов и сценариев оболочки для автоматизированных процессов.

Гораздо проще централизовать ответ по электронной почте в модели (например, когда запись заказа «отменена»), чем переписать письмо в нескольких местах.

Кроме того, у меня есть автоматизированные процессы в моделях, которые обрабатывают некоторую базовую «логику», каскадную с другими моделями hasOne, ownTo или hasMany, которые являются бизнес-правилами.

Например, сценарий оболочки crontabbed вызывает Offer-> expire () для «истечения срока действия» предложения, которое затем вызывает Offer-> make () для создания другого предложения, но если это невозможно, он вызывает Request-> expire () для истечения срока действия исходного запроса. Электронные письма должны отправляться первому получателю предложения с истекшим сроком действия, любым новым получателям предложения и / или запрашивающей стороне, если срок ее действия истекает. Они могут быть вызваны оболочкой crontabbed, пользователями или администраторами, которые могут управлять запросами и предложениями вручную. Все с использованием разных контроллеров или интерфейсов.

Это то, что я сделал и могу назвать в моделях и контроллерах:

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

2 голосов
/ 07 декабря 2008

ОК, правда, не рекомендуется использовать компоненты в моделях. Моя проблема была в том, что я не хотел миллион раз писать блок электронной почты в моих контроллерах:

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

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

$ this-> Email-> sendAs = 'text';

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

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

$ this-> Email-> subject = $ subject;

$ this-> email-> отправить ();

Вряд ли СУХО, если я использую это 5 раз в контроллере. Поэтому я создал компонент под названием Wrapper и добавил подпрограмму sendEmail, поэтому я могу просто написать:

$ this-> Wrapper-> SendEmail ($ от, $ к, $ вопросу, $ шаблон, $ тела);

2 голосов
/ 24 ноября 2008

Компоненты должны использоваться в контроллерах, а не в моделях.

В вашем контроллере используйте

var $components = array('Email');

Нет необходимости использовать App :: import ();

Не зная вашего приложения и причин, по которым вы хотите использовать его в модели, я мог бы предложить вам переосмыслить архитектуру вашей системы и перенести эту логику на контроллер.

Если вам определенно нужно это в вашем режиме, ваш код включает что-то вроде ...

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

Вы поместили созданный новый экземпляр компонента и задали для него свойство вашей модели с именем Email? (Понятия не имею, будет ли это работать умом.)

Ошибка, которую вы получаете, заключается в том, что вы вызываете метод send () для объекта stdClass, то есть не для экземпляра EmailComponent.

0 голосов
/ 27 августа 2009

Посмотрите на плагин под названием Eventful

Это позволит вам транслировать и прослушивать пользовательские события. Для плаката ниже меня: вы можете передать событие Model1Saved, прослушать его в model2, затем выполнить второе сохранение, и они передадут событие успеха обратно модели1 или даже контроллеру. Оттуда вы можете отправить свою электронную почту.

0 голосов
/ 16 апреля 2009

У меня есть приложение, в котором я добавляю одну строку в модель (model1). Затем эта модель запускает записи в другую модель (model2). модель1 имеет много модель2. Я хотел только отправлять электронные письма, если model2 вставляет успешно. Поэтому я хотел, чтобы model1 отправлял электронные письма каждый раз, когда он успешно вставляется в model2.

На этом этапе перестройка архитектуры системы занимает слишком много времени.

Мое решение? Когда я делаю Model1-> addRecord, он делает model2-> addRecord (). У меня есть model1 отслеживать каждый сбой или успех из model2-> addRecord. Из model1-> addRecord я затем возвращаю массив успеха / неудачи вызывающему контроллеру (model1_controller). Оттуда я получу, что model1_controller выдаст электронные письма.

Так что это можно сделать правильно, не переписывая архитектуру полностью. Просто верните больше информации от Model1 к контроллеру, затем попросите контроллер (правильно) отправить электронные письма.

Извините за несколько непонятный пост. Мой мозг сейчас в кодовом режиме.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...