diff --git a/aaa-option-optimizer.php b/aaa-option-optimizer.php index cf090b9..212fcd1 100644 --- a/aaa-option-optimizer.php +++ b/aaa-option-optimizer.php @@ -1,54 +1,43 @@ get_row( - $wpdb->prepare( "SELECT count(*) AS count, SUM( LENGTH( option_value ) ) as autoload_size FROM {$wpdb->options} WHERE autoload IN ( $placeholders )", $autoload_values ) - ); - // phpcs:enable WordPress.DB +function aaa_meta_optimizer_activation() { update_option( - 'option_optimizer', + 'meta_optimizer', [ - 'starting_point_kb' => ( $result->autoload_size / 1024 ), - 'starting_point_num' => $result->count, 'starting_point_date' => current_time( 'mysql' ), - 'used_options' => [], + 'used_meta_fields' => [], ], true ); @@ -59,9 +48,9 @@ function aaa_option_optimizer_activation() { * * @return void */ -function aaa_option_optimizer_deactivation() { - $aaa_option_value = get_option( 'option_optimizer' ); - update_option( 'option_optimizer', $aaa_option_value, false ); +function aaa_meta_optimizer_deactivation() { + $aaa_option_value = get_option( 'meta_optimizer' ); + update_option( 'meta_optimizer', $aaa_option_value, false ); } /** @@ -69,9 +58,9 @@ function aaa_option_optimizer_deactivation() { * * @return void */ -function aaa_option_optimizer_init() { - $optimizer = new Emilia\OptionOptimizer\Plugin(); +function aaa_meta_optimizer_init() { + $optimizer = new Emilia\MetaOptimizer\Plugin(); $optimizer->register_hooks(); } -aaa_option_optimizer_init(); +aaa_meta_optimizer_init(); diff --git a/composer.json b/composer.json index 68a8d8f..77d1480 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { - "name": "emilia/aaa-option-optimizer", - "description": "Plugin that tracks autoloaded options usage and allows the user to optimize them.", + "name": "emilia/aaa-meta-optimizer", + "description": "Plugin that tracks post meta usage and allows the user to optimize them.", "type": "wordpress-plugin", "license": "GPL-3.0-or-later", "authors": [ diff --git a/composer.lock b/composer.lock index caaaa3c..1719f90 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "fd7786df413fbfa0ec1e1564845fe06c", + "content-hash": "2d53a78063241227f4ef57a4e0cf8e15", "packages": [], "packages-dev": [ { @@ -148,16 +148,16 @@ }, { "name": "php-stubs/wordpress-stubs", - "version": "v6.6.0", + "version": "v6.7.2", "source": { "type": "git", "url": "https://github.com/php-stubs/wordpress-stubs.git", - "reference": "86e8753e89d59849276dcdd91b9a7dd78bb4abe2" + "reference": "c04f96cb232fab12a3cbcccf5a47767f0665c3f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/86e8753e89d59849276dcdd91b9a7dd78bb4abe2", - "reference": "86e8753e89d59849276dcdd91b9a7dd78bb4abe2", + "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/c04f96cb232fab12a3cbcccf5a47767f0665c3f4", + "reference": "c04f96cb232fab12a3cbcccf5a47767f0665c3f4", "shasum": "" }, "require-dev": { @@ -166,9 +166,9 @@ "php": "^7.4 || ^8.0", "php-stubs/generator": "^0.8.3", "phpdocumentor/reflection-docblock": "^5.4.1", - "phpstan/phpstan": "^1.10.49", + "phpstan/phpstan": "^1.11", "phpunit/phpunit": "^9.5", - "szepeviktor/phpcs-psr-12-neutron-hybrid-ruleset": "^1.0", + "szepeviktor/phpcs-psr-12-neutron-hybrid-ruleset": "^1.1.1", "wp-coding-standards/wpcs": "3.1.0 as 2.3.0" }, "suggest": { @@ -190,9 +190,9 @@ ], "support": { "issues": "https://github.com/php-stubs/wordpress-stubs/issues", - "source": "https://github.com/php-stubs/wordpress-stubs/tree/v6.6.0" + "source": "https://github.com/php-stubs/wordpress-stubs/tree/v6.7.2" }, - "time": "2024-07-17T08:50:38+00:00" + "time": "2025-02-12T04:51:58+00:00" }, { "name": "phpcompatibility/php-compatibility", @@ -200,12 +200,12 @@ "source": { "type": "git", "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", - "reference": "d9ae4b030f174c8f01d400244107e28ad65ec5e1" + "reference": "9013cd039fe5740953f9fdeebd19d901b80e26f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/d9ae4b030f174c8f01d400244107e28ad65ec5e1", - "reference": "d9ae4b030f174c8f01d400244107e28ad65ec5e1", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9013cd039fe5740953f9fdeebd19d901b80e26f2", + "reference": "9013cd039fe5740953f9fdeebd19d901b80e26f2", "shasum": "" }, "require": { @@ -218,7 +218,7 @@ }, "require-dev": { "php-parallel-lint/php-console-highlighter": "^1.0.0", - "php-parallel-lint/php-parallel-lint": "^1.3.2", + "php-parallel-lint/php-parallel-lint": "^1.4.0", "phpcsstandards/phpcsdevcs": "^1.1.3", "phpcsstandards/phpcsdevtools": "^1.2.0", "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4 || ^10.1.0", @@ -280,34 +280,38 @@ { "url": "https://opencollective.com/php_codesniffer", "type": "open_collective" + }, + { + "url": "https://thanks.dev/u/gh/phpcompatibility", + "type": "thanks_dev" } ], - "time": "2024-08-31T21:55:43+00:00" + "time": "2025-01-20T20:06:48+00:00" }, { "name": "phpcompatibility/phpcompatibility-paragonie", - "version": "1.3.2", + "version": "1.3.3", "source": { "type": "git", "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git", - "reference": "bba5a9dfec7fcfbd679cfaf611d86b4d3759da26" + "reference": "293975b465e0e709b571cbf0c957c6c0a7b9a2ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/bba5a9dfec7fcfbd679cfaf611d86b4d3759da26", - "reference": "bba5a9dfec7fcfbd679cfaf611d86b4d3759da26", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/293975b465e0e709b571cbf0c957c6c0a7b9a2ac", + "reference": "293975b465e0e709b571cbf0c957c6c0a7b9a2ac", "shasum": "" }, "require": { "phpcompatibility/php-compatibility": "^9.0" }, "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7", + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", "paragonie/random_compat": "dev-master", "paragonie/sodium_compat": "dev-master" }, "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", + "dealerdirect/phpcodesniffer-composer-installer": "^1.0 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." }, "type": "phpcodesniffer-standard", @@ -337,22 +341,37 @@ ], "support": { "issues": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/issues", + "security": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/security/policy", "source": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie" }, - "time": "2022-10-25T01:46:02+00:00" + "funding": [ + { + "url": "https://github.com/PHPCompatibility", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + } + ], + "time": "2024-04-24T21:30:46+00:00" }, { "name": "phpcompatibility/phpcompatibility-wp", - "version": "2.1.5", + "version": "2.1.6", "source": { "type": "git", "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git", - "reference": "01c1ff2704a58e46f0cb1ca9d06aee07b3589082" + "reference": "80ccb1a7640995edf1b87a4409fa584cd5869469" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/01c1ff2704a58e46f0cb1ca9d06aee07b3589082", - "reference": "01c1ff2704a58e46f0cb1ca9d06aee07b3589082", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/80ccb1a7640995edf1b87a4409fa584cd5869469", + "reference": "80ccb1a7640995edf1b87a4409fa584cd5869469", "shasum": "" }, "require": { @@ -409,7 +428,7 @@ "type": "open_collective" } ], - "time": "2024-04-24T21:37:59+00:00" + "time": "2025-01-16T22:34:19+00:00" }, { "name": "phpcsstandards/phpcsextra", @@ -627,16 +646,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.12.2", + "version": "1.12.23", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "0ca1c7bb55fca8fe6448f16fff0f311ccec960a1" + "reference": "29201e7a743a6ab36f91394eab51889a82631428" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0ca1c7bb55fca8fe6448f16fff0f311ccec960a1", - "reference": "0ca1c7bb55fca8fe6448f16fff0f311ccec960a1", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/29201e7a743a6ab36f91394eab51889a82631428", + "reference": "29201e7a743a6ab36f91394eab51889a82631428", "shasum": "" }, "require": { @@ -681,20 +700,20 @@ "type": "github" } ], - "time": "2024-09-05T16:09:28+00:00" + "time": "2025-03-23T14:57:32+00:00" }, { "name": "squizlabs/php_codesniffer", - "version": "3.10.2", + "version": "3.12.0", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "86e5f5dd9a840c46810ebe5ff1885581c42a3017" + "reference": "2d1b63db139c3c6ea0c927698e5160f8b3b8d630" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/86e5f5dd9a840c46810ebe5ff1885581c42a3017", - "reference": "86e5f5dd9a840c46810ebe5ff1885581c42a3017", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/2d1b63db139c3c6ea0c927698e5160f8b3b8d630", + "reference": "2d1b63db139c3c6ea0c927698e5160f8b3b8d630", "shasum": "" }, "require": { @@ -759,32 +778,36 @@ { "url": "https://opencollective.com/php_codesniffer", "type": "open_collective" + }, + { + "url": "https://thanks.dev/u/gh/phpcsstandards", + "type": "thanks_dev" } ], - "time": "2024-07-21T23:26:44+00:00" + "time": "2025-03-18T05:04:51+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "21bd091060673a1177ae842c0ef8fe30893114d2" + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/21bd091060673a1177ae842c0ef8fe30893114d2", - "reference": "21bd091060673a1177ae842c0ef8fe30893114d2", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/0f68c03565dcaaf25a890667542e8bd75fe7e5bb", + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -821,7 +844,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.31.0" }, "funding": [ { @@ -837,7 +860,7 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "szepeviktor/phpstan-wordpress", diff --git a/js/admin-script.js b/js/admin-script.js index acfc640..381357f 100644 --- a/js/admin-script.js +++ b/js/admin-script.js @@ -1,7 +1,7 @@ /** * JavaScript for the admin page. * - * @package Emilia\OptionOptimizer + * @package Emilia\MetaOptimizer */ /** @@ -17,7 +17,6 @@ jQuery( document ).ready( const tablesToInitialize = [ '#unused_options_table', '#used_not_autoloaded_table', - '#requested_do_not_exist_table', ]; $( '#all_options_table' ).hide(); @@ -49,15 +48,15 @@ jQuery( document ).ready( if (selector === '#all_options_table') { options.ajax = { - url: aaaOptionOptimizer.root + 'aaa-option-optimizer/v1/all-options', - headers: { 'X-WP-Nonce': aaaOptionOptimizer.nonce }, + url: aaaMetaOptimizer.root + 'aaa-option-optimizer/v1/all-options', + headers: { 'X-WP-Nonce': aaaMetaOptimizer.nonce }, type: 'GET', dataSrc: 'data' }; options.rowId = 'row_id'; } - options.language = aaaOptionOptimizer.i18n; + options.language = aaaMetaOptimizer.i18n; const dataTable = new DataTable( selector, options ).columns.adjust().responsive.recalc();; } @@ -73,8 +72,6 @@ jQuery( document ).ready( const commonColumns = [ { name: 'name' }, { name: 'source' }, - { name: 'size', searchable: false }, - { name: 'autoload', className: 'autoload', searchable: false }, { name: 'actions', searchable: false, orderable: false } ]; @@ -89,8 +86,6 @@ jQuery( document ).ready( return [ { name: 'name' }, { name: 'source' }, - { name: 'size', searchable: false }, - { name: 'autoload', className: 'autoload', searchable: false }, { name: 'calls', searchable: false }, { name: 'actions', searchable: false, orderable: false } ] @@ -125,7 +120,7 @@ jQuery( document ).ready( function setupColumnFilters() { const column = this; const select = document.createElement( 'select' ); - select.add( new Option( aaaOptionOptimizer.i18n.filterBySource, '', true, true ) ); + select.add( new Option( aaaMetaOptimizer.i18n.filterBySource, '', true, true ) ); column.footer().replaceChildren( select ); select.addEventListener( @@ -157,26 +152,26 @@ jQuery( document ).ready( ''; const actions = [ - '', + '', popoverContent, row.autoload === 'no' ? - '' : - '', - '' + '' : + '', + '' ]; return actions.join( '' ); } - $( '#aaa-option-reset-data' ).on( + $( '#aaa-meta-reset-data' ).on( 'click', function (e) { e.preventDefault(); $.ajax( { - url: aaaOptionOptimizer.root + 'aaa-option-optimizer/v1/reset', + url: aaaMetaOptimizer.root + 'aaa-meta-optimizer/v1/reset', method: 'POST', - beforeSend: xhr => xhr.setRequestHeader( 'X-WP-Nonce', aaaOptionOptimizer.nonce ), + beforeSend: xhr => xhr.setRequestHeader( 'X-WP-Nonce', aaaMetaOptimizer.nonce ), success: response => window.location = window.location.href + '&tracking_reset=true', error: response => console.error( 'Failed to reset tracking.', @@ -214,9 +209,9 @@ jQuery( document ).ready( $.ajax( { - url: aaaOptionOptimizer.root + 'aaa-option-optimizer/v1/' + route, + url: aaaMetaOptimizer.root + 'aaa-option-optimizer/v1/' + route, method: 'POST', - beforeSend: xhr => xhr.setRequestHeader( 'X-WP-Nonce', aaaOptionOptimizer.nonce ), + beforeSend: xhr => xhr.setRequestHeader( 'X-WP-Nonce', aaaMetaOptimizer.nonce ), data: requestData, success: response => updateRowOnSuccess( response, table, optionName, action ), error: response => console.error( @@ -241,8 +236,8 @@ jQuery( document ).ready( } else if ( action === 'add-autoload' || action === 'remove-autoload' ) { const autoloadStatus = action === 'add-autoload' ? 'yes' : 'no'; const buttonHTML = action === 'add-autoload' ? - '': - ''; + '': + ''; $( 'tr#option_' + optionName ).find( 'td.autoload' ).text( autoloadStatus ); const oldButton = 'button.' + ( action === 'add-autoload' ? 'add' : 'remove' ) + '-autoload'; diff --git a/known-plugins/known-plugins.json b/known-plugins/known-plugins.json index 3f6db85..7b45850 100644 --- a/known-plugins/known-plugins.json +++ b/known-plugins/known-plugins.json @@ -1,317 +1,17 @@ { - "aaa-option-optimizer": { - "name": "AAA Option Optimizer", - "option_prefixes": ["option_optimizer"] - }, - "accessibility-checker": { - "name": "Equalize Digital Accessibility Checker", - "option_prefixes": ["edac_"] - }, - "advanced-custom-fields": { - "name": "Advanced Custom Fields", - "option_prefixes": ["acf_"] - }, - "affiliate-wp": { - "name": "Affiliate WP", - "option_prefixes": ["affwp_"] - }, - "all-in-one-seo-pack": { - "name": "AIOSEO - The Best WordPress SEO Plugin & Toolkit", - "option_prefixes": ["aioseo_","widget_aioseo"] - }, - "breeze": { - "name": "Breeze - WordPress Cache Plugin", - "option_prefixes": ["breeze_"] - }, - "bunnycdn": { - "name": "bunny.net - WordPress CDN Plugin", - "option_prefixes": ["bunny"] - }, - "burst": { - "name": "Burst Statistics", - "option_prefixes": ["burst_"] - }, - "chaty": { - "name": "Floating Chat Widget: Contact Chat Icons, WhatsApp, Telegram Chat, Line Messenger, WeChat, Email, SMS, Call Button – Chaty", - "option_prefixes": ["chaty_"] - }, - "complianz": { - "name": "Complianz GDPR", - "option_prefixes": ["cmplz_", "complianz_"] - }, - "cookiebot": { - "name": "Cookie banner plugin for WordPress – Cookiebot CMP by Usercentrics", - "option_prefixes": ["cookiebot_", "cookiebot-"] - }, - "duplicate-post": { - "name": "Yoast Duplicate Post", - "option_prefixes": ["duplicate_post_"] - }, - "easy-digital-downloads": { - "name": "Easy Digital Downloads", - "option_prefixes": ["edd_"] - }, - "elementor": { - "name": "Elementor", - "option_prefixes": ["elementor_"] - }, - "fewer-tags": { - "name": "Fewer Tags", - "option_prefixes": ["fewer_tags"] - }, - "fluentform": { - "name": "Fluent Forms", - "option_prefixes": ["_fluentform_", "fluentform_"] - }, - "generateblocks": { - "name": "GenerateBlocks", - "option_prefixes": ["generateblocks_"] - }, - "google-analytics-for-wordpress": { - "name": "Google Analytics for WordPress by MonsterInsights", - "option_prefixes": ["yst_"] - }, - "gravity-forms": { - "name": "Gravity Forms", - "option_prefixes": ["gf_","gforms_"] - }, - "indeed-membership-pro": { - "name": "Indeed Ultimate Membership Pro", - "option_prefixes": ["ihc_"] - }, - "jetpack": { - "name": "Jetpack", - "option_prefixes": ["jetpack_"] - }, - "js_composer": { - "name": "Visual Composer Website Builder, Landing Page Builder, Custom Theme Builder, Maintenance Mode & Coming Soon Pages", - "option_prefixes": ["vcv-"] - }, - "litespeed-cache": { - "name": "LiteSpeed Cache", - "option_prefixes": ["litespeed-", "_litespeed_"] - }, - "loginizer": { - "name": "Loginizer", - "option_prefixes": ["loginizer_"] - }, - "perfmatters": { - "name": "Perfmatters", - "option_prefixes": ["perfmatters_"] - }, - "pixel-caffeine": { - "name": "Pixel Caffeine", - "option_prefixes": ["aepc_"] - }, - "pojo-accessibility": { - "name": "One Click Accessibility", - "option_prefixes": ["pojo_a11y"] - }, - "porto-functionality": { - "name": "Porto Theme - Functionality", - "option_prefixes": ["porto_"] - }, - "really-simple-ssl": { - "name": "Really Simple SSL", - "option_prefixes": ["rsssl_"] - }, - "redirection": { - "name": "Redirection", - "option_prefixes": ["redirection_"] - }, - "revslider": { - "name": "Slider Revolution", - "option_prefixes": ["revslider-"] - }, - "seedprod": { - "name": "Seedprod", - "option_prefixes": ["seedprod", "seed_"] - }, - "seo-by-rank-math": { - "name": "Rank Math SEO with AI Best SEO Tools", - "option_prefixes": ["rank_math_"] - }, - "updraft": { - "name": "Updraft Plus", - "option_prefixes": ["updraft_", "updraftplus_"] - }, - "yoast": { - "name": "Yoast SEO", - "option_prefixes": ["wpseo", "yoast_"] - }, - "woocommerce": { - "name": "WooCommerce", - "option_prefixes": ["wc_", "_transient__woocommerce_", "woocommerce_"] - }, - "wordfence": { - "name": "Wordfence", - "option_prefixes": ["wordfence_"] - }, "wordpress": { "name": "WordPress", "option_prefixes": [ - "_site_transient_timeout_available_translations", - "_site_transient_timeout_theme_roots", - "_site_transient_update_core", - "active_plugins", - "admin_email", - "adminhash", - "auth_key", - "auth_salt", - "auto_core_update_notified", - "auto_plugin_theme_update_emails", - "auto_update_core_dev", - "auto_update_core_major", - "auto_update_core_minor", - "auto_updater.lock", - "avatar_default", - "avatar_rating", - "blacklist_keys", - "blog_charset", - "blog_public", - "blogdescription", - "blogname", - "can_compress_scripts", - "category_base", - "category_children", - "close_comments_days_old", - "close_comments_for_old_posts", - "comment_max_links", - "comment_moderation", - "comment_order", - "comment_previously_approved", - "comment_registration", - "comment_whitelist", - "comments_notify", - "comments_per_page", - "core_updater.lock", - "cron", - "current_theme", - "date_format", - "db_upgraded", - "db_version", - "default_category", - "default_comment_status", - "default_comments_page", - "default_email_category", - "default_link_category", - "default_ping_status", - "default_pingback_flag", - "default_post_format", - "default_role", - "disallowed_keys", - "embed_size_h", - "embed_size_w", - "finished_splitting_shared_terms", - "finished_updating_comment_type", - "fresh_site", - "gmt_offset", - "hack_file", - "home", - "html_type", - "https_detection_errors", - "https_migration_required", - "image_default_align", - "image_default_link_type", - "image_default_size", - "initial_db_version", - "large_size_h", - "large_size_w", - "link_manager_enabled", - "links_updated_date_format", - "logged_in_key", - "logged_in_salt", - "mailserver_login", - "mailserver_pass", - "mailserver_port", - "mailserver_url", - "medium_large_size_h", - "medium_large_size_w", - "medium_size_h", - "medium_size_w", - "moderation_keys", - "moderation_notify", - "new_admin_email", - "nonce_key", - "nonce_salt", - "page_comments", - "page_for_posts", - "page_on_front", - "permalink_structure", - "ping_sites", - "posts_per_page", - "posts_per_rss", - "recently_activated", - "recovery_keys", - "require_name_email", - "rewrite_rules", - "rss_use_excerpt", - "secure_auth_key", - "secure_auth_salt", - "show_on_front", - "show_avatars", - "show_comments_cookies_opt_in", - "sidebars_widgets", - "site_icon", - "site_logo", - "siteurl", - "start_of_week", - "sticky_posts", - "stylesheet", - "tag_base", - "template", - "theme_mods_", - "theme_switched", - "thumbnail_crop", - "thumbnail_size_h", - "thumbnail_size_w", - "thread_comments", - "thread_comments_depth", - "time_format", - "timezone_string", - "uninstall_plugins", - "upload_path", - "upload_url_path", - "uploads_use_yearmonth_folders", - "use_balanceTags", - "use_smilies", - "use_trackback", - "user_count", - "users_can_register", - "widget_", - "wp_attachment_pages_enabled", - "wp_force_deactivated_plugins", - "wp_page_for_privacy_policy", - "wp_user_roles", - "WPLANG" + "_thumbnail_id", + "_wp_attached_file", + "_wp_attachment_image_alt", + "_wp_attachment_metadata", + "_wp_ignored_hooked_blocks", + "_wp_suggested_privacy_policy_content", + "is_wp_suggestion", + "origin", + "_edit_lock", + "_wp_page_template" ] - }, - "worker": { - "name": "ManageWP Worker", - "option_prefixes": ["mwp_", "worker_"] - }, - "wpcf7": { - "name": "Contact From 7", - "option_prefixes": ["wpcf7"] - }, - "wpforms": { - "name": "WPForms", - "option_prefixes": ["wpforms_"] - }, - "wpml": { - "name": "WPML", - "option_prefixes": ["_wpml_", "wpml_", "otgs-", "otgs_", "_icl_"] - }, - "wp-optimize": { - "name": "WP Optimize", - "option_prefixes": ["wpo_", "wp-optimize"] - }, - "wp-rocket": { - "name": "WP Rocket", - "option_prefixes": ["wp_rocket_", "rocket_"] - }, - "wpvivid-backuprestore": { - "name": "WPvivid Backup Plugin", - "option_prefixes": ["wpvivid_"] } } diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 36a7308..a5d29c7 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -98,7 +98,7 @@ - + diff --git a/src/autoload.php b/src/autoload.php index 502fda2..832ea48 100644 --- a/src/autoload.php +++ b/src/autoload.php @@ -2,12 +2,12 @@ /** * Autoload PHP classes for the plugin. * - * @package Emilia\OptionOptimizer + * @package Emilia\MetaOptimizer */ spl_autoload_register( function ( $class_name ) { - $prefix = 'Emilia\\OptionOptimizer\\'; + $prefix = 'Emilia\\MetaOptimizer\\'; if ( 0 !== \strpos( $class_name, $prefix ) ) { return; @@ -15,7 +15,7 @@ function ( $class_name ) { $class_name = \str_replace( $prefix, '', $class_name ); - $file = AAA_OPTION_OPTIMIZER_DIR . '/src/class-' . \str_replace( '_', '-', \strtolower( $class_name ) ) . '.php'; + $file = AAA_META_OPTIMIZER_DIR . '/src/class-' . \str_replace( '_', '-', \strtolower( $class_name ) ) . '.php'; if ( \file_exists( $file ) ) { require_once $file; diff --git a/src/class-admin-page.php b/src/class-admin-page.php index 3bb2d6d..089f417 100644 --- a/src/class-admin-page.php +++ b/src/class-admin-page.php @@ -2,10 +2,10 @@ /** * Admin page functionality for AAA Option Optimizer. * - * @package Emilia\OptionOptimizer + * @package Emilia\MetaOptimizer */ -namespace Emilia\OptionOptimizer; +namespace Emilia\MetaOptimizer; /** * Admin page functionality for AAA Option Optimizer. @@ -47,11 +47,11 @@ public function filter_plugin_actions( $links, $file ): array { /* Static so we don't call plugin_basename on every plugin row. */ static $this_plugin; if ( ! $this_plugin ) { - $this_plugin = \plugin_basename( AAA_OPTION_OPTIMIZER_FILE ); + $this_plugin = \plugin_basename( AAA_META_OPTIMIZER_FILE ); } if ( $file === $this_plugin ) { - $settings_link = '' . \__( 'Optimize Options', 'aaa-option-optimizer' ) . ''; + $settings_link = '' . \__( 'Optimize Meta Fields', 'aaa-meta-optimizer' ) . ''; // Put our link before other links. \array_unshift( $links, $settings_link ); } @@ -66,10 +66,10 @@ public function filter_plugin_actions( $links, $file ): array { */ public function add_admin_page() { \add_management_page( - __( 'AAA Option Optimizer', 'aaa-option-optimizer' ), - __( 'Option Optimizer', 'aaa-option-optimizer' ), + __( 'AAA Meta Optimizer', 'aaa-meta-optimizer' ), + __( 'Meta Optimizer', 'aaa-meta-optimizer' ), 'manage_options', - 'aaa-option-optimizer', + 'aaa-meta-optimizer', [ $this, 'render_admin_page' ] ); } @@ -82,20 +82,20 @@ public function add_admin_page() { * @return void */ public function enqueue_scripts( $hook ) { - if ( $hook !== 'tools_page_aaa-option-optimizer' ) { + if ( $hook !== 'tools_page_aaa-meta-optimizer' ) { return; } \wp_enqueue_style( - 'aaa-option-optimizer', - plugin_dir_url( AAA_OPTION_OPTIMIZER_FILE ) . 'css/style.css', + 'aaa-meta-optimizer', + plugin_dir_url( AAA_META_OPTIMIZER_FILE ) . 'css/style.css', [], '2.0.1' ); \wp_enqueue_script( 'datatables', - plugin_dir_url( AAA_OPTION_OPTIMIZER_FILE ) . 'js/vendor/datatables.min.js', + plugin_dir_url( AAA_META_OPTIMIZER_FILE ) . 'js/vendor/datatables.min.js', [], // Dependencies. '2.0.1', true // In footer. @@ -103,62 +103,62 @@ public function enqueue_scripts( $hook ) { \wp_enqueue_style( 'datatables', - plugin_dir_url( AAA_OPTION_OPTIMIZER_FILE ) . 'js/vendor/datatables.min.css', + plugin_dir_url( AAA_META_OPTIMIZER_FILE ) . 'js/vendor/datatables.min.css', [], '2.0.1' ); \wp_enqueue_script( - 'aaa-option-optimizer-admin-js', - plugin_dir_url( AAA_OPTION_OPTIMIZER_FILE ) . 'js/admin-script.js', + 'aaa-meta-optimizer-admin-js', + plugin_dir_url( AAA_META_OPTIMIZER_FILE ) . 'js/admin-script.js', [ 'jquery', 'datatables' ], // Dependencies. - filemtime( plugin_dir_path( AAA_OPTION_OPTIMIZER_FILE ) . 'js/admin-script.js' ), // Version. + filemtime( plugin_dir_path( AAA_META_OPTIMIZER_FILE ) . 'js/admin-script.js' ), // Version. true // In footer. ); \wp_localize_script( - 'aaa-option-optimizer-admin-js', - 'aaaOptionOptimizer', + 'aaa-meta-optimizer-admin-js', + 'aaaMetaOptimizer', [ 'root' => esc_url_raw( rest_url() ), 'nonce' => wp_create_nonce( 'wp_rest' ), 'i18n' => [ - 'filterBySource' => esc_html__( 'Filter by source', 'aaa-option-optimizer' ), - 'showValue' => esc_html__( 'Show', 'aaa-option-optimizer' ), - 'addAutoload' => esc_html__( 'Add autoload', 'aaa-option-optimizer' ), - 'removeAutoload' => esc_html__( 'Remove autoload', 'aaa-option-optimizer' ), - 'deleteOption' => esc_html__( 'Delete', 'aaa-option-optimizer' ), + 'filterBySource' => esc_html__( 'Filter by source', 'aaa-meta-optimizer' ), + 'showValue' => esc_html__( 'Show', 'aaa-meta-optimizer' ), + 'addAutoload' => esc_html__( 'Add autoload', 'aaa-meta-optimizer' ), + 'removeAutoload' => esc_html__( 'Remove autoload', 'aaa-meta-optimizer' ), + 'deleteOption' => esc_html__( 'Delete', 'aaa-meta-optimizer' ), - 'search' => esc_html__( 'Search:', 'aaa-option-optimizer' ), + 'search' => esc_html__( 'Search:', 'aaa-meta-optimizer' ), 'entries' => [ - '_' => \esc_html__( 'entries', 'aaa-option-optimizer' ), - '1' => \esc_html__( 'entry', 'aaa-option-optimizer' ), + '_' => \esc_html__( 'entries', 'aaa-meta-optimizer' ), + '1' => \esc_html__( 'entry', 'aaa-meta-optimizer' ), ], 'sInfo' => sprintf( // translators: %1$s is the start, %2$s is the end, %3$s is the total, %4$s is the entries. - esc_html__( 'Showing %1$s to %2$s of %3$s %4$s', 'aaa-option-optimizer' ), + esc_html__( 'Showing %1$s to %2$s of %3$s %4$s', 'aaa-meta-optimizer' ), '_START_', '_END_', '_TOTAL_', '_ENTRIES-TOTAL_' ), - 'sInfoEmpty' => esc_html__( 'Showing 0 to 0 of 0 entries', 'aaa-option-optimizer' ), + 'sInfoEmpty' => esc_html__( 'Showing 0 to 0 of 0 entries', 'aaa-meta-optimizer' ), 'sInfoFiltered' => sprintf( // translators: %1$s is the max, %2$s is the entries-max. - esc_html__( '(filtered from %1$s total %2$s)', 'aaa-option-optimizer' ), + esc_html__( '(filtered from %1$s total %2$s)', 'aaa-meta-optimizer' ), '_MAX_', '_ENTRIES-MAX_' ), - 'sZeroRecords' => esc_html__( 'No matching records found', 'aaa-option-optimizer' ), + 'sZeroRecords' => esc_html__( 'No matching records found', 'aaa-meta-optimizer' ), 'oAria' => [ - 'orderable' => esc_html__( ': Activate to sort', 'aaa-option-optimizer' ), - 'orderableReverse' => esc_html__( ': Activate to invert sorting', 'aaa-option-optimizer' ), - 'orderableRemove' => esc_html__( ': Activate to remove sorting', 'aaa-option-optimizer' ), + 'orderable' => esc_html__( ': Activate to sort', 'aaa-meta-optimizer' ), + 'orderableReverse' => esc_html__( ': Activate to invert sorting', 'aaa-meta-optimizer' ), + 'orderableRemove' => esc_html__( ': Activate to remove sorting', 'aaa-meta-optimizer' ), 'paginate' => [ - 'first' => esc_html__( 'First', 'aaa-option-optimizer' ), - 'last' => esc_html__( 'Last', 'aaa-option-optimizer' ), - 'next' => esc_html__( 'Next', 'aaa-option-optimizer' ), - 'previous' => esc_html__( 'Previous', 'aaa-option-optimizer' ), + 'first' => esc_html__( 'First', 'aaa-meta-optimizer' ), + 'last' => esc_html__( 'Last', 'aaa-meta-optimizer' ), + 'next' => esc_html__( 'Next', 'aaa-meta-optimizer' ), + 'previous' => esc_html__( 'Previous', 'aaa-meta-optimizer' ), ], ], ], @@ -180,22 +180,16 @@ public function table_section( $section, $columns ) { foreach ( $columns as $column ) { switch ( $column ) { case 'actions': - echo '' . esc_html__( 'Actions', 'aaa-option-optimizer' ) . ''; - break; - case 'autoload': - echo '' . esc_html__( 'Autoload', 'aaa-option-optimizer' ) . ''; + echo '' . esc_html__( 'Actions', 'aaa-meta-optimizer' ) . ''; break; case 'calls': - echo '' . esc_html__( '# Calls', 'aaa-option-optimizer' ) . ''; + echo '' . esc_html__( '# Calls', 'aaa-meta-optimizer' ) . ''; break; case 'option': - echo '' . esc_html__( 'Option', 'aaa-option-optimizer' ) . ''; - break; - case 'size': - echo '' . esc_html__( 'Size (KB)', 'aaa-option-optimizer' ) . ''; + echo '' . esc_html__( 'Option', 'aaa-meta-optimizer' ) . ''; break; case 'source': - echo '' . esc_html__( 'Source', 'aaa-option-optimizer' ) . ''; + echo '' . esc_html__( 'Source', 'aaa-meta-optimizer' ) . ''; break; } } @@ -203,248 +197,95 @@ public function table_section( $section, $columns ) { echo ''; } - /** - * Get the length of a value. - * - * @param mixed $value The input value. - * - * @return string - */ - private function get_length( $value ) { - if ( empty( $value ) ) { - return '0.00'; - } - if ( is_array( $value ) || is_object( $value ) ) { - // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize -- intended here. - $length = strlen( serialize( $value ) ); - } elseif ( is_string( $value ) || is_numeric( $value ) ) { - $length = strlen( strval( $value ) ); - } - if ( ! isset( $length ) ) { - return '0.00'; - } - return number_format( ( $length / 1024 ), 2 ); - } - /** * Renders the admin page. * * @return void */ public function render_admin_page() { - $option_optimizer = get_option( 'option_optimizer', [ 'used_options' => [] ] ); - $all_options = wp_load_alloptions(); - // Filter out transients. - $autoload_options = array_filter( - $all_options, - function ( $value, $key ) { - return strpos( $key, '_transient_' ) === false; - }, - ARRAY_FILTER_USE_BOTH - ); + global $wpdb; + $meta_optimizer = get_option( 'meta_optimizer', [ 'used_meta_fields' => [] ] ); - $unused_options = []; - $non_autoloaded_options = []; + $all_meta_keys = $wpdb->get_results( "SELECT DISTINCT meta_key FROM {$wpdb->postmeta}", ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching + $all_meta_keys = wp_list_pluck( $all_meta_keys, 'meta_key' ); - // Get the autoloaded options that aren't used. - foreach ( $autoload_options as $option => $value ) { - if ( isset( $option_optimizer['used_options'][ $option ] ) ) { - continue; - } - $unused_options[ $option ] = $value; - } + $unused_meta_fields = []; - // Determine the options that _are_ used, but not auto-loaded. - foreach ( $option_optimizer['used_options'] as $option => $count ) { - if ( isset( $autoload_options[ $option ] ) ) { + // Get the meta fields that aren't used. + foreach ( $all_meta_keys as $meta_key ) { + if ( isset( $meta_optimizer['used_meta_fields'][ $meta_key ] ) ) { continue; } - $non_autoloaded_options[ $option ] = $count; - } - - // Some of the options that are used but not auto-loaded, may not exist. - if ( ! empty( $non_autoloaded_options ) ) { - $options_that_do_not_exist = []; - $non_autoloaded_options_full = []; - foreach ( $non_autoloaded_options as $option => $count ) { - $value = get_option( $option, 'aaa-no-return-value' ); - if ( $value === 'aaa-no-return-value' ) { - $options_that_do_not_exist[ $option ] = $count; - continue; - } - $non_autoloaded_options_full[ $option ] = [ - 'count' => $count, - 'value' => $value, - ]; - } + $unused_meta_fields[ $meta_key ] = true; } // Start HTML output. - echo '

' . esc_html__( 'AAA Option Optimizer', 'aaa-option-optimizer' ) . '

'; - - global $wpdb; - $autoload_values = \wp_autoload_values_to_autoload(); - $placeholders = implode( ',', array_fill( 0, count( $autoload_values ), '%s' ) ); - - // phpcs:disable WordPress.DB - $result = $wpdb->get_row( - $wpdb->prepare( "SELECT count(*) AS count, SUM( LENGTH( option_value ) ) as autoload_size FROM {$wpdb->options} WHERE autoload IN ( $placeholders )", $autoload_values ) - ); - // phpcs:enable WordPress.DB - - echo '

' . esc_html__( 'Stats', 'aaa-option-optimizer' ) . '

'; - echo '

' . - sprintf( - // translators: %1$s is the date, %2$s is the number of options at stat, %3$s is the size at start in KB, %4$s is the number of options now, %5$s is the size in KB now. - esc_html__( 'When you started on %1$s you had %2$s autoloaded options, for %3$sKB of memory. Now you have %4$s options, for %5$sKB of memory.', 'aaa-option-optimizer' ), - esc_html( gmdate( 'Y-m-d', strtotime( $option_optimizer['starting_point_date'] ) ) ), - isset( $option_optimizer['starting_point_num'] ) ? esc_html( $option_optimizer['starting_point_num'] ) : '-', - number_format( ( $option_optimizer['starting_point_kb'] ), 1 ), - esc_html( $result->count ), - number_format( ( $result->autoload_size / 1024 ), 1 ) - ) . '

