├── .gitignore ├── LICENSE ├── README.md └── app ├── code └── community │ └── FreeLunchLabs │ └── MailGun │ ├── Block │ └── Adminhtml │ │ ├── Customer │ │ ├── Email.php │ │ ├── Email │ │ │ └── Grid.php │ │ └── Tab │ │ │ └── Mailgun.php │ │ ├── Emailtracking.php │ │ ├── Event │ │ ├── Container.php │ │ ├── Grid.php │ │ └── Renderer │ │ │ ├── Timestamp.php │ │ │ └── Type.php │ │ └── Global │ │ ├── Container.php │ │ └── Grid.php │ ├── Helper │ └── Data.php │ ├── Model │ ├── Email.php │ ├── Email │ │ └── Template.php │ ├── Event.php │ ├── Exceptions │ │ ├── InvalidParameter.php │ │ ├── InvalidParameterType.php │ │ ├── MissingRequiredMIMEParameters.php │ │ └── TooManyParameters.php │ ├── Mailgun.php │ ├── Messagebuilder.php │ └── Resource │ │ ├── Email.php │ │ ├── Email │ │ └── Collection.php │ │ ├── Event.php │ │ └── Event │ │ └── Collection.php │ ├── controllers │ └── Adminhtml │ │ └── EmailtrackingController.php │ ├── etc │ ├── config.xml │ └── system.xml │ └── sql │ └── mailgun_setup │ ├── mysql4-install-1.0.0.php │ ├── mysql4-upgrade-1.0.0-1.0.1.php │ └── mysql4-upgrade-1.0.1-1.0.2.php ├── design └── adminhtml │ └── default │ └── default │ ├── layout │ └── mailgun.xml │ └── template │ └── mailgun │ ├── customer │ └── tab │ │ └── tab.phtml │ ├── emaildetail.phtml │ └── globalemailgrid.phtml └── etc └── modules └── FreeLunchLabs_MailGun.xml /.gitignore: -------------------------------------------------------------------------------- 1 | .modgit/ 2 | app/code/community/Find/ 3 | app/code/community/Phoenix/ 4 | app/code/community/Cm/ 5 | app/code/core/ 6 | app/design/adminhtml/default/default/ 7 | app/design/adminhtml/default/find/ 8 | app/design/frontend/base/ 9 | app/design/frontend/default/blank/ 10 | app/design/frontend/default/default/ 11 | app/design/frontend/default/iphone/ 12 | app/design/frontend/default/modern/ 13 | app/design/frontend/enterprise/default 14 | app/design/install/ 15 | app/etc/modules/Enterprise_* 16 | app/etc/modules/Find_Feed.xml 17 | app/etc/modules/Mage_All.xml 18 | app/etc/modules/Mage_Api.xml 19 | app/etc/modules/Mage_Api2.xml 20 | app/etc/modules/Mage_Authorizenet.xml 21 | app/etc/modules/Mage_Bundle.xml 22 | app/etc/modules/Mage_Captcha.xml 23 | app/etc/modules/Mage_Centinel.xml 24 | app/etc/modules/Mage_Compiler.xml 25 | app/etc/modules/Mage_Connect.xml 26 | app/etc/modules/Mage_CurrencySymbol.xml 27 | app/etc/modules/Mage_Downloadable.xml 28 | app/etc/modules/Mage_ImportExport.xml 29 | app/etc/modules/Mage_LoadTest.xml 30 | app/etc/modules/Mage_Oauth.xml 31 | app/etc/modules/Mage_PageCache.xml 32 | app/etc/modules/Mage_Persistent.xml 33 | app/etc/modules/Mage_Weee.xml 34 | app/etc/modules/Mage_Widget.xml 35 | app/etc/modules/Mage_XmlConnect.xml 36 | app/etc/modules/Phoenix_Moneybookers.xml 37 | app/etc/modules/Cm_RedisSession.xml 38 | app/etc/applied.patches.list 39 | app/etc/config.xml 40 | app/etc/enterprise.xml 41 | app/etc/local.xml.additional 42 | app/etc/local.xml.template 43 | app/etc/local.xml 44 | app/.htaccess 45 | app/locale/ 46 | app/Mage.php 47 | cron.php 48 | cron.sh 49 | downloader/ 50 | errors/ 51 | favicon.ico 52 | get.php 53 | includes/ 54 | index.php 55 | index.php.sample 56 | /install.php 57 | js/blank.html 58 | js/calendar/ 59 | js/enterprise/ 60 | js/extjs/ 61 | js/firebug/ 62 | js/flash/ 63 | js/index.php 64 | js/jscolor/ 65 | js/lib/ 66 | js/mage/ 67 | js/prototype/ 68 | js/scriptaculous/ 69 | js/spacer.gif 70 | js/tiny_mce/ 71 | js/varien/ 72 | lib/3Dsecure/ 73 | lib/Apache/ 74 | lib/flex/ 75 | lib/googlecheckout/ 76 | lib/.htaccess 77 | lib/LinLibertineFont/ 78 | lib/Mage/ 79 | lib/PEAR/ 80 | lib/phpseclib/ 81 | lib/Varien/ 82 | lib/Zend/ 83 | lib/Cm/ 84 | lib/Credis/ 85 | lib/Magento/ 86 | LICENSE_AFL.txt 87 | LICENSE.html 88 | LICENSE.txt 89 | LICENSE_EE* 90 | mage 91 | media/customer/ 92 | media/dhl/ 93 | media/downloadable/ 94 | media/.htaccess 95 | media/import/ 96 | media/xmlconnect/ 97 | media/catalog/product/cache/ 98 | api.php 99 | nbproject/ 100 | pear 101 | pear/ 102 | php.ini.sample 103 | pkginfo/ 104 | RELEASE_NOTES.txt 105 | shell/abstract.php 106 | shell/compiler.php 107 | shell/indexer.php 108 | shell/log.php 109 | skin/adminhtml/default/default/ 110 | skin/adminhtml/default/enterprise 111 | skin/frontend/base/ 112 | skin/frontend/default/blank/ 113 | skin/frontend/default/blue/ 114 | skin/frontend/default/default/ 115 | skin/frontend/default/french/ 116 | skin/frontend/default/german/ 117 | skin/frontend/default/iphone/ 118 | skin/frontend/default/modern/ 119 | skin/frontend/enterprise 120 | skin/install/ 121 | var/ 122 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 chuckdrew 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | mailgun_magento 2 | =============== 3 | 4 | Avoid spam folders, track opens, clicks, bounces, and spam reports. This Magento extension configures your store to send all transactional emails via Mailgun. Mailgun optimizes your emails so they are sure to reach your customers inbox. The extension uses Mailgun's Web API (rather than the SMTP API) so it will work on hosts (HostGator, SiteGround, BlueHost, etc) that block 3rd party SMTP services. 5 | -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Customer/Email.php: -------------------------------------------------------------------------------- 1 | _blockGroup = 'freelunchlabs_mailgun'; 9 | $this->_controller = 'adminhtml_customer_email'; 10 | $this->_headerText = false; 11 | 12 | } 13 | } -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Customer/Email/Grid.php: -------------------------------------------------------------------------------- 1 | setId('mailgun_email_grid'); 8 | $this->setDefaultSort('id'); 9 | $this->setDefaultDir('ASC'); 10 | $this->setUseAjax(true); 11 | $this->setFilterVisibility(true); 12 | } 13 | 14 | protected function _prepareCollection() { 15 | $collection = Mage::getResourceModel('freelunchlabs_mailgun/email_collection')->getGridCollection(); 16 | 17 | //Filter on Customer 18 | $collection->addFieldToFilter('customer_id', Mage::registry('current_customer')->getId()); 19 | 20 | $this->setCollection($collection); 21 | return parent::_prepareCollection(); 22 | } 23 | 24 | protected function _prepareColumns() { 25 | 26 | $this->addColumn('subject', array( 27 | 'header' => 'Subject', 28 | 'type' => 'text', 29 | 'index' => 'subject' 30 | )); 31 | 32 | $this->addColumn('mailgun_id', array( 33 | 'header' => 'Mailgun ID', 34 | 'type' => 'text', 35 | 'index' => 'mailgun_id' 36 | )); 37 | 38 | $this->addColumn('current_status', array( 39 | 'header' => 'Latest Status', 40 | 'index' => 'current_status', 41 | 'renderer' => 'FreeLunchLabs_MailGun_Block_Adminhtml_Event_Renderer_Type' 42 | )); 43 | 44 | $this->addColumn('date_sent', array( 45 | 'header' => 'Date Sent', 46 | 'type' => 'datetime', 47 | 'index' => 'date_sent' 48 | )); 49 | 50 | return parent::_prepareColumns(); 51 | } 52 | 53 | public function getRowUrl($row) { 54 | return $this->getUrl('*/emailtracking/emaildetail', array( 55 | 'id' => $row->getId() 56 | )); 57 | } 58 | 59 | public function getGridUrl() { 60 | return $this->getUrl('*/emailtracking/emailgrid', array( 61 | '_current' => true, 62 | 'id' => Mage::registry('current_customer')->getId() 63 | )); 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Customer/Tab/Mailgun.php: -------------------------------------------------------------------------------- 1 | setTemplate('mailgun/customer/tab/tab.phtml'); 9 | } 10 | 11 | public function getTabLabel() { 12 | return $this->__('Email Tracking'); 13 | } 14 | 15 | public function getTabTitle() { 16 | return $this->__('View emails sent to this customer and the email history'); 17 | } 18 | 19 | public function canShowTab() { 20 | return Mage::getStoreConfig('mailgun/events/store'); 21 | } 22 | 23 | public function isHidden() { 24 | return false; 25 | } 26 | 27 | public function getAfter() { 28 | return 'tags'; 29 | } 30 | 31 | public function getGrid() { 32 | $gridBlock = $this->getLayout()->createBlock('freelunchlabs_mailgun/adminhtml_customer_email'); 33 | 34 | return $gridBlock->getGridHtml(); 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Emailtracking.php: -------------------------------------------------------------------------------- 1 | getUrl('*/*/getEmailEvents'); 7 | } 8 | 9 | public function getEmailDetail() { 10 | $email = Mage::registry('current_email'); 11 | 12 | if ($email->getCustomerId()) { 13 | $customer = Mage::getModel('customer/customer')->load($email->getCustomerId()); 14 | $email->setCustomer($customer); 15 | } 16 | 17 | return $email; 18 | } 19 | 20 | public function getBackButtonHtml() { 21 | return $this->getLayout()->createBlock('adminhtml/widget')->getButtonHtml('Back', 'history.back()', 'back'); 22 | } 23 | 24 | public function getViewEmailBodyButtonHtml($emailId) { 25 | $url = $this->getUrl('*/*/emailView', array( 26 | 'id' => $emailId 27 | )); 28 | 29 | $onClick = "window.open('{$url}','name','width=700,height=800')"; 30 | 31 | return $this->getLayout()->createBlock('adminhtml/widget')->getButtonHtml('View Email Body', $onClick); 32 | } 33 | 34 | public function getEditCustomerUrl($customerId) { 35 | return $url = $this->getUrl('*/customer/edit', array( 36 | 'id' => $customerId 37 | )); 38 | } 39 | 40 | public function getCustomerGroupName($customerGroupId) { 41 | return Mage::getModel('customer/group')->load($customerGroupId)->getCustomerGroupCode(); 42 | } 43 | 44 | public function formatCustomerCreateDate($createdTimestamp) { 45 | return Mage::helper('core')->formatDate($createdTimestamp, Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM, true); 46 | } 47 | 48 | public function getFetch24HoursOfEmailActivityButton() { 49 | $onClick = "setLocation('{$this->getFetchActivityUrl()}')"; 50 | 51 | return $this->getLayout()->createBlock('adminhtml/widget')->getButtonHtml('Fetch Past 24 Hours of Email Activity', $onClick); 52 | } 53 | 54 | public function getDeleteEmailTrackingLogsDaysButton() { 55 | $days = Mage::getStoreConfig('mailgun/events/days'); 56 | 57 | if ($days) { 58 | $url = $this->getUrl('*/*/deleteEmailTrackingLogsDays'); 59 | $onClick = "confirmSetLocation('Are you sure?', '{$url}')"; 60 | 61 | return $this->getLayout()->createBlock('adminhtml/widget')->getButtonHtml("Delete Email Records Older Than {$days} Days", $onClick, 'delete'); 62 | } else { 63 | return ""; 64 | } 65 | } 66 | 67 | public function getDeleteAllEmailTrackingLogsButton() { 68 | $url = $this->getUrl('*/*/deleteEmailTrackingLogs'); 69 | $onClick = "confirmSetLocation('Are you sure?', '{$url}')"; 70 | 71 | return $this->getLayout()->createBlock('adminhtml/widget')->getButtonHtml('Delete All Email Records', $onClick, 'delete'); 72 | } 73 | 74 | } 75 | 76 | -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Container.php: -------------------------------------------------------------------------------- 1 | _blockGroup = 'freelunchlabs_mailgun'; 9 | $this->_controller = 'adminhtml_event'; 10 | $this->_headerText = false; 11 | 12 | } 13 | } -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Grid.php: -------------------------------------------------------------------------------- 1 | setId('mailgun_event_grid'); 8 | $this->setDefaultSort('timestamp'); 9 | $this->setDefaultDir('ASC'); 10 | $this->setUseAjax(false); 11 | $this->setFilterVisibility(false); 12 | } 13 | 14 | protected function _prepareCollection() { 15 | $collection = Mage::getResourceModel('freelunchlabs_mailgun/event_collection'); 16 | $collection->addFieldToFilter('email_id', Mage::registry('current_email')->getId()); 17 | 18 | $this->setCollection($collection); 19 | return parent::_prepareCollection(); 20 | } 21 | 22 | protected function _prepareColumns() { 23 | 24 | $this->addColumn('event_type', array( 25 | 'header' => 'Event', 26 | 'index' => 'event_type', 27 | 'renderer' => 'FreeLunchLabs_MailGun_Block_Adminhtml_Event_Renderer_Type' 28 | )); 29 | 30 | $this->addColumn('timestamp', array( 31 | 'header' => 'Event Time', 32 | 'index' => 'timestamp', 33 | 'renderer' => 'FreeLunchLabs_MailGun_Block_Adminhtml_Event_Renderer_Timestamp' 34 | )); 35 | 36 | return parent::_prepareColumns(); 37 | } 38 | 39 | public function getRowUrl($row) { 40 | return null; 41 | } 42 | 43 | public function getGridUrl() { 44 | return $this->getUrl('*/emailTracking/emailDetail', array( 45 | '_current' => true, 46 | 'id' => Mage::registry('current_email')->getId() 47 | )); 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Renderer/Timestamp.php: -------------------------------------------------------------------------------- 1 | getData($this->getColumn()->getIndex()); 7 | $date = Mage::getSingleton('core/date')->timestamp($value); 8 | return Mage::helper('core')->formatDate(new Zend_Date($date), 'medium', true); 9 | } 10 | } -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Renderer/Type.php: -------------------------------------------------------------------------------- 1 | getData($this->getColumn()->getIndex()); 7 | return ucwords($value); 8 | } 9 | } -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Global/Container.php: -------------------------------------------------------------------------------- 1 | _blockGroup = 'freelunchlabs_mailgun'; 9 | $this->_controller = 'adminhtml_global'; 10 | $this->_headerText = false; 11 | 12 | } 13 | } -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Global/Grid.php: -------------------------------------------------------------------------------- 1 | setId('mailgun_global_grid'); 8 | $this->setDefaultSort('date_sent'); 9 | $this->setDefaultDir('ASC'); 10 | $this->setUseAjax(false); 11 | $this->setFilterVisibility(true); 12 | } 13 | 14 | protected function _prepareCollection() { 15 | $collection = Mage::getResourceModel('freelunchlabs_mailgun/email_collection')->getGridCollection(); 16 | 17 | $this->setCollection($collection); 18 | return parent::_prepareCollection(); 19 | } 20 | 21 | protected function _prepareColumns() { 22 | 23 | $this->addColumn('subject', array( 24 | 'header' => 'Subject', 25 | 'type' => 'text', 26 | 'index' => 'subject' 27 | )); 28 | 29 | $this->addColumn('email_address', array( 30 | 'header' => 'Recipient Address', 31 | 'type' => 'email', 32 | 'index' => 'email_address' 33 | )); 34 | 35 | $this->addColumn('mailgun_id', array( 36 | 'header' => 'Mailgun ID', 37 | 'type' => 'text', 38 | 'index' => 'mailgun_id' 39 | )); 40 | 41 | $this->addColumn('current_status', array( 42 | 'header' => 'Latest Status', 43 | 'index' => 'current_status', 44 | 'renderer' => 'FreeLunchLabs_MailGun_Block_Adminhtml_Event_Renderer_Type' 45 | )); 46 | 47 | $this->addColumn('date_sent', array( 48 | 'header' => 'Date Sent', 49 | 'type' => 'datetime', 50 | 'index' => 'date_sent' 51 | )); 52 | 53 | return parent::_prepareColumns(); 54 | } 55 | 56 | public function getRowUrl($row) { 57 | return $this->getUrl('*/emailtracking/emaildetail', array( 58 | 'id' => $row->getId() 59 | )); 60 | } 61 | 62 | public function getGridUrl() { 63 | return $this->getUrl('*/emailtracking'); 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Helper/Data.php: -------------------------------------------------------------------------------- 1 | _init('freelunchlabs_mailgun/email'); 7 | } 8 | 9 | public function saveInitialSend($message, $sendResponse) { 10 | $customer = Mage::getModel('customer/customer'); 11 | $customer->setWebsiteId($message->getStore()->getWebsite()->getId()); 12 | $customer->loadByEmail($message->getPrimaryRecipient()); 13 | 14 | if ($customer) { 15 | $this->setCustomerId($customer->getId()); 16 | } 17 | 18 | $this->setEmailAddress($message->getPrimaryRecipient()); 19 | $this->setMailgunId(str_replace(array("<", ">"), "", $sendResponse->id)); 20 | $this->setSubject($message->getSubject()); 21 | $this->setBody($message->getHtmlBody()); 22 | $this->setDateSent(Mage::getSingleton('core/date')->gmtTimestamp()); 23 | $this->save(); 24 | 25 | Mage::getModel('freelunchlabs_mailgun/event')->logEmailEvent($this->getId(), FreeLunchLabs_MailGun_Model_Event::GENERATED, $this); 26 | } 27 | 28 | public function loadByMailgunIdAndRecipient($mailgunId, $recipient) { 29 | $collection = $this->getCollection(); 30 | $collection->addFieldToFilter('mailgun_id', $mailgunId); 31 | $collection->addFieldToFilter('email_address', $recipient); 32 | 33 | return $collection->getFirstItem(); 34 | } 35 | 36 | public function deleteEmailTrackingLogsDays() { 37 | $days = Mage::getStoreConfig('mailgun/events/days'); 38 | 39 | if ($days) { 40 | $this->deleteEmailTrackingLogs($days); 41 | } 42 | } 43 | 44 | public function deleteEmailTrackingLogs($days = false) { 45 | $this->getResource()->deleteEmailTrackingLogs($days); 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Model/Email/Template.php: -------------------------------------------------------------------------------- 1 | getDesignConfig()->getStore()) { 14 | $store = Mage::getModel('core/store')->load($this->getDesignConfig()->getStore()); 15 | } else { 16 | $store = Mage::app()->getStore(); 17 | } 18 | 19 | if ($store->getConfig('mailgun/general/active')) { 20 | if (!$this->isValidForSend()) { 21 | Mage::logException(new Exception('This letter cannot be sent.')); 22 | return false; 23 | } 24 | 25 | $message = Mage::getModel('freelunchlabs_mailgun/messagebuilder'); 26 | 27 | //Recipient(s) 28 | $emails = array_values((array) $email); 29 | $names = is_array($name) ? $name : (array) $name; 30 | $names = array_values($names); 31 | foreach ($emails as $key => $email) { 32 | if (!isset($names[$key])) { 33 | $names[$key] = substr($email, 0, strpos($email, '@')); 34 | } 35 | } 36 | 37 | $variables['email'] = reset($emails); 38 | $variables['name'] = reset($names); 39 | 40 | //Add To Recipients 41 | $isPrimary = true; 42 | foreach ($emails as $key => $email) { 43 | if($isPrimary) { 44 | //Add primary recipient 45 | $message->setPrimaryRecipient($email); 46 | } 47 | $isPrimary = false; 48 | 49 | $message->addToRecipient($names[$key] . " <" . $email . ">"); 50 | } 51 | 52 | //Subject 53 | $subject = $this->getProcessedTemplateSubject($variables); 54 | $message->setSubject($subject); 55 | 56 | //From Name 57 | $message->setFromAddress($this->getSenderName() . " <" . $this->getSenderEmail() . ">"); 58 | 59 | //Bcc 60 | if (is_array($this->bcc)) { 61 | foreach ($this->bcc as $bcc_email) { 62 | $message->addBccRecipient($bcc_email); 63 | } 64 | } elseif ($this->bcc) { 65 | $message->addBccRecipient($this->bcc); 66 | } 67 | 68 | //Reply To 69 | if (!is_null($this->replyto)) { 70 | $message->setReplyToAddress($this->replyto); 71 | } 72 | 73 | //Message Body 74 | $this->setUseAbsoluteLinks(true); 75 | $processedTemplateBody = $this->getProcessedTemplate($variables, true); 76 | 77 | if ($this->isPlain()) { 78 | $message->setTextBody($processedTemplateBody); 79 | } else { 80 | $message->setHtmlBody($processedTemplateBody); 81 | } 82 | 83 | //Attachments 84 | if($this->getMail()->hasAttachments) { 85 | foreach($this->getMail()->getParts() as $part) { 86 | if($part->disposition == "attachment") { 87 | $message->addAttachment($part->filename, $part->getRawContent()); 88 | } 89 | } 90 | } 91 | 92 | //Add Unique Args 93 | $message->addCustomData("message_data", array('id' => 123456)); 94 | 95 | //Tag message with type 96 | $message->addTag($this->getTemplateId()); 97 | $message->addTag($store->getConfig('mailgun/general/tag')); 98 | 99 | if($store->getConfig('mailgun/events/opens')) { 100 | $message->setOpenTracking(true); 101 | } 102 | 103 | if($store->getConfig('mailgun/events/clicks')) { 104 | $message->setClickTracking(true); 105 | } 106 | 107 | //Set store 108 | $message->setStore($store); 109 | 110 | //Send it! 111 | try { 112 | Mage::getModel('freelunchlabs_mailgun/mailgun')->send($message); 113 | $this->_mail = null; 114 | } catch (Exception $e) { 115 | $this->_mail = null; 116 | Mage::logException($e); 117 | return false; 118 | } 119 | 120 | return true; 121 | } else { 122 | return parent::send($email, $name, $variables); 123 | } 124 | } 125 | 126 | public function addBcc($bcc) { 127 | $this->bcc = $bcc; 128 | return parent::addBcc($bcc); 129 | } 130 | 131 | public function setReturnPath($email) { 132 | $this->returnPath = $email; 133 | return parent::setReturnPath($email); 134 | 135 | } 136 | 137 | public function setReplyTo($email) { 138 | $this->replyto = $email; 139 | return parent::setReplyTo($email); 140 | } 141 | 142 | } -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Model/Event.php: -------------------------------------------------------------------------------- 1 | _init('freelunchlabs_mailgun/event'); 19 | } 20 | 21 | public function logEmailEvent($emailId, $eventType, $email = false) { 22 | $this->setEmailId($emailId); 23 | $this->setEventType($eventType); 24 | $this->setTimestamp(Mage::getSingleton('core/date')->gmtTimestamp()); 25 | $this->save(); 26 | } 27 | 28 | public function loadByTimestampAndEmailId($timestamp, $emailId) { 29 | $collection = $this->getCollection(); 30 | $collection->addFieldToFilter('timestamp', $timestamp); 31 | $collection->addFieldToFilter('email_id', $emailId); 32 | 33 | return $collection->getFirstItem(); 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/InvalidParameter.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/InvalidParameterType.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/MissingRequiredMIMEParameters.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/TooManyParameters.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Model/Mailgun.php: -------------------------------------------------------------------------------- 1 | setAuth("api", $apiKey); 11 | $client->setMethod($method); 12 | 13 | if($uriOveride) { 14 | $client->setUri($uriOveride); 15 | } else { 16 | $client->setUri($this->apiUrl . $domain . "/" . $type); 17 | } 18 | 19 | if($method == Zend_Http_Client::POST) { 20 | foreach($data as $key => $value) { 21 | $client->setParameterPost($key, $value); 22 | } 23 | } else { 24 | foreach($data as $key => $value) { 25 | $client->setParameterGet($key, $value); 26 | } 27 | } 28 | 29 | if($files) { 30 | foreach($files as $file) { 31 | $client->setFileUpload($file['filename'], $file['param'], $file['data']); 32 | } 33 | } 34 | 35 | try { 36 | $response = $client->request(); 37 | 38 | if($response->getStatus() == 200) { 39 | return json_decode($response->getBody()); 40 | } else { 41 | throw new Zend_Http_Exception("Error connecting to MailGun API. Returned error code: " . $response->getStatus() . " --- " . $response->getBody()); 42 | } 43 | } catch (Exception $e) { 44 | Mage::logException($e); 45 | return false; 46 | } 47 | } 48 | 49 | public function send($message) { 50 | 51 | $domain = $message->getStore()->getConfig('mailgun/general/domain'); 52 | $apiKey = $message->getStore()->getConfig('mailgun/general/key'); 53 | $files = null; 54 | 55 | if(count($message->getAttachments())) { 56 | foreach($message->getAttachments() as $attachment) { 57 | $files[] = $attachment; 58 | } 59 | } 60 | 61 | $sendResponse = $this->mailgunRequest('messages', $domain, $apiKey, $message->getMessage(), Zend_Http_Client::POST, false, $files); 62 | 63 | if($message->getStore()->getConfig('mailgun/events/store')) { 64 | Mage::getModel('freelunchlabs_mailgun/email')->saveInitialSend($message, $sendResponse); 65 | } 66 | 67 | return $sendResponse; 68 | } 69 | 70 | public function processEmailEventsForAllStores() { 71 | 72 | $stores = Mage::getModel('core/store')->getCollection(); 73 | 74 | foreach($stores as $store) { 75 | if($store->getConfig('mailgun/events/store')) { 76 | $this->processEmailEventsForSingleStore($store); 77 | } 78 | } 79 | } 80 | 81 | public function processEmailEventsForSingleStore(Mage_Core_Model_Store $store) { 82 | 83 | if($store->getConfig('mailgun/events/store')) { 84 | 85 | $data = array( 86 | 'end' => date("r", time() - 86400), 87 | 'tags' => $store->getConfig('mailgun/general/tag') 88 | ); 89 | 90 | $mailgunEvents = $this->mailgunRequest( 91 | 'events', 92 | $store->getConfig('mailgun/general/domain'), 93 | $store->getConfig('mailgun/general/key'), 94 | $data 95 | ); 96 | 97 | $events = $mailgunEvents->items; 98 | 99 | while (sizeof($mailgunEvents->items) > 0) { 100 | $mailgunEvents = $this->mailgunRequest( 101 | 'events', 102 | $store->getConfig('mailgun/general/domain'), 103 | $store->getConfig('mailgun/general/key'), 104 | $data, 105 | Zend_Http_Client::GET, 106 | $mailgunEvents->paging->next 107 | ); 108 | 109 | $events = array_merge($events, $mailgunEvents->items); 110 | } 111 | 112 | $this->storeEvents($events); 113 | } 114 | } 115 | 116 | public function storeEvents($events) { 117 | foreach($events as $mailgunEvent) { 118 | $email = Mage::getModel('freelunchlabs_mailgun/email')->loadByMailgunIdAndRecipient($mailgunEvent->message->headers->{'message-id'}, $mailgunEvent->recipient); 119 | 120 | if($email->getId()) { 121 | $event = Mage::getModel('freelunchlabs_mailgun/event')->loadByTimestampAndEmailId($mailgunEvent->timestamp, $email->getId()); 122 | 123 | if(!$event->getId()) { 124 | $event->setEmailId($email->getId()); 125 | $event->setEventType($mailgunEvent->event); 126 | $event->setTimestamp($mailgunEvent->timestamp); 127 | $event->save(); 128 | } 129 | } 130 | } 131 | } 132 | 133 | } -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Model/Messagebuilder.php: -------------------------------------------------------------------------------- 1 | array('to' => 0, 30 | 'cc' => 0, 31 | 'bcc' => 0), 32 | 'attributes' => array('attachment' => 0, 33 | 'campaign_id' => 0, 34 | 'custom_option' => 0, 35 | 'tag' => 0) 36 | ); 37 | 38 | protected function safeGet($params, $key, $default) { 39 | if (array_key_exists($key, $params)) { 40 | return $params[$key]; 41 | } 42 | return $default; 43 | } 44 | 45 | protected function getFullName($params) { 46 | if (array_key_exists("first", $params)) { 47 | $first = $this->safeGet($params, "first", ""); 48 | $last = $this->safeGet($params, "last", ""); 49 | return trim("$first $last"); 50 | } 51 | return $this->safeGet($params, "full_name", ""); 52 | } 53 | 54 | protected function parseAddress($address, $variables) { 55 | if (!is_array($variables)) { 56 | return $address; 57 | } 58 | $fullName = $this->getFullName($variables); 59 | if ($fullName != null) { 60 | return "'$fullName' <$address>"; 61 | } 62 | return $address; 63 | } 64 | 65 | protected function addRecipient($headerName, $address, $variables) { 66 | $compiledAddress = $this->parseAddress($address, $variables); 67 | 68 | if (isset($this->message[$headerName])) { 69 | array_push($this->message[$headerName], $compiledAddress); 70 | } elseif ($headerName == "h:reply-to") { 71 | $this->message[$headerName] = $compiledAddress; 72 | } else { 73 | $this->message[$headerName] = array($compiledAddress); 74 | } 75 | if (array_key_exists($headerName, $this->counters['recipients'])) { 76 | $this->counters['recipients'][$headerName] += 1; 77 | } 78 | } 79 | 80 | public function addToRecipient($address, $variables = null) { 81 | if ($this->counters['recipients']['to'] > self::RECIPIENT_COUNT_LIMIT) { 82 | throw new FreeLunchLabs_MailGun_Model_Exceptions_TooManyParameters(TOO_MANY_PARAMETERS_RECIPIENT); 83 | } 84 | $this->addRecipient("to", $address, $variables); 85 | return end($this->message['to']); 86 | } 87 | 88 | public function addCcRecipient($address, $variables = null) { 89 | if ($this->counters['recipients']['cc'] > self::RECIPIENT_COUNT_LIMIT) { 90 | throw new FreeLunchLabs_MailGun_Model_Exceptions_TooManyParameters(TOO_MANY_PARAMETERS_RECIPIENT); 91 | } 92 | $this->addRecipient("cc", $address, $variables); 93 | return end($this->message['cc']); 94 | } 95 | 96 | public function addBccRecipient($address, $variables = null) { 97 | if ($this->counters['recipients']['bcc'] > self::RECIPIENT_COUNT_LIMIT) { 98 | throw new FreeLunchLabs_MailGun_Model_Exceptions_TooManyParameters(TOO_MANY_PARAMETERS_RECIPIENT); 99 | } 100 | $this->addRecipient("bcc", $address, $variables); 101 | return end($this->message['bcc']); 102 | } 103 | 104 | public function setFromAddress($address, $variables = null) { 105 | $this->addRecipient("from", $address, $variables); 106 | return $this->message['from']; 107 | } 108 | 109 | public function setReplyToAddress($address, $variables = null) { 110 | $this->addRecipient("h:reply-to", $address, $variables); 111 | return $this->message['h:reply-to']; 112 | } 113 | 114 | public function setSubject($subject = NULL) { 115 | if ($subject == NULL || $subject == "") { 116 | $subject = " "; 117 | } 118 | $this->message['subject'] = $subject; 119 | return $this->message['subject']; 120 | } 121 | 122 | public function getSubject() { 123 | return $this->message['subject']; 124 | } 125 | 126 | public function addCustomHeader($headerName, $headerData) { 127 | if (!preg_match("/^h:/i", $headerName)) { 128 | $headerName = "h:" . $headerName; 129 | } 130 | $this->message[$headerName] = array($headerData); 131 | return $this->message[$headerName]; 132 | } 133 | 134 | public function setTextBody($textBody) { 135 | if ($textBody == NULL || $textBody == "") { 136 | $textBody = " "; 137 | } 138 | $this->message['text'] = $textBody; 139 | return $this->message['text']; 140 | } 141 | 142 | public function setHtmlBody($htmlBody) { 143 | if ($htmlBody == NULL || $htmlBody == "") { 144 | $htmlBody = " "; 145 | } 146 | $this->message['html'] = $htmlBody; 147 | return $this->message['html']; 148 | } 149 | 150 | public function getHtmlBody() { 151 | return isset($this->message['html']) ? $this->message['html'] : " "; 152 | } 153 | 154 | public function addAttachment($filename, $data) { 155 | if ($filename != null && $data != null) { 156 | $this->attachments[] = array( 157 | 'filename' => $filename, 158 | 'data' => $data, 159 | 'param' => 'attachment' 160 | ); 161 | return true; 162 | } else { 163 | throw new FreeLunchLabs_MailGun_Model_Exceptions_InvalidParameter(self::INVALID_PARAMETER_ATTACHMENT); 164 | } 165 | } 166 | 167 | public function addInlineImage($inlineImagePath, $inlineImageName = null) { 168 | if (preg_match("/^@/", $inlineImagePath)) { 169 | if (isset($this->files['inline'])) { 170 | $inlineAttachment = array('filePath' => $inlineImagePath, 171 | 'remoteName' => $inlineImageName); 172 | array_push($this->files['inline'], $inlineAttachment); 173 | } else { 174 | $this->files['inline'] = array(array('filePath' => $inlineImagePath, 175 | 'remoteName' => $inlineImageName)); 176 | } 177 | return true; 178 | } else { 179 | throw new FreeLunchLabs_MailGun_Model_Exceptions_InvalidParameter(self::INVALID_PARAMETER_INLINE); 180 | } 181 | } 182 | 183 | public function setTestMode($testMode) { 184 | if (filter_var($testMode, self::FILTER_VALIDATE_BOOLEAN)) { 185 | $testMode = "yes"; 186 | } else { 187 | $testMode = "no"; 188 | } 189 | $this->message['o:testmode'] = $testMode; 190 | return $this->message['o:testmode']; 191 | } 192 | 193 | public function addCampaignId($campaignId) { 194 | if ($this->counters['attributes']['campaign_id'] < self::CAMPAIGN_ID_LIMIT) { 195 | if (isset($this->message['o:campaign'])) { 196 | array_push($this->message['o:campaign'], $campaignId); 197 | } else { 198 | $this->message['o:campaign'] = array($campaignId); 199 | } 200 | $this->counters['attributes']['campaign_id'] += 1; 201 | return $this->message['o:campaign']; 202 | } else { 203 | throw new FreeLunchLabs_MailGun_Model_Exceptions_TooManyParameters(self::TOO_MANY_PARAMETERS_CAMPAIGNS); 204 | } 205 | } 206 | 207 | public function addTag($tag) { 208 | if ($this->counters['attributes']['tag'] < self::TAG_LIMIT) { 209 | if (isset($this->message['o:tag'])) { 210 | array_push($this->message['o:tag'], $tag); 211 | } else { 212 | $this->message['o:tag'] = array($tag); 213 | } 214 | $this->counters['attributes']['tag'] += 1; 215 | return $this->message['o:tag']; 216 | } else { 217 | throw new FreeLunchLabs_MailGun_Model_Exceptions_TooManyParameters(self::TOO_MANY_PARAMETERS_TAGS); 218 | } 219 | } 220 | 221 | public function setDkim($enabled) { 222 | if (filter_var($enabled, FILTER_VALIDATE_BOOLEAN)) { 223 | $enabled = "yes"; 224 | } else { 225 | $enabled = "no"; 226 | } 227 | $this->message["o:dkim"] = $enabled; 228 | return $this->message["o:dkim"]; 229 | } 230 | 231 | public function setOpenTracking($enabled) { 232 | if (filter_var($enabled, FILTER_VALIDATE_BOOLEAN)) { 233 | $enabled = "yes"; 234 | } else { 235 | $enabled = "no"; 236 | } 237 | $this->message['o:tracking-opens'] = $enabled; 238 | return $this->message['o:tracking-opens']; 239 | } 240 | 241 | public function setClickTracking($enabled) { 242 | if (filter_var($enabled, FILTER_VALIDATE_BOOLEAN)) { 243 | $enabled = "yes"; 244 | } elseif ($enabled == "html") { 245 | $enabled = "html"; 246 | } else { 247 | $enabled = "no"; 248 | } 249 | $this->message['o:tracking-clicks'] = $enabled; 250 | return $this->message['o:tracking-clicks']; 251 | } 252 | 253 | public function setDeliveryTime($timeDate, $timeZone = NULL) { 254 | if (isset($timeZone)) { 255 | $timeZoneObj = new DateTimeZone("$timeZone"); 256 | } else { 257 | $timeZoneObj = new DateTimeZone(self::DEFAULT_TIME_ZONE); 258 | } 259 | 260 | $dateTimeObj = new DateTime($timeDate, $timeZoneObj); 261 | $formattedTimeDate = $dateTimeObj->format(DateTime::RFC2822); 262 | $this->message['o:deliverytime'] = $formattedTimeDate; 263 | return $this->message['o:deliverytime']; 264 | } 265 | 266 | public function addCustomData($customName, $data) { 267 | if (is_array($data)) { 268 | $jsonArray = json_encode($data); 269 | $this->message['v:' . $customName] = $jsonArray; 270 | return $this->message['v:' . $customName]; 271 | } else { 272 | throw new FreeLunchLabs_MailGun_Model_Exceptions_InvalidParameter(self::INVALID_PARAMETER_NON_ARRAY); 273 | } 274 | } 275 | 276 | public function addCustomParameter($parameterName, $data) { 277 | if (isset($this->message[$parameterName])) { 278 | array_push($this->message[$parameterName], $data); 279 | return $this->message[$parameterName]; 280 | } else { 281 | $this->message[$parameterName] = array($data); 282 | return $this->message[$parameterName]; 283 | } 284 | } 285 | 286 | public function getMessage() { 287 | return $this->message; 288 | } 289 | 290 | public function getFiles() { 291 | return $this->files; 292 | } 293 | 294 | public function getAttachments() { 295 | return $this->attachments; 296 | } 297 | 298 | } -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Model/Resource/Email.php: -------------------------------------------------------------------------------- 1 | _init('freelunchlabs_mailgun/email', 'id'); 8 | } 9 | 10 | public function deleteEmailTrackingLogs($days = false) { 11 | if($days) { 12 | $daysPrior = date("Y-m-d H:i:s", Mage::getModel('core/date')->timestamp(time() - (86400 * $days))); 13 | $where = " WHERE date_sent < '{$daysPrior}'"; 14 | } else { 15 | $where = ""; 16 | } 17 | 18 | $query = "DELETE FROM {$this->getMainTable()}" . $where; 19 | 20 | Mage::getSingleton('core/resource') 21 | ->getConnection('core_write') 22 | ->query($query); 23 | 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Model/Resource/Email/Collection.php: -------------------------------------------------------------------------------- 1 | _init('freelunchlabs_mailgun/email'); 10 | } 11 | 12 | public function getGridCollection() { 13 | //Fields 14 | $this->addFieldToSelect('id'); 15 | $this->addFieldToSelect('subject'); 16 | $this->addFieldToSelect('email_address'); 17 | $this->addFieldToSelect('mailgun_id'); 18 | $this->addFieldToSelect('date_sent'); 19 | $this->addFieldToSelect('customer_id'); 20 | 21 | //Get latest status 22 | $this->getSelect()->joinLeft( 23 | array('me1' => Mage::getResourceModel('freelunchlabs_mailgun/event')->getMainTable()), 24 | 'main_table.id = me1.email_id', 25 | 'event_type as current_status' 26 | ); 27 | 28 | $this->getSelect()->joinLeft( 29 | array('me2' => Mage::getResourceModel('freelunchlabs_mailgun/event')->getMainTable()), 30 | '(main_table.id = me2.email_id AND (me1.timestamp < me2.timestamp OR me1.timestamp = me2.timestamp AND me1.id < me2.id))', 31 | false 32 | ); 33 | 34 | $this->getSelect()->where('me2.id IS NULL'); 35 | 36 | return $this; 37 | } 38 | } -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Model/Resource/Event.php: -------------------------------------------------------------------------------- 1 | _init('freelunchlabs_mailgun/event', 'id'); 8 | } 9 | 10 | } 11 | -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/Model/Resource/Event/Collection.php: -------------------------------------------------------------------------------- 1 | _init('freelunchlabs_mailgun/event'); 10 | } 11 | } -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/controllers/Adminhtml/EmailtrackingController.php: -------------------------------------------------------------------------------- 1 | _title($this->__('Customers'))->_title($this->__('Manage Customers')); 8 | 9 | $customerId = (int) $this->getRequest()->getParam($idFieldName); 10 | $customer = Mage::getModel('customer/customer'); 11 | 12 | if ($customerId) { 13 | $customer->load($customerId); 14 | } 15 | 16 | Mage::register('current_customer', $customer); 17 | return $this; 18 | } 19 | 20 | protected function _initEmail($idFieldName = 'id') { 21 | $emailId = (int) $this->getRequest()->getParam($idFieldName); 22 | $email = Mage::getModel('freelunchlabs_mailgun/email'); 23 | 24 | if ($emailId) { 25 | $email->load($emailId); 26 | } 27 | 28 | Mage::register('current_email', $email); 29 | return $this; 30 | } 31 | 32 | public function emailGridAction() 33 | { 34 | $this->_initCustomer(); 35 | $this->loadLayout(); 36 | $gridBlock = $this->getLayout()->createBlock('freelunchlabs_mailgun/adminhtml_customer_email'); 37 | 38 | $this->getResponse()->setBody($gridBlock->getGridHtml()); 39 | } 40 | 41 | public function indexAction() { 42 | $this->_title($this->__('System'))->_title($this->__('Email Tracking')); 43 | 44 | $this->loadLayout(); 45 | $this->_setActiveMenu('customer'); 46 | $this->renderLayout(); 47 | } 48 | 49 | public function emailDetailAction() { 50 | $this->_title($this->__('System'))->_title($this->__('Email Tracking - Detail')); 51 | 52 | $this->_initEmail(); 53 | 54 | $this->loadLayout(); 55 | $this->_setActiveMenu('customer'); 56 | $this->renderLayout(); 57 | } 58 | 59 | public function getEmailEventsAction() { 60 | Mage::getModel('freelunchlabs_mailgun/mailgun')->processEmailEventsForAllStores(); 61 | 62 | $this->_getSession()->addSuccess( 63 | Mage::helper('adminhtml')->__('Past 24 hours of email events fetched.') 64 | ); 65 | 66 | $this->_redirect('*/*'); 67 | } 68 | 69 | public function emailViewAction() { 70 | $this->_title($this->__('System'))->_title($this->__('Email Tracking - Detail - Email Body')); 71 | $this->_initEmail(); 72 | 73 | $this->getResponse()->setBody(Mage::registry('current_email')->getBody()); 74 | } 75 | 76 | public function deleteEmailTrackingLogsDaysAction() { 77 | Mage::getModel('freelunchlabs_mailgun/email')->deleteEmailTrackingLogsDays(); 78 | 79 | $this->_getSession()->addSuccess( 80 | Mage::helper('adminhtml')->__('Email records older than ' . Mage::getStoreConfig('mailgun/events/days') . ' days were deleted.') 81 | ); 82 | 83 | $this->_redirect('*/*'); 84 | } 85 | 86 | public function deleteEmailTrackingLogsAction() { 87 | Mage::getModel('freelunchlabs_mailgun/email')->deleteEmailTrackingLogs(); 88 | 89 | $this->_getSession()->addSuccess( 90 | Mage::helper('adminhtml')->__('All Email Records Were Deleted.') 91 | ); 92 | 93 | $this->_redirect('*/*'); 94 | } 95 | 96 | } -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/etc/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 1.0.2 6 | 7 | 8 | 9 | 10 | 11 | FreeLunchLabs_MailGun_Model 12 | freelunchlabs_mailgun_resource 13 | 14 | 15 | 16 | FreeLunchLabs_MailGun_Model_Email_Template 17 | 18 | 19 | 20 | FreeLunchLabs_MailGun_Model_Resource 21 | 22 | 23 | mailgun_email_tracking
24 |
25 | 26 | mailgun_email_tracking_event
27 |
28 |
29 |
30 |
31 | 32 | 33 | 34 | FreeLunchLabs_MailGun 35 | 36 | 37 | core_setup 38 | 39 | 40 | 41 | 42 | core_write 43 | 44 | 45 | 46 | 47 | core_read 48 | 49 | 50 | 51 | 52 | 53 | FreeLunchLabs_MailGun_Helper 54 | 55 | 56 | 57 | 58 | FreeLunchLabs_MailGun_Block 59 | 60 | 61 |
62 | 63 | 64 | 65 | 66 | 67 | FreeLunchLabs_MailGun_Adminhtml 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | Email Tracking 79 | 9999 80 | adminhtml/emailtracking 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | Email Tracking 93 | 70 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | MailGun Configuration 103 | 50 104 | 105 | 106 | 107 | 108 | Email Tracking 109 | 70 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | mailgun.xml 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 0 129 | magento-store 130 | 131 | 132 | 1 133 | 30 134 | 1 135 | 1 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 0,15,30,45 * * * * 144 | 145 | 146 | freelunchlabs_mailgun/email::deleteEmailTrackingLogsDays 147 | 148 | 149 | 150 | 151 | 0,15,30,45 * * * * 152 | 153 | 154 | freelunchlabs_mailgun/mailgun::processEmailEventsForAllStores 155 | 156 | 157 | 158 | 159 |
160 | -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/etc/system.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | separator-top 6 | 7 | general 8 | 110 9 | 1 10 | 1 11 | 1 12 | 13 | 14 | 15 | text 16 | 1 17 | 1 18 | 0 19 | 1 20 | 21 | 22 | 23 | select 24 | adminhtml/system_config_source_yesno 25 | 1 26 | 1 27 | 1 28 | 1 29 | 30 | 31 | 32 | password 33 | 3 34 | 1 35 | 1 36 | 1 37 | Your MailGun API Key 38 | 39 | 40 | 41 | text 42 | 4 43 | 1 44 | 1 45 | 1 46 | Your verified sending domain. For example, "example.com", "email.example.com" 47 | 48 | 49 | 50 | text 51 | 5 52 | 1 53 | 1 54 | 1 55 | For Administrative purposes only. This tag is used for filtering emails in MailGun. 56 | 57 | 58 | 59 | 60 | 61 | text 62 | 2 63 | 1 64 | 1 65 | 1 66 | 67 | 68 | 69 | select 70 | adminhtml/system_config_source_yesno 71 | 1 72 | 1 73 | 1 74 | 1 75 | Keep a record of all transactional emails sent. 76 | 77 | 78 | 79 | text 80 | 2 81 | 1 82 | 0 83 | 0 84 | Days to save email records. Leave blank for indefinitely. 85 | 86 | 87 | 88 | select 89 | adminhtml/system_config_source_yesno 90 | 3 91 | 1 92 | 1 93 | 1 94 | Keep track of every time a recipient clicks on links in your messages. Links will be overwritten and pointed to MailGun servers so they can track clicks. 95 | 96 | 97 | 98 | select 99 | adminhtml/system_config_source_yesno 100 | 4 101 | 1 102 | 1 103 | 1 104 | Keep track of every time a recipient opens your messages. Opens are tracked by including a transparent .png file in you email. 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/sql/mailgun_setup/mysql4-install-1.0.0.php: -------------------------------------------------------------------------------- 1 | startSetup(); 6 | 7 | $installer->run(" 8 | 9 | SET FOREIGN_KEY_CHECKS = 0; 10 | DROP TABLE IF EXISTS {$this->getTable('freelunchlabs_mailgun/email')}; 11 | DROP TABLE IF EXISTS {$this->getTable('freelunchlabs_mailgun/event')}; 12 | SET FOREIGN_KEY_CHECKS = 1; 13 | 14 | -- DROP TABLE IF EXISTS {$this->getTable('freelunchlabs_mailgun/email')}; 15 | CREATE TABLE {$this->getTable('freelunchlabs_mailgun/email')} ( 16 | `id` int(11) unsigned NOT NULL auto_increment, 17 | `customer_id` int(11) NULL, 18 | `mailgun_id` varchar(255) NOT NULL default '', 19 | `email_address` varchar(255) NOT NULL default '', 20 | `subject` text, 21 | `body` text, 22 | `date_sent` timestamp NOT NULL, 23 | PRIMARY KEY (`id`) 24 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 25 | 26 | -- DROP TABLE IF EXISTS {$this->getTable('freelunchlabs_mailgun/event')}; 27 | CREATE TABLE {$this->getTable('freelunchlabs_mailgun/event')} ( 28 | `id` int(11) unsigned NOT NULL auto_increment, 29 | `email_id` int(11) unsigned NULL, 30 | `event_type` varchar(255) NOT NULL default '', 31 | `timestamp` varchar(255), 32 | PRIMARY KEY (`id`), 33 | CONSTRAINT `fk_mailgun_event` FOREIGN KEY (`email_id`) REFERENCES `{$this->getTable('freelunchlabs_mailgun/email')}` (`id`) ON DELETE CASCADE 34 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 35 | 36 | "); 37 | 38 | $installer->endSetup(); -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/sql/mailgun_setup/mysql4-upgrade-1.0.0-1.0.1.php: -------------------------------------------------------------------------------- 1 | startSetup(); 6 | 7 | // do nothing! 8 | 9 | $installer->endSetup(); 10 | -------------------------------------------------------------------------------- /app/code/community/FreeLunchLabs/MailGun/sql/mailgun_setup/mysql4-upgrade-1.0.1-1.0.2.php: -------------------------------------------------------------------------------- 1 | startSetup(); 6 | 7 | $installer->run(" 8 | 9 | ALTER TABLE {$this->getTable('freelunchlabs_mailgun/event')} 10 | CHANGE `timestamp` `timestamp_old` varchar(255); 11 | 12 | ALTER TABLE {$this->getTable('freelunchlabs_mailgun/event')} 13 | ADD COLUMN `timestamp` timestamp; 14 | 15 | UPDATE {$this->getTable('freelunchlabs_mailgun/event')} 16 | SET `timestamp`=from_unixtime(`timestamp_old`+(((timediff(now(),convert_tz(now(),@@session.time_zone,'+00:00'))*-1)/10000)*60*60)); 17 | 18 | ALTER TABLE {$this->getTable('freelunchlabs_mailgun/event')} 19 | DROP COLUMN `timestamp_old`; 20 | 21 | "); 22 | 23 | $installer->endSetup(); 24 | -------------------------------------------------------------------------------- /app/design/adminhtml/default/default/layout/mailgun.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | customer_tab_mailgun 7 | freelunchlabs_mailgun/adminhtml_customer_tab_mailgun 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/design/adminhtml/default/default/template/mailgun/customer/tab/tab.phtml: -------------------------------------------------------------------------------- 1 | getGrid(); ?> -------------------------------------------------------------------------------- /app/design/adminhtml/default/default/template/mailgun/emaildetail.phtml: -------------------------------------------------------------------------------- 1 | getEmailDetail(); ?> 2 |
3 | 4 | 5 | 8 | 12 | 13 |
6 |

__('Email Details') ?>

7 |
9 | getBackButtonHtml(); ?> 10 | getViewEmailBodyButtonHtml($_emailDetail->getId()); ?> 11 |
14 |
15 |
16 |
17 |
18 | 19 |
20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
formatDate($_emailDetail->getDateSent(), 'full', true); ?>
getSubject(); ?>
getMailgunId(); ?>
getEmailAddress(); ?>
41 |
42 |
43 |
44 |
45 |
46 |
47 | 48 |
49 |
50 | getCustomer()): ?> 51 | 52 | 53 | 54 | 55 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 |
56 | 57 | getCustomer()->getName(); ?> 58 | 59 |
getCustomer()->getStore()->getName(); ?>
getCustomerGroupName($_emailDetail->getCustomer()->getGroupId()); ?>
formatCustomerCreateDate($_emailDetail->getCustomer()->getCreatedAt()); ?>
75 | 76 |

No Customer Data Available.

77 | 78 |
79 |
80 |
81 |
82 | 83 | 84 | 87 | 88 |
85 |

__('Email Events') ?>

86 |
89 |
90 | getLayout()->createBlock('freelunchlabs_mailgun/adminhtml_event_container')->getGridHtml(); ?> 91 | -------------------------------------------------------------------------------- /app/design/adminhtml/default/default/template/mailgun/globalemailgrid.phtml: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 7 | 12 | 13 |
5 |

__('Email Activity') ?>

6 |
8 | getFetch24HoursOfEmailActivityButton(); ?> 9 | getDeleteEmailTrackingLogsDaysButton(); ?> 10 | getDeleteAllEmailTrackingLogsButton(); ?> 11 |
14 |
15 | getLayout()->createBlock('freelunchlabs_mailgun/adminhtml_global_container')->getGridHtml(); ?> -------------------------------------------------------------------------------- /app/etc/modules/FreeLunchLabs_MailGun.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | true 6 | community 7 | 8 | 9 | 10 | --------------------------------------------------------------------------------