<?php
/**
 *	Laborator - Contact Form Plugin
 *
 *	Developed by: Arlind Nushi
 *
 *	www.mobanbus.cn
 */


if(!class_exists('WP_List_Table')){
    require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
}
 
 
class LaboratorContactForm
{
	public static $instance;
	
	private $parent_slug = '';
	private $menu_slug = 'laborator_contactform';
	
	private $contact_table_id = 'laborator_contact_form_table';
	private $nonce_field = 'laborator_contact_form_nonce';
	
	private $required_settings_id = 'kolor_contact_form_required_';
	
	private $new_entry_timeout = 60; // Every 60 seconds the same user can send new contact request
	
	private $fields = array(
								'firstname' => array('Name', 'user'), 
								'lastname' => array('Surname', 'user'), 
								'subject' => array('Subject', 'subject'), 
								'email' => array('Email', 'email', true), 
								'message' => array('Message', 'message')
							);
	
	
	# Email Notifications Option Vars
	private $email_notifications_on = 'kolor_contact_form_notifications_on';
	private $email_notifications_email = 'kolor_contact_form_notifications_email';
	private $email_notifications_subject = 'kolor_contact_form_notifications_subject';
	private $email_notifications_message = 'kolor_contact_form_notifications_message';
	
	public function __construct($ps)
	{
		global $wpdb;
		
		$this->parent_slug = $ps;
		
		add_action('admin_menu', array(&$this, 'contactform_menu'));
		
		# Check for new contact form requests
		if( ! is_admin())
			$this->process_request();
		
		# Admin Backend
		if(is_admin())
		{
			if(isset($_GET['page']) && $_GET['page'] == $this->menu_slug)
			{	
				function laborator_contactform_enqueue_scripts()
				{					
					wp_enqueue_script('thickbox');
					wp_enqueue_style('thickbox');
				}
				
				add_action('init', 'laborator_contactform_enqueue_scripts');
				
				# View Message
				if(isset($_GET['view_message']))
				{
					$message_id = $_GET['view_message'];
					
					$message = $this->get_contact_entry($message_id);
					
					if($message)
					{
						$this->mark_as_read($message_id);
						$this->render_message($message);
						exit;
					}
				}
				
				# Delete Message
				if(isset($_GET['delete_message']))
				{
					$message_id = $_GET['delete_message'];
					
					if($this->delete_entry($message_id))
					{
						define('LABCF_DELETED', 1);
					}
				}
			}
		}
		
		# Save Instance for general use
		self::$instance = $this;
	}
	
	
	public function get_fields()
	{
		return $this->fields;
	}
	
	
	public function contactform_menu()
	{
		$parent_slug = $this->parent_slug;
		
		$page_title = 'Laborator - Contact Form';
		$menu_title = 'Contact Form';
		$capability = 'administrator';
		$menu_slug = $this->menu_slug;
		$function = array( & $this, 'admin_main_page');
		
		add_submenu_page( $parent_slug, $page_title, $menu_title, $capability, $menu_slug, $function );
	}
	
	/* Admin Page for module */
	public function admin_main_page()
	{
?>
<script type="text/javascript">
jQuery(function($)
{
	$(".labcf_read_message").click(function(ev)
	{
		ev.preventDefault();
		
		var $this = $(this);
		var href = $this.attr('href');
		
		$this.parent().parent().parent().parent().removeClass('highlighted');
		
		tb_show('Read Message', href + '&TB_iframe=true');
	});
	
	$(".labcf_delete").click(function(ev)
	{
		if( ! confirm('Are you sure you want to delete this entry?'))
			ev.preventDefault();
	});
	
	$(".unread_message").parent().parent().addClass('highlighted');
});
</script>
<style>
	.tablenav {
	}
	
	.unread_message {
		font-weight: bold;
	}
	
	.highlighted td {
		background: rgba(255,255,204,0.3);
	}
</style>
<div class="wrap">
	<h2>
		Contact Form
	</h2>
	
	<?php
		
		if( defined("LABCF_DELETED") )
		{
			?>
			<div class="updated below-h2">
				<p>Message has been deleted.</p>
			</div>
			<?php
		}
	
		$table = new LaboratorContactForm_Table();
		
		$table->prepare_items( $this->get_contact_entries(TRUE) );
		
		$table->display();
	
	?>
</div>
<?php
		$this->copyrights();
	}
	
