Merge branch 'trunk' into add/api-t-order-search

This commit is contained in:
Rodel 2021-12-01 23:43:23 +08:00
commit 99f63cb378
227 changed files with 2351 additions and 1146 deletions

View File

@ -28,7 +28,7 @@ jobs:
run: |
npm install -g pnpm
pnpm install
pnpm nx composer-install-no-dev" woocommerce
pnpm nx composer-install-no-dev woocommerce
pnpm nx build-assets woocommerce
pnpm install jest

View File

@ -73,10 +73,11 @@ jobs:
with:
path: package/woocommerce
- name: Run npm install.
working-directory: package/woocommerce/plugins/woocommerce
npm install -g pnpm
pnpm install
- 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

View File

@ -34,9 +34,8 @@ The port # might be different depending on your `.wp-env.override.json` configur
Once you have WP-ENV container up, we need to run a few commands to start developing.
1. Run `pnpm install` to install npm modules.
2. Navigate to Core WooCommerce `cd plugins/woocommerce`.
3. Run `pnpm run build:core`
4. Run `composer install` to install PHP dependencies.
2. Run `pnpm nx build woocommerce` to build core.
3. Run `pnpm nx composer-install woocommerce` to install PHP dependencies.
If you don't have Composer available locally, run the following command. It runs the command in WP-ENV container.

View File

@ -6,4 +6,5 @@
- Coupons API Tests
- Refunds API Tests
- Products API Tests
- CRUD tests for the Orders API
- Order Search API Tests

View File

@ -12,15 +12,15 @@
"formatter": {
"filename": "../../../tools/changelogger/PackageFormatter.php"
},
"types": [
"Fix",
"Add",
"Update",
"Dev",
"Tweak",
"Performance",
"Enhancement"
],
"types": {
"fix": "Fixes an existing bug",
"add": "Adds functionality",
"update": "Update existing functionality",
"dev": "Development related task",
"tweak": "A minor adjustment to the codebase",
"performance": "Address performance issues",
"enhancement": "Improve existing functionality"
},
"changelog": "NEXT_CHANGELOG.md"
}
}

View File

@ -14,5 +14,5 @@ const refund = {
};
module.exports = {
refund: refund,
refund,
};

View File

@ -0,0 +1,215 @@
const { ordersApi, productsApi } = require( '../../endpoints' );
const { order } = require( '../../data' );
/**
* Billing properties to update.
*/
const updatedCustomerBilling = {
first_name: 'Jane',
last_name: 'Doe',
company: 'Automattic',
country: 'US',
address_1: '123 Market Street',
address_2: 'Suite 500',
city: 'Austin',
state: 'TX',
postcode: '73301',
phone: '123456789',
email: 'jane.doe@example.com',
};
/**
* Shipping properties to update.
*/
const updatedCustomerShipping = {
first_name: 'Mike',
last_name: 'Anderson',
company: 'Automattic',
country: 'US',
address_1: '123 Ocean Ave',
address_2: '',
city: 'New York',
state: 'NY',
postcode: '10013',
phone: '123456789',
};
/**
* Data tables to be used for testing the 'Create an order' API.
*/
const statusesDataTable = [
'pending',
'processing',
'on-hold',
'completed',
'cancelled',
'refunded',
'failed',
];
/**
* A simple product that will be added to an order.
*/
const simpleProduct = {
name: 'Incredible Plastic Table',
regular_price: '48',
};
/**
* Tests for the WooCommerce Orders API.
*
* @group api
* @group orders
*
*/
describe( 'Orders API tests: CRUD', () => {
let orderId;
describe( 'Create an order', () => {
it( 'can create a pending order by default', async () => {
// Create an order that has a null status
const requestPayload = {
...order,
status: null,
};
const { body, status } = await ordersApi.create.order(
requestPayload
);
// Save the order ID. It will be used by the retrieve, update, and delete tests.
orderId = body.id;
// Verify that the order status is 'pending'
expect( status ).toEqual( ordersApi.create.responseCode );
expect( typeof body.id ).toEqual( 'number' );
expect( body.status ).toEqual( 'pending' );
} );
it.each( statusesDataTable )(
"can create an order with status '%s'",
async ( expectedStatus ) => {
const requestPayload = {
...order,
status: expectedStatus,
};
const { status, body } = await ordersApi.create.order(
requestPayload
);
expect( status ).toEqual( ordersApi.create.responseCode );
expect( typeof body.id ).toEqual( 'number' );
expect( body.status ).toEqual( expectedStatus );
// Cleanup: Delete this order
await ordersApi.delete.order( body.id, true );
}
);
} );
describe( 'Retrieve an order', () => {
it( 'can retrieve an order', async () => {
const response = await ordersApi.retrieve.order( orderId );
expect( response.status ).toEqual(
ordersApi.retrieve.responseCode
);
expect( response.body.id ).toEqual( orderId );
} );
} );
describe( 'Update an order', () => {
beforeAll( async () => {
// Create the product and save its id
const { body } = await productsApi.create.product( simpleProduct );
simpleProduct.id = body.id;
} );
afterAll( async () => {
// Delete the created product
await productsApi.delete.product( simpleProduct.id, true );
} );
it.each( statusesDataTable )(
"can update status of an order to '%s'",
async ( expectedOrderStatus ) => {
const requestPayload = {
status: expectedOrderStatus,
};
const { status, body } = await ordersApi.update.order(
orderId,
requestPayload
);
expect( status ).toEqual( ordersApi.update.responseCode );
expect( body.id ).toEqual( orderId );
expect( body.status ).toEqual( expectedOrderStatus );
}
);
it( 'can add shipping and billing contacts to an order', async () => {
// Update the billing and shipping fields on the order
order.billing = updatedCustomerBilling;
order.shipping = updatedCustomerShipping;
const response = await ordersApi.update.order( orderId, order );
expect( response.status ).toEqual( ordersApi.update.responseCode );
expect( response.body.billing ).toEqual( updatedCustomerBilling );
expect( response.body.shipping ).toEqual( updatedCustomerShipping );
} );
it( 'can add a product to an order', async () => {
// Add the product to the order
const requestPayload = {
line_items: [ { product_id: simpleProduct.id } ],
};
const { body, status } = await ordersApi.update.order(
orderId,
requestPayload
);
// Verify that the added product has the correct values
expect( status ).toEqual( ordersApi.update.responseCode );
expect( body.line_items ).toHaveLength( 1 );
expect( body.line_items[ 0 ].product_id ).toEqual(
simpleProduct.id
);
expect( body.line_items[ 0 ].name ).toEqual( simpleProduct.name );
} );
it( 'can pay for an order', async () => {
// Setup: Set order status to 'pending'
await ordersApi.update.order( orderId, {
status: 'pending',
} );
// Pay for the order by setting `set_paid` to true
const updateRequestPayload = {
set_paid: true,
};
const { status, body } = await ordersApi.update.order(
orderId,
updateRequestPayload
);
expect( status ).toEqual( ordersApi.update.responseCode );
expect( body.id ).toEqual( orderId );
// Validate that the status of the order was automatically set to 'processing'
expect( body.status ).toEqual( 'processing' );
// Validate that the date_paid and date_paid_gmt properties are no longer null
expect( body.date_paid ).not.toBeNull();
expect( body.date_paid_gmt ).not.toBeNull();
} );
} );
describe( 'Delete an order', () => {
it( 'can permanently delete an order', async () => {
// Delete the order.
const response = await ordersApi.delete.order( orderId, true );
expect( response.status ).toEqual( ordersApi.delete.responseCode );
// Verify that the order can no longer be retrieved.
const getOrderResponse = await ordersApi.retrieve.order( orderId );
expect( getOrderResponse.status ).toEqual( 404 );
} );
} );
} );

View File

@ -12,15 +12,15 @@
"formatter": {
"filename": "../../../tools/changelogger/PackageFormatter.php"
},
"types": [
"Fix",
"Add",
"Update",
"Dev",
"Tweak",
"Performance",
"Enhancement"
],
"types": {
"fix": "Fixes an existing bug",
"add": "Adds functionality",
"update": "Update existing functionality",
"dev": "Development related task",
"tweak": "A minor adjustment to the codebase",
"performance": "Address performance issues",
"enhancement": "Improve existing functionality"
},
"changelog": "NEXT_CHANGELOG.md"
}
}

1
packages/js/e2e-core-tests/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/test-data/sample_products.csv

View File

@ -1,8 +1,14 @@
# Unreleased
## Added
- A `specs/data` folder to store page element data.
- Tests to verify that different top-level menu and their associated sub-menus load successfully.
## Changed
- New coupon test deletes the coupon instead of trashing it.
- A copy of sample_data.csv is included in the package.
# 0.1.6

View File

@ -72,6 +72,7 @@ The functions to access the core tests are:
- `runAnalyticsPageLoadsTest` - Merchant can load and see all pages in Analytics
- `runImportProductsTest` - Merchant can import products via CSV file
- `runInitiateWccomConnectionTest` - Merchant can initiate connection to WooCommerce.com
- `runAdminPageLoadTests` - Merchant can load pages from the WP Admin sidebar
### Shopper

View File

@ -0,0 +1,8 @@
#!/usr/bin/env bash
#
# Copy the WooCommerce sample data file to the package
#
PACKAGEPATH=$(dirname $(dirname "$0"))
cp -v $PACKAGEPATH/../../../plugins/woocommerce/sample-data/sample_products.csv $PACKAGEPATH/test-data

View File

@ -12,15 +12,15 @@
"formatter": {
"filename": "../../../tools/changelogger/PackageFormatter.php"
},
"types": [
"Fix",
"Add",
"Update",
"Dev",
"Tweak",
"Performance",
"Enhancement"
],
"types": {
"fix": "Fixes an existing bug",
"add": "Adds functionality",
"update": "Update existing functionality",
"dev": "Development related task",
"tweak": "A minor adjustment to the codebase",
"performance": "Address performance issues",
"enhancement": "Improve existing functionality"
},
"changelog": "NEXT_CHANGELOG.md"
}
}

View File

@ -11,6 +11,7 @@
"main": "index.js",
"dependencies": {
"@jest/globals": "^26.4.2",
"@wordpress/deprecated": "^3.2.3",
"config": "3.3.3",
"faker": "^5.1.0"
},
@ -20,5 +21,9 @@
},
"publishConfig": {
"access": "public"
},
"scripts": {
"build": "./bin/build.sh",
"prepare": "pnpm run build"
}
}

View File

