From f225ee145f29a792a8c45dc58531ca619b50912f Mon Sep 17 00:00:00 2001 From: Estevao de Oliveira da Costa Date: Mon, 15 Aug 2016 13:15:41 -0300 Subject: [PATCH 1/5] Added new option: GLOBAL_SMTP_AUTH. Allow send mails without authentication. --- global-smtp.php | 592 ++++++++++++++------------- nbproject/private/private.properties | 6 + nbproject/project.properties | 7 + nbproject/project.xml | 9 + 4 files changed, 336 insertions(+), 278 deletions(-) create mode 100644 nbproject/private/private.properties create mode 100644 nbproject/project.properties create mode 100644 nbproject/project.xml diff --git a/global-smtp.php b/global-smtp.php index 775cb95..146c172 100644 --- a/global-smtp.php +++ b/global-smtp.php @@ -1,289 +1,325 @@ prepare_settings(); - $this->errors = $this->validate(); - $this->cancel = array( 'from' => false, 'from_name' => false ); - - if( !empty( $this->errors ) ) { - $this->is_multisite = is_multisite(); - $this->title = __( 'Global SMTP Setup', 'global-smtp' ); - add_action( ( $this->is_multisite ) ? 'network_admin_menu' : 'admin_menu', array( $this, 'register_admin_menu' ) ); - } else { - add_action( 'phpmailer_init', array( $this, 'mailer' ) ); - } - - - // Filter the from name and address early, allowing them to be set in a constant but also overriden by plugins. - - if ( defined( 'GLOBAL_SMTP_FROM' ) ) { - add_filter( 'wp_mail_from', array( $this, 'get_from' ), -999 ); - } - - if ( defined( 'GLOBAL_SMTP_FROM_NAME' ) ) { - add_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ), -999 ); - } - - - add_filter( 'wp_mail', array( $this, 'check_headers') ); - - unset( $this->validations ); - - } - - /** - * Self Instantiate - * Note: Plugin can be disable internally by setting GLOBAL_SMTP_DISABLE to true. - * This is useful if you have different needs between staging and production environments. - */ - public static function launch() { - self::$instance = ( defined( 'GLOBAL_SMTP_DISABLE' ) && GLOBAL_SMTP_DISABLE ) ? null : new self(); - } - - /** - * Get this plugin's main class instance - * @return object - */ - public static function instance() { - return self::$instance; - } - - /** - * Register our admin menu in the correct context. - * @return none - */ - public function register_admin_menu() { - $parent = ( $this->is_multisite ) ? 'settings.php' : 'options-general.php'; - $capability = ( $this->is_multisite ) ? 'manage_network_options' : 'manage_options'; - add_submenu_page( $parent, $this->title, $this->title, $capability, 'global-smtp', array( $this, 'render_admin_page' ) ); - } - - /** - * Display the admin page - * @return none - */ - public function render_admin_page() { - - $minimum = "define('GLOBAL_SMTP_HOST','smtp.gmail.com');\n" . - "define('GLOBAL_SMTP_USER','user@example.com');\n" . - "define('GLOBAL_SMTP_PASSWORD','**********')"; - - $optional = "define('GLOBAL_SMTP_FROM','you@example.com');\n" . - "define('GLOBAL_SMTP_FROM_NAME','Your Name');\n" . - "define('GLOBAL_SMTP_PORT', 465);\n" . - "define('GLOBAL_SMTP_SECURE', 'ssl');"; - - ?> - - -
-

title; ?>

-

check email plugin', 'global-smtp' ), 'https://wordpress.org/plugins/check-email/' ); ?>. -

- -
- errors as $error ) : ?> -

get_error_message(); ?>

- -
-

Example of minimum configuration (example for gmail)', 'global-smtp' ) ?>

-

-

-
-

-

-

-
- - validations = new stdClass; - $this->validations->required = array( 'GLOBAL_SMTP_HOST', 'GLOBAL_SMTP_USER', 'GLOBAL_SMTP_PASSWORD' ); - $this->validations->is_email = array( 'GLOBAL_SMTP_RETURN_PATH', 'GLOBAL_SMTP_REPLYTO_FROM' ); - $this->validations->is_int = array( 'GLOBAL_SMTP_PORT', 'GLOBAL_SMTP_TIMEOUT' ); - $this->validations->should_be = array( 'GLOBAL_SMTP_SECURE' => array( 'ssl', 'tls', 'none' ), 'GLOBAL_SMTP_AUTH_TYPE' => array( 'LOGIN', 'PLAIN', 'NTLM' ) ); - - //Assume any undefined settings - $assume = array( - 'GLOBAL_SMTP_PORT' => 587, - 'GLOBAL_SMTP_SECURE' => 'tls', - 'GLOBAL_SMTP_TIMEOUT' => 10, - 'GLOBAL_SMTP_FROM' => '', - 'GLOBAL_SMTP_FROM_NAME' => '', - 'GLOBAL_SMTP_AUTH_TYPE' => 'LOGIN', - ); - - foreach ( $assume as $setting => $default ) { - if( !defined( $setting ) ) { - define( $setting, $default ); - } - } - } - - /** - * Callback for wp_mail_from filter. - * Applies the from address constant if a - * "From" header was not present. - * @return string from email address - */ - public function get_from( $from ) { - $value = ( $this->cancel['from'] ) ? $from : GLOBAL_SMTP_FROM; - $this->cancel['from'] = false; - return $value; - } - - /** - * Callback for wp_mail_from_name filter - * Applies the from name constant if a - * "From" header was not present. - * @return string from email address - */ - public function get_from_name( $from_name ) { - $value = ( $this->cancel['from_name'] ) ? $from_name : GLOBAL_SMTP_FROM_NAME; - $this->cancel['from_name'] = false; - return $value; - } - - /** - * Validate Configuration to ensure things are setup correctly - * @return bool|WP_Error Returns true if successful, else WP_Error with message - */ - protected function validate() { - - $errors = array(); - - foreach ( $this->validations->required as $setting ) { - if( !defined( $setting ) ) { - $errors[] = new WP_Error( 'global-smtp', sprintf( __( '%s is required for Multisite SMTP. Please define this in wp-config.php.', 'global-smtp' ), $setting ) ); - } - } - - foreach ( $this->validations->is_email as $setting ) { - if ( defined( $setting ) && !is_email( constant( $setting ) ) ) { - $errors[] = new WP_Error( 'global-smtp', sprintf( __( 'Value of %s is not a valid email address. Check wp-config.php, or ensure a valid fallback is available.', 'global-smtp' ), $setting ) ); - } - } - - foreach ( $this->validations->is_int as $setting ) { - if( defined( $setting ) && !is_int( constant( $setting ) ) ) { - $errors[] = new WP_Error( 'global-smtp', sprintf( __( '%s should be a number', 'global-smtp' ), $setting ) ); - } - } - - foreach ( $this->validations->should_be as $setting => $allowed ) { - if( defined( $setting ) && !in_array( constant( $setting ), $allowed ) ) { - $errors[] = new WP_Error( 'global-smtp', sprintf( __( '%s is invalid. It should be one of these values: "%s"', 'global-smtp' ), $setting, implode('" , "', $allowed ) ) ); - } - } - - return $errors; - - } - - /** - * Filter for `wp_mail` used for introspection - * @param array $atts Arguments passed into wp_mail - * @return array Unmodified $atts - */ - public function check_headers( $atts ) { - - // Detect from headers in string based headers - if ( is_string( $atts['headers'] ) && strpos( $atts['headers'], 'From: ' ) !== false ) { - $this->cancel['from'] = true; - $this->cancel['from_name'] = true; - } - - // Detect from headers in array based headers - if ( is_array( $atts['headers'] ) ) { - foreach ( $atts['headers'] as $header) { - if ( is_string( $header ) && strpos( $header, 'From: ' ) !== false ) { - $this->cancel['from'] = true; - $this->cancel['from_name'] = true; - } - } - } - - // Passthough original values unchanged. - return $atts; - - } - - /** - * Hook PHP Mailer to use our SMTP settings - */ - public function mailer( $phpmailer ) { - - // Allow debug output to be displayed - if ( defined('GLOBAL_SMTP_DEBUG') && GLOBAL_SMTP_DEBUG && is_admin() && ( !defined('DOING_AJAX') || !DOING_AJAX ) ) { - - $phpmailer->SMTPDebug = true; - - // There's no way to close this
 without plugging wp_mail, which this project aims to avoid
-			// It will make the PHPMailer output more readable, but only when used with: https://wordpress.org/plugins/check-email/
-			if ( isset( $_GET['page'] ) && 'checkemail' == $_GET['page'] )
-			  echo '
';
-
-		}
-
-		//preset
-		$phpmailer->Mailer = "smtp";
-		$phpmailer->SMTPAuth = true;
-
-		//required
-		$phpmailer->Host = GLOBAL_SMTP_HOST;
-		$phpmailer->Username = GLOBAL_SMTP_USER;
-		$phpmailer->Password = GLOBAL_SMTP_PASSWORD;
-
-		//assumed
-		$phpmailer->Port = (int) GLOBAL_SMTP_PORT;
-		$phpmailer->SMTPSecure = GLOBAL_SMTP_SECURE;
-		$phpmailer->AuthType = GLOBAL_SMTP_AUTH_TYPE;
-
-		//Optional
-		$phpmailer->Sender = defined('GLOBAL_SMTP_RETURN_PATH') ? GLOBAL_SMTP_RETURN_PATH : $phpmailer->From;
-
-		if ( defined('GLOBAL_SMTP_REPLYTO_FROM') ) {
-			$phpmailer->AddReplyTo(GLOBAL_SMTP_REPLYTO_FROM, defined('GLOBAL_SMTP_REPLYTO_FROM_NAME') ? GLOBAL_SMTP_REPLYTO_FROM_NAME : $phpmailer->FromName );
-		}
-
-	}
+    /**
+     * Singleton
+     */
+    protected static $instance;
+
+    /**
+     * Checks settings, and hooks into phpmailer if everything is good.
+     */
+    function __construct() {
+
+        $this->prepare_settings();
+        $this->errors = $this->validate();
+        $this->cancel = array('from' => false, 'from_name' => false);
+
+        if (!empty($this->errors)) {
+            $this->is_multisite = is_multisite();
+            $this->title = __('Global SMTP Setup', 'global-smtp');
+            add_action(( $this->is_multisite ) ? 'network_admin_menu' : 'admin_menu', array($this, 'register_admin_menu'));
+        } else {
+            add_action('phpmailer_init', array($this, 'mailer'));
+        }
+
+
+        // Filter the from name and address early, allowing them to be set in a constant but also overriden by plugins.
+
+        if (defined('GLOBAL_SMTP_FROM')) {
+            add_filter('wp_mail_from', array($this, 'get_from'), -999);
+        }
+
+        if (defined('GLOBAL_SMTP_FROM_NAME')) {
+            add_filter('wp_mail_from_name', array($this, 'get_from_name'), -999);
+        }
+
+
+        add_filter('wp_mail', array($this, 'check_headers'));
+
+        unset($this->validations);
+    }
+
+    /**
+     * Self Instantiate
+     * Note: Plugin can be disable internally by setting GLOBAL_SMTP_DISABLE to true.
+     * This is useful if you have different needs between staging and production environments.
+     */
+    public static function launch() {
+        self::$instance = ( defined('GLOBAL_SMTP_DISABLE') && GLOBAL_SMTP_DISABLE ) ? null : new self();
+    }
+
+    /**
+     * Get this plugin's main class instance
+     * @return object
+     */
+    public static function instance() {
+        return self::$instance;
+    }
+
+    /**
+     * Register our admin menu in the correct context.
+     * @return none
+     */
+    public function register_admin_menu() {
+        $parent = ( $this->is_multisite ) ? 'settings.php' : 'options-general.php';
+        $capability = ( $this->is_multisite ) ? 'manage_network_options' : 'manage_options';
+        add_submenu_page($parent, $this->title, $this->title, $capability, 'global-smtp', array($this, 'render_admin_page'));
+    }
+
+    /**
+     * Display the admin page
+     * @return none
+     */
+    public function render_admin_page() {
+
+        $minimum = "define('GLOBAL_SMTP_HOST','smtp.gmail.com');\n" .
+                "define('GLOBAL_SMTP_AUTH','true');\n" .
+                "define('GLOBAL_SMTP_USER','user@example.com');\n" .
+                "define('GLOBAL_SMTP_PASSWORD','**********')";
+
+        $optional = "define('GLOBAL_SMTP_FROM','you@example.com');\n" .
+                "define('GLOBAL_SMTP_FROM_NAME','Your Name');\n" .
+                "define('GLOBAL_SMTP_PORT', 465);\n" .
+                "define('GLOBAL_SMTP_SECURE', 'ssl');";
+        ?>
+
+
+        
+

title; ?>

+

check email plugin', 'global-smtp'), 'https://wordpress.org/plugins/check-email/'); ?>. +

+ +
+ errors as $error) : ?> +

