diff --git a/includes/squat-radar-connector.php b/includes/squat-radar-connector.php
index 2183fc0..54e5510 100644
--- a/includes/squat-radar-connector.php
+++ b/includes/squat-radar-connector.php
@@ -57,11 +57,11 @@ class Squat_Radar_Connector {
}
function events( $facets, $fields = [], $language = NULL, $limit = 10, $expiration = 10800, $reset = FALSE ) {
+ $fields = array_merge($fields, ['uuid', 'url']);
$transient_key = 'squat_radar_events_' . sha1(implode($facets) . implode($fields) . $language . $limit);
if (! $reset && $data = get_transient( $transient_key )) {
return $data;
}
-
$query = $this->encode_api_query( $facets, $fields, $language, $limit );
$events = $this->get_events($query);
diff --git a/includes/squat-radar-formatter.php b/includes/squat-radar-formatter.php
index b2ced4f..43e87c1 100644
--- a/includes/squat-radar-formatter.php
+++ b/includes/squat-radar-formatter.php
@@ -2,50 +2,318 @@
class Squat_Radar_Formatter {
- static public function format_event($event, $fields) {
- foreach ($fields as $field) {
- $value = self::getValue($event, explode(':', $field));
- }
+ static public function register() {
+ // Filter to go through fields and then call filters to turn these into HTML.
+ add_filter('squat_radar_format_event', [__CLASS__, 'format_event'], 10, 3);
+
+ // Filters to turn each individual field into HTML.
+ //
+ // $value is the data from the field and can be an array or string.
+ // These filters extract data from arrays based on the field structure.
+ add_filter('squat_radar_field_html', [__CLASS__, 'field_date_html'], 5, 4);
+ add_filter('squat_radar_field_html', [__CLASS__, 'field_location_html'], 5, 4);
+ add_filter('squat_radar_field_html', [__CLASS__, 'field_link_html'], 5, 4);
+ // field 'url' was turned into a more link, example of an override with more specificity.
+ add_filter('squat_radar_field_html', [__CLASS__, 'field_image_html'], 7, 4);
+ // If $value is an array it is flattened into a string here.
+ // If $value != $original it will _not_ be sanitized, assumption is that it has been already.
+ add_filter('squat_radar_field_html', [__CLASS__, 'field_html'], 10, 4);
+ // $value is always a string. These filters just add additional wrapper markup.
+ add_filter('squat_radar_field_html', [__CLASS__, 'field_title_html'], 15, 4);
}
+ static public function format_event($event, $fields, $context) {
+
+ $context['event'] = $event;
+ $output = [];
+ $output[] = '
';
+ foreach ($fields as $field) {
+ $field_tree = explode(':', $field);
+ $value = self::getValue($event, $field_tree);
+ $field_tree = array_reverse($field_tree);
+ $output[] = apply_filters('squat_radar_field_html', $value, $value, $field_tree, $context);
+ }
+ $output[] = '
';
+ return $output;
+
+ }
+
+ /**
+ * Date field formatting implementation of 'squat_radar_field_html' filter.
+ */
+ static public function field_date_html($value, $original, $field, $context) {
+
+ switch ($field[0]) {
+ case 'created':
+ case 'updated':
+ $output = '';
+ if ($value) {
+ $output = date_i18n( get_option( 'date_format' ), $value );
+ $placeholder = ($field[0] == 'created') ? __('Created: %s', 'squat-radar') : __('Updated: %s', 'squat-radar');
+ $output = '' . sprintf($placeholder, $output) . '';
+ }
+ return $output;
+
+ // "date_time": [
+ // {
+ // "value": "1556442000",
+ // "value2": "1556442000",
+ // "duration": 0,
+ // "time_start": "2019-04-28T11:00:00+02:00",
+ // "time_end": "2019-04-28T11:00:00+02:00",
+ // "rrule": null
+ // }
+ // ],
+ case 'date_time':
+
+ $output = '';
+ // There can only be one date. With repeat etc. but just one.
+ // Repeating events will appear as a new item for each repeat in the feed.
+ $value = $value[0];
+ $output = '';
+ $output .= self::field_date_format($value['time_start'], 'start');
+ if ($value['time_start'] != $value['time_end']) {
+ $output .= self::field_date_format($value['time_end'], 'end');
+ }
+ $output .= '';
+ return $output;
+
+ case 'time_start':
+
+ $output = '';
+ $output .= self::field_date_format($value, 'start');
+ $output .= '';
+ return $output;
+
+ case 'time_end':
+
+ $output = '';
+ $output .= self::field_date_format($value, 'start');
+ $output .= '';
+ return $output;
+
+ }
+
+ return $value;
+ }
+
+ private static function field_date_format($time, $start_end) {
+
+ $date_format = get_option('squat_radar_date_format', 'j M Y');
+ $time_format = get_option('squat_radar_time_format', 'H:i');
+
+ $output = '';
+ $output .= '';
+ $output .= date_i18n($date_format, strtotime($time));
+ $output .= ' ';
+ $output .= date_i18n($time_format, strtotime($time));
+ $output .= '';
+
+ return $output;
+ }
+
+ /**
+ * Location field implementation of 'squat_radar_field_html' filter.
+ *
+ * "offline": [
+ * {
+ * "uri": "https://radar.squat.net/api/1.2/location/b5786379-da49-4026-8c4e-bcc1a1563284",
+ * "id": "b5786379-da49-4026-8c4e-bcc1a1563284",
+ * "resource": "location",
+ * "title": "Yorck-Kino Yorckstr. 86 Berlin Deutschland",
+ * "map": {
+ * "geom": "POINT (13.3853499 52.4930248)",
+ * "geo_type": "point",
+ * "lat": "52.493024800000",
+ * "lon": "13.385349900000",
+ * "left": "13.385349900000",
+ * "top": "52.493024800000",
+ * "right": "13.385349900000",
+ * "bottom": "52.493024800000",
+ * "srid": null,
+ * "latlon": "52.493024800000,13.385349900000",
+ * "schemaorg_shape": ""
+ * }
+ * }
+ * ]
+ */
+ function field_location_html($value, $original, $field, $context) {
+ switch ($field[0]) {
+ case 'map':
+ $output = [];
+ foreach ($value as $map) {
+ if ( is_array($value) && $value['lat'] !== NULL && $value['lon'] !== NULL ) {
+ $this_output = '';
+ $lat = $value['lat'];
+ $lon = $value['lon'];
+ $this_output .= "";
+ $this_output .= __('[Map]', 'squat-radar');
+ $this_output .= '';
+ $output[] = $this_output;
+ }
+ }
+ return implode(', ', $output);
+
+ case 'address':
+ $output = [];
+ foreach ($value as $address) {
+ if ( is_array($value) ) {
+ $this_address = [];
+ foreach (['name_line', 'thoroughfare', 'locality', 'postal_code', 'country'] as $field_name) {
+ if (! empty($value[$field_name])) {
+ $this_line = '';
+ $this_line .= sanitize_text_field($value[$field_name]);
+ $this_line .= '';
+ $this_address[] = $this_line;
+ }
+ }
+
+ $this_output = '';
+ $this_output .= implode(' ,', $this_address);
+ $this_output .= '';
+ $output[] = $this_output;
+ }
+ }
+ return implode('; ', $output);
+ }
+
+ return $value;
+ }
+
+ /**
+ * Item Radar links implementation of 'squat_radar_field_html' filter.
+ */
+ function field_link_html($value, $original, $field, $context) {
+ if ($field[0] == 'title' && ! empty($context['event']['url'])) {
+ return '' . sanitize_text_field( $value ) . '';
+ }
+
+ if ($field[0] == 'url' && count($field) == 1) {
+ return '' . __('moreā¦', 'squat-radar') . '';
+ }
+
+ if ($field[0] == 'url') {
+ array_shift($field);
+ $field_tree = array_reverse($field);
+ $sibling_fields = self::getValue($event, $field_tree);
+ $title = esc_url($value);
+ $class = 'squat-radar-url-link';
+ if (! empty($sibling_fields['title']) ) {
+ $title = sanitize_text_field( $sibling_fields['title']);
+ $class = 'squat-radar-url-title';
+ }
+ elseif ( ! empty($sibling_fields['name']) ) {
+ $title = sanitize_text_field( $sibling_fields['name']);
+ $class = 'squat-radar-url-name';
+ }
+ return '' . $title . '';
+ }
+
+ if ($field[0] == 'link') {
+ return '' . esc_url($value['url']) . '';
+ }
+
+ return $value;
+ }
+
+ /**
+ * Format image implementation of 'squat_radar_field_html' filter.
+ *
+ * Deliberatly run after field_link_html. Showing how to override an existing filter.
+ * image:file:url
+ */
+ function field_image_html($value, $original, $field, $context) {
+ if ($field[0] == 'url' && $field[1] == 'file' && $field[2] == 'image') {
+ return '';
+ }
+
+ return $value;
+ }
+
+ /**
+ * Basic implementation of 'squat_radar_field_html' filter.
+ *
+ * Put the output into HTML.
+ *
+ * @param array|string $value
+ * The field value being manipulated to become HTML to be displayed.
+ * @param array|string $original
+ * The original value of the field before any changes by filters.
+ * @param array $field
+ * The field tree. $field[0] being the name of the present field. $field[1]
+ * being any parent etc.
+ * @param array $context
+ *
+ * @return string
+ * Flattend array with additional default classes.
+ */
+ function field_html($value, $original, $field, $context) {
+ if ($value != $original) {
+ return $value;
+ }
+
+ if (is_array($value)) {
+ if ( ! empty($value['value']) ) {
+ $value = $value['value'];
+ }
+ elseif ( ! empty($value['title']) ) {
+ $value = $value['title'];
+ }
+ elseif ( ! empty($value['name']) ) {
+ $value = $value['name'];
+ }
+ elseif ( ! empty($value[0]['value']) ) {
+ foreach ($value as $row) {
+ $values[] = $row['value'];
+ }
+ $value = $values;
+ }
+ elseif ( ! empty($value[0]['title']) ) {
+ foreach ($value as $row) {
+ $titles[] = $row['title'];
+ }
+ $value = $titles;
+ }
+ elseif ( ! empty($value[0]['name']) ) {
+ foreach ($value as $row) {
+ $names[] = $row['name'];
+ }
+ $value = $names;
+ }
+ }
+
+ if (is_array($value)) {
+ $output = '';
+ foreach ($value as $row) {
+ $output .= '- ' . sanitize_text_field( $row ) . '
';
+ }
+ $output .= '
';
+
+ return $output;
+ }
+ else {
+ $value = '' . $value . '';
+ }
+
+ return $value;
+ }
+
+ /**
+ * Title field HTML implentation of 'squat_radar_field_html' filter.
+ */
+ function field_title_html($value, $original, $field, $context) {
+ if ($field[0] == 'title' && count($field) == 1) {
+ $value = '' . $value . '
';
+ }
+
+ return $value;
+ }
+
/**
* Retrieves a value from a nested array with variable depth.
*
- * This helper function should be used when the depth of the array element
- * being retrieved may vary (that is, the number of parent keys is variable).
- * It is primarily used for form structures and renderable arrays.
- *
- * Without this helper function the only way to get a nested array value with
- * variable depth in one line would be using eval(), which should be avoided:
- * @code
- * // Do not do this! Avoid eval().
- * // May also throw a PHP notice, if the variable array keys do not exist.
- * eval('$value = $array[\'' . implode("']['", $parents) . "'];");
- * @endcode
- *
- * Instead, use this helper function:
- * @code
- * $value = NestedArray::getValue($form, $parents);
- * @endcode
- *
- * A return value of NULL is ambiguous, and can mean either that the requested
- * key does not exist, or that the actual value is NULL. If it is required to
- * know whether the nested array key actually exists, pass a third argument
- * that is altered by reference:
- * @code
- * $key_exists = NULL;
- * $value = NestedArray::getValue($form, $parents, $key_exists);
- * if ($key_exists) {
- * // Do something with $value.
- * }
- * @endcode
- *
- * However if the number of array parent keys is static, the value should
- * always be retrieved directly rather than calling this function.
- * For instance:
- * @code
- * $value = $form['signature_settings']['signature'];
- * @endcode
+ * Handles on level of multiple[] values on a key.
+ * It will work for deeper multiples, but return the top match.
*
* @param array $array
* The array from which to get the value.
@@ -61,15 +329,28 @@ class Squat_Radar_Formatter {
* Boolean that indicates whether all nested parent keys exist (TRUE) or not
* (FALSE). This allows to distinguish between the two possibilities when
* NULL is returned.
- *
- * @author drupal.org contributors
*/
public static function &getValue(array &$array, array $parents, &$key_exists = NULL) {
$ref =& $array;
- foreach ($parents as $parent) {
+ while ($parent = array_shift($parents)) {
if (is_array($ref) && array_key_exists($parent, $ref)) {
$ref =& $ref[$parent];
}
+ elseif (is_array($ref) && isset($ref[0])) {
+ $multiple = [];
+ array_unshift($parents, $parent);
+ foreach ($ref as &$value) {
+ $multiple[] = self::getValue($value, $parents, $key_exists);
+ }
+ if (!empty($multiple) ) {
+ return $multiple;
+ }
+ else {
+ $key_exists = FALSE;
+ $null = NULL;
+ return $null;
+ }
+ }
else {
$key_exists = FALSE;
$null = NULL;
diff --git a/includes/squat-radar-widget.php b/includes/squat-radar-widget.php
index 17d7c69..6d8657b 100644
--- a/includes/squat-radar-widget.php
+++ b/includes/squat-radar-widget.php
@@ -76,46 +76,12 @@ class Squat_Radar_Widget extends WP_Widget {
$html = '';
foreach ($data['result'] as $id => $event) {
- $html .= Squat_Radar_Formatter::format_event($event);
+ $output = apply_filters( 'squat_radar_format_event', $event, $instance['fields'], ['instance' => $instance] );
+ $html .= implode($output);
}
$data['html'] = $html;
wp_send_json($data);
-
- $print.="";
-
- if ($r->title) {
- $print.="";
- $print.=strip_tags($r->title);
- $print.="
";
- }
-
- if ($r->date_time[0]) {
- $print.="";
- $print.=verwerk_datum($r->date_time[0]);
- $print.="";
- }
-
- if ($r->body and $r->body->value) {
- $print.="".limit_text(strip_tags($r->body->value), 40) . "
";
- }
-
- if ($r->title and $r->date_time[0]) {
-
- $radar_link = "https://radar.squat.net/en/node/$r_id";
-
- if ( $squat_lang == "nl") {
- $nog_meer = "zie alles";
- $meer = "meer";
- } else {
- $nog_meer = "see all";
- $meer = "more";
- }
-
- $print.= "$meer";
- }
-
- $print.="";
}
public function form( $instance ) {
@@ -179,7 +145,7 @@ class Squat_Radar_Widget extends WP_Widget {
echo '' . __('Go to
https://radar.squat.net/en/events 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') . '
';
}
- if ( ! $instance['url']['error'] && ! empty( $instance['url']['keys'] ) ) {
+ if ( empty($instance['url']['error']) && ! empty( $instance['url']['keys'] ) ) {
echo '
';
echo '' . __('Currently selecting events:', 'squat-radar') . '
';
echo '';
@@ -259,7 +225,7 @@ class Squat_Radar_Widget extends WP_Widget {
if ( ! empty($new_instance['fields']) ) {
$matches = [];
- preg_match_all('/([a-zA-Z:]+)/', $new_instance['fields'], $matches);
+ preg_match_all('/([a-zA-Z_:]+)/', $new_instance['fields'], $matches);
$options['fields'] = $matches[0];
}
else {