wp_create_nonce( 'adasprso-dismiss-notice-nonce' ), 'ajaxurl' => admin_url( 'admin-ajax.php' ), ) ); } /** * Work out which review round, if any, is currently eligible to display. * * Kept separate from the rendering so the donation notice can defer to the * review notice without depending on admin_notices callback ordering. * * @return int|false Round number (1 or 2), or false when nothing is due. */ private function get_review_round() { if ( ! current_user_can( 'manage_options' ) ) { return false; } // Skip on our own settings page. $screen = get_current_screen(); if ( $screen && 'settings_page_add-as-preferred-source' === $screen->id ) { return false; } // Never show again once the user has left (or clicked) a review. if ( get_option( 'adasprso_user_already_reviewed', false ) ) { return false; } $activation_date = get_option( 'adasprso_activation_date', false ); if ( false === $activation_date ) { return false; } $days_active = ( time() - $activation_date ) / DAY_IN_SECONDS; $r1_dismissed = get_option( 'adasprso_review_notice_dismissed', false ); $r2_dismissed = get_option( 'adasprso_review_dismissed_r2', false ); if ( $days_active >= 16 && $r1_dismissed && ! $r2_dismissed ) { return 2; } if ( $days_active >= 8 && ! $r1_dismissed ) { return 1; } return false; } /** * Display the review request notice after 8 days, then again at 16 days * if the user dismissed round 1 without leaving a review. */ public function display_review_notice() { $round = $this->get_review_round(); if ( false === $round ) { return; } wp_enqueue_style( 'adasprso-admin-notices', ADASPRSO_PLUGIN_URL . 'admin/css/admin-notices.css', array(), ADASPRSO_VERSION ); wp_enqueue_script( 'adasprso-admin-notices' ); $review_url = 'https://wordpress.org/support/plugin/add-as-preferred-source/reviews/#new-post'; $support_url = 'https://wordpress.org/support/plugin/add-as-preferred-source/#new-topic-0'; ?> 'Unauthorized' ) ); wp_die(); } $round = isset( $_POST['round'] ) ? absint( $_POST['round'] ) : 1; if ( 2 === $round ) { update_option( 'adasprso_review_dismissed_r2', true ); } else { update_option( 'adasprso_review_notice_dismissed', true ); } if ( isset( $_POST['dismiss_reason'] ) ) { $dismiss_reason = sanitize_text_field( wp_unslash( $_POST['dismiss_reason'] ) ); if ( in_array( $dismiss_reason, array( 'already_reviewed', 'leave_review_clicked' ), true ) ) { update_option( 'adasprso_user_already_reviewed', true ); } elseif ( in_array( $dismiss_reason, array( 'needs_help_dismissed', 'needs_help_clicked' ), true ) ) { update_option( 'adasprso_user_needs_help', true ); } } wp_send_json_success(); } /** * Display the donation request notice at the 20, 40, 100 and 200 day * usage milestones. * * Unlike the review notice this one shows on every admin screen, including * our own settings page, and dismissing it only clears the current * milestone so later milestones still come around. */ public function display_donation_notice() { if ( ! current_user_can( 'manage_options' ) ) { return; } $activation_date = get_option( 'adasprso_activation_date', false ); if ( false === $activation_date ) { return; } // The review notice takes priority so the two never stack up together. if ( false !== $this->get_review_round() ) { return; } $days_active = ( time() - $activation_date ) / DAY_IN_SECONDS; $last_shown = (int) get_option( 'adasprso_donation_last_milestone', 0 ); // Pick the highest milestone reached so someone returning after a long // absence gets one ask, not one for every milestone they passed. $milestone = 0; foreach ( $this->get_donation_milestones() as $candidate ) { if ( $days_active >= $candidate && $candidate > $last_shown ) { $milestone = $candidate; } } if ( 0 === $milestone ) { return; } wp_enqueue_style( 'adasprso-admin-notices', ADASPRSO_PLUGIN_URL . 'admin/css/admin-notices.css', array(), ADASPRSO_VERSION ); wp_enqueue_script( 'adasprso-admin-notices' ); $donate_url = 'https://seoactionplan.com/extdonate'; ?> 'Unauthorized' ) ); wp_die(); } $milestone = isset( $_POST['milestone'] ) ? absint( $_POST['milestone'] ) : 0; // Only accept a real milestone so a crafted request cannot skip ahead // to the final one and silence every remaining ask. if ( ! in_array( $milestone, $this->get_donation_milestones(), true ) ) { wp_send_json_error( array( 'message' => 'Invalid milestone' ) ); wp_die(); } update_option( 'adasprso_donation_last_milestone', $milestone ); wp_send_json_success(); } }