rootPluginFilenameAndPath = $rootPluginFilenameAndPath; // load the dependencies require_once 'PostmanOptions.php'; require_once 'PostmanState.php'; require_once 'PostmanLogger.php'; require_once 'PostmanUtils.php'; require_once 'Postman-Mail/PostmanTransportRegistry.php'; require_once 'Postman-Mail/PostmanDefaultModuleTransport.php'; require_once 'Postman-Mail/PostmanSmtpModuleTransport.php'; require_once 'Postman-Mail/PostmanGmailApiModuleTransport.php'; require_once 'Postman-Mail/PostmanMandrillTransport.php'; require_once 'Postman-Mail/PostmanSendGridTransport.php'; require_once 'Postman-Mail/PostmanMailgunTransport.php'; require_once 'PostmanOAuthToken.php'; require_once 'PostmanWpMailBinder.php'; require_once 'PostmanConfigTextHelper.php'; require_once 'Postman-Email-Log/PostmanEmailLogPostType.php'; require_once 'Postman-Mail/PostmanMyMailConnector.php'; //require_once 'Postman-Mail/PostmanWooCommerce.php'; // get plugin metadata - alternative to get_plugin_data $this->pluginData = array( 'name' => __( 'Postman SMTP', Postman::TEXT_DOMAIN ), 'version' => $version, ); // register the plugin metadata filter (part of the Postman API) add_filter( 'postman_get_plugin_metadata', array( $this, 'getPluginMetaData', ) ); // create an instance of the logger $this->logger = new PostmanLogger( get_class( $this ) ); if ( $this->logger->isDebug() ) { $this->logger->debug( sprintf( '%1$s v%2$s starting', $this->pluginData ['name'], $this->pluginData ['version'] ) ); } if ( isset( $_REQUEST ['page'] ) && $this->logger->isTrace() ) { $this->logger->trace( 'Current page: ' . $_REQUEST ['page'] ); } // register the email transports $this->registerTransports( $rootPluginFilenameAndPath ); // store an instance of the WpMailBinder $this->wpMailBinder = PostmanWpMailBinder::getInstance(); // bind to wp_mail - this has to happen before the "init" action // this design allows other plugins to register a Postman transport and call bind() // bind may be called more than once $this->wpMailBinder->bind(); // registers the custom post type for all callers PostmanEmailLogPostType::automaticallyCreatePostType(); // run the DatastoreUpgrader any time there is a version mismatch if ( PostmanState::getInstance()->getVersion() != $this->pluginData ['version'] ) { // manually trigger the activation hook if ( $this->logger->isInfo() ) { $this->logger->info( sprintf( 'Upgrading datastore from version %s to %s', PostmanState::getInstance()->getVersion(), $this->pluginData ['version'] ) ); } require_once 'PostmanInstaller.php'; $upgrader = new PostmanInstaller(); $upgrader->activatePostman(); } // MyMail integration new PostmanMyMailConnector( $rootPluginFilenameAndPath ); // WooCommerce Integration //new PostmanWoocommerce(); // register the shortcode handler on the add_shortcode event add_shortcode( 'postman-version', array( $this, 'version_shortcode', ) ); // hook on the plugins_loaded event add_action( 'plugins_loaded', array( $this, 'on_plugins_loaded', ) ); /** * @todo: WPML say they fix the issue in version 3.9 * https://wordpress.org/support/topic/error-in-pluggable-php173/#post-10021301 */ if ( get_option( 'icl_sitepress_version' ) && version_compare( get_option( 'icl_sitepress_version' ), '3.9', '<' ) ) { $active_plugins = (array)get_option('active_plugins', array()); if (in_array('sitepress-multilingual-cms/sitepress.php', $active_plugins) && !get_option('postman_wpml_fixed')) { add_action('admin_notices', array($this, 'post_smtp_wpml_admin_notice')); // Temp: Just a quick solution, need to find a better option. add_action('admin_init', array($this, 'postman_fix_wpml')); } } // hook on the wp_loaded event add_action( 'wp_loaded', array( $this, 'on_wp_loaded', ) ); // hook on the acivation event register_activation_hook( $rootPluginFilenameAndPath, array( $this, 'on_activation', ) ); // hook on the deactivation event register_deactivation_hook( $rootPluginFilenameAndPath, array( $this, 'on_deactivation', ) ); } public function post_smtp_wpml_admin_notice() { $class = 'notice notice-error'; $title = __( 'Post SMTP notice!', Postman::TEXT_DOMAIN ); $intro = __( 'WPML is installed and has a known bug with Post SMTP and few other plugins - you better upgrade, but we can try to fix it.', Postman::TEXT_DOMAIN ); $text = __( 'Click here to fix', Postman::TEXT_DOMAIN ); $message = '
' . $text . ''; printf( '

%2$s

%3$s

%4$s

', esc_attr( $class ), $title, $intro, $message ); } public function postman_fix_wpml() { if ( isset( $_GET['action'] ) && $_GET['action'] == 'postman_fix_wpml' ) { $wpml_file_path = WP_PLUGIN_DIR . '/sitepress-multilingual-cms/inc/utilities/wpml-data-encryptor.class.php'; if ( file_exists( $wpml_file_path ) ) { $content = file_get_contents( $wpml_file_path ); $content = str_replace( "require_once ABSPATH . '/wp-includes/pluggable.php';", "//require_once ABSPATH . '/wp-includes/pluggable.php';", $content ); file_put_contents( $wpml_file_path, $content ); } update_option( 'postman_wpml_fixed', true ); wp_redirect( esc_url( remove_query_arg( 'action' ) ) ); } } /** * Functions to execute on the plugins_loaded event * * "After active plugins and pluggable functions are loaded" * ref: http://codex.wordpress.org/Plugin_API/Action_Reference#Actions_Run_During_a_Typical_Request */ public function on_plugins_loaded() { // load the text domain $this->loadTextDomain(); // register the setup_admin function on plugins_loaded because we need to call // current_user_can to verify the capability of the current user if ( PostmanUtils::isAdmin() && is_admin() ) { $this->setup_admin(); } } /** * Functions to execute on the wp_loaded event * * "After WordPress is fully loaded" * ref: http://codex.wordpress.org/Plugin_API/Action_Reference#Actions_Run_During_a_Typical_Request */ public function on_wp_loaded() { // register the check for configuration errors on the wp_loaded hook, // because we want it to run after the OAuth Grant Code check on the init hook $this->check_for_configuration_errors(); } /** * Functions to execute on the register_activation_hook * ref: https://codex.wordpress.org/Function_Reference/register_activation_hook */ public function on_activation() { if ( $this->logger->isInfo() ) { $this->logger->info( 'Activating plugin' ); } require_once 'PostmanInstaller.php'; $upgrader = new PostmanInstaller(); $upgrader->activatePostman(); } /** * Functions to execute on the register_deactivation_hook * ref: https://codex.wordpress.org/Function_Reference/register_deactivation_hook */ public function on_deactivation() { if ( $this->logger->isInfo() ) { $this->logger->info( 'Deactivating plugin' ); } require_once 'PostmanInstaller.php'; $upgrader = new PostmanInstaller(); $upgrader->deactivatePostman(); } /** * If the user is on the WordPress Admin page, creates the Admin screens */ public function setup_admin() { $this->logger->debug( 'Admin start-up sequence' ); $options = PostmanOptions::getInstance(); $authToken = PostmanOAuthToken::getInstance(); $rootPluginFilenameAndPath = $this->rootPluginFilenameAndPath; // load the dependencies require_once 'PostmanMessageHandler.php'; require_once 'PostmanAdminController.php'; require_once 'Postman-Controller/PostmanWelcomeController.php'; require_once 'Postman-Controller/PostmanDashboardWidgetController.php'; require_once 'Postman-Controller/PostmanAdminPointer.php'; require_once 'Postman-Email-Log/PostmanEmailLogController.php'; require_once 'Postman-Connectivity-Test/PostmanConnectivityTestController.php'; require_once 'Postman-Configuration/PostmanConfigurationController.php'; require_once 'Postman-Send-Test-Email/PostmanSendTestEmailController.php'; require_once 'Postman-Diagnostic-Test/PostmanDiagnosticTestController.php'; // create and store an instance of the MessageHandler $this->messageHandler = new PostmanMessageHandler(); // create the Admin Controllers new PostmanWelcomeController( $rootPluginFilenameAndPath ); new PostmanDashboardWidgetController( $rootPluginFilenameAndPath, $options, $authToken, $this->wpMailBinder ); new PostmanAdminController( $rootPluginFilenameAndPath, $options, $authToken, $this->messageHandler, $this->wpMailBinder ); new PostmanEmailLogController( $rootPluginFilenameAndPath ); new PostmanConnectivityTestController( $rootPluginFilenameAndPath ); new PostmanConfigurationController( $rootPluginFilenameAndPath ); new PostmanSendTestEmailController( $rootPluginFilenameAndPath ); new PostmanDiagnosticTestController( $rootPluginFilenameAndPath ); // register the Postman signature (only if we're on a postman admin screen) on the in_admin_footer event if ( PostmanUtils::isCurrentPagePostmanAdmin() ) { add_action( 'in_admin_footer', array( $this, 'print_signature', ) ); } } /** * Check for configuration errors and displays messages to the user */ public function check_for_configuration_errors() { $options = PostmanOptions::getInstance(); $authToken = PostmanOAuthToken::getInstance(); // did Postman fail binding to wp_mail()? if ( $this->wpMailBinder->isUnboundDueToException() ) { // this message gets printed on ANY WordPress admin page, as it's a fatal error that // may occur just by activating a new plugin // log the fatal message $this->logger->fatal( 'Postman: wp_mail has been declared by another plugin or theme, so you won\'t be able to use Postman until the conflict is resolved.' ); if ( PostmanUtils::isAdmin() && is_admin() ) { // on any admin pages, show this error message // I noticed the wpMandrill and SendGrid plugins have the exact same error message here // I've adopted their error message as well, for shits and giggles .... :D $reflFunc = new ReflectionFunction( 'wp_mail' ); $message = __( 'Postman: wp_mail has been declared by another plugin or theme, so you won\'t be able to use Postman until the conflict is resolved.', Postman::TEXT_DOMAIN ); $plugin_full_path = $reflFunc->getFileName(); if ( strpos( $plugin_full_path, 'plugins' ) !== false ) { require_once ABSPATH . '/wp-admin/includes/plugin.php'; preg_match( '/([a-z]+\/[a-z]+\.php)$/', $plugin_full_path, $output_array ); $plugin_file = $output_array[1]; $plugin_data = get_plugin_data( $plugin_full_path ); $deactivate_url = '' . __( 'Deactivate' ) . '
'; $message .= '
Plugin Name: ' . $plugin_data['Name']; $message .= '
' . $deactivate_url; } $message .= '
More info that may help - ' . $reflFunc->getFileName() . ':' . $reflFunc->getStartLine(); $this->messageHandler->addError( $message ); } } else { $transport = PostmanTransportRegistry::getInstance()->getCurrentTransport(); $scribe = $transport->getScribe(); $virgin = $options->isNew(); if ( ! $transport->isConfiguredAndReady() ) { // if the configuration is broken, and the user has started to configure the plugin // show this error message $messages = $transport->getConfigurationMessages(); foreach ( $messages as $message ) { if ( $message ) { // log the warning message $this->logger->warn( sprintf( '%s Transport has a configuration problem: %s', $transport->getName(), $message ) ); if ( PostmanUtils::isAdmin() && PostmanUtils::isCurrentPagePostmanAdmin() ) { // on pages that are Postman admin pages only, show this error message $this->messageHandler->addError( $message ); } } } } // on pages that are NOT Postman admin pages only, show this error message if ( PostmanUtils::isAdmin() && ! PostmanUtils::isCurrentPagePostmanAdmin() && ! $transport->isConfiguredAndReady() ) { // on pages that are *NOT* Postman admin pages only.... // if the configuration is broken show this error message add_action( 'admin_notices', array( $this, 'display_configuration_required_warning', ) ); } } } /** * Returns the plugin version number and name * Part of the Postman API * * @return multitype:unknown NULL */ public function getPluginMetaData() { // get plugin metadata return $this->pluginData; } /** * This is the general message that Postman requires configuration, to warn users who think * the plugin is ready-to-go as soon as it is activated. * This message only goes away once the plugin is configured. */ public function display_configuration_required_warning() { if ( PostmanUtils::isAdmin() ) { if ( $this->logger->isDebug() ) { $this->logger->debug( 'Displaying configuration required warning' ); } $msg = PostmanTransportRegistry::getInstance()->getReadyMessage(); $message = sprintf( $msg['message'] ); $goToSettings = sprintf( '%s', PostmanUtils::getSettingsPageUrl(), __( 'Settings', Postman::TEXT_DOMAIN ) ); $goToEmailLog = sprintf( '%s', _x( 'Email Log', 'The log of Emails that have been delivered', Postman::TEXT_DOMAIN ) ); if ( PostmanOptions::getInstance()->isMailLoggingEnabled() ) { $goToEmailLog = sprintf( '%s', PostmanUtils::getEmailLogPageUrl(), $goToEmailLog ); } $message .= (sprintf( ' %s | %s', $goToEmailLog, $goToSettings )); $message .= ''; $hide = get_option('postman_release_version_not_configured' ); if ( $msg['error'] == true && ! $hide ) { $this->messageHandler->printMessage( $message, 'postman-not-configured-notice notice notice-error is-dismissible' ); } } } /** * Register the email transports. * * The Gmail API used to be a separate plugin which was registered when that plugin * was loaded. But now both the SMTP, Gmail API and other transports are registered here. * * @param unknown $pluginData */ private function registerTransports( $rootPluginFilenameAndPath ) { PostmanTransportRegistry::getInstance()->registerTransport( new PostmanDefaultModuleTransport( $rootPluginFilenameAndPath ) ); PostmanTransportRegistry::getInstance()->registerTransport( new PostmanSmtpModuleTransport( $rootPluginFilenameAndPath ) ); PostmanTransportRegistry::getInstance()->registerTransport( new PostmanGmailApiModuleTransport( $rootPluginFilenameAndPath ) ); PostmanTransportRegistry::getInstance()->registerTransport( new PostmanMandrillTransport( $rootPluginFilenameAndPath ) ); PostmanTransportRegistry::getInstance()->registerTransport( new PostmanSendGridTransport( $rootPluginFilenameAndPath ) ); PostmanTransportRegistry::getInstance()->registerTransport( new PostmanMailgunTransport( $rootPluginFilenameAndPath ) ); } /** * Print the Postman signature on the bottom of the page * * http://striderweb.com/nerdaphernalia/2008/06/give-your-wordpress-plugin-credit/ */ function print_signature() { printf( '%s %s
', $this->pluginData ['name'], $this->pluginData ['version'] ); } /** * Loads the appropriate language file */ private function loadTextDomain() { // had to hardcode the third parameter, Relative path to WP_PLUGIN_DIR, // because __FILE__ returns the wrong path if the plugin is installed as a symlink $shortLocale = substr( get_locale(), 0, 2 ); if ( $shortLocale != 'en' ) { $langDir = 'postman-smtp/Postman/languages'; $success = load_plugin_textdomain( Postman::TEXT_DOMAIN, false, $langDir ); if ( $this->logger->isDebug() ) { if ( $success ) { $this->logger->debug( sprintf( 'local translation file loaded for locale=%s', get_locale() ) ); } else { $this->logger->debug( sprintf( 'failed to load local translation file: locale=%s file=%s/%s-%s.mo', get_locale(), $langDir, Postman::TEXT_DOMAIN, get_locale() ) ); } } } } /** * Shortcode to return the current plugin version. * * From http://code.garyjones.co.uk/get-wordpress-plugin-version/ * * @return string Plugin version */ function version_shortcode() { return $this->pluginData ['version']; } } if ( ! function_exists( 'str_getcsv' ) ) { /** * PHP version less than 5.3 don't have str_getcsv natively. * * @param unknown $string * @return multitype: */ function str_getcsv( $string ) { $logger = new PostmanLogger( 'postman-common-functions' ); if ( $logger->isDebug() ) { $logger->debug( 'Using custom str_getcsv' ); } return PostmanUtils::postman_strgetcsv_impl( $string ); } }