Laravel-exchange EWS邮件服务

Laravel-exchange EWS服务库

PHP Exchange Web Services

PHP Exchange Web服务库(PHP-ews)旨在使用Exchange Web服务简化与Microsoft Exchange服务器的通信。它处理使用SOAP服务所需的NTLM身份验证,并为形成请求所需的复杂类型提供面向对象的接口。

github:https://github.com/jamesiarmes/php-ews

Dependencies(依赖)

  • Composer
  • PHP 5.4 or greater
  • Exchange 2007 or later
  • php extension=soap open

Installation(安装)

$ composer require php-ews/php-ews "~1.0"

Usage(使用)

.env

EWS_HOST=mail.test.com.cn
EWS_USERNAME=test@test.com.cn
EWS_PASSWORD='你的密码'

创建EWS类

App\Libs\EWS.php

<?php

namespace App\Libs;

use jamesiarmes\PhpEws\Client;
use App\Exceptions\EWSException;
use jamesiarmes\PhpEws\Type\BodyType;
use jamesiarmes\PhpEws\Type\ItemIdType;
use jamesiarmes\PhpEws\Type\MessageType;
use jamesiarmes\PhpEws\Request\SendItemType;
use jamesiarmes\PhpEws\Type\EmailAddressType;
use jamesiarmes\PhpEws\Request\CreateItemType;
use jamesiarmes\PhpEws\Type\TargetFolderIdType;
use jamesiarmes\PhpEws\Type\FileAttachmentType;
use jamesiarmes\PhpEws\Enumeration\BodyTypeType;
use jamesiarmes\PhpEws\Type\SingleRecipientType;
use jamesiarmes\PhpEws\Request\CreateAttachmentType;
use jamesiarmes\PhpEws\Enumeration\ResponseClassType;
use jamesiarmes\PhpEws\Type\DistinguishedFolderIdType;
use jamesiarmes\PhpEws\ArrayType\ArrayOfRecipientsType;
use jamesiarmes\PhpEws\Enumeration\MessageDispositionType;
use jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAllItemsType;
use jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfAttachmentsType;
use jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseItemIdsType;
use jamesiarmes\PhpEws\Enumeration\DistinguishedFolderIdNameType;

class EWS
{
    /**
     * [EWS client]
     *
     * @var  [Object]
     */
    public $client;

    /**
     * [邮箱地址]
     *
     * @var  [String]
     */
    public $emails;

    /**
     * [邮件标题]
     *
     * @var  [String]
     */
    public $subject;

    /**
     * [邮件内容]
     *
     * @var  [String]
     */
    public $body;

    /**
     * [附件的绝对路径]
     *
     * @var  [String]
     */
    public $attachment;

    /**
     * [构造方法]
     *
     * @return  [Object]  
     */
    public function __construct()
    {
        $host         = env('EWS_HOST', null);
        $username     = env('EWS_USERNAME', null);
        $password     = env('EWS_PASSWORD', null);
        $version      = Client::VERSION_2016;
        $this->client = new Client($host, $username, $password, $version);
    }
    
    /**
     * 发送邮件
     *
     * @param   [Array]  $data   [数据]
     *
     * @return  [Json]           [结果]
     */
    public function send($data)
    {
        if(empty($data['emails'])){
            throw new EWSException('The email is invalid.', 422);
        }

        if(!empty($data['attachments'])){
            foreach ($data['attachments'] as $path) {
                if(!file_exists($path)){
                    throw new EWSException("The file:{$path} is not exists.", 404);
                }
            }
        }
        //初始化
        $this->emails      = $data['emails'] ?? '';
        $this->subject     = $data['subject'] ?? '';
        $this->body        = $data['body'] ?? '';
        $this->attachments = $data['attachments'] ?? '';
        //创建所需要参数
        $message = $this->createMessage();
        $request  = $this->createRequest($message);
        //创建草稿并返回
        $item = $this->createItem($request);
        
        $send = $this->doSend($item);

        return $send;
    }

    /**
     * [创建草稿并且返回]
     *
     * @param   [Request]  $request  [message]
     *
     * @return  [Array]              [返回创建信息]
     */
    protected function createItem($request)
    {
        $response  = $this->client->CreateItem($request);
        //分析结果
        $response_messages = $response->ResponseMessages->CreateItemResponseMessage;
        $data = [];
        foreach ($response_messages as $response_message) {
            // Make sure the request succeeded.
            if ($response_message->ResponseClass != ResponseClassType::SUCCESS) {
                throw new EWSException($response_message->MessageText, $response_message->ResponseCode);
            }
            // Iterate over the created messages, printing the id for each.
            foreach ($response_message->Items->Message as $item) {
                $data['code']       = 0;
                $data['item_id']    = $item->ItemId->Id;
                $data['change_key'] = $item->ItemId->ChangeKey;
            }
        }

        return $data;
    }

    /**
     * [执行发送]
     *
     * @param   [Array]  $item  [草稿]
     *
     * @return  [Array]         [结果]
     */
    protected function doSend($item)
    {
        //判断是否有附件添加
        if(!empty($this->attachments) && $item['code'] == 0){
            $item = $this->addAttachment($item);
        }

        $message_id = $item['item_id'];
        $change_key = $item['change_key'];
        
        // Build the request.
        $request = new SendItemType();
        $request->SaveItemToFolder = true;
        $request->ItemIds = new NonEmptyArrayOfBaseItemIdsType();

        // Add the message to the request.
        $item = new ItemIdType();
        $item->Id = $message_id;
        $item->ChangeKey = $change_key;
        $request->ItemIds->ItemId[] = $item;
        
        // Configure the folder to save the sent message to.
        $send_folder = new TargetFolderIdType();
        $send_folder->DistinguishedFolderId = new DistinguishedFolderIdType();
        $send_folder->DistinguishedFolderId->Id = DistinguishedFolderIdNameType::SENT;
        $request->SavedItemFolderId = $send_folder;
        
        $response = $this->client->SendItem($request);

        // Iterate over the results, printing any error messages.
        $response_messages = $response->ResponseMessages->SendItemResponseMessage;
        $data = [];
        foreach ($response_messages as $response_message) {
            // Make sure the request succeeded.
            if ($response_message->ResponseClass != ResponseClassType::SUCCESS) {
                throw new EWSException($response_message->MessageText, $response_message->ResponseCode);
            }
            $data['code']    = 0;
            $data['message'] = 'Message sent successfully.';
        }

       return $data;
    }

    /**
     * [添加附件]
     *
     * @param   [Item]  $item  [草稿]
     *
     * @return  [Array]        [附件结果]
     */
    protected function addAttachment($item)
    {
        

        // Build the request,
        $request = new CreateAttachmentType();
        $request->ParentItemId = new ItemIdType();
        $request->ParentItemId->Id = $item['item_id'];
        $request->Attachments = new NonEmptyArrayOfAttachmentsType();

        // Build the file attachment.
        foreach ($this->attachments as $path) {
            // Open file handlers.
            $file = new \SplFileObject($path);
            $finfo = finfo_open();
            $attachment = new FileAttachmentType();
            $attachment->Content = $file->openFile()->fread($file->getSize());
            $attachment->Name = $file->getBasename();
            $attachment->ContentType = finfo_file($finfo, $path);
            
            $request->Attachments->FileAttachment[] = $attachment;
        }
        $response = $this->client->CreateAttachment($request);
        
        $response_messages = $response->ResponseMessages->CreateAttachmentResponseMessage;
        $item = [];
        foreach ($response_messages as $response_message) {
            // Make sure the request succeeded.
            if ($response_message->ResponseClass != ResponseClassType::SUCCESS) {
                throw new EWSException($response_message->MessageText, $response_message->ResponseCode);
            }
            // Iterate over the created attachments, printing the id of each.
            foreach ($response_message->Attachments->FileAttachment as $attachment) {
                $item['code']          = 0;
                $item['item_id']       = $attachment->AttachmentId->RootItemId;
                $item['change_key']    = $attachment->AttachmentId->RootItemChangeKey;
                $item['attachment_id'] = $attachment->AttachmentId->Id;
            }
        }

        return $item;
    }

    /**
     * 创建草稿箱
     *
     * @param   [Message]  $message  [要发送的文本信息]
     *
     * @return  [request]            []
     */
    protected function createRequest($message)
    {
        // Build the request,
        $request = new CreateItemType();
        $request->Items = new NonEmptyArrayOfAllItemsType();
        // Add the message to the request.
        $request->Items->Message[] = $message;
        // Save the message, but do not send it.
        $request->MessageDisposition = MessageDispositionType::SAVE_ONLY;

        return $request;
    }

    /**
     * 创建 发件人 标题 内容
     *
     * @param   [Client]            $client   [EWS客户端]
     * @param   [EmailAddress]      $email    [邮箱地址]
     * @param   [Subject]           $subject  [标题]
     * @param   [Body]              $body     [内容]
     *
     * @return  [Message]             [message]
     */
    protected function createMessage()
    {
        // Create the message.
        $message = new MessageType();
        $message->Subject = $this->subject;
        $message->ToRecipients = new ArrayOfRecipientsType();

        // Set the sender.
        $message->From = new SingleRecipientType();
        $message->From->Mailbox = new EmailAddressType();
        $message->From->Mailbox->EmailAddress = env('EWS_USERNAME', null);

        foreach ($this->emails as $key => $email) {
            // Set the recipient.
            $to        = $email['to'] ?? '';
            $name      = $email['name'] ?? $to;
            $recipient = new EmailAddressType();
            $recipient->Name = $name;
            $recipient->EmailAddress = $to;
            $message->ToRecipients->Mailbox[] = $recipient;
        }

        // Set the message body.
        $message->Body = new BodyType();
        $message->Body->BodyType = BodyTypeType::HTML;
        $message->Body->_ = $this->body;

        return $message;
    }
}

发送邮件:

App\Controllers\MailController.php

<?php

namespace App\Http\Controllers;

use App\Libs\EWS;
use Illuminate\Http\Request;

class MailController extends Controller
{
    public function seed(Request $request)
    {
        //要发送给的人的姓名和邮箱地址
        $emails = [
            [
                'to'   => 'test1@test.com',
                'name' => '张三'
            ],
            [
                'to'   => 'test2@test.com',
                'name' => '李四'
            ]
        ];
        //附件路径
        $attachments = [
            storage_path('1.pdf'),
            storage_path('2.pdf')
        ];
        //发送
        $exchange   = new EWS();
        $send =  $exchange->send([
            'emails'      => $emails,
            'subject'     => 'test',
            'body'        => response(view('emails.pdf', ['name' => '邮箱测试']))->getContent(), //这里可以使用blade模板自定义你的模板样式
            'attachments' => $attachments
        ]);

        return response()->json($send);
    }
}    

自定义异常

App\Exceptions\EWSException.php

<?php

namespace App\Exceptions;

use Exception;

class EWSException extends Exception
{
    
}

自定义异常处理

App\Exceptions\Handler.php

<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;

class Handler extends ExceptionHandler
{
    /**
     * A list of the exception types that are not reported.
     *
     * @var array
     */
    protected $dontReport = [
        //
    ];

    /**
     * A list of the inputs that are never flashed for validation exceptions.
     *
     * @var array
     */
    protected $dontFlash = [
        'password',
        'password_confirmation',
    ];

    /**
     * Report or log an exception.
     *
     * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
     *
     * @param  \Exception  $exception
     * @return void
     */
    public function report(Exception $exception)
    {
        if ($exception instanceof EWSException) {
            //如果是邮件发送异常,这里做一些记录
        }
        
        parent::report($exception);
    }

    /**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Exception  $exception
     * @return \Illuminate\Http\Response
     */
    public function render($request, Exception $exception)
    {
        if($exception instanceof EWSException) {
            $result = [
                "code"   => $exception->getCode(),
                "message" => $exception->getMessage()
            ];
            
            return response()->json($result, $exception->getCode());
        }

        return parent::render($request, $exception);
    }
}

 

posted @ 2018-12-27 14:49  丶中医  阅读(756)  评论(0编辑  收藏  举报