diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0d60308..11acaf7 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 5146f29..772366b 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 0000000..1015402
Binary files /dev/null and b/src/assets/img/default-property.jpg differ
diff --git a/src/phpunit.xml b/src/phpunit.xml
index 44f0fdb..9fa13ad 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 704c56a..6d8df45 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 950b3e4..a009f8d 100644
--- a/src/simply-rets-admin.php
+++ b/src/simply-rets-admin.php
@@ -19,19 +19,24 @@
class SrAdminSettings {
+ public static function invalidateLegacyPageCounts() {
+ SimplyRetsSetup::invalidateLegacyPageCounts();
+ }
+
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 f6f158d..38d4aa6 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 5689cc6..551459d 100644
--- a/src/simply-rets-renderer.php
+++ b/src/simply-rets-renderer.php
@@ -1994,7 +1994,7 @@ public static function renderSearchForm($atts) {