<?php

 if ( ! defined( 'ABSPATH' ) ) exit;
class WPLMS_ZIP_UPLOAD_HANDLER{

	public static $instance;

    var $schedule;

    public static function init(){

        if ( is_null( self::$instance ) )
            self::$instance = new WPLMS_ZIP_UPLOAD_HANDLER();

        return self::$instance;
    }

	function __construct(){
		
		add_action('media_upload_upload',array($this,'media_upload_upload'));
		add_action( 'media_buttons', array($this,'wp_zip_upload_media_button'),100,1);
		add_action('wp_enqueue_scripts', array($this,'add_media_upload_scripts'));
		add_action('admin_enqueue_scripts','wp_enqueue_media');
	}


	function wp_zip_upload_media_button($editor_id) {
		$editor_id = apply_filters('wplms_upload_zip_button',$editor_id);
		if($editor_id){
			echo '<a href="'.admin_url('media-upload.php?type=upload&TB_iframe=true&tab=upload').'" class="thickbox button">
	  		 <div class="dashicons dashicons-upload"></div> '.__('Upload ZIP','wplms').'</a>';
		}
	}

	function add_media_upload_scripts() {
	    if ( is_admin() ) {
	         return;
	       }
	    if(isset($_GET['edit']))   
	    wp_enqueue_media();   
	}

	function media_upload_upload(){ 

		if(isset($_GET['tab']) && $_GET['tab']=='zip'){
		wp_iframe( "media_upload_zip_content" );
		}
		else{
			wp_iframe( "media_upload_zip_form" );
		}
	}
	function zip_tabs($tabs) {
		$newtab1 = array('zip' => __('Upload Library','wplms'));
		$newtab2 = array('upload' => __('Upload File','wplms'));
		return array_merge( $newtab2,$newtab1);
	}

	function print_tabs(){ 
		add_filter('media_upload_tabs', array($this,'zip_tabs'));
		media_upload_header();
	}

	function print_page_navi($num_records){ 
					//$num_records;	#holds total number of record
					$page_size;		#holds how many items per page
					$page;			#holds the curent page index
					$num_pages; 	#holds the total number of pages
					$page_size = 10;
					#get the page index
					if (empty($_GET['npage']) || !is_numeric($_GET['npage'])){$page = 1;
					}else{$page = $_GET['npage'];}
					
					#caluculate number of pages to display
					if(($num_records%$page_size)){
						$num_pages = (floor($num_records/$page_size) + 1);
					}else{
						$num_pages = (floor($num_records/$page_size));
					}
			
					if ($num_pages != 1)
					{
						for ($i = 1; $i <= $num_pages; ++$i)
						{
							if ($i == $page){
								echo "$i";	
							}else{
								echo "<a href=\"media-upload.php?type=upload&tab=zip&npage=$i\">$i</a>";
				
							}
							if($i != $num_pages)
							{
								echo " | ";
							}
						}
					}
			
					#calculate boundaries for limit query
					$upper_bound = (($page_size * ($page-1)) + $page_size);/*$page_size;*/
					$lower_bound = ($page_size * ($page-1));
					$bound=array($lower_bound,$upper_bound,);
					return $bound;
	}



