<?php
/*
Plugin Name:  Gorilla Themes - Automatic Feed XML and CSV Export
Plugin URI:   https://gorillathemes.com
Description:  XML-CSV Inventory Feed Export by Gorilla Themes
Version:      1.0
Author:       Gorilla Themes
Author URI:   https://gorillathemes.com
*/

define( 'GTE_STORE_URL', 'https://gorillathemes.com' ); 

define( 'GTE_ITEM_ID', 21863 ); 

define( 'GTE_PLUGIN_LICENSE_PAGE', 'gt_gte_license_page' );

if( !class_exists( 'EDD_SL_Plugin_Updater' ) ) {

	include( dirname( __FILE__ ) . '/assets/inc/EDD_SL_Plugin_Updater.php' );
}

function gte_plugin_updater() {

	$license_key = trim( get_option( 'gte_license_key' ) );

	$edd_updater = new EDD_SL_Plugin_Updater( GTE_STORE_URL, __FILE__,
		array(
			'version' => '1.0',                   
			'license' => $license_key,       
			'item_id' => 21863,  
			'author'  => 'Gorilla Themes', 
			'beta'    => false,
		)
	);

}
add_action( 'admin_init', 'gte_plugin_updater', 0 );

function gte_license_menu() {
	add_plugins_page( 'Automatic Feed XML and CSV Export License', 'Automatic Feed XML and CSV Export License', 'manage_options', 'gt_gte_license_page', 'gte_license_page' );
}
add_action('admin_menu', 'gte_license_menu');

function gte_license_page() {
	$license = get_option( 'gte_license_key' );
	$status  = get_option( 'gte_license_status' );
	?>
	<div class="wrap">
		<h2><?php _e('Automatic Feed XML and CSV Export License'); ?></h2>
		<form method="post" action="options.php">

			<?php settings_fields('gte_license'); ?>

			<table class="form-table">
				<tbody>
					<tr valign="top">
						<th scope="row" valign="top">
							<?php _e('License Key'); ?>
						</th>
						<td>
							<input id="gte_license_key" name="gte_license_key" type="text" class="regular-text" value="<?php esc_attr_e( $license ); ?>" />
							<label class="description" for="gte_license_key"><?php _e('Enter your license key'); ?></label>
						</td>
					</tr>
					<?php if( false !== $license ) { ?>
						<tr valign="top">
							<th scope="row" valign="top">
								<?php _e('Activate License'); ?>
							</th>
							<td>
								<?php if( $status !== false && $status == 'valid' ) { ?>
									<span style="color:green;"><?php _e('active'); ?></span>
									<?php wp_nonce_field( 'gte_sample_nonce', 'gte_sample_nonce' ); ?>
									<input type="submit" class="button-secondary" name="gte_license_deactivate" value="<?php _e('Deactivate License'); ?>"/>
								<?php } else {
									wp_nonce_field( 'gte_sample_nonce', 'gte_sample_nonce' ); ?>
									<input type="submit" class="button-secondary" name="gte_license_activate" value="<?php _e('Activate License'); ?>"/>
								<?php } ?>
							</td>
						</tr>
					<?php } ?>
				</tbody>
			</table>
			<?php submit_button(); ?>

		</form>
	<?php
}

function gte_register_option() {
	// creates our settings in the options table
	register_setting('gte_license', 'gte_license_key', 'gte_sanitize_license' );
}
add_action('admin_init', 'gte_register_option');

function gte_sanitize_license( $new ) {
	$old = get_option( 'gte_license_key' );
	if( $old && $old != $new ) {
		delete_option( 'gte_license_status' ); // new license has been entered, so must reactivate
	}
	return $new;
}

function gte_activate_license() {

	if( isset( $_POST['gte_license_activate'] ) ) {

	 	if( ! check_admin_referer( 'gte_sample_nonce', 'gte_sample_nonce' ) )
			return;

		$license = trim( get_option( 'gte_license_key' ) );

		$api_params = array(
			'edd_action' => 'activate_license',
			'license'    => $license,
			'item_name'  => urlencode( 'Automatic Feed XML and CSV Export' ),  
			'url'        => home_url()
		);

		$response = wp_remote_post( GTE_STORE_URL, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );

		if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {

			if ( is_wp_error( $response ) ) {
				$message = $response->get_error_message();
			} else {
				$message = __( 'An error occurred, please try again.' );
			}

		} else {

			$license_data = json_decode( wp_remote_retrieve_body( $response ) );

			if ( false === $license_data->success ) {

				switch( $license_data->error ) {

					case 'expired' :

						$message = sprintf(
							__( 'Your license key expired on %s.' ),
							date_i18n( get_option( 'date_format' ), strtotime( $license_data->expires, current_time( 'timestamp' ) ) )
						);
						break;

					case 'disabled' :
					case 'revoked' :

						$message = __( 'Your license key has been disabled.' );
						break;

					case 'missing' :

						$message = __( 'Invalid license.' );
						break;

					case 'invalid' :
					case 'site_inactive' :

						$message = __( 'Your license is not active for this URL.' );
						break;

					case 'item_name_mismatch' :

						$message = sprintf( __( 'This appears to be an invalid license key for %s.' ), 'Automatic Feed XML and CSV Export' );
						break;

					case 'no_activations_left':

						$message = __( 'Your license key has reached its activation limit.' );
						break;

					default :

						$message = __( 'An error occurred, please try again.' );
						break;
				}

			}

		}

		if ( ! empty( $message ) ) {
			$base_url = admin_url( 'plugins.php?page=' . 'gt_gte_license_page' );
			$redirect = add_query_arg( array( 'sl_activation' => 'false', 'message' => urlencode( $message ) ), $base_url );

			wp_redirect( $redirect );
			exit();
		}

		update_option( 'gte_license_status', $license_data->license );
		wp_redirect( admin_url( 'plugins.php?page=' . 'gt_gte_license_page' ) );
		exit();
	}
}
add_action('admin_init', 'gte_activate_license');

function gte_deactivate_license() {

	if( isset( $_POST['gte_license_deactivate'] ) ) {

	 	if( ! check_admin_referer( 'gte_sample_nonce', 'gte_sample_nonce' ) )
			return;

		$license = trim( get_option( 'gte_license_key' ) );

		$api_params = array(
			'edd_action' => 'deactivate_license',
			'license'    => $license,
			'item_name'  => urlencode( 'Automatic Feed XML and CSV Export' ), 
			'url'        => home_url()
		);

		$response = wp_remote_post( GTE_STORE_URL, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );

		if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {

			if ( is_wp_error( $response ) ) {
				$message = $response->get_error_message();
			} else {
				$message = __( 'An error occurred, please try again.' );
			}

			$base_url = admin_url( 'plugins.php?page=' . 'gt_gte_license_page' );
			$redirect = add_query_arg( array( 'sl_activation' => 'false', 'message' => urlencode( $message ) ), $base_url );

			wp_redirect( $redirect );
			exit();
		}

		$license_data = json_decode( wp_remote_retrieve_body( $response ) );

		if( $license_data->license == 'deactivated' ) {
			delete_option( 'gte_license_status' );
		}

		wp_redirect( admin_url( 'plugins.php?page=' . 'gt_gte_license_page' ) );
		exit();

	}
}
add_action('admin_init', 'gte_deactivate_license');

function gte_check_license() {

	global $wp_version;

	$license = trim( get_option( 'gte_license_key' ) );

	$api_params = array(
		'edd_action' => 'check_license',
		'license' => $license,
		'item_name' => urlencode( 'Automatic Feed XML and CSV Export' ),
		'url'       => home_url()
	);

	// Call the custom API.
	$response = wp_remote_post( GTE_STORE_URL, array( 'timeout' => 15, 'sslverify' => false, 'body' => $api_params ) );

	if ( is_wp_error( $response ) )
		return false;

	$license_data = json_decode( wp_remote_retrieve_body( $response ) );

	if( $license_data->license == 'valid' ) {
		echo 'valid'; exit;

	} else {
		echo 'invalid'; exit;

	}
}

