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

Please consider adding back the woocommerce_product_default_attributes filter #19814

Closed
jnachtigall opened this issue Apr 22, 2018 · 3 comments
Closed

Comments

@jnachtigall
Copy link

There used to be a woocommerce_product_default_attributes filter for the default variation attributes. I used this in 2.6 for programatically selecting a certain a certain product variation. (e.g. 3 different variants, but 2 of them are sold out, so we select the only one being not sold out).

This filter does not work anymore in WC 3 since it has been move to a deprecated method that is not called any more from core:

/**
* If set, get the default attributes for a variable product.
*
* @deprecated 3.0.0
* @return array
*/
public function get_variation_default_attributes() {
wc_deprecated_function( 'WC_Product_Variable::get_variation_default_attributes', '3.0', 'WC_Product::get_default_attributes' );
return apply_filters( 'woocommerce_product_default_attributes', $this->get_default_attributes(), $this );
}

I cannot find any upgrade, migration or changelog notes on how to do handle the removal of this filter.

At Stackoverflow a user suggests to use the woocommerce_before_add_to_cart_form action to get the default variation, mangle it and then set them back to the product. This seems overly complicated and a filter should be there for this.

Would you consider adding the old woocommerce_product_default_attributes or a filter with a new name back to either public function get_variation_default_attributes():

public function get_variation_default_attribute( $attribute_name ) {
$defaults = $this->get_default_attributes();
$attribute_name = sanitize_title( $attribute_name );
return isset( $defaults[ $attribute_name ] ) ? $defaults[ $attribute_name ] : '';
}

or get_default_attributes():

/**
* Get default attributes.
*
* @since 3.0.0
* @param string $context What the value is for. Valid values are view and edit.
* @return array
*/
public function get_default_attributes( $context = 'view' ) {
return $this->get_prop( 'default_attributes', $context );
}

?

Otherwise I'll go down the action road but as said there should be a filter for this.

@lomars
Copy link

lomars commented Apr 22, 2018

You can use the filter woocommerce_product_get_default_attributes which has 2 arguments $attributes and $product.

So no need to add back woocommerce_product_default_attributes filter hook.

@jnachtigall
Copy link
Author

jnachtigall commented Apr 22, 2018

@lomars thanks so much, this works! The 2 arguments are even the same like for the old filter, so in fact it looks like it was more or less just renamed.

FWIW, I find it strange that this filter can neither be found on GitHub nor on the hooks API docs. That's and also with DDG is where I search for 1h or so without finding...

I'll change the subject, so maybe to docs could be made to include this filter, too.
Edit: No, I'll file a separate bug instead :)

@lomars
Copy link

lomars commented Apr 23, 2018

This hook can not be referenced as it's a dynamic hook

Explanations:

Since Woocommerce 3 and new introduced CRUDS setter methods, when a method is using get_prop() WC_Data method, a dynamic hook based on the object type and the method name can be used (essentially for frontend: "view" context)

See this line $value = apply_filters( $this->get_hook_prefix() . $prop, $value, $this ); in

/**
* Gets a prop for a getter method.
*
* Gets the value from either current pending changes, or the data itself.
* Context controls what happens to the value before it's returned.
*
* @since 3.0.0
* @param string $prop Name of prop to get.
* @param string $context What the value is for. Valid values are view and edit.
* @return mixed
*/
protected function get_prop( $prop, $context = 'view' ) {
$value = null;
if ( array_key_exists( $prop, $this->data ) ) {
$value = array_key_exists( $prop, $this->changes ) ? $this->changes[ $prop ] : $this->data[ $prop ];
if ( 'view' === $context ) {
$value = apply_filters( $this->get_hook_prefix() . $prop, $value, $this );
}
}
return $value;
}

and this linereturn 'woocommerce_' . $this->object_type . '_get_'; in

/**
* Prefix for action and filter hooks on data.
*
* @since 3.0.0
* @return string
*/
protected function get_hook_prefix() {
return 'woocommerce_' . $this->object_type . '_get_';
}

So the filter hook is dynamically made this way (where $this->object_type is equal to 'product'):
'woocommerce_' . $this->object_type . '_get_' . 'default_attributes'

with 2 arguments:

  • $default_attributes (the property value that replace $value)
  • $product (the class instance object that replace $this)

Related update on StackOverFlow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants