Changeset 3803670
- Timestamp:
- 11/15/2026 06:04:19 PM (less than one hour ago)
- Location:
- site-reviews
- Files:
-
- 98 edited
- 1 copied
-
tags/8.3.8 (copied) (copied from site-reviews/trunk )
-
tags/8.3.8/changelog.txt (modified) (1 diff)
-
tags/8.3.8/languages/site-reviews-en_US.po (modified) (19 diffs)
-
tags/8.3.8/languages/site-reviews.pot (modified) (18 diffs)
-
tags/8.3.8/plugin/Api.php (modified) (2 diffs)
-
tags/8.3.8/plugin/Commands/CreateReview.php (modified) (3 diffs)
-
tags/8.3.8/plugin/Commands/FetchPagedReviews.php (modified) (1 diff)
-
tags/8.3.8/plugin/Controllers/AdminController.php (modified) (7 diffs)
-
tags/8.3.8/plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php (modified) (3 diffs)
-
tags/8.3.8/plugin/Controllers/Api/Version1/RestReviewController.php (modified) (1 diff)
-
tags/8.3.8/plugin/Controllers/EditorController.php (modified) (1 diff)
-
tags/8.3.8/plugin/Controllers/ListTableController.php (modified) (2 diffs)
-
tags/8.3.8/plugin/Controllers/MainController.php (modified) (1 diff)
-
tags/8.3.8/plugin/Controllers/PrivacyController.php (modified) (1 diff)
-
tags/8.3.8/plugin/Controllers/ToolsController.php (modified) (2 diffs)
-
tags/8.3.8/plugin/Controllers/VerificationController.php (modified) (2 diffs)
-
tags/8.3.8/plugin/Database.php (modified) (3 diffs)
-
tags/8.3.8/plugin/Database/OptionManager.php (modified) (3 diffs)
-
tags/8.3.8/plugin/Database/Query.php (modified) (3 diffs)
-
tags/8.3.8/plugin/Database/RatingManager.php (modified) (1 diff)
-
tags/8.3.8/plugin/Database/Sql.php (modified) (7 diffs)
-
tags/8.3.8/plugin/Database/Tables.php (modified) (1 diff)
-
tags/8.3.8/plugin/Defaults/ApiDefaults.php (modified) (2 diffs)
-
tags/8.3.8/plugin/Helpers/Arr.php (modified) (1 diff)
-
tags/8.3.8/plugin/Helpers/Text.php (modified) (3 diffs)
-
tags/8.3.8/plugin/Integrations/MultilingualPress/Defaults/SyncReviewDefaults.php (modified) (2 diffs)
-
tags/8.3.8/plugin/Integrations/MultilingualPress/RelationSaveHelper.php (modified) (3 diffs)
-
tags/8.3.8/plugin/Integrations/MultilingualPress/ReviewCopier.php (modified) (2 diffs)
-
tags/8.3.8/plugin/Integrations/WPLoyalty/Controller.php (modified) (1 diff)
-
tags/8.3.8/plugin/Integrations/WooCommerce/Controllers/RestApi/ProductReviewsController.php (modified) (1 diff)
-
tags/8.3.8/plugin/Modules/Html/Form.php (modified) (2 diffs)
-
tags/8.3.8/plugin/Modules/Html/ReviewForm.php (modified) (3 diffs)
-
tags/8.3.8/plugin/Modules/Html/SettingForm.php (modified) (1 diff)
-
tags/8.3.8/plugin/Modules/Paginate.php (modified) (1 diff)
-
tags/8.3.8/plugin/Modules/Sanitizers/ArraySanitizer.php (modified) (2 diffs)
-
tags/8.3.8/plugin/Modules/Sanitizers/SanitizeEmails.php (modified) (1 diff)
-
tags/8.3.8/plugin/Modules/Sanitizers/SanitizePostIds.php (modified) (1 diff)
-
tags/8.3.8/plugin/Modules/Sanitizers/SanitizeTermIds.php (modified) (1 diff)
-
tags/8.3.8/plugin/Modules/Sanitizers/SanitizeUserIds.php (modified) (1 diff)
-
tags/8.3.8/plugin/Modules/Schema.php (modified) (2 diffs)
-
tags/8.3.8/plugin/Modules/SystemInfo.php (modified) (1 diff)
-
tags/8.3.8/plugin/Modules/Validator.php (modified) (1 diff)
-
tags/8.3.8/plugin/Modules/Validator/CaptchaValidatorAbstract.php (modified) (1 diff)
-
tags/8.3.8/plugin/Modules/Validator/FriendlycaptchaV2Validator.php (modified) (1 diff)
-
tags/8.3.8/plugin/Modules/Validator/ProcaptchaValidator.php (modified) (1 diff)
-
tags/8.3.8/plugin/Modules/Validator/SignatureValidator.php (modified) (3 diffs)
-
tags/8.3.8/plugin/Modules/Validator/ValidationRules.php (modified) (2 diffs)
-
tags/8.3.8/plugin/Notices/GatekeeperNotice.php (modified) (3 diffs)
-
tags/8.3.8/readme.txt (modified) (2 diffs)
-
tags/8.3.8/site-reviews.php (modified) (1 diff)
-
trunk/changelog.txt (modified) (1 diff)
-
trunk/languages/site-reviews-en_US.po (modified) (19 diffs)
-
trunk/languages/site-reviews.pot (modified) (18 diffs)
-
trunk/plugin/Api.php (modified) (2 diffs)
-
trunk/plugin/Commands/CreateReview.php (modified) (3 diffs)
-
trunk/plugin/Commands/FetchPagedReviews.php (modified) (1 diff)
-
trunk/plugin/Controllers/AdminController.php (modified) (7 diffs)
-
trunk/plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php (modified) (3 diffs)
-
trunk/plugin/Controllers/Api/Version1/RestReviewController.php (modified) (1 diff)
-
trunk/plugin/Controllers/EditorController.php (modified) (1 diff)
-
trunk/plugin/Controllers/ListTableController.php (modified) (2 diffs)
-
trunk/plugin/Controllers/MainController.php (modified) (1 diff)
-
trunk/plugin/Controllers/PrivacyController.php (modified) (1 diff)
-
trunk/plugin/Controllers/ToolsController.php (modified) (2 diffs)
-
trunk/plugin/Controllers/VerificationController.php (modified) (2 diffs)
-
trunk/plugin/Database.php (modified) (3 diffs)
-
trunk/plugin/Database/OptionManager.php (modified) (3 diffs)
-
trunk/plugin/Database/Query.php (modified) (3 diffs)
-
trunk/plugin/Database/RatingManager.php (modified) (1 diff)
-
trunk/plugin/Database/Sql.php (modified) (7 diffs)
-
trunk/plugin/Database/Tables.php (modified) (1 diff)
-
trunk/plugin/Defaults/ApiDefaults.php (modified) (2 diffs)
-
trunk/plugin/Helpers/Arr.php (modified) (1 diff)
-
trunk/plugin/Helpers/Text.php (modified) (3 diffs)
-
trunk/plugin/Integrations/MultilingualPress/Defaults/SyncReviewDefaults.php (modified) (2 diffs)
-
trunk/plugin/Integrations/MultilingualPress/RelationSaveHelper.php (modified) (3 diffs)
-
trunk/plugin/Integrations/MultilingualPress/ReviewCopier.php (modified) (2 diffs)
-
trunk/plugin/Integrations/WPLoyalty/Controller.php (modified) (1 diff)
-
trunk/plugin/Integrations/WooCommerce/Controllers/RestApi/ProductReviewsController.php (modified) (1 diff)
-
trunk/plugin/Modules/Html/Form.php (modified) (2 diffs)
-
trunk/plugin/Modules/Html/ReviewForm.php (modified) (3 diffs)
-
trunk/plugin/Modules/Html/SettingForm.php (modified) (1 diff)
-
trunk/plugin/Modules/Paginate.php (modified) (1 diff)
-
trunk/plugin/Modules/Sanitizers/ArraySanitizer.php (modified) (2 diffs)
-
trunk/plugin/Modules/Sanitizers/SanitizeEmails.php (modified) (1 diff)
-
trunk/plugin/Modules/Sanitizers/SanitizePostIds.php (modified) (1 diff)
-
trunk/plugin/Modules/Sanitizers/SanitizeTermIds.php (modified) (1 diff)
-
trunk/plugin/Modules/Sanitizers/SanitizeUserIds.php (modified) (1 diff)
-
trunk/plugin/Modules/Schema.php (modified) (2 diffs)
-
trunk/plugin/Modules/SystemInfo.php (modified) (1 diff)
-
trunk/plugin/Modules/Validator.php (modified) (1 diff)
-
trunk/plugin/Modules/Validator/CaptchaValidatorAbstract.php (modified) (1 diff)
-
trunk/plugin/Modules/Validator/FriendlycaptchaV2Validator.php (modified) (1 diff)
-
trunk/plugin/Modules/Validator/ProcaptchaValidator.php (modified) (1 diff)
-
trunk/plugin/Modules/Validator/SignatureValidator.php (modified) (3 diffs)
-
trunk/plugin/Modules/Validator/ValidationRules.php (modified) (2 diffs)
-
trunk/plugin/Notices/GatekeeperNotice.php (modified) (3 diffs)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/site-reviews.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
site-reviews/tags/8.3.8/changelog.txt
r3777315 r3803670 1 1 == Changelog == 2 3 = 8.3.8 (2026-11-15) = 4 5 - Fixed a security issue in review excerpts 6 - Fixed a security issue in the notice shown after restoring a revision 7 - Fixed a security issue in the review type filter 8 - Fixed a security issue in the schema 9 - Fixed captcha checks slowly filling up the database 10 - Fixed forms with more than one Assigned Pages, Categories or Users field not submitting 11 - Fixed hidden form fields changing after a failed submission 12 - Fixed MultilingualPress translations losing their custom field values when the original review is edited 13 - Fixed number fields ignoring decimals in their minimum and maximum 14 - Fixed reviews not saving with version 3 of the SQLite Database Integration plugin 15 - Fixed some assigned pages, categories or users not being saved with a review 16 - Fixed the admin search permission check 17 - Fixed the Install button in the missing plugin notice 18 - Fixed the IP address detection tool permission check 19 - Fixed the review approval permission check 20 - Fixed the validation of submitted reviews 21 - Fixed the verification email permission check 2 22 3 23 = 8.3.7 (2026-10-31) = -
site-reviews/tags/8.3.8/languages/site-reviews-en_US.po
r3777315 r3803670 116 116 117 117 #: plugin/Controllers/Api/Version1/RestRenderController.php:103 118 #: plugin/Controllers/VerificationController.php: 96118 #: plugin/Controllers/VerificationController.php:105 119 119 msgid "Thank you, your review has been verified." 120 120 msgstr "Thank you, your review has been verified." 121 121 122 122 #: plugin/Controllers/Api/Version1/RestRenderController.php:104 123 #: plugin/Controllers/VerificationController.php: 97123 #: plugin/Controllers/VerificationController.php:106 124 124 msgid "Thank you, your review has been verified and is awaiting approval." 125 125 msgstr "Thank you, your review has been verified and is awaiting approval." … … 432 432 msgstr "Submitting, please wait..." 433 433 434 #: plugin/Modules/Html/ReviewForm.php:1 4434 #: plugin/Modules/Html/ReviewForm.php:15 435 435 msgid "Submit Review" 436 436 msgstr "Submit Review" … … 476 476 msgstr "You have already submitted a review." 477 477 478 #: plugin/Modules/Validator/SignatureValidator.php:2 7478 #: plugin/Modules/Validator/SignatureValidator.php:28 479 479 #: views/pages/documentation/support/common-problems-and-solutions.php:89 480 480 msgid "This review cannot be submitted, please refresh the page and try again." … … 2437 2437 msgstr "Enabling this option will persist field values entered into the review form until either the review is submitted or the browser tab or window is closed." 2438 2438 2439 #: plugin/Database.php:23 72439 #: plugin/Database.php:231 2440 2440 msgctxt "admin-text" 2441 2441 msgid "(no title)" … … 3400 3400 3401 3401 #: plugin/Commands/SendVerificationEmail.php:71 3402 #: plugin/Controllers/VerificationController.php:3 43402 #: plugin/Controllers/VerificationController.php:35 3403 3403 msgctxt "admin-text" 3404 3404 msgid "Resend Verification Request" … … 3486 3486 msgstr "Import" 3487 3487 3488 #: plugin/Controllers/AdminController.php:3 093489 #: plugin/Controllers/AdminController.php:3 273490 #: plugin/Controllers/AdminController.php:34 03488 #: plugin/Controllers/AdminController.php:313 3489 #: plugin/Controllers/AdminController.php:332 3490 #: plugin/Controllers/AdminController.php:346 3491 3491 msgctxt "admin-text" 3492 3492 msgid "Nothing found." … … 3580 3580 3581 3581 #. translators: %s: the review type 3582 #: plugin/Controllers/EditorController.php:10 83582 #: plugin/Controllers/EditorController.php:109 3583 3583 #, php-format 3584 3584 msgctxt "admin-text" … … 3681 3681 msgstr "Respond" 3682 3682 3683 #: plugin/Controllers/ListTableController.php:27 23683 #: plugin/Controllers/ListTableController.php:270 3684 3684 msgctxt "admin-text" 3685 3685 msgid "Sorry, you are not allowed to respond to this review." 3686 3686 msgstr "Sorry, you are not allowed to respond to this review." 3687 3687 3688 #: plugin/Controllers/ListTableController.php:27 53688 #: plugin/Controllers/ListTableController.php:273 3689 3689 msgctxt "admin-text" 3690 3690 msgid "Someone" … … 3692 3692 3693 3693 #. translators: %s: user's name 3694 #: plugin/Controllers/ListTableController.php:2 813694 #: plugin/Controllers/ListTableController.php:279 3695 3695 #, php-format 3696 3696 msgctxt "admin-text" … … 3821 3821 msgstr "You do not have permission to import settings." 3822 3822 3823 #: plugin/Controllers/ToolsController.php:3 663823 #: plugin/Controllers/ToolsController.php:380 3824 3824 msgctxt "admin-text" 3825 3825 msgid "reload the page" … … 3827 3827 3828 3828 #. translators: %s: a link with the text "reload the page" 3829 #: plugin/Controllers/ToolsController.php:3 713829 #: plugin/Controllers/ToolsController.php:385 3830 3830 #, php-format 3831 3831 msgctxt "admin-text" … … 3833 3833 msgstr "The permissions have been repaired, please %s for them to take effect." 3834 3834 3835 #: plugin/Controllers/ToolsController.php:4 463835 #: plugin/Controllers/ToolsController.php:460 3836 3836 msgctxt "admin-text" 3837 3837 msgid "You do not have permission to rollback the plugin." … … 3921 3921 msgstr "Approved on:" 3922 3922 3923 #: plugin/Controllers/VerificationController.php:3 53923 #: plugin/Controllers/VerificationController.php:36 3924 3924 msgctxt "admin-text" 3925 3925 msgid "Send Verification Request" … … 4224 4224 4225 4225 #. translators: %s: the plugin name 4226 #: plugin/Notices/GatekeeperNotice.php:13 04226 #: plugin/Notices/GatekeeperNotice.php:133 4227 4227 #, php-format 4228 4228 msgctxt "admin-text" … … 4231 4231 4232 4232 #. translators: %s: the plugin name 4233 #: plugin/Notices/GatekeeperNotice.php:14 64233 #: plugin/Notices/GatekeeperNotice.php:149 4234 4234 #, php-format 4235 4235 msgctxt "admin-text" … … 7116 7116 msgstr "Limit result set to verified status." 7117 7117 7118 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:1 87118 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:19 7119 7119 msgctxt "admin-text" 7120 7120 msgid "Cannot create existing review." 7121 7121 msgstr "Cannot create existing review." 7122 7122 7123 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:2 27123 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:23 7124 7124 msgctxt "admin-text" 7125 7125 msgid "Sorry, you are not allowed to create reviews as this user." 7126 7126 msgstr "Sorry, you are not allowed to create reviews as this user." 7127 7127 7128 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:2 67128 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:27 7129 7129 msgctxt "admin-text" 7130 7130 msgid "Sorry, you are not allowed to create reviews as this review author." 7131 7131 msgstr "Sorry, you are not allowed to create reviews as this review author." 7132 7132 7133 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:3 07134 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:1 397133 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:31 7134 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:146 7135 7135 msgctxt "admin-text" 7136 7136 msgid "Sorry, you are not allowed to assign the provided terms." 7137 7137 msgstr "Sorry, you are not allowed to assign the provided terms." 7138 7138 7139 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:4 57140 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:6 87141 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:12 17139 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:46 7140 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:69 7141 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:122 7142 7142 msgctxt "admin-text" 7143 7143 msgid "Invalid review ID." 7144 7144 msgstr "Invalid review ID." 7145 7145 7146 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:5 17146 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:52 7147 7147 msgctxt "admin-text" 7148 7148 msgid "Sorry, you are not allowed to delete this review." 7149 7149 msgstr "Sorry, you are not allowed to delete this review." 7150 7150 7151 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:7 47151 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:75 7152 7152 msgctxt "admin-text" 7153 7153 msgid "Sorry, you are not allowed to view this review." 7154 7154 msgstr "Sorry, you are not allowed to view this review." 7155 7155 7156 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:8 17157 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:12 77156 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:82 7157 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:128 7158 7158 msgctxt "admin-text" 7159 7159 msgid "Sorry, you are not allowed to edit this review." 7160 7160 msgstr "Sorry, you are not allowed to edit this review." 7161 7161 7162 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:9 77162 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:98 7163 7163 msgctxt "admin-text" 7164 7164 msgid "Sorry, you do not have permission to access reviews." 7165 7165 msgstr "Sorry, you do not have permission to access reviews." 7166 7166 7167 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:10 47167 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:105 7168 7168 msgctxt "admin-text" 7169 7169 msgid "Sorry, you are not allowed to edit reviews." 7170 7170 msgstr "Sorry, you are not allowed to edit reviews." 7171 7171 7172 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:1 337172 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:140 7173 7173 msgctxt "admin-text" 7174 7174 msgid "Sorry, you are not allowed to update the review as this user." … … 7560 7560 7561 7561 #. translators: %s: plugin name 7562 #: plugin/Controllers/ToolsController.php:4 277562 #: plugin/Controllers/ToolsController.php:441 7563 7563 #, php-format 7564 7564 msgctxt "Site Reviews (admin-text)" … … 9235 9235 msgstr "" 9236 9236 9237 #: plugin/Controllers/ToolsController.php:4 519237 #: plugin/Controllers/ToolsController.php:465 9238 9238 #: views/pages/tools/general/rollback-plugin.php:21 9239 9239 msgctxt "admin-text" … … 9254 9254 msgid "%s was not updated because its folder is a git repository." 9255 9255 msgstr "" 9256 9257 #: plugin/Controllers/AdminController.php:390 9258 msgctxt "admin-text" 9259 msgid "You do not have permission to search." 9260 msgstr "" 9261 9262 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:134 9263 msgctxt "admin-text" 9264 msgid "Sorry, you are not allowed to approve this review." 9265 msgstr "" 9266 9267 #: plugin/Controllers/ToolsController.php:314 9268 #: plugin/Controllers/ToolsController.php:332 9269 msgctxt "admin-text" 9270 msgid "You do not have permission to change the IP address detection." 9271 msgstr "" 9272 9273 #: plugin/Controllers/VerificationController.php:52 9274 msgctxt "admin-text" 9275 msgid "You do not have permission to request verification of this review." 9276 msgstr "" -
site-reviews/tags/8.3.8/languages/site-reviews.pot
r3777315 r3803670 3 3 msgid "" 4 4 msgstr "" 5 "Project-Id-Version: Site Reviews 8.3. 7\n"5 "Project-Id-Version: Site Reviews 8.3.8\n" 6 6 "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/site-reviews\n" 7 7 "Last-Translator: Paul Ryley <paul@geminilabs.io>\n" … … 3268 3268 3269 3269 #: plugin/Commands/SendVerificationEmail.php:71 3270 #: plugin/Controllers/VerificationController.php:3 43270 #: plugin/Controllers/VerificationController.php:35 3271 3271 msgctxt "admin-text" 3272 3272 msgid "Resend Verification Request" … … 3358 3358 msgstr "" 3359 3359 3360 #: plugin/Controllers/AdminController.php:3 093361 #: plugin/Controllers/AdminController.php:3 273362 #: plugin/Controllers/AdminController.php:34 03360 #: plugin/Controllers/AdminController.php:313 3361 #: plugin/Controllers/AdminController.php:332 3362 #: plugin/Controllers/AdminController.php:346 3363 3363 msgctxt "admin-text" 3364 3364 msgid "Nothing found." 3365 msgstr "" 3366 3367 #: plugin/Controllers/AdminController.php:390 3368 msgctxt "admin-text" 3369 msgid "You do not have permission to search." 3365 3370 msgstr "" 3366 3371 … … 3494 3499 msgstr "" 3495 3500 3496 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:1 83501 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:19 3497 3502 msgctxt "admin-text" 3498 3503 msgid "Cannot create existing review." 3499 3504 msgstr "" 3500 3505 3501 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:2 23506 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:23 3502 3507 msgctxt "admin-text" 3503 3508 msgid "Sorry, you are not allowed to create reviews as this user." 3504 3509 msgstr "" 3505 3510 3506 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:2 63511 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:27 3507 3512 msgctxt "admin-text" 3508 3513 msgid "Sorry, you are not allowed to create reviews as this review author." 3509 3514 msgstr "" 3510 3515 3511 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:3 03512 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:1 393516 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:31 3517 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:146 3513 3518 msgctxt "admin-text" 3514 3519 msgid "Sorry, you are not allowed to assign the provided terms." 3515 3520 msgstr "" 3516 3521 3517 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:4 53518 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:6 83519 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:12 13522 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:46 3523 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:69 3524 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:122 3520 3525 msgctxt "admin-text" 3521 3526 msgid "Invalid review ID." 3522 3527 msgstr "" 3523 3528 3524 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:5 13529 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:52 3525 3530 msgctxt "admin-text" 3526 3531 msgid "Sorry, you are not allowed to delete this review." 3527 3532 msgstr "" 3528 3533 3529 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:7 43534 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:75 3530 3535 msgctxt "admin-text" 3531 3536 msgid "Sorry, you are not allowed to view this review." 3532 3537 msgstr "" 3533 3538 3534 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:8 13535 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:12 73539 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:82 3540 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:128 3536 3541 msgctxt "admin-text" 3537 3542 msgid "Sorry, you are not allowed to edit this review." 3538 3543 msgstr "" 3539 3544 3540 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:9 73545 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:98 3541 3546 msgctxt "admin-text" 3542 3547 msgid "Sorry, you do not have permission to access reviews." 3543 3548 msgstr "" 3544 3549 3545 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:10 43550 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:105 3546 3551 msgctxt "admin-text" 3547 3552 msgid "Sorry, you are not allowed to edit reviews." 3548 3553 msgstr "" 3549 3554 3550 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:133 3555 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:134 3556 msgctxt "admin-text" 3557 msgid "Sorry, you are not allowed to approve this review." 3558 msgstr "" 3559 3560 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:140 3551 3561 msgctxt "admin-text" 3552 3562 msgid "Sorry, you are not allowed to update the review as this user." … … 3562 3572 3563 3573 #: plugin/Controllers/Api/Version1/RestRenderController.php:103 3564 #: plugin/Controllers/VerificationController.php: 963574 #: plugin/Controllers/VerificationController.php:105 3565 3575 msgid "Thank you, your review has been verified." 3566 3576 msgstr "" 3567 3577 3568 3578 #: plugin/Controllers/Api/Version1/RestRenderController.php:104 3569 #: plugin/Controllers/VerificationController.php: 973579 #: plugin/Controllers/VerificationController.php:106 3570 3580 msgid "Thank you, your review has been verified and is awaiting approval." 3571 3581 msgstr "" … … 3923 3933 3924 3934 #. translators: %s: the review type 3925 #: plugin/Controllers/EditorController.php:10 83935 #: plugin/Controllers/EditorController.php:109 3926 3936 #, php-format 3927 3937 msgctxt "admin-text" … … 4192 4202 msgstr "" 4193 4203 4194 #: plugin/Controllers/ListTableController.php:27 24204 #: plugin/Controllers/ListTableController.php:270 4195 4205 msgctxt "admin-text" 4196 4206 msgid "Sorry, you are not allowed to respond to this review." 4197 4207 msgstr "" 4198 4208 4199 #: plugin/Controllers/ListTableController.php:27 54209 #: plugin/Controllers/ListTableController.php:273 4200 4210 msgctxt "admin-text" 4201 4211 msgid "Someone" … … 4203 4213 4204 4214 #. translators: %s: user's name 4205 #: plugin/Controllers/ListTableController.php:2 814215 #: plugin/Controllers/ListTableController.php:279 4206 4216 #, php-format 4207 4217 msgctxt "admin-text" … … 4339 4349 msgstr "" 4340 4350 4341 #: plugin/Controllers/ToolsController.php:366 4351 #: plugin/Controllers/ToolsController.php:314 4352 #: plugin/Controllers/ToolsController.php:332 4353 msgctxt "admin-text" 4354 msgid "You do not have permission to change the IP address detection." 4355 msgstr "" 4356 4357 #: plugin/Controllers/ToolsController.php:380 4342 4358 msgctxt "admin-text" 4343 4359 msgid "reload the page" … … 4345 4361 4346 4362 #. translators: %s: a link with the text "reload the page" 4347 #: plugin/Controllers/ToolsController.php:3 714363 #: plugin/Controllers/ToolsController.php:385 4348 4364 #, php-format 4349 4365 msgctxt "admin-text" … … 4352 4368 4353 4369 #. translators: %s: plugin name 4354 #: plugin/Controllers/ToolsController.php:4 274370 #: plugin/Controllers/ToolsController.php:441 4355 4371 #, php-format 4356 4372 msgctxt "Site Reviews (admin-text)" … … 4358 4374 msgstr "" 4359 4375 4360 #: plugin/Controllers/ToolsController.php:4 464376 #: plugin/Controllers/ToolsController.php:460 4361 4377 msgctxt "admin-text" 4362 4378 msgid "You do not have permission to rollback the plugin." 4363 4379 msgstr "" 4364 4380 4365 #: plugin/Controllers/ToolsController.php:4 514381 #: plugin/Controllers/ToolsController.php:465 4366 4382 #: views/pages/tools/general/rollback-plugin.php:21 4367 4383 msgctxt "admin-text" … … 4471 4487 msgstr "" 4472 4488 4473 #: plugin/Controllers/VerificationController.php:3 54489 #: plugin/Controllers/VerificationController.php:36 4474 4490 msgctxt "admin-text" 4475 4491 msgid "Send Verification Request" 4492 msgstr "" 4493 4494 #: plugin/Controllers/VerificationController.php:52 4495 msgctxt "admin-text" 4496 msgid "You do not have permission to request verification of this review." 4476 4497 msgstr "" 4477 4498 … … 4507 4528 msgstr "" 4508 4529 4509 #: plugin/Database.php:23 74530 #: plugin/Database.php:231 4510 4531 msgctxt "admin-text" 4511 4532 msgid "(no title)" … … 6497 6518 msgstr "" 6498 6519 6499 #: plugin/Modules/Html/ReviewForm.php:1 46520 #: plugin/Modules/Html/ReviewForm.php:15 6500 6521 msgid "Submit Review" 6501 6522 msgstr "" … … 6629 6650 msgstr "" 6630 6651 6631 #: plugin/Modules/Validator/SignatureValidator.php:2 76652 #: plugin/Modules/Validator/SignatureValidator.php:28 6632 6653 #: views/pages/documentation/support/common-problems-and-solutions.php:89 6633 6654 msgid "This review cannot be submitted, please refresh the page and try again." … … 6660 6681 6661 6682 #. translators: %s: the plugin name 6662 #: plugin/Notices/GatekeeperNotice.php:13 06683 #: plugin/Notices/GatekeeperNotice.php:133 6663 6684 #, php-format 6664 6685 msgctxt "admin-text" … … 6667 6688 6668 6689 #. translators: %s: the plugin name 6669 #: plugin/Notices/GatekeeperNotice.php:14 66690 #: plugin/Notices/GatekeeperNotice.php:149 6670 6691 #, php-format 6671 6692 msgctxt "admin-text" -
site-reviews/tags/8.3.8/plugin/Api.php
r3769299 r3803670 81 81 $this->forget($transientKey); 82 82 } else { 83 $result = get_site_transient($transientKey);83 $result = $args['cache'] ? get_site_transient($transientKey) : false; 84 84 if (!empty($result)) { 85 85 return new Response($result); … … 97 97 $response = new Response($result); 98 98 if ($response->successful()) { 99 $this->remember($transientKey, $result, $args['expiration']); 99 if ($args['cache']) { 100 $this->remember($transientKey, $result, $args['expiration']); 101 } 100 102 if ($args['skip_when_down']) { 101 103 $this->markReachable(); -
site-reviews/tags/8.3.8/plugin/Commands/CreateReview.php
r3777315 r3803670 60 60 $this->request = $this->normalize($request); // IP address is set here 61 61 $this->setProperties(); // do this after setting the request 62 $this->review = new Review($this->toArray(), $init = false);62 $this->review = new Review($this->toArray(), false); // don't init 63 63 $this->validation = new Arguments(); 64 64 $this->custom = $this->custom(); … … 239 239 $request->set('date', ''); 240 240 $request->set('date_gmt', ''); 241 $request->set('geolocation', ''); 241 242 $request->set('is_pinned', false); 242 243 $request->set('is_verified', false); … … 244 245 $request->set('response_by', 0); 245 246 $request->set('type', 'local'); 247 $request->set('verified', ''); 248 $request->set('verified_on', ''); 249 $request->set('verified_requested', ''); 246 250 } 247 251 glsr()->action('review/request', $request); -
site-reviews/tags/8.3.8/plugin/Commands/FetchPagedReviews.php
r3683434 r3803670 33 33 return [ 34 34 'max_num_pages' => $this->html->max_num_pages, 35 'pagination' => $this->html->getPagination( $wrap = false),35 'pagination' => $this->html->getPagination(false), // don't wrap 36 36 'reviews' => $this->html->getReviews(), 37 37 ]; -
site-reviews/tags/8.3.8/plugin/Controllers/AdminController.php
r3683434 r3803670 262 262 public function searchAssignedPostsAjax(Request $request): void 263 263 { 264 $this->checkSearchPermission(); 264 265 $search = glsr(Sanitizer::class)->sanitizeText($request->search); 265 266 $results = glsr(Database::class)->searchAssignedPosts($search)->results(); … … 274 275 public function searchAssignedUsersAjax(Request $request): void 275 276 { 277 $this->checkSearchPermission(); 276 278 $search = glsr(Sanitizer::class)->sanitizeText($request->search); 277 279 $results = glsr(Database::class)->searchAssignedUsers($search)->results(); … … 289 291 public function searchAuthorsAjax(Request $request): void 290 292 { 293 $this->checkSearchPermission(); 291 294 $search = glsr(Sanitizer::class)->sanitizeText($request->search); 292 295 $results = glsr(Database::class)->searchUsers($search)->results(); … … 304 307 public function searchPostsAjax(Request $request): void 305 308 { 309 $this->checkSearchPermission(); 306 310 $search = glsr(Sanitizer::class)->sanitizeText($request->search); 307 311 $results = glsr(Database::class)->searchPosts($search)->render(); … … 317 321 public function searchStringsAjax(Request $request): void 318 322 { 323 $this->checkSearchPermission(); 319 324 $search = glsr(Sanitizer::class)->sanitizeText($request->search); 320 325 $exclude = Arr::consolidate($request->exclude); … … 335 340 public function searchUsersAjax(Request $request): void 336 341 { 342 $this->checkSearchPermission(); 337 343 $search = glsr(Sanitizer::class)->sanitizeText($request->search); 338 344 $results = glsr(Database::class)->searchUsers($search)->render(); … … 372 378 $this->execute(new ToggleStatus($request))->sendJsonResponse(); 373 379 } 380 381 /** 382 * Refuse the request with an error notice unless the user can edit reviews. 383 */ 384 protected function checkSearchPermission(): void 385 { 386 if (glsr()->can('edit_posts')) { 387 return; 388 } 389 glsr(Notice::class)->addError( 390 _x('You do not have permission to search.', 'admin-text', 'site-reviews') 391 ); 392 wp_send_json_error([ 393 'notices' => glsr(Notice::class)->get(), 394 ]); 395 } 374 396 } -
site-reviews/tags/8.3.8/plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php
r3583819 r3803670 3 3 namespace GeminiLabs\SiteReviews\Controllers\Api\Version1\Permissions; 4 4 5 use GeminiLabs\SiteReviews\Defaults\UpdateReviewDefaults; 5 6 use GeminiLabs\SiteReviews\Helpers\Arr; 6 7 use GeminiLabs\SiteReviews\Review; … … 127 128 $message = _x('Sorry, you are not allowed to edit this review.', 'admin-text', 'site-reviews'); 128 129 return new \WP_Error('rest_cannot_edit', $message, [ 130 'status' => rest_authorization_required_code(), 131 ]); 132 } 133 if ($this->is_approving($request, $review) && !glsr()->can('publish_post', $review->ID)) { 134 $message = _x('Sorry, you are not allowed to approve this review.', 'admin-text', 'site-reviews'); 135 return new \WP_Error('rest_cannot_publish', $message, [ 129 136 'status' => rest_authorization_required_code(), 130 137 ]); … … 183 190 return true; 184 191 } 192 193 /** 194 * Whether the update approves a review that is not approved yet. 195 */ 196 protected function is_approving(\WP_REST_Request $request, Review $review): bool 197 { 198 $values = glsr(UpdateReviewDefaults::class)->restrict($request->get_params()); // the status comes from is_approved 199 return 'publish' === Arr::get($values, 'status') && !$review->is_approved; 200 } 185 201 } -
site-reviews/tags/8.3.8/plugin/Controllers/Api/Version1/RestReviewController.php
r3683434 r3803670 291 291 ->buildReviewsHtml(); 292 292 $response = rest_ensure_response([ 293 'pagination' => $html->getPagination( $wrap = false),293 'pagination' => $html->getPagination(false), // don't wrap 294 294 'rendered' => $html->getReviews(), 295 295 ]); -
site-reviews/tags/8.3.8/plugin/Controllers/EditorController.php
r3642444 r3803670 73 73 } 74 74 $strings = glsr(UpdatedMessageDefaults::class)->defaults(); 75 $restored = filter_input(\INPUT_GET, 'revision'); 76 if ($revisionTitle = wp_post_revision_title(intval($restored), false)) { 75 $restored = false; 76 $revisionId = intval(filter_input(\INPUT_GET, 'revision')); 77 if ($revisionTitle = wp_post_revision_title($revisionId, false)) { 77 78 $restored = sprintf($strings['restored'], $revisionTitle); 78 79 } -
site-reviews/tags/8.3.8/plugin/Controllers/ListTableController.php
r3642444 r3803670 206 206 unset($filters['type']); 207 207 } 208 foreach ($filters as $key => &$value) { 209 $value = glsr($value)->title(); 210 } 208 $filters = array_map(fn ($value) => glsr($value)->title(), $filters); 211 209 ksort($filters); 212 210 $setting = 'edit_'.glsr()->post_type.'_filters'; … … 441 439 $clause['clauses'][] = "AND {$assignedTable}.{$column} = {$value}"; 442 440 } 443 } elseif (in_array($key, ['rating', 'terms' , 'type'])) {441 } elseif (in_array($key, ['rating', 'terms'])) { 444 442 $clause['clauses'][] = "AND {$ratings}.{$key} = '{$value}'"; 443 } elseif ('type' === $key && array_key_exists($value, glsr()->retrieveAs('array', 'review_types'))) { 444 $clause['clauses'][] = "AND {$ratings}.type = '{$value}'"; 445 445 } elseif ('author' === $key && '0' === $value) { 446 446 // Filtering by the "author" URL parameter is automatically done -
site-reviews/tags/8.3.8/plugin/Controllers/MainController.php
r3722268 r3803670 52 52 $table = glsr($classname); 53 53 if ($table instanceof TableRatings) { 54 $ratingsTable[$table->name( $prefixName = true)] = $table->tablename;54 $ratingsTable[$table->name(true)] = $table->tablename; // use the prefixed name 55 55 continue; 56 56 } 57 $customTables[$table->name( $prefixName = true)] = $table->tablename;57 $customTables[$table->name(true)] = $table->tablename; // use the prefixed name 58 58 } 59 59 return $customTables + $ratingsTable + $tables; -
site-reviews/tags/8.3.8/plugin/Controllers/PrivacyController.php
r3769299 r3803670 152 152 ", $email, glsr()->post_type, $this->perPage, ($page - 1) * $this->perPage); 153 153 $reviewIds = glsr(Database::class)->dbGetCol($sql); 154 return empty($reviewIds) ? [] : glsr(Query::class)->reviews([ ], $reviewIds);154 return empty($reviewIds) ? [] : glsr(Query::class)->reviews(['order' => 'asc', 'orderby' => 'id'], $reviewIds); 155 155 } 156 156 } -
site-reviews/tags/8.3.8/plugin/Controllers/ToolsController.php
r3769299 r3803670 310 310 public function ipAddressDetection(Request $request): void 311 311 { 312 if (!glsr()->can(glsr()->getPermission('settings'))) { 313 glsr(Notice::class)->addError( 314 _x('You do not have permission to change the IP address detection.', 'admin-text', 'site-reviews') 315 ); 316 return; 317 } 312 318 if (wp_validate_boolean($request->get('alt', 0))) { 313 319 $this->execute(new DetectIpAddress()); … … 322 328 public function ipAddressDetectionAjax(Request $request): void 323 329 { 330 if (!glsr()->can(glsr()->getPermission('settings'))) { 331 glsr(Notice::class)->addError( 332 _x('You do not have permission to change the IP address detection.', 'admin-text', 'site-reviews') 333 ); 334 wp_send_json_error([ 335 'notices' => glsr(Notice::class)->get(), 336 ]); 337 } 324 338 $command = wp_validate_boolean($request->get('alt', 0)) 325 339 ? $this->execute(new DetectIpAddress()) -
site-reviews/tags/8.3.8/plugin/Controllers/VerificationController.php
r3642444 r3803670 14 14 use GeminiLabs\SiteReviews\Modules\Encryption; 15 15 use GeminiLabs\SiteReviews\Modules\Html\Template; 16 use GeminiLabs\SiteReviews\Modules\Notice; 16 17 use GeminiLabs\SiteReviews\Request; 17 18 use GeminiLabs\SiteReviews\Review; … … 47 48 { 48 49 $review = glsr(ReviewManager::class)->get($request->cast('post_id', 'int')); 50 if (!$review->isValid() || !glsr()->can('edit_post', $review->ID)) { 51 glsr(Notice::class)->addError( 52 _x('You do not have permission to request verification of this review.', 'admin-text', 'site-reviews') 53 ); 54 wp_send_json_error([ 55 'notices' => glsr(Notice::class)->get(), 56 ]); 57 } 49 58 $pathPostId = $review->meta()->cast('_submitted._post_id', 'int'); 50 59 $path = Cast::toString(wp_parse_url((string) get_permalink($pathPostId), \PHP_URL_PATH)); -
site-reviews/tags/8.3.8/plugin/Database.php
r3642444 r3803670 31 31 public function beginTransaction(string $table): void 32 32 { 33 if (glsr(Tables::class)->isSqlite ()) {33 if (glsr(Tables::class)->isSqliteLegacy()) { 34 34 $this->dbQuery("BEGIN TRANSACTION;"); 35 } elseif (glsr(Tables::class)->is Innodb($table)) {35 } elseif (glsr(Tables::class)->isSqlite() || glsr(Tables::class)->isInnodb($table)) { 36 36 $this->dbQuery("START TRANSACTION;"); 37 37 } elseif (glsr(Tables::class)->isMyisam($table)) { … … 159 159 $fields = glsr(Query::class)->escFieldsForInsert(array_keys($data)); 160 160 $values = glsr(Query::class)->escValuesForInsert($data); 161 if (glsr(Tables::class)->isSqlite()) { 162 $sql = glsr(Query::class)->sql("INSERT OR IGNORE INTO {$table} {$fields} VALUES {$values}"); 163 } else { 164 $sql = glsr(Query::class)->sql("INSERT IGNORE INTO {$table} {$fields} VALUES {$values}"); 165 } 161 $ignore = glsr(Tables::class)->isSqliteLegacy() ? 'OR IGNORE' : 'IGNORE'; 162 $sql = glsr(Query::class)->sql("INSERT {$ignore} INTO {$table} {$fields} VALUES {$values}"); 166 163 return $this->dbQuery($sql); 167 164 } … … 186 183 $fields = glsr(Query::class)->escFieldsForInsert($fields); 187 184 $values = implode(',', $data); 188 if (glsr(Tables::class)->isSqlite()) { 189 $sql = glsr(Query::class)->sql("INSERT OR IGNORE INTO {$table} {$fields} VALUES {$values}"); 190 } else { 191 $sql = glsr(Query::class)->sql("INSERT IGNORE INTO {$table} {$fields} VALUES {$values}"); 192 } 185 $ignore = glsr(Tables::class)->isSqliteLegacy() ? 'OR IGNORE' : 'IGNORE'; 186 $sql = glsr(Query::class)->sql("INSERT {$ignore} INTO {$table} {$fields} VALUES {$values}"); 193 187 return $this->dbQuery($sql); 194 188 } -
site-reviews/tags/8.3.8/plugin/Database/OptionManager.php
r3769299 r3803670 313 313 $writes = []; 314 314 $versions = []; 315 foreach (static::addons() as $ slug => $addon) {315 foreach (static::addons() as $addon) { 316 316 if ($addon->hostedBy()) { 317 317 continue; // the host claims its whole subtree, hosted values included … … 382 382 { 383 383 $option = get_option($path, $fallback); 384 return Cast::to($cast, Helper::ifEmpty($option, $fallback, $strict = true));384 return Cast::to($cast, Helper::ifEmpty($option, $fallback, true)); // use strict comparison 385 385 } 386 386 … … 393 393 protected function compose(array $settings): array 394 394 { 395 foreach (static::addons() as $ slug => $addon) {395 foreach (static::addons() as $addon) { 396 396 if ($addon->hostedBy()) { 397 397 continue; // mounted by its host's whole subtree -
site-reviews/tags/8.3.8/plugin/Database/Query.php
r3642444 r3803670 44 44 public function ratings(array $args = []): array 45 45 { 46 $this->setArgs($args, $unset = ['orderby']);46 $this->setArgs($args, ['orderby']); // unset orderby 47 47 $results = glsr(Database::class)->dbGetResults($this->queryRatings(), \ARRAY_A); 48 48 return $this->normalizeRatings($results); … … 55 55 return []; 56 56 } 57 $this->setArgs($args, $unset = ['orderby']);57 $this->setArgs($args, ['orderby']); // unset orderby 58 58 $results = glsr(Database::class)->dbGetResults($this->$method(), \ARRAY_A); 59 59 return $this->normalizeRatingsByAssignedId($results); … … 125 125 public function totalReviews(array $args = [], array $reviews = []): int 126 126 { 127 $this->setArgs($args, $unset = ['orderby']);127 $this->setArgs($args, ['orderby']); // unset orderby 128 128 if (empty($this->sqlLimit()) && !empty($reviews)) { 129 129 return count($reviews); -
site-reviews/tags/8.3.8/plugin/Database/RatingManager.php
r3474155 r3803670 22 22 $metaTable = sprintf('%smeta', $metaGroup); 23 23 $ratings = glsr(Query::class)->ratingsFor($metaTable, $args); 24 foreach ($ratings as $id => &$group) { 25 $group = $this->reduce($group, $args); 26 } 24 $ratings = array_map(fn ($group) => $this->reduce($group, $args), $ratings); 27 25 return glsr()->filterArray('ratings/grouped', $ratings, $metaGroup, $args); 28 26 } -
site-reviews/tags/8.3.8/plugin/Database/Sql.php
r3642444 r3803670 284 284 $this->join('assigned_posts', $this->joinKeyword()), 285 285 $this->args['assigned_posts'], 286 $prepare = false286 false // don't prepare 287 287 ); 288 288 } … … 304 304 $this->join('assigned_terms', $this->joinKeyword()), 305 305 $this->args['assigned_terms'], 306 $prepare = false306 false // don't prepare 307 307 ); 308 308 } … … 313 313 $this->join('assigned_users', $this->joinKeyword()), 314 314 $this->args['assigned_users'], 315 $prepare = false315 false // don't prepare 316 316 ); 317 317 } … … 322 322 $this->join('posts', 'INNER JOIN'), 323 323 $this->args['content'], 324 $prepare = false324 false // don't prepare 325 325 ); 326 326 } … … 331 331 $this->join('posts', 'INNER JOIN'), 332 332 array_filter($this->args['date']), 333 $prepare = false333 false // don't prepare 334 334 ); 335 335 } … … 340 340 $this->join('posts', 'INNER JOIN'), 341 341 $this->args['user__in'], 342 $prepare = false342 false // don't prepare 343 343 ); 344 344 } … … 349 349 $this->join('posts', 'INNER JOIN'), 350 350 $this->args['user__not_in'], 351 $prepare = false351 false // don't prepare 352 352 ); 353 353 } -
site-reviews/tags/8.3.8/plugin/Database/Tables.php
r3683434 r3803670 124 124 { 125 125 return 'sqlite' === $this->engine; 126 } 127 128 /** 129 * If SQLite Database Integration plugin is < v3. 130 */ 131 public function isSqliteLegacy(): bool 132 { 133 return $this->isSqlite() 134 && is_a($this->db->dbh, 'WP_SQLite_Translator'); // @phpstan-ignore-line 126 135 } 127 136 -
site-reviews/tags/8.3.8/plugin/Defaults/ApiDefaults.php
r3769299 r3803670 13 13 public array $casts = [ 14 14 'blocking' => 'bool', 15 'cache' => 'bool', 15 16 'compress' => 'bool', 16 17 'cookies' => 'array', … … 50 51 'blocking' => true, // Whether the calling code requires the result of the request. 51 52 'body' => null, 53 'cache' => true, // if the response is cached 52 54 'compress' => false, // Whether to compress the $body when sending the request. 53 55 'cookies' => [], -
site-reviews/tags/8.3.8/plugin/Helpers/Arr.php
r3642444 r3803670 25 25 if (is_object($value)) { 26 26 $values = get_object_vars($value); 27 $value = Helper::ifEmpty($values, (array) $value, $strict = true);27 $value = Helper::ifEmpty($values, (array) $value, true); // use strict comparison 28 28 } 29 29 return is_array($value) ? $value : $fallback; -
site-reviews/tags/8.3.8/plugin/Helpers/Text.php
r3777315 r3803670 124 124 } 125 125 $wordCount = 0; 126 foreach ($iterator->getPartsIterator() as $part) {126 while (\IntlBreakIterator::DONE !== $iterator->next()) { 127 127 if (\IntlBreakIterator::WORD_NONE !== $iterator->getRuleStatus()) { 128 128 ++$wordCount; … … 245 245 } 246 246 $iterator = \IntlRuleBasedBreakIterator::createWordInstance(''); 247 if (!$iterator instanceof \IntlRuleBasedBreakIterator) { // has getRuleStatus() 248 return null; 249 } 247 250 $normalizedText = \Normalizer::normalize($text); 248 251 if (empty($normalizedText)) { … … 258 261 { 259 262 $map = []; 263 $text = str_replace('⍈', '⍈', $text); // a ⍈ in the text is not a placeholder 260 264 $result = preg_replace_callback('|<([a-z]+)[^>]*?>.*?</\\1>|siu', function ($matches) use (&$map) { 261 265 $map[] = $matches[0]; -
site-reviews/tags/8.3.8/plugin/Integrations/MultilingualPress/Defaults/SyncReviewDefaults.php
r3474155 r3803670 3 3 namespace GeminiLabs\SiteReviews\Integrations\MultilingualPress\Defaults; 4 4 5 use GeminiLabs\SiteReviews\Defaults\CustomFieldsDefaults; 5 6 use GeminiLabs\SiteReviews\Defaults\UpdateReviewDefaults; 6 7 … … 39 40 'author' => 'name', 40 41 ]; 42 43 /** 44 * Normalize provided values, this always runs first. 45 */ 46 protected function normalize(array $values = []): array 47 { 48 $customKeys = array_keys(glsr(CustomFieldsDefaults::class)->call('merge', $values)); 49 $this->guarded = array_values(array_unique(array_merge($this->guarded, $customKeys))); // guard all custom keys 50 return parent::normalize($values); 51 } 41 52 } -
site-reviews/tags/8.3.8/plugin/Integrations/MultilingualPress/RelationSaveHelper.php
r3518858 r3803670 8 8 use GeminiLabs\SiteReviews\Defaults\RatingDefaults; 9 9 use GeminiLabs\SiteReviews\Helpers\Arr; 10 use GeminiLabs\SiteReviews\Integrations\MultilingualPress\Defaults\SyncReviewDefaults;11 10 use GeminiLabs\SiteReviews\Integrations\MultilingualPress\MetaboxFields\AssignedPostsField; 12 11 use GeminiLabs\SiteReviews\Integrations\MultilingualPress\MetaboxFields\AssignedUsersField; … … 201 200 } 202 201 202 /** 203 * Write the values on the remote review with the assigned posts and users mapped to the remote site. 204 * 205 * @param array $data The guarded values (ReviewCopier::syncData) with the source site's assigned ids 206 */ 203 207 public function syncUpdate(array $data, bool $force = false): void 204 208 { … … 206 210 return; 207 211 } 208 $guarded = glsr(SyncReviewDefaults::class)->merge($data); 212 // Not merged here as this runs on the remote site. 213 $values = $data; 214 unset($values['assigned_posts'], $values['assigned_users']); 209 215 if ($force || $this->canSyncAssignment(AssignedPostsField::FIELD_COPY_ASSIGNED_POSTS)) { 210 216 $sourcePostIds = Arr::consolidate($data['assigned_posts'] ?? []); 211 $ guarded['assigned_posts'] = $this->remoteAssignedPosts($sourcePostIds);217 $values['assigned_posts'] = $this->remoteAssignedPosts($sourcePostIds); 212 218 } 213 219 if ($force || $this->canSyncAssignment(AssignedUsersField::FIELD_COPY_ASSIGNED_USERS)) { 214 220 $sourceUserIds = Arr::consolidate($data['assigned_users'] ?? []); 215 $ guarded['assigned_users'] = $this->remoteAssignedUsers($sourceUserIds);216 } 217 $originalSiteId = $this->maybeSwitchSite($this->context->remoteSiteId()); 218 glsr_update_review($this->context->remotePostId(), $ guarded);221 $values['assigned_users'] = $this->remoteAssignedUsers($sourceUserIds); 222 } 223 $originalSiteId = $this->maybeSwitchSite($this->context->remoteSiteId()); 224 glsr_update_review($this->context->remotePostId(), $values); 219 225 $this->syncAssignedTerms(); 220 226 $this->maybeRestoreSite($originalSiteId); -
site-reviews/tags/8.3.8/plugin/Integrations/MultilingualPress/ReviewCopier.php
r3637056 r3803670 3 3 namespace GeminiLabs\SiteReviews\Integrations\MultilingualPress; 4 4 5 use GeminiLabs\SiteReviews\Integrations\MultilingualPress\Defaults\SyncReviewDefaults; 6 use GeminiLabs\SiteReviews\Review; 5 7 use Inpsyde\MultilingualPress\Framework\Api\ContentRelations; 6 8 use Inpsyde\MultilingualPress\Framework\SwitchSiteTrait; … … 91 93 public function sync(): void 92 94 { 93 $review = glsr_get_review($this->sourcePostId); 94 $data = wp_parse_args($review->toArray(), $review->custom()->toArray()); 95 $data = $this->syncData(glsr_get_review($this->sourcePostId)); 95 96 $this->run(function ($context) use ($data) { 96 97 $helper = new RelationSaveHelper($context); 97 98 $helper->syncUpdate($data, true); 98 99 }); 100 } 101 102 public function syncData(Review $review): array 103 { 104 $data = wp_parse_args($review->toArray(), $review->custom()->toArray()); 105 // Guarded on the source site: the site-reviews/defaults/sync-review filter reads the review's form here. 106 $data = glsr(SyncReviewDefaults::class)->merge($data); 107 $data['assigned_posts'] = $review->assigned_posts; // the source ids mapped by syncUpdate() on each remote site 108 $data['assigned_users'] = $review->assigned_users; 109 return $data; 99 110 } 100 111 -
site-reviews/tags/8.3.8/plugin/Integrations/WPLoyalty/Controller.php
r3637056 r3803670 44 44 ]); 45 45 $messages = [$field->after]; 46 foreach ($rewardsList as $ action => $rewards) {47 foreach ($rewards as $ key => $reward) {46 foreach ($rewardsList as $rewards) { 47 foreach ($rewards as $reward) { 48 48 $messages[] = $reward['messages'] ?? ''; 49 49 } -
site-reviews/tags/8.3.8/plugin/Integrations/WooCommerce/Controllers/RestApi/ProductReviewsController.php
r3642444 r3803670 226 226 $postArgs = $this->prepare_item_for_update($request); 227 227 $postArgs['ID'] = $review->ID; 228 $updatePost = wp_update_post($postArgs, $wperror = true);228 $updatePost = wp_update_post($postArgs, true); // return a WP_Error on failure 229 229 if (is_wp_error($updatePost)) { 230 230 return new \WP_Error('woocommerce_rest_comment_failed_edit', 'Updating review failed.', ['status' => 500]); -
site-reviews/tags/8.3.8/plugin/Modules/Html/Form.php
r3683434 r3803670 500 500 protected function normalizeFieldValue(FieldContract $field): void 501 501 { 502 if ($this->session->failed && 'hidden' === $field->original_type) { 503 return; // hidden fields are signed 504 } 502 505 if ($field->isChoiceField()) { 503 506 $value = Cast::toArray($this->session->values[$field->original_name] ?? []); … … 511 514 } 512 515 516 /** 517 * @return array<string, string|array{hidden: string[], visible: int}> 518 */ 519 protected function signedValues(): array 520 { 521 $lists = $values = []; 522 foreach ($this->hidden() as $field) { 523 $values[$field->original_name] = $field->value; 524 if (str_ends_with($field->name, '[]')) { // PHP reads these fields as a list 525 $lists[$field->original_name]['hidden'][] = Cast::toString($field->value); 526 } 527 } 528 $visibleFields = $this->visible(); 529 foreach (array_keys($lists) as $name) { 530 $lists[$name]['visible'] = count( 531 array_filter($visibleFields, fn ($field) => $name === $field->original_name) 532 ); 533 } 534 $values = array_merge($values, $lists); 535 return $this->app()->filterArray("{$this->formName()}/signature/values", $values, $this); 536 } 537 513 538 protected function signForm(): void 514 539 { 515 $hidden = $this->hidden(); 516 $values = []; 517 foreach ($hidden as $field) { 518 $values[$field->original_name] = $field->value; 519 } 520 $values = $this->app()->filterArray("{$this->formName()}/signature/values", $values, $this); 540 $values = $this->signedValues(); 521 541 $signatureField = $this->field('form_signature', [ 522 542 'type' => 'hidden', 523 543 'value' => glsr(Encryption::class)->encrypt(maybe_serialize($values)), 524 544 ]); 525 $fields = array_values(array_merge($ hidden, [$signatureField], $this->visible()));545 $fields = array_values(array_merge($this->hidden(), [$signatureField], $this->visible())); 526 546 $this->exchangeArray($fields); 527 547 } -
site-reviews/tags/8.3.8/plugin/Modules/Html/ReviewForm.php
r3683434 r3803670 6 6 use GeminiLabs\SiteReviews\Helpers\Arr; 7 7 use GeminiLabs\SiteReviews\Helpers\Cast; 8 use GeminiLabs\SiteReviews\Request; 8 9 9 10 class ReviewForm extends Form … … 26 27 { 27 28 do_action('litespeed_nonce', 'submit-review'); // @litespeedcache 28 $referer = glsr()->filterString('review-form/referer', wp_get_referer());29 $referer = glsr()->filterString('review-form/referer', $this->referer()); 29 30 $config = [ 30 31 '_action' => 'submit-review', … … 88 89 return $fields; 89 90 } 91 92 /** 93 * The page the visitor came from. 94 */ 95 protected function referer(): string 96 { 97 if (glsr()->session()->cast('form_invalid', 'bool')) { 98 $submitted = new Request(glsr()->session()->array('form_values')); 99 if ($referer = Cast::toString($submitted->signedValues()['_referer'] ?? '')) { 100 return $referer; 101 } 102 } 103 return Cast::toString(wp_get_referer()); 104 } 90 105 } -
site-reviews/tags/8.3.8/plugin/Modules/Html/SettingForm.php
r3722268 r3803670 141 141 return; // only a setting field has dependencies 142 142 } 143 $isHidden = false;144 143 foreach (Arr::consolidate($field->depends_on) as $path => $expectedValue) { 145 144 $default = Arr::get(glsr()->defaults(), $path); -
site-reviews/tags/8.3.8/plugin/Modules/Paginate.php
r3769299 r3803670 19 19 $parts = explode('?', $base); 20 20 if (wp_is_serving_rest_request() || !NormalizePaginationArgs::pagedRequest()->isEmpty()) { 21 $parts = [ $parts[0]]; // this is an AJAX request21 $parts = []; // this is an AJAX request 22 22 } 23 23 if ($parts[1] ?? false) { -
site-reviews/tags/8.3.8/plugin/Modules/Sanitizers/ArraySanitizer.php
r2878258 r3803670 3 3 namespace GeminiLabs\SiteReviews\Modules\Sanitizers; 4 4 5 use GeminiLabs\SiteReviews\Helpers\Arr; 5 6 use GeminiLabs\SiteReviews\Helpers\Cast; 6 7 … … 9 10 abstract public function run(): array; 10 11 12 /** 13 * The values, with a comma-separated string among them read as several values. 14 */ 15 protected function splitValue(): array 16 { 17 $values = []; 18 foreach ($this->value() as $value) { 19 $values[] = is_string($value) ? Arr::convertFromString($value) : [$value]; 20 } 21 return array_merge([], ...$values); 22 } 23 11 24 protected function value(): array 12 25 { -
site-reviews/tags/8.3.8/plugin/Modules/Sanitizers/SanitizeEmails.php
r2884378 r3803670 8 8 { 9 9 $emails = explode(',', $this->value()); 10 foreach ($emails as &$email) { 11 $email = sanitize_email($email); 12 } 10 $emails = array_map(fn ($email) => sanitize_email($email), $emails); 13 11 return implode(',', array_filter($emails)); 14 12 } -
site-reviews/tags/8.3.8/plugin/Modules/Sanitizers/SanitizePostIds.php
r2878258 r3803670 11 11 { 12 12 return Arr::uniqueInt( 13 array_map([Helper::class, 'getPostId'], $this-> value())13 array_map([Helper::class, 'getPostId'], $this->splitValue()) 14 14 ); 15 15 } -
site-reviews/tags/8.3.8/plugin/Modules/Sanitizers/SanitizeTermIds.php
r2878258 r3803670 11 11 { 12 12 return Arr::uniqueInt( 13 array_map([Helper::class, 'getTermTaxonomyId'], $this-> value())13 array_map([Helper::class, 'getTermTaxonomyId'], $this->splitValue()) 14 14 ); 15 15 } -
site-reviews/tags/8.3.8/plugin/Modules/Sanitizers/SanitizeUserIds.php
r2878258 r3803670 11 11 { 12 12 return Arr::uniqueInt( 13 array_map([Helper::class, 'getUserId'], $this-> value())13 array_map([Helper::class, 'getUserId'], $this->splitValue()) 14 14 ); 15 15 } -
site-reviews/tags/8.3.8/plugin/Modules/Schema.php
r3642444 r3803670 114 114 { 115 115 if ($schema = $this->retrieve()) { 116 $json = (string) wp_json_encode($schema, \JSON_ UNESCAPED_UNICODE | \JSON_UNESCAPED_SLASHES);116 $json = (string) wp_json_encode($schema, \JSON_HEX_AMP | \JSON_HEX_TAG | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE); 117 117 printf('<script type="application/ld+json" class="%s-schema">%s</script>', glsr()->id, $json); 118 118 } … … 209 209 return $this->getSchemaOptionDefault($setting, $fallback); 210 210 } 211 return Helper::ifEmpty($setting, $fallback, $strict = true);211 return Helper::ifEmpty($setting, $fallback, true); // use strict comparison 212 212 } 213 213 -
site-reviews/tags/8.3.8/plugin/Modules/SystemInfo.php
r3642444 r3803670 117 117 ]; 118 118 } 119 $engines = glsr(Tables::class)->tableEngines( $removePrefix = true);119 $engines = glsr(Tables::class)->tableEngines(true); // remove the prefix 120 120 foreach ($engines as $engine => $tables) { 121 121 $engines[$engine] = sprintf('%s (%s)', $engine, implode('|', $tables)); -
site-reviews/tags/8.3.8/plugin/Modules/Validator.php
r3474155 r3803670 172 172 * @param mixed $value 173 173 */ 174 protected function getSize(string $attribute, $value): int174 protected function getSize(string $attribute, $value): float 175 175 { 176 176 $hasNumeric = $this->hasRule($attribute, $this->numericRules); 177 177 if (is_numeric($value) && $hasNumeric) { 178 return ( int) $value;178 return (float) $value; 179 179 } 180 180 if (is_array($value)) { -
site-reviews/tags/8.3.8/plugin/Modules/Validator/CaptchaValidatorAbstract.php
r3488530 r3803670 84 84 return [ 85 85 'body' => $body, 86 ' force' => true,86 'cache' => false, 87 87 ]; 88 88 } -
site-reviews/tags/8.3.8/plugin/Modules/Validator/FriendlycaptchaV2Validator.php
r3488530 r3803670 65 65 { 66 66 return [ 67 'force' => true, 67 'body' => wp_json_encode($body), 68 'cache' => false, 68 69 'headers' => [ 69 70 'Content-Type' => 'application/json', 70 71 'X-API-Key' => $this->siteSecret(), 71 72 ], 72 'body' => wp_json_encode($body),73 73 ]; 74 74 } -
site-reviews/tags/8.3.8/plugin/Modules/Validator/ProcaptchaValidator.php
r3637056 r3803670 55 55 { 56 56 return [ 57 'force' => true, 57 'body' => wp_json_encode($body), 58 'cache' => false, 58 59 'headers' => ['Content-Type' => 'application/json'], 59 'body' => wp_json_encode($body),60 60 ]; 61 61 } -
site-reviews/tags/8.3.8/plugin/Modules/Validator/SignatureValidator.php
r3683434 r3803670 3 3 namespace GeminiLabs\SiteReviews\Modules\Validator; 4 4 5 use GeminiLabs\SiteReviews\Helpers\Arr; 5 6 use GeminiLabs\SiteReviews\Helpers\Cast; 6 7 … … 10 11 { 11 12 $isValid = true; 12 $ values = $this->request->signedValues(['form_id' => '']);13 foreach ($ values as $key => $value) {14 if ( Cast::toString($value) !== $this->request->cast($key, 'string')) {13 $signedValues = $this->request->signedValues(['form_id' => '']); 14 foreach ($signedValues as $key => $signedValue) { 15 if ($this->hasValueChanged($signedValue, $this->request->get($key))) { 15 16 $isValid = false; 16 glsr_log()->debug($ values);17 glsr_log()->debug($signedValues); 17 18 break; 18 19 } 19 20 } 20 return glsr()->filterBool('validate/signature', $isValid, $ values, $this->request);21 return glsr()->filterBool('validate/signature', $isValid, $signedValues, $this->request); 21 22 } 22 23 … … 30 31 } 31 32 } 33 34 /** 35 * @param string|array{hidden?: string[], visible?: int} $signedValue 36 * @param mixed $requestValue 37 */ 38 protected function hasValueChanged($signedValue, $requestValue): bool 39 { 40 if (!is_array($signedValue)) { 41 return is_array($requestValue) || Cast::toString($signedValue) !== Cast::toString($requestValue); 42 } 43 if (!Arr::isIndexedAndFlat($requestValue)) { 44 return true; 45 } 46 $requestValue = array_map([Cast::class, 'toString'], $requestValue); 47 foreach (Arr::consolidate($signedValue['hidden'] ?? []) as $hidden) { 48 $index = array_search(Cast::toString($hidden), $requestValue, true); 49 if (false === $index) { 50 return true; 51 } 52 unset($requestValue[$index]); 53 } 54 return count($requestValue) > Cast::toInt($signedValue['visible'] ?? 0); 55 } 32 56 } -
site-reviews/tags/8.3.8/plugin/Modules/Validator/ValidationRules.php
r3642444 r3803670 162 162 * @param mixed $value 163 163 */ 164 abstract protected function getSize(string $attribute, $value): int;164 abstract protected function getSize(string $attribute, $value): float; 165 165 166 166 /** … … 173 173 } 174 174 return preg_replace_callback('/(%s)/', function () use (&$parameters) { 175 foreach ($parameters as $key => $value) { 176 return array_shift($parameters); 177 } 175 return array_shift($parameters); 178 176 }, $message); 179 177 } -
site-reviews/tags/8.3.8/plugin/Notices/GatekeeperNotice.php
r3642444 r3803670 121 121 return ''; 122 122 } 123 if (!str_starts_with($data['plugin_uri'], 'https://wordpress.org/plugins/')) { 124 return ''; 125 } 123 126 return $this->pluginAction([ 124 127 'action' => 'install-plugin', … … 126 129 'name' => $data['name'], 127 130 'nonce_prefix' => 'install-plugin_', 128 'plugin' => $data['textdomain'],131 'plugin' => dirname($data['plugin']), // wordpress.org names a plugin's folder after its slug 129 132 /* translators: %s: the plugin name */ 130 133 'text' => _x('Install %s', 'admin-text', 'site-reviews'), … … 183 186 { 184 187 $links = []; 185 foreach ($errors as $ plugin => $data) {188 foreach ($errors as $data) { 186 189 $links[] = sprintf('<span class="plugin-%s"><a href="%s">%s</a></span>', 187 190 $data['textdomain'], -
site-reviews/tags/8.3.8/readme.txt
r3777315 r3803670 4 4 Tags: reviews, ratings, testimonials, product reviews, business reviews 5 5 Tested up to: 7.1 6 Stable tag: 8.3. 76 Stable tag: 8.3.8 7 7 License: GPLv3 8 8 License URI: https://www.gnu.org/licenses/gpl-3.0.html … … 211 211 212 212 == Changelog == 213 214 = 8.3.8 (2026-11-15) = 215 216 - Fixed a security issue in review excerpts 217 - Fixed a security issue in the notice shown after restoring a revision 218 - Fixed a security issue in the review type filter 219 - Fixed a security issue in the schema 220 - Fixed captcha checks slowly filling up the database 221 - Fixed forms with more than one Assigned Pages, Categories or Users field not submitting 222 - Fixed hidden form fields changing after a failed submission 223 - Fixed MultilingualPress translations losing their custom field values when the original review is edited 224 - Fixed number fields ignoring decimals in their minimum and maximum 225 - Fixed reviews not saving with version 3 of the SQLite Database Integration plugin 226 - Fixed some assigned pages, categories or users not being saved with a review 227 - Fixed the admin search permission check 228 - Fixed the Install button in the missing plugin notice 229 - Fixed the IP address detection tool permission check 230 - Fixed the review approval permission check 231 - Fixed the validation of submitted reviews 232 - Fixed the verification email permission check 213 233 214 234 = 8.3.7 (2026-10-31) = -
site-reviews/tags/8.3.8/site-reviews.php
r3777315 r3803670 8 8 * Plugin URI: https://wordpress.org/plugins/site-reviews 9 9 * Description: Receive and display reviews on your website 10 * Version: 8.3. 710 * Version: 8.3.8 11 11 * Author: Paul Ryley 12 12 * Author URI: https://site-reviews.com -
site-reviews/trunk/changelog.txt
r3777315 r3803670 1 1 == Changelog == 2 3 = 8.3.8 (2026-11-15) = 4 5 - Fixed a security issue in review excerpts 6 - Fixed a security issue in the notice shown after restoring a revision 7 - Fixed a security issue in the review type filter 8 - Fixed a security issue in the schema 9 - Fixed captcha checks slowly filling up the database 10 - Fixed forms with more than one Assigned Pages, Categories or Users field not submitting 11 - Fixed hidden form fields changing after a failed submission 12 - Fixed MultilingualPress translations losing their custom field values when the original review is edited 13 - Fixed number fields ignoring decimals in their minimum and maximum 14 - Fixed reviews not saving with version 3 of the SQLite Database Integration plugin 15 - Fixed some assigned pages, categories or users not being saved with a review 16 - Fixed the admin search permission check 17 - Fixed the Install button in the missing plugin notice 18 - Fixed the IP address detection tool permission check 19 - Fixed the review approval permission check 20 - Fixed the validation of submitted reviews 21 - Fixed the verification email permission check 2 22 3 23 = 8.3.7 (2026-10-31) = -
site-reviews/trunk/languages/site-reviews-en_US.po
r3777315 r3803670 116 116 117 117 #: plugin/Controllers/Api/Version1/RestRenderController.php:103 118 #: plugin/Controllers/VerificationController.php: 96118 #: plugin/Controllers/VerificationController.php:105 119 119 msgid "Thank you, your review has been verified." 120 120 msgstr "Thank you, your review has been verified." 121 121 122 122 #: plugin/Controllers/Api/Version1/RestRenderController.php:104 123 #: plugin/Controllers/VerificationController.php: 97123 #: plugin/Controllers/VerificationController.php:106 124 124 msgid "Thank you, your review has been verified and is awaiting approval." 125 125 msgstr "Thank you, your review has been verified and is awaiting approval." … … 432 432 msgstr "Submitting, please wait..." 433 433 434 #: plugin/Modules/Html/ReviewForm.php:1 4434 #: plugin/Modules/Html/ReviewForm.php:15 435 435 msgid "Submit Review" 436 436 msgstr "Submit Review" … … 476 476 msgstr "You have already submitted a review." 477 477 478 #: plugin/Modules/Validator/SignatureValidator.php:2 7478 #: plugin/Modules/Validator/SignatureValidator.php:28 479 479 #: views/pages/documentation/support/common-problems-and-solutions.php:89 480 480 msgid "This review cannot be submitted, please refresh the page and try again." … … 2437 2437 msgstr "Enabling this option will persist field values entered into the review form until either the review is submitted or the browser tab or window is closed." 2438 2438 2439 #: plugin/Database.php:23 72439 #: plugin/Database.php:231 2440 2440 msgctxt "admin-text" 2441 2441 msgid "(no title)" … … 3400 3400 3401 3401 #: plugin/Commands/SendVerificationEmail.php:71 3402 #: plugin/Controllers/VerificationController.php:3 43402 #: plugin/Controllers/VerificationController.php:35 3403 3403 msgctxt "admin-text" 3404 3404 msgid "Resend Verification Request" … … 3486 3486 msgstr "Import" 3487 3487 3488 #: plugin/Controllers/AdminController.php:3 093489 #: plugin/Controllers/AdminController.php:3 273490 #: plugin/Controllers/AdminController.php:34 03488 #: plugin/Controllers/AdminController.php:313 3489 #: plugin/Controllers/AdminController.php:332 3490 #: plugin/Controllers/AdminController.php:346 3491 3491 msgctxt "admin-text" 3492 3492 msgid "Nothing found." … … 3580 3580 3581 3581 #. translators: %s: the review type 3582 #: plugin/Controllers/EditorController.php:10 83582 #: plugin/Controllers/EditorController.php:109 3583 3583 #, php-format 3584 3584 msgctxt "admin-text" … … 3681 3681 msgstr "Respond" 3682 3682 3683 #: plugin/Controllers/ListTableController.php:27 23683 #: plugin/Controllers/ListTableController.php:270 3684 3684 msgctxt "admin-text" 3685 3685 msgid "Sorry, you are not allowed to respond to this review." 3686 3686 msgstr "Sorry, you are not allowed to respond to this review." 3687 3687 3688 #: plugin/Controllers/ListTableController.php:27 53688 #: plugin/Controllers/ListTableController.php:273 3689 3689 msgctxt "admin-text" 3690 3690 msgid "Someone" … … 3692 3692 3693 3693 #. translators: %s: user's name 3694 #: plugin/Controllers/ListTableController.php:2 813694 #: plugin/Controllers/ListTableController.php:279 3695 3695 #, php-format 3696 3696 msgctxt "admin-text" … … 3821 3821 msgstr "You do not have permission to import settings." 3822 3822 3823 #: plugin/Controllers/ToolsController.php:3 663823 #: plugin/Controllers/ToolsController.php:380 3824 3824 msgctxt "admin-text" 3825 3825 msgid "reload the page" … … 3827 3827 3828 3828 #. translators: %s: a link with the text "reload the page" 3829 #: plugin/Controllers/ToolsController.php:3 713829 #: plugin/Controllers/ToolsController.php:385 3830 3830 #, php-format 3831 3831 msgctxt "admin-text" … … 3833 3833 msgstr "The permissions have been repaired, please %s for them to take effect." 3834 3834 3835 #: plugin/Controllers/ToolsController.php:4 463835 #: plugin/Controllers/ToolsController.php:460 3836 3836 msgctxt "admin-text" 3837 3837 msgid "You do not have permission to rollback the plugin." … … 3921 3921 msgstr "Approved on:" 3922 3922 3923 #: plugin/Controllers/VerificationController.php:3 53923 #: plugin/Controllers/VerificationController.php:36 3924 3924 msgctxt "admin-text" 3925 3925 msgid "Send Verification Request" … … 4224 4224 4225 4225 #. translators: %s: the plugin name 4226 #: plugin/Notices/GatekeeperNotice.php:13 04226 #: plugin/Notices/GatekeeperNotice.php:133 4227 4227 #, php-format 4228 4228 msgctxt "admin-text" … … 4231 4231 4232 4232 #. translators: %s: the plugin name 4233 #: plugin/Notices/GatekeeperNotice.php:14 64233 #: plugin/Notices/GatekeeperNotice.php:149 4234 4234 #, php-format 4235 4235 msgctxt "admin-text" … … 7116 7116 msgstr "Limit result set to verified status." 7117 7117 7118 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:1 87118 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:19 7119 7119 msgctxt "admin-text" 7120 7120 msgid "Cannot create existing review." 7121 7121 msgstr "Cannot create existing review." 7122 7122 7123 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:2 27123 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:23 7124 7124 msgctxt "admin-text" 7125 7125 msgid "Sorry, you are not allowed to create reviews as this user." 7126 7126 msgstr "Sorry, you are not allowed to create reviews as this user." 7127 7127 7128 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:2 67128 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:27 7129 7129 msgctxt "admin-text" 7130 7130 msgid "Sorry, you are not allowed to create reviews as this review author." 7131 7131 msgstr "Sorry, you are not allowed to create reviews as this review author." 7132 7132 7133 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:3 07134 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:1 397133 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:31 7134 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:146 7135 7135 msgctxt "admin-text" 7136 7136 msgid "Sorry, you are not allowed to assign the provided terms." 7137 7137 msgstr "Sorry, you are not allowed to assign the provided terms." 7138 7138 7139 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:4 57140 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:6 87141 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:12 17139 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:46 7140 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:69 7141 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:122 7142 7142 msgctxt "admin-text" 7143 7143 msgid "Invalid review ID." 7144 7144 msgstr "Invalid review ID." 7145 7145 7146 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:5 17146 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:52 7147 7147 msgctxt "admin-text" 7148 7148 msgid "Sorry, you are not allowed to delete this review." 7149 7149 msgstr "Sorry, you are not allowed to delete this review." 7150 7150 7151 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:7 47151 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:75 7152 7152 msgctxt "admin-text" 7153 7153 msgid "Sorry, you are not allowed to view this review." 7154 7154 msgstr "Sorry, you are not allowed to view this review." 7155 7155 7156 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:8 17157 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:12 77156 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:82 7157 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:128 7158 7158 msgctxt "admin-text" 7159 7159 msgid "Sorry, you are not allowed to edit this review." 7160 7160 msgstr "Sorry, you are not allowed to edit this review." 7161 7161 7162 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:9 77162 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:98 7163 7163 msgctxt "admin-text" 7164 7164 msgid "Sorry, you do not have permission to access reviews." 7165 7165 msgstr "Sorry, you do not have permission to access reviews." 7166 7166 7167 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:10 47167 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:105 7168 7168 msgctxt "admin-text" 7169 7169 msgid "Sorry, you are not allowed to edit reviews." 7170 7170 msgstr "Sorry, you are not allowed to edit reviews." 7171 7171 7172 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:1 337172 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:140 7173 7173 msgctxt "admin-text" 7174 7174 msgid "Sorry, you are not allowed to update the review as this user." … … 7560 7560 7561 7561 #. translators: %s: plugin name 7562 #: plugin/Controllers/ToolsController.php:4 277562 #: plugin/Controllers/ToolsController.php:441 7563 7563 #, php-format 7564 7564 msgctxt "Site Reviews (admin-text)" … … 9235 9235 msgstr "" 9236 9236 9237 #: plugin/Controllers/ToolsController.php:4 519237 #: plugin/Controllers/ToolsController.php:465 9238 9238 #: views/pages/tools/general/rollback-plugin.php:21 9239 9239 msgctxt "admin-text" … … 9254 9254 msgid "%s was not updated because its folder is a git repository." 9255 9255 msgstr "" 9256 9257 #: plugin/Controllers/AdminController.php:390 9258 msgctxt "admin-text" 9259 msgid "You do not have permission to search." 9260 msgstr "" 9261 9262 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:134 9263 msgctxt "admin-text" 9264 msgid "Sorry, you are not allowed to approve this review." 9265 msgstr "" 9266 9267 #: plugin/Controllers/ToolsController.php:314 9268 #: plugin/Controllers/ToolsController.php:332 9269 msgctxt "admin-text" 9270 msgid "You do not have permission to change the IP address detection." 9271 msgstr "" 9272 9273 #: plugin/Controllers/VerificationController.php:52 9274 msgctxt "admin-text" 9275 msgid "You do not have permission to request verification of this review." 9276 msgstr "" -
site-reviews/trunk/languages/site-reviews.pot
r3777315 r3803670 3 3 msgid "" 4 4 msgstr "" 5 "Project-Id-Version: Site Reviews 8.3. 7\n"5 "Project-Id-Version: Site Reviews 8.3.8\n" 6 6 "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/site-reviews\n" 7 7 "Last-Translator: Paul Ryley <paul@geminilabs.io>\n" … … 3268 3268 3269 3269 #: plugin/Commands/SendVerificationEmail.php:71 3270 #: plugin/Controllers/VerificationController.php:3 43270 #: plugin/Controllers/VerificationController.php:35 3271 3271 msgctxt "admin-text" 3272 3272 msgid "Resend Verification Request" … … 3358 3358 msgstr "" 3359 3359 3360 #: plugin/Controllers/AdminController.php:3 093361 #: plugin/Controllers/AdminController.php:3 273362 #: plugin/Controllers/AdminController.php:34 03360 #: plugin/Controllers/AdminController.php:313 3361 #: plugin/Controllers/AdminController.php:332 3362 #: plugin/Controllers/AdminController.php:346 3363 3363 msgctxt "admin-text" 3364 3364 msgid "Nothing found." 3365 msgstr "" 3366 3367 #: plugin/Controllers/AdminController.php:390 3368 msgctxt "admin-text" 3369 msgid "You do not have permission to search." 3365 3370 msgstr "" 3366 3371 … … 3494 3499 msgstr "" 3495 3500 3496 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:1 83501 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:19 3497 3502 msgctxt "admin-text" 3498 3503 msgid "Cannot create existing review." 3499 3504 msgstr "" 3500 3505 3501 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:2 23506 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:23 3502 3507 msgctxt "admin-text" 3503 3508 msgid "Sorry, you are not allowed to create reviews as this user." 3504 3509 msgstr "" 3505 3510 3506 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:2 63511 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:27 3507 3512 msgctxt "admin-text" 3508 3513 msgid "Sorry, you are not allowed to create reviews as this review author." 3509 3514 msgstr "" 3510 3515 3511 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:3 03512 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:1 393516 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:31 3517 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:146 3513 3518 msgctxt "admin-text" 3514 3519 msgid "Sorry, you are not allowed to assign the provided terms." 3515 3520 msgstr "" 3516 3521 3517 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:4 53518 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:6 83519 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:12 13522 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:46 3523 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:69 3524 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:122 3520 3525 msgctxt "admin-text" 3521 3526 msgid "Invalid review ID." 3522 3527 msgstr "" 3523 3528 3524 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:5 13529 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:52 3525 3530 msgctxt "admin-text" 3526 3531 msgid "Sorry, you are not allowed to delete this review." 3527 3532 msgstr "" 3528 3533 3529 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:7 43534 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:75 3530 3535 msgctxt "admin-text" 3531 3536 msgid "Sorry, you are not allowed to view this review." 3532 3537 msgstr "" 3533 3538 3534 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:8 13535 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:12 73539 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:82 3540 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:128 3536 3541 msgctxt "admin-text" 3537 3542 msgid "Sorry, you are not allowed to edit this review." 3538 3543 msgstr "" 3539 3544 3540 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:9 73545 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:98 3541 3546 msgctxt "admin-text" 3542 3547 msgid "Sorry, you do not have permission to access reviews." 3543 3548 msgstr "" 3544 3549 3545 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:10 43550 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:105 3546 3551 msgctxt "admin-text" 3547 3552 msgid "Sorry, you are not allowed to edit reviews." 3548 3553 msgstr "" 3549 3554 3550 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:133 3555 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:134 3556 msgctxt "admin-text" 3557 msgid "Sorry, you are not allowed to approve this review." 3558 msgstr "" 3559 3560 #: plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php:140 3551 3561 msgctxt "admin-text" 3552 3562 msgid "Sorry, you are not allowed to update the review as this user." … … 3562 3572 3563 3573 #: plugin/Controllers/Api/Version1/RestRenderController.php:103 3564 #: plugin/Controllers/VerificationController.php: 963574 #: plugin/Controllers/VerificationController.php:105 3565 3575 msgid "Thank you, your review has been verified." 3566 3576 msgstr "" 3567 3577 3568 3578 #: plugin/Controllers/Api/Version1/RestRenderController.php:104 3569 #: plugin/Controllers/VerificationController.php: 973579 #: plugin/Controllers/VerificationController.php:106 3570 3580 msgid "Thank you, your review has been verified and is awaiting approval." 3571 3581 msgstr "" … … 3923 3933 3924 3934 #. translators: %s: the review type 3925 #: plugin/Controllers/EditorController.php:10 83935 #: plugin/Controllers/EditorController.php:109 3926 3936 #, php-format 3927 3937 msgctxt "admin-text" … … 4192 4202 msgstr "" 4193 4203 4194 #: plugin/Controllers/ListTableController.php:27 24204 #: plugin/Controllers/ListTableController.php:270 4195 4205 msgctxt "admin-text" 4196 4206 msgid "Sorry, you are not allowed to respond to this review." 4197 4207 msgstr "" 4198 4208 4199 #: plugin/Controllers/ListTableController.php:27 54209 #: plugin/Controllers/ListTableController.php:273 4200 4210 msgctxt "admin-text" 4201 4211 msgid "Someone" … … 4203 4213 4204 4214 #. translators: %s: user's name 4205 #: plugin/Controllers/ListTableController.php:2 814215 #: plugin/Controllers/ListTableController.php:279 4206 4216 #, php-format 4207 4217 msgctxt "admin-text" … … 4339 4349 msgstr "" 4340 4350 4341 #: plugin/Controllers/ToolsController.php:366 4351 #: plugin/Controllers/ToolsController.php:314 4352 #: plugin/Controllers/ToolsController.php:332 4353 msgctxt "admin-text" 4354 msgid "You do not have permission to change the IP address detection." 4355 msgstr "" 4356 4357 #: plugin/Controllers/ToolsController.php:380 4342 4358 msgctxt "admin-text" 4343 4359 msgid "reload the page" … … 4345 4361 4346 4362 #. translators: %s: a link with the text "reload the page" 4347 #: plugin/Controllers/ToolsController.php:3 714363 #: plugin/Controllers/ToolsController.php:385 4348 4364 #, php-format 4349 4365 msgctxt "admin-text" … … 4352 4368 4353 4369 #. translators: %s: plugin name 4354 #: plugin/Controllers/ToolsController.php:4 274370 #: plugin/Controllers/ToolsController.php:441 4355 4371 #, php-format 4356 4372 msgctxt "Site Reviews (admin-text)" … … 4358 4374 msgstr "" 4359 4375 4360 #: plugin/Controllers/ToolsController.php:4 464376 #: plugin/Controllers/ToolsController.php:460 4361 4377 msgctxt "admin-text" 4362 4378 msgid "You do not have permission to rollback the plugin." 4363 4379 msgstr "" 4364 4380 4365 #: plugin/Controllers/ToolsController.php:4 514381 #: plugin/Controllers/ToolsController.php:465 4366 4382 #: views/pages/tools/general/rollback-plugin.php:21 4367 4383 msgctxt "admin-text" … … 4471 4487 msgstr "" 4472 4488 4473 #: plugin/Controllers/VerificationController.php:3 54489 #: plugin/Controllers/VerificationController.php:36 4474 4490 msgctxt "admin-text" 4475 4491 msgid "Send Verification Request" 4492 msgstr "" 4493 4494 #: plugin/Controllers/VerificationController.php:52 4495 msgctxt "admin-text" 4496 msgid "You do not have permission to request verification of this review." 4476 4497 msgstr "" 4477 4498 … … 4507 4528 msgstr "" 4508 4529 4509 #: plugin/Database.php:23 74530 #: plugin/Database.php:231 4510 4531 msgctxt "admin-text" 4511 4532 msgid "(no title)" … … 6497 6518 msgstr "" 6498 6519 6499 #: plugin/Modules/Html/ReviewForm.php:1 46520 #: plugin/Modules/Html/ReviewForm.php:15 6500 6521 msgid "Submit Review" 6501 6522 msgstr "" … … 6629 6650 msgstr "" 6630 6651 6631 #: plugin/Modules/Validator/SignatureValidator.php:2 76652 #: plugin/Modules/Validator/SignatureValidator.php:28 6632 6653 #: views/pages/documentation/support/common-problems-and-solutions.php:89 6633 6654 msgid "This review cannot be submitted, please refresh the page and try again." … … 6660 6681 6661 6682 #. translators: %s: the plugin name 6662 #: plugin/Notices/GatekeeperNotice.php:13 06683 #: plugin/Notices/GatekeeperNotice.php:133 6663 6684 #, php-format 6664 6685 msgctxt "admin-text" … … 6667 6688 6668 6689 #. translators: %s: the plugin name 6669 #: plugin/Notices/GatekeeperNotice.php:14 66690 #: plugin/Notices/GatekeeperNotice.php:149 6670 6691 #, php-format 6671 6692 msgctxt "admin-text" -
site-reviews/trunk/plugin/Api.php
r3769299 r3803670 81 81 $this->forget($transientKey); 82 82 } else { 83 $result = get_site_transient($transientKey);83 $result = $args['cache'] ? get_site_transient($transientKey) : false; 84 84 if (!empty($result)) { 85 85 return new Response($result); … … 97 97 $response = new Response($result); 98 98 if ($response->successful()) { 99 $this->remember($transientKey, $result, $args['expiration']); 99 if ($args['cache']) { 100 $this->remember($transientKey, $result, $args['expiration']); 101 } 100 102 if ($args['skip_when_down']) { 101 103 $this->markReachable(); -
site-reviews/trunk/plugin/Commands/CreateReview.php
r3777315 r3803670 60 60 $this->request = $this->normalize($request); // IP address is set here 61 61 $this->setProperties(); // do this after setting the request 62 $this->review = new Review($this->toArray(), $init = false);62 $this->review = new Review($this->toArray(), false); // don't init 63 63 $this->validation = new Arguments(); 64 64 $this->custom = $this->custom(); … … 239 239 $request->set('date', ''); 240 240 $request->set('date_gmt', ''); 241 $request->set('geolocation', ''); 241 242 $request->set('is_pinned', false); 242 243 $request->set('is_verified', false); … … 244 245 $request->set('response_by', 0); 245 246 $request->set('type', 'local'); 247 $request->set('verified', ''); 248 $request->set('verified_on', ''); 249 $request->set('verified_requested', ''); 246 250 } 247 251 glsr()->action('review/request', $request); -
site-reviews/trunk/plugin/Commands/FetchPagedReviews.php
r3683434 r3803670 33 33 return [ 34 34 'max_num_pages' => $this->html->max_num_pages, 35 'pagination' => $this->html->getPagination( $wrap = false),35 'pagination' => $this->html->getPagination(false), // don't wrap 36 36 'reviews' => $this->html->getReviews(), 37 37 ]; -
site-reviews/trunk/plugin/Controllers/AdminController.php
r3683434 r3803670 262 262 public function searchAssignedPostsAjax(Request $request): void 263 263 { 264 $this->checkSearchPermission(); 264 265 $search = glsr(Sanitizer::class)->sanitizeText($request->search); 265 266 $results = glsr(Database::class)->searchAssignedPosts($search)->results(); … … 274 275 public function searchAssignedUsersAjax(Request $request): void 275 276 { 277 $this->checkSearchPermission(); 276 278 $search = glsr(Sanitizer::class)->sanitizeText($request->search); 277 279 $results = glsr(Database::class)->searchAssignedUsers($search)->results(); … … 289 291 public function searchAuthorsAjax(Request $request): void 290 292 { 293 $this->checkSearchPermission(); 291 294 $search = glsr(Sanitizer::class)->sanitizeText($request->search); 292 295 $results = glsr(Database::class)->searchUsers($search)->results(); … … 304 307 public function searchPostsAjax(Request $request): void 305 308 { 309 $this->checkSearchPermission(); 306 310 $search = glsr(Sanitizer::class)->sanitizeText($request->search); 307 311 $results = glsr(Database::class)->searchPosts($search)->render(); … … 317 321 public function searchStringsAjax(Request $request): void 318 322 { 323 $this->checkSearchPermission(); 319 324 $search = glsr(Sanitizer::class)->sanitizeText($request->search); 320 325 $exclude = Arr::consolidate($request->exclude); … … 335 340 public function searchUsersAjax(Request $request): void 336 341 { 342 $this->checkSearchPermission(); 337 343 $search = glsr(Sanitizer::class)->sanitizeText($request->search); 338 344 $results = glsr(Database::class)->searchUsers($search)->render(); … … 372 378 $this->execute(new ToggleStatus($request))->sendJsonResponse(); 373 379 } 380 381 /** 382 * Refuse the request with an error notice unless the user can edit reviews. 383 */ 384 protected function checkSearchPermission(): void 385 { 386 if (glsr()->can('edit_posts')) { 387 return; 388 } 389 glsr(Notice::class)->addError( 390 _x('You do not have permission to search.', 'admin-text', 'site-reviews') 391 ); 392 wp_send_json_error([ 393 'notices' => glsr(Notice::class)->get(), 394 ]); 395 } 374 396 } -
site-reviews/trunk/plugin/Controllers/Api/Version1/Permissions/ReviewPermissions.php
r3583819 r3803670 3 3 namespace GeminiLabs\SiteReviews\Controllers\Api\Version1\Permissions; 4 4 5 use GeminiLabs\SiteReviews\Defaults\UpdateReviewDefaults; 5 6 use GeminiLabs\SiteReviews\Helpers\Arr; 6 7 use GeminiLabs\SiteReviews\Review; … … 127 128 $message = _x('Sorry, you are not allowed to edit this review.', 'admin-text', 'site-reviews'); 128 129 return new \WP_Error('rest_cannot_edit', $message, [ 130 'status' => rest_authorization_required_code(), 131 ]); 132 } 133 if ($this->is_approving($request, $review) && !glsr()->can('publish_post', $review->ID)) { 134 $message = _x('Sorry, you are not allowed to approve this review.', 'admin-text', 'site-reviews'); 135 return new \WP_Error('rest_cannot_publish', $message, [ 129 136 'status' => rest_authorization_required_code(), 130 137 ]); … … 183 190 return true; 184 191 } 192 193 /** 194 * Whether the update approves a review that is not approved yet. 195 */ 196 protected function is_approving(\WP_REST_Request $request, Review $review): bool 197 { 198 $values = glsr(UpdateReviewDefaults::class)->restrict($request->get_params()); // the status comes from is_approved 199 return 'publish' === Arr::get($values, 'status') && !$review->is_approved; 200 } 185 201 } -
site-reviews/trunk/plugin/Controllers/Api/Version1/RestReviewController.php
r3683434 r3803670 291 291 ->buildReviewsHtml(); 292 292 $response = rest_ensure_response([ 293 'pagination' => $html->getPagination( $wrap = false),293 'pagination' => $html->getPagination(false), // don't wrap 294 294 'rendered' => $html->getReviews(), 295 295 ]); -
site-reviews/trunk/plugin/Controllers/EditorController.php
r3642444 r3803670 73 73 } 74 74 $strings = glsr(UpdatedMessageDefaults::class)->defaults(); 75 $restored = filter_input(\INPUT_GET, 'revision'); 76 if ($revisionTitle = wp_post_revision_title(intval($restored), false)) { 75 $restored = false; 76 $revisionId = intval(filter_input(\INPUT_GET, 'revision')); 77 if ($revisionTitle = wp_post_revision_title($revisionId, false)) { 77 78 $restored = sprintf($strings['restored'], $revisionTitle); 78 79 } -
site-reviews/trunk/plugin/Controllers/ListTableController.php
r3642444 r3803670 206 206 unset($filters['type']); 207 207 } 208 foreach ($filters as $key => &$value) { 209 $value = glsr($value)->title(); 210 } 208 $filters = array_map(fn ($value) => glsr($value)->title(), $filters); 211 209 ksort($filters); 212 210 $setting = 'edit_'.glsr()->post_type.'_filters'; … … 441 439 $clause['clauses'][] = "AND {$assignedTable}.{$column} = {$value}"; 442 440 } 443 } elseif (in_array($key, ['rating', 'terms' , 'type'])) {441 } elseif (in_array($key, ['rating', 'terms'])) { 444 442 $clause['clauses'][] = "AND {$ratings}.{$key} = '{$value}'"; 443 } elseif ('type' === $key && array_key_exists($value, glsr()->retrieveAs('array', 'review_types'))) { 444 $clause['clauses'][] = "AND {$ratings}.type = '{$value}'"; 445 445 } elseif ('author' === $key && '0' === $value) { 446 446 // Filtering by the "author" URL parameter is automatically done -
site-reviews/trunk/plugin/Controllers/MainController.php
r3722268 r3803670 52 52 $table = glsr($classname); 53 53 if ($table instanceof TableRatings) { 54 $ratingsTable[$table->name( $prefixName = true)] = $table->tablename;54 $ratingsTable[$table->name(true)] = $table->tablename; // use the prefixed name 55 55 continue; 56 56 } 57 $customTables[$table->name( $prefixName = true)] = $table->tablename;57 $customTables[$table->name(true)] = $table->tablename; // use the prefixed name 58 58 } 59 59 return $customTables + $ratingsTable + $tables; -
site-reviews/trunk/plugin/Controllers/PrivacyController.php
r3769299 r3803670 152 152 ", $email, glsr()->post_type, $this->perPage, ($page - 1) * $this->perPage); 153 153 $reviewIds = glsr(Database::class)->dbGetCol($sql); 154 return empty($reviewIds) ? [] : glsr(Query::class)->reviews([ ], $reviewIds);154 return empty($reviewIds) ? [] : glsr(Query::class)->reviews(['order' => 'asc', 'orderby' => 'id'], $reviewIds); 155 155 } 156 156 } -
site-reviews/trunk/plugin/Controllers/ToolsController.php
r3769299 r3803670 310 310 public function ipAddressDetection(Request $request): void 311 311 { 312 if (!glsr()->can(glsr()->getPermission('settings'))) { 313 glsr(Notice::class)->addError( 314 _x('You do not have permission to change the IP address detection.', 'admin-text', 'site-reviews') 315 ); 316 return; 317 } 312 318 if (wp_validate_boolean($request->get('alt', 0))) { 313 319 $this->execute(new DetectIpAddress()); … … 322 328 public function ipAddressDetectionAjax(Request $request): void 323 329 { 330 if (!glsr()->can(glsr()->getPermission('settings'))) { 331 glsr(Notice::class)->addError( 332 _x('You do not have permission to change the IP address detection.', 'admin-text', 'site-reviews') 333 ); 334 wp_send_json_error([ 335 'notices' => glsr(Notice::class)->get(), 336 ]); 337 } 324 338 $command = wp_validate_boolean($request->get('alt', 0)) 325 339 ? $this->execute(new DetectIpAddress()) -
site-reviews/trunk/plugin/Controllers/VerificationController.php
r3642444 r3803670 14 14 use GeminiLabs\SiteReviews\Modules\Encryption; 15 15 use GeminiLabs\SiteReviews\Modules\Html\Template; 16 use GeminiLabs\SiteReviews\Modules\Notice; 16 17 use GeminiLabs\SiteReviews\Request; 17 18 use GeminiLabs\SiteReviews\Review; … … 47 48 { 48 49 $review = glsr(ReviewManager::class)->get($request->cast('post_id', 'int')); 50 if (!$review->isValid() || !glsr()->can('edit_post', $review->ID)) { 51 glsr(Notice::class)->addError( 52 _x('You do not have permission to request verification of this review.', 'admin-text', 'site-reviews') 53 ); 54 wp_send_json_error([ 55 'notices' => glsr(Notice::class)->get(), 56 ]); 57 } 49 58 $pathPostId = $review->meta()->cast('_submitted._post_id', 'int'); 50 59 $path = Cast::toString(wp_parse_url((string) get_permalink($pathPostId), \PHP_URL_PATH)); -
site-reviews/trunk/plugin/Database.php
r3642444 r3803670 31 31 public function beginTransaction(string $table): void 32 32 { 33 if (glsr(Tables::class)->isSqlite ()) {33 if (glsr(Tables::class)->isSqliteLegacy()) { 34 34 $this->dbQuery("BEGIN TRANSACTION;"); 35 } elseif (glsr(Tables::class)->is Innodb($table)) {35 } elseif (glsr(Tables::class)->isSqlite() || glsr(Tables::class)->isInnodb($table)) { 36 36 $this->dbQuery("START TRANSACTION;"); 37 37 } elseif (glsr(Tables::class)->isMyisam($table)) { … … 159 159 $fields = glsr(Query::class)->escFieldsForInsert(array_keys($data)); 160 160 $values = glsr(Query::class)->escValuesForInsert($data); 161 if (glsr(Tables::class)->isSqlite()) { 162 $sql = glsr(Query::class)->sql("INSERT OR IGNORE INTO {$table} {$fields} VALUES {$values}"); 163 } else { 164 $sql = glsr(Query::class)->sql("INSERT IGNORE INTO {$table} {$fields} VALUES {$values}"); 165 } 161 $ignore = glsr(Tables::class)->isSqliteLegacy() ? 'OR IGNORE' : 'IGNORE'; 162 $sql = glsr(Query::class)->sql("INSERT {$ignore} INTO {$table} {$fields} VALUES {$values}"); 166 163 return $this->dbQuery($sql); 167 164 } … … 186 183 $fields = glsr(Query::class)->escFieldsForInsert($fields); 187 184 $values = implode(',', $data); 188 if (glsr(Tables::class)->isSqlite()) { 189 $sql = glsr(Query::class)->sql("INSERT OR IGNORE INTO {$table} {$fields} VALUES {$values}"); 190 } else { 191 $sql = glsr(Query::class)->sql("INSERT IGNORE INTO {$table} {$fields} VALUES {$values}"); 192 } 185 $ignore = glsr(Tables::class)->isSqliteLegacy() ? 'OR IGNORE' : 'IGNORE'; 186 $sql = glsr(Query::class)->sql("INSERT {$ignore} INTO {$table} {$fields} VALUES {$values}"); 193 187 return $this->dbQuery($sql); 194 188 } -
site-reviews/trunk/plugin/Database/OptionManager.php
r3769299 r3803670 313 313 $writes = []; 314 314 $versions = []; 315 foreach (static::addons() as $ slug => $addon) {315 foreach (static::addons() as $addon) { 316 316 if ($addon->hostedBy()) { 317 317 continue; // the host claims its whole subtree, hosted values included … … 382 382 { 383 383 $option = get_option($path, $fallback); 384 return Cast::to($cast, Helper::ifEmpty($option, $fallback, $strict = true));384 return Cast::to($cast, Helper::ifEmpty($option, $fallback, true)); // use strict comparison 385 385 } 386 386 … … 393 393 protected function compose(array $settings): array 394 394 { 395 foreach (static::addons() as $ slug => $addon) {395 foreach (static::addons() as $addon) { 396 396 if ($addon->hostedBy()) { 397 397 continue; // mounted by its host's whole subtree -
site-reviews/trunk/plugin/Database/Query.php
r3642444 r3803670 44 44 public function ratings(array $args = []): array 45 45 { 46 $this->setArgs($args, $unset = ['orderby']);46 $this->setArgs($args, ['orderby']); // unset orderby 47 47 $results = glsr(Database::class)->dbGetResults($this->queryRatings(), \ARRAY_A); 48 48 return $this->normalizeRatings($results); … … 55 55 return []; 56 56 } 57 $this->setArgs($args, $unset = ['orderby']);57 $this->setArgs($args, ['orderby']); // unset orderby 58 58 $results = glsr(Database::class)->dbGetResults($this->$method(), \ARRAY_A); 59 59 return $this->normalizeRatingsByAssignedId($results); … … 125 125 public function totalReviews(array $args = [], array $reviews = []): int 126 126 { 127 $this->setArgs($args, $unset = ['orderby']);127 $this->setArgs($args, ['orderby']); // unset orderby 128 128 if (empty($this->sqlLimit()) && !empty($reviews)) { 129 129 return count($reviews); -
site-reviews/trunk/plugin/Database/RatingManager.php
r3474155 r3803670 22 22 $metaTable = sprintf('%smeta', $metaGroup); 23 23 $ratings = glsr(Query::class)->ratingsFor($metaTable, $args); 24 foreach ($ratings as $id => &$group) { 25 $group = $this->reduce($group, $args); 26 } 24 $ratings = array_map(fn ($group) => $this->reduce($group, $args), $ratings); 27 25 return glsr()->filterArray('ratings/grouped', $ratings, $metaGroup, $args); 28 26 } -
site-reviews/trunk/plugin/Database/Sql.php
r3642444 r3803670 284 284 $this->join('assigned_posts', $this->joinKeyword()), 285 285 $this->args['assigned_posts'], 286 $prepare = false286 false // don't prepare 287 287 ); 288 288 } … … 304 304 $this->join('assigned_terms', $this->joinKeyword()), 305 305 $this->args['assigned_terms'], 306 $prepare = false306 false // don't prepare 307 307 ); 308 308 } … … 313 313 $this->join('assigned_users', $this->joinKeyword()), 314 314 $this->args['assigned_users'], 315 $prepare = false315 false // don't prepare 316 316 ); 317 317 } … … 322 322 $this->join('posts', 'INNER JOIN'), 323 323 $this->args['content'], 324 $prepare = false324 false // don't prepare 325 325 ); 326 326 } … … 331 331 $this->join('posts', 'INNER JOIN'), 332 332 array_filter($this->args['date']), 333 $prepare = false333 false // don't prepare 334 334 ); 335 335 } … … 340 340 $this->join('posts', 'INNER JOIN'), 341 341 $this->args['user__in'], 342 $prepare = false342 false // don't prepare 343 343 ); 344 344 } … … 349 349 $this->join('posts', 'INNER JOIN'), 350 350 $this->args['user__not_in'], 351 $prepare = false351 false // don't prepare 352 352 ); 353 353 } -
site-reviews/trunk/plugin/Database/Tables.php
r3683434 r3803670 124 124 { 125 125 return 'sqlite' === $this->engine; 126 } 127 128 /** 129 * If SQLite Database Integration plugin is < v3. 130 */ 131 public function isSqliteLegacy(): bool 132 { 133 return $this->isSqlite() 134 && is_a($this->db->dbh, 'WP_SQLite_Translator'); // @phpstan-ignore-line 126 135 } 127 136 -
site-reviews/trunk/plugin/Defaults/ApiDefaults.php
r3769299 r3803670 13 13 public array $casts = [ 14 14 'blocking' => 'bool', 15 'cache' => 'bool', 15 16 'compress' => 'bool', 16 17 'cookies' => 'array', … … 50 51 'blocking' => true, // Whether the calling code requires the result of the request. 51 52 'body' => null, 53 'cache' => true, // if the response is cached 52 54 'compress' => false, // Whether to compress the $body when sending the request. 53 55 'cookies' => [], -
site-reviews/trunk/plugin/Helpers/Arr.php
r3642444 r3803670 25 25 if (is_object($value)) { 26 26 $values = get_object_vars($value); 27 $value = Helper::ifEmpty($values, (array) $value, $strict = true);27 $value = Helper::ifEmpty($values, (array) $value, true); // use strict comparison 28 28 } 29 29 return is_array($value) ? $value : $fallback; -
site-reviews/trunk/plugin/Helpers/Text.php
r3777315 r3803670 124 124 } 125 125 $wordCount = 0; 126 foreach ($iterator->getPartsIterator() as $part) {126 while (\IntlBreakIterator::DONE !== $iterator->next()) { 127 127 if (\IntlBreakIterator::WORD_NONE !== $iterator->getRuleStatus()) { 128 128 ++$wordCount; … … 245 245 } 246 246 $iterator = \IntlRuleBasedBreakIterator::createWordInstance(''); 247 if (!$iterator instanceof \IntlRuleBasedBreakIterator) { // has getRuleStatus() 248 return null; 249 } 247 250 $normalizedText = \Normalizer::normalize($text); 248 251 if (empty($normalizedText)) { … … 258 261 { 259 262 $map = []; 263 $text = str_replace('⍈', '⍈', $text); // a ⍈ in the text is not a placeholder 260 264 $result = preg_replace_callback('|<([a-z]+)[^>]*?>.*?</\\1>|siu', function ($matches) use (&$map) { 261 265 $map[] = $matches[0]; -
site-reviews/trunk/plugin/Integrations/MultilingualPress/Defaults/SyncReviewDefaults.php
r3474155 r3803670 3 3 namespace GeminiLabs\SiteReviews\Integrations\MultilingualPress\Defaults; 4 4 5 use GeminiLabs\SiteReviews\Defaults\CustomFieldsDefaults; 5 6 use GeminiLabs\SiteReviews\Defaults\UpdateReviewDefaults; 6 7 … … 39 40 'author' => 'name', 40 41 ]; 42 43 /** 44 * Normalize provided values, this always runs first. 45 */ 46 protected function normalize(array $values = []): array 47 { 48 $customKeys = array_keys(glsr(CustomFieldsDefaults::class)->call('merge', $values)); 49 $this->guarded = array_values(array_unique(array_merge($this->guarded, $customKeys))); // guard all custom keys 50 return parent::normalize($values); 51 } 41 52 } -
site-reviews/trunk/plugin/Integrations/MultilingualPress/RelationSaveHelper.php
r3518858 r3803670 8 8 use GeminiLabs\SiteReviews\Defaults\RatingDefaults; 9 9 use GeminiLabs\SiteReviews\Helpers\Arr; 10 use GeminiLabs\SiteReviews\Integrations\MultilingualPress\Defaults\SyncReviewDefaults;11 10 use GeminiLabs\SiteReviews\Integrations\MultilingualPress\MetaboxFields\AssignedPostsField; 12 11 use GeminiLabs\SiteReviews\Integrations\MultilingualPress\MetaboxFields\AssignedUsersField; … … 201 200 } 202 201 202 /** 203 * Write the values on the remote review with the assigned posts and users mapped to the remote site. 204 * 205 * @param array $data The guarded values (ReviewCopier::syncData) with the source site's assigned ids 206 */ 203 207 public function syncUpdate(array $data, bool $force = false): void 204 208 { … … 206 210 return; 207 211 } 208 $guarded = glsr(SyncReviewDefaults::class)->merge($data); 212 // Not merged here as this runs on the remote site. 213 $values = $data; 214 unset($values['assigned_posts'], $values['assigned_users']); 209 215 if ($force || $this->canSyncAssignment(AssignedPostsField::FIELD_COPY_ASSIGNED_POSTS)) { 210 216 $sourcePostIds = Arr::consolidate($data['assigned_posts'] ?? []); 211 $ guarded['assigned_posts'] = $this->remoteAssignedPosts($sourcePostIds);217 $values['assigned_posts'] = $this->remoteAssignedPosts($sourcePostIds); 212 218 } 213 219 if ($force || $this->canSyncAssignment(AssignedUsersField::FIELD_COPY_ASSIGNED_USERS)) { 214 220 $sourceUserIds = Arr::consolidate($data['assigned_users'] ?? []); 215 $ guarded['assigned_users'] = $this->remoteAssignedUsers($sourceUserIds);216 } 217 $originalSiteId = $this->maybeSwitchSite($this->context->remoteSiteId()); 218 glsr_update_review($this->context->remotePostId(), $ guarded);221 $values['assigned_users'] = $this->remoteAssignedUsers($sourceUserIds); 222 } 223 $originalSiteId = $this->maybeSwitchSite($this->context->remoteSiteId()); 224 glsr_update_review($this->context->remotePostId(), $values); 219 225 $this->syncAssignedTerms(); 220 226 $this->maybeRestoreSite($originalSiteId); -
site-reviews/trunk/plugin/Integrations/MultilingualPress/ReviewCopier.php
r3637056 r3803670 3 3 namespace GeminiLabs\SiteReviews\Integrations\MultilingualPress; 4 4 5 use GeminiLabs\SiteReviews\Integrations\MultilingualPress\Defaults\SyncReviewDefaults; 6 use GeminiLabs\SiteReviews\Review; 5 7 use Inpsyde\MultilingualPress\Framework\Api\ContentRelations; 6 8 use Inpsyde\MultilingualPress\Framework\SwitchSiteTrait; … … 91 93 public function sync(): void 92 94 { 93 $review = glsr_get_review($this->sourcePostId); 94 $data = wp_parse_args($review->toArray(), $review->custom()->toArray()); 95 $data = $this->syncData(glsr_get_review($this->sourcePostId)); 95 96 $this->run(function ($context) use ($data) { 96 97 $helper = new RelationSaveHelper($context); 97 98 $helper->syncUpdate($data, true); 98 99 }); 100 } 101 102 public function syncData(Review $review): array 103 { 104 $data = wp_parse_args($review->toArray(), $review->custom()->toArray()); 105 // Guarded on the source site: the site-reviews/defaults/sync-review filter reads the review's form here. 106 $data = glsr(SyncReviewDefaults::class)->merge($data); 107 $data['assigned_posts'] = $review->assigned_posts; // the source ids mapped by syncUpdate() on each remote site 108 $data['assigned_users'] = $review->assigned_users; 109 return $data; 99 110 } 100 111 -
site-reviews/trunk/plugin/Integrations/WPLoyalty/Controller.php
r3637056 r3803670 44 44 ]); 45 45 $messages = [$field->after]; 46 foreach ($rewardsList as $ action => $rewards) {47 foreach ($rewards as $ key => $reward) {46 foreach ($rewardsList as $rewards) { 47 foreach ($rewards as $reward) { 48 48 $messages[] = $reward['messages'] ?? ''; 49 49 } -
site-reviews/trunk/plugin/Integrations/WooCommerce/Controllers/RestApi/ProductReviewsController.php
r3642444 r3803670 226 226 $postArgs = $this->prepare_item_for_update($request); 227 227 $postArgs['ID'] = $review->ID; 228 $updatePost = wp_update_post($postArgs, $wperror = true);228 $updatePost = wp_update_post($postArgs, true); // return a WP_Error on failure 229 229 if (is_wp_error($updatePost)) { 230 230 return new \WP_Error('woocommerce_rest_comment_failed_edit', 'Updating review failed.', ['status' => 500]); -
site-reviews/trunk/plugin/Modules/Html/Form.php
r3683434 r3803670 500 500 protected function normalizeFieldValue(FieldContract $field): void 501 501 { 502 if ($this->session->failed && 'hidden' === $field->original_type) { 503 return; // hidden fields are signed 504 } 502 505 if ($field->isChoiceField()) { 503 506 $value = Cast::toArray($this->session->values[$field->original_name] ?? []); … … 511 514 } 512 515 516 /** 517 * @return array<string, string|array{hidden: string[], visible: int}> 518 */ 519 protected function signedValues(): array 520 { 521 $lists = $values = []; 522 foreach ($this->hidden() as $field) { 523 $values[$field->original_name] = $field->value; 524 if (str_ends_with($field->name, '[]')) { // PHP reads these fields as a list 525 $lists[$field->original_name]['hidden'][] = Cast::toString($field->value); 526 } 527 } 528 $visibleFields = $this->visible(); 529 foreach (array_keys($lists) as $name) { 530 $lists[$name]['visible'] = count( 531 array_filter($visibleFields, fn ($field) => $name === $field->original_name) 532 ); 533 } 534 $values = array_merge($values, $lists); 535 return $this->app()->filterArray("{$this->formName()}/signature/values", $values, $this); 536 } 537 513 538 protected function signForm(): void 514 539 { 515 $hidden = $this->hidden(); 516 $values = []; 517 foreach ($hidden as $field) { 518 $values[$field->original_name] = $field->value; 519 } 520 $values = $this->app()->filterArray("{$this->formName()}/signature/values", $values, $this); 540 $values = $this->signedValues(); 521 541 $signatureField = $this->field('form_signature', [ 522 542 'type' => 'hidden', 523 543 'value' => glsr(Encryption::class)->encrypt(maybe_serialize($values)), 524 544 ]); 525 $fields = array_values(array_merge($ hidden, [$signatureField], $this->visible()));545 $fields = array_values(array_merge($this->hidden(), [$signatureField], $this->visible())); 526 546 $this->exchangeArray($fields); 527 547 } -
site-reviews/trunk/plugin/Modules/Html/ReviewForm.php
r3683434 r3803670 6 6 use GeminiLabs\SiteReviews\Helpers\Arr; 7 7 use GeminiLabs\SiteReviews\Helpers\Cast; 8 use GeminiLabs\SiteReviews\Request; 8 9 9 10 class ReviewForm extends Form … … 26 27 { 27 28 do_action('litespeed_nonce', 'submit-review'); // @litespeedcache 28 $referer = glsr()->filterString('review-form/referer', wp_get_referer());29 $referer = glsr()->filterString('review-form/referer', $this->referer()); 29 30 $config = [ 30 31 '_action' => 'submit-review', … … 88 89 return $fields; 89 90 } 91 92 /** 93 * The page the visitor came from. 94 */ 95 protected function referer(): string 96 { 97 if (glsr()->session()->cast('form_invalid', 'bool')) { 98 $submitted = new Request(glsr()->session()->array('form_values')); 99 if ($referer = Cast::toString($submitted->signedValues()['_referer'] ?? '')) { 100 return $referer; 101 } 102 } 103 return Cast::toString(wp_get_referer()); 104 } 90 105 } -
site-reviews/trunk/plugin/Modules/Html/SettingForm.php
r3722268 r3803670 141 141 return; // only a setting field has dependencies 142 142 } 143 $isHidden = false;144 143 foreach (Arr::consolidate($field->depends_on) as $path => $expectedValue) { 145 144 $default = Arr::get(glsr()->defaults(), $path); -
site-reviews/trunk/plugin/Modules/Paginate.php
r3769299 r3803670 19 19 $parts = explode('?', $base); 20 20 if (wp_is_serving_rest_request() || !NormalizePaginationArgs::pagedRequest()->isEmpty()) { 21 $parts = [ $parts[0]]; // this is an AJAX request21 $parts = []; // this is an AJAX request 22 22 } 23 23 if ($parts[1] ?? false) { -
site-reviews/trunk/plugin/Modules/Sanitizers/ArraySanitizer.php
r2878258 r3803670 3 3 namespace GeminiLabs\SiteReviews\Modules\Sanitizers; 4 4 5 use GeminiLabs\SiteReviews\Helpers\Arr; 5 6 use GeminiLabs\SiteReviews\Helpers\Cast; 6 7 … … 9 10 abstract public function run(): array; 10 11 12 /** 13 * The values, with a comma-separated string among them read as several values. 14 */ 15 protected function splitValue(): array 16 { 17 $values = []; 18 foreach ($this->value() as $value) { 19 $values[] = is_string($value) ? Arr::convertFromString($value) : [$value]; 20 } 21 return array_merge([], ...$values); 22 } 23 11 24 protected function value(): array 12 25 { -
site-reviews/trunk/plugin/Modules/Sanitizers/SanitizeEmails.php
r2884378 r3803670 8 8 { 9 9 $emails = explode(',', $this->value()); 10 foreach ($emails as &$email) { 11 $email = sanitize_email($email); 12 } 10 $emails = array_map(fn ($email) => sanitize_email($email), $emails); 13 11 return implode(',', array_filter($emails)); 14 12 } -
site-reviews/trunk/plugin/Modules/Sanitizers/SanitizePostIds.php
r2878258 r3803670 11 11 { 12 12 return Arr::uniqueInt( 13 array_map([Helper::class, 'getPostId'], $this-> value())13 array_map([Helper::class, 'getPostId'], $this->splitValue()) 14 14 ); 15 15 } -
site-reviews/trunk/plugin/Modules/Sanitizers/SanitizeTermIds.php
r2878258 r3803670 11 11 { 12 12 return Arr::uniqueInt( 13 array_map([Helper::class, 'getTermTaxonomyId'], $this-> value())13 array_map([Helper::class, 'getTermTaxonomyId'], $this->splitValue()) 14 14 ); 15 15 } -
site-reviews/trunk/plugin/Modules/Sanitizers/SanitizeUserIds.php
r2878258 r3803670 11 11 { 12 12 return Arr::uniqueInt( 13 array_map([Helper::class, 'getUserId'], $this-> value())13 array_map([Helper::class, 'getUserId'], $this->splitValue()) 14 14 ); 15 15 } -
site-reviews/trunk/plugin/Modules/Schema.php
r3642444 r3803670 114 114 { 115 115 if ($schema = $this->retrieve()) { 116 $json = (string) wp_json_encode($schema, \JSON_ UNESCAPED_UNICODE | \JSON_UNESCAPED_SLASHES);116 $json = (string) wp_json_encode($schema, \JSON_HEX_AMP | \JSON_HEX_TAG | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE); 117 117 printf('<script type="application/ld+json" class="%s-schema">%s</script>', glsr()->id, $json); 118 118 } … … 209 209 return $this->getSchemaOptionDefault($setting, $fallback); 210 210 } 211 return Helper::ifEmpty($setting, $fallback, $strict = true);211 return Helper::ifEmpty($setting, $fallback, true); // use strict comparison 212 212 } 213 213 -
site-reviews/trunk/plugin/Modules/SystemInfo.php
r3642444 r3803670 117 117 ]; 118 118 } 119 $engines = glsr(Tables::class)->tableEngines( $removePrefix = true);119 $engines = glsr(Tables::class)->tableEngines(true); // remove the prefix 120 120 foreach ($engines as $engine => $tables) { 121 121 $engines[$engine] = sprintf('%s (%s)', $engine, implode('|', $tables)); -
site-reviews/trunk/plugin/Modules/Validator.php
r3474155 r3803670 172 172 * @param mixed $value 173 173 */ 174 protected function getSize(string $attribute, $value): int174 protected function getSize(string $attribute, $value): float 175 175 { 176 176 $hasNumeric = $this->hasRule($attribute, $this->numericRules); 177 177 if (is_numeric($value) && $hasNumeric) { 178 return ( int) $value;178 return (float) $value; 179 179 } 180 180 if (is_array($value)) { -
site-reviews/trunk/plugin/Modules/Validator/CaptchaValidatorAbstract.php
r3488530 r3803670 84 84 return [ 85 85 'body' => $body, 86 ' force' => true,86 'cache' => false, 87 87 ]; 88 88 } -
site-reviews/trunk/plugin/Modules/Validator/FriendlycaptchaV2Validator.php
r3488530 r3803670 65 65 { 66 66 return [ 67 'force' => true, 67 'body' => wp_json_encode($body), 68 'cache' => false, 68 69 'headers' => [ 69 70 'Content-Type' => 'application/json', 70 71 'X-API-Key' => $this->siteSecret(), 71 72 ], 72 'body' => wp_json_encode($body),73 73 ]; 74 74 } -
site-reviews/trunk/plugin/Modules/Validator/ProcaptchaValidator.php
r3637056 r3803670 55 55 { 56 56 return [ 57 'force' => true, 57 'body' => wp_json_encode($body), 58 'cache' => false, 58 59 'headers' => ['Content-Type' => 'application/json'], 59 'body' => wp_json_encode($body),60 60 ]; 61 61 } -
site-reviews/trunk/plugin/Modules/Validator/SignatureValidator.php
r3683434 r3803670 3 3 namespace GeminiLabs\SiteReviews\Modules\Validator; 4 4 5 use GeminiLabs\SiteReviews\Helpers\Arr; 5 6 use GeminiLabs\SiteReviews\Helpers\Cast; 6 7 … … 10 11 { 11 12 $isValid = true; 12 $ values = $this->request->signedValues(['form_id' => '']);13 foreach ($ values as $key => $value) {14 if ( Cast::toString($value) !== $this->request->cast($key, 'string')) {13 $signedValues = $this->request->signedValues(['form_id' => '']); 14 foreach ($signedValues as $key => $signedValue) { 15 if ($this->hasValueChanged($signedValue, $this->request->get($key))) { 15 16 $isValid = false; 16 glsr_log()->debug($ values);17 glsr_log()->debug($signedValues); 17 18 break; 18 19 } 19 20 } 20 return glsr()->filterBool('validate/signature', $isValid, $ values, $this->request);21 return glsr()->filterBool('validate/signature', $isValid, $signedValues, $this->request); 21 22 } 22 23 … … 30 31 } 31 32 } 33 34 /** 35 * @param string|array{hidden?: string[], visible?: int} $signedValue 36 * @param mixed $requestValue 37 */ 38 protected function hasValueChanged($signedValue, $requestValue): bool 39 { 40 if (!is_array($signedValue)) { 41 return is_array($requestValue) || Cast::toString($signedValue) !== Cast::toString($requestValue); 42 } 43 if (!Arr::isIndexedAndFlat($requestValue)) { 44 return true; 45 } 46 $requestValue = array_map([Cast::class, 'toString'], $requestValue); 47 foreach (Arr::consolidate($signedValue['hidden'] ?? []) as $hidden) { 48 $index = array_search(Cast::toString($hidden), $requestValue, true); 49 if (false === $index) { 50 return true; 51 } 52 unset($requestValue[$index]); 53 } 54 return count($requestValue) > Cast::toInt($signedValue['visible'] ?? 0); 55 } 32 56 } -
site-reviews/trunk/plugin/Modules/Validator/ValidationRules.php
r3642444 r3803670 162 162 * @param mixed $value 163 163 */ 164 abstract protected function getSize(string $attribute, $value): int;164 abstract protected function getSize(string $attribute, $value): float; 165 165 166 166 /** … … 173 173 } 174 174 return preg_replace_callback('/(%s)/', function () use (&$parameters) { 175 foreach ($parameters as $key => $value) { 176 return array_shift($parameters); 177 } 175 return array_shift($parameters); 178 176 }, $message); 179 177 } -
site-reviews/trunk/plugin/Notices/GatekeeperNotice.php
r3642444 r3803670 121 121 return ''; 122 122 } 123 if (!str_starts_with($data['plugin_uri'], 'https://wordpress.org/plugins/')) { 124 return ''; 125 } 123 126 return $this->pluginAction([ 124 127 'action' => 'install-plugin', … … 126 129 'name' => $data['name'], 127 130 'nonce_prefix' => 'install-plugin_', 128 'plugin' => $data['textdomain'],131 'plugin' => dirname($data['plugin']), // wordpress.org names a plugin's folder after its slug 129 132 /* translators: %s: the plugin name */ 130 133 'text' => _x('Install %s', 'admin-text', 'site-reviews'), … … 183 186 { 184 187 $links = []; 185 foreach ($errors as $ plugin => $data) {188 foreach ($errors as $data) { 186 189 $links[] = sprintf('<span class="plugin-%s"><a href="%s">%s</a></span>', 187 190 $data['textdomain'], -
site-reviews/trunk/readme.txt
r3777315 r3803670 4 4 Tags: reviews, ratings, testimonials, product reviews, business reviews 5 5 Tested up to: 7.1 6 Stable tag: 8.3. 76 Stable tag: 8.3.8 7 7 License: GPLv3 8 8 License URI: https://www.gnu.org/licenses/gpl-3.0.html … … 211 211 212 212 == Changelog == 213 214 = 8.3.8 (2026-11-15) = 215 216 - Fixed a security issue in review excerpts 217 - Fixed a security issue in the notice shown after restoring a revision 218 - Fixed a security issue in the review type filter 219 - Fixed a security issue in the schema 220 - Fixed captcha checks slowly filling up the database 221 - Fixed forms with more than one Assigned Pages, Categories or Users field not submitting 222 - Fixed hidden form fields changing after a failed submission 223 - Fixed MultilingualPress translations losing their custom field values when the original review is edited 224 - Fixed number fields ignoring decimals in their minimum and maximum 225 - Fixed reviews not saving with version 3 of the SQLite Database Integration plugin 226 - Fixed some assigned pages, categories or users not being saved with a review 227 - Fixed the admin search permission check 228 - Fixed the Install button in the missing plugin notice 229 - Fixed the IP address detection tool permission check 230 - Fixed the review approval permission check 231 - Fixed the validation of submitted reviews 232 - Fixed the verification email permission check 213 233 214 234 = 8.3.7 (2026-10-31) = -
site-reviews/trunk/site-reviews.php
r3777315 r3803670 8 8 * Plugin URI: https://wordpress.org/plugins/site-reviews 9 9 * Description: Receive and display reviews on your website 10 * Version: 8.3. 710 * Version: 8.3.8 11 11 * Author: Paul Ryley 12 12 * Author URI: https://site-reviews.com
Note:
See TracChangeset
for help on using the changeset viewer.