FreeLunchLabs_MailGun - Version 1.0.1

Version Notes

Stable Production Ready Release. Added support for sending email attachments.

Download this release

Release Info

Developer Charles Drew
Extension FreeLunchLabs_MailGun
Version 1.0.1
Comparing to
See all releases


Code changes from version 1.0.0 to 1.0.1

Files changed (23) hide show
  1. app/code/community/FreeLunchLabs/CloudFront/Block/Adminhtml/Cdnmanagement.php +53 -0
  2. app/code/community/FreeLunchLabs/CloudFront/Block/Adminhtml/Testconnection.php +29 -0
  3. app/code/community/FreeLunchLabs/CloudFront/Helper/Data.php +7 -0
  4. app/code/community/FreeLunchLabs/CloudFront/Model/Cloudfront.php +110 -0
  5. app/code/community/FreeLunchLabs/CloudFront/Model/Config.php +87 -0
  6. app/code/community/FreeLunchLabs/CloudFront/Model/Observer.php +11 -0
  7. app/code/community/FreeLunchLabs/CloudFront/Model/Refresh.php +137 -0
  8. app/code/community/FreeLunchLabs/CloudFront/Model/Refreshadapters/Apache.php +18 -0
  9. app/code/community/FreeLunchLabs/CloudFront/Model/Setup/Observer.php +25 -0
  10. app/code/community/FreeLunchLabs/CloudFront/Model/Store.php +47 -0
  11. app/code/community/FreeLunchLabs/CloudFront/controllers/Adminhtml/CdnmanagementController.php +53 -0
  12. app/code/community/FreeLunchLabs/CloudFront/controllers/Adminhtml/TestconnectionController.php +21 -0
  13. app/code/community/FreeLunchLabs/CloudFront/etc/config.xml +133 -0
  14. app/code/community/FreeLunchLabs/CloudFront/etc/system.xml +237 -0
  15. app/code/community/FreeLunchLabs/MailGun/Model/Email/Template.php +9 -0
  16. app/code/community/FreeLunchLabs/MailGun/Model/Mailgun.php +16 -3
  17. app/code/community/FreeLunchLabs/MailGun/Model/Messagebuilder.php +12 -10
  18. app/code/community/FreeLunchLabs/MailGun/etc/config.xml +1 -1
  19. app/code/community/FreeLunchLabs/SendGrid/Helper/Data.php +7 -0
  20. app/code/community/FreeLunchLabs/SendGrid/Model/Email/Template.php +160 -0
  21. app/code/community/FreeLunchLabs/SendGrid/etc/config.xml +59 -0
  22. app/code/community/FreeLunchLabs/SendGrid/etc/system.xml +53 -0
  23. package.xml +6 -6
app/code/community/FreeLunchLabs/CloudFront/Block/Adminhtml/Cdnmanagement.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class FreeLunchLabs_CloudFront_Block_Adminhtml_Cdnmanagement extends Mage_Adminhtml_Block_Template {
4
+
5
+ function isRefreshEnabled() {
6
+ if (Mage::getStoreConfig('cloudfront/general/refresh') && Mage::getStoreConfig('cloudfront/general/active')) {
7
+ return true;
8
+ } else {
9
+ return false;
10
+ }
11
+ }
12
+
13
+ function getRefreshAllLink() {
14
+ return $this->getUrl('*/*/refreshAll');
15
+ }
16
+
17
+ function getMediaRefreshLink() {
18
+ return $this->getUrl('*/*/refreshMedia');
19
+ }
20
+
21
+ function getSkinRefreshLink() {
22
+ return $this->getUrl('*/*/refreshSkin');
23
+ }
24
+
25
+ function getJsRefreshLink() {
26
+ return $this->getUrl('*/*/refreshJs');
27
+ }
28
+
29
+ function isMediaCdnEnabled() {
30
+ if (Mage::getStoreConfig('cloudfront/media/media')) {
31
+ return true;
32
+ } else {
33
+ return false;
34
+ }
35
+ }
36
+
37
+ function isSkinCdnEnabled() {
38
+ if (Mage::getStoreConfig('cloudfront/skin/skin')) {
39
+ return true;
40
+ } else {
41
+ return false;
42
+ }
43
+ }
44
+
45
+ function isJsCdnEnabled() {
46
+ if (Mage::getStoreConfig('cloudfront/js/js')) {
47
+ return true;
48
+ } else {
49
+ return false;
50
+ }
51
+ }
52
+
53
+ }
app/code/community/FreeLunchLabs/CloudFront/Block/Adminhtml/Testconnection.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class FreeLunchLabs_CloudFront_Block_Adminhtml_Testconnection extends Mage_Adminhtml_Block_System_Config_Form_Field {
4
+
5
+ protected function _prepareLayout() {
6
+ parent::_prepareLayout();
7
+ if (!$this->getTemplate()) {
8
+ $this->setTemplate('cloudfront/testconnection.phtml');
9
+ }
10
+ return $this;
11
+ }
12
+
13
+ public function render(Varien_Data_Form_Element_Abstract $element) {
14
+ $element->unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue();
15
+ return parent::render($element);
16
+ }
17
+
18
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) {
19
+
20
+ $this->addData(array(
21
+ 'button_label' => 'Create New Distribution',
22
+ 'html_id' => $element->getHtmlId(),
23
+ 'ajax_url' => Mage::getSingleton('adminhtml/url')->getUrl('*/testconnection/ping')
24
+ ));
25
+
26
+ return $this->_toHtml();
27
+ }
28
+
29
+ }
app/code/community/FreeLunchLabs/CloudFront/Helper/Data.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class FreeLunchLabs_CloudFront_Helper_Data extends Mage_Core_Helper_Abstract {
4
+
5
+ }
6
+
7
+ ?>
app/code/community/FreeLunchLabs/CloudFront/Model/Cloudfront.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class FreeLunchLabs_CloudFront_Model_CloudFront extends Varien_Object {
4
+
5
+ protected $_adapter;
6
+
7
+ public function __construct($args) {
8
+
9
+ if (!isset($args['key']) || !isset($args['secret'])) {
10
+ $args['key'] = Mage::getStoreConfig('cloudfront/general/key');
11
+ $args['secret'] = Mage::getStoreConfig('cloudfront/general/secret');
12
+ }
13
+
14
+ $args['certificate_authority'] = true;
15
+ define('AWS_DISABLE_CONFIG_AUTO_DISCOVERY', true);
16
+
17
+ require_once Mage::getBaseDir('lib') . DS . 'AWS' . DS . 'sdk.class.php';
18
+ $this->_adapter = new AmazonCloudFront($args);
19
+ }
20
+
21
+ public function createDistribution() {
22
+
23
+ $response = $this->_adapter->create_distribution($this->getOriginUrl(), $this->getCallerReference(), $this->getDistributionOptions());
24
+ $result = $this->processResponse($response);
25
+
26
+ return array(
27
+ "status" => $result['status'],
28
+ "message" => $result['message'],
29
+ "distribution" => $result['payload']['Id']
30
+ );
31
+ }
32
+
33
+ public function getDistribution() {
34
+ $distributionId = Mage::getStoreConfig('cloudfront/general/distribution');
35
+
36
+ $response = $this->_adapter->get_distribution_info($distributionId);
37
+ $result = $this->processResponse($response);
38
+
39
+ return $result;
40
+ }
41
+
42
+ private function getDistributionOptions() {
43
+
44
+ $distributionOptions = array(
45
+ 'Comment' => 'Free Lunch Labs / Magento CloudFront',
46
+ 'CachingBehavior' => array('MinTTL' => 7200),
47
+ 'OriginProtocolPolicy' => 'http-only'
48
+ );
49
+
50
+ return $distributionOptions;
51
+ }
52
+
53
+ private function getCallerReference() {
54
+ return "FLL_CloudFront_" . time();
55
+ }
56
+
57
+ private function getOriginUrlParts() {
58
+ if (is_null($this->getOrigin())) {
59
+ $orginConfig = Mage::getStoreConfig('cloudfront/general/origin');
60
+ } else {
61
+ $orginConfig = $this->getOrigin();
62
+ }
63
+
64
+ switch ($orginConfig) {
65
+ case "{{unsecure_base_url}}":
66
+ $orginConfig = Mage::getStoreConfig('web/unsecure/base_url');
67
+ break;
68
+ case "{{secure_base_url}}":
69
+ $orginConfig = Mage::getStoreConfig('web/secure/base_url');
70
+ break;
71
+ case "{{base_url}}":
72
+ $orginConfig = Mage::getStoreConfig('web/unsecure/base_url');
73
+ break;
74
+ }
75
+
76
+ return parse_url($orginConfig);
77
+ }
78
+
79
+ private function getOriginUrl() {
80
+ $parts = $this->getOriginUrlParts();
81
+
82
+ return $parts['scheme'] . "://" . $parts['host'];
83
+ }
84
+
85
+ public function getOriginPath() {
86
+ $parts = $this->getOriginUrlParts();
87
+
88
+ return $parts['path'];
89
+ }
90
+
91
+ private function processResponse($response) {
92
+
93
+ $result = array();
94
+
95
+ if ($response->isOK()) {
96
+ $result['status'] = true;
97
+ $result['message'] = "";
98
+ $result['payload'] = get_object_vars($response->body);
99
+ $result['enabled'] = (string) $response->body->DistributionConfig->Enabled;
100
+ } else {
101
+ $result['status'] = false;
102
+ $result['message'] = (string) $response->body->Error->Message;
103
+ $result['payload'] = "";
104
+ $result['enabled'] = "";
105
+ }
106
+
107
+ return $result;
108
+ }
109
+
110
+ }
app/code/community/FreeLunchLabs/CloudFront/Model/Config.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class FreeLunchLabs_CloudFront_Model_Config extends Varien_Object {
4
+
5
+ private $UnsecureMediaConfigPath = "cloudfront/unsecure/base_media_url";
6
+ private $UnsecureSkinConfigPath = "cloudfront/unsecure/base_skin_url";
7
+ private $UnsecureJsConfigPath = "cloudfront/unsecure/base_js_url";
8
+ private $SecureMediaConfigPath = "cloudfront/secure/base_media_url";
9
+ private $SecureSkinConfigPath = "cloudfront/secure/base_skin_url";
10
+ private $SecureJsConfigPath = "cloudfront/secure/base_js_url";
11
+
12
+ const IS_CLOUDFRONT_DISTRIBUTION_DEPLOYED = "cloudfront/general/deployed";
13
+
14
+ public function setCloudFrontConfig() {
15
+ $cloudfront = Mage::getModel('freelunchlabs_cloudfront/cloudfront');
16
+ $distribution = $cloudfront->getDistribution();
17
+
18
+ if ($distribution['payload']['Status'] == "Deployed" && $distribution['enabled'] == "true") {
19
+ if (Mage::getStoreConfig('cloudfront/media/media')) {
20
+ $this->setMediaConfig($distribution['payload']['DomainName'] . $cloudfront->getOriginPath());
21
+ }
22
+
23
+ if (Mage::getStoreConfig('cloudfront/skin/skin')) {
24
+ $this->setSkinConfig($distribution['payload']['DomainName'] . $cloudfront->getOriginPath());
25
+ }
26
+
27
+ if (Mage::getStoreConfig('cloudfront/js/js')) {
28
+ $this->setJsConfig($distribution['payload']['DomainName'] . $cloudfront->getOriginPath());
29
+ }
30
+
31
+ $this->setIsDeployedFlag();
32
+
33
+ if (Mage::getStoreConfig('cloudfront/general/refreshCache')) {
34
+ Mage::getModel('core/cache')->clean("CONFIG");
35
+ }
36
+ } else {
37
+ $this->removedIsDeployedFlag();
38
+ Mage::getSingleton('core/session')->addError('Your Cloud Front distribution is not enabled and deployed yet. Please wait 15 minutes and then try this action again.');
39
+ }
40
+ }
41
+
42
+ public function setMediaConfig($distribution_url) {
43
+ if ($distribution_url != "") {
44
+
45
+ $refresh_support = Mage::getModel('freelunchlabs_cloudfront/refresh');
46
+
47
+ $unsecure_media_url = "http://" . $distribution_url . $refresh_support->getRefreshURL('media') . Mage::getStoreConfig('cloudfront/media/media_path');
48
+ Mage::getModel('core/config')->saveConfig($this->UnsecureMediaConfigPath, $unsecure_media_url);
49
+
50
+ $secure_media_url = "https://" . $distribution_url . $refresh_support->getRefreshURL('media') . Mage::getStoreConfig('cloudfront/media/media_path');
51
+ Mage::getModel('core/config')->saveConfig($this->SecureMediaConfigPath, $secure_media_url);
52
+ }
53
+ }
54
+
55
+ public function setSkinConfig($distribution_url) {
56
+ if ($distribution_url != "") {
57
+ $refresh_support = Mage::getModel('freelunchlabs_cloudfront/refresh');
58
+
59
+ $unsecure_skin_url = "http://" . $distribution_url . $refresh_support->getRefreshURL('skin') . Mage::getStoreConfig('cloudfront/skin/skin_path');
60
+ Mage::getModel('core/config')->saveConfig($this->UnsecureSkinConfigPath, $unsecure_skin_url);
61
+
62
+ $secure_skin_url = "https://" . $distribution_url . $refresh_support->getRefreshURL('skin') . Mage::getStoreConfig('cloudfront/skin/skin_path');
63
+ Mage::getModel('core/config')->saveConfig($this->SecureSkinConfigPath, $secure_skin_url);
64
+ }
65
+ }
66
+
67
+ public function setJsConfig($distribution_url) {
68
+ if ($distribution_url != "") {
69
+ $refresh_support = Mage::getModel('freelunchlabs_cloudfront/refresh');
70
+
71
+ $unsecure_js_url = "http://" . $distribution_url . $refresh_support->getRefreshURL('js') . Mage::getStoreConfig('cloudfront/js/js_path');
72
+ Mage::getModel('core/config')->saveConfig($this->UnsecureJsConfigPath, $unsecure_js_url);
73
+
74
+ $secure_js_url = "https://" . $distribution_url . $refresh_support->getRefreshURL('js') . Mage::getStoreConfig('cloudfront/js/js_path');
75
+ Mage::getModel('core/config')->saveConfig($this->SecureJsConfigPath, $secure_js_url);
76
+ }
77
+ }
78
+
79
+ public function setIsDeployedFlag() {
80
+ Mage::getModel('core/config')->saveConfig(self::IS_CLOUDFRONT_DISTRIBUTION_DEPLOYED, 1);
81
+ }
82
+
83
+ public function removedIsDeployedFlag() {
84
+ Mage::getModel('core/config')->saveConfig(self::IS_CLOUDFRONT_DISTRIBUTION_DEPLOYED, 0);
85
+ }
86
+
87
+ }
app/code/community/FreeLunchLabs/CloudFront/Model/Observer.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class FreeLunchLabs_CloudFront_Model_Observer {
4
+
5
+ function catalog_product_gallery_upload_image_after() {
6
+ if (Mage::getStoreConfig('cloudfront/general/refresh') && Mage::getStoreConfig('cloudfront/general/active') && Mage::getStoreConfig('cloudfront/media/auto_refresh_media')) {
7
+ Mage::getModel('freelunchlabs_cloudfront/refresh')->refreshDirectory('media');
8
+ }
9
+ }
10
+
11
+ }
app/code/community/FreeLunchLabs/CloudFront/Model/Refresh.php ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class FreeLunchLabs_CloudFront_Model_Refresh extends Varien_Object {
4
+
5
+ public $cdn_rewrite_directory = "cdn";
6
+ private $cdn_directories = array('media', 'skin', 'js');
7
+
8
+ function addRefreshSupport() {
9
+ $this->getAllKeys();
10
+ $this->writeRewriteFile();
11
+ }
12
+
13
+ function refreshDirectory($directory = null) {
14
+ if (is_null($directory)) {
15
+ $directories = $this->cdn_directories;
16
+ } else {
17
+ $directories = array(0 => $directory);
18
+ }
19
+
20
+ foreach ($directories as $cdn_directory) {
21
+ $this->setKey($cdn_directory);
22
+ }
23
+
24
+ Mage::getModel('freelunchlabs_cloudfront/config')->setCloudFrontConfig();
25
+ }
26
+
27
+ function writeRewriteFile() {
28
+ $adapter = Mage::getModel('freelunchlabs_cloudfront/refreshadapters_apache');
29
+ $base_dir = Mage::getBaseDir() . DS;
30
+ $file = new Varien_Io_File();
31
+
32
+ try {
33
+ if ($file->cd($base_dir) && $file->checkAndCreateFolder($this->cdn_rewrite_directory, 0755)) {
34
+ if ($file->cd($base_dir . $this->cdn_rewrite_directory)) {
35
+ if(!$file->write($adapter->filename, $adapter->buildFileContents(), 0644)){
36
+ throw new Exception("Could not write .htaccess to: " . $file->pwd());
37
+ }
38
+ }
39
+ }
40
+ } catch (Exception $e) {
41
+ Mage::getSingleton('core/session')->addWarning('Configuration saved but there was an error creating the .htaccess file: ' . $e->getMessage());
42
+ }
43
+ }
44
+
45
+ public function isDirectoryWriteable() {
46
+ $base_dir = Mage::getBaseDir() . DS;
47
+ $file = new Varien_Io_File();
48
+
49
+ if ($file->isWriteable($base_dir)) {
50
+ return true;
51
+ } else {
52
+ return false;
53
+ }
54
+ }
55
+
56
+ function getRefreshURL($directory) {
57
+ if (Mage::getStoreConfig('cloudfront/general/refresh') == 1) {
58
+ return $this->cdn_rewrite_directory . "/" . $this->getKey($directory) . "/";
59
+ } else {
60
+ return "";
61
+ }
62
+ }
63
+
64
+ function getAllKeys() {
65
+ $keys = array();
66
+
67
+ foreach ($this->cdn_directories as $directory) {
68
+ $keys[$directory] = $this->getKey($directory);
69
+ }
70
+
71
+ return $keys;
72
+ }
73
+
74
+ function getKey($directory) {
75
+ Mage::app()->getStore()->resetConfig();
76
+ $key = Mage::getStoreConfig('cloudfront/general/refresh_' . $directory . '_key');
77
+
78
+ if ($key) {
79
+ return $key;
80
+ } else {
81
+ return $this->setKey($directory);
82
+ }
83
+ }
84
+
85
+ function setKey($directory) {
86
+ $key = rand(0, 999999);
87
+ Mage::getModel('core/config')->saveConfig('cloudfront/general/refresh_' . $directory . '_key', $key);
88
+ return $key;
89
+ }
90
+
91
+ function loadProxiedURL($url) {
92
+ $header[] = "Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
93
+ $header[] = "Cache-Control: max-age=0";
94
+ $header[] = "Connection: keep-alive";
95
+ $header[] = "Keep-Alive: 300";
96
+ $header[] = "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7";
97
+ $header[] = "Accept-Language: en-us,en;q=0.5";
98
+
99
+ $ch = curl_init();
100
+ curl_setopt($ch, CURLOPT_URL, $url);
101
+ curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.0.2) Gecko/2008092313 Ubuntu/9.25 (jaunty) Firefox/3.8');
102
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
103
+ curl_setopt($ch, CURLOPT_HEADER, 0);
104
+ curl_setopt($ch, CURLOPT_REFERER, Mage::getStoreConfig('web/unsecure/base_link_url'));
105
+ curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
106
+ curl_setopt($ch, CURLOPT_AUTOREFERER, true);
107
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
108
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
109
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
110
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
111
+
112
+ $data = curl_exec($ch);
113
+
114
+ $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
115
+ $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
116
+
117
+ curl_close($ch);
118
+
119
+ return array(
120
+ 'data' => $data,
121
+ 'http_status' => $http_status,
122
+ 'content_type' => $contentType
123
+ );
124
+ }
125
+
126
+ public function testRefreshSupport() {
127
+ $url = Mage::getStoreConfig('web/unsecure/base_link_url') . $this->$cdn_rewrite_directory . $this->getKey('skin') . Mage::getStoreConfig('cloudfront/general/testFile');
128
+
129
+ $content = $this->loadProxiedURL($url);
130
+
131
+ if ($content['http_status'] == 200) {
132
+ return true;
133
+ } else {
134
+ return false;
135
+ }
136
+ }
137
+ }
app/code/community/FreeLunchLabs/CloudFront/Model/Refreshadapters/Apache.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class FreeLunchLabs_CloudFront_Model_RefreshAdapters_Apache extends Varien_Object {
4
+
5
+ public $filename = '.htaccess';
6
+
7
+ function buildFileContents() {
8
+ $contents = "RewriteEngine on \n";
9
+ $contents .="RewriteRule ^[0-9]{1,6}/(.*)$ ../$1 [PT] \n";
10
+
11
+ return $contents;
12
+ }
13
+
14
+ function getAdapterFileName() {
15
+ return $this->filename;
16
+ }
17
+
18
+ }
app/code/community/FreeLunchLabs/CloudFront/Model/Setup/Observer.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class FreeLunchLabs_CloudFront_Model_Setup_Observer {
4
+
5
+ public function admin_system_config_changed_section_cloudfront() {
6
+ $active = Mage::getStoreConfig('cloudfront/general/active');
7
+ $refresh = Mage::getStoreConfig('cloudfront/general/refresh');
8
+ $distributionId = Mage::getStoreConfig('cloudfront/general/distribution');
9
+ $key = Mage::getStoreConfig('cloudfront/general/key');
10
+ $secret = Mage::getStoreConfig('cloudfront/general/secret');
11
+
12
+ if ($active == 1 && $distributionId != "" && $key != "" && $secret != "") {
13
+ Mage::getModel('freelunchlabs_cloudfront/config')->setCloudFrontConfig();
14
+ } elseif ($active == 1) {
15
+ Mage::getSingleton('core/session')->addError('Please check that Distribution ID, AWS Key, and Secret Key are set correctly.');
16
+ } elseif ($active == 0) {
17
+ Mage::getSingleton('core/session')->addSuccess('CloudFront CDN successfully disabled.');
18
+ }
19
+
20
+ if ($active == 1 && $refresh == 1) {
21
+ Mage::getModel('freelunchlabs_cloudfront/refresh')->addRefreshSupport();
22
+ }
23
+ }
24
+
25
+ }
app/code/community/FreeLunchLabs/CloudFront/Model/Store.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class FreeLunchLabs_CloudFront_Model_Store extends Mage_Core_Model_Store {
4
+
5
+ public function getBaseUrl($type = self::URL_TYPE_LINK, $secure = null) {
6
+ $cacheKey = $type . '/' . (is_null($secure) ? 'null' : ($secure ? 'true' : 'false'));
7
+ if (!isset($this->_baseUrlCache[$cacheKey])) {
8
+ if ($this->getConfig('cloudfront/general/active') && $this->getConfig('cloudfront/general/deployed') && !$this->isAdmin() && Mage::getDesign()->getArea() != 'adminhtml') {
9
+ $secure = is_null($secure) ? $this->isCurrentlySecure() : (bool) $secure;
10
+
11
+ if ($type == self::URL_TYPE_SKIN && $this->getConfig('cloudfront/skin/skin')) {
12
+ if ($secure) {
13
+ $url = $this->getConfig('cloudfront/secure/base_skin_url');
14
+ } else {
15
+ $url = $this->getConfig('cloudfront/unsecure/base_skin_url');
16
+ }
17
+ } elseif ($type == self::URL_TYPE_JS && $this->getConfig('cloudfront/js/js')) {
18
+ if ($secure) {
19
+ $url = $this->getConfig('cloudfront/secure/base_js_url');
20
+ } else {
21
+ $url = $this->getConfig('cloudfront/unsecure/base_js_url');
22
+ }
23
+ } elseif ($type == self::URL_TYPE_MEDIA && $this->getConfig('cloudfront/media/media')) {
24
+ if ($secure) {
25
+ $url = $this->getConfig('cloudfront/secure/base_media_url');
26
+ } else {
27
+ $url = $this->getConfig('cloudfront/unsecure/base_media_url');
28
+ }
29
+ } else {
30
+ return parent::getBaseUrl($type, $secure);
31
+ }
32
+
33
+ if (false !== strpos($url, '{{base_url}}')) {
34
+ $baseUrl = Mage::getConfig()->substDistroServerVars('{{base_url}}');
35
+ $url = str_replace('{{base_url}}', $baseUrl, $url);
36
+ }
37
+
38
+ $this->_baseUrlCache[$cacheKey] = rtrim($url, '/') . '/';
39
+ } else {
40
+ return parent::getBaseUrl($type, $secure);
41
+ }
42
+ }
43
+
44
+ return $this->_baseUrlCache[$cacheKey];
45
+ }
46
+
47
+ }
app/code/community/FreeLunchLabs/CloudFront/controllers/Adminhtml/CdnmanagementController.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class FreeLunchLabs_CloudFront_Adminhtml_CdnmanagementController extends Mage_Adminhtml_Controller_Action {
4
+
5
+ public function indexAction() {
6
+ $this->_title($this->__('System'))->_title($this->__('CloudFront CDN Management'));
7
+
8
+ $this->loadLayout();
9
+ $this->_setActiveMenu('system');
10
+ $this->renderLayout();
11
+ }
12
+
13
+ public function refreshAllAction() {
14
+ Mage::getModel('freelunchlabs_cloudfront/refresh')->refreshDirectory();
15
+
16
+ $this->_getSession()->addSuccess(
17
+ Mage::helper('adminhtml')->__('All files on CDN have been refreshed.')
18
+ );
19
+
20
+ $this->_redirect('*/*');
21
+ }
22
+
23
+ public function refreshMediaAction() {
24
+ Mage::getModel('freelunchlabs_cloudfront/refresh')->refreshDirectory('media');
25
+
26
+ $this->_getSession()->addSuccess(
27
+ Mage::helper('adminhtml')->__('All media files on CDN have been refreshed.')
28
+ );
29
+
30
+ $this->_redirect('*/*');
31
+ }
32
+
33
+ public function refreshSkinAction() {
34
+ Mage::getModel('freelunchlabs_cloudfront/refresh')->refreshDirectory('skin');
35
+
36
+ $this->_getSession()->addSuccess(
37
+ Mage::helper('adminhtml')->__('All skin files on CDN have been refreshed.')
38
+ );
39
+
40
+ $this->_redirect('*/*');
41
+ }
42
+
43
+ public function refreshJsAction() {
44
+ Mage::getModel('freelunchlabs_cloudfront/refresh')->refreshDirectory('js');
45
+
46
+ $this->_getSession()->addSuccess(
47
+ Mage::helper('adminhtml')->__('All JavaScript files on CDN have been refreshed.')
48
+ );
49
+
50
+ $this->_redirect('*/*');
51
+ }
52
+
53
+ }
app/code/community/FreeLunchLabs/CloudFront/controllers/Adminhtml/TestconnectionController.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class FreeLunchLabs_CloudFront_Adminhtml_TestconnectionController extends Mage_Adminhtml_Controller_Action {
4
+
5
+ public function pingAction() {
6
+ $key = Mage::app()->getRequest()->getParam('awskey');
7
+ $secret = Mage::app()->getRequest()->getParam('awssecret');
8
+ $origin = Mage::app()->getRequest()->getParam('awsorigin');
9
+
10
+ $cloudfront = Mage::getModel('freelunchlabs_cloudfront/cloudfront', array('key' => $key, 'secret' => $secret));
11
+ $cloudfront->setOrigin($origin);
12
+ $result = $cloudfront->createDistribution();
13
+
14
+ if ($result['status']) {
15
+ echo json_encode(array('status' => 'success', 'message' => 'Distribution Successfully Created', 'distribution' => $result['distribution']));
16
+ } else {
17
+ echo json_encode(array('status' => 'error', 'message' => $result['message'], 'distribution' => $result['distribution']));
18
+ }
19
+ }
20
+
21
+ }
app/code/community/FreeLunchLabs/CloudFront/etc/config.xml ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <FreeLunchLabs_CloudFront>
5
+ <version>1.0.0</version>
6
+ </FreeLunchLabs_CloudFront>
7
+ </modules>
8
+ <global>
9
+ <models>
10
+ <freelunchlabs_cloudfront>
11
+ <class>FreeLunchLabs_CloudFront_Model</class>
12
+ </freelunchlabs_cloudfront>
13
+ <core>
14
+ <rewrite>
15
+ <store>FreeLunchLabs_CloudFront_Model_Store</store>
16
+ </rewrite>
17
+ </core>
18
+ </models>
19
+ <helpers>
20
+ <cloudfront>
21
+ <class>FreeLunchLabs_CloudFront_Helper</class>
22
+ </cloudfront>
23
+ </helpers>
24
+ <blocks>
25
+ <freelunchlabs_cloudfront>
26
+ <class>FreeLunchLabs_CloudFront_Block</class>
27
+ </freelunchlabs_cloudfront>
28
+ </blocks>
29
+ <events>
30
+ <catalog_product_gallery_upload_image_after>
31
+ <observers>
32
+ <freelunchlabs_cloudfront_observer>
33
+ <type>singleton</type>
34
+ <class>FreeLunchLabs_CloudFront_Model_Observer</class>
35
+ <method>catalog_product_gallery_upload_image_after</method>
36
+ </freelunchlabs_cloudfront_observer>
37
+ </observers>
38
+ </catalog_product_gallery_upload_image_after>
39
+ <admin_system_config_changed_section_cloudfront>
40
+ <observers>
41
+ <freelunchlabs_cloudfront_observer>
42
+ <type>singleton</type>
43
+ <class>FreeLunchLabs_CloudFront_Model_Setup_Observer</class>
44
+ <method>admin_system_config_changed_section_cloudfront</method>
45
+ </freelunchlabs_cloudfront_observer>
46
+ </observers>
47
+ </admin_system_config_changed_section_cloudfront>
48
+ </events>
49
+ </global>
50
+ <admin>
51
+ <routers>
52
+ <adminhtml>
53
+ <args>
54
+ <modules>
55
+ <freelunchlabs_cloudfront before="Mage_Adminhtml">FreeLunchLabs_CloudFront_Adminhtml</freelunchlabs_cloudfront>
56
+ </modules>
57
+ </args>
58
+ </adminhtml>
59
+ </routers>
60
+ </admin>
61
+ <adminhtml>
62
+ <menu>
63
+ <system>
64
+ <children>
65
+ <cloudfront translate="title" module="cloudfront">
66
+ <title>CDN Management</title>
67
+ <sort_order>100</sort_order>
68
+ <action>adminhtml/cdnmanagement</action>
69
+ </cloudfront>
70
+ </children>
71
+ </system>
72
+ </menu>
73
+ <acl>
74
+ <resources>
75
+ <admin>
76
+ <children>
77
+ <system>
78
+ <children>
79
+ <config>
80
+ <children>
81
+ <cloudfront translate="title" module="cloudfront">
82
+ <title>CloudFront CDN Configuration</title>
83
+ <sort_order>50</sort_order>
84
+ </cloudfront>
85
+ </children>
86
+ </config>
87
+ <cdnmanagement>
88
+ <title>CloudFront CDN Managment</title>
89
+ <sort_order>70</sort_order>
90
+ </cdnmanagement>
91
+ </children>
92
+ </system>
93
+ </children>
94
+ </admin>
95
+ </resources>
96
+ </acl>
97
+ <layout>
98
+ <updates>
99
+ <cloudfront>
100
+ <file>cloudfront.xml</file>
101
+ </cloudfront>
102
+ </updates>
103
+ </layout>
104
+ </adminhtml>
105
+ <default>
106
+ <cloudfront>
107
+ <general>
108
+ <active>0</active>
109
+ <origin>{{unsecure_base_url}}</origin>
110
+ <refresh>0</refresh>
111
+ <refreshCache>0</refreshCache>
112
+ <deployed>0</deployed>
113
+ <test_file>/skin/adminhtml/default/default/images/blank.gif</test_file>
114
+ </general>
115
+ <media>
116
+ <media>1</media>
117
+ <media_path>media/</media_path>
118
+ <auto_refresh_media>1</auto_refresh_media>
119
+ </media>
120
+ <skin>
121
+ <skin>1</skin>
122
+ <skin_path>skin/</skin_path>
123
+ </skin>
124
+ <js>
125
+ <js>1</js>
126
+ <js_path>js/</js_path>
127
+ </js>
128
+ <test_mode>
129
+ <enabled>1</enabled>
130
+ </test_mode>
131
+ </cloudfront>
132
+ </default>
133
+ </config>
app/code/community/FreeLunchLabs/CloudFront/etc/system.xml ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <cloudfront translate="label" module="cloudfront">
5
+ <class>separator-top</class>
6
+ <label>Cloud Front CDN Configuration</label>
7
+ <tab>general</tab>
8
+ <sort_order>110</sort_order>
9
+ <show_in_default>1</show_in_default>
10
+ <show_in_website>1</show_in_website>
11
+ <show_in_store>1</show_in_store>
12
+ <groups>
13
+ <general translate="label">
14
+ <label>General</label>
15
+ <frontend_type>text</frontend_type>
16
+ <sort_order>1</sort_order>
17
+ <show_in_default>1</show_in_default>
18
+ <show_in_website>0</show_in_website>
19
+ <show_in_store>1</show_in_store>
20
+ <fields>
21
+ <active translate="label">
22
+ <label>Enabled CloudFront CDN</label>
23
+ <frontend_type>select</frontend_type>
24
+ <source_model>adminhtml/system_config_source_yesno</source_model>
25
+ <sort_order>1</sort_order>
26
+ <show_in_default>1</show_in_default>
27
+ <show_in_website>0</show_in_website>
28
+ <show_in_store>0</show_in_store>
29
+ </active>
30
+ <key translate="label comment">
31
+ <label>AWS Access Key ID</label>
32
+ <frontend_type>text</frontend_type>
33
+ <sort_order>2</sort_order>
34
+ <show_in_default>1</show_in_default>
35
+ <show_in_website>0</show_in_website>
36
+ <show_in_store>0</show_in_store>
37
+ <comment><![CDATA[Your Amazon Web Services Access Key. <a href="https://portal.aws.amazon.com/gp/aws/securityCredentials#cred_tab_block" target="_blank">Find It Here.</a>]]>
38
+ </comment>
39
+ </key>
40
+ <secret translate="label comment">
41
+ <label>AWS Secret Access Key</label>
42
+ <frontend_type>password</frontend_type>
43
+ <sort_order>3</sort_order>
44
+ <show_in_default>1</show_in_default>
45
+ <show_in_website>0</show_in_website>
46
+ <show_in_store>0</show_in_store>
47
+ <comment><![CDATA[Your Amazon Web Services Secret Access Key. <a href="https://portal.aws.amazon.com/gp/aws/securityCredentials#cred_tab_block" target="_blank">Find It Here.</a>]]>
48
+ </comment>
49
+ </secret>
50
+ <distribution translate="label comment">
51
+ <label>CloudFront Distribution ID</label>
52
+ <frontend_type>text</frontend_type>
53
+ <sort_order>4</sort_order>
54
+ <show_in_default>1</show_in_default>
55
+ <show_in_website>0</show_in_website>
56
+ <show_in_store>0</show_in_store>
57
+ </distribution>
58
+ <cloudfront_test_connect_wizard translate="button_label">
59
+ <label></label>
60
+ <button_label>Create New Distribution</button_label>
61
+ <frontend_model>freelunchlabs_cloudfront/adminhtml_testconnection</frontend_model>
62
+ <sort_order>5</sort_order>
63
+ <show_in_default>1</show_in_default>
64
+ <show_in_website>0</show_in_website>
65
+ <show_in_store>0</show_in_store>
66
+ <comment>The Distribution ID is how CloudFront identifies your Distribution. If you don't have one, click the "Create New Distribution" button. You can also enter your own Distribution ID if you already have one configured.</comment>
67
+ </cloudfront_test_connect_wizard>
68
+ <origin translate="label comment">
69
+ <label>Source URL</label>
70
+ <frontend_type>text</frontend_type>
71
+ <sort_order>6</sort_order>
72
+ <show_in_default>1</show_in_default>
73
+ <show_in_website>0</show_in_website>
74
+ <show_in_store>0</show_in_store>
75
+ <comment>The URL where CloudFront will look to find your file. In almost all cases, this will be you Unsecure Base URL.</comment>
76
+ </origin>
77
+ <refresh translate="label">
78
+ <label>Enabled Quick CDN Refresh Support</label>
79
+ <frontend_type>select</frontend_type>
80
+ <source_model>adminhtml/system_config_source_yesno</source_model>
81
+ <sort_order>7</sort_order>
82
+ <show_in_default>1</show_in_default>
83
+ <show_in_website>0</show_in_website>
84
+ <show_in_store>0</show_in_store>
85
+ <comment>Highly recommended. Gives you the ability to instainiously refresh the files stored on the CDN. Requires Apache mod_rewrite.</comment>
86
+ </refresh>
87
+ <refreshCache translate="label">
88
+ <label>Refresh Config Cache on CDN Refresh</label>
89
+ <frontend_type>select</frontend_type>
90
+ <source_model>adminhtml/system_config_source_yesno</source_model>
91
+ <sort_order>8</sort_order>
92
+ <show_in_default>1</show_in_default>
93
+ <show_in_website>0</show_in_website>
94
+ <show_in_store>0</show_in_store>
95
+ <comment>Automatically clears the Config Cache when content on the CDN is refreshed. If set to "no", you might have to manually clear the config cache after a CDN refresh.</comment>
96
+ </refreshCache>
97
+ </fields>
98
+ </general>
99
+ <media>
100
+ <label>Media Files</label>
101
+ <frontend_type>text</frontend_type>
102
+ <sort_order>2</sort_order>
103
+ <show_in_default>1</show_in_default>
104
+ <show_in_website>0</show_in_website>
105
+ <show_in_store>1</show_in_store>
106
+ <fields>
107
+ <media translate="label">
108
+ <label>Enabled CDN for Media</label>
109
+ <frontend_type>select</frontend_type>
110
+ <source_model>adminhtml/system_config_source_yesno</source_model>
111
+ <sort_order>1</sort_order>
112
+ <show_in_default>1</show_in_default>
113
+ <show_in_website>0</show_in_website>
114
+ <show_in_store>0</show_in_store>
115
+ <comment>If set to "Yes" this will add all of your media files to the CDN. This includes files from the CMS and Catalog.</comment>
116
+ </media>
117
+ <media_path translate="label comment">
118
+ <label>Media Path</label>
119
+ <frontend_type>text</frontend_type>
120
+ <sort_order>2</sort_order>
121
+ <show_in_default>1</show_in_default>
122
+ <show_in_website>0</show_in_website>
123
+ <show_in_store>0</show_in_store>
124
+ <comment>The path to your media directory relative to your Source URL. In almost all cases, this will be: media/</comment>
125
+ </media_path>
126
+ <auto_refresh_media>
127
+ <label>Auto Refresh Media</label>
128
+ <frontend_type>select</frontend_type>
129
+ <source_model>adminhtml/system_config_source_yesno</source_model>
130
+ <sort_order>3</sort_order>
131
+ <show_in_default>1</show_in_default>
132
+ <show_in_website>0</show_in_website>
133
+ <show_in_store>0</show_in_store>
134
+ <comment>If set to "Yes" this will automatically refresh the Media Files on the CDN when you upload new Product images. Requires "Quick CDN Refresh Support" to be enabled.</comment>
135
+ </auto_refresh_media>
136
+ </fields>
137
+ </media>
138
+ <skin>
139
+ <label>Skin Files</label>
140
+ <frontend_type>text</frontend_type>
141
+ <sort_order>3</sort_order>
142
+ <show_in_default>1</show_in_default>
143
+ <show_in_website>0</show_in_website>
144
+ <show_in_store>1</show_in_store>
145
+ <fields>
146
+ <skin translate="label">
147
+ <label>Enabled CDN for Skin</label>
148
+ <frontend_type>select</frontend_type>
149
+ <source_model>adminhtml/system_config_source_yesno</source_model>
150
+ <sort_order>8</sort_order>
151
+ <show_in_default>1</show_in_default>
152
+ <show_in_website>0</show_in_website>
153
+ <show_in_store>0</show_in_store>
154
+ <comment>If set to "Yes" this will add all of your skin files to the CDN. This includes files used in your theme, such as CSS, Logos, and Background Images.</comment>
155
+ </skin>
156
+ <skin_path translate="label comment">
157
+ <label>Skin Path</label>
158
+ <frontend_type>text</frontend_type>
159
+ <sort_order>11</sort_order>
160
+ <show_in_default>1</show_in_default>
161
+ <show_in_website>0</show_in_website>
162
+ <show_in_store>0</show_in_store>
163
+ <comment>The path to your skin directory relative to your Source URL. In most cases, this will be: skin/</comment>
164
+ </skin_path>
165
+ </fields>
166
+ </skin>
167
+ <js>
168
+ <label>Javascript Files</label>
169
+ <frontend_type>text</frontend_type>
170
+ <sort_order>4</sort_order>
171
+ <show_in_default>1</show_in_default>
172
+ <show_in_website>0</show_in_website>
173
+ <show_in_store>0</show_in_store>
174
+ <fields>
175
+ <js translate="label">
176
+ <label>Enabled CDN for JavaScript</label>
177
+ <frontend_type>select</frontend_type>
178
+ <source_model>adminhtml/system_config_source_yesno</source_model>
179
+ <sort_order>9</sort_order>
180
+ <show_in_default>1</show_in_default>
181
+ <show_in_website>0</show_in_website>
182
+ <show_in_store>0</show_in_store>
183
+ <comment>If set to "Yes" this will add all of your JavaScript files to the CDN. This includes all the files within the root "js" directory.</comment>
184
+ </js>
185
+ <js_path translate="label comment">
186
+ <label>Javascript Path</label>
187
+ <frontend_type>text</frontend_type>
188
+ <sort_order>12</sort_order>
189
+ <show_in_default>1</show_in_default>
190
+ <show_in_website>0</show_in_website>
191
+ <show_in_store>0</show_in_store>
192
+ <comment>The path to your Javascript directory relative to your Source URL. In most cases, this will be: js/</comment>
193
+ </js_path>
194
+ </fields>
195
+ </js>
196
+ <test_mode>
197
+ <label>Testing Tools</label>
198
+ <frontend_type>text</frontend_type>
199
+ <sort_order>5</sort_order>
200
+ <show_in_default>0</show_in_default>
201
+ <show_in_website>0</show_in_website>
202
+ <show_in_store>0</show_in_store>
203
+ <fields>
204
+ <enabled translate="label">
205
+ <label>Enabled CDN for JavaScript</label>
206
+ <frontend_type>select</frontend_type>
207
+ <source_model>adminhtml/system_config_source_yesno</source_model>
208
+ <sort_order>9</sort_order>
209
+ <show_in_default>1</show_in_default>
210
+ <show_in_website>0</show_in_website>
211
+ <show_in_store>0</show_in_store>
212
+ <comment>If set to "Yes", this will only allow the CDN to work for the below IP address. This is useful if you want to test the CDN without disrupting users on your live site.</comment>
213
+ </enabled>
214
+ <ip_address translate="label comment">
215
+ <label>Javascript Path</label>
216
+ <frontend_type>text</frontend_type>
217
+ <sort_order>12</sort_order>
218
+ <show_in_default>1</show_in_default>
219
+ <show_in_website>0</show_in_website>
220
+ <show_in_store>0</show_in_store>
221
+ <comment>The path to your Javascript directory relative to your Source URL. In most cases, this will be: js/</comment>
222
+ </ip_address>
223
+ <test_file>
224
+ <label>Test File Path</label>
225
+ <frontend_type>text</frontend_type>
226
+ <sort_order>9</sort_order>
227
+ <show_in_default>1</show_in_default>
228
+ <show_in_website>0</show_in_website>
229
+ <show_in_store>0</show_in_store>
230
+ <comment>Path to a test file to make sure Quick CDN Refresh Support will work.</comment>
231
+ </test_file>
232
+ </fields>
233
+ </test_mode>
234
+ </groups>
235
+ </cloudfront>
236
+ </sections>
237
+ </config>
app/code/community/FreeLunchLabs/MailGun/Model/Email/Template.php CHANGED
@@ -80,6 +80,15 @@ class FreeLunchLabs_MailGun_Model_Email_Template extends Mage_Core_Model_Email_T
80
  $message->setHtmlBody($processedTemplateBody);
81
  }
82
 
 
 
 
 
 
 
 
 
 
83
  //Add Unique Args
84
  $message->addCustomData("message_data", array('id' => 123456));
85
 
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
 
app/code/community/FreeLunchLabs/MailGun/Model/Mailgun.php CHANGED
@@ -4,7 +4,7 @@ class FreeLunchLabs_MailGun_Model_Mailgun extends Mage_Core_Model_Abstract {
4
 
5
  public $apiUrl = "https://api.mailgun.net/v2/";
6
 
7
- public function mailgunRequest($type, $domain, $apiKey, $data, $method = Zend_Http_Client::GET, $uriOveride = false) {
8
 
9
  $client = new Zend_Http_Client();
10
  $client->setAuth("api", $apiKey);
@@ -25,6 +25,12 @@ class FreeLunchLabs_MailGun_Model_Mailgun extends Mage_Core_Model_Abstract {
25
  $client->setParameterGet($key, $value);
26
  }
27
  }
 
 
 
 
 
 
28
 
29
  try {
30
  $response = $client->request();
@@ -44,8 +50,15 @@ class FreeLunchLabs_MailGun_Model_Mailgun extends Mage_Core_Model_Abstract {
44
 
45
  $domain = $message->getStore()->getConfig('mailgun/general/domain');
46
  $apiKey = $message->getStore()->getConfig('mailgun/general/key');
47
-
48
- $sendResponse = $this->mailgunRequest('messages', $domain, $apiKey, $message->getMessage(), Zend_Http_Client::POST);
 
 
 
 
 
 
 
49
 
50
  if($message->getStore()->getConfig('mailgun/events/store')) {
51
  Mage::getModel('freelunchlabs_mailgun/email')->saveInitialSend($message, $sendResponse);
4
 
5
  public $apiUrl = "https://api.mailgun.net/v2/";
6
 
7
+ public function mailgunRequest($type, $domain, $apiKey, $data, $method = Zend_Http_Client::GET, $uriOveride = false, $files = null) {
8
 
9
  $client = new Zend_Http_Client();
10
  $client->setAuth("api", $apiKey);
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();
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);
app/code/community/FreeLunchLabs/MailGun/Model/Messagebuilder.php CHANGED
@@ -25,6 +25,7 @@ class FreeLunchLabs_MailGun_Model_Messagebuilder extends Varien_Object {
25
  protected $message = array();
26
  protected $variables = array();
27
  protected $files = array();
 
28
  protected $counters = array('recipients' => array('to' => 0,
29
  'cc' => 0,
30
  'bcc' => 0),
@@ -150,16 +151,13 @@ class FreeLunchLabs_MailGun_Model_Messagebuilder extends Varien_Object {
150
  return $this->message['html'];
151
  }
152
 
153
- public function addAttachment($attachmentPath, $attachmentName = null) {
154
- if (preg_match("/^@/", $attachmentPath)) {
155
- if (isset($this->files["attachment"])) {
156
- $attachment = array('filePath' => $attachmentPath,
157
- 'remoteName' => $attachmentName);
158
- array_push($this->files["attachment"], $attachment);
159
- } else {
160
- $this->files["attachment"] = array(array('filePath' => $attachmentPath,
161
- 'remoteName' => $attachmentName));
162
- }
163
  return true;
164
  } else {
165
  throw new FreeLunchLabs_MailGun_Model_Exceptions_InvalidParameter(self::INVALID_PARAMETER_ATTACHMENT);
@@ -293,4 +291,8 @@ class FreeLunchLabs_MailGun_Model_Messagebuilder extends Varien_Object {
293
  return $this->files;
294
  }
295
 
 
 
 
 
296
  }
25
  protected $message = array();
26
  protected $variables = array();
27
  protected $files = array();
28
+ protected $attachments = array();
29
  protected $counters = array('recipients' => array('to' => 0,
30
  'cc' => 0,
31
  'bcc' => 0),
151
  return $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);
291
  return $this->files;
292
  }
293
 
294
+ public function getAttachments() {
295
+ return $this->attachments;
296
+ }
297
+
298
  }
app/code/community/FreeLunchLabs/MailGun/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <FreeLunchLabs_MailGun>
5
- <version>1.0.0</version>
6
  </FreeLunchLabs_MailGun>
7
  </modules>
8
  <global>
2
  <config>
3
  <modules>
4
  <FreeLunchLabs_MailGun>
5
+ <version>1.0.1</version>
6
  </FreeLunchLabs_MailGun>
7
  </modules>
8
  <global>
app/code/community/FreeLunchLabs/SendGrid/Helper/Data.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class FreeLunchLabs_SendGrid_Helper_Data extends Mage_Core_Helper_Abstract {
4
+
5
+ }
6
+
7
+ ?>
app/code/community/FreeLunchLabs/SendGrid/Model/Email/Template.php ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class FreeLunchLabs_SendGrid_Model_Email_Template extends Mage_Core_Model_Email_Template {
4
+
5
+ var $bcc = null;
6
+ var $replyto = null;
7
+ var $returnPath = null; //This is not used because SendGrid overides it for their internal purposes.
8
+
9
+ public function send($email, $name = null, array $variables = array()) {
10
+ if (Mage::getStoreConfig('sendgrid/general/active')) {
11
+ if (!$this->isValidForSend()) {
12
+ Mage::logException(new Exception('This letter cannot be sent.'));
13
+ return false;
14
+ }
15
+
16
+ //Rest Client
17
+ $client = new Zend_Http_Client();
18
+ $client->setUri('https://api.sendgrid.com/api/mail.send.json');
19
+ $client->setMethod(Zend_Http_Client::POST);
20
+
21
+ //Recipient(s)
22
+ $emails = array_values((array) $email);
23
+ $names = is_array($name) ? $name : (array) $name;
24
+ $names = array_values($names);
25
+ foreach ($emails as $key => $email) {
26
+ if (!isset($names[$key])) {
27
+ $names[$key] = substr($email, 0, strpos($email, '@'));
28
+ }
29
+ }
30
+
31
+ $variables['email'] = reset($emails);
32
+ $variables['name'] = reset($names);
33
+
34
+ $is_first = true;
35
+ foreach ($emails as $key => $email) {
36
+ if ($is_first) {
37
+ $client->setParameterPost('to', $email);
38
+ $client->setParameterPost('toname', $names[$key]);
39
+ } else {
40
+ $smtp_options['to'][] = $names[$key] . " <" . $email . ">";
41
+ }
42
+
43
+ $is_first = false;
44
+ }
45
+
46
+ //Subject
47
+ $subject = $this->getProcessedTemplateSubject($variables);
48
+ $client->setParameterPost('subject', $subject);
49
+
50
+ //From Name
51
+ $client->setParameterPost('from', $this->getSenderEmail());
52
+ $client->setParameterPost('fromname', $this->getSenderName());
53
+
54
+ //Bcc
55
+ if (is_array($this->bcc)) {
56
+ foreach ($this->bcc as $bcc_email) {
57
+ $client->setParameterPost('bcc[]', $bcc_email);
58
+ }
59
+ } elseif ($this->bcc) {
60
+ $client->setParameterPost('bcc', $this->bcc);
61
+ }
62
+
63
+ //Reply To
64
+ if (!is_null($this->replyto)) {
65
+ $client->setParameterPost('replyto', $this->replyto);
66
+ }
67
+
68
+ //Message Body
69
+ $this->setUseAbsoluteLinks(true);
70
+ $processedTemplateBody = $this->getProcessedTemplate($variables, true);
71
+
72
+ if ($this->isPlain()) {
73
+ $client->setParameterPost('text', $processedTemplateBody);
74
+ } else {
75
+ $client->setParameterPost('html', $processedTemplateBody);
76
+ }
77
+
78
+ //Add Unique Args
79
+ $smtp_options['unique_args'] = $this->buildUniqueArgs($variables);
80
+ $smtp_options['unique_args']['email_subject'] = $subject;
81
+
82
+ //Extra Header Options
83
+ if(!is_null($smtp_options)) {
84
+ $client->setParameterPost('x-smtpapi', json_encode($smtp_options));
85
+ }
86
+
87
+ //Set Post Params
88
+ $client->setParameterPost('api_user', Mage::getStoreConfig('sendgrid/general/username'));
89
+ $client->setParameterPost('api_key', Mage::getStoreConfig('sendgrid/general/password'));
90
+
91
+ //Send it!
92
+ try {
93
+ $client->request();
94
+ $this->_mail = null;
95
+ } catch (Exception $e) {
96
+ $this->_mail = null;
97
+ Mage::logException($e);
98
+ return false;
99
+ }
100
+
101
+ return true;
102
+ } else {
103
+ return parent::send($email, $name, $variables);
104
+ }
105
+ }
106
+
107
+ public function addBcc($bcc) {
108
+ if (Mage::getStoreConfig('sendgrid/general/active')) {
109
+ $this->bcc = $bcc;
110
+ } else {
111
+ return parent::addBcc($bcc);
112
+ }
113
+
114
+ return $this;
115
+ }
116
+
117
+ public function setReturnPath($email) {
118
+ if (Mage::getStoreConfig('sendgrid/general/active')) {
119
+ $this->returnPath = $email;
120
+ } else {
121
+ return parent::setReturnPath($email);
122
+ }
123
+
124
+ return $this;
125
+ }
126
+
127
+ public function setReplyTo($email) {
128
+ if (Mage::getStoreConfig('sendgrid/general/active')) {
129
+ $this->replyto = $email;
130
+ } else {
131
+ return parent::setReplyTo($email);
132
+ }
133
+
134
+ return $this;
135
+ }
136
+
137
+ public function buildUniqueArgs($variables) {
138
+
139
+ $unique_args = array();
140
+
141
+ //Send email type
142
+ $unique_args['email_type'] = $this->getTemplateId();
143
+
144
+ //Send data in variable array
145
+ foreach($variables as $key => $variable) {
146
+ if(is_subclass_of($variable, 'Varien_Object')) {
147
+ if(is_array($variable->getData())) {
148
+ foreach($variable->getData() as $dataKey => $dataItem) {
149
+ $unique_args[$key . " - " . $dataKey] = $dataItem;
150
+ }
151
+ }
152
+ } else {
153
+ $unique_args[$key] = $variable;
154
+ }
155
+ }
156
+
157
+ return $unique_args;
158
+ }
159
+
160
+ }
app/code/community/FreeLunchLabs/SendGrid/etc/config.xml ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <FreeLunchLabs_SendGrid>
5
+ <version>1.0.0</version>
6
+ </FreeLunchLabs_SendGrid>
7
+ </modules>
8
+ <global>
9
+ <models>
10
+ <freelunchlabs_sendgrid>
11
+ <class>FreeLunchLabs_SendGrid_Model</class>
12
+ </freelunchlabs_sendgrid>
13
+ <core>
14
+ <rewrite>
15
+ <email_template>FreeLunchLabs_SendGrid_Model_Email_Template</email_template>
16
+ </rewrite>
17
+ </core>
18
+ </models>
19
+ <helpers>
20
+ <sendgrid>
21
+ <class>FreeLunchLabs_SendGrid_Helper</class>
22
+ </sendgrid>
23
+ </helpers>
24
+ <blocks>
25
+ <freelunchlabs_sendgrid>
26
+ <class>FreeLunchLabs_SendGrid_Block</class>
27
+ </freelunchlabs_sendgrid>
28
+ </blocks>
29
+ </global>
30
+ <adminhtml>
31
+ <acl>
32
+ <resources>
33
+ <admin>
34
+ <children>
35
+ <system>
36
+ <children>
37
+ <config>
38
+ <children>
39
+ <sendgrid translate="title" module="sendgrid">
40
+ <title>SendGrid Configuration</title>
41
+ <sort_order>50</sort_order>
42
+ </sendgrid>
43
+ </children>
44
+ </config>
45
+ </children>
46
+ </system>
47
+ </children>
48
+ </admin>
49
+ </resources>
50
+ </acl>
51
+ </adminhtml>
52
+ <default>
53
+ <sendgrid>
54
+ <general>
55
+ <active>0</active>
56
+ </general>
57
+ </sendgrid>
58
+ </default>
59
+ </config>
app/code/community/FreeLunchLabs/SendGrid/etc/system.xml ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <sendgrid translate="label" module="sendgrid">
5
+ <class>separator-top</class>
6
+ <label>SendGrid Configuration</label>
7
+ <tab>general</tab>
8
+ <sort_order>110</sort_order>
9
+ <show_in_default>1</show_in_default>
10
+ <show_in_website>0</show_in_website>
11
+ <show_in_store>0</show_in_store>
12
+ <groups>
13
+ <general translate="label">
14
+ <label>SendGrid Configuration</label>
15
+ <frontend_type>text</frontend_type>
16
+ <sort_order>1</sort_order>
17
+ <show_in_default>1</show_in_default>
18
+ <show_in_website>0</show_in_website>
19
+ <show_in_store>1</show_in_store>
20
+ <fields>
21
+ <active translate="label">
22
+ <label>Enabled SendGrid For Sending Emails</label>
23
+ <frontend_type>select</frontend_type>
24
+ <source_model>adminhtml/system_config_source_yesno</source_model>
25
+ <sort_order>1</sort_order>
26
+ <show_in_default>1</show_in_default>
27
+ <show_in_website>0</show_in_website>
28
+ <show_in_store>0</show_in_store>
29
+ </active>
30
+ <username translate="label comment">
31
+ <label>SendGrid Username</label>
32
+ <frontend_type>text</frontend_type>
33
+ <sort_order>2</sort_order>
34
+ <show_in_default>1</show_in_default>
35
+ <show_in_website>0</show_in_website>
36
+ <show_in_store>0</show_in_store>
37
+ <comment>Your SendGrid Username</comment>
38
+ </username>
39
+ <password translate="label comment">
40
+ <label>SendGrid Password</label>
41
+ <frontend_type>password</frontend_type>
42
+ <sort_order>3</sort_order>
43
+ <show_in_default>1</show_in_default>
44
+ <show_in_website>0</show_in_website>
45
+ <show_in_store>0</show_in_store>
46
+ <comment>Your SendGrid Password</comment>
47
+ </password>
48
+ </fields>
49
+ </general>
50
+ </groups>
51
+ </sendgrid>
52
+ </sections>
53
+ </config>
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>FreeLunchLabs_MailGun</name>
4
- <version>1.0.0</version>
5
  <stability>stable</stability>
6
  <license>Massachusetts Institute of Technology License (MITL)</license>
7
  <channel>community</channel>
@@ -10,11 +10,11 @@
10
  <description>Community extension to send all transactional emails via MailGun. Uses the MailGun web/rest API so emails are send via HTTP eliminating the need for a SMTP service on the server.&#xD;
11
  &#xD;
12
  Keeps track of email events (ie opens, clicks, spam reports...) and formats it into a timeline table that it tied to a customer's records in the Magento Admin.</description>
13
- <notes>First stable release</notes>
14
  <authors><author><name>Charles Drew</name><user>freelunchlabs</user><email>info@freelunchlabs.com</email></author></authors>
15
- <date>2014-10-23</date>
16
- <time>19:20:13</time>
17
- <contents><target name="magecommunity"><dir name="FreeLunchLabs"><dir name="MailGun"><dir name="Block"><dir name="Adminhtml"><dir name="Customer"><dir name="Email"><file name="Grid.php" hash="cb7c77bac08eca31fe835eee5e30bbeb"/></dir><file name="Email.php" hash="14c57a6b10ef0553253962ab230b2ce1"/><dir name="Tab"><file name="Mailgun.php" hash="048db6b7f890f3aec7471e1556819260"/></dir></dir><file name="Emailtracking.php" hash="b1d3754829b97e7008625fa39ad9adf6"/><dir name="Event"><file name="Container.php" hash="712cf721b61a7634711922eca6dd5743"/><file name="Grid.php" hash="1c50d4e231eb3fc78271a789896b500b"/><dir name="Renderer"><file name="Timestamp.php" hash="bcee53b40f2936fcf9f20b2aafcb5616"/><file name="Type.php" hash="f353b01f7f86171b2ff3c920e4d3d723"/></dir></dir><dir name="Global"><file name="Container.php" hash="15edc0b922a74082f2652d939cd03061"/><file name="Grid.php" hash="e26caae9e0d91cfb8cc19734ed342b4d"/></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="063a1cf7646cbf7c99bff0e1ede47177"/></dir><dir name="Model"><dir name="Email"><file name="Template.php" hash="28332f213ca5eb63a8143317c0ad3b93"/></dir><file name="Email.php" hash="120563b544c1313fe9991d292a27ecb1"/><file name="Event.php" hash="b13b9057fc969eb13329f37f33ad75ff"/><dir name="Exceptions"><file name="InvalidParameter.php" hash="8f2484b9abfadf317900cd4fa4a9291a"/><file name="InvalidParameterType.php" hash="0f2c37ff7d3743b121658960627e889c"/><file name="MissingRequiredMIMEParameters.php" hash="64e9466d6027273f9a45a2a41289ed27"/><file name="TooManyParameters.php" hash="bdd51d1d22fcca606a7fff230f3f716e"/></dir><file name="Mailgun.php" hash="da78d7f75fd4fbc1bdb4f81b2259ad6f"/><file name="Messagebuilder.php" hash="d01e64628eae574d0333cc5d562ddf5d"/><dir name="Resource"><dir name="Email"><file name="Collection.php" hash="8750f4d92e14706f9aa43d232e148be0"/></dir><file name="Email.php" hash="4380e6993259ea53fc2b37c4281b8f54"/><dir name="Event"><file name="Collection.php" hash="35bdbf0bcdec4df33f8073fec29afdc1"/></dir><file name="Event.php" hash="e7ac66eb2f30142b5b57acbe46c84a34"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="EmailtrackingController.php" hash="a4c2eb160e733acf9024472a0ef8c1c7"/></dir></dir><dir name="etc"><file name="config.xml" hash="7f1371ef3801a1fa07f6ca09c70d16eb"/><file name="system.xml" hash="8208268e98b32046d34afb7e9b4e6745"/></dir><dir name="sql"><dir name="mailgun_setup"><file name="mysql4-install-1.0.0.php" hash="3429c478be1a072beef83cb6169766b6"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="mailgun.xml" hash="85aed5b6d3aa2ca8934fb98ffa6cb2eb"/></dir><dir name="template"><dir name="mailgun"><dir name="customer"><dir name="tab"><file name="tab.phtml" hash="01bcc905ad74afe78d40114658b69ea0"/></dir></dir><file name="emaildetail.phtml" hash="f9bbfcb29a0ae6fb581ceba2f6682c3f"/><file name="globalemailgrid.phtml" hash="c6331e297cd1645395e7121372ba4ba1"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="FreeLunchLabs_MailGun.xml" hash="f950bcd34fa6d0949074ac5c51375495"/></dir></target></contents>
18
  <compatible/>
19
- <dependencies><required><php><min>5.3.0</min><max>5.6.1</max></php></required></dependencies>
20
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>FreeLunchLabs_MailGun</name>
4
+ <version>1.0.1</version>
5
  <stability>stable</stability>
6
  <license>Massachusetts Institute of Technology License (MITL)</license>
7
  <channel>community</channel>
10
  <description>Community extension to send all transactional emails via MailGun. Uses the MailGun web/rest API so emails are send via HTTP eliminating the need for a SMTP service on the server.&#xD;
11
  &#xD;
12
  Keeps track of email events (ie opens, clicks, spam reports...) and formats it into a timeline table that it tied to a customer's records in the Magento Admin.</description>
13
+ <notes>Stable Production Ready Release. Added support for sending email attachments.</notes>
14
  <authors><author><name>Charles Drew</name><user>freelunchlabs</user><email>info@freelunchlabs.com</email></author></authors>
15
+ <date>2015-04-01</date>
16
+ <time>19:22:33</time>
17
+ <contents><target name="magecommunity"><dir name="FreeLunchLabs"><dir name="CloudFront"><dir name="Block"><dir name="Adminhtml"><file name="Cdnmanagement.php" hash="27d399379552a09312a4ac7231255d2b"/><file name="Testconnection.php" hash="5f4b90cd4aa25685db7bcb2bf985d7d7"/></dir></dir><dir name="Helper"><file name="Data.php" hash="d92fc6f334210d291258b418f342a41e"/></dir><dir name="Model"><file name="Cloudfront.php" hash="531c2785d13efb98aa16d2bc3c30184d"/><file name="Config.php" hash="4b0c72935d0810b6b5073d32c08c8345"/><file name="Observer.php" hash="fa7f4a4073afd7463d29e685b84b1cfb"/><file name="Refresh.php" hash="7b3105c9d818b73737eb2f0591542c3d"/><dir name="Refreshadapters"><file name="Apache.php" hash="e1a6abe6aeb70a4f09ea7a8b7bd506d6"/></dir><dir name="Setup"><file name="Observer.php" hash="a564352145821859a071fe555e0be973"/></dir><file name="Store.php" hash="2041aa5a455acdfbf81bf620c5c6ca40"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="CdnmanagementController.php" hash="dc17b1435b37d106f4f03458822525d9"/><file name="TestconnectionController.php" hash="4039d531425c97f23898489f3ebf61f5"/></dir></dir><dir name="etc"><file name="config.xml" hash="467d4bd82393a2bd33c8d93f1c4277b5"/><file name="system.xml" hash="88ffddb187c87c3f504772d2a32af7e1"/></dir></dir><dir name="MailGun"><dir name="Block"><dir name="Adminhtml"><dir name="Customer"><dir name="Email"><file name="Grid.php" hash="cb7c77bac08eca31fe835eee5e30bbeb"/></dir><file name="Email.php" hash="14c57a6b10ef0553253962ab230b2ce1"/><dir name="Tab"><file name="Mailgun.php" hash="048db6b7f890f3aec7471e1556819260"/></dir></dir><file name="Emailtracking.php" hash="b1d3754829b97e7008625fa39ad9adf6"/><dir name="Event"><file name="Container.php" hash="712cf721b61a7634711922eca6dd5743"/><file name="Grid.php" hash="1c50d4e231eb3fc78271a789896b500b"/><dir name="Renderer"><file name="Timestamp.php" hash="bcee53b40f2936fcf9f20b2aafcb5616"/><file name="Type.php" hash="f353b01f7f86171b2ff3c920e4d3d723"/></dir></dir><dir name="Global"><file name="Container.php" hash="15edc0b922a74082f2652d939cd03061"/><file name="Grid.php" hash="e26caae9e0d91cfb8cc19734ed342b4d"/></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="063a1cf7646cbf7c99bff0e1ede47177"/></dir><dir name="Model"><dir name="Email"><file name="Template.php" hash="59fe0710124bb2ecc21f90f9ec19f610"/></dir><file name="Email.php" hash="120563b544c1313fe9991d292a27ecb1"/><file name="Event.php" hash="b13b9057fc969eb13329f37f33ad75ff"/><dir name="Exceptions"><file name="InvalidParameter.php" hash="8f2484b9abfadf317900cd4fa4a9291a"/><file name="InvalidParameterType.php" hash="0f2c37ff7d3743b121658960627e889c"/><file name="MissingRequiredMIMEParameters.php" hash="64e9466d6027273f9a45a2a41289ed27"/><file name="TooManyParameters.php" hash="bdd51d1d22fcca606a7fff230f3f716e"/></dir><file name="Mailgun.php" hash="94e9bfa2b9d57cfee49969279f5f58b3"/><file name="Messagebuilder.php" hash="2a16c059aaf4fa695007974027bc1809"/><dir name="Resource"><dir name="Email"><file name="Collection.php" hash="8750f4d92e14706f9aa43d232e148be0"/></dir><file name="Email.php" hash="4380e6993259ea53fc2b37c4281b8f54"/><dir name="Event"><file name="Collection.php" hash="35bdbf0bcdec4df33f8073fec29afdc1"/></dir><file name="Event.php" hash="e7ac66eb2f30142b5b57acbe46c84a34"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="EmailtrackingController.php" hash="a4c2eb160e733acf9024472a0ef8c1c7"/></dir></dir><dir name="etc"><file name="config.xml" hash="7f9c114a3fdc6bf68faca04eb1518f3f"/><file name="system.xml" hash="8208268e98b32046d34afb7e9b4e6745"/></dir><dir name="sql"><dir name="mailgun_setup"><file name="mysql4-install-1.0.0.php" hash="3429c478be1a072beef83cb6169766b6"/></dir></dir></dir><dir name="SendGrid"><dir name="Helper"><file name="Data.php" hash="42504974ad0149a441b803781756f18c"/></dir><dir name="Model"><dir name="Email"><file name="Template.php" hash="7159ae2f54bb6457921f5c5aea554878"/></dir></dir><dir name="etc"><file name="config.xml" hash="aef24975c3e0937091093389be2235f1"/><file name="system.xml" hash="50867b8895390683d1181b2ceb3be090"/></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="mailgun.xml" hash="85aed5b6d3aa2ca8934fb98ffa6cb2eb"/></dir><dir name="template"><dir name="mailgun"><dir name="customer"><dir name="tab"><file name="tab.phtml" hash="01bcc905ad74afe78d40114658b69ea0"/></dir></dir><file name="emaildetail.phtml" hash="f9bbfcb29a0ae6fb581ceba2f6682c3f"/><file name="globalemailgrid.phtml" hash="c6331e297cd1645395e7121372ba4ba1"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="FreeLunchLabs_MailGun.xml" hash="f950bcd34fa6d0949074ac5c51375495"/></dir></target></contents>
18
  <compatible/>
19
+ <dependencies><required><php><min>5.3.0</min><max>5.6.7</max></php></required></dependencies>
20
  </package>