From 0121cdde00ce071e0d6e23ee7d2c2a32ec07125d Mon Sep 17 00:00:00 2001 From: Cody Reichert Date: Sun, 11 Oct 2026 19:46:53 -0500 Subject: [PATCH 1/2] Fix Plugin Check findings and retain WordPress 4.7 compatibility --- .github/workflows/ci.yml | 9 +- CHANGELOG | 7 + src/assets/img/default-property.jpg | Bin 0 -> 65213 bytes src/phpunit.xml | 2 +- src/readme.txt | 12 +- src/simply-rets-admin.php | 18 ++- src/simply-rets-openhouses.php | 33 ++++- src/simply-rets-renderer.php | 4 +- src/simply-rets-utils.php | 6 +- src/simply-rets.php | 2 + src/tests/bootstrap.php | 8 +- src/tests/test-legacy-pages.php | 35 +++++ src/tests/test-plugin-check-compatibility.php | 122 ++++++++++++++++++ 13 files changed, 239 insertions(+), 19 deletions(-) create mode 100644 src/assets/img/default-property.jpg create mode 100644 src/tests/test-plugin-check-compatibility.php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0d603085..11acaf71 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,7 @@ jobs: strategy: fail-fast: false matrix: - php: ["7.4", "8.1"] + php: ["7.0", "7.4", "8.1"] steps: - uses: actions/checkout@v4 @@ -85,6 +85,13 @@ jobs: working-directory: src run: bash tests/install-wp-tests.sh wordpress_test root root 127.0.0.1 ${{ matrix.wordpress }} true + - name: Install WordPress test polyfills + run: | + mkdir -p /tmp/wordpress-test-tools + composer require --working-dir=/tmp/wordpress-test-tools --no-interaction --no-progress yoast/phpunit-polyfills:^4.0 phpunit/phpunit:^9.6 + - name: Run tests working-directory: src + env: + WP_TESTS_PHPUNIT_POLYFILLS_PATH: /tmp/wordpress-test-tools/vendor/yoast/phpunit-polyfills run: phpunit diff --git a/CHANGELOG b/CHANGELOG index 5146f290..772366b8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,12 @@ # Changelog +## Unreleased + +* FIX: Resolve Plugin Check findings while preserving existing markup and customization hooks +* FIX: Support open-house timezone conversion on WordPress 4.7 through 5.2 +* IMPROVE: Bundle the existing fallback listing photo and use cached WordPress counts for Legacy Pages +* REQUIRE: WordPress 4.7 or later; PHP 7.0.27 or later remains supported + ## 3.3.0 * FIX: Escape API error messages to prevent reflected cross-site scripting on listing pages diff --git a/src/assets/img/default-property.jpg b/src/assets/img/default-property.jpg new file mode 100644 index 0000000000000000000000000000000000000000..101540218f24d5f4cc01f64fb641bfb984c39810 GIT binary patch literal 65213 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 literal 0 HcmV?d00001 diff --git a/src/phpunit.xml b/src/phpunit.xml index 44f0fdb6..9fa13ad9 100644 --- a/src/phpunit.xml +++ b/src/phpunit.xml @@ -7,7 +7,7 @@ convertWarningsToExceptions="true" > - + ./tests/ diff --git a/src/readme.txt b/src/readme.txt index 704c56ae..6d8df451 100644 --- a/src/readme.txt +++ b/src/readme.txt @@ -2,8 +2,9 @@ Author: SimplyRETS Contributors: SimplyRETS Tags: real estate, idx, mls, rets, reso web api -Requires at least: 3.0.1 -Tested up to: 7.0 +Requires at least: 4.7 +Requires PHP: 7.0.27 +Tested up to: 7.1 Stable tag: 3.3.0 License: GPLv3 License URI: http://www.gnu.org/licenses/gpl-3.0.html @@ -235,6 +236,13 @@ listing sidebar widget. == Changelog == += Unreleased = + +* FIX: Resolve Plugin Check findings while preserving existing markup and customization hooks +* FIX: Support open-house timezone conversion on WordPress 4.7 through 5.2 +* IMPROVE: Bundle the existing fallback listing photo and use cached WordPress counts for Legacy Pages +* REQUIRE: WordPress 4.7 or later; PHP 7.0.27 or later remains supported + = 3.3.0 = * FIX: Escape API error messages to prevent reflected cross-site scripting on listing pages diff --git a/src/simply-rets-admin.php b/src/simply-rets-admin.php index 950b3e49..dde58571 100644 --- a/src/simply-rets-admin.php +++ b/src/simply-rets-admin.php @@ -16,22 +16,30 @@ add_action("admin_notices", array("SrAdminSettings", "adminMessages")); add_action('admin_notices', array('SrAdminSettings', 'legacyPagesNotice')); add_action('admin_post_sr_dismiss_legacy_pages_notice', array('SrAdminSettings', 'dismissLegacyPagesNotice')); +add_action('clean_post_cache', array('SrAdminSettings', 'invalidateLegacyPageCounts')); class SrAdminSettings { + public static function invalidateLegacyPageCounts() { + // Core clears counts on status transitions, but not every deletion or + // post-type change. Follow post cache invalidation for both cases. + wp_cache_delete('posts-sr-listings', 'counts'); + } + public static function canManageLegacyPages() { $post_type = get_post_type_object('sr-listings'); return $post_type && current_user_can('manage_options') && current_user_can($post_type->cap->edit_posts); } public static function hasLegacyPages() { - global $wpdb; // Look for persisted posts only, including drafts, private pages and trash. // Automatic drafts are editor placeholders; dynamic routes are not stored. - return $wpdb->get_var($wpdb->prepare( - "SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_status NOT IN (%s, %s) LIMIT 1", - 'sr-listings', 'auto-draft', 'inherit' - )) !== null; + foreach (wp_count_posts('sr-listings') as $status => $count) { + if ($status !== 'auto-draft' && $status !== 'inherit' && $count > 0) { + return true; + } + } + return false; } public static function legacyPagesSettingsUrl() { diff --git a/src/simply-rets-openhouses.php b/src/simply-rets-openhouses.php index f6f158df..38d4aa62 100644 --- a/src/simply-rets-openhouses.php +++ b/src/simply-rets-openhouses.php @@ -12,6 +12,28 @@ class SimplyRetsOpenHouses { + /** Get the site's timezone on WordPress versions before and after 5.3. */ + private static function siteTimezone() { + if (function_exists('wp_timezone')) { + return wp_timezone(); + } + + $timezone_string = get_option('timezone_string'); + if (!$timezone_string) { + $offset = (float) get_option('gmt_offset'); + $hours = (int) $offset; + $minutes = ($offset - $hours) * 60; + $timezone_string = sprintf( + '%s%02d:%02d', + $offset < 0 ? '-' : '+', + abs($hours), + abs($minutes) + ); + } + + return new DateTimeZone($timezone_string); + } + /** * Get open house data for a listingId. * Return an empty array if no openhouses exist. @@ -41,7 +63,8 @@ public static function getOpenHouseDateTimes($openhouse) { */ // 1. Get the setting. - $timezone_setting = get_option("sr_date_default_timezone", wp_timezone()); + $site_timezone = self::siteTimezone(); + $timezone_setting = get_option("sr_date_default_timezone", $site_timezone); $timezone_name_string = ''; // 2. Reliably get the timezone *string* name @@ -50,7 +73,7 @@ public static function getOpenHouseDateTimes($openhouse) { } elseif (is_string($timezone_setting) && !empty($timezone_setting)) { $timezone_name_string = $timezone_setting; } else { - $timezone_name_string = wp_timezone_string(); + $timezone_name_string = timezone_name_get($site_timezone); } // 3. Create a DateTimeZone object from the string @@ -59,7 +82,7 @@ public static function getOpenHouseDateTimes($openhouse) { // 4. Validation if ($display_time_zone_object === false) { // Fall back to the default WP timezone object - $display_time_zone_object = wp_timezone(); + $display_time_zone_object = $site_timezone; } // 5. Create DateTime objects FROM the UTC string. @@ -225,12 +248,12 @@ class="sr-photo"
diff --git a/src/simply-rets-renderer.php b/src/simply-rets-renderer.php index 5689cc60..551459dc 100644 --- a/src/simply-rets-renderer.php +++ b/src/simply-rets-renderer.php @@ -1994,7 +1994,7 @@ public static function renderSearchForm($atts) {