The assertion is useless (the constant is already tested a few Lines
above), and it was failing in PHP 8 because 'auto' < 2 is evaluated
as false, while it's evaluated to true in PHP 7.
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'.
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.
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.
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.
Now, if there are filters present the logic is as follows:
- For multiple filtering values of the same attribute:
the product is visible if there's at least one variation
that has one of the filtering values associated to the attribute,
or if there's at least one variation having the attribute
with a value of "Any".
- For filtering by more than one attribute:
the product is visible if there's at least one variation that
is visible for ALL the attributes according to the above rule.
Note that this is irrespective of the type of logic configured for
the filter (OR or AND).
Two adjustments were needed:
- Adjust the count even when there's no nav filtering in the query.
This is necessary to present the proper products count.
even when the woocommerce_product_is_visible filter is used.
- Account for the case where $GLOBALS['wp_query']->posts
returns objects instead of ids (for example when viewing
a product page).