Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Product Block Editor: Add the fundamental support and map Text and Integer attribute inputs to currently available generic blocks #2151

Conversation

eason9487
Copy link
Member

@eason9487 eason9487 commented Nov 10, 2023

Changes proposed in this Pull Request:

To be compatible with Product Block Editor, this PR adds fundamental support:

  • Extract the processing of getting the visible and hidden product types in AttributesForm as a method.
  • Convert the init_input method in AttributesForm to a static method.
  • Add methods to Admin\Input\Input for getting block config.
  • Add a new class AttributesBlock to register blocks to Product Block Editor for product attributes.

Also, it turns a few attribute inputs to support Product Block Editor first:

  • Map Text and Integer inputs to currently available generic blocks.
  • Add the block attribute 'min' to the multipack input.

Last, it adds some PHP tests and removes a few unused PHP classes or method:

  • Remove the unused method is_custom_value from SelectWithTextInput.
  • Add PHP unit tests for
    • the Admin\Input\Input class and its inheritance classes.
    • the attribute input classes under Admin\Product\Attributes\Input.
    • the AttributesForm class.
    • the AttributesBlock class.

Screenshots:

📷 Simple product

image

📷 Variation product

image

📷 The min attribute of the multipack input

image

Detailed test instructions:

📌 Prepare test environment

  1. Set up WooCommerce 8.3.0
  2. Install WooCommerce Beta Tester
  3. Go to WooCommerce > Settings > Advanced > Features. Enable the New product editor
    1
  4. Go to Tools > WCA Test Helper > Features. Make sure the product-block-editor and product-variation-management options are enabled.
    2023-11-22 14 27 50
  5. Deactivate WooCommerce Beta Tester as it's incompatible with GLA for now. See GLA inaccessible when WooCommerce Beta Tester plugin is active #2147

📌 Test the simple product type

  1. Go to edit a simple product, e.g. the Beanie with Logo imported from WC's sample products
  2. Switch to the Organization tab and find the Attributes section.
  3. Check if there is the Google Listings & Ads section under the Attributes section.
  4. Within the Google Listings & Ads section, operate the text and number fields and change their values.
  5. Click on the Update button at the top-right of the page.
  6. Refresh the page or switch back to the classical product editor to see if the changed values are saved.

📌 Test the variable and variation product type

  1. Go to edit a variable product, e.g. the Hoodie imported from WC's sample products
  2. Switch to the Organization tab and find the Attributes section.
  3. Check if there is the Google Listings & Ads section under the Attributes section.
  4. Within the Google Listings & Ads section, there should be only a brand field for now. Operate the brand field and change its value.
  5. Click on the Update button at the top-right of the page.
  6. Refresh the page or switch back to the classical product editor to see if the changed value is saved.
  7. Back to edit the same variable product with Product Block Editor.
  8. Switch to the Variations tab and find the Variations section.
  9. Click on one of the Edit links within the Variations section to go to edit a variation product.
  10. With the General tab, find the Image section.
  11. Check if there is the Google Listings & Ads section under the Image section.
  12. Repeat the similar test to verify the fields for this variation product.

📌 Test the related filters

  1. Continue to use the above variation product editing page.
  2. Filters the list of applicable product types for each attribute - "woocommerce_gla_attribute_applicable_product_types_{$attribute_id}"
    1. Confirm there is no Brand field.
    2. Add a filter to the google-listings-and-ads.php file:
      add_filter(
      	"woocommerce_gla_attribute_applicable_product_types_brand",
      	function ( array $applicable_types ) {
      		$applicable_types[] = 'variation';
      
      		return $applicable_types;
      	}
      );
    3. Refresh the page.
    4. Check if the Brand field appears.
  3. Filters the list of product types to hide for each attribute - "woocommerce_gla_attribute_hidden_product_types_{$attribute_id}"
    1. Confirm there is the Size field.
    2. Add a filter to the google-listings-and-ads.php file:
      add_filter(
      	"woocommerce_gla_attribute_hidden_product_types_size",
      	function ( array $applicable_types ) {
      		$applicable_types[] = 'variation';
      
      		return $applicable_types;
      	}
      );
    3. Refresh the page.
    4. Check if the Size field disappears.

Additional details:

The generic number block ('woocommerce/product-number-field') doesn't support verifying/limiting for entering an integer. If it's not supported afterward, then we may have to convert it to a custom block.

Changelog entry

@eason9487 eason9487 self-assigned this Nov 10, 2023
@github-actions github-actions bot added changelog: add A new feature, function, or functionality was added. type: enhancement The issue is a request for an enhancement. labels Nov 10, 2023
Copy link

codecov bot commented Nov 10, 2023

Codecov Report

Attention: 3 lines in your changes are missing coverage. Please review.

Comparison is base (abb5fcb) 58.2% compared to head (9ff6a97) 60.6%.

Additional details and impacted files

Impacted file tree graph

@@                           Coverage Diff                            @@
##             feature/support-product-block-editor   #2151     +/-   ##
========================================================================
+ Coverage                                    58.2%   60.6%   +2.4%     
- Complexity                                   4127    4144     +17     
========================================================================
  Files                                         453     453             
  Lines                                       17691   17785     +94     
========================================================================
+ Hits                                        10300   10777    +477     
+ Misses                                       7391    7008    -383     
Flag Coverage Δ
php-unit-tests 60.6% <97.5%> (+2.4%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
src/Admin/Input/Input.php 100.0% <100.0%> (+100.0%) ⬆️
src/Admin/Input/InputInterface.php 100.0% <ø> (+100.0%) ⬆️
src/Admin/Input/Integer.php 100.0% <100.0%> (+100.0%) ⬆️
src/Admin/Input/SelectWithTextInput.php 100.0% <ø> (+100.0%) ⬆️
src/Admin/Input/Text.php 100.0% <100.0%> (+100.0%) ⬆️
src/Admin/Product/Attributes/AttributesForm.php 97.2% <100.0%> (+97.2%) ⬆️
src/Admin/Product/Attributes/AttributesTab.php 0.0% <ø> (ø)
src/Admin/Product/Attributes/AttributesTrait.php 100.0% <100.0%> (ø)
.../Admin/Product/Attributes/Input/MultipackInput.php 100.0% <100.0%> (+100.0%) ⬆️
...ernal/DependencyManagement/CoreServiceProvider.php 0.0% <0.0%> (ø)
... and 1 more

... and 36 files with indirect coverage changes

@eason9487 eason9487 force-pushed the add/product-block-editor-generic-blocks branch 3 times, most recently from c91d7f0 to 406382b Compare November 22, 2023 04:00
@eason9487 eason9487 marked this pull request as ready for review November 22, 2023 07:14
@eason9487 eason9487 requested a review from a team November 22, 2023 07:14
@eason9487 eason9487 force-pushed the add/product-block-editor-generic-blocks branch 3 times, most recently from 75e1ace to 9a81d84 Compare November 28, 2023 11:05
@eason9487 eason9487 changed the title Product Block Editor: Add the fundamental support and map Text and Number attribute inputs to currently available generic blocks Product Block Editor: Add the fundamental support and map Text and Integer attribute inputs to currently available generic blocks Nov 30, 2023
Copy link
Contributor

@jorgemd24 jorgemd24 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @eason9487 for working on this, I ran some tests with simple products, and things went smoothly, except for the issue I mentioned in the comment about encountering an error with the filter.

Regarding the variation you mentioned:

Within the Google Listings & Ads section, there should be only a brand field for now. Operate the brand field and change its value.

All I'm seeing is a blank section.

image

The filters didn't seem to affect anything when I tested them with the variations.

I ran out of time today, but I am happy to debug this issue deeper if you are not able to replicate it.

* @param BlockInterface $reference_section The reference section block to add this extension's section block
*/
private function add_section( BlockInterface $reference_section ): BlockInterface {
$group = $reference_section->get_parent();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to have the type reference here: /** @var Automattic\WooCommerce\Internal\Admin\Features\ProductBlockEditor\ProductTemplates\Group */

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line will be removed by PR #2179. I added related type references to that PR in ac4abe9.

*
* @param BlockInterface $reference_section The reference section block to add this extension's section block
*/
private function add_section( BlockInterface $reference_section ): BlockInterface {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This method will be removed by this commit in PR #2179. To avoid future code conflicts, I would skip this adjustment.

return;
}

$section = $this->add_section( $attributes_section );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially this part confused me, as it seems that the method add_section would add the $attributes_section. However, it turns out the 'add' method retrieves the group from this attribute section and subsequently adds a new section. I'm thinking, perhaps renaming this function to something like 'add_section_to_group' could better clarify its purpose.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion.

This method call will be inlined by this commit in PR #2179. Instead of using $this to indirectly add group and section to template, the changed code fragment now calls to the literal callee, which I believe should not cause similar confusion as here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, yes that will remove the ambiguity!

}

$section = $this->add_section( $attributes_section );
$this->add_blocks( $section );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to my earlier comment, this could be add_blocks_to_section

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this commit of PR #2179, this line will be changed to $this->add_product_attribute_blocks( $product_attributes_section );, which should be able to clarify the purpose that it adds product attribute blocks to a section.

add_action(
"woocommerce_block_template_area_{$template_area}_after_add_block_{$block_id}",
function ( BlockInterface $attributes_section ) {
// Please note that the simple and variable product types use the same product block template 'simple-product'.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to keep the type generic using BlockInterface ? Or can we use Automattic\WooCommerce\Internal\Admin\Features\ProductBlockEditor\ProductTemplates\Section?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the definition of this hook, there are several possible incoming instances, and each of them is a class that implements BlockInterface.

image

Although in runtime it passes in a Section instance, I think it also makes sense to use the more generic type BlockInterface here. Like when I adjusted their insertion position in #2179, the type reference here didn't need to be changed.

/**
* Get the hidden and visible types of an attribute's applicable product types.
*
* @param string $attribute_type An attribute class extending AttributeInterface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe An attribute classname ....

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't understand this comment. Could you explain a bit more?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, I should have clarified this better 😅. What I meant was in the PHP doc, when we mention 'An attribute class,' strictly speaking, it refers to the actual name of that class. So, my suggestion was more along the lines of asking whether we should update this to: 'The name of the Attribute class extending AttributeInterface.'

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion! Updated all related PHP docs for the AttributesForm class by 9ff6a97.

/**
* Filters the list of product types to hide the attribute for.
*/
$hidden_product_types = apply_filters( "woocommerce_gla_attribute_hidden_product_types_{$attribute_id}", [] );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I use the filter in the following way I get an error:

add_filter(
	'woocommerce_gla_attribute_hidden_product_types_gtin',
	function ( array $applicable_types ) {
		return [ 'simple', 'variation' ];
	}
);

image

Copy link
Member Author

@eason9487 eason9487 Dec 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eason9487
Copy link
Member Author

Hi @jorgemd24, thanks for the review.

Regarding the variation you mentioned:

Within the Google Listings & Ads section, there should be only a brand field for now. Operate the brand field and change its value.

All I'm seeing is a blank section.
[...]
The filters didn't seem to affect anything when I tested them with the variations.

Could you check if WooCommerce Brands is activated? If it is, the Brand attribute input will be dynamically converted to use SelectWithTextInput, which is not yet converted in this PR. Attribute inputs that are not yet converted will be skipped, so the GL&A section in a variable product will be blank.

// TODO: Remove this check after all attribute inputs have specified a block name
if ( '' === $input->get_block_config()['blockName'] ) {
continue;
}

If this is not the cause, then I can't reproduce it, so I may need your help to find the cause.

Copy link
Contributor

@jorgemd24 jorgemd24 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @eason9487, for fixing the issue and your comments. The reason why the brands field is not displayed was because the SelectInput doesn't have a block name, therefore the code is skipping this field. For this test, I added the blockname 'woocommerce/product-text-field' and I could test the behaviour. I see that you already work on this here https://github.com/woocommerce/google-listings-and-ads/pull/2178/files#diff-eb72915300551a54c7e5237203c3878b9c0bcedb253bb0d0624e45890e7b so I am approving this PR as everything works nos smoothly.

Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog: add A new feature, function, or functionality was added. type: enhancement The issue is a request for an enhancement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants