Source: inc/utilities.php

<?php
/**
 * Utility functions for My Calendar Pro.
 *
 * @category Utilities
 * @package  My Calendar Pro
 * @author   Joe Dolson
 * @license  GPLv2 or later
 * @link     https://www.joedolson.com/my-calendar-pro/
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Test whether the current user can submit events.
 *
 * @return boolean
 */
function mcs_user_can_submit_events() {
	$permission = (int) get_option( 'mcs_criteria', '2' );
	switch ( $permission ) {
		case 0:
			return false;
			break;
		case 1:
			return true;
			break;
		case 2:
			if ( is_user_logged_in() ) {
				return true;
			}
			break;
		case 3:
			if ( current_user_can( 'mc_add_events' ) ) {
				return true;
			}
			break;
		default:
			return false;
	}
}

/**
 * Produce a notification for users without permission to submit events.
 *
 * @return string
 */
function mcs_submission_not_available() {
	$permission = (int) get_option( 'mcs_criteria', '2' );
	$redirect   = mc_get_current_url();
	// translators: login URL.
	$login = '<p class="mc-submissions-notice">' . sprintf( __( 'You need to be logged in to submit events. <a href="%s">Please login.</a>', 'my-calendar-pro' ), esc_url( wp_login_url( $redirect ) ) ) . '</p>';

	switch ( $permission ) {
		case 1: // Anybody can submit. Doesn't hide content and shouldn't happen here.
			return '';
			break;
		case 2: // Can submit if logged in.
			return $login;
			break;
		case 3: // Can submit if has appropriate permissions.
			if ( is_user_logged_in() ) {
				return '<p class="mc-submissions-notice">' . __( 'You need upgraded permissions to be able to submit events.', 'my-calendar-pro' ) . '</p>';
			} else {
				return $login;
			}
			break;
	}

	return '';
}

/**
 * Required text string for required My Calendar form fields.
 *
 * @return string
 */
function mcs_required_text() {
	$text = '<span class="required">' . __( '(required)', 'my-calendar-pro' ) . '</span>';
	/**
	 * Filter required text string.
	 *
	 * @hook mcs_required_text
	 *
	 * @param {string} $text Default required text.
	 *
	 * @return string
	 */
	$filtered = apply_filters( 'mcs_required_text', $text );

	return ( '' === wp_strip_all_tags( $filtered ) ) ? $text : $filtered;
}

/**
 * Produce placeholders in a meaningful format.
 *
 * @return string
 */
function mcs_parse_date_format() {
	$format = get_option( 'mcs_date_format' );
	switch ( $format ) {
		case 'Y-m-d':
			$parsed = 'YYYY-MM-DD';
			break;
		case 'm/d/Y':
			$parsed = 'MM/DD/YYYY';
			break;
		case 'd-m-Y':
			$parsed = 'DD-MM-YYYY';
			break;
		case 'j F Y':
			$parsed = 'DD MMMM YYYY';
			break;
		case 'M j, Y':
			$parsed = 'MMM DD, YYYY';
			break;
		default:
			$parsed = 'YYYY-MM-DD';
	}

	return $parsed;
}


add_action( 'send_headers', 'mcs_set_unique_id' );
/**
 * Set unique ID in cookie to trace this transaction
 */
function mcs_set_unique_id() {
	if ( is_admin() || ! mcs_user_can_submit_events() ) {
		return;
	}
	$unique_id = ( isset( $_COOKIE['mcs_unique_id'] ) && '' !== $_COOKIE['mcs_unique_id'] ) ? true : false;
	if ( ! $unique_id ) {
		$unique_id = mcs_generate_unique_id();
		if ( version_compare( PHP_VERSION, '7.3.0', '>' ) ) {
			// Fix syntax.
			$options = array(
				'expires'  => time() + WEEK_IN_SECONDS,
				'path'     => COOKIEPATH,
				'domain'   => COOKIE_DOMAIN,
				'secure'   => false,
				'httponly' => true,
				'samesite' => 'Lax',
			);
			setcookie( 'mcs_unique_id', $unique_id, $options );
		} else {
			setcookie( 'mcs_unique_id', $unique_id, time() + WEEK_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN, false, true );
		}
	}
}

/**
 * Create unique ID to trace this transaction.
 */
function mcs_generate_unique_id() {
	$length     = 32;
	$characters = '0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz-_';
	$string     = '';
	for ( $p = 0; $p < $length; $p++ ) {
		$string .= $characters[ wp_rand( 0, strlen( $characters ) - 1 ) ];
	}

	return $string;
}

/**
 * Transform a string of field tokens into an array of field data.
 *
 * @param string $f Comma separated list of field tokens and characteristics.
 *
 * @return array
 */