function gte_admin_notices() {
	if ( isset( $_GET['sl_activation'] ) && ! empty( $_GET['message'] ) ) {

		switch( $_GET['sl_activation'] ) {

			case 'false':
				$message = urldecode( $_GET['message'] );
				?>
				<div class="error">
					<p><?php echo $message; ?></p>
				</div>
				<?php
				break;

			case 'true':
			default:

				break;

		}
	}
}
add_action( 'admin_notices', 'gte_admin_notices' );  
add_action( 'init', 'initExporter', 100 );
function initExporter(){ $exporter = new Exporter(); }
//flush_rewrite_rules(true);
class Exporter{
	
	public $exportDir;
	public $exportDirUri;
	public $exportDirInc;
	
	public function __construct(){
		
		$template_dir = plugin_dir_path( __FILE__ );
		
		$this->exportDir = $template_dir;
		$this->exportDirUri = plugin_dir_url( __FILE__ );
		$this->exportDirInc = $template_dir.'includes/';
		
		add_action('admin_menu', array($this, 'admin_menu_item'));
		add_action('admin_enqueue_scripts', array($this, 'admin_scripts'));
		
		// check if flush rules was done after setting rewrite urls, if not, create rewrite urls and flush rules
		add_filter('rewrite_rules_array', array($this, 'export_rewrite_rules'));
		add_filter('query_vars', array($this, 'export_query_vars'));
		add_action('wp_loaded', array($this, 'export_flush_rules'));
		
		add_action('parse_request', array($this, 'run_export'));
	}
	
	public function export_rewrite_rules($rules){
		$newrules = array();
		$newrules['(gtcd-export)/(.*)$'] = 'index.php?export=1&name=$matches[2]';
		return $newrules + $rules;
	}
	
	public function export_query_vars($vars){
		array_push($vars, 'name','export');
		return $vars;
	}
	
	public function export_flush_rules(){
		$rules = get_option( 'rewrite_rules' );

		if ( ! isset( $rules['(gtcd-export)/(.*)$'] ) ) {
			global $wp_rewrite;
		   	$wp_rewrite->flush_rules();
		}
	}
	
	public function admin_menu_item(){
		add_submenu_page( 
			'edit.php?post_type=gtcd', 
			'Car Dealer XML & CSV File Exporter', 
			'Export Vehicles', 
			'administrator', 
			'gtcdi_exports', 
			array($this, 'admin_page')
		);
	}
	
