<commit_before><?php

namespace BitsOfLove\MailStats;

use BitsOfLove\MailStats\Events\EmailAddedToQueue;
use BitsOfLove\MailStats\Exceptions\EmailDataMissmatchException;
use BitsOfLove\MailStats\Exceptions\ProjectNotSupported;
use BitsOfLove\MailStats\Entities\Project;
use BitsOfLove\MailStats\ValueObjects\Emails\From;
use BitsOfLove\MailStats\ValueObjects\Emails\To;
use Illuminate\Validation\ValidationException;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Mailgun;
use Mailgun\Connection\Exceptions\MissingRequiredParameters;

class SendMail
{
    /**
     * @var To
     */
    protected $to;

    /**
     * @var From
     */
    protected $from;

    /**
     * @var string
     */
    protected $subject;

    /**
     * @var string
     */
    protected $view;

    /**
     * @var array
     */
    protected $viewData;

    /**
     * @var array
     */
    protected $tags;

    /**
     * @var Model
     */
    protected $project;

    /**
     * @param To $to
     * @param From $from
     * @param string $subject
     * @param string $view
     * @param array $viewData
     * @param Model $project
     * @param array $tags
     * @param array $options
     */
    public function __construct(
        To $to,
        From $from,
        $subject,
        $view,
        array $viewData = [],
        Model $project,
        array $tags = [],
        array $options = []
    ) {
        $options += [
            'view_namespace' => "mail-stats"
        ];

        $this->to = $to;
        $this->from = $from;
        $this->subject = $subject;
        $this->setView($view, $options['view_namespace']);
        $this->viewData = $viewData;
        $this->project = $project;
        $this->tags = $tags;
    }

    /**
     * @return To
     */
    public function getTo()
    {
        return $this->to;
    }

    /**
     * @return From
     */
    public function getFrom()
    {
        return $this->from;
    }

    /**
     * @return string
     */
    public function getSubject()
    {
        return $this->subject;
    }

    /**
     * @return string
     */
    public function getView()
    {
        return $this->view;
    }

    /**
     * Set the view that should be used to send the email
     *
     * @param string $view
     * @param null|string $namespace
     * @todo: add possibility to change the namespace from outside the class
     */
    public function setView($view, $namespace = null)
    {
        // no namespace was given for the email views
        if (is_null($namespace) || empty($namespace)) {
            $this->view = $view;
            return;
        }

        // detect if the namespace is all ready included in the view name
        $pattern = "^$namespace::";

        if (!preg_match("/$pattern/", $view)) {
            $this->view = "{$namespace}::{$view}";
        } else {
            $this->view = $view;
        }
    }

    /**
     * @return array
     */
    public function getViewData()
    {
        return $this->viewData;
    }

    /**
     * @return Model
     */
    public function getProject()
    {
        return $this->project;
    }

    /**
     * @return array
     */
    public function getTags()
    {
        return $this->tags;
    }


    /**
     * Create a SendMail instance from a given request
     *
     * @param Request $request
     * @return SendMail
     */
    public static function create(Request $request)
    {
        // ensure the project is available via the request
        $project = self::fetchProjectFromRequest($request);

        // add missing information to the request
        // create a collection to work with
        $data = self::injectExtraInfoInRequest($project, $request->request->all());

        // validate the data
        self::validate($data);

        // init the options
        $options = [];

        $from = new From(
            $data['from']['email'], $data['from']['name']
        );

        $to = new To(
            $data['to']['email'], $data['to']['name']
        );

        $tags[] = $project->name;
        $subject = $data['subject'];

        $view = $data['messageData']['view'];
        $viewData = $data['messageData']['variables'];

        // if the namespace for the
        if (isset($data['messageData']['view_namespace'])) {
            $options['view_namespace'] = $data['messageData']['view_namespace'];
        }

        return new static($to, $from, $subject, $view, $viewData, $project, $tags, $options);
    }

    /**
     * Inject extra information given on the project if it does not exist in the request data
     *
     * @param Project $project
     * @param array $data
     * @return Collection
     */
    public static function injectExtraInfoInRequest(Project $project, $data)
    {
        // replace missing recipient information with the defaults
        if (!isset($data['to']['name'])) {
            $data['to']['name'] = $project->recipient_name;
        }

        if (!isset($data['to']['email'])) {
            $data['to']['email'] = $project->recipient_email;
        }

        // replace missing sender information with the defaults
        if (!isset($data['from']['name'])) {
            $data['from']['name'] = $project->sender_name;
        }

        if (!isset($data['from']['email'])) {
            $data['from']['email'] = $project->sender_email;
        }

        // return a new collection
        return collect($data);
    }

    /**
     * Send the actual
     *
     * @return JsonResponse
     */
    public function send()
    {
        try {
            $res = Mailgun::send($this->view, $this->viewData,
                function ($message) {
                    $message->from($this->from->getEmail(), $this->from->getName());
                    $message->to($this->to->getEmail(), $this->to->getName())
                        ->subject($this->subject);
                    foreach ($this->tags as $tag) {
                        $message->tag($tag);
                    }
                });

            // cleanup the result for later use
            self::cleanupResults($res);
<commit_msg>Replaced Mailgun facade with app container created instance<commit_after><?php

namespace BitsOfLove\MailStats;

use BitsOfLove\MailStats\Events\EmailAddedToQueue;
use BitsOfLove\MailStats\Exceptions\EmailDataMissmatchException;
use BitsOfLove\MailStats\Exceptions\ProjectNotSupported;
use BitsOfLove\MailStats\Entities\Project;
use BitsOfLove\MailStats\ValueObjects\Emails\From;
use BitsOfLove\MailStats\ValueObjects\Emails\To;
use Illuminate\Validation\ValidationException;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Bogardo\Mailgun\Mailgun;
use Mailgun\Connection\Exceptions\MissingRequiredParameters;

class SendMail
{
    protected $mailgun;

    /**
     * @var To
     */
    protected $to;

    /**
     * @var From
     */
    protected $from;

    /**
     * @var string
     */
    protected $subject;

    /**
     * @var string
     */
    protected $view;

    /**
     * @var array
     */
    protected $viewData;

    /**
     * @var array
     */
    protected $tags;

    /**
     * @var Model
     */
    protected $project;

    /**
     * @param To $to
     * @param From $from
     * @param string $subject
     * @param string $view
     * @param array $viewData
     * @param Model $project
     * @param array $tags
     * @param array $options
     */
    public function __construct(
        To $to,
        From $from,
        $subject,
        $view,
        array $viewData = [],
        Model $project,
        array $tags = [],
        array $options = []
    ) {
        $this->mailgun = app('mailgun');

        $options += [
            'view_namespace' => "mail-stats"
        ];

        $this->to = $to;
        $this->from = $from;
        $this->subject = $subject;
        $this->setView($view, $options['view_namespace']);
        $this->viewData = $viewData;
        $this->project = $project;
        $this->tags = $tags;
    }

    /**
     * @return To
     */
    public function getTo()
    {
        return $this->to;
    }

    /**
     * @return From
     */
    public function getFrom()
    {
        return $this->from;
    }

    /**
     * @return string
     */
    public function getSubject()
    {
        return $this->subject;
    }

    /**
     * @return string
     */
    public function getView()
    {
        return $this->view;
    }

    /**
     * Set the view that should be used to send the email
     *
     * @param string $view
     * @param null|string $namespace
     * @todo: add possibility to change the namespace from outside the class
     */
    public function setView($view, $namespace = null)
    {
        // no namespace was given for the email views
        if (is_null($namespace) || empty($namespace)) {
            $this->view = $view;
            return;
        }

        // detect if the namespace is all ready included in the view name
        $pattern = "^$namespace::";

        if (!preg_match("/$pattern/", $view)) {
            $this->view = "{$namespace}::{$view}";
        } else {
            $this->view = $view;
        }
    }

    /**
     * @return array
     */
    public function getViewData()
    {
        return $this->viewData;
    }

    /**
     * @return Model
     */
    public function getProject()
    {
        return $this->project;
    }

    /**
     * @return array
     */
    public function getTags()
    {
        return $this->tags;
    }


    /**
     * Create a SendMail instance from a given request
     *
     * @param Request $request
     * @return SendMail
     */
    public static function create(Request $request)
    {
        // ensure the project is available via the request
        $project = self::fetchProjectFromRequest($request);

        // add missing information to the request
        // create a collection to work with
        $data = self::injectExtraInfoInRequest($project, $request->request->all());

        // validate the data
        self::validate($data);

        // init the options
        $options = [];

        $from = new From(
            $data['from']['email'], $data['from']['name']
        );

        $to = new To(
            $data['to']['email'], $data['to']['name']
        );

        $tags[] = $project->name;
        $subject = $data['subject'];

        $view = $data['messageData']['view'];
        $viewData = $data['messageData']['variables'];

        // if the namespace for the
        if (isset($data['messageData']['view_namespace'])) {
            $options['view_namespace'] = $data['messageData']['view_namespace'];
        }

        return new static($to, $from, $subject, $view, $viewData, $project, $tags, $options);
    }

    /**
     * Inject extra information given on the project if it does not exist in the request data
     *
     * @param Project $project
     * @param array $data
     * @return Collection
     */
    public static function injectExtraInfoInRequest(Project $project, $data)
    {
        // replace missing recipient information with the defaults
        if (!isset($data['to']['name'])) {
            $data['to']['name'] = $project->recipient_name;
        }

        if (!isset($data['to']['email'])) {
            $data['to']['email'] = $project->recipient_email;
        }

        // replace missing sender information with the defaults
        if (!isset($data['from']['name'])) {
            $data['from']['name'] = $project->sender_name;
        }

        if (!isset($data['from']['email'])) {
            $data['from']['email'] = $project->sender_email;
        }

        // return a new collection
        return collect($data);
    }

    /**
     * Send the actual
     *
     * @return JsonResponse
     */
    public function send()
    {
        try {
            $res = $this->mailgun->send($this->view, $this->viewData,
                function ($message) {
                    $message->from($this->from->getEmail(), $this->from->getName());
                    $message->to($this->to->getEmail(), $this->to->getName())
                        ->subject($this->subject);
                    foreach ($this->tags as $tag) {
                        $message->tag($tag);
                    }
                });

            // cleanup the result for later use
            self::cleanupResults($res);

{'fraction_non_alphanumeric': 0.14358484559057624, 'fraction_numerical': 0.0, 'mean_word_length': 1.8661040145985401, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 88, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5784577', 'n_tokens_mistral': 3569, 'n_tokens_neox': 3495, 'n_words': 851}