@ -11,6 +11,7 @@ const {
describe,
beforeAll,
} = require( '@jest/globals' );
import deprecated from '@wordpress/deprecated';
const runActivationTest = () => {
describe('Store owner can login and make sure WooCommerce is activated', () => {
@ -19,6 +20,10 @@ const runActivationTest = () => {
});
it('can make sure WooCommerce is activated. If not, activate it', async () => {
deprecated( 'runActivationTest', {
alternative: '@woocommerce/admin-e2e-tests `testAdminBasicSetup()`',
});
const slug = 'woocommerce';
await merchant.openPlugins();
const disableLink = await page.$(`tr[data-slug="${slug}"] .deactivate a`);

View File

@ -13,6 +13,7 @@ const {
* External dependencies
*/
const config = require( 'config' );
import deprecated from '@wordpress/deprecated';
const {
it,
describe,
@ -47,6 +48,9 @@ const runOnboardingFlowTest = () => {
}
it('can start and complete onboarding when visiting the site for the first time.', async () => {
deprecated( 'runOnboardingFlowTest', {
alternative: '@woocommerce/admin-e2e-tests `testAdminOnboardingWizard()`',
});
await completeOnboardingWizard();
});
});
@ -59,6 +63,9 @@ const runTaskListTest = () => {
});
it('can setup shipping', async () => {
deprecated( 'runTaskListTest', {
alternative: '@woocommerce/admin-e2e-tests `testAdminHomescreenTasklist()`',
});
await page.evaluate(() => {
document.querySelector('.woocommerce-list__item-title').scrollIntoView();
});

View File

@ -6,6 +6,7 @@ const {
it,
describe,
} = require( '@jest/globals' );
import deprecated from '@wordpress/deprecated';
/**
* Internal dependencies
@ -31,6 +32,9 @@ const runInitialStoreSettingsTest = () => {
});
it('can enable tax rates and calculations', async () => {
deprecated( 'runInitialStoreSettingsTest', {
alternative: '@woocommerce/admin-e2e-tests `testAdminBasicSetup()`',
});
// Go to general settings page
await merchant.openSettings('general');

View File

@ -0,0 +1,85 @@
/**
* WP top-level menu items and their associated sub-menus
*/
export const MENUS = [
[
'WooCommerce',
'#adminmenu > li:nth-child(8) > a',
[
[
'Home',
'#toplevel_page_woocommerce > ul > li:nth-child(2) > a',
'Home',
],
[
'Orders',
'#toplevel_page_woocommerce > ul > li:nth-child(3) > a',
'Orders',
],
[
'Reports',
'#toplevel_page_woocommerce > ul > li:nth-child(6) > a',
'Orders',
],
[
'Settings',
'#toplevel_page_woocommerce > ul > li:nth-child(7) > a',
'General',
],
[
'Status',
'#toplevel_page_woocommerce > ul > li:nth-child(8) > a',
'System status',
],
// [ 'Extensions', '#toplevel_page_woocommerce > ul > li:nth-child(9)', 'Extensions' ],
],
],
[
'Products',
'#adminmenu > li:nth-child(9) > a',
[
[
'All Products',
'#menu-posts-product > ul > li:nth-child(2) > a',
'Products',
],
[
'Add New',
'#menu-posts-product > ul > li:nth-child(3) > a',
'Add New',
],
[
'Categories',
'#menu-posts-product > ul > li:nth-child(4) > a',
'Product categories',
],
[
'Product tags',
'#menu-posts-product > ul > li:nth-child(5) > a',
'Product tags',
],
[
'Attributes',
'#menu-posts-product > ul > li:nth-child(6) > a',
'Attributes',
],
],
],
[
'Marketing',
'#adminmenu > li:nth-child(11) > a',
[
[
'Overview',
'#toplevel_page_woocommerce-marketing > ul > li:nth-child(2) > a',
'Overview',
],
[
'Coupons',
'#toplevel_page_woocommerce-marketing > ul > li:nth-child(3) > a',
'Coupons',
],
],
],
];

View File

@ -37,6 +37,7 @@ const runProductSettingsTest = require( './merchant/wp-admin-settings-product.te
const runTaxSettingsTest = require( './merchant/wp-admin-settings-tax.test' );
const runOrderStatusFiltersTest = require( './merchant/wp-admin-order-status-filters.test' );
const runOrderRefundTest = require( './merchant/wp-admin-order-refund.test' );
const runOrderRefundRestockTest = require( './merchant/wp-admin-order-refund-restock.test' );
const runOrderApplyCouponTest = require( './merchant/wp-admin-order-apply-coupon.test' );
const runProductEditDetailsTest = require( './merchant/wp-admin-product-edit-details.test' );
const runProductSearchTest = require( './merchant/wp-admin-product-search.test' );
@ -46,6 +47,7 @@ const runOrderSearchingTest = require( './merchant/wp-admin-order-searching.test
const runAnalyticsPageLoadsTest = require( './merchant/wp-admin-analytics-page-loads.test' );
const runImportProductsTest = require( './merchant/wp-admin-product-import-csv.test' );
const runInitiateWccomConnectionTest = require( './merchant/wp-admin-extensions-connect-wccom.test' );
const runAdminPageLoadTests = require( './merchant/wp-admin-page-loads.test.js' );
// REST API tests
const runExternalProductAPITest = require( './api/external-product.test' );
@ -95,12 +97,14 @@ const runMerchantTests = () => {
runTaxSettingsTest();
runOrderStatusFiltersTest();
runOrderRefundTest();
runOrderRefundRestockTest();
runOrderApplyCouponTest();
runProductEditDetailsTest();
runProductSearchTest();
runMerchantOrdersCustomerPaymentPage();
runAnalyticsPageLoadsTest();
runInitiateWccomConnectionTest();
runAdminPageLoadTests();
}
const runApiTests = () => {
@ -142,6 +146,7 @@ module.exports = {
runOrderApiTest,
runOrderStatusFiltersTest,
runOrderRefundTest,
runOrderRefundRestockTest,
runOrderApplyCouponTest,
runProductEditDetailsTest,
runProductSearchTest,
@ -163,4 +168,5 @@ module.exports = {
runOrderEmailReceivingTest,
runInitiateWccomConnectionTest,
runTelemetryAPITest,
runAdminPageLoadTests,
};

View File

@ -15,6 +15,7 @@ const {
describe,
beforeAll,
} = require( '@jest/globals' );
import deprecated from '@wordpress/deprecated';
/**
* Quick check for page title and no data message.
@ -57,6 +58,10 @@ const runAnalyticsPageLoadsTest = () => {
await merchant.login();
});
deprecated( 'runAnalyticsPageLoadsTest', {
alternative: '@woocommerce/admin-e2e-tests `testAdminAnalyticsPages()`',
});
it.each(pages)(
'can see %s page properly',
async (pageTitle, element, elementText) => {

View File

@ -0,0 +1,117 @@
/**
* Internal dependencies
*/
const {
merchant,
createOrder,
createSimpleProduct,
verifyCheckboxIsSet,
uiUnblocked,
evalAndClick,
clickUpdateOrder,
} = require( '@woocommerce/e2e-utils' );
const { waitForSelector } = require( '@woocommerce/e2e-environment' );
/**
* Evaluate and click a button selector then wait for a result selector.
* This is a work around for what appears to be intermittent delays in handling confirm dialogs.
*
* @param {string} buttonSelector
* @param {string} resultSelector
* @returns {Promise<void>}
*/
const clickAndWaitForSelector = async ( buttonSelector, resultSelector ) => {
await evalAndClick( buttonSelector );
await waitForSelector( page, resultSelector, {
timeout: 5000,
} );
};
const getRefundQuantityInputSelector = ( productName ) =>
`td.name[data-sort-value="${ productName }"] ~ td.quantity input.refund_order_item_qty`;
const runOrderRefundRestockTest = () => {
describe( 'WooCommerce Orders > Refund and restock an order item', () => {
// See: https://github.com/woocommerce/woocommerce/issues/30618
it( 'Can update order after refunding item without automatic stock adjustment', async () => {
const noInventoryProductId = await createSimpleProduct();
const productToRestockId = await createSimpleProduct(
'Product with Stock',
'10',
{
trackInventory: true,
remainingStock: 10,
}
);
const orderId = await createOrder( {
status: 'completed',
lineItems: [
{
product_id: noInventoryProductId,
},
{
product_id: productToRestockId,
quantity: 2,
},
],
} );
await merchant.login();
await merchant.goToOrder( orderId );
// Get the currency symbol for the store's selected currency
await page.waitForSelector( '.woocommerce-Price-currencySymbol' );
// Verify stock reduction system note was added
await expect( page ).toMatchElement( '.system-note', {
text: `Stock levels reduced: Product with Stock (#${ productToRestockId }) 10→8`,
} );
// Click the Refund button
await expect( page ).toClick( 'button.refund-items' );
// Verify the refund section shows
await page.waitForSelector( 'div.wc-order-refund-items', {
visible: true,
} );
await verifyCheckboxIsSet( '#restock_refunded_items' );
// Initiate a refund
await expect( page ).toFill(
getRefundQuantityInputSelector( 'Product with Stock' ),
'2'
);
await expect( page ).toFill( '#refund_reason', 'No longer wanted' );
await clickAndWaitForSelector(
'.do-manual-refund',
'.quantity .refunded'
);
await uiUnblocked();
// Verify restock system note was added
await expect( page ).toMatchElement( '.system-note', {
text: `Item #${ productToRestockId } stock increased from 8 to 10.`,
} );
// Update the order.
await clickUpdateOrder( 'Order updated.' );
// Verify that inventory wasn't modified.
// For some reason using expect().not.toMatchElement() did not work for this case.
expect(
await page.$$eval( '.note', ( notes ) =>
notes.every(
( note ) =>
! note.textContent.match(
/Adjusted stock: Product with Stock \(10→8\)/
)
)
)
).toEqual( true );
} );
} );
};
module.exports = runOrderRefundRestockTest;

View File

@ -0,0 +1,49 @@
/**
* Internal dependencies
*/
const { merchant } = require( '@woocommerce/e2e-utils' );
const { MENUS } = require( '../data/elements' );
/**
* External dependencies
*/
const { it, describe, beforeAll } = require( '@jest/globals' );
const runPageLoadTest = () => {
describe.each( MENUS )(
' %s > Opening Top Level Pages',
( menuTitle, menuElement, subMenus ) => {
beforeAll( async () => {
await merchant.login();
} );
afterAll( async () => {
await merchant.logout();
} );
it.each( subMenus )(
'can see %s page properly',
async ( subMenuTitle, subMenuElement, subMenuText ) => {
// Go to Top Level Menu
await Promise.all( [
page.click( menuElement ),
page.waitForNavigation( { waitUntil: 'networkidle0' } ),
] );
// Click sub-menu item and wait for the page to finish loading
await Promise.all( [
page.click( subMenuElement ),
page.waitForNavigation( { waitUntil: 'networkidle0' } ),
] );
await expect( page ).toMatchElement( 'h1', {
text: subMenuText,
} );
}
);
}
);
};
// eslint-disable-next-line jest/no-export
module.exports = runPageLoadTest;

View File

@ -17,8 +17,8 @@ const { it, describe, beforeAll, afterAll } = require( '@jest/globals' );
const path = require( 'path' );
const coreTestsPath = getCoreTestsRoot();
const filePath = path.resolve(
coreTestsPath.appRoot,
'plugins/woocommerce/sample-data/sample_products.csv'
coreTestsPath.packageRoot,
'test-data/sample_products.csv'
);
const filePathOverride = path.resolve(
coreTestsPath.packageRoot,

View File

@ -8,12 +8,13 @@ const {
uiUnblocked,
evalAndClick,
setCheckbox,
setBrowserViewport,
verifyAndPublish,
waitForSelector,
waitForSelectorWithoutThrow
} = require( '@woocommerce/e2e-utils' );
const {
waitAndClick,
waitForSelector,
} = require( '@woocommerce/e2e-environment' );
/**
@ -45,6 +46,13 @@ const runAddSimpleProductTest = () => {
});
it('can create simple virtual product and add it to the cart', async () => {
// @todo: remove this once https://github.com/woocommerce/woocommerce/issues/31337 has been addressed
await setBrowserViewport( {
width: 970,
height: 700,
} );
await openNewProductAndVerify();
// Set product data and publish the product
@ -72,6 +80,12 @@ const runAddSimpleProductTest = () => {
});
it('can create simple non-virtual product and add it to the cart', async () => {
// @todo: remove this once https://github.com/woocommerce/woocommerce/issues/31337 has been addressed
await setBrowserViewport( {
width: 960,
height: 700,
} );
await merchant.login();
await openNewProductAndVerify();

View File

@ -39,6 +39,10 @@ const runAddNewShippingZoneTest = () => {
await merchant.login();
});
afterAll( async () => {
shopper.logout();
} );
it('add shipping zone for San Francisco with free Local pickup', async () => {
// Add a new shipping zone for San Francisco 94107, CA, US with Local pickup
await addShippingZoneAndMethod(shippingZoneNameSF, california, sanFranciscoZIP, 'local_pickup');

View File

@ -25,6 +25,10 @@ const runMyAccountCreateAccountTest = () => {
await merchant.logout();
});
afterAll( async () => {
shopper.logout();
} );
it('can create a new account via my account', async () => {
await shopper.gotoMyAccount();
await page.waitForSelector('.woocommerce-form-register');

View File

@ -34,6 +34,10 @@ const runMyAccountPayOrderTest = () => {
await merchant.logout();
});
afterAll( async () => {
shopper.logout();
} );
it('allows customer to pay for their order in My Account', async () => {
await shopper.login();
await shopper.goToOrders();

View File

@ -15,6 +15,10 @@ const pages = [
const runMyAccountPageTest = () => {
describe('My account page', () => {
afterAll( async () => {
shopper.logout();
} );
it('allows customer to login', async () => {
await shopper.login();
expect(page).toMatch('Hello');

View File

@ -30,12 +30,16 @@ const runOrderEmailReceivingTest = () => {
describe('Shopper Order Email Receiving', () => {
beforeAll(async () => {
simplePostIdValue = await createSimpleProduct();
await merchant.login();
await deleteAllEmailLogs();
await merchant.logout();
});
afterAll( async () => {
shopper.logout();
} );
it('should receive order email after purchasing an item', async () => {
await shopper.login();

View File

@ -1,10 +1,15 @@
# Unreleased
## Fixed
- Updated the browserViewport in `jest.setup.js` to match the `defaultViewport` dimensions defined in `jest-puppeteer.config.js`
## Added
- Added quotes around `WORDPRESS_TITLE` value in .env file to address issue with docker compose 2 "key cannot contain a space" error.
- Added `LATEST_WP_VERSION_MINUS` that allows setting a number to subtract from the current WordPress version for the WordPress Docker image.
- Support for PHP_VERSION, MARIADB_VERSION environment variables for built in container initialization
- `resolveLocalE2ePath` to resolve path to local E2E file
- `WC_E2E_FOLDER` for mapping plugin root to path within repo
## Fixed

View File

@ -10,6 +10,7 @@ const {
getAppRoot,
getAppName,
getTestConfig,
resolveLocalE2ePath,
} = require( '../utils' );
const dockerArgs = [];
@ -56,10 +57,7 @@ if ( appPath ) {
const appInitFile = customInitFile
? customInitFile
: path.resolve(
appPath,
'plugins/woocommerce/tests/e2e/docker/initialize.sh'
);
: resolveLocalE2ePath( 'docker/initialize.sh' );
// If found, copy it into the wp-cli Docker context so
// it gets picked up by the entrypoint script.
if ( fs.existsSync( appInitFile ) ) {
@ -84,11 +82,6 @@ if ( ! process.env.WC_E2E_FOLDER_MAPPING ) {
'/var/www/html/wp-content/plugins/' + getAppBase();
}
// Set some environment variables
if ( ! process.env.WC_CORE_PATH ) {
envVars.WC_CORE_PATH = 'plugins/woocommerce';
}
if ( ! process.env.WORDPRESS_PORT ) {
process.env.WORDPRESS_PORT = testConfig.port;
}

View File

@ -4,7 +4,7 @@ const { spawnSync } = require( 'child_process' );
const program = require( 'commander' );
const path = require( 'path' );
const fs = require( 'fs' );
const { getAppRoot } = require( '../utils' );
const { getAppRoot, resolveLocalE2ePath } = require( '../utils' );
const {
WC_E2E_SCREENSHOTS,
JEST_PUPPETEER_CONFIG,
@ -21,10 +21,7 @@ const appPath = getAppRoot();
// clear the screenshots folder before running tests.
if ( WC_E2E_SCREENSHOTS ) {
const screenshotPath = path.resolve(
appPath,
'plugins/woocommerce/tests/e2e/screenshots'
);
const screenshotPath = resolveLocalE2ePath( 'screenshots' );
if ( fs.existsSync( screenshotPath ) ) {
fs.readdirSync( screenshotPath ).forEach( ( file, index ) => {
const filename = path.join( screenshotPath, file );
@ -36,9 +33,7 @@ if ( WC_E2E_SCREENSHOTS ) {
const nodeConfigDirs = [ path.resolve( __dirname, '../config' ) ];
if ( appPath ) {
nodeConfigDirs.unshift(
path.resolve( appPath, 'plugins/woocommerce/tests/e2e/config' )
);
nodeConfigDirs.unshift( resolveLocalE2ePath( 'config' ) );
}
const testEnvVars = {
@ -55,10 +50,7 @@ if ( DEFAULT_TIMEOUT_OVERRIDE ) {
if ( ! JEST_PUPPETEER_CONFIG ) {
// Use local Puppeteer config if there is one.
// Load test configuration file into an object.
const localJestConfigFile = path.resolve(
appPath,
'tests/e2e/config/jest-puppeteer.config.js'
);
const localJestConfigFile = resolveLocalE2ePath( 'config/jest-puppeteer.config.js' );
const jestConfigFile = path.resolve(
__dirname,
'../config/jest-puppeteer.config.js'
@ -100,10 +92,7 @@ let configPath = path.resolve( __dirname, '../config/jest.config.js' );
// Look for a Jest config in the dependent app's path.
if ( appPath ) {
const appConfig = path.resolve(
appPath,
'plugins/woocommerce/tests/e2e/config/jest.config.js'
);
const appConfig = resolveLocalE2ePath( 'config/jest.config.js' );
if ( fs.existsSync( appConfig ) ) {
configPath = appConfig;

View File

@ -11,7 +11,8 @@ count=0
WP_BASE_URL=$(node utils/get-base-url.js)
printf "Testing URL: $WP_BASE_URL\n\n"
while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' ${WP_BASE_URL}/?pagename=ready)" != "200" ]]
RAWDATA=$(curl -s -o /dev/null -w '%{http_code}' ${WP_BASE_URL}/?pagename=ready)
while [[ "${RAWDATA: -3}" != "200" ]]
do
echo "$(date) - Waiting for testing environment"
@ -23,6 +24,7 @@ do
echo "$(date) - Testing environment couldn't be found"
exit 1
fi
RAWDATA=$(curl -s -o /dev/null -w '%{http_code}' ${WP_BASE_URL}/?pagename=ready)
done
if [[ $count -gt 0 ]]; then

View File

@ -33,6 +33,18 @@ SCRIPTPATH=$(dirname "$0")
REALPATH=$(readlink "$0")
cd "$SCRIPTPATH/$(dirname "$REALPATH")/.."
# Set a flag to distinguish between the development repo and npm package
DEV_PATH=$(echo $0 | rev | cut -f4 -d/ | rev)
if [ "$DEV_PATH" != "node_modules" ]; then
export WC_E2E_WOOCOMMERCE_DEV='true'
export WC_E2E_FOLDER='plugins/woocommerce'
else
export WC_E2E_WOOCOMMERCE_DEV=''
if [ -z $WC_E2E_FOLDER ]; then
export WC_E2E_FOLDER=''
fi
fi
# Run scripts
case $1 in
'docker:up')

View File

@ -119,7 +119,12 @@ You can override these in `/tests/e2e/config/default.json`.
### Folder Mapping
The built in container defaults to mapping the root folder of the repository to a folder in the `plugins` folder. For example `woocommerce` is mapped to `/var/www/html/wp-content/plugins/woocommerce`. Use the `WC_E2E_FOLDER_MAPPING` environment variable to override this mapping.
The built in container defaults to mapping the root folder of the repository to a folder in the `plugins` folder. Use the environment variables `WC_E2E_FOLDER` and `WC_E2E_FOLDER_MAPPING` to override this mapping. The `WC_E2E_FOLDER` is a path relative to the root of the project. For example, in the `woocommerce` repository this mapping is:
- `WC_E2E_FOLDER=plugins/woocommerce`
- `WC_E2E_FOLDER_MAPPING=/var/www/html/wp-content/plugins/woocommerce`
Other repository examples:
- Storefront Theme - ```WC_E2E_FOLDER_MAPPING=/var/www/html/wp-content/themes/storefront npx wc-e2e docker:up```
- Site Project - ```WC_E2E_FOLDER_MAPPING=/var/www/html/wp-content npx wc-e2e docker:up```

View File

@ -12,15 +12,15 @@
"formatter": {
"filename": "../../../tools/changelogger/PackageFormatter.php"
},
"types": [
"Fix",
"Add",
"Update",
"Dev",
"Tweak",
"Performance",
"Enhancement"
],
"types": {
"fix": "Fixes an existing bug",
"add": "Adds functionality",
"update": "Update existing functionality",
"dev": "Development related task",
"tweak": "A minor adjustment to the codebase",
"performance": "Address performance issues",
"enhancement": "Improve existing functionality"
},
"changelog": "NEXT_CHANGELOG.md"
}
}

View File

@ -1,32 +1,46 @@
/** @format */
const { jestPuppeteerConfig } = require( '@automattic/puppeteer-utils' );
/**
* For a detailed explanation of configuration properties, visit:
* https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions
*/
const { CI, E2E_DEBUG, PUPPETEER_SLOWMO, E2E_EXE_PATH } = process.env;
let executablePath = '';
let dumpio = false;
let puppeteerConfig;
if ( ! CI && E2E_EXE_PATH !== '' ) {
executablePath = E2E_EXE_PATH;
}
if ( E2E_DEBUG ) {
dumpio = true;
}
const jestPuppeteerLaunch = {
// Required for the logged out and logged in tests so they don't share app state/token.
browserContext: 'incognito',
defaultViewport: {
width: 1280,
height: 800,
},
};
if ( 'no' == global.process.env.node_config_dev ) {
puppeteerConfig = {
launch: {
// Required for the logged out and logged in tests so they don't share app state/token.
browserContext: 'incognito',
defaultViewport: {
width: 1280,
height: 800,
},
},
launch: jestPuppeteerLaunch,
};
} else {
puppeteerConfig = {
launch: {
...jestPuppeteerConfig.launch,
slowMo: process.env.PUPPETEER_SLOWMO ? process.env.PUPPETEER_SLOWMO : 50,
...jestPuppeteerLaunch,
executablePath,
dumpio,
slowMo: PUPPETEER_SLOWMO ? PUPPETEER_SLOWMO : 50,
headless: false,
ignoreHTTPSErrors: true,
args: [ '--window-size=1920,1080', '--user-agent=chrome' ],
devtools: true,
defaultViewport: {
width: 1280,
height: 800,
},
},
};
}

View File

@ -1,7 +1,6 @@
/**
* External Dependencies
*/
const { jestConfig } = require( '@automattic/puppeteer-utils' );
const { WC_E2E_SCREENSHOTS } = process.env;
const path = require( 'path' );
const fs = require( 'fs' );
@ -9,7 +8,7 @@ const fs = require( 'fs' );
/**
* Internal Dependencies
*/
const { getAppRoot } = require( '../utils' );
const { resolveLocalE2ePath } = require( '../utils' );
const failureSetup = [];
if ( WC_E2E_SCREENSHOTS ) {
@ -23,19 +22,24 @@ const setupFilesAfterEnv = [
'expect-puppeteer',
];
const appPath = getAppRoot();
const localJestSetupFile = path.resolve(
appPath,
'plugins/woocommerce/tests/e2e/config/jest.setup.js'
);
const localJestSetupFile = resolveLocalE2ePath( 'config/jest.setup.js' );
const moduleNameMap = resolveLocalE2ePath( '$1' );
const testSpecs = resolveLocalE2ePath( 'specs' );
if ( fs.existsSync( localJestSetupFile ) ) {
setupFilesAfterEnv.push( localJestSetupFile );
}
const combinedConfig = {
...jestConfig,
preset: 'jest-puppeteer',
clearMocks: true,
moduleFileExtensions: [ 'js' ],
testMatch: [
'**/*.(test|spec).js',
'*.(test|spec).js'
],
moduleNameMapper: {
'@woocommerce/e2e/tests/(.*)': appPath + 'tests/e2e/$1',
'@woocommerce/e2e/tests/(.*)': moduleNameMap,
},
setupFiles: [ '<rootDir>/config/env.setup.js' ],
@ -49,10 +53,9 @@ const combinedConfig = {
testTimeout: parseInt( global.process.env.jest_test_timeout ),
transformIgnorePatterns: [
...jestConfig.transformIgnorePatterns,
'node_modules/(?!(woocommerce)/)',
],
roots: [ appPath + 'tests/e2e/specs' ],
roots: [ testSpecs ],
};
if ( process.env.jest_test_spec ) {

View File

@ -35,7 +35,7 @@ services:
WORDPRESS_DEBUG: 1
volumes:
- wordpress:/var/www/html
- "../../../${WC_CORE_PATH}:${WC_E2E_FOLDER_MAPPING}"
- "../../../${WC_E2E_FOLDER}:${WC_E2E_FOLDER_MAPPING}"
wordpress-cli:
container_name: "${APP_NAME}_wordpress-cli"
@ -60,7 +60,7 @@ services:
volumes:
- wordpress:/var/www/html
- "../../../plugins/woocommerce:${WC_E2E_FOLDER_MAPPING}"
- "../../../${WC_E2E_FOLDER}:${WC_E2E_FOLDER_MAPPING}"
volumes:
db:

View File

@ -38,7 +38,10 @@ const OBSERVED_CONSOLE_MESSAGE_TYPES = {
async function setupBrowser() {
await clearLocalStorage();
await setBrowserViewport( 'large' );
await setBrowserViewport( {
width: 1280,
height: 800,
});
}
/**

View File

@ -1,6 +1,6 @@
const getAppRoot = require( './app-root' );
const { getAppName, getAppBase } = require( './app-name' );
const { getTestConfig, getAdminConfig } = require( './test-config' );
const { getTestConfig, getAdminConfig, resolveLocalE2ePath } = require( './test-config' );
const { getRemotePluginZip, getLatestReleaseZipUrl } = require('./get-plugin-zip');
const takeScreenshotFor = require( './take-screenshot' );
const updateReadyPageStatus = require('./update-ready-page');
@ -12,6 +12,7 @@ module.exports = {
getAppName,
getTestConfig,
getAdminConfig,
resolveLocalE2ePath,
getRemotePluginZip,
getLatestReleaseZipUrl,
takeScreenshotFor,

View File

@ -1,6 +1,6 @@
const path = require( 'path' );
const mkdirp = require( 'mkdirp' );
const getAppRoot = require( './app-root' );
const { resolveLocalE2ePath } = require( './test-config' );
/**
* Take a screenshot if browser context exists.
@ -10,11 +10,7 @@ const getAppRoot = require( './app-root' );
*/
const takeScreenshotFor = async ( message ) => {
const title = message.replace( /\.$/, '' );
const appPath = getAppRoot();
const savePath = path.resolve(
appPath,
'plugins/woocommerce/tests/e2e/screenshots'
);
const savePath = resolveLocalE2ePath( 'screenshots' );
const filePath = path.join(
savePath,
`${ title }.png`.replace( /[^a-z0-9.-]+/gi, '-' )

View File

@ -2,12 +2,27 @@ const path = require( 'path' );
const fs = require( 'fs' );
const getAppRoot = require( './app-root' );
// Copy local test configuration file if it exists.
const appPath = getAppRoot();
const localTestConfigFile = path.resolve(
appPath,
'plugins/woocommerce/tests/e2e/config/default.json'
);
/**
* Resolve a local E2E file.
*
* @param {string} filename Filename to append to the path.
* @return {string}
*/
const resolveLocalE2ePath = ( filename = '' ) => {
const { WC_E2E_FOLDER } = process.env;
const localPath = `${WC_E2E_FOLDER}/tests/e2e/${filename}`;
const resolvedPath = path.resolve(
appPath,
localPath.indexOf( '/' ) == 0 ? localPath.slice( 1 ) : localPath
);
return resolvedPath;
}
// Copy local test configuration file if it exists.
const localTestConfigFile = resolveLocalE2ePath( 'config/default.json' );
const defaultConfigFile = path.resolve(
__dirname,
'../config/default/default.json'
@ -78,4 +93,5 @@ const getAdminConfig = () => {
module.exports = {
getTestConfig,
getAdminConfig,
resolveLocalE2ePath,
};

View File

@ -14,6 +14,7 @@
- `withRestApi.addTaxRates()` that adds an array of tax rates if they do not exist
- `clickAndWaitForSelector( buttonSelector, resultSelector, timeout )` to click a button and wait for response
- Optional parameter `testResponse` to `withRestApi` functions that contain an `expect()`
- `shopper.logout()` to log out the shopper account
# 0.1.6

View File

@ -129,6 +129,7 @@ This package provides support for enabling retries in tests:
| `goToProduct` | `productId` | Go to a single product in the shop |
| `goToShop` | | Go to the shop page |
| `login` | | Log in as the shopper |
| `logout` | | Log out of the shopper account |
| `placeOrder` | | Place an order from the checkout page |
| `productIsInCheckout` | `productTitle, quantity, total, cartSubtotal` | Verify product is in cart on checkout page |
| `removeFromCart` | `productIdOrTitle` | Remove a product from the cart on the cart page |

View File

@ -12,15 +12,15 @@
"formatter": {
"filename": "../../../tools/changelogger/PackageFormatter.php"
},
"types": [
"Fix",
"Add",
"Update",
"Dev",
"Tweak",
"Performance",
"Enhancement"
],
"types": {
"fix": "Fixes an existing bug",
"add": "Adds functionality",
"update": "Update existing functionality",
"dev": "Development related task",
"tweak": "A minor adjustment to the codebase",
"performance": "Address performance issues",
"enhancement": "Improve existing functionality"
},
"changelog": "NEXT_CHANGELOG.md"
}
}

View File

@ -12,7 +12,7 @@
"module": "build-module/index.js",
"dependencies": {
"@automattic/puppeteer-utils": "github:Automattic/puppeteer-utils#0f3ec50",
"@wordpress/deprecated": "^2.10.0",
"@wordpress/deprecated": "^3.2.3",
"@wordpress/e2e-test-utils": "^4.16.1",
"config": "3.3.3",
"faker": "^5.1.0",

View File

@ -190,16 +190,23 @@ const completeOnboardingWizard = async () => {
/**
* Create simple product.
*
* @param productTitle Defaults to Simple Product. Customizable title.
* @param productPrice Defaults to $9.99. Customizable pricing.
* @param {string} productTitle Defaults to Simple Product. Customizable title.
* @param {string} productPrice Defaults to $9.99. Customizable pricing.
* @param {Object} additionalProps Defaults to nothing. Additional product properties.
*/
const createSimpleProduct = async ( productTitle = simpleProductName, productPrice = simpleProductPrice ) => {
const product = await factories.products.simple.create( {
const createSimpleProduct = async (
productTitle = simpleProductName,
productPrice = simpleProductPrice,
additionalProps = {}
) => {
const newProduct = {
name: productTitle,
regularPrice: productPrice,
} );
...additionalProps,
};
const product = await factories.products.simple.create( newProduct );
return product.id;
} ;
};
/**
* Create simple product with categories
@ -335,21 +342,29 @@ const createGroupedProduct = async (groupedProduct = defaultGroupedProduct) => {
*/
const createOrder = async ( orderOptions = {} ) => {
const newOrder = {
...( orderOptions.status ) && { status: orderOptions.status },
...( orderOptions.customerId ) && { customer_id: orderOptions.customerId },
...( orderOptions.customerBilling ) && { billing: orderOptions.customerBilling },
...( orderOptions.customerShipping ) && { shipping: orderOptions.customerShipping },
...( orderOptions.productId ) && { line_items: [
{ product_id: orderOptions.productId },
]
},
...( orderOptions.status && { status: orderOptions.status } ),
...( orderOptions.customerId && {
customer_id: orderOptions.customerId,
} ),
...( orderOptions.customerBilling && {
billing: orderOptions.customerBilling,
} ),
...( orderOptions.customerShipping && {
shipping: orderOptions.customerShipping,
} ),
...( orderOptions.productId && {
line_items: [ { product_id: orderOptions.productId } ],
} ),
...( orderOptions.lineItems && {
line_items: orderOptions.lineItems,
} ),
};
const repository = Order.restRepository( client );
const order = await repository.create( newOrder );
return order.id;
}
};
/**
* Create a basic order with the provided order status.

View File

@ -24,7 +24,7 @@ const {
SHOP_PRODUCT_PAGE
} = require( './constants' );
const { uiUnblocked } = require( '../page-utils' );
const { uiUnblocked, clickAndWaitForSelector } = require( '../page-utils' );
const gotoMyAccount = async () => {
await page.goto( SHOP_MY_ACCOUNT_PAGE, {
@ -235,6 +235,13 @@ const shopper = {
page.click( 'button[name="login"]' ),
] );
},
logout: async () => {
await gotoMyAccount();
await expect( page.title() ).resolves.toMatch( 'My account' );
await page.click( '.woocommerce-MyAccount-navigation-link--customer-logout a' );
await page.waitForNavigation( { waitUntil: 'networkidle0' } );
},
};
module.exports = shopper;

View File

@ -2,7 +2,6 @@
* External dependencies
*/
import { pressKeyWithModifier } from '@wordpress/e2e-test-utils';
import { waitForSelector } from '@automattic/puppeteer-utils';
/**
* Internal dependencies
@ -318,3 +317,21 @@ export const clickAndWaitForSelector = async ( buttonSelector, resultSelector, t
}
);
};
/**
* Waits for selector to be present in DOM.
* Throws a `TimeoutError` if element was not found after 30 sec.
* Behavior can be modified with @param options. Possible keys: `visible`, `hidden`, `timeout`.
* More details at: https://pptr.dev/#?product=Puppeteer&show=api-pagewaitforselectorselector-options
*
* @param {Puppeteer.Page} page Puppeteer representation of the page.
* @param {string} selector CSS selector of the element
* @param {Object} options Custom options to modify function behavior.
*/
export async function waitForSelector( page, selector, options = {} ) {
// set up default options
const defaultOptions = { timeout: 30000, logHTML: false };
options = Object.assign( defaultOptions, options );
const element = await page.waitForSelector( selector, options );
return element;
}

View File

@ -5,24 +5,25 @@
*.zip
/bin/
/build/
/changelog/
/node_modules/
/tests/
babel.config.js
changelog.txt
composer.*
tsconfig.*
contributors.html
docker-compose.yaml
Dockerfile
Gruntfile.js
none
project.json
package-lock.json
package.json
packages/woocommerce-admin/docs
phpcs.xml
phpunit.xml
phpunit.xml.dist
project.json
README.md
renovate.json
tsconfig.*
webpack.config.js

View File

@ -7,12 +7,13 @@ none
# Sass
.sass-cache/
# Compiled CSS
# All CSS
/assets/css/**
/assets/css/*.css
/assets/css/photoswipe/**/*.min.css
# Minified JS
/assets/js/**/*.min.js
# All JS
/assets/js/**
/assets/js/*.js
# Behat/CLI Tests
tests/cli/installer
@ -34,6 +35,9 @@ tests/cli/vendor
# Logs
/logs
# TypeScript files
tsconfig.tsbuildinfo
# Composer
/vendor/
/bin/composer/**/vendor/

View File

@ -1,231 +0,0 @@
module.exports = function( grunt ) {
'use strict';
var sass = require( 'node-sass' );
grunt.initConfig({
// Setting folder templates.
dirs: {
css: 'assets/css',
fonts: 'assets/fonts',
images: 'assets/images',
js: 'assets/js',
php: 'includes'
},
// JavaScript linting with ESLint.
eslint: {
src: [
'<%= dirs.js %>/admin/*.js',
'!<%= dirs.js %>/admin/*.min.js',
'<%= dirs.js %>/frontend/*.js',
'!<%= dirs.js %>/frontend/*.min.js'
]
},
// Sass linting with Stylelint.
stylelint: {
options: {
configFile: '.stylelintrc'
},
all: [
'<%= dirs.css %>/*.scss',
'!<%= dirs.css %>/select2.scss'
]
},
// Minify .js files.
uglify: {
options: {
ie8: true,
parse: {
strict: false
},
output: {
comments : /@license|@preserve|^!/
}
},
js_assets: {
files: [{
expand: true,
cwd: '<%= dirs.js %>/',
src: [
'**/*.js',
'!**/*.min.js'
],
extDot: 'last',
dest: '<%= dirs.js %>',
ext: '.min.js'
}]
}
},
// Compile all .scss files.
sass: {
compile: {
options: {
implementation: sass,
sourceMap: 'none'
},
files: [{
expand: true,
cwd: '<%= dirs.css %>/',
src: ['*.scss'],
dest: '<%= dirs.css %>/',
ext: '.css'
}]
}
},
// Generate RTL .css files.
rtlcss: {
woocommerce: {
expand: true,
cwd: '<%= dirs.css %>',
src: [
'*.css',
'!select2.css',
'!*-rtl.css'
],
dest: '<%= dirs.css %>/',
ext: '-rtl.css'
}
},
// Minify all .css files.
cssmin: {
minify: {
files: [
{
expand: true,
cwd: '<%= dirs.css %>/',
src: ['*.css'],
dest: '<%= dirs.css %>/',
ext: '.css'
},
{
expand: true,
cwd: '<%= dirs.css %>/photoswipe/',
src: ['*.css', '!*.min.css'],
dest: '<%= dirs.css %>/photoswipe/',
ext: '.min.css'
},
{
expand: true,
cwd: '<%= dirs.css %>/photoswipe/default-skin/',
src: ['*.css', '!*.min.css'],
dest: '<%= dirs.css %>/photoswipe/default-skin/',
ext: '.min.css'
}
]
}
},
// Concatenate select2.css onto the admin.css files.
concat: {
admin: {
files: {
'<%= dirs.css %>/admin.css' : ['<%= dirs.css %>/select2.css', '<%= dirs.css %>/admin.css'],
'<%= dirs.css %>/admin-rtl.css' : ['<%= dirs.css %>/select2.css', '<%= dirs.css %>/admin-rtl.css']
}
}
},
// Watch changes for assets.
watch: {
css: {
files: ['<%= dirs.css %>/*.scss'],
tasks: ['sass', 'rtlcss', 'postcss', 'cssmin', 'concat']
},
js: {
files: [
'GruntFile.js',
'<%= dirs.js %>/**/*.js',
'!<%= dirs.js %>/**/*.min.js'
],
tasks: ['eslint','newer:uglify']
}
},
// PHP Code Sniffer.
phpcs: {
options: {
bin: 'vendor/bin/phpcs'
},
dist: {
src: [
'**/*.php', // Include all php files.
'!includes/api/legacy/**',
'!includes/libraries/**',
'!node_modules/**',
'!tests/cli/**',
'!tmp/**',
'!vendor/**'
]
}
},
// Autoprefixer.
postcss: {
options: {
processors: [
require( 'autoprefixer' )
]
},
dist: {
src: [
'<%= dirs.css %>/*.css'
]
}
}
});
// Load NPM tasks to be used here.
grunt.loadNpmTasks( 'grunt-sass' );
grunt.loadNpmTasks( 'grunt-phpcs' );
grunt.loadNpmTasks( 'grunt-rtlcss' );
grunt.loadNpmTasks( 'grunt-postcss' );
grunt.loadNpmTasks( 'grunt-stylelint' );
grunt.loadNpmTasks( 'gruntify-eslint' );
grunt.loadNpmTasks( 'grunt-contrib-uglify' );
grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
grunt.loadNpmTasks( 'grunt-contrib-concat' );
grunt.loadNpmTasks( 'grunt-contrib-copy' );
grunt.loadNpmTasks( 'grunt-contrib-watch' );
grunt.loadNpmTasks( 'grunt-contrib-clean' );
grunt.loadNpmTasks( 'grunt-newer' );
// Register tasks.
grunt.registerTask( 'default', [
'js',
'css'
]);
grunt.registerTask( 'js', [
'eslint',
'uglify:js_assets'
]);
grunt.registerTask( 'css', [
'sass',
'rtlcss',
'postcss',
'cssmin',
'concat'
]);
grunt.registerTask( 'assets', [
'js',
'css'
]);
grunt.registerTask( 'e2e-build', [
'uglify:js_assets',
'css'
]);
// Only an alias to 'default' task.
grunt.registerTask( 'dev', [
'default'
]);
};

View File

View File

View File

@ -33,7 +33,6 @@
"squizlabs/php_codesniffer": "^3.5",
"vimeo/psalm": "^4.4"
},
"default-branch": true,
"bin": [
"bin/mozart"
],
@ -54,10 +53,6 @@
}
],
"description": "Composes all dependencies as a package inside a WordPress plugin",
"support": {
"issues": "https://github.com/coenjacobs/mozart/issues",
"source": "https://github.com/coenjacobs/mozart/tree/master"
},
"funding": [
{
"url": "https://github.com/coenjacobs",
@ -68,16 +63,16 @@
},
{
"name": "league/flysystem",
"version": "1.1.5",
"version": "1.1.8",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
"reference": "18634df356bfd4119fe3d6156bdb990c414c14ea"
"reference": "c995bb0c23c58c9813d081f9523c9b7bb496698e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/18634df356bfd4119fe3d6156bdb990c414c14ea",
"reference": "18634df356bfd4119fe3d6156bdb990c414c14ea",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/c995bb0c23c58c9813d081f9523c9b7bb496698e",
"reference": "c995bb0c23c58c9813d081f9523c9b7bb496698e",
"shasum": ""
},
"require": {
@ -148,30 +143,26 @@
"sftp",
"storage"
],
"support": {
"issues": "https://github.com/thephpleague/flysystem/issues",
"source": "https://github.com/thephpleague/flysystem/tree/1.1.5"
},
"funding": [
{
"url": "https://offset.earth/frankdejonge",
"type": "other"
}
],
"time": "2021-08-17T13:49:42+00:00"
"time": "2021-11-28T21:50:23+00:00"
},
{
"name": "league/mime-type-detection",
"version": "1.8.0",
"version": "1.9.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/mime-type-detection.git",
"reference": "b38b25d7b372e9fddb00335400467b223349fd7e"
"reference": "aa70e813a6ad3d1558fc927863d47309b4c23e69"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/b38b25d7b372e9fddb00335400467b223349fd7e",
"reference": "b38b25d7b372e9fddb00335400467b223349fd7e",
"url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/aa70e813a6ad3d1558fc927863d47309b4c23e69",
"reference": "aa70e813a6ad3d1558fc927863d47309b4c23e69",
"shasum": ""
},
"require": {
@ -179,7 +170,7 @@
"php": "^7.2 || ^8.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.18",
"friendsofphp/php-cs-fixer": "^3.2",
"phpstan/phpstan": "^0.12.68",
"phpunit/phpunit": "^8.5.8 || ^9.3"
},
@ -200,10 +191,6 @@
}
],
"description": "Mime-type detection for Flysystem",
"support": {
"issues": "https://github.com/thephpleague/mime-type-detection/issues",
"source": "https://github.com/thephpleague/mime-type-detection/tree/1.8.0"
},
"funding": [
{
"url": "https://github.com/frankdejonge",
@ -214,7 +201,7 @@
"type": "tidelift"
}
],
"time": "2021-09-25T08:23:19+00:00"
"time": "2021-11-21T11:48:40+00:00"
},
{
"name": "psr/container",
@ -258,34 +245,30 @@
"container-interop",
"psr"
],
"support": {
"issues": "https://github.com/php-fig/container/issues",
"source": "https://github.com/php-fig/container/tree/1.1.1"
},
"time": "2021-03-05T17:36:06+00:00"
},
{
"name": "symfony/console",
"version": "v5.3.10",
"version": "v5.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "d4e409d9fbcfbf71af0e5a940abb7b0b4bad0bd3"
"reference": "ec3661faca1d110d6c307e124b44f99ac54179e3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/d4e409d9fbcfbf71af0e5a940abb7b0b4bad0bd3",
"reference": "d4e409d9fbcfbf71af0e5a940abb7b0b4bad0bd3",
"url": "https://api.github.com/repos/symfony/console/zipball/ec3661faca1d110d6c307e124b44f99ac54179e3",
"reference": "ec3661faca1d110d6c307e124b44f99ac54179e3",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/deprecation-contracts": "^2.1",
"symfony/deprecation-contracts": "^2.1|^3",
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php73": "^1.8",
"symfony/polyfill-php80": "^1.16",
"symfony/service-contracts": "^1.1|^2",
"symfony/string": "^5.1"
"symfony/service-contracts": "^1.1|^2|^3",
"symfony/string": "^5.1|^6.0"
},
"conflict": {
"psr/log": ">=3",
@ -300,12 +283,12 @@
},
"require-dev": {
"psr/log": "^1|^2",
"symfony/config": "^4.4|^5.0",
"symfony/dependency-injection": "^4.4|^5.0",
"symfony/event-dispatcher": "^4.4|^5.0",
"symfony/lock": "^4.4|^5.0",
"symfony/process": "^4.4|^5.0",
"symfony/var-dumper": "^4.4|^5.0"
"symfony/config": "^4.4|^5.0|^6.0",
"symfony/dependency-injection": "^4.4|^5.0|^6.0",
"symfony/event-dispatcher": "^4.4|^5.0|^6.0",
"symfony/lock": "^4.4|^5.0|^6.0",
"symfony/process": "^4.4|^5.0|^6.0",
"symfony/var-dumper": "^4.4|^5.0|^6.0"
},
"suggest": {
"psr/log": "For using the console logger",
@ -344,9 +327,6 @@
"console",
"terminal"
],
"support": {
"source": "https://github.com/symfony/console/tree/v5.3.10"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -361,20 +341,20 @@
"type": "tidelift"
}
],
"time": "2021-10-26T09:30:15+00:00"
"time": "2021-11-29T15:30:56+00:00"
},
{
"name": "symfony/deprecation-contracts",
"version": "v2.4.0",
"version": "v2.5.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627"
"reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627",
"reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8",
"reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8",
"shasum": ""
},
"require": {
@ -383,7 +363,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "2.4-dev"
"dev-main": "2.5-dev"
},
"thanks": {
"name": "symfony/contracts",
@ -411,9 +391,6 @@
],
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v2.4.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -428,24 +405,25 @@
"type": "tidelift"
}
],
"time": "2021-03-23T23:28:01+00:00"
"time": "2021-07-12T14:48:14+00:00"
},
{
"name": "symfony/finder",
"version": "v5.3.7",
"version": "v5.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "a10000ada1e600d109a6c7632e9ac42e8bf2fb93"
"reference": "d2f29dac98e96a98be467627bd49c2efb1bc2590"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/a10000ada1e600d109a6c7632e9ac42e8bf2fb93",
"reference": "a10000ada1e600d109a6c7632e9ac42e8bf2fb93",
"url": "https://api.github.com/repos/symfony/finder/zipball/d2f29dac98e96a98be467627bd49c2efb1bc2590",
"reference": "d2f29dac98e96a98be467627bd49c2efb1bc2590",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/deprecation-contracts": "^2.1|^3",
"symfony/polyfill-php80": "^1.16"
},
"type": "library",
@ -473,9 +451,6 @@
],
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/finder/tree/v5.3.7"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -490,7 +465,7 @@
"type": "tidelift"
}
],
"time": "2021-08-04T21:20:46+00:00"
"time": "2021-11-28T15:25:38+00:00"
},
{
"name": "symfony/polyfill-ctype",
@ -552,9 +527,6 @@
"polyfill",
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -633,9 +605,6 @@
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.23.1"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -717,9 +686,6 @@
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.23.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -797,9 +763,6 @@
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.1"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -876,9 +839,6 @@
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php73/tree/v1.23.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -959,9 +919,6 @@
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.23.1"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -980,21 +937,25 @@
},
{
"name": "symfony/service-contracts",
"version": "v2.4.0",
"version": "v2.5.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
"reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb"
"reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb",
"reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc",
"reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"psr/container": "^1.1"
"psr/container": "^1.1",
"symfony/deprecation-contracts": "^2.1"
},
"conflict": {
"ext-psr": "<1.1|>=2"
},
"suggest": {
"symfony/service-implementation": ""
@ -1002,7 +963,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "2.4-dev"
"dev-main": "2.5-dev"
},
"thanks": {
"name": "symfony/contracts",
@ -1038,9 +999,6 @@
"interoperability",
"standards"
],
"support": {
"source": "https://github.com/symfony/service-contracts/tree/v2.4.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -1055,20 +1013,20 @@
"type": "tidelift"
}
],
"time": "2021-04-01T10:43:52+00:00"
"time": "2021-11-04T16:48:04+00:00"
},
{
"name": "symfony/string",
"version": "v5.3.10",
"version": "v5.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
"reference": "d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c"
"reference": "9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c",
"reference": "d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c",
"url": "https://api.github.com/repos/symfony/string/zipball/9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d",
"reference": "9ffaaba53c61ba75a3c7a3a779051d1e9ec4fd2d",
"shasum": ""
},
"require": {
@ -1079,11 +1037,14 @@
"symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php80": "~1.15"
},
"conflict": {
"symfony/translation-contracts": ">=3.0"
},
"require-dev": {
"symfony/error-handler": "^4.4|^5.0",
"symfony/http-client": "^4.4|^5.0",
"symfony/error-handler": "^4.4|^5.0|^6.0",
"symfony/http-client": "^4.4|^5.0|^6.0",
"symfony/translation-contracts": "^1.1|^2",
"symfony/var-exporter": "^4.4|^5.0"
"symfony/var-exporter": "^4.4|^5.0|^6.0"
},
"type": "library",
"autoload": {
@ -1121,9 +1082,6 @@
"utf-8",
"utf8"
],
"support": {
"source": "https://github.com/symfony/string/tree/v5.3.10"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -1138,7 +1096,7 @@
"type": "tidelift"
}
],
"time": "2021-10-27T18:21:46+00:00"
"time": "2021-11-24T10:02:00+00:00"
}
],
"aliases": [],
@ -1153,5 +1111,5 @@
"platform-overrides": {
"php": "7.3"
},
"plugin-api-version": "2.1.0"
"plugin-api-version": "1.1.0"
}

View File

@ -71,10 +71,6 @@
"stylecheck",
"tests"
],
"support": {
"issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues",
"source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer"
},
"time": "2020-12-07T18:04:37+00:00"
},
{
@ -133,10 +129,6 @@
"phpcs",
"standards"
],
"support": {
"issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues",
"source": "https://github.com/PHPCompatibility/PHPCompatibility"
},
"time": "2019-12-27T09:44:58+00:00"
},
{
@ -189,10 +181,6 @@
"polyfill",
"standards"
],
"support": {
"issues": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/issues",
"source": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie"
},
"time": "2021-02-15T10:24:51+00:00"
},
{
@ -243,10 +231,6 @@
"standards",
"wordpress"
],
"support": {
"issues": "https://github.com/PHPCompatibility/PHPCompatibilityWP/issues",
"source": "https://github.com/PHPCompatibility/PHPCompatibilityWP"
},
"time": "2021-07-21T11:09:57+00:00"
},
{
@ -298,11 +282,6 @@
"phpcs",
"standards"
],
"support": {
"issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
"source": "https://github.com/squizlabs/PHP_CodeSniffer",
"wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
},
"time": "2021-10-11T04:00:11+00:00"
},
{
@ -343,10 +322,6 @@
"woocommerce",
"wordpress"
],
"support": {
"issues": "https://github.com/woocommerce/woocommerce-sniffs/issues",
"source": "https://github.com/woocommerce/woocommerce-sniffs/tree/0.1.1"
},
"time": "2021-07-29T17:25:16+00:00"
},
{
@ -393,11 +368,6 @@
"standards",
"wordpress"
],
"support": {
"issues": "https://github.com/WordPress/WordPress-Coding-Standards/issues",
"source": "https://github.com/WordPress/WordPress-Coding-Standards",
"wiki": "https://github.com/WordPress/WordPress-Coding-Standards/wiki"
},
"time": "2020-05-13T23:57:56+00:00"
}
],
@ -411,5 +381,5 @@
"platform-overrides": {
"php": "7.0"
},
"plugin-api-version": "2.1.0"
"plugin-api-version": "1.1.0"
}

