Fix two bugs related to the product attributes lookup table:
1. The DataRegenerator::check_can_do_lookup_table_regeneration method
was incorrectly throwing an exception when invoked with no product id
(this method will always be called without method id in order to
create the table, and by then the table will not exist).
2. The products - advanced settings page was using the wrong option
name to enable the feature.
Instead, a product selector has been added to the "Regenerate
product attributes lookup table" entry in the tools page. If a product
is selected, the tool regenerates the data only for that product;
otherwise, it regenerates the entire table.
This has forced a change on how the tools page is rendered. Now,
instead of each tool being just a description and a trigger link,
a form with GET method is rendered for each tool. The forms are rendered
first and then the tools, since HTML doesn't allow to include forms
inside tables; each button is associated to its form with a "form"
attribute.
Additionally, now the tools array returned by the woocommerce_debug_tools`
hook can have a 'selector' array with the details needed to render a
selector, which will also be part of the form for the tool.
The query to count products using the attributes lookup table for the
filter by attribute widget was adding an "AND term_ids in (...)"-type
subquery for each attribute participating in the filtering. Now at most
two such subqueries are generated, one for attributes configured for
OR type filtering and another one for the ones configured as AND; this
speeds up the query significantly when many attributes are used
simultaneously for the filtering.
The SQL query used to calculate the product counts using the product
attributes lookup table for the attribute filtering widget was missing
the JOIN parts coming from the tax meta and meta queries. The WHERE
parts however were being used, so the enitre query could fail if there
was a tax or meta query in place.
A new "Lookup data" metabox has been added to the product page
with a "Renegerate" button that regenerates the attributes lookup
data for that product.
There's a new option, 'woocommerce_attribute_lookup__direct_updates'.
When set to 'yes', updates to the lookup table are performed as soon
as the change happen; otherwise, a scheduled action will do it,
the hook name is 'woocommerce_run_product_attribute_lookup_update_callback'
(the existing hook in the DataRegenerator class is renamed to
'woocommerce_run_product_attribute_lookup_update_callback')
Also, the settings page has a new "Advanced" section with a checkbox
to control the value of that new option; the section is visible only
when the feature has been enabled via LookupDataStore::show_feature.
Lookup entries for a product or a variation are created whenever
the product is created, including untrashing and duplication
(not yet when an existing product is modified).
The default functionality within the `ThemeSupport` class has an unintended
side-effect of breaking the existing default functionality within the
`wc_get_theme_support()` function. Since the default set in the support
class is prioritized over the one given to `ThemeSupport::get_option()`,
the WordPress options set in the Customizer are never used for images.
To show the entries the following needs to be run:
wc_get_container()
->get(\Automattic\WooCommerce\Internal\ProductAttributesLookup\LookupDataStore::class)
->show_feature();
The status is displayed in the disabled "Regenerate table" button
as follows: "Filling in progress (X)", where X is the number of
products processed so far.
This class creates and fills the product attributes lookup table
from the existing products. It does so by in small chunks by using
Action Scheduler; it handles all the batches and the scheduling
by itself.
It also adds two entries to the debug tools menu:
- Initiate lookup table regeneration (deleting the existing table first)
- Enable or disable the actual usage of the lookup table
for product filtering
The first one is the only way to generate the lookup table for now
(there's no explicit data migration).
The actual filling of the table is delegated to a LookupDataStore class
that is not implemented yet, so for now the table isn't actually filled.
Also enabling/disabling the lookup table usage has no real effect yet.
Two new optional keys have been added to the tool definition array:
- 'disabled': when true the tool button will appear disabled.
- 'needs_refresh': when running a tool, by default the tool definitions
are retrieved first, then the selected tool is executed,
then the definitions previously retrieved are rendered.
When this key is true the tool definitions are retrieved again
after execution, useful for cases where the tool description
or button enable/disable state changes after the tool execution.
Also now if a tool execution throws an exception a notice will be
shown with the execption message, previously the exception
was unhandled.