From 8579648b77a4f751f5e31f512e56a82feab5de30 Mon Sep 17 00:00:00 2001
From: Jakub Mikita
Date: Fri, 29 Oct 2021 09:19:31 +0200
Subject: [PATCH 01/21] add escaping and nonce verification
---
composer.json | 3 +-
composer.lock | 52 ++++++++++++-
phpstan-baseline.neon | 15 ----
readme.txt | 4 +
resources/js/src/component/mergetag.js | 1 +
resources/js/src/component/switch.js | 1 +
resources/js/src/component/sync.js | 1 +
resources/templates/carriers/widget-add.php | 11 ++-
resources/templates/debug/error-log.php | 2 +-
.../templates/debug/notification-log.php | 16 +++-
resources/templates/debug/pagination.php | 14 ++--
.../extension/extension-box-premium.php | 2 +-
.../templates/extension/extension-box.php | 2 +-
resources/templates/form/field-hidden.php | 4 +-
resources/templates/form/field.php | 8 +-
.../templates/help/global-merge-tags.php | 2 +-
resources/templates/settings/page.php | 4 +-
resources/templates/upsell/carriers-list.php | 11 ++-
.../templates/upsell/conditionals-metabox.php | 3 +-
.../templates/upsell/custom-development.php | 6 +-
.../upsell/scheduled-triggers-setting.php | 3 +-
src/Abstracts/MergeTag.php | 2 +-
src/Admin/Debugging.php | 21 +++--
src/Admin/Extensions.php | 76 +++++++++++--------
src/Admin/ImportExport.php | 34 ++++-----
src/Admin/NotificationDuplicator.php | 18 +++--
src/Admin/PostTable.php | 29 +++----
src/Admin/PostType.php | 34 ++-------
src/Admin/Screen.php | 31 +-------
src/Admin/Scripts.php | 1 +
src/Admin/Settings.php | 13 +---
src/Admin/Sync.php | 4 +-
src/Admin/Wizard.php | 22 +-----
src/Core/Cron.php | 7 +-
src/Core/Debugging.php | 23 ++----
src/Core/Queue.php | 6 +-
src/Core/Sync.php | 36 ++++++---
src/Core/Upgrade.php | 20 ++---
src/Defaults/Carrier/Email.php | 6 +-
src/Defaults/Trigger/Post/PostTrigger.php | 10 +--
.../Trigger/User/UserPasswordResetRequest.php | 5 +-
.../Trigger/WordPress/UpdatesAvailable.php | 27 +++----
src/Repository/GlobalMergeTagRepository.php | 6 +-
src/Traits/Webhook.php | 2 +-
src/Utils/Settings.php | 39 +++-------
src/Utils/Settings/CoreFields/Button.php | 2 +-
src/Utils/Settings/CoreFields/Message.php | 5 +-
src/Utils/Settings/CoreFields/Select.php | 6 +-
src/Utils/WpObjectHelper.php | 47 +++++++-----
49 files changed, 348 insertions(+), 349 deletions(-)
diff --git a/composer.json b/composer.json
index 3f40757f9..6a47a370a 100644
--- a/composer.json
+++ b/composer.json
@@ -4,8 +4,9 @@
"license": "GPL-3.0-or-later",
"description": "Notification plugin for WordPress",
"require": {
- "composer-runtime-api": "^2.0",
"php": "^7.0",
+ "composer-runtime-api": "^2.0",
+ "enshrined/svg-sanitize": "^0.14.1",
"micropackage/ajax": "^1.0",
"micropackage/dochooks": "1.0.2",
"micropackage/filesystem": "^1.1",
diff --git a/composer.lock b/composer.lock
index b65f8c075..2c00c5bfb 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,54 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "73caec09742a40d66eb761a8ac5d029a",
+ "content-hash": "73d95408e7ddb8485b92b953cf7868d2",
"packages": [
+ {
+ "name": "enshrined/svg-sanitize",
+ "version": "0.14.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/darylldoyle/svg-sanitizer.git",
+ "reference": "307b42066fb0b76b5119f5e1f0826e18fefabe95"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/darylldoyle/svg-sanitizer/zipball/307b42066fb0b76b5119f5e1f0826e18fefabe95",
+ "reference": "307b42066fb0b76b5119f5e1f0826e18fefabe95",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-libxml": "*",
+ "php": "^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "codeclimate/php-test-reporter": "^0.1.2",
+ "phpunit/phpunit": "^6.5 || ^8.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "enshrined\\svgSanitize\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "GPL-2.0-or-later"
+ ],
+ "authors": [
+ {
+ "name": "Daryll Doyle",
+ "email": "daryll@enshrined.co.uk"
+ }
+ ],
+ "description": "An SVG sanitizer for PHP",
+ "support": {
+ "issues": "https://github.com/darylldoyle/svg-sanitizer/issues",
+ "source": "https://github.com/darylldoyle/svg-sanitizer/tree/0.14.1"
+ },
+ "time": "2021-08-09T23:46:54+00:00"
+ },
{
"name": "micropackage/ajax",
"version": "1.0.1",
@@ -2815,8 +2861,8 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
- "composer-runtime-api": "^2.0",
- "php": "^7.0"
+ "php": "^7.0",
+ "composer-runtime-api": "^2.0"
},
"platform-dev": [],
"plugin-api-version": "2.0.0"
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index c2a43bf51..0f1e04bcf 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -590,11 +590,6 @@ parameters:
count: 1
path: src/Admin/Extensions.php
- -
- message: "#^Parameter \\#2 \\$now of function strtotime expects int, int\\|string given\\.$#"
- count: 1
- path: src/Admin/Extensions.php
-
-
message: "#^Property BracketSpace\\\\Notification\\\\Admin\\\\Extensions\\:\\:\\$extensions type has no value type specified in iterable type array\\.$#"
count: 1
@@ -615,11 +610,6 @@ parameters:
count: 1
path: src/Admin/ImportExport.php
- -
- message: "#^Method BracketSpace\\\\Notification\\\\Admin\\\\ImportExport\\:\\:prepare_notifications_export_data\\(\\) return type has no value type specified in iterable type array\\.$#"
- count: 1
- path: src/Admin/ImportExport.php
-
-
message: "#^Method BracketSpace\\\\Notification\\\\Admin\\\\ImportExport\\:\\:process_notifications_import_request\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#"
count: 1
@@ -990,11 +980,6 @@ parameters:
count: 2
path: src/Core/Binder.php
- -
- message: "#^Binary operation \"\\+\" between int\\|string and 86400 results in an error\\.$#"
- count: 1
- path: src/Core/Cron.php
-
-
message: "#^Method BracketSpace\\\\Notification\\\\Core\\\\Cron\\:\\:register_intervals\\(\\) has parameter \\$intervals with no value type specified in iterable type array\\.$#"
count: 1
diff --git a/readme.txt b/readme.txt
index 50981d524..511d82abf 100644
--- a/readme.txt
+++ b/readme.txt
@@ -295,6 +295,10 @@ Yes, just activate the debug log in the DEBUGGING section of the plugin settings
== Changelog ==
+= [Next] =
+
+* [Added] HTML escaping and nonce verifications.
+
= 8.0.1 =
* [Changed] Field and Merge Tag description field is now escaped and cannot contain any HTML tags.
diff --git a/resources/js/src/component/mergetag.js b/resources/js/src/component/mergetag.js
index 4b97b1599..dec9de9d4 100644
--- a/resources/js/src/component/mergetag.js
+++ b/resources/js/src/component/mergetag.js
@@ -41,6 +41,7 @@ import "jquery-collapse/src/jquery.collapse.js";
const data = {
action: "get_merge_tags_for_trigger",
+ _ajax_nonce: notification.csrfToken,
trigger_slug: triggerSlug
};
diff --git a/resources/js/src/component/switch.js b/resources/js/src/component/switch.js
index 0665ef4a9..5f25dfa97 100644
--- a/resources/js/src/component/switch.js
+++ b/resources/js/src/component/switch.js
@@ -25,6 +25,7 @@
const data = {
action: "change_notification_status",
+ _ajax_nonce: notification.csrfToken,
post_id: postId,
status,
nonce: $switch.data("nonce")
diff --git a/resources/js/src/component/sync.js b/resources/js/src/component/sync.js
index 0d630b1c7..59de0869f 100644
--- a/resources/js/src/component/sync.js
+++ b/resources/js/src/component/sync.js
@@ -61,6 +61,7 @@
const data = {
action: "notification_sync",
+ _ajax_nonce: notification.csrfToken,
hash,
type: syncType,
nonce
diff --git a/resources/templates/carriers/widget-add.php b/resources/templates/carriers/widget-add.php
index 1bcdc9809..2d615353d 100644
--- a/resources/templates/carriers/widget-add.php
+++ b/resources/templates/carriers/widget-add.php
@@ -9,6 +9,10 @@
* @var BracketSpace\Notification\Dependencies\Micropackage\Templates\Template $this Template instance.
*/
+use BracketSpace\Notification\Dependencies\enshrined\svgSanitize\Sanitizer;
+
+$svg_sanitizer = new Sanitizer();
+
?>
diff --git a/resources/templates/debug/notification-log.php b/resources/templates/debug/notification-log.php
index c9455a6b5..3a62607a6 100644
--- a/resources/templates/debug/notification-log.php
+++ b/resources/templates/debug/notification-log.php
@@ -64,7 +64,13 @@
|
-
+
+
+
@@ -84,7 +90,13 @@
|
|
-
+
+
+
diff --git a/resources/templates/debug/pagination.php b/resources/templates/debug/pagination.php
index 3c6f704c3..41ddbf540 100644
--- a/resources/templates/debug/pagination.php
+++ b/resources/templates/debug/pagination.php
@@ -9,14 +9,14 @@
* @var BracketSpace\Notification\Dependencies\Micropackage\Templates\Template $this Template instance.
*/
+$links = paginate_links( [
+ 'base' => admin_url( 'edit.php?post_type=notification&page=settings§ion=debugging&' . $get( 'query_arg' ) . '=%#%' ),
+ 'current' => $get( 'current' ),
+ 'total' => $get( 'total' ),
+] );
+
?>
diff --git a/resources/templates/extension/extension-box-premium.php b/resources/templates/extension/extension-box-premium.php
index fd0b4f1fd..df18110ac 100644
--- a/resources/templates/extension/extension-box-premium.php
+++ b/resources/templates/extension/extension-box-premium.php
@@ -31,7 +31,7 @@
expires ) : ?>
- expires, current_time( 'timestamp' ) ) ) ) ); // phpcs:ignore ?>
+ expires, time() ) ) ) ); ?>
diff --git a/resources/templates/extension/extension-box.php b/resources/templates/extension/extension-box.php
index 3d833bf4d..4beba9aee 100644
--- a/resources/templates/extension/extension-box.php
+++ b/resources/templates/extension/extension-box.php
@@ -86,7 +86,7 @@
|
diff --git a/resources/templates/upsell/carriers-list.php b/resources/templates/upsell/carriers-list.php
index 0bcb00df8..37dd1346a 100644
--- a/resources/templates/upsell/carriers-list.php
+++ b/resources/templates/upsell/carriers-list.php
@@ -9,6 +9,10 @@
* @var BracketSpace\Notification\Dependencies\Micropackage\Templates\Template $this Template instance.
*/
+use BracketSpace\Notification\Dependencies\enshrined\svgSanitize\Sanitizer;
+
+$svg_sanitizer = new Sanitizer();
+
?>
@@ -16,7 +20,12 @@
diff --git a/resources/templates/upsell/conditionals-metabox.php b/resources/templates/upsell/conditionals-metabox.php
index 0fb4539d3..7eb33ec76 100644
--- a/resources/templates/upsell/conditionals-metabox.php
+++ b/resources/templates/upsell/conditionals-metabox.php
@@ -21,5 +21,6 @@
PRO
diff --git a/resources/templates/upsell/custom-development.php b/resources/templates/upsell/custom-development.php
index 7feb04e37..be41bd69a 100644
--- a/resources/templates/upsell/custom-development.php
+++ b/resources/templates/upsell/custom-development.php
@@ -11,9 +11,11 @@
%s',
esc_html__( 'Find out more', 'notification' )
- ); // phpcs:ignore
+ );
+
+ echo wp_kses_post( $description );
?>
diff --git a/resources/templates/upsell/scheduled-triggers-setting.php b/resources/templates/upsell/scheduled-triggers-setting.php
index 7e2c8d13b..d9cb73744 100644
--- a/resources/templates/upsell/scheduled-triggers-setting.php
+++ b/resources/templates/upsell/scheduled-triggers-setting.php
@@ -16,7 +16,8 @@
PRO
diff --git a/src/Abstracts/MergeTag.php b/src/Abstracts/MergeTag.php
index 8e1b6d91d..77dfa8fc5 100644
--- a/src/Abstracts/MergeTag.php
+++ b/src/Abstracts/MergeTag.php
@@ -142,7 +142,7 @@ public function resolve() {
$value = call_user_func( $this->resolver, $this->get_trigger() );
} catch ( \Throwable $t ) {
$value = null;
- trigger_error( $t->getMessage(), E_USER_NOTICE ); // phpcs:ignore
+ trigger_error( esc_html( $t->getMessage() ), E_USER_NOTICE );
}
if ( ! empty( $value ) && ! $this->validate( $value ) ) {
diff --git a/src/Admin/Debugging.php b/src/Admin/Debugging.php
index a34595a92..fef42044b 100644
--- a/src/Admin/Debugging.php
+++ b/src/Admin/Debugging.php
@@ -103,8 +103,11 @@ public function debugging_settings( $settings ) {
*/
public function get_notification_log() {
- $debug = \Notification::component( 'core_debugging' );
- $page = isset( $_GET['notification_log_page'] ) ? intval( $_GET['notification_log_page'] ) : 1; // phpcs:ignore
+ $debug = \Notification::component( 'core_debugging' );
+
+ // This is a simple pagination request.
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ $page = isset( $_GET['notification_log_page'] ) ? intval( $_GET['notification_log_page'] ) : 1;
$raw_logs = $debug->get_logs( $page, 'notification' );
$logs = [];
@@ -142,7 +145,10 @@ public function get_notification_log() {
public function get_error_log() {
$debug = \Notification::component( 'core_debugging' );
- $page = isset( $_GET['error_log_page'] ) ? intval( $_GET['error_log_page'] ) : 1; // phpcs:ignore
+
+ // This is a simple pagination request.
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ $page = isset( $_GET['error_log_page'] ) ? intval( $_GET['error_log_page'] ) : 1;
$html = Templates::get( 'debug/error-log', [
'datetime_format' => get_option( 'date_format' ) . ' ' . get_option( 'time_format' ),
@@ -176,7 +182,7 @@ public function debug_warning() {
$message = esc_html__( 'Debug log is active and no notifications will be sent.', 'notification' );
$debug_log_link = '' . esc_html__( 'See debug log', 'notification' ) . '';
- echo '' . $message . ' ' . $debug_log_link . '
'; // phpcs:ignore
+ echo wp_kses_post( '' . $message . ' ' . $debug_log_link . '
' );
}
@@ -189,12 +195,12 @@ public function debug_warning() {
* @return void
*/
public function action_clear_logs() {
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
+ check_admin_referer( 'notification_clear_log_' . wp_unslash( $_GET['log_type'] ?? '' ), 'nonce' );
- $data = $_GET; // phpcs:ignore
+ $data = $_GET;
$log_type = isset( $data['log_type'] ) ? $data['log_type'] : '';
- check_admin_referer( 'notification_clear_log_' . $log_type, 'nonce' );
-
$debug = \Notification::component( 'core_debugging' );
$remove_types = [];
@@ -210,7 +216,6 @@ public function action_clear_logs() {
wp_safe_redirect( wp_get_referer() );
exit;
-
}
}
diff --git a/src/Admin/Extensions.php b/src/Admin/Extensions.php
index 58b1a43ec..e781cfc28 100644
--- a/src/Admin/Extensions.php
+++ b/src/Admin/Extensions.php
@@ -55,7 +55,6 @@ class Extensions {
* @return void
*/
public function register_page() {
-
if ( ! apply_filters( 'notification/whitelabel/extensions', true ) ) {
return;
}
@@ -77,7 +76,6 @@ public function register_page() {
);
add_action( 'load-' . $this->page_hook, [ $this, 'load_extensions' ] );
-
}
/**
@@ -88,7 +86,6 @@ public function register_page() {
* @return void
*/
public function load_extensions() {
-
if ( ! function_exists( 'is_plugin_active' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
@@ -129,7 +126,6 @@ public function load_extensions() {
$this->extensions[] = $extension;
}
}
-
}
/**
@@ -138,7 +134,6 @@ public function load_extensions() {
* @return array
*/
public function get_raw_extensions() {
-
$extensions_cache = new TransientCache( 'notification_extensions', DAY_IN_SECONDS );
if ( ErrorHandler::debug_enabled() ) {
@@ -159,7 +154,6 @@ public function get_raw_extensions() {
}
return $extensions;
-
}
/**
@@ -220,7 +214,6 @@ public static function get_bundles() {
* @return void
*/
public function updater() {
-
if ( ! function_exists( 'get_plugins' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
@@ -261,7 +254,6 @@ public function updater() {
);
}
-
}
/**
@@ -272,8 +264,21 @@ public function updater() {
* @return void
*/
public function activate() {
+ if ( ! isset( $_POST['_wpnonce'] ) ) {
+ return;
+ }
+
+ if (
+ ! wp_verify_nonce(
+ wp_unslash( sanitize_key( $_POST['_wpnonce'] ) ),
+ 'activate_extension_' . wp_unslash( sanitize_key( $_POST['extension'] ?? '' ) )
+ )
+ ) {
+ wp_safe_redirect( add_query_arg( 'activation-status', 'wrong-nonce', esc_url_raw( wp_unslash( $_POST['_wp_http_referer'] ?? '' ) ) ) );
+ exit();
+ }
- $data = $_POST; // phpcs:ignore
+ $data = $_POST;
$extension = $this->get_raw_extension( $data['extension'] );
@@ -282,11 +287,6 @@ public function activate() {
exit();
}
- if ( ! wp_verify_nonce( $_POST['_wpnonce'], 'activate_extension_' . $extension['slug'] ) ) { // phpcs:ignore
- wp_safe_redirect( add_query_arg( 'activation-status', 'wrong-nonce', $_POST['_wp_http_referer'] ) ); // phpcs:ignore
- exit();
- }
-
$license = new License( $extension );
$activation = $license->activate( $data['license-key'] );
@@ -319,8 +319,21 @@ public function activate() {
* @return void
*/
public function deactivate() {
+ if ( ! isset( $_POST['_wpnonce'] ) ) {
+ return;
+ }
+
+ if (
+ ! wp_verify_nonce(
+ wp_unslash( sanitize_key( $_POST['_wpnonce'] ) ),
+ 'activate_extension_' . sanitize_key( $_POST['extension'] ?? '' )
+ )
+ ) {
+ wp_safe_redirect( add_query_arg( 'activation-status', 'wrong-nonce', esc_url_raw( wp_unslash( $_POST['_wp_http_referer'] ?? '' ) ) ) );
+ exit();
+ }
- $data = $_POST; // phpcs:ignore
+ $data = $_POST;
$extension = $this->get_raw_extension( $data['extension'] );
@@ -329,11 +342,6 @@ public function deactivate() {
exit();
}
- if ( ! wp_verify_nonce( $_POST['_wpnonce'], 'activate_extension_' . $extension['slug'] ) ) { // phpcs:ignore
- wp_safe_redirect( add_query_arg( 'activation-status', 'wrong-nonce', $_POST['_wp_http_referer'] ) ); // phpcs:ignore
- exit();
- }
-
$license = new License( $extension );
$activation = $license->deactivate();
@@ -352,7 +360,6 @@ public function deactivate() {
wp_safe_redirect( add_query_arg( 'activation-status', 'deactivated', $data['_wp_http_referer'] ) );
exit();
-
}
/**
@@ -364,11 +371,19 @@ public function deactivate() {
*/
public function activation_notices() {
- if ( ! isset( $_GET['activation-status'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ // We're just checking for the status slug.
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ if ( ! isset( $_GET['activation-status'] ) ) {
return;
}
- switch ( $_GET['activation-status'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ $status = sanitize_key( $_GET['activation-status'] );
+
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ $extension_slug = sanitize_title_with_dashes( wp_unslash( $_GET['extension'] ?? '' ) );
+
+ switch ( $status ) {
case 'success':
$view = 'success';
$message = __( 'Your license has been activated.', 'notification' );
@@ -385,11 +400,14 @@ public function activation_notices() {
break;
case 'expired':
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ $expiration = strtotime( sanitize_text_field( wp_unslash( $_GET['expiration'] ?? '' ) ) );
+
$view = 'error';
$message = sprintf(
// translators: 1. Date.
__( 'Your license key expired on %s.', 'notification' ),
- date_i18n( get_option( 'date_format' ), strtotime( $_GET['expiration'], current_time( 'timestamp' ) ) ) // phpcs:ignore
+ date_i18n( get_option( 'date_format' ), $expiration )
);
break;
@@ -400,8 +418,9 @@ public function activation_notices() {
break;
case 'missing':
- $view = 'error';
- $message = sprintf( __( 'Invalid license key for %s.', 'notification' ), $_GET['extension'] ); // phpcs:ignore
+ $view = 'error';
+ // Translators: Extension slug.
+ $message = sprintf( __( 'Invalid license key for %s.', 'notification' ), $extension_slug );
break;
case 'invalid':
@@ -413,7 +432,7 @@ public function activation_notices() {
case 'item_name_mismatch':
$view = 'error';
// translators: 1. Extension name.
- $message = sprintf( __( 'This appears to be an invalid license key for %s.', 'notification' ), $_GET['extension'] ); // phpcs:ignore
+ $message = sprintf( __( 'This appears to be an invalid license key for %s.', 'notification' ), $extension_slug );
break;
case 'no_activations_left':
@@ -428,7 +447,6 @@ public function activation_notices() {
}
Templates::render( sprintf( 'extension/activation-%s', $view ), [ 'message' => $message ] );
-
}
/**
@@ -439,7 +457,6 @@ public function activation_notices() {
* @return void
*/
public function activation_nag() {
-
if ( Whitelabel::is_whitelabeled() ) {
return;
}
@@ -478,7 +495,6 @@ public function activation_nag() {
}
}
}
-
}
}
diff --git a/src/Admin/ImportExport.php b/src/Admin/ImportExport.php
index 3abda16af..36fc29d35 100644
--- a/src/Admin/ImportExport.php
+++ b/src/Admin/ImportExport.php
@@ -23,7 +23,6 @@ class ImportExport {
* @return void
*/
public function settings( $settings ) {
-
$importexport = $settings->add_section( __( 'Import / Export', 'notification' ), 'import_export' );
$importexport->add_group( __( 'Import', 'notification' ), 'import' )
@@ -51,7 +50,6 @@ public function settings( $settings ) {
'sanitize' => [ new CoreFields\Message(), 'sanitize' ],
]
);
-
}
/**
@@ -71,14 +69,12 @@ public function notification_import_form() {
* @return string
*/
public function notification_export_form() {
-
$download_link = admin_url( 'admin-post.php?action=notification_export&nonce=' . wp_create_nonce( 'notification-export' ) . '&type=notifications&items=' );
return Templates::get( 'export/notifications', [
'notifications' => NotificationQueries::all( true ),
'download_link' => $download_link,
] );
-
}
/**
@@ -90,7 +86,6 @@ public function notification_export_form() {
* @return void
*/
public function export_request() {
-
check_admin_referer( 'notification-export', 'nonce' );
if ( ! isset( $_GET['type'] ) ) {
@@ -100,18 +95,24 @@ public function export_request() {
$type = sanitize_text_field( wp_unslash( $_GET['type'] ) );
try {
- $data = call_user_func( [ $this, 'prepare_' . $type . '_export_data' ] );
+ $data = call_user_func(
+ [ $this, 'prepare_' . $type . '_export_data' ],
+ explode( ',', sanitize_text_field( wp_unslash( $_GET['items'] ?? '' ) ) )
+ );
} catch ( \Exception $e ) {
wp_die( esc_html( $e->getMessage() ), '', [ 'back_link' => true ] );
}
header( 'Content-Description: File Transfer' );
- header( 'Content-Disposition: attachment; filename=notification-export-' . $type . '-' . current_time( 'Y-m-d-H-i-s' ) . '.json' );
header( 'Content-Type: application/json; charset=utf-8' );
+ header( sprintf(
+ 'Content-Disposition: attachment; filename=notification-export-%s-%s.json',
+ $type,
+ current_time( 'Y-m-d-H-i-s' )
+ ) );
echo wp_json_encode( $data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE );
die;
-
}
/**
@@ -119,16 +120,16 @@ public function export_request() {
*
* @throws \Exception When no items selected for export.
* @since 6.0.0
- * @return array
+ * @since [Next] Accepts the items argument, instead reading it from GET.
+ * @param array $items Items to export.
+ * @return array
*/
- public function prepare_notifications_export_data() {
-
- if ( ! isset( $_GET['items'] ) || empty( $_GET['items'] ) ) { // phpcs:ignore
+ public function prepare_notifications_export_data( array $items = [] ) {
+ if ( empty( $items ) ) {
throw new \Exception( __( 'No items selected for export' ) );
}
$data = [];
- $items = explode( ',', sanitize_text_field( wp_unslash( $_GET['items'] ) ) ); // phpcs:ignore
$posts = get_posts( [
'post_type' => 'notification',
'post_status' => [ 'publish', 'draft' ],
@@ -137,7 +138,6 @@ public function prepare_notifications_export_data() {
] );
foreach ( $posts as $wppost ) {
-
$wp_adapter = notification_adapt_from( 'WordPress', $wppost );
/**
@@ -150,11 +150,9 @@ public function prepare_notifications_export_data() {
// Decode because it's encoded in the last step of export.
$data[] = json_decode( $json );
-
}
return $data;
-
}
/**
@@ -166,7 +164,6 @@ public function prepare_notifications_export_data() {
* @return void
*/
public function import_request() {
-
if ( false === check_ajax_referer( 'import-notifications', 'nonce', false ) ) {
wp_send_json_error( __( 'Security check failed. Please refresh the page and try again' ) );
}
@@ -205,7 +202,6 @@ public function import_request() {
}
wp_send_json_success( $result );
-
}
/**
@@ -216,7 +212,6 @@ public function import_request() {
* @return string
*/
public function process_notifications_import_request( $data ) {
-
$added = 0;
$skipped = 0;
$updated = 0;
@@ -251,7 +246,6 @@ public function process_notifications_import_request( $data ) {
// translators: number and number and number of notifications.
return sprintf( __( '%1$d notifications imported successfully. %2$d updated. %3$d skipped.' ), ( $added + $updated ), $updated, $skipped );
-
}
}
diff --git a/src/Admin/NotificationDuplicator.php b/src/Admin/NotificationDuplicator.php
index 1668f5f13..fcb2c41ea 100644
--- a/src/Admin/NotificationDuplicator.php
+++ b/src/Admin/NotificationDuplicator.php
@@ -24,15 +24,21 @@ class NotificationDuplicator {
* @return array filtered actions
*/
public function add_duplicate_row_action( $row_actions, $post ) {
-
if ( 'notification' !== $post->post_type ) {
return $row_actions;
}
- $row_actions['duplicate'] = sprintf( '%s', admin_url( 'admin-post.php?action=notification_duplicate&duplicate=' . $post->ID ), __( 'Duplicate', 'notification' ) );
+ $row_actions['duplicate'] = sprintf(
+ '%s',
+ admin_url( sprintf(
+ 'admin-post.php?action=notification_duplicate&duplicate=%s&nonce=%s',
+ $post->ID,
+ wp_create_nonce( 'duplicate_notification' )
+ ) ),
+ __( 'Duplicate', 'notification' )
+ );
return $row_actions;
-
}
/**
@@ -44,13 +50,13 @@ public function add_duplicate_row_action( $row_actions, $post ) {
* @return void
*/
public function notification_duplicate() {
+ check_admin_referer( 'duplicate_notification', 'nonce' );
- if ( ! isset( $_GET['duplicate'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ if ( ! isset( $_GET['duplicate'] ) ) {
exit;
}
// Get the source notification post.
- // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$source = get_post( intval( wp_unslash( $_GET['duplicate'] ) ) );
$wp = notification_adapt_from( 'WordPress', $source );
@@ -62,6 +68,7 @@ public function notification_duplicate() {
$json = notification_swap_adapter( 'JSON', $wp );
$json->refresh_hash();
+ $json->set_enabled( false );
if ( get_post_type( $source ) !== 'notification' ) {
wp_die( 'You cannot duplicate post that\'s not Notification post' );
@@ -76,7 +83,6 @@ public function notification_duplicate() {
wp_safe_redirect( html_entity_decode( get_edit_post_link( $new_id ) ) );
exit;
-
}
}
diff --git a/src/Admin/PostTable.php b/src/Admin/PostTable.php
index 0b3da4184..dab351f10 100644
--- a/src/Admin/PostTable.php
+++ b/src/Admin/PostTable.php
@@ -21,7 +21,6 @@ class PostTable {
* @return array filtered columns
*/
public function table_columns( $columns ) {
-
$date_column = $columns['date'];
$title_column = $columns['title'];
unset( $columns['date'] );
@@ -35,7 +34,6 @@ public function table_columns( $columns ) {
$columns['date'] = $date_column;
return $columns;
-
}
/**
@@ -48,7 +46,6 @@ public function table_columns( $columns ) {
* @return void
*/
public function table_column_content( $column, $post_id ) {
-
/**
* WordPress Adapter
*
@@ -79,7 +76,6 @@ public function table_column_content( $column, $post_id ) {
}
break;
}
-
}
/**
@@ -92,13 +88,11 @@ public function table_column_content( $column, $post_id ) {
* @return array filtered states
*/
public function remove_status_display( $post_states, $post ) {
-
if ( 'notification' === $post->post_type ) {
return [];
}
return $post_states;
-
}
/**
@@ -111,7 +105,6 @@ public function remove_status_display( $post_states, $post ) {
* @return array filtered actions
*/
public function remove_quick_edit( $row_actions, $post ) {
-
if ( 'notification' === $post->post_type ) {
if ( isset( $row_actions['inline hide-if-no-js'] ) ) {
unset( $row_actions['inline hide-if-no-js'] );
@@ -122,7 +115,6 @@ public function remove_quick_edit( $row_actions, $post ) {
}
return $row_actions;
-
}
/**
@@ -136,7 +128,6 @@ public function remove_quick_edit( $row_actions, $post ) {
* @return array filtered actions
*/
public function adjust_trash_link( $row_actions, $post ) {
-
if ( 'notification' !== $post->post_type ) {
return $row_actions;
}
@@ -144,7 +135,6 @@ public function adjust_trash_link( $row_actions, $post ) {
$row_actions['trash'] = '' . esc_html__( 'Remove', 'notification' ) . '';
return $row_actions;
-
}
/**
@@ -156,7 +146,6 @@ public function adjust_trash_link( $row_actions, $post ) {
* @return array Filtered actions
*/
public function adjust_bulk_actions( $actions ) {
-
unset( $actions['edit'] );
unset( $actions['trash'] );
@@ -165,7 +154,6 @@ public function adjust_bulk_actions( $actions ) {
$actions['enable'] = __( 'Enable', 'notification' );
return $actions;
-
}
/**
@@ -180,7 +168,6 @@ public function adjust_bulk_actions( $actions ) {
* @return string Redirect link.
*/
public function handle_status_bulk_actions( $redirect_to, $doaction, $post_ids ) {
-
if ( ! in_array( $doaction, [ 'enable', 'disable' ], true ) ) {
return $redirect_to;
}
@@ -193,8 +180,12 @@ public function handle_status_bulk_actions( $redirect_to, $doaction, $post_ids )
$notification->save();
}
- return add_query_arg( 'bulk_' . $doaction . '_notifications', count( $post_ids ), $redirect_to );
+ $action = sprintf( 'bulk_%s_notifications', $doaction );
+ return add_query_arg( [
+ $action => count( $post_ids ),
+ 'nonce' => wp_create_nonce( 'notification_bulk_action' ),
+ ], $redirect_to );
}
/**
@@ -206,13 +197,14 @@ public function handle_status_bulk_actions( $redirect_to, $doaction, $post_ids )
* @return void
*/
public function display_bulk_actions_admin_notices() {
-
- $action = $_GET; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
-
- if ( ! isset( $action['bulk_disable_notifications'] ) && ! isset( $action['bulk_enable_notifications'] ) ) {
+ if ( ! isset( $_GET['bulk_disable_notifications'], $_GET['bulk_enable_notifications'] ) ) {
return;
}
+ check_admin_referer( 'notification_bulk_action', 'nonce' );
+
+ $action = $_GET;
+
if ( ! empty( $action['bulk_disable_notifications'] ) ) {
$action_type = esc_html__( 'disabled', 'notification' );
$bulk_count = intval( $action['bulk_disable_notifications'] );
@@ -228,7 +220,6 @@ public function display_bulk_actions_admin_notices() {
$bulk_count,
$action_type
);
-
}
}
diff --git a/src/Admin/PostType.php b/src/Admin/PostType.php
index 58685b8d3..34f90db61 100644
--- a/src/Admin/PostType.php
+++ b/src/Admin/PostType.php
@@ -41,7 +41,6 @@ class PostType {
* @return void
*/
public function register() {
-
$labels = [
'name' => __( 'Notifications', 'notification' ),
'singular_name' => __( 'Notification', 'notification' ),
@@ -85,7 +84,6 @@ public function register() {
] ),
'supports' => [ 'title' ],
] );
-
}
/**
@@ -98,7 +96,6 @@ public function register() {
* @return array
*/
public function post_updated_messages( $messages ) {
-
$messages['notification'] = [
'',
__( 'Notification updated.', 'notification' ),
@@ -114,7 +111,6 @@ public function post_updated_messages( $messages ) {
];
return $messages;
-
}
/**
@@ -128,14 +124,12 @@ public function post_updated_messages( $messages ) {
* @return array
*/
public function bulk_action_messages( $bulk_messages, $bulk_counts ) {
-
$bulk_messages['notification'] = [
// translators: Number of Notifications.
'deleted' => _n( '%s notification removed.', '%s notifications removed.', $bulk_counts['trashed'] ),
];
return $bulk_messages;
-
}
/**
@@ -148,17 +142,15 @@ public function bulk_action_messages( $bulk_messages, $bulk_counts ) {
* @return array
*/
public function change_post_statuses( $statuses ) {
-
if ( isset( $statuses['publish'] ) ) {
- $statuses['publish'] = str_replace( __( 'Published', 'wordpress' ), __( 'Active', 'notification' ), $statuses['publish'] ); // phpcs:ignore
+ $statuses['publish'] = str_replace( __( 'Published', 'notification' ), __( 'Active', 'notification' ), $statuses['publish'] );
}
if ( isset( $statuses['draft'] ) ) {
- $statuses['draft'] = str_replace( __( 'Draft', 'wordpress' ), __( 'Disabled', 'notification' ), $statuses['draft'] ); // phpcs:ignore
+ $statuses['draft'] = str_replace( __( 'Draft', 'notification' ), __( 'Disabled', 'notification' ), $statuses['draft'] );
}
return $statuses;
-
}
/**
@@ -177,13 +169,11 @@ public function change_post_statuses( $statuses ) {
* @return void
*/
public function bypass_trash( $post_id ) {
-
if ( 'notification' !== get_post_type( $post_id ) ) {
return;
}
wp_delete_post( $post_id, true );
-
}
/**
@@ -203,7 +193,6 @@ public function bypass_trash( $post_id ) {
* @return array
*/
public function create_notification_hash( $data, $postarr ) {
-
// Another save process is in progress, abort.
if ( defined( 'DOING_NOTIFICATION_SAVE' ) && DOING_NOTIFICATION_SAVE ) {
return $data;
@@ -218,7 +207,6 @@ public function create_notification_hash( $data, $postarr ) {
}
return $data;
-
}
/**
@@ -232,7 +220,6 @@ public function create_notification_hash( $data, $postarr ) {
* @return void
*/
public function save( $post_id, $post, $update ) {
-
// Another save process is in progress, abort.
if ( defined( 'DOING_NOTIFICATION_SAVE' ) && DOING_NOTIFICATION_SAVE ) {
return;
@@ -279,7 +266,6 @@ public function save( $post_id, $post, $update ) {
$carriers = [];
foreach ( Store\Carrier::all() as $carrier ) {
-
if ( ! isset( $data[ 'notification_carrier_' . $carrier->get_slug() ] ) ) {
continue;
}
@@ -305,7 +291,6 @@ public function save( $post_id, $post, $update ) {
}
$carriers[ $carrier->get_slug() ] = $carrier;
-
}
$notification_post->set_carriers( $carriers );
@@ -319,7 +304,6 @@ public function save( $post_id, $post, $update ) {
$cache->delete();
do_action( 'notification/data/save/after', $notification_post );
-
}
/**
@@ -336,9 +320,10 @@ public function save( $post_id, $post, $update ) {
* @return void
*/
public function ajax_change_notification_status() {
+ check_ajax_referer( 'notification_csrf' );
$ajax = new Response();
- $data = $_POST; // phpcs:ignore
+ $data = $_POST;
$error = false;
$ajax->verify_nonce( 'change_notification_status_' . $data['post_id'] );
@@ -353,7 +338,6 @@ public function ajax_change_notification_status() {
}
$ajax->send( true );
-
}
/**
@@ -370,27 +354,25 @@ public function ajax_change_notification_status() {
* @return array
*/
public static function get_all_notifications() {
-
global $wpdb;
$cache = new ObjectCache( 'notifications', 'notification' );
$notifications = $cache->get();
if ( empty( $notifications ) ) {
-
$sql = "SELECT p.post_content
FROM {$wpdb->posts} p
WHERE p.post_type = 'notification' AND p.post_status = 'publish'
ORDER BY p.menu_order ASC, p.post_modified DESC";
- $notifications = $wpdb->get_col( $sql ); // phpcs:ignore
+ // We're using direct db call for performance purposes - we only need the post_content field.
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared
+ $notifications = $wpdb->get_col( $sql );
$cache->set( $notifications );
-
}
return $notifications;
-
}
/**
@@ -403,7 +385,6 @@ public static function get_all_notifications() {
* @return void
*/
public function setup_notifications() {
-
$notifications = self::get_all_notifications();
foreach ( $notifications as $notification_json ) {
@@ -424,7 +405,6 @@ public function setup_notifications() {
}
}
-
}
}
diff --git a/src/Admin/Screen.php b/src/Admin/Screen.php
index 579dbbd1a..691201c3c 100644
--- a/src/Admin/Screen.php
+++ b/src/Admin/Screen.php
@@ -42,7 +42,6 @@ class Screen {
* @return void
*/
public function render_main_column( $post ) {
-
if ( 'notification' !== get_post_type( $post ) ) {
return;
}
@@ -50,7 +49,6 @@ public function render_main_column( $post ) {
$notification_post = notification_adapt_from( 'WordPress', $post );
do_action( 'notification/post/column/main', $notification_post );
-
}
/**
@@ -62,7 +60,6 @@ public function render_main_column( $post ) {
* @return void
*/
public function render_trigger_select( $notification_post ) {
-
$grouped_triggers = Store\Trigger::grouped();
$trigger = $notification_post->get_trigger();
@@ -78,7 +75,6 @@ public function render_trigger_select( $notification_post ) {
'select_name' => 'notification_trigger',
'notification' => $notification_post,
] );
-
}
/**
@@ -91,7 +87,6 @@ public function render_trigger_select( $notification_post ) {
* @return void
*/
public function render_carrier_boxes( $notification_post ) {
-
echo '' . esc_html__( 'Carriers', 'notification' ) . '
';
do_action_deprecated( 'notitication/admin/notifications/pre', [
@@ -138,7 +133,6 @@ public function render_carrier_boxes( $notification_post ) {
], '6.0.0', 'notification/admin/carriers' );
do_action( 'notification/admin/carriers', $notification_post );
-
}
/**
@@ -150,7 +144,6 @@ public function render_carrier_boxes( $notification_post ) {
* @return void
*/
public function render_carriers_widget( $notification_post ) {
-
$carriers = Store\Carrier::all();
$exists = $notification_post->get_carriers();
@@ -160,7 +153,6 @@ public function render_carriers_widget( $notification_post ) {
'carriers' => $carriers,
'carriers_exists' => (array) $exists,
] );
-
}
/**
@@ -171,7 +163,6 @@ public function render_carriers_widget( $notification_post ) {
* @return string Form HTML.
*/
public function get_carrier_form( Interfaces\Sendable $carrier ) {
-
$fields = $carrier->get_form_fields();
// No fields available so return the default view.
@@ -183,7 +174,6 @@ public function get_carrier_form( Interfaces\Sendable $carrier ) {
return Templates::get( 'form/table', [
'carrier' => $carrier,
] );
-
}
/**
@@ -194,7 +184,6 @@ public function get_carrier_form( Interfaces\Sendable $carrier ) {
* @return void
*/
public function add_save_meta_box() {
-
add_meta_box(
'notification_save',
__( 'Save', 'notification' ),
@@ -206,7 +195,6 @@ public function add_save_meta_box() {
// enable metabox.
add_filter( 'notification/admin/allow_metabox/notification_save', '__return_true' );
-
}
/**
@@ -216,7 +204,6 @@ public function add_save_meta_box() {
* @return void
*/
public function render_save_metabox( $post ) {
-
if ( ! EMPTY_TRASH_DAYS ) {
$delete_text = __( 'Delete Permanently', 'notification' );
} else {
@@ -231,7 +218,6 @@ public function render_save_metabox( $post ) {
'post_id' => $post->ID,
'delete_link_label' => $delete_text,
] );
-
}
/**
@@ -242,7 +228,6 @@ public function render_save_metabox( $post ) {
* @return void
*/
public function add_merge_tags_meta_box() {
-
add_meta_box(
'notification_merge_tags',
__( 'Merge Tags', 'notification' ),
@@ -254,7 +239,6 @@ public function add_merge_tags_meta_box() {
// enable metabox.
add_filter( 'notification/admin/allow_metabox/notification_merge_tags', '__return_true' );
-
}
/**
@@ -264,7 +248,6 @@ public function add_merge_tags_meta_box() {
* @return void
*/
public function render_merge_tags_metabox( $post ) {
-
$notification = notification_adapt_from( 'WordPress', $post );
$trigger = $notification->get_trigger();
$trigger_slug = $trigger ? $trigger->get_slug() : false;
@@ -275,7 +258,6 @@ public function render_merge_tags_metabox( $post ) {
}
$this->render_merge_tags_list( $trigger_slug );
-
}
/**
@@ -285,7 +267,6 @@ public function render_merge_tags_metabox( $post ) {
* @return void
*/
public function render_merge_tags_list( $trigger_slug ) {
-
$trigger = Store\Trigger::get( $trigger_slug );
if ( empty( $trigger ) ) {
@@ -320,7 +301,6 @@ public function render_merge_tags_list( $trigger_slug ) {
* @return array $groups Grouped tags.
*/
public function prepare_merge_tag_groups( $trigger ) {
-
$groups = [];
$tags = $trigger->get_merge_tags( 'visible' );
@@ -347,7 +327,6 @@ public function prepare_merge_tag_groups( $trigger ) {
}
return apply_filters( 'notification/trigger/tags/groups', $groups, $trigger );
-
}
/**
@@ -358,7 +337,6 @@ public function prepare_merge_tag_groups( $trigger ) {
* @return void
*/
public function metabox_cleanup() {
-
global $wp_meta_boxes;
if ( ! isset( $wp_meta_boxes['notification'] ) ) {
@@ -376,7 +354,6 @@ public function metabox_cleanup() {
}
}
}
-
}
/**
@@ -394,7 +371,6 @@ public function metabox_cleanup() {
* @return void
*/
public function add_help( $screen ) {
-
if ( 'notification' !== $screen->post_type ) {
return;
}
@@ -408,7 +384,6 @@ public function add_help( $screen ) {
] );
$screen->set_help_sidebar( Templates::get( 'help/sidebar' ) );
-
}
/**
@@ -425,18 +400,18 @@ public function add_help( $screen ) {
* @return void
*/
public function ajax_render_merge_tags() {
+ check_ajax_referer( 'notification_csrf' );
$ajax = new Response();
- if ( ! isset( $_POST['trigger_slug'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
+ if ( ! isset( $_POST['trigger_slug'] ) ) {
$ajax->error();
}
ob_start();
- $this->render_merge_tags_list( sanitize_text_field( wp_unslash( $_POST['trigger_slug'] ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing
+ $this->render_merge_tags_list( sanitize_text_field( wp_unslash( $_POST['trigger_slug'] ) ) );
$ajax->send( ob_get_clean() );
-
}
}
diff --git a/src/Admin/Scripts.php b/src/Admin/Scripts.php
index 5b77d3b00..9023da0f1 100644
--- a/src/Admin/Scripts.php
+++ b/src/Admin/Scripts.php
@@ -78,6 +78,7 @@ public function enqueue_scripts( $page_hook ) {
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'postId' => get_the_ID(),
'rest_nonce' => wp_create_nonce( 'wp_rest' ),
+ 'csrfToken' => wp_create_nonce( 'notification_csrf' ),
'select_rest_url' => get_rest_url( null, 'notification/v1/repeater-field/select/' ),
'repeater_rest_url' => get_rest_url( null, 'notification/v1/repeater-field/' ),
'section_repeater_rest_url' => get_rest_url( null, 'notification/v1/section-repeater-field/' ),
diff --git a/src/Admin/Settings.php b/src/Admin/Settings.php
index 1155972bc..3bce575da 100644
--- a/src/Admin/Settings.php
+++ b/src/Admin/Settings.php
@@ -22,7 +22,6 @@ class Settings {
* @return void
*/
public function general_settings( $settings ) {
-
$general = $settings->add_section( __( 'General', 'notification' ), 'general' );
$general->add_group( __( 'Content', 'notification' ), 'content' )
@@ -106,7 +105,6 @@ public function general_settings( $settings ) {
'sanitize' => [ new CoreFields\Checkbox(), 'sanitize' ],
] )
->description( __( 'Choose what to remove upon plugin removal', 'notification' ) );
-
}
/**
@@ -116,7 +114,6 @@ public function general_settings( $settings ) {
* @return void
*/
public function triggers_settings( $settings ) {
-
$triggers = $settings->add_section( __( 'Triggers', 'notification' ), 'triggers' );
$triggers->add_group( __( 'Post', 'notification' ), 'post_types' )
@@ -227,7 +224,8 @@ public function triggers_settings( $settings ) {
'sanitize' => [ new CoreFields\Checkbox(), 'sanitize' ],
] );
- $triggers->add_group( __( 'WordPress', 'notification' ), 'wordpress' ) // phpcs:ignore
+ // phpcs:ignore WordPress.WP.CapitalPDangit.Misspelled
+ $triggers->add_group( __( 'WordPress', 'notification' ), 'wordpress' )
->add_field( [
'name' => __( 'Updates', 'notification' ),
'slug' => 'updates',
@@ -286,7 +284,6 @@ public function triggers_settings( $settings ) {
'render' => [ new CoreFields\Checkbox(), 'input' ],
'sanitize' => [ new CoreFields\Checkbox(), 'sanitize' ],
] );
-
}
/**
@@ -296,7 +293,6 @@ public function triggers_settings( $settings ) {
* @return void
*/
public function carriers_settings( $settings ) {
-
if ( ! empty( $_SERVER['SERVER_NAME'] ) ) {
$sitename = strtolower( sanitize_text_field( wp_unslash( $_SERVER['SERVER_NAME'] ) ) );
if ( substr( $sitename, 0, 4 ) === 'www.' ) {
@@ -395,7 +391,6 @@ public function carriers_settings( $settings ) {
'render' => [ new CoreFields\Checkbox(), 'input' ],
'sanitize' => [ new CoreFields\Checkbox(), 'sanitize' ],
] );
-
}
/**
@@ -405,7 +400,6 @@ public function carriers_settings( $settings ) {
* @return void
*/
public function emails_settings( $settings ) {
-
$general = $settings->add_section( __( 'Integration', 'notification' ), 'integration' );
$general->add_group( __( 'Default WordPress emails', 'notification' ), 'emails' )
@@ -531,7 +525,6 @@ public function emails_settings( $settings ) {
'sanitize' => [ new CoreFields\Checkbox(), 'sanitize' ],
] )
->description( __( 'Disable each default emails by selecting the option.', 'notification' ) );
-
}
/**
@@ -544,13 +537,11 @@ public function emails_settings( $settings ) {
* @return array
*/
public function filter_post_types( $post_types ) {
-
if ( isset( $post_types['attachment'] ) ) {
unset( $post_types['attachment'] );
}
return $post_types;
-
}
}
diff --git a/src/Admin/Sync.php b/src/Admin/Sync.php
index 7157a4461..fd8409565 100644
--- a/src/Admin/Sync.php
+++ b/src/Admin/Sync.php
@@ -169,9 +169,10 @@ public function template_notifications() {
* @return void
*/
public function ajax_sync() {
+ check_ajax_referer( 'notification_csrf' );
$ajax = new Response();
- $data = $_POST; // phpcs:ignore
+ $data = $_POST;
$ajax->verify_nonce( 'notification_sync_' . $data['hash'] );
@@ -186,7 +187,6 @@ public function ajax_sync() {
}
$ajax->send( $response );
-
}
/**
diff --git a/src/Admin/Wizard.php b/src/Admin/Wizard.php
index bbea8c366..c19f703ea 100644
--- a/src/Admin/Wizard.php
+++ b/src/Admin/Wizard.php
@@ -56,7 +56,6 @@ public function __construct( Filesystem $fs ) {
* @return void
*/
public function register_page() {
-
$this->page_hook = add_submenu_page(
'',
__( 'Wizard', 'notification' ),
@@ -65,7 +64,6 @@ public function register_page() {
'wizard',
[ $this, 'wizard_page' ]
);
-
}
/**
@@ -76,7 +74,6 @@ public function register_page() {
* @return void
*/
public function maybe_redirect() {
-
if ( ! self::should_display() ) {
return;
}
@@ -87,7 +84,6 @@ public function maybe_redirect() {
wp_safe_redirect( admin_url( 'edit.php?post_type=notification&page=wizard' ) );
exit;
}
-
}
/**
@@ -107,7 +103,6 @@ public function wizard_page() {
* @return array List of settings groups.
*/
public function get_settings() {
-
return [
[
'name' => __( 'Common Notifications', 'notification' ),
@@ -253,7 +248,6 @@ public function get_settings() {
],
],
];
-
}
/**
@@ -264,25 +258,21 @@ public function get_settings() {
* @return void
*/
public function save_settings() {
-
- $data = $_POST; // phpcs:ignore
-
- if ( wp_verify_nonce( $data['_wpnonce'], 'notification_wizard' ) === false ) {
+ if ( wp_verify_nonce( sanitize_key( $_POST['_wpnonce'] ?? '' ), 'notification_wizard' ) === false ) {
wp_die( 'Can\'t touch this' );
}
- if ( ! isset( $data['skip-wizard'] ) ) {
+ $data = $_POST;
+ if ( ! isset( $data['skip-wizard'] ) ) {
$notifications = isset( $data['notification_wizard'] ) ? $data['notification_wizard'] : [];
$this->add_notifications( $notifications );
-
}
$this->save_option_to_dismiss_wizard();
wp_safe_redirect( admin_url( 'edit.php?post_type=notification' ) );
exit;
-
}
/**
@@ -294,11 +284,9 @@ public function save_settings() {
* @return void
*/
private function add_notifications( $notifications ) {
-
$json_path_tmpl = 'resources/wizard-data/%s.json';
foreach ( $notifications as $notification_slug ) {
-
$json_path = sprintf( $json_path_tmpl, $notification_slug );
if ( ! $this->filesystem->is_readable( $json_path ) ) {
@@ -312,9 +300,7 @@ private function add_notifications( $notifications ) {
$wp_adapter = notification_swap_adapter( 'WordPress', $json_adapter );
$wp_adapter->save();
-
}
-
}
/**
@@ -323,13 +309,11 @@ private function add_notifications( $notifications ) {
* @return void
*/
private function save_option_to_dismiss_wizard() {
-
if ( get_option( $this->dismissed_option ) !== false ) {
update_option( $this->dismissed_option, true );
} else {
add_option( $this->dismissed_option, true, '', 'no' );
}
-
}
/**
diff --git a/src/Core/Cron.php b/src/Core/Cron.php
index ea575dacc..c7557e87d 100644
--- a/src/Core/Cron.php
+++ b/src/Core/Cron.php
@@ -22,7 +22,6 @@ class Cron {
* @return array
*/
public function register_intervals( $intervals ) {
-
$intervals['ntfn_2days'] = [
'interval' => 2 * DAY_IN_SECONDS,
'display' => __( 'Every two days', 'notification' ),
@@ -49,7 +48,6 @@ public function register_intervals( $intervals ) {
];
return $intervals;
-
}
/**
@@ -61,7 +59,6 @@ public function register_intervals( $intervals ) {
* @return void
*/
public function register_check_updates_event() {
-
$event = wp_get_schedule( 'notification_check_wordpress_updates' );
$schedule = notification_get_setting( 'triggers/wordpress/updates_cron_period' );
@@ -74,7 +71,6 @@ public function register_check_updates_event() {
$this->unschedule( 'notification_check_wordpress_updates' );
$this->schedule( $schedule, 'notification_check_wordpress_updates' );
}
-
}
/**
@@ -87,12 +83,11 @@ public function register_check_updates_event() {
* @return void
*/
public function schedule( $schedule, $event_name, $once = false ) {
-
if ( $once && false !== wp_get_schedule( $event_name ) ) {
return;
}
- wp_schedule_event( current_time( 'timestamp' ) + DAY_IN_SECONDS, $schedule, $event_name ); // phpcs:ignore
+ wp_schedule_event( time() + DAY_IN_SECONDS, $schedule, $event_name );
}
/**
diff --git a/src/Core/Debugging.php b/src/Core/Debugging.php
index fb08f7e63..6e655ee57 100644
--- a/src/Core/Debugging.php
+++ b/src/Core/Debugging.php
@@ -35,11 +35,9 @@ class Debugging {
* @since 6.0.0
*/
public function __construct() {
-
global $wpdb;
$this->logs_table = $wpdb->prefix . 'notification_logs';
-
}
/**
@@ -51,7 +49,6 @@ public function __construct() {
* @return bool
*/
public function add_log( $log_data = [] ) {
-
global $wpdb;
$allowed_types = [
@@ -72,7 +69,8 @@ public function add_log( $log_data = [] ) {
throw new \Exception( 'Log message cannot be empty' );
}
- return (bool) $wpdb->insert( // phpcs:ignore
+ // phpcs:ignore
+ return (bool) $wpdb->insert(
$this->logs_table,
[
'type' => $log_data['type'],
@@ -87,7 +85,6 @@ public function add_log( $log_data = [] ) {
'%s',
]
);
-
}
/**
@@ -100,7 +97,6 @@ public function add_log( $log_data = [] ) {
* @return array
*/
public function get_logs( $page = 1, $types = null, $component = null ) {
-
global $wpdb;
if ( empty( $types ) ) {
@@ -110,7 +106,7 @@ public function get_logs( $page = 1, $types = null, $component = null ) {
$esc_types = [];
foreach ( (array) $types as $type ) {
- $esc_types[] = $wpdb->prepare( is_numeric( $type ) ? '%d' : '%s', $type ); // phpcs:ignore
+ $esc_types[] = $wpdb->prepare( '%s', (string) $type );
}
$query = 'SELECT SQL_CALC_FOUND_ROWS * FROM ' . $this->logs_table . ' WHERE type IN(' . implode( ',', $esc_types ) . ')';
@@ -135,8 +131,9 @@ public function get_logs( $page = 1, $types = null, $component = null ) {
$query .= ' LIMIT ' . $this->logs_per_page . ' ' . $offset;
- return $wpdb->get_results( $query ); // phpcs:ignore
-
+ // We need to get the live results.
+ // phpcs:ignore
+ return $wpdb->get_results( $query );
}
/**
@@ -147,7 +144,6 @@ public function get_logs( $page = 1, $types = null, $component = null ) {
* @return void
*/
public function remove_logs( $types = null ) {
-
global $wpdb;
if ( empty( $types ) ) {
@@ -155,9 +151,9 @@ public function remove_logs( $types = null ) {
}
foreach ( $types as $type ) {
- $wpdb->delete( $this->logs_table, [ 'type' => $type ], [ '%s' ] ); // phpcs:ignore
+ // phpcs:ignore
+ $wpdb->delete( $this->logs_table, [ 'type' => $type ], [ '%s' ] );
}
-
}
/**
@@ -178,7 +174,6 @@ public function get_logs_count( $type = 'total' ) {
}
return $total;
-
}
/**
@@ -194,7 +189,6 @@ public function get_logs_count( $type = 'total' ) {
* @return void
*/
public function catch_notification( $carrier, $trigger, $notification ) {
-
if ( ! notification_get_setting( 'debugging/settings/debug_log' ) ) {
return;
}
@@ -231,7 +225,6 @@ public function catch_notification( $carrier, $trigger, $notification ) {
if ( true === apply_filters( 'notification/debug/suppress', (bool) notification_get_setting( 'debugging/settings/debug_suppressing' ), $data['notification'], $data['carrier'], $data['trigger'] ) ) {
$carrier->suppress();
}
-
}
}
diff --git a/src/Core/Queue.php b/src/Core/Queue.php
index 1c058c5e7..3a70ef0fb 100644
--- a/src/Core/Queue.php
+++ b/src/Core/Queue.php
@@ -59,8 +59,7 @@ public static function add( CoreNotification $notification, Triggerable $trigger
public static function add_replace( CoreNotification $notification, Triggerable $trigger ) {
// Check if item already exists.
foreach ( self::$items as $index => $item ) {
- // phpcs:ignore.
- if ( $item['notification'] == $notification && $item['trigger'] == $trigger ) {
+ if ( $item['notification'] === $notification && $item['trigger'] === $trigger ) {
self::add( $notification, $trigger, $index );
return;
}
@@ -79,8 +78,7 @@ public static function add_replace( CoreNotification $notification, Triggerable
*/
public static function has( CoreNotification $notification, Triggerable $trigger ) : bool {
foreach ( self::$items as $item ) {
- // phpcs:ignore.
- if ( $item['notification'] == $notification && $item['trigger'] == $trigger ) {
+ if ( $item['notification'] === $notification && $item['trigger'] === $trigger ) {
return true;
}
}
diff --git a/src/Core/Sync.php b/src/Core/Sync.php
index a2060d1f2..1a0bdf82f 100644
--- a/src/Core/Sync.php
+++ b/src/Core/Sync.php
@@ -8,6 +8,7 @@
namespace BracketSpace\Notification\Core;
use BracketSpace\Notification\Defaults\Adapter\WordPress;
+use BracketSpace\Notification\Dependencies\Micropackage\Filesystem\Filesystem;
/**
* Sync class
@@ -28,7 +29,6 @@ class Sync {
* @return array
*/
public static function get_all_json() {
-
if ( ! self::is_syncing() ) {
return [];
}
@@ -42,24 +42,24 @@ public static function get_all_json() {
$notifications = [];
- while ( false !== ( $file = readdir( $dir ) ) ) { // phpcs:ignore
-
+ // phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
+ while ( false !== ( $file = readdir( $dir ) ) ) {
if ( pathinfo( $file, PATHINFO_EXTENSION ) !== 'json' ) {
continue;
}
- $json = file_get_contents( $path . '/' . $file ); // phpcs:ignore
+ // We need to read the file contents.
+ // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
+ $json = file_get_contents( $path . '/' . $file );
if ( empty( $json ) ) {
continue;
}
$notifications[] = $json;
-
}
return $notifications;
-
}
/**
@@ -71,7 +71,6 @@ public static function get_all_json() {
* @return void
*/
public function load_local_json() {
-
if ( ! self::is_syncing() ) {
return;
}
@@ -92,7 +91,6 @@ public function load_local_json() {
return;
}
}
-
}
/**
@@ -105,7 +103,6 @@ public function load_local_json() {
* @return void
*/
public static function save_local_json( $wp_adapter ) {
-
if ( ! self::is_syncing() ) {
return;
}
@@ -119,8 +116,8 @@ public static function save_local_json( $wp_adapter ) {
$file = $wp_adapter->get_hash() . '.json';
$json = notification_swap_adapter( 'JSON', $wp_adapter )->save();
- file_put_contents( $path . '/' . $file, $json ); // phpcs:ignore
-
+ // phpcs:ignore
+ file_put_contents( $path . '/' . $file, $json );
}
/**
@@ -175,7 +172,8 @@ public static function enable( string $path = null ) {
}
if ( ! file_exists( trailingslashit( $path ) . 'index.php' ) ) {
- file_put_contents( trailingslashit( $path ) . 'index.php', '= static::$data_version ) {
@@ -72,7 +71,6 @@ public function check_upgrade() {
}
update_option( static::$data_setting_name, static::$data_version );
-
}
/**
@@ -88,7 +86,6 @@ public function check_upgrade() {
* @return void
*/
public function upgrade_db() {
-
$current_version = get_option( static::$db_setting_name );
if ( $current_version >= static::$db_version ) {
@@ -125,7 +122,6 @@ public function upgrade_db() {
dbDelta( $sql );
update_option( static::$db_setting_name, static::$db_version );
-
}
/**
@@ -144,7 +140,6 @@ public function upgrade_db() {
* @return Interfaces\Sendable
*/
protected function populate_carrier( $carrier, $post_id ) {
-
if ( ! $carrier instanceof Interfaces\Sendable ) {
$carrier = Store\Carrier::get( $carrier );
}
@@ -174,7 +169,6 @@ protected function populate_carrier( $carrier, $post_id ) {
}
return $carrier;
-
}
/**
@@ -184,7 +178,6 @@ protected function populate_carrier( $carrier, $post_id ) {
* @return array
*/
public function trigger_slug_replacements() {
-
$taxonomies = '(' . implode( '|', array_keys( WpObjectHelper::get_taxonomies() ) ) . ')';
// phpcs:disable
@@ -199,7 +192,6 @@ public function trigger_slug_replacements() {
'/wordpress\/theme\/(.*)/' => 'theme/${1}',
];
// phpcs:enable
-
}
/**
@@ -218,7 +210,6 @@ public function trigger_slug_replacements() {
* @return void
*/
public function upgrade_to_v1() {
-
// 1. Save the Notification cache in post_content field.
$notifications = NotificationQueries::all( true );
foreach ( $notifications as $adapter ) {
@@ -268,7 +259,6 @@ public function upgrade_to_v1() {
// 3. Remove old debug log
delete_option( 'notification_debug_log' );
-
}
/**
@@ -280,12 +270,12 @@ public function upgrade_to_v1() {
* @return void
*/
public function upgrade_to_v2() {
-
global $wpdb;
// 1. Changes the Trigger slugs.
- $notifications = $wpdb->get_results( // phpcs:ignore
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
+ $notifications = $wpdb->get_results(
"SELECT p.ID, p.post_content
FROM {$wpdb->posts} p
WHERE p.post_type = 'notification'"
@@ -301,7 +291,8 @@ public function upgrade_to_v2() {
$data['trigger']
);
- $wpdb->update( // phpcs:ignore
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
+ $wpdb->update(
$wpdb->posts,
[
'post_content' => wp_json_encode( $data, JSON_UNESCAPED_UNICODE ),
@@ -317,7 +308,8 @@ public function upgrade_to_v2() {
// 2. Changes the settings section `notifications` to `carriers`.
- $wpdb->update( // phpcs:ignore
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
+ $wpdb->update(
$wpdb->options,
[ 'option_name' => 'notification_carriers' ],
[ 'option_name' => 'notification_notifications' ],
diff --git a/src/Defaults/Carrier/Email.php b/src/Defaults/Carrier/Email.php
index a929f9f66..4ed693244 100644
--- a/src/Defaults/Carrier/Email.php
+++ b/src/Defaults/Carrier/Email.php
@@ -115,7 +115,6 @@ public function set_mail_type() {
* @return void
*/
public function send( Triggerable $trigger ) {
-
$default_html_mime = notification_get_setting( 'carriers/email/type' ) === 'html';
$html_mime = apply_filters_deprecated( 'notification/email/use_html_mime', [ $default_html_mime, $this, $trigger ], '6.0.0', 'notification/carrier/email/use_html_mime' );
$html_mime = apply_filters( 'notification/carrier/email/use_html_mime', $html_mime, $this, $trigger );
@@ -180,7 +179,7 @@ public function send( Triggerable $trigger ) {
}
foreach ( $errors as $error => $error_data ) {
- // phpcs:ignore
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
notification_log( $this->get_name(), 'error', '' . print_r( [
'error' => $error,
'recipients_affected' => $error_data['recipients'],
@@ -192,7 +191,6 @@ public function send( Triggerable $trigger ) {
if ( $html_mime ) {
remove_filter( 'wp_mail_content_type', [ $this, 'set_mail_type' ] );
}
-
}
/**
@@ -205,13 +203,11 @@ public function send( Triggerable $trigger ) {
* @return array Carrier data with the unfiltered body, if notifications/email/unfiltered_html setting is true.
**/
public function allow_unfiltered_html_body( $carrier_data, $raw_data ) {
-
if ( notification_get_setting( 'carriers/email/unfiltered_html' ) ) {
$carrier_data['body'] = $raw_data['body'];
}
return $carrier_data;
-
}
}
diff --git a/src/Defaults/Trigger/Post/PostTrigger.php b/src/Defaults/Trigger/Post/PostTrigger.php
index 90f3167d0..8925fa572 100644
--- a/src/Defaults/Trigger/Post/PostTrigger.php
+++ b/src/Defaults/Trigger/Post/PostTrigger.php
@@ -124,28 +124,21 @@ public function merge_tags() {
] ) );
if ( 'post' === $this->post_type ) {
-
$this->add_merge_tag( new MergeTag\StringTag( [
'slug' => sprintf( '%s_sticky', $this->post_type ),
// translators: singular post name.
'name' => sprintf( __( '%s sticky status', 'notification' ), $post_type_name ),
'group' => $post_type_name,
'resolver' => function( $trigger ) {
- if ( is_admin() ) {
- return isset( $_POST['sticky'] ) && ! empty( $_POST['sticky'] ) ? __( 'Sticky', 'notification' ) : __( 'Not sticky', 'notification' ); // phpcs:ignore
- } else {
- return is_sticky( $trigger->{ $this->post_type }->ID ) ? __( 'Sticky', 'notification' ) : __( 'Not sticky', 'notification' );
- }
+ return is_sticky( $trigger->{ $this->post_type }->ID ) ? __( 'Sticky', 'notification' ) : __( 'Not sticky', 'notification' );
},
] ) );
-
}
$taxonomies = get_object_taxonomies( $this->post_type, 'objects' );
if ( ! empty( $taxonomies ) ) {
foreach ( $taxonomies as $taxonomy ) {
-
// Post format special treatment.
if ( 'post_format' === $taxonomy->name ) {
$group = $post_type_name;
@@ -158,7 +151,6 @@ public function merge_tags() {
'taxonomy' => $taxonomy,
'group' => $group,
] ) );
-
}
}
diff --git a/src/Defaults/Trigger/User/UserPasswordResetRequest.php b/src/Defaults/Trigger/User/UserPasswordResetRequest.php
index 298a069cc..6f4d5c5fb 100644
--- a/src/Defaults/Trigger/User/UserPasswordResetRequest.php
+++ b/src/Defaults/Trigger/User/UserPasswordResetRequest.php
@@ -49,14 +49,14 @@ public function __construct() {
* @return mixed
*/
public function context( $username, $reset_key ) {
-
$user = get_user_by( 'login', $username );
/**
* Bail if we are handling the registration.
* Use the filter to integrate with 3rd party code.
*/
- if ( ( isset( $_GET['action'] ) && 'register' === $_GET['action'] ) || // phpcs:ignore
+ // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ if ( ( isset( $_GET['action'] ) && 'register' === $_GET['action'] ) ||
apply_filters( 'notification/trigger/wordpress/user_password_reset_request/bail_for_registration', false, $user ) ) {
return false;
}
@@ -68,7 +68,6 @@ public function context( $username, $reset_key ) {
$this->user_registered_datetime = strtotime( $this->user_object->user_registered );
$this->password_reset_request_datetime = time();
-
}
/**
diff --git a/src/Defaults/Trigger/WordPress/UpdatesAvailable.php b/src/Defaults/Trigger/WordPress/UpdatesAvailable.php
index 08ee3da37..7402c1e2c 100644
--- a/src/Defaults/Trigger/WordPress/UpdatesAvailable.php
+++ b/src/Defaults/Trigger/WordPress/UpdatesAvailable.php
@@ -44,7 +44,6 @@ public function __construct() {
* @return mixed
*/
public function context() {
-
require_once ABSPATH . '/wp-admin/includes/update.php';
// Check if any updates are available.
@@ -60,7 +59,6 @@ public function context() {
if ( ! $has_updates && ! notification_get_setting( 'triggers/wordpress/updates_send_anyway' ) ) {
return false;
}
-
}
/**
@@ -178,7 +176,6 @@ public function get_list_title( $update_type ) {
* @return string
*/
public function get_core_updates_list() {
-
$updates = get_core_updates();
foreach ( $updates as $update_key => $update ) {
@@ -201,7 +198,6 @@ public function get_core_updates_list() {
$html .= '';
return $html;
-
}
/**
@@ -211,7 +207,6 @@ public function get_core_updates_list() {
* @return string
*/
public function get_plugin_updates_list() {
-
$updates = get_plugin_updates();
if ( empty( $updates ) ) {
@@ -221,8 +216,13 @@ public function get_plugin_updates_list() {
$html = '
';
foreach ( $updates as $update ) {
- // translators: 1. Plugin name, 2. Current version, 3. Update version.
- $html .= '- ' . sprintf( __( '%1$s (current version: %2$s): %3$s', 'notification' ), $update->Name, $update->Version, $update->update->new_version ) . '
'; // phpcs:ignore
+ $html .= '- ' . sprintf(
+ // translators: 1. Plugin name, 2. Current version, 3. Update version.
+ __( '%1$s (current version: %2$s): %3$s', 'notification' ),
+ $update->Name, // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+ $update->Version, // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+ $update->update->new_version
+ ) . '
';
}
$html .= '
';
@@ -238,7 +238,6 @@ public function get_plugin_updates_list() {
* @return string
*/
public function get_theme_updates_list() {
-
$updates = get_theme_updates();
if ( empty( $updates ) ) {
@@ -248,14 +247,18 @@ public function get_theme_updates_list() {
$html = '';
foreach ( $updates as $update ) {
- // translators: 1. Theme name, 2. Current version, 3. Update version.
- $html .= '- ' . sprintf( __( '%1$s (current version: %2$s): %3$s', 'notification' ), $update->Name, $update->Version, $update->update['new_version'] ) . '
'; // phpcs:ignore
+ $html .= '- ' . sprintf(
+ // translators: 1. Theme name, 2. Current version, 3. Update version.
+ __( '%1$s (current version: %2$s): %3$s', 'notification' ),
+ $update->Name, // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+ $update->Version, // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
+ $update->update['new_version']
+ ) . '
';
}
$html .= '
';
return $html;
-
}
/**
@@ -266,7 +269,6 @@ public function get_theme_updates_list() {
* @return integer
*/
public function get_updates_count( $update_type = 'all' ) {
-
if ( 'all' !== $update_type ) {
$updates = call_user_func( 'get_' . $update_type . '_updates' );
@@ -288,7 +290,6 @@ public function get_updates_count( $update_type = 'all' ) {
}
return $count;
-
}
}
diff --git a/src/Repository/GlobalMergeTagRepository.php b/src/Repository/GlobalMergeTagRepository.php
index 87e254adf..6c9dfe200 100644
--- a/src/Repository/GlobalMergeTagRepository.php
+++ b/src/Repository/GlobalMergeTagRepository.php
@@ -126,21 +126,21 @@ public static function register() {
'slug' => 'date',
'name' => __( 'Trigger execution date', 'notification' ),
'hidden' => true,
- 'timestamp' => current_time( 'timestamp' ), // phpcs:ignore
+ 'timestamp' => time(),
] ) );
Register::global_merge_tag( new MergeTag\DateTime\DateTime( [
'slug' => 'date_time',
'name' => __( 'Trigger execution date and time', 'notification' ),
'hidden' => true,
- 'timestamp' => current_time( 'timestamp' ), // phpcs:ignore
+ 'timestamp' => time(),
] ) );
Register::global_merge_tag( new MergeTag\DateTime\Time( [
'slug' => 'time',
'name' => __( 'Trigger execution time', 'notification' ),
'hidden' => true,
- 'timestamp' => current_time( 'timestamp' ), // phpcs:ignore
+ 'timestamp' => time(),
] ) );
}
diff --git a/src/Traits/Webhook.php b/src/Traits/Webhook.php
index ca65a3014..c6f633372 100644
--- a/src/Traits/Webhook.php
+++ b/src/Traits/Webhook.php
@@ -48,7 +48,7 @@ public function http_request( $url, $args = [], $headers = [], $method ) {
$response = wp_remote_request( $url, $remote_args );
if ( is_wp_error( $response ) ) {
- // phpcs:ignore
+ // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
notification_log( $this->get_name(), 'error', '' . print_r( [
'url' => $url,
'args' => $remote_args,
diff --git a/src/Utils/Settings.php b/src/Utils/Settings.php
index 9f0016f5e..a11df5fa9 100644
--- a/src/Utils/Settings.php
+++ b/src/Utils/Settings.php
@@ -74,7 +74,6 @@ class Settings {
* @param string|bool $textdomain textdomain.
*/
public function __construct( $handle, $textdomain = false ) {
-
if ( empty( $handle ) ) {
throw new \Exception( 'Handle cannot be empty' );
}
@@ -89,9 +88,7 @@ public function __construct( $handle, $textdomain = false ) {
// settings autoload on admin side.
add_action( 'admin_init', [ $this, 'setup_field_values' ], 10 );
-
add_action( 'admin_post_save_' . $this->handle . '_settings', [ $this, 'save_settings' ] );
-
}
/**
@@ -100,17 +97,18 @@ public function __construct( $handle, $textdomain = false ) {
* @return void
*/
public function settings_page() {
-
+ // We're using the GET variable only to get the section name.
+ // phpcs:disable WordPress.Security.NonceVerification
$sections = $this->get_sections();
- if ( isset( $_GET['section'] ) && ! empty( $_GET['section'] ) ) { // phpcs:ignore
- $current_section = sanitize_text_field( wp_unslash( $_GET['section'] ) ); // phpcs:ignore
+ if ( isset( $_GET['section'] ) && ! empty( $_GET['section'] ) ) {
+ $current_section = sanitize_text_field( wp_unslash( $_GET['section'] ) );
} else {
$current_section = key( $this->get_sections() );
}
include $this->path . '/resources/templates/settings/page.php';
-
+ // phpcs:enable
}
/**
@@ -165,13 +163,15 @@ public function get_section( $slug = '' ) {
* @return void
*/
public function save_settings() {
-
- $data = $_POST; // phpcs:ignore
-
- if ( wp_verify_nonce( $data['nonce'], 'save_' . $this->handle . '_settings' ) === false ) {
+ if ( false === wp_verify_nonce(
+ sanitize_text_field( wp_unslash( $_POST['nonce'] ?? '' ) ),
+ 'save_' . $this->handle . '_settings'
+ ) ) {
wp_die( 'Can\'t touch this' );
}
+ $data = $_POST;
+
$settings = $data[ $this->handle . '_settings' ];
$to_save = [];
@@ -197,7 +197,6 @@ public function save_settings() {
do_action( $this->handle . '/settings/saved', $to_save, $this );
wp_safe_redirect( add_query_arg( 'updated', 'true', $data['_wp_http_referer'] ) );
-
}
/**
@@ -206,7 +205,6 @@ public function save_settings() {
* @return array settings
*/
public function get_settings() {
-
if ( empty( $this->settings ) ) {
foreach ( $this->get_sections() as $section_slug => $section ) {
$setting = get_option( $this->handle . '_' . $section_slug );
@@ -234,7 +232,6 @@ public function get_settings() {
}
return apply_filters( $this->handle . '/settings/saved_settings', $this->settings, $this );
-
}
/**
@@ -244,20 +241,14 @@ public function get_settings() {
* @return void
*/
public function setup_field_values() {
-
foreach ( $this->get_sections() as $section_slug => $section ) {
-
foreach ( $section->get_groups() as $group_slug => $group ) {
-
foreach ( $group->get_fields() as $field_slug => $field ) {
-
$setting_name = implode( '/', [ $section_slug, $group_slug, $field_slug ] );
$field->value( $this->get_setting( $setting_name ) );
-
}
}
}
-
}
@@ -269,7 +260,6 @@ public function setup_field_values() {
* @return mixed field value or null if name not found
*/
public function get_setting( $setting ) {
-
$parts = explode( '/', $setting );
if ( count( $parts ) !== 3 ) {
@@ -285,7 +275,6 @@ public function get_setting( $setting ) {
$value = $settings[ $parts[0] ][ $parts[1] ][ $parts[2] ];
return apply_filters( $this->handle . '/settings/setting/' . $setting, $value, $this );
-
}
/**
@@ -357,7 +346,6 @@ public function update_setting( $setting, $value ) {
* @return void
*/
public function set_variables() {
-
// path.
$this->path = dirname( dirname( dirname( __FILE__ ) ) );
@@ -366,16 +354,11 @@ public function set_variables() {
$theme_pos = strpos( $this->path, $theme_url['path'] );
if ( false !== $theme_pos ) { // loaded from theme.
-
$plugin_relative_dir = str_replace( $theme_url['path'], '', substr( $this->path, $theme_pos ) );
$this->uri = $theme_url['scheme'] . '://' . $theme_url['host'] . $theme_url['path'] . $plugin_relative_dir;
-
} else { // loaded from plugin.
-
$this->uri = trailingslashit( plugins_url( '', dirname( __FILE__ ) ) );
-
}
-
}
}
diff --git a/src/Utils/Settings/CoreFields/Button.php b/src/Utils/Settings/CoreFields/Button.php
index 3885882f4..9c5c063e3 100644
--- a/src/Utils/Settings/CoreFields/Button.php
+++ b/src/Utils/Settings/CoreFields/Button.php
@@ -22,7 +22,7 @@ class Button {
*/
public function input( $field ) {
- echo '' . $field->addon( 'label' ) . ''; // phpcs:ignore
+ echo '' . esc_html( $field->addon( 'label' ) ) . '';
}
diff --git a/src/Utils/Settings/CoreFields/Message.php b/src/Utils/Settings/CoreFields/Message.php
index b698986e4..cc619db51 100644
--- a/src/Utils/Settings/CoreFields/Message.php
+++ b/src/Utils/Settings/CoreFields/Message.php
@@ -27,7 +27,10 @@ public function input( $field ) {
$message = $field->addon( 'message' );
- echo is_callable( $message ) ? $message() : $message; // phpcs:ignore
+ // We cannot escape message contents as it may use complicated HTML to render
+ // advanced setting sections.
+ // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+ echo is_callable( $message ) ? $message() : $message;
if ( $field->addon( 'code' ) ) {
echo '
';
diff --git a/src/Utils/Settings/CoreFields/Select.php b/src/Utils/Settings/CoreFields/Select.php
index fdaa7c37b..437bc5463 100644
--- a/src/Utils/Settings/CoreFields/Select.php
+++ b/src/Utils/Settings/CoreFields/Select.php
@@ -27,13 +27,15 @@ public function input( $field ) {
$name = $field->addon( 'multiple' ) ? $field->input_name() . '[]' : $field->input_name();
$pretty = $field->addon( 'pretty' ) ? 'pretty-select' : '';
- echo '