diff --git a/.github/workflows/pull-requests.yml b/.github/workflows/pull-requests.yml index 20f8d809..86e9e4d1 100644 --- a/.github/workflows/pull-requests.yml +++ b/.github/workflows/pull-requests.yml @@ -30,11 +30,10 @@ jobs: echo "ZIP_FILENAME=${ZIP_FILENAME}" >> $GITHUB_ENV PROD=1 make build unzip "${BUILD_DIR}/${ZIP_FILENAME}" -d "./bread" - - - name: Run plugin check - uses: wordpress/plugin-check-action@v1 - with: - build-dir: "./bread" - exclude-directories: 'vendor' - categories: 'plugin_repo' - ignore-warnings: true +# Removed until https://github.com/WordPress/plugin-check-action/issues/579 is fixed +# - name: Run plugin check +# uses: wordpress/plugin-check-action@v1 +# with: +# exclude-directories: 'vendor' +# categories: 'plugin_repo' +# ignore-warnings: true diff --git a/admin/class-bread-admin.php b/admin/class-bread-admin.php index 7b91b6a2..dc20d101 100644 --- a/admin/class-bread-admin.php +++ b/admin/class-bread-admin.php @@ -74,11 +74,9 @@ public function enqueue_styles($hook) wp_enqueue_style("tooltipster", plugin_dir_url(__FILE__) . "css/tooltipster.bundle.min.css", false, BREAD_VERSION, 'all'); wp_enqueue_style("tooltipster-noir", plugin_dir_url(__FILE__) . "css/tooltipster-sideTip-noir.min.css", false, BREAD_VERSION, 'all'); wp_enqueue_style("admin", plugin_dir_url(__FILE__) . "css/admin.css", false, BREAD_VERSION, 'all'); - wp_enqueue_style("bread-fonts", plugin_dir_url(__FILE__) . "css/admin-fonts.css", false, BREAD_VERSION, 'all'); wp_enqueue_style("select2", plugin_dir_url(__FILE__) . "css/select2.min.css", false, BREAD_VERSION, 'all'); wp_enqueue_style("smartWizard-dots", plugin_dir_url(__FILE__) . "css/smart_wizard_dots.css", false, BREAD_VERSION, 'all'); } - /** * Register the JavaScript for the admin area. * @@ -97,6 +95,7 @@ public function enqueue_scripts($hook) wp_enqueue_script("tooltipster", plugin_dir_url(__FILE__) . "js/tooltipster.bundle.min.js", array('jquery'), "1.2", true); wp_enqueue_script("spectrum", plugin_dir_url(__FILE__) . "js/spectrum.min.js", array('jquery'), "1.2", true); wp_enqueue_script("select2", plugin_dir_url(__FILE__) . "js/select2.min.js", array('jquery'), "1.2", true); + wp_enqueue_script("dayjs", plugin_dir_url(__FILE__) . "js/dayjs.min.js", array('jquery'), "1.2", true); wp_enqueue_script("fetch-jsonp", plugin_dir_url(__FILE__) . "js/fetch-jsonp.js", array('jquery'), "1.30", true); wp_enqueue_script("smartWizard", plugin_dir_url(__FILE__) . "js/jquery.smartWizard.js", array('jquery'), "6.0.6", true); wp_enqueue_script("breadWizard", plugin_dir_url(__FILE__) . "js/bread-wizard.js", array('smartWizard'), BREAD_VERSION, true); @@ -204,46 +203,23 @@ function tiny_tweaks($initArray) { if (function_exists('get_current_screen')) { $screen = get_current_screen(); + $fonts = apply_filters('bread_custom_fonts', $this->bread->fonts); if ($screen != null && str_ends_with($screen->id, $this->bmltEnabled_admin->getSlug())) { $initArray['fontsize_formats'] = "5pt 6pt 7pt 8pt 9pt 10pt 11pt 12pt 13pt 14pt 15pt 16pt 17pt 18pt 19pt 20pt 22pt 24pt 26pt 28pt 30pt 32pt 34pt 36pt 38pt"; $initArray['theme_advanced_blockformats'] = 'h2,h3,h4,p'; $initArray['wordpress_adv_hidden'] = false; - $initArray['font_formats'] = 'Arial (Sans-Serif)=arial;'; - $initArray['font_formats'] .= 'Times (Sans-Serif)=times;'; - $initArray['font_formats'] .= 'Courier (Monospace)=courier;'; - $initArray['font_formats'] .= 'DejaVu (Sans-Serif)=DejaVuSansCondensed;'; + $initArray['font_formats'] = ''; + foreach ($fonts as $font_key => $font_name) { + $initArray['font_formats'] .= "$font_name=$font_key;"; + } $dir = plugin_dir_url(__FILE__); $font = $this->bread->getOption('base_font'); - if ($font == 'dejavusanscondensed') { - $initArray['content_style'] = "@import url('$dir/css/fonts.css'); body { font-family: DejaVuSansCondensed; }"; - } elseif ($font == 'times') { - $initArray['content_style'] = "@import url('$dir/css/fonts.css'); body { font-family: Times; }"; - } elseif ($font == 'courier') { - $initArray['content_style'] = "@import url('$dir/css/fonts.css'); body { font-family: Courier; }"; - } else { - $initArray['content_style'] = "@import url('$dir/css/fonts.css'); body { font-family: Arial; }"; - } - //$initArray['content_style'] = "body { font-family: Arial; }"; + $initArray['content_style'] = apply_filters('bread_content_style', "@import url('$dir/css/fonts.css');"); + $initArray['content_style'] .= "body { font-family: $font; }"; } } return $initArray; } - function is_root_server_missing() - { - if (!function_exists('get_current_screen')) { - return; - } - $screen = get_current_screen(); - if ($screen != null && str_ends_with($screen->id, $this->bmltEnabled_admin->getSlug())) { - $root_server = $this->bread->getOption('root_server'); - if ($root_server == '') { - echo '

Missing BMLT Server in settings for bread.

'; - $url = admin_url('options-general.php?page=class-bread-admin.php'); - echo "

Settings

"; - echo '
'; - } - } - } function pwsix_process_rename_settings() { @@ -421,36 +397,6 @@ function save_admin_options() { $this->bread->updateOptions(); } - public function getLatestRootVersion() - { - $results = $this->get("https://api.github.com/repos/bmlt-enabled/bmlt-root-server/releases/latest"); - $httpcode = wp_remote_retrieve_response_code($results); - $response_message = wp_remote_retrieve_response_message($results); - if ($httpcode != 200 && $httpcode != 302 && $httpcode != 304 && ! empty($response_message)) { - return 'Problem Connecting to Server!'; - }; - $body = wp_remote_retrieve_body($results); - $result = json_decode($body, true); - return $result['name']; - } - function get($url, $cookies = array()) - { - $args = array( - 'timeout' => '120', - 'cookies' => $cookies, - ); - if (isset($this->options['user_agent']) - && $this->bread->getOption('user_agent') != 'None' - ) { - $args['headers'] = array( - 'User-Agent' => $this->bread->getOption('user_agent') - ); - } - if ($this->bread->getOption('sslverify') == '1') { - $args['sslverify'] = false; - } - return wp_remote_get($url, $args); - } /** * @desc Adds the options sub-panel */ @@ -521,9 +467,9 @@ function pwsix_process_wizard() $settings['page_size'] = $layoutInfos[1]; $settings['authors'] = array(); $settings['root_server'] = sanitize_url($_POST['wizard_root_server']); + $settings['service_bodies'] = []; for ($i = 0; $i < count($_POST['wizard_service_bodies']); $i++) { - $j = $i + 1; - $settings['service_body_' . $j] = sanitize_text_field($_POST['wizard_service_bodies'][$i]); + $settings['service_bodies'][] = sanitize_text_field($_POST['wizard_service_bodies'][$i]); } $settings['used_format_1'] = intval($_POST['wizard_format_filter']); $settings['weekday_language'] = sanitize_key($_POST['wizard_language']); @@ -675,7 +621,7 @@ function process_customize_form() isset($_POST['pagenumbering_font_size']) ? floatval($_POST['pagenumbering_font_size']) : '9' ); - $this->bread->setOption('used_format_1', sanitize_text_field($_POST['used_format_1'])); + $this->bread->setOption('used_format_1', isset($_POST['used_format_1']) ? sanitize_text_field($_POST['used_format_1']) : ''); $this->bread->setOption('recurse_service_bodies', isset($_POST['recurse_service_bodies']) ? 1 : 0); $this->bread->setOption('extra_meetings_enabled', isset($_POST['extra_meetings_enabled']) ? intval($_POST['extra_meetings_enabled']) : 0); $this->bread->setOption('include_protection', boolval($_POST['include_protection'])); @@ -709,11 +655,7 @@ function process_customize_form() $this->bread->setOption('remove_space', boolval($_POST['remove_space'])); $this->bread->setOption('content_line_height', floatval($_POST['content_line_height'])); $this->bread->setOption('root_server', sanitize_url($_POST['root_server'])); - $this->bread->setOption('service_body_1', sanitize_text_field($_POST['service_body_1'])); - $this->bread->setOption('service_body_2', sanitize_text_field($_POST['service_body_2'])); - $this->bread->setOption('service_body_3', sanitize_text_field($_POST['service_body_3'])); - $this->bread->setOption('service_body_4', sanitize_text_field($_POST['service_body_4'])); - $this->bread->setOption('service_body_5', sanitize_text_field($_POST['service_body_5'])); + $this->bread->setOption('service_bodies', isset($_POST['service_bodies']) ? array_map('sanitize_text_field', $_POST['service_bodies']) : array()); $this->bread->setOption('cache_time', intval($_POST['cache_time'])); $this->bread->setOption('custom_query', sanitize_text_field($_POST['custom_query'])); $this->bread->setOption('additional_list_custom_query', sanitize_text_field($_POST['additional_list_custom_query'])); diff --git a/admin/css/admin-fonts.css b/admin/css/admin-fonts.css deleted file mode 100644 index 93686b8f..00000000 --- a/admin/css/admin-fonts.css +++ /dev/null @@ -1,24 +0,0 @@ -@font-face { - font-family:'DejaVuSansCondensed'; - src:url(../../vendor/mpdf/mpdf/ttfonts/DejaVuSansCondensed.ttf) format('truetype'); - font-display: block; -} -@font-face { - font-family:'DejaVuSansCondensed'; - src:url(../../vendor/mpdf/mpdf/ttfonts/DejaVuSansCondensed-Bold.ttf) format('truetype'); - font-display: block; - font-weight: bold; -} -@font-face { - font-family:'DejaVuSansCondensed'; - src:url(../../vendor/mpdf/mpdf/ttfonts/DejaVuSansCondensed-BoldOblique.ttf) format('truetype'); - font-display: block; - font-weight: bold; - font-style: italic; -} -@font-face { - font-family:'DejaVuSansCondensed'; - src:url(../../vendor/mpdf/mpdf/ttfonts/DejaVuSansCondensed-Oblique.ttf) format('truetype'); - font-display: block; - font-style: italic; -} \ No newline at end of file diff --git a/admin/css/admin.css b/admin/css/admin.css index 42069cb1..375ce0bf 100644 --- a/admin/css/admin.css +++ b/admin/css/admin.css @@ -556,4 +556,4 @@ select.bread_service_body_select { .nav-tab-wrapper { width: max-content !important; } -.select2-search--inline { display: contents; } .select2-search__field:placeholder-shown { width: 100% !important; } \ No newline at end of file +.select2-search--inline { display: contents; } \ No newline at end of file diff --git a/admin/js/bmlt_meeting_list.js b/admin/js/bmlt_meeting_list.js index af2a46da..50cec5e6 100644 --- a/admin/js/bmlt_meeting_list.js +++ b/admin/js/bmlt_meeting_list.js @@ -1,354 +1,599 @@ -var $ml = jQuery.noConflict -jQuery(document).ready( - function($ml) { - $ml(".connecting").hide(); - $ml(".saving").hide(); - $ml(".bmlt-accordion").accordion( - { - heightStyle: "content", - active: false, - collapsible: true - } - ); - $ml(".bmlt_color").spectrum({preferredFormat: 'hex', showInput: true, showPalette: false}); - $ml("#col_color").on("click", () => $ml("#triggerSet").spectrum("set", this.val())); - $ml("#bmlt_meeting_list_options").on( - "keypress", function(event) { - if(event.which == 13 && !event.shiftKey) { - event.preventDefault(); - return false; - } - } - ); - $ml(".gears-working").click( - function(e) { - $ml(".saving").show(); - } - ); - $ml('input[name="submit_import_file"]').on( - 'click', function(e) { - e.preventDefault(); - var import_file_val = $ml('input[name=import_file]').val(); - if(import_file_val == false) { - $ml('#nofileModal').dialog('open'); - } else { - $ml('#basicModal').dialog('open'); - } - } - ); - $ml("#nofileModal").dialog( - { - autoOpen: false, - modal: true, - buttons: { - Ok: function() { - $ml(this).dialog("close"); - } - } - } - ); - $ml('#basicModal').dialog({ - autoOpen: false, - width: 'auto', - title: "Are you sure?", - modal: true, - buttons: { - "Confirm": function(e) { - $ml(this).dialog('close'); - $ml(".saving").show(); - $ml('#form_import_file').submit(); - }, - "Cancel": function() { - $ml(this).dialog('close'); - } - } - }); - $ml('.my-tooltip').each(function(i, e) { - $ml(e).tooltipster( - { - contentAsHTML: true, - theme: 'tooltipster-noir', - trigger: 'click' - } - ) - }); - $ml("#meeting-list-tabs").tabs( - { - active: 0 - } - ); - $ml('#meeting-list-tabs').tabs().addClass('ui-tabs-vertical ui-helper-clearfix'); - $ml("#container").removeClass('hide'); - var meeting_sort_val = $ml("#meeting_sort").val(); - $ml('.borough_by_suffix').hide(); - $ml('.county_by_suffix').hide(); - if(meeting_sort_val === 'borough_county') { - $ml('.borough_by_suffix').show(); - $ml('.county_by_suffix').show(); - } else if(meeting_sort_val === 'borough') { - $ml('.borough_by_suffix').show(); - } else if(meeting_sort_val === 'county') { - $ml('.county_by_suffix').show(); - } - $ml('.neighborhood_by_suffix').hide(); - $ml('.city_by_suffix').hide(); - if(meeting_sort_val === 'neighborhood_city') { - $ml('.neighborhood_by_suffix').show(); - $ml('.city_by_suffix').show(); - } - var user_defined_sub = false; - $ml('.user_defined_headings').hide(); - if(meeting_sort_val === 'user_defined') { - $ml('.user_defined_headings').show(); - if($ml("#subgrouping").val() != '') { - user_defined_sub = true; - } - } - if(meeting_sort_val == 'weekday_area' - || meeting_sort_val == 'weekday_city' - || meeting_sort_val == 'weekday_county' - || meeting_sort_val == 'state' - || user_defined_sub - ) { - $ml('.show_subheader').show(); - } else { - $ml('.show_subheader').hide(); - } - $ml("#suppress_heading").click( - function() { - var val = $ml("#suppress_heading:checked").val(); - if(val == 1) { - $ml("#header_options_div").hide(); - } else { - $ml("#header_options_div").show(); - } - } - ); - $ml("#meeting_sort").change( - function() { - var meeting_sort_val = $ml("#meeting_sort").val(); - $ml('.borough_by_suffix').hide(); - $ml('.county_by_suffix').hide(); - $ml('.neighborhood_by_suffix').hide(); - $ml('.city_by_suffix').hide(); - if(meeting_sort_val === 'borough_county') { - $ml('.borough_by_suffix').show(); - $ml('.county_by_suffix').show(); - } else if(meeting_sort_val === 'borough') { - $ml('.borough_by_suffix').show(); - } else if(meeting_sort_val === 'county') { - $ml('.county_by_suffix').show(); - } - if(meeting_sort_val === 'neighborhood_city') { - $ml('.neighborhood_by_suffix').show(); - $ml('.city_by_suffix').show(); - } - var user_defined_sub = false; - $ml('.user_defined_headings').hide(); - if(meeting_sort_val === 'user_defined') { - $ml('.user_defined_headings').show(); - if($ml("#subgrouping").val() != '') { - user_defined_sub = true; - } - } - if(meeting_sort_val == 'weekday_area' - || meeting_sort_val == 'weekday_city' - || meeting_sort_val == 'weekday_county' - || meeting_sort_val == 'state' - || user_defined_sub - ) { - $ml('.show_subheader').show(); - } else { - $ml('.show_subheader').hide(); - } - } - ); - $ml("#subgrouping").click( - function() { - $ml('.user_defined_headings').hide(); - if($ml("#meeting_sort").val() === 'user_defined') { - $ml('.user_defined_headings').show(); - if($ml("#subgrouping").val() != '') { - $ml('.show_subheader').show(); - } else { - $ml('.show_subheader').hide(); - } - } - } - ); - function calcTimeDisplay(hasEndTime) { - let clock = $ml('input[name=time_clock]:checked').val(); - let removeSpaces = $ml('input[name=remove_space]:checked').val() - let startTime = '8:00 PM'; - let endTime = '9:00 PM'; - if(clock == '24') { - startTime = '20:00'; - endTime = '21:00'; - } else if(clock == '24fr') { - startTime = '20h00'; - endTime = '21h00'; - } - if(hasEndTime == 2) { - startTime += ' - ' + endTime; - } - if(hasEndTime == 3) { - startTime = clock == '12' ? '8 - 9' : ''; - } - if(removeSpaces != "0") { - startTime = startTime.replaceAll(' ', ''); - } - return startTime; - } - function setTimeOptionText() { - $ml('label[for=option1]').html(calcTimeDisplay(1)); - $ml('label[for=option2]').html(calcTimeDisplay(2)); - $ml('label[for=option3]').html(calcTimeDisplay(3)); - if($ml('input[name=time_clock]:checked').val() != '12') { - if($ml('input[name=time_clock]:checked').val() == 3) - $ml('#option2').prop('checked', true); - $ml('#option3').hide(); - } else $ml('#option3').show(); - }; - setTimeOptionText(); - $ml('.recalcTimeLabel').on('click', setTimeOptionText); - function bookletControlsShowHide() { - $ml('#half').prop('checked') && $ml('#landscape').prop("checked", true); - $ml('#full').prop('checked') && $ml('#portrait').prop("checked", true); - $ml('.booklet').show(); - $ml('.single-page').hide(); - $ml('#half').prop('checked') && $ml('#A6').hide(); - $ml('#half').prop('checked') && $ml('#A6').hide(); - $ml('#half').prop('checked') && $ml("label[for=A6]").hide(); - } - function singlePageControlsShowHide() { - $ml('.booklet').hide(); - $ml('.single-page').show(); - } - $ml('.single-page-check').on('click', singlePageControlsShowHide); - $ml('.booklet-check').on('click', bookletControlsShowHide); - $ml('input[name=page_fold]:checked').hasClass('booklet-check') && bookletControlsShowHide(); - $ml('input[name=page_fold]:checked').hasClass('single-page-check') && singlePageControlsShowHide(); - $ml(".bread_service_body_select").select2(); - $ml('#extra_meetings').select2( - { - placeholder: "Select extra meetings", - } - ); - $ml("#bread_author_select").select2( - { - placeholder: "Select authors", - } - ); - $ml('.bread-select').on("change", function (e) { - const self = $ml(this); - const field = self.parent().find('.select2-search--inline'); - field.css('display', (self.val().length == 0 ? 'contents' : 'block')); - field.find('input').css('width', (self.val().length == 0 ? '100%' : 'auto')); - }); - $ml("#meeting-list-tabs").tabs( - { - active: 0 - } - ); - $ml("#meeting-list-tabs-wrapper").removeClass('hide'); - // Define friendly index name - var index = 'key'; - // Define friendly data store name - var dataStore = window.sessionStorage; - // Start magic! - try { - // getter: Fetch previous value - var oldIndex = dataStore.getItem(index); - } catch(e) { - // getter: Always default to first tab in error state - var oldIndex = 0; - } - $ml('#meeting-list-tabs').tabs( - { - // The zero-based index of the panel that is active (open) - active: oldIndex, - // Triggered after a tab has been activated - activate: function(event, ui) { - // Get future value - var newIndex = ui.newTab.parent().children().index(ui.newTab); - // Set future value - dataStore.setItem(index, newIndex) - } - } - ); - var aggregator = "https://aggregator.bmltenabled.org/main_server"; - $ml(window).on( - "load", function() { - if($ml('#use_aggregator').is(':checked')) { - $ml("#root_server").prop("readonly", true); - } - } - ); - $ml('#use_aggregator').click( - function() { - if($ml(this).is(':checked')) { - $ml("#root_server").val(aggregator); - $ml("#root_server").prop("readonly", true); - } else { - $ml("#root_server").val(""); - $ml("#root_server").prop("readonly", false); - } - } - ); - var rootServerValue = $ml('#root_server').val(); - if(~rootServerValue.indexOf(aggregator)) { - $ml("#use_aggregator").prop("checked", true); - } - } -); -/** - * Get Tab Key - */ -function getTabKey(href) { - return href.replace('#', ''); -} -/** - * Hide all tabs - */ -function hideAllTabs() { - tabs.each(function() { - var href = getTabKey(jQuery(this).attr('href')); - jQuery('#' + href).hide(); - }); -} -/** - * Activate Tab - */ -function activateTab(tab) { - var href = getTabKey(tab.attr('href')); - tabs.removeClass('nav-tab-active'); - tab.addClass('nav-tab-active'); - jQuery('#' + href).show(); -} -jQuery(document).ready(function($) { - var activeTab, firstTab; - // First load, activate first tab or tab with nav-tab-active class - firstTab = false; - activeTab = false; - tabs = $('a.nav-tab'); - hideAllTabs(); - tabs.each(function() { - var href = $(this).attr('href').replace('#', ''); - if(!firstTab) { - firstTab = $(this); - } - if($(this).hasClass('nav-tab-active')) { - activeTab = $(this); - } - }); - if(!activeTab) { - activeTab = firstTab; - } - activateTab(activeTab); - //Click tab - tabs.click(function(e) { - e.preventDefault(); - hideAllTabs(); - activateTab($(this)); - }); +jQuery(document).ready(function ($) { + $(".connecting").hide(); + $(".saving").hide(); + $(".bmlt-accordion").accordion({ + heightStyle: "content", + active: false, + collapsible: true, + }); + $(".bmlt_color").spectrum({ + preferredFormat: "hex", + showInput: true, + showPalette: false, + }); + $("#col_color").on("click", () => + $("#triggerSet").spectrum("set", this.val()), + ); + $("#bmlt_meeting_list_options").on("keypress", function (event) { + if (event.which == 13 && !event.shiftKey) { + event.preventDefault(); + return false; + } + }); + $(".gears-working").click(function (e) { + $(".saving").show(); + }); + $('input[name="submit_import_file"]').on("click", function (e) { + e.preventDefault(); + var import_file_val = $("input[name=import_file]").val(); + if (import_file_val == false) { + $("#nofileModal").dialog("open"); + } else { + $("#basicModal").dialog("open"); + } + }); + $("#nofileModal").dialog({ + autoOpen: false, + modal: true, + buttons: { + Ok: function () { + $(this).dialog("close"); + }, + }, + }); + $("#basicModal").dialog({ + autoOpen: false, + width: "auto", + title: "Are you sure?", + modal: true, + buttons: { + Confirm: function (e) { + $(this).dialog("close"); + $(".saving").show(); + $("#form_import_file").submit(); + }, + Cancel: function () { + $(this).dialog("close"); + }, + }, + }); + $(".my-tooltip").each(function (i, e) { + $(e).tooltipster({ + contentAsHTML: true, + theme: "tooltipster-noir", + trigger: "click", + }); + }); + $("#meeting-list-tabs").tabs({ + active: 0, + }); + $("#meeting-list-tabs") + .tabs() + .addClass("ui-tabs-vertical ui-helper-clearfix"); + $("#container").removeClass("hide"); + var meeting_sort_val = $("#meeting_sort").val(); + $(".borough_by_suffix").hide(); + $(".county_by_suffix").hide(); + if (meeting_sort_val === "borough_county") { + $(".borough_by_suffix").show(); + $(".county_by_suffix").show(); + } else if (meeting_sort_val === "borough") { + $(".borough_by_suffix").show(); + } else if (meeting_sort_val === "county") { + $(".county_by_suffix").show(); + } + $(".neighborhood_by_suffix").hide(); + $(".city_by_suffix").hide(); + if (meeting_sort_val === "neighborhood_city") { + $(".neighborhood_by_suffix").show(); + $(".city_by_suffix").show(); + } + var user_defined_sub = false; + $(".user_defined_headings").hide(); + if (meeting_sort_val === "user_defined") { + $(".user_defined_headings").show(); + if ($("#subgrouping").val() != "") { + user_defined_sub = true; + } + } + if ( + meeting_sort_val == "weekday_area" || + meeting_sort_val == "weekday_city" || + meeting_sort_val == "weekday_county" || + meeting_sort_val == "state" || + user_defined_sub + ) { + $(".show_subheader").show(); + } else { + $(".show_subheader").hide(); + } + $("#suppress_heading").click(function () { + var val = $("#suppress_heading:checked").val(); + if (val == 1) { + $("#header_options_div").hide(); + } else { + $("#header_options_div").show(); + } + }); + $("#meeting_sort").change(function () { + var meeting_sort_val = $("#meeting_sort").val(); + $(".borough_by_suffix").hide(); + $(".county_by_suffix").hide(); + $(".neighborhood_by_suffix").hide(); + $(".city_by_suffix").hide(); + if (meeting_sort_val === "borough_county") { + $(".borough_by_suffix").show(); + $(".county_by_suffix").show(); + } else if (meeting_sort_val === "borough") { + $(".borough_by_suffix").show(); + } else if (meeting_sort_val === "county") { + $(".county_by_suffix").show(); + } + if (meeting_sort_val === "neighborhood_city") { + $(".neighborhood_by_suffix").show(); + $(".city_by_suffix").show(); + } + var user_defined_sub = false; + $(".user_defined_headings").hide(); + if (meeting_sort_val === "user_defined") { + $(".user_defined_headings").show(); + if ($("#subgrouping").val() != "") { + user_defined_sub = true; + } + } + if ( + meeting_sort_val == "weekday_area" || + meeting_sort_val == "weekday_city" || + meeting_sort_val == "weekday_county" || + meeting_sort_val == "state" || + user_defined_sub + ) { + $(".show_subheader").show(); + } else { + $(".show_subheader").hide(); + } + }); + $("#subgrouping").click(function () { + $(".user_defined_headings").hide(); + if ($("#meeting_sort").val() === "user_defined") { + $(".user_defined_headings").show(); + if ($("#subgrouping").val() != "") { + $(".show_subheader").show(); + } else { + $(".show_subheader").hide(); + } + } + }); + function calcTimeDisplay(hasEndTime) { + let clock = $("input[name=time_clock]:checked").val(); + let removeSpaces = $("input[name=remove_space]:checked").val(); + let startTime = "8:00 PM"; + let endTime = "9:00 PM"; + if (clock == "24") { + startTime = "20:00"; + endTime = "21:00"; + } else if (clock == "24fr") { + startTime = "20h00"; + endTime = "21h00"; + } + if (hasEndTime == 2) { + startTime += " - " + endTime; + } + if (hasEndTime == 3) { + startTime = clock == "12" ? "8 - 9" : ""; + } + if (removeSpaces != "0") { + startTime = startTime.replaceAll(" ", ""); + } + return startTime; + } + function setTimeOptionText() { + $("label[for=option1]").html(calcTimeDisplay(1)); + $("label[for=option2]").html(calcTimeDisplay(2)); + $("label[for=option3]").html(calcTimeDisplay(3)); + if ($("input[name=time_clock]:checked").val() != "12") { + if ($("input[name=time_clock]:checked").val() == 3) + $("#option2").prop("checked", true); + $("#option3").hide(); + } else $("#option3").show(); + } + setTimeOptionText(); + $(".recalcTimeLabel").on("click", setTimeOptionText); + function bookletControlsShowHide() { + $("#half").prop("checked") && $("#landscape").prop("checked", true); + $("#full").prop("checked") && $("#portrait").prop("checked", true); + $(".booklet").show(); + $(".single-page").hide(); + $("#half").prop("checked") && $("#A6").hide(); + $("#half").prop("checked") && $("#A6").hide(); + $("#half").prop("checked") && $("label[for=A6]").hide(); + } + function singlePageControlsShowHide() { + $(".booklet").hide(); + $(".single-page").show(); + } + $(".single-page-check").on("click", singlePageControlsShowHide); + $(".booklet-check").on("click", bookletControlsShowHide); + $("input[name=page_fold]:checked").hasClass("booklet-check") && + bookletControlsShowHide(); + $("input[name=page_fold]:checked").hasClass("single-page-check") && + singlePageControlsShowHide(); + $("#service_bodies").select2(); + $("#extra_meetings").select2({ + placeholder: "Select extra meetings", + }); + $("#bread_author_select").select2({ + placeholder: "Select authors", + }); + $(".bread-select").on("change", function (e) { + const self = $(this); + const field = self.parent().find(".select2-search--inline"); + field.css("display", self.val().length == 0 ? "contents" : "block"); + field + .find("input") + .css("width", self.val().length == 0 ? "100%" : "auto"); + }); + $("#meeting-list-tabs").tabs({ + active: 0, + }); + $("#meeting-list-tabs-wrapper").removeClass("hide"); + // Define friendly index name + var index = "key"; + // Define friendly data store name + var dataStore = window.sessionStorage; + // Start magic! + try { + // getter: Fetch previous value + var oldIndex = dataStore.getItem(index); + } catch (e) { + // getter: Always default to first tab in error state + var oldIndex = 0; + } + $("#meeting-list-tabs").tabs({ + // The zero-based index of the panel that is active (open) + active: oldIndex, + // Triggered after a tab has been activated + activate: function (event, ui) { + // Get future value + var newIndex = ui.newTab.parent().children().index(ui.newTab); + // Set future value + dataStore.setItem(index, newIndex); + }, + }); + var aggregator = "https://aggregator.bmltenabled.org/main_server"; + $(window).on("load", function () { + if ($("#use_aggregator").is(":checked")) { + $("#root_server").prop("readonly", true); + } + }); + $("#use_aggregator").click(function () { + if ($(this).is(":checked")) { + $("#root_server").val(aggregator); + $("#root_server").prop("readonly", true); + } else { + $("#root_server").val(""); + $("#root_server").prop("readonly", false); + } + }); + var rootServerValue = $("#root_server").val(); + if (~rootServerValue.indexOf(aggregator)) { + $("#use_aggregator").prop("checked", true); + } + $(".service_body_select").select2({ + width: "40%", + }); + $(".theme_select").select2({ + width: "20%", + }); + $("#select_filters").select2({ + width: "60%", + }); + $("#extra_meetings").select2({ + width: "60%", + placeholder: "Select Extra Meetings", + }); + handle_error = function (error) { + console.log(error); + }; + ask_bmlt = function (query, success, fail) { + const url = + $("#root_server").val() + + "/client_interface/jsonp/?" + + query; + fetchJsonp(url) + .then((response) => { + if (response.ok) { + return response.json(); + } + return Promise.reject(response); // 2. reject instead of throw + }) + .then((json) => { + success(json); + return json; + }) + .catch((response) => { + fail(response); + return false; + }); + }; + test_root_server = function () { + if (!$("#root_server").val()) { + $("#connected_message").hide(); + $("#disconnected_message").hide(); + fill_service_bodies([]); + fill_extra_meetings([]); + return; + } + ask_bmlt( + "switcher=GetServerInfo", + (info) => { + $("#server_version").html(info[0].version); + $("#connected_message").show(); + $("#disconnected_message").hide(); + ask_bmlt( + "switcher=GetServiceBodies", + fill_service_bodies, + handle_error, + ); + query_extra_meetings(); + }, + (error) => { + console.log(error); + $("#connected_message").hide(); + $("#disconnected_message").show(); + fill_service_bodies([]); + fill_extra_meetings([]); + }, + ); + }; + query_extra_meetings = function () { + if ($('#root_server').val() == aggregator) { + $("#extra_meetings_enabled").prop('checked', false) + $("#extra_meetings_enabled").prop("disabled", true) + $("#extra_meetings_select").hide(); + $("#fetching_meetings").hide(); + fill_extra_meetings([]); + return; + } + if ($("#extra_meetings_enabled").is(":checked")) { + $("#extra_meetings_select").hide(); + $("#fetching_meetings").show(); + ask_bmlt( + "switcher=GetSearchResults", + fill_extra_meetings, + handle_error, + ); + } else { + fill_extra_meetings([]); + } + }; + test_root_server(); + $("#extra_meetings_enabled").on("change", function () { + query_extra_meetings(); + }); + write_service_body_with_childern = function ( + options, + sb, + parents, + my_parent, + level, + ) { + let prefix = ""; + for (i = 0; i < level; i++) prefix += "-"; + const sbVal = [sb.name, sb.id, sb.parent_id, my_parent].join(","); + const option = + '"; + options.push(option); + found = parents.find((p) => p.id == sb.id); + if (typeof found !== "undefined") + found.children.forEach( + (child) => + (options = write_service_body_with_childern( + options, + child, + parents, + sb.name, + level + 1, + )), + ); + return options; + }; + var breadServiceBodies ={} ; + fill_service_bodies = function (service_bodies) { + service_bodies = service_bodies.sort((a, b) => + a.name.localeCompare(b.name), + ); + breadServiceBodies = service_bodies.reduce((obj, item) => { obj[item.id] = item; return obj; }, {}) + const roots = service_bodies.filter((sb) => sb.parent_id == "0"); + const parents = service_bodies.reduce((carry, item) => { + const found = carry.find((p) => p.id == item.parent_id); + if (found) { + found.children.push(item); + } else { + carry.push({ id: item.parent_id, children: [item] }); + } + return carry; + }, []); + let options = []; + roots.forEach((sb) => { + options = write_service_body_with_childern( + options, + sb, + parents, + "ROOT", + 0, + ); + }); + $("#service_bodies").html(options.join("")); + + query_used_formats(); + }; + root_server_keypress = function (event) { + if (event.code == "Enter") { + this.test_root_server(); + event.preventDefault(); + } + return true; + }; + extraMeetingDayAndTime = function (extra_meeting) { + const meetingDay = dayjs().day(extra_meeting.weekday_tinyint) + .hour(parseInt(extra_meeting.start_time.substring(0, 2))) + .minute(parseInt(extra_meeting.start_time.substring(3, 5))); + return meetingDay.format("ddd h:mm A"); + } + fill_extra_meetings = function (extra_meetings_array) { + $("#fetching_meetings").hide(); + if ($("#extra_meetings_enabled").is(":checked")) { + $("#extra_meetings").next(".select2-container").show(); + $("#extra_meetings_hint").show(); + } else { + $("#extra_meetings").next(".select2-container").hide(); + $("#extra_meetings_hint").hide(); + } + const options = extra_meetings_array.map( + (extra_meeting) => + '", + ); + $("#extra_meetings").html(options.join("")); + }; + fill_formats = function (formats) { + const select = (key) => + bread_admin.used_format == key ? "selected" : ""; + const options = formats.formats.reduce( + (carry, item) => { + carry.push( + '", + ); + return carry; + }, + [''], + ); + $("#used_format_1").html(options.join("")); + fill_additional_list_formats(formats); + }; + fill_additional_list_formats = function (formats) { + const select = (key) => + bread_admin.additional_list_format_key == key ? "selected" : ""; + const options = formats.formats.reduce( + (carry, item) => { + carry.push( + '", + ); + return carry; + }, + [ + '', + '', + '', + ], + ); + $("#additional_list_format_key").html(options.join("")); + }; + query_used_formats = function () { + const serviceBodies = $("#service_bodies") + .val() + .map((s) => s.split(",")[1]); + if (serviceBodies.length == 0) { + fill_formats({formats: []}); + return; + } + const query = serviceBodies.reduce( + (carry, item) => { + return carry + "&services[]=" + item; + }, + $("#recurse_service_bodies").is(":checked") ? "&recursive=1" : "", + ); + ask_bmlt( + "switcher=GetSearchResults&get_formats_only" + query, + fill_formats, + handle_error, + ); + }; + /** + * Get Tab Key + */ + function getTabKey(href) { + return href.replace("#", ""); + } + /** + * Hide all tabs + */ + function hideAllTabs() { + tabs.each(function () { + var href = getTabKey(jQuery(this).attr("href")); + jQuery("#" + href).hide(); + }); + } + /** + * Activate Tab + */ + function activateTab(tab) { + var href = getTabKey(tab.attr("href")); + tabs.removeClass("nav-tab-active"); + tab.addClass("nav-tab-active"); + jQuery("#" + href).show(); + } + var activeTab, firstTab; + // First load, activate first tab or tab with nav-tab-active class + firstTab = false; + activeTab = false; + tabs = $("a.nav-tab"); + hideAllTabs(); + tabs.each(function () { + var href = $(this).attr("href").replace("#", ""); + if (!firstTab) { + firstTab = $(this); + } + if ($(this).hasClass("nav-tab-active")) { + activeTab = $(this); + } + }); + if (!activeTab) { + activeTab = firstTab; + } + activateTab(activeTab); + //Click tab + tabs.click(function (e) { + e.preventDefault(); + hideAllTabs(); + activateTab($(this)); + }); }); diff --git a/admin/js/bread-wizard.js b/admin/js/bread-wizard.js index 5eb5b3c5..476c45eb 100644 --- a/admin/js/bread-wizard.js +++ b/admin/js/bread-wizard.js @@ -1,6 +1,6 @@ jQuery(document).ready(function($){ - var BreadWizard = function() { - ask_bmlt = function(query, success, fail) { + window.BreadWizard = {}; + BreadWizard.ask_bmlt = function(query, success, fail) { const url = $("#wizard_root_server").val()+"/client_interface/jsonp/?"+query; fetchJsonp(url) .then((response) => { @@ -18,7 +18,7 @@ jQuery(document).ready(function($){ return false; }) } - BreadWizard.prototype.ajax_submit = function() { + BreadWizard.ajax_submit = function() { $(".saving").show(); var myform = document.getElementById("wizard_form"); var formData = new FormData(myform); @@ -33,34 +33,32 @@ jQuery(document).ready(function($){ return response.json(); }) .then((resp) => { - finalInstructions(resp); + BreadWizard.finalInstructions(resp); }) .catch((error) => { // Handle error console.log("error ", error); }); } - var href; - var setting; - finalInstructions = function(response) { + BreadWizard.finalInstructions = function(response) { $(".saving").hide(); $('#wizard-before-create').hide(); $('#wizard-after-create').show(); - href = window.location.href.substring(0, window.location.href.indexOf('/wp-admin')); - setting = response.result.setting; - href = href+"?current-meeting-list="+setting; - const tag = '
'+href+'
'; + BreadWizard.href = window.location.href.substring(0, window.location.href.indexOf('/wp-admin')); + BreadWizard.setting = response.result.setting; + BreadWizard.href = href+"?current-meeting-list="+BreadWizard.setting; + const tag = '
'+BreadWizard.href+'
'; $('#wizard-show-link').html(tag); } - BreadWizard.prototype.generate_meeting_list = function() { - window.open(href, '_blank').focus(); + BreadWizard.generate_meeting_list = function() { + window.open(BreadWizard.href, '_blank').focus(); } - BreadWizard.prototype.redo_layout = function() { - $('#wizard_setting_id').val(setting); + BreadWizard.redo_layout = function() { + $('#wizard_setting_id').val(BreadWizard.setting); $('#bread-wizard').smartWizard("goToStep", 2); } - BreadWizard.prototype.test_root_server = function() { - ask_bmlt("switcher=GetServerInfo", + BreadWizard.test_root_server = function() { + BreadWizard.ask_bmlt("switcher=GetServerInfo", (info) => { $('#wizard_root_server_result').removeClass('invalid-feedback dashicons-dismiss') .addClass('valid-feedback dashicons-before dashicons-yes-alt').html($('#wizard_connected_message').html()+info[0].version); @@ -70,14 +68,14 @@ jQuery(document).ready(function($){ .addClass('invalid-feedback dashicons-before dashicons-dismiss').html($('#wizard_disconnected_message').html()); }); } - BreadWizard.prototype.root_server_keypress = function(event) { + BreadWizard.root_server_keypress = function(event) { if (event.code == 'Enter') this.test_root_server(); } - BreadWizard.prototype.root_server_changed = function() { + BreadWizard.root_server_changed = function() { $('#wizard_root_server_result').removeClass('valid-feedback').addClass('invalid-feedback dashicons-before dashicons-dismiss') .html($('#wizard_testnow_message').html()); } - BreadWizard.prototype.finish = function() { + BreadWizard.finish = function() { $('#bread-wizard').smartWizard("reset"); var form = document.createElement("form"); form.method = "POST"; @@ -85,12 +83,12 @@ jQuery(document).ready(function($){ var input = document.createElement("input"); input.type = "hidden"; input.name = "current-meeting-list"; - input.value = setting; + input.value = BreadWizard.setting; form.appendChild(input); document.body.appendChild(form); form.submit(); } - write_service_body_with_childern = function(options, sb, parents, my_parent, level) { + BreadWizard.write_service_body_with_childern = function(options, sb, parents, my_parent, level) { let prefix = ''; for (i=0; i p.id == sb.id); if (typeof found !== 'undefined') found.children.forEach((child) => - options = write_service_body_with_childern(options, child, parents, sb.name, level+1)); + options = BreadWizard.write_service_body_with_childern(options, child, parents, sb.name, level+1)); return options; } - fill_service_bodies = function(service_bodies) { + BreadWizard.fill_service_bodies = function(service_bodies) { service_bodies = service_bodies.sort((a,b) => a.name.localeCompare(b.name)); const roots = service_bodies.filter((sb) => sb.parent_id=='0'); const parents = service_bodies.reduce((carry,item) => { @@ -115,28 +113,28 @@ jQuery(document).ready(function($){ }, []); let options = []; roots.forEach((sb) => { - options = write_service_body_with_childern(options, sb, parents, 'ROOT', 0); + options = BreadWizard.write_service_body_with_childern(options, sb, parents, 'ROOT', 0); }); $('#wizard_service_bodies').html(options.join('')); } - fill_formats = function(formats) { + BreadWizard.fill_formats = function(formats) { const options = formats.reduce((carry,item) => { carry.push(''); return carry; }, ['']); $('#wizard_format_filter').html(options.join('')); } - var hasVirtualMeetings = false; - layout_options = function(meetings) { + BreadWizard.hasVirtualMeetings = false; + BreadWizard.layout_options = function(meetings) { const meeting_count = meetings.length; - hasVirtualMeetings = meetings.some((m) => m.formats.split(',').some(format => ['VM','HY'].includes(format))); + BreadWizard.hasVirtualMeetings = meetings.some((m) => m.formats.split(',').some(format => ['VM','HY'].includes(format))); $('#wizard_meeting_count').html(meeting_count); const layouts = breadLayouts.find((layouts) => meeting_count <= Number(layouts.maxSize)); const options = breadLayouts.reduce((carry,group) => { const name = (group.maxSize == '99999') ? 'Very Large Fellowships' : 'Approx. '+group.maxSize+' meetings'; carry.push(''); group.configurations.reduce((carryGroup, item, idx) => { - carryGroup.push(...getOptionsFromFilename(group.maxSize, item, idx, layouts)); + carryGroup.push(...BreadWizard.getOptionsFromFilename(group.maxSize, item, idx, layouts)); return carryGroup; }, carry); carry.push(''); @@ -144,7 +142,7 @@ jQuery(document).ready(function($){ }, []); $('#wizard_layout').html(options.join('')); } - getOptionsFromFilename = function(size, filename, idx, layouts) { + BreadWizard.getOptionsFromFilename = function(size, filename, idx, layouts) { const type = filename.split('-'); const fold = type[0]; const orientation = type[1]; @@ -156,7 +154,7 @@ jQuery(document).ready(function($){ return carry; },[]); } - lang_options = function() { + BreadWizard.lang_options = function() { const options = breadTranslations.reduce((carry,item)=>{ const selected = (item.key==='en') ? ' selected' : ''; carry.push('') @@ -168,15 +166,15 @@ jQuery(document).ready(function($){ $('#wizard-virtual-meeting-section').hide(); } } - handle_error = function(error) { + BreadWizard.handle_error = function(error) { console.log(error); $('#bread-wizard').smartWizard("goToStep", 0); } - BreadWizard.prototype.getContent = function(idx, stepDirection, stepPosition, selStep, callback) { + BreadWizard.getContent = function(idx, stepDirection, stepPosition, selStep, callback) { switch(idx) { case 1: - ask_bmlt('switcher=GetServiceBodies', fill_service_bodies, handle_error); - ask_bmlt('switcher=GetFormats', fill_formats, handle_error); + BreadWizard.ask_bmlt('switcher=GetServiceBodies', BreadWizard.fill_service_bodies, BreadWizard.handle_error); + BreadWizard.ask_bmlt('switcher=GetFormats', BreadWizard.fill_formats, BreadWizard.handle_error); break; case 2: const services = $('#wizard_service_bodies').val().reduce((carry,item) => { @@ -185,10 +183,10 @@ jQuery(document).ready(function($){ }, '&recursive=1'); const formats = (Number($('#wizard_format_filter').val()) > 0) ? '&formats='+$('#wizard_format_filter').val() : ''; - ask_bmlt('switcher=GetSearchResults'+services+formats, layout_options, handle_error); + BreadWizard.ask_bmlt('switcher=GetSearchResults'+services+formats, BreadWizard.layout_options, BreadWizard.handle_error); break; case 3: - lang_options(); + BreadWizard.lang_options(); case 4: if ($("wizard_layout").val()=='') handle_error('Layout not defined'); $('#wizard-before-create').show(); @@ -198,8 +196,7 @@ jQuery(document).ready(function($){ } callback(); } - }; - window.breadWizard = new BreadWizard(); + // SmartWizard initialize $('#bread-wizard').smartWizard( @@ -213,9 +210,9 @@ jQuery(document).ready(function($){ anchor: { enableNavigation: false, }, - getContent: breadWizard.getContent + getContent: BreadWizard.getContent } - ); + ) // Initialize the leaveStep event $("#bread-wizard").on("leaveStep", function(e, anchorObject, currentStepIndex, nextStepIndex, stepDirection) { switch(currentStepIndex) { @@ -238,4 +235,4 @@ jQuery(document).ready(function($){ max_selected_options:5, width: "62%" }); -}); \ No newline at end of file +}) diff --git a/admin/js/dayjs.min.js b/admin/js/dayjs.min.js new file mode 100644 index 00000000..cfcd9845 --- /dev/null +++ b/admin/js/dayjs.min.js @@ -0,0 +1 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).dayjs=e()}(this,(function(){"use strict";var t=1e3,e=6e4,n=36e5,r="millisecond",i="second",s="minute",u="hour",a="day",o="week",c="month",f="quarter",h="year",d="date",l="Invalid Date",$=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,y=/\[([^\]]+)]|YYYY|YY|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,M={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(t){var e=["th","st","nd","rd"],n=t%100;return"["+t+(e[(n-20)%10]||e[n]||e[0])+"]"}},m=function(t,e,n){var r=String(t);return!r||r.length>=e?t:""+Array(e+1-r.length).join(n)+t},v={s:m,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),i=n%60;return(e<=0?"+":"-")+m(r,2,"0")+":"+m(i,2,"0")},m:function t(e,n){if(e.date()1)return t(u[0])}else{var a=e.name;D[a]=e,i=a}return!r&&i&&(g=i),i||!r&&g},O=function(t,e){if(S(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new _(n)},b=v;b.l=w,b.i=S,b.w=function(t,e){return O(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var _=function(){function M(t){this.$L=w(t.locale,null,!0),this.parse(t),this.$x=this.$x||t.x||{},this[p]=!0}var m=M.prototype;return m.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(b.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match($);if(r){var i=r[2]-1||0,s=(r[7]||"0").substring(0,3);return n?new Date(Date.UTC(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)):new Date(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)}}return new Date(e)}(t),this.init()},m.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},m.$utils=function(){return b},m.isValid=function(){return!(this.$d.toString()===l)},m.isSame=function(t,e){var n=O(t);return this.startOf(e)<=n&&n<=this.endOf(e)},m.isAfter=function(t,e){return O(t) +
@@ -23,49 +31,30 @@ function Bread_bmlt_server_setup_page_render(Bread_AdminDisplay $breadAdmin)

