Conversation
Introduces Helper.php with methods for sanitizing content using wp_kses and retrieving plugin settings. Provides a centralized array of allowed HTML elements and attributes for safe output, and a utility for accessing plugin options.
Refines namespace mapping to ensure trailing backslash, adds checks for PAGEFLASH_DIR definition, and restricts autoloading to the PageFlash namespace. Improves error logging for missing classes in development and clarifies function documentation.
Introduces a new Support section to the admin dashboard, including documentation, contact, and FAQ cards. Adds a responsive skeleton loader for improved loading experience, with new DashboardContent and DashboardLoader components. Updates FormField, Select, and Switch to support optional external link icons. Refactors routing and menu handling in AdminDashboard and Header for better route awareness. Includes new SCSS for skeleton and support styling.
Revised the changelog with new feature highlights and enhancements. Added 'react-content-loader' version 7.1.2 to project dependencies for improved UI loading states.
Replaces the textdomain loading hook with a new pageflash_init function that loads the textdomain and fires a pageflash_init action. This change improves plugin initialization extensibility and aligns with best practices.
Added IcoMoon font files (eot, svg, ttf, woff) to assets for icon support. Introduced a disabled heartbeat.js stub to prevent heartbeat functionality.
Added initial developer docs for documentation writing, dynamic feature instantiation, and the feature management system in dev-docs/. Added user-facing documentation in docs/ for Quicklink and Instant.page, including a main README. These documents describe usage, customization, and technical architecture for both developers and end users.
Replaces the admin menu icon constant with a string identifier and updates the admin icon CSS to use a custom font icon. Removes frontend asset loading and related methods from AssetsManager, focusing asset management on the admin area.
Introduces Boot.php for centralized feature registration and BootManager.php as an abstract base class for feature managers, including feature instantiation, dependency validation, and settings integration. These classes provide a foundation for managing PageFlash features with support for namespaces, premium checks, and extensibility.
Changed the namespace and @Package annotation from PageFlash\Landmark\General to TheAminul\PageFlash\Landmark\General in DisableDashicons.php for consistency with project naming.
Changed the namespace and package to TheAminul\PageFlash\Landmark\General. Added removal of 'pre_oembed_result' filter and disabled oEmbed discovery to further improve performance.
Updated the namespace and package to TheAminul\PageFlash\Landmark\General. The DisableRestAPI class now accepts a restriction mode, supports two modes ('disabled' and 'disabled_when_logged_out'), and introduces an exception mechanism for specific REST routes. Added a filter for customizing exception routes and improved error handling for unauthorized access.
Changed the namespace and package to TheAminul\PageFlash\Landmark\General. Added a filter for 'pre_option_enable_xmlrpc' to further ensure XML-RPC is disabled.
Replaces the previous feature instantiation logic with a static registration method using Boot::register for all general features. Updates namespace and class inheritance to align with the new architecture, and adds a can_load_feature method for conditional feature loading. Removes direct feature management methods and streamlines page builder detection.
Changed the namespace and @Package annotation from PageFlash\Landmark\General to TheAminul\PageFlash\Landmark\General in HideWPVersion.php for consistency with project structure.
Changed the namespace and @Package annotation from PageFlash\Landmark\General to TheAminul\PageFlash\Landmark\General in RemoveJQueryMigrate.php for consistency with project structure.
Introduces RemoveRestAPILink class to remove REST API links from WordPress headers and frontend output. This helps improve security and reduce unnecessary exposure of REST API endpoints.
Refactored the Landmark class to introduce a feature registration and instance management system, improving extensibility and maintainability. Updated LandmarkList to add new general options for REST API, XML-RPC, WordPress version hiding, and jQuery Migrate, enhancing security and performance configuration capabilities.
Introduces the InstantPage feature for prefetching links using instant.page, including script registration, enqueueing, and module loading. Refactors NoReload to use BootManager and Boot for feature registration, and enhances Quicklink integration by registering scripts earlier, handling dependencies, and improving script loading for better frontend performance.
There was a problem hiding this comment.
Pull request overview
This pull request introduces a comprehensive license management and feature refactoring system for the PageFlash WordPress plugin. The PR implements a new architecture for managing features dynamically, adds several new optimization features (InstantPage, various WordPress performance tweaks), introduces a Support page UI component, and includes extensive documentation.
Changes:
- Implements a new Boot/BootManager architecture for centralized feature registration and dynamic loading
- Adds InstantPage integration alongside existing Quicklink functionality
- Introduces multiple WordPress optimization features (disable emojis, embeds, dashicons, heartbeat, XML-RPC, REST API controls, etc.)
- Adds admin dashboard skeleton loader and Support page component
- Refactors autoloader for better namespace handling
- Adds comprehensive developer documentation for the feature management system
- Replaces icon handling with icon font instead of SVG constant
Reviewed changes
Copilot reviewed 46 out of 51 changed files in this pull request and generated 19 comments.
Show a summary per file
| File | Description |
|---|---|
| src/admin/index.jsx | Adds StrictMode wrapper and improved initialization with error handling |
| src/admin/components/support/Support.jsx | New Support page component with documentation and FAQ links |
| src/admin/DashboardLoader.jsx | New skeleton loader component for improved UX during loading |
| src/admin/DashboardContent.jsx | Wrapper component for conditional dashboard rendering |
| src/admin/AdminDashboard.jsx | Updates routing to use new Support component and fixes route configuration |
| src/scss/admin/_support.scss | Styling for Support page component |
| src/scss/admin/_skeleton.scss | Comprehensive skeleton loader styles with responsive design |
| includes/Landmark/Boot.php | New centralized feature registration system |
| includes/Landmark/BootManager.php | Abstract base class for feature managers with dynamic instantiation |
| includes/Landmark/Landmark.php | Refactored to use new Boot architecture |
| includes/Landmark/General/*.php | Multiple new WordPress optimization feature implementations |
| includes/Landmark/NoReload/Quicklink.php | Moved from AssetsManager to NoReload namespace |
| includes/Landmark/NoReload/InstantPage.php | New InstantPage integration |
| includes/AssetsManager/AssetsManager.php | Removed Quicklink enqueuing, added icon font support |
| autoload.php | Improved autoloader with better namespace handling |
| pageflash.php | Updated initialization hook and removed PAGEFLASH_ICON constant |
| docs/*.md | Comprehensive user documentation for Quicklink and InstantPage |
| dev-docs/*.md | Extensive developer documentation for new architecture |
| // Check OAuth license for Pro/Agency features (real-time validation) | ||
|
|
||
| // if ( ! LicenseManager::can_use_feature( $config['package'] ) ) { | ||
| // continue; // Skip premium features without valid license | ||
| // } | ||
|
|
There was a problem hiding this comment.
Commented-out license validation code should be removed or implemented. Lines 77-79 contain commented-out license validation logic that appears to be part of the feature's core functionality based on the PR title "Feature/license management". Either implement this properly with the LicenseManager class or remove it if it's not ready. Leaving commented code suggests incomplete implementation.
| // Check OAuth license for Pro/Agency features (real-time validation) | |
| // if ( ! LicenseManager::can_use_feature( $config['package'] ) ) { | |
| // continue; // Skip premium features without valid license | |
| // } |
| define( 'PAGEFLASH_ICON', PAGEFLASH_URL . 'assets/logo/icon.svg' ); | ||
|
|
||
| add_action( 'plugins_loaded', 'pageflash_load_plugin_textdomain' ); | ||
| add_action( 'plugins_loaded', 'pageflash_init' ); |
There was a problem hiding this comment.
Removed constant PAGEFLASH_ICON without verifying all references are updated. The constant definition was removed from line 41, but you should verify that no other files in the codebase reference this constant. Based on the AdminMenu.php change replacing it with 'icon-pageflash', this appears to be handled, but comprehensive verification is recommended.
| // target="_blank" | ||
| rel="noopener noreferrer" | ||
| > | ||
| { __( 'Documentation', 'pageflash' ) } | ||
| </Button> | ||
| </CardBody> | ||
| </Card> | ||
|
|
||
| { /* Contact Us Section */ } | ||
| <Card> | ||
| <CardHeader> | ||
| <h2>{ __( 'Contact Us', 'pageflash' ) }</h2> | ||
| </CardHeader> | ||
| <CardBody> | ||
| <p> | ||
| { __( | ||
| "If you have questions or problems, please send us a message. We'll get back to you as soon as possible.", | ||
| 'pageflash' | ||
| ) } | ||
| </p> | ||
| <Button | ||
| variant="secondary" | ||
| icon={ <LiaExternalLinkAltSolid /> } | ||
| iconPosition="right" | ||
| href="#" | ||
| // target="_blank" |
There was a problem hiding this comment.
Commented-out code should be removed. Lines 39 and 64 contain commented-out target="_blank" attributes. If these are intentional placeholders for future functionality, add a TODO comment explaining why. Otherwise, remove them to keep the code clean.
| * Remove REST API links from header and response | ||
| */ | ||
| public function remove_rest_api_links() { | ||
| error_log( 'Removing REST API links' ); |
There was a problem hiding this comment.
Debug error_log statement left in production code. This debugging line should be removed before merging to production. According to WordPress and custom coding guidelines, debug logging should only occur in development mode with proper conditionals.
| error_log( 'Removing REST API links' ); |
| // Exception pages | ||
| if ( 'admin.php' === $pagenow && ! empty( $_GET['page'] ) ) { | ||
| $exceptions = array( | ||
| 'gf_edit_forms', | ||
| 'gf_entries', | ||
| 'gf_settings', | ||
| ); | ||
| if ( in_array( $_GET['page'], $exceptions, true ) ) { | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| // Site Health check |
There was a problem hiding this comment.
Missing nonce verification for $_GET parameters. The code accesses $_GET['page'] without verifying a nonce. While this is checking for exception pages, the access to $_GET should include a nonce verification comment explaining why it's safe, or use proper WordPress nonce verification. The phpcs:ignore comment doesn't address the security concern.
| // Exception pages | |
| if ( 'admin.php' === $pagenow && ! empty( $_GET['page'] ) ) { | |
| $exceptions = array( | |
| 'gf_edit_forms', | |
| 'gf_entries', | |
| 'gf_settings', | |
| ); | |
| if ( in_array( $_GET['page'], $exceptions, true ) ) { | |
| return; | |
| } | |
| } | |
| // Site Health check | |
| // Exception pages. | |
| if ( 'admin.php' === $pagenow && ! empty( $_GET['page'] ) ) { | |
| // Nonce verification is not required here because we only perform | |
| // a read-only comparison to decide whether to keep the default | |
| // Heartbeat behavior on specific admin screens, and no state | |
| // changes or privileged actions depend on this value. | |
| $page = sanitize_key( wp_unslash( $_GET['page'] ) ); | |
| $exceptions = array( | |
| 'gf_edit_forms', | |
| 'gf_entries', | |
| 'gf_settings', | |
| ); | |
| if ( in_array( $page, $exceptions, true ) ) { | |
| return; | |
| } | |
| } | |
| // Site Health check. |
| useEffect( () => { | ||
| const path = location.pathname.replace( '/', '' ) || menus[ 0 ]?.slug; | ||
| if ( path && path !== activeMenu ) { | ||
| dispatch( setActiveMenu( path ) ); | ||
| } | ||
| }, [ location, menus, activeMenu ] ); |
There was a problem hiding this comment.
Missing dependency in useEffect hook. The dispatch and setActiveMenu should be included in the dependency array to follow React's exhaustive-deps rule. According to React best practices and the custom coding guidelines requiring modern JavaScript standards, all variables used inside useEffect should be in the dependency array unless there's a specific reason to omit them.
| href="#" | ||
| // target="_blank" | ||
| rel="noopener noreferrer" | ||
| > | ||
| { __( 'Documentation', 'pageflash' ) } | ||
| </Button> | ||
| </CardBody> | ||
| </Card> | ||
|
|
||
| { /* Contact Us Section */ } | ||
| <Card> | ||
| <CardHeader> | ||
| <h2>{ __( 'Contact Us', 'pageflash' ) }</h2> | ||
| </CardHeader> | ||
| <CardBody> | ||
| <p> | ||
| { __( | ||
| "If you have questions or problems, please send us a message. We'll get back to you as soon as possible.", | ||
| 'pageflash' | ||
| ) } | ||
| </p> | ||
| <Button | ||
| variant="secondary" | ||
| icon={ <LiaExternalLinkAltSolid /> } | ||
| iconPosition="right" | ||
| href="#" | ||
| // target="_blank" | ||
| rel="noopener noreferrer" | ||
| > | ||
| { __( 'Contact Us', 'pageflash' ) } | ||
| </Button> | ||
| </CardBody> | ||
| </Card> | ||
|
|
||
| { /* FAQ Section */ } | ||
| <Card> | ||
| <CardHeader> | ||
| <h2>{ __( 'Frequently Asked Questions', 'pageflash' ) }</h2> | ||
| </CardHeader> | ||
| <CardBody> | ||
| <Flex gap={ 4 } wrap={ true }> | ||
| <FlexBlock> | ||
| <div className="pageflash-support-faq-column"> | ||
| <Button | ||
| variant="link" | ||
| href="#" | ||
| // target="_blank" | ||
| rel="noopener noreferrer" | ||
| > | ||
| { __( | ||
| 'How do I license activate the plugin?', | ||
| 'pageflash' | ||
| ) } | ||
| </Button> | ||
| <Button | ||
| variant="link" | ||
| href="#" | ||
| // target="_blank" | ||
| rel="noopener noreferrer" | ||
| > | ||
| { __( | ||
| 'How do I update the plugin?', | ||
| 'pageflash' | ||
| ) } | ||
| </Button> | ||
| <Button | ||
| variant="link" | ||
| href="#" | ||
| // target="_blank" | ||
| rel="noopener noreferrer" | ||
| > | ||
| { __( | ||
| 'How do I upgrade my license?', | ||
| 'pageflash' | ||
| ) } | ||
| </Button> | ||
| <Button | ||
| variant="link" | ||
| href="#" | ||
| // target="_blank" | ||
| rel="noopener noreferrer" | ||
| > | ||
| { __( | ||
| 'Where can I view the changelog?', | ||
| 'pageflash' | ||
| ) } | ||
| </Button> | ||
| <Button | ||
| variant="link" | ||
| href="#" | ||
| // target="_blank" | ||
| rel="noopener noreferrer" | ||
| > | ||
| { __( | ||
| 'Where can I sign up for the affiliate program?', | ||
| 'pageflash' | ||
| ) } | ||
| </Button> | ||
| </div> | ||
| </FlexBlock> | ||
| <FlexBlock> | ||
| <div className="pageflash-support-faq-column"> | ||
| <Button | ||
| variant="link" | ||
| href="#" | ||
| // target="_blank" | ||
| rel="noopener noreferrer" | ||
| > | ||
| { __( | ||
| 'How do I disable scripts on a per post/page basis?', | ||
| 'pageflash' | ||
| ) } | ||
| </Button> | ||
| <Button | ||
| variant="link" | ||
| href="#" | ||
| // target="_blank" | ||
| rel="noopener noreferrer" | ||
| > | ||
| { __( | ||
| 'How do I delay JavaScript?', | ||
| 'pageflash' | ||
| ) } | ||
| </Button> | ||
| <Button | ||
| variant="link" | ||
| href="#" | ||
| // target="_blank" | ||
| rel="noopener noreferrer" | ||
| > | ||
| { __( | ||
| 'How do I remove unused CSS?', | ||
| 'pageflash' | ||
| ) } | ||
| </Button> | ||
| <Button | ||
| variant="link" | ||
| href="#" | ||
| // target="_blank" | ||
| rel="noopener noreferrer" | ||
| > | ||
| { __( | ||
| 'How do I lazy load images and videos?', | ||
| 'pageflash' | ||
| ) } | ||
| </Button> | ||
| <Button | ||
| variant="link" | ||
| href="#" | ||
| // target="_blank" | ||
| rel="noopener noreferrer" | ||
| > | ||
| { __( | ||
| 'How do I host Google Analytics locally?', | ||
| 'pageflash' | ||
| ) } | ||
| </Button> |
There was a problem hiding this comment.
Hardcoded placeholder URLs. All button href attributes are set to "#" which is not functional. These should either be removed until proper URLs are available, or use actual documentation/support URLs. This creates a poor user experience as users will click links that don't work.
| 'child_id' => wp_unique_id( 'pf-' ), | ||
| 'type' => 'select', | ||
| 'label' => esc_html__( 'Behavior', 'pageflash' ), | ||
| 'description' => esc_html__( 'Choose where to disable the Heartbeat API.', 'pageflash' ), | ||
| 'slug' => 'behavior', | ||
| 'value' => 'disable_everywhere', | ||
| 'default' => 'disable_everywhere', | ||
| 'options' => array( | ||
| 'default' => esc_html__( 'Default Behavior', 'pageflash' ), | ||
| 'disable_everywhere' => esc_html__( 'Disable Everywhere', 'pageflash' ), | ||
| 'allow_posts' => esc_html__( 'Only Allow When Editing Posts/Pages', 'pageflash' ), | ||
| 'disable_dashboard' => esc_html__( 'Disable on admin Dashboard Only', 'pageflash' ), | ||
| ), | ||
| ), | ||
| 'frequency' => array( | ||
| 'child_id' => wp_unique_id( 'pf-' ), | ||
| 'type' => 'select', | ||
| 'label' => esc_html__( 'Frequency', 'pageflash' ), | ||
| 'description' => esc_html__( 'Controls how often the WordPress Heartbeat API is allowed to run.', 'pageflash' ), | ||
| 'slug' => 'frequency', |
There was a problem hiding this comment.
Trailing comma missing in child_id additions. Lines 124, 139, and 143 add 'child_id' keys to arrays but don't follow the existing code style which includes trailing commas. For consistency with the rest of the array structure and modern PHP standards, add trailing commas after these additions.
| /** | ||
| * Internal dependencies | ||
| */ | ||
| import { SKELETON_OPTIONS } from './constants'; |
There was a problem hiding this comment.
Unused import SKELETON_OPTIONS.
| /** | ||
| * External dependencies | ||
| */ | ||
| import ContentLoader from 'react-content-loader'; |
There was a problem hiding this comment.
Unused import ContentLoader.
Eliminated an error_log statement from the remove_rest_api_links method to clean up debug output.
Added sanitization for the 'page' parameter in the Heartbeat exception logic to improve security. Nonce verification is not required as the check is read-only and does not affect privileged actions.
No description provided.