Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 11 additions & 12 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,20 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 1.4.0 (2026-06-26)

### Fixed
## 1.5.0 (2026-06-26)

- `use_block_editor_for_post` filter was incorrectly registered as `add_action` — now uses proper `add_filter` (#19)
- Plugin deactivation never cleaned up options — `delete_option()` was wrapped in `add_action('init', ...)` which never runs during deactivation
- `update_option('default_ping_status')` and `update_option('default_comment_status')` ran on every admin page load — moved to activation hook, runs once
- `uninstall.php` now cleans up `ct-optimization` and `ct_optimization_activation_flushed` options from database

### Performance
### Added

- Centralized option loading: new `Codetot_Optimization::get_options()` parses options once per request with static cache. Process, Gravity Forms, and Assets classes share the same instance instead of each calling `get_option()` independently
- Reduced DB queries: `get_option('ct-optimization')` called 1× per request instead of 3×+
- **Remove query strings** (`?ver=`) from enqueued scripts and styles — improves cache hit rate on CDN and proxy caches
- **Disable self pingbacks** — prevents WordPress from sending pingbacks to your own domain
- **Disable REST API for non-authenticated users** — returns 401 for unauthenticated REST requests; keeps public endpoints intact
- **Remove default dashboard widgets** — cleans up Quick Draft, WP News, Site Health, At a Glance, Activity, and Welcome panel
- **Disable attachment pages** — 301 redirects attachment pages to parent post (or homepage if no parent)
- **Remove jQuery Migrate** — removes the jquery-migrate dependency from jquery on front-end
- **Disable native XML sitemaps** — disables WordPress 5.5+ built-in sitemaps (let SEO plugins handle it)
- **Remove front-end dashicons** — dequeues dashicons stylesheet on front-end when not used by theme

## 1.3.0 (2026-06-26)
## 1.4.0 (2026-06-26)

### Added

Expand Down
23 changes: 16 additions & 7 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Donate link: https://codetot.com
Tags: optimization, compress, settings, codetot
Requires at least: 6.0
Tested up to: 6.8
Stable tag: 1.4.0
Stable tag: 1.5.0
Requires PHP: 8.0
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Expand Down Expand Up @@ -78,13 +78,22 @@ Yes, if you are using our themes.

== Changelog ==

= 1.5.0 =
* **[New]** Remove query strings (`?ver=`) from static assets for improved cache hit rate
* **[New]** Disable self pingbacks to reduce server load
* **[New]** Disable REST API for non-authenticated users (returns 401)
* **[New]** Remove default dashboard widgets (Quick Draft, WP News, etc.)
* **[New]** Disable attachment pages (301 redirect to parent post or home)
* **[New]** Remove jQuery Migrate script from front-end
* **[New]** Disable native WordPress XML sitemaps (WP 5.5+)
* **[New]** Remove dashicons styles on front-end when not used by theme

= 1.4.0 =
* **[Fix]** `use_block_editor_for_post` filter was incorrectly registered as `add_action` → now uses proper `add_filter` (B1)
* **[Fix]** Plugin deactivation never cleaned up options — `delete_option()` was wrapped in an `add_action('init', ...)` that never runs during deactivation (B2)
* **[Fix]** `update_option('default_ping_status')` and `update_option('default_comment_status')` ran on **every admin page load** → moved to activation hook, runs once (B3)
* **[Fix]** `uninstall.php` now cleans up `ct-optimization` and `ct_optimization_activation_flushed` options (B4)
* **[Perf]** Centralized option loading — `Codetot_Optimization::get_options()` parses options once per request with static cache; Process, Gravity Forms, and Assets classes share the same call instead of each calling `get_option()` independently (P1)
* **[Perf]** Reduced DB queries: `get_option('ct-optimization')` now called 1× per request instead of 3×+
* **[Fix]** `use_block_editor_for_post` filter was incorrectly registered as `add_action` → now uses proper `add_filter`
* **[Fix]** Plugin deactivation never cleaned up options — `delete_option()` was wrapped in `add_action('init', ...)` that never runs during deactivation
* **[Fix]** `update_option()` calls for default comment/ping statuses moved from per-request admin to activation hook (runs once)
* **[Fix]** `uninstall.php` now cleans up plugin options from database
* **[Perf]** Centralized option loading — `Codetot_Optimization::get_options()` with static cache; 1 DB call per request instead of 3

= 1.3.0 =
* Official PHP 8.0-8.4 support, bumped Requires PHP to 8.0
Expand Down
10 changes: 9 additions & 1 deletion admin/class-codetot-optimization-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,15 @@ public function get_global_keys()
'disable_feed' => __('Feed', 'codetot-optimization'),
'disable_shortlink' => __('Shortlink', 'codetot-optimization'),
'disable_wlw_manifest' => __('WLW Manifest', 'codetot-optimization'),
'disable_inline_comment_style' => __('Inline Comment Style', 'codetot-optimization')
'disable_inline_comment_style' => __('Inline Comment Style', 'codetot-optimization'),
'disable_query_strings' => __('Query Strings from Assets', 'codetot-optimization'),
'disable_self_pingbacks' => __('Self Pingbacks', 'codetot-optimization'),
'disable_rest_api' => __('REST API (non-auth)', 'codetot-optimization'),
'remove_dashboard_widgets' => __('Dashboard Widgets', 'codetot-optimization'),
'disable_attachment_pages' => __('Attachment Pages', 'codetot-optimization'),
'remove_jquery_migrate' => __('jQuery Migrate', 'codetot-optimization'),
'disable_xml_sitemaps' => __('XML Sitemaps', 'codetot-optimization'),
'remove_frontend_dashicons' => __('Front-end Dashicons', 'codetot-optimization'),
];
}

Expand Down
4 changes: 2 additions & 2 deletions codetot-optimization.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* Plugin Name: CT Optimization
* Plugin URI: https://codetot.com
* Description: Provides settings for enable/disable WordPress core features and some tweaks for ACF, Gravity Forms, such like Enable CDN, Lazyload assets.
* Version: 1.4.0
* Version: 1.5.0
* Requires at least: 6.0
* Requires PHP: 8.0
* Author: CODE TOT JSC
Expand All @@ -24,7 +24,7 @@
die;
}

define( 'CODETOT_OPTIMIZATION_VERSION', '1.4.0' );
define( 'CODETOT_OPTIMIZATION_VERSION', '1.5.0' );
define( 'CODETOT_OPTIMIZATION_PATH', plugin_dir_path(__FILE__) );
define( 'CODETOT_OPTIMIZATION_URL', plugin_dir_url(__FILE__) );

Expand Down
162 changes: 162 additions & 0 deletions includes/class-codetot-optimization-process.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,17 @@ public function __construct()

// Advanced Settings
add_action('init', array($this, 'check_cdn'));

// New Optimization Features
add_filter('script_loader_src', array($this, 'remove_query_strings'), 15, 1);
add_filter('style_loader_src', array($this, 'remove_query_strings'), 15, 1);
add_action('init', array($this, 'check_self_pingbacks'));
add_action('init', array($this, 'check_rest_api'));
add_action('init', array($this, 'check_dashboard_widgets'));
add_action('init', array($this, 'check_attachment_pages'));
add_action('init', array($this, 'check_jquery_migrate'));
add_action('init', array($this, 'check_xml_sitemaps'));
add_action('wp_enqueue_scripts', array($this, 'check_frontend_dashicons'), 100);
}

public function check_gutenberg()
Expand Down Expand Up @@ -429,4 +440,155 @@ public function calculate_image_srcset($sources)
}
return $sources;
}

// ==========================================================================
// Phase 2: New Optimization Features
// ==========================================================================

/**
* Remove query strings (?ver=) from enqueued scripts and styles.
*
* @since 1.5.0
* @param string $src
* @return string
*/
public function remove_query_strings($src)
{
if (!empty($this->options['disable_query_strings'])) {
$src = remove_query_arg('ver', $src);
}
return $src;
}

/**
* Disable self pingbacks.
*
* @since 1.5.0
*/
public function check_self_pingbacks()
{
if (!empty($this->options['disable_self_pingbacks'])) {
add_action('pre_ping', function (&$links) {
$home = get_option('home');
foreach ($links as $l => $link) {
if (strpos($link, $home) === 0) {
unset($links[$l]);
}
}
});
}
}

/**
* Disable REST API for non-authenticated users.
*
* @since 1.5.0
*/
public function check_rest_api()
{
if (!empty($this->options['disable_rest_api'])) {
add_filter('rest_authentication_errors', function ($result) {
if (!empty($result)) {
return $result;
}
if (!is_user_logged_in()) {
return new WP_Error(
'rest_not_logged_in',
__('You are not currently logged in.', 'codetot-optimization'),
array('status' => 401)
);
}
return $result;
});
}
}

/**
* Remove default dashboard widgets.
*
* @since 1.5.0
*/
public function check_dashboard_widgets()
{
if (!empty($this->options['remove_dashboard_widgets'])) {
add_action('wp_dashboard_setup', function () {
remove_meta_box('dashboard_quick_press', 'dashboard', 'side');
remove_meta_box('dashboard_primary', 'dashboard', 'side');
remove_meta_box('dashboard_secondary', 'dashboard', 'side');
remove_meta_box('dashboard_site_health', 'dashboard', 'normal');
remove_meta_box('dashboard_right_now', 'dashboard', 'normal');
remove_meta_box('dashboard_activity', 'dashboard', 'normal');
remove_meta_box('dashboard_incoming_links', 'dashboard', 'normal');
remove_meta_box('dashboard_plugins', 'dashboard', 'normal');
remove_meta_box('dashboard_recent_comments', 'dashboard', 'normal');
remove_meta_box('dashboard_recent_drafts', 'dashboard', 'normal');
remove_action('welcome_panel', 'wp_welcome_panel');
});
}
}

/**
* Disable attachment pages — redirect to parent or home.
*
* @since 1.5.0
*/
public function check_attachment_pages()
{
if (!empty($this->options['disable_attachment_pages'])) {
add_action('template_redirect', function () {
if (is_attachment()) {
global $post;
if ($post && $post->post_parent) {
wp_redirect(get_permalink($post->post_parent), 301);
} else {
wp_redirect(home_url(), 301);
}
exit;
}
});
}
}

/**
* Remove jQuery Migrate script.
*
* @since 1.5.0
*/
public function check_jquery_migrate()
{
if (!empty($this->options['remove_jquery_migrate'])) {
add_action('wp_default_scripts', function ($scripts) {
if (!empty($scripts->registered['jquery'])) {
$jquery_deps = $scripts->registered['jquery']->deps;
$scripts->registered['jquery']->deps = array_diff($jquery_deps, array('jquery-migrate'));
}
});
}
}

/**
* Disable native WordPress XML sitemaps (WP 5.5+).
*
* @since 1.5.0
*/
public function check_xml_sitemaps()
{
if (!empty($this->options['disable_xml_sitemaps'])) {
add_filter('wp_sitemaps_enabled', '__return_false');
}
}

/**
* Remove dashicons styles on front-end when not used by theme.
*
* @since 1.5.0
*/
public function check_frontend_dashicons()
{
if (!empty($this->options['remove_frontend_dashicons'])) {
if (!is_admin() && !is_customize_preview()) {
wp_dequeue_style('dashicons');
}
}
}
}
Loading