	function print_detail_form($tab="upload", $file_url="", $dirname=""){
		?>
		<div class="package_upload_detail_form" style="display:none">
			<label><?php _e('Iframe source','wplms'); ?> : </label> 
			<input type="text" size="80"  class="package_upload_file_url" value="<?php echo $file_url; ?>" />
			<input type="hidden" size="40"  class="package_upload_dir_name" value="<?php echo $dirname; ?>" />
			<?php 
			if($tab=='upload'){ 
			 echo '<input type="hidden" class="package_uploads_file_name" value="" size="20" />';
			}
			?>		
			<hr />
			<label><?php _e('Package Type','wplms') ?></label> : <select name="package_type"><option value="default"><?php _e('Default (xAPI or None or Tincan)','wplms'); ?></option><option value="2004"><?php _e('SCORM 2004','wplms'); ?></option><option value="1.1"><?php _e('SCORM 1.1, 1.2','wplms'); ?></option></select>
			<label><?php _e('Maximum height of iFrame','wplms'); ?> : </label> <input type="text" name="package_upload_max_height" class="package_upload_max_height" value="800">

			<br>
			<label><?php _e('Open in Popup','wplms'); ?> : </label> <input type="checkbox" name="open_in_popup" class="package_open_in_popup" value="1" style="margin: 5px 0px;">
				
			<div  class="package_popup_button_label_div" style="display:none;">
				<label><?php _e('Popup Button label','wplms'); ?> : </label> <input type="text" name="popup_button_label" class="package_popup_button_label" value="<?php _e('Open','wplms'); ?>" style="margin: 5px 0px;">
			</div>
			<div   class="package_tincan_endpoint_div">
				<label><?php _e('Tincan Endpoint','wplms'); ?> : </label> <input type="text" name="tincan_endpoint" class="package_tincan_endpoint" value="<?php echo site_url(); ?>" style="margin: 5px 0px;">
			</div>

			<input type="button" class="button package_upload_insert_into_post"  value="<?php _e('Insert Into Post','wplms'); ?>" /> 
		</div>
	<?php
	}




	function printInsertForm(){

		$dirs = $this->getDirs();
		if (count($dirs)>0){
		$this->print_js("zip");
		$uploadDirUrl=$this->getUploadsUrl();
		 //START PAGIGNATION
		 ?>
		 <div class="upload_dirs_navigation"> 
		 <?php  $bound= $this->print_page_navi(count($dirs)); // print the pagignation and return upper and lower bound ?>
		 </div>
		 <?php
		 
		  $lower_bound=$bound[0];
		  $upper_bound=$bound[1]; 

		  if($upper_bound>count($dirs))
		  	$upper_bound = count($dirs);
		  echo '<span>'.sprintf(__('Showing Content %d - %d from %d','wplms'),$lower_bound,$upper_bound,count($dirs)).'</span>';
		  //$dirs = array_slice($dirs, $lower_bound, $upper_bound);
		  $dirs = array_slice($dirs, $lower_bound, 10);
		  //END PAGIGNATION
		 	
			echo "<table class='widefat'>";
				foreach ($dirs as $i=>$dir):
					extract($dir);
					$package_name = str_replace("_"," " ,$dir);
					echo '<tr '.(($i%2)?'class="alternate"':'').'>
							<td>';
							echo '<strong>'.$package_name.'</strong>';
							echo '<span class="package_upload_controls" style="float:right">';
							echo '<span class="package_uploads_show_button"><i class="dashicons dashicons-plus"></i></span> | ';
							echo '<span class="package_uploads_delete_dir"><i class="dashicons dashicons-no"></i></span>';
							echo '</span>';
							$this->print_detail_form("zip" , $uploadDirUrl.$dir."/".$file, $dir);
							echo '
							</td>
						 </tr>';

				endforeach;
			echo "</table>";
		
		}else{
		echo __('No packages available','wplms');
		}
		
	}

	function getUploadsPath($user_id=null){
		$dir = wp_upload_dir();
		$privacy = vibe_get_option('instructor_content_privacy');
		if(isset($privacy) && $privacy){
			if(empty($user_id)){
				$user_id = get_current_user_id();
			}
			return $dir['basedir'] . '/private_package_uploads/'.$user_id.'/';
		}else{
			return $dir['basedir'] . '/package_uploads/';
		}
	}
	function getUploadsUrl($user_id=null){
		$dir = wp_upload_dir();
		$privacy = vibe_get_option('instructor_content_privacy');
		if(isset($privacy) && $privacy){
			if(empty($user_id)){
				$user_id = get_current_user_id();
			}
			return $dir['baseurl'] . '/private_package_uploads/'.$user_id.'/';
		}else{
			return $dir['baseurl'] . '/package_uploads/';
		}
	}

	function getDirs($user_id=null){
		$paths = $this->getUploadsPath($user_id);
		if(file_exists($paths)){
			$myDirectory = opendir($paths);
			$dirArray = array();
			$i=0;
			while($entryName = readdir($myDirectory)) {
				if ($entryName != "." && $entryName !=".." && is_dir($this->getUploadsPath($user_id).$entryName)):
				$dirArray[$i]['dir'] = $entryName;
				$dirArray[$i]['file'] = $this->getFile($this->getUploadsPath($user_id).$entryName);
				$i++;
				endif;
			}
			// close directory
			closedir($myDirectory);
			return $dirArray;
		}
		return array();
	}

	function getFile($dir){
        $myDirectory = opendir($dir);
        $fileArray = array();
        $myDirectory = opendir($dir);
        $fileArray = array();
        $file1 = '';
        // get each entry

        while($entryName = readdir($myDirectory)) {
          	if ($entryName != "." && $entryName !=".."){
          		$f = '';
	          	if($entryName == 'imsmanifest.xml'){
	          		$xml = simplexml_load_file($dir.'/'.$entryName);
	 
	          		if(!empty($xml->resources->resource)){

	          			$link = (string)$xml->resources->resource[0]['href'];

	          			$f = $dir.'/'.$link;
	          			$entryName = $link;
	          			return $entryName;
	          		}

	          		if(!empty($xml->resources->resource->attributes()) && !empty($xml->resources->resource->attributes()->href)){
	          			
	          			$link = (string)$xml->resources->resource->attributes()->href;
	          			$f = $dir.'/'.$link;
	          			$entryName = $link;
	          			return $entryName;
	          		}
	          	}

	          	if(empty($f)){	
	          		$f = $this->getUploadsPath().$entryName;
	          	}

          		$fname = pathinfo ($f, PATHINFO_FILENAME);
            	$ext = pathinfo ($f,PATHINFO_EXTENSION);
            	if (in_array($ext,array('html','htm','mov','avi','mp4','mp3','txt'))){
	              	if(!empty($entryName)){
		                if(strpos($fname, 'index') !== false || strpos($fname, 'story') !== false){
		                    return $entryName;
		                    break;
		                }else{
		                    $file1 = $entryName;
		                }
	                }
	            }
          	}
        }
        closedir($myDirectory);
        if(!empty($file1)){
          	return $file1;
        }
        return false;
    }

	function print_js(){ 
		wp_enqueue_script('package_uploads',WPLMS_PLUGIN_INCLUDES_URL.'/vibe-shortcodes/js/package_uploads.js',array('jquery'),'1.3');
		$translation_array = array( 
			'upload_zip_error'=> __( 'Please upload a Zip package with index.html file','wplms' ), 
			'no_data'=> __( 'No data found!','wplms' ), 
			'remove_package'=> __( 'Are you sure you want to remove this package?','wplms' ), 
			);
		wp_localize_script( 'package_uploads', 'package_upload_strings', $translation_array );
		return;
	}

	function print_upload(){
		$this->print_js();
		?>
		<form enctype="multipart/form-data" id="zip_upload_form" style="background: #fff;margin: 0 -30px;padding: 30px;" action="admin-ajax.php" method="POST">
		<input type="hidden" name="action" value="zip_upload" />
		<input type="hidden" name="MAX_FILE_SIZE" value="1000000000" />
		<div style="display: grid; grid-template-columns: 1fr 1fr; grid-gap: 10px;">
			<div style="border: 2px dashed rgba(0,0,0,0.2); padding: 15px;">
				<strong><?php _e('Choose a file to upload','wplms'); ?></strong></td><td> <input name="uploadedfile"  id="uploadedfile" type="file" /></td></tr>
			</div>
			<div>
				<div style="display:grid;grid-template-columns: 1fr 1fr;margin-bottom:10px">
					<label><?php _e('Package Type','wplms') ?></label>
					<select name="package_type"><option value="default"><?php _e('Default (xAPI or None or Tincan)','wplms'); ?></option><option value="2004"><?php _e('SCORM 2004','wplms'); ?></option><option value="1.1"><?php _e('SCORM 1.1, 1.2','wplms'); ?></option>
					</select>
				</div>
				<div  style="display:grid;grid-template-columns: 1fr 1fr;">
					<label><?php _e('Maximum height of iFrame','wplms'); ?> : </label> <input type="text" name="package_upload_max_height" class="package_upload_max_height" value="800">
				</div>
				<div  style="display:grid;grid-template-columns: 1fr 1fr;">
					<label><?php _e('Open in Popup','wplms'); ?> : </label> <input type="checkbox" name="open_in_popup" class="package_open_in_popup" value="1" style="margin: 5px 0px;">
				</div>
				<div  style=" display:none;" class="package_popup_button_label_div">
					<label style=" width:50%;    display: inline-block;"><?php _e('Popup Button label','wplms'); ?> : </label> <input type="text" name="popup_button_label" class="package_popup_button_label" value="<?php _e('Open','wplms'); ?>" style="margin: 5px 0px;">
				</div>
				<div  style="display:grid;grid-template-columns: 1fr 1fr;justify-content: center; align-items: center;" class="package_tincan_endpoint_div">
					<label><?php _e('Tincan Endpoint','wplms'); ?> : </label> <input type="text" name="tincan_endpoint" class="package_tincan_endpoint" value="<?php echo site_url(); ?>" style="margin: 5px 0px;">
				</div>
			</div>
			<input type="submit" value="<?php _e('Upload File','wplms'); ?>" class="button" /></td>
		</div>
		</form>
		<p><i><?php _e('Please choose a .zip package file','wplms'); ?></i></p>
		<img id="media_loading" style='display:none;' src= "<?php echo WPLMS_PLUGIN_INCLUDES_URL . '/vibe-shortcodes/images/loading.gif' ;?>" /><br />
		<?php $this->print_detail_form();?>
		<p/>
		<?php
	}



	function extractZip($fileName,$target,$dir,$user_id=null){
	 		$arr = array();

	 		if ( ! class_exists( '\ZipArchive' ) ) {
                        return new \WP_Error( 'zip_error', 'PHP Zip extension not loaded' );
	                }

	 	 $zip = new ZipArchive;
	     $res = $zip->open($fileName);
	     if ($res === TRUE) {

	     	$ext = wp_get_ext_types();
	     	unset($ext["archive"]);
	     	unset($ext["code"]["php"]);
	     	$allowed_extensions = array_merge(...array_values($ext));
	     	$allowed_extensions[]="xsd";$allowed_extensions[]="xml";
	     	$file_names_to_extract = [];
		    for ($i = 0; $i < $zip->numFiles; $i++) {
		        $fileName = $zip->getNameIndex($i);
		        $fileExtension = pathinfo($fileName, PATHINFO_EXTENSION);
		        if (in_array(strtolower($fileExtension), $allowed_extensions)) {
		            $file_names_to_extract[] = $fileName; 
		        }
		    }

	     	 $zip->extractTo($target, $file_names_to_extract);
	         //$zip->extractTo($target);//,$allowed_extensions);
	         $zip->close();
			 $file = $this->getFile($target);

			$non_allowed_extensions = ["php", "py", "rb", "cgi", "pl", "jsp", "java","exe","asp", "aspx", "jsp","sh", "bash", "bat"];

			$non_allowed_mimes =  [
			    "application/x-httpd-php",
			    "text/x-python",
			    "application/php",
			    "application/x-ruby",
			    "text/x-php",
			    "application/x-msdos-program",
			    "application/x-cgi",
			    "application/x-perl",
			    "application/x-jsp",
			    "text/x-java-source,java",
			    "application/x-msdownload",
			    "text/asp",
			    "application/xml",
			    "application/x-jsp",
			    "application/x-sh",
			    "application/x-bsh",
			    "application/bat"
			];

			//scan folder and subfolders for mimetype check
			$files = wplms_getAllFiles($target);
			if(!empty($files)){
				foreach($files as $nfile){
					$extension = pathinfo($nfile, PATHINFO_EXTENSION);
					if(in_array($extension,$non_allowed_extensions)){
						@unlink($nfile);
					}
					$mime_type = $this->_mime_content_type($nfile);
				
					if(in_array($mime_type,$non_allowed_mimes)){
						@unlink($nfile);
					}
				}
			}


			if($file){
				 $arr[0] = 'uploaded'; 
				 $arr[1] = $this->getUploadsUrl($user_id).$dir."/".$file; 
				 $arr[2] = $dir;
				 $arr[3] =$file;
				 $arr[4] = $this->getUploadsPath($user_id).$dir; 
			 }else{
				 $arr[0] = __('Please upload zip file, Index.html file not found in package','wplms').$target.print_r($file);
				 $this->rrmdir($target);
			 }
	     }else{
			$arr[0] = __('Upload failed !','wplms');;
	     }
		 return  $arr;
	}

