Merge branch 'trunk' into fix/e2e-env-monorepo

This commit is contained in:
Ron Rennick 2021-11-18 22:13:53 -04:00
commit fc9c3c7aa0
20 changed files with 246 additions and 172 deletions

View File

@ -17,7 +17,7 @@ jobs:
ref: ${{ github.event.inputs.ref || github.ref }}
- name: Build the zip file
id: build
uses: woocommerce/action-build@v2
uses: woocommerce/action-build@trunk
- name: Unzip the file (prevents double zip problem)
run: unzip ${{ steps.build.outputs.zip_path }} -d zipfile
- name: Upload the zip file as an artifact

View File

@ -11,7 +11,7 @@ jobs:
uses: actions/checkout@v2
- name: Build
id: build
uses: woocommerce/action-build@v2
uses: woocommerce/action-build@trunk
- name: Upload release asset
uses: actions/upload-release-asset@v1
env:

View File

@ -59,8 +59,13 @@ jobs:
./vendor
key: ${{ runner.os }}-${{ hashFiles('./composer.lock') }}
- name: Install PNPM and install dependencies
run: |
npm install -g pnpm
pnpm install
- name: Setup and install composer
run: composer install
run: pnpm nx composer-install woocommerce
- name: Add PHP8 Compatibility.
run: |
@ -71,11 +76,11 @@ jobs:
composer bin phpunit config repositories.0 '{"type": "path", "url": "/tmp/phpunit-7.5-fork/phpunit-add-compatibility-with-php8-to-phpunit-7", "options": {"symlink": false}}'
composer bin phpunit require --dev -W phpunit/phpunit:@dev --ignore-platform-reqs
rm -rf ./vendor/phpunit/
composer dump-autoload
pnpm nx composer-dump-autoload woocommerce
fi
- name: Init DB and WP
run: ./tests/bin/install.sh woo_test root root 127.0.0.1 ${{ matrix.wp }}
- name: Run tests
run: ./vendor/bin/phpunit -c ./phpunit.xml
run: pnpm nx test-unit woocommerce

View File

@ -77,9 +77,60 @@ jobs:
WC_E2E_SCREENSHOTS: 1
E2E_SLACK_TOKEN: ${{ secrets.E2E_SLACK_TOKEN }}
E2E_SLACK_CHANNEL: ${{ secrets.E2E_SLACK_CHANNEL }}
run: pnpx wc-e2e test:e2e
api-tests-run:
name: Runs API tests.
runs-on: ubuntu-18.04
needs: [build]
steps:
- name: Create dirs.
run: |
mkdir -p code/woocommerce
mkdir -p package/woocommerce
mkdir -p tmp/woocommerce
mkdir -p node_modules
- name: Checkout code.
uses: actions/checkout@v2
with:
path: package/woocommerce
- name: Install PNPM and install dependencies
working-directory: package/woocommerce
run: |
npm install -g pnpm
pnpm install
- name: Load docker images and start containers.
working-directory: package/woocommerce/plugins/woocommerce
run: pnpx wc-e2e docker:up
- name: Move current directory to code. We will install zip file in this dir later.
run: mv ./package/woocommerce/plugins/woocommerce/* ./code/woocommerce
- name: Download WooCommerce ZIP.
uses: actions/download-artifact@v2
with:
name: woocommerce
path: tmp
- name: Extract and replace WooCommerce zip.
working-directory: tmp
run: |
unzip woocommerce.zip -d woocommerce
mv woocommerce/woocommerce/* ../package/woocommerce/plugins/woocommerce/
- name: Install dependencies again
working-directory: package/woocommerce
run: |
npm install -g pnpm
pnpm install
- name: Run tests command.
working-directory: package/woocommerce/plugins/woocommerce
env:
BASE_URL: ${{ secrets.PR_E2E_TEST_URL }}
USER_KEY: ${{ secrets.PR_E2E_TEST_ADMIN_USER }}
USER_SECRET: ${{ secrets.PR_E2E_TEST_ADMIN_PASSWORD }}
run: |
pnpx wc-e2e test:e2e
pnpx wc-api-tests test api
run: pnpx wc-api-tests test api

View File

@ -45,15 +45,20 @@ jobs:
./vendor
key: ${{ runner.os }}-${{ hashFiles('./composer.lock') }}
- name: Install PNPM and install dependencies
run: |
npm install -g pnpm
pnpm install
- name: Setup and install composer
run: composer install
run: pnpm nx composer-install woocommerce
- name: Init DB and WP
run: ./tests/bin/install.sh woo_test root root 127.0.0.1 latest
run: pnpm nx install-unit-test-db woocommerce
- name: Run unit tests with code coverage. Allow to fail.
run: |
RUN_CODE_COVERAGE=1 bash ./tests/bin/phpunit.sh
pnpm nx test-code-coverage woocommerce
exit 0
- name: Send code coverage to Codecov.

View File

@ -35,8 +35,13 @@ jobs:
./vendor
key: ${{ runner.os }}-${{ hashFiles('./composer.lock') }}
- name: Install PNPM and install dependencies
run: |
npm install -g pnpm
pnpm install
- name: Setup and install composer
run: composer install
run: pnpm nx composer-install woocommerce
- name: Run code sniff
continue-on-error: true

View File

@ -28,8 +28,8 @@ jobs:
run: |
npm install -g pnpm
pnpm install
composer install --no-dev
pnpm run build:assets
pnpm nx composer-install-no-dev" woocommerce
pnpm nx build-assets woocommerce
pnpm install jest
- name: Run smoke test.

View File

@ -56,8 +56,11 @@ jobs:
./vendor
key: ${{ runner.os }}-${{ hashFiles('./composer.lock') }}
- name: Setup and install composer
run: composer install
- name: Install PNPM and install dependencies
run: |
npm install -g pnpm
pnpm install
pnpm nx composer-install woocommerce
- name: Add PHP8 Compatibility.
run: |
@ -75,4 +78,4 @@ jobs:
run: ./tests/bin/install.sh woo_test root root 127.0.0.1 ${{ matrix.wp }}
- name: Run tests
run: ./vendor/bin/phpunit -c ./phpunit.xml
run: pnpm nx test-unit woocommerce

View File

@ -26,8 +26,8 @@ jobs:
run: |
npm install -g pnpm
pnpm install
composer install --no-dev
pnpm run build:assets
pnpm nx composer-install-no-dev woocommerce
pnpm nx build-assets woocommerce
pnpm install jest
- name: Run smoke test.

View File

@ -26,8 +26,8 @@ jobs:
run: |
npm install -g pnpm
pnpm install
composer install --no-dev
pnpm run build:assets
pnpm nx composer-install-no-dev woocommerce
pnpm nx build-assets woocommerce
pnpm install jest
- name: Run smoke test.
@ -82,7 +82,7 @@ jobs:
working-directory: package/woocommerce/plugins/woocommerce
env:
LATEST_WP_VERSION_MINUS: ${{ matrix.wp }}
run: pnpx wc-e2e docker:up
run: pnpm nx docker-up woocommerce
- name: Move current directory to code. We will install zip file in this dir later.
run: mv ./package/woocommerce/plugins/woocommerce/* ./code/woocommerce
@ -103,4 +103,4 @@ jobs:
WC_E2E_SCREENSHOTS: 1
E2E_SLACK_TOKEN: ${{ secrets.SMOKE_TEST_SLACK_TOKEN }}
E2E_SLACK_CHANNEL: ${{ secrets.RELEASE_TEST_SLACK_CHANNEL }}
run: pnpx wc-e2e test:e2e
run: pnpm nx test-e2e woocommerce

View File

@ -9,6 +9,7 @@ const {
applyCoupon,
removeCoupon,
} = require( '@woocommerce/e2e-utils' );
const { getCouponId, getCouponsTable } = require( '../utils/coupons' );
/**
* External dependencies
@ -19,36 +20,12 @@ const {
beforeAll,
} = require( '@jest/globals' );
const couponsTable = [
['fixed cart', { text: '$5.00' }, { text: '$4.99' }],
['percentage', { text: '$4.99' }, { text: '$5.00' }],
['fixed product', { text: '$5.00' }, { text: '$4.99' }]
];
let couponFixedCart;
let couponPercentage;
let couponFixedProduct;
const getCoupon = (couponType) => {
switch (couponType) {
case 'fixed cart':
return couponFixedCart;
case 'percentage':
return couponPercentage;
case 'fixed product':
return couponFixedProduct;
}
};
const runCartApplyCouponsTest = () => {
describe('Cart applying coupons', () => {
let productId;
beforeAll(async () => {
productId = await createSimpleProduct();
couponFixedCart = await createCoupon();
couponPercentage = await createCoupon('50', 'Percentage discount');
couponFixedProduct = await createCoupon('5', 'Fixed product discount');
await shopper.emptyCart();
await shopper.goToShop();
await shopper.addToCartFromShopPage( productId );
@ -56,8 +33,8 @@ const runCartApplyCouponsTest = () => {
await shopper.goToCart();
});
it.each(couponsTable)('allows cart to apply %s coupon', async (couponType, cartDiscount, orderTotal) => {
const coupon = getCoupon(couponType);
it.each( getCouponsTable() )( 'allows cart to apply %s coupon', async ( couponType, cartDiscount, orderTotal ) => {
const coupon = await getCouponId( couponType );
await applyCoupon(coupon);
await expect(page).toMatchElement('.woocommerce-message', { text: 'Coupon code applied successfully.' });
@ -69,9 +46,10 @@ const runCartApplyCouponsTest = () => {
});
it('prevents cart applying same coupon twice', async () => {
await applyCoupon(couponFixedCart);
const couponId = await getCouponId( 'fixed cart' );
await applyCoupon( couponId );
await expect(page).toMatchElement('.woocommerce-message', {text: 'Coupon code applied successfully.'});
await applyCoupon(couponFixedCart);
await applyCoupon( couponId );
// Verify only one discount applied
// This is a work around for Puppeteer inconsistently finding 'Coupon code already applied'
await expect(page).toMatchElement('.cart-discount .amount', {text: '$5.00'});
@ -79,7 +57,7 @@ const runCartApplyCouponsTest = () => {
});
it('allows cart to apply multiple coupons', async () => {
await applyCoupon(couponFixedProduct);
await applyCoupon( await getCouponId( 'fixed product' ) );
await expect(page).toMatchElement('.woocommerce-message', {text: 'Coupon code applied successfully.'});
// Verify discount applied and order total
@ -88,8 +66,8 @@ const runCartApplyCouponsTest = () => {
});
it('restores cart total when coupons are removed', async () => {
await removeCoupon(couponFixedCart);
await removeCoupon(couponFixedProduct);
await removeCoupon( await getCouponId( 'fixed cart' ) );
await removeCoupon( await getCouponId( 'fixed product' ) );
await expect(page).toMatchElement('.order-total .amount', {text: '$9.99'});
});
});

View File

@ -10,6 +10,7 @@ const {
removeCoupon,
waitForSelectorWithoutThrow,
} = require( '@woocommerce/e2e-utils' );
const { getCouponId, getCouponsTable } = require( '../utils/coupons' );
/**
* External dependencies
@ -20,26 +21,6 @@ const {
beforeAll,
} = require( '@jest/globals' );
const couponsTable = [
['fixed cart', { text: '$5.00' }, { text: '$4.99' }],
['percentage', { text: '$4.99' }, { text: '$5.00' }],
['fixed product', { text: '$5.00' }, { text: '$4.99' }]
];
let couponFixedCart;
let couponPercentage;
let couponFixedProduct;
const getCoupon = (couponType) => {
switch (couponType) {
case 'fixed cart':
return couponFixedCart;
case 'percentage':
return couponPercentage;
case 'fixed product':
return couponFixedProduct;
}
};
const runCheckoutApplyCouponsTest = () => {
describe('Checkout coupons', () => {
@ -47,9 +28,6 @@ const runCheckoutApplyCouponsTest = () => {
beforeAll(async () => {
productId = await createSimpleProduct();
couponFixedCart = await createCoupon();
couponPercentage = await createCoupon('50', 'Percentage discount');
couponFixedProduct = await createCoupon('5', 'Fixed product discount');
await shopper.emptyCart();
await shopper.goToShop();
await waitForSelectorWithoutThrow( '.add_to_cart_button' );
@ -58,8 +36,8 @@ const runCheckoutApplyCouponsTest = () => {
await shopper.goToCheckout();
});
it.each(couponsTable)('allows checkout to apply %s coupon', async (couponType, cartDiscount, orderTotal) => {
const coupon = getCoupon(couponType);
it.each( getCouponsTable() )( 'allows checkout to apply %s coupon', async ( couponType, cartDiscount, orderTotal ) => {
const coupon = await getCouponId( couponType );
await applyCoupon(coupon);
await expect(page).toMatchElement('.woocommerce-message', { text: 'Coupon code applied successfully.' });
@ -73,9 +51,10 @@ const runCheckoutApplyCouponsTest = () => {
});
it('prevents checkout applying same coupon twice', async () => {
await applyCoupon(couponFixedCart);
const couponId = await getCouponId( 'fixed cart' );
await applyCoupon( couponId );
await expect(page).toMatchElement('.woocommerce-message', {text: 'Coupon code applied successfully.'});
await applyCoupon(couponFixedCart);
await applyCoupon( couponId );
// Verify only one discount applied
// This is a work around for Puppeteer inconsistently finding 'Coupon code already applied'
await expect(page).toMatchElement('.cart-discount .amount', {text: '$5.00'});
@ -83,7 +62,7 @@ const runCheckoutApplyCouponsTest = () => {
});
it('allows checkout to apply multiple coupons', async () => {
await applyCoupon(couponFixedProduct);
await applyCoupon( await getCouponId( 'fixed product' ) );
await expect(page).toMatchElement('.woocommerce-message', {text: 'Coupon code applied successfully.'});
// Verify discount applied and order total
@ -92,8 +71,8 @@ const runCheckoutApplyCouponsTest = () => {
});
it('restores checkout total when coupons are removed', async () => {
await removeCoupon(couponFixedCart);
await removeCoupon(couponFixedProduct);
await removeCoupon( await getCouponId( 'fixed cart' ) );
await removeCoupon( await getCouponId( 'fixed product' ) );
await expect(page).toMatchElement('.order-total .amount', {text: '$9.99'});
});
});

View File

@ -0,0 +1,49 @@
/**
* Internal dependencies
*/
const { createCoupon } = require( '@woocommerce/e2e-utils' );
const couponsTable = [
[ 'fixed cart', { text: '$5.00' }, { text: '$4.99' } ],
[ 'percentage', { text: '$4.99' }, { text: '$5.00' } ],
[ 'fixed product', { text: '$5.00' }, { text: '$4.99' } ]
];
let couponFixedCart;
let couponPercentage;
let couponFixedProduct;
/**
* Get a test coupon Id. Create the coupon if it does not exist.
*
* @param {string} couponType Coupon type.
* @return {string} Coupon code.
*/
const getCouponId = async ( couponType ) => {
switch ( couponType ) {
case 'fixed cart':
if ( ! couponFixedCart ) {
couponFixedCart = await createCoupon();
}
return couponFixedCart;
case 'percentage':
if ( ! couponPercentage ) {
couponPercentage = await createCoupon( '50', 'Percentage discount' );
}
return couponPercentage;
case 'fixed product':
if ( ! couponFixedProduct ) {
couponFixedProduct = await createCoupon( '5', 'Fixed product discount' );
}
return couponFixedProduct;
}
};
const getCouponsTable = () => {
return couponsTable;
};
module.exports = {
getCouponsTable,
getCouponId,
};

View File

@ -21,8 +21,8 @@
"pelago/emogrifier": "3.1.0",
"psr/container": "1.0.0",
"woocommerce/action-scheduler": "3.3.0",
"woocommerce/woocommerce-admin": "2.8.0",
"woocommerce/woocommerce-blocks": "6.1.0"
"woocommerce/woocommerce-admin": "2.9.0-rc.2",
"woocommerce/woocommerce-blocks": "6.3.2"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.4",

View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "f6fc527d8719df0b0247ee188eb3eee9",
"content-hash": "83379234b653f45a89537a0bb470eb69",
"packages": [
{
"name": "automattic/jetpack-autoloader",
@ -542,16 +542,16 @@
},
{
"name": "woocommerce/woocommerce-admin",
"version": "2.8.0",
"version": "2.9.0-rc.2",
"source": {
"type": "git",
"url": "https://github.com/woocommerce/woocommerce-admin.git",
"reference": "63b93a95db4bf788f42587a41f2378128a2adfdf"
"reference": "6c81e761d9a19e6ed4484db82d6710331f375a3a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/63b93a95db4bf788f42587a41f2378128a2adfdf",
"reference": "63b93a95db4bf788f42587a41f2378128a2adfdf",
"url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/6c81e761d9a19e6ed4484db82d6710331f375a3a",
"reference": "6c81e761d9a19e6ed4484db82d6710331f375a3a",
"shasum": ""
},
"require": {
@ -607,22 +607,22 @@
"homepage": "https://github.com/woocommerce/woocommerce-admin",
"support": {
"issues": "https://github.com/woocommerce/woocommerce-admin/issues",
"source": "https://github.com/woocommerce/woocommerce-admin/tree/v2.8.0"
"source": "https://github.com/woocommerce/woocommerce-admin/tree/v2.9.0-rc.2"
},
"time": "2021-11-02T19:28:38+00:00"
"time": "2021-11-18T08:35:56+00:00"
},
{
"name": "woocommerce/woocommerce-blocks",
"version": "v6.1.0",
"version": "v6.3.2",
"source": {
"type": "git",
"url": "https://github.com/woocommerce/woocommerce-gutenberg-products-block.git",
"reference": "8556efd69e85c01f5571d39e6581d9b8486b682f"
"reference": "5b3aea9adb718a1f78525881e4f0c33c72ba175d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/woocommerce/woocommerce-gutenberg-products-block/zipball/8556efd69e85c01f5571d39e6581d9b8486b682f",
"reference": "8556efd69e85c01f5571d39e6581d9b8486b682f",
"url": "https://api.github.com/repos/woocommerce/woocommerce-gutenberg-products-block/zipball/5b3aea9adb718a1f78525881e4f0c33c72ba175d",
"reference": "5b3aea9adb718a1f78525881e4f0c33c72ba175d",
"shasum": ""
},
"require": {
@ -630,6 +630,8 @@
"composer/installers": "^1.7.0"
},
"require-dev": {
"johnbillion/wp-hooks-generator": "0.6.1",
"mockery/mockery": "^1.4",
"woocommerce/woocommerce-sniffs": "0.1.0",
"wp-phpunit/wp-phpunit": "^5.4",
"yoast/phpunit-polyfills": "^1.0"
@ -659,9 +661,9 @@
],
"support": {
"issues": "https://github.com/woocommerce/woocommerce-gutenberg-products-block/issues",
"source": "https://github.com/woocommerce/woocommerce-gutenberg-products-block/tree/v6.1.0"
"source": "https://github.com/woocommerce/woocommerce-gutenberg-products-block/tree/v6.3.2"
},
"time": "2021-10-12T13:07:11+00:00"
"time": "2021-11-18T03:27:03+00:00"
}
],
"packages-dev": [

View File

@ -13,8 +13,6 @@
"wp_org_slug": "woocommerce"
},
"scripts": {
"composer:install": "composer install",
"composer:dump-autoload": "composer dump-autoload",
"preinstall": "npx only-allow pnpm",
"build": "./bin/build-zip.sh",
"build:core": "grunt && pnpm run makepot",

View File

@ -4,17 +4,26 @@
"projectType": "application",
"targets": {
"composer-install": {
"executor": "@nrwl/workspace:run-script",
"executor": "@nrwl/workspace:run-commands",
"options": {
"script": "composer:install"
"command": "composer install",
"cwd": "plugins/woocommerce"
}
},
},
"composer-install-no-dev": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "composer install --no-dev",
"cwd": "plugins/woocommerce"
}
},
"composer-dump-autoload": {
"executor": "@nrwl/workspace:run-script",
"executor": "@nrwl/workspace:run-commands",
"options": {
"script": "composer:dump-autoload"
"command": "composer dump-autoload",
"cwd": "plugins/woocommerce"
}
},
},
"build": {
"executor": "@nrwl/workspace:run-script",
"options": {
@ -122,6 +131,20 @@
"options": {
"script": "make:collection"
}
},
"install-unit-test-db": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "bash tests/bin/install.sh woo_test root root 127.0.0.1 latest",
"cwd": "plugins/woocommerce"
}
},
"test-code-coverage": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "RUN_CODE_COVERAGE=1 bash tests/bin/phpunit.sh",
"cwd": "plugins/woocommerce"
}
}
}
}