'; + echo '

' . esc_html__( 'AAA Meta Optimizer', 'aaa-meta-optimizer' ) . '

'; - echo '

' . esc_html__( 'Optimize', 'aaa-option-optimizer' ) . '

'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- nonce is used for REST API. if ( isset( $_GET['tracking_reset'] ) && $_GET['tracking_reset'] === 'true' ) { - echo '

' . esc_html__( 'Tracking data has been reset.', 'aaa-option-optimizer' ) . '

'; + echo '

' . esc_html__( 'Tracking data has been reset.', 'aaa-meta-optimizer' ) . '

'; // Take the parameter out of the URL without reloading the page. echo ''; } - echo '
'; - echo '

' . esc_html__( 'We\'ve found the following things you can maybe optimize:', 'aaa-option-optimizer' ) . '

'; + echo '
'; ?>
- +
' . esc_html__( 'Unused, but autoloaded', 'aaa-option-optimizer' ) . ''; - if ( ! empty( $unused_options ) ) { - echo '

' . esc_html__( 'The following options are autoloaded on each pageload, but AAA Option Optimizer has not been able to detect them being used.', 'aaa-option-optimizer' ); + echo '

' . esc_html__( 'Unused meta fields', 'aaa-meta-optimizer' ) . '

'; + if ( ! empty( $unused_meta_fields ) ) { + echo '