View File

@ -59,10 +59,6 @@
"constructor",
"instantiate"
],
"support": {
"issues": "https://github.com/doctrine/instantiator/issues",
"source": "https://github.com/doctrine/instantiator/tree/master"
},
"time": "2015-06-14T21:17:01+00:00"
},
{
@ -108,10 +104,6 @@
"object",
"object graph"
],
"support": {
"issues": "https://github.com/myclabs/DeepCopy/issues",
"source": "https://github.com/myclabs/DeepCopy/tree/1.x"
},
"time": "2017-10-19T19:58:43+00:00"
},
{
@ -167,10 +159,6 @@
}
],
"description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
"support": {
"issues": "https://github.com/phar-io/manifest/issues",
"source": "https://github.com/phar-io/manifest/tree/master"
},
"time": "2017-03-05T18:14:27+00:00"
},
{
@ -218,10 +206,6 @@
}
],
"description": "Library for handling version information and constraints",
"support": {
"issues": "https://github.com/phar-io/version/issues",
"source": "https://github.com/phar-io/version/tree/master"
},
"time": "2017-03-05T17:38:23+00:00"
},
{
@ -276,10 +260,6 @@
"reflection",
"static analysis"
],
"support": {
"issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
"source": "https://github.com/phpDocumentor/ReflectionCommon/tree/master"
},
"time": "2017-09-11T18:02:19+00:00"
},
{
@ -332,10 +312,6 @@
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
"support": {
"issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
"source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/release/4.x"
},
"time": "2019-12-28T18:55:12+00:00"
},
{
@ -381,10 +357,6 @@
"email": "me@mikevanriel.com"
}
],
"support": {
"issues": "https://github.com/phpDocumentor/TypeResolver/issues",
"source": "https://github.com/phpDocumentor/TypeResolver/tree/master"
},
"time": "2017-12-30T13:23:38+00:00"
},
{
@ -448,10 +420,6 @@
"spy",
"stub"
],
"support": {
"issues": "https://github.com/phpspec/prophecy/issues",
"source": "https://github.com/phpspec/prophecy/tree/v1.10.3"
},
"time": "2020-03-05T15:02:03+00:00"
},
{
@ -515,10 +483,6 @@
"testing",
"xunit"
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/5.3"
},
"time": "2018-04-06T15:36:58+00:00"
},
{
@ -566,11 +530,6 @@
"filesystem",
"iterator"
],
"support": {
"irc": "irc://irc.freenode.net/phpunit",
"issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
"source": "https://github.com/sebastianbergmann/php-file-iterator/tree/1.4.5"
},
"time": "2017-11-27T13:52:08+00:00"
},
{
@ -612,10 +571,6 @@
"keywords": [
"template"
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-text-template/issues",
"source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1"
},
"time": "2015-06-21T13:50:34+00:00"
},
{
@ -665,10 +620,6 @@
"keywords": [
"timer"
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-timer/issues",
"source": "https://github.com/sebastianbergmann/php-timer/tree/master"
},
"time": "2017-02-26T11:10:40+00:00"
},
{
@ -718,10 +669,6 @@
"keywords": [
"tokenizer"
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-token-stream/issues",
"source": "https://github.com/sebastianbergmann/php-token-stream/tree/master"
},
"abandoned": true,
"time": "2017-11-27T05:48:46+00:00"
},
@ -807,10 +754,6 @@
"testing",
"xunit"
],
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"source": "https://github.com/sebastianbergmann/phpunit/tree/6.5.14"
},
"time": "2019-02-01T05:22:47+00:00"
},
{
@ -870,10 +813,6 @@
"mock",
"xunit"
],
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit-mock-objects/issues",
"source": "https://github.com/sebastianbergmann/phpunit-mock-objects/tree/5.0.10"
},
"abandoned": true,
"time": "2018-08-09T05:50:03+00:00"
},
@ -920,10 +859,6 @@
],
"description": "Looks up which function or method a line of code belongs to",
"homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
"support": {
"issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
"source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2"
},
"funding": [
{
"url": "https://github.com/sebastianbergmann",
@ -994,10 +929,6 @@
"compare",
"equality"
],
"support": {
"issues": "https://github.com/sebastianbergmann/comparator/issues",
"source": "https://github.com/sebastianbergmann/comparator/tree/master"
},
"time": "2018-02-01T13:46:46+00:00"
},
{
@ -1050,10 +981,6 @@
"keywords": [
"diff"
],
"support": {
"issues": "https://github.com/sebastianbergmann/diff/issues",
"source": "https://github.com/sebastianbergmann/diff/tree/master"
},
"time": "2017-08-03T08:09:46+00:00"
},
{
@ -1104,10 +1031,6 @@
"environment",
"hhvm"
],
"support": {
"issues": "https://github.com/sebastianbergmann/environment/issues",
"source": "https://github.com/sebastianbergmann/environment/tree/master"
},
"time": "2017-07-01T08:51:00+00:00"
},
{
@ -1175,10 +1098,6 @@
"export",
"exporter"
],
"support": {
"issues": "https://github.com/sebastianbergmann/exporter/issues",
"source": "https://github.com/sebastianbergmann/exporter/tree/3.1.4"
},
"funding": [
{
"url": "https://github.com/sebastianbergmann",
@ -1236,10 +1155,6 @@
"keywords": [
"global state"
],
"support": {
"issues": "https://github.com/sebastianbergmann/global-state/issues",
"source": "https://github.com/sebastianbergmann/global-state/tree/2.0.0"
},
"time": "2017-04-27T15:39:26+00:00"
},
{
@ -1287,10 +1202,6 @@
],
"description": "Traverses array structures and object graphs to enumerate all referenced objects",
"homepage": "https://github.com/sebastianbergmann/object-enumerator/",
"support": {
"issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
"source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4"
},
"funding": [
{
"url": "https://github.com/sebastianbergmann",
@ -1342,10 +1253,6 @@
],
"description": "Allows reflection of object attributes, including inherited and non-public ones",
"homepage": "https://github.com/sebastianbergmann/object-reflector/",
"support": {
"issues": "https://github.com/sebastianbergmann/object-reflector/issues",
"source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2"
},
"funding": [
{
"url": "https://github.com/sebastianbergmann",
@ -1405,10 +1312,6 @@
],
"description": "Provides functionality to recursively process PHP variables",
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
"support": {
"issues": "https://github.com/sebastianbergmann/recursion-context/issues",
"source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1"
},
"funding": [
{
"url": "https://github.com/sebastianbergmann",
@ -1457,10 +1360,6 @@
],
"description": "Provides a list of PHP built-in functions that operate on resources",
"homepage": "https://www.github.com/sebastianbergmann/resource-operations",
"support": {
"issues": "https://github.com/sebastianbergmann/resource-operations/issues",
"source": "https://github.com/sebastianbergmann/resource-operations/tree/master"
},
"time": "2015-07-28T20:34:47+00:00"
},
{
@ -1504,10 +1403,6 @@
],
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
"homepage": "https://github.com/sebastianbergmann/version",
"support": {
"issues": "https://github.com/sebastianbergmann/version/issues",
"source": "https://github.com/sebastianbergmann/version/tree/master"
},
"time": "2016-10-03T07:35:21+00:00"
},
{
@ -1570,9 +1465,6 @@
"polyfill",
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.19.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -1627,10 +1519,6 @@
}
],
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
"support": {
"issues": "https://github.com/theseer/tokenizer/issues",
"source": "https://github.com/theseer/tokenizer/tree/master"
},
"time": "2019-06-13T22:48:21+00:00"
},
{
@ -1680,10 +1568,6 @@
"check",
"validate"
],
"support": {
"issues": "https://github.com/webmozarts/assert/issues",
"source": "https://github.com/webmozarts/assert/tree/1.9.1"
},
"time": "2020-07-08T17:02:28+00:00"
}
],
@ -1697,5 +1581,5 @@
"platform-overrides": {
"php": "7.0"
},
"plugin-api-version": "2.1.0"
"plugin-api-version": "1.1.0"
}

View File

@ -67,11 +67,6 @@
"po",
"translation"
],
"support": {
"email": "oom@oscarotero.com",
"issues": "https://github.com/oscarotero/Gettext/issues",
"source": "https://github.com/php-gettext/Gettext/tree/v4.8.6"
},
"funding": [
{
"url": "https://paypal.me/oscarotero",
@ -146,10 +141,6 @@
"translations",
"unicode"
],
"support": {
"issues": "https://github.com/php-gettext/Languages/issues",
"source": "https://github.com/php-gettext/Languages/tree/2.9.0"
},
"funding": [
{
"url": "https://paypal.me/mlocati",
@ -205,10 +196,6 @@
}
],
"description": "Peast is PHP library that generates AST for JavaScript code",
"support": {
"issues": "https://github.com/mck89/peast/issues",
"source": "https://github.com/mck89/peast/tree/v1.13.9"
},
"time": "2021-11-12T13:44:49+00:00"
},
{
@ -255,10 +242,6 @@
"mustache",
"templating"
],
"support": {
"issues": "https://github.com/bobthecow/mustache.php/issues",
"source": "https://github.com/bobthecow/mustache.php/tree/master"
},
"time": "2019-11-23T21:40:31+00:00"
},
{
@ -315,10 +298,6 @@
"iri",
"sockets"
],
"support": {
"issues": "https://github.com/WordPress/Requests/issues",
"source": "https://github.com/WordPress/Requests/tree/v1.8.1"
},
"time": "2021-06-04T09:56:25+00:00"
},
{
@ -368,9 +347,6 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/finder/tree/3.3"
},
"time": "2017-06-01T21:01:25+00:00"
},
{
@ -431,10 +407,6 @@
],
"description": "Provides internationalization tools for WordPress projects.",
"homepage": "https://github.com/wp-cli/i18n-command",
"support": {
"issues": "https://github.com/wp-cli/i18n-command/issues",
"source": "https://github.com/wp-cli/i18n-command/tree/v2.2.9"
},
"time": "2021-07-20T21:25:54+00:00"
},
{
@ -483,9 +455,6 @@
],
"description": "A simple YAML loader/dumper class for PHP (WP-CLI fork)",
"homepage": "https://github.com/mustangostang/spyc/",
"support": {
"source": "https://github.com/wp-cli/spyc/tree/autoload"
},
"time": "2017-04-25T11:26:20+00:00"
},
{
@ -536,10 +505,6 @@
"cli",
"console"
],
"support": {
"issues": "https://github.com/wp-cli/php-cli-tools/issues",
"source": "https://github.com/wp-cli/php-cli-tools/tree/v0.11.13"
},
"time": "2021-07-01T15:08:16+00:00"
},
{
@ -606,11 +571,6 @@
"cli",
"wordpress"
],
"support": {
"docs": "https://make.wordpress.org/cli/handbook/",
"issues": "https://github.com/wp-cli/wp-cli/issues",
"source": "https://github.com/wp-cli/wp-cli"
},
"time": "2021-05-14T13:44:51+00:00"
}
],
@ -624,5 +584,5 @@
"platform-overrides": {
"php": "7.0"
},
"plugin-api-version": "2.1.0"
"plugin-api-version": "1.1.0"
}

View File

@ -20,9 +20,9 @@
"maxmind-db/reader": "1.6.0",
"pelago/emogrifier": "3.1.0",
"psr/container": "1.0.0",
"woocommerce/action-scheduler": "3.3.0",
"woocommerce/woocommerce-admin": "2.9.0-rc.2",
"woocommerce/woocommerce-blocks": "6.3.2"
"woocommerce/action-scheduler": "3.4.0",
"woocommerce/woocommerce-admin": "2.9.0",
"woocommerce/woocommerce-blocks": "6.3.3"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.4",
@ -39,7 +39,7 @@
"sort-packages": true,
"platform": {
"php": "7.0.33"
}
}
},
"autoload": {
"exclude-from-classmap": [
@ -122,15 +122,15 @@
"formatter": {
"filename": "../../tools/changelogger/PluginFormatter.php"
},
"types": [
"Fix",
"Add",
"Update",
"Dev",
"Tweak",
"Performance",
"Enhancement"
],
"types": {
"fix": "Fixes an existing bug",
"add": "Adds functionality",
"update": "Update existing functionality",
"dev": "Development related task",
"tweak": "A minor adjustment to the codebase",
"performance": "Address performance issues",
"enhancement": "Improve existing functionality"
},
"versioning": "wordpress",
"changelog": "NEXT_CHANGELOG.md"
}

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": "83379234b653f45a89537a0bb470eb69",
"content-hash": "ec7987721f51ed5c0faf6251128ba110",
"packages": [
{
"name": "automattic/jetpack-autoloader",
@ -51,9 +51,6 @@
"GPL-2.0-or-later"
],
"description": "Creates a custom autoloader for a plugin or theme.",
"support": {
"source": "https://github.com/Automattic/jetpack-autoloader/tree/2.10.1"
},
"time": "2021-03-30T15:15:59+00:00"
},
{
@ -85,9 +82,6 @@
"GPL-2.0-or-later"
],
"description": "A wrapper for defining constants in a more testable way.",
"support": {
"source": "https://github.com/Automattic/jetpack-constants/tree/v1.5.1"
},
"time": "2020-10-28T19:00:31+00:00"
},
{
@ -221,10 +215,6 @@
"zend",
"zikula"
],
"support": {
"issues": "https://github.com/composer/installers/issues",
"source": "https://github.com/composer/installers/tree/v1.12.0"
},
"funding": [
{
"url": "https://packagist.com",
@ -299,10 +289,6 @@
"geolocation",
"maxmind"
],
"support": {
"issues": "https://github.com/maxmind/MaxMind-DB-Reader-php/issues",
"source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.6.0"
},
"time": "2019-12-19T22:59:03+00:00"
},
{
@ -377,10 +363,6 @@
"email",
"pre-processing"
],
"support": {
"issues": "https://github.com/MyIntervals/emogrifier/issues",
"source": "https://github.com/MyIntervals/emogrifier"
},
"time": "2019-12-26T19:37:31+00:00"
},
{
@ -430,10 +412,6 @@
"container-interop",
"psr"
],
"support": {
"issues": "https://github.com/php-fig/container/issues",
"source": "https://github.com/php-fig/container/tree/master"
},
"time": "2017-02-14T16:28:37+00:00"
},
{
@ -482,9 +460,6 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/css-selector/tree/v3.4.47"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -503,22 +478,23 @@
},
{
"name": "woocommerce/action-scheduler",
"version": "3.3.0",
"version": "3.4.0",
"source": {
"type": "git",
"url": "https://github.com/woocommerce/action-scheduler.git",
"reference": "5588a831cd2453ecf7d4803f3a81063e13cde93d"
"reference": "3218a33ff14b968f8cb05de9656c2efa1eeb1330"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/woocommerce/action-scheduler/zipball/5588a831cd2453ecf7d4803f3a81063e13cde93d",
"reference": "5588a831cd2453ecf7d4803f3a81063e13cde93d",
"url": "https://api.github.com/repos/woocommerce/action-scheduler/zipball/3218a33ff14b968f8cb05de9656c2efa1eeb1330",
"reference": "3218a33ff14b968f8cb05de9656c2efa1eeb1330",
"shasum": ""
},
"require-dev": {
"phpunit/phpunit": "^7.5",
"woocommerce/woocommerce-sniffs": "0.1.0",
"wp-cli/wp-cli": "~2.5.0"
"wp-cli/wp-cli": "~2.5.0",
"yoast/phpunit-polyfills": "^1.0"
},
"type": "wordpress-plugin",
"extra": {
@ -534,24 +510,20 @@
],
"description": "Action Scheduler for WordPress and WooCommerce",
"homepage": "https://actionscheduler.org/",
"support": {
"issues": "https://github.com/woocommerce/action-scheduler/issues",
"source": "https://github.com/woocommerce/action-scheduler/tree/3.3.0"
},
"time": "2021-09-15T21:08:48+00:00"
"time": "2021-10-28T17:09:12+00:00"
},
{
"name": "woocommerce/woocommerce-admin",
"version": "2.9.0-rc.2",
"version": "2.9.0",
"source": {
"type": "git",
"url": "https://github.com/woocommerce/woocommerce-admin.git",
"reference": "6c81e761d9a19e6ed4484db82d6710331f375a3a"
"reference": "8040a6ac2af1b217324ae83a4137b0bfe3edbc23"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/6c81e761d9a19e6ed4484db82d6710331f375a3a",
"reference": "6c81e761d9a19e6ed4484db82d6710331f375a3a",
"url": "https://api.github.com/repos/woocommerce/woocommerce-admin/zipball/8040a6ac2af1b217324ae83a4137b0bfe3edbc23",
"reference": "8040a6ac2af1b217324ae83a4137b0bfe3edbc23",
"shasum": ""
},
"require": {
@ -605,24 +577,20 @@
],
"description": "A modern, javascript-driven WooCommerce Admin experience.",
"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.9.0-rc.2"
},
"time": "2021-11-18T08:35:56+00:00"
"time": "2021-11-29T23:28:44+00:00"
},
{
"name": "woocommerce/woocommerce-blocks",
"version": "v6.3.2",
"version": "v6.3.3",
"source": {
"type": "git",
"url": "https://github.com/woocommerce/woocommerce-gutenberg-products-block.git",
"reference": "5b3aea9adb718a1f78525881e4f0c33c72ba175d"
"reference": "38975ad6de9c6a556059c4de6e9ffc586ab82245"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/woocommerce/woocommerce-gutenberg-products-block/zipball/5b3aea9adb718a1f78525881e4f0c33c72ba175d",
"reference": "5b3aea9adb718a1f78525881e4f0c33c72ba175d",
"url": "https://api.github.com/repos/woocommerce/woocommerce-gutenberg-products-block/zipball/38975ad6de9c6a556059c4de6e9ffc586ab82245",
"reference": "38975ad6de9c6a556059c4de6e9ffc586ab82245",
"shasum": ""
},
"require": {
@ -661,9 +629,9 @@
],
"support": {
"issues": "https://github.com/woocommerce/woocommerce-gutenberg-products-block/issues",
"source": "https://github.com/woocommerce/woocommerce-gutenberg-products-block/tree/v6.3.2"
"source": "https://github.com/woocommerce/woocommerce-gutenberg-products-block/tree/v6.3.3"
},
"time": "2021-11-18T03:27:03+00:00"
"time": "2021-11-25T09:47:27+00:00"
}
],
"packages-dev": [
@ -719,9 +687,6 @@
"GPL-2.0-or-later"
],
"description": "Jetpack Changelogger tool. Allows for managing changelogs by dropping change files into a changelog directory with each PR.",
"support": {
"source": "https://github.com/Automattic/jetpack-changelogger/tree/v3.0.2"
},
"time": "2021-11-02T14:06:49+00:00"
},
{
@ -768,10 +733,6 @@
"isolation",
"tool"
],
"support": {
"issues": "https://github.com/bamarni/composer-bin-plugin/issues",
"source": "https://github.com/bamarni/composer-bin-plugin/tree/master"
},
"time": "2020-05-03T08:27:20+00:00"
},
{
@ -826,10 +787,6 @@
"constructor",
"instantiate"
],
"support": {
"issues": "https://github.com/doctrine/instantiator/issues",
"source": "https://github.com/doctrine/instantiator/tree/master"
},
"time": "2015-06-14T21:17:01+00:00"
},
{
@ -875,10 +832,6 @@
"object",
"object graph"
],
"support": {
"issues": "https://github.com/myclabs/DeepCopy/issues",
"source": "https://github.com/myclabs/DeepCopy/tree/1.x"
},
"time": "2017-10-19T19:58:43+00:00"
},
{
@ -934,10 +887,6 @@
}
],
"description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
"support": {
"issues": "https://github.com/phar-io/manifest/issues",
"source": "https://github.com/phar-io/manifest/tree/master"
},
"time": "2017-03-05T18:14:27+00:00"
},
{
@ -985,10 +934,6 @@
}
],
"description": "Library for handling version information and constraints",
"support": {
"issues": "https://github.com/phar-io/version/issues",
"source": "https://github.com/phar-io/version/tree/master"
},
"time": "2017-03-05T17:38:23+00:00"
},
{
@ -1043,10 +988,6 @@
"reflection",
"static analysis"
],
"support": {
"issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
"source": "https://github.com/phpDocumentor/ReflectionCommon/tree/master"
},
"time": "2017-09-11T18:02:19+00:00"
},
{
@ -1099,10 +1040,6 @@
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
"support": {
"issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
"source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/release/4.x"
},
"time": "2019-12-28T18:55:12+00:00"
},
{
@ -1148,10 +1085,6 @@
"email": "me@mikevanriel.com"
}
],
"support": {
"issues": "https://github.com/phpDocumentor/TypeResolver/issues",
"source": "https://github.com/phpDocumentor/TypeResolver/tree/master"
},
"time": "2017-12-30T13:23:38+00:00"
},
{
@ -1215,10 +1148,6 @@
"spy",
"stub"
],
"support": {
"issues": "https://github.com/phpspec/prophecy/issues",
"source": "https://github.com/phpspec/prophecy/tree/v1.10.3"
},
"time": "2020-03-05T15:02:03+00:00"
},
{
@ -1282,10 +1211,6 @@
"testing",
"xunit"
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/5.3"
},
"time": "2018-04-06T15:36:58+00:00"
},
{
@ -1333,11 +1258,6 @@
"filesystem",
"iterator"
],
"support": {
"irc": "irc://irc.freenode.net/phpunit",
"issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
"source": "https://github.com/sebastianbergmann/php-file-iterator/tree/1.4.5"
},
"time": "2017-11-27T13:52:08+00:00"
},
{
@ -1379,10 +1299,6 @@
"keywords": [
"template"
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-text-template/issues",
"source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1"
},
"time": "2015-06-21T13:50:34+00:00"
},
{
@ -1432,10 +1348,6 @@
"keywords": [
"timer"
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-timer/issues",
"source": "https://github.com/sebastianbergmann/php-timer/tree/master"
},
"time": "2017-02-26T11:10:40+00:00"
},
{
@ -1485,10 +1397,6 @@
"keywords": [
"tokenizer"
],
"support": {
"issues": "https://github.com/sebastianbergmann/php-token-stream/issues",
"source": "https://github.com/sebastianbergmann/php-token-stream/tree/master"
},
"abandoned": true,
"time": "2017-11-27T05:48:46+00:00"
},
@ -1574,10 +1482,6 @@
"testing",
"xunit"
],
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"source": "https://github.com/sebastianbergmann/phpunit/tree/6.5.14"
},
"time": "2019-02-01T05:22:47+00:00"
},
{
@ -1637,10 +1541,6 @@
"mock",
"xunit"
],
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit-mock-objects/issues",
"source": "https://github.com/sebastianbergmann/phpunit-mock-objects/tree/5.0.10"
},
"abandoned": true,
"time": "2018-08-09T05:50:03+00:00"
},
@ -1689,9 +1589,6 @@
"psr",
"psr-3"
],
"support": {
"source": "https://github.com/php-fig/log/tree/1.1.4"
},
"time": "2021-05-03T11:20:27+00:00"
},
{
@ -1737,10 +1634,6 @@
],
"description": "Looks up which function or method a line of code belongs to",
"homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
"support": {
"issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
"source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2"
},
"funding": [
{
"url": "https://github.com/sebastianbergmann",
@ -1811,10 +1704,6 @@
"compare",
"equality"
],
"support": {
"issues": "https://github.com/sebastianbergmann/comparator/issues",
"source": "https://github.com/sebastianbergmann/comparator/tree/master"
},
"time": "2018-02-01T13:46:46+00:00"
},
{
@ -1867,10 +1756,6 @@
"keywords": [
"diff"
],
"support": {
"issues": "https://github.com/sebastianbergmann/diff/issues",
"source": "https://github.com/sebastianbergmann/diff/tree/master"
},
"time": "2017-08-03T08:09:46+00:00"
},
{
@ -1921,10 +1806,6 @@
"environment",
"hhvm"
],
"support": {
"issues": "https://github.com/sebastianbergmann/environment/issues",
"source": "https://github.com/sebastianbergmann/environment/tree/master"
},
"time": "2017-07-01T08:51:00+00:00"
},
{
@ -1992,10 +1873,6 @@
"export",
"exporter"
],
"support": {
"issues": "https://github.com/sebastianbergmann/exporter/issues",
"source": "https://github.com/sebastianbergmann/exporter/tree/3.1.4"
},
"funding": [
{
"url": "https://github.com/sebastianbergmann",
@ -2053,10 +1930,6 @@
"keywords": [
"global state"
],
"support": {
"issues": "https://github.com/sebastianbergmann/global-state/issues",
"source": "https://github.com/sebastianbergmann/global-state/tree/2.0.0"
},
"time": "2017-04-27T15:39:26+00:00"
},
{
@ -2104,10 +1977,6 @@
],
"description": "Traverses array structures and object graphs to enumerate all referenced objects",
"homepage": "https://github.com/sebastianbergmann/object-enumerator/",
"support": {
"issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
"source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4"
},
"funding": [
{
"url": "https://github.com/sebastianbergmann",
@ -2159,10 +2028,6 @@
],
"description": "Allows reflection of object attributes, including inherited and non-public ones",
"homepage": "https://github.com/sebastianbergmann/object-reflector/",
"support": {
"issues": "https://github.com/sebastianbergmann/object-reflector/issues",
"source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2"
},
"funding": [
{
"url": "https://github.com/sebastianbergmann",
@ -2222,10 +2087,6 @@
],
"description": "Provides functionality to recursively process PHP variables",
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
"support": {
"issues": "https://github.com/sebastianbergmann/recursion-context/issues",
"source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1"
},
"funding": [
{
"url": "https://github.com/sebastianbergmann",
@ -2274,10 +2135,6 @@
],
"description": "Provides a list of PHP built-in functions that operate on resources",
"homepage": "https://www.github.com/sebastianbergmann/resource-operations",
"support": {
"issues": "https://github.com/sebastianbergmann/resource-operations/issues",
"source": "https://github.com/sebastianbergmann/resource-operations/tree/master"
},
"time": "2015-07-28T20:34:47+00:00"
},
{
@ -2321,10 +2178,6 @@
],
"description": "Library that helps with managing the version number of Git-hosted PHP projects",
"homepage": "https://github.com/sebastianbergmann/version",
"support": {
"issues": "https://github.com/sebastianbergmann/version/issues",
"source": "https://github.com/sebastianbergmann/version/tree/master"
},
"time": "2016-10-03T07:35:21+00:00"
},
{
@ -2392,9 +2245,6 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/console/tree/v3.4.47"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -2460,9 +2310,6 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/debug/tree/v3.4.47"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -2539,9 +2386,6 @@
"polyfill",
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.19.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -2619,9 +2463,6 @@
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.19.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -2680,9 +2521,6 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/process/tree/v3.4.47"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
@ -2737,10 +2575,6 @@
}
],
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
"support": {
"issues": "https://github.com/theseer/tokenizer/issues",
"source": "https://github.com/theseer/tokenizer/tree/master"
},
"time": "2019-06-13T22:48:21+00:00"
},
{
@ -2790,10 +2624,6 @@
"check",
"validate"
],
"support": {
"issues": "https://github.com/webmozarts/assert/issues",
"source": "https://github.com/webmozarts/assert/tree/1.9.1"
},
"time": "2020-07-08T17:02:28+00:00"
},
{
@ -2846,23 +2676,20 @@
],
"description": "Safe replacement to @ for suppressing warnings.",
"homepage": "https://www.mediawiki.org/wiki/at-ease",
"support": {
"source": "https://github.com/wikimedia/at-ease/tree/master"
},
"time": "2018-10-10T15:39:06+00:00"
},
{
"name": "yoast/phpunit-polyfills",
"version": "1.0.2",
"version": "1.0.3",
"source": {
"type": "git",
"url": "https://github.com/Yoast/PHPUnit-Polyfills.git",
"reference": "1a582ab1d91e86aa450340c4d35631a85314ff9f"
"reference": "5ea3536428944955f969bc764bbe09738e151ada"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/1a582ab1d91e86aa450340c4d35631a85314ff9f",
"reference": "1a582ab1d91e86aa450340c4d35631a85314ff9f",
"url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/5ea3536428944955f969bc764bbe09738e151ada",
"reference": "5ea3536428944955f969bc764bbe09738e151ada",
"shasum": ""
},
"require": {
@ -2906,11 +2733,7 @@
"polyfill",
"testing"
],
"support": {
"issues": "https://github.com/Yoast/PHPUnit-Polyfills/issues",
"source": "https://github.com/Yoast/PHPUnit-Polyfills"
},
"time": "2021-10-03T08:40:26+00:00"
"time": "2021-11-23T01:37:03+00:00"
}
],
"aliases": [],

View File