	public function copyrights()
	{
		?>
		<style>
			.copyrights { color: #777 !important; margin-top: 10px; }
		</style>
		<div class="copyrights">
			&copy; <strong>Contact Form</strong> created by <a href="http://laborator.co" target="_blank">Laborator</a> team.
		</div>
		<?php
	}
	
	
	# Contact Actions API
	public function process_request()
	{
		global $wp, $wp_query;
		
		$nonce_field = isset($_POST[$this->nonce_field]) ? $_POST[$this->nonce_field] : '';	
		
		if($nonce_field && wp_verify_nonce($nonce_field, __CLASS__))
		{
			// Valid Request
			$gen_id = 'ce' . time() . mt_rand(1000,9999);
			
			$valid_entry = TRUE;
			
			$contact_entry = array();
			
			foreach($this->fields as $field_id => $field)
			{
				$field_title = $field[0];
				$value = $_POST[$field_id];
				
				$is_required = get_option("{$this->required_settings_id}{$field_id}") == 'true';
				$is_email = $field[2];
				
				$ce_column = array();
				
				$ce_column['id'] = $field_id;
				$ce_column['title'] = $field_title;
				$ce_column['value'] = $value;
				
				if($is_required)
				{
					if( ! $value)
						$valid_entry = FALSE;
				}
				
				if($is_email && $value)
				{
					if( ! is_email($value))
						$valid_entry = FALSE;
				}
				
				array_push($contact_entry, $ce_column);
			}
			
			# Valid Entry
			if($valid_entry)
			{
				$this->insert_entry($gen_id, $contact_entry);
				define("LCF_CONTACT_FORM_SUCCESS", TRUE);
				
				# Email Notifications
				if(get_option($this->email_notifications_on) == 'true')
				{
					$to_email 	= get_option($this->email_notifications_email);
					$subject 	= get_option($this->email_notifications_subject);
					$message 	= get_option($this->email_notifications_message);
					
					if(is_email($to_email))
					{
						# Replace Strings
						foreach($this->fields as $field_id => $field)
						{
							$value = $_POST[$field_id];
							
							if($field_id != 'message')
								$subject = str_replace("#{$field_id}#", $value, $subject);
								
							$message = str_replace("#{$field_id}#", $value, $message);
						}
						
						# Extra Vairables
						$from = array('#date#', '#ip#', '#link#');
						$to = array(date("r"), $_SERVER['REMOTE_ADDR'], admin_url("admin.php?page={$this->menu_slug}"));
						
						$subject = str_replace($from, $to, $subject);
						$message = wpautop(str_replace($from, $to, $message));
						
						
						$headers[] = 'From: Laborator Contact Form <' . get_option('admin_email') . '>';
						$headers[] = 'Content-Type: text/html';
						
						wp_mail($to_email, $subject, $message, $headers);
					}
					
				}
				# End: Email Notifications 
			}
			else
			{
				define("LCF_CONTACT_FORM_ERRORS", TRUE);
			}
		}
	}
	
	public function render_message($message)
	{
?>
<style>
	
	body {
		background: #FAFAFA;
		font-family: Helvetica, Arial, sans-serif;
		font-size: 12px;
		line-height: 1.4;
	}
	
	.th_box_rm {
		background: #FFF;
		margin: 5px;
		padding: 15px;
		margin-top: 15px;
	}
	
	.th_box_rm .entry {
		background: #FAFAFA;
		padding: 0px 10px;
		margin: 5px;
	}
	
	.th_box_rm .entry div {
		display: inline-block;
		width: 150px;
		font-weight: bold;
		color: #888;
		vertical-align: middle;
	}
	
	.th_box_rm .entry div.value {
		width: auto;
		font-weight: normal;
		color: #555;
	}
	
</style>
<div class="th_box_rm">
<?php
foreach($message['data'] as $id => $entry)
{
?>
	<div class="entry">
		<div><?php echo $entry['title']; ?></div>
		<div class="value"><?php echo ! $entry['value'] ? wpautop('-') : wpautop($entry['value']); ?></div>
	</div>
<?php
}

?>
</div>
<?php
	}
	
	
	public function get_contact_entries($wp_table_mode = FALSE)
	{
		$contact_table = get_option($this->contact_table_id);
		
		if( ! is_array($contact_table))
		{
			$contact_table = array();
		}
		
		if($wp_table_mode)
		{
			$wp_table_items = array();
			
			foreach($contact_table as $id => $entry)
			{
				$data = $entry['data'];
				
				$from = $this->get_field($data, 'firstname') . ' ' . $this->get_field($data, 'lastname');
				$email = $this->get_field($data, 'email');
				$subject = $this->get_field($data, 'subject');
				 
				$wp_table_entry = array(
					'id' => $id, 
					'from' => $from, 
					'email' => $email, 
					'subject' => $subject,
					'ip' => $entry['ip'],
					'time' => date('D d, M Y - H:i:s', $entry['time']),
					'read' => $entry['read'] // message is read or not
				);
				
				array_push($wp_table_items, $wp_table_entry);
			}
			
			return $wp_table_items;
		}
		
		return $contact_table;
	}
	
	public function get_contact_entry($id)
	{
		$entries = $this->get_contact_entries();
		
		return $entries[$id];
	}
	
	public function mark_as_read($id)
	{
		$entries = $this->get_contact_entries();
		
		if($entries[$id])
		{
			$entries[$id]['read'] = TRUE;
			update_option($this->contact_table_id, $entries);
		}
	}
	
	public function delete_entry($id)
	{
		$entries = $this->get_contact_entries();
		
		if($entries[$id])
		{
			unset($entries[$id]);
			update_option($this->contact_table_id, $entries);
			
			return TRUE;
		}
		
		return FALSE;
	}
	
	public function get_field($data, $field_id)
	{
		foreach($data as $field)
		{
			if($field['id'] == $field_id)
			{
				return $field['value'];
			}
		}
		
		return '';
	}
	
	
	public function can_send_request($nonce)
	{
		$ip = $_SERVER['REMOTE_ADDR'];
		
		$table_entries = $this->get_contact_entries();
		
		foreach($table_entries as $entry)
		{
			if($entry['ip'] == $ip && $entry['nonce'] == $nonce && ($entry['time'] + $this->new_entry_timeout) > time())
			{
				return FALSE;
			}
		}
		
		return TRUE;
	}
	
	public function insert_entry($id, $fields)
	{
		$nonce = $_POST[$this->nonce_field];
		
		if( ! $this->can_send_request($nonce))
		{
			return FALSE;
		}
		
		$contact_table = $this->get_contact_entries();
		
		$table_entry = array(
			'time' => time(),
			'ip' => $_SERVER['REMOTE_ADDR'],
			'nonce' => $nonce,
			'data' => $fields
		);
		
		$contact_table[$id] = $table_entry;
		
		update_option($this->contact_table_id, $contact_table);
		
		return TRUE;
	}
}





/* Contact Entries Table */
class LaboratorContactForm_Table extends WP_List_Table
{
	public function __construct($items = array())
	{
        global $status, $page;
                
        //Set parent defaults
        parent::__construct( array(
            'singular'  => 'contact_entry',
            'plural'    => 'contacts',
            'ajax'      => false
        ) );
        
        $this->items = $items;
	}
	