' . esc_html__( 'The following meta fields are not used.', 'aaa-meta-optimizer' ); echo ''; - $this->table_section( 'thead', [ 'option', 'source', 'size', 'autoload', 'actions' ] ); + $this->table_section( 'thead', [ 'option', 'source', 'actions' ] ); echo ''; - foreach ( $unused_options as $option => $value ) { + foreach ( $unused_meta_fields as $option => $value ) { echo ''; echo ''; - echo ''; - echo ''; echo ''; } echo ''; - $this->table_section( 'tfoot', [ 'option', 'source', 'size', 'autoload', 'actions' ] ); + $this->table_section( 'tfoot', [ 'option', 'source', 'actions' ] ); echo '
' . esc_html( $option ) . '' . esc_html( $this->get_plugin_name( $option ) ) . '' . esc_html( $this->get_length( $value ) ) . 'yes'; - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- output escaped in get_value_button. - echo $this->get_value_button( $option, $value ); - echo ' '; - echo ' '; echo '
'; } else { - echo '

' . esc_html__( 'All autoloaded options are in use.', 'aaa-option-optimizer' ) . '

'; + echo '

' . esc_html__( 'All meta fields are in use.', 'aaa-meta-optimizer' ) . '

'; } ?>
- +
' . esc_html__( 'Used, but not autoloaded options', 'aaa-option-optimizer' ) . ''; - echo '