get_error_message(); ?>

+ +
+

Example of minimum configuration (example for gmail)', 'global-smtp') ?>

+

+

+
+

+

+

+
+ + validations = new stdClass; + $this->validations->required = array('GLOBAL_SMTP_HOST', 'GLOBAL_SMTP_AUTH'); + $this->validations->required_auth = array('GLOBAL_SMTP_USER', 'GLOBAL_SMTP_PASSWORD'); + $this->validations->is_email = array('GLOBAL_SMTP_RETURN_PATH', 'GLOBAL_SMTP_REPLYTO_FROM'); + $this->validations->is_int = array('GLOBAL_SMTP_PORT', 'GLOBAL_SMTP_TIMEOUT'); + $this->validations->should_be = array('GLOBAL_SMTP_SECURE' => array('ssl', 'tls', 'none'), 'GLOBAL_SMTP_AUTH_TYPE' => array('LOGIN', 'PLAIN', 'NTLM')); + + //Assume any undefined settings + $assume = array( + 'GLOBAL_SMTP_PORT' => 587, + 'GLOBAL_SMTP_SECURE' => 'tls', + 'GLOBAL_SMTP_TIMEOUT' => 10, + 'GLOBAL_SMTP_FROM' => '', + 'GLOBAL_SMTP_FROM_NAME' => '', + 'GLOBAL_SMTP_AUTH_TYPE' => 'LOGIN', + ); + + foreach ($assume as $setting => $default) { + if (!defined($setting)) { + define($setting, $default); + } + } + } + + /** + * Callback for wp_mail_from filter. + * Applies the from address constant if a + * "From" header was not present. + * @return string from email address + */ + public function get_from($from) { + $value = ( $this->cancel['from'] ) ? $from : GLOBAL_SMTP_FROM; + $this->cancel['from'] = false; + return $value; + } + + /** + * Callback for wp_mail_from_name filter + * Applies the from name constant if a + * "From" header was not present. + * @return string from email address + */ + public function get_from_name($from_name) { + $value = ( $this->cancel['from_name'] ) ? $from_name : GLOBAL_SMTP_FROM_NAME; + $this->cancel['from_name'] = false; + return $value; + } + + /** + * Validate Configuration to ensure things are setup correctly + * @return bool|WP_Error Returns true if successful, else WP_Error with message + */ + protected function validate() { + + $errors = array(); + + foreach ($this->validations->required as $setting) { + if (!defined($setting)) { + $errors[] = new WP_Error('global-smtp', sprintf(__('%s is required for Multisite SMTP. Please define this in wp-config.php.', 'global-smtp'), $setting)); + } + } + + if (defined('GLOBAL_SMTP_AUTH') && str_true(GLOBAL_SMTP_AUTH)) { + foreach ($this->validations->required_auth as $setting) { + if (!defined($setting)) { + $errors[] = new WP_Error('global-smtp', sprintf(__('%s is required for Multisite SMTP. Please define this in wp-config.php.', 'global-smtp'), $setting)); + } + } + } + + foreach ($this->validations->is_email as $setting) { + if (defined($setting) && !is_email(constant($setting))) { + $errors[] = new WP_Error('global-smtp', sprintf(__('Value of %s is not a valid email address. Check wp-config.php, or ensure a valid fallback is available.', 'global-smtp'), $setting)); + } + } + + foreach ($this->validations->is_int as $setting) { + if (defined($setting) && !is_int(constant($setting))) { + $errors[] = new WP_Error('global-smtp', sprintf(__('%s should be a number', 'global-smtp'), $setting)); + } + } + + foreach ($this->validations->should_be as $setting => $allowed) { + if (defined($setting) && !in_array(constant($setting), $allowed)) { + $errors[] = new WP_Error('global-smtp', sprintf(__('%s is invalid. It should be one of these values: "%s"', 'global-smtp'), $setting, implode('" , "', $allowed))); + } + } + + return $errors; + } + + /** + * Filter for `wp_mail` used for introspection + * @param array $atts Arguments passed into wp_mail + * @return array Unmodified $atts + */ + public function check_headers($atts) { + + // Detect from headers in string based headers + if (is_string($atts['headers']) && strpos($atts['headers'], 'From: ') !== false) { + $this->cancel['from'] = true; + $this->cancel['from_name'] = true; + } + + // Detect from headers in array based headers + if (is_array($atts['headers'])) { + foreach ($atts['headers'] as $header) { + if (is_string($header) && strpos($header, 'From: ') !== false) { + $this->cancel['from'] = true; + $this->cancel['from_name'] = true; + } + } + } + + // Passthough original values unchanged. + return $atts; + } + + /** + * Hook PHP Mailer to use our SMTP settings + */ + public function mailer($phpmailer) { + + // Allow debug output to be displayed + if (defined('GLOBAL_SMTP_DEBUG') && GLOBAL_SMTP_DEBUG && is_admin() && (!defined('DOING_AJAX') || !DOING_AJAX )) { + + $phpmailer->SMTPDebug = true; + + // There's no way to close this
 without plugging wp_mail, which this project aims to avoid
+            // It will make the PHPMailer output more readable, but only when used with: https://wordpress.org/plugins/check-email/
+            if (isset($_GET['page']) && 'checkemail' == $_GET['page'])
+                echo '
';
+        }
+
+        //preset
+        $phpmailer->Mailer = "smtp";
+        $phpmailer->SMTPAuth = str_true(GLOBAL_SMTP_AUTH);
+
+        //required
+        $phpmailer->Host = GLOBAL_SMTP_HOST;
+        if ($phpmailer->SMTPAuth) {
+            $phpmailer->Username = GLOBAL_SMTP_USER;
+            $phpmailer->Password = GLOBAL_SMTP_PASSWORD;
+        }
+
+        //assumed
+        $phpmailer->Port = (int) GLOBAL_SMTP_PORT;
+        $phpmailer->SMTPSecure = GLOBAL_SMTP_SECURE;
+        $phpmailer->AuthType = GLOBAL_SMTP_AUTH_TYPE;
+
+        //Optional
+        $phpmailer->Sender = defined('GLOBAL_SMTP_RETURN_PATH') ? GLOBAL_SMTP_RETURN_PATH : $phpmailer->From;
+
+        if (defined('GLOBAL_SMTP_REPLYTO_FROM')) {
+            $phpmailer->AddReplyTo(GLOBAL_SMTP_REPLYTO_FROM, defined('GLOBAL_SMTP_REPLYTO_FROM_NAME') ? GLOBAL_SMTP_REPLYTO_FROM_NAME : $phpmailer->FromName );
+        }
+    }
+
+}
+
+if (!function_exists('str_true')) {
+
+    /**
+     * Evaluates natural language strings to boolean equivalent
+     *
+     * Used primarily for handling boolean text provided in shopp() tag options.
+     * All values defined as true will return true, anything else is false.
+     *
+     * Boolean values will be passed through.
+     *
+     * Replaces the 1.0-1.1 value_is_true()
+     *
+     * @author Jonathan Davis
+     * @since 1.2
+     *
+     * @param string $string The natural language value
+     * @param array $istrue A list strings that are true
+     * @return boolean The boolean value of the provided text
+     * */
+    function str_true($string, $istrue = array('yes', 'y', 'true', '1', 'on', 'open')) {
+        if (is_array($string)) {
+            return false;
+        }
+        if (is_bool($string)) {
+            return $string;
+        }
+        return in_array(strtolower($string), $istrue);
+    }
 
 }
 
 /**
-* Fire it up.
-*/
+ * Fire it up.
+ */
 Global_SMTP_Mailer::launch();
diff --git a/nbproject/private/private.properties b/nbproject/private/private.properties
new file mode 100644
index 0000000..6b48614
--- /dev/null
+++ b/nbproject/private/private.properties
@@ -0,0 +1,6 @@
+copy.src.files=false
+copy.src.on.open=false
+copy.src.target=
+index.file=
+run.as=LOCAL
+url=http://localhost/global-smtp/
diff --git a/nbproject/project.properties b/nbproject/project.properties
new file mode 100644
index 0000000..d37ef95
--- /dev/null
+++ b/nbproject/project.properties
@@ -0,0 +1,7 @@
+include.path=${php.global.include.path}
+php.version=PHP_54
+source.encoding=UTF-8
+src.dir=.
+tags.asp=false
+tags.short=false
+web.root=.
diff --git a/nbproject/project.xml b/nbproject/project.xml
new file mode 100644
index 0000000..ab1d921
--- /dev/null
+++ b/nbproject/project.xml
@@ -0,0 +1,9 @@
+
+
+    org.netbeans.modules.php.project
+    
+        
+            global-smtp
+        
+    
+

From 6cd73ace71176da1147d54fb6ecf230ad31318cf Mon Sep 17 00:00:00 2001
From: Estevao de Oliveira da Costa 
Date: Mon, 15 Aug 2016 13:40:38 -0300
Subject: [PATCH 2/5] Update readme to include the new option.

---
 README.md  | 11 ++++++++++-
 readme.txt |  5 +++--
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 26669b7..8ea6667 100644
--- a/README.md
+++ b/README.md
@@ -11,13 +11,22 @@ First install as a WordPress pluing. Optionally, you could install as a "must us
 
 Once the plugin is installing installed, add the constants to `wp-config.php`
 
-The minimum requirement is setting the host, username, and password. Everything else will be assumed from some defaults.
+The minimum requirement is setting the host, username, and password (if authentication is needed). Everything else will be assumed from some defaults.
+
 ```
 define('GLOBAL_SMTP_HOST','mail.example.com');
+define('GLOBAL_SMTP_AUTH','true');
 define('GLOBAL_SMTP_USER','admin@example.com');
 define('GLOBAL_SMTP_PASSWORD','password');
 ```
 
+or 
+
+```
+define('GLOBAL_SMTP_HOST','mail.example.com');
+define('GLOBAL_SMTP_AUTH','false');
+```
+
 Assumed defaults:
 * From and From Name: WordPress defaults (or possibly overriden by your mail server)
 * Port -> 587
diff --git a/readme.txt b/readme.txt
index ab00e07..c39d622 100644
--- a/readme.txt
+++ b/readme.txt
@@ -28,8 +28,9 @@ When used with multisite, the configuration is applied network wide. This is oft
 
 **Required**
 `GLOBAL_SMTP_HOST` - The FQDN of the mail server (supplied by your SMTP provider)
-`GLOBAL_SMTP_USER` - Username for accessing the mail server (most often your email address).
-`GLOBAL_SMTP_PASSWORD` - Password to authenticate your email account.
+`GLOBAL_SMTP_AUTH` - True if authentication is needed or false if isn't necessary
+`GLOBAL_SMTP_USER` - If GLOBAL_SMTP_AUTH is true, Username for accessing the mail server (most often your email address).
+`GLOBAL_SMTP_PASSWORD` - If GLOBAL_SMTP_AUTH is true, Password to authenticate your email account.
 
 **Optional**
 `GLOBAL_SMTP_FROM` - Email address to use for outgoing mail. Uses WordPress defaults when not set. Many hosts will force this to be the same as the username.

From c34d7b662dd22e09344549ead683b31b25642e14 Mon Sep 17 00:00:00 2001
From: Estevao de Oliveira da Costa 
Date: Mon, 17 Oct 2016 16:04:05 -0200
Subject: [PATCH 3/5] Add gitignore

---
 .gitignore | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 .gitignore

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7c2dc84
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/nbproject/private*
\ No newline at end of file

From 7573a0695f78493ab549b2645cfdd616abb4fed6 Mon Sep 17 00:00:00 2001
From: Estevao de Oliveira da Costa 
Date: Mon, 5 Dec 2016 14:00:19 -0200
Subject: [PATCH 4/5] Add script to create wordpress plugin zip file

---
 buildZipWP.sh | 5 +++++
 1 file changed, 5 insertions(+)
 create mode 100644 buildZipWP.sh

diff --git a/buildZipWP.sh b/buildZipWP.sh
new file mode 100644
index 0000000..41b08f2
--- /dev/null
+++ b/buildZipWP.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+zip -FSrq global-smtp . -x "nbproject/*" ".*" "*.sh" "*.md"
+
+

From 8e1c1803cdc4de529620b08635425775cc07804f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Estev=C3=A3o=20de=20Oliveira=20da=20Costa?=
 
Date: Wed, 25 Jan 2017 14:13:13 -0200
Subject: [PATCH 5/5] Update gitignore

---
 .gitignore | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index 7c2dc84..14bc68c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-/nbproject/private*
\ No newline at end of file
+/nbproject/private/
\ No newline at end of file