function mcs_create_field_array( $f ) {
	if ( is_array( $f ) ) {
		return $f;
	}
	$fields = explode( ',', $f );
	$fld    = array();
	foreach ( $fields as $value ) {
		$set           = explode( '=', $value );
		$value         = strtolower( trim( $set[0] ) );
		$fld[ $value ] = ( isset( $set[1] ) ) ? $set[1] : 'true';
	}

	return $fld;
}

/**
 * Format fee costs.
 *
 * @param float $fee Cost.
 *
 * @return string
 */
function mcs_format_submission_fee( $fee ) {
	return sprintf( '%01.2f', $fee );
}
add_filter( 'mcs_submission_fee', 'mcs_format_submission_fee' );

/**
 * Check whether a given feature is enabled.
 *
 * @param string $feature Feature string.
 *
 * @return bool
 */
function mcs_is_enabled( $feature ) {
	switch ( $feature ) {
		case 'responsive-mode':
			$enabled = ( 'true' === get_option( 'mcs_responsive_mode' ) ) ? true : false;
			break;
		case 'server-api':
			$enabled = ( 'server-api' === apply_filters( 'mcs_api_state', get_option( 'mcs_api' ) ) ) ? true : false;
			break;
		case 'client-api':
			$enabled = ( 'client-api' === apply_filters( 'mcs_api_state', get_option( 'mcs_api' ) ) ) ? true : false;
			break;
		default:
			$enabled = false;
	}

	return $enabled;
}

/**
 * Format email messages as HTML.
 */
function mcs_html_email() {
	return 'text/html';
}

/**
 * Matches mc_date in core plug-in, added in 3.2.0.
 *
 * @param string $format Format to use.
 * @param int    $timestamp Timestamp.
 * @param bool   $offset false to not add offset; if already a true timestamp.
 *
 * @return string Formatted date.
 */
function mcs_date( $format, $timestamp = false, $offset = true ) {
	if ( function_exists( 'mc_date' ) ) {
		return mc_date( $format, $timestamp, $offset );
	} else {
		if ( ! $timestamp ) {
			$timestamp = time();
		}
		if ( $offset ) {
			$offset = intval( get_option( 'gmt_offset', 0 ) ) * 60 * 60;
		} else {
			$offset = 0;
		}
		$timestamp = $timestamp + $offset;

		return ( '' === $format ) ? $timestamp : gmdate( $format, $timestamp );
	}
}

/**
 * Label My Calendar Pro pages in the admin.
 *
 * @param array  $states States for post.
 * @param object $post The post object.
 *
 * @return array
 */
function mcs_admin_state( $states, $post ) {
	if ( is_admin() ) {
		if ( absint( get_option( 'mcs_submit_id' ) ) === $post->ID ) {
			$states[] = __( 'Event Submissions', 'my-calendar-pro' );
		}
		if ( absint( get_option( 'mcs_edit_id' ) ) === $post->ID ) {
			$states[] = __( 'Event Editing', 'my-calendar-pro' );
		}
		$options = get_option( 'mcs_advanced_search', array() );
		if ( isset( $options['home'] ) && absint( $options['home'] ) === $post->ID ) {
			$states[] = __( 'Advanced Event Search', 'my-calendar-pro' );
		}
	}

	return $states;
}
add_filter( 'display_post_states', 'mcs_admin_state', 10, 2 );

/**
 * Generate array of known post IDs. These are post IDs known to be used by existing My Calendar features.
 *
 * @return array
 */
function mcs_known_posts() {
	$known = array(
		mc_get_option( 'uri_id' ),
		get_option( 'mcs_submit_id', false ),
		mcs_advanced_search_options()['home'],
		get_option( 'mcs_edit_id' ),
	);

	return $known;
}

/**
 * Verify whether a remotely loaded image is a valid image.
 *
 * @param string $url Url to image.
 *
 * @return bool
 */
function mcs_check_remote_image( $url ) {
	if ( ! function_exists( 'download_url' ) ) {
		require_once ABSPATH . 'wp-admin/includes/file.php';
	}
	$is_valid = false;
	$tmp      = download_url( $url );
	if ( ! is_wp_error( $tmp ) ) {
		$size     = wp_getimagesize( $tmp );
		$is_valid = ! empty( $size );
	}
	wp_delete_file( $tmp );

	return $is_valid;
}

/**
 * Alias for `wp_kses( $output, mc_kses_elements() )` for use in callbacks.
 *
 * @param string $output Output to verify.
 *
 * @return string
 */
function mc_kses_callback( $output ) {
	return wp_kses( $output, mc_kses_elements() );
}