	public function column_cb($item)
	{
        return sprintf('', $this->_args['singular'], $item['id']);
    }
	
	public function column_default($item, $column_name)
	{
		return $item[$column_name];
    }
    
    
    public function column_from($item)
    {
    	if( ! $item['read'])
    	{
	    	?>
	    	<div class="unread_message"><?php echo $item['from']; ?></div>
	    	<?php
    	}
    	else
    		echo $item['from'];
    }
    
    public function column_action($item)
    {
    	$actions = array(
    		'view' => '<a href="admin.php?page='.$_GET['page'].'&view_message='.$item['id'].'" class="labcf_read_message">Read Message</a>',
    		'delete' => '<a href="admin.php?page='.$_GET['page'].'&delete_message='.$item['id'].'" class="submitdelete labcf_delete">Delete</a>',
    	);
	    
	    echo $this->row_actions($actions, TRUE);
    }
    
	
	public function get_columns()
	{
        $columns = array(
            //'cb'        => '<input type="checkbox" />',
            'from'     	=> 'From',
            'subject'	=> 'Subject',
            'email'     => 'Email',
            'time'		=> 'Date',
            'ip'    	=> 'IP',
            'action'	=> 'Action'
        );
        
        return $columns;
    }
    
    public function get_sorted_columns()
    {
	    $sorted = array(
	    	'time' => array('from', false)
	    );
	    
	    return $sorted;
    }
	
	public function no_items()
	{
		echo 'No contact form entries';
	}
    
    public function prepare_items($items)
    {
    	$columns = $this->get_columns();
    	$hidden = array();
    	$sorted = $this->get_sorted_columns();
    	
	    $this->_column_headers = array($columns, $hidden, $sorted);
	    
	    $total_items = count($items);
	    $per_page = 15;
	    
	    $paged = isset($_GET['paged']) ? $_GET['paged'] : 1;
	    $paged = $paged > 1 ? $paged : 1;
	    $paged -= 1;
	    
	    // Sort
	    function sort_items($a, $b)
	    {
	    	$type = (isset($_GET['order']) ? $_GET['order'] : '') == 'asc' ? 1 : -1;
	    	
	    	return $a['time'] > $b['time'] ? 1*$type : -1*$type;
	    }
	    
	    usort($items, 'sort_items');
	    
	    
	    $offset = $paged * $per_page;
	    
	    $items = array_slice($items, $offset, $per_page);
	    
	    $this->items = $items;
	    
	    
	    $this->set_pagination_args( array(
            'total_items' => $total_items,                  //WE have to calculate the total number of items
            'per_page'    => $per_page,                     //WE have to determine how many items to show on a page
            'total_pages' => ceil($total_items/$per_page)   //WE have to calculate the total number of pages
        ) );
    }
}