	function rrmdir($dir) {
		if (is_dir($dir)) {
		 $objects = scandir($dir);
		 foreach ($objects as $object) {
		   if ($object != "." && $object != "..") {
		     if (filetype($dir."/".$object) == "dir") $this->rrmdir($dir."/".$object); else unlink($dir."/".$object);
		   }
		 }
		 reset($objects);
		 rmdir($dir);
		}
	}
	function _mime_content_type($filename) {

        /**
        *    mimetype
        *    Returns a file mimetype. Note that it is a true mimetype fetch, using php and OS methods. It will NOT
        *    revert to a guessed mimetype based on the file extension if it can't find the type.
        *    In that case, it will return false
        **/
        if (!file_exists($filename) || !is_readable($filename)) return false;
        if(class_exists('finfo')){
            $result = new finfo();
            if (is_resource($result) === true) {
                return $result->file($filename, FILEINFO_MIME_TYPE);
            }
        }
        
         // Trying finfo
         if (function_exists('finfo_open')) {
           $finfo = finfo_open(FILEINFO_MIME);
           $mimeType = finfo_file($finfo, $filename);
           finfo_close($finfo);
           // Mimetype can come in text/plain; charset=us-ascii form
           if (strpos($mimeType, ';')) list($mimeType,) = explode(';', $mimeType);
           return $mimeType;
         }
        
         // Trying mime_content_type
         if (function_exists('mime_content_type')) {
           return mime_content_type($filename);
         }
        

         // Trying to get mimetype from images
         $imageData = getimagesize($filename);
         if (!empty($imageData['mime'])) {
           return $imageData['mime'];
         }
         // Trying exec
         if (function_exists('wp_check_filetype')) {
            $mimeType = wp_check_filetype($filename);
           $mimeType = $mimeType['type'];
           if (!empty($mimeType)) return $mimeType;
         }
        return false;
    }


}


function media_upload_zip_form(){
	$wplmsthis = WPLMS_ZIP_UPLOAD_HANDLER::init();
	$wplmsthis->print_tabs();
	echo '<div class="upload_directory">';
	echo '<h2>'.__('Upload File','wplms').'</h2>';
	$wplmsthis->print_upload();
	echo "</div>";
}

function media_upload_zip_content(){
	$wplmsthis = WPLMS_ZIP_UPLOAD_HANDLER::init();
	$wplmsthis->print_tabs();
	echo '<div class="upload_directory">';
	echo '<h2>'.__('Upload Library','wplms').'</h2>';
	$wplmsthis->printInsertForm();
	echo '</div>';
}

?>