Plugin Directory

Changeset 3799472


Ignore:
Timestamp:
11/13/2026 12:28:48 AM (less than one hour ago)
Author:
nigelbmlt
Message:

Deploy version 1.2.4

Location:
bmlt-workflow/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • bmlt-workflow/trunk/CHANGELOG.md

    r3777421 r3799472  
     1## 1.2.4 (November 12, 2026)
     2- #239 Fixes the whole site slowing to ~35-40s per page (and fatal errors on form pages) when the configured BMLT Root Server is slow or unreachable: server info lookups now use a short 5s timeout, failures are briefly cached so an unreachable server no longer triggers a blocking network call on every page load, REST request and 404, and the version lookup is no longer made during plugin bootstrap on every request.
     3- The meeting update form now shows an inline error notice instead of a fatal `wp_die()` when the BMLT server can't be reached, so the rest of the page still renders.
     4
    15## 1.2.3 (October 31, 2026)
    26- Fixes approving a change to a meeting that has coordinates but no timezone; the timezone is now resolved from the meeting's existing coordinates via the geo service.
  • bmlt-workflow/trunk/bmlt-workflow.php

    r3777421 r3799472  
    2121 * Plugin URI: https://github.com/bmlt-enabled/bmlt-workflow
    2222 * Description: Workflows for BMLT meeting management!
    23  * Version: 1.2.3
     23 * Version: 1.2.4
    2424 * Requires at least: 5.2
    2525 * Author: @nigel-bmlt
    … …  
    3030
    3131
    32 define('BMLTWF_PLUGIN_VERSION', '1.2.3');
     32define('BMLTWF_PLUGIN_VERSION', '1.2.4');
    3333
    3434if ((!defined('ABSPATH') && (!defined('BMLTWF_RUNNING_UNDER_PHPUNIT')))) exit; // die if being called directly
    … …  
    170170        }
    171171
     172        /**
     173         * Render a non-fatal error notice for a shortcode.
     174         *
     175         * Returned (not wp_die'd) so the surrounding page - theme, header,
     176         * footer and any other content - still renders when the BMLT server is
     177         * unreachable or misconfigured.
     178         *
     179         * @param string $message Human-readable error detail.
     180         * @return string
     181         */
     182        private function bmltwf_form_error($message)
     183        {
     184            return '<div class="bmltwf-error-notice" style="padding:1em;border:1px solid #c00;background:#fff3f3;color:#900;">'
     185                . '<strong>' . esc_html__('BMLT Workflow Plugin Error', 'bmlt-workflow') . ':</strong> '
     186                . esc_html($message)
     187                . '</div>';
     188        }
     189
    172190        public function bmltwf_meeting_update_form($atts = [], $content = null, $tag = '')
    173191        {
    … …  
    175193            $bmltwf_bmlt_test_status = get_option('bmltwf_bmlt_test_status', "failure");
    176194            if ($bmltwf_bmlt_test_status != "success") {
    177                 wp_die("<h4>BMLTWF Plugin Error: BMLT Root Server not configured and tested.</h4>");
     195                return $this->bmltwf_form_error(__('BMLT Root Server not configured and tested.', 'bmlt-workflow'));
    178196            }
    179197            // $this->debug_log(("inside shortcode setup"));
    … …  
    207225            $meeting_counties_and_sub_provinces = $this->bmlt_integration->getMeetingCounties();
    208226            if (is_wp_error($meeting_counties_and_sub_provinces)) {
    209                 wp_die("<h4>" . __('BMLTWF Plugin Error: Unable to retrieve meeting counties from BMLT server.', 'bmlt-workflow') . "</h4>");
     227                return $this->bmltwf_form_error(__('Unable to retrieve meeting counties from BMLT server.', 'bmlt-workflow'));
    210228            }
    211229            $script .= "var bmltwf_counties_and_sub_provinces = " . json_encode($meeting_counties_and_sub_provinces) . ";";
    … …  
    218236            $meeting_states_and_provinces = $this->bmlt_integration->getMeetingStates();
    219237            if (is_wp_error($meeting_states_and_provinces)) {
    220                 wp_die("<h4>" . __('BMLTWF Plugin Error: Unable to retrieve meeting states/provinces from BMLT server.', 'bmlt-workflow') . "</h4>");
     238                return $this->bmltwf_form_error(__('Unable to retrieve meeting states/provinces from BMLT server.', 'bmlt-workflow'));
    221239            }
    222240            $script .= "var bmltwf_do_states_and_provinces = " . json_encode($meeting_states_and_provinces) . ";";
    … …  
    229247            $formatarr = $this->bmlt_integration->getMeetingFormats();
    230248            if (is_wp_error($formatarr)) {
    231                 wp_die("<h4>" . __('BMLTWF Plugin Error: Unable to retrieve meeting formats from BMLT server.', 'bmlt-workflow') . "</h4>");
     249                return $this->bmltwf_form_error(__('Unable to retrieve meeting formats from BMLT server.', 'bmlt-workflow'));
    232250            }
    233251
    … …  
    245263            $result = rest_get_server()->response_to_data($response, true);
    246264            if (count($result) == 0) {
    247                 wp_die("<h4>BMLT Workflow Plugin Error: Service bodies not configured.</h4>");
     265                return $this->bmltwf_form_error(__('Service bodies not configured.', 'bmlt-workflow'));
    248266            }
    249267            $script .= 'var bmltwf_service_bodies = ' . json_encode($result) . '; ';
  • bmlt-workflow/trunk/readme.txt

    r3777421 r3799472  
    55Requires PHP: 8.0
    66License: GPLv2
    7 Stable tag: 1.2.3
     7Stable tag: 1.2.4
    88Contributors: nigelbmlt, pjaudiomv
    99
  • bmlt-workflow/trunk/src/BMLT/Integration.php

    r3777421 r3799472  
    114114        }
    115115
    116         if (empty($root_server_version)) {
    117             $server_address = \get_option('bmltwf_bmlt_server_address');
    118             if ($server_address && $server_address !== 'true' && filter_var($server_address, FILTER_VALIDATE_URL)) {
    119                 $this->bmlt_root_server_version = $this->bmltwf_get_remote_server_version($server_address);
    120             }
    121         } else {
     116        if (!empty($root_server_version)) {
    122117            $this->bmlt_root_server_version = $root_server_version;
    123118        }
     119        // Otherwise resolve the version lazily via getRootServerVersion(). This
     120        // class is constructed during plugin bootstrap on every request, so
     121        // fetching the version here used to make a blocking HTTP call to the
     122        // BMLT server on every page load - taking the whole site down when that
     123        // server was slow or unreachable.
    124124    }
    125125
    … …  
    143143    }
    144144
     145    /**
     146     * Lazily resolve and cache the BMLT root server version.
     147     *
     148     * @return string|false|null
     149     */
     150    public function getRootServerVersion()
     151    {
     152        if ($this->bmlt_root_server_version === null) {
     153            $server_address = \get_option('bmltwf_bmlt_server_address');
     154            if ($server_address && $server_address !== 'true' && filter_var($server_address, FILTER_VALIDATE_URL)) {
     155                $this->bmlt_root_server_version = $this->bmltwf_get_remote_server_version($server_address);
     156            }
     157        }
     158        return $this->bmlt_root_server_version;
     159    }
     160
    145161    public function update_root_server_version()
    146162    {
    147163        $server_address = \get_option('bmltwf_bmlt_server_address');
    148         // Clear the cache to force a fresh fetch
     164        // Clear the cache (and any negative-cache marker) to force a fresh fetch
    149165        \delete_transient('bmltwf_server_info_' . md5($server_address));
     166        \delete_transient('bmltwf_server_info_fail_' . md5($server_address));
    150167        $new_version = $this->bmltwf_get_remote_server_version($server_address);
    151168        $this->bmlt_root_server_version = $new_version;
    … …  
    178195    private function bmltwf_get_server_info_cached($server)
    179196    {
     197        if (empty($server)) {
     198            return false;
     199        }
     200
    180201        $cache_key = 'bmltwf_server_info_' . md5($server);
    181        
     202        $fail_key  = 'bmltwf_server_info_fail_' . md5($server);
     203
    182204        // Skip cache if nocache parameter is present
    183205        $use_cache = !isset($_GET['nocache']);
    184        
     206
    185207        if ($use_cache) {
    186208            $cached = \get_transient($cache_key);
    … …  
    188210                return $cached;
    189211            }
    190         }
    191        
     212            // Negative cache: if we recently failed to reach the server, don't
     213            // block this request on another (likely slow) network call. This
     214            // prevents an unreachable/slow BMLT server from stalling every page
     215            // load, REST request and 404.
     216            if (\get_transient($fail_key) !== false) {
     217                return false;
     218            }
     219        }
     220
    192221        $url = $server . "client_interface/json/?switcher=GetServerInfo";
    193222        $headers = array("Accept: */*");
    194         $resp = $this->bmltwf_wp_remote_get($url, array('headers' => $headers));
    195        
     223        // Use a short, explicit timeout so a slow server fails fast rather than
     224        // hanging on WP's default timeout and stacking across multiple calls.
     225        $resp = $this->bmltwf_wp_remote_get($url, array('headers' => $headers, 'timeout' => 5));
     226
    196227        if (is_wp_error($resp) || \wp_remote_retrieve_response_code($resp) != 200) {
     228            if ($use_cache) {
     229                \set_transient($fail_key, 1, 60);
     230            }
    197231            return false;
    198232        }
    199        
     233
    200234        $data = json_decode(\wp_remote_retrieve_body($resp), true);
    201235        if ($data === null || !isset($data[0])) {
     236            if ($use_cache) {
     237                \set_transient($fail_key, 1, 60);
     238            }
    202239            return false;
    203240        }
    204        
     241
    205242        // Cache for 1 hour (3600 seconds) if caching is enabled
    206243        if ($use_cache) {
     244            \delete_transient($fail_key);
    207245            \set_transient($cache_key, $data[0], 3600);
    208246        }
    209        
     247
    210248        return $data[0];
    211249    }
  • bmlt-workflow/trunk/src/REST/Handlers/BMLTServerHandler.php

    r3765048 r3799472  
    111111        if ($current_server !== $server) {
    112112            \delete_transient('bmltwf_server_info_' . md5($server));
     113            \delete_transient('bmltwf_server_info_fail_' . md5($server));
    113114        }
    114115
Note: See TracChangeset for help on using the changeset viewer.