<?xml version="1.0"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="WordPress Core" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/squizlabs/PHP_CodeSniffer/master/phpcs.xsd">

	<description>Non-controversial generally-agreed upon WordPress Coding Standards</description>

	<!-- Default tab width for indentation fixes and such. -->
	<arg name="tab-width" value="4"/>

	<!--
	#############################################################################
	Handbook: PHP - Single and Double Quotes.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#single-and-double-quotes
	#############################################################################
	-->
	<!-- Covers rule: Use single and double quotes when appropriate.
		 If you're not evaluating anything in the string, use single quotes. -->
	<rule ref="Squiz.Strings.DoubleQuoteUsage.NotRequired"/>

	<!-- Rule: Text that goes into attributes should be run through esc_attr().
		 https://github.com/WordPress/WordPress-Coding-Standards/issues/527 -->


	<!--
	#############################################################################
	Handbook: PHP - Indentation.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#indentation
	#############################################################################
	-->
	<!-- Covers rule: Your indentation should always reflect logical structure. -->
	<rule ref="Generic.WhiteSpace.ScopeIndent">
		<properties>
			<property name="exact" value="false"/>
			<property name="indent" value="4"/>
			<property name="tabIndent" value="true"/>
			<property name="ignoreIndentationTokens" type="array">
				<element value="T_HEREDOC"/>
				<element value="T_NOWDOC"/>
				<element value="T_INLINE_HTML"/>
			</property>
		</properties>
	</rule>
	<rule ref="WordPress.Arrays.ArrayIndentation"/>

	<!-- Covers rule: Use real tabs and not spaces. -->
	<rule ref="Generic.WhiteSpace.DisallowSpaceIndent"/>
	<rule ref="WordPress.WhiteSpace.PrecisionAlignment"/>

	<!-- Generic array layout check. -->
	<!-- Covers rule: For associative arrays, each item should start on a new line
		 when the array contains more than one item.
		 Also covers various single-line array whitespace issues. -->
	<rule ref="WordPress.Arrays.ArrayDeclarationSpacing"/>

	<!-- Covers rule: Note the comma after the last array item: this is recommended. -->
	<rule ref="WordPress.Arrays.CommaAfterArrayItem"/>

	<!-- Covers rule: For switch structures case should indent one tab from the
		 switch statement and break one tab from the case statement. -->
	<rule ref="PSR2.ControlStructures.SwitchDeclaration"/>
	<!-- Prevent duplicate messages for the same issue. Covered by other sniffs. -->
	<rule ref="PSR2.ControlStructures.SwitchDeclaration.NotLower">
		<severity>0</severity>
	</rule>
	<rule ref="PSR2.ControlStructures.SwitchDeclaration.BreakNotNewLine">
		<severity>0</severity>
	</rule>
	<rule ref="PSR2.ControlStructures.SwitchDeclaration.BodyOnNextLine">
		<severity>0</severity>
	</rule>

	<!-- Covers rule: ... while spaces can be used mid-line for alignment. -->
	<rule ref="WordPress.WhiteSpace.DisallowInlineTabs"/>

	<!-- Implied through the examples: align the assignment operator in a block of assignments. -->
	<rule ref="Generic.Formatting.MultipleStatementAlignment">
		<properties>
			<property name="maxPadding" value="40"/>
		</properties>
	</rule>

	<!-- Implied through the examples: align the double arrows. -->
	<rule ref="WordPress.Arrays.MultipleStatementAlignment">
		<properties>
			<property name="maxColumn" value="60"/>
		</properties>
	</rule>


	<!--
	#############################################################################
	Handbook: PHP - Brace Style.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#brace-style
	#############################################################################
	-->
	<!-- 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"/>


	<!--
	#############################################################################
	Handbook: PHP - Declaring Arrays.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#declaring-arrays
	#############################################################################
	-->
	<!-- Covers rule: Arrays must be declared using long array syntax. -->
	<rule ref="Generic.Arrays.DisallowShortArraySyntax"/>


	<!--
	#############################################################################
	Handbook: PHP - Use elseif, not else if.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#use-elseif-not-else-if
	#############################################################################
	-->
	<!-- Covers rule: ... use elseif for conditionals. -->
	<rule ref="PSR2.ControlStructures.ElseIfDeclaration"/>


	<!--
	#############################################################################
	Handbook: PHP - Multiline Function Calls.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#multiline-function-calls
	#############################################################################
	-->
	<!-- Rule: When splitting a function call over multiple lines, each parameter must be on a separate line.
		 Covered via PEAR.Functions.FunctionCallSignature in Space Usage section. -->

	<!-- Rule: Single line inline comments can take up their own line. -->
	<!-- Rule: Each parameter must take up no more than a single line. Multi-line parameter
		 values must be assigned to a variable and then that variable should be passed to the function call.
		 https://github.com/WordPress/WordPress-Coding-Standards/issues/1330 -->


	<!--
	#############################################################################
	Handbook: PHP - Regular Expressions.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#regular-expressions
	#############################################################################
	-->
	<!-- Covers rule: Perl compatible regular expressions should be used in preference
		 to their POSIX counterparts. -->
	<rule ref="WordPress.PHP.POSIXFunctions"/>

	<!-- Rule: Never use the /e switch, use preg_replace_callback instead.
		 https://github.com/WordPress/WordPress-Coding-Standards/issues/632 -->

	<!-- Rule: It's most convenient to use single-quoted strings for regular expressions.
		 Already covered by Squiz.Strings.DoubleQuoteUsage -->


	<!--
	#############################################################################
	Handbook: PHP - Opening and Closing PHP Tags.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#opening-and-closing-php-tags
	#############################################################################
	-->
	<!-- Covers rule: When embedding multi-line PHP snippets within a HTML block, the
		 PHP open and close tags must be on a line by themselves. -->
	<rule ref="Squiz.PHP.EmbeddedPhp"/>
	<rule ref="Squiz.PHP.EmbeddedPhp.SpacingBefore">
		<severity>0</severity>
	</rule>
	<rule ref="Squiz.PHP.EmbeddedPhp.Indent">
		<severity>0</severity>
	</rule>
	<rule ref="Squiz.PHP.EmbeddedPhp.OpenTagIndent">
		<severity>0</severity>
	</rule>
	<rule ref="Squiz.PHP.EmbeddedPhp.SpacingAfter">
		<severity>0</severity>
	</rule>


	<!--
	#############################################################################
	Handbook: PHP - No Shorthand PHP Tags.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#no-shorthand-php-tags
	#############################################################################
	-->
	<!-- Covers rule: Never use shorthand PHP start tags. Always use full PHP tags. -->
	<rule ref="Generic.PHP.DisallowShortOpenTag"/>
	<rule ref="Generic.PHP.DisallowAlternativePHPTags"/>


	<!--
	#############################################################################
	Handbook: PHP - Remove Trailing Spaces.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#remove-trailing-spaces
	#############################################################################
	-->
	<!-- 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"/>


	<!--
	#############################################################################
	Handbook: PHP - Space Usage.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#space-usage
	#############################################################################
	-->
	<!-- Covers rule: Always put spaces after commas, and on both sides of logical,
		 comparison, string and assignment operators. -->
	<rule ref="WordPress.WhiteSpace.OperatorSpacing"/>
	<rule ref="Squiz.Strings.ConcatenationSpacing">
		<properties>
			<property name="spacing" value="1"/>
			<property name="ignoreNewlines" value="true"/>
		</properties>
	</rule>

	<!-- Covers rule: Put spaces on both sides of the opening and closing parenthesis of
		 if, elseif, foreach, for, and switch blocks. -->
	<rule ref="WordPress.WhiteSpace.ControlStructureSpacing"/>

	<!-- Covers rule: Define a function like so: function my_function( $param1 = 'foo', $param2 = 'bar' ) { -->
	<rule ref="Generic.Functions.OpeningFunctionBraceKernighanRitchie">
		<properties>
			<property name="checkClosures" value="true"/>
		</properties>
	</rule>
	<rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing">
		<properties>
			<property name="equalsSpacing" value="1"/>
			<property name="requiredSpacesAfterOpen" value="1"/>
			<property name="requiredSpacesBeforeClose" value="1"/>
		</properties>
	</rule>
	<rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing.SpacingBeforeClose">
		<severity>0</severity>
	</rule>


	<!-- Covers rule: Call a function, like so: my_function( $param1, func_param( $param2 ) ); -->
	<rule ref="PEAR.Functions.FunctionCallSignature">
		<properties>
			<property name="requiredSpacesAfterOpen" value="1"/>
			<property name="requiredSpacesBeforeClose" value="1"/>

			<!-- ... and for multi-line function calls, there should only be one parameter per line. -->
			<property name="allowMultipleArguments" value="false"/>
		</properties>
	</rule>

	<rule ref="Generic.Functions.FunctionCallArgumentSpacing"/>

	<!-- Rule: Perform logical comparisons, like so: if ( ! $foo ) { -->

	<!-- Covers rule: Type casts must be lowercase. Always prefer the short form
		 of type casts, (int) instead of (integer) and (bool) rather than (boolean).
		 For float casts use (float). -->
	<rule ref="Generic.Formatting.SpaceAfterCast"/>
	<rule ref="Squiz.WhiteSpace.CastSpacing"/>
	<rule ref="WordPress.WhiteSpace.CastStructureSpacing"/>
	<rule ref="WordPress.PHP.TypeCasts"/>
	<rule ref="PSR12.Keywords.ShortFormTypeKeywords"/>
	<!-- N.B.: This sniff also checks the case of (parameter/return) type declarations, not just type casts. -->
	<rule ref="Generic.PHP.LowerCaseType"/>

	<!-- Covers rule: ... array items, only include a space around the index if it is a variable. -->
	<rule ref="WordPress.Arrays.ArrayKeySpacingRestrictions"/>

	<!-- Rule: In a switch block, there must be no space before the colon for a case statement. -->
	<!-- Covered by the PSR2.ControlStructures.SwitchDeclaration sniff. -->

	<!-- Rule: Similarly, there should be no space before the colon on return type declarations. -->

	<!-- Covers rule: Unless otherwise specified, parentheses should have spaces inside of them. -->
	<rule ref="Generic.WhiteSpace.ArbitraryParenthesesSpacing">
		<properties>
			<property name="spacing" value="1"/>
			<property name="ignoreNewlines" value="true"/>
		</properties>
	</rule>


	<!--
	#############################################################################
	Handbook: PHP - Formatting SQL statements.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#formatting-sql-statements
	#############################################################################
	-->
	<!-- Rule: Always capitalize the SQL parts of the statement like UPDATE or WHERE.
		 https://github.com/WordPress/WordPress-Coding-Standards/issues/639 -->

	<!-- Rule: Functions that update the database should expect their parameters to lack
		 SQL slash escaping when passed.
		 https://github.com/WordPress/WordPress-Coding-Standards/issues/640 -->

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

	<!-- Covers rule:  $wpdb->prepare()... The benefit of this is that we don't have to remember
		 to manually use esc_sql(), and also that it is easy to see at a glance whether something
		 has been escaped or not, because it happens right when the query happens. -->
	<rule ref="WordPress.DB.PreparedSQL"/>


	<!--
	#############################################################################
	Handbook: PHP - Database Queries.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#database-queries
	#############################################################################
	-->
	<!-- Covers rule: Avoid touching the database directly. -->
	<rule ref="WordPress.DB.RestrictedFunctions"/>
	<rule ref="WordPress.DB.RestrictedClasses"/>


	<!--
	#############################################################################
	Handbook: PHP - Naming Conventions.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#naming-conventions
	#############################################################################
	-->
	<!-- Covers rule: Use lowercase letters in variable, action/filter, and function names.
		 Separate words via underscores. -->
	<rule ref="WordPress.NamingConventions.ValidFunctionName"/>
	<rule ref="WordPress.NamingConventions.ValidHookName"/>
	<rule ref="WordPress.NamingConventions.ValidVariableName"/>

	<!-- Covers rule: Class names should use capitalized words separated by underscores. -->
	<rule ref="PEAR.NamingConventions.ValidClassName"/>

	<!-- Covers rule: Constants should be in all upper-case with underscores separating words. -->
	<rule ref="Generic.NamingConventions.UpperCaseConstantName"/>

	<!-- Covers rule: Files should be named descriptively using lowercase letters.
		 Hyphens should separate words. -->
	<!-- Covers rule: Class file names should be based on the class name with "class-"
		 prepended and the underscores in the class name replaced with hyphens.
		 https://github.com/WordPress/WordPress-Coding-Standards/issues/642 -->
	<!-- Covers rule: Files containing template tags in wp-includes should have "-template"
		 appended to the end of the name.
		 https://github.com/WordPress/WordPress-Coding-Standards/issues/642 -->
	<rule ref="WordPress.Files.FileName"/>


	<!--
	#############################################################################
	Handbook: PHP - Self-Explanatory Flag Values for Function Arguments.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#self-explanatory-flag-values-for-function-arguments
	#############################################################################
	-->


	<!--
	#############################################################################
	Handbook: PHP - Interpolation for Naming Dynamic Hooks.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#interpolation-for-naming-dynamic-hooks

	https://github.com/WordPress/WordPress-Coding-Standards/issues/751
	#############################################################################
	-->
	<!-- Rule: Dynamic hooks should be named using interpolation rather than concatenation. -->

	<!-- Rule: Variables used in hook tags should be wrapped in curly braces { and },
		 with the complete outer tag name wrapped in double quotes. -->

	<!-- Rule: Where possible, dynamic values in tag names should also be as succinct
		 and to the point as possible. -->


	<!--
	#############################################################################
	Handbook: PHP - Ternary Operator.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#ternary-operator
	#############################################################################
	-->
	<!-- Rule: Always have Ternaries test if the statement is true, not false.
		 An exception would be using ! empty(), as testing for false here is generally more intuitive.
		 https://github.com/WordPress/WordPress-Coding-Standards/issues/643 -->

	<!-- Rule: The short ternary operator must not be used. -->
	<rule ref="WordPress.PHP.DisallowShortTernary"/>

	<!--
	#############################################################################
	Handbook: PHP - Yoda Conditions.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#yoda-conditions
	#############################################################################
	-->
	<!-- Covers rule: When doing logical comparisons, always put the variable on the right side,
		 constants or literals on the left. -->
	<rule ref="WordPress.PHP.YodaConditions"/>

	<!-- Rule: Yoda conditions for <, >, <= or >= are significantly more difficult to read
		 and are best avoided. -->

	<!--
	#############################################################################
	Handbook: PHP - Clever Code.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#clever-code
	#############################################################################
	-->
	<!-- Rule: In general, readability is more important than cleverness or brevity.
		 https://github.com/WordPress/WordPress-Coding-Standards/issues/607 -->
	<rule ref="Squiz.PHP.DisallowMultipleAssignments"/>
	<rule ref="Generic.Formatting.DisallowMultipleStatements"/>

	<!-- Rule: Unless absolutely necessary, loose comparisons should not be used,
		 as their behaviour can be misleading. -->
	<rule ref="WordPress.PHP.StrictComparisons"/>
	<rule ref="WordPress.PHP.StrictInArray"/>

	<!-- Rule: Assignments must not be placed in placed in conditionals.
		 Note: sniff is a duplicate of upstream. Can be removed once minimum PHPCS requirement has gone up.
		 https://github.com/squizlabs/PHP_CodeSniffer/pull/1594
		 Update: the "assignment in ternary" part of the sniff is currently not yet covered in
		 the upstream version. This needs to be pulled first before we can defer to upstream. -->
	<rule ref="WordPress.CodeAnalysis.AssignmentInCondition"/>

	<!-- Rule: In a switch statement... If a case contains a block, then falls through
		 to the next block, this must be explicitly commented. -->
	<!-- Covered by the PSR2.ControlStructures.SwitchDeclaration sniff. -->

	<!-- Rule: The goto statement must never be used. -->
	<rule ref="Generic.PHP.DiscourageGoto">
		<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.Discouraged">
		<type>error</type>
		<message>eval() is a security risk so not allowed.</message>
	</rule>

	<!-- Rule: create_function() function, which internally performs an eval(),
		 is deprecated in PHP 7.2. ... these must not be used. -->
	<rule ref="WordPress.PHP.RestrictedPHPFunctions"/>


	<!--
	#############################################################################
	Handbook: PHP - (No) Error Control Operator @.
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#error-control-operator
	#############################################################################
	-->
	<!-- Covers rule: This operator is often used lazily instead of doing proper error checking.
		 Its use is highly discouraged. -->
	<rule ref="WordPress.PHP.NoSilencedErrors"/>


	<!--
	#############################################################################
	Handbook: PHP - Don't extract().
	Ref: https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#dont-extract
	#############################################################################
	-->
	<rule ref="WordPress.PHP.DontExtract"/>


	<!--
	#############################################################################
	Not in the handbook: Generic sniffs.
	#############################################################################
	-->
	<!-- Important to prevent issues with content being sent before headers. -->
	<rule ref="Generic.Files.ByteOrderMark"/>

	<!-- All line endings should be \n. -->
	<rule ref="Generic.Files.LineEndings">
		<properties>
			<property name="eolChar" value="\n"/>
		</properties>
	</rule>

	<!-- All files should end with a new line. -->
	<rule ref="Generic.Files.EndFileNewline"/>

	<!-- No whitespace should come before semicolons. -->
	<rule ref="Squiz.WhiteSpace.SemicolonSpacing"/>

	<!-- There should be no empty statements, i.e. lone semi-colons or open/close tags without content. -->
	<rule ref="WordPress.CodeAnalysis.EmptyStatement"/>

	<!-- Lowercase PHP constants, like true, false and null. -->
	<!-- https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/#naming-conventions -->
	<rule ref="Generic.PHP.LowerCaseConstant"/>

	<!-- Lowercase PHP keywords, like class, function and case. -->
	<rule ref="Generic.PHP.LowerCaseKeyword"/>

	<!-- Class opening braces should be on the same line as the statement. -->
	<rule ref="Generic.Classes.OpeningBraceSameLine"/>

	<!-- Object operators should not have whitespace around them unless they are multi-line. -->
	<rule ref="Squiz.WhiteSpace.ObjectOperatorSpacing">
		<properties>
			<property name="ignoreNewlines" value="true"/>
		</properties>
	</rule>

	<!-- References to self in a class should be lower-case and not have extraneous spaces,
		 per implicit conventions in the core codebase; the NotUsed code refers to using the
		 fully-qualified class name instead of self, for which there are instances in core. -->
	<rule ref="Squiz.Classes.SelfMemberReference"/>
	<rule ref="Squiz.Classes.SelfMemberReference.NotUsed">
		<severity>0</severity>
	</rule>

	<!--
	#############################################################################
	Not in the coding standard handbook: WP specific sniffs.
	Ref: https://make.wordpress.org/core/handbook/best-practices/internationalization/ (limited info)
	Ref: https://developer.wordpress.org/plugins/internationalization/ (more extensive)
	#############################################################################
	-->
	<!-- Check for correct usage of the WP i18n functions. -->
	<rule ref="WordPress.WP.I18n"/>

	<!-- Check for correct spelling of WordPress. -->
	<rule ref="WordPress.WP.CapitalPDangit"/>

	<!-- Use the appropriate DateTime functions.
		 See: https://github.com/WordPress/WordPress-Coding-Standards/issues/1713 -->
	<rule ref="WordPress.DateTime.RestrictedFunctions"/>

	<!-- Don't use current_time() to retrieve a timestamp. -->
	<rule ref="WordPress.DateTime.CurrentTimeTimestamp"/>

</ruleset>
