PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.8.13
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.8.13
1.8.13 1.8.12.3 1.8.12.2 1.8.12.1 1.8.12 1.8.11.3 1.8.11.2 1.8.11.1 1.8.11 1.6.6 1.6.60 1.6.7 1.6.8 1.6.9 1.7.0 1.7.0.1 1.7.0.11 1.7.0.12 1.7.0.14 1.7.0.2 1.7.0.3 1.7.0.5 1.7.0.6 1.7.0.7 1.7.0.9 All 211 releases
charitable / includes / admin / notifications / class-charitable-notification-test-helper.php

class-charitable-notification-test-helper.php in Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) 1.8.13, at includes/admin/notifications/class-charitable-notification-test-helper.php

245 lines 8.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Charitable Notification Test Helper.
4 *
5 * Admin-only test harness for the notifications v2 system. Triggered by
6 * URL query params on any Charitable admin page. Lets a developer / QA
7 * seed and clear local notifications, fire the cron jobs, and exercise
8 * the donation / campaign triggers without waiting for real events.
9 *
10 * Gated to manage_options. Intended for in-dev use; remove (or no-op
11 * gate behind WP_DEBUG) before public release.
12 *
13 * Usage:
14 * ?charitable_notif_test=seed_all — adds one notification per category
15 * ?charitable_notif_test=clear — clears local + dismissed + new_feed
16 * ?charitable_notif_test=fire_cron — runs all 4 cron jobs inline
17 * ?charitable_notif_test=fire_health — adds a health alert (red dot)
18 * ?charitable_notif_test=fire_milestone — adds a milestone notification
19 * ?charitable_notif_test=fire_nudge — adds a nudge notification
20 * ?charitable_notif_test=fire_lifecycle — adds a lifecycle notification
21 * ?charitable_notif_test=fire_legal — adds a legal/compliance alert (red dot)
22 * ?charitable_notif_test=force_empty — clears everything so empty state shows
23 *
24 * @package Charitable/Classes/Charitable_Notification_Test_Helper
25 * @since 1.8.12
26 */
27
28 if ( ! defined( 'ABSPATH' ) ) {
29 exit;
30 }
31
32 class Charitable_Notification_Test_Helper {
33
34 private static $instance = null;
35
36 public static function get_instance() {
37 if ( is_null( self::$instance ) ) {
38 self::$instance = new self();
39 }
40 return self::$instance;
41 }
42
43 public function init() {
44 add_action( 'admin_init', array( $this, 'maybe_run_test' ), 99 );
45 }
46
47 /**
48 * Intercept ?charitable_notif_test=<action> and dispatch.
49 */
50 public function maybe_run_test() {
51 if ( empty( $_GET['charitable_notif_test'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
52 return;
53 }
54 if ( ! current_user_can( 'manage_options' ) ) {
55 return;
56 }
57
58 $action = sanitize_key( wp_unslash( $_GET['charitable_notif_test'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
59
60 switch ( $action ) {
61 case 'seed_all':
62 $this->seed_one_of_each();
63 $message = 'Seeded one notification per category.';
64 break;
65 case 'clear':
66 $this->clear_all();
67 $message = 'Cleared all local + new_feed + dismissed notifications.';
68 break;
69 case 'force_empty':
70 $this->force_empty();
71 $message = 'Forced empty state (cleared everything + disabled legacy feed for this user).';
72 break;
73 case 'fire_cron':
74 $this->fire_cron();
75 $message = 'Ran all 4 cron jobs inline.';
76 break;
77 case 'fire_health':
78 $this->seed( 'health_test', 'health' );
79 $message = 'Added a HEALTH alert (red dot).';
80 break;
81 case 'fire_legal':
82 $this->seed( 'legal_test', 'legal' );
83 $message = 'Added a LEGAL alert (red dot).';
84 break;
85 case 'fire_milestone':
86 $this->seed( 'milestone_test', 'milestone' );
87 $message = 'Added a MILESTONE notification.';
88 break;
89 case 'fire_nudge':
90 $this->seed( 'nudge_test', 'nudge' );
91 $message = 'Added a NUDGE notification.';
92 break;
93 case 'fire_lifecycle':
94 $this->seed( 'lifecycle_test', 'lifecycle' );
95 $message = 'Added a LIFECYCLE notification.';
96 break;
97 default:
98 return;
99 }
100
101 // Stash a notice to display after redirect (so the user sees confirmation).
102 set_transient( 'charitable_notif_test_notice_' . get_current_user_id(), $message, 30 );
103
104 // Redirect to drop the query param.
105 $redirect_url = remove_query_arg( 'charitable_notif_test' );
106 wp_safe_redirect( $redirect_url );
107 exit;
108 }
109
110 /**
111 * Seed one notification for each category.
112 */
113 private function seed_one_of_each() {
114 $this->seed( 'health_test', 'health' );
115 $this->seed( 'legal_test', 'legal' );
116 $this->seed( 'lifecycle_test', 'lifecycle' );
117 $this->seed( 'milestone_test', 'milestone' );
118 $this->seed( 'nudge_test', 'nudge' );
119 }
120
121 /**
122 * Seed a single local notification for a category.
123 *
124 * @param string $id
125 * @param string $category
126 */
127 private function seed( $id, $category ) {
128 $copy = array(
129 'health' => array(
130 'title' => __( 'TEST: Failed donations detected', 'charitable' ),
131 'content' => '<p>' . __( 'This is a seeded HEALTH alert used to verify the red dot and red border.', 'charitable' ) . '</p>',
132 'notification_type' => 'warning',
133 'badge_label' => __( 'Health Alert', 'charitable' ),
134 'badge_type' => 'critical',
135 ),
136 'legal' => array(
137 'title' => __( 'TEST: Compliance settings need attention', 'charitable' ),
138 'content' => '<p>' . __( 'This is a seeded LEGAL alert used to verify the red dot and red border.', 'charitable' ) . '</p>',
139 'notification_type' => 'warning',
140 'badge_label' => __( 'Compliance', 'charitable' ),
141 'badge_type' => 'warning',
142 ),
143 'lifecycle' => array(
144 'title' => __( 'TEST: Campaign is now live', 'charitable' ),
145 'content' => '<p>' . __( 'This is a seeded LIFECYCLE notification used to verify the blue flag icon.', 'charitable' ) . '</p>',
146 'notification_type' => 'info',
147 'badge_label' => __( 'Campaign', 'charitable' ),
148 'badge_type' => 'info',
149 ),
150 'milestone' => array(
151 'title' => __( 'TEST: 100 donors reached', 'charitable' ),
152 'content' => '<p>' . __( 'This is a seeded MILESTONE used to verify the star icon and green check.', 'charitable' ) . '</p>',
153 'notification_type' => 'success',
154 'badge_label' => __( 'Milestone', 'charitable' ),
155 'badge_type' => 'success',
156 ),
157 'nudge' => array(
158 'title' => __( 'TEST: Create your first campaign', 'charitable' ),
159 'content' => '<p>' . __( 'This is a seeded NUDGE used to verify the lightbulb icon.', 'charitable' ) . '</p>',
160 'notification_type' => 'info',
161 'badge_label' => '',
162 'badge_type' => 'nudge',
163 ),
164 );
165
166 if ( ! isset( $copy[ $category ] ) ) {
167 return;
168 }
169
170 $data = array_merge(
171 $copy[ $category ],
172 array(
173 'dismissible' => true,
174 'category' => $category,
175 'btns' => array(
176 'main' => array(
177 'url' => admin_url( 'admin.php?page=charitable-dashboard' ),
178 'text' => __( 'View Dashboard', 'charitable' ),
179 ),
180 ),
181 )
182 );
183
184 Charitable_Local_Notifications::get_instance()->add( $id, $data );
185 }
186
187 /**
188 * Clear all local + new_feed + dismissed.
189 */
190 private function clear_all() {
191 Charitable_Notifications::get_instance()->save_option_partial( array(
192 'local' => array(),
193 'new_feed' => array(),
194 'dismissed' => array(),
195 'dismissed_times' => array(),
196 ) );
197 }
198
199 /**
200 * Clear everything AND set legacy_feed to false so the empty state shows.
201 */
202 private function force_empty() {
203 $this->clear_all();
204
205 // Also overwrite the cached legacy feed.
206 $option = (array) get_option( 'charitable_notifications', array() );
207 $option['feed'] = array();
208 $option['events'] = array();
209 update_option( 'charitable_notifications', $option );
210
211 // Turn off the legacy_feed category so the legacy feed is suppressed even after re-fetch.
212 Charitable_Notification_Settings::get_instance();
213 $settings = (array) Charitable_Notifications::get_instance()->get_option()['settings'];
214 $settings['legacy_feed'] = false;
215 Charitable_Notifications::get_instance()->save_option_partial( array( 'settings' => $settings ) );
216 }
217
218 /**
219 * Fire all 4 cron jobs inline.
220 */
221 private function fire_cron() {
222 $cron = Charitable_Notification_Cron::get_instance();
223 $cron->run_health_check();
224 $cron->run_compliance_check();
225 $cron->run_nudge_check();
226 $cron->run_new_feed_fetch();
227 }
228
229 /**
230 * Display the success message after redirect.
231 */
232 public function maybe_show_notice() {
233 $key = 'charitable_notif_test_notice_' . get_current_user_id();
234 $message = get_transient( $key );
235 if ( ! $message ) {
236 return;
237 }
238 delete_transient( $key );
239 printf(
240 '<div class="notice notice-info is-dismissible"><p><strong>Notification test:</strong> %s</p></div>',
241 esc_html( $message )
242 );
243 }
244 }
245