PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 2.9.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v2.9.0
2.9.0 2.8.0 2.7.0 2.6.0 2.5.0 2.4.0 2.3.0 2.2.0 2.1.1 2.1.0 2.0.2 2.0.1 2.0.0 1.32.0 1.31.0 1.30.0 1.29.0 1.28.0 1.27.0 1.26.0 1.25.0 trunk 1.0.0 1.0.1 1.0.2 All 50 releases
← All changes | includes/core/class-plugin-usage-tracker.php +83 -0 2.2.02.9.0 View file →
@@ -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.