build: 移植 PHPCS + PHPStan L6 品質 gate(PR-I 前半)
- phpcs.xml(自 A 移植):ruleset 改名、*/tools/* 例外換成 */back-compat/*、 中文註解全域排除 Squiz.Commenting.InlineComment.InvalidEndChar、 interface 別名檔排除 OneObjectStructurePerFile - 檔頭正規化:16 個檔案的 declare(strict_types=1) 與前導 // 註解移到 file docblock 之後,並移除 <?php 後多餘空行(phpcbf 另自動修 190 處) - phpstan.neon + .phpstan/stubs.php(TMDO_ 與 WPDO_ 兩套常數)+ 重新產生的 phpstan-baseline.neon(710 errors,A 的 3877 行 baseline 因前綴與路徑不同無法沿用) 現況:PHPCS 0 errors / 0 warnings、PHPStan L6 No errors、 unit 451 / integration 398 GREEN Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
This commit is contained in:
@@ -0,0 +1,245 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset name="2meet Data Optimizer">
|
||||
<description>WPCS ruleset for WP Data Optimizer plugin.</description>
|
||||
|
||||
<!-- Scan these files/directories -->
|
||||
<file>.</file>
|
||||
|
||||
<!-- Exclude vendor and test directories -->
|
||||
<exclude-pattern>*/vendor/*</exclude-pattern>
|
||||
<exclude-pattern>*/tests/*</exclude-pattern>
|
||||
<exclude-pattern>*/back-compat/*</exclude-pattern>
|
||||
<exclude-pattern>*/node_modules/*</exclude-pattern>
|
||||
<!-- v2.13.4: JS files are out of PHPCS scope (use ESLint instead) -->
|
||||
<exclude-pattern>*/admin/assets/*.js</exclude-pattern>
|
||||
|
||||
<!-- Only lint PHP files -->
|
||||
<arg name="extensions" value="php"/>
|
||||
|
||||
<!--
|
||||
UAE-ported files: includes/adapters/ and includes/engine/ were ported wholesale
|
||||
from UAE in PR-1. File-level phpcs:disable comments have been replaced with these
|
||||
sniff-level directory exclusions. Auto-fixable violations (7) were fixed with phpcbf.
|
||||
Rules already globally excluded (NotPrepared, NoSilencedErrors, file_get_contents,
|
||||
UnusedFunctionParameter) are not repeated here.
|
||||
-->
|
||||
<!-- Doc-comment style sniffs: FunctionComment, ClassComment, InlineComment, etc. -->
|
||||
<rule ref="Squiz.Commenting.FunctionComment">
|
||||
<exclude-pattern>*/includes/adapters/*</exclude-pattern>
|
||||
<exclude-pattern>*/includes/engine/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="Squiz.Commenting.ClassComment">
|
||||
<exclude-pattern>*/includes/adapters/*</exclude-pattern>
|
||||
<exclude-pattern>*/includes/engine/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="Squiz.Commenting.FileComment">
|
||||
<exclude-pattern>*/includes/adapters/*</exclude-pattern>
|
||||
<exclude-pattern>*/includes/engine/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="Squiz.Commenting.InlineComment">
|
||||
<exclude-pattern>*/includes/adapters/*</exclude-pattern>
|
||||
<exclude-pattern>*/includes/engine/*</exclude-pattern>
|
||||
<!-- Comments in this codebase are predominantly Chinese; the sniff only
|
||||
accepts . ! ? as terminators, so 。 always trips it. -->
|
||||
<exclude name="Squiz.Commenting.InlineComment.InvalidEndChar"/>
|
||||
</rule>
|
||||
|
||||
<!-- interface-entity-adapter.php declares the WPDO_ alias interface next to
|
||||
the real one on purpose, so `instanceof WPDO_Entity_Adapter_Interface`
|
||||
works for classes implementing the TMDO_ name. -->
|
||||
<rule ref="Generic.Files.OneObjectStructurePerFile">
|
||||
<exclude-pattern>*/includes/adapters/interface-entity-adapter.php</exclude-pattern>
|
||||
<exclude-pattern>*/includes/back-compat/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="Squiz.Commenting.VariableComment">
|
||||
<exclude-pattern>*/includes/adapters/*</exclude-pattern>
|
||||
<exclude-pattern>*/includes/engine/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="Generic.Commenting.DocComment">
|
||||
<exclude-pattern>*/includes/adapters/*</exclude-pattern>
|
||||
<exclude-pattern>*/includes/engine/*</exclude-pattern>
|
||||
</rule>
|
||||
<!-- PHP style / structure sniffs -->
|
||||
<rule ref="Squiz.PHP.DisallowMultipleAssignments">
|
||||
<exclude-pattern>*/includes/adapters/*</exclude-pattern>
|
||||
<exclude-pattern>*/includes/engine/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="Squiz.PHP.DisallowSizeFunctionsInLoops">
|
||||
<exclude-pattern>*/includes/adapters/*</exclude-pattern>
|
||||
<exclude-pattern>*/includes/engine/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="Squiz.PHP.CommentedOutCode">
|
||||
<exclude-pattern>*/includes/adapters/*</exclude-pattern>
|
||||
<exclude-pattern>*/includes/engine/*</exclude-pattern>
|
||||
</rule>
|
||||
<!-- WordPress-specific sniffs -->
|
||||
<rule ref="WordPress.DB.PreparedSQL.InterpolatedNotPrepared">
|
||||
<exclude-pattern>*/includes/adapters/*</exclude-pattern>
|
||||
<exclude-pattern>*/includes/engine/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber">
|
||||
<exclude-pattern>*/includes/adapters/*</exclude-pattern>
|
||||
<exclude-pattern>*/includes/engine/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="WordPress.PHP.YodaConditions">
|
||||
<exclude-pattern>*/includes/adapters/*</exclude-pattern>
|
||||
<exclude-pattern>*/includes/engine/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="WordPress.WP.I18n.MissingTranslatorsComment">
|
||||
<exclude-pattern>*/includes/adapters/*</exclude-pattern>
|
||||
<exclude-pattern>*/includes/engine/*</exclude-pattern>
|
||||
</rule>
|
||||
<!-- Universal naming: avoids PHP reserved words as param names -->
|
||||
<rule ref="Universal.NamingConventions.NoReservedKeywordParameterNames">
|
||||
<exclude-pattern>*/includes/adapters/*</exclude-pattern>
|
||||
<exclude-pattern>*/includes/engine/*</exclude-pattern>
|
||||
</rule>
|
||||
|
||||
<!--
|
||||
Migration phase objects: throw new \RuntimeException(...) is never echoed to
|
||||
the browser — it is caught by WPDO_Migration_Orchestrator and turned into a
|
||||
structured array. EscapeOutput fires on the raw string inside the throw expression.
|
||||
-->
|
||||
<rule ref="WordPress.Security.EscapeOutput">
|
||||
<exclude-pattern>*/migration/phases/*</exclude-pattern>
|
||||
</rule>
|
||||
<!--
|
||||
Migration phase SQL: table names come from WPDO_DB::table() / $wpdb core
|
||||
properties and are sanitized by Schema_Manager::sanitize_column_name().
|
||||
User-controlled values always go through $wpdb->prepare() placeholders.
|
||||
-->
|
||||
<rule ref="WordPress.DB.PreparedSQL.InterpolatedNotPrepared">
|
||||
<exclude-pattern>*/migration/phases/*</exclude-pattern>
|
||||
</rule>
|
||||
|
||||
<!--
|
||||
WP-CLI callbacks must accept ($args, $assoc_args) by framework contract.
|
||||
MissingParamTag fires when only one of the two is used.
|
||||
ShortNotCapital fires on WP-CLI-style imperative command descriptions.
|
||||
-->
|
||||
<rule ref="Squiz.Commenting.FunctionComment.MissingParamTag">
|
||||
<exclude-pattern>*/cli/*</exclude-pattern>
|
||||
</rule>
|
||||
<rule ref="Generic.Commenting.DocComment.ShortNotCapital">
|
||||
<exclude-pattern>*/cli/*</exclude-pattern>
|
||||
</rule>
|
||||
|
||||
<!-- Use WordPress Coding Standards -->
|
||||
<rule ref="WordPress">
|
||||
<!--
|
||||
This plugin IS the database optimization layer.
|
||||
Direct DB queries are intentional and by design.
|
||||
-->
|
||||
<exclude name="WordPress.DB.DirectDatabaseQuery.DirectQuery" />
|
||||
<exclude name="WordPress.DB.DirectDatabaseQuery.NoCaching" />
|
||||
<exclude name="WordPress.DB.DirectDatabaseQuery.SchemaChange" />
|
||||
|
||||
<!--
|
||||
Slow DB queries (meta_key / meta_value) are intentional —
|
||||
the plugin migrates data AWAY from these patterns.
|
||||
-->
|
||||
<exclude name="WordPress.DB.SlowDBQuery.slow_db_query_meta_key" />
|
||||
<exclude name="WordPress.DB.SlowDBQuery.slow_db_query_meta_value" />
|
||||
|
||||
<!--
|
||||
error_log() usage is intentional in WPDO_Logger for dev environments.
|
||||
The production build suppresses it via feature flag.
|
||||
-->
|
||||
<exclude name="WordPress.PHP.DevelopmentFunctions.error_log_error_log" />
|
||||
|
||||
<!--
|
||||
base64_encode/decode used for gzip archive compression in Zone D.
|
||||
This is data storage, not obfuscation.
|
||||
-->
|
||||
<exclude name="WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode" />
|
||||
<exclude name="WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode" />
|
||||
|
||||
<!-- rand() → wp_rand() not applicable for benchmark timing -->
|
||||
<exclude name="WordPress.WP.AlternativeFunctions.rand_rand" />
|
||||
|
||||
<!--
|
||||
Slash-separated hook names (wpdo/health_alert_critical, wpdo/fsm_guard/bypass, etc.)
|
||||
are intentional — they follow the WP Core convention for scoped action namespaces
|
||||
(e.g. 'customize_save_{$id}', 'heartbeat_received', 'rest_api_init').
|
||||
Partner plugins subscribe to these hooks; renaming would be a breaking API change.
|
||||
-->
|
||||
<exclude name="WordPress.NamingConventions.ValidHookName.UseUnderscores" />
|
||||
|
||||
<!--
|
||||
File system operations (fopen/fwrite/fclose/file_put_contents/file_get_contents/unlink)
|
||||
are intentional in snapshot/backup code and CLI benchmark/export handlers.
|
||||
WP_Filesystem is not available outside wp-admin context and introduces state
|
||||
that complicates CLI and cron use-cases. The backup directory is created with
|
||||
wp_mkdir_p and access-controlled via .htaccess / direct_filesystem fallback.
|
||||
-->
|
||||
<exclude name="WordPress.WP.AlternativeFunctions.file_system_operations_fopen" />
|
||||
<exclude name="WordPress.WP.AlternativeFunctions.file_system_operations_fwrite" />
|
||||
<exclude name="WordPress.WP.AlternativeFunctions.file_system_operations_fclose" />
|
||||
<exclude name="WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents" />
|
||||
<exclude name="WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents" />
|
||||
<exclude name="WordPress.WP.AlternativeFunctions.unlink_unlink" />
|
||||
<exclude name="WordPress.WP.AlternativeFunctions.file_system_operations_is_writable" />
|
||||
|
||||
<!--
|
||||
manage_woocommerce is a standard WooCommerce capability, not a custom one.
|
||||
WPCS cannot know third-party capabilities; this is a known false-positive.
|
||||
-->
|
||||
<exclude name="WordPress.WP.Capabilities.Unknown" />
|
||||
|
||||
<!--
|
||||
REST API callbacks must accept WP_REST_Request $request even when not used
|
||||
(e.g. /status endpoints). Removing the param breaks WP REST contract.
|
||||
-->
|
||||
<exclude name="Generic.CodeAnalysis.UnusedFunctionParameter.Found" />
|
||||
<exclude name="Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed" />
|
||||
|
||||
<!--
|
||||
Snapshot / migration backup paths use @chmod on freshly-created files
|
||||
inside admin-only context. Failure-to-chmod is non-fatal (we still
|
||||
have .htaccess deny + dir-level guards) and surfacing the notice
|
||||
would mask other diagnostics. Documented in
|
||||
class-wpdo-migration-orchestrator.php / class-wpdo-snapshot-*.
|
||||
-->
|
||||
<exclude name="WordPress.PHP.NoSilencedErrors.Discouraged" />
|
||||
|
||||
<!--
|
||||
chmod() / mkdir() / rename() / fseek() / etc are intentional in
|
||||
snapshot/backup write paths. WP_Filesystem is unavailable outside
|
||||
wp-admin context (we run in CLI + cron + admin) and introduces
|
||||
unwanted state. The fopen/fwrite/file_put_contents/unlink rules
|
||||
are already excluded above; chmod / mkdir need their own excludes.
|
||||
-->
|
||||
<exclude name="WordPress.WP.AlternativeFunctions.file_system_operations_chmod" />
|
||||
<exclude name="WordPress.WP.AlternativeFunctions.file_system_operations_mkdir" />
|
||||
<exclude name="WordPress.WP.AlternativeFunctions.rename_rename" />
|
||||
|
||||
<!--
|
||||
Dynamic SQL with $wpdb->prepare() flagged "Replacement variables found,
|
||||
but no valid placeholders found" when placeholders live in interpolated
|
||||
sub-strings (e.g. table names from sanitize_key, IN-list expansion).
|
||||
Each call site has phpcs:ignore comments documenting why; project-wide
|
||||
silence avoids cluttering every call.
|
||||
-->
|
||||
<exclude name="WordPress.DB.PreparedSQL.NotPrepared" />
|
||||
<exclude name="WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare" />
|
||||
</rule>
|
||||
|
||||
<!--
|
||||
Slash-separated hook name delimiter (wpdo/zone/event pattern).
|
||||
Redundant with the UseUnderscores exclude above, but belt-and-suspenders.
|
||||
-->
|
||||
<rule ref="WordPress.NamingConventions.ValidHookName">
|
||||
<properties>
|
||||
<property name="additionalWordDelimiters" value="/"/>
|
||||
</properties>
|
||||
</rule>
|
||||
|
||||
<!-- Allow short ternary (?:) — used extensively in this codebase -->
|
||||
<rule ref="Universal.Operators.DisallowShortTernary">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<!-- PHP minimum version -->
|
||||
<config name="minimum_supported_wp_version" value="6.0" />
|
||||
<config name="testVersion" value="8.1-" />
|
||||
</ruleset>
|
||||
Reference in New Issue
Block a user