' . esc_html__( 'The following options are *not* autoloaded on each pageload, but AAA Option Optimizer has detected that they are being used. If one of the options below has been called a lot and is not very big, you might consider adding autoload to that option.', 'aaa-option-optimizer' ); + if ( ! empty( $meta_optimizer['used_meta_fields'] ) ) { + echo '

' . esc_html__( 'Used meta fields', 'aaa-meta-optimizer' ) . '

'; + echo '

' . esc_html__( 'The following meta fields are being used.', 'aaa-meta-optimizer' ); echo ''; - $this->table_section( 'thead', [ 'option', 'source', 'size', 'autoload', 'calls', 'actions' ] ); + $this->table_section( 'thead', [ 'option', 'source', 'calls', 'actions' ] ); echo ''; - foreach ( $non_autoloaded_options_full as $option => $arr ) { + foreach ( $meta_optimizer['used_meta_fields'] as $option => $arr ) { echo ''; echo ''; echo ''; - echo ''; - echo ''; - echo ''; + echo ''; echo ''; } echo ''; - $this->table_section( 'tfoot', [ 'option', 'source', 'size', 'autoload', 'calls', 'actions' ] ); - echo '
' . esc_html( $option ) . '' . esc_html( $this->get_plugin_name( $option ) ) . '' . esc_html( $this->get_length( $arr['value'] ) ) . 'no' . esc_html( $arr['count'] ) . '' . esc_html( $arr ) . ''; - // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- output escaped in get_value_button. - echo $this->get_value_button( $option, $arr['value'] ); - echo ' '; echo '
'; - } else { - echo '

' . esc_html__( 'All options that are used are autoloaded.', 'aaa-option-optimizer' ) . '

'; - } - ?> -
- - -
- ' . esc_html__( 'Requested options that do not exist', 'aaa-option-optimizer' ) . ''; - echo '

' . esc_html__( 'The following options are requested sometimes, but AAA Option Optimizer has detected that they do not exist. If one of the options below has been called a lot, it might help to create it with a value of false.', 'aaa-option-optimizer' ); - echo ''; - $this->table_section( 'thead', [ 'option', 'source', 'calls', 'actions' ] ); - echo ''; - foreach ( $options_that_do_not_exist as $option => $count ) { - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; $this->table_section( 'tfoot', [ 'option', 'source', 'calls', 'actions' ] ); echo '
' . esc_html( $option ) . '' . esc_html( $this->get_plugin_name( $option ) ) . '' . esc_html( $count ) . ' '; - } - echo '
'; + } else { + echo '

' . esc_html__( 'There are no used meta fields.', 'aaa-meta-optimizer' ) . '

'; } ?>
- - -
-

- - - table_section( 'thead', [ 'option', 'source', 'size', 'autoload', 'actions' ] ); ?> - - - - - - - - - - table_section( 'tfoot', [ 'option', 'source', 'size', 'autoload', 'actions' ] ); ?> - -
' . esc_html__( 'Show', 'aaa-option-optimizer' ) . ' -
- ' . - // translators: %s is the name of the option. - '

