Skip to content

Instantly share code, notes, and snippets.

@vin-ai
Last active April 27, 2017 22:53
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vin-ai/ed4411b55f33db1ab41e to your computer and use it in GitHub Desktop.
Save vin-ai/ed4411b55f33db1ab41e to your computer and use it in GitHub Desktop.
PHP Class for Yii PHP Framework to Send E-mails using Curl. It's uses MailGun API to send emails.
<?php
/**
* MailGun PHP Curl Client
*
* @version 1.1b
* @copyright &copy; 2015, VINAY KUMAR SHARMA <vinaykrsharma@live.in>
* @author VINAY KUMAR SHARMA
*/
class MailGun extends CApplicationComponent {
/* * *************************************************************************
PUBLIC Properties
* ************************************************************************* */
/**
* PHP Curl Options, use PHP Curl constant variable to pass.
* e.g:
* CURLOPT_HEADER => TRUE
* CURLOPT_USERAGENT => 'Bond/0.0.7'
* @var array PHP Curl extension options
*/
public $options = array();
/**
* Default Sender Address
* if don't found in send() method parameters
*
* @var string Sender email
*/
public $defaultFromEmail;
/**
* Domain listed in MailGun Control Panel
* @var string Mail will be used to sent using
*/
public $domain;
/**
* You can find your API Key in your
* <a href="https://mailgun.com/cp">Control Panel</a>
* @var string MailGun Api Key
*/
public $apiKey;
/* * *************************************************************************
PRIVATE and PROTECTED Properties
* ************************************************************************* */
/**
* MailGun Api URL Address
*
* @var string Api URL
*/
protected $mailGunApiURL = 'https://api.mailgun.net/v2/';
/**
* The path to the directory where the view for getView is stored. Must not
* have ending dot.
*
* @var string
*/
protected $pathViews = 'application.views.email';
/**
* The path to the directory where the layout for getView is stored. Must
* not have ending dot.
*
* @var string
*/
protected $pathLayouts = 'application.views.email.layouts';
/**
* NOT IMPLEMENT YET
*
* HTTP Request Headers
* @var array request with headers
*/
protected $httpHeaders = array(
CURLOPT_HTTPHEADER => array(
'Accept: application/json',
'Accept-Language: en-us;q=0.5,en;q=0.3',
'Accept-Charset: utf-8;q=0.7,*;q=0.7',
'Keep-Alive: 300'
),
);
/**
* @var object curl_init() return value
*/
private $_ch;
/**
* CURL Options, see PHP curl options for more
*
* @var array options
*/
private $_curlOptions = array(
CURLOPT_HEADER => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POST => true,
CURLOPT_USERAGENT => 'MailGun-PHP-Curl-Client/1.1b'
);
public function __construct() {
}
public function init() {
parent::init();
if (empty($this->domain)) {
throw new CException('MailGun: Domain can not be empty.');
}
if (empty($this->apiKey)) {
throw new CException('MailGun: API Key is not found in option');
}
// Unset `CURLOPT_URL` is found in options,
// This will be created later using `$domain` and API end point call
if (isset($this->options[CURLOPT_URL])) {
unset($this->options[CURLOPT_URL]);
}
if (isset($this->options[CURLOPT_USERPWD])) {
unset($this->options[CURLOPT_USERPWD]);
}
foreach ($this->options as $key => $value) {
$this->_curlOptions[$key] = $value;
}
$this->_curlOptions[CURLOPT_USERPWD] = "api:$this->apiKey";
}
/* * *************************************************************************
GETTERS and SETTERS
* ************************************************************************* */
/**
* Setter
*
* @param string $value pathLayouts
*/
public function setPathLayouts($value) {
if (!is_string($value) && !preg_match("/[a-z0-9\.]/i", $value)) {
throw new CException('MailGun: pathLayouts must be a Yii alias path');
}
$this->pathLayouts = $value;
}
/**
* Getter
*
* @return string pathLayouts
*/
public function getPathLayouts() {
return $this->pathLayouts;
}
/**
* Setter
*
* @param string $value pathViews
*/
public function setPathViews($value) {
if (!is_string($value) && !preg_match("/[a-z0-9\.]/i", $value)) {
throw new CException('MailGun: pathViews must be a Yii alias path');
}
$this->pathViews = $value;
}
/**
* Getter
*
* @return string pathViews
*/
public function getPathViews() {
return $this->pathViews;
}
/**
* Displays an e-mail in preview mode.
*
* @param string $view the class
* @param array $vars Controller->renderPartial() options
* @param string $layout
*/
public function getView($view, $vars = array(), $layout = null) {
$controller = Yii::app()->controller;
$body = $controller->renderPartial($this->pathViews . '.' . $view, $vars, true);
if ($layout === null) {
return $body;
}
return $controller->renderPartial($this->pathLayouts . '.' . $layout, array('content' => $body), true);
}
/* * *************************************************************************
MailGun API call methods
* ************************************************************************* */
/**
* Send Email
*
* @param string $to Send emails to. comma seperate email address for multiple
* receipients
* @param string $subject Subject of the Email
* @param string $html_body HTML Body of the email
* @param array $extras options
* <ul>
* <li><strong>from:</strong> Sender Email ID</li>
* <li><strong>text:</strong> Alternate email in simple text format</li>
* <li><strong>tags:</strong> Tag the email with comma seperated value</li>
* </ul>
* for more options please check MailGun API Reference:
* <a href="https://documentation.mailgun.com/api-sending.html#sending">
* https://documentation.mailgun.com/api-sending.html#sending
* </a>
*/
public function send($to, $subject, $html_body, $extras = array()) {
try {
$this->_curlOptions[CURLOPT_URL] = $this->getApiUrl('messages');
$this->_ch = curl_init($this->_curlOptions[CURLOPT_URL]);
$fields = array(
"from" => $this->defaultFromEmail,
);
if (isset($extras['from']) && !empty($extras['from'])) {
$fields['from'] = & $extras['from'];
}
if (empty($fields['from'])) {
throw new CException('MailGun: Send Email address can not be null');
}
if (empty($to) || strlen($to) < 5) {
throw new CException('MailGun: Receipients can not be empty');
}
$fields['to'] = & $to;
$fields['subject'] = & $subject;
if (!empty($html_body) && strlen($html_body) >= 5) {
$fields['html'] = & $html_body;
}
if (isset($extras['text']) && !empty($extras['text'])) {
$fields['text'] = & $extras['text'];
} elseif (isset($fields['html'])) {
$fields['text'] = strip_tags($fields['html']);
}
if (isset($extras['tags']) && !empty($extras['tags'])) {
$fields['o:tag'] = & $extras['tags'];
}
if (isset($extras['attachment']) && !empty($extras['attachment'])) {
$attachment = $extras['attachment'];
// For older version of PHP, which does not supports PHPFILE for upload
$fields['attachment'] = "@{$attachment['file']};filename={$attachment['name']};type={$attachment['mime_type']}";
// PHP 5.5 introduced a CurlFile object that deprecates the old @filename syntax
// See: https://wiki.php.net/rfc/curl-file-upload
if (function_exists('curl_file_create')) {
$fields['attachment'] = curl_file_create($attachment['file'], $attachment['mime_type'], $attachment['name']);
}
unset($extras['attachment']);
}
$fields = CMap::mergeArray($fields, $extras);
$this->_curlOptions[CURLOPT_POSTFIELDS] = $fields;
curl_setopt_array($this->_ch, $this->_curlOptions);
$response_with_headers = curl_exec($this->_ch);
curl_close($this->_ch);
return $response_with_headers;
} catch (Exception $e) {
}
return NULL;
}
private function getApiUrl($action) {
return $this->mailGunApiURL . $this->domain . "/$action";
}
/**
* This action allows you to create, access, and validate domains
* programmatically.
*/
public function domains() {
$this->_curlOptions[CURLOPT_URL] = $this->getApiUrl('domains');
}
/**
* Mailgun allows you to quickly add “Unsubscribe me” feature to your
* outgoing emails without any programming on your end. You can enable
* this in your Control Panel under your domain settings.
*/
public function unsubscribes() {
$this->_curlOptions[CURLOPT_URL] = $this->getApiUrl('unsubscribes');
}
/**
* This API allows you to programmatically download the list of users
* who have complained, add a complaint, or delete a complaint.
*/
public function complaints() {
$this->_curlOptions[CURLOPT_URL] = $this->getApiUrl('complaints');
}
/**
* The list of bounced addresses can be accessed programmatically:
*/
public function bounces() {
$this->_curlOptions[CURLOPT_URL] = $this->getApiUrl('bounces');
}
/**
* Mailgun collects many different events and generates event statistics
* which are available in your Control Panel.
*/
public function stats() {
$this->_curlOptions[CURLOPT_URL] = $this->getApiUrl('stats');
}
/**
* Mailgun tracks every event that happens to your emails and makes this
* data available to you through the Events API.
*/
public function events() {
$this->_curlOptions[CURLOPT_URL] = $this->getApiUrl('events');
}
/**
* Mailgun Routes are a powerful way to handle the incoming traffic.
*/
public function routes() {
$this->_curlOptions[CURLOPT_URL] = $this->getApiUrl('routes');
}
/**
* Unlike other email platforms Mailgun analytics is not limited to
* campaigns sent to the mailing lists. You can generate powerful reports
* and analytize data for any subset of your email traffic: just create an
* email campaign and specify that campaign’s ID when sending a message.
*/
public function campaigns() {
$this->_curlOptions[CURLOPT_URL] = $this->getApiUrl('campaigns');
}
/**
* This API allows you to create, access, and delete webhooks programmatically.
*/
public function webhooks() {
$this->_curlOptions[CURLOPT_URL] = $this->getApiUrl('webhooks');
}
/**
* You can programmatically create mailing lists using Mailgun Mailing
* List API. A mailing list is a group of members (recipients) which itself
* has an email address, like developers@mailgun.net. This address becomes
* an ID for this mailing list.
*/
public function lists() {
$this->_curlOptions[CURLOPT_URL] = $this->getApiUrl('lists');
}
/**
* This API endpoint is an email address validation service.
* Given an arbitrary address, we will validate the address based on:
*/
public function address_validate() {
$this->_curlOptions[CURLOPT_URL] = $this->getApiUrl('address/validate');
}
}
@vin-ai
Copy link
Author

vin-ai commented Oct 23, 2015

Configure MailGun to Yii PHP Framework:

Create a mailgun component to config/main.php as below:

return array(
    // ...
    'components' => array(
        // ...
        'mailgun' => array(
            'class' => 'application.components.MailGun',
            'domain' => 'example.com',
            'apiKey' => 'key-xxxxxxxxxxxxxxxxxxxxx-xxxxxxx',
            'defaultFromEmail' => 'Sender Name <no-reply@example.com>',
            'pathLayouts' => 'application.views.layouts.emailer',
            'pathViews' => 'application.views.partials',
        ),
        // ...
    )
);

And Use:

// Get MailGun component object
$mg = Yii::app()->mailgun;
// Generate Email body HTML from template
$body = $mg->getView('__emailer_your_email_template', $array_data_to_pass_in_template);
// [OPTIONAL] Extra data to pass to MailGun
$extras = array(
    'attachment' => array(
        'file' => $attachment,
        'name' => $file_name,
        'mime_type' => $file_mime_type,
    )
);

$to = 'sendto@example.com'
$subject = 'Testing some awesomeness!'

// Now trigger send, and capture json response
$response = $mg->send($to, $subject, $body, $extras);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment