<?php 

// get the current URL
function pc_curr_url() {
	$pageURL = 'http';
	
	if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
	$pageURL .= "://" . $_SERVER['HTTP_HOST'].$_SERVER["REQUEST_URI"];

	return $pageURL;
}


// get file extension from a filename
function pc_stringToExt($string) {
	$pos = strrpos($string, '.');
	$ext = strtolower(substr($string,$pos));
	return $ext;	
}


// get filename without extension
function pc_stringToFilename($string, $raw_name = false) {
	$pos = strrpos($string, '.');
	$name = substr($string,0 ,$pos);
	if(!$raw_name) {$name = ucwords(str_replace('_', ' ', $name));}
	return $name;	
}


// string to url format
function pc_stringToUrl($string){
	$trans = array("à" => "a", "è" => "e", "é" => "e", "ò" => "o", "ì" => "i", "ù" => "u");
	$string = trim(strtr($string, $trans));
	$string = preg_replace('/[^a-zA-Z0-9-.]/', '_', $string);
	$string = preg_replace('/-+/', "_", $string);
	return $string;
}


// normalize a url string
function pc_urlToName($string) {
	$string = ucwords(str_replace('_', ' ', $string));
	return $string;	
}


// sanitize input field values
function pc_sanitize_input($val) {
	global $wp_version;
	
	// not sanitize quotes  in WP 4.3 and newer
	if ($wp_version >= 4.3) {
		return trim(
			str_replace(array('"'), array('&quot;'), (string)$val)
		);	
	}
	else {
		return trim(
			str_replace(array('\'', '"', '<', '>', '&'), array('&apos;', '&quot;', '&lt;', '&gt;', '&amp;'), (string)$val)
		);	
	}
}
function pg_sanitize_input($val) {return pc_sanitize_input($val);} // retrocompatibility



// add array index after or before another one
//// $to_inject = array(index => val)
//// $what  	= related array index
//// $where 	= before / after
function pc_inject_array_elem($to_inject, $array, $what, $where = 'after') {
	$tot_elems = count($array);
	if(!$tot_elems) {return $to_inject;}
	
	$keys = array_keys($array);
	$pos = array_search($what, $keys); 
	if($pos === false) {return false;}

	$a = 0;
	$new_arr = array(); 
	foreach($array as $index => $val) {
		if($a == $pos && $where == 'before') {
			$new_arr = $new_arr + $to_inject;	
		}
		
		$new_arr[$index] = $val;
		
		if($a == $pos && $where == 'after') {
			$new_arr = $new_arr + $to_inject;	
		}
		
		$a++;
	}
		
	return $new_arr;
}



// calculate elapsed time
function pc_elapsed_time($date) {
    // PHP <5.3 fix
	if(!method_exists('DateTime','getTimestamp')) {
		include_once(PC_DIR . '/classes/datetime_getimestamp_fix.php');
		
		$dt = new pc_DateTime($date);
		$timestamp = $dt->getTimestamp();	
	}
	else {	
		$dt = new DateTime($date);
		$timestamp = $dt->getTimestamp();
	}
	
	// calculate difference between server time and given timestamp
    $timestamp = current_time('timestamp') - $timestamp;

    //if no time was passed return 0 seconds
    if ($timestamp < 1){
        return '1 '. __('second', 'pc_ml');
    }

    //create multi-array with seconds and define values
    $values = array(
		12*30*24*60*60  =>  'year',
		30*24*60*60     =>  'month',
		24*60*60        =>  'day',
		60*60           =>  'hour',
		60              =>  'minute',
		1               =>  'second'
	);

    //loop over the array
    foreach ($values as $secs => $point){
        
		//check if timestamp is equal or bigger the array value
        $divRes = $timestamp / $secs;
        if ($divRes >= 1){
            
			//if timestamp is bigger, round the divided value and return it
            $res = round($divRes);
			
			// translatable strings
			switch($point) {
				case 'year' : $txt = ($res > 1) ? __('years', 'pc_ml') : __('year', 'pc_ml'); break; 
				case 'month': $txt = ($res > 1) ? __('months', 'pc_ml') : __('month', 'pc_ml'); break;
				case 'day'  : $txt = ($res > 1) ? __('days', 'pc_ml') : __('day', 'pc_ml'); break;	
				case 'hour' : $txt = ($res > 1) ? __('hours', 'pc_ml') : __('hour', 'pc_ml'); break;	
				case'minute': $txt = ($res > 1) ? __('minutes', 'pc_ml') : __('minute', 'pc_ml'); break;	
				case'second': $txt = ($res > 1) ? __('seconds', 'pc_ml') : __('second', 'pc_ml'); break;	
			}
            return $res. ' ' .$txt;
        }
    }
}



