<?php

namespace Illuminate\Mail;

use Swift_Mailer;
use Illuminate\Support\ServiceProvider;

class MailServiceProvider extends ServiceProvider
{
    /**
     * Indicates if loading of the provider is deferred.
     * 指示是否延迟加载提供者程序。
     * @var bool
     */
    protected $defer = true;

    /**
     * Register the service provider.
     * 注册服务提供者
     * @return void
     */
    public function register()
    {
        $this->registerSwiftMailer();

        $this->app->singleton('mailer', function ($app) {
            // 一旦我们创建了邮件程序实例,我们将在邮件程序上设置一个容器实例。 这允许我们通过容器解析邮件程序类,以实现对所述类的最大可测试性,而不是传递闭包。
            $mailer = new Mailer(
                $app['view'], $app['swift.mailer'], $app['events']
            );

            $this->setMailerDependencies($mailer, $app);

            // 如果设置了“发件人”地址,我们将在邮件程序上设置它,这样应用程序发送的所有邮件消息都将使用相同的“发件人”地址,这使开发人员的生活更加方便。
            $from = $app['config']['mail.from'];

            if (is_array($from) && isset($from['address'])) {
                $mailer->alwaysFrom($from['address'], $from['name']);
            }

            $to = $app['config']['mail.to'];

            if (is_array($to) && isset($to['address'])) {
                $mailer->alwaysTo($to['address'], $to['name']);
            }

            return $mailer;
        });
    }

    /**
     * Set a few dependencies on the mailer instance.
     * 在邮件程序实例上设置一些依赖项。
     * @param  \Illuminate\Mail\Mailer  $mailer
     * @param  \Illuminate\Foundation\Application  $app
     * @return void
     */
    protected function setMailerDependencies($mailer, $app)
    {
        $mailer->setContainer($app);

        if ($app->bound('queue')) {
            $mailer->setQueue($app['queue.connection']);
        }
    }

    /**
     * Register the Swift Mailer instance.
     * 注册 Swift Mailer 实例。
     * @return void
     */
    public function registerSwiftMailer()
    {
        $this->registerSwiftTransport();

        // 一旦我们注册了传输器,我们将注册实际的 Swift 邮件程序实例,传入传输实例,这允许我们在应用程序启动期间在必要时覆盖此传输器实例。
        $this->app['swift.mailer'] = $this->app->share(function ($app) {
            return new Swift_Mailer($app['swift.transport']->driver());
        });
    }

    /**
     * Register the Swift Transport instance.
     * 注册 Swift Transport 实例。
     * @return void
     */
    protected function registerSwiftTransport()
    {
        $this->app['swift.transport'] = $this->app->share(function ($app) {
            return new TransportManager($app);
        });
    }

    /**
     * Get the services provided by the provider.
     * 获取提供者提供的服务。
     * @return array
     */
    public function provides()
    {
        return ['mailer', 'swift.mailer', 'swift.transport'];
    }
}