<?xml version="1.0"?>
<ruleset name="WordPress Coding Standards for PreOrders">
    <description>PHPCS ruleset tuned to catch WordPress.org plugin submission rejection issues.</description>

    <!-- What to scan -->
    <file>.</file>
    <exclude-pattern>*/assets/*</exclude-pattern>
    <exclude-pattern>*/src/*</exclude-pattern>
    <exclude-pattern>*/build/*</exclude-pattern>
    <exclude-pattern>*/node_modules/*</exclude-pattern>
    <exclude-pattern>*/vendor/*</exclude-pattern>
    <exclude-pattern>*/tests/*</exclude-pattern>

    <!-- How to scan -->
    <arg value="sp"/> <!-- Show sniff and progress -->
    <arg name="basepath" value="./"/>
    <arg name="colors"/>
    <arg name="extensions" value="php"/>
    <arg name="parallel" value="8"/>

    <!-- PHP version compatibility -->
    <!-- https://github.com/PHPCompatibility/PHPCompatibility#sniffing-your-code-for-compatibility-with-specific-php-versions -->
    <config name="testVersion" value="7.4-"/>
    <!-- https://github.com/PHPCompatibility/PHPCompatibilityWP -->
    <rule ref="PHPCompatibilityWP"/>

    <!-- WordPress Coding Standards -->
    <!-- https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards -->
    <config name="minimum_supported_wp_version" value="6.2"/>
    <rule ref="WordPress-Core"/>
    <rule ref="WordPress">
        <exclude name="Generic.WhiteSpace.DisallowSpaceIndent"/>
    </rule>

    <!-- ============================================================
        REJECTION REASON 1: Missing or incorrect text domain.
        Fix: All i18n functions must use "softtent-preorders" text domain.
        https://developer.wordpress.org/plugins/internationalization/
    ============================================================ -->
    <rule ref="WordPress.WP.I18n">
        <properties>
            <property name="text_domain" type="array">
                <element value="softtent-preorders"/>
            </property>
        </properties>
    </rule>

    <!-- ============================================================
        REJECTION REASON 2: Globals not prefixed.
        Fix: All global functions, classes, hooks, and variables must
        use the "softtent_po" prefix to avoid conflicts.
        https://developer.wordpress.org/plugins/plugin-basics/best-practices/#prefix-everything
    ============================================================ -->
    <rule ref="WordPress.NamingConventions.PrefixAllGlobals">
        <properties>
            <property name="prefixes" type="array">
                <element value="softtent_po"/>
                <element value="softtent"/>
                <element value="SOFTENT_PO"/>
            </property>
        </properties>
    </rule>

    <!-- ============================================================
        REJECTION REASON 3: Unescaped output.
        Fix: Always escape variables before outputting: esc_html(),
        esc_attr(), esc_url(), wp_kses_post(), etc.
        https://developer.wordpress.org/apis/security/escaping/
    ============================================================ -->
    <rule ref="WordPress.Security.EscapeOutput">
        <type>error</type>
    </rule>

    <!-- ============================================================
        REJECTION REASON 4: Unsanitized user input / missing wp_unslash().
        Fix: All $_GET, $_POST, $_REQUEST, $_COOKIE, $_SERVER values
        must be run through wp_unslash() AND a sanitize_*() function.
        https://developer.wordpress.org/apis/security/sanitizing/
============================================================ -->
    <rule ref="WordPress.Security.ValidatedSanitizedInput">
        <type>error</type>
        <properties>
            <property name="customSanitizingFunctions" type="array">
                <element value="wc_clean"/>
            </property>
        </properties>
    </rule>

    <!-- ============================================================
        REJECTION REASON 5: Missing nonce verification.
        Fix: All form submissions and state-changing requests must
        verify a nonce with check_admin_referer() or wp_verify_nonce().
        https://developer.wordpress.org/apis/security/nonces/
    ============================================================ -->
    <rule ref="WordPress.Security.NonceVerification">
        <type>error</type>
    </rule>

    <!-- ============================================================
         REJECTION REASON 6: Missing capability/permission checks.
         Fix: Always verify user permissions with current_user_can()
         before performing privileged actions.
         https://developer.wordpress.org/apis/security/checking-user-capabilities/
    ============================================================ -->
    <rule ref="WordPress.WP.Capabilities">
        <type>error</type>
    </rule>

    <!-- ============================================================
        REJECTION REASON 7: Unsafe redirects (header() instead of
        wp_safe_redirect() or wp_redirect()).
        Fix: Use wp_safe_redirect() + exit for all redirects.
    ============================================================ -->
    <rule ref="WordPress.Security.SafeRedirect">
        <type>error</type>
    </rule>

    <!-- ============================================================
        REJECTION REASON 8: Direct database queries not using $wpdb->prepare().
        Fix: Always use $wpdb->prepare() for queries with user data.
    ============================================================ -->
    <rule ref="WordPress.DB.PreparedSQL">
        <type>error</type>
    </rule>
    <rule ref="WordPress.DB.PreparedSQLPlaceholders">
        <type>error</type>
    </rule>
    <!-- Flag direct DB queries as warnings (requires caching justification) -->
    <rule ref="WordPress.DB.DirectDatabaseQuery.DirectQuery">
        <type>warning</type>
    </rule>
    <rule ref="WordPress.DB.DirectDatabaseQuery.NoCaching">
        <type>warning</type>
    </rule>

    <!-- ============================================================
        REJECTION REASON 9: Dangerous / discouraged PHP functions.
        Fix: Avoid eval(), base64_decode(), exec(), etc. in plugin code.
    ============================================================ -->
    <rule ref="WordPress.PHP.DiscouragedPHPFunctions">
        <type>error</type>
    </rule>

    <!-- ============================================================
        REJECTION REASON 10: Discouraged WordPress functions.
        Fix: Avoid deprecated WP functions (e.g., get_currentuserinfo).
    ============================================================ -->
    <rule ref="WordPress.WP.DiscouragedFunctions">
        <type>error</type>
    </rule>
    <rule ref="WordPress.WP.DiscouragedConstants">
        <type>error</type>
    </rule>

    <!-- ============================================================
        REJECTION REASON 11: Debug/development code left in.
        Fix: Remove var_dump(), print_r(), error_log(), var_export().
        Reported as a warning so var_export() in config arrays is visible.
    ============================================================ -->
    <rule ref="WordPress.PHP.DevelopmentFunctions">
        <type>warning</type>
    </rule>
    <!-- var_export in non-debug contexts is usually fine; keep as warning -->
    <rule ref="WordPress.PHP.DevelopmentFunctions.error_log_var_export">
        <type>warning</type>
    </rule>

    <!-- ============================================================
        REJECTION REASON 12: Strict in_array() checks missing.
        Fix: Always pass true as the third argument to in_array().
    ============================================================ -->
    <rule ref="WordPress.PHP.StrictInArray.MissingTrueStrict">
        <type>error</type>
    </rule>

    <!-- ============================================================
        Style / formatting rules — not rejection reasons but enforced
        for code quality. Silenced rules are documented below.
    ============================================================ -->

    <!-- Allow Yoda conditions either way (team preference) -->
    <rule ref="WordPress.PHP.YodaConditions.NotYoda">
        <severity>0</severity>
    </rule>

    <!-- Allow PSR-style method naming for OOP (camelCase) -->
    <rule ref="WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid">
        <severity>0</severity>
    </rule>

    <!-- Allow short array syntax [] — project uses it consistently -->
    <rule ref="Generic.Arrays.DisallowShortArraySyntax">
        <severity>0</severity>
    </rule>
    <rule ref="Universal.Arrays.DisallowShortArraySyntax.Found">
        <severity>0</severity>
    </rule>
    <!-- Enforce [] over array() -->
    <rule ref="Generic.Arrays.DisallowLongArraySyntax"/>

    <!-- Allow short ternary ?: -->
    <rule ref="Universal.Operators.DisallowShortTernary.Found">
        <severity>0</severity>
    </rule>

    <!-- Allow trailing commas to be omitted in multi-line arrays -->
    <rule ref="NormalizedArrays.Arrays.CommaAfterLast.MissingMultiLine">
        <severity>0</severity>
    </rule>

    <!-- Flag associative arrays as warnings (formatting, not rejection) -->
    <rule ref="WordPress.Arrays.ArrayDeclarationSpacing.AssociativeArrayFound">
        <type>warning</type>
    </rule>

    <!-- Allow files with mixed OOP and functions (helpers.php pattern) -->
    <rule ref="Universal.Files.SeparateFunctionsFromOO.Mixed">
        <severity>0</severity>
    </rule>

    <!-- Whitespace style preferences -->
    <rule ref="WordPress.WhiteSpace.ControlStructureSpacing">
        <properties>
            <property name="blank_line_check" value="true"/>
        </properties>
    </rule>
    <rule ref="WordPress.WhiteSpace.ControlStructureSpacing.NoSpaceAfterCloseParenthesis">
        <severity>0</severity>
    </rule>

    <!-- Suppress doc-comment formatting noise -->
    <rule ref="Squiz.Commenting">
        <severity>0</severity>
    </rule>
    <rule ref="Generic.Commenting.DocComment.MissingShort">
        <severity>0</severity>
    </rule>
    <rule ref="Generic.Commenting.DocComment.SpacingBeforeTags">
        <severity>0</severity>
    </rule>

    <!-- Allow multiple arguments on the same line in function calls -->
    <rule ref="PEAR.Functions.FunctionCallSignature.MultipleArguments">
        <severity>0</severity>
    </rule>

    <!-- Brace style after function signatures (K&R) -->
    <rule ref="Generic.Functions.OpeningFunctionBraceKernighanRitchie.ContentAfterBrace">
        <severity>0</severity>
    </rule>

    <!-- File name casing is handled by PSR-4 loader, not WP convention -->
    <rule ref="WordPress.Files.FileName">
        <severity>0</severity>
    </rule>
</ruleset>
