| @@ -1,8 +1,9 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | 3 | namespace Better_Payment\Lite\Traits; |
| 4 | 4 | |
| 5 | +use Better_Payment\Lite\Admin\Setup_Wizard; | |
| 5 | 6 | use Better_Payment\Lite\Classes\Plugin_Usage_Tracker; |
| 6 | 7 | |
| 7 | 8 | /** |
| 8 | 9 | * Exit if accessed directly |
| @@ -19,33 +20,8 @@ | ||
| 19 | 20 | trait Helper |
| 20 | 21 | { |
| 21 | 22 | use Elements, ElementorHelper, WordPressHelper, TemplateQuery; |
| 22 | 23 | |
| 23 | - public function bp_template_render($filePath, $variables = array(), $print = true) | |
| 24 | - { | |
| 25 | - $output = NULL; | |
| 26 | - | |
| 27 | - if (file_exists($filePath)) { | |
| 28 | - // Extract the variables to a local namespace | |
| 29 | - extract($variables); | |
| 30 | - | |
| 31 | - // Start output buffering | |
| 32 | - ob_start(); | |
| 33 | - | |
| 34 | - // Include the template file | |
| 35 | - include $filePath; | |
| 36 | - | |
| 37 | - // End buffering and return its contents | |
| 38 | - $output = ob_get_clean(); | |
| 39 | - } | |
| 40 | - | |
| 41 | - if ( $print ) { | |
| 42 | - print $output; | |
| 43 | - } | |
| 44 | - | |
| 45 | - return $output; | |
| 46 | - } | |
| 47 | - | |
| 48 | 24 | /** |
| 49 | 25 | * List of allowed html tag for wp_kses |
| 50 | 26 | * |
| 51 | 27 | * bp_allowed_tags |
| @@ -303,8 +279,33 @@ | ||
| 303 | 279 | * @since v1.1.1 |
| 304 | 280 | */ |
| 305 | 281 | public function start_plugin_tracking() |
| 306 | 282 | { |
| 283 | + /** | |
| 284 | + * Lite-only, exactly as before — this guard used to live in the | |
| 285 | + * `! $this->pro_enabled` block in Admin::init(). It moved here when | |
| 286 | + * tracking was rewired to also run on cron requests, so the single | |
| 287 | + * remaining caller does not have to repeat it. | |
| 288 | + * | |
| 289 | + * Evaluating the filter at `init` rather than at `plugins_loaded` is | |
| 290 | + * strictly safer too: every plugin has loaded by then, so Pro cannot | |
| 291 | + * lose a race to register its filter and have Lite start tracking on a | |
| 292 | + * Pro site. | |
| 293 | + * | |
| 294 | + * @since 2.3.2 | |
| 295 | + */ | |
| 296 | + if ( apply_filters( 'better_payment/pro_enabled', false ) ) { | |
| 297 | + return; | |
| 298 | + } | |
| 299 | + | |
| 300 | + /** | |
| 301 | + * Must run BEFORE init() below: init() calls maybe_schedule_tracking(), | |
| 302 | + * which only schedules once consent is on record. Recording consent | |
| 303 | + * first means a fresh install gets its daily event in this same request | |
| 304 | + * rather than the next one. | |
| 305 | + */ | |
| 306 | + $this->maybe_auto_enable_usage_tracking(); | |
| 307 | + | |
| 307 | 308 | $tracker = Plugin_Usage_Tracker::get_instance( BETTER_PAYMENT_FILE, [ |
| 308 | 309 | 'opt_in' => true, |
| 309 | 310 | 'goodbye_form' => true, |
| 310 | 311 | 'item_id' => '64e1f724b5e14edb343e' |
| @@ -310,16 +311,58 @@ | ||
| 310 | 311 | 'item_id' => '64e1f724b5e14edb343e' |
| 311 | 312 | ] ); |
| 312 | 313 | $tracker->set_notice_options(array( |
| 313 | 314 | 'notice' => 'Want to help make <strong>Better Payment</strong> even more awesome? You can get a <strong>10% discount coupon</strong> for Pro upgrade if you allow.', |
| 314 | - 'extra_notice' => 'We collect non-sensitive diagnostic data and plugin usage information. | |
| 315 | - Your site URL, WordPress & PHP version, plugins & themes and email address to send you the | |
| 316 | - discount coupon. This data lets us make sure this plugin always stays compatible with the most | |
| 317 | - popular plugins and themes. No spam, I promise.', | |
| 315 | + 'extra_notice' => 'Nothing is sent unless you allow it. If you do: your site URL and name; | |
| 316 | + WordPress, PHP and server versions; language and charset; your <strong>active</strong> plugins and | |
| 317 | + theme (and how many inactive); which Better Payment widgets, blocks and campaign elements you use, | |
| 318 | + and which features and gateways you have switched on; and your admin email, for the coupon. | |
| 319 | + We never collect your payment or transaction data, your customers\' details, your API keys, | |
| 320 | + or your inactive plugin names. No spam, I promise.', | |
| 318 | 321 | )); |
| 319 | 322 | $tracker->init(); |
| 320 | 323 | } |
| 321 | 324 | |
| 325 | + /** | |
| 326 | + * Turn usage tracking on for a fresh install that never answered the wizard. | |
| 327 | + * | |
| 328 | + * The wizard's two buttons cover the cases where the user answers: "Proceed | |
| 329 | + * To Next Step" and "Skip It" both call Setup_Wizard::wpins_process(). A user | |
| 330 | + * who closes the wizard, navigates away, or never opens it at all answers | |
| 331 | + * neither, and this is what covers them. | |
| 332 | + * | |
| 333 | + * Three things this deliberately does: | |
| 334 | + * | |
| 335 | + * 1. **Fresh installs only.** The `pending` marker is written by | |
| 336 | + * Installer::enable_setup_wizard() and only on a site with no | |
| 337 | + * `better_payment_setup_wizard` option — i.e. one being installed, not | |
| 338 | + * upgraded. An existing site keeps whatever tracking state it has. | |
| 339 | + * 2. **Exactly once.** The marker flips to `done` before any work, so this | |
| 340 | + * cannot re-assert consent on a later request. That is what keeps a | |
| 341 | + * future opt-out from being silently undone on the next page load, and | |
| 342 | + * it holds even if the call below throws. | |
| 343 | + * 3. **No forced send.** `wpins_process( false )` records consent and stops. | |
| 344 | + * This runs on `init` during an ordinary admin (or cron) request, and | |
| 345 | + * the tracker's send is a blocking POST with a 30s timeout — it belongs | |
| 346 | + * on the scheduled event, which init() arranges immediately after. | |
| 347 | + * | |
| 348 | + * Inherits start_plugin_tracking()'s Pro gate: a site running Better Payment | |
| 349 | + * Pro never reaches here, exactly like every other tracking code path. | |
| 350 | + * | |
| 351 | + * @return void | |
| 352 | + * @since 2.3.2 | |
| 353 | + */ | |
| 354 | + protected function maybe_auto_enable_usage_tracking() | |
| 355 | + { | |
| 356 | + if ( get_option( 'better_payment_tracking_auto_optin' ) !== 'pending' ) { | |
| 357 | + return; | |
| 358 | + } | |
| 359 | + | |
| 360 | + update_option( 'better_payment_tracking_auto_optin', 'done' ); | |
| 361 | + | |
| 362 | + Setup_Wizard::wpins_process( false ); | |
| 363 | + } | |
| 364 | + | |
| 322 | 365 | /** |
| 323 | 366 | * List of currencies not supported by paypal or stripe |
| 324 | 367 | * |
| 325 | 368 | * @since v1.3.1 |
| @@ -492,8 +535,36 @@ | ||
| 492 | 535 | |
| 493 | 536 | return $currency_code; // Fallback to currency code |
| 494 | 537 | } |
| 495 | 538 | |
| 539 | + /** | |
| 540 | + * Whether a visitor may pay through a form stored on this post. | |
| 541 | + * | |
| 542 | + * Every payment handler takes the form's page id from the request, and nothing stopped it | |
| 543 | + * pointing at a draft, private, scheduled or password-protected post — so an unpublished | |
| 544 | + * form could be paid, and any form's configuration probed by id. A published post | |
| 545 | + * qualifies; anything else only for a user allowed to read it (an editor testing a draft | |
| 546 | + * in preview), and never while its password has not been entered. | |
| 547 | + * | |
| 548 | + * @since 2.3.4 | |
| 549 | + * | |
| 550 | + * @param int $page_id Post id. | |
| 551 | + * @return bool | |
| 552 | + */ | |
| 553 | + public function is_payable_form_page( $page_id ) { | |
| 554 | + $post = get_post( absint( $page_id ) ); | |
| 555 | + | |
| 556 | + if ( ! $post ) { | |
| 557 | + return false; | |
| 558 | + } | |
| 559 | + | |
| 560 | + if ( 'publish' !== $post->post_status && ! current_user_can( 'read_post', $post->ID ) ) { | |
| 561 | + return false; | |
| 562 | + } | |
| 563 | + | |
| 564 | + return ! post_password_required( $post ); | |
| 565 | + } | |
| 566 | + | |
| 496 | 567 | /** |
| 497 | 568 | * Widget settings |
| 498 | 569 | * |
| 499 | 570 | * @since 1.0.0 |
| @@ -569,9 +640,8 @@ | ||
| 569 | 640 | } |
| 570 | 641 | |
| 571 | 642 | $body = wp_remote_retrieve_body( $response ); |
| 572 | 643 | $data = json_decode( $body, true ); |
| 573 | - // dd( $data ); | |
| 574 | 644 | |
| 575 | 645 | if ( ! isset( $data ) || ! is_array( $data ) ) { |
| 576 | 646 | error_log( 'Stripe API response format error.' ); |
| 577 | 647 | return []; |
| @@ -765,9 +835,8 @@ | ||
| 765 | 835 | * @param array $blocks Parsed blocks from parse_blocks() |
| 766 | 836 | * @return bool |
| 767 | 837 | */ |
| 768 | 838 | public function detect_better_payment_blocks( $blocks ) { |
| 769 | - dd('ok'); | |
| 770 | 839 | $bp_block_names = [ 'better-payment/payment-form', 'better-payment/user-dashboard' ]; |
| 771 | 840 | |
| 772 | 841 | foreach ( $blocks as $block ) { |
| 773 | 842 | if ( in_array( $block['blockName'], $bp_block_names, true ) ) { |