Having a separate variable for each field that uses nodeaccess_userreference would make it possible to export settings via Features+Strongarm per-field (or per-content type, etc.), rather than only in a single batch.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

danielb’s picture

Can you elaborate further? My understanding is that using variables to store settings isn't particularly friendly no matter how you go about it (but it is particularly convenient for internal workings of this module). Do the modules you mention have some ability to export variables over programmatically or something like that? But they don't have the ability to call the settings function from this module to get and then set the setting?
Ideally any integration done with this module would use the settings function from this module to get/set settings, and not worry about how the underlying storage works.
The settings could, of course, also be properties of the field itself, but there are some awkward things about that too depending on the approach taken.

jeffschuler’s picture

Title: Separate variable for each field » Features support

I was looking for the quickest fix here, but I'm all for the best solution. I'm changing the title to reflect that.

Features is the current standard for managing site configuration. It allows you to export "features," or chunks of functionality, (which could include multiple module dependencies and configurations,) to code, so you can use them on multiple sites, and/or source-control your site configuration to push changes from development to staging to production. It also handles the import process: enabling/disabling of these features, and tracking differences between code & database.

Strongarm allows inclusion of Drupal variables in a feature.

A common way of packaging features are by content type: to include the content type itself, Views that use it, Context, Taxonomy, Permissions, etc that are relevant to that type. So, I'd like to be able to package the Node Access Node Reference (NANR) configuration for that type with it as well. I saw that NANR stores data in a variable, so I figured I'd use Strongarm to export that variable in my feature. However, I have multiple content types that use it and therefore multiple features. I'd like to include only the data relevant to a particular content type with it. That's why I was asking for one variable per instance.

However, if there's more that needs to happen for proper export/importabiliy, let's do it the right way...

Thoughts?

danielb’s picture

Is there are a features hook we can add data to during the export and another hook to read it back upon import?
If you give me that I can fill in the blanks

danielb’s picture

Status: Active » Postponed (maintainer needs more info)
cweagans’s picture

Field configuration should automatically be exported by features. Have you tried exporting a content type with a nodeaccess_nodereference field on it?

danielb’s picture

cweagens, not sure if you're aware but nodeaccess_nodereference stores it's field configuration, for all fields, in one big array which is kept in a variable_set() variable. This is because the most efficiency-critical functionality requires finding fields by the nature of their settings, not by their names, etc... The settings are probably stored by the field module's default behaviour too, but the settings page and the module's functionality will get the current settings from the variable.

I suppose a potential fix would be to check if the field module's default settings are present when the variable data is not.

jeffschuler’s picture

Project: Node access node reference » Node access user reference
Version: 7.x-1.x-dev » 7.x-3.x-dev

Whoops. Just noticed I got my wires crossed somewhere along the way.
I meant for this to be in the Node access user reference queue.

danielb’s picture

either way, same problem

danielb’s picture

Status: Postponed (maintainer needs more info) » Active
jeffschuler’s picture

Status: Active » Needs review
FileSize
0 bytes

OK, I gave this a shot. It's working in some simple export & import/revert scenarios.
Reviews appreciated! :]

jeffschuler’s picture

Oops, last diff was a whiff.
Here's the patch.

danielb’s picture

Oh man, that's a lot of code.

danielb’s picture

Any reason why something like this wouldn't work?
(ignore the whitespace fixes, just the last bit of the patch)

danielb’s picture

wtf empty patch

danielb’s picture

I committed it because it's good to have anyway I reckon
http://drupalcode.org/project/nodeaccess_userreference.git/commitdiff/59...

I do hope this solves the issue, because I can't see myself being able maintain and port to 8 all that features code.

It won't function correctly straight away though, there is a catch in that you have to at least view the field's edit form to trigger the code :/
Perhaps a way to automate this 'discovery' would be good.

danielb’s picture

Perhaps with hook_field_update_instance()

danielb’s picture

<?php

/**
 * Implements hook_field_update_instance().
 */
