<?php
/**
* REST API Client Admin UI
*
* @category API
* @package My Calendar Pro
* @author Joe Dolson
* @license GPLv2 or later
* @link https://www.joedolson.com/my-calendar-pro/
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// add checkbox in event creation.
// admin UI to show calendars to display on central.
/**
* Add custom fields under event title.
*
* @since 3.0. Filter adds tools directly under event title.
*
* @param string $fields Existing fields.
* @param bool $has_data Does this event have data.
* @param array $data Array of event data.
*
* @return string new field data.
*/
function mcs_api_choose_targets( $fields, $has_data, $data ) {
$sites = mcs_api_endpoints();
$output = '';
$shared = ( $has_data ) ? get_post_meta( $data->event_post, '_log_endpoint' ) : array();
if ( ! is_array( $shared ) ) {
$shared = array();
}
if ( ! empty( $sites ) ) {
foreach ( $sites as $endpoint => $site ) {
// verify and regularize URL.
$label = $site['label'];
$verified = mcs_api_verify_endpoint( $endpoint );
$checked = '';
// checked if either in extant endpoints *or* creating a new event.
if ( $has_data && in_array( $endpoint, $shared, true ) ) {
$checked = "checked='checked'";
}
// toggle default state using mcapi_default_state.
if ( ! isset( $_GET['event_id'] ) ) {
/**
* Filter the checked state of an API endpoint in the admin.
*
* @hook mcapi_default_state
*
* @param {string} $checked Default checked state for an endpoint. E.g 'checked="checked"'.
* @param {string} $endpoint The endpoint being displayed. URL from API settings.
*
* @return {string}
*/
$checked = apply_filters( 'mcapi_default_state', $checked, $endpoint );
}
$id = 'mc_api_' . sanitize_title( $endpoint );
if ( $verified ) {
$output .= "<li><input type='checkbox' name='mc_api_endpoints[]' id='" . esc_attr( $id ) . "' value='" . esc_url( $endpoint ) . "' $checked /> <label for='" . esc_attr( $id ) . "'>" . esc_html( $label ) . '</label></li>';
}
}
if ( '' !== $output ) {
// The filter this is attached to doesn't echo itself.
?>
<div class='mc_api_endpoints selector'>
<fieldset>
<legend><?php esc_html_e( 'Cross Post Event:', 'my-calendar-pro' ); ?></legend>
<ul class='checkboxes'>
<?php echo wp_kses( $output, mc_kses_elements() ); ?>
</ul>
</fieldset>
</div>
<?php
}
}
return $fields;
}
add_filter( 'mc_insert_custom_fields', 'mcs_api_choose_targets', 10, 3 );
/**
* Save response from API for display
*
* @param array $responses Log of responses to this API event.
* @param int $event_id Event ID.
*/
function mcs_api_log_responses( $responses, $event_id ) {
$event_post = mc_get_event_post( $event_id );
update_post_meta( $event_post, '_log_response', $responses );
foreach ( $responses as $ep => $response ) {
// record sites shared with.
update_post_meta( $event_post, '_log_endpoint', $ep );
}
}
/**
* Add filter to display responses
*
* @param array $response Response from server.
*
* @return array $response.
*/
function mcs_api_display_responses( $response ) {
$event_post = mc_get_event_post( $response['event_id'] );
$log = get_post_meta( $event_post, '_log_response', true );
$original_message = $response['message'];
$new_message = '';
if ( ! is_array( $log ) ) {
return $response;
}
foreach ( $log as $endpoint => $resp ) {
if ( ! is_string( $resp['body'] ) ) {
continue;
}
$r = json_decode( $resp['body'] );
$label = mcs_api_id_endpoint( $endpoint );
if ( is_object( $r ) ) {
$event_id = ( property_exists( $r, 'event_id' ) ) ? $r->event_id : false;
if ( ! $event_id ) {
$error = trim( $r->message );
// Translators: Link to source of error.
$new_message .= "<div class='error'><p>" . sprintf( __( 'Error at %s.', 'my-calendar-pro' ), "<a href='" . esc_url( $endpoint ) . "'>" . esc_html( $label ) . '</a>' ) . '</p></div>';
$new_message .= $error;
} else {
// Translators: 1) Link to site being shared to, 2) Event ID on other site.
$new_message .= "<div class='updated'><p>" . sprintf( __( 'Event shared to %1$s. (Event ID: %2$d)', 'my-calendar-pro' ), "<a href='" . esc_url( $endpoint ) . "'>" . esc_html( $label ) . '</a>', $event_id ) . '</p></div>';
}
} else {
// Translators: Link to remote site.
$new_message .= "<div class='error'><p>" . sprintf( __( 'There was an error posting that event to the remote site (%s).', 'my-calendar-pro' ), "<a href='" . esc_url( $endpoint ) . "'>" . esc_html( $label ) . '</a>' ) . '</p></div>';
}
$new_message = apply_filters( 'mcs_api_message', $new_message, $r );
}
$response['message'] = $original_message . $new_message;
return $response;
}
add_filter( 'mc_event_saved_message', 'mcs_api_display_responses', 10, 1 );
/**
* Take endpoint URL and verify that it is a permitted endpoint & get title.
*
* @param string $endpoint URL of API endpoint.
*
* @return Label of valid endpoint.
*/
function mcs_api_id_endpoint( $endpoint ) {
$endpoints = mcs_api_endpoints();
// endpoints should be considered identical whether they're https or http, slashed or unslashed.
// this way, if a endpoint is changed from one to the other, references aren't lost.
$endpoint1 = str_replace( 'http:', 'https:', $endpoint );
$endpoint2 = str_replace( 'https:', 'http:', $endpoint );
$endpoint3 = trailingslashit( $endpoint1 );
$endpoint4 = untrailingslashit( $endpoint1 );
$endpoint5 = trailingslashit( $endpoint2 );
$endpoint6 = untrailingslashit( $endpoint2 );
$id = ( isset( $endpoints[ $endpoint1 ] ) ) ? $endpoints[ $endpoint1 ] : false;
if ( ! $id ) {
$id = ( isset( $endpoints[ $endpoint2 ] ) ) ? $endpoints[ $endpoint2 ] : false;
}
if ( ! $id ) {
$id = ( isset( $endpoints[ $endpoint3 ] ) ) ? $endpoints[ $endpoint3 ] : false;
}
if ( ! $id ) {
$id = ( isset( $endpoints[ $endpoint4 ] ) ) ? $endpoints[ $endpoint4 ] : false;
}
if ( ! $id ) {
$id = ( isset( $endpoints[ $endpoint5 ] ) ) ? $endpoints[ $endpoint5 ] : false;
}
if ( ! $id ) {
$id = ( isset( $endpoints[ $endpoint6 ] ) ) ? $endpoints[ $endpoint6 ] : false;
}
if ( $id ) {
$label = $id['label'];
} else {
$label = __( 'Untitled Endpoint', 'my-calendar-pro' );
}
return $label;
}
/**
* Add filter to show where event is saved.
*
* @param array $data Event data.
* @param int $event_id Event ID.
*/
function mcs_api_shared_events( $data, $event_id ) {
if ( $event_id ) {
if ( is_object( $event_id ) ) {
$data = $event_id;
}
// given Event ID, fetch site where event has been shared/where event came from.
$post = $data->event_post;
$response = get_post_meta( $post, '_log_endpoint', true );
}
}
add_filter( 'mc_event_notices', 'mcs_api_shared_events', 10, 2 );