<?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() );
}