The DownloadPermissionsAdjuster class hooks to adjust_download_permissions
from within its init method. However this method is executed only
if the class is resolved, otherwise the hooks doesn't get attached
and then the scheduled action is not serviced.
To solve this, the class is resolved from WooCommerce::init_hooks.
This requires a change in DownloadPermissionsAdjuster::init
to use wc_get_container()->get( LegacyProxy::class )->get_instance_of
instead of WC()->get_instance_of, since WC() can't be used from
WooCommerce::construct (which invokes init_hooks).
This commit re-works the `WC_Shipping_Zone_Data_Store::read()` method in the following ways:
1. Remove a confusing conditional (`if ( 0 !== $zone->get_id() || '0' !== $zone->get_id() ) { ... }`)
2. Return early if we're dealing with Zone 0, eliminating additional conditional steps
3. Add documentation for the "woocommerce_shipping_zone_loaded" action hook
This commit revert some of the changes added in #27735 because wc_get_products and wc_get_orders is not fully compitable with API controller queries. Since we are close to release 4.9, its better to revert and fix them properly then rush a fix. This undones some the performance improvements we acheived in 27735, in favor of more stability, hopefully we will be able to restore this soon.
When called from V3, controller calls V2s get_product_data method, where stock_status was did not existed and was renamed. In V3 controller, we compute it based on V2 in_stock field.
In PHP 8 "iconv( 'UTF-8', 'ASCII//TRANSLIT')" doesn't work as expected:
instead of returning a proper substitute for non-ASCII characters
it returns "?". Temporarily changing the locale to C.UTF-8
fixes the issue.
The featured extension list was static but now it's fetched from
WooCommerce.com and may change more frequently. Reducing the
cache duration to allow users to see changes much more quickly.
- Jest/Puppeteer sometimes will not find an element on page load when that element is outside the initial viewport
- There were duplicate .variation_tab classes which confused Jest/Puppeteer
- Add function for opening and verifying new product page
- Update test sequence for changes in flow in markup and Jest/Puppeteer
We are using func_get_arg method to receive argument in a backward compatible way since we cannot modify function signature to add more params even with default params. Earlier I was hoping to use DI to create another child class with modified signature and load it depending upon where we are executing from, however since we had to revert DI, we add this workaround to unblock #27735.
1. Use $already_reduced_stock instead of also considering $refunded_item_quantity while deleting orders. This will bring back part of #27504 again, but for now this seems to be the best solution for countering #28605. It needs discussion whether deleting a line item completely should also undo any refund related changes on it or not.
2. Also mark `stock_reduced` flag on order if any of the line item has any `_reduced_stock` flag. This will allow for stock restoring logic to work properly when order is cancelled.
3. Only adjust line item stock when order is in `processing`, `completed` or `on-hold` status state, because we need to reduce stocks on these status only. Stock adjustments in refunds or when changing statuses is already taken care of by their specific hooks.
Earlier, we were just showing an "Usage limit reached message", however in some cases, specially when user is logged in, we can also ask them to go to MyAccount page and cancel order if they'd like to (to free up the coupon). This will hopefully make for a better user experience.
We hold coupons when payment is failed if the setting "hold stock for checkout" is enabled for some minutes. This is to allow the customers to try again if they want, and to give time to complete payment for gateways where it could take some time.
Unfortunately this cause for some bad UX user retries by starting the order from scratch again, and then if they apply the coupon, usage limit gets hit because the earlier coupon is still held and is counted towards the usage. This commit improves the error message in these cases when usage is applied per customer and is hit, by stating to go to my account to complete/cancel payment (in case of logged in user) or to wait for some time in case of guest users.
This commit adds the 'Select a country / region...' text as a placeholder text displayed in the country select field indicating to the user that they need to select a country. This is only needed when the option ¨Default customer location" is set to "No location by default".
When a simple product with downloads gets converted into a variable
product all the existing download permissions for past orders become
invalid. This commit adds an extra verification procedure to the
product save code:
- Get all the existing download permissions for the product and all
the children (variations)
- For each download permission for the parent product, if there's a
variation that offers the same file for download (same file URL)
AND an equivalent download permission doesn't exist (equivalent means
same file URL, same order id and same user id), then create it.
Additionally, a new WC_Customer_Download_Data_Store::create_from_data
method is added.
This commit removes the setting "Page style" from WooCommerce -> Settings -> Payments -> PayPal Standard. This setting was used to define the value of the parameter "page_style" passed to the PayPal Standard API, but PayPal deprecated this parameter and ignores it. According to PayPal in https://developer.paypal.com/docs/paypal-payments-standard/integration-guide/Appx-websitestandard-htmlvariables/?mark=page_style#deprecated-variables: "Deprecated variables are ignored when you pass them to PayPal". In the same link, you can see that "page_style" is included in the list of deprecated parameters.
This commit replaces double quotes with single quotes inside a MySQL query to avoid a syntax error when the SQL mode ANSI_QUOTES is enabled in MySQL. When this mode is enabled, MySQL treats double quotes as identifiers (like the backtick character) instead of as string delimiters. Before this change, sites running with this mode enabled wouldn't be able to add products to orders created manually in the admin as the modified query would fail (other places that also use product search including variations would fail as well). The commit that introduced this issue shipped in WC 4.5.0 (see https://github.com/woocommerce/woocommerce/pull/27171).
`lostpassword_post` is a WP action that is duplicated in WooCommerce to replicate the functionality to retrieve user password in the 'My Account' pages. WP recently added the variable `$user_data` as a second parameter to this action (a6cecef42f). This commit simply copies this change to the version of the action that we maintain. Similar to what was done in 1a99235dc8 when a first parameter as added to the action in WP and we had to do the same in WC core.
After chevron clicking on attribute section complete edit product data section toggled insted cliackig area.
Key point issue is missing 'postbox' class of wordpress postbox.js library for a attribute block that we try to toggle.
As these fields were mandatory for Serbia from the beginning, making them optional by default is causing shop owners additional effort to set them back to mandatory. This PR is making them mandatory by default.
Fixes#28366
Issue
When changing the "low stock amount" on product level, a.k.a. setting a "low stock amount" for a specific product. The message on the single product page does not change from "%s in stock" to "Only %s left in stock". It only checks the global setting "low stock quantity" defined in WooCommerce > Products > Stock.
This commit replaces a few more instances of jQuery.fn.click() event shorthand that were missed in the previous commit. For more information see the commit message for 8ebead165e.
- New class class-wc-twenty-twenty-one.php
- New stylesheet twenty-twenty-one.scss
- Updates checks for default themes in theme_support_includes() and wc_is_wp_default_theme_active()
This method will prioritize getting rates from billing/shipping address instead of `WC()->customer` which in irrevelant in context of editing order from admin screen.
We were not passing tax location while computing discount in orders, hence it was defaulting to shop's base address resulting in incorrect tax calculation.
This commit refactors `get_rates` method into another method that allows getting rates from location directly.
This commit simply replaces the single call in WooCommerce core codebase to the deprecated woocommerce_reset_loop() function with its replacement wc_reset_loop().
This creates a tradeoff in optimizing repeated queries vs on off queries.
Another tradeoff is making more cache get calls as opposed to more SQL calls.
Primary reason for dropping the cache hydration is that seems like we can acheive the same results without it, so no need to add this additional complexity to our code.
This commit breaks down `read_meta_data` so that individual methods for cache key and setting raw meta data can be reused.
Also adds set_meta_data_from_raw_data to initialize metadata from manual cache.
A potential fix for #26851
This does change the get_next functionality slightly but if the hook is
already running then the next state should trigger a new one anyway.
- Added the `ThemeSupport class`, with methods to add and get
theme support options.
- It also has a new `add_default_options` method that adds the
options under a `_defaults` key.
- The `WC_Twenty_*` classes now use `ThemeSupport` instead of
the `add_theme_support` function to define image and thumbnail sizes.
- The values are defined as default options.
- The `WC_Shop_Customizer` class now uses `ThemeSupport` instead of
`wc_get_theme_support` to check if image and thumbnail sizes UI
should be rendered.
- The check is made excluding default values.
With these changes the UI to change the image and thumbnail sizes
is hidden only if the options are added as non-defaults elsewhere.
Additional changes:
- The code of the `wc_get_theme_support` function is replaced with
a simple call to `get_option` in `ThemeSupport`.
- Added the utility class `ArrayUtil`.
Removing the potential undesired retrieval of hundreds or thousands of unreadable WC_Product objects into memory just to filter them out immediately.
This change prevented some out-of-memory situations in our site.
With PHP 8.0, non-strict comparisons between integers and strings containing
non-numeric characters are being tightened. This affects comparisons like:
0 < '0000-00-00 00:00:00'
PHP 8.0 that equates to true whereas prior to 8.0 it would be false.
More details of this change can be found at: https://wiki.php.net/rfc/string_to_number_comparison
`WC_Admin_Dashboard::recent_reviews()` was calling `get_avatar()` passing `$comment->comment_author` which is not one of the list of parameters that the function accepts to get the avatar. As a result, the widget that displays the recent reviews in the admin dashboard was never displaying the avatar of the user that left the review. This commit fixes this issue by passing `$comment->comment_email` instead. I opted to use `$comment->comment_author` as it should be available for reviews left both by authenticated and anonymous users and because getting the comment object wouldn't be so simple (either we need to perform an extra query for each review or deprecate the `woocommerce_report_recent_reviews_query_from` filter).
Using the WPCS native whitelist comments is deprecated. So this PR just replaces all instances of `// WPCS: XSS ok.` found in `includes/wc-cart-functions.php` with the PHPCS native "// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped". I found this while working on another issue in the same file.
This commit improves the i18n of a string displayed during checkout showing the total amount of the order when the store is configured to display prices inclusive of taxes.
Before string concatenation was used to build the final string which is almost always a bad practice from i18n point of view (https://codex.wordpress.org/I18n_for_WordPress_Developers#Best_Practices). This commit uses sprintf() and two separate strings to make translation easier.
This commit replaces a call to the now deprecated jQuery.fn.toggle(handler, handler...) (https://api.jquery.com/toggle-event/) with a jQuery.click(). The deprecated call was used in the page where admins can edit e-mail templates (example: wp-admin/admin.php?page=wc-settings&tab=email§ion=wc_email_customer_on_hold_order) to show or hide the contents of the template and at the same time change the label of the button. We are now using jQuery.click() with a if statement inside to decide which label to use.
In PHP 8 required parameters after optional parameters in
function/method signatures trigger a deprecation notice. These type
of parameters are pointless since a value needs to always be
provided for them anyway, so they are actually de-facto required.
This commit converts all these not-so-optional parameters into
truly required parameters by removing their default values.
- this prevents the password reset process earlier (before the redirect)
- also now shows a notice informing the user that they need to log out
of (other) account
- in the checkout signup use case, the user may be setting their
password in a logged-in browser session; they need to be able to set an
initial account password
- add @since (original since based on git blame)
- document all params
- add @since for newly-added params
- add docs for woocommerce_endpoint_{$endpoint}_title
- get_endpoint_title now takes an extra `action` param
- this also is passed to the relevant hook (as an additional arg)
- woocommerce_endpoint_{$endpoint}_title
- for `lost-password?action=rp`, use `Set password`
- pass action query param through when using get_endpoint_title
After the League's Container package has been reintroduced, all the
code that implements the dependency injection mechanism in woocommerce
can be brought back as well.
In PHP 8 required parameters after optional parameters in
function/method signatures trigger a deprecation notice. These type
of parameters are pointless since a value needs to always be
provided for them anyway, so they are actually de-facto required.
This commit converts all these not-so-optional parameters into
truly required parameters by removing their default values.
There's a number of places in the WooCommerce codebase where the
built-in function 'round' is executed passing a non-numeric value
(not a number and not a string that can be parsed as a number),
for example round(''). In PHP 7 this yields a value of 0, but in
PHP 8 this throws an error.
This commit adds a 'NumberUtil' class with a static 'round' method,
this method checks if the passed value is numeric and if so it just
executes the built-in function, otherwise it returns 0. And all the
calls to 'round' in the codebase are replaced with 'NumberUtil::round'.
In #26642 we removed adding reduced_stock meta when adding new order item to prevent ghost entries, but in inadvertently exposed an underlying bug where _reduced_stock meta was getting set to 0 if its emtpy.
We were then checking the presence of this meta, but also not reducing the stock in case it was not set.
After the code that creates term relationships for variations has been
removed, a data migration is required to remove all the no longer needed
term relationships.
Also, the original migration that backfilled those relationships has
been removed (the migration function is kept but with an empty body).
A mechanism for improved filtering by attribute for variations was
introduced some time ago. This mechanism implied maintaining term
relationships for variations, where the terms were the attributes
that defined the variation.
The mechanism was reverted because it was complex and presented many
issues, but the code that created those term relationships was kept.
This pull request removes that code and the associated unit tests.
The setup wizard is going to be deprecated in WC 4.6.0 which should be
released soon. Some functions were marked as if they were deprecated in
WC 4.5.0 which is not the case.
In an environment with persistent object caching, concurrent calls
to delete_option() + add_option() can result in the option value
leaking out of the alloptions cache key, and into its own cache
item under the options group, while deleting the value from the
database.
This causes future function calls to add_option() to fail, since
the value already exists in cache (under the wrong key). It also
causes calls to delete_option() to fail, since the value is not
in the database.
This commit forces update_option() instead of the delete + add
combination, as well as removes multiple unnecessary calls to
update the woocommerce_db_version from admin notes and notices.
This commit reverts the functionality introduced in PR #26260
(later refined by #27175, #27190, #27508) in which filtering by
attribute using the layered nav widget was improved to handle the
cases of variations out of stock. The revert is a response to the
numerous problems reported by users in Woo 4.4 and 4.5
Not all the code has been reverted, only the code that resulted in
visible functionality changes. Thus, the code that generates
term relationships for variations is still in place to keep database
consistency and to keep the reverting changes to the minimum needed.
We were doing state and postcode even for countries where its not required, but unfortunately as an unintended effect we were ending up not checking shipping requirements if this was not met.
This commit changes the order of the error handling check to protect the code against a possible fatal error if wp_safe_remote_post() returns an instance of WP_Error().
This will introduce two new filters:
woocommerce_from_product_type_changed
woocommerce_to_product_type_changed
to filter the $from and $to variables respectively.
This will be useful in WCS pr_3732!
This commit fixes a bug that made it impossible to assign to a product a tax class that contained non-ASCII characters that are URL encoded by sanitize_title().
WooCommerce uses sanitize_title() to generate a slug when creating a tax class (d48f1d4e2e/includes/class-wc-tax.php (L808)). sanitize_title() converts some non-ASCII to ASCII equivalents (those handled by remove_accents()) and URL encodes others (like some Greek characters, for example).
The code was using wc_clean() to sanitize the tax class when the user edited a product. The problem is that wc_clean() removes URL encoded characters, changing the slug of some tax class, causing WooCommerce to use the standard tax class instead without any errors. To fix this issue, this commit replaces wc_clean() with sanitize_title(). This should be enough for security purposes and should not cause any issues with non-ASCII characters.
Implements the following expected behaviour:
1. Switch from variable subscription to non-variable one will delete variations.
2. Switch from variable subscription to variable product and vice-versa will NOT delete any variations.
This shall have no side-effects in WooCommerce Core.
By changing to auto invoking call the `c` variable will be encapsulated in its scope therefore not polluting the global scope and will continue to function as previously.
Fixes conflict and reassigning of already used variables when using other minified scripts. In my case the problem occurred with the Speed Booster Pack plugin.
The previous query was counting variable products twice when they
had a variation with a concrete value for the attribute and also
a variation with "Any..." value for the same attribute.
The new query fixes a bug where variations were being counted twice:
if a product was included in both the queries then it would be counted
differently and added; e.g. when a product had two variations,
one with "Any" attribute and other with a attribute that has a value.
The new query also optimizes performance, so that filter conditions
can be improved and better indexes can be used.
For performance reasons the query is split in two: one for simple
products and variations with a concrete attribute value, and another
one for variations having "Any..." as the attribute value.
Previously, we were using the `$formatted_meta_data` to build the final array.
However, this does not consider the fact that
`WC_Order_Item->get_formatted_meta_data` can exclude `meta_data` from the
result. There would be less `meta_data` objects return than the previous
implementation.
This fixes the issue by using the `$data['meta_data']` value as the main list of
meta data and only using `$formatted_meta_data` to optionally apply the
`display_key` and `display_value` properties.
The new query doesn't need empty attribute entries in the meta table,
therefore the code that generates them and the migration to backfill
the missing existing ones have been removed.
When set_attributes is used on WC_Product to remove existing attributes
the wc_product_attribute_uasort_comparison ends up being called
with a null argument, and this breaks tests in PHP 7.4 since
null is used as an array. This commit modifies the function so that
if null is passed no array access is attempted.
Right now the filter by attributes widget counts available variations
(for variation products). This is confusing since the counter shows
numbers that are higher than the actual count of products displayed.
This commit changes the query used by the widget so that instead
of counting variations it returns the parent product ids, and then
counts the distinct values. This also covers the case of products
where some of the variations have concrete values and some have
"Any..." values.
When "Create variations from all attributes" is used to create
variations it generates term relationship entries for all the generated
variations, however that doesn't happen when the term can be interpreted
as a numeric value. This is because in that case product->get_attributes
returns the attribute values as numbers, but the code that generates
the term relationships expect those to always be strings.
When manually adding a given variation this doesn't happen.
The fix is to simply strval-ize the value before using it, but it might
be worth investigating why this is happening.
The previous commit fixes a bug that causes the "attribute_" metadata
with an empty value to not be created when a new variation attribute
is added to the product (so that all variations have the attribute
with a value of "Any..."). This commit adds a data migration to
backfill the missing metadata for existing variations.
When a new variation attribute is added, the corresponding 'attribute_'
meta entries are added for all variations with an empty value;
and when an existing variation attribute is removed, the existing
'attribute_' meta entries are deleted for all variations.
This is necessary for the filter by attribute widget to work properly
when variations exist with a value of "Any..." for attributes.
When a variation product has an attribute with a value of "Any...",
and there's a filter by attribute widget for that attribute, then
that product won't be included in the counts displayed in the widget
(and if the count ends up being zero, the attribute won't be shown
in the widget).
This happens before since Woo 4.4, this widget works by looking at
entries in the term relationships table for varitions too
(used to do so for simple products and for "main" variable products
only), see PR #26260; but there are no such entries for
"Any..." attributes.
This commit fixes that by extending the SQL query used by the widget
to look for variations that have empty attribute values in the meta
table too.
Previously 'dirname( __FILE__ )' was used to import files, however, the directory separator was missing.
This commit replaces 'dirname( __FILE__ )' that was introduced in 5370d02484 with __DIR__ and added DIRECTORY_SEPARATOR
Relative include paths in PHP can break whenever the server is running opcache. As such, WordPress.com deploy system refuses to include WooCommerce because of that issue.
This commit changes the relative include paths to absolute include paths.
Relates to #27269
This bug was introduced in #26260. The sequence is:
1. WC_Query::adjust_posts_count runs, to handle found_posts filter,
this indirectly executes wc_setup_loop.
2. At this point $GLOBALS['wp_query']->max_num_pages hasn't been set
yet, and has a value of 0. Thus the loop variable total_pages
is set to 0.
3. Later wc_setup_loop runs again and this time
$GLOBALS['wp_query']->max_num_pages is already set, but since
the loop variable total_pages already exists, it keeps its
value of 0.
4. The pagination controls never show if total_pages is less than 2.
The fix consists of hooking into the_posts to set the value of
total_pages again, at that point $GLOBALS['wp_query']->max_num_pages
is already set.
PR #26260 introduced a handler for 'found_posts' filter in WC_Query
class in order to adjust the count depending on the visibility
of variation products. However the handler incorrectly assumed
that the filter was triggered only when listing products, when
actually it's also triggered for any post type e.g. pages.
In these cases the post count was set to zero, which caused bugs.
Now the handler starts with the originally supplied posts count,
and only decrements it when a post is a product AND is not visible.