Skip to content

Add a license page and connector activating a free license to myDot - #1311

Closed
pattonwebz wants to merge 3 commits into
developfrom
william/pro-285-move-a-minimal-safe-portion-of-the-license-handler-into-the
Closed

Add a license page and connector activating a free license to myDot#1311
pattonwebz wants to merge 3 commits into
developfrom
william/pro-285-move-a-minimal-safe-portion-of-the-license-handler-into-the

Conversation

@pattonwebz

@pattonwebz pattonwebz commented Dec 19, 2025

Copy link
Copy Markdown
Member

This adds a page to enter a license key in the free plugin, enabling connection to our myDot site for additional services not offered in the plugin.

It contains no update logic, and no code is sent from the service for execution. This verifies that a license key exists in our service, nothing in the plugin is gated behind it, and users are not required to fill it in unless they want to make use of the services from the myDot site.

Easily accessible terms will be added before this is released that show what is sent and why.

Checklist

  • PR is linked to the main issue in the repo
  • Tests are added that cover changes

Summary by CodeRabbit

  • New Features
    • Added a new License settings tab in the admin area with activation and deactivation capabilities.
    • Displays current license status with detailed error messages and automatic periodic license validation.

✏️ Tip: You can customize this high-level summary in your review settings.

Copilot AI review requested due to automatic review settings December 19, 2025 20:16
@coderabbitai

coderabbitai Bot commented Dec 19, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

A new license management system is introduced, consisting of a LicensePage admin UI class and a Connector class for MyDot API integration. The system handles license activation, deactivation, periodic verification, settings registration, and error handling with WordPress hooks and settings APIs.

Changes

Cohort / File(s) Summary
License Admin UI
admin/AdminPage/LicensePage.php
New class implementing PageInterface to manage the license settings tab in WordPress admin. Includes license form rendering with key input, status display, activate/deactivate actions, nonce protection, and admin notices for license errors with localized messages mapped to error codes.
License API Integration
includes/classes/MyDot/Connector.php
New class providing MyDot API integration for license management. Handles activation/deactivation API calls, periodic license verification via cron, settings registration with sanitization, admin-post form submission handling, and error management using WordPress options and HTTP APIs.
Plugin Bootstrap
includes/classes/class-plugin.php
Added Connector import and initialization in Plugin constructor to wire up license management during plugin setup.

Sequence Diagram

sequenceDiagram
    participant Admin as Admin User
    participant UI as LicensePage
    participant Handler as Connector<br/>(handle_license_post)
    participant API as MyDot API
    participant Store as WordPress<br/>Options
    participant Notice as Admin<br/>Notices
    
    Admin->>UI: Submit license form (activate/deactivate)
    UI->>Handler: POST via admin-post hook with nonce
    Handler->>Handler: Verify nonce & permissions
    Handler->>Handler: Normalize license key
    
    alt Activate License
        Handler->>API: POST activation request with key, site, product ID
        API-->>Handler: Response (valid/error with code)
        alt Success
            Handler->>Store: Save license_status = active
            Handler->>Store: Clear license_error
        else Error
            Handler->>Store: Save license_status
            Handler->>Store: Save license_error (error code)
        end
    else Deactivate License
        Handler->>API: POST deactivate request
        API-->>Handler: Response
        Handler->>Store: Clear license key, status, error
    end
    
    Handler-->>Admin: Redirect with status parameter
    UI->>Store: Read license status/error on page load
    UI->>Notice: Render admin notice with localized error message
    Notice-->>Admin: Display status or error message
    
    Note over Handler,API: Cron also calls periodic_check_license() daily<br/>to verify stored license remains valid
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Areas requiring extra attention:

  • API endpoint validation and security: Verify the MyDot API endpoint (http://my.equalizedigital.local) is correct for production and that SSL verification is properly handled via the verify_ssl() filter
  • Nonce handling and permission checks: Ensure nonce validation and capability checks ($settings_capability) are correctly implemented in handle_license_post() to prevent unauthorized access
  • Error code mapping: Review all error codes (expired, disabled, revoked, missing, invalid, site_inactive, item_name_mismatch, no_activations_left) and their corresponding localized messages for completeness and accuracy
  • Cron scheduling logic: Verify that check_license_cron() is only scheduled when EDACP is inactive to avoid duplicate checks
  • License key sanitization: Confirm that license key normalization in handle_license_post() is robust and matches API expectations

Poem

🐰 A license to thrive, now alive in the code,
With MyDot connections and settings galore,
Activate, deactivate, check every day,
The Accessibility Checker is here to stay! ✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: introducing a license page UI and a connector class for MyDot license activation.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch william/pro-285-move-a-minimal-safe-portion-of-the-license-handler-into-the

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @pattonwebz, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a comprehensive licensing system for the 'Accessibility Checker Free' plugin. It provides a new administrative page where users can enter and manage a license key, which then connects to the myDot service to unlock additional features and services. The implementation includes robust mechanisms for license activation, deactivation, and periodic validation, ensuring that the core plugin functionality remains free while offering an upgrade path for enhanced capabilities.

Highlights

  • New License Page: A dedicated 'License' page has been added to the WordPress admin settings, allowing users to input and manage their license keys for additional services.
  • myDot Connector Integration: A new Connector class has been implemented to facilitate communication with the myDot licensing service, handling license activation, deactivation, and status checks.
  • License Management: Users can now activate and deactivate their license keys directly from the new settings page, with clear indicators for license status (active, expired) and detailed error messages for various issues.
  • Periodic License Validation: The system includes a daily scheduled cron job to periodically check the validity of the entered license key with the myDot service.
  • Conditional Feature Activation: The new licensing features are only initialized if the premium version of the plugin is not already active, preventing potential conflicts.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new license page and a connector to the myDot service for the free plugin. The changes are well-structured, adding new classes for the UI and API communication. However, my review identified several critical and high-severity issues that must be addressed. These include a hardcoded local development API endpoint, use of an undefined constant which will cause a fatal error, and inconsistent option names that will lead to incorrect behavior. I have also provided suggestions to improve code quality and maintainability.

Comment thread includes/classes/MyDot/Connector.php

// Call the custom API.
$response = wp_remote_post(
EDACP_STORE_URL,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This line uses the constant EDACP_STORE_URL, which is not defined in this context (it's likely from the Pro version). Since this code path is executed when the Pro version is not active, this will result in a fatal error. You should use self::API_ENDPOINT instead.

            self::API_ENDPOINT,

Comment thread admin/AdminPage/LicensePage.php
Comment thread includes/classes/MyDot/Connector.php
Comment thread includes/classes/MyDot/Connector.php
Comment thread admin/AdminPage/LicensePage.php
Comment thread includes/classes/MyDot/Connector.php
Comment thread includes/classes/MyDot/Connector.php
Comment thread includes/classes/MyDot/Connector.php

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (8)
admin/AdminPage/LicensePage.php (3)

1-24: Update version placeholders before release.

The @since 1.xx.x placeholders throughout the file should be replaced with the actual version number (likely 1.34.0 based on the package-level docblock).


54-73: Consider scoping admin notices to the license settings page.

The register_admin_notices() method (line 116-117) registers admin_notices globally on all admin pages. License error notices should ideally only display on the license settings page to avoid cluttering unrelated admin screens.

🔎 Proposed fix to scope notices to the license page
 public function register_admin_notices() {
-	add_action( 'admin_notices', [ $this, 'admin_notices' ] );
+	$screen = get_current_screen();
+	if ( $screen && 'accessibility_checker_settings' === $screen->id ) {
+		add_action( 'admin_notices', [ $this, 'admin_notices' ] );
+	}
 }

127-185: Replace inline styles with CSS classes.

Lines 150 and 152 use inline style="color:green;" and style="color:red;" attributes. Per WordPress best practices, use CSS classes instead for better maintainability and accessibility.

🔎 Proposed fix using CSS classes
 						<label class="description" for="edac_license_key">
 							<?php if ( false !== $status && 'valid' === $status ) : ?>
-								<span style="color:green;"> <?php esc_html_e( 'active', 'accessibility-checker' ); ?></span>
+								<span class="edac-license-status-active"> <?php esc_html_e( 'active', 'accessibility-checker' ); ?></span>
 							<?php elseif ( false !== $status && 'expired' === $status ) : ?>
-								<span style="color:red;"> <?php esc_html_e( 'expired', 'accessibility-checker' ); ?></span>
+								<span class="edac-license-status-expired"> <?php esc_html_e( 'expired', 'accessibility-checker' ); ?></span>
 							<?php else : ?>
 								<?php esc_html_e( 'Enter your license key', 'accessibility-checker' ); ?>
 							<?php endif; ?>

Then add corresponding CSS rules in your admin stylesheet.

includes/classes/MyDot/Connector.php (5)

151-193: Consider adding license key format validation.

The activate_license() method sanitizes the license key but doesn't validate its format. Consider adding validation to provide early feedback if the key format is obviously invalid (e.g., too short, contains invalid characters).


183-193: Handle potential JSON decode errors.

Lines 183 and 228 use json_decode() without checking for decode errors. If the API returns malformed JSON, $license_data could be null, causing potential notices when accessing properties.

🔎 Proposed fix with error checking
 	$license_data = json_decode( wp_remote_retrieve_body( $response ) );
+
+	if ( null === $license_data ) {
+		update_option( 'edac_license_error', 'invalid_response' );
+		return;
+	}
 
 	if ( isset( $license_data->error ) ) {

Apply similar logic to deactivate_license() at line 228.


242-281: Add error handling for periodic license check.

The periodic_check_license() method has a comment about "silent failure" (line 272) but doesn't log errors or provide any observability. Consider adding error logging for debugging and monitoring.


303-305: Document the SSL verification filter.

The verify_ssl() method references filter edac_verify_ssl_for_licensing but there's no PHPDoc describing when developers might want to use this filter. Consider adding documentation about use cases (e.g., local development, SSL certificate issues).


1-306: Update version placeholders before release.

All @since 1.xx.x placeholders should be replaced with the actual version number (likely 1.34.0 based on the PR context).

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 35faecf and 5fec71e.

📒 Files selected for processing (3)
  • admin/AdminPage/LicensePage.php (1 hunks)
  • includes/classes/MyDot/Connector.php (1 hunks)
  • includes/classes/class-plugin.php (2 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.php

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.php: Follow WordPress Coding Standards (WPCS) in all PHP files
Class names use CamelCase (ClassNameConvention) for new classes
Use edac_ prefix for all custom action/filter hook names
Ensure PHP 7.4+ compatibility
Use type hints where appropriate (parameters, return types, properties)
Sanitize inputs, validate data, and escape outputs following WordPress security best practices; use nonces for forms/AJAX
Use the WordPress database API ($wpdb) for all database operations
Prefix functions and classes in the global namespace with edac_
Use WordPress transients for caching temporary data where appropriate
All user-facing text in PHP must be translatable using the accessibility-checker text domain
Use PHPDoc for all public classes, methods, and properties
Document all custom hooks (actions/filters) with docblocks including parameters and types

Files:

  • includes/classes/MyDot/Connector.php
  • admin/AdminPage/LicensePage.php
  • includes/classes/class-plugin.php
includes/**/*.php

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Place core (non-admin) functionality in the /includes directory

Files:

  • includes/classes/MyDot/Connector.php
  • includes/classes/class-plugin.php
{admin,includes}/**/[A-Z][A-Za-z0-9]*.php

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

New PHP class files must use CamelCase file names like ClassName.php

Files:

  • includes/classes/MyDot/Connector.php
  • admin/AdminPage/LicensePage.php
admin/**/*.php

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Place admin classes and admin-only PHP code in the /admin directory

Files:

  • admin/AdminPage/LicensePage.php
**/class-*.php

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/class-*.php: Legacy PHP class files must use WordPress style naming class-class-name.php
Legacy class names use WordPress underscore style (Class_Name_Convention)

Files:

  • includes/classes/class-plugin.php
🧠 Learnings (2)
📚 Learning: 2025-08-27T14:11:05.736Z
Learnt from: pattonwebz
Repo: equalizedigital/accessibility-checker PR: 1171
File: includes/helper-functions.php:808-826
Timestamp: 2025-08-27T14:11:05.736Z
Learning: In the Accessibility Checker Pro plugin, the class '\EqualizeDigital\AccessibilityCheckerPro\VirtualContent\PostType\VirtualPageType' was never released, so backward compatibility checks for this class name are not needed in edac_is_virtual_page() function.

Applied to files:

  • admin/AdminPage/LicensePage.php
  • includes/classes/class-plugin.php
📚 Learning: 2025-08-29T11:15:35.151Z
Learnt from: CR
Repo: equalizedigital/accessibility-checker PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-29T11:15:35.151Z
Learning: Applies to composer.json : Use PSR-4 autoloading with the EqualizeDigital\AccessibilityChecker namespace

Applied to files:

  • includes/classes/class-plugin.php
🧬 Code graph analysis (2)
includes/classes/MyDot/Connector.php (2)
admin/class-admin.php (1)
  • Admin (20-114)
admin/AdminPage/LicensePage.php (3)
  • LicensePage (24-278)
  • add_page (54-73)
  • get_error_message (221-277)
admin/AdminPage/LicensePage.php (1)
includes/classes/MyDot/Connector.php (1)
  • Connector (20-306)
🪛 PHPStan (2.1.33)
includes/classes/MyDot/Connector.php

264-264: Constant EDACP_STORE_URL not found.
Learn more at https://phpstan.org/user-guide/discovering-symbols

(constant.notFound)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Agent
🔇 Additional comments (5)
admin/AdminPage/LicensePage.php (2)

194-209: Verify the admin notice display logic.

The admin_notices() method retrieves and displays license errors on every admin page load. Consider:

  1. Clearing the error option after displaying it once (transient pattern)
  2. Only showing errors on relevant pages
  3. Adding a dismissible notice option for better UX

221-277: Good error handling with comprehensive error messages.

The get_error_message() method provides clear, user-friendly messages for all license error states with proper localization and contextual links.

includes/classes/class-plugin.php (2)

13-13: Import added correctly.

The Connector class is properly imported using the correct namespace.


47-48: Connector initialization looks correct.

The Connector is instantiated and initialized at an appropriate point in the plugin lifecycle, after the fixes manager registration.

includes/classes/MyDot/Connector.php (1)

117-142: Good security practices in form handler.

The handle_license_post() method properly implements:

  • Capability checks (manage_options)
  • Nonce verification
  • Input sanitization
  • Safe redirects

Comment thread includes/classes/MyDot/Connector.php
Comment thread includes/classes/MyDot/Connector.php
Comment thread includes/classes/MyDot/Connector.php

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds MyDot license integration to the free Accessibility Checker plugin, enabling users to optionally connect to myDot services via a license key. The implementation includes a new license settings page in the WordPress admin and API connector for license validation.

Key changes:

  • New MyDot Connector class to handle license activation, deactivation, and periodic validation via API
  • New License settings page in the admin area with form handling and error notices
  • Integration of the connector into the plugin's initialization flow

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 15 comments.

File Description
includes/classes/class-plugin.php Initializes the new MyDot Connector during plugin bootstrap
includes/classes/MyDot/Connector.php Implements license API communication, activation/deactivation logic, and scheduled license validation
admin/AdminPage/LicensePage.php Provides the admin UI for license key entry, status display, and error notifications

Comment thread includes/classes/MyDot/Connector.php
Comment thread admin/AdminPage/LicensePage.php
Comment thread admin/AdminPage/LicensePage.php
Comment thread includes/classes/MyDot/Connector.php
Comment thread includes/classes/MyDot/Connector.php
Comment thread admin/AdminPage/LicensePage.php
Comment thread includes/classes/MyDot/Connector.php
Comment thread includes/classes/MyDot/Connector.php
Comment thread includes/classes/MyDot/Connector.php
Comment thread includes/classes/MyDot/Connector.php
@pattonwebz

Copy link
Copy Markdown
Member Author

The code for this PR formed the basis of what was needed for #1315. All the code from here is in that PR and it makes sense to deal with the AI review comments over there (most of which were already tackled on the more recent PR).

@pattonwebz pattonwebz closed this Jan 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants