| @@ -79,8 +79,19 @@ | ||
| 79 | 79 | private $item_id; |
| 80 | 80 | private $notice_options; |
| 81 | 81 | |
| 82 | 82 | /** |
| 83 | + * Unix timestamp before which the opt-in notice stays hidden. | |
| 84 | + * | |
| 85 | + * 0 keeps the SDK's original behaviour (ask on the first admin page load). | |
| 86 | + * ThinkRank sets it to install time + a grace period via | |
| 87 | + * {@see Usage_Tracker_Manager::start_tracking()}. | |
| 88 | + * | |
| 89 | + * @var int | |
| 90 | + */ | |
| 91 | + private $notice_after = 0; | |
| 92 | + | |
| 93 | + /** | |
| 83 | 94 | * Get Instance of Plugin_Usage_Tracker |
| 84 | 95 | * |
| 85 | 96 | * @return Plugin_Usage_Tracker |
| 86 | 97 | */ |
| @@ -192,9 +203,16 @@ | ||
| 192 | 203 | */ |
| 193 | 204 | public function init() { |
| 194 | 205 | add_action('admin_init', array($this, 'clicked')); |
| 195 | 206 | add_action($this->event_hook, array($this, 'do_tracking')); |
| 207 | + | |
| 208 | + // Both hooks, deliberately: Admin\Manager::remove_admin_notice() strips | |
| 209 | + // every `admin_notices` callback on ThinkRank's own screens and re-fires | |
| 210 | + // `thinkrank_admin_notices` in their place. Since notice() now renders | |
| 211 | + // only on those screens, registering on `admin_notices` alone would mean | |
| 212 | + // it never renders anywhere. The two never both run on one request. | |
| 196 | 213 | add_action('admin_notices', array($this, 'notice')); |
| 214 | + add_action('thinkrank_admin_notices', array($this, 'notice')); | |
| 197 | 215 | /** |
| 198 | 216 | * Deactivation Reason Form and Submit Data to Insights. |
| 199 | 217 | */ |
| 200 | 218 | add_filter('plugin_action_links_' . plugin_basename($this->plugin_file), array($this, 'deactivate_action_links')); |
| @@ -663,8 +681,24 @@ | ||
| 663 | 681 | } |
| 664 | 682 | if (!current_user_can('manage_options')) { |
| 665 | 683 | return; |
| 666 | 684 | } |
| 685 | + /** | |
| 686 | + * Too soon after install to ask. A consent request on the user's very | |
| 687 | + * first admin page load is the loudest possible first impression, and | |
| 688 | + * it competes with the Setup Wizard the activation redirect just put | |
| 689 | + * them in. | |
| 690 | + */ | |
| 691 | + if ($this->notice_after > 0 && time() < $this->notice_after) { | |
| 692 | + return; | |
| 693 | + } | |
| 694 | + /** | |
| 695 | + * Ask on ThinkRank's own screens only. The card used to render on every | |
| 696 | + * admin screen in the site, including other plugins' settings pages. | |
| 697 | + */ | |
| 698 | + if (!$this->is_own_screen()) { | |
| 699 | + return; | |
| 700 | + } | |
| 667 | 701 | |
| 668 | 702 | $url_yes = add_query_arg([ |
| 669 | 703 | 'plugin' => $this->plugin_name, |
| 670 | 704 | 'plugin_action' => 'yes', |
| @@ -711,8 +745,57 @@ | ||
| 711 | 745 | $output .= '</div>'; |
| 712 | 746 | |
| 713 | 747 | // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
| 714 | 748 | echo $output; |
| 749 | + } | |
| 750 | + | |
| 751 | + /** | |
| 752 | + * Hold the opt-in notice back until the given time. | |
| 753 | + * | |
| 754 | + * @since 2.8.1 | |
| 755 | + * @param int $timestamp Unix timestamp; 0 restores "ask immediately". | |
| 756 | + * @return void | |
| 757 | + */ | |
| 758 | + public function set_notice_after($timestamp) { | |
| 759 | + $this->notice_after = max(0, (int) $timestamp); | |
| 760 | + } | |
| 761 | + | |
| 762 | + /** | |
| 763 | + * Whether the current admin screen belongs to ThinkRank. | |
| 764 | + * | |
| 765 | + * Matched on the screen id rather than against a list of page slugs: | |
| 766 | + * Admin\Manager already keeps such a list and it has drifted from the | |
| 767 | + * pages actually registered, and Pro adds screens of its own that a list | |
| 768 | + * living in free could not know about. | |
| 769 | + * | |
| 770 | + * The Setup Wizard screen is excluded — it suppresses admin notices | |
| 771 | + * wholesale and collects consent itself, so a card there would be both | |
| 772 | + * invisible and redundant. | |
| 773 | + * | |
| 774 | + * @since 2.8.1 | |
| 775 | + * @return bool | |
| 776 | + */ | |
| 777 | + private function is_own_screen() { | |
| 778 | + if (!function_exists('get_current_screen')) { | |
| 779 | + return false; | |
| 780 | + } | |
| 781 | + | |
| 782 | + $screen = get_current_screen(); | |
| 783 | + if (!$screen instanceof \WP_Screen || empty($screen->id)) { | |
| 784 | + return false; | |
| 785 | + } | |
| 786 | + | |
| 787 | + $is_own = strpos($screen->id, 'thinkrank') !== false | |
| 788 | + && strpos($screen->id, 'thinkrank_setup_wizard') === false; | |
| 789 | + | |
| 790 | + /** | |
| 791 | + * Filter whether the usage-tracking opt-in notice may render here. | |
| 792 | + * | |
| 793 | + * @since 2.8.1 | |
| 794 | + * @param bool $is_own Whether this is a ThinkRank screen. | |
| 795 | + * @param \WP_Screen $screen Current screen. | |
| 796 | + */ | |
| 797 | + return (bool) apply_filters('thinkrank_usage_notice_is_own_screen', $is_own, $screen); | |
| 715 | 798 | } |
| 716 | 799 | |
| 717 | 800 | /** |
| 718 | 801 | * Set all notice options to customized notice. |