diff --git a/assets/js/recommendations/litespeed-cache-browser-cache.js b/assets/js/recommendations/litespeed-cache-browser-cache.js new file mode 100644 index 000000000..55dd1340e --- /dev/null +++ b/assets/js/recommendations/litespeed-cache-browser-cache.js @@ -0,0 +1,32 @@ +/* global prplInteractiveTaskFormListener, progressPlanner */ + +/* + * LiteSpeed Cache: enable browser cache. + * + * Dependencies: progress-planner/recommendations/interactive-task + */ + +prplInteractiveTaskFormListener.customSubmit( { + taskId: 'litespeed-cache-browser-cache', + popoverId: 'prpl-popover-litespeed-cache-browser-cache', + callback: () => { + return new Promise( ( resolve, reject ) => { + fetch( progressPlanner.ajaxUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: new URLSearchParams( { + action: 'prpl_interactive_task_submit_litespeed-cache-browser-cache', + nonce: progressPlanner.nonce, + } ), + } ) + .then( ( response ) => { + resolve( { response, success: true } ); + } ) + .catch( ( error ) => { + reject( { success: false, error } ); + } ); + } ); + }, +} ); diff --git a/assets/js/recommendations/litespeed-cache-css-minification.js b/assets/js/recommendations/litespeed-cache-css-minification.js new file mode 100644 index 000000000..59dc868fa --- /dev/null +++ b/assets/js/recommendations/litespeed-cache-css-minification.js @@ -0,0 +1,32 @@ +/* global prplInteractiveTaskFormListener, progressPlanner */ + +/* + * LiteSpeed Cache: enable CSS minification. + * + * Dependencies: progress-planner/recommendations/interactive-task + */ + +prplInteractiveTaskFormListener.customSubmit( { + taskId: 'litespeed-cache-css-minification', + popoverId: 'prpl-popover-litespeed-cache-css-minification', + callback: () => { + return new Promise( ( resolve, reject ) => { + fetch( progressPlanner.ajaxUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: new URLSearchParams( { + action: 'prpl_interactive_task_submit_litespeed-cache-css-minification', + nonce: progressPlanner.nonce, + } ), + } ) + .then( ( response ) => { + resolve( { response, success: true } ); + } ) + .catch( ( error ) => { + reject( { success: false, error } ); + } ); + } ); + }, +} ); diff --git a/assets/js/recommendations/litespeed-cache-guest-mode.js b/assets/js/recommendations/litespeed-cache-guest-mode.js new file mode 100644 index 000000000..638e16c41 --- /dev/null +++ b/assets/js/recommendations/litespeed-cache-guest-mode.js @@ -0,0 +1,32 @@ +/* global prplInteractiveTaskFormListener, progressPlanner */ + +/* + * LiteSpeed Cache: enable guest mode. + * + * Dependencies: progress-planner/recommendations/interactive-task + */ + +prplInteractiveTaskFormListener.customSubmit( { + taskId: 'litespeed-cache-guest-mode', + popoverId: 'prpl-popover-litespeed-cache-guest-mode', + callback: () => { + return new Promise( ( resolve, reject ) => { + fetch( progressPlanner.ajaxUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: new URLSearchParams( { + action: 'prpl_interactive_task_submit_litespeed-cache-guest-mode', + nonce: progressPlanner.nonce, + } ), + } ) + .then( ( response ) => { + resolve( { response, success: true } ); + } ) + .catch( ( error ) => { + reject( { success: false, error } ); + } ); + } ); + }, +} ); diff --git a/assets/js/recommendations/litespeed-cache-image-lazy-load.js b/assets/js/recommendations/litespeed-cache-image-lazy-load.js new file mode 100644 index 000000000..d91fdbb94 --- /dev/null +++ b/assets/js/recommendations/litespeed-cache-image-lazy-load.js @@ -0,0 +1,32 @@ +/* global prplInteractiveTaskFormListener, progressPlanner */ + +/* + * LiteSpeed Cache: enable image lazy loading. + * + * Dependencies: progress-planner/recommendations/interactive-task + */ + +prplInteractiveTaskFormListener.customSubmit( { + taskId: 'litespeed-cache-image-lazy-load', + popoverId: 'prpl-popover-litespeed-cache-image-lazy-load', + callback: () => { + return new Promise( ( resolve, reject ) => { + fetch( progressPlanner.ajaxUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: new URLSearchParams( { + action: 'prpl_interactive_task_submit_litespeed-cache-image-lazy-load', + nonce: progressPlanner.nonce, + } ), + } ) + .then( ( response ) => { + resolve( { response, success: true } ); + } ) + .catch( ( error ) => { + reject( { success: false, error } ); + } ); + } ); + }, +} ); diff --git a/assets/js/recommendations/litespeed-cache-js-minification.js b/assets/js/recommendations/litespeed-cache-js-minification.js new file mode 100644 index 000000000..50952dae1 --- /dev/null +++ b/assets/js/recommendations/litespeed-cache-js-minification.js @@ -0,0 +1,32 @@ +/* global prplInteractiveTaskFormListener, progressPlanner */ + +/* + * LiteSpeed Cache: enable JS minification. + * + * Dependencies: progress-planner/recommendations/interactive-task + */ + +prplInteractiveTaskFormListener.customSubmit( { + taskId: 'litespeed-cache-js-minification', + popoverId: 'prpl-popover-litespeed-cache-js-minification', + callback: () => { + return new Promise( ( resolve, reject ) => { + fetch( progressPlanner.ajaxUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: new URLSearchParams( { + action: 'prpl_interactive_task_submit_litespeed-cache-js-minification', + nonce: progressPlanner.nonce, + } ), + } ) + .then( ( response ) => { + resolve( { response, success: true } ); + } ) + .catch( ( error ) => { + reject( { success: false, error } ); + } ); + } ); + }, +} ); diff --git a/assets/js/recommendations/litespeed-cache-page-cache.js b/assets/js/recommendations/litespeed-cache-page-cache.js new file mode 100644 index 000000000..da345b1f5 --- /dev/null +++ b/assets/js/recommendations/litespeed-cache-page-cache.js @@ -0,0 +1,32 @@ +/* global prplInteractiveTaskFormListener, progressPlanner */ + +/* + * LiteSpeed Cache: enable page cache. + * + * Dependencies: progress-planner/recommendations/interactive-task + */ + +prplInteractiveTaskFormListener.customSubmit( { + taskId: 'litespeed-cache-page-cache', + popoverId: 'prpl-popover-litespeed-cache-page-cache', + callback: () => { + return new Promise( ( resolve, reject ) => { + fetch( progressPlanner.ajaxUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: new URLSearchParams( { + action: 'prpl_interactive_task_submit_litespeed-cache-page-cache', + nonce: progressPlanner.nonce, + } ), + } ) + .then( ( response ) => { + resolve( { response, success: true } ); + } ) + .catch( ( error ) => { + reject( { success: false, error } ); + } ); + } ); + }, +} ); diff --git a/classes/suggested-tasks/class-tasks-manager.php b/classes/suggested-tasks/class-tasks-manager.php index 64b2aefb5..f0947a0f1 100644 --- a/classes/suggested-tasks/class-tasks-manager.php +++ b/classes/suggested-tasks/class-tasks-manager.php @@ -25,6 +25,7 @@ use Progress_Planner\Suggested_Tasks\Tasks_Interface; use Progress_Planner\Suggested_Tasks\Providers\Integrations\Yoast\Add_Yoast_Providers; use Progress_Planner\Suggested_Tasks\Providers\Integrations\AIOSEO\Add_AIOSEO_Providers; +use Progress_Planner\Suggested_Tasks\Providers\Integrations\Litespeed_Cache\Add_Litespeed_Cache_Providers; use Progress_Planner\Suggested_Tasks\Providers\User as User_Tasks; use Progress_Planner\Suggested_Tasks\Providers\Email_Sending; use Progress_Planner\Suggested_Tasks\Providers\Set_Valuable_Post_Types; @@ -119,6 +120,9 @@ public function add_plugin_integration() { // All in One SEO integration. new Add_AIOSEO_Providers(); + + // LiteSpeed Cache integration. + new Add_Litespeed_Cache_Providers(); } /** diff --git a/classes/suggested-tasks/providers/integrations/litespeed-cache/class-add-litespeed-cache-providers.php b/classes/suggested-tasks/providers/integrations/litespeed-cache/class-add-litespeed-cache-providers.php new file mode 100644 index 000000000..8f86fafa6 --- /dev/null +++ b/classes/suggested-tasks/providers/integrations/litespeed-cache/class-add-litespeed-cache-providers.php @@ -0,0 +1,52 @@ +providers = [ + new Page_Cache(), + new Browser_Cache(), + new Css_Minification(), + new Js_Minification(), + new Image_Lazy_Load(), + new Guest_Mode(), + ]; + + return \array_merge( + $providers, + $this->providers + ); + } +} diff --git a/classes/suggested-tasks/providers/integrations/litespeed-cache/class-browser-cache.php b/classes/suggested-tasks/providers/integrations/litespeed-cache/class-browser-cache.php new file mode 100644 index 000000000..4db049fc1 --- /dev/null +++ b/classes/suggested-tasks/providers/integrations/litespeed-cache/class-browser-cache.php @@ -0,0 +1,126 @@ +get_litespeed_option( 'cache-browser' ); + } + + /** + * Get the popover instructions. + * + * @return void + */ + public function print_popover_instructions() { + echo '
'; + \esc_html_e( 'Browser caching tells visitors\' browsers to store static files (images, CSS, JavaScript) locally. When they return to your site, these files load from their device instead of being downloaded again, making repeat visits significantly faster.', 'progress-planner' ); + echo '
'; + } + + /** + * Print the popover input field for the form. + * + * @return void + */ + public function print_popover_form_contents() { + $this->print_submit_button( \__( 'Enable browser cache', 'progress-planner' ) ); + } + + /** + * Handle the interactive task submit. + * + * @return void + */ + public function handle_interactive_task_specific_submit() { + $this->verify_litespeed_cache_ajax_security(); + + $this->update_litespeed_option( 'cache-browser', 1 ); + + \wp_send_json_success( [ 'message' => \esc_html__( 'Setting updated.', 'progress-planner' ) ] ); + } + + /** + * Add task actions specific to this task. + * + * @param array $data The task data. + * @param array $actions The existing actions. + * + * @return array + */ + public function add_task_actions( $data = [], $actions = [] ) { + return $this->add_popover_action( $actions, \__( 'Enable', 'progress-planner' ) ); + } +} diff --git a/classes/suggested-tasks/providers/integrations/litespeed-cache/class-css-minification.php b/classes/suggested-tasks/providers/integrations/litespeed-cache/class-css-minification.php new file mode 100644 index 000000000..c9346566e --- /dev/null +++ b/classes/suggested-tasks/providers/integrations/litespeed-cache/class-css-minification.php @@ -0,0 +1,126 @@ +get_litespeed_option( 'optm-css_min' ); + } + + /** + * Get the popover instructions. + * + * @return void + */ + public function print_popover_instructions() { + echo ''; + \esc_html_e( 'CSS minification removes unnecessary whitespace, comments, and formatting from your CSS files, reducing their size by 10-30%. This is a low-risk optimization that helps pages load faster by reducing the amount of data browsers need to download.', 'progress-planner' ); + echo '
'; + } + + /** + * Print the popover input field for the form. + * + * @return void + */ + public function print_popover_form_contents() { + $this->print_submit_button( \__( 'Enable CSS minification', 'progress-planner' ) ); + } + + /** + * Handle the interactive task submit. + * + * @return void + */ + public function handle_interactive_task_specific_submit() { + $this->verify_litespeed_cache_ajax_security(); + + $this->update_litespeed_option( 'optm-css_min', 1 ); + + \wp_send_json_success( [ 'message' => \esc_html__( 'Setting updated.', 'progress-planner' ) ] ); + } + + /** + * Add task actions specific to this task. + * + * @param array $data The task data. + * @param array $actions The existing actions. + * + * @return array + */ + public function add_task_actions( $data = [], $actions = [] ) { + return $this->add_popover_action( $actions, \__( 'Enable', 'progress-planner' ) ); + } +} diff --git a/classes/suggested-tasks/providers/integrations/litespeed-cache/class-guest-mode.php b/classes/suggested-tasks/providers/integrations/litespeed-cache/class-guest-mode.php new file mode 100644 index 000000000..6289759ca --- /dev/null +++ b/classes/suggested-tasks/providers/integrations/litespeed-cache/class-guest-mode.php @@ -0,0 +1,126 @@ +get_litespeed_option( 'guest' ); + } + + /** + * Get the popover instructions. + * + * @return void + */ + public function print_popover_instructions() { + echo ''; + \esc_html_e( 'Guest mode serves a cached version of your pages to first-time visitors before determining their specific cache vary. This improves the cache hit ratio and ensures most anonymous visitors get the fastest possible page loads.', 'progress-planner' ); + echo '
'; + } + + /** + * Print the popover input field for the form. + * + * @return void + */ + public function print_popover_form_contents() { + $this->print_submit_button( \__( 'Enable guest mode', 'progress-planner' ) ); + } + + /** + * Handle the interactive task submit. + * + * @return void + */ + public function handle_interactive_task_specific_submit() { + $this->verify_litespeed_cache_ajax_security(); + + $this->update_litespeed_option( 'guest', 1 ); + + \wp_send_json_success( [ 'message' => \esc_html__( 'Setting updated.', 'progress-planner' ) ] ); + } + + /** + * Add task actions specific to this task. + * + * @param array $data The task data. + * @param array $actions The existing actions. + * + * @return array + */ + public function add_task_actions( $data = [], $actions = [] ) { + return $this->add_popover_action( $actions, \__( 'Enable', 'progress-planner' ) ); + } +} diff --git a/classes/suggested-tasks/providers/integrations/litespeed-cache/class-image-lazy-load.php b/classes/suggested-tasks/providers/integrations/litespeed-cache/class-image-lazy-load.php new file mode 100644 index 000000000..e64622807 --- /dev/null +++ b/classes/suggested-tasks/providers/integrations/litespeed-cache/class-image-lazy-load.php @@ -0,0 +1,126 @@ +get_litespeed_option( 'media-lazy' ); + } + + /** + * Get the popover instructions. + * + * @return void + */ + public function print_popover_instructions() { + echo ''; + \esc_html_e( 'Image lazy loading defers loading of images that are below the visible area of the page. Images are only loaded when the visitor scrolls near them. This significantly reduces initial page load time, especially on image-heavy pages.', 'progress-planner' ); + echo '
'; + } + + /** + * Print the popover input field for the form. + * + * @return void + */ + public function print_popover_form_contents() { + $this->print_submit_button( \__( 'Enable image lazy loading', 'progress-planner' ) ); + } + + /** + * Handle the interactive task submit. + * + * @return void + */ + public function handle_interactive_task_specific_submit() { + $this->verify_litespeed_cache_ajax_security(); + + $this->update_litespeed_option( 'media-lazy', 1 ); + + \wp_send_json_success( [ 'message' => \esc_html__( 'Setting updated.', 'progress-planner' ) ] ); + } + + /** + * Add task actions specific to this task. + * + * @param array $data The task data. + * @param array $actions The existing actions. + * + * @return array + */ + public function add_task_actions( $data = [], $actions = [] ) { + return $this->add_popover_action( $actions, \__( 'Enable', 'progress-planner' ) ); + } +} diff --git a/classes/suggested-tasks/providers/integrations/litespeed-cache/class-js-minification.php b/classes/suggested-tasks/providers/integrations/litespeed-cache/class-js-minification.php new file mode 100644 index 000000000..9861c9add --- /dev/null +++ b/classes/suggested-tasks/providers/integrations/litespeed-cache/class-js-minification.php @@ -0,0 +1,126 @@ +get_litespeed_option( 'optm-js_min' ); + } + + /** + * Get the popover instructions. + * + * @return void + */ + public function print_popover_instructions() { + echo ''; + \esc_html_e( 'JavaScript minification strips unnecessary characters from your JS files without changing their functionality. This reduces file sizes and helps your pages load faster, especially on slower connections.', 'progress-planner' ); + echo '
'; + } + + /** + * Print the popover input field for the form. + * + * @return void + */ + public function print_popover_form_contents() { + $this->print_submit_button( \__( 'Enable JS minification', 'progress-planner' ) ); + } + + /** + * Handle the interactive task submit. + * + * @return void + */ + public function handle_interactive_task_specific_submit() { + $this->verify_litespeed_cache_ajax_security(); + + $this->update_litespeed_option( 'optm-js_min', 1 ); + + \wp_send_json_success( [ 'message' => \esc_html__( 'Setting updated.', 'progress-planner' ) ] ); + } + + /** + * Add task actions specific to this task. + * + * @param array $data The task data. + * @param array $actions The existing actions. + * + * @return array + */ + public function add_task_actions( $data = [], $actions = [] ) { + return $this->add_popover_action( $actions, \__( 'Enable', 'progress-planner' ) ); + } +} diff --git a/classes/suggested-tasks/providers/integrations/litespeed-cache/class-litespeed-cache-interactive-provider.php b/classes/suggested-tasks/providers/integrations/litespeed-cache/class-litespeed-cache-interactive-provider.php new file mode 100644 index 000000000..8e625a36a --- /dev/null +++ b/classes/suggested-tasks/providers/integrations/litespeed-cache/class-litespeed-cache-interactive-provider.php @@ -0,0 +1,56 @@ +get_litespeed_option( 'cache' ) !== 1; + } + + /** + * Get the popover instructions. + * + * @return void + */ + public function print_popover_instructions() { + echo ''; + \esc_html_e( 'Page caching is the foundation of LiteSpeed Cache. It stores pre-built versions of your pages so they load instantly for visitors instead of being generated fresh each time. This is the single most impactful performance setting you can enable.', 'progress-planner' ); + echo '
'; + } + + /** + * Print the popover input field for the form. + * + * @return void + */ + public function print_popover_form_contents() { + $this->print_submit_button( \__( 'Enable page cache', 'progress-planner' ) ); + } + + /** + * Handle the interactive task submit. + * + * @return void + */ + public function handle_interactive_task_specific_submit() { + $this->verify_litespeed_cache_ajax_security(); + + $this->update_litespeed_option( 'cache', 1 ); + + \wp_send_json_success( [ 'message' => \esc_html__( 'Setting updated.', 'progress-planner' ) ] ); + } + + /** + * Add task actions specific to this task. + * + * @param array $data The task data. + * @param array $actions The existing actions. + * + * @return array + */ + public function add_task_actions( $data = [], $actions = [] ) { + return $this->add_popover_action( $actions, \__( 'Enable', 'progress-planner' ) ); + } +} diff --git a/classes/suggested-tasks/providers/traits/class-ajax-security-litespeed-cache.php b/classes/suggested-tasks/providers/traits/class-ajax-security-litespeed-cache.php new file mode 100644 index 000000000..daed8c7be --- /dev/null +++ b/classes/suggested-tasks/providers/traits/class-ajax-security-litespeed-cache.php @@ -0,0 +1,53 @@ + \esc_html__( 'LiteSpeed Cache is not active.', 'progress-planner' ) ] ); + } + } + + /** + * Perform complete LiteSpeed Cache AJAX security checks. + * + * Runs LiteSpeed Cache active check, capability check, and nonce verification. + * This is a convenience method for LiteSpeed Cache interactive tasks. + * + * @param string $capability The capability to require (default: 'manage_options'). + * @param string $action The nonce action to verify (default: 'progress_planner'). + * @param string $field The POST field containing the nonce (default: 'nonce'). + * + * @return void Exits with wp_send_json_error() if any check fails. + */ + protected function verify_litespeed_cache_ajax_security( $capability = 'manage_options', $action = 'progress_planner', $field = 'nonce' ) { + $this->verify_litespeed_cache_active_or_fail(); + $this->verify_ajax_security( $capability, $action, $field ); + } +}