<?php
if (!defined('ABSPATH'))
    die('No direct access allowed');

//18-04-2016
final class WOOF_EXT_PRODS_MESSENGER extends WOOF_EXT {

    public $type = 'by_html_type';
    public $html_type = 'products_messenger'; //your custom key here
    public $index = '';
    public $html_type_dynamic_recount_behavior = 'none';
    protected $user_meta_key = 'woof_user_messenger';
    //public $unsubscribe_lang="";  //not use now
    public $subscribe_lang = "";
    public $date_expire = "";
    public $count_message = -1;
    public $subscr_count = 2; //options
    public $priority_limit = 'both';
    public $subscr_period_option = "twicemonthly"; //options
    public $header_email = '';
    public $subject_email = '';
    public $text_email = '';
    public $cron = NULL;
    public $cron_hook = 'woof_products_messenger';
    public $wp_cron_period = WEEK_IN_SECONDS;

    public function __construct() {
	parent::__construct();
	//lang variables
	$this->header_email = __("New Products by your request", 'woocommerce-products-filter');
	$this->subject_email = __("New products", 'woocommerce-products-filter');
	$this->text_email = __("Dear [DISPLAY_NAME], we increased the range of our products. Number of new products: [PRODUCT_COUNT]", 'woocommerce-products-filter');

	//***

	if (isset($this->woof_settings["products_messenger"]['subscr_count']) AND ! empty($this->woof_settings["products_messenger"]['subscr_count'])) {
	    $this->subscr_count = (int) $this->woof_settings["products_messenger"]['subscr_count'];
	}
	if (isset($this->woof_settings["products_messenger"]['wp_cron_period'])AND ! empty($this->woof_settings["products_messenger"]['wp_cron_period'])) {
	    $this->subscr_period_option = $this->woof_settings["products_messenger"]['wp_cron_period'];
	}
	if (isset($this->woof_settings["products_messenger"]['header_email'])AND ! empty($this->woof_settings["products_messenger"]['header_email'])) {
	    $this->header_email = $this->woof_settings["products_messenger"]['header_email'];
	}
	if (isset($this->woof_settings["products_messenger"]['subject_email'])AND ! empty($this->woof_settings["products_messenger"]['subject_email'])) {
	    $this->subject_email = $this->woof_settings["products_messenger"]['subject_email'];
	}
	if (isset($this->woof_settings["products_messenger"]['text_email'])AND ! empty($this->woof_settings["products_messenger"]['text_email'])) {
	    $this->text_email = $this->woof_settings["products_messenger"]['text_email'];
	}
	if (isset($this->woof_settings["products_messenger"]['date_expire'])AND !empty($this->woof_settings["products_messenger"]['date_expire'])) {
	    $this->date_expire = $this->woof_settings["products_messenger"]['date_expire'];
	}
	if (isset($this->woof_settings["products_messenger"]['count_message'])AND ! empty($this->woof_settings["products_messenger"]['count_message'])) {
	    $this->count_message = $this->woof_settings["products_messenger"]['count_message'];
	}
	if (isset($this->woof_settings["products_messenger"]['priority_limit'])AND ! empty($this->woof_settings["products_messenger"]['priority_limit'])) {
	    $this->priority_limit = $this->woof_settings["products_messenger"]['priority_limit'];
	}

	$this->subscribe_lang = __('Subscription', 'woocommerce-products-filter');
	//$this->unsubscribe_lang =__('Unsubscribe','woocommerce-products-filter');  // not used
	add_action('woof_products_messenger', array($this, 'woof_products_messenger'), 10);
	$this->cron = new PN_WP_CRON_WOOF('woof_messenger_wpcron');
	$this->wp_cron_period = (int) $this->get_woof_cron_schedules($this->subscr_period_option);
	$this->make_send_emails();
	$this->init();
    }

    public function get_ext_path() {
	return plugin_dir_path(__FILE__);
    }

    public function get_ext_link() {
	return plugin_dir_url(__FILE__);
    }