// manage URL attrbutes (add/edit/remove) - returns complete URL
function pc_man_url_attr($url, $action, $param_name, $val = false) {
	$raw_arr = explode('?', $url);
	
	$base = $raw_arr[0];
	$params = array();
	
	if(count($raw_arr) > 1) {
		$raw_params = explode('&', $raw_arr[1]);
		
		foreach($raw_params as $part) {
			$arr = explode('=', $part);

			if(count($arr) == 1) {
				$params[ $arr[0] ]	= false;
			} else {
				$params[ $arr[0] ]	= $arr[1];	
			}
		}
	}
	
	####	
	
	if($action == 'add' || $action == 'edit') {
		$params[ $param_name ] = urlencode($val);
	}
	
	elseif($action == 'remove' && count($raw_arr) > 1) {
		if(isset($params[ $param_name ])) {
			unset( $params[ $param_name ] );	
		}
	}
	
	####

	if(count($params)) {
		$to_merge = array();
		
		foreach($params as $name => $pval) {
			$to_merge[] = ($pval !== false) ? $name.'='.$pval : $name; 	
		}
		
		return $base .'?'. implode('&', $to_merge);
	}
	else{
		return $base;
	}
}


/////////////////////////////////////////////////////////////////


// get WP pages list - id => title
function pc_get_pages() {
	$pages = array();
	
	foreach(get_pages() as $pag) {
		$pages[ $pag->ID ] = $pag->post_title;	
	}
	
	return $pages;	
}


// get lightbox instances - id => note
function pc_get_lb_instances() {
	$inst = array();
	
	// if isset global variable from settings saving
	if(isset($GLOBALS['pc_lb_data'])) {
		foreach($GLOBALS['pc_lb_data'] as $lb_id => $lb_data) {
			$inst[ $lb_id ] = $lb_data['note'];		
		}
	}
	else {
		if(isset($GLOBALS['pc_cached_lb_list'])) {return $GLOBALS['pc_cached_lb_list'];}
		$lb_instances = get_terms('pc_lightboxes', 'hide_empty=0&order=ASC');

		foreach($lb_instances as $i) {
			$name = ($i->name == '|||pclbft|||') ? $i->term_id : $i->name;
			$inst[ $i->term_id ] = $name;	
		}
		
		$GLOBALS['pc_cached_lb_list'] = $inst;
	}
	
	return $inst;	
}


// enqueue lightbox instance to be loaded in page's footer
function pc_enqueue_lb($lightbox_id) {
	if(!isset($GLOBALS['pc_queued_lb'])) {$GLOBALS['pc_queued_lb'] = array();}
	
	if(is_numeric($lightbox_id) && !in_array($lightbox_id, $GLOBALS['pc_queued_lb'])) {
		$GLOBALS['pc_queued_lb'][] = $lightbox_id;
		return true;		
	}
	
	return false;	
}




// get all the custom post types
function pc_get_cpt() {
	$args = array(
		'public'   => true,
		'publicly_queryable' => true,
		'_builtin' => false
	);
	$cpt_obj = get_post_types($args, 'objects');
	
	if(count($cpt_obj) == 0) { return false;}
	else {
		$cpt = array();
		foreach($cpt_obj as $id => $obj) {
			$cpt[$id] = $obj->labels->name;	
		}
		
		return $cpt;
	}	
}


// get all the custom taxonomies
function pc_get_ct() {
	$args = array(
		'public' => true,
		'_builtin' => false
	);
	$ct_obj = get_taxonomies($args, 'objects');
	
	if(count($ct_obj) == 0) { return false;}
	else {
		$ct = array();
		foreach($ct_obj as $id => $obj) {
			$ct[$id] = $obj->labels->name;	
		}
		
		return $ct;
	}	
}


// get affected post types
function pc_affected_pt() {
	if(isset($GLOBALS['pc_affected_pt'])) {
		return $GLOBALS['pc_affected_pt']; // cache	
	}
	
	$rpt = array('post','page');	
	$cpt = get_option('pg_extend_cpt'); 

	if(is_array($cpt)) {
		foreach($cpt as $pt) {
			if(is_admin() || post_type_exists($pt)) { // frontend check - be sure CPT are registered
				$rpt[] = $pt;	
			}
		}
	}

	// PC-FILTER - allow manual CPT integration - passes already affected CPT slugs array
	$rpt = apply_filters('pc_affected_pt', $rpt);
	
	$GLOBALS['pc_affected_pt'] = $rpt;
	return $rpt;
}
function pg_affected_pt() {return pc_affected_pt();} // retrocompatibility


// get affected  taxonomies
function pc_affected_tax() {
	if(isset($GLOBALS['pc_affected_tax'])) {
		return $GLOBALS['pc_affected_tax']; // cache	
	}
	
	$tax = array('category');	
	$cts = get_option('pg_extend_ct'); 
	
	if(is_array($cts)) {
		foreach($cts as $ct) {
			if(is_admin() || taxonomy_exists($ct)) { // frontend check - be sure taxonomies are registered
				$tax[] = $ct;	
			}
		}
	}

	// PC-FILTER - allow manual taxonomies integration - passes already affected taxonomies slug array
	$tax = apply_filters('pc_affected_tax', $tax);
	
	$GLOBALS['pc_affected_tax'] = $tax;
	return $tax;
}


/////////////////////////////////////////////////////////////////


// associative array of user categories (id => name) 
// $escape_no_reg = escape ones prevented from registration
function pc_user_cats($escape_no_reg = false) {
	$user_categories = get_terms('pg_user_categories', 'orderby=name&hide_empty=0');	
	$cats = array();

	if (!is_wp_error($user_categories)) {
		foreach ($user_categories as $ucat) {
			if($escape_no_reg && get_option("pg_ucat_".$ucat->term_id."_no_registration")) {continue;}
				
			// WPML - Polylang compatibility
			if(function_exists('icl_t')){
				$cat_name = icl_t('PrivateContent Categories', $ucat->term_taxonomy_id, $ucat->name);
			}
			else if(function_exists('pll__')){
				$cat_name = pll__($ucat->name);
			} else {
				$cat_name = $ucat->name;
			}
			
			$cats[$ucat->term_id] = $cat_name;	
		}
	}
	
	return $cats;
}


/* create restriction options array
 * @param (bool) $bulk_opts - whether to add "all/unlogged" options or not
 * @param (bool) $apply_filter - whether to apply filter to add new options
 * @param (array) $remove - specific values to discard
 */
function pc_restr_opts_arr($bulk_opts = true, $apply_filter = true, $remove = array()) {
	$opts = array();
	
	// pvtContent cats
	$opts['pc_cats'] = array(
		'name' => __('User Categories', 'pc_ml'),
		'opts' => array()
	);
	
	if($bulk_opts) {
		$opts['pc_cats']['opts'] = array(
			'all' => __('Any logged user', 'pc_ml'),
			'unlogged' => __('Unlogged Users', 'pc_ml'),
		);	
	}
	
	foreach(pc_user_cats() as $ucat_id => $ucat_name) {
		$opts['pc_cats']['opts'][$ucat_id] = $ucat_name;	
	}
	
	// PC-FILTER - add custom values in user categories dropdown to manage restrictions - passes PC opts array and the ones to exclude - structure must comply
	if($apply_filter) {
		$opts = apply_filters('pc_user_cat_dd_opts', $opts, $remove);
	}
	
	// selective removal
	if(!empty($remove) && is_array($remove)) {
		foreach($opts as $subj => $data) {
			foreach($data['opts'] as $key => $name) {
				
				if(in_array($key, $remove)) {
					unset( $opts[$subj]['opts'][$key] );	
				}
			}
		}
	}
	return $opts;	
}



/* get user categories dropdown options
 *
 * @param (string) $sel - selected value
 * @param (bool) $bulk_opts - whether to add "all/unlogged" options or not
 * @param (bool) $apply_filter - whether to apply filter to add new options
 */
function pc_user_cat_dd_opts($sel = false, $bulk_opts = true, $apply_filter = true, $remove = array()) {
	$opts = pc_restr_opts_arr($bulk_opts, $apply_filter, $remove);
	
	//// setup code
	$code = '';
	foreach($opts as $data) {
		if($apply_filter && count($opts) > 1) {$code .= '<optgroup label="'. $data['name'] .'">';}
		
		foreach($data['opts'] as $opt_id => $opt_name) {
			switch($opt_id) {
				case 'all' 		: $class = 'class="pc_all_field"'; break;
				case 'unlogged' : $class = 'class="pc_unl_field"'; break;
				default 		: $class = ''; break; 	
			}
			
			if(is_array($sel)) {
				$sel_attr = (in_array($opt_id, $sel)) ? 'selected="selected"' : '';	
			} else {
				$sel_attr = ($opt_id == $sel) ? 'selected="selected"' : '';	
			}

			$code .= '<option value="'. $opt_id .'" '.$sel_attr.' '.$class.'>'. $opt_name .'</option>';	
		}
		
		if($apply_filter && count($opts) > 1) {$code .= '</optgroup>';}
	}
	
	return $code;
}


// given user categories - return first category custom login redirect
function pc_user_cats_login_redirect($cats) {
	if(!is_array($cats)) {return '';}
	
	foreach($cats as $term_id) {
		$redirect = get_option("pg_ucat_".$term_id."_login_redirect");
		if($redirect) {
			return $redirect;
			break;	
		}
	}
}


// get term object knowing only its ID
function pc_term_obj_from_term_id($term_id) {
    global $wpdb;
	$tax = $wpdb->get_var( $wpdb->prepare("SELECT t.taxonomy FROM $wpdb->term_taxonomy AS t WHERE t.term_id = %s LIMIT 1", $term_id) );
	
	return (!empty($tax)) ? get_term_by('id', $term_id, $tax) : false;
}



// Settings -> URL-based custom restrictions - HTML template
function pc_cr_template($url = '', $allow = false, $block = false) {
	$code = '<li>';
	
	$code .= '
	<aside>
		<span class="pc_del_field" title="'. esc_attr( __('remove restriction', 'pc_ml')) .'"></span>
		<span class="pc_move_field" title="'. esc_attr( __('sort restriction', 'pc_ml')) .'"></span>
	</aside>';
	
	$code .= '
	<div style="padding-left: 50px; margin-bottom: 13px;">
		<input type="text" name="pg_cr_url[]" value="'. $url .'" placeholder="'. esc_attr( __("URL to restrict. Supports also regular expressions", 'pc_ml')) .'" autocomplete="off" />
	</div>';
		
	$code .= '
	<div style="display: inline-block; width: 49%; padding-left: 50px;">
		<label>'. __('Which user categories can access?', 'pc_ml') .'</label>
		<select name="pg_cr_allow[][]" class="lcwp_sf_chosen pg_cr_allow" multiple="multiple" autocomplete="off">
			'. pc_user_cat_dd_opts($allow) .'
		</select>
	</div>';
	
	
	$code .= '
	<div style="display: inline-block; width: 49%; padding-left: 50px;"">
		<label>'. __('Among them - want to block someone?', 'pc_ml') .'</label>
		<select name="pg_cr_block[][]" class="lcwp_sf_chosen pg_cr_block" multiple="multiple" autocomplete="off">
			'. pc_user_cat_dd_opts($block, false) .'
		</select>
	</div>';	
			
			
	return $code . '</li>';
}


/////////////////////////////////////////////////////////////////


// align forms (since v6)
function pc_form_align($form_code, $align = 'center') {
	
	// exception for widget login form
	if(isset($GLOBALS['pc_login_widget'])) {
		unset($GLOBALS['pc_login_widget']);
		return $form_code;	
	}
	
	return '<div class="pc_aligned_form pc_falign_'. $align .'">'. $form_code .'</div>';	
}


/////////////////////////////////////////////////////////////////


// stripslashes for options inserted
function pc_strip_opts($fdata) {
	if(!is_array($fdata)) {return false;}
	
	foreach($fdata as $key=>$val) {
		if(!is_array($val)) {
			$fdata[$key] = stripslashes($val);
		}
		else {
			$fdata[$key] = array();
			foreach($val as $arr_val) {$fdata[$key][] = stripslashes($arr_val);}
		}
	}
	
	return $fdata;
}


// WPML & Polylang integration - given a page ID, searches a translation. If not found, return original value
function pc_wpml_translated_pag_id($obj_id){
	
	// WPML
	if(function_exists('icl_object_id')) {
		$trans_val = icl_object_id($obj_id, 'page', true);
		if($trans_val && get_post_status($trans_val) == 'publish') {
			return $trans_val;
		}
	} 	
	
	// polylang
	if(function_exists('pll_get_post')) {
		$trans_val = pll_get_post($obj_id);
		if($trans_val && get_post_status($trans_val) == 'publish') {
			return $trans_val;
		}
	} 	
	
	return $obj_id;
}


// create the frontend css and js
function pc_create_custom_style() {	
	ob_start();
	require(PC_DIR.'/custom_style.php');
	
	$css = ob_get_clean();
	if(trim($css) != '') {
		if(!@file_put_contents(PC_DIR.'/css/custom.css', $css, LOCK_EX)) {$error = true;}
	} else {
		if(file_exists(PC_DIR.'/css/custom.css'))	{ unlink(PC_DIR.'/css/custom.css'); }
	}
	
	if(isset($error)) {return false;}
	else {return true;}
}


/////////////////////////////////////////////////////


// is email mandatory?
function pc_mail_is_required() {
	include_once(PC_DIR . '/classes/pc_form_framework.php');
	$form_fw = new pc_form;
	return $form_fw->mail_is_required;	
}



/////////////////////////////////////////////////////


// addons list database
function pc_addons_db($addon = false) {
	$addons = array(
		'pcud' => array(
			'name' => 'User Data',
			'descr'	=> 'User Data add-on boosts PrivateContent plugin allowing you to create and use unlimited fields to record more informations from your users',
			'link'	=> 'https://codecanyon.net/item/privatecontent-user-data-addon/2399731',
			'path'	=> 'private-content-user-data/pc_user_data.php'
		),
		
		'pcpp' => array(
			'name' 	=> 'Premium Plans',
			'descr'	=> 'Turn PrivateContent into a true premium membership platform.<br/> The add-on takes advantage of WooCommerce systems to handle payments and set subscription time limits',
			'link'	=> 'https://codecanyon.net/item/privatecontent-premium-plans-addon/15316736',
			'path'	=> 'private-content-premium-plans/pc_premium_plans.php'
		),
		
		'pcma' => array(
			'name' => 'Mail Actions',
			'descr'	=> 'Mail Actions add-on integrates e-mails in each process and allows you to seamlessly sync users with MailChimp, the best way to manage newsletter campaigns.',
			'link'	=> 'https://codecanyon.net/item/privatecontent-mail-actions-addon/3606728',
			'path'	=> 'private-content-mail-actions/pc_mail_actions.php'
		),
		
		'pcsl' => array(
			'name' => 'Secure Links',
			'descr'	=> 'With PrivateContent you can restrict any site element, but what about file links? With Secure Links add-on you can fulfill also this need!',
			'link'	=> 'https://codecanyon.net/item/privatecontent-secure-links-addon/3907407',
			'path'	=> 'private-content-secure-links/pc_secure_links.php'
		),	
	);	
	return (!$addon || !isset($addons[$addon])) ? $addons : $addons[$addon]; 	
}


// returns an array of add-ons not enabled yet 
function pc_addons_not_installed() {
	$found = array();
	
	foreach(pc_addons_db() as $id => $data) {
		if(!is_plugin_active( $data['path'] )) {
			$found[] = $id;	
		}
	}
	
	return $found;
}