View File

@ -255,10 +255,6 @@ CREATE TABLE ' . $this->lookup_table_name . '(
* @return array The tools array with the entry added.
*/
private function add_initiate_regeneration_entry_to_tools_array( array $tools_array ) {
if ( ! $this->data_store->is_feature_visible() ) {
return $tools_array;
}
$lookup_table_exists = $this->data_store->check_lookup_table_exists();
$generation_is_in_progress = $this->data_store->regeneration_is_in_progress();
@ -375,9 +371,6 @@ CREATE TABLE ' . $this->lookup_table_name . '(
* @throws \Exception Something prevents the regeneration from starting.
*/
private function check_can_do_lookup_table_regeneration( $product_id = null ) {
if ( ! $this->data_store->is_feature_visible() ) {
throw new \Exception( "Can't do product attribute lookup data regeneration: feature is not visible" );
}
if ( $product_id && ! $this->data_store->check_lookup_table_exists() ) {
throw new \Exception( "Can't do product attribute lookup data regeneration: lookup table doesn't exist" );
}

View File

@ -63,13 +63,17 @@ class Filterer {
return $args;
}
$clause_root = " {$wpdb->prefix}posts.ID IN (";
// The extra derived table ("SELECT product_or_parent_id FROM") is needed for performance
// (causes the filtering subquery to be executed only once).
$clause_root = " {$wpdb->posts}.ID IN ( SELECT product_or_parent_id FROM (";
if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) ) {
$in_stock_clause = ' AND in_stock = 1';
} else {
$in_stock_clause = '';
}
$attribute_ids_for_and_filtering = array();
foreach ( $attributes_to_filter_by as $taxonomy => $data ) {
$all_terms = get_terms( $taxonomy, array( 'hide_empty' => false ) );
$term_ids_by_slug = wp_list_pluck( $all_terms, 'term_id', 'slug' );
@ -79,24 +83,10 @@ class Filterer {
$is_and_query = 'and' === $data['query_type'];
$count = count( $term_ids_to_filter_by );
if ( 0 !== $count ) {
if ( $is_and_query ) {
$clauses[] = "
{$clause_root}
SELECT product_or_parent_id
FROM {$this->lookup_table_name} lt
WHERE is_variation_attribute=0
{$in_stock_clause}
AND term_id in {$term_ids_to_filter_by_list}
GROUP BY product_id
HAVING COUNT(product_id)={$count}
UNION
SELECT product_or_parent_id
FROM {$this->lookup_table_name} lt
WHERE is_variation_attribute=1
{$in_stock_clause}
AND term_id in {$term_ids_to_filter_by_list}
)";
if ( $is_and_query && $count > 1 ) {
$attribute_ids_for_and_filtering = array_merge( $attribute_ids_for_and_filtering, $term_ids_to_filter_by );
} else {
$clauses[] = "
{$clause_root}
@ -109,8 +99,30 @@ class Filterer {
}
}
if ( ! empty( $attribute_ids_for_and_filtering ) ) {
$count = count( $attribute_ids_for_and_filtering );
$term_ids_to_filter_by_list = '(' . join( ',', $attribute_ids_for_and_filtering ) . ')';
$clauses[] = "
{$clause_root}
SELECT product_or_parent_id
FROM {$this->lookup_table_name} lt
WHERE is_variation_attribute=0
{$in_stock_clause}
AND term_id in {$term_ids_to_filter_by_list}
GROUP BY product_id
HAVING COUNT(product_id)={$count}
UNION
SELECT product_or_parent_id
FROM {$this->lookup_table_name} lt
WHERE is_variation_attribute=1
{$in_stock_clause}
AND term_id in {$term_ids_to_filter_by_list}
)";
}
if ( ! empty( $clauses ) ) {
$args['where'] .= ' AND (' . join( ' AND ', $clauses ) . ')';
// "temp" is needed because the extra derived tables require an alias.
$args['where'] .= ' AND (' . join( ' temp ) AND ', $clauses ) . ' temp ))';
} elseif ( ! empty( $attributes_to_filter_by ) ) {
$args['where'] .= ' AND 1=0';
}
@ -228,10 +240,12 @@ class Filterer {
}
if ( ! empty( $and_term_ids ) ) {
$terms_count = count( $and_term_ids );
$term_ids_list = '(' . join( ',', $and_term_ids ) . ')';
$terms_count = count( $and_term_ids );
$term_ids_list = '(' . join( ',', $and_term_ids ) . ')';
// The extra derived table ("SELECT product_or_parent_id FROM") is needed for performance
// (causes the filtering subquery to be executed only once).
$query['where'] .= "
AND product_or_parent_id IN (
AND product_or_parent_id IN ( SELECT product_or_parent_id FROM (
SELECT product_or_parent_id
FROM {$this->lookup_table_name} lt
WHERE is_variation_attribute=0
@ -245,17 +259,17 @@ class Filterer {
WHERE is_variation_attribute=1
{$in_stock_clause}
AND term_id in {$term_ids_list}
)";
) temp )";
}
if ( ! empty( $or_term_ids ) ) {
$term_ids_list = '(' . join( ',', $or_term_ids ) . ')';
$query['where'] .= "
AND product_or_parent_id IN (
AND product_or_parent_id IN ( SELECT product_or_parent_id FROM (
SELECT product_or_parent_id FROM {$this->lookup_table_name}
WHERE term_id in {$term_ids_list}
{$in_stock_clause}
)";
) temp )";
}
} else {

View File

@ -30,13 +30,6 @@ class LookupDataStore {
*/
private $lookup_table_name;
/**
* Is the feature visible?
*
* @var bool
*/
private $is_feature_visible;
/**
* LookupDataStore constructor. Makes the feature hidden by default.
*/
@ -44,7 +37,6 @@ class LookupDataStore {
global $wpdb;
$this->lookup_table_name = $wpdb->prefix . 'wc_product_attributes_lookup';
$this->is_feature_visible = false;
$this->init_hooks();
}
@ -65,7 +57,7 @@ class LookupDataStore {
add_filter(
'woocommerce_get_sections_products',
function ( $products ) {
if ( $this->is_feature_visible() && $this->check_lookup_table_exists() ) {
if ( $this->check_lookup_table_exists() ) {
$products['advanced'] = __( 'Advanced', 'woocommerce' );
}
return $products;
@ -77,7 +69,7 @@ class LookupDataStore {
add_filter(
'woocommerce_get_settings_products',
function ( $settings, $section_id ) {
if ( 'advanced' === $section_id && $this->is_feature_visible() && $this->check_lookup_table_exists() ) {
if ( 'advanced' === $section_id && $this->check_lookup_table_exists() ) {
$title_item = array(
'title' => __( 'Product attributes lookup table', 'woocommerce' ),
'type' => 'title',
@ -136,29 +128,6 @@ class LookupDataStore {
return $this->lookup_table_name === $wpdb->get_var( $query );
}
/**
* Checks if the feature is visible (so that dedicated entries will be added to the debug tools page).
*
* @return bool True if the feature is visible.
*/
public function is_feature_visible() {
return $this->is_feature_visible;
}
/**
* Makes the feature visible, so that dedicated entries will be added to the debug tools page.
*/
public function show_feature() {
$this->is_feature_visible = true;
}
/**
* Hides the feature, so that no entries will be added to the debug tools page.
*/
public function hide_feature() {
$this->is_feature_visible = false;
}
/**
* Get the name of the lookup table.
*