    public function woof_add_items_keys($keys) {
	$keys[] = $this->html_type;
	return $keys;
    }

    public function init() {
	add_filter('woof_add_items_keys', array($this, 'woof_add_items_keys'));
	add_action('woof_print_html_type_options_' . $this->html_type, array($this, 'woof_print_html_type_options'), 10, 1);
	add_action('woof_print_html_type_' . $this->html_type, array($this, 'print_html_type'), 10, 1);
	add_action('wp_head', array($this, 'wp_head'), 999);
	// Ajax  action
	add_action('wp_ajax_woof_messenger_add_subscr', array($this, 'woof_add_subscr'));
	add_action('wp_ajax_nopriv_woof_messenger_add_subscr', array($this, 'woof_add_subscr'));
	add_action('wp_ajax_woof_messenger_remove_subscr', array($this, 'woof_remove_subscr'));
	add_action('wp_ajax_nopriv_woof_messenger_remove_subscr', array($this, 'woof_remove_subscr'));
	//+++
	// Check if user want to unsubscribe without auth  AND check external cron  Plugin shuld be init on  current page
	add_action('init', array($this, 'woof_unsubscr'));
        // add shortcode
        add_shortcode('woof_products_messenger',array($this,'woof_products_messenger_shortcode'));
   
	//add_action('init', array($this, 'woof_external_cron_init'));
       
	self::$includes['js']['woof_' . $this->html_type . '_html_items'] = $this->get_ext_link() . 'js/' . $this->html_type . '.js';
	self::$includes['css']['woof_' . $this->html_type . '_html_items'] = $this->get_ext_link() . 'css/' . $this->html_type . '.css';
	self::$includes['js_init_functions'][$this->html_type] = 'woof_init_products_messenger';
    }

    public function woof_unsubscr() {
	global $WOOF;
	$this->woof_external_cron_init();
	if (!isset($_GET['id_user']) OR ! isset($_GET['key']) OR ! isset($_GET['woof_skey'])) {
	    return;
	}

	$sanit_get = $this->sanitaz_array_r($_GET);
	$subscr = get_user_meta($sanit_get['id_user'], $this->user_meta_key, true);
	$text = "";
	if ($subscr[$sanit_get['key']]['secret_key'] == $sanit_get['woof_skey']) {
	    unset($subscr[$sanit_get['key']]);
	    update_user_meta($sanit_get['id_user'], $this->user_meta_key, $subscr);
	    // $text=__('You unsubscribed from the newsletter.','woocommerce-products-filter'); 
	} else {
	    // $text=__('This link does not work.','woocommerce-products-filter'); // if you want use another message
	}
	$data['text'] = __('You are unsubscribed from the future products newsletters.', 'woocommerce-products-filter');
	echo $WOOF->render_html($this->get_ext_path() . 'views' . DIRECTORY_SEPARATOR . 'unsubscr_template.php', $data);
	die();
    }

    public function woof_external_cron_init() {

	global $WOOF;
         
	//check secret key  ( min  16 symbol )  
	if (!isset($_GET['woof_pm_cron_key']) OR empty($_GET['woof_pm_cron_key']) OR strlen($_GET['woof_pm_cron_key']) < 16) {
	    return false;
	}

	$sanitazed_key = WOOF_HELPER::escape($_GET['woof_pm_cron_key']);
	if ($sanitazed_key AND isset($WOOF->settings['products_messenger']['use_external_cron']) AND $WOOF->settings['products_messenger']['use_external_cron'] === $sanitazed_key) {
	    $this->woof_do_mesenger_action();
	} else {
	    return false;
	}
    }

