2

I am trying to alter the way commerce_file module shows the product file in the Product display. Actually it is shown to all users owning sort of administrative permissions (such as administer commerce_file or administer commerce_field type). Its format is:

label: file.pdf

This code is driven by the

commerce_file_field_access($op, $field, $entity_type, $entity = NULL, $account = NULL)

function in commerce_file module itself, it seems.

I would like with my_module to override this behavior to make the file visible to users that doesn't own those permissions but that have already bought the digital product and had license granted for that, but really don't know how to. (I already succeeded in disabling the add to chart button)

I am able to define if the user/buyer already bought it, but just cannot override the module access conditions to apply my rules. I already tried defining another function like my_module_field_access(), but it doesn't seem to work...

How is it possible to override the hook_field_access() function already defined in commerce_file module?

As an alternative I was minding to replicate/copy that field and render it again without that access control, just in the defined conditions I define in my module. To do that I tried with a my_module_preprocess_node() function, but didn't succeeded. The new $vars['elements'] is not rendered ...

I hope have been sufficiently clear. really any advice (on the best approach & way) would be very welcome. Wasted so many hours on this ... yet. Thanks so much

1 Answer 1

1

hook_field_access() implementations are invoked by field_access() using the following code:

  foreach (module_implements('field_access') as $module) {
    $function = $module . '_field_access';
    $access = $function($op, $field, $entity_type, $entity, $account);
    if ($access === FALSE) {
      return FALSE;
    }
  }

The hook is not invoked for the module implementing that field, but for any module implementing the hook.

If you want to override what done by commerce_file_field_access(), you just implement hook_field_access() in your own module.
As field_access() immediately returns FALSE when a hook_field_access() implementation returns FALSE, you can only override what returned from commerce_file_field_access() if your hook is executed before commerce_file_field_access(). This means that your module, when it is installed, should alter the weight associated with it, and assign it a lower value than the value assigned to the Commerce File module. The following is an example of hook_install() implementation for achieving that; it is similar to the code executed in block_install().

function mymodule_install() {
  db_update('system')
    ->fields(array('weight' => -5))
    ->condition('name', 'mymodule')
    ->execute();
}

The same can be done in hook_update_N().

Any value lower than 5 actually works, as the Commerce File module uses the following code:

/**
 * Implements hook_install().
 */
function commerce_file_install() {
  // Make module weight heavier than field module
  db_query("UPDATE {system} SET weight = 5 WHERE name = 'commerce_file'");
}

The alternative of changing the weight of your module, which would influence when every hook in your module is executed, is to alter the order used for that specific hook implementations, using code similar to the following one.

function mymodule_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'field_access') {
    // Move mymodule_field_access() to the top of the list. module_implements()
    // iterates through $implementations with a foreach loop which PHP iterates
    // in the order that the items were added, so to move an item to the end of
    // the array, we remove it and then add it.
    $group = $implementations['mymodule'];
    unset($implementations['mymodule']);
    $implementations = array('mymodule' => $group) + $implementations;
  }
}
2
  • Ok, thanks ... and I realized why it didn't work for me. The API doc says " If no module returns FALSE, the operation is allowed.". So, as the commerce_file_field_access() returns FALSE, how to override its result?
    – itamair
    Commented Feb 23, 2012 at 18:28
  • I have updated my answer.
    – avpaderno
    Commented Feb 23, 2012 at 19:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.