Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 43 additions & 25 deletions .github/workflows/php-compat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,53 @@ on: pull_request

jobs:
php-compatibility:
name: PHP compatibility
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

- name: Setup proper PHP version
uses: shivammathur/setup-php@9e72090525849c5e82e596468b86eb55e9cc5401 # v2.32.0
- name: Prepare PHP
uses: woocommerce/grow/prepare-php@da5279aa4d76745ef32970e49b5ef7903a3b457a # v2.2.2
with:
php-version: 7.4
tools: composer

- name: Validate composer.json and composer.lock
run: composer validate --strict --no-check-all

- name: Get composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
tools: cs2pr
install-deps: no

- name: Cache dependencies
uses: actions/cache@d4323d4df104b026a6aa633fdb11d772146be0bf # v4.2.2
- name: Prepare node
uses: woocommerce/grow/prepare-node@da5279aa4d76745ef32970e49b5ef7903a3b457a # v2.2.2
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-

- name: Install dependencies
run: composer install

- name: Run PHP Compatibility
run: ./vendor/bin/phpcs --standard=phpcs-compat.xml.dist -p .
node-version-file: ".nvmrc"
ignore-scripts: "no"

# The use of WP-Scripts results in PHP files being generated during the npm build step.
# In order to ensure PHP Compatibility, the build step must be run in order to ensure all
# files in the production release of the plugin are compatible with the target PHP versions.
- name: Build production bundle
run: npm run build

# Unzip the newly created zip file to a separate directory.
- name: Unzip production bundle
run: |
mv woocommerce-square.zip ~
cd ~
mkdir prod
unzip woocommerce-square.zip -d prod
cd -

- name: Copy phpcompat sniffs to production directory
run: cp phpcs-compat.xml.dist ~/prod/woocommerce-square/phpcs-compat.xml.dist

# Installed globally to ensure dev dependencies are not included in compatibility sniffs.
# At the time of writing no production version of PHPCompatibility/PHP-Compatibility supports
# PHP 8.4 so a dev version is used in order to ensure the sniffs that have been created are
# included in the checks.
- name: Install PHP Compatibility dev-develop globally
run: |
composer global config --no-plugins allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
composer global require --dev phpcompatibility/php-compatibility:dev-develop#8daeec54772a592ad369be23ae02ed593c71e7f1

- name: Run PHPCompatibility on all files
run: |
cd ~/prod/woocommerce-square
~/.composer/vendor/bin/phpcs . --standard=phpcs-compat.xml.dist -ps --basepath=.
7 changes: 6 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@
"!/vendor",
"!/assets/js/**/*.min.js",
"!/assets/css/**/*.min.css",
"*.zip"
"*.zip",
"/vendor/apimatic/*/tests/**",
"/vendor/apimatic/*/.*",
"/vendor/square/square/tests/**",
"/vendor/square/square/doc/**",
"/vendor/square/square/.*"
Comment on lines +31 to +35
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Various unit tests and dot files that have no place in production.

A couple of them were throwing errors in the php-compat sniffs but I figured we could remove them as they never run in our code base.

]
},
"extra": {
Expand Down
2 changes: 1 addition & 1 deletion includes/Admin/Rest/WC_REST_Square_Settings_Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public function get_settings() {
$filtered_settings['connection_url'] = wc_square()->get_gateway()->get_plugin()->get_connection_handler()->get_connect_url( false );
$filtered_settings['connection_url_wizard'] = wc_square()->get_gateway()->get_plugin()->get_connection_handler()->get_connect_url( false, array( 'from' => 'wizard' ) );
$filtered_settings['connection_url_sandbox'] = wc_square()->get_gateway()->get_plugin()->get_connection_handler()->get_connect_url( true, array( 'from' => 'wizard' ) );
$filtered_settings['disconnection_url'] = html_entity_decode( wp_nonce_url( $url, $action ) );
$filtered_settings['disconnection_url'] = html_entity_decode( wp_nonce_url( $url, $action ), ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 );

// Add locations to the response.
if ( wc_square()->get_settings_handler()->is_connected() ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ public function ajax_process_capture() {

wp_send_json_success(
array(
'message' => html_entity_decode( wp_strip_all_tags( $result['message'] ) ), // ensure any HTML tags are removed and the currency symbol entity is decoded
'message' => html_entity_decode( wp_strip_all_tags( $result['message'] ), ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 ), // ensure any HTML tags are removed and the currency symbol entity is decoded
)
);

Expand Down
12 changes: 6 additions & 6 deletions includes/Framework/PaymentGateway/Payment_Gateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -3621,7 +3621,7 @@ public function get_authorization_time_window() {
* @param \WC_Order $order Optional. The order being charged
* @return bool
*/
public function perform_credit_card_charge( \WC_Order $order = null ) {
public function perform_credit_card_charge( ?\WC_Order $order = null ) {

assert( $this->supports_credit_card_charge() );

Expand Down Expand Up @@ -3652,7 +3652,7 @@ public function perform_credit_card_charge( \WC_Order $order = null ) {
* @param \WC_Order $order Optional. The order being authorized
* @return bool
*/
public function perform_credit_card_authorization( \WC_Order $order = null ) {
public function perform_credit_card_authorization( ?\WC_Order $order = null ) {

assert( $this->supports_credit_card_authorization() );

Expand All @@ -3677,7 +3677,7 @@ public function perform_credit_card_authorization( \WC_Order $order = null ) {
* @param \WC_Order $order Optional. The order being charged
* @return bool
*/
public function perform_charge( \WC_Order $order = null ) {
public function perform_charge( ?\WC_Order $order = null ) {

assert( $this->supports_charge() );

Expand Down Expand Up @@ -3708,7 +3708,7 @@ public function perform_charge( \WC_Order $order = null ) {
* @param \WC_Order $order Optional. The order being authorized
* @return bool
*/
public function perform_authorization( \WC_Order $order = null ) {
public function perform_authorization( ?\WC_Order $order = null ) {

assert( $this->supports_authorization() );

Expand Down Expand Up @@ -4002,12 +4002,12 @@ public function add_debug_message( $message, $type = 'message' ) {

if ( 'message' === $type ) {

Square_Helper::wc_add_notice( str_replace( "\n", '<br/>', htmlspecialchars( $message ) ), 'notice' );
Square_Helper::wc_add_notice( str_replace( "\n", '<br/>', htmlspecialchars( $message, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 ) ), 'notice' );

} else {

// defaults to error message
Square_Helper::wc_add_notice( str_replace( "\n", '<br/>', htmlspecialchars( $message ) ), 'error' );
Square_Helper::wc_add_notice( str_replace( "\n", '<br/>', htmlspecialchars( $message, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 ) ), 'error' );
}
}
}
Expand Down
11 changes: 7 additions & 4 deletions includes/Framework/Square_Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,14 @@ public static function str_exists( $haystack, $needle ) {
*/
public static function str_to_ascii( $string ) {

// strip ASCII chars 32 and under
$string = filter_var( $string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW );
// Remove HTML tags.
$string = wp_strip_all_tags( $string );

// strip ASCII chars 127 and higher
return filter_var( $string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH );
// Encode HTML special characters.
$string = htmlspecialchars( $string, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 );

// strip ASCII chars 32 and under; 127 and higher
return filter_var( $string, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH );
}

/**
Expand Down
2 changes: 1 addition & 1 deletion includes/Gateway/API.php
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ public function retrieve_gift_card_by_gan( $gan = '' ) {
*
* @throws \Exception
*/
public function search_orders( $location_ids = array(), $start_time, $limit = 100, $cursor = '', $end_time = '' ) {
public function search_orders( $location_ids, $start_time, $limit = 100, $cursor = '', $end_time = '' ) {

$request = new API\Requests\Orders( $this->client );

Expand Down
2 changes: 1 addition & 1 deletion includes/Handlers/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -1012,7 +1012,7 @@ public static function extract_catalog_item_data( \WC_Product $product, array $v
* * @param bool $is_soft_delete whether or not this item data is for a soft-delete
* @return array
*/
public static function extract_catalog_item_variation_data( \WC_Product $product, \WC_Product $parent_product = null, $is_soft_delete = false ) {
public static function extract_catalog_item_variation_data( \WC_Product $product, ?\WC_Product $parent_product = null, $is_soft_delete = false ) {

if ( ! $product ) {
return null;
Expand Down
4 changes: 2 additions & 2 deletions includes/Sync/Catalog_Item.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public function __construct( $product, $is_soft_delete = false ) {
* @return \Square\Models\CatalogObjectBatch
* @throws \Exception
*/
public function get_batch( \Square\Models\CatalogObject $catalog_object = null ) {
public function get_batch( ?\Square\Models\CatalogObject $catalog_object = null ) {

if ( ! $this->batch ) {
$this->create_batch( $catalog_object );
Expand Down Expand Up @@ -122,7 +122,7 @@ protected function is_soft_delete() {
* @param \Square\Models\CatalogObject|null $catalog_object existing catalog object or null to create a new one
* @throws \Exception
*/
protected function create_batch( \Square\Models\CatalogObject $catalog_object = null ) {
protected function create_batch( ?\Square\Models\CatalogObject $catalog_object = null ) {

if ( ! $catalog_object ) {
$catalog_id = Product\Woo_SOR::get_square_item_id( $this->product );
Expand Down
13 changes: 8 additions & 5 deletions includes/Utilities/String_Utility.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,18 +78,21 @@ public static function truncate( $string, $length, $omission = '...' ) {
* @return string
*/
public static function to_ascii( $string ) {
// strip ASCII chars 32 and under
$string = filter_var( $string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW );
// Remove HTML tags.
$string = wp_strip_all_tags( $string );

// strip ASCII chars 127 and higher
return filter_var( $string, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH );
// Encode HTML special characters.
$string = htmlspecialchars( $string, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401 );

// strip ASCII chars 32 and under; 127 and higher
return filter_var( $string, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH );
}

/**
* Returns true if the haystack string starts with needle
*
* Note: case-sensitive
*
*
* See Square_Helper::str_starts_with()
*
* @since 2.2.0
Expand Down
74 changes: 60 additions & 14 deletions phpcs-compat.xml.dist
Original file line number Diff line number Diff line change
@@ -1,19 +1,65 @@
<?xml version="1.0"?>
<ruleset name="PHPCompatibilityWP">
<rule ref="PHPCompatibility"/>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="PHPCompatibilityWP" xsi:noNamespaceSchemaLocation="https://schema.phpcodesniffer.com/phpcs.xsd">

<!-- Files to check -->
<arg name="extensions" value="php"/>
<file>.</file>
<description>WordPress specific ruleset which checks for PHP cross version compatibility.</description>
<!-- Once PHPCompatibility/PHPCompatibilityWP supports the targeted versions of PHP, this config file can be updated accordingly. -->

<exclude-pattern>vendor/</exclude-pattern>
<exclude-pattern>dist/</exclude-pattern>
<exclude-pattern>docker/</exclude-pattern>
<exclude-pattern>build/</exclude-pattern>
<exclude-pattern>docs/</exclude-pattern>
<exclude-pattern>node_modules</exclude-pattern>
<exclude-pattern>tests</exclude-pattern>
<exclude-pattern>assets</exclude-pattern>
<!-- Test PHP 7.4 thru 8.4 -->
<config name="testVersion" value="7.4-8.4"/>
<file>.</file>
<arg name="extensions" value="php,inc" />

<rule ref="PHPCompatibility">
<!--
Contained in /wp-includes/compat.php.

History of the polyfills in WP:
* hash_hmac(): since WP 3.2.0.
* json_encode() and json_decode(): since unknown.
* hash_equals(): since WP 3.9.2.
* JSON_PRETTY_PRINT: since WP 4.1.0.
* json_last_error_msg(): since WP 4.4.0.
* JsonSerializable: since WP 4.4.0.
* array_replace_recursive(): since WP 4.5.3 up to 5.2.x. The polyfill was removed in WP 5.3.
* is_iterable(): since WP 4.9.6
* is_countable(): since WP 4.9.6
* IMAGETYPE_WEBP and IMG_WEBP: since WP 5.8.0.
* array_key_first(): since WP 5.9.0
* array_key_last(): since WP 5.9.0
* str_contains(): since WP 5.9.0
* str_starts_with(): since WP 5.9.0
* str_ends_with(): since WP 5.9.0
* array_is_list(): since WP 6.5.0
-->
<exclude name="PHPCompatibility.FunctionUse.NewFunctions.hash_hmacFound"/>
<exclude name="PHPCompatibility.FunctionUse.NewFunctions.json_encodeFound"/>
<exclude name="PHPCompatibility.FunctionUse.NewFunctions.json_decodeFound"/>
<exclude name="PHPCompatibility.FunctionUse.NewFunctions.hash_equalsFound"/>
<exclude name="PHPCompatibility.Constants.NewConstants.json_pretty_printFound"/>
<exclude name="PHPCompatibility.FunctionUse.NewFunctions.json_last_error_msgFound"/>
<exclude name="PHPCompatibility.Interfaces.NewInterfaces.jsonserializableFound"/>
<exclude name="PHPCompatibility.FunctionUse.NewFunctions.array_replace_recursiveFound"/>
<exclude name="PHPCompatibility.FunctionUse.NewFunctions.is_iterableFound"/>
<exclude name="PHPCompatibility.FunctionUse.NewFunctions.is_countableFound"/>
<exclude name="PHPCompatibility.Constants.NewConstants.imagetype_webpFound"/>
<exclude name="PHPCompatibility.Constants.NewConstants.img_webpFound"/>
<exclude name="PHPCompatibility.FunctionUse.NewFunctions.array_key_firstFound"/>
<exclude name="PHPCompatibility.FunctionUse.NewFunctions.array_key_lastFound"/>
<exclude name="PHPCompatibility.FunctionUse.NewFunctions.str_containsFound"/>
<exclude name="PHPCompatibility.FunctionUse.NewFunctions.str_starts_withFound"/>
<exclude name="PHPCompatibility.FunctionUse.NewFunctions.str_ends_withFound"/>
<exclude name="PHPCompatibility.FunctionUse.NewFunctions.array_is_listFound"/>

<!--
Contained in /wp-includes/spl-autoload-compat.php.

History of the polyfills in WP:
* spl_autoload_register(), spl_autoload_unregister() and spl_autoload_functions() were
introduced in WP 4.6.0 and available up to WP 5.2.x. The polyfills were removed in WP 5.3.
-->
<exclude name="PHPCompatibility.FunctionUse.NewFunctions.spl_autoload_registerFound"/>
<exclude name="PHPCompatibility.FunctionUse.NewFunctions.spl_autoload_unregisterFound"/>
<exclude name="PHPCompatibility.FunctionUse.NewFunctions.spl_autoload_functionsFound"/>
</rule>

<config name="testVersion" value="7.4-"/>
</ruleset>
2 changes: 1 addition & 1 deletion woocommerce-square.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* Requires at least: 6.7
* Tested up to: 6.8
* Requires PHP: 7.4
* PHP tested up to: 8.3
* PHP tested up to: 8.4
*
* Description: Securely accept payments, synchronize sales, and seamlessly manage inventory and product data between WooCommerce and Square POS.
* Author: WooCommerce
Expand Down
Loading