A helper function in Commerce to determine whether a given node is a product display node (ie, has a product reference field) would be really useful, as otherwise lots of contrib modules will be reinventing the same wheel when providing node tabs etc.

#6 1588226-product-reference-node-types.patch1.12 KBbojanz
PASSED: [[SimpleTest]]: [MySQL] 3,588 pass(es). View
#3 1588226-product-reference-node-types.patch1.19 KBbojanz
PASSED: [[SimpleTest]]: [MySQL] 3,567 pass(es). View
#1 commerce_product_reference_node_types.diff1.35 KBtheo_
PASSED: [[SimpleTest]]: [MySQL] 3,567 pass(es). View


theo_’s picture

Component:Developer experience» Product reference
Status:Active» Needs review
new1.35 KB
PASSED: [[SimpleTest]]: [MySQL] 3,567 pass(es). View

Here is a function which list all node types using a product reference field (what we actually call a product display).

We provide a way to alter this list, for example if you want to hide some elements from it. Maybe we should document it ?

Damien Tournoud’s picture

Title:need a helper function is_product_display_node()» Need a helper function is_product_display_node()
Status:Needs review» Needs work

Let's make the following modifications:

+ * Returns a list of all node types that contain a product reference field.
+ *
+ * @return
+ *   An array of node types, keyed by type.
+ */
+function commerce_product_reference_node_types() {
+  $list = array();
+  $types = node_type_get_types();
+  // Get all fields of type commerce_product_reference.
+  $fields = field_read_fields(array('type' => 'commerce_product_reference'));

^ You should rather use field_info_fields() (which is cached and gives you the bundles). Just iterate over the result looking for $field['type'] == 'commerce_product_reference'.

+  foreach($fields as $field_name => $field) {

^ Code style: space after the "foreach".

+    $field = field_info_field($field_name);
+    foreach($field['bundles'] as $entity => $bundles) {

^ Same code style issue.

+      if ($entity == 'node') {

Just iterate directly over $field['bundles']['node'] instead of searching it.

+        foreach($bundles as $bundle) {
+          $list[$bundle] = $types[$bundle];
+        }
+      }
+    }
+  }
+  drupal_alter('commerce_product_reference_nodes_list_info', $list);

^ For consistency, the hook should be called hook_commerce_product_reference_node_types_alter() + the new hook needs to be documented.

bojanz’s picture

Title:Need a helper function is_product_display_node()» Add commerce_product_reference_node_types()
Status:Needs work» Needs review
new1.19 KB
PASSED: [[SimpleTest]]: [MySQL] 3,567 pass(es). View

Rerolled. Still needs documentation for the alter hook.

joachim’s picture

Looks great, but can we also have an is_product_display_node() that makes use of it please?

joachim’s picture

Also, I don't really understand the point of the alter hook. Who might want to alter that list and why?

bojanz’s picture

new1.12 KB
PASSED: [[SimpleTest]]: [MySQL] 3,588 pass(es). View

Removed the alter hook.
I don't see a point in is_product_display_node(). Just do an in_array($node->type, array_keys($whatever_this_function_returns));

rszrama’s picture

Status:Needs review» Fixed

I'm committing the patch in #6 as is. I agree, I'm not sure why we'd need an alter hook here, since we're simply reading the field info for node types with product reference fields. If someone needs alter logic, I'd presume they would just do that after calling this function.

My first hunch was that we make this more abstract with a parameter to specify the entity type, but bojanz talked me out of it. This gets the job done, but having made this specific to nodes now, I'm also not sure I'd keep out a function that could determine if a node had a product reference field or not. I'm not adding it in at this point b/c it's not a pattern we're following elsewhere in this module (e.g. look for our usage of commerce_product_line_item_types() throughout core). I can be convinced otherwise. ; )

Status:Fixed» Closed (fixed)

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