@ -15,6 +15,20 @@ defined( 'ABSPATH' ) || exit;
return array(
'AF' => array(),
'AL' => array( // Albania states.
'AL-01' => __( 'Berat', 'woocommerce' ),
'AL-09' => __( 'Dibër', 'woocommerce' ),
'AL-02' => __( 'Durrës', 'woocommerce' ),
'AL-03' => __( 'Elbasan', 'woocommerce' ),
'AL-04' => __( 'Fier', 'woocommerce' ),
'AL-05' => __( 'Gjirokastër', 'woocommerce' ),
'AL-06' => __( 'Korçë', 'woocommerce' ),
'AL-07' => __( 'Kukës', 'woocommerce' ),
'AL-08' => __( 'Lezhë', 'woocommerce' ),
'AL-10' => __( 'Shkodër', 'woocommerce' ),
'AL-11' => __( 'Tirana', 'woocommerce' ),
'AL-12' => __( 'Vlorë', 'woocommerce' ),
),
'AO' => array( // Angola states.
'BGO' => __( 'Bengo', 'woocommerce' ),
'BLU' => __( 'Benguela', 'woocommerce' ),
@ -187,15 +201,15 @@ return array(
'ZO' => __( 'Zou', 'woocommerce' ),
),
'BO' => array( // Bolivian states.
'B' => __( 'Chuquisaca', 'woocommerce' ),
'H' => __( 'Beni', 'woocommerce' ),
'C' => __( 'Cochabamba', 'woocommerce' ),
'L' => __( 'La Paz', 'woocommerce' ),
'O' => __( 'Oruro', 'woocommerce' ),
'N' => __( 'Pando', 'woocommerce' ),
'P' => __( 'Potosí', 'woocommerce' ),
'S' => __( 'Santa Cruz', 'woocommerce' ),
'T' => __( 'Tarija', 'woocommerce' ),
'BO-B' => __( 'Beni', 'woocommerce' ),
'BO-H' => __( 'Chuquisaca', 'woocommerce' ),
'BO-C' => __( 'Cochabamba', 'woocommerce' ),
'BO-L' => __( 'La Paz', 'woocommerce' ),
'BO-O' => __( 'Oruro', 'woocommerce' ),
'BO-N' => __( 'Pando', 'woocommerce' ),
'BO-P' => __( 'Potosí', 'woocommerce' ),
'BO-S' => __( 'Santa Cruz', 'woocommerce' ),
'BO-T' => __( 'Tarija', 'woocommerce' ),
),
'BR' => array( // Brazillian states.
'AC' => __( 'Acre', 'woocommerce' ),
@ -321,6 +335,50 @@ return array(
'CN31' => __( 'Tibet / 西藏', 'woocommerce' ),
'CN32' => __( 'Xinjiang / 新疆', 'woocommerce' ),
),
'CO' => array( // Colombia States.
'CO-AMA' => __( 'Amazonas', 'woocommerce' ),
'CO-ANT' => __( 'Antioquia', 'woocommerce' ),
'CO-ARA' => __( 'Arauca', 'woocommerce' ),
'CO-ATL' => __( 'Atlántico', 'woocommerce' ),
'CO-BOL' => __( 'Bolívar', 'woocommerce' ),
'CO-BOY' => __( 'Boyacá', 'woocommerce' ),
'CO-CAL' => __( 'Caldas', 'woocommerce' ),
'CO-CAQ' => __( 'Caquetá', 'woocommerce' ),
'CO-CAS' => __( 'Casanare', 'woocommerce' ),
'CO-CAU' => __( 'Cauca', 'woocommerce' ),
'CO-CES' => __( 'Cesar', 'woocommerce' ),
'CO-CHO' => __( 'Chocó', 'woocommerce' ),
'CO-COR' => __( 'Córdoba', 'woocommerce' ),
'CO-CUN' => __( 'Cundinamarca', 'woocommerce' ),
'CO-DC' => __( 'Capital District', 'woocommerce' ),
'CO-GUA' => __( 'Guainía', 'woocommerce' ),
'CO-GUV' => __( 'Guaviare', 'woocommerce' ),
'CO-HUI' => __( 'Huila', 'woocommerce' ),
'CO-LAG' => __( 'La Guajira', 'woocommerce' ),
'CO-MAG' => __( 'Magdalena', 'woocommerce' ),
'CO-MET' => __( 'Meta', 'woocommerce' ),
'CO-NAR' => __( 'Nariño', 'woocommerce' ),
'CO-NSA' => __( 'Norte de Santander', 'woocommerce' ),
'CO-PUT' => __( 'Putumayo', 'woocommerce' ),
'CO-QUI' => __( 'Quindío', 'woocommerce' ),
'CO-RIS' => __( 'Risaralda', 'woocommerce' ),
'CO-SAN' => __( 'Santander', 'woocommerce' ),
'CO-SAP' => __( 'San Andrés & Providencia', 'woocommerce' ),
'CO-SUC' => __( 'Sucre', 'woocommerce' ),
'CO-TOL' => __( 'Tolima', 'woocommerce' ),
'CO-VAC' => __( 'Valle del Cauca', 'woocommerce' ),
'CO-VAU' => __( 'Vaupés', 'woocommerce' ),
'CO-VID' => __( 'Vichada', 'woocommerce' ),
),
'CR' => array( // Costa Rica states.
'CR-A' => __( 'Alajuela', 'woocommerce' ),
'CR-C' => __( 'Cartago', 'woocommerce' ),
'CR-G' => __( 'Guanacaste', 'woocommerce' ),
'CR-H' => __( 'Heredia', 'woocommerce' ),
'CR-L' => __( 'Limón', 'woocommerce' ),
'CR-P' => __( 'Puntarenas', 'woocommerce' ),
'CR-SJ' => __( 'San José', 'woocommerce' ),
),
'CZ' => array(),
'DE' => array(),
'DK' => array(),
@ -329,34 +387,44 @@ return array(
'DO-02' => __( 'Azua', 'woocommerce' ),
'DO-03' => __( 'Baoruco', 'woocommerce' ),
'DO-04' => __( 'Barahona', 'woocommerce' ),
'DO-33' => __( 'Cibao Nordeste', 'woocommerce' ),
'DO-34' => __( 'Cibao Noroeste', 'woocommerce' ),
'DO-35' => __( 'Cibao Norte', 'woocommerce' ),
'DO-36' => __( 'Cibao Sur', 'woocommerce' ),
'DO-05' => __( 'Dajabón', 'woocommerce' ),
'DO-06' => __( 'Duarte', 'woocommerce' ),
'DO-07' => __( 'Elías Piña', 'woocommerce' ),
'DO-08' => __( 'El Seibo', 'woocommerce' ),
'DO-37' => __( 'El Valle', 'woocommerce' ),
'DO-07' => __( 'Elías Piña', 'woocommerce' ),
'DO-38' => __( 'Enriquillo', 'woocommerce' ),
'DO-09' => __( 'Espaillat', 'woocommerce' ),
'DO-30' => __( 'Hato Mayor', 'woocommerce' ),
'DO-19' => __( 'Hermanas Mirabal', 'woocommerce' ),
'DO-39' => __( 'Higüamo', 'woocommerce' ),
'DO-10' => __( 'Independencia', 'woocommerce' ),
'DO-11' => __( 'La Altagracia', 'woocommerce' ),
'DO-12' => __( 'La Romana', 'woocommerce' ),
'DO-13' => __( 'La Vega', 'woocommerce' ),
'DO-14' => __( 'María Trinidad Sánchez', 'woocommerce' ),
'DO-28' => __( 'Monseñor Nouel', 'woocommerce' ),
'DO-15' => __( 'Monte Cristi', 'woocommerce' ),
'DO-29' => __( 'Monte Plata', 'woocommerce' ),
'DO-40' => __( 'Ozama', 'woocommerce' ),
'DO-16' => __( 'Pedernales', 'woocommerce' ),
'DO-17' => __( 'Peravia', 'woocommerce' ),
'DO-18' => __( 'Puerto Plata', 'woocommerce' ),
'DO-19' => __( 'Hermanas Mirabal', 'woocommerce' ),
'DO-20' => __( 'Samaná', 'woocommerce' ),
'DO-21' => __( 'San Cristóbal', 'woocommerce' ),
'DO-31' => __( 'San José de Ocoa', 'woocommerce' ),
'DO-22' => __( 'San Juan', 'woocommerce' ),
'DO-23' => __( 'San Pedro de Macorís', 'woocommerce' ),
'DO-24' => __( 'Sánchez Ramírez', 'woocommerce' ),
'DO-25' => __( 'Santiago', 'woocommerce' ),
'DO-26' => __( 'Santiago Rodríguez', 'woocommerce' ),
'DO-27' => __( 'Valverde', 'woocommerce' ),
'DO-28' => __( 'Monseñor Nouel', 'woocommerce' ),
'DO-29' => __( 'Monte Plata', 'woocommerce' ),
'DO-30' => __( 'Hato Mayor', 'woocommerce' ),
'DO-31' => __( 'San José de Ocoa', 'woocommerce' ),
'DO-32' => __( 'Santo Domingo', 'woocommerce' ),
'DO-41' => __( 'Valdesia', 'woocommerce' ),
'DO-27' => __( 'Valverde', 'woocommerce' ),
'DO-42' => __( 'Yuma', 'woocommerce' ),
),
'DZ' => array(
'DZ-01' => __( 'Adrar', 'woocommerce' ),
@ -409,6 +477,32 @@ return array(
'DZ-48' => __( 'Relizane', 'woocommerce' ),
),
'EE' => array(),
'EC' => array( // Ecuador states.
'EC-A' => __( 'Azuay', 'woocommerce' ),
'EC-B' => __( 'Bolívar', 'woocommerce' ),
'EC-F' => __( 'Cañar', 'woocommerce' ),
'EC-C' => __( 'Carchi', 'woocommerce' ),
'EC-H' => __( 'Chimborazo', 'woocommerce' ),
'EC-X' => __( 'Cotopaxi', 'woocommerce' ),
'EC-O' => __( 'El Oro', 'woocommerce' ),
'EC-E' => __( 'Esmeraldas', 'woocommerce' ),
'EC-W' => __( 'Galápagos', 'woocommerce' ),
'EC-G' => __( 'Guayas', 'woocommerce' ),
'EC-I' => __( 'Imbabura', 'woocommerce' ),
'EC-L' => __( 'Loja', 'woocommerce' ),
'EC-R' => __( 'Los Ríos', 'woocommerce' ),
'EC-M' => __( 'Manabí', 'woocommerce' ),
'EC-S' => __( 'Morona-Santiago', 'woocommerce' ),
'EC-N' => __( 'Napo', 'woocommerce' ),
'EC-D' => __( 'Orellana', 'woocommerce' ),
'EC-Y' => __( 'Pastaza', 'woocommerce' ),
'EC-P' => __( 'Pichincha', 'woocommerce' ),
'EC-SE' => __( 'Santa Elena', 'woocommerce' ),
'EC-SD' => __( 'Santo Domingo de los Tsáchilas', 'woocommerce' ),
'EC-U' => __( 'Sucumbíos', 'woocommerce' ),
'EC-T' => __( 'Tungurahua', 'woocommerce' ),
'EC-Z' => __( 'Zamora-Chinchipe', 'woocommerce' ),
),
'EG' => array( // Egypt states.
'EGALX' => __( 'Alexandria', 'woocommerce' ),
'EGASN' => __( 'Aswan', 'woocommerce' ),
@ -531,34 +625,54 @@ return array(
'M' => __( 'Crete', 'woocommerce' ),
),
'GT' => array( // Guatemalan states.
'AV' => __( 'Alta Verapaz', 'woocommerce' ),
'BV' => __( 'Baja Verapaz', 'woocommerce' ),
'CM' => __( 'Chimaltenango', 'woocommerce' ),
'CQ' => __( 'Chiquimula', 'woocommerce' ),
'PR' => __( 'El Progreso', 'woocommerce' ),
'ES' => __( 'Escuintla', 'woocommerce' ),
'GU' => __( 'Guatemala', 'woocommerce' ),
'HU' => __( 'Huehuetenango', 'woocommerce' ),
'IZ' => __( 'Izabal', 'woocommerce' ),
'JA' => __( 'Jalapa', 'woocommerce' ),
'JU' => __( 'Jutiapa', 'woocommerce' ),
'PE' => __( 'Petén', 'woocommerce' ),
'QZ' => __( 'Quetzaltenango', 'woocommerce' ),
'QC' => __( 'Quiché', 'woocommerce' ),
'RE' => __( 'Retalhuleu', 'woocommerce' ),
'SA' => __( 'Sacatepéquez', 'woocommerce' ),
'SM' => __( 'San Marcos', 'woocommerce' ),
'SR' => __( 'Santa Rosa', 'woocommerce' ),
'SO' => __( 'Sololá', 'woocommerce' ),
'SU' => __( 'Suchitepéquez', 'woocommerce' ),
'TO' => __( 'Totonicapán', 'woocommerce' ),
'ZA' => __( 'Zacapa', 'woocommerce' ),
'GT-AV' => __( 'Alta Verapaz', 'woocommerce' ),
'GT-BV' => __( 'Baja Verapaz', 'woocommerce' ),
'GT-CM' => __( 'Chimaltenango', 'woocommerce' ),
'GT-CQ' => __( 'Chiquimula', 'woocommerce' ),
'GT-PR' => __( 'El Progreso', 'woocommerce' ),
'GT-ES' => __( 'Escuintla', 'woocommerce' ),
'GT-GU' => __( 'Guatemala', 'woocommerce' ),
'GT-HU' => __( 'Huehuetenango', 'woocommerce' ),
'GT-IZ' => __( 'Izabal', 'woocommerce' ),
'GT-JA' => __( 'Jalapa', 'woocommerce' ),
'GT-JU' => __( 'Jutiapa', 'woocommerce' ),
'GT-PE' => __( 'Petén', 'woocommerce' ),
'GT-QZ' => __( 'Quetzaltenango', 'woocommerce' ),
'GT-QC' => __( 'Quiché', 'woocommerce' ),
'GT-RE' => __( 'Retalhuleu', 'woocommerce' ),
'GT-SA' => __( 'Sacatepéquez', 'woocommerce' ),
'GT-SM' => __( 'San Marcos', 'woocommerce' ),
'GT-SR' => __( 'Santa Rosa', 'woocommerce' ),
'GT-SO' => __( 'Sololá', 'woocommerce' ),
'GT-SU' => __( 'Suchitepéquez', 'woocommerce' ),
'GT-TO' => __( 'Totonicapán', 'woocommerce' ),
'GT-ZA' => __( 'Zacapa', 'woocommerce' ),
),
'HK' => array( // Hong Kong states.
'HONG KONG' => __( 'Hong Kong Island', 'woocommerce' ),
'KOWLOON' => __( 'Kowloon', 'woocommerce' ),
'NEW TERRITORIES' => __( 'New Territories', 'woocommerce' ),
),
'HN' => array( // Honduras states.
'HN-AT' => __( 'Atlántida', 'woocommerce' ),
'HN-IB' => __( 'Bay Islands', 'woocommerce' ),
'HN-CH' => __( 'Choluteca', 'woocommerce' ),
'HN-CL' => __( 'Colón', 'woocommerce' ),
'HN-CM' => __( 'Comayagua', 'woocommerce' ),
'HN-CP' => __( 'Copán', 'woocommerce' ),
'HN-CR' => __( 'Cortés', 'woocommerce' ),
'HN-EP' => __( 'El Paraíso', 'woocommerce' ),
'HN-FM' => __( 'Francisco Morazán', 'woocommerce' ),
'HN-GD' => __( 'Gracias a Dios', 'woocommerce' ),
'HN-IN' => __( 'Intibucá', 'woocommerce' ),
'HN-LE' => __( 'Lempira', 'woocommerce' ),
'HN-LP' => __( 'La Paz', 'woocommerce' ),
'HN-OC' => __( 'Ocotepeque', 'woocommerce' ),
'HN-OL' => __( 'Olancho', 'woocommerce' ),
'HN-SB' => __( 'Santa Bárbara', 'woocommerce' ),
'HN-VA' => __( 'Valle', 'woocommerce' ),
'HN-YO' => __( 'Yoro', 'woocommerce' ),
),
'HU' => array( // Hungary states.
'BK' => __( 'Bács-Kiskun', 'woocommerce' ),
'BE' => __( 'Békés', 'woocommerce' ),
@ -1168,6 +1282,25 @@ return array(
'SAG' => __( 'Sagarmatha', 'woocommerce' ),
'SET' => __( 'Seti', 'woocommerce' ),
),
'NI' => array( // Nicaragua states
'NI-AN' => __( 'Atlántico Norte', 'woocommerce' ),
'NI-AS' => __( 'Atlántico Sur', 'woocommerce' ),
'NI-BO' => __( 'Boaco', 'woocommerce' ),
'NI-CA' => __( 'Carazo', 'woocommerce' ),
'NI-CI' => __( 'Chinandega', 'woocommerce' ),
'NI-CO' => __( 'Chontales', 'woocommerce' ),
'NI-ES' => __( 'Estelí', 'woocommerce' ),
'NI-GR' => __( 'Granada', 'woocommerce' ),
'NI-JI' => __( 'Jinotega', 'woocommerce' ),
'NI-LE' => __( 'León', 'woocommerce' ),
'NI-MD' => __( 'Madriz', 'woocommerce' ),
'NI-MN' => __( 'Managua', 'woocommerce' ),
'NI-MS' => __( 'Masaya', 'woocommerce' ),
'NI-MT' => __( 'Matagalpa', 'woocommerce' ),
'NI-NS' => __( 'Nueva Segovia', 'woocommerce' ),
'NI-RI' => __( 'Rivas', 'woocommerce' ),
'NI-SJ' => __( 'Río San Juan', 'woocommerce' ),
),
'NZ' => array( // New Zealand States.
'NL' => __( 'Northland', 'woocommerce' ),
'AK' => __( 'Auckland', 'woocommerce' ),
@ -1186,6 +1319,21 @@ return array(
'OT' => __( 'Otago', 'woocommerce' ),
'SL' => __( 'Southland', 'woocommerce' ),
),
'PA' => array( // Panama states.
'PA-1' => __( 'Bocas del Toro', 'woocommerce' ),
'PA-2' => __( 'Coclé', 'woocommerce' ),
'PA-3' => __( 'Colón', 'woocommerce' ),
'PA-4' => __( 'Chiriquí', 'woocommerce' ),
'PA-5' => __( 'Darién', 'woocommerce' ),
'PA-6' => __( 'Herrera', 'woocommerce' ),
'PA-7' => __( 'Los Santos', 'woocommerce' ),
'PA-8' => __( 'Panamá', 'woocommerce' ),
'PA-9' => __( 'Veraguas', 'woocommerce' ),
'PA-10' => __( 'West Panamá', 'woocommerce' ),
'PA-EM' => __( 'Emberá', 'woocommerce' ),
'PA-KY' => __( 'Guna Yala', 'woocommerce' ),
'PA-NB' => __( 'Ngöbe-Buglé', 'woocommerce' ),
),
'PE' => array( // Peru states.
'CAL' => __( 'El Callao', 'woocommerce' ),
'LMA' => __( 'Municipalidad Metropolitana de Lima', 'woocommerce' ),
@ -1383,6 +1531,22 @@ return array(
'SG' => array(),
'SK' => array(),
'SI' => array(),
'SV' => array( // El Salvador states.
'SV-AH' => __( 'Ahuachapán', 'woocommerce' ),
'SV-CA' => __( 'Cabañas', 'woocommerce' ),
'SV-CH' => __( 'Chalatenango', 'woocommerce' ),
'SV-CU' => __( 'Cuscatlán', 'woocommerce' ),
'SV-LI' => __( 'La Libertad', 'woocommerce' ),
'SV-MO' => __( 'Morazán', 'woocommerce' ),
'SV-PA' => __( 'La Paz', 'woocommerce' ),
'SV-SA' => __( 'Santa Ana', 'woocommerce' ),
'SV-SM' => __( 'San Miguel', 'woocommerce' ),
'SV-SO' => __( 'Sonsonate', 'woocommerce' ),
'SV-SS' => __( 'San Salvador', 'woocommerce' ),
'SV-SV' => __( 'San Vicente', 'woocommerce' ),
'SV-UN' => __( 'La Unión', 'woocommerce' ),
'SV-US' => __( 'Usulután', 'woocommerce' ),
),
'TH' => array( // Thailand states.
'TH-37' => __( 'Amnat Charoen', 'woocommerce' ),
'TH-15' => __( 'Ang Thong', 'woocommerce' ),
@ -1836,32 +2000,53 @@ return array(
'AE' => __( 'Armed Forces (AE)', 'woocommerce' ),
'AP' => __( 'Armed Forces (AP)', 'woocommerce' ),
),
'UY' => array( // Uruguay States.
'UY-AR' => __( 'Artigas', 'woocommerce' ),
'UY-CA' => __( 'Canelones', 'woocommerce' ),
'UY-CL' => __( 'Cerro Largo', 'woocommerce' ),
'UY-CO' => __( 'Colonia', 'woocommerce' ),
'UY-DU' => __( 'Durazno', 'woocommerce' ),
'UY-FS' => __( 'Flores', 'woocommerce' ),
'UY-FD' => __( 'Florida', 'woocommerce' ),
'UY-LA' => __( 'Lavalleja', 'woocommerce' ),
'UY-MA' => __( 'Maldonado', 'woocommerce' ),
'UY-MO' => __( 'Montevideo', 'woocommerce' ),
'UY-PA' => __( 'Paysandú', 'woocommerce' ),
'UY-RN' => __( 'Río Negro', 'woocommerce' ),
'UY-RV' => __( 'Rivera', 'woocommerce' ),
'UY-RO' => __( 'Rocha', 'woocommerce' ),
'UY-SA' => __( 'Salto', 'woocommerce' ),
'UY-SJ' => __( 'San José', 'woocommerce' ),
'UY-SO' => __( 'Soriano', 'woocommerce' ),
'UY-TA' => __( 'Tacuarembó', 'woocommerce' ),
'UY-TT' => __( 'Treinta y Tres', 'woocommerce' ),
),
'VE' => array( // Venezuela States.
'A' => __( 'Capital', 'woocommerce' ),
'B' => __( 'Anzoátegui', 'woocommerce' ),
'C' => __( 'Apure', 'woocommerce' ),
'D' => __( 'Aragua', 'woocommerce' ),
'E' => __( 'Barinas', 'woocommerce' ),
'F' => __( 'Bolívar', 'woocommerce' ),
'G' => __( 'Carabobo', 'woocommerce' ),
'H' => __( 'Cojedes', 'woocommerce' ),
'I' => __( 'Falcón', 'woocommerce' ),
'J' => __( 'Guárico', 'woocommerce' ),
'K' => __( 'Lara', 'woocommerce' ),
'L' => __( 'Mérida', 'woocommerce' ),
'M' => __( 'Miranda', 'woocommerce' ),
'N' => __( 'Monagas', 'woocommerce' ),
'O' => __( 'Nueva Esparta', 'woocommerce' ),
'P' => __( 'Portuguesa', 'woocommerce' ),
'R' => __( 'Sucre', 'woocommerce' ),
'S' => __( 'Táchira', 'woocommerce' ),
'T' => __( 'Trujillo', 'woocommerce' ),
'U' => __( 'Yaracuy', 'woocommerce' ),
'V' => __( 'Zulia', 'woocommerce' ),
'W' => __( 'Federal Dependencies', 'woocommerce' ),
'X' => __( 'Vargas', 'woocommerce' ),
'Y' => __( 'Delta Amacuro', 'woocommerce' ),
'Z' => __( 'Amazonas', 'woocommerce' ),
'VE-A' => __( 'Capital', 'woocommerce' ),
'VE-B' => __( 'Anzoátegui', 'woocommerce' ),
'VE-C' => __( 'Apure', 'woocommerce' ),
'VE-D' => __( 'Aragua', 'woocommerce' ),
'VE-E' => __( 'Barinas', 'woocommerce' ),
'VE-F' => __( 'Bolívar', 'woocommerce' ),
'VE-G' => __( 'Carabobo', 'woocommerce' ),
'VE-H' => __( 'Cojedes', 'woocommerce' ),
'VE-I' => __( 'Falcón', 'woocommerce' ),
'VE-J' => __( 'Guárico', 'woocommerce' ),
'VE-K' => __( 'Lara', 'woocommerce' ),
'VE-L' => __( 'Mérida', 'woocommerce' ),
'VE-M' => __( 'Miranda', 'woocommerce' ),
'VE-N' => __( 'Monagas', 'woocommerce' ),
'VE-O' => __( 'Nueva Esparta', 'woocommerce' ),
'VE-P' => __( 'Portuguesa', 'woocommerce' ),
'VE-R' => __( 'Sucre', 'woocommerce' ),
'VE-S' => __( 'Táchira', 'woocommerce' ),
'VE-T' => __( 'Trujillo', 'woocommerce' ),
'VE-U' => __( 'Yaracuy', 'woocommerce' ),
'VE-V' => __( 'Zulia', 'woocommerce' ),
'VE-W' => __( 'Federal Dependencies', 'woocommerce' ),
'VE-X' => __( 'La Guaira (Vargas)', 'woocommerce' ),
'VE-Y' => __( 'Delta Amacuro', 'woocommerce' ),
'VE-Z' => __( 'Amazonas', 'woocommerce' ),
),
'VN' => array(),
'YT' => array(),

View File

@ -87,17 +87,57 @@ class WC_Admin_Addons {
)
);
if ( ! is_wp_error( $raw_featured ) ) {
$featured = json_decode( wp_remote_retrieve_body( $raw_featured ) );
if ( $featured ) {
set_transient( 'wc_addons_featured', $featured, DAY_IN_SECONDS );
}
if ( is_wp_error( $raw_featured ) ) {
do_action( 'woocommerce_page_wc-addons_connection_error', $raw_featured->get_error_message() );
$message = self::is_ssl_error( $raw_featured->get_error_message() )
? __( 'We encountered an SSL error. Please ensure your site supports TLS version 1.2 or above.', 'woocommerce' )
: $raw_featured->get_error_message();
self::output_empty( $message );
return;
}
$response_code = (int) wp_remote_retrieve_response_code( $raw_featured );
if ( 200 !== $response_code ) {
do_action( 'woocommerce_page_wc-addons_connection_error', $response_code );
/* translators: %d: HTTP error code. */
$message = sprintf(
esc_html(
__(
'Our request to the featured API got error code %d.',
'woocommerce'
)
),
$response_code
);
self::output_empty( $message );
return;
}
$featured = json_decode( wp_remote_retrieve_body( $raw_featured ) );
if ( empty( $featured ) || ! is_array( $featured ) ) {
do_action( 'woocommerce_page_wc-addons_connection_error', 'Empty or malformed response' );
$message = __( 'Our request to the featured API got a malformed response.', 'woocommerce' );
self::output_empty( $message );
return;
}
if ( $featured ) {
set_transient( 'wc_addons_featured', $featured, DAY_IN_SECONDS );
}
}
if ( ! empty( $featured ) ) {
self::output_featured( $featured );
}
self::output_featured( $featured );
}
public static function is_ssl_error( $error_message ) {
return false !== stripos( $error_message, 'cURL error 35' );
}
/**
@ -127,7 +167,7 @@ class WC_Admin_Addons {
* @param string $term Search terms.
* @param string $country Store country.
*
* @return object of extensions and promotions.
* @return object|WP_Error Object with products and promotions properties, or WP_Error
*/
public static function get_extension_data( $category, $term, $country ) {
$parameters = self::build_parameter_string( $category, $term, $country );
@ -144,9 +184,24 @@ class WC_Admin_Addons {
array( 'headers' => $headers )
);
if ( ! is_wp_error( $raw_extensions ) ) {
$addons = json_decode( wp_remote_retrieve_body( $raw_extensions ) );
if ( is_wp_error( $raw_extensions ) ) {
do_action( 'woocommerce_page_wc-addons_connection_error', $raw_extensions->get_error_message() );
return $raw_extensions;
}
$response_code = (int) wp_remote_retrieve_response_code( $raw_extensions );
if ( 200 !== $response_code ) {
do_action( 'woocommerce_page_wc-addons_connection_error', $response_code );
return new WP_Error( 'error', __( "Our request to the search API got response code $response_code.", 'woocommerce' ) );
}
$addons = json_decode( wp_remote_retrieve_body( $raw_extensions ) );
if ( ! is_object( $addons ) || ! isset( $addons->products ) ) {
do_action( 'woocommerce_page_wc-addons_connection_error', 'Empty or malformed response' );
return new WP_Error( 'error', __( "Our request to the search API got a malformed response.", 'woocommerce' ) );
}
return $addons;
}
@ -908,6 +963,31 @@ class WC_Admin_Addons {
<?php
}
public static function output_empty( $message = '' ) {
?>
<div class="wc-addons__empty">
<h2><?php echo wp_kses_post( __( 'Oh no! We\'re having trouble connecting to the extensions catalog right now.', 'woocommerce' ) ); ?></h2>
<?php if ( ! empty( $message ) ) : ?>
<p><?php echo esc_html( $message ); ?></p>
<?php endif; ?>
<p>
<?php
/* translators: a url */
printf(
wp_kses_post(
__(
'To start growing your business, head over to <a href="%s">WooCommerce.com</a>, where you\'ll find the most popular WooCommerce extensions.',
'woocommerce'
)
),
'https://woocommerce.com/products/?utm_source=extensionsscreen&utm_medium=product&utm_campaign=connectionerror'
);
?>
</p>
</div>
<?php
}
/**
* Handles output of the addons page in admin.
@ -946,7 +1026,7 @@ class WC_Admin_Addons {
$term = $search ? $search : null;
$country = WC()->countries->get_base_country();
$extension_data = self::get_extension_data( $category, $term, $country );
$addons = $extension_data->products;
$addons = is_wp_error( $extension_data ) ? $extension_data : $extension_data->products;
$promotions = ! empty( $extension_data->promotions ) ? $extension_data->promotions : array();
}

View File

@ -70,12 +70,12 @@ $current_section_name = __( 'Browse Categories', 'woocommerce' );
<div class="wrap">
<div class="marketplace-content-wrapper">
<?php require __DIR__ . '/html-admin-page-addons-category-nav.php'; ?>
<?php if ( ! empty( $search ) && 0 === count( $addons ) ) : ?>
<?php if ( ! empty( $search ) && ! is_wp_error( $addons ) && 0 === count( $addons ) ) : ?>
<h1 class="search-form-title">
<?php esc_html_e( 'Sorry, could not find anything. Try searching again using a different term.', 'woocommerce' ); ?></p>
</h1>
<?php endif; ?>
<?php if ( ! empty( $search ) && count( $addons ) > 0 ) : ?>
<?php if ( ! empty( $search ) && ! is_wp_error( $addons ) && count( $addons ) > 0 ) : ?>
<h1 class="search-form-title">
<?php // translators: search keyword. ?>
<?php printf( esc_html__( 'Search results for "%s"', 'woocommerce' ), esc_html( sanitize_text_field( wp_unslash( $search ) ) ) ); ?>
@ -87,42 +87,46 @@ $current_section_name = __( 'Browse Categories', 'woocommerce' );
<?php WC_Admin_Addons::render_featured(); ?>
</div>
<?php endif; ?>
<?php if ( '_featured' !== $current_section && $addons ) : ?>
<?php
if ( ! empty( $promotions ) && WC()->is_wc_admin_active() ) {
foreach ( $promotions as $promotion ) {
WC_Admin_Addons::output_search_promotion_block( $promotion );
}
}
?>
<ul class="products">
<?php foreach ( $addons as $addon ) : ?>
<?php
if ( 'shipping_methods' === $current_section ) {
// Do not show USPS or Canada Post extensions for US and CA stores, respectively.
$country = WC()->countries->get_base_country();
if ( 'US' === $country
&& false !== strpos(
$addon->link,
'woocommerce.com/products/usps-shipping-method'
)
) {
continue;
}
if ( 'CA' === $country
&& false !== strpos(
$addon->link,
'woocommerce.com/products/canada-post-shipping-method'
)
) {
continue;
}
<?php if ( '_featured' !== $current_section ) : ?>
<?php if ( is_wp_error( $addons ) ) : ?>
<?php WC_Admin_Addons::output_empty( $addons->get_error_message() ); ?>
<?php else: ?>
<?php
if ( ! empty( $promotions ) && WC()->is_wc_admin_active() ) {
foreach ( $promotions as $promotion ) {
WC_Admin_Addons::output_search_promotion_block( $promotion );
}
}
?>
<ul class="products">
<?php foreach ( $addons as $addon ) : ?>
<?php
if ( 'shipping_methods' === $current_section ) {
// Do not show USPS or Canada Post extensions for US and CA stores, respectively.
$country = WC()->countries->get_base_country();
if ( 'US' === $country
&& false !== strpos(
$addon->link,
'woocommerce.com/products/usps-shipping-method'
)
) {
continue;
}
if ( 'CA' === $country
&& false !== strpos(
$addon->link,
'woocommerce.com/products/canada-post-shipping-method'
)
) {
continue;
}
}
WC_Admin_Addons::render_product_card( $addon );
?>
<?php endforeach; ?>
</ul>
WC_Admin_Addons::render_product_card( $addon );
?>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?php endif; ?>
</div>
<?php else : ?>

View File

@ -812,6 +812,11 @@ class WC_Countries {
'hidden' => true,
),
),
'AL' => array(
'state' => array(
'label' => __( 'County', 'woocommerce' ),
),
),
'AO' => array(
'postcode' => array(
'required' => false,
@ -897,6 +902,9 @@ class WC_Countries {
'required' => false,
'hidden' => true,
),
'state' => array(
'label' => __( 'Department', 'woocommerce' ),
),
),
'BS' => array(
'postcode' => array(
@ -941,6 +949,14 @@ class WC_Countries {
'postcode' => array(
'required' => false,
),
'state' => array(
'label' => __( 'Department', 'woocommerce' ),
),
),
'CR' => array(
'state' => array(
'label' => __( 'Province', 'woocommerce' ),
),
),
'CW' => array(
'postcode' => array(
@ -975,6 +991,16 @@ class WC_Countries {
'hidden' => true,
),
),
'DO' => array(
'state' => array(
'label' => __( 'Province', 'woocommerce' ),
),
),
'EC' => array(
'state' => array(
'label' => __( 'Province', 'woocommerce' ),
),
),
'EE' => array(
'postcode' => array(
'priority' => 65,
@ -1047,6 +1073,11 @@ class WC_Countries {
'label' => __( 'Region', 'woocommerce' ),
),
),
'HN' => array(
'state' => array(
'label' => __( 'Department', 'woocommerce' ),
),
),
'HU' => array(
'last_name' => array(
'class' => array( 'form-row-first' ),
@ -1214,6 +1245,11 @@ class WC_Countries {
'label' => __( 'Province', 'woocommerce' ),
),
),
'NI' => array(
'state' => array(
'label' => __( 'Department', 'woocommerce' ),
),
),
'NL' => array(
'postcode' => array(
'priority' => 65,
@ -1259,6 +1295,11 @@ class WC_Countries {
'required' => false,
),
),
'PA' => array(
'state' => array(
'label' => __( 'Province', 'woocommerce' ),
),
),
'PL' => array(
'postcode' => array(
'priority' => 65,
@ -1283,6 +1324,11 @@ class WC_Countries {
'hidden' => true,
),
),
'PY' => array(
'state' => array(
'label' => __( 'Department', 'woocommerce' ),
),
),
'RE' => array(
'state' => array(
'required' => false,
@ -1340,6 +1386,11 @@ class WC_Countries {
'hidden' => true,
),
),
'SV' => array(
'state' => array(
'label' => __( 'Department', 'woocommerce' ),
),
),
'ES' => array(
'postcode' => array(
'priority' => 65,
@ -1413,6 +1464,11 @@ class WC_Countries {
'label' => __( 'State', 'woocommerce' ),
),
),
'UY' => array(
'state' => array(
'label' => __( 'Department', 'woocommerce' ),
),
),
'GB' => array(
'postcode' => array(
'label' => __( 'Postcode', 'woocommerce' ),

View File

@ -311,14 +311,15 @@ downloads_remaining = IF( downloads_remaining = '', '', GREATEST( 0, downloads_r
WHERE permission_id = %d",
$this->get_id()
);
$wpdb->query( $query ); // WPCS: unprepared SQL ok.
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$wpdb->query( $query );
// Re-read this download from the data store to pull updated counts.
$this->data_store->read( $this );
// Track download in download log.
$download_log = new WC_Customer_Download_Log();
$download_log->set_timestamp( current_time( 'timestamp', true ) );
$download_log->set_timestamp( time() );
$download_log->set_permission_id( $this->get_id() );
if ( ! is_null( $user_id ) ) {
@ -341,9 +342,10 @@ WHERE permission_id = %d",
/**
* OffsetGet.
*
* @param string $offset Offset.
* @param mixed $offset Offset.
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet( $offset ) {
if ( is_callable( array( $this, "get_$offset" ) ) ) {
return $this->{"get_$offset"}();
@ -353,9 +355,10 @@ WHERE permission_id = %d",
/**
* OffsetSet.
*
* @param string $offset Offset.
* @param mixed $value Value.
* @param mixed $offset Offset.
* @param mixed $value Value.
*/
#[\ReturnTypeWillChange]
public function offsetSet( $offset, $value ) {
if ( is_callable( array( $this, "set_$offset" ) ) ) {
$this->{"set_$offset"}( $value );
@ -365,8 +368,9 @@ WHERE permission_id = %d",
/**
* OffsetUnset
*
* @param string $offset Offset.
* @param mixed $offset Offset.
*/
#[\ReturnTypeWillChange]
public function offsetUnset( $offset ) {
if ( is_callable( array( $this, "set_$offset" ) ) ) {
$this->{"set_$offset"}( '' );
@ -376,9 +380,10 @@ WHERE permission_id = %d",
/**
* OffsetExists.
*
* @param string $offset Offset.
* @param mixed $offset Offset.
* @return bool
*/
#[\ReturnTypeWillChange]
public function offsetExists( $offset ) {
return in_array( $offset, array_keys( $this->data ), true );
}

View File

@ -270,7 +270,7 @@ class WC_Download_Handler {
);
$count = 0;
$file_path = str_replace( array_keys( $replacements ), array_values( $replacements ), $file_path );
$file_path = str_replace( array_keys( $replacements ), array_values( $replacements ), $file_path, $count );
$parsed_file_path = wp_parse_url( $file_path );
$remote_file = null === $count || 0 === $count; // Remote file only if there were no replacements.

View File

@ -1046,7 +1046,7 @@ CREATE TABLE {$wpdb->prefix}wc_reserved_stock (
`expires` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`order_id`, `product_id`)
) $collate;
CREATE TABLE {$wpdb->prefix}woocommerce_rate_limits (
CREATE TABLE {$wpdb->prefix}wc_rate_limits (
rate_limit_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
rate_limit_key varchar(200) NOT NULL,
rate_limit_expiry BIGINT UNSIGNED NOT NULL,
@ -1087,7 +1087,7 @@ CREATE TABLE {$wpdb->prefix}woocommerce_rate_limits (
"{$wpdb->prefix}woocommerce_tax_rate_locations",
"{$wpdb->prefix}woocommerce_tax_rates",
"{$wpdb->prefix}wc_reserved_stock",
"{$wpdb->prefix}woocommerce_rate_limits",
"{$wpdb->prefix}wc_rate_limits",
);
/**

View File

@ -140,6 +140,7 @@ class WC_Order_Item_Coupon extends WC_Order_Item {
* @param string $offset Offset.
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet( $offset ) {
wc_deprecated_function( 'WC_Order_Item_Coupon::offsetGet', '4.4.0', '' );
if ( 'discount_amount' === $offset ) {
@ -157,6 +158,7 @@ class WC_Order_Item_Coupon extends WC_Order_Item {
* @param string $offset Offset.
* @param mixed $value Value.
*/
#[\ReturnTypeWillChange]
public function offsetSet( $offset, $value ) {
wc_deprecated_function( 'WC_Order_Item_Coupon::offsetSet', '4.4.0', '' );
if ( 'discount_amount' === $offset ) {
@ -173,6 +175,7 @@ class WC_Order_Item_Coupon extends WC_Order_Item {
* @param string $offset Offset.
* @return bool
*/
#[\ReturnTypeWillChange]
public function offsetExists( $offset ) {
if ( in_array( $offset, array( 'discount_amount', 'discount_amount_tax' ), true ) ) {
return true;

View File

@ -293,6 +293,7 @@ class WC_Order_Item_Fee extends WC_Order_Item {
* @param string $offset Offset.
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet( $offset ) {
if ( 'line_total' === $offset ) {
$offset = 'total';
@ -311,6 +312,7 @@ class WC_Order_Item_Fee extends WC_Order_Item {
* @param string $offset Offset.
* @param mixed $value Value.
*/
#[\ReturnTypeWillChange]
public function offsetSet( $offset, $value ) {
wc_deprecated_function( 'WC_Order_Item_Fee::offsetSet', '4.4.0', '' );
if ( 'line_total' === $offset ) {
@ -329,6 +331,7 @@ class WC_Order_Item_Fee extends WC_Order_Item {
* @param string $offset Offset.
* @return bool
*/
#[\ReturnTypeWillChange]
public function offsetExists( $offset ) {
if ( in_array( $offset, array( 'line_total', 'line_tax', 'line_tax_data' ), true ) ) {
return true;

View File

@ -428,6 +428,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
* @param string $offset Offset.
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet( $offset ) {
if ( 'line_subtotal' === $offset ) {
$offset = 'subtotal';
@ -452,6 +453,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
* @param string $offset Offset.
* @param mixed $value Value.
*/
#[\ReturnTypeWillChange]
public function offsetSet( $offset, $value ) {
wc_deprecated_function( 'WC_Order_Item_Product::offsetSet', '4.4.0', '' );
if ( 'line_subtotal' === $offset ) {
@ -476,6 +478,7 @@ class WC_Order_Item_Product extends WC_Order_Item {
* @param string $offset Offset.
* @return bool
*/
#[\ReturnTypeWillChange]
public function offsetExists( $offset ) {
if ( in_array( $offset, array( 'line_subtotal', 'line_subtotal_tax', 'line_total', 'line_tax', 'line_tax_data', 'item_meta_array', 'item_meta', 'qty' ), true ) ) {
return true;

View File

@ -279,6 +279,7 @@ class WC_Order_Item_Shipping extends WC_Order_Item {
* @param string $offset Key.
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet( $offset ) {
if ( 'cost' === $offset ) {
$offset = 'total';
@ -293,6 +294,7 @@ class WC_Order_Item_Shipping extends WC_Order_Item {
* @param string $offset Key.
* @param mixed $value Value to set.
*/
#[\ReturnTypeWillChange]
public function offsetSet( $offset, $value ) {
wc_deprecated_function( 'WC_Order_Item_Shipping::offsetSet', '4.4.0', '' );
if ( 'cost' === $offset ) {
@ -307,6 +309,7 @@ class WC_Order_Item_Shipping extends WC_Order_Item {
* @param string $offset Key.
* @return bool
*/
#[\ReturnTypeWillChange]
public function offsetExists( $offset ) {
if ( in_array( $offset, array( 'cost' ), true ) ) {
return true;

View File

@ -247,6 +247,7 @@ class WC_Order_Item_Tax extends WC_Order_Item {
* @param string $offset Offset.
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet( $offset ) {
if ( 'tax_amount' === $offset ) {
$offset = 'tax_total';
@ -263,6 +264,7 @@ class WC_Order_Item_Tax extends WC_Order_Item {
* @param string $offset Offset.
* @param mixed $value Value.
*/
#[\ReturnTypeWillChange]
public function offsetSet( $offset, $value ) {
wc_deprecated_function( 'WC_Order_Item_Tax::offsetSet', '4.4.0', '' );
if ( 'tax_amount' === $offset ) {
@ -279,6 +281,7 @@ class WC_Order_Item_Tax extends WC_Order_Item {
* @param string $offset Offset.
* @return bool
*/
#[\ReturnTypeWillChange]
public function offsetExists( $offset ) {
if ( in_array( $offset, array( 'tax_amount', 'shipping_tax_amount' ), true ) ) {
return true;

View File

@ -310,6 +310,7 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
* @param string $offset Offset.
* @param mixed $value Value.
*/
#[\ReturnTypeWillChange]
public function offsetSet( $offset, $value ) {
if ( 'item_meta_array' === $offset ) {
foreach ( $value as $meta_id => $meta ) {
@ -334,6 +335,7 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
*
* @param string $offset Offset.
*/
#[\ReturnTypeWillChange]
public function offsetUnset( $offset ) {
$this->maybe_read_meta_data();
@ -359,6 +361,7 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
* @param string $offset Offset.
* @return bool
*/
#[\ReturnTypeWillChange]
public function offsetExists( $offset ) {
$this->maybe_read_meta_data();
if ( 'item_meta_array' === $offset || 'item_meta' === $offset || array_key_exists( $offset, $this->data ) ) {
@ -373,6 +376,7 @@ class WC_Order_Item extends WC_Data implements ArrayAccess {
* @param string $offset Offset.
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet( $offset ) {
$this->maybe_read_meta_data();

View File

@ -266,6 +266,7 @@ class WC_Product_Attribute implements ArrayAccess {
* @param string $offset Offset.
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet( $offset ) {
switch ( $offset ) {
case 'is_variation':
@ -291,6 +292,7 @@ class WC_Product_Attribute implements ArrayAccess {
* @param string $offset Offset.
* @param mixed $value Value.
*/
#[\ReturnTypeWillChange]
public function offsetSet( $offset, $value ) {
switch ( $offset ) {
case 'is_variation':
@ -304,7 +306,7 @@ class WC_Product_Attribute implements ArrayAccess {
break;
default:
if ( is_callable( array( $this, "set_$offset" ) ) ) {
return $this->{"set_$offset"}( $value );
$this->{"set_$offset"}( $value );
}
break;
}
@ -315,6 +317,7 @@ class WC_Product_Attribute implements ArrayAccess {
*
* @param string $offset Offset.
*/
#[\ReturnTypeWillChange]
public function offsetUnset( $offset ) {}
/**
@ -323,6 +326,7 @@ class WC_Product_Attribute implements ArrayAccess {
* @param string $offset Offset.
* @return bool
*/
#[\ReturnTypeWillChange]
public function offsetExists( $offset ) {
return in_array( $offset, array_merge( array( 'is_variation', 'is_visible', 'is_taxonomy', 'value' ), array_keys( $this->data ) ), true );
}

View File

@ -53,14 +53,14 @@ class WC_Product_Download implements ArrayAccess {
* @return string absolute, relative, or shortcode.
*/
public function get_type_of_file_path( $file_path = '' ) {
$file_path = $file_path ? $file_path : $this->get_file();
$parsed_url = parse_url( $file_path );
$file_path = $file_path ? $file_path : $this->get_file();
$parsed_url = wp_parse_url( $file_path );
if (
$parsed_url &&
isset( $parsed_url['host'] ) && // Absolute url means that it has a host.
( // Theoretically we could permit any scheme (like ftp as well), but that has not been the case before. So we allow none or http(s).
! isset( $parsed_url['scheme'] ) ||
in_array( $parsed_url['scheme'], array( 'http', 'https' ) )
in_array( $parsed_url['scheme'], array( 'http', 'https' ), true )
)
) {
return 'absolute';
@ -255,6 +255,7 @@ class WC_Product_Download implements ArrayAccess {
* @param string $offset Offset.
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet( $offset ) {
switch ( $offset ) {
default:
@ -272,11 +273,12 @@ class WC_Product_Download implements ArrayAccess {
* @param string $offset Offset.
* @param mixed $value Offset value.
*/
#[\ReturnTypeWillChange]
public function offsetSet( $offset, $value ) {
switch ( $offset ) {
default:
if ( is_callable( array( $this, "set_$offset" ) ) ) {
return $this->{"set_$offset"}( $value );
$this->{"set_$offset"}( $value );
}
break;
}
@ -287,6 +289,7 @@ class WC_Product_Download implements ArrayAccess {
*
* @param string $offset Offset.
*/
#[\ReturnTypeWillChange]
public function offsetUnset( $offset ) {}
/**
@ -295,6 +298,7 @@ class WC_Product_Download implements ArrayAccess {
* @param string $offset Offset.
* @return bool
*/
#[\ReturnTypeWillChange]
public function offsetExists( $offset ) {
return in_array( $offset, array_keys( $this->data ), true );
}

View File

@ -101,7 +101,7 @@ class WC_Rate_Limiter {
$wpdb->prepare(
"
SELECT rate_limit_expiry
FROM {$wpdb->prefix}woocommerce_rate_limits
FROM {$wpdb->prefix}wc_rate_limits
WHERE rate_limit_key = %s
",
$action_id
@ -138,7 +138,7 @@ class WC_Rate_Limiter {
$next_try_allowed_at = time() + $delay;
$result = $wpdb->replace(
$wpdb->prefix . 'woocommerce_rate_limits',
$wpdb->prefix . 'wc_rate_limits',
array(
'rate_limit_key' => $action_id,
'rate_limit_expiry' => $next_try_allowed_at,
@ -159,7 +159,7 @@ class WC_Rate_Limiter {
$wpdb->query(
$wpdb->prepare(
"DELETE FROM {$wpdb->prefix}woocommerce_rate_limits WHERE rate_limit_expiry < %d",
"DELETE FROM {$wpdb->prefix}wc_rate_limits WHERE rate_limit_expiry < %d",
time()
)
);

View File

@ -27,7 +27,7 @@ final class WooCommerce {
*
* @var string
*/
public $version = '6.0.0';
public $version = '6.1.0';
/**
* WooCommerce Schema version.
@ -932,7 +932,7 @@ final class WooCommerce {
return;
}
$message_one = __( 'You have installed a development version of WooCommerce which requires files to be built and minified. From the plugin directory, run <code>grunt assets</code> to build and minify assets.', 'woocommerce' );
$message_one = __( 'You have installed a development version of WooCommerce which requires files to be built and minified. From the plugin directory, run <code>pnpm install</code> and then <code>pnpm nx build woocommerce-legacy-assets</code> to build and minify assets.', 'woocommerce' );
$message_two = sprintf(
/* translators: 1: URL of WordPress.org Repository 2: URL of the GitHub Repository release page */
__( 'Or you can download a pre-built version of the plugin from the <a href="%1$s">WordPress.org repository</a> or by visiting <a href="%2$s">the releases page in the GitHub repository</a>.', 'woocommerce' ),

View File

@ -51,6 +51,13 @@ if ( ! class_exists( 'WC_Email_Customer_New_Account', false ) ) :
*/
public $password_generated;
/**
* Magic link to set initial password.
*
* @var string
*/
public $set_password_url;
/**
* Constructor.
*/
@ -104,6 +111,7 @@ if ( ! class_exists( 'WC_Email_Customer_New_Account', false ) ) :
$this->user_email = stripslashes( $this->object->user_email );
$this->recipient = $this->user_email;
$this->password_generated = $password_generated;
$this->set_password_url = $this->generate_set_password_url();
}
if ( $this->is_enabled() && $this->get_recipient() ) {
@ -131,6 +139,7 @@ if ( ! class_exists( 'WC_Email_Customer_New_Account', false ) ) :
'sent_to_admin' => false,
'plain_text' => false,
'email' => $this,
'set_password_url' => $this->set_password_url,
)
);
}
@ -153,6 +162,7 @@ if ( ! class_exists( 'WC_Email_Customer_New_Account', false ) ) :
'sent_to_admin' => false,
'plain_text' => true,
'email' => $this,
'set_password_url' => $this->set_password_url,
)
);
}
@ -166,6 +176,26 @@ if ( ! class_exists( 'WC_Email_Customer_New_Account', false ) ) :
public function get_default_additional_content() {
return __( 'We look forward to seeing you soon.', 'woocommerce' );
}
/**
* Generate set password URL link for a new user.
*
* See also Automattic\WooCommerce\Blocks\Domain\Services\Email\CustomerNewAccount and wp_new_user_notification.
*
* @since 6.0.0
* @return string
*/
protected function generate_set_password_url() {
// Generate a magic link so user can set initial password.
$key = get_password_reset_key( $this->object );
if ( ! is_wp_error( $key ) ) {
$action = 'newaccount';
return wc_get_account_endpoint_url( 'lost-password' ) . "?action=$action&key=$key&login=" . rawurlencode( $this->object->user_login );
} else {
// Something went wrong while getting the key for new password URL, send customer to the generic password reset.
return wc_get_account_endpoint_url( 'lost-password' );
}
}
}
endif;

View File

@ -275,24 +275,31 @@ class WC_REST_Taxes_V1_Controller extends WC_REST_Controller {
$response = rest_ensure_response( $taxes );
// Store pagination values for headers then unset for count query.
$per_page = (int) $prepared_args['number'];
$page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 );
// Query only for ids.
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
$query = str_replace( 'SELECT *', 'SELECT tax_rate_id', $query );
$wpdb->get_results(
$wpdb->prepare(
$query,
$wpdb_prepare_args
)
// Unset LIMIT args.
array_splice( $wpdb_prepare_args, -2 );
// Count query.
$query = str_replace(
array(
'SELECT *',
'LIMIT %d, %d',
),
array(
'SELECT COUNT(*)',
'',
),
$query
);
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
$total_taxes = (int) $wpdb->get_var( empty( $wpdb_prepare_args ) ? $query : $wpdb->prepare( $query, $wpdb_prepare_args ) );
// phpcs:enable WordPress.DB.PreparedSQL.NotPrepared
// Calculate totals.
$total_taxes = (int) $wpdb->num_rows;
$response->header( 'X-WP-Total', (int) $total_taxes );
$response->header( 'X-WP-Total', $total_taxes );
$max_pages = ceil( $total_taxes / $per_page );
$response->header( 'X-WP-TotalPages', (int) $max_pages );

View File

@ -68,6 +68,7 @@ class WC_Tracks {
/**
* Record an event in Tracks - this is the preferred way to record events from PHP.
* Note: the event request won't be made if $properties has a member called `error`.
*
* @param string $event_name The name of the event.
* @param array $properties Custom properties to send with the event.

View File

@ -22,6 +22,7 @@ class WC_Extensions_Tracking {
add_action( 'woocommerce_helper_disconnected', array( $this, 'track_helper_disconnected' ) );
add_action( 'woocommerce_helper_subscriptions_refresh', array( $this, 'track_helper_subscriptions_refresh' ) );
add_action( 'woocommerce_addon_installed', array( $this, 'track_addon_install' ), 10, 2 );
add_action( 'woocommerce_page_wc-addons_connection_error', array( $this, 'track_extensions_page_connection_error' ), 10, 1 );
}
/**
@ -47,6 +48,29 @@ class WC_Extensions_Tracking {
WC_Tracks::record_event( $event, $properties );
}
/**
* Send a Tracks event when the Extensions page gets a bad response or no response
* from the WCCOM extensions API.
*
* @param string $error
*/
public function track_extensions_page_connection_error( string $error = '' ) {
// phpcs:disable WordPress.Security.NonceVerification.Recommended
$properties = array(
'section' => empty( $_REQUEST['section'] ) ? '_featured' : wc_clean( wp_unslash( $_REQUEST['section'] ) ),
);
if ( ! empty( $_REQUEST['search'] ) ) {
$properties['search_term'] = wc_clean( wp_unslash( $_REQUEST['search'] ) );
}
// phpcs:enable
if ( ! empty( $error ) ) {
$properties['error_data'] = $error;
}
WC_Tracks::record_event( 'extensions_view_connection_error', $properties );
}
/**
* Send a Tracks even when a Helper connection process is initiated.
*/

View File

@ -715,16 +715,11 @@ function wc_restock_refunded_items( $order, $refunded_line_items ) {
// Update _reduced_stock meta to track changes.
$item_stock_reduced = $item_stock_reduced - $qty_to_refund;
if ( 0 < $item_stock_reduced ) {
// Keeps track of total running tally of reduced stock.
$item->update_meta_data( '_reduced_stock', $item_stock_reduced );
// Keeps track of total running tally of reduced stock.
$item->update_meta_data( '_reduced_stock', $item_stock_reduced );
// Keeps track of only refunded items that needs restock.
$item->update_meta_data( '_restock_refunded_items', $qty_to_refund + $restock_refunded_items );
} else {
$item->delete_meta_data( '_reduced_stock' );
$item->delete_meta_data( '_restock_refunded_items' );
}
// Keeps track of only refunded items that needs restock.
$item->update_meta_data( '_restock_refunded_items', $qty_to_refund + $restock_refunded_items );
/* translators: 1: product ID 2: old stock level 3: new stock level */
$order->add_order_note( sprintf( __( 'Item #%1$s stock increased from %2$s to %3$s.', 'woocommerce' ), $product->get_id(), $old_stock, $new_stock ) );

View File

@ -0,0 +1,3 @@
> 0.1%
ie 8
ie 9

View File

@ -0,0 +1,21 @@
*.min.js
/js/accounting/**
/js/flexslider/**
/js/jquery-blockui/**
/js/jquery-cookie/**
/js/jquery-flot/**
/js/jquery-payment/**
/js/jquery-qrcode/**
/js/jquery-serializejson/**
/js/jquery-tiptip/**
/js/jquery-ui-touch-punch/**
/js/js-cookie/**
/js/photoswipe/**
/js/prettyPhoto/**
/js/round/**
/js/select2/**
/js/selectWoo/**
/js/stupidtable/**
/js/zeroclipboard/**
/js/zoom/**

View File

@ -0,0 +1,31 @@
/** @format */
module.exports = {
root: true,
env: {
browser: true,
es6: true,
node: true
},
globals: {
wp: true,
wpApiSettings: true,
wcSettings: true,
es6: true
},
rules: {
camelcase: 0,
indent: 0,
'max-len': [ 2, { 'code': 140 } ],
'no-console': 1
},
parser: 'babel-eslint',
parserOptions: {
ecmaVersion: 8,
ecmaFeatures: {
modules: true,
experimentalObjectRestSpread: true,
jsx: true
}
},
};

3
plugins/woocommerce/legacy/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
js/**/*.min.js
css/*.css
css/photoswipe/**/*.min.css

View File

@ -0,0 +1,3 @@
{
"extends": "stylelint-config-wordpress",
}

View File

@ -0,0 +1,271 @@
module.exports = function ( grunt ) {
'use strict';
var sass = require( 'node-sass' );
grunt.initConfig( {
// Setting folder templates.
dirs: {
css: 'css',
cssDest: '../assets/css',
fonts: 'assets/fonts',
images: 'assets/images',
js: 'js',
jsDest: '../assets/js',
php: 'includes',
},
// JavaScript linting with ESLint.
eslint: {
src: [
'<%= dirs.js %>/admin/*.js',
'!<%= dirs.js %>/admin/*.min.js',
'<%= dirs.js %>/frontend/*.js',
'!<%= dirs.js %>/frontend/*.min.js',
],
},
// Sass linting with Stylelint.
stylelint: {
options: {
configFile: '.stylelintrc',
},
all: [ '<%= dirs.css %>/*.scss', '!<%= dirs.css %>/select2.scss' ],
},
// Minify .js files.
uglify: {
options: {
ie8: true,
parse: {
strict: false,
},
output: {
comments: /@license|@preserve|^!/,
},
},
js_assets: {
files: [
{
expand: true,
cwd: '<%= dirs.jsDest %>/',
src: [ '**/*.js', '!**/*.min.js' ],
extDot: 'last',
dest: '<%= dirs.jsDest %>',
ext: '.min.js',
},
],
},
},
// Compile all .scss files.
sass: {
compile: {
options: {
implementation: sass,
sourceMap: false,
},
files: [
{
expand: true,
cwd: '<%= dirs.css %>/',
src: [ '*.scss' ],
dest: '<%= dirs.css %>/',
ext: '.css',
},
],
},
},
// Generate RTL .css files.
rtlcss: {
woocommerce: {
expand: true,
cwd: '<%= dirs.css %>',
src: [ '*.css', '!select2.css', '!*-rtl.css' ],
dest: '<%= dirs.css %>/',
ext: '-rtl.css',
},
},
// Minify all .css files.
cssmin: {
minify: {
files: [
{
expand: true,
cwd: '<%= dirs.css %>/',
src: [ '*.css' ],
dest: '<%= dirs.css %>/',
ext: '.css',
},
{
expand: true,
cwd: '<%= dirs.css %>/photoswipe/',
src: [ '*.css', '!*.min.css' ],
dest: '<%= dirs.css %>/photoswipe/',
ext: '.min.css',
},
{
expand: true,
cwd: '<%= dirs.css %>/photoswipe/default-skin/',
src: [ '*.css', '!*.min.css' ],
dest: '<%= dirs.css %>/photoswipe/default-skin/',
ext: '.min.css',
},
],
},
},
// Concatenate select2.css onto the admin.css files.
concat: {
admin: {
files: {
'<%= dirs.css %>/admin.css': [
'<%= dirs.css %>/select2.css',
'<%= dirs.css %>/admin.css',
],
'<%= dirs.css %>/admin-rtl.css': [
'<%= dirs.css %>/select2.css',
'<%= dirs.css %>/admin-rtl.css',
],
},
},
},
// Watch changes for assets.
watch: {
css: {
files: [ '<%= dirs.css %>/*.scss' ],
tasks: [
'sass',
'rtlcss',
'postcss',
'cssmin',
'concat',
'move:css',
'copy:css',
],
},
js: {
files: [
'GruntFile.js',
'<%= dirs.js %>/**/*.js',
'!<%= dirs.js %>/**/*.min.js',
],
tasks: [ 'eslint', 'copy:js', 'newer:uglify' ],
},
},
// PHP Code Sniffer.
phpcs: {
options: {
bin: 'vendor/bin/phpcs',
},
dist: {
src: [
'**/*.php', // Include all php files.
'!includes/api/legacy/**',
'!includes/libraries/**',
'!node_modules/**',
'!tests/cli/**',
'!tmp/**',
'!vendor/**',
],
},
},
// Autoprefixer.
postcss: {
options: {
processors: [ require( 'autoprefixer' ) ],
},
dist: {
src: [ '<%= dirs.css %>/*.css' ],
},
},
// Specifying different src/dest for postcss broke everything,
// so we'll just move files to their new location afterwards.
move: {
css: {
files: [
{
src: '<%= dirs.css %>/*.css',
dest: '<%= dirs.cssDest %>/',
},
{
src: '<%= dirs.css %>/photoswipe/*.min.css',
dest: '<%= dirs.cssDest %>/photoswipe/',
},
{
src:
'<%= dirs.css %>/photoswipe/default-skin/*.min.css',
dest: '<%= dirs.cssDest %>/photoswipe/default-skin/',
},
],
},
},
copy: {
css: {
files: [
{
cwd: '<%= dirs.css %>',
expand: true,
src: 'photoswipe/**',
dest: '<%= dirs.cssDest %>/',
},
{
cwd: '<%= dirs.css %>',
expand: true,
src: 'jquery-ui/**',
dest: '<%= dirs.cssDest %>/',
},
],
},
js: {
cwd: '<%= dirs.js %>/',
expand: true,
src: '**',
dest: '<%= dirs.jsDest %>/',
},
},
} );
// Load NPM tasks to be used here.
grunt.loadNpmTasks( 'grunt-sass' );
grunt.loadNpmTasks( 'grunt-phpcs' );
grunt.loadNpmTasks( 'grunt-rtlcss' );
grunt.loadNpmTasks( 'grunt-postcss' );
grunt.loadNpmTasks( 'grunt-stylelint' );
grunt.loadNpmTasks( 'gruntify-eslint' );
grunt.loadNpmTasks( 'grunt-contrib-uglify' );
grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
grunt.loadNpmTasks( 'grunt-contrib-concat' );
grunt.loadNpmTasks( 'grunt-contrib-copy' );
grunt.loadNpmTasks( 'grunt-contrib-watch' );
grunt.loadNpmTasks( 'grunt-contrib-clean' );
grunt.loadNpmTasks( 'grunt-newer' );
grunt.loadNpmTasks( 'grunt-move' );
// Register tasks.
grunt.registerTask( 'default', [ 'js', 'css' ] );
grunt.registerTask( 'js', [ 'eslint', 'copy:js', 'uglify:js_assets' ] );
grunt.registerTask( 'css', [
'sass',
'rtlcss',
'postcss',
'cssmin',
'concat',
'move:css',
'copy:css',
] );
grunt.registerTask( 'assets', [ 'js', 'css' ] );
grunt.registerTask( 'e2e-build', [ 'uglify:js_assets', 'css' ] );
// Only an alias to 'default' task.
grunt.registerTask( 'dev', [ 'default' ] );
};

View File

@ -7733,6 +7733,22 @@ table.bar_chart {
font-weight: bold;
}
.wc-addons__empty {
margin: 48px auto;
max-width: 640px;
h2 {
font-size: 20px;
font-weight: 400;
line-height: 1.2;
}
p {
font-size: 16px;
line-height: 1.5;
}
}
@media screen and (min-width: 600px) {
.wc-addons-wrap {

Some files were not shown because too many files have changed in this diff Show More