| 1 |
<?php |
| 2 |
/** |
| 3 |
* Charitable Admin Splash. |
| 4 |
* |
| 5 |
* @package Charitable/Classes/Charitable_Admin_Splash |
| 6 |
* @author David Bisset |
| 7 |
* @copyright Copyright (c) 2023, WP Charitable LLC |
| 8 |
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License |
| 9 |
* @since 1.8.6 |
| 10 |
*/ |
| 11 |
|
| 12 |
// Exit if accessed directly. |
| 13 |
if ( ! defined( 'ABSPATH' ) ) { |
| 14 |
exit; |
| 15 |
} |
| 16 |
|
| 17 |
if ( ! class_exists( 'Charitable_Admin_Splash' ) ) : |
| 18 |
|
| 19 |
/** |
| 20 |
* Charitable_Advanced_Settings |
| 21 |
* |
| 22 |
* @final |
| 23 |
* @since 1.8.6 |
| 24 |
*/ |
| 25 |
final class Charitable_Admin_Splash { |
| 26 |
|
| 27 |
/** |
| 28 |
* The single instance of this class. |
| 29 |
* |
| 30 |
* @var Charitable_Admin_Splash|null |
| 31 |
*/ |
| 32 |
private static $instance = null; |
| 33 |
|
| 34 |
/** |
| 35 |
* Default plugin version. |
| 36 |
* |
| 37 |
* @since 1.8.6 |
| 38 |
* |
| 39 |
* @var string |
| 40 |
*/ |
| 41 |
private $default_plugin_version = '1.8.6'; // The last version before the "What's New?" feature. |
| 42 |
|
| 43 |
/** |
| 44 |
* Previous plugin version. |
| 45 |
* |
| 46 |
* @since 1.8.6 |
| 47 |
* |
| 48 |
* @var string |
| 49 |
*/ |
| 50 |
private $previous_plugin_version; |
| 51 |
|
| 52 |
/** |
| 53 |
* Latest splash version. |
| 54 |
* |
| 55 |
* @since 1.8.6 |
| 56 |
* |
| 57 |
* @var string |
| 58 |
*/ |
| 59 |
private $latest_splash_version; |
| 60 |
|
| 61 |
/** |
| 62 |
* Splash data. |
| 63 |
* |
| 64 |
* @since 1.8.6 |
| 65 |
* |
| 66 |
* @var array |
| 67 |
*/ |
| 68 |
private $splash_data = array(); |
| 69 |
|
| 70 |
/** |
| 71 |
* Whether it is a new Charitable installation. |
| 72 |
* |
| 73 |
* @since 1.8.6 |
| 74 |
* |
| 75 |
* @var bool |
| 76 |
*/ |
| 77 |
private $is_new_install; |
| 78 |
|
| 79 |
/** |
| 80 |
* Whether the splash link is added. |
| 81 |
* |
| 82 |
* @since 1.8.6 |
| 83 |
* |
| 84 |
* @var bool |
| 85 |
*/ |
| 86 |
private $splash_link_added = false; |
| 87 |
|
| 88 |
/** |
| 89 |
* Create object instance. |
| 90 |
* |
| 91 |
* @since 1.8.6 |
| 92 |
*/ |
| 93 |
private function __construct() { |
| 94 |
} |
| 95 |
|
| 96 |
/** |
| 97 |
* Returns and/or create the single instance of this class. |
| 98 |
* |
| 99 |
* @since 1.8.6 |
| 100 |
* |
| 101 |
* @return Charitable_Admin_Splash |
| 102 |
*/ |
| 103 |
public static function get_instance() { |
| 104 |
if ( is_null( self::$instance ) ) { |
| 105 |
self::$instance = new self(); |
| 106 |
} |
| 107 |
|
| 108 |
return self::$instance; |
| 109 |
} |
| 110 |
|
| 111 |
/** |
| 112 |
* Initialize splash data. |
| 113 |
* |
| 114 |
* @since 1.8.6 |
| 115 |
*/ |
| 116 |
public function initialize_splash_data() { |
| 117 |
|
| 118 |
if ( ! $this->is_allow_splash() ) { |
| 119 |
return; |
| 120 |
} |
| 121 |
|
| 122 |
if ( empty( $this->splash_data ) ) { |
| 123 |
$this->splash_data = $this->get_default_data(); |
| 124 |
|
| 125 |
// Add splash data to a transient. |
| 126 |
set_transient( 'charitable_splash_data', $this->splash_data, 60 * 60 * 24 ); |
| 127 |
|
| 128 |
$version = $this->get_major_version( charitable()->get_version() ); |
| 129 |
|
| 130 |
$this->update_splash_data_version( $version ); |
| 131 |
} |
| 132 |
} |
| 133 |
|
| 134 |
/** |
| 135 |
* Enqueue assets. |
| 136 |
* |
| 137 |
* @since 1.8.6 |
| 138 |
*/ |
| 139 |
public function admin_enqueue_scripts() { |
| 140 |
|
| 141 |
$min = charitable_get_min_suffix(); |
| 142 |
|
| 143 |
if ( ! wp_style_is( 'jquery-confirm', 'enqueued' ) ) { |
| 144 |
wp_enqueue_style( |
| 145 |
'jquery-confirm', |
| 146 |
charitable()->get_path( 'directory', false ) . 'assets/lib/jquery.confirm/jquery-confirm.min.css', |
| 147 |
null, |
| 148 |
'3.3.4' |
| 149 |
); |
| 150 |
} |
| 151 |
|
| 152 |
if ( ! wp_script_is( 'jquery-confirm', 'enqueued' ) ) { |
| 153 |
wp_enqueue_script( |
| 154 |
'jquery-confirm', |
| 155 |
charitable()->get_path( 'directory', false ) . 'assets/lib/jquery.confirm/jquery-confirm.min.js', |
| 156 |
array( 'jquery' ), |
| 157 |
'3.3.4', |
| 158 |
false |
| 159 |
); |
| 160 |
} |
| 161 |
|
| 162 |
wp_register_script( |
| 163 |
'charitable-admin-splash', |
| 164 |
charitable()->get_path( 'assets', false ) . 'js/admin/charitable-admin-splash' . $min . '.js', |
| 165 |
array( 'jquery', 'wp-util' ), |
| 166 |
charitable()->get_version(), |
| 167 |
true |
| 168 |
); |
| 169 |
|
| 170 |
wp_register_style( |
| 171 |
'charitable-admin-splash', |
| 172 |
charitable()->get_path( 'assets', false ) . 'css/admin/charitable-admin-splash' . $min . '.css', |
| 173 |
array(), |
| 174 |
charitable()->get_version() |
| 175 |
); |
| 176 |
|
| 177 |
wp_localize_script( |
| 178 |
'charitable-admin-splash', |
| 179 |
'charitable_admin_splash_data', |
| 180 |
array( |
| 181 |
'nonce' => wp_create_nonce( 'charitable_admin_splash_nonce' ), |
| 182 |
'triggerForceOpen' => $this->should_open_splash(), |
| 183 |
) |
| 184 |
); |
| 185 |
} |
| 186 |
|
| 187 |
/** |
| 188 |
* Render splash modal. |
| 189 |
* |
| 190 |
* @since 1.8.6 |
| 191 |
* |
| 192 |
* @param array $data Splash modal data. |
| 193 |
*/ |
| 194 |
public function render_modal( array $data = array() ) { // phpcs:ignore |
| 195 |
|
| 196 |
wp_enqueue_script( 'jquery-confirm' ); |
| 197 |
wp_enqueue_style( 'jquery-confirm' ); |
| 198 |
|
| 199 |
wp_enqueue_script( 'charitable-admin-splash' ); |
| 200 |
wp_enqueue_style( 'charitable-admin-splash' ); |
| 201 |
|
| 202 |
if ( $this->should_open_splash() ) { |
| 203 |
$this->update_splash_version(); |
| 204 |
} |
| 205 |
|
| 206 |
// Get splash data from a transient. |
| 207 |
$this->splash_data = get_transient( 'charitable_splash_data' ); |
| 208 |
|
| 209 |
if ( empty( $this->splash_data ) ) { |
| 210 |
$this->splash_data = $this->get_default_data(); |
| 211 |
} |
| 212 |
|
| 213 |
// Always reflect the current plugin major version in the header, even if the transient is stale. |
| 214 |
$this->splash_data['header']['version'] = $this->get_major_version( charitable()->get_version() ); |
| 215 |
|
| 216 |
$this->splash_data['sections'] = $this->retrieve_sections_for_user( $this->splash_data['sections'] ?? array() ); |
| 217 |
|
| 218 |
$template_location = '/admin/templates/splash/splash-modal'; |
| 219 |
$template_location = apply_filters( 'charitable_admin_splash_modal_template_location', $template_location ); |
| 220 |
echo charitable_render( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 221 |
$template_location, |
| 222 |
array( |
| 223 |
'data' => $this->splash_data, |
| 224 |
), |
| 225 |
true |
| 226 |
); |
| 227 |
} |
| 228 |
|
| 229 |
/** |
| 230 |
* Retrieve sections for user. |
| 231 |
* |
| 232 |
* @since 1.8.6 |
| 233 |
* |
| 234 |
* @param array $sections Sections. |
| 235 |
* @return array Sections. |
| 236 |
*/ |
| 237 |
public function retrieve_sections_for_user( array $sections = array() ): array { |
| 238 |
|
| 239 |
$sections = array( |
| 240 |
/* |
| 241 |
* 1.8.13 — AI assistants, the headline feature. |
| 242 |
* |
| 243 |
* This section is FIRST on purpose: the dark treatment comes from |
| 244 |
* `.charitable-splash-section:first-child` in the compiled |
| 245 |
* charitable-admin-splash.css (background #2c3338, white text), so the |
| 246 |
* marquee feature gets that look by position, not by a class of its own. |
| 247 |
* Reorder these and the dark block follows whatever ends up first. |
| 248 |
* |
| 249 |
* Ported from the Pro modal, where the same section leads Pro 1.8.19. |
| 250 |
* The copy is Pro's with one change: Pro reads "New in 1.8.19: switch on |
| 251 |
* write access", because Pro 1.8.18 shipped the read-only assistant first. |
| 252 |
* Lite never had that intermediate release — abilities and the write gate |
| 253 |
* both land here in 1.8.13 — so the clause is stated plainly instead of |
| 254 |
* pinned to a version Lite has no concept of. |
| 255 |
* |
| 256 |
* Video and poster are the same CDN objects Pro points at; both are live. |
| 257 |
* The 1-8-19 path is Pro's release folder, not a Lite version — the bucket |
| 258 |
* is shared, and the PayPal section below already does the same thing with |
| 259 |
* splash/1-8-15 under a Lite 1.8.11 badge. |
| 260 |
*/ |
| 261 |
array( |
| 262 |
'new' => true, |
| 263 |
'version' => '1.8.13', |
| 264 |
'layout' => 'fifty-fifty', |
| 265 |
'class' => 'no-order', |
| 266 |
'title' => __( 'Build Campaigns Just By Asking Your AI Assistant', 'charitable' ), |
| 267 |
'content' => __( 'Connect an assistant like Claude or ChatGPT using the free WPVibe plugin, or any MCP client, then just say what you need. Switch on write access and it makes the change itself. Launch a fundraiser, add a question to a donation form, restyle a campaign, or log a check that came in the post.', 'charitable' ), |
| 268 |
'video' => array( |
| 269 |
'url' => 'https://wpcharitable-space.nyc3.digitaloceanspaces.com/splash/1-8-19/ai-assistants.mp4', |
| 270 |
'poster' => 'https://wpcharitable-space.nyc3.digitaloceanspaces.com/splash/1-8-19/ai-assistants-poster.jpg', |
| 271 |
), |
| 272 |
'buttons' => array( |
| 273 |
'main' => array( |
| 274 |
'text' => __( 'Get Started', 'charitable' ), |
| 275 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/ai-assistants-getting-started/', 'splash-modal', 'AI Assistants Main' ), |
| 276 |
), |
| 277 |
'secondary' => array( |
| 278 |
'text' => __( 'Learn More', 'charitable' ), |
| 279 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/ai-assistants-learn-more/', 'splash-modal', 'AI Assistants Secondary' ), |
| 280 |
), |
| 281 |
), |
| 282 |
), |
| 283 |
/* |
| 284 |
* Charitable Events, slot 2. Ported from the Pro modal, where it carries |
| 285 |
* the 'new-addon' badge — Events ships on its own 1.0.0 cycle and is not a |
| 286 |
* Pro 1.8.19 feature. Here it is 'new-for-pro' instead, because for a Lite |
| 287 |
* reader the relevant fact is that it needs Pro, not that it is new. |
| 288 |
* |
| 289 |
* Buttons follow the Lite house style for Pro sections (main + upgrade) |
| 290 |
* rather than Pro's main + secondary. That is also what keeps the second |
| 291 |
* button alive: Pro's Learn More points at |
| 292 |
* /charitable-events-learn-more/, which is not published yet and 404s. |
| 293 |
*/ |
| 294 |
array( |
| 295 |
'new-for-pro' => true, |
| 296 |
'layout' => 'fifty-fifty', |
| 297 |
'class' => 'no-order', |
| 298 |
'title' => __( 'Charitable Events', 'charitable' ), |
| 299 |
'content' => __( 'Sell tickets to galas, dinners and virtual events without leaving Charitable. Every ticket is a donation, so the money lands in the event\'s own campaign. Set a fair market value per ticket and the deductible portion appears on the receipt. Each attendee gets a QR code, and you check them in at the door from your phone.', 'charitable' ), |
| 300 |
'img' => array( |
| 301 |
'url' => charitable()->get_path( 'assets', false ) . 'images/splash/1-8-19-charitable-events.png', |
| 302 |
'shadow' => 'none', |
| 303 |
), |
| 304 |
'buttons' => array( |
| 305 |
'main' => array( |
| 306 |
'text' => __( 'Get Started', 'charitable' ), |
| 307 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/charitable-events-getting-started/', 'splash-modal', 'Charitable Events Main' ), |
| 308 |
), |
| 309 |
'upgrade' => array( |
| 310 |
'text' => __( 'Upgrade to Pro', 'charitable' ), |
| 311 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/lite-upgrade/', 'splash-modal', 'Charitable Events Upgrade' ), |
| 312 |
), |
| 313 |
), |
| 314 |
), |
| 315 |
// 1.8.12 — Beacon campaign templates. |
| 316 |
array( |
| 317 |
'new' => true, |
| 318 |
'version' => '1.8.12', |
| 319 |
'layout' => 'fifty-fifty', |
| 320 |
'class' => 'no-order', |
| 321 |
'title' => __( 'New Beacon Campaign Templates', 'charitable' ), |
| 322 |
'content' => __( 'Two new campaign templates — Beacon (1 Column) and Beacon (2 Column) — built on the new Hero layout. Pick either from the template chooser for a bold, modern campaign page.', 'charitable' ), |
| 323 |
'img' => array( |
| 324 |
'url' => charitable()->get_path( 'assets', false ) . 'images/splash/1-8-12-beacon.jpg', |
| 325 |
'shadow' => 'none', |
| 326 |
), |
| 327 |
'buttons' => array( |
| 328 |
'main' => array( |
| 329 |
'text' => __( 'Get Started', 'charitable' ), |
| 330 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/beacon-templates-getting-started/', 'splash-modal', 'Beacon Templates Main' ), |
| 331 |
), |
| 332 |
'secondary' => array( |
| 333 |
'text' => __( 'Learn More', 'charitable' ), |
| 334 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/beacon-templates-learn-more/', 'splash-modal', 'Beacon Templates Secondary' ), |
| 335 |
), |
| 336 |
), |
| 337 |
), |
| 338 |
// PayPal Commerce — headline feature, uses same self-hosted video as Pro. |
| 339 |
array( |
| 340 |
'new' => true, |
| 341 |
'version' => '1.8.11', |
| 342 |
'layout' => 'fifty-fifty', |
| 343 |
'class' => 'no-order', |
| 344 |
'title' => __( 'PayPal Commerce', 'charitable' ), |
| 345 |
'content' => __( 'Accept donations through PayPal, Venmo, Pay Later, cards, Apple Pay, and Google Pay from a single integration. One-click Connect with PayPal setup, with support for one-time and recurring donations, saved payment methods, and refunds handled in the donation admin.', 'charitable' ), |
| 346 |
'video' => array( |
| 347 |
'url' => 'https://wpcharitable-space.nyc3.digitaloceanspaces.com/splash/1-8-15/paypal-commerce.mp4', |
| 348 |
), |
| 349 |
'buttons' => array( |
| 350 |
'main' => array( |
| 351 |
'text' => __( 'Get Started', 'charitable' ), |
| 352 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/paypal-commerce-getting-started/', 'splash-modal', 'PayPal Commerce Main' ), |
| 353 |
), |
| 354 |
'secondary' => array( |
| 355 |
'text' => __( 'Learn More', 'charitable' ), |
| 356 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/paypal-commerce-learn-more/', 'splash-modal', 'PayPal Commerce Secondary' ), |
| 357 |
), |
| 358 |
), |
| 359 |
), |
| 360 |
// 1.8.10 — Lite headline feature: Migration & Import Tools. |
| 361 |
array( |
| 362 |
'new' => true, |
| 363 |
'version' => '1.8.10', |
| 364 |
'layout' => 'fifty-fifty', |
| 365 |
'class' => 'no-order', |
| 366 |
'title' => __( 'Migration & Import Tools', 'charitable' ), |
| 367 |
'content' => __( 'Move from GiveWP or GiveButter to Charitable in minutes. Expanded import tools include CSV donations import and a new GiveWP Migration Tool (Beta) under a redesigned, tabbed interface.', 'charitable' ), |
| 368 |
'img' => array( |
| 369 |
'url' => charitable()->get_path( 'assets', false ) . 'images/splash/1-8-10-import-tools.svg', |
| 370 |
'shadow' => 'none', |
| 371 |
), |
| 372 |
'buttons' => array( |
| 373 |
'main' => array( |
| 374 |
'text' => __( 'Get Started', 'charitable' ), |
| 375 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/how-to-switch-from-givewp-to-charitable/', 'splash-modal', 'Import Tools Main' ), |
| 376 |
), |
| 377 |
), |
| 378 |
), |
| 379 |
// 1.8.17 — DonationExpress (Pro-only). |
| 380 |
array( |
| 381 |
'new-for-pro' => true, |
| 382 |
'layout' => 'fifty-fifty', |
| 383 |
'class' => 'no-order', |
| 384 |
'title' => __( 'DonationExpress ⚡', 'charitable' ), |
| 385 |
'content' => __( 'DonationExpress opens your donation forms in a full-screen, theme-independent sheet on phones. It loads fast, looks consistent on every device, and avoids theme conflicts.', 'charitable' ), |
| 386 |
'video' => array( |
| 387 |
'url' => 'https://wpcharitable-space.nyc3.digitaloceanspaces.com/splash/1-8-17/donationexpress.mp4', |
| 388 |
), |
| 389 |
'buttons' => array( |
| 390 |
'main' => array( |
| 391 |
'text' => __( 'Get Started', 'charitable' ), |
| 392 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/donationexpress-getting-started/', 'splash-modal', 'DonationExpress Main' ), |
| 393 |
), |
| 394 |
'upgrade' => array( |
| 395 |
'text' => __( 'Upgrade to Pro', 'charitable' ), |
| 396 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/lite-upgrade/', 'splash-modal', 'DonationExpress Upgrade' ), |
| 397 |
), |
| 398 |
), |
| 399 |
), |
| 400 |
// 1.8.17 — Style Your Campaigns Visually (Pro-only). |
| 401 |
array( |
| 402 |
'new-for-pro' => true, |
| 403 |
'layout' => 'fifty-fifty', |
| 404 |
'class' => 'no-order', |
| 405 |
'title' => __( 'Style Your Campaigns Visually', 'charitable' ), |
| 406 |
'content' => __( 'Campaign styling just got a major upgrade. Beyond the existing options, the new Styles tab brings ready-made design presets, a full global color palette (buttons, tabs, progress bar, text, and background), typography controls, and animations — all with a live preview and no code.', 'charitable' ), |
| 407 |
'img' => array( |
| 408 |
'url' => charitable()->get_path( 'assets', false ) . 'images/splash/1-8-17-campaign-styles.png', |
| 409 |
'shadow' => 'none', |
| 410 |
), |
| 411 |
'buttons' => array( |
| 412 |
'main' => array( |
| 413 |
'text' => __( 'Get Started', 'charitable' ), |
| 414 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/campaign-builder-styles-getting-started/', 'splash-modal', 'Campaign Builder Styles Main' ), |
| 415 |
), |
| 416 |
'upgrade' => array( |
| 417 |
'text' => __( 'Upgrade to Pro', 'charitable' ), |
| 418 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/lite-upgrade/', 'splash-modal', 'Campaign Builder Styles Upgrade' ), |
| 419 |
), |
| 420 |
), |
| 421 |
), |
| 422 |
// 1.8.14 — Campaign Countdown (Pro-only). |
| 423 |
array( |
| 424 |
'new-for-pro' => true, |
| 425 |
'layout' => 'fifty-fifty', |
| 426 |
'class' => 'no-order', |
| 427 |
'title' => __( 'Campaign Countdown', 'charitable' ), |
| 428 |
'content' => __( 'Add a countdown timer to any campaign with the new Campaign Builder field or Gutenberg block. Fully customizable, with a built-in fireworks effect when the campaign ends.', 'charitable' ), |
| 429 |
'img' => array( |
| 430 |
'url' => charitable()->get_path( 'assets', false ) . 'images/splash/1-8-14-campaign-countdown.png', |
| 431 |
'shadow' => 'none', |
| 432 |
), |
| 433 |
'buttons' => array( |
| 434 |
'main' => array( |
| 435 |
'text' => __( 'Get Started', 'charitable' ), |
| 436 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/campaign-countdown-getting-started/', 'splash-modal', 'Campaign Countdown Main' ), |
| 437 |
), |
| 438 |
'upgrade' => array( |
| 439 |
'text' => __( 'Upgrade to Pro', 'charitable' ), |
| 440 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/lite-upgrade/', 'splash-modal', 'Campaign Countdown Upgrade' ), |
| 441 |
), |
| 442 |
), |
| 443 |
), |
| 444 |
// 1.8.9 — Lite security feature. |
| 445 |
array( |
| 446 |
'new' => true, |
| 447 |
'version' => '1.8.9', |
| 448 |
'layout' => 'fifty-fifty', |
| 449 |
'class' => 'no-order', |
| 450 |
'title' => __( 'Security Enhancements', 'charitable' ), |
| 451 |
'content' => __( 'Charitable Lite now supports Google reCAPTCHA, hCaptcha, and Cloudflare Turnstile for improved security.', 'charitable' ), |
| 452 |
'img' => array( |
| 453 |
'url' => charitable()->get_path( 'assets', false ) . 'images/splash/1-8-9-security.svg', |
| 454 |
'shadow' => 'none', |
| 455 |
), |
| 456 |
'buttons' => array( |
| 457 |
'main' => array( |
| 458 |
'text' => __( 'Get Started', 'charitable' ), |
| 459 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/introducing-improved-security-and-clean-donation-tool/', 'splash-modal', 'Security Main' ), |
| 460 |
), |
| 461 |
), |
| 462 |
), |
| 463 |
// 1.8.14 — Donorbox CSV Importer (Pro-only). |
| 464 |
array( |
| 465 |
'new-for-pro' => true, |
| 466 |
'layout' => 'fifty-fifty', |
| 467 |
'class' => 'no-order', |
| 468 |
'title' => __( 'Donorbox CSV Importer', 'charitable' ), |
| 469 |
'content' => __( 'Move from Donorbox to Charitable in a single CSV upload. Import historical donations, donors, campaigns, and recurring plans with preview, dry-run, and rollback.', 'charitable' ), |
| 470 |
'img' => array( |
| 471 |
'url' => charitable()->get_path( 'assets', false ) . 'images/splash/1-8-14-donorbox-importer.png', |
| 472 |
'shadow' => 'none', |
| 473 |
), |
| 474 |
'buttons' => array( |
| 475 |
'main' => array( |
| 476 |
'text' => __( 'Get Started', 'charitable' ), |
| 477 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/donorbox-csv-importer-getting-started/', 'splash-modal', 'Donorbox CSV Importer Main' ), |
| 478 |
), |
| 479 |
'upgrade' => array( |
| 480 |
'text' => __( 'Upgrade to Pro', 'charitable' ), |
| 481 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/lite-upgrade/', 'splash-modal', 'Donorbox CSV Importer Upgrade' ), |
| 482 |
), |
| 483 |
), |
| 484 |
), |
| 485 |
// 1.8.13 — Mini Donation Widget (Pro-only, Vimeo embed for Lite). |
| 486 |
array( |
| 487 |
'new-for-pro' => true, |
| 488 |
'layout' => 'fifty-fifty', |
| 489 |
'class' => 'no-order', |
| 490 |
'title' => __( 'Mini Donation Widget', 'charitable' ), |
| 491 |
'content' => __( 'Embed a compact donation form anywhere on your site, no page redirect required. Add it to sidebars, landing pages, or any widget area using a simple block or shortcode.', 'charitable' ), |
| 492 |
'video' => array( |
| 493 |
'vimeo_id' => '1186687749', |
| 494 |
), |
| 495 |
'buttons' => array( |
| 496 |
'main' => array( |
| 497 |
'text' => __( 'Get Started', 'charitable' ), |
| 498 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/documentation/mini-donation-widget/', 'splash-modal', 'Mini Donation Widget Main' ), |
| 499 |
), |
| 500 |
'upgrade' => array( |
| 501 |
'text' => __( 'Upgrade to Pro', 'charitable' ), |
| 502 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/lite-upgrade/', 'splash-modal', 'Mini Donation Widget Upgrade' ), |
| 503 |
), |
| 504 |
), |
| 505 |
), |
| 506 |
// Pro upsells. |
| 507 |
array( |
| 508 |
'new-for-pro' => true, |
| 509 |
'layout' => 'fifty-fifty', |
| 510 |
'class' => 'no-order', |
| 511 |
'title' => __( 'Campaign Showcase', 'charitable' ), |
| 512 |
'content' => __( 'Display all your campaigns beautifully with full layout control including grid, list, or masonry. No coding required.', 'charitable' ), |
| 513 |
'img' => array( |
| 514 |
'url' => charitable()->get_path( 'assets', false ) . 'images/splash/1-8-13-campaign-showcase.png', |
| 515 |
'shadow' => 'none', |
| 516 |
), |
| 517 |
'buttons' => array( |
| 518 |
'main' => array( |
| 519 |
'text' => __( 'Get Started', 'charitable' ), |
| 520 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/campaign-showcase-getting-started/', 'splash-modal', 'Campaign Showcase Main' ), |
| 521 |
), |
| 522 |
'upgrade' => array( |
| 523 |
'text' => __( 'Upgrade to Pro', 'charitable' ), |
| 524 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/lite-upgrade/', 'splash-modal', 'Campaign Showcase Upgrade' ), |
| 525 |
), |
| 526 |
), |
| 527 |
), |
| 528 |
array( |
| 529 |
'new-for-pro' => true, |
| 530 |
'layout' => 'fifty-fifty', |
| 531 |
'class' => 'no-order', |
| 532 |
'title' => __( 'Donations Feed', 'charitable' ), |
| 533 |
'content' => __( 'Display recent donations in beautiful list or card views with sorting, filtering, pagination, and live polling that automatically refreshes when new donations arrive.', 'charitable' ), |
| 534 |
'img' => array( |
| 535 |
'url' => charitable()->get_path( 'assets', false ) . 'images/splash/1-8-13-donate-feed.png', |
| 536 |
'shadow' => 'none', |
| 537 |
), |
| 538 |
'buttons' => array( |
| 539 |
'main' => array( |
| 540 |
'text' => __( 'Get Started', 'charitable' ), |
| 541 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/donations-feed-getting-started/', 'splash-modal', 'Donations Feed Main' ), |
| 542 |
), |
| 543 |
'upgrade' => array( |
| 544 |
'text' => __( 'Upgrade to Pro', 'charitable' ), |
| 545 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/lite-upgrade/', 'splash-modal', 'Donations Feed Upgrade' ), |
| 546 |
), |
| 547 |
), |
| 548 |
), |
| 549 |
array( |
| 550 |
'new-for-pro' => true, |
| 551 |
'layout' => 'fifty-fifty', |
| 552 |
'class' => 'no-order', |
| 553 |
'title' => __( 'Campaign Modal Button', 'charitable' ), |
| 554 |
'content' => __( 'Add a donate button anywhere on your site that opens a donation form in a modal popup, no page redirect required. Available as a block or shortcode.', 'charitable' ), |
| 555 |
'img' => array( |
| 556 |
'url' => charitable()->get_path( 'assets', false ) . 'images/splash/1-8-13-modal-button.png', |
| 557 |
'shadow' => 'none', |
| 558 |
), |
| 559 |
'buttons' => array( |
| 560 |
'main' => array( |
| 561 |
'text' => __( 'Get Started', 'charitable' ), |
| 562 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/campaign-modal-button-getting-started/', 'splash-modal', 'Campaign Modal Button Main' ), |
| 563 |
), |
| 564 |
'upgrade' => array( |
| 565 |
'text' => __( 'Upgrade to Pro', 'charitable' ), |
| 566 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/lite-upgrade/', 'splash-modal', 'Campaign Modal Button Upgrade' ), |
| 567 |
), |
| 568 |
), |
| 569 |
), |
| 570 |
// Two-column "More Recent Features" list. |
| 571 |
array( |
| 572 |
'layout' => 'more-features', |
| 573 |
'class' => 'no-order', |
| 574 |
'title' => __( 'More Recent Features:', 'charitable' ), |
| 575 |
'items' => array( |
| 576 |
__( 'Prefill Donation Forms', 'charitable' ), |
| 577 |
__( 'Campaign Featured Image', 'charitable' ), |
| 578 |
__( 'Campaign Selector', 'charitable' ), |
| 579 |
__( 'Envira Gallery Integration', 'charitable' ), |
| 580 |
__( 'Visual Form Builder', 'charitable' ), |
| 581 |
__( 'Donor Leaderboards', 'charitable' ), |
| 582 |
__( 'Magic Donor Dashboard Link', 'charitable' ), |
| 583 |
__( 'DIVI Integration', 'charitable' ), |
| 584 |
__( 'DonorTrust', 'charitable' ), |
| 585 |
__( 'Google Analytics', 'charitable' ), |
| 586 |
), |
| 587 |
), |
| 588 |
); |
| 589 |
|
| 590 |
return $sections; |
| 591 |
} |
| 592 |
|
| 593 |
/** |
| 594 |
* Check if splash data is empty. |
| 595 |
* |
| 596 |
* @since 1.8.6 |
| 597 |
* |
| 598 |
* @return bool True if empty, false otherwise. |
| 599 |
*/ |
| 600 |
public function is_splash_empty(): bool { |
| 601 |
|
| 602 |
if ( empty( $this->splash_data ) ) { |
| 603 |
return true; |
| 604 |
} |
| 605 |
|
| 606 |
return empty( $this->retrieve_sections_for_user( $this->splash_data['sections'] ?? array() ) ); |
| 607 |
} |
| 608 |
|
| 609 |
/** |
| 610 |
* Output splash modal. |
| 611 |
* |
| 612 |
* @since 1.8.6 |
| 613 |
*/ |
| 614 |
public function admin_footer() { |
| 615 |
if ( ! $this->is_allow_splash() ) { |
| 616 |
return; |
| 617 |
} |
| 618 |
|
| 619 |
$this->render_modal(); |
| 620 |
} |
| 621 |
|
| 622 |
/** |
| 623 |
* Get splash data version. |
| 624 |
* |
| 625 |
* @since 1.8.6 |
| 626 |
* |
| 627 |
* @return string Splash data version. |
| 628 |
*/ |
| 629 |
private function get_splash_data_version(): string { |
| 630 |
|
| 631 |
return get_option( 'charitable_splash_data_version', charitable()->get_version() ); |
| 632 |
} |
| 633 |
|
| 634 |
/** |
| 635 |
* Update splash data version. |
| 636 |
* |
| 637 |
* @since 1.8.6 |
| 638 |
* |
| 639 |
* @param string $version Splash data version. |
| 640 |
*/ |
| 641 |
private function update_splash_data_version( string $version ) { |
| 642 |
|
| 643 |
update_option( 'charitable_splash_data_version', $version ); |
| 644 |
} |
| 645 |
|
| 646 |
/** |
| 647 |
* Get the latest splash version. |
| 648 |
* |
| 649 |
* @since 1.8.6 |
| 650 |
* |
| 651 |
* @return string Splash version. |
| 652 |
*/ |
| 653 |
private function get_latest_splash_version(): string { |
| 654 |
|
| 655 |
if ( $this->latest_splash_version ) { |
| 656 |
return $this->latest_splash_version; |
| 657 |
} |
| 658 |
|
| 659 |
$this->latest_splash_version = get_option( 'charitable_splash_version', '1.8.6' ); |
| 660 |
|
| 661 |
// Create option if it doesn't exist. |
| 662 |
if ( empty( $this->latest_splash_version ) ) { |
| 663 |
$this->latest_splash_version = $this->default_plugin_version; |
| 664 |
|
| 665 |
update_option( 'charitable_splash_version', $this->latest_splash_version ); |
| 666 |
} |
| 667 |
|
| 668 |
return $this->latest_splash_version; |
| 669 |
} |
| 670 |
|
| 671 |
/** |
| 672 |
* Update option with the latest splash version. |
| 673 |
* |
| 674 |
* @since 1.8.6 |
| 675 |
*/ |
| 676 |
private function update_splash_version() { |
| 677 |
|
| 678 |
update_option( 'charitable_splash_version', $this->get_major_version( charitable()->get_version() ) ); |
| 679 |
} |
| 680 |
|
| 681 |
/** |
| 682 |
* Get a major version. |
| 683 |
* |
| 684 |
* @since 1.8.6 |
| 685 |
* |
| 686 |
* @param string $version Version. |
| 687 |
* |
| 688 |
* @return string Major version. |
| 689 |
*/ |
| 690 |
private function get_major_version( $version ): string { |
| 691 |
|
| 692 |
// Allow only digits and dots. |
| 693 |
$clean_version = preg_replace( '/[^0-9.]/', '.', $version ); |
| 694 |
|
| 695 |
// Get version parts. |
| 696 |
$version_parts = explode( '.', $clean_version ); |
| 697 |
|
| 698 |
// If a version has more than 3 parts - use only first 3. Get block data only for major versions. |
| 699 |
if ( count( $version_parts ) > 3 ) { |
| 700 |
$version = implode( '.', array_slice( $version_parts, 0, 3 ) ); |
| 701 |
} |
| 702 |
|
| 703 |
return $version; |
| 704 |
} |
| 705 |
|
| 706 |
/** |
| 707 |
* Get user license type. |
| 708 |
* |
| 709 |
* @since 1.8.6 |
| 710 |
* |
| 711 |
* @return string |
| 712 |
*/ |
| 713 |
private function get_user_license(): string { |
| 714 |
|
| 715 |
/** |
| 716 |
* License type used for splash screen. |
| 717 |
* |
| 718 |
* @since 1.8.6 |
| 719 |
* |
| 720 |
* @param string $license License type. |
| 721 |
*/ |
| 722 |
return (string) apply_filters( 'charitable_admin_splash_splashtrait_get_user_license', 'lite' ); |
| 723 |
} |
| 724 |
|
| 725 |
/** |
| 726 |
* Get default splash modal data. |
| 727 |
* |
| 728 |
* @since 1.8.6 |
| 729 |
* |
| 730 |
* @return array Splash modal data. |
| 731 |
*/ |
| 732 |
private function get_default_data(): array { |
| 733 |
|
| 734 |
$default_data = array( |
| 735 |
'license' => $this->get_user_license(), |
| 736 |
'buttons' => array( |
| 737 |
'get_started' => __( 'Get Started', 'charitable' ), |
| 738 |
'learn_more' => __( 'Learn More', 'charitable' ), |
| 739 |
), |
| 740 |
'header' => array( |
| 741 |
'image' => charitable()->get_path( 'assets', false ) . 'images/charitable-logo.svg', |
| 742 |
'title' => __( 'What\'s New in Charitable', 'charitable' ), |
| 743 |
'description' => __( 'Since you\'ve been gone, we\'ve added some great new features to help grow your campaigns and generate more donations. Here are some highlights...', 'charitable' ), |
| 744 |
'version' => $this->get_major_version( charitable()->get_version() ), |
| 745 |
), |
| 746 |
|
| 747 |
); |
| 748 |
|
| 749 |
// If the chartiable_pro is active, that means they are licensed but not using Charitable Pro plugin. |
| 750 |
if ( ! charitable_is_pro() ) : |
| 751 |
$default_data['footer'] = array( |
| 752 |
'title' => __( 'Add Your License To Activate Charitable Pro Plugin Now And Start Getting More Donations!', 'charitable' ), |
| 753 |
'description' => __( 'Charitable Pro is a powerful upgrade that allows you to manage donors along with built-in features like videos, donor comments, PDF receipts, a dashboard for donors, and more.', 'charitable' ), |
| 754 |
'upgrade' => array( |
| 755 |
'text' => __( 'Learn More', 'charitable' ), |
| 756 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/lite-upgrade/', 'splash-modal', 'learn-more' ), |
| 757 |
), |
| 758 |
); |
| 759 |
else : |
| 760 |
$default_data['footer'] = array( |
| 761 |
'title' => __( 'Upgrade To The Charitable Pro Plugin At No Cost!', 'charitable' ), |
| 762 |
'description' => __( 'Registered users with active license can upgrade to Charitable Pro plugin at NO COST. It\'s included in all plans (basic, plus, pro, elite).', 'charitable' ), |
| 763 |
'upgrade' => array( |
| 764 |
'text' => __( 'Learn More', 'charitable' ), |
| 765 |
'url' => charitable_utm_link( 'https://www.wpcharitable.com/pricing/upgrade-lite-to-pro/', 'splash-modal', 'learn-more' ), |
| 766 |
), |
| 767 |
); |
| 768 |
endif; |
| 769 |
|
| 770 |
return $default_data; |
| 771 |
} |
| 772 |
|
| 773 |
/** |
| 774 |
* Determine if the current update is a minor update. |
| 775 |
* |
| 776 |
* Checks the charitable_upgrade_log option for the latest upgrade entry |
| 777 |
* and compares its version with the current version to determine if this is |
| 778 |
* a minor update (same major version) or major update (different major version). |
| 779 |
* |
| 780 |
* @since 1.8.6 |
| 781 |
* |
| 782 |
* @return bool True if it's a minor update, false otherwise. |
| 783 |
*/ |
| 784 |
private function is_minor_update(): bool { |
| 785 |
$upgrade_log = get_option( 'charitable_upgrade_log', array() ); |
| 786 |
|
| 787 |
// If no upgrade log exists, this is not a minor update. |
| 788 |
if ( empty( $upgrade_log ) ) { |
| 789 |
return false; |
| 790 |
} |
| 791 |
|
| 792 |
// Get the latest upgrade entry. |
| 793 |
$latest_entry = end( $upgrade_log ); |
| 794 |
|
| 795 |
// If no version in the latest entry, this is not a minor update. |
| 796 |
if ( ! isset( $latest_entry['version'] ) ) { |
| 797 |
return false; |
| 798 |
} |
| 799 |
|
| 800 |
$latest_version = $latest_entry['version']; |
| 801 |
$current_version = charitable()->get_version(); |
| 802 |
|
| 803 |
// Get major versions (e.g., 1.8.5 from 1.8.5.1). |
| 804 |
$latest_major = $this->get_major_version( $latest_version ); |
| 805 |
$current_major = $this->get_major_version( $current_version ); |
| 806 |
|
| 807 |
// If major versions match, this is a minor update. |
| 808 |
return $latest_major === $current_major; |
| 809 |
} |
| 810 |
|
| 811 |
/** |
| 812 |
* Check if splash modal is allowed. |
| 813 |
* Only allow on Charitable dashboard or settings screens; never on onboarding/setup welcome. |
| 814 |
* |
| 815 |
* @since 1.8.6 |
| 816 |
* |
| 817 |
* @return bool True if allowed, false otherwise. |
| 818 |
*/ |
| 819 |
public function is_allow_splash(): bool { |
| 820 |
|
| 821 |
// Never show on onboarding/setup welcome flow (splash would sit on top of onboarding UI). |
| 822 |
if ( $this->is_onboarding_setup_page() ) { |
| 823 |
return false; |
| 824 |
} |
| 825 |
|
| 826 |
// Only show on Charitable pages OR dashboard. |
| 827 |
return charitable_is_admin_screen() || $this->is_dashboard(); |
| 828 |
} |
| 829 |
|
| 830 |
/** |
| 831 |
* Check if current screen is the onboarding/setup welcome flow. |
| 832 |
* Splash must not show here so it doesn't overlay the onboarding UI. |
| 833 |
* |
| 834 |
* @since 1.8.9.6 |
| 835 |
* |
| 836 |
* @return bool True if on onboarding setup page, false otherwise. |
| 837 |
*/ |
| 838 |
private function is_onboarding_setup_page(): bool { |
| 839 |
|
| 840 |
if ( ! is_admin() || empty( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 841 |
return false; |
| 842 |
} |
| 843 |
|
| 844 |
$page = sanitize_text_field( $_GET['page'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 845 |
|
| 846 |
// Block splash on the setup wizard, checklist, and any charitable-setup* pages. |
| 847 |
if ( strpos( $page, 'charitable-setup' ) !== false ) { |
| 848 |
return true; |
| 849 |
} |
| 850 |
|
| 851 |
// Block splash on the welcome/onboarding flow (page=charitable&wpchar_lite=lite&setup=...). |
| 852 |
if ( 'charitable' !== $page ) { |
| 853 |
return false; |
| 854 |
} |
| 855 |
|
| 856 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 857 |
if ( empty( $_GET['wpchar_lite'] ) || 'lite' !== $_GET['wpchar_lite'] ) { |
| 858 |
return false; |
| 859 |
} |
| 860 |
|
| 861 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 862 |
if ( empty( $_GET['setup'] ) ) { |
| 863 |
return false; |
| 864 |
} |
| 865 |
|
| 866 |
$setup = sanitize_key( $_GET['setup'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 867 |
|
| 868 |
return in_array( $setup, array( 'welcome', 'cancelled', 'return' ), true ); |
| 869 |
} |
| 870 |
|
| 871 |
/** |
| 872 |
* Check if splash modal should be opened. |
| 873 |
* |
| 874 |
* @since 1.8.6 |
| 875 |
* |
| 876 |
* @return bool True if splash should open, false otherwise. |
| 877 |
*/ |
| 878 |
private function should_open_splash(): bool { |
| 879 |
|
| 880 |
// Skip if announcements are hidden, or it is the dashboard page. |
| 881 |
if ( $this->is_dashboard() || $this->hide_splash_modal() ) { |
| 882 |
return false; |
| 883 |
} |
| 884 |
|
| 885 |
// If we are forcing the preview, then we should open the splash. |
| 886 |
if ( $this->is_force_open() ) { |
| 887 |
return true; |
| 888 |
} |
| 889 |
|
| 890 |
if ( ! $this->is_allow_splash() ) { |
| 891 |
return false; |
| 892 |
} |
| 893 |
|
| 894 |
// Allow if a splash version different from the current plugin major version, and it's not a new installation. |
| 895 |
if ( charitable_is_debug( 'splash' ) ) { |
| 896 |
// phpcs:disable |
| 897 |
error_log( 'Charitable Admin Splash: Latest splash version: ' . $this->get_latest_splash_version() ); |
| 898 |
error_log( 'Charitable Admin Splash: Current major version: ' . $this->get_major_version( charitable()->get_version() ) ); |
| 899 |
error_log( 'Charitable Admin Splash: Is new install: ' . ( $this->is_new_install() ? 'true' : 'false' ) ); |
| 900 |
error_log( 'Charitable Admin Splash: Is force open: ' . ( $this->is_force_open() ? 'true' : 'false' ) ); |
| 901 |
// phpcs:enable |
| 902 |
} |
| 903 |
|
| 904 |
$should_open_splash = $this->get_latest_splash_version() !== $this->get_major_version( charitable()->get_version() ) && |
| 905 |
( ! $this->is_new_install() || $this->is_force_open() ); |
| 906 |
|
| 907 |
if ( ! $should_open_splash ) { |
| 908 |
return false; |
| 909 |
} |
| 910 |
|
| 911 |
// Skip if user on the builder page and the Challenge can be started. |
| 912 |
if ( $this->is_builder_page() ) { |
| 913 |
return false; |
| 914 |
} |
| 915 |
|
| 916 |
return true; |
| 917 |
} |
| 918 |
|
| 919 |
/** |
| 920 |
* Check if the current page is the builder page. |
| 921 |
* |
| 922 |
* @since 1.8.6 |
| 923 |
* |
| 924 |
* @return bool True if it is the builder page, false otherwise. |
| 925 |
*/ |
| 926 |
private function is_builder_page(): bool { |
| 927 |
return ! empty( $_GET['page'] ) && 'charitable-campaign-builder' === $_GET['page']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 928 |
} |
| 929 |
|
| 930 |
/** |
| 931 |
* Check if the current page is the dashboard. |
| 932 |
* |
| 933 |
* @since 1.8.6 |
| 934 |
* |
| 935 |
* @return bool True if it is the dashboard, false otherwise. |
| 936 |
*/ |
| 937 |
private function is_dashboard(): bool { |
| 938 |
|
| 939 |
global $pagenow; |
| 940 |
|
| 941 |
if ( ! empty( $_GET['page'] ) && 'charitable-dashboard' === $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 942 |
return true; |
| 943 |
} |
| 944 |
|
| 945 |
return false; |
| 946 |
} |
| 947 |
|
| 948 |
/** |
| 949 |
* Check if splash modal should be forced open. |
| 950 |
* |
| 951 |
* @since 1.8.6 |
| 952 |
* |
| 953 |
* @return bool True if it should be forced open, false otherwise. |
| 954 |
*/ |
| 955 |
private function is_force_open(): bool { |
| 956 |
|
| 957 |
// phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 958 |
return sanitize_key( $_GET['charitable_action'] ?? '' ) === 'preview-splash-screen'; |
| 959 |
} |
| 960 |
|
| 961 |
/** |
| 962 |
* Check if the plugin is newly installed. |
| 963 |
* |
| 964 |
* Checks the charitable_upgrade_log option for the initial installation entry |
| 965 |
* and compares its version with the current version to determine if this is |
| 966 |
* a new installation. |
| 967 |
* |
| 968 |
* @since 1.8.6 |
| 969 |
* |
| 970 |
* @return bool True if new install, false otherwise. |
| 971 |
*/ |
| 972 |
private function is_new_install(): bool { |
| 973 |
$upgrade_log = get_option( 'charitable_upgrade_log', array() ); |
| 974 |
|
| 975 |
// If no upgrade log exists, this is a new install. |
| 976 |
if ( empty( $upgrade_log ) ) { |
| 977 |
return true; |
| 978 |
} |
| 979 |
|
| 980 |
// Find the initial installation entry. |
| 981 |
$install_entry = null; |
| 982 |
foreach ( $upgrade_log as $entry ) { |
| 983 |
if ( isset( $entry['message'] ) && 'Charitable was installed.' === $entry['message'] ) { |
| 984 |
$install_entry = $entry; |
| 985 |
break; |
| 986 |
} |
| 987 |
} |
| 988 |
|
| 989 |
// If no installation entry found, this is a new install. |
| 990 |
if ( ! $install_entry || ! isset( $install_entry['version'] ) ) { |
| 991 |
return true; |
| 992 |
} |
| 993 |
|
| 994 |
$installed_version = $install_entry['version']; |
| 995 |
$current_version = charitable()->get_version(); |
| 996 |
|
| 997 |
// Get major versions (e.g., 1.8.5 from 1.8.5.1). |
| 998 |
$installed_major = $this->get_major_version( $installed_version ); |
| 999 |
$current_major = $this->get_major_version( $current_version ); |
| 1000 |
|
| 1001 |
// If major versions match and current version is not greater, this is a new install. |
| 1002 |
return $installed_major === $current_major && version_compare( $current_version, $installed_version, '<=' ); |
| 1003 |
} |
| 1004 |
|
| 1005 |
/** |
| 1006 |
* Check if splash modal should be hidden. |
| 1007 |
* |
| 1008 |
* @since 1.8.6 |
| 1009 |
* |
| 1010 |
* @return bool True if hidden, false otherwise. |
| 1011 |
*/ |
| 1012 |
private function hide_splash_modal(): bool { |
| 1013 |
|
| 1014 |
/** |
| 1015 |
* Force to hide splash modal. |
| 1016 |
* |
| 1017 |
* @since 1.8.6 |
| 1018 |
* |
| 1019 |
* @param bool $hide_splash_modal True to hide, false otherwise. |
| 1020 |
*/ |
| 1021 |
return (bool) apply_filters( 'charitable_admin_splash_screen_hide_splash_modal', charitable_get_option( 'hide_announcements' ) ); |
| 1022 |
} |
| 1023 |
} |
| 1024 |
|
| 1025 |
endif; |
| 1026 |
|