- -

- isConnected()) { - echo wp_kses($breadAdmin->getServerVersion(), 'post'); - echo ''; - if ($bread->getOption('sslverify') == '1') { ?> -

- - - emptyOption('root_server')) { - echo "

".esc_html(__('ERROR: Please enter a BMLT Server', 'bread')).""; - echo ''; - if ($bread->getOption('sslverify') == '1') { ?> -

- - -

- -

bmlt()->connection_error); ?> + + -

- - -

-

- getOption('sslverify') ? 'checked' : ''; ?> /> - -

- + +

-
    select_service_bodies(); ?>
+

+ + +

- getOption('recurse_service_bodies') == 1 ? 'checked' : '') ?> /> + getOption('recurse_service_bodies') == 1 ? 'checked' : '') ?> />
@@ -97,21 +86,14 @@ function Bread_bmlt_server_setup_page_render(Bread_AdminDisplay $breadAdmin)

(?)

- isConnected() && $bread->getOption('extra_meetings_enabled') == 1) {?> - -

- +

- emptyOption('extra_meetings_enabled') && $bread->getOption('extra_meetings_enabled') == 1 ? 'checked' : '') ?> /> + emptyOption('extra_meetings_enabled') && $bread->getOption('extra_meetings_enabled') == 1 ? 'checked' : '') ?> />
diff --git a/admin/partials/_bread_wizard.php b/admin/partials/_bread_wizard.php index 0daa1a13..fdf835d4 100644 --- a/admin/partials/_bread_wizard.php +++ b/admin/partials/_bread_wizard.php @@ -53,8 +53,8 @@

Do I have the BMLT? to find your BMLT server', 'bread')) ?>
- + onKeypress="BreadWizard.root_server_keypress(event)" onChange="BreadWizard.root_server_changed()" /> + @@ -150,19 +150,19 @@

- +

- +

-

+

- +
diff --git a/admin/partials/_layout_setup.php b/admin/partials/_layout_setup.php index 7f8659b3..f8a8662f 100644 --- a/admin/partials/_layout_setup.php +++ b/admin/partials/_layout_setup.php @@ -2,6 +2,13 @@ if (! defined('ABSPATH')) { exit; } +function echo_font_options($base_font, $bread) +{ + $fonts = apply_filters('bread_custom_fonts', $bread->fonts); + foreach ($fonts as $font_key => $font_name) { + echo ''; + } +} function Bread_layout_setup_page_render(Bread_AdminDisplay $breadAdmin) { $bread = $breadAdmin->getBreadInstance(); @@ -152,10 +159,7 @@ function Bread_layout_setup_page_render(Bread_AdminDisplay $breadAdmin) diff --git a/admin/partials/_meetings_setup.php b/admin/partials/_meetings_setup.php index 15223b89..8099750a 100644 --- a/admin/partials/_meetings_setup.php +++ b/admin/partials/_meetings_setup.php @@ -109,16 +109,6 @@ function Bread_meetings_setup_page_render(Bread_AdminDisplay $breadAdmin) - bmlt()->get_nonstandard_fieldkeys(); - foreach ($fks as $fk) { - $selected = ''; - if ($fk['key'] == $bread->getOption('main_grouping')) { - $selected = 'selected'; - } - echo ''; - } - ?>

@@ -282,22 +263,6 @@ function Bread_meetings_setup_page_render(Bread_AdminDisplay $breadAdmin)
@@ -312,19 +277,8 @@ function Bread_meetings_setup_page_render(Bread_AdminDisplay $breadAdmin)

diff --git a/admin/partials/bread-admin-display.php b/admin/partials/bread-admin-display.php index e927d3c9..aeedc854 100644 --- a/admin/partials/bread-admin-display.php +++ b/admin/partials/bread-admin-display.php @@ -32,26 +32,6 @@ function __construct($admin) { $this->admin = $admin; $this->bread = $admin->get_bread_instance(); - $this->refresh_status(); - } - private function refresh_status() - { - $serverInfo = $this->bread->bmlt()->testRootServer(); - $this->connected = is_array($serverInfo) && array_key_exists("version", $serverInfo[0]) ? $serverInfo[0]["version"] : ''; - if ($this->connected) { - $this->unique_areas = $this->bread->bmlt()->get_areas(); - asort($this->unique_areas); - if ($serverInfo[0]["aggregator_mode_enabled"] ?? false) { - $this->server_version = "

".__('Using Tomato Server', 'bread').""; - } elseif ($this->connected) { - /* translators: string is the version number of the BMLT Server */ - $this->server_version = "
".sprintf(__('Your BMLT Server is running %s', 'bread'), esc_html($this->connected)). "
"; - } - } - } - public function isConnected() - { - return $this->connected; } public function getBreadInstance() { @@ -61,43 +41,6 @@ public function getServerVersion() { return $this->server_version; } - public function select_service_bodies() - { - for ($i = 1; $i <= 5; $i++) { ?> -
  • - -
  • - - unique_areas as $area) { - $area_data = explode(',', $area); - $area_name = $this->bread->arraySafeGet($area_data); - $area_id = $this->bread->arraySafeGet($area_data, 1); - $area_parent = $this->bread->arraySafeGet($area_data, 2); - $area_parent_name = $this->bread->arraySafeGet($area_data, 3); - $descr = $area_name . " (" . $area_id . ") " . $area_parent_name . " (" . $area_parent . ")"; - $selected = ''; - $sb = esc_html($this->bread->getOption("service_body_$i")); - $area_selected = explode(',', $sb); - if ($this->bread->arraySafeGet($area_selected) != "Not Used" && $area_id == $this->bread->arraySafeGet($area_selected, 1)) { - $selected = 'selected'; - } ?> - @@ -159,7 +102,6 @@ function admin_options_page($filename = '') - refresh_status(); ?>
    diff --git a/bmlt-meeting-list.php b/bmlt-meeting-list.php index 3be9b1ae..ef93c6c5 100644 --- a/bmlt-meeting-list.php +++ b/bmlt-meeting-list.php @@ -11,7 +11,7 @@ * Plugin Name: Bread * Plugin URI: https://bmlt.app * Description: Maintains and generates PDF Meeting Lists from BMLT. - * Version: 2.9.15 + * Version: 2.10.0 * Author: bmlt-enabled * Author URI: https://bmlt.app/ * License: GPL-2.0+ @@ -30,7 +30,7 @@ * Start at version 2.8.0 and use SemVer - https://semver.org * Rename this for your plugin and update it as you release new versions. */ -define('BREAD_VERSION', '2.9.13'); +define('BREAD_VERSION', '2.10.0'); /** * The code that runs during plugin activation. diff --git a/includes/class-bread-bmlt.php b/includes/class-bread-bmlt.php index 90ca05e1..722f8ac4 100644 --- a/includes/class-bread-bmlt.php +++ b/includes/class-bread-bmlt.php @@ -8,15 +8,19 @@ class Bread_Bmlt private $bmlt_server_lang = ''; private array $unique_areas; private Bread $bread; + private ?array $preloaded = null; function __construct($bread) { $this->bread = $bread; } - - public function get_configured_root_server_request($url, $raw = false) + public function preload($results) + { + $this->preloaded = $results; + } + private function get_configured_root_server_request($url, $raw = false) { - $results = $this->bread->bmlt()->get($this->bread->getOption('root_server') . "/" . $url); + $results = $this->get($this->bread->getOption('root_server') . "/$url"); if ($raw) { return $results; } @@ -24,7 +28,10 @@ public function get_configured_root_server_request($url, $raw = false) } public function get_formats_by_language(string $lang) { - return $this->bread->bmlt()->get_configured_root_server_request("client_interface/json/?switcher=GetFormats&lang_enum=$lang"); + if ($this->preloaded !== null) { + return $this->preloaded['allFormats'][substr($lang, 0, 2)]; + } + return $this->get_configured_root_server_request("client_interface/json/?switcher=GetFormats&lang_enum=$lang"); } /** * Undocumented function @@ -50,77 +57,6 @@ private function get(string $url): WP_Error | array } return wp_remote_get($url, $args); } - /** - * Gets all the meetins in the root server as an array with id=>string. Used to select extra meetings. - * - * @return array - */ - public function get_all_meetings(): array - { - $lang = $this->bread->bmlt()->get_bmlt_server_lang(); - $result = $this->bread->bmlt()->get_configured_root_server_request("client_interface/json/?switcher=GetSearchResults&data_field_key=weekday_tinyint,start_time,service_body_bigint,id_bigint,meeting_name,location_text,email_contact&sort_keys=meeting_name,service_body_bigint,weekday_tinyint,start_time"); - - $unique_areas = $this->bread->bmlt()->get_areas(); - $all_meetings = array(); - foreach ($result as $value) { - foreach ($unique_areas as $unique_area) { - $area_data = explode(',', $unique_area); - $area_id = $this->bread->arraySafeGet($area_data, 1); - if ($area_id === $value['service_body_bigint']) { - $area_name = $this->bread->arraySafeGet($area_data); - } - } - - $value['start_time'] = gmdate("g:iA", strtotime($value['start_time'])); - $all_meetings[$value['id_bigint']] = wp_strip_all_tags($value['meeting_name'] . ' - ' . $this->bread->getday($value['weekday_tinyint'], true, $lang) . ' ' . $value['start_time'] . ' in ' . $area_name . ' at ' . $value['location_text']); - } - - return $all_meetings; - } - public function get_fieldkeys() - { - $ret = $this->bread->bmlt()->get_configured_root_server_request("client_interface/json/?switcher=GetFieldKeys"); - return is_null($ret) ? array() : $ret; - } - private $standard_keys = array( - "id_bigint", - "worldid_mixed", - "service_body_bigint", - "weekday_tinyint", - "start_time", - "duration_time", - "formats", - "lang_enum", - "longitude", - "latitude", - "meeting_name" . "location_text", - "location_info", - "location_street", - "location_city_subsection", - "location_neighborhood", - "location_municipality", - "location_sub_province", - "location_province", - "location_postal_code_1", - "location_nation", - "comments", - "zone" - ); - public function get_nonstandard_fieldkeys() - { - $all_fks = $this->bread->bmlt()->get_fieldkeys(); - $ret = array(); - foreach ($all_fks as $fk) { - if (!in_array($fk['key'], $this->standard_keys)) { - $ret[] = $fk; - } - } - $ext_fields = apply_filters("Bread_Enrich_Meeting_Data", array(), array()); - foreach ($ext_fields as $key => $value) { - $ret[] = array("key" => $key, "description" => $key); - } - return $ret; - } /** * Generates a list of service bodies to be used in the admin UI's drop downs. * @@ -131,7 +67,8 @@ public function get_areas() if (!empty($this->unique_areas)) { return $this->unique_areas; } - $result = $this->bread->bmlt()->get_configured_root_server_request("client_interface/json/?switcher=GetServiceBodies"); + $result = ($this->preloaded !== null) ? $this->preloaded['serviceBodies'] + : $this->get_configured_root_server_request("client_interface/json/?switcher=GetServiceBodies"); $this->unique_areas = array(); foreach ($result as $value) { @@ -149,15 +86,86 @@ public function get_areas() return $this->unique_areas; } + public function generateMainQuery($json = 'json') + { + $sort_keys = 'weekday_tinyint,start_time,meeting_name'; + $get_used_formats = '&get_used_formats'; + $select_language = '&lang_enum=' . substr($this->bread->getOption('weekday_language'), 0, 2); + $services = $this->generateDefaultQuery(); + if (isset($_GET['custom_query'])) { + $services = $_GET['custom_query']; + } elseif ($this->bread->getOption('custom_query') !== '') { + $services = $this->bread->getOption('custom_query'); + } + if ($this->bread->getOption('used_format_1') == '') { + return "client_interface/$json/?switcher=GetSearchResults$services&sort_keys=$sort_keys$get_used_formats$select_language"; + } else { + return "client_interface/$json/?switcher=GetSearchResults$services&sort_keys=$sort_keys&get_used_formats&formats[]=" . $this->bread->getOption('used_format_1') . $select_language; + } + } + public function doMainQuery() + { + if ($this->preloaded !== null) { + return $this->preloaded['mainResults']; + } + return $this->get_configured_root_server_request($this->generateMainQuery()); + } + public function generateExtraMeetingQuery($json = 'json') + { + if (empty($this->bread->getOption('extra_meetings'))) { + return null; + } + $sort_keys = 'weekday_tinyint,start_time,meeting_name'; + $get_used_formats = '&get_used_formats'; + $select_language = ''; + $extras = ""; + foreach ((array)$this->bread->getOption('extra_meetings') as $value) { + $data = array(" [", "]"); + $value = str_replace($data, "", $value); + $extras .= "&meeting_ids[]=" . $value; + } + + return "client_interface/$json/?switcher=GetSearchResults&sort_keys=" . $sort_keys . "" . $extras . "" . $get_used_formats . $select_language; + } + public function doExtraMeetingQuery() + { + if ($this->preloaded !== null) { + return $this->preloaded['extraMeetings']; + } + return $this->get_configured_root_server_request($this->generateExtraMeetingQuery()); + } + public function generateAdditionalListQuery($json = 'json') + { + if (!empty($this->options['additional_list_custom_query'])) { + $sort_order = $this->bread->getOption('additional_list_sort_order'); + if ($sort_order == 'same') { + $sort_order = 'weekday_tinyint,start_time'; + } + $services = $this->bread->getOption('additional_list_custom_query'); + return "client_interface/$json/?switcher=GetSearchResults$services&sort_keys=$sort_order"; + } + return null; + } + public function doAdditionalListQuery() + { + $url = $this->generateAdditionalListQuery(); + if ($url == null) { + return []; + } + if ($this->preloaded !== null) { + return $this->preloaded['additionalListMeetings']; + } + return $this->get_configured_root_server_request($url); + } /** * Gets the default language of the root server. * * @return string 2 character string ISO standard for the language. */ - public function get_bmlt_server_lang(): string + private function get_bmlt_server_lang(): string { if ($this->bmlt_server_lang == '') { - $result = $this->bread->bmlt()->testRootServer(); + $result = $this->testRootServer(); if (!($result && is_array($result) && is_array($result[0]))) { return 'en'; } @@ -174,9 +182,9 @@ public function get_bmlt_server_lang(): string public function testRootServer(string $override_root_server = null): array|bool { if ($override_root_server == null) { - $results = $this->bread->bmlt()->get_configured_root_server_request("client_interface/json/?switcher=GetServerInfo", true); + $results = $this->get_configured_root_server_request("client_interface/json/?switcher=GetServerInfo", true); } else { - $results = $this->bread->bmlt()->get($override_root_server . "/client_interface/json/?switcher=GetServerInfo", true); + $results = $this->get($override_root_server . "client_interface/json/?switcher=GetServerInfo", true); } if ($results instanceof WP_Error) { $this->connection_error = $results->get_error_message(); @@ -190,36 +198,6 @@ public function testRootServer(string $override_root_server = null): array|bool return json_decode(wp_remote_retrieve_body($results), true); } - /** - * This is used from the AdminUI, not to generate the meeting list. - * - * @param boolean $all should we get all the formats defined in the root server, or only those used in the service body. This respects the option recurse_service_bodies but only the first service body. - * @return array the formats - */ - public function getFormatsForSelect(bool $all = false): array - { - if ($all) { - $results = $this->bread->bmlt()->get_configured_root_server_request("client_interface/json/?switcher=GetFormats"); - $this->bread->bmlt()->sortBySubkey($results, 'key_string'); - return $results; - } - $area_data = explode(',', $this->bread->getOption('service_body_1')); - $service_body_id = $this->bread->arraySafeGet($area_data, 1); - if ($this->bread->getOption('recurse_service_bodies') == 1) { - $services = '&recursive=1&services[]=' . $service_body_id; - } else { - $services = '&services[]=' . $service_body_id; - } - if (empty($service_body_id)) { - $queryUrl = "client_interface/json/?switcher=GetFormats"; - } else { - $queryUrl = "client_interface/json/?switcher=GetSearchResults$services&get_formats_only"; - } - $results = $this->bread->bmlt()->get_configured_root_server_request($queryUrl); - $results = empty($service_body_id) ? $results : $results['formats']; - $this->sortBySubkey($results, 'key_string'); - return $results; - } /** * Convenient front end to array_multisort. Sorts the array in place. * @@ -251,27 +229,14 @@ public function generateDefaultQuery(): string // only the name of the service body. So we cache the value so it only // needs to be called once. if (!$this->default_query) { - $this->default_query = $this->addServiceBody('service_body_1'); - $this->default_query .= $this->addServiceBody('service_body_2'); - $this->default_query .= $this->addServiceBody('service_body_3'); - $this->default_query .= $this->addServiceBody('service_body_4'); - $this->default_query .= $this->addServiceBody('service_body_5'); - } - return $this->default_query; - } - private function addServiceBody($service_body_name) - { - if (false === ($this->bread->getOption($service_body_name) == 'Not Used')) { - $area_data = explode(',', $this->bread->getOption($service_body_name)); - $area = $this->bread->arraySafeGet($area_data); - $this->bread->setOption($service_body_name, ($area == 'NOT USED' ? '' : $area)); - $service_body_id = $this->bread->arraySafeGet($area_data, 1); - if ($this->bread->getOption('recurse_service_bodies') == 1) { - return '&recursive=1&services[]=' . $service_body_id; - } else { - return '&services[]=' . $service_body_id; + $this->default_query = ($this->bread->getOption('recurse_service_bodies') == 1) ? '&recursive=1' : ''; + for ($i=0; $ibread->getOption('service_bodies')); $i++) { + $area_data = explode(',', $this->bread->getOption('service_bodies')[$i]); + $service_body_id = $this->bread->arraySafeGet($area_data, 1); + $this->default_query .= '&services[]=' . $service_body_id; } } + return $this->default_query; } public function parse_field($text) { diff --git a/includes/class-bread.php b/includes/class-bread.php index 94da3290..8a27021a 100644 --- a/includes/class-bread.php +++ b/includes/class-bread.php @@ -53,9 +53,10 @@ class Bread protected $version; public const SETTINGS = 'bmlt_meeting_list_settings'; public const OPTIONS_NAME = 'bmlt_meeting_list_options'; - private $optionsName; + private string $optionsName; private $allSettings = array(); private $maxSetting = 1; + public $fonts = []; /** * The setting we are editing, generating or otherwise working with. Generally set with query string "?current-meeting-list". * @@ -240,6 +241,9 @@ public function setAndSaveSetting($id, $name): void } public function getSettingName($id) { + if (count($this->allSettings) == 0) { + return "Default Setting"; + } return $this->allSettings[$id]; } public function getSettingNames() @@ -305,7 +309,7 @@ public function &getConfigurationForSettingId($current_setting) if ($current_setting < 1) { $current_setting = is_admin() ? 1 : $this->requested_setting; } - if (is_array($this->allSettings[$current_setting])) { + if ($this->allSettings && !empty($this->allSettings[$current_setting]) && is_array($this->allSettings[$current_setting])) { $this->options = $this->allSettings[$current_setting]; } else { $this->optionsName = $this->generateOptionName($current_setting); @@ -382,6 +386,15 @@ public function __construct() $this->load_translations(); $this->define_admin_hooks(); $this->define_public_hooks(); + + $this->fonts = [ + 'dejavusanscondensed' => __('DejaVu Sans Condensed', 'bread'), + 'times' => __('New Times Roman (DejaVu Serif)', 'bread'), + 'courier' => __('Courier (DejaVu Sans Mono)', 'bread'), + 'ccourier' => __('PDF Core Font - Courier', 'bread'), + 'ctimes' => __('PDF Core Font - New Times Roman', 'bread'), + 'chelvetica' => __('PDF Core Font - Helvetica', 'bread'), + ]; } function load_translations() { @@ -498,7 +511,6 @@ private function define_admin_hooks() $this->loader->add_filter('tiny_mce_before_init', $plugin_admin, 'tiny_tweaks'); $this->loader->add_filter('mce_external_plugins', $plugin_admin, 'my_custom_plugins'); $this->loader->add_filter('mce_buttons', $plugin_admin, 'my_register_mce_button'); - //add_action("admin_notices", $plugin_admin, "is_root_server_missing"); $this->loader->add_action("admin_init", $plugin_admin, "my_theme_add_editor_styles"); $this->loader->add_action("wp_default_editor", $plugin_admin, "ml_default_editor"); $this->loader->add_filter('tiny_mce_version', $plugin_admin, 'force_mce_refresh'); @@ -528,6 +540,8 @@ private function define_public_hooks() $this->loader->add_action('wp_enqueue_scripts', $plugin_public, 'enqueue_styles'); $this->loader->add_action('wp_enqueue_scripts', $plugin_public, 'enqueue_scripts'); + $this->loader->add_action('wp_ajax_bread_generate_queries_action', $plugin_public, 'generate_preload_configuration'); + $this->loader->add_action('wp_ajax_nopriv_bread_generate_queries_action', $plugin_public, 'generate_preload_configuration'); $this->loader->add_action('plugins_loaded', $plugin_public, 'bmlt_meeting_list'); } @@ -679,6 +693,7 @@ private function fillUnsetOptionsInner() $this->fillUnsetStringOption('used_format_1', ''); $this->fillUnsetOption('base_font', 'dejavusanscondensed'); $this->fillUnsetOption('colorspace', 0); + $this->fillUnsetArrayOption('service_bodies', []); $this->fillUnsetOption('recurse_service_bodies', 1); $this->fillUnsetOption('extra_meetings_enabled', 0); $this->fillUnsetOption('include_protection', 0); @@ -721,7 +736,7 @@ private function upgrade_settings(): void || $this->options['meeting_sort'] === 'weekday_city' || $this->options['meeting_sort'] === 'weekday_county' || $this->options['meeting_sort'] === 'day')) { - $this->options['weekday_language'] = $this->bmlt()->get_bmlt_server_lang(); + $this->options['weekday_language'] = 'en'; } if ($this->options['page_fold'] == 'half') { if ($this->options['page_size'] == 'A5') { @@ -777,7 +792,7 @@ private function upgrade_settings(): void $this->renamed_option('asm_language', 'additional_list_language'); $this->renamed_option('asm_custom_query', 'additional_list_custom_query'); $this->renamed_option('asm_template_content', 'additional_list_template_content'); - if (!isset($this->options['bread_version']) || $this->options['bread_version'] < '2.8') { + if ($this->versionLessThan('2.8')) { if (($this->options['page_fold'] == 'half' || $this->options['page_fold'] == 'full') && trim($this->options['last_page_content']) !== '') { $this->options['custom_section_content'] = $this->options['last_page_content']; $this->options['custom_section_font_size'] = $this->options['last_page_font_size']; @@ -787,8 +802,55 @@ private function upgrade_settings(): void unset($this->options['last_page_font_size']); } } + if ($this->versionLessThan('2.10')) { + $this->options['service_bodies'] = []; + if (!empty($this->options['service_body_1']) && $this->options['service_body_1'] != 'Not Used') { + $this->options['service_bodies'][] = $this->options['service_body_1']; + } + if (!empty($this->options['service_body_2']) && $this->options['service_body_2'] != 'Not Used') { + $this->options['service_bodies'][] = $this->options['service_body_2']; + } + if (!empty($this->options['service_body_3']) && $this->options['service_body_3'] != 'Not Used') { + $this->options['service_bodies'][] = $this->options['service_body_3']; + } + if (!empty($this->options['service_body_4']) && $this->options['service_body_4'] != 'Not Used') { + $this->options['service_bodies'][] = $this->options['service_body_4']; + } + if (!empty($this->options['service_body_5']) && $this->options['service_body_5'] != 'Not Used') { + $this->options['service_bodies'][] = $this->options['service_body_5']; + } + unset($this->options['service_body_1']); + unset($this->options['service_body_2']); + unset($this->options['service_body_3']); + unset($this->options['service_body_4']); + unset($this->options['service_body_5']); + + if ($this->options['base_font'] == 'arial') { + $this->options['base_font'] = 'dejabusanscondensed'; + } + } $this->options['bread_version'] = BREAD_VERSION; } + private function versionLessThan($version): bool + { + if (empty($this->options['bread_version'])) { + return true; + } + $current = explode('.', $this->options['bread_version']); + $test = explode('.', $version); + for ($i=0; $i= count($test)) { + return false; + } + if (intval($current[$i]) > intval($test[$i])) { + return false; + } + if (intval($current[$i]) < intval($test[$i])) { + return true; + } + } + return false; + } private function renamed_option(string $old, string $new) { if (!empty($this->options[$old])) { diff --git a/public/class-bread-content-generator.php b/public/class-bread-content-generator.php index 7dc8d125..df3fe591 100644 --- a/public/class-bread-content-generator.php +++ b/public/class-bread-content-generator.php @@ -122,7 +122,7 @@ function __construct(Mpdf $mpdf, Bread $bread, array $result_meetings, Bread_For '

    [page_break]

    ' => '', '[page_break]' => '', '' => '', - "[area]" => strtoupper($this->options['service_body_1']), + "[area]" => strtoupper($this->options['service_bodies'][0]), '
    [new_column]
    ' => '', '

    [new_column]

    ' => '', '[new_column]' => '', @@ -133,12 +133,12 @@ function __construct(Mpdf $mpdf, Bread $bread, array $result_meetings, Bread_For "[month]" => strtoupper(gmdate("F")), "[day]" => strtoupper(gmdate("j")), "[year]" => strtoupper(gmdate("Y")), - "[service_body]" => strtoupper($this->options['service_body_1']), - "[service_body_1]" => strtoupper($this->options['service_body_1']), - "[service_body_2]" => strtoupper($this->options['service_body_2']), - "[service_body_3]" => strtoupper($this->options['service_body_3']), - "[service_body_4]" => strtoupper($this->options['service_body_4']), - "[service_body_5]" => strtoupper($this->options['service_body_5']), + "[service_body]" => (count($this->options['service_bodies']) > 0) ? explode(',', strtoupper($this->options['service_bodies'][0]))[0] : 'Not Used', + "[service_body_1]" => (count($this->options['service_bodies']) > 0) ?explode(',', strtoupper($this->options['service_bodies'][0]))[0] : 'Not Used', + "[service_body_2]" => (count($this->options['service_bodies']) > 1) ? explode(',', strtoupper($this->options['service_bodies'][1]))[0] : 'Not Used', + "[service_body_3]" => (count($this->options['service_bodies']) > 2) ? explode(',', strtoupper($this->options['service_bodies'][2]))[0] : 'Not Used', + "[service_body_4]" => (count($this->options['service_bodies']) > 3) ? explode(',', strtoupper($this->options['service_bodies'][3]))[0] : 'Not Used', + "[service_body_5]" => (count($this->options['service_bodies']) > 4) ? explode(',', strtoupper($this->options['service_bodies'][4]))[0] : 'Not Used', ); $this->shortcodes = apply_filters("Bread_Section_Shortcodes", $this->shortcodes, $this->bread->bmlt()->get_areas(), $formatsManager->getFormatsUsed()); @@ -580,17 +580,7 @@ function write_additional_meetinglist() * If we are selecting the meetings in the second list based on some format, we don't need another BMLT query. */ if (empty($this->options['additional_list_format_key'])) { - $additional_list_query = true; - $sort_order = $this->options['additional_list_sort_order']; - if ($sort_order == 'same') { - $sort_order = 'weekday_tinyint,start_time'; - } - $services = $this->bread->bmlt()->generateDefaultQuery(); - if (!empty($this->options['additional_list_custom_query'])) { - $services = $this->options['additional_list_custom_query']; - } - $additional_list_query = "client_interface/json/?switcher=GetSearchResults$services&sort_keys=$sort_order"; - $additional_meetinglist_result = $this->bread->bmlt()->get_configured_root_server_request($additional_list_query); + $additional_meetinglist_result = $this->bread->bmlt()->doAdditionalListQuery(); $this->adjust_timezone($additional_meetinglist_result, $this->target_timezone); } if ($additional_list_query || $this->options['weekday_language'] != $this->options['additional_list_language']) { diff --git a/public/class-bread-public.php b/public/class-bread-public.php index 4f3e9cd6..0584942f 100644 --- a/public/class-bread-public.php +++ b/public/class-bread-public.php @@ -3,10 +3,12 @@ exit; } use Mpdf\Mpdf; +use Mpdf\Config\ConfigVariables; use Monolog\Logger; use Monolog\Handler\StreamHandler; use Monolog\Level; +define('MPDF_MODE', 's'); // Try to keep the file small by subsetting fonts and only including the characters we need. This is especially important for languages with large character sets like Chinese, Japanese, and Korean. If you have a lot of different characters in your meeting list, you may want to switch to 'utf-8' or 'c' mode which includes more characters but results in larger file sizes. /** * Main class for generating the PDF meeting list. * @@ -19,7 +21,6 @@ */ class Bread_Public { - /** * The ID of this plugin. * @@ -67,6 +68,10 @@ public function __construct($plugin_name, $version, $bread) $this->version = $version; $this->bread = $bread; $this->options = $bread->getOptions(); + add_shortcode('bread_button', array( + &$this, + "doBreadButton" + )); } /** @@ -76,7 +81,9 @@ public function __construct($plugin_name, $version, $bread) */ public function enqueue_styles() { - wp_enqueue_style($this->plugin_name, plugin_dir_url(__FILE__) . 'css/bread-public.css', array(), $this->version, 'all'); + if (($current = $this->doPreloading()) > 0) { + wp_enqueue_style('bread-public', plugin_dir_url(__FILE__) . 'css/bread-public.css', array(), $this->version, 'all'); + } } /** @@ -86,14 +93,79 @@ public function enqueue_styles() */ public function enqueue_scripts() { - wp_enqueue_script($this->plugin_name, plugin_dir_url(__FILE__) . 'js/bread-public.js', array('jquery'), $this->version, false); + if (($current = $this->doPreloading()) > 0) { + wp_enqueue_script('fetch-jsonp', plugin_dir_url(__FILE__) . 'js/fetch-jsonp.js', array(), $this->version, true); + wp_enqueue_script($this->plugin_name, plugin_dir_url(__FILE__) . 'js/bread-public.js', array('jquery','fetch-jsonp'), $this->version, true); + wp_localize_script($this->plugin_name, 'ajax_object', [ + 'ajax_url' => admin_url('admin-ajax.php'), + 'nonce' => wp_create_nonce('bread-ajax-nonce'), // Can use the same even if there are multiple buttons on the page since WP nonces are single use but can be used multiple times within 24 hours + ]); + } } - - public function bmlt_meeting_list($atts = null, $content = null) + /** + * Check if the shortcode is being used on this page. + * + * @return int the id of the configuration + */ + private function doPreloading(): int + { + $post_to_check = get_post(get_the_ID()); + $post_content = $post_to_check->post_content ?? ''; + $tags = ['bread_button']; + preg_match_all('/' . get_shortcode_regex($tags) . '/', $post_content, $matches, PREG_SET_ORDER); + if (empty($matches)) { + return -1; + } + foreach ($matches as $shortcode) { + switch ($shortcode[2]) { + case 'bread_button': + $atts = shortcode_parse_atts($shortcode[3]); + return intval($atts['current_meeting_list']); + } + } + return -1; + } + public function generate_preload_configuration(): string + { + if (!wp_verify_nonce($_GET['nonce'], 'bread-ajax-nonce')) { + wp_die('Security check failed'); + } + $id = intval($_GET['current-meeting-list'] ?? 1); + $options = $this->bread->getConfigurationForSettingId($id); + ob_clean(); + wp_send_json([ + 'root_server' => $options['root_server'], + 'main_query' => $this->bread->bmlt()->generateMainQuery('jsonp'), + 'extra_meetings_query' => $this->bread->bmlt()->generateExtraMeetingQuery('jsonp'), + 'additional_list_query' => $this->bread->bmlt()->generateAdditionalListQuery('jsonp'), + 'weekday_language' => $options['weekday_language'], + 'additional_list_language' => $options['additional_list_language'], + ]); + die(); + } + public function doBreadButton($atts) + { + $label = $atts['label'] ?? 'Generate PDF'; + $id = $atts['current_meeting_list'] ?? "1"; + return "
    ". + "". + "". + "". + "". + "
    "; + } + public function bmlt_meeting_list() { if (!$this->bread->generatingMeetingList()) { return; } + if (!empty($_POST['preload'])) { + if (! wp_verify_nonce($_POST['nonce'], 'bread-button-nonce')) { + die; + } + $preload = json_decode($_POST['preload'], true); + $this->bread->bmlt()->preload($preload); + } $this->options = $this->bread->getConfigurationForSettingId($this->bread->getRequestedSetting()); $import_streams = []; ini_set('max_execution_time', 600); // tomato server can take a long time to generate a schedule, override the server setting @@ -102,7 +174,7 @@ public function bmlt_meeting_list($atts = null, $content = null) echo '

    bread Error: BMLT Server missing.

    Please go to Settings -> bread and verify BMLT Server

    '; exit; } - if ($this->options['service_body_1'] == 'Not Used' && true === ($this->options['custom_query'] == '')) { + if (count($this->options['service_bodies']) == 0 && true === ($this->options['custom_query'] == '')) { echo '

    bread Error: Service Body 1 missing from configuration.

    Please go to Settings -> bread and verify Service Body


    Contact the bread administrator and report this problem!

    '; exit; } @@ -128,13 +200,7 @@ public function bmlt_meeting_list($atts = null, $content = null) exit; } } - $page_type_settings = $this->constuct_page_type_settings(); - $default_font = $this->options['base_font'] == "freesans" ? "dejavusanscondensed" : $this->options['base_font']; - $mode = 's'; - $mpdf_init_options = $this->construct_init_options($default_font, $mode, $page_type_settings); - if (isset($this->options['packTabledata']) && $this->options['packTabledata']) { - $mpdf_init_options['packTabledata'] = true; - } + @ob_end_clean(); // We load mPDF only when we need to and as late as possible. This prevents // conflicts with other plugins that use the same PSRs in different versions @@ -143,6 +209,11 @@ public function bmlt_meeting_list($atts = null, $content = null) include_once plugin_dir_path(__FILE__) . '../vendor/autoload.php'; require_once __DIR__ . '/class-bread-content-generator.php'; require_once __DIR__ . '/class-bread-format-manager.php'; + $default_font = $this->options['base_font']; + $mpdf_init_options = $this->construct_init_options($default_font); + if (isset($this->options['packTabledata']) && $this->options['packTabledata']) { + $mpdf_init_options['packTabledata'] = true; + } $this->mpdf = new mPDF($mpdf_init_options); if (isset($this->options['logging']) && $this->options['logging']) { $logger = new Logger('bread-log'); @@ -173,25 +244,9 @@ public function bmlt_meeting_list($atts = null, $content = null) if ($this->options['column_line'] == 1 && ($this->options['page_fold'] == 'tri' || $this->options['page_fold'] == 'quad') ) { - $this->drawLinesSeperatingColumns($mode, $mpdf_init_options['format'], $default_font); - } - $sort_keys = 'weekday_tinyint,start_time,meeting_name'; - $get_used_formats = '&get_used_formats'; - $select_language = ''; - if ($this->options['weekday_language'] != $this->bread->bmlt()->get_bmlt_server_lang()) { - $select_language = '&lang_enum=' . $this->getSingleLanguage($this->options['weekday_language']); - } - $services = $this->bread->bmlt()->generateDefaultQuery(); - if (isset($_GET['custom_query'])) { - $services = $_GET['custom_query']; - } elseif ($this->options['custom_query'] !== '') { - $services = $this->options['custom_query']; - } - if ($this->options['used_format_1'] == '') { - $result = $this->bread->bmlt()->get_configured_root_server_request("client_interface/json/?switcher=GetSearchResults$services&sort_keys=$sort_keys$get_used_formats$select_language"); - } elseif ($this->options['used_format_1'] != '') { - $result = $this->bread->bmlt()->get_configured_root_server_request("client_interface/json/?switcher=GetSearchResults$services&sort_keys=$sort_keys&get_used_formats&formats[]=" . $this->options['used_format_1'] . $select_language); + $this->drawLinesSeperatingColumns($mpdf_init_options['format'], $default_font); } + $result = $this->bread->bmlt()->doMainQuery(); if ($result == null) { echo "