function nodeaccess_userreference_field_update_instance($instance, $prior_instance) {
  // Trigger discovery of settings in case this is an imported content type.
  nodeaccess_userreference_field_settings($instance['bundle'], $instance['field_name']);
}

?>

I assume this would be called upon a features content type import, and this would trigger the necessary code.

danielb’s picture

committed that too

danielb’s picture

Infact I wonder whether some stuff from the submit function could be moved to the new hook, and the 'failsafe' could be removed in favour of calling that function and setting the new data through the new hook.

danielb’s picture

If that works the submit func can be removed completely, and perhaps we can replace the form hook with a standard hook_field_instance_settings_form().

If this hook isn't invoked by features we might also have to use hook_field_create_instance()??

cweagans’s picture

because I can't see myself being able maintain and port to 8 all that features code.

"All" that code? It's like 50 lines of code, and it's a better way to do features export.

danielb’s picture

Can you elaborate on why? Do other field modules have this code? My impression is that they do not. (Not that this is a field module, but it can attach itself to the appropriate field and that should be the equivalent.)
50 lines is quite a lot. If I add 50 lines to every field module I maintain.. well that's several lots of 50 lines. To support a 3rd party contrib module that I don't use myself, that is a pretty big commitment.
I already added features support to at least one module. All it has brought is problems. There were people like you that pushed for it, but when it comes time to solve the bugs and upgrade to a new Drupal version - where are they? Gone.

cweagans’s picture

To support a 3rd party contrib module that I don't use myself, that is a pretty big commitment.

Well, that 3rd party module does a TON of stuff, and it's a pretty popular module. Personally, I won't use this module unless it supports features, but I don't have time to code it up and maintain it. In an ideal world, this module would just dump its configuration into exported field definitions, but I don't know where to even start with that one. Another approach would be to use ctools exportables: at that point, you basically get features exportability for free.

You can do what you want, but if you want people to use your module, you really should support features properly and I don't think your fixes do that. It seems like kind of a hack.

danielb’s picture

My fixes make the module work like the settings of a normal field module, which features should be able to handle.
I don't see how that is a hack, or why specific features integration would be required. Again, do other field modules do this sort of thing? I bet you use plenty of fields that don't. I don't see how ctools exportables would be suitable for this sort of thing.

danielb’s picture

In fact once I've added the proposed changes I think this module will overall be a lot less hackish than it was before.
Ultimately if the settings still won't import through Features I will, of course, look at other suggestions.

jeffschuler’s picture

Relying on the data stored in the field, itself, alleviates the need for specific features integration code and would be ideal.

Instead of adding extra logic to ensure that the data in the variable stays consistent with that of the field instances, would it be possible to change nodeaccess_userreference_field_settings() to rely on the field instance and remove the need for the variable, entirely? Was that a performance concern?

BTW, the $conditions param in node_load_multiple() is deprecated (I see it in the new nodeaccess_userreference_field_update_instance().)

danielb’s picture

Status: Needs review » Fixed

Relying on the data stored in the field, itself, alleviates the need for specific features integration code and would be ideal.

Thanks, that's what I was hoping. I do appreciate that full Features integration has more benefits like enforcing this module as a dependency, but at this stage I'm not convinced it is worth doing unless more people find that problematic. As someone who has built an export/import type module I don't think I'll be happy until Drupal core standardises how this sort of thing is done.

would it be possible to change nodeaccess_userreference_field_settings() to rely on the field instance and remove the need for the variable, entirely?

It is possible, but it is awkward because on every page load I would have to load up every field/instance on the site, iterate them and determine whether any of those are relevant to this module. I don't think I'm willing to change that as the method of duplicating the settings into the variable and then using that has proven to be quite quick, convenient, and reliable. Variables are always loaded up on page load, and this module kicks in upon a vast majority of page loads, so it makes sense.

Re: node_load_multiple() I've created a new issue.
#1568186: Reconsider the use of node_load_multiple

If there is anything more to revisit here please reopen, but yeah... I'd like to avoid overcomplicating things for myself *if possible*.

Cheers.

Status: Fixed » Closed (fixed)

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