Ahh, yes, a productive day is always nice. I got cracking on the product features system I brainstormed about in this thread. The end result is something that looks a lot different and is much simpler. I really like the interface, too. 
So, what is the product features system? Well, it is a handy new API that lets modules declare new product features that may be added to individual products in your catalog. These features are things like a role assignment, a file download, a gift card, etc. The API is very lightweight and simply provides an easy way for users to attach features to individual product nodes. You can see the form that gets generated when product feature modules are enabled in the screenshot attached to this post.
In this initial version, the rest of the work (like detecting this product purchase on checkout) should be handled by the module itself using the normal Ubercart hooks (like hook_order()).
Please note that product features should not be confused with:
- Product attributes which let customers specify the details of a product and then modify the price and other product info based on their choice.
- CCK fields which let administrators store custom data to the product nodes.
So, the API is very simple to use. First, there is hook_product_feature() which your module should implement to tell Ubercart that it defines a product feature type. This should return an array of product feature arrays like so:
<?php
function ucpf_example_product_feature() {
$features[] = array(
'id' => 'example',
'title' => t('Example feature'),
'callback' => 'uc_example_feature_form',
'delete' => 'uc_example_feature_delete',
'settings' => 'uc_example_feature_settings',
);
return $features;
}
?>The keys are pretty straightforward - a unique id string, a display title, a callback for the add/edit form, a delete function to call when a feature gets deleted from a product, and a settings function to define form elements for the settings page in the product configuration.
Your callback form should receive two arguments, a node object and a feature array. It should present the form elements required for your feature to be added to this project (like a set of checkboxes to specify which product role should be granted when this project is purchased). You can use the arguments passed to the callback to fill in default values when a feature is being edited. There is a helper function called uc_product_feature_form() that adds form elements for the nid, feature id, submit button, and cancel link that should be used. The submit function should also make use of the function uc_product_feature_save() to create/update the feature when it is saved. This includes providing a meaningful description to display on the features overview page (the screenshot attached below).
The delete function doesn't need to return anything... it should simply be used to delete any appropriate info from the database pertaining to that feature. A module isn't required to implement this function if it isn't necessary (for example, if a product feature saves all its data in the description field).
The settings function should simply return an array of form elements that will be added to a fieldset for that product feature. If the module doesn't require any settings, well... then this isn't necessary.
I have attached an example module that create a feature by implementing the hook and callbacks. Feel free to check it out and start using the API. I'm holding off till tomorrow to put up Alpha 7e so this can go in. Look for role purchasing in Alpha 8 thanks to Shawn. 
Go ahead and update to the development version to test it out. Post any bugs or ideas up here. And... have a nice evening. 
| Preview | Attachment | Size |
|---|---|---|
| example_product_feature.tar | 5 KB | |
![]() | features-form.jpg | 26.92 KB |