	public function admin_scripts(){
		$screen = get_current_screen();

		if(isset($screen) && $screen->id=='gtcd_page_gtcdi_exports'):
			wp_enqueue_script('gtcdi_exporter_script', $this->exportDirUri.'scripts/script.js',array('jquery'), '1.0', true);	
			wp_enqueue_style('gtcdi_exporter_style', $this->exportDirUri.'scripts/style.css');
			wp_enqueue_style('gtcdi_exporter_jquery_ui', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/themes/smoothness/jquery-ui.css');
			wp_enqueue_style('gtcdi_exporter_fontawesome', 'https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css');
		endif;
	}
	
	public function admin_page(){
		$step = isset($_POST['step']) && !empty($_POST['step']) ? $_POST['step'] : '';	
		$this->get_page($step);
	}
	
	public function check_var($var){
		return isset($var) && !empty($var) && $var!==0 ? true : false;
	}
	
	public function get_page($step){
		
		$template_dir = plugin_dir_url( __FILE__ );
		$export = array();
		
		if ( $_SERVER['REQUEST_METHOD'] == 'POST' ):
			if(Exporter::check_var($_POST['id']) && Exporter::check_var($_POST['action'])):
				$id = $_POST['id'];
				$action = $_POST['action'];
				
				$export_id = $id - 1;	
				$exports = get_option('gtcd_exports', json_encode(array()));
				$exports = json_decode($exports, true);
			endif;
		endif;
			
		switch($step):
			case 'map':
				if ( $_SERVER['REQUEST_METHOD'] == 'POST' ):
					$meta_data 	= $this->get_meta_data();
					$taxonomies = $this->get_taxonomies();
					
					$export_name = $_POST['export_name'];
					$file_type 	= $_POST['file_type'];
					$id 		= $_POST['id'];
					$action 	= $_POST['action'];
					
					if(!empty($id)):
						$mapper = $exports[$id-1]['fields'];
					endif;
				endif;
				
				include_once $this->exportDirInc.'map.php';
			break;
			
			case 'save':
				if ( $_SERVER['REQUEST_METHOD'] == 'POST' ):
					$this->save_export($_POST);
					
					$export_name = $_POST['export_name'];
					$file_type 	= $_POST['file_type'];
					$id 		= $_POST['id'];
					$action 	= $_POST['action'];
					
					$post_action = !empty($id) ? 'updated' : 'created';
				endif;
				
				include_once $this->exportDirInc.'complete.php';
			break;
			
			case 'url':
				$include_file = $this->exportDirInc.'url.php';
				$post_action = '';
				
				if ( $_SERVER['REQUEST_METHOD'] == 'POST' ):
					if(!empty($id)):
						if($action == 'delete'):
							if(isset($exports[$export_id])) unset($exports[$export_id]);
							$new_exports = array_values($exports);
							
							$exports = json_encode($new_exports);
							update_option('gtcd_exports', $exports);
						
							$post_action = 'deleted';
							$include_file = $this->exportDirInc.'complete.php';
						elseif($exports[$export_id]):
							$export = $exports[$export_id];
							
							$export_name = $export['name'];
							$type = $export['type'];
						endif;
					else:
						$export_name = '';
						$xpath = '';
						$type = '';
						$id = '';
						$action = '';
					endif;
				endif;
				
				include_once $include_file;
			break;
			
			default: // list
				include_once $this->exportDirInc.'list.php'; //change to list
			break;
		endswitch;
	}
	
	public function run_export(){
		global $wpdb, $wp;
		
		if ( ! isset ( $wp->query_vars['export'] ) || ! isset( $wp->query_vars['name'] ) ):
	      return;
		endif;

		$name = str_replace(strrchr($wp->query_vars['name'], '.'), '', $wp->query_vars['name']);
		$exports = get_option('gtcd_exports', json_encode(array()));
		$exports = json_decode($exports, true);
		
		$current = array();
		foreach($exports as $export):
			if($export['slug'] == $name):
				$current = $export;
				break;
			endif;
		endforeach;
		
		$fields = $current['fields'];
		
		if(empty($fields)) return;

		// get all inventory posts
		$args = array(
			'posts_per_page'   => -1,
			'orderby'          => 'date',
			'order'            => 'DESC',
			'post_type'        => 'gtcd',
			'post_status'		=> array('publish'), //array_keys(get_post_statuses())
		);
		
		$posts = get_posts($args);
		
		$meta_data 	= $this->get_meta_data();
		$taxonomies = $this->get_taxonomies();
		
		$records = array();
		$headers = array();
		$counter = 0;
		
		foreach($posts as $post):
			
			$record = array();
			foreach($fields as $field):
				if(empty($field)) continue;
				
				$split = explode(':', $field);
				$section = $split[0];
				$value = $split[1];
				
				// check if in $meta_data
				if($section == 'post'):
					array_push($record, $post->$value);
					if($counter == 0): array_push($headers, 'Vehicle Title'); endif;
				elseif($section == 'meta'):
					$meta_title = '';
					$meta_value = '';
					
					foreach($meta_data as $meta_key => $meta_value):
						if($meta_value['name'] == $value):
							$meta_title = $meta_value['title'];
							$meta_value = get_post_meta($post->ID, $meta_key, true);
							break;
						endif;
					endforeach;				
					
					array_push($record, $meta_value);
					if($counter == 0): array_push($headers, $meta_title); endif;
				elseif($section == 'tax'):
					switch($value):
						case 'make':
							$terms = wp_get_post_terms($post->ID, 'makemodel', array('orderby' => 'parent', 'order' => 'ASC', 'fields' => 'all'));
							$tax_title = 'Make';
							$tax_value = !empty($terms) ? $terms[0]->name : '';
							break;
						case 'model':
							$terms = wp_get_post_terms($post->ID, 'makemodel', array('orderby' => 'parent', 'order' => 'DESC', 'fields' => 'all'));
							$tax_title = 'Model';
							$tax_value = !empty($terms) ? $terms[0]->name : '';
							break;
						case 'state':
							$terms = wp_get_post_terms($post->ID, 'location', array('orderby' => 'parent', 'order' => 'ASC', 'fields' => 'all'));
							$tax_title = 'State';
							$tax_value = !empty($terms) ? $terms[0]->name : '';
							break;
						case 'city':
							$terms = wp_get_post_terms($post->ID, 'location', array('orderby' => 'parent', 'order' => 'DESC', 'fields' => 'all'));
							$tax_title = 'City';
							$tax_value = !empty($terms) ? $terms[0]->name : '';
							break;
						default:
							$taxonomy = $taxonomies[$value];
							$terms = wp_get_post_terms($post->ID, $value, array('orderby' => 'name', 'order' => 'DESC', 'fields' => 'all'));
							
							$items = array();
							foreach($terms as $term):
								array_push($items, $term->name);
							endforeach;
							
							$tax_title = $taxonomy->labels->singular_name;
							$tax_value = implode(',', $items);
							break;
					endswitch;
					
					array_push($record, $tax_value);
					if($counter == 0): array_push($headers, $tax_title); endif;
				elseif($section == 'gallery'):
					$photos = get_post_meta($post->ID, 'CarsGallery', true);
					$photos = explode(',', $photos);
					
					$arr_photos = array();
					foreach($photos as $photo):
						$link = wp_get_attachment_url( $photo );
						array_push($arr_photos, $link);
					endforeach;
					
					array_push($record, implode(',', $arr_photos));
					if($counter == 0): array_push($headers, 'Photo Gallery'); endif;
				endif;
				
			endforeach;
			
			array_push($records, $record);
			$counter++;
		endforeach;

		if($current['type'] == 'xml'):
		
			header('Content-type: text/xml');		
			if(isset($_GET['download']) && !empty($_GET['download'])): 
				header('Content-Disposition: attachment; filename="'.$current['slug'].($current['type']=='xml' ? '.xml' : '.csv').'"'); 
			endif;
			
			$dom = new DomDocument();
			$listings = $dom->createElement('listings', '');
	
			foreach($records as $record):
				$listing = $dom->createElement('listing', '');
				foreach($headers as $key => $header):
					if(empty($record[$key])) continue; 
					
					$header = preg_replace('#[^0-9a-zA-Z]#', '_', strtolower($header));
					$element = $dom->createElement($header, $record[$key]);
					$listing->appendChild($element);
				endforeach;
				
				$listings->appendChild($listing);
			endforeach;
			
			$dom->appendChild($listings);
			echo $dom->saveXML();
			
		else:
			if(isset($_GET['download']) && !empty($_GET['download'])):
				header('Content-type: text/csv');
				header('Content-Disposition: attachment; filename="'.$current['slug'].($current['type']=='xml' ? '.xml' : '.csv').'"');
			endif;
			
			if(count($records) > 0):
				$out = fopen('php://memory', 'w');
				fputcsv($out, $headers);
				
				foreach($records as $record):
					fputcsv($out, $record);
				endforeach;
				fseek($out, 0);
				//fclose($out);
				
				// ob_end_clean();
				fpassthru($out);
			endif;
		endif;
		
		exit;
	}
	
	// Private Functions used for Running Schedule Import //	
	private function get_meta_data(){
		global $wpdb, $meta_boxes, $feat_boxes, $comment_boxes;
		
		if(!is_array($meta_boxes)) 		$meta_boxes = array();
		if(!is_array($feat_boxes)) 		$feat_boxes = array();
		if(!is_array($comment_boxes)) 	$comment_boxes = array();
		
		$meta_keys = array_merge($meta_boxes,$feat_boxes,$comment_boxes);					 
		$meta = array();
		
		//Loop through each of the returned keys
		foreach ($meta_keys as $key=>$value) : 
			$meta_key = ltrim($value['name'], '_');
			
			if(!empty($feat_boxes[$meta_key]['name'])):
				$meta['_'.$meta_key] = array(
					'parent' => 'feat_boxes', 
					'meta_key' => '_'.$meta_key, 
					'title' => $feat_boxes[$meta_key]['title'], 
					'name' => $feat_boxes[$meta_key]['name']
				);
			elseif(!empty($meta_boxes[$meta_key]['name'])):
				$meta['_'.$meta_key] = array(
					'parent' => 'meta_boxes', 
					'meta_key' => '_'.$meta_key, 
					'title' => $meta_boxes[$meta_key]['title'], 
					'name' => $meta_boxes[$meta_key]['name']
				);
			elseif(!empty($comment_boxes[$meta_key]['name'])):
				$meta['_'.$meta_key] = array(
					'parent' => 'comment_boxes', 
					'meta_key' => '_'.$meta_key, 
					'title' => $comment_boxes[$meta_key]['title'], 
					'name' => $comment_boxes[$meta_key]['name']
				);
			endif;
		endforeach;
		
		return $meta;
	}
	
	private function get_taxonomies(){
		return get_object_taxonomies( 'gtcd','objects' );
	}
	
	private function save_export($post){		
		if(!isset($post['file_type']) || empty($post['file_type'])):
			wp_redirect('edit.php?post_type=gtcd&page=gtcdi_exports');
			exit;
		endif;
		
		$slug = sanitize_title($post['export_name']);
		
		$exporter = array(
			'name'		=> $post['export_name'],
			'slug'		=> $slug,
			'type'   	=> $post['file_type'],
			'fields' 	=> isset($post['exportField']) ? $post['exportField'] : ''
		);
		
		$exports = get_option('gtcd_exports');
		$exports = !empty($exports) ? json_decode($exports, true) : array();
		
		// check if that slug already exists, if so append the next incremented number to it
		$last_slug = '';
		foreach($exports as $export):
			if($slug == $export['slug']):
				$last_slug = $export['slug'];
			endif;
		endforeach;
		
		if(!empty($last_slug)):
			$inc  = substr(strrchr($last_slug, '_'), strlen($last_slug));
			$inc += 1;
			$slug .= '_'.$inc;
			
			$exporter['slug'] = $slug;
		endif;
		
		if($post['action'] == 'edit' && !empty($post['id'])):
			$export_id = $post['id'];
			$export_id = $export_id - 1;
			
			$current_export = $exports[$export_id];
			
			$exporter['created']	= $current_export['created'];
			$exporter['updated']	= time();
			
			$exports[$export_id] = $exporter;
		else:				
			$exporter['created']	= time();
			$exporter['updated']	= null;

			array_push($exports, $exporter);
		endif;
		
		$exports = json_encode($exports);
		
		update_option('gtcd_exports', $exports);
	}
	
	private function get_mod_meta_box_key($key){
		global $meta_boxes, $feat_boxes, $comment_boxes;
		
		if(array_key_exists($key, $meta_boxes))
			return 'mod1';
		elseif(array_key_exists($key, $feat_boxes))
			return 'mod2';
		elseif(array_key_exists($key, $comment_boxes))
			return 'mod3';
	}
}