    public function woof_do_mesenger_action() { //return;
	global $wpdb;
	// get all users
	$users = get_users(array('count_total' => false, 'fields' => array('ID', 'display_name', 'user_login', 'user_nicename', ' user_email'),));
        
	foreach ($users as $user) {
	    $data_user = get_user_meta($user->ID, $this->user_meta_key, true); // get subscribtion of user 
	    if (empty($data_user) OR count($data_user) <= 0 OR ! is_array($data_user)) {
		continue;
	    }
	    foreach ($data_user as $key => $data_subscr) {    // check subcr
		$data_email = array();
		$data_email['products'] = array();
		$products = $wpdb->get_results($data_subscr['request']);
		foreach ($products as $p) {      // if it has new products
		    if (!in_array($p->ID, $data_subscr['product_ids'])) {
			$data_email['products'][] = $p->ID;
		    }
		  // $diff=array_diff($products,$data_subscr[product_ids]);
		}
               
		if (count($data_email['products']) > 0) {
		    $last_email = $by_date = $by_count = false;
		    (int) $data_user[$key]['count'] --;
		    if (((int) $data_user[$key]['count']) <= 0) {
			$by_count = true;
		    }
		    if (((int) $data_subscr['date']) < time()) {
			$by_date = true;
		    }
		    if ($this->priority_limit == 'by_date' AND $by_date) {   //priority by date  
			$last_email = true;
		    } elseif ($this->priority_limit == 'by_count' AND $by_count) { //priority by count 
			$last_email = true;
		    } elseif ($this->priority_limit == 'both' AND ( $by_count OR $by_date)) {   //both
			$last_email = true;
		    }
		    $data_email['user'] = $user;
		    $data_email['text_email'] = $this->text_email;
		    $data_email['subscr'] = $data_subscr;
		    $data_email['last_email'] = $last_email;
		   /* $data_email['test']=array(    //just for test logic
		      'by_date'=>$by_date,
		      'by_count'=>$by_count,
		      'count'=>$data_user[$key]['count'],
                      'time'=>date('D, d M Y H:i:s',$data_user[$key]['date']),
                      'realtime'=>date('D, d M Y H:i:s',time()),
		      'products'=>$products,
		      ); */
               
		    if ($last_email) {
			unset($data_user[$key]);
		    } else {
			$data_user[$key]['product_ids'] = array_merge($data_subscr['product_ids'], $data_email['products']);
		    }
                    $successful_sending=$this->create_new_email($data_email);
                    //safe all info. If the wp_email does not work, the data is not updated
                   
                    if($successful_sending){
                        update_user_meta($user->ID, $this->user_meta_key, $data_user);
                    }
		    //$this->create_new_email($data_email);
		}
	    }
	}
    }

    public function create_new_email($data) {
	global $WOOF;
	$mailer = $GLOBALS['woocommerce']->mailer();
	// get the preview email subject
	$email_heading = $this->header_email;
	$subject = $this->subject_email;
	// get the preview email content

	$message = $WOOF->render_html($this->get_ext_path() . 'views' . DIRECTORY_SEPARATOR . 'email_template.php', $data);


	// create a new email
	$email = new WC_Email();

	// wrap the content with the email template and then add styles
	$message = apply_filters('woocommerce_mail_content', $email->style_inline($mailer->wrap_message($email_heading, $message)));
	
	$headers=array();
	$headers[] = 'content-type: text/html';
        
        //create new  email name
        $home_url=array();
        $home_url=explode("//",home_url());
        $site_name="messenger.woof";
        if(isset($home_url[1])){
            $site_name=explode("/",$home_url[1] );
            $site_name= $site_name[0];
        }else{
            $site_name=explode("/",$home_url[0] );
            $site_name= $site_name[0];
        }
        $headers[]= 'From: '.get_bloginfo('name').' <no-reply@'.$site_name .'>';
	//+++
	// send email
	return wp_mail($data['user']->user_email, $subject, $message, $headers);
    }

    //settings page hook
    public function woof_print_html_type_options() {
	global $WOOF;
	echo $WOOF->render_html($this->get_ext_path() . 'views' . DIRECTORY_SEPARATOR . 'options.php', array(
	    'key' => $this->html_type,
	    "woof_settings" => get_option('woof_settings', array())
		)
	);
    }

    public function woof_add_subscr() {
	global $WOOF,$wpdb,$wp_query;

	if (! isset($_POST['link']) OR ! isset($_POST['user_id'])) {
	    die();
	}

	//***

	$data = array();
	$sanit_user_id = sanitize_key($_POST['user_id']);
	if ($sanit_user_id < 1) {
	    die(); //if user id - wrong!!!
	}

	$key = uniqid('woofms_'); // Create   key for this subscr
	$data['key'] = $key;
        
	$data['secret_key'] = bin2hex(random_bytes(9)); //Key for check link from email
        
	$data['user_id'] = $sanit_user_id;
	$data['link'] = esc_url($_POST['link']);
	$data['get'] =$this->woof_get_html_terms($this->sanitaz_array_r($_POST['get_var']));
	$subscr = get_user_meta($data['user_id'], $this->user_meta_key, true);
        $data['request'] =$this->sanitazed_sql_query(base64_decode($WOOF->storage->get_val("woof_pm_request_".$data['user_id'])));
        // If the request has banned operators or is empty
        if(!$data['request'] OR empty($data['request'])){
             die();
        }
        //+++
        //Remove limit frim request
        $pos = stripos($data['request'], "LIMIT");
        if($pos){
            $data['request']=substr($data['request'],0,$pos);
        }
        if(!is_array($subscr)){
            $subscr=array();
        }
	if (count($subscr) >= $this->subscr_count) {
	    die('count is max'); // Check limit count on backend
	}
        //+++
	$data['subscr_lang'] = apply_filters('woof_subscribe_lang', $this->subscribe_lang); //Text of  the subscriptions
	// $data['unsubscr_lang']=apply_filters('woof_subscribe_lang',$this->unsubscribe_lang); // not use now
        
	$data['count'] = ((int) $this->count_message != -1) ? (int) $this->count_message : PHP_INT_MAX; // not limit* million times
	$data['date'] = time();
	if ($this->get_woof_cron_schedules($this->date_expire)) {
	    $data['date'] = $data['date'] + $this->get_woof_cron_schedules($this->date_expire); // date of expire
	} else {
	    $data['date'] = $data['date'] + YEAR_IN_SECONDS*10; // not limit*  10 years
	}

	$data['product_ids'] = array();
        $products=$wpdb->get_results($data['request']);
	foreach ($products as $product) {
	    $data['product_ids'][] = $product->ID; //Get current product ids
	}

	$subscr[$key] = $data;
	update_user_meta($data['user_id'], $this->user_meta_key, $subscr);
	//for Ajax redraw
	$cont = $WOOF->render_html($this->get_ext_path() . 'views' . DIRECTORY_SEPARATOR . 'item_list_subscr.php', $data);
	//die(json_encode($data));
	die($cont);
    }

    public function woof_remove_subscr() {
	if (!isset($_POST['key']) OR ! isset($_POST['user_id'])) {
	    die('No data!');
	}

	$user_id = sanitize_key($_POST['user_id']);
	$key = sanitize_key($_POST['key']);
	$subscr = get_user_meta($user_id, $this->user_meta_key, true);
	unset($subscr[$key]);
	update_user_meta($user_id, $this->user_meta_key, $subscr);
	$arg = array('key' => $key);
	die(json_encode($arg));
    }

    public function make_send_emails($reset = false) {
	if ($this->subscr_period_option != 'no' AND ! empty($this->subscr_period_option)) {
	    if ($this->wp_cron_period) {
		if ($reset) {
		    // $this->cron->reset($this->cron_hook, $this->wp_cron_period); // not used in this case 
		}

		$this->woocs_wpcron_init();
	    }
	}
    }

    public function woocs_wpcron_init($remove = false) {
	if ($remove) {
	    $this->cron->remove($this->cron_hook);
	    return;
	}

	if ($this->wp_cron_period) {
	    if (!$this->cron->is_attached($this->cron_hook, $this->wp_cron_period)) {
		$this->cron->attach($this->cron_hook, time(), $this->wp_cron_period);
	    }

	    $this->cron->process();
	}
    }

    public function get_woof_cron_schedules($key = '') {
	$schedules = array(
	    'hourly' => HOUR_IN_SECONDS,
	    'twicedaily' => HOUR_IN_SECONDS * 12,
	    'daily' => DAY_IN_SECONDS,
	    'week' => WEEK_IN_SECONDS,
	    'twicemonthly' => WEEK_IN_SECONDS * 2,
	    'month' => WEEK_IN_SECONDS * 4,
	    'twomonth' => WEEK_IN_SECONDS * 9,
	    'min1' => MINUTE_IN_SECONDS, // only for test
	);
	if (!empty($key) AND isset($schedules[$key])) {
	    return (int) $schedules[$key];
	} else {
	    return NULL;
	}

	return $schedules;
    }

    public function woof_products_messenger() {
	add_action('init', array($this, 'woof_do_mesenger_action'), 999); // init messeng function
    }

    //it create  html for tooltip and list of the terms in email
    public function woof_get_html_terms($args) {
	$html = "";
       
	$not_show = array( 'swoof','paged','orderby', 'min_price', 'max_price', 'woof_author','page');
	if (isset($args['min_price'])) {
	    $price_text = sprintf(__('Price - from %s to %s', 'woocommerce-products-filter'), $args['min_price'], $args['max_price']);
	    $price_text .= '<br />';
	    $html .= '<span class="woof_subscr_price">' . $price_text . '</span>';
	}
	if (isset($args['woof_author'])) {
	    $ids = explode(',', $args['woof_author']);
	    $auths = "";
	    foreach ($ids as $auth) {
		$auths .= " " . get_userdata((int) $auth)->display_name;
	    }
	    $html .= "<span class='woof_author_name'>" . $auths . "</span><br />";
	}
 
	foreach ($args as $key => $val) {
            
	    if (in_array($key, $not_show)) {
		continue;
	    }
            
            if(class_exists('WOOF_META_FILTER')){
                $meta_title=WOOF_META_FILTER::get_meta_title_messenger($val, $key);
                //var_dump($meta_title);
                if(!empty($meta_title) AND $meta_title){
                    $html .= $meta_title; 
                    
                    continue;
                }
            }
            $tax=get_taxonomy($key);
            if(is_object($tax)){
                $name = $tax->labels->name;
                if (!empty($name)) {
                    $name .= ": ";
                }
                $name .= $val;
                $html .= "<span class='woof_terms'>" . $name . "</span><br />";                
            }

	}
	if (empty($html)) {
	   $html = __('None', 'woocommerce-products-filter');
	}
        //var_dump($html);
	return $html;
    }

    // Recursive sanitaze arrais
    public function sanitaz_array_r($arr) {
	$newArr = array();
	foreach ($arr as $key => $value) {
	    $newArr[WOOF_HELPER::escape($key)] = ( is_array($value) ) ? $this->sanitaz_array_r($value) : WOOF_HELPER::escape($value);
	}
	return $newArr;
    }

    public function wp_head() {
	?>
	<script type="text/javascript">
	    var woof_confirm_lang = "<?php _e('Are you sure?', 'woocommerce-products-filter') ?>";
	</script>
	<?php
    }
    public function  woof_products_messenger_shortcode($args){
        $data=shortcode_atts(array(
	    'in_filter' => 0
			), $args);
        global $WOOF;
        return $WOOF->render_html($this->get_ext_path() . 'views' . DIRECTORY_SEPARATOR . 'shortcodes'. DIRECTORY_SEPARATOR.'woof_products_messenger.php',$data);
    }

    public function  sanitazed_sql_query($sql){
        $conditional_operator=array('TRUNCATE','DELETE','UPDATE','INSERT','REPLACE','CREATE');
        foreach($conditional_operator as $operator){
            $result=stripos($sql,$operator);
            if($result!==false){
                return false;
                break;
            }
        }
        return $sql;
    }
}

WOOF_EXT::$includes['html_type_objects']['products_messenger'] = new WOOF_EXT_PRODS_MESSENGER();