' . sprintf( esc_html__( 'Value of %s', 'aaa-option-optimizer' ), '' . esc_html( $name ) . '' ) . '

-
' . htmlentities( $string, ENT_QUOTES | ENT_SUBSTITUTE ) . '
-
'; - } - /** * Find plugin in known plugin prefixes list. * diff --git a/src/class-map-plugin-to-options.php b/src/class-map-plugin-to-options.php index 2732f9a..93741ec 100644 --- a/src/class-map-plugin-to-options.php +++ b/src/class-map-plugin-to-options.php @@ -2,15 +2,15 @@ /** * Functionality to map options to plugins. * - * @package Emilia\OptionOptimizer + * @package Emilia\MetaOptimizer */ -namespace Emilia\OptionOptimizer; +namespace Emilia\MetaOptimizer; /** * Class Map_Plugin_To_Options * - * @package Emilia\OptionOptimizer + * @package Emilia\MetaOptimizer */ class Map_Plugin_To_Options { /** @@ -30,7 +30,7 @@ class Map_Plugin_To_Options { public function get_plugin_name( string $option ): string { $plugins_list = []; if ( empty( $this->plugins_list ) ) { - $this->plugins_list = json_decode( file_get_contents( plugin_dir_path( AAA_OPTION_OPTIMIZER_FILE ) . 'known-plugins/known-plugins.json' ), true ); + $this->plugins_list = json_decode( file_get_contents( plugin_dir_path( AAA_META_OPTIMIZER_FILE ) . 'known-plugins/known-plugins.json' ), true ); } // for each plugin in the list, check if the option starts with the prefix. @@ -44,6 +44,6 @@ public function get_plugin_name( string $option ): string { } } - return __( 'Unknown', 'aaa-option-optimizer' ); + return __( 'Unknown', 'aaa-meta-optimizer' ); } } diff --git a/src/class-plugin.php b/src/class-plugin.php index a679ed2..b42f17f 100644 --- a/src/class-plugin.php +++ b/src/class-plugin.php @@ -2,10 +2,10 @@ /** * Plugin functionality for AAA Option Optimizer. * - * @package Emilia\OptionOptimizer + * @package Emilia\MetaOptimizer */ -namespace Emilia\OptionOptimizer; +namespace Emilia\MetaOptimizer; /** * Core functionality of AAA Option Optimizer. @@ -19,11 +19,11 @@ class Plugin { public static $instance; /** - * Holds the names of the options accessed during the request. + * Holds the names of the meta fields accessed during the request. * * @var string[] */ - protected $accessed_options = []; + protected $accessed_meta_fields = []; /** * Whether the plugin should reset the option_optimizer data. @@ -60,14 +60,14 @@ public static function get_instance() { * @return void */ public function register_hooks() { - $this->accessed_options = \get_option( 'option_optimizer', [ 'used_options' => [] ] )['used_options']; + $this->accessed_meta_fields = \get_option( 'meta_optimizer', [ 'used_meta_fields' => [] ] )['used_meta_fields']; // Hook into all actions and filters to monitor option accesses. // @phpstan-ignore-next-line -- The 'all' hook does not need a return. - \add_filter( 'all', [ $this, 'monitor_option_accesses' ] ); + \add_filter( 'all', [ $this, 'monitor_meta_field_accesses' ] ); // Use the shutdown action to update the option with tracked data. - \add_action( 'shutdown', [ $this, 'update_tracked_options' ] ); + \add_action( 'shutdown', [ $this, 'update_tracked_meta_fields' ] ); // Register the REST routes. $rest = new REST(); @@ -98,50 +98,73 @@ public function reset( $should_reset = true ) { * * @return void */ - public function monitor_option_accesses( $tag ) { - // Check if the tag is related to an option access. - if ( strpos( $tag, 'option_' ) === 0 ) { - $option_name = substr( $tag, strlen( 'option_' ) ); - $this->add_option_usage( $option_name ); + public function monitor_meta_field_accesses( $tag ) { + + // Check if the tag is related to a post meta field access. + if ( 'get_post_metadata' === $tag ) { + $args = func_get_args(); // phpcs:ignore -- Get all arguments passed to the hook. + $meta_key = $args[3]; + $this->add_meta_field_usage( $meta_key ); + } + + // Check if the tag is related to a default post meta field access, meaning that the meta field doesn't exist in the database yet. + if ( 'default_post_metadata' === $tag ) { + $args = func_get_args(); // phpcs:ignore -- Get all arguments passed to the hook. + $meta_key = $args[3]; + $this->remove_meta_field_usage( $meta_key ); } } /** - * Add an option to the list of used options if it's not already there. + * Add a meta field to the list of used meta fields if it's not already there. * - * @param string $option_name Name of the option being accessed. + * @param string $meta_key Name of the meta field being accessed. * * @return void */ - protected function add_option_usage( $option_name ) { + protected function add_meta_field_usage( $meta_key ) { // Check if this option hasn't been tracked yet and add it to the array. - if ( ! array_key_exists( $option_name, $this->accessed_options ) ) { - $this->accessed_options[ $option_name ] = 1; + if ( ! array_key_exists( $meta_key, $this->accessed_meta_fields ) ) { + $this->accessed_meta_fields[ $meta_key ] = 1; return; } - ++$this->accessed_options[ $option_name ]; + ++$this->accessed_meta_fields[ $meta_key ]; + } + + /** + * Add a meta field to the list of used meta fields if it's not already there. + * + * @param string $meta_key Name of the meta field being accessed. + * + * @return void + */ + protected function remove_meta_field_usage( $meta_key ) { + // Check if this option hasn't been tracked yet and add it to the array. + if ( array_key_exists( $meta_key, $this->accessed_meta_fields ) ) { + unset( $this->accessed_meta_fields[ $meta_key ] ); + } } /** - * Update the 'option_optimizer' option with the list of used options at the end of the page load. + * Update the 'meta_optimizer' option with the list of used meta fields at the end of the page load. * * @return void */ - public function update_tracked_options() { + public function update_tracked_meta_fields() { // phpcs:ignore WordPress.Security.NonceVerification -- not doing anything. - if ( isset( $_GET['page'] ) && $_GET['page'] === 'aaa-option-optimizer' ) { + if ( isset( $_GET['page'] ) && $_GET['page'] === 'aaa-meta-optimizer' ) { return; } - // Retrieve the existing option_optimizer data. - $option_optimizer = get_option( 'option_optimizer', [ 'used_options' => [] ] ); + // Retrieve the existing meta_optimizer data. + $meta_optimizer = get_option( 'meta_optimizer', [ 'used_meta_fields' => [] ] ); - $option_optimizer['used_options'] = $this->accessed_options; + $meta_optimizer['used_meta_fields'] = $this->accessed_meta_fields; if ( $this->should_reset ) { - $option_optimizer['used_options'] = []; + $meta_optimizer['used_meta_fields'] = []; } - // Update the 'option_optimizer' option with the new list. - update_option( 'option_optimizer', $option_optimizer, true ); + // Update the 'meta_optimizer' option with the new list. + update_option( 'meta_optimizer', $meta_optimizer, true ); } } diff --git a/src/class-rest.php b/src/class-rest.php index f32ec3f..0b54570 100644 --- a/src/class-rest.php +++ b/src/class-rest.php @@ -2,13 +2,12 @@ /** * REST functionality for AAA Option Optimizer. * - * @package Emilia\OptionOptimizer + * @package Emilia\MetaOptimizer */ -namespace Emilia\OptionOptimizer; +namespace Emilia\MetaOptimizer; use WP_Error; -use WP_REST_Request; use WP_REST_Response; /** @@ -16,21 +15,12 @@ */ class REST { - /** - * The map plugin to options class. - * - * @var Map_Plugin_To_Options - */ - private $map_plugin_to_options; - /** * Registers hooks. * * @return void */ public function register_hooks() { - $this->map_plugin_to_options = new Map_Plugin_To_Options(); - add_action( 'rest_api_init', [ $this, 'register_rest_routes' ] ); } @@ -40,78 +30,9 @@ public function register_hooks() { * @return void */ public function register_rest_routes() { - \register_rest_route( - 'aaa-option-optimizer/v1', - '/update-autoload', - [ - 'methods' => 'POST', - 'callback' => [ $this, 'update_option_autoload' ], - 'permission_callback' => function () { - return current_user_can( 'manage_options' ); - }, - 'args' => [ - 'option_name' => [ - 'required' => true, - 'sanitize_callback' => 'sanitize_text_field', - ], - 'autoload' => [ - 'required' => true, - 'sanitize_callback' => 'sanitize_text_field', - ], - ], - ] - ); \register_rest_route( - 'aaa-option-optimizer/v1', - '/delete-option', - [ - 'methods' => 'POST', - 'callback' => [ $this, 'delete_option' ], - 'permission_callback' => function () { - return current_user_can( 'manage_options' ); - }, - 'args' => [ - 'option_name' => [ - 'required' => true, - 'sanitize_callback' => 'sanitize_text_field', - ], - ], - ] - ); - - \register_rest_route( - 'aaa-option-optimizer/v1', - '/create-option-false', - [ - 'methods' => 'POST', - 'callback' => [ $this, 'create_option_false' ], - 'permission_callback' => function () { - return current_user_can( 'manage_options' ); - }, - 'args' => [ - 'option_name' => [ - 'required' => true, - 'sanitize_callback' => 'sanitize_text_field', - ], - ], - ] - ); - - \register_rest_route( - 'aaa-option-optimizer/v1', - '/all-options', - [ - 'methods' => 'GET', - 'callback' => [ $this, 'get_all_options' ], - 'permission_callback' => function () { - return current_user_can( 'manage_options' ); - }, - ] - ); - - \register_rest_route( - 'aaa-option-optimizer/v1', + 'aaa-meta-optimizer/v1', '/reset', [ 'methods' => 'POST', @@ -132,92 +53,4 @@ public function reset_stats() { Plugin::get_instance()->reset(); return new \WP_REST_Response( [ 'success' => true ], 200 ); } - - /** - * Update autoload status of an option. - * - * @return \WP_Error|\WP_REST_Response - */ - public function get_all_options() { - global $wpdb; - - $output = []; - // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- We need to query all options. - $options = $wpdb->get_results( "SELECT option_name, option_value, autoload FROM $wpdb->options" ); - foreach ( $options as $option ) { - $output[] = [ - 'name' => $option->option_name, - 'plugin' => $this->map_plugin_to_options->get_plugin_name( $option->option_name ), - 'value' => htmlentities( $option->option_value, ENT_QUOTES | ENT_SUBSTITUTE ), - 'size' => number_format( strlen( $option->option_value ) / 1024, 2 ), - 'autoload' => $option->autoload, - 'row_id' => 'option_' . $option->option_name, - ]; - } - return new \WP_REST_Response( [ 'data' => $output ], 200 ); - } - - /** - * Update autoload status of an option. - * - * @param \WP_REST_Request $request The REST request object. - * - * @return \WP_Error|\WP_REST_Response - */ - public function update_option_autoload( $request ) { - $option_name = $request['option_name']; - $autoload = $request['autoload']; - $option_value = get_option( $option_name ); - - if ( ! in_array( $autoload, [ 'yes', 'on', 'no', 'off','auto', 'auto-on', 'auto-off' ], true ) ) { - return new \WP_Error( 'invalid_autoload_value', 'Invalid autoload value', [ 'status' => 400 ] ); - } - - if ( false === $option_value ) { - return new \WP_Error( 'option_not_found', 'Option does not exist', [ 'status' => 404 ] ); - } - - delete_option( $option_name ); - $autoload_values = \wp_autoload_values_to_autoload(); - $bool_autoload = false; - if ( in_array( $autoload, $autoload_values, true ) ) { - $bool_autoload = true; - } - $succeeded = add_option( $option_name, $option_value, '', $bool_autoload ); - - if ( ! $succeeded ) { - return new \WP_Error( 'update_failed', 'Updating the option failed', [ 'status' => 400 ] ); - } - return new \WP_REST_Response( [ 'success' => true ], 200 ); - } - - /** - * Delete an option. - * - * @param \WP_REST_Request $request The REST request object. - * - * @return \WP_REST_Response|\WP_Error - */ - public function delete_option( $request ) { - $option_name = $request['option_name']; - if ( delete_option( $option_name ) ) { - return new \WP_REST_Response( [ 'success' => true ], 200 ); - } - return new \WP_Error( 'option_not_found_or_deleted', 'Option does not exist or could not be deleted', [ 'status' => 404 ] ); - } - - /** - * Create an option with a false value. - * - * @param \WP_REST_Request $request The REST request object. - * - * @return \WP_Error|\WP_REST_Response - */ - public function create_option_false( $request ) { - $option_name = $request['option_name']; - if ( add_option( $option_name, false, '', false ) ) { - return new \WP_REST_Response( [ 'success' => true ], 200 ); - } - return new \WP_Error( 'option_not_created', 'Option could not be created', [ 'status' => 400 ] ); - } } diff --git a/uninstall.php b/uninstall.php index 4fa17e2..25981cd 100644 --- a/uninstall.php +++ b/uninstall.php @@ -13,4 +13,4 @@ } // Delete the plugin option. -delete_option( 'option_optimizer' ); +delete_option( 'meta_optimizer' );