wpmudev-sls
6/1/2018 - 6:10 PM

[MarketPress] - Preview Order Notifications

Preview Order Notifications

<?php
/**
* Plugin Name: [MarketPress] - Preview Order Notifications
* Plugin URI: https://premium.wpmudev.org/
* Description: Preview Order Notifications
* Author: Panos Lyrakis @ WPMUDEV
* Author URI: https://premium.wpmudev.org/
* License: GPLv2 or later
*/
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

if ( ! class_exists( 'WPMUDEV_MP_Preview_Notifications' ) ) {
    
    class WPMUDEV_MP_Preview_Notifications {
        private static $_instance = null;

        public static function get_instance() {
            if( is_null( self::$_instance ) ){
                self::$_instance = new WPMUDEV_MP_Preview_Notifications();
            }
            return self::$_instance;
            
        }

        private function __construct() {

        	add_action( 'admin_menu', array( $this, 'admin_menu' ), 20 );
        	add_action( 'load-product_page_mp_order_notification_previews', array( $this, 'footer_hook' ) );
        	add_action( 'wp_ajax_wpmudev_send_mp_preview', array( $this, 'send_preview' ) );
        }

        public function footer_hook() {
        	add_action( 'admin_footer', array( $this, 'footer_scripts' ) );
        }

        public function admin_menu() {

        	$order_cap = apply_filters( 'mp_orders_cap', 'edit_store_orders' );

        	if ( current_user_can( $order_cap ) ) {
        		$preview_page = add_submenu_page( 'edit.php?post_type=' . MP_Product::get_post_type(), __( 'Preview Notifications', 'mp' ), __( 'Preview Notifications', 'mp' ), $order_cap, 'mp_order_notification_previews', array( $this, 'admin_page' ) );
        	}

        }


        public function admin_page() {
        	?>
        	<h1><?php _e( 'Notifications Previews', 'mp' ); ?></h1>

        	<div id="preview-options-wrap">
        		<fieldset style="float: left; padding: 0 20px 0 20px;">
        			<legend style="font-weight: bold;"><?php _e( 'Select an order id:', 'mp' ); ?></legend>
        			<?php $this->print_orders_list(); ?>
        		</fieldset>

        		<fieldset style="float: left; padding: 0 20px 0 20px;">
        			<legend style="font-weight: bold;"><?php _e( 'Choose notification type:', 'mp' ); ?></legend>
        			<label>
        				<?php _e( 'New Order', 'mp' ); ?>
        				<input type="radio" name="notification-type" id="notification-type" value="new-order" checked="checked" />
        			</label>
        			<br />
        			<label>
        				<?php _e( 'Order Shipped', 'mp' ); ?>
        				<input type="radio" name="notification-type" id="notification-type" value="order-shipped" />
        			</label>
        		</fieldset>

        		<fieldset style="float: left; padding: 0 20px 0 20px;">
        			<legend style="font-weight: bold;"><?php _e( 'Send to:', 'mp' ); ?></legend>
        			<input type="email" value="<?php echo mp_get_store_email(); ?>" id="send-to" />
        		</fieldset>

        		<fieldset style="float: left; padding: 0 20px 0 20px;">
        			<br />
        			<a class="button-secondary" id="send-button"><?php _e( 'Send preview', 'mp' ); ?></a>
        		</fieldset>

        		<div style="clear: both;"></div>
        	</div>

        	<?php
        }


        protected function _send_new_order_notifications( $order, $send_to = null ) {

        	if ( ! $order instanceof MP_Order ) {
        		return false;
        	}

        	$send_to = is_null( $send_to ) ? mp_get_store_email() : $send_to;       

			// We can't rely on cart's is_digital_only() because we have three scenarios here
			$has_downloads = $has_physical = false;
			$items = $order->get_cart()->get_items_as_objects();
			foreach ( $items as $product ) {
				if( $product->is_download() ) {
					$has_downloads = true;
				} else {
					$has_physical = true;
				}
			}

			$notification_kind = 'new_order';
			if($has_downloads && $has_physical) {
				$notification_kind = 'new_order_mixed';
			} else if( $has_downloads ) {
				$notification_kind = 'new_order_downloads';
			}

			$send_email = mp_get_setting( 'email->'.$notification_kind.'->send_email', 1 );
			if ( $send_email ) {
				$subject = mp_filter_email( $order, stripslashes( mp_get_setting( 'email->'.$notification_kind.'->subject' ) ) );
				$msg     = mp_filter_email( $order, nl2br( stripslashes( mp_get_setting( 'email->'.$notification_kind.'->text' ) ) ) );

				$subject = apply_filters( 'mp_order/notification_subject', $subject, $order );

				$msg         = apply_filters( 'mp_order/notification_body', $msg, $order );
				$msg         = apply_filters( 'mp_order/notification_body/' . mp_get_post_value( 'payment_method', '' ), $msg, $order );
				$attachments = apply_filters( 'mp_order/sendmail_attachments', array(), $order, 'new_order_client' );

				return mp_send_email( $send_to, $subject, $msg, $attachments );

			}

		}

		protected function _send_shipment_notification( $order, $send_to = null ) {

			if ( ! $order instanceof MP_Order ) {
        		return false;
        	}

        	$send_to = is_null( $send_to ) ? mp_get_store_email() : $send_to;

			// We can't rely on cart's is_digital_only() because we have three scenarios here
			$has_downloads = $has_physical = false;
			$items = $order->get_cart()->get_items_as_objects();
			foreach ( $items as $product ) {
				if( $product->is_download() ) {
					$has_downloads = true;
				} else {
					$has_physical = true;
				}
			}

			$notification_kind = 'order_shipped';
			if($has_downloads && $has_physical) {
				$notification_kind = 'order_shipped_mixed';
			} else if( $has_downloads ) {
				$notification_kind = 'order_shipped_downloads';
			}

			$send_email = mp_get_setting( 'email->'.$notification_kind.'->send_email', 1 );
			if ( $send_email ) {
				$subject = stripslashes( mp_get_setting( 'email->'.$notification_kind.'->subject' ) );
				$msg     = nl2br( stripslashes( mp_get_setting( 'email->'.$notification_kind.'->text' ) ) );

				if ( has_filter( 'mp_shipped_order_notification_subject' ) ) {
					trigger_error( 'The <strong>mp_shipped_order_notification_subject</strong> hook has been replaced with <strong>mp_order/shipment_notification_subject</strong> as of MP 3.0', E_USER_ERROR );
				}

				if ( has_filter( 'mp_shipped_order_notification_body' ) ) {
					trigger_error( 'The <strong>mp_shipped_order_notification_body</strong> hook has been replaced with <strong>mp_order/shipment_notification_body</strong> as of MP 3.0', E_USER_ERROR );
				}

				if ( has_filter( 'mp_shipped_order_notification' ) ) {
					trigger_error( 'The <strong>mp_shipped_order_notification</strong> hook has been replaced with <strong>mp_order/shipment_notification</strong> as of MP 3.0', E_USER_ERROR );
				}

				$subject = apply_filters( 'mp_order/shipment_notification_subject', $subject, $order );
				$subject = mp_filter_email( $order, $subject );

				$msg = apply_filters( 'mp_order/shipment_notification_body', $msg, $order );
				$msg = mp_filter_email( $order, $msg );

				$msg         = apply_filters( 'mp_order/shipment_notification', $msg, $order );
				$attachments = apply_filters( 'mp_order/sendmail_attachments', array(), $order, 'order_shipped_client' );
				
				return mp_send_email( $send_to, $subject, $msg, $attachments );
			}
		}

		public function send_preview() {

        	check_ajax_referer( 'wpmudev_mp_previews_nonce', 'nonce' );

			global $wpdb;
			$order_id 	= filter_input( INPUT_POST, 'order_id', FILTER_VALIDATE_INT );
			$type 		= filter_input( INPUT_POST, 'type', FILTER_DEFAULT );
			$send_to 	= filter_input( INPUT_POST, 'send_to', FILTER_VALIDATE_EMAIL );
			$order 		= new MP_Order( $order_id );

			if ( 'new-order' === $type ) {
				if( $this->_send_new_order_notifications( $order, $send_to ) ) {
					$return = array(
					    'message'  => '_SUCCESS_',
					);

					wp_send_json($return);
				}
			}
			elseif ( 'order-shipped' === $type ) {

				if( $this->_send_shipment_notification( $order, $send_to ) ) {
					$return = array(
					    'message'  => '_SUCCESS_',
					);

					wp_send_json($return);
				}

			}

			$return = array(
			    'message'  => '_FAIL_',
			);

			wp_send_json($return);

        }

		public function footer_scripts(){
        	?>
        	<script type="text/javascript">
        		(function(d,$){
        			$(d).ready(function(){
        				const 	send_button = $('#send-button'),
        						orig_btn_txt = send_button.html(),
        						wpmudev_previews_nonce = '<?php echo wp_create_nonce("wpmudev_mp_previews_nonce"); ?>';        				

        				$(send_button).on('click', function(){
        					let order_id = $( '#order_id' ).val(),
        						type = $( 'input[name=notification-type]:checked' ).val(),
        						send_to = $('#send-to').val(),
        						notice;
        						ajax_data ={
	        						action: 		'wpmudev_send_mp_preview',
									nonce: 			wpmudev_previews_nonce,
									order_id: 		order_id,
									type: 			type,
									send_to: 		send_to
	        					};

	        					send_button.html( 'Sending <img src="/wp-admin/images/spinner.gif" />' ).prop( "disabled", true );

	        					$.ajax({
								    type: "POST",
								    url: ajaxurl,						    
								    data: ajax_data,
								    dataType: "json",
								    success: function(resp){

								    	if( resp.message == "_SUCCESS_" ) {
								    		notice = $('<div />',{
								    			'class': 'updated notice is-dismissible',
								    			text : 'Preview has been sent fuccesfully to ' + send_to
								    		});
								    	}
								    	else{
								    		notice = $('<div />',{
								    			'class': 'error notice is-dismissible',
								    			'html' : '<p>Something went wrong and the preview was not sent to <strong>' + send_to + '</strong></p>'
								    		});
								    	}

								    	$('#preview-options-wrap').append(notice);
								    	setTimeout(function(){
										  notice.hide(300, function(){$(this).remove()} );
										}, 5000);
								    	send_button.html(orig_btn_txt).prop( "disabled", false );
								    },
								    failure: function(errMsg) {
								        console.log(errMsg);
								    }
								});
        				});
        			});
        		})(document,jQuery);
        	</script>
        	<?php
        }


        public function print_orders_list() {
        	$orders 	= $this->get_orders();
        	$options 	= '';

        	foreach ( $orders as $order_id ) {
        		$options .= sprintf( '<option value="%1$d">%1$d</option>' . PHP_EOL , $order_id );
        	}
        	
        	?>	
        	<select id="order_id">
        		<?php echo $options; ?>
        	</select>
        	<?php
        }

        public function get_orders( $args = array() ) {

        	$default_args = array(
        		'post_type' 		=> 'mp_order',
        		'posts_per_page' 	=> -1,
        		'order'				=> 'DESC',
        		'order_by'			=> 'ID',
        		'post_status'		=> 'any',
        		'fields'			=> 'ids'
        	);

        	$args = wp_parse_args( $args, $default_args );

        	$order_ids = new WP_Query( $args );
        	return $order_ids->posts;

        }

    }

    if ( ! function_exists( 'wpmudev_mp_preview_notifications' ) ) {

		function wpmudev_mp_preview_notifications() {
			return WPMUDEV_MP_Preview_Notifications::get_instance();
		}

		add_action( 'plugins_loaded', 'wpmudev_mp_preview_notifications', 10 );
	}

}