Creating a Link on a Product Display Node to Edit a Referenced Product
Drupal Commerce is amazing. On a recent project I had the pleasure of working with it for the first time. I understood the link between products and product displays, but there were a few things that bothered me about the relationship. This example demonstrates a simple administrative UI modification to make it easier to edit a product display node’s referenced product. Notice I said product, not products. On this site, the requirement calls for a one-to-one relationship. Every product display will only have a single product. You’ll have to make modifications (to the block’s contextual filter (to support multiple arguments) and the PHP code (to pass back multiple product ids)) if you want to show multiple referenced products.
Here’s the result of this example (take note of the “Related Product” bubble):
Now, while viewing a product display node, we have an administrative bubble that will easily let us get to the “edit product” screen for the referenced product. This solution uses Views and some simple PHP. There are a number of ways I could have done this (add a menu local task, just add markup to the template, etc.) but I wanted to do something views-based so that we can easily edit the data that shown. The requirements were pretty simple, so the solution is pretty simple.
Step 1: Setup the View
This is a normal Commerce Product view that contains a single block. The block is named “Related products” and is setup to show in “fields” mode. I’m showing the Commerce Product: SKU, Commerce Product: Edit link, and Commerce Product: title fields. I’ve set the “Access” to be role based and selected some administrative roles I created for the site, including administrator. The bold Related Product text is just a Header “Global: Text area” item. To make the information jump out at the admin a bit, I’ve set a CSS class value of ”messages warning” (without the quotes).
Those are the basics of the block. All that is left is to tell the block which product to show. In order to do this, we use a little bit of PHP to get the product_id of the product that the product display node references. To do that, you can create a new Commerce Product: Product ID contextual filter in the view. This should be set to provide a default value of PHP code:
1 2 3 |
if (arg(0) == 'node' && is_numeric(arg(1))) { return mymodule_get_product_display_product_id(arg(1)); } |
Then, in mymodule.module I’ve declared a simple function. You can just put a modified version of this code into the PHP contextual filter code box if you’d like (I’ll leave it up to you to figure out how to modify it, it’s easy); I prefer keeping as much PHP in my module files as possible. Please note that my product_reference field has the machine name of field_program_nr. You’ll need to replace that with whatever your product_reference field is called.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/** * Return the product_id for the product referenced in a product display * * @param $product_display_nid * The node id of a product display node * @return * A product id */ function mymodule_get_product_display_product_id($product_display_nid) { // NOTE: we only use one product per product display on this site. // If the product display's product reference field supported multiple values // this code would need some modifications. Also, any code that // calls this would have to support receiving multiple values. $wrapper = entity_metadata_wrapper('node', $product_display_nid); return $wrapper->field_program_nr->product_id->value(); } |
Step 2: Configure the block to show
This is simple. Simply go to the Blocks administration page and move the new block into a region (I chose to put mine at the top of “Content”). Next, configure the block to only show on your product display content type.
Note that you could define your block visibility (access-wise) through the Roles tab on the block configuration form, but I chose to do it through the view. Maybe there’s an advantage to one over the other?
Conclusion
I think that’s it. You could use the same PHP function in addition to some more code to, for example, add product edit links to the contextual links for the program display nodes too (so that when viewing a product display teaser you could click the cog wheel to get to the associated products). That’d be neat. Maybe it’s already been done…
Just in case there’s any confusion, here’s the view administration screen for this block: