示例#1
0
 /**
  *
  * @param Account $account
  * @param \GO\Base\Mail\EmailRecipients $recipients
  * @return \GO\Email\Model\Alias|false 
  */
 private function _findAliasFromRecipients($account, \GO\Base\Mail\EmailRecipients $recipients, $alias_id = 0, $allAvailableAliases = false)
 {
     $alias = false;
     $defaultAlias = false;
     $findParams = \GO\Base\Db\FindParams::newInstance()->select('t.*')->joinModel(array('model' => 'GO\\Email\\Model\\AccountSort', 'foreignField' => 'account_id', 'localField' => 'account_id', 'type' => 'LEFT'))->permissionLevel(Acl::CREATE_PERMISSION)->ignoreAdminGroup()->order('order', 'DESC');
     //find the right sender alias
     $stmt = !$allAvailableAliases && $account && $account->checkPermissionLevel(Acl::CREATE_PERMISSION) ? $account->aliases : \GO\Email\Model\Alias::model()->find($findParams);
     while ($possibleAlias = $stmt->fetch()) {
         if (!$defaultAlias) {
             $defaultAlias = $possibleAlias;
         }
         if ($recipients->hasRecipient($possibleAlias->email)) {
             $alias = $possibleAlias;
             break;
         }
     }
     if (!$alias) {
         $alias = empty($alias_id) ? $defaultAlias : \GO\Email\Model\Alias::model()->findByPk($alias_id);
     }
     return $alias;
 }
示例#2
0
 protected function actionBatchSend($params)
 {
     $this->requireCli();
     $this->_sentEmails = array();
     \GO::$disableModelCache = true;
     $mailing = \GO\Addressbook\Model\SentMailing::model()->findByPk($params['mailing_id']);
     if (!$mailing) {
         throw new \Exception("Mailing not found!\n");
     }
     \GO::session()->runAs($mailing->user_id);
     echo 'Status: ' . $mailing->status . "\n";
     if (empty($mailing->status)) {
         echo "Starting mailing at " . \GO\Base\Util\Date::get_timestamp(time()) . "\n";
         $mailing->reset();
     } elseif (!empty($params['restart'])) {
         echo "Restarting mailing at " . \GO\Base\Util\Date::get_timestamp(time()) . "\n";
         $mailing->reset();
     } elseif ($mailing->status == \GO\Addressbook\Model\SentMailing::STATUS_PAUSED) {
         echo "Resuming mailing at " . \GO\Base\Util\Date::get_timestamp(time()) . "\n";
         $mailing->status = \GO\Addressbook\Model\SentMailing::STATUS_RUNNING;
         $mailing->save();
     }
     $htmlToText = new \GO\Base\Util\Html2Text();
     //$addresslist = \GO\Addressbook\Model\Addresslist::model()->findByPk($mailing->addresslist_id);
     $mimeData = file_get_contents(\GO::config()->file_storage_path . $mailing->message_path);
     $message = \GO\Base\Mail\Message::newInstance()->loadMimeMessage($mimeData);
     $joinCriteria = \GO\Base\Db\FindCriteria::newInstance()->addRawCondition('t.id', 'a.account_id');
     $findParams = \GO\Base\Db\FindParams::newInstance()->single()->join(\GO\Email\Model\Alias::model()->tableName(), $joinCriteria, 'a')->criteria(\GO\Base\Db\FindCriteria::newInstance()->addCondition('id', $mailing->alias_id, '=', 'a'));
     if ($mailing->campaign_id > 0 && \GO::modules()->isAvailable('campaigns')) {
         $account = new \GO\Email\Model\Account();
         $account->username = \GO::config()->campaigns_imap_user;
         $account->password = \GO::config()->campaigns_imap_pass;
         $account->host = \GO::config()->campaigns_imap_server;
         $account->port = \GO::config()->campaigns_imap_port;
         $account->smtp_username = \GO::config()->campaigns_smtp_user;
         $account->smtp_password = \GO::config()->campaigns_smtp_pass;
         $account->smtp_host = \GO::config()->campaigns_smtp_server;
         $account->smtp_port = \GO::config()->campaigns_smtp_port;
         $message->setFrom(\GO::config()->campaigns_from);
     } else {
         $account = \GO\Email\Model\Account::model()->find($findParams);
         if (!$account->store_password && !empty($mailing->temp_pass)) {
             $account->smtp_password = $mailing->temp_pass;
         }
     }
     $mailer = \GO\Base\Mail\Mailer::newGoInstance(\GO\Email\Transport::newGoInstance($account));
     echo "Will send emails from " . $account->username . ".\n";
     if (empty(\GO::config()->mailing_messages_per_minute)) {
         \GO::config()->mailing_messages_per_minute = 30;
     }
     //Rate limit to 100 emails per-minute
     $mailer->registerPlugin(new \Swift_Plugins_ThrottlerPlugin(\GO::config()->mailing_messages_per_minute, \Swift_Plugins_ThrottlerPlugin::MESSAGES_PER_MINUTE));
     // Use AntiFlood to re-connect after 50 emails
     $mailer->registerPlugin(new \Swift_Plugins_AntiFloodPlugin(\GO::config()->mailing_messages_per_minute));
     echo 'Sending a maximum of ' . \GO::config()->mailing_messages_per_minute . ' messages per minute' . "\n";
     $failedRecipients = array();
     $bodyWithTags = $message->getBody();
     foreach ($mailing->contacts as $contact) {
         $sentMailingContactModel = \GO\Addressbook\Model\SentMailingContact::model()->findSingleByAttributes(array('sent_mailing_id' => $mailing->id, 'contact_id' => $contact->id));
         if (!$sentMailingContactModel->sent) {
             $errors = 1;
             $unsubscribeHref = \GO::url('addressbook/sentMailing/unsubscribe', array('addresslist_id' => $mailing->addresslist_id, 'contact_id' => $contact->id, 'token' => md5($contact->ctime . $contact->addressbook_id . $contact->firstEmail)), false, true);
             $body = str_replace('%unsubscribe_href%', $unsubscribeHref, $bodyWithTags);
             //curly brackets don't work inside links in browser wysiwyg editors.
             $templateModel = \GO\Addressbook\Model\Template::model();
             $templateModel->htmlSpecialChars = false;
             $body = $templateModel->replaceCustomTags($body, array('unsubscribe_link' => '<a href="' . $unsubscribeHref . '" target="_blank">' . \GO::t("unsubscription", "addressbook") . '</a>'), true);
             $templateModel->htmlSpecialChars = true;
             try {
                 if (!$contact->email_allowed) {
                     echo "Skipping contact " . $contact->firstEmail . " because newsletter sending is disabled in the addresslists tab.\n\n";
                 } elseif (empty($contact->firstEmail)) {
                     echo "Skipping contact " . $contact->name . " no e-mail address was set.\n\n";
                 } else {
                     $body = \GO\Addressbook\Model\Template::model()->replaceContactTags($body, $contact);
                     $message->setTo($contact->firstEmail, $contact->name);
                     $message->setBody($body);
                     $plainTextPart = $message->findPlainTextBody();
                     if ($plainTextPart) {
                         $htmlToText->set_html($body);
                         $plainTextPart->setBody($htmlToText->get_text());
                     }
                     // Check mail limit
                     $nSentMails = \GO::config()->get_setting('campaigns_number_sent_mails', 0);
                     if ($mailing->campaign_id > 0 && $nSentMails >= \GO::config()->campaigns_max_mails_per_period) {
                         $this->_pauseMailing($mailing->id);
                         echo "Error for " . $contact->firstEmail . ": \n";
                         echo str_replace('%maxMails', \GO::config()->campaigns_max_mails_per_period, \GO::t('sentMailLimitReached', 'campaigns'));
                         exit;
                     }
                     $this->_sendmail($message, $contact, $mailer, $mailing);
                     \GO::config()->save_setting('campaigns_number_sent_mails', $nSentMails + 1, 0);
                     $errors = 0;
                 }
             } catch (\Exception $e) {
                 echo "Error for " . $contact->firstEmail . ": " . $e->getMessage() . "\n";
             }
             if ($errors) {
                 $mailing->errors++;
                 $mailing->save();
             }
         }
     }
     foreach ($mailing->companies as $company) {
         $sentMailingCompanyModel = \GO\Addressbook\Model\SentMailingCompany::model()->findSingleByAttributes(array('sent_mailing_id' => $mailing->id, 'company_id' => $company->id));
         if (!$sentMailingCompanyModel->sent) {
             $errors = 1;
             $unsubscribeHref = \GO::url('addressbook/sentMailing/unsubscribe', array('addresslist_id' => $mailing->addresslist_id, 'company_id' => $company->id, 'token' => md5($company->ctime . $company->addressbook_id . $company->email)), true, true);
             $body = str_replace('%unsubscribe_href%', $unsubscribeHref, $bodyWithTags);
             //curly brackets don't work inside links in browser wysiwyg editors.
             $body = \GO\Addressbook\Model\Template::model()->replaceCustomTags($body, array('unsubscribe_link' => '<a href="' . $unsubscribeHref . '">' . \GO::t("unsubscription", "addressbook") . '</a>'), true);
             try {
                 if (!$company->email_allowed) {
                     echo "Skipping company " . $company->email . " because newsletter sending is disabled in the addresslists tab.\n\n";
                 } elseif (empty($company->email)) {
                     echo "Skipping company " . $company->name . " no e-mail address was set.\n\n";
                 } else {
                     $body = \GO\Addressbook\Model\Template::model()->replaceModelTags($body, $company);
                     $message->setTo($company->email, $company->name);
                     $message->setBody($body);
                     $plainTextPart = $message->findPlainTextBody();
                     if ($plainTextPart) {
                         $htmlToText->set_html($body);
                         $plainTextPart->setBody($htmlToText->get_text());
                     }
                     // Check mail limit
                     $nSentMails = \GO::config()->get_setting('campaigns_number_sent_mails', 0);
                     if ($mailing->campaign_id > 0 && $nSentMails >= \GO::config()->campaigns_max_mails_per_period) {
                         $this->_pauseMailing($mailing->id);
                         echo "Error for " . $contact->firstEmail . ": \n";
                         echo str_replace('%maxMails', \GO::config()->campaigns_max_mails_per_period, \GO::t('sentMailLimitReached', 'campaigns'));
                         exit;
                     }
                     $this->_sendmail($message, $company, $mailer, $mailing);
                     \GO::config()->save_setting('campaigns_number_sent_mails', $nSentMails + 1, 0);
                     $errors = 0;
                 }
             } catch (\Exception $e) {
                 echo "Error for " . $company->email . ": " . $e->getMessage() . "\n";
             }
             if ($errors) {
                 $mailing->errors++;
                 $mailing->save();
             }
         }
     }
     $mailing->status = \GO\Addressbook\Model\SentMailing::STATUS_FINISHED;
     // Unset the temp_pass
     if (!empty($mailing->temp_pass)) {
         $mailing->temp_pass = "";
     }
     $mailing->save();
     echo "Mailing finished at " . \GO\Base\Util\Date::get_timestamp(time()) . "\n";
 }
示例#3
0
    /**
     * handleEmailFormInput
     * 
     * This method can be used in Models and Controllers. It puts the email body
     * and inline (image) attachments from the client in the message, which can
     * then be used for storage in the database or sending emails.
     * 
     * @param Array $params Must contain elements: body (string) and
     * 
     * inlineAttachments (string).
     */
    public function handleEmailFormInput($params)
    {
        if (!empty($params['subject'])) {
            $this->setSubject($params['subject']);
        }
        if (!empty($params['to'])) {
            $to = new EmailRecipients($params['to']);
            foreach ($to->getAddresses() as $email => $personal) {
                $this->addTo($email, $personal);
            }
        }
        if (!empty($params['cc'])) {
            $cc = new EmailRecipients($params['cc']);
            foreach ($cc->getAddresses() as $email => $personal) {
                $this->addCc($email, $personal);
            }
        }
        if (!empty($params['bcc'])) {
            $bcc = new EmailRecipients($params['bcc']);
            foreach ($bcc->getAddresses() as $email => $personal) {
                $this->addBcc($email, $personal);
            }
        }
        if (isset($params['alias_id'])) {
            $alias = \GO\Email\Model\Alias::model()->findByPk($params['alias_id']);
            $this->setFrom($alias->email, $alias->name);
            if (!empty($params['notification'])) {
                $this->setReadReceiptTo(array($alias->email => $alias->name));
            }
        }
        if (isset($params['priority'])) {
            $this->setPriority($params['priority']);
        }
        if (isset($params['in_reply_to'])) {
            $headers = $this->getHeaders();
            $headers->addTextHeader('In-Reply-To', $params['in_reply_to']);
            $headers->addTextHeader('References', $params['in_reply_to']);
        }
        if ($params['content_type'] == 'html') {
            $params['htmlbody'] = $this->_embedPastedImages($params['htmlbody']);
            //inlineAttachments is an array(array('url'=>'',tmp_file=>'relative/path/');
            if (!empty($params['inlineAttachments'])) {
                $inlineAttachments = json_decode($params['inlineAttachments']);
                /* inline attachments must of course exist as a file, and also be used in
                 * the message body
                 */
                if (count($inlineAttachments)) {
                    foreach ($inlineAttachments as $ia) {
                        //$tmpFile = new \GO\Base\Fs\File(\GO::config()->tmpdir.$ia['tmp_file']);
                        if (empty($ia->tmp_file)) {
                            continue;
                            // Continue to the next inline attachment for processing.
                            //throw new Exception("No temp file for inline attachment ".$ia->name);
                        }
                        $path = empty($ia->from_file_storage) ? \GO::config()->tmpdir . $ia->tmp_file : \GO::config()->file_storage_path . $ia->tmp_file;
                        $tmpFile = new \GO\Base\Fs\File($path);
                        if ($tmpFile->exists()) {
                            //Different browsers reformat URL's to absolute or relative. So a pattern match on the filename.
                            //$filename = rawurlencode($tmpFile->name());
                            $result = preg_match('/="([^"]*' . preg_quote($ia->token) . '[^"]*)"/', $params['htmlbody'], $matches);
                            if ($result) {
                                $img = \Swift_EmbeddedFile::fromPath($tmpFile->path());
                                $img->setContentType($tmpFile->mimeType());
                                $contentId = $this->embed($img);
                                //$tmpFile->delete();
                                $params['htmlbody'] = \GO\Base\Util\String::replaceOnce($matches[1], $contentId, $params['htmlbody']);
                            } else {
                                //this may happen when an inline image was attached but deleted in the editor afterwards.
                                //
                                //throw new \Exception("Error: inline attachment could not be found in text: ".$ia->token);
                            }
                        } else {
                            throw new \Exception("Error: inline attachment missing on server: " . $tmpFile->stripTempPath() . ".<br /><br />The temporary files folder is cleared on each login. Did you relogin?");
                        }
                    }
                }
            }
            $params['htmlbody'] = $this->_fixRelativeUrls($params['htmlbody']);
            $htmlTop = '<html>
<head>
<style type="text/css">
body,p,td,div,span{
	' . \GO::config()->html_editor_font . '
};
body p{
	margin:0px;
}
</style>
</head>
<body>';
            $htmlBottom = '</body></html>';
            $this->setHtmlAlternateBody($htmlTop . $params['htmlbody'] . $htmlBottom);
        } else {
            $this->setBody($params['plainbody'], 'text/plain');
        }
        if (!empty($params['attachments'])) {
            $attachments = json_decode($params['attachments']);
            foreach ($attachments as $att) {
                $path = empty($att->from_file_storage) ? \GO::config()->tmpdir . $att->tmp_file : \GO::config()->file_storage_path . $att->tmp_file;
                $tmpFile = new \GO\Base\Fs\File($path);
                if ($tmpFile->exists()) {
                    $file = \Swift_Attachment::fromPath($tmpFile->path());
                    $file->setContentType($tmpFile->mimeType());
                    $file->setFilename($att->fileName);
                    $this->attach($file);
                    //$tmpFile->delete();
                } else {
                    throw new \Exception("Error: attachment missing on server: " . $tmpFile->stripTempPath() . ".<br /><br />The temporary files folder is cleared on each login. Did you relogin?");
                }
            }
        }
    }
示例#4
0
 public function addAlias($email, $name, $signature = '', $default = 1)
 {
     $a = new Alias();
     $a->account_id = $this->id;
     $a->email = $email;
     $a->name = $name;
     $a->signature = $signature;
     $a->default = $default;
     $a->save();
     return $a;
 }
示例#5
0
文件: Sieve.php 项目: ajaboa/crmpuan
 /**
  * Returns active script name
  */
 public function get_active($accountId)
 {
     $aliasEmails = array();
     $aliasesStmt = \GO\Email\Model\Alias::model()->findByAttribute('account_id', $accountId);
     while ($aliasModel = $aliasesStmt->fetch()) {
         $aliasEmails[] = $aliasModel->email;
     }
     if (!$this->sieve) {
         return $this->_set_error(SIEVE_ERROR_INTERNAL);
     }
     $active = $this->sieve->getActive();
     if (!$active) {
         $all_scripts = $this->get_scripts();
         if (empty($all_scripts)) {
             $createFlag = '';
             $require = array("vacation", "fileinto");
             // Check if the "mailbox" extension is supported
             if ($this->sieve->hasExtension('mailbox')) {
                 $require[] = 'mailbox';
                 $createFlag = ':create ';
             }
             $requireString = 'require ["' . implode('","', $require) . '"];';
             $content = $requireString . "\n\t# rule:[" . GO::t('standardvacation', 'sieve') . "]\n\tif false # anyof (true)\n\t{\n\t\tvacation :days 3 :addresses [\"" . implode('","', $aliasEmails) . "\"] \"" . GO::t('standardvacationmessage', 'sieve') . "\";\n\t\tstop;\n\t}\n\t# rule:[Spam]\n\tif anyof (header :contains \"X-Spam-Flag\" \"YES\")\n\t{\n\t\tfileinto " . $createFlag . "\"Spam\";\n\t}";
             if (!$this->save_script('default', $content)) {
                 throw new \Exception("Could not create default sieve script: " . $this->error());
             }
             $this->activate('default');
             $active = 'default';
         } else {
             $this->activate($all_scripts[0]);
             $active = $all_scripts[0];
         }
     }
     return $active;
 }
示例#6
0
 protected function actionAccountAliases($params)
 {
     $response = array();
     $aliasesStmt = \GO\Email\Model\Alias::model()->findByAttribute('account_id', $params['account_id']);
     $aliases = array();
     while ($aliasModel = $aliasesStmt->fetch()) {
         $aliases[] = $aliasModel->email;
     }
     $response['data']['aliases'] = implode(',', $aliases);
     $response['success'] = true;
     return $response;
 }