radar-wp/includes/squat-radar-widget.php
2019-04-28 17:23:55 +02:00

250 lines
9.3 KiB
PHP

<?php
class Squat_Radar_Widget extends WP_Widget {
public function __construct() {
$widget_ops = array(
'classname' => 'squat-radar-widget',
'description' => 'Radar Events List',
);
$this->connector = new Squat_Radar_Connector();
parent::__construct( 'Squat_Radar', 'Squat Radar Events', $widget_ops );
}
/**
* Register the widget
*/
public static function register_widget() {
register_widget( __CLASS__ );
add_action( 'wp_ajax_squat_radar_events', [__CLASS__, 'ajax_callback'] );
add_action( 'wp_ajax_nopriv_squat_radar_events', [__CLASS__, 'ajax_callback'] );
add_action( 'wp_enqueue_scripts', [__CLASS__, 'widget_script'] );
add_action( 'wp_enqueue_style', [__CLASS__, 'widget_style'] );
}
static public function widget_style() {
wp_register_style( 'squat-radar-widget', SQUAT_RADAR_URL . '/assets/squat-radar.css' );
}
static public function widget_script() {
wp_register_script( 'squat-radar-widget', SQUAT_RADAR_URL . '/assets/squat-radar.js', ['jquery'] );
}
public function widget( $args, $instance ) {
wp_enqueue_style( 'squat-radar-widget' );
wp_enqueue_script( 'squat-radar-widget');
wp_localize_script( 'squat-radar-widget', 'squat_radar_widget', [ 'ajaxurl' => admin_url( 'admin-ajax.php' ) ] );
// Seems non-trivial to send (potentially) multiple values for different widget instances appending an array/hash.
$widget_id = 'squat_radar_widget_' . $this->number;
wp_localize_script( 'squat-radar-widget', $widget_id, $instance );
echo $args['before_widget'];
if ( ! empty( $instance['title'] ) ) {
echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
}
echo '<div id="' . $widget_id . '" class="squat-radar-widget squat-radar-ajax"><a href="' . esc_url_raw( $instance['url']['value'] ) . '">'
. esc_url( $instance['url']['value'] )
. '</a></div>';
echo $args['after_widget'];
}
public static function ajax_callback() {
if ( ! array_key_exists('instance', $_POST) ) {
wp_die();
}
$instance = $_POST['instance'];
$language = defined('ICL_LANGUAGE_CODE') ? ICL_LANGUAGE_CODE : $instance['url']['keys']['language'];
$connector = new Squat_Radar_Connector();
try {
$data = $connector->events($instance['url']['keys']['facets'], $instance['fields'], $language, $instance['limit'], $instance['cache_expire'], TRUE );
}
catch ( Squat_Radar_Connector_Exception $e ) {
$data = ['is_error' => TRUE];
if ( current_user_can( 'administrator' ) ) {
$data['error']['code'] = $e->getCode();
$data['error']['message'] = $e->getMessage();
}
wp_send_json($data);
}
$html = '';
foreach ($data['result'] as $id => $event) {
$output = apply_filters( 'squat_radar_format_event', $event, $instance['fields'], ['instance' => $instance] );
$html .= implode($output);
}
$data['html'] = $html;
wp_send_json($data);
}
public function form( $instance ) {
//
// Introduction.
//
echo "<p>";
echo __('If you want to display this single widget in a page or post use the Shortcode:') . '&nbsp;';
if ( $this->number == '__i__' ) {
echo '<em>' . __( 'Shortcode will be available once you have saved this the first time') . '</em>';
}
else {
esc_attr_e( '[squat_radar_widget id="' . $this->number . '"]' );
}
echo "</p>";
//
// Title.
//
$field_id = esc_attr( $this->get_field_id( 'title' ) );
$field_name = esc_attr( $this->get_field_name( 'title' ) );
$field_label = esc_attr( 'Title:', 'squat-radar' );
$field_value = empty( $instance['title'] ) ? '' : esc_attr( $instance['title'] );
$field_class = 'widefat';
echo "<p>";
echo "<label for=\"$field_id\">$field_label</label>";
echo "<input class=\"$field_class\" id=\"$field_id\" name=\"$field_name\" type=\"text\" value=\"$field_value\">";
echo "</p>";
//
// Limit
//
$field_id = esc_attr( $this->get_field_id( 'limit' ) );
$field_name = esc_attr( $this->get_field_name( 'limit' ) );
$field_label = esc_attr( 'Number of events to display:', 'squat-radar' );
$field_value = empty( $instance['limit'] ) ? '10' : (int) $instance['limit'];
$field_class = 'tiny-text';
echo "<p>";
echo "<label for=\"$field_id\">$field_label</label>";
echo "<input class=\"$field_class\" id=\"$field_id\" name=\"$field_name\" type=\"number\" step=\"1\" min=\"1\" value=\"$field_value\" size=\"3\">";
echo "</p>";
//
// URL.
//
$field_error = ! empty( $instance['url']['error'] );
$field_id = esc_attr( $this->get_field_id( 'url' ) );
$field_name = esc_attr( $this->get_field_name( 'url' ) );
$field_label = esc_attr( 'Event Search URL:', 'squat-radar' );
$field_value = empty( $instance['url']['value'] ) ? '' : esc_attr( $instance['url']['value'] );
$field_class = 'widefat' . $field_error ? ' error' : '';
echo "<p>";
echo "<label for=\"$field_id\">$field_label</label>";
echo "<input class=\"$field_class\" id=\"$field_id\" name=\"$field_name\" type=\"text\" value=\"$field_value\">";
echo "</p>";
if ( $field_error ) {
echo '<div class="description error">' . __('The URL was not recognised as a Radar Events search result. It needs to include the domain and the rest of the /events/search/path like: https://radar.squat.net/en/events/city/City_Name/group/123 Start from <a href="https://radar.squat.net/en/events" target="_blank">https://radar.squat.net/en/events</a> and use the filters in the right hand colunm there before copying the URL from your browser address bar.', 'squat-radar') . '</div>';
}
else {
echo '<div class="description">' . __('Go to <a href="https://radar.squat.net/en/events" target="_blank">https://radar.squat.net/en/events</a> and filter for the events you want to show. Then copy the URL from your address bar into here. It will look similar to: https://radar.squat.net/en/events/city/City_Name/group/123', 'squat-radar') . '</div>';
}
if ( empty($instance['url']['error']) && ! empty( $instance['url']['keys'] ) ) {
echo '<hr>';
echo '<p>' . __('Currently selecting events:', 'squat-radar') . '</p>';
echo '<dl>';
echo '<dt>' . __('Default language', 'squat-radar') . '</dt>';
echo '<dd>' . esc_html($instance['url']['keys']['language']) . '</dd>';
foreach ($instance['url']['keys']['facets'] as $key => $value) {
echo '<dt>' . esc_html($key) . '</dt>';
echo '<dd>' . esc_html($value) . '</dd>';
}
echo '</dl>';
}
// ADVANCED
echo '<hr>';
echo '<fieldset>';
echo '<legend>' . __('Advanced settings', 'squat-radar') . '</legend>';
//
// Fields.
//
$field_id = esc_attr( $this->get_field_id( 'fields' ) );
$field_name = esc_attr( $this->get_field_name( 'fields' ) );
$field_label = esc_attr( 'Fields:', 'squat-radar' );
$field_value = empty( $instance['fields'] ) ? '' : esc_attr( implode( ' ,', $instance['fields'] ) );
$field_class = 'widefat';
echo "<p>";
echo "<label for=\"$field_id\">$field_label</label>";
echo "<input class=\"$field_class\" id=\"$field_id\" name=\"$field_name\" type=\"text\" value=\"$field_value\">";
echo "</p>";
echo '<div class="description">' . __('A list of fields to display. Presently these are API names, hence advanced field. Examples: title, body, topic, category, date_time, image, flyer, tags, offline:map') . '</div>';
//
// Cache expiry.
//
$field_id = esc_attr( $this->get_field_id( 'cache_expire' ) );
$field_name = esc_attr( $this->get_field_name( 'cache_expire' ) );
$field_label = esc_attr( 'Cache length:', 'squat-radar' );
$field_value = empty( $instance['cache_expire'] ) ? 10800 : (int) $instance['cache_expire'];
$field_class = 'widefat';
echo "<p>";
echo "<label for=\"$field_id\">$field_label</label>";
echo "<select class=\"$field_class\" id=\"$field_id\" name=\"$field_name\">";
echo '<option value="3600"' . selected( $field_value, 3600 ) . '>' . __('1 hour') . '</option>';
echo '<option value="10800"' . selected( $field_value, 10800 ) . '>' . __('3 hours') . '</option>';
echo '<option value="43200"' . selected( $field_value, 43200 ) . '>' . __('12 hours') . '</option>';
echo "</select>";
echo "</p>";
echo '<div class="description">' . __('Length of time the cache of events will be kept. Longer faster, but updated less often.') . '</div>';
echo '</fieldset>';
}
public function update( $new_instance, $old_instance ) {
$options = [];
$options['debug'] = $new_instance;
if ( ! empty( $new_instance['title'] ) ) {
$options['title'] = sanitize_text_field( $new_instance['title'] );
}
else {
$options['title'] = '';
}
if ( ! empty($new_instance['url']) ) {
$keys = $this->connector->decode_search_url($new_instance['url']);
$options['url']['keys'] = $keys;
$options['url']['value'] = $new_instance['url'];
if (empty($keys)) {
$options['url']['error'] = 'URL not recognised';
}
}
else {
$options['url'] = ['value' => '', 'keys' => []];
}
if ( ! empty($new_instance['fields']) ) {
$matches = [];
preg_match_all('/([a-zA-Z_:]+)/', $new_instance['fields'], $matches);
$options['fields'] = $matches[0];
}
else {
$options['fields'] = [];
}
if ( ! empty( $new_instance['limit'] ) ) {
$options['limit'] = (int) $new_instance['limit'];
}
if ( ! empty( $new_instance['cache_expire'] ) ) {
$options['cache_expire'] = (int) $new_instance['cache_expire'];
}
else {
$options['cache_expire'] = 10800;
}
return $options;
}
}