/** * Set the body of this entity, either as a string, or array of view * variables if a view is set, or as an instance of * {@link Swift_OutputByteStream}. * * @param mixed the body of the message. If a $this->view is set and this * is a string, this is passed to the view as $body. If $this->view is set * and this is an array, the array values are passed to the view like in the * controller render() method * @param string content type optional. For html, set to 'html/text' * @param string charset optional */ public function setBody($body = '', $contentType = null, $charset = null) { if ($this->view !== null) { if (!is_array($body)) { $body = array('body' => $body); } // if Yii::app()->controller doesn't exist create a dummy // controller to render the view (needed in the console app) if (isset(Yii::app()->controller)) { $controller = Yii::app()->controller; } else { $controller = new Controller('YiiMail'); } // File Path to Template $viewPath = ""; // Name of current theme if enabled $themeName = ""; if (Yii::app() instanceof CConsoleApplication) { if (Yii::app()->theme && Yii::app()->theme != "") { $themeName = Yii::app()->theme; } } else { // WebApplication if (($theme = Yii::app()->getTheme()) !== null) { $themeName = $theme->getName(); } } // When ThemeName is speified if ($themeName != "") { $viewThemed = str_replace('application.views.', 'webroot.themes.' . $themeName . '.views.', $this->view); $viewThemed = preg_replace('/application\\.modules(?:_core)?\\.(.*?)\\.views\\.(.*)/i', 'webroot.themes.' . $themeName . '.views.\\1.\\2', $viewThemed); if (file_exists(Yii::getPathOfAlias($viewThemed) . ".php")) { $viewPath = Yii::getPathOfAlias($viewThemed) . ".php"; } } // Use orginal view name, if not set yet if ($viewPath == "") { $viewPath = Yii::getPathOfAlias($this->view) . ".php"; } $body = $controller->renderInternal($viewPath, array_merge($body, array('mail' => $this)), true); } return $this->message->setBody($body, $contentType, $charset); }
/** * Generates Mail Output for this notification * * @return type */ public function getMailOut() { $controller = new Controller('MailX'); $viewPath = Yii::getPathOfAlias($this->mailView) . '.php'; if ($viewPath == ".php") { return "not found: " . $this->mailView; } return $controller->renderInternal($viewPath, array('notification' => $this, 'sourceObject' => $this->getSourceObject(), 'targetObject' => $this->getTargetObject(), 'creator' => $this->getCreator()), true); }
public function send($Campaign) { //exit(); $configs = Yii::app()->db->createCommand("SELECT * FROM `config` WHERE `key` IN ('host', 'https')")->queryAll(); if (sizeof($configs) < 2) { throw new CException("\n\n\n===\nDomain or HTTPS config not yet set. View any admin area page in a browser to remedy this.\n===\n\n"); } foreach ($configs as $config) { $params[$config['key']] = $config['value']; } // Load contacts for this invite from the invite table // They'll be marked with this campaign ID, and status=0 - unsent $Invite = Invite::model(); $transaction = $Invite->dbConnection->beginTransaction(); try { $InviteRows = $Invite->with("store")->findAll(array("condition" => "campaign_id = :campaign_id AND processing = 0 AND status = :status", "params" => array(":campaign_id" => $Campaign->id, ":status" => Invite::STATUS_UNSENT))); $inviteIDs = []; foreach ($InviteRows as $Invite) { $inviteIDs[] = $Invite->id; } $command = Yii::app()->db->createCommand(); $command->update('invite', array("processing" => 1), array('in', 'id', $inviteIDs)); $transaction->commit(); } catch (Exception $e) { $transaction->rollback(); throw $e; } set_time_limit(0); // Load all organisations, we'll need their info $Organisations = Organisation::model()->findAll(array('condition' => 'id IN (1,2,3,4,5,6,7,8,9)', 'index' => 'id')); // Group by organisation $orgContacts = array(); foreach ($InviteRows as $Invite) { $orgContacts[$Invite->organisation_id][] = $Invite; } // Chunk these into arrays of up to 1000 contacts per organisation - this is the Mailgun limit $chunkedOrgContacts = array(); foreach ($orgContacts as $orgID => $contactArray) { $chunkedOrgContacts[$orgID] = array_chunk($orgContacts[$orgID], 1000); } // Parse the email content, replace tags with the Mailgun recipient params $parsedContent = $this->parseEmailContent($Campaign->invite_email_subject, $Campaign->invite_email_body, array('first_name' => '%recipient.first_name%', 'last_name' => '%recipient.last_name%', 'invite_url' => '%recipient.invite_url%', 'unsubscribe_url' => '%recipient.unsubscribe_url%')); // Debug / counter vars $sentCount = 0; $campaignSuccess = false; $toEmails = []; Yii::import('application.extensions.*'); foreach ($chunkedOrgContacts as $orgID => $orgChunks) { // Only set real email info if we're on production server // Let's not send emails to everyone in Newcastle before we're live... if (ENVIRONMENT === 'PRODUCTION' || ENVIRONMENT === 'PHOENIX') { // Get the correct email domain for the organisation in question $fromEmailDomain = $Organisations[$orgID]->email_domain; $fromEmailAddress = $Organisations[$orgID]->email_address; $fromEmailName = $Organisations[$orgID]->title; } else { $fromEmailDomain = Yii::app()->params['insiderEmailDomain']; $fromEmailAddress = 'email@' . $fromEmailDomain; $fromEmailName = $Organisations[$orgID]->title; } $mailgunApi = new MailgunApi($fromEmailDomain, Yii::app()->params['mailgun']['key']); $message = $mailgunApi->newMessage(); $message->setFrom($fromEmailAddress, $fromEmailName); $message->setSubject($parsedContent['subject']); $message->addTag('Invite'); // Tag with invite so it can be filtered in Mailgun admin if (ENVIRONMENT !== 'PRODUCTION') { $message->addTag('Test'); } /* TEST MODE */ //$message->enableTestMode(); // Now loop the contacts, which are in chunks (arrays) of up to 1000 foreach ($orgChunks as $upTo1000Invites) { //start transaction? try { $transaction = $Invite->dbConnection->beginTransaction(); $invite1000IDs = []; //reset the to fields $message->resetTo(); // Add all the contacts in this chunk, there could be up to 1000 of 'em foreach ($upTo1000Invites as $Invite) { $invite1000IDs[] = $Invite->id; if (strlen($Invite->store->email)) { $Store2Contact = Store2Contact::model()->findByPk($Invite->store2contact_id); if (!is_null($Store2Contact)) { // Check values match if ($Store2Contact->contact_warehouse_id === $Invite->contact_warehouse_id && $Store2Contact->store_id === $Invite->store_id) { // Also save the date they were invited to Store2Contact so we can query it easily $Store2Contact->most_recent_invite_date = date('Y-m-d H:i:s'); $Store2Contact->save(true, array('most_recent_invite_date')); unset($Store2Contact); // Now create the invitation link to pass into the email template $inviteURL = ($params['https'] === 1 ? 'https://' : 'http://') . $params['host'] . '/accession/invite/' . $Invite->hash; // Only set real email info if we're on production server // Let's not send emails to everyone in Newcastle before we're live... if (ENVIRONMENT === 'PRODUCTION') { $toEmail = $Invite->store->email; } else { $toEmail = '*****@*****.**'; } $unsubscribeUrl = $Invite->unsubscribeUrl; // Check first name $firstName = $Invite->store->first_name; if (!strlen(trim($firstName))) { $firstName = 'friend'; } // Add the recipient to the message object, including the params unique for them $message->addTo($toEmail, $Invite->store->first_name . ' ' . $Invite->store->last_name, array('first_name' => $firstName, 'last_name' => $Invite->store->last_name, 'invite_url' => $inviteURL, 'unsubscribe_url' => $unsubscribeUrl)); //$toEmails[] = 'Email: ' . $toEmail . " - " . $contact['first_name'] . ' ' . $lastName . '('.$fromEmailName.')' . "\n\n"; // Increment the counter $sentCount++; } else { $contactInfo = print_r($contact, true); mail('*****@*****.**', 'Invite attempted but store2contact row did not match contact found in query', $contactInfo); } } else { $contactInfo = print_r($contact, true); mail('*****@*****.**', 'Invite attempted but store2contact could not be found', $contactInfo); } } else { $contactInfo = print_r($contact, true); mail('*****@*****.**', 'Invite attempted with no email address', $contactInfo); } } // foreach upTo1000Invites } catch (Exception $e) { $transaction->rollback(); $campaignSuccess = false; } // Now we have the data for our 1000 contacts set up, render the template for the organisation $Controller = new Controller('foo'); $renderedView = $Controller->renderInternal(Yii::app()->basePath . '/views/mail/organisation-templates/' . $Organisations[$orgID]->email_template . ".php", array('body' => $parsedContent['body']), true); $message->setHtml($renderedView); // SEND THE MESSAGE if (sizeof($message->getTo())) { try { $response = $message->send(); $command = Yii::app()->db->createCommand(); $command->update('invite', array("status" => Invite::STATUS_SENT, "processing" => 0), array('in', 'id', $invite1000IDs)); $transaction->commit(); $campaignSuccess = true; } catch (Exception $e) { print $e->getMessage(); // mailgun returned an error - we rollback the transaction and remove the number of failed ids from the sent count // consider mainatining a fail count?? $sentCount -= count($invite1000IDs); $command = Yii::app()->db->createCommand(); $command->update('invite', array("status" => Invite::STATUS_MAILGUN_ERROR, "processing" => 0), array('in', 'id', $invite1000IDs)); $transaction->commit(); $msg = print_r($e, true); $msg .= print_r($message, true); mail('*****@*****.**', 'Mailgun error', $msg); } } } // end of org 1000 chunk } // foreach organisations if ($campaignSuccess) { $Campaign->status = Campaign::STATUS_HAS_BEEN_RUN; } else { $Campaign->status = Campaign::STATUS_ERROR_SEND; } $Campaign->save(true, array("status")); }
/** * Returns Mail Output for that activity * * @return type */ public function getMailOut() { $controller = new Controller('MailX'); // Determine View $view = 'application.modules_core.activity.views.activities.' . $this->type . "_mail"; if ($this->module != "") { $view = 'application.modules_core.' . $this->module . '.views.activities.' . $this->type . "_mail"; $viewPath = Yii::getPathOfAlias($view) . '.php'; // Seems not exists, try 3rd party module folder if (!file_exists($viewPath)) { $view = 'application.modules.' . $this->module . '.views.activities.' . $this->type . "_mail"; } } $viewPath = Yii::getPathOfAlias($view) . '.php'; $underlyingObject = $this->getUnderlyingObject(); $workspace = null; if ($this->content->space_id != "") { $workspace = Space::model()->findByPk($this->content->space_id); } $user = $this->content->user; if ($user == null) { return; } return $controller->renderInternal($viewPath, array('activity' => $this, 'wallEntryId' => 0, 'user' => $user, 'target' => $underlyingObject, 'workspace' => $workspace), true); }