$type, 'style' => $style, 'sessions' => self::sessions(isset($data['sessions']) && is_array($data['sessions']) ? $data['sessions'] : []), 'statuses' => self::statuses($data['statuses'] ?? []), 'date_range' => self::dateRange(isset($data['date_range']) && is_array($data['date_range']) ? $data['date_range'] : []), 'filters' => self::filters(isset($data['filters']) && is_array($data['filters']) ? $data['filters'] : []), 'display' => self::display(isset($data['display']) && is_array($data['display']) ? $data['display'] : []), 'pagination' => self::pagination(isset($data['pagination']) && is_array($data['pagination']) ? $data['pagination'] : []), 'link' => self::link(isset($data['link']) && is_array($data['link']) ? $data['link'] : []), 'date_format' => self::dateFormat(isset($data['date_format']) && is_array($data['date_format']) ? $data['date_format'] : []), ]; } /** * @return mixed[] */ public static function get(int $view_id): array { $config = get_post_meta($view_id, self::META, true); if (!is_array($config)) $config = []; return self::normalize($config); } /** * @param mixed[] $data * @return mixed[] */ private static function sessions(array $data): array { $modes = Registry::sessionModes(); $mode = sanitize_key((string) ($data['mode'] ?? 'all')); if (!isset($modes[$mode])) $mode = 'all'; return ['mode' => $mode]; } /** * @param mixed $statuses * @return string[] */ private static function statuses($statuses): array { $allowed = array_keys(Registry::statuses()); if (!is_array($statuses)) $statuses = []; $statuses = array_values(array_intersect(array_map('sanitize_key', $statuses), $allowed)); return count($statuses) ? $statuses : ['upcoming', 'ongoing']; } /** * @param mixed[] $data * @return mixed[] */ private static function dateRange(array $data): array { return [ 'start' => self::dateRangeBoundary(isset($data['start']) && is_array($data['start']) ? $data['start'] : []), 'end' => self::dateRangeBoundary(isset($data['end']) && is_array($data['end']) ? $data['end'] : []), ]; } /** * @param mixed[] $data * @return mixed[] */ private static function dateRangeBoundary(array $data): array { $modes = Registry::dateRangeModes(); $directions = Registry::dateRangeDirections(); $units = Registry::dateRangeUnits(); $mode = sanitize_key((string) ($data['mode'] ?? 'none')); if (!isset($modes[$mode])) $mode = 'none'; $direction = sanitize_key((string) ($data['direction'] ?? 'future')); if (!isset($directions[$direction])) $direction = 'future'; $unit = sanitize_key((string) ($data['unit'] ?? 'days')); if (!isset($units[$unit])) $unit = 'days'; $date = sanitize_text_field((string) ($data['date'] ?? '')); if ($date !== '' && !preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) $date = ''; return [ 'mode' => $mode, 'date' => $date, 'amount' => max(0, min(10000, absint($data['amount'] ?? 0))), 'direction' => $direction, 'unit' => $unit, ]; } /** * @param mixed[] $data * @return mixed[] */ private static function filters(array $data): array { return [ 'taxonomies' => self::taxonomyFilters(isset($data['taxonomies']) && is_array($data['taxonomies']) ? $data['taxonomies'] : []), 'users' => [ 'include' => self::ids($data['users']['include'] ?? []), 'exclude' => self::ids($data['users']['exclude'] ?? []), ], 'repeat_types' => [ 'include' => self::repeatTypes($data['repeat_types']['include'] ?? []), 'exclude' => self::repeatTypes($data['repeat_types']['exclude'] ?? []), ], 'custom_fields' => self::customFieldFilters(isset($data['custom_fields']) && is_array($data['custom_fields']) ? $data['custom_fields'] : []), ]; } /** * @param mixed[] $data * @return mixed[] */ private static function taxonomyFilters(array $data): array { $filters = []; foreach ($data as $taxonomy => $filter) { $taxonomy = sanitize_key((string) $taxonomy); if (!taxonomy_exists($taxonomy) || !is_array($filter)) continue; $filters[$taxonomy] = [ 'include' => self::ids($filter['include'] ?? []), 'exclude' => self::ids($filter['exclude'] ?? []), ]; } return $filters; } /** * @param mixed $value * @return int[] */ private static function ids($value): array { if (!is_array($value)) $value = []; return array_values(array_unique(array_filter(array_map('absint', $value)))); } /** * @param mixed $value * @return string[] */ private static function repeatTypes($value): array { if (!is_array($value)) $value = []; $allowed = array_keys(Registry::repeatTypes()); return array_values(array_intersect(array_map('sanitize_key', $value), $allowed)); } /** * @param mixed[] $data * @return mixed[] */ private static function customFieldFilters(array $data): array { $filters = []; foreach ($data as $field_id => $filter) { if (!is_array($filter)) continue; $field_id = sanitize_key((string) $field_id); $type = sanitize_key((string) ($filter['type'] ?? 'text')); $operator = sanitize_key((string) ($filter['operator'] ?? '')); $item = [ 'type' => $type, 'operator' => $operator, 'value' => sanitize_text_field((string) ($filter['value'] ?? '')), 'min' => sanitize_text_field((string) ($filter['min'] ?? '')), 'max' => sanitize_text_field((string) ($filter['max'] ?? '')), 'values' => [], ]; if (isset($filter['values']) && is_array($filter['values'])) { $item['values'] = self::strings($filter['values']); } $has_filter = $item['value'] !== '' || $item['min'] !== '' || $item['max'] !== '' || count($item['values']); if ($has_filter) { $filters[$field_id] = $item; } } return $filters; } /** * @param mixed $value * @return string[] */ private static function strings($value): array { if (!is_array($value)) return []; $strings = array_map('sanitize_text_field', $value); return array_values(array_unique(array_filter($strings, static function (string $string): bool { return $string !== ''; }))); } /** * @param mixed[] $data * @return mixed[] */ private static function display(array $data): array { $defaults = Registry::displayOptions(); $common_defaults = isset($defaults['common']) && is_array($defaults['common']) ? $defaults['common'] : []; $common_data = isset($data['common']) && is_array($data['common']) ? $data['common'] : []; $list_data = isset($data['list']) && is_array($data['list']) ? $data['list'] : []; $grid_data = isset($data['grid']) && is_array($data['grid']) ? $data['grid'] : []; $calendar_data = isset($data['full_calendar']) && is_array($data['full_calendar']) ? $data['full_calendar'] : []; $display = [ 'common' => [], 'list' => [], 'grid' => [], 'full_calendar' => [], ]; foreach ($common_defaults as $key => $default) { $display['common'][$key] = Arr::truthy($common_data, $key) ? 1 : 0; if (!isset($common_data[$key])) $display['common'][$key] = $default ? 1 : 0; } $list_image_position = $list_data['image_position'] ?? 'left'; $display['list'] = [ 'image_position' => in_array($list_image_position, ['left', 'right', 'top'], true) ? $list_image_position : 'left', 'excerpt_length' => max(0, min(120, absint($list_data['excerpt_length'] ?? ($defaults['list']['excerpt_length'] ?? 24)))), ]; $display['grid'] = [ 'columns' => max(1, min(6, absint($grid_data['columns'] ?? ($defaults['grid']['columns'] ?? 3)))), 'image_ratio' => sanitize_text_field((string) ($grid_data['image_ratio'] ?? ($defaults['grid']['image_ratio'] ?? '16/9'))), 'excerpt_length' => max(0, min(120, absint($grid_data['excerpt_length'] ?? ($defaults['grid']['excerpt_length'] ?? 18)))), ]; $calendar_views = array_keys(Registry::calendarViews()); $enabled_views = isset($calendar_data['enabled_views']) && is_array($calendar_data['enabled_views']) ? array_values(array_intersect($calendar_data['enabled_views'], $calendar_views)) : ($defaults['full_calendar']['enabled_views'] ?? $calendar_views); if (!count($enabled_views)) $enabled_views = ['dayGridMonth']; $default_view = sanitize_text_field((string) ($calendar_data['default_view'] ?? ($defaults['full_calendar']['default_view'] ?? 'dayGridMonth'))); if (!in_array($default_view, $enabled_views, true)) $default_view = $enabled_views[0]; $display['full_calendar'] = [ 'default_view' => $default_view, 'enabled_views' => $enabled_views, 'show_session_time' => isset($calendar_data['show_session_time']) ? (Arr::truthy($calendar_data, 'show_session_time') ? 1 : 0) : (!empty($defaults['full_calendar']['show_session_time']) ? 1 : 0), 'height' => sanitize_text_field((string) ($calendar_data['height'] ?? '')), 'aspect_ratio' => sanitize_text_field((string) ($calendar_data['aspect_ratio'] ?? ($defaults['full_calendar']['aspect_ratio'] ?? '1.35'))), ]; return $display; } /** * @param mixed[] $data * @return mixed[] */ private static function pagination(array $data): array { $methods = Registry::paginationMethods(); $method = sanitize_key((string) ($data['method'] ?? 'load_more')); if (!isset($methods[$method])) $method = 'load_more'; return [ 'method' => $method, 'per_page' => max(1, min(100, absint($data['per_page'] ?? 12))), ]; } /** * @param mixed[] $data * @return mixed[] */ private static function link(array $data): array { $methods = Registry::linkMethods(); $target = sanitize_key((string) ($data['target'] ?? 'same')); if (!isset($methods[$target])) $target = 'same'; return ['target' => $target]; } /** * @param mixed[] $data * @return mixed[] */ private static function dateFormat(array $data): array { $mode = (string) ($data['mode'] ?? 'inherit'); $mode = $mode === 'custom' ? 'custom' : 'inherit'; return [ 'mode' => $mode, 'date' => sanitize_text_field((string) ($data['date'] ?? '')), 'time' => sanitize_text_field((string) ($data['time'] ?? '')), 'range' => [ 'hour' => sanitize_text_field((string) ($data['range']['hour'] ?? '')), 'day' => sanitize_text_field((string) ($data['range']['day'] ?? '')), 'month' => sanitize_text_field((string) ($data['range']['month'] ?? '')), 'year' => sanitize_text_field((string) ($data['range']['year'] ?? '')), 'other' => sanitize_text_field((string) ($data['range']['other'] ?? '')), ], ]; } /** * @param mixed[] $config */ public static function dateSettings(array $config, GeneralSettings $settings): GeneralSettings { $date_format = isset($config['date_format']) && is_array($config['date_format']) ? $config['date_format'] : []; if (($date_format['mode'] ?? 'inherit') !== 'custom') return $settings; $data = []; if (!empty($date_format['date'])) $data['date_format'] = (string) $date_format['date']; if (!empty($date_format['time'])) $data['time_format'] = (string) $date_format['time']; if (isset($date_format['range']) && is_array($date_format['range'])) { $range = []; foreach (['hour', 'day', 'month', 'year', 'other'] as $key) { if (!empty($date_format['range'][$key])) $range[$key] = (string) $date_format['range'][$key]; } if (count($range)) $data['range_format'] = array_merge($settings->rangeFormat(), $range); } return $settings->merge($data); } }