5, 'message' => ''], $arguments, 'tsml_next_meetings'); $meetings = tsml_get_meetings([ 'day' => intval(current_time('w')), 'time' => 'upcoming', 'attendance_option' => 'active', ]); if (!count($meetings) && empty($arguments['message'])) { return false; } if (!count($meetings) && !empty($arguments['message'])) { return '
' . sanitize_text_field($arguments['message']) . '
'; } $meetings = array_slice($meetings, 0, $arguments['count']); $rows = ''; foreach ($meetings as $meeting) { $meeting_types = $classes = ''; if (!empty($meeting['types'])) { $classes = tsml_to_css_classes($meeting['types']); $meeting_types = ' ' . tsml_format_types($meeting['types']) . ''; } if (!empty($meeting['notes'])) { $classes .= ' notes'; } $meeting_location = ''; if (!empty($meeting['location'])) { $meeting_location = $meeting['location']; } if ($meeting['attendance_option'] == 'online' || $meeting['attendance_option'] == 'inactive') { $meeting_location = !empty($meeting['group']) ? $meeting['group'] : ''; } $region = ''; if (!empty($meeting['sub_region'])) { $region = $meeting['sub_region']; } elseif (!empty($meeting['region'])) { $region = $meeting['region']; } $rows .= ' ' . tsml_format_time($meeting['time']) . ' ' . @$meeting['name'] . '' . $meeting_types . '
' . $meeting_location . '
' . ($meeting['attendance_option'] != 'in_person' ? $tsml_meeting_attendance_options[$meeting['attendance_option']] : '') . '
' . $region . ' '; } return ' ' . $rows . '
' . __('Time', '12-step-meeting-list') . ' ' . __('Meeting', '12-step-meeting-list') . ' ' . __('Location', '12-step-meeting-list') . ' ' . __('Region', '12-step-meeting-list') . '
'; } add_shortcode('tsml_next_meetings', 'tsml_next_meetings'); // output a list of types with links for AA-DC add_shortcode('tsml_types_list', function () { global $tsml_types_in_use, $tsml_programs, $tsml_program, $tsml_user_interface; $types = []; foreach ($tsml_types_in_use as $type) { if ($tsml_user_interface === 'tsml_ui') { $filter_url = tsml_meetings_url([ 'type' => str_replace(' ', '-', strtolower($tsml_programs[$tsml_program]['types'][$type])) ]); } else { $filter_url = tsml_meetings_url(['tsml-day' => 'any', 'tsml-type' => $type]); } $types[$tsml_programs[$tsml_program]['types'][$type]] = '
  • ' . $tsml_programs[$tsml_program]['types'][$type] . '
  • '; } ksort($types); return '

    Types

    '; }); // output a react meeting finder widget https://github.com/code4recovery/tsml-ui function tsml_ui($arguments = []) { global $tsml_nonce, $tsml_conference_providers, $tsml_language, $tsml_programs, $tsml_program, $tsml_ui_config, $tsml_feedback_addresses, $tsml_cache, $tsml_cache_writable, $tsml_distance_units, $tsml_columns, $tsml_timezone, $tsml_slug, $tsml_map; $defaults = shortcode_atts([ 'distance' => '', 'language' => '', 'mode' => '', 'region' => '', 'search' => '', 'time' => '', 'type' => '', 'view' => '', 'weekday' => '', ], $arguments, 'tsml_ui'); // sanitize arrays foreach (['region', 'time', 'type', 'weekday'] as $key) { $defaults[$key] = explode(',', $defaults[$key]); $defaults[$key] = array_map('sanitize_title', $defaults[$key]); $defaults[$key] = array_filter($defaults[$key]); } // sanitize language $defaults['language'] = sanitize_text_field($defaults['language']); // sanitize search $defaults['search'] = sanitize_text_field($defaults['search']); // view must either be table or map if (!in_array($defaults['view'], ['table', 'map'])) { $defaults['view'] = 'table'; } // mode must either be search, location, or me if (!in_array($defaults['mode'], ['search', 'location', 'me'])) { $defaults['mode'] = 'search'; } // distance must be an integer $defaults['distance'] = intval($defaults['distance']); $defaults['distance'] = in_array($defaults['distance'], [1, 2, 5, 10, 15, 25, 50, 100]) ? strval($defaults['distance']) : ''; if (empty($defaults['distance'])) { unset($defaults['distance']); } // enqueue app script $js = defined('TSML_UI_PATH') ? TSML_UI_PATH : 'https://tsml-ui.code4recovery.org/app.js'; wp_enqueue_script('tsml_ui', $js, [], TSML_VERSION, ['in_footer' => true, 'strategy' => 'async']); // get program types and type descriptions $types = !empty($tsml_programs[$tsml_program]['types']) ? $tsml_programs[$tsml_program]['types'] : []; $type_descriptions = !empty($tsml_programs[$tsml_program]['type_descriptions']) ? $tsml_programs[$tsml_program]['type_descriptions'] : []; // apply settings wp_localize_script( 'tsml_ui', 'tsml_react_config', array_replace_recursive( [ 'columns' => array_keys($tsml_columns), 'defaults' => $defaults, 'conference_providers' => $tsml_conference_providers, 'distance_unit' => $tsml_distance_units, 'feedback_emails' => array_values($tsml_feedback_addresses), 'flags' => $tsml_programs[$tsml_program]['flags'], 'language' => $defaults['language'], 'map' => $tsml_map, 'strings' => [ $tsml_language => array_replace_recursive( $tsml_columns, compact('types', 'type_descriptions'), // Get any existing strings for this language if they exist !empty($tsml_ui_config['strings'][$tsml_language]) ? $tsml_ui_config['strings'][$tsml_language] : [] ), ], ], $tsml_ui_config ) ); // use meetings.json if it's writable, otherwise use the admin-ajax URL to the feed $data = $tsml_cache_writable && file_exists(WP_CONTENT_DIR . $tsml_cache) ? content_url($tsml_cache) . '?' . filemtime(WP_CONTENT_DIR . $tsml_cache) : admin_url('admin-ajax.php') . '?action=meetings&nonce=' . wp_create_nonce($tsml_nonce); // remove URL domain to fix CORS issues caused by GoDaddy Managed WP $url = parse_url($data); $data = $url['path'] . '?' . $url['query']; // pretty permalinks $meeting_finder = parse_url(tsml_meetings_url()); $request_starts_with_meeting_finder_path = substr($_SERVER['REQUEST_URI'], 0, strlen($meeting_finder['path'])) === $meeting_finder['path']; $tsml_path = empty($meeting_finder['query']) && $request_starts_with_meeting_finder_path ? $meeting_finder['path'] : ''; return "
    "; } add_shortcode('tsml_react', 'tsml_ui'); add_shortcode('tsml_ui', 'tsml_ui'); // output a list of regions with links for AA-DC add_shortcode('tsml_regions_list', function () { // run function recursively function get_regions($parent = 0) { global $tsml_user_interface; $taxonomy = 'tsml_region'; // phpcs:ignore $terms = get_terms(compact('taxonomy', 'parent')); if (!count($terms)) { return; } foreach ($terms as &$term) { if ($tsml_user_interface === 'tsml_ui') { $filter_url = tsml_meetings_url(['region' => $term->slug]); } else { $filter_url = tsml_meetings_url( ['tsml-day' => 'any', 'tsml-region' => $term->slug] ); } $term = '
  • ' . $term->name . '' . get_regions($term->term_id) . '
  • '; } return ''; } return '

    Regions

    ' . get_regions(); });