<?xml version="1.0"?>
<ruleset name="PHP_CodeSniffer">
    <description>Joomunited coding standard for Wordpress plugins</description>

    <file>.</file>

    <arg name="basepath" value="."/>
    <arg name="colors" />
    <arg name="parallel" value="75" />
    <arg name="extensions" value="php"/>

    <!-- Define installed path of standards used -->
    <config name="installed_paths" value="vendor/wimg/php-compatibility,vendor/wp-coding-standards/wpcs" />

    <!-- Memory phpcs can you for this task -->
    <ini name="memory_limit" value="200M"/>

    <!--
    #############################################################################
    Exclude files we did not create
    #############################################################################
    -->
    <exclude-pattern>vendor/*</exclude-pattern>

    <!--
    #############################################################################
    Php compatibility check
    #############################################################################
    -->
    <autoload>vendor/wimg/php-compatibility/PHPCSAliases.php</autoload>
    <rule ref="PHPCompatibility"/>
    <config name="testVersion" value="5.3-"/>

    <!--
	#############################################################################
	Include the whole PSR2 standard
	#############################################################################
	-->
    <rule ref="PSR2">
        <!-- Excluded because of the defined('ABSPATH') check -->
        <exclude name="PSR1.Files.SideEffects" />

        <!-- Excluded because we don't have yet namespace in our plugins -->
        <exclude name="PSR1.Classes.ClassDeclaration" />

        <!-- Allow long line length -->
        <exclude name="Generic.Files.LineLength" />
    </rule>

    <!--
	#############################################################################
	Our own coding style
	#############################################################################
	-->

    <!-- Don't use double quotes -->
    <rule ref="Squiz.Strings.DoubleQuoteUsage"/>
    <rule ref="Squiz.Strings.DoubleQuoteUsage.ContainsVar" />

    <!-- Covers rule: Braces shall be used for all blocks. -->
    <rule ref="Squiz.ControlStructures.ControlSignature"/>

    <!-- Covers rule: Braces should always be used, even when they are not required. -->
    <rule ref="Generic.ControlStructures.InlineControlStructure"/>

    <!-- Covers rule: Never use shorthand PHP start tags. Always use full PHP tags. -->
    <rule ref="Generic.PHP.DisallowShortOpenTag"/>
    <rule ref="Generic.PHP.DisallowAlternativePHPTags"/>

    <!-- Covers rule: Remove trailing whitespace at the end of each line of code. -->
    <rule ref="Squiz.WhiteSpace.SuperfluousWhitespace"/>

    <!-- Covers rule: Omitting the closing PHP tag at the end of a file is preferred. -->
    <rule ref="PSR2.Files.ClosingTag"/>

    <!-- Rule: In general, readability is more important than cleverness or brevity.
    https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/607 -->
    <rule ref="Squiz.PHP.DisallowMultipleAssignments"/>
    <rule ref="Generic.Formatting.DisallowMultipleStatements"/>

    <!-- Rule: The goto statement must never be used. -->
    <!-- Duplicate of upstream. Should defer to upstream version once minimum PHPCS requirement has gone up.
         https://github.com/squizlabs/PHP_CodeSniffer/pull/1664 -->
    <rule ref="WordPress.PHP.DiscourageGoto"/>
    <rule ref="WordPress.PHP.DiscourageGoto.Found">
        <type>error</type>
        <message>The "goto" language construct should not be used.</message>
    </rule>

    <!-- Rule: The eval() construct is very dangerous, and is impossible to secure. ... these must not be used. -->
    <rule ref="Squiz.PHP.Eval"/>
    <rule ref="Squiz.PHP.Eval.Discouraged">
        <type>error</type>
        <message>eval() is a security risk so not allowed.</message>
    </rule>

    <!-- Don't use extract for readability and security -->
    <rule ref="WordPress.Functions.DontExtract"/>

    <!-- Do not use @ for silent errors -->
    <rule ref="Generic.PHP.NoSilencedErrors"/>

    <!-- Some general php rules -->
    <rule ref="Generic.PHP.DeprecatedFunctions"/>
    <rule ref="Generic.PHP.ForbiddenFunctions"/>
    <rule ref="Generic.Functions.CallTimePassByReference"/>
    <rule ref="Generic.CodeAnalysis.EmptyStatement"/>
    <rule ref="Generic.CodeAnalysis.ForLoopShouldBeWhileLoop"/>
    <rule ref="Generic.CodeAnalysis.ForLoopWithTestFunctionCall"/>
    <rule ref="Generic.CodeAnalysis.JumbledIncrementer"/>
    <rule ref="Generic.CodeAnalysis.UnconditionalIfStatement"/>
    <rule ref="Generic.CodeAnalysis.UnnecessaryFinalModifier"/>
    <rule ref="Generic.CodeAnalysis.UselessOverridingMethod"/>
    <rule ref="Generic.Classes.DuplicateClassName"/>
    <rule ref="Generic.Strings.UnnecessaryStringConcat">
        <properties>
            <property name="allowMultiline" value="true"/>
        </properties>
    </rule>

    <!-- More generic PHP best practices.
		 https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/607 -->
    <rule ref="Squiz.PHP.NonExecutableCode"/>
    <rule ref="Squiz.Operators.IncrementDecrementUsage"/>
    <rule ref="Squiz.Operators.ValidLogicalOperators"/>
    <rule ref="Squiz.Functions.FunctionDuplicateArgument"/>

    <!-- Encourage having only one class/interface/trait per file. -->
    <!-- Once the minimum WPCS PHPCS requirement has gone up to PHPCS 3.1.0, these three sniffs can be
         replaced by the more comprehensive Generic.Files.OneObjectStructurePerFile sniff. -->
    <rule ref="Generic.Files.OneClassPerFile"/>
    <rule ref="Generic.Files.OneClassPerFile.MultipleFound">
        <type>warning</type>
        <message>Best practice suggestion: Declare only one class in a file.</message>
    </rule>
    <rule ref="Generic.Files.OneInterfacePerFile"/>
    <rule ref="Generic.Files.OneInterfacePerFile.MultipleFound">
        <type>warning</type>
        <message>Best practice suggestion: Declare only one interface in a file.</message>
    </rule>
    <rule ref="Generic.Files.OneTraitPerFile"/>
    <rule ref="Generic.Files.OneTraitPerFile.MultipleFound">
        <type>warning</type>
        <message>Best practice suggestion: Declare only one trait in a file.</message>
    </rule>

    <!-- Warn against using fully-qualified class names instead of the self keyword. -->
    <rule ref="Squiz.Classes.SelfMemberReference.NotUsed">
        <!-- Restore default severity of 5 which WordPress-Core sets to 0. -->
        <severity>5</severity>
    </rule>

    <!-- Check for PHP Parse errors.
		 https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/522 -->
    <rule ref="Generic.PHP.Syntax"/>

    <!-- Phpdoc code commenting -->
    <rule ref="Generic.Commenting.DocComment" />
    <rule ref="Squiz.Commenting.FunctionComment">
        <exclude name="Squiz.Commenting.FunctionComment.ParamCommentFullStop" />
        <exclude name="Squiz.Commenting.FunctionComment.ThrowsNoFullStop" />
        <exclude name="Squiz.Commenting.FunctionComment.ScalarTypeHintMissing" />
        <exclude name="Squiz.Commenting.FunctionComment.TypeHintMissing" />
    </rule>
    <rule ref="Squiz.Commenting.ClassComment" />
    <rule ref="Squiz.Commenting.VariableComment" />

    <!--
	#############################################################################
	WordPress rules
	#############################################################################
	-->
    <autoload>vendor/wp-coding-standards/wpcs/WordPress/PHPCSAliases.php</autoload>

    <!-- Rule: in $wpdb->prepare - only %s and %d are used as placeholders. Note that they are not "quoted"! -->
    <rule ref="WordPress.DB.PreparedSQLPlaceholders"/>

    <!-- Covers rule: Escaping should be done as close to the time of the query as possible,
         preferably by using $wpdb->prepare() -->
    <rule ref="WordPress.WP.PreparedSQL"/>

    <!-- Covers rule: Avoid touching the database directly. -->
    <rule ref="WordPress.DB.RestrictedFunctions"/>
    <rule ref="WordPress.DB.RestrictedClasses"/>

    <!-- Check for correct usage of the WP i18n functions. -->
    <rule ref="WordPress.WP.I18n">
        <exclude name="WordPress.WP.I18n.NonSingularStringLiteralDomain" />
        <exclude name="WordPress.WP.I18n.NonSingularStringLiteralText" />
    </rule>

    <!-- https://vip.wordpress.com/documentation/code-review-what-we-look-for/#validation-sanitization-and-escaping -->
    <rule ref="WordPress.XSS.EscapeOutput"/>

    <!-- Verify that a nonce check is done before using values in superglobals.
    https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/73 -->
    <rule ref="WordPress.CSRF.NonceVerification"/>

    <!-- Encourage the use of strict ( === and !== ) comparisons.
		 https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/242 -->
    <rule ref="WordPress.PHP.StrictComparisons"/>

    <!-- https://vip.wordpress.com/documentation/code-review-what-we-look-for/#commented-out-code-debug-code-or-output -->
    <rule ref="WordPress.PHP.DevelopmentFunctions"/>
    <rule ref="WordPress.PHP.DevelopmentFunctions.error_log">
        <type>error</type>
    </rule>
    <!-- https://vip.wordpress.com/documentation/vip/code-review-what-we-look-for/#settings-alteration -->
    <rule ref="WordPress.PHP.DevelopmentFunctions.prevent_path_disclosure">
        <type>error</type>
    </rule>

    <!-- VIP recommends other functions -->
    <rule ref="WordPress.WP.AlternativeFunctions.curl">
        <message>Using cURL functions is highly discouraged within VIP context. Check (Fetching Remote Data) on VIP Documentation.</message>
    </rule>
    <rule ref="WordPress.WP.AlternativeFunctions.file_get_contents">
        <message>%s() is highly discouraged, please use vip_safe_wp_remote_get() instead.</message>
        <type>warning</type>
    </rule>

    <!-- Scripts & style should be enqueued.
		 https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/35 -->
    <rule ref="WordPress.WP.EnqueuedResources"/>

    <!-- Warn against overriding WP global variables.
         https://github.com/WordPress-Coding-Standards/WordPress-Coding-Standards/issues/26 -->
    <rule ref="WordPress.Variables.GlobalVariables"/>

    <!-- Verify that everything in the global namespace is prefixed. -->
    <rule ref="WordPress.NamingConventions.PrefixAllGlobals"/>
</ruleset>