Add Appsero tracking and update dependencies#514
Conversation
Introduced Appsero client and updater dependencies for tracking and insights. Added a new Tracker class to handle plugin analytics and custom deactivation reasons. Updated Bootstrap to initialize Tracker and defined STOREGROWTH_VERSION constant in main plugin file.
📝 WalkthroughWalkthroughAdds Appsero-based telemetry: new Tracker class initializes an Appsero client, collects insights and dynamic plugin data, and provides custom deactivation reasons. Bootstrap is updated to instantiate the tracker. composer.json gains PHP >=7.4 and Appsero dev dependencies; plugin version constant STOREGROWTH_VERSION is defined. Changes
Sequence DiagramsequenceDiagram
participant Bootstrap as Bootstrap
participant Tracker as Tracker
participant Appsero as Appsero Client
Bootstrap->>Tracker: new Tracker()
Tracker->>Tracker: __construct()
Tracker->>Appsero: appsero_init_tracker_dokan() / instantiate Client
Appsero-->>Tracker: return Client & Insights
Tracker->>Appsero: register dynamic extras (products, pro status, versions)
Tracker->>Appsero: initialize plugin telemetry
Tracker->>Tracker: add filter for custom deactivation reasons
Tracker-->>Bootstrap: tracker initialized
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (8)
storegrowth-sales-booster.php (1)
33-38: Fix docblock label and guard against version drift.
- The comment says “Define plugin FILE” but defines version. Update it.
- Keep header Version and constant in sync to avoid drift.
-/** - * Define plugin __FILE__ - */ +/** + * Define plugin version. + */ if ( ! defined( 'STOREGROWTH_VERSION' ) ) { define( 'STOREGROWTH_VERSION', '2.0.2' ); }Optionally enforce sync in CI (fail if header Version ≠ STOREGROWTH_VERSION).
includes/Tracker.php (6)
14-20: Type and narrow visibility for $insights.Use a typed, private property to prevent accidental external mutation.
- /** - * Insights class - * - * @var Insights - */ - public $insights = null; + /** + * Insights instance. + * + * @var Insights|null + */ + private ?Insights $insights = null;
27-29: Rename init method and add return types.Name is plugin-agnostic; add return type hints.
- public function __construct() { - $this->appsero_init_tracker_dokan(); - } + public function __construct() { + $this->appsero_init_tracker(); + } @@ - public function appsero_init_tracker_dokan() { + public function appsero_init_tracker(): void {Also applies to: 37-38
37-56: Defensive check: ensure constants are defined; optional early exit.If STOREGROWTH_FILE isn’t defined for any reason, bail to avoid fatals.
- $client = new Client( '512b82bc-5d26-46d3-9d14-e51642c15ff3', 'StoreGrowth', STOREGROWTH_FILE ); + if ( ! defined( 'STOREGROWTH_FILE' ) ) { + return; + } + $client = new Client( '512b82bc-5d26-46d3-9d14-e51642c15ff3', 'StoreGrowth', STOREGROWTH_FILE );Also confirm that the Appsero project key is intended to be public in VCS.
67-76: Fix docblock types and add method return type.The filter receives/returns an array of arrays, not string[].
- * @param string[] $reasons - * @param null|Client $client + * @param array $reasons + * @param null|Client $client @@ - public function get_custom_deactivation_reasons( $reasons, $client = null ) { + public function get_custom_deactivation_reasons( array $reasons, $client = null ): array {
78-121: Merge default reasons, localize strings, and keep HTML sanitized.
- Merge with existing $reasons instead of replacing.
- Make user-visible strings translatable.
- Rely on Appsero/WP sanitization for SVG; confirm it’s kses‑sanitized.
- return [ + return array_merge( + $reasons, + [ [ 'id' => 'storegrowth-sales-booster-pro-is-expensive', - 'text' => 'StoreGrowth PRO is expensive ', - 'placeholder' => 'We’ve discounts going all year round. Please copy & visit this link to instantly get 30% off your purchase: https://storegrowth.io/pricing/?utm_source=plugin&utm_medium=wp-admin&utm_campaign=storegrowth-sales-booster', + 'text' => __( 'StoreGrowth PRO is expensive', 'storegrowth-sales-booster' ), + 'placeholder' => __( 'We’ve discounts going all year round. Please copy & visit this link to instantly get 30% off your purchase: https://storegrowth.io/pricing/?utm_source=plugin&utm_medium=wp-admin&utm_campaign=storegrowth-sales-booster', 'storegrowth-sales-booster' ), 'icon' => '<svg height="23" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 23 23"><path d="M11.5 0C17.9 0 23 5.1 23 11.5S17.9 23 11.5 23 0 17.9 0 11.5 5.1 0 11.5 0zm0 2C6.3 2 2 6.3 2 11.5S6.3 21 11.5 21s9.5-4.3 9.5-9.5S16.7 2 11.5 2zm.5 3v1.1c.5 0 .9.1 1.4.3.4.1.8.3 1.1.6.3.2.6.5.8.9.2.4.3.8.4 1.3h-2.3c0-.4-.1-.7-.4-1-.3-.3-.6-.4-.9-.4v2.5c.1 0 .3.1.4.1.1 0 .3.1.4.1.8.2 1.4.4 1.8.7s.7.6 1 .9c.2.3.3.6.4.9 0 .3.1.6.1.8 0 .2-.1.5-.2.8-.1.3-.3.6-.6.9-.3.3-.7.6-1.2.8s-1.2.4-2 .4V18h-1v-1.2c-1.2-.1-2.1-.4-2.8-1S7.1 14.4 7 13.2h2.3c0 .5.2 1 .5 1.3.3.3.7.5 1.2.6v-3c-.1 0-.1 0-.2-.1-.1 0-.2 0-.3-.1l-1.2-.3c-.4-.1-.7-.3-1-.5-.3-.2-.6-.5-.7-.8s-.3-.7-.3-1.1c0-.5.1-.9.3-1.3.2-.4.5-.7.8-.9.3-.3.7-.4 1.2-.6l1.4-.3V5h1zm0 7.4v2.7c.2 0 .4-.1.6-.1l.6-.3c.2-.1.3-.3.4-.4.1-.2.2-.4.2-.6 0-.4-.1-.7-.4-.8-.4-.2-.8-.4-1.4-.5zm-1-4.6c-.2 0-.4 0-.5.1-.2 0-.3.1-.5.2l-.3.3c-.1.2-.1.4-.1.6 0 .3.1.6.3.7.2.2.6.3 1.1.4V7.8z" fill-rule="evenodd" clip-rule="evenodd" fill="#3b86ff"/></svg>', ], [ 'id' => 'testing-debugging', - 'text' => 'I’m Testing or Debugging', - 'placeholder' => 'If you’re temporarily deactivating, please let us know if we can help you in any way.', + 'text' => __( 'I’m Testing or Debugging', 'storegrowth-sales-booster' ), + 'placeholder' => __( 'If you’re temporarily deactivating, please let us know if we can help you in any way.', 'storegrowth-sales-booster' ), 'icon' => '<svg height="23" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 23 23"><path d="M21 17.4c-.1-1.7-1.4-3-3-3.1v-1.2h-.3v1.2c-1.6.1-2.9 1.4-3 3.1h-1.2v.4h1.2c.1 1.7 1.4 3 3 3.1v1.2h.3v-1.2c1.6-.1 2.9-1.4 3-3.1h1.5v-.4H21zm-3.4 3.1c-1.4-.1-2.6-1.3-2.7-2.7h2.7v2.7zm0-3.1h-2.7c.1-1.5 1.2-2.6 2.7-2.7v2.7zm.4 3.1v-2.7h2.7c-.2 1.4-1.3 2.6-2.7 2.7zm0-3.1v-2.7c1.4.1 2.6 1.3 2.7 2.7H18zM16.2 4.9c0-.3.1-.5.4-.6.1 0 2.8-.5 3-2.9 0-.3.2-.5.5-.5s.5.3.4.5c-.2 3.1-3.7 3.8-3.8 3.8h-.1c-.1.1-.3-.1-.4-.3zM1.8 1.5c0-.2.2-.5.4-.5.3 0 .5.2.5.5.2 2.4 2.9 2.8 3 2.9.3 0 .4.3.4.6 0 .2-.2.4-.5.4h-.1c-.1-.1-3.5-.7-3.7-3.9zM18.4 9c.1 0 3.4.2 4 2.8 0 .1 0 .3-.1.4-.1.1-.2.2-.3.2h-.1c-.2 0-.4-.2-.5-.4-.5-1.9-3.1-2.1-3.2-2.1-.1 0-.2-.1-.3-.2-.1-.1-.1-.2-.1-.4.1-.1.3-.3.6-.3zM4.1 10s-2.7.2-3.2 2.1c-.1.2-.2.4-.5.4H.3c-.1 0-.2-.1-.3-.2v-.5C.7 9.2 3.9 9 4.1 9c.3 0 .5.2.5.5 0 .2-.2.5-.5.5zM9 2.6v-.3C8.9 1 10 0 11.2 0c1.2 0 2.3 1 2.3 2.3v.3c1.4.6 2.5 1.8 3.3 3.3V6l-.2.1c-1.5.8-3.1 1.2-4.9 1.2-2.5 0-4.7-.9-5.8-1.4l-.2-.1.1-.2c.7-1.4 1.9-2.4 3.2-3zM6.5 16.7c.1.3-.1.5-.3.6 0 0-2.6.7-2.9 3 0 .2-.2.4-.5.4h-.1c-.3 0-.4-.3-.4-.6.4-3 3.5-3.8 3.6-3.8H6c.2 0 .4.2.5.4zm11.3-4.3h-.2c.1-.7.2-1.4.2-2.1 0-1.3-.2-2.5-.7-3.7l-.1-.2-.2.1c-1.2.6-3.2 1-4.6 1.1h-.1v.1c-.4 1.5-.6 3.4-.8 5.2-.2-2.8-.5-5.1-.5-5.2v-.2C8.2 7.3 6 6.4 5.7 6.3l-.2-.1-.1.2c-.5 1.2-.8 2.5-.8 3.9 0 4.5 3 8.2 6.6 8.2.5 0 1-.1 1.4-.2a5.21 5.21 0 0010.4-.6c0-2.9-2.3-5.3-5.2-5.3z" fill-rule="evenodd" clip-rule="evenodd" fill="#3b86ff"/></svg>', ], // ...apply the same __(...) wrapping for all remaining 'text' and 'placeholder' fields... - ]; + ] );Please confirm Appsero escapes these fields with wp_kses before output. If not, we should sanitize here.
31-56: Consent and privacy notice check (GDPR/CCPA).Confirm the integration shows explicit opt‑in and updates your privacy policy. If not, enable Appsero’s consent notice and add a settings toggle to opt‑out.
includes/Bootstrap.php (1)
29-36: Instantiate Tracker only in admin.Telemetry/deactivation UI are admin concerns; avoid front-end cost.
- public ?Tracker $tracker = null; + public ?Tracker $tracker = null; @@ - private function __construct() { - $this->tracker = new Tracker(); + private function __construct() { + if ( is_admin() ) { + $this->tracker = new Tracker(); + } add_action( 'woocommerce_loaded', [ $this, 'on_wc_loaded' ] ); add_action( 'admin_notices', [ $this, 'show_notice_if_wc_is_not_active' ] ); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
composer.lockis excluded by!**/*.lock
📒 Files selected for processing (4)
composer.json(1 hunks)includes/Bootstrap.php(1 hunks)includes/Tracker.php(1 hunks)storegrowth-sales-booster.php(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
includes/Tracker.php (2)
includes/Bootstrap.php (2)
__construct(34-38)has_pro(188-190)storegrowth-sales-booster.php (1)
sp_store_growth(118-120)
includes/Bootstrap.php (1)
includes/Tracker.php (2)
Tracker(12-123)__construct(27-29)
🔇 Additional comments (2)
includes/Tracker.php (1)
73-76: Slug comparison verified—no issue found.The code at lines 73–76 is correct.
STOREGROWTH_FILEis defined as the plugin's main file (storegrowth-sales-booster.php), and Appsero derives$client->slugfrom the plugin basename of that file, which is'storegrowth-sales-booster'. The comparison will match and the deactivation reasons filter will execute as intended.composer.json (1)
3-7: No action required—code already handles Appsero single-argument filter correctly.The code registers the filter with 2-arg capacity, but the method signature makes
$clientoptional with default null, and checks if it's null before using it. The implementation includes a comment explicitly addressing this: "return if old version of appsero client is loaded, where corresponding hooks provides only one argument". This defensive pattern already ensures compatibility with Appsero v2.x's single-argument filter—no verification or fix needed.The side note about
"minimum-stability": "dev"is accurate; switching to"stable"is a reasonable optional improvement to avoid pre-releases, but this is not critical.Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
includes/Tracker.php (1)
80-119: Wrap user-facing deactivation strings with translation functions.All text and placeholder strings in the deactivation reasons (lines 81–118) are hardcoded without translation function wrappers, making this flow non-localizable. Use
__()for simple text oresc_html__()where appropriate for WordPress localization support.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@includes/Tracker.php` around lines 80 - 119, The deactivation-reasons array in includes/Tracker.php contains hardcoded user-facing strings (e.g. entries with ids like 'storegrowth-sales-booster-pro-is-expensive', 'testing-debugging', 'dont-need-anymore') — wrap all 'text' and 'placeholder' values with proper i18n functions: use esc_html__() (or __() if raw HTML is intentionally allowed) for visible text and esc_attr__() for attribute/placeholders, passing the plugin text-domain (or the existing TEXT_DOMAIN constant) as the second arg; update every array element that contains a literal string accordingly so these strings are localizable.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@composer.json`:
- Around line 26-31: The Appsero packages are required at runtime
(includes/Tracker.php instantiates Appsero\Client) but are currently in
"require-dev"; move "appsero/client" and "appsero/updater" from require-dev into
the top-level "require" in composer.json so they are installed in production,
and also fix the post-install/post-update script condition that currently reads
'[ $COMPOSER_DEV_MODE -eq 0 ] || "vendor/bin/mozart" compose' so Mozart runs
during production installs (either remove the conditional or invert it) to
ensure vendor/bin/mozart compose executes when --no-dev is used.
---
Nitpick comments:
In `@includes/Tracker.php`:
- Around line 80-119: The deactivation-reasons array in includes/Tracker.php
contains hardcoded user-facing strings (e.g. entries with ids like
'storegrowth-sales-booster-pro-is-expensive', 'testing-debugging',
'dont-need-anymore') — wrap all 'text' and 'placeholder' values with proper i18n
functions: use esc_html__() (or __() if raw HTML is intentionally allowed) for
visible text and esc_attr__() for attribute/placeholders, passing the plugin
text-domain (or the existing TEXT_DOMAIN constant) as the second arg; update
every array element that contains a literal string accordingly so these strings
are localizable.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
composer.jsonincludes/Tracker.phpstoregrowth-sales-booster.php
🚧 Files skipped from review as they are similar to previous changes (1)
- storegrowth-sales-booster.php
Introduced Appsero client and updater dependencies for tracking and insights. Added a new Tracker class to handle plugin analytics and custom deactivation reasons. Updated Bootstrap to initialize Tracker and defined STOREGROWTH_VERSION constant in main plugin file.
Summary by CodeRabbit
New Features
Requirements
Chores