For currency codes, I've given them an 'options list' callback that returns an options array of all enabled currency codes. When one of these lists is displayed, I want to default it to the store's default currency. I made a quick pass at using 'property defaults', but that seemed like a dead end and didn't look like it was really what I wanted anyways. Is there a way to set the default value?

As a secondary question, I'm wondering if I haven't screwed up by restricting the currency code list to only enabled currencies. The problem is there could be a situation where price fields have currency codes that aren't currently enabled but were at one point in time. Commerce supports this by adding them in as an exception on the edit widget. It seems like what I need to do for the Entity module is tell it all the possible currency codes but restrict which ones actually appear in the widget to enabled currencies + other currencies in use. I suppose this would require a separate UI component?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

fago’s picture

'property defaults' is for 'property info defaults' and only useful in certain, special situations, thus it won't help you with a default value.

Where would you like your default value to be shown/used?

@options list: Indeed, just as for the field API there is currently no way to distinct between getting $options for choosing possible values and using $options to get a human readable label for something.

For a separate rules UI component, we'd need to introduce a new data type - but that's not supported for primitive types. So perhaps you can come up with a good solution to improve the options list callback for both cases? Maybe, you could use $info passed to the options list callback to detect any non-enabled currencies and add them dynamically to the options list too? $info['parent']->$property_name->value() should give you the value or throw an exception if there are no data values.

fago’s picture

Title: How should I use property defaults? Or should I be? » Support different use-cases of options list
Component: Entity Metadata - main » Core integration
Category: support » task

ok, thinking more about 'options list' they currently serve multiple purposes:
1) Get the list of allowed values when setting a new value.
2) Get a list of key/value pairs in order to determine the value for a key.

2) is a bit odd already, is options might have optgroups - what would require us to flatten the options for that case. So probably, we want to add separate support for retrieving human readable value of a property value, i.e. support a 'label callback'.

Also 1) is not always that simple, as we might have
1) a: get the list of allowed values the current user is allowed to set
1) b: get the list of allowed values that could be currently set (i.e. to be used in a rules condition or a views exposed filter)

Looking at the docs of hook_options_list() I think for the field API, 1)a needs to equal 1)b. However we have already some properties for which this is not the case, e.g. filter formats. To support that, we could just pass an additional parameter to option list callbacks, such that it is possible to treat both cases different.

rszrama’s picture

Ahh, yes, I've had cases already where I would've liked to use optgroups. That would be good. : )

fago’s picture

FileSize
6.42 KB

I took a stab on that.
When working on it, I realized that a distinction between the options used in situation 1)a and 1)b may not depend on access permissions, as else that would mean we support different options having different access levels. But that doesn't play with the property-level access callbacks, e.g. means having 'edit' access now access to change each value? This is were stuff becomes complicated, and I think we better don't get there.

However, still we have some cases where 1)a and 1)b differ, as rszrama has described or as it is the case for user roles. So I've added an additional parameter so this cases can be treated different + added a label() method determining the label based upon the options list / entity labels.

@opt-groups:
Yep, you can already use them as shown in the documentation of hook_options_list().

Patch attached. Please review and report whether it makes sense to you.

fago’s picture

Status: Active » Needs review

Status: Needs review » Needs work

The last submitted patch, entity_options_fix.patch, failed testing.

fago’s picture

Status: Needs work » Needs review
FileSize
9.18 KB

ouch.
fixed the tests + added test coverage for the label() method.

drunken monkey’s picture

Patch looks good to me. And would also help to polish a few rough edges in the Search API.

Two comments, though:
1) Wouldn't it be better to return the value itself in label(), if no option list is present? If there is no explicit label, I think the value itself can generally be seen as the label. This would make using the method even easier.
2) Could you change label() to only call value() once, not three times? Even though the method is rather small, this looks like completely unnecessary overhead, for a method that might be called heavily, e.g. when displaying entities with Views.

fago’s picture

2) makes definitely sense. I'm unsure about that as it makes it more difficult to know whether there was actually an provided label or not. Even if there is an options list, the label might not be in the options list - in which case the caller would have no way to tell if a label has been returned or just the value.

fago’s picture

FileSize
9.19 KB

Fixed 2).

drunken monkey’s picture

OK, your decision. Certainly makes sense in some cases and which case is more likely is anyone's guess.
So, looks RTBC to me. rszrama might want to comment too, though, so not changing the status.

rszrama’s picture

This approach looks good to me... I can update my currency selector accordingly. : D

Additionally, assuming this supports optgroups, I can use groups for order states / statuses.

It would be nice if the parameters for options list callbacks were documented somewhere.

rszrama’s picture

Hmm, actually, I wonder if this might be incorrect now... I just added a condition to a Rule checking the user's role, and I couldn't check for anonymous or authenticated roles. I shouldn't be able to set those roles, but I should be able to check for them. Can you see the same thing?

drunken monkey’s picture

Since the patch wasn't committed yet, the Rules module of course won't be updated, either.
Therefore it's only natural that when applying the patch, the Rules code will not work correctly with the new option list, I guess.

rszrama’s picture

Ahh, true, I guess it's just a side effect of the $op defaulting to 'edit'. : ?

fago’s picture

Status: Needs review » Fixed

>Ahh, true, I guess it's just a side effect of the $op defaulting to 'edit'. : ?
exactly.

Committed. :)

@docs: Indeed, all the callback arguments are poorly documented as of now. Unfortunately, I'm not aware of any proper way to do so, any suggestions?

drunken monkey’s picture

See an old version of search_api.api.php for a suggestion (search for "example_random_alter"). So you could just create an example function for each callback type in .api.php, outside of the "hooks" group, and reference that in the hook documentations.

fago’s picture

Nikro’s picture

Status: Fixed » Needs review

Hey, has this patch been committed? Rules new version already uses "entity_property_options_flatten()" and it's not there =\ it simply crashes.

emzemz’s picture

I'm getting the same crash - Fatal error: Call to undefined function entity_property_options_flatten() - will the patch help? Where do I put it--in which file in the rules folder? (sorry, sort of new to drupal).

fago’s picture

Status: Needs review » Fixed

Just update to the entity API dev version. I guess we should roll a new release though.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.