<commit_before><?php
/**
 * Mailgun Plugin for CakePHP 3
 * Copyright (c) <NAME> (http://www.narendravaghela.com)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.md
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright Copyright (c) <NAME> (http://www.narendravaghela.com)
 * @license   https://opensource.org/licenses/mit-license.php MIT License
 * @link      https://github.com/narendravaghela/cakephp-mailgun
 * @since     1.0.0
 */

namespace Mailgun\Mailer\Transport;

use Cake\Core\Configure;
use Cake\Http\Client;
use Cake\Http\Client\FormData;
use Cake\Http\Client\FormDataPart;
use Cake\Mailer\AbstractTransport;
use Cake\Mailer\Email;
use Mailgun\Mailer\Exception\MailgunApiException;

/**
 * Send mail using Mailgun API
 */
class MailgunTransport extends AbstractTransport
{

    /**
     * Default config for this class
     *
     * @var array
     */
    protected $_defaultConfig = [
        'apiEndpoint' => 'https://api.mailgun.net/v3',
        'domain' => '',
        'apiKey' => ''
    ];

    /**
     * Additional options allowed by Mailgun API
     *
     * @var array
     */
    protected $_allowedOptions = [
        'tag',
        'dkim',
        'deliverytime',
        'testmode',
        'tracking',
        'tracking-clicks',
        'tracking-opens',
        'require-tls',
        'skip-verification'
    ];

    protected $_mailgunHeaderPrefix = 'X-Mailgun';

    protected $_mailgunHeaders = [
        'X-Mailgun-Tag' => 'tag',
        'X-Mailgun-Dkim' => 'dkim',
        'X-Mailgun-Deliver-By' => 'deliverytime',
        'X-Mailgun-Drop-Message' => 'testmode',
        'X-Mailgun-Track' => 'tracking',
        'X-Mailgun-Track-Clicks' => 'tracking-clicks',
        'X-Mailgun-Track-Opens' => 'tracking-opens',
        'X-Mailgun-Require-TLS' => 'require-tls',
        'X-Mailgun-Skip-Verification' => 'skip-verification'
    ];

    /**
     * Prefix for setting options
     *
     * @var string
     */
    protected $_optionPrefix = 'o:';

    /**
     * Prefix for setting custom headers
     *
     * @var string
     */
    protected $_customHeaderPrefix = 'h:';

    /**
     * Prefix for variables
     *
     * @var string
     */
    protected $_varPrefix = 'v:';

    /**
     * FormData object
     *
     * @var \Cake\Http\Client\FormData
     */
    protected $_formData;

    /**
     * Constructor
     *
     * @param array $config Configuration options.
     */
    public function __construct($config = [])
    {
        parent::__construct($config);
        $this->_formData = new FormData();
    }

    /**
     * Send mail
     *
     * @param \Cake\Mailer\Email $email Cake Email
     * @return array An array with api response and email parameters
     * @throws MailgunApiException If api key or domain is not set
     */
    public function send(Email $email)
    {
        if (empty($this->getConfig('apiKey'))) {
            throw new MailgunApiException('Api Key for Mailgun could not found.');
        }

        if (empty($this->getConfig('domain'))) {
            throw new MailgunApiException('Domain for Mailgun could not found.');
        }

        $this->_prepareEmailAddresses($email);

        $subject = new FormDataPart('subject', $email->getSubject());
        $this->_formData->add($subject);

        $emailFormat = $email->getEmailFormat();
        $this->_formData->add('html', trim($email->message(Email::MESSAGE_HTML)));
        if ('both' == $emailFormat || 'text' == $emailFormat) {
            $this->_formData->add('text', trim($email->message(Email::MESSAGE_TEXT)));
        }

        $this->_processHeaders($email);

        $attachments = $email->getAttachments();
        if (!empty($attachments)) {
            foreach ($attachments as $fileName => $attachment) {
                if (empty($attachment['contentId'])) {
                    $file = $this->_addFile('attachment', $attachment, $fileName);
                } else {
                    $file = $this->_addFile('inline', $attachment, $fileName);
                    $file->contentId($attachment['contentId']);
                }
                $file->disposition('attachment');
            }
        }

        $apiResponse = $this->_sendEmail();
        $res = ['apiResponse' => $apiResponse];

        if (Configure::read('debug')) {
            $res['reqData'] = $this->_formData;
        }

        $this->_reset();

        return $res;
    }

    /**
     * Add file attachment to email.
     *
     * @param string $partName Name of the file part
     * @param array $attachment Attachment as initially set via setAttachment()
     * @param string $fileName Desired filename of the attachment
     * @return \Cake\Http\Client\FormDataPart
     */
    protected function _addFile($partName, $attachment, $fileName = '')
    {
        if (isset($attachment['file'])) {
            $file = $this->_formData->addFile($partName, fopen($attachment['file'], 'r'));
        } else {
            $file = $this->_formData->newPart($partName, base64_decode($attachment['data']));
            $file->type($attachment['mimetype']);
            $file->filename($fileName);
            $this->_formData->add($file);
        }

        return $file;
    }

    /**
     * Returns the parameters for API request.
     *
     * @return array<commit_msg>Ensure that internal state is always reset<commit_after><?php
/**
 * Mailgun Plugin for CakePHP 3
 * Copyright (c) <NAME> (http://www.narendravaghela.com)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.md
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright Copyright (c) <NAME> (http://www.narendravaghela.com)
 * @license   https://opensource.org/licenses/mit-license.php MIT License
 * @link      https://github.com/narendravaghela/cakephp-mailgun
 * @since     1.0.0
 */

namespace Mailgun\Mailer\Transport;

use Cake\Core\Configure;
use Cake\Http\Client;
use Cake\Http\Client\FormData;
use Cake\Http\Client\FormDataPart;
use Cake\Mailer\AbstractTransport;
use Cake\Mailer\Email;
use Mailgun\Mailer\Exception\MailgunApiException;

/**
 * Send mail using Mailgun API
 */
class MailgunTransport extends AbstractTransport
{

    /**
     * Default config for this class
     *
     * @var array
     */
    protected $_defaultConfig = [
        'apiEndpoint' => 'https://api.mailgun.net/v3',
        'domain' => '',
        'apiKey' => ''
    ];

    /**
     * Additional options allowed by Mailgun API
     *
     * @var array
     */
    protected $_allowedOptions = [
        'tag',
        'dkim',
        'deliverytime',
        'testmode',
        'tracking',
        'tracking-clicks',
        'tracking-opens',
        'require-tls',
        'skip-verification'
    ];

    protected $_mailgunHeaderPrefix = 'X-Mailgun';

    protected $_mailgunHeaders = [
        'X-Mailgun-Tag' => 'tag',
        'X-Mailgun-Dkim' => 'dkim',
        'X-Mailgun-Deliver-By' => 'deliverytime',
        'X-Mailgun-Drop-Message' => 'testmode',
        'X-Mailgun-Track' => 'tracking',
        'X-Mailgun-Track-Clicks' => 'tracking-clicks',
        'X-Mailgun-Track-Opens' => 'tracking-opens',
        'X-Mailgun-Require-TLS' => 'require-tls',
        'X-Mailgun-Skip-Verification' => 'skip-verification'
    ];

    /**
     * Prefix for setting options
     *
     * @var string
     */
    protected $_optionPrefix = 'o:';

    /**
     * Prefix for setting custom headers
     *
     * @var string
     */
    protected $_customHeaderPrefix = 'h:';

    /**
     * Prefix for variables
     *
     * @var string
     */
    protected $_varPrefix = 'v:';

    /**
     * FormData object
     *
     * @var \Cake\Http\Client\FormData
     */
    protected $_formData;

    /**
     * Constructor
     *
     * @param array $config Configuration options.
     */
    public function __construct($config = [])
    {
        parent::__construct($config);
        $this->_formData = new FormData();
    }

    /**
     * Send mail
     *
     * @param \Cake\Mailer\Email $email Cake Email
     * @return array An array with api response and email parameters
     * @throws MailgunApiException If api key or domain is not set
     */
    public function send(Email $email)
    {
        if (empty($this->getConfig('apiKey'))) {
            throw new MailgunApiException('Api Key for Mailgun could not found.');
        }

        if (empty($this->getConfig('domain'))) {
            throw new MailgunApiException('Domain for Mailgun could not found.');
        }

        $this->_prepareEmailAddresses($email);

        $subject = new FormDataPart('subject', $email->getSubject());
        $this->_formData->add($subject);

        $emailFormat = $email->getEmailFormat();
        $this->_formData->add('html', trim($email->message(Email::MESSAGE_HTML)));
        if ('both' == $emailFormat || 'text' == $emailFormat) {
            $this->_formData->add('text', trim($email->message(Email::MESSAGE_TEXT)));
        }

        $this->_processHeaders($email);

        $attachments = $email->getAttachments();
        if (!empty($attachments)) {
            foreach ($attachments as $fileName => $attachment) {
                if (empty($attachment['contentId'])) {
                    $file = $this->_addFile('attachment', $attachment, $fileName);
                } else {
                    $file = $this->_addFile('inline', $attachment, $fileName);
                    $file->contentId($attachment['contentId']);
                }
                $file->disposition('attachment');
            }
        }

        try {
            $apiResponse = $this->_sendEmail();
            $res = ['apiResponse' => $apiResponse];

            if (Configure::read('debug')) {
                $res['reqData'] = $this->_formData;
            }

            return $res;
        } finally {
            $this->_reset();
        }
    }

    /**
     * Add file attachment to email.
     *
     * @param string $partName Name of the file part
     * @param array $attachment Attachment as initially set via setAttachment()
     * @param string $fileName Desired filename of the attachment
     * @return \Cake\Http\Client\FormDataPart
     */
    protected function _addFile($partName, $attachment, $fileName = '')
    {
        if (isset($attachment['file'])) {
            $file = $this->_formData->addFile($partName, fopen($attachment['file'], 'r'));
        } else {
            $file = $this->_formData->newPart($partName, base64_decode($attachment['data']));
            $file->type($attachment['mimetype']);
            $file->filename($fileName);
            $this->_formData->add($file);
        }

        return $file;
    }

    /**
     * Returns the parameters for API request.
     *
     * @return array
{'fraction_non_alphanumeric': 0.1470101195952162, 'fraction_numerical': 0.0012879484820607176, 'mean_word_length': 2.2067846607669614, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 97, 'https://': 6, 'lorem ipsum': 0, 'www.': 4, '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': '3004983', 'n_tokens_mistral': 3206, 'n_tokens_neox': 3128, 'n_words': 681}