Changeset 3418432
- Timestamp:
- 12/12/2025 05:02:23 PM (3 months ago)
- Location:
- weather-write/trunk
- Files:
-
- 4 edited
-
includes/class-admin.php (modified) (1 diff)
-
includes/class-scheduler.php (modified) (1 diff)
-
readme.txt (modified) (2 diffs)
-
weather-write.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
weather-write/trunk/includes/class-admin.php
r3393864 r3418432 1346 1346 // Help: placeholders available to the model 1347 1347 echo '<p class="description">' . esc_html__( 'Possible fields you can reference in your instructions (the AI will infer or be given these values):', 'weather-write') . '</p>'; 1348 // Use current date for examples to keep them fresh 1349 $example_date = current_time( 'timestamp' ); 1350 $ex_numeric = wp_date( 'n/j/y', $example_date ); 1351 $ex_long = wp_date( 'F j, Y', $example_date ); 1352 $ex_abbrev = wp_date( 'M j', $example_date ); 1353 $ex_abbrev_dot = wp_date( 'M. j', $example_date ); 1354 $ex_iso = wp_date( 'Y-m-d', $example_date ); 1348 1355 echo '<ul style="margin:.3em 0 0 1.2em; list-style:disc"' 1349 . '<li><code>{date}</code> — ' . esc_html__( 'Numeric date like 8/18/25', 'weather-write') . '</li>'1350 . '<li><code>{date_long}</code> — ' . esc_html__( 'Long date: August 2, 2025', 'weather-write') . '</li>'1351 . '<li><code>{date_abbrev}</code> — ' . esc_html__( 'Abbreviated month: Aug 2', 'weather-write') . '</li>'1352 . '<li><code>{date_abbrev_dot}</code> — ' . esc_html__( 'Abbreviated month with period: Aug. 2', 'weather-write') . '</li>'1353 . '<li><code>{date_iso}</code> — ' . esc_html__( 'ISO style: 2025-08-02', 'weather-write') . '</li>'1356 . '<li><code>{date}</code> — ' . sprintf( esc_html__( 'Numeric date like %s', 'weather-write'), $ex_numeric ) . '</li>' 1357 . '<li><code>{date_long}</code> — ' . sprintf( esc_html__( 'Long date: %s', 'weather-write'), $ex_long ) . '</li>' 1358 . '<li><code>{date_abbrev}</code> — ' . sprintf( esc_html__( 'Abbreviated month: %s', 'weather-write'), $ex_abbrev ) . '</li>' 1359 . '<li><code>{date_abbrev_dot}</code> — ' . sprintf( esc_html__( 'Abbreviated month with period: %s', 'weather-write'), $ex_abbrev_dot ) . '</li>' 1360 . '<li><code>{date_iso}</code> — ' . sprintf( esc_html__( 'ISO style: %s', 'weather-write'), $ex_iso ) . '</li>' 1354 1361 . '<li><code>{city}</code> / <code>{location}</code> — ' . esc_html__( 'Location/city name', 'weather-write') . '</li>' 1355 1362 . '<li><code>{condition}</code> — ' . esc_html__( 'Current weather summary', 'weather-write') . '</li>' -
weather-write/trunk/includes/class-scheduler.php
r3393864 r3418432 175 175 $slot_time = $hm ? wp_date( 'Y-m-d H:i:s', strtotime( $hm ), $tz ) : wp_date( 'Y-m-d H:i:s' ); 176 176 $location_key = wwrt_compute_location_key(); 177 178 // Deduplication guard: prevent multiple successful runs for the same date, time slot, and location. 179 // This protects against double triggers from internal WP-Cron, external cron, or retries. 180 $hm_key = ( is_string( $hm ) && preg_match( '/^\d{2}:\d{2}$/', $hm ) ) ? $hm : ''; 181 if ( $hm_key !== '' ) { 182 // Normalize to the site-local date for this run 183 $today_local = function_exists( 'wp_date' ) ? wp_date( 'Y-m-d', null, $tz ) : date_i18n( 'Y-m-d' ); 184 $dedupe_key = 'wwrt_run_' . md5( $today_local . '|' . $hm_key . '|' . $location_key ); 185 if ( get_transient( $dedupe_key ) ) { 186 // A run for this slot has already been executed recently; skip to avoid duplicate posts and API usage. 187 wwrt_log_and_notify( 'duplicate_run', 'Duplicate run prevented for this time slot', [ 188 'slot_time' => $slot_time, 189 'location_key' => $location_key, 190 'run_id' => $run_id, 191 ], false ); 192 return new WP_Error( 'wwrt_duplicate_run', 'A run for this time slot has already been executed.' ); 193 } 194 // Mark this slot as in-progress/done for a short window (15 minutes is plenty for a single run). 195 set_transient( $dedupe_key, 'running', 15 * MINUTE_IN_SECONDS ); 196 } 177 197 178 198 // CRITICAL: Use try/finally to ALWAYS schedule next run, even on failure -
weather-write/trunk/readme.txt
r3393864 r3418432 4 4 Requires at least: 6.5 5 5 Tested up to: 6.8 6 Stable tag: 1.3. 16 Stable tag: 1.3.2 7 7 License: GPLv2 or later 8 8 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 87 87 88 88 == Changelog == 89 90 = 1.3.2 = 91 - CRITICAL FIX: Added slot-level deduplication to prevent duplicate scheduled runs for the same time and location 92 - RELIABILITY: Protects against double posts and double API usage when multiple triggers fire for the same slot 93 - TECHNICAL: Uses a transient key based on local date, schedule time, and location to short-circuit duplicate runs 89 94 90 95 = 1.3.1 = -
weather-write/trunk/weather-write.php
r3393864 r3418432 3 3 * Plugin Name: Weather Write 4 4 * Description: Generate and publish weather-aware posts with summaries, charts, images, alerts, SEO, and more — fully automated or on-demand. 5 * Version: 1.3. 15 * Version: 1.3.2 6 6 * Author: Mike Freeman - WeatherWrite 7 7 * Plugin URI: https://www.weatherwrite.com/
Note: See TracChangeset
for help on using the changeset viewer.