Updated: Comment #25
Problem/Motivation
I've been implementing locked fields on Drupal Commerce entities in modules to do things like have default price fields on products and a default line item reference field on orders. This is great, because I don't want these fields to be deletable.
However, I then discovered the side effect that these fields' settings could not be altered. I figured I'd deal with that when I discovered that yea though settings can't be adjusted, the widget for the locked field can be changed. The problem is different widgets have different settings for the same field, and one widget's default settings won't make any sense to another widget.
Proposed resolution
I can see maybe three quick solutions here (I'm sure there are other options) but need input from those in the know:
- Don't allow locked field instance widgets to be changed.
- Allow settings for locked fields to be adjusted but do not allow locked fields to be deleted.
- Introduce a multi-level lock so a field could be either non-deletable but alterable or non-deletable and non-alterable.
Remaining tasks
Patch needs review.
User interface changes
As mentioned above.
API changes
None.
Original report by rszrama
| Comment | File | Size | Author |
|---|---|---|---|
| #41 | 806102-41.patch | 3.24 KB | chr.fritsch |
| #34 | Screen Shot 2017-07-12 at 16.47.22.png | 9.46 KB | wim leers |
| #24 | drupal7.field-system.test_only.806102-24.patch | 1.31 KB | rosk0 |
| #24 | drupal7.field-system.806102-24.patch | 2.4 KB | rosk0 |
Comments
Comment #1
rszrama commentedBy way of example: my product reference field comes with two default widgets, a select list or an autocomplete textfield. If I add a locked product reference field to a bundle using the select list widget, there are no settings necessary. However, if a user changed the widget to the autocomplete, they'd have no way to specify the operator for the autocomplete (i.e. the matching operator and the size of the textfield).
See hook_field_widget_settings_form().
Comment #2
yched commentedsubscribe for now
Comment #3
ksenzeeI just ran into this myself, and in my case, preventing users from changing the widget type would be fine (solution 1). It seems like it might be the easiest to implement, especially at this late date. Solution 2 wouldn't work for me. Solution 3 would be a good approach for D8.
I don't have time right this minute to roll a patch, but it shouldn't be hard. In fact, I'm going to tag this 'novice' in the wildly optimistic hope that somebody will feel like grabbing it.
Comment #4
ksenzeeOh, and if someone does grab this from the novice queue and needs help attacking it, come find me on IRC in #drupal and I will be glad to help.
Comment #6
mdm commentedThis patch removes the "Change Widget" control from the Manage Fields admin page for locked fields and displays the same message as field_ui_field_edit_form does for locked fields. Also corrects a problem where $instance['locked'] is checked. There is no locked property for $instance, it should check $field['locked'] instead.
Comment #7
mdm commentedComment #8
rszrama commentedI'm still not sure this is the best approach... it's entirely reasonable for modules to want locked fields that can't be deleted but that still allow for adjustable widgets. In my use case, I do want a Price field to always be on Products, but I want it to have an adjustable widget so the user can choose whether or not a currency selector shows up on the widget form.
Think about it this way... why lock a Field at all? You need the data to be there. You don't really care how it gets in there (was it selected with a select list or a radio button?), just that the data is there. Thus... locking the Widget in the same way as the Field doesn't make sense to me.
I guess I should've been more clear that number 2 or 3 would've been the preferred approach. Regardless, I'll review your patch and tweak as necessary later today or tomorrow instead of just being a Negative Nancy.
Comment #9
mdm commentedIn this patch I'm trying to do #2 as suggested by rszrama.
Comment #11
miklOh, this is a bit of a gotcha if you want to have programmable fields…
Comment #12
googletorp commented#8
For a project like Drupal commerce, that creates a foundation you can build upon, I can understand if you want all the configurability possible, In this case it makes good sense to want to allow settings to be changeable.
However, some times you really want to opposite, create a configured field that cannot be changed. An example of this, could be a field that uses an option widget. By locked and requiring this value, you know that it'll always be there and have a sensible value. For a product in a shop, this could be used to configure it's current storage status, you could allow values like.
• In stock
• Out of stock
• Out of production
If an admin changed the configuration, and renamed the values saved in the db or added some new ones, it would break things if you needed special theming or actions happening for products with a select status. It would really be nice to be able to create fields that truely are locked, set in stone and know nothing can change it.
Comment #13
mrfelton commentedJust found this issue after working on a solution for #922570: Allow gallery content to be public or private where my problem is that Media Gallery provides some fields which are locked, but I need to be able to apply field level permissions to those fields. The Field Permissions module won't work on locked fields, because there is no field settings form or form handling for these locked fields at all.
The patch that I came up with in http://drupal.org/node/922570#comment-5163720 is possibly rather crude, but it allows individual fields to be unlocked.
It would be better if the Drupal Core provided more control around what exactly 'locked' means - allowing developers to choose the level of locked-ness that they want for their fields.
Comment #14
kevster commentedI have just come across this problem when using the schemaorg module. I want to add the price tag to the product commerce price field under product types but it wont let me:
Notice: Undefined index: instance in schemaorg_ui_form_field_ui_field_edit_form_alter() (line 62 of /mnt/web/www/sites/xxx/html/sites/all/modules/contrib/schemaorg/schemaorg_ui/schemaorg_ui.module).
The field Price is locked and cannot be edited.
This does need the option to unlock or allow updates such as this example to the field?
Thx..
Comment #15
q00p commentedI'm in a similar boat. I've got a site up with Drupal Commerce (using the Commerce Kickstart installation profile).
I have a scenario where I want the Price field to only be viewable by Authenticated users. I installed the Field Permissions module, which allows you to change field visibility and permissions.
However, the module won't work because the field is locked: "The field Price is locked and cannot be edited" :/
Have yet to try mrfelton's patch, but since he says it's crude I'd rather try other workarounds first.
Comment #16
q00p commentedProblem solved for me, as I went into the database and changed the locked attribute of the price field to 0.
I found this post in the Drupal Commerce forums by dannyd:
"... For unlock price you can go to your database -> table field_config -> edit commerce_price entry to change "locked" from 1 (enabled) to 0 (disabled)
Then you can have your field price unlock for edit it and use field permissions module to made it hide to anonymous users.
Also you can lock it again after doing the change!!.
Please D8 developers, add this kind of permisions in core! :P"
---
Thread found here.
Comment #17
sja1 commentedAnother problem locking fields can cause is making it impossible to modify the original text of a field label. I came across this also while configuring Commerce Kickstart. I switched the default language post installation, and (to give just one example) need to change the original text of the field "commerce_order_total" (admin/commerce/config/order/fields/commerce_order_total). The original text is "Order total" but I need to change the original to Spanish, and have the translated text be in Englsh. If I click on the Translate tab, and then hit "edit" for the "Spanish (source)" language, I get the following error:
"The field Order total is locked and cannot be edited."
Comment #18
sja1 commentedFound a quick and dirty workaround, in case it helps someone. I tried the solution in comment 16 above, but it didn't work for me. What did work was to hack (temporarily) /modules/field_ui/field_ui.admin.inc and comment out lines 1811 to 1817, which check for the lock. This allowed me to edit the locked field and perform the translation. You can then remove the hack.
Comment #19
bohemier commented#16 worked for me after clearing the cache
Comment #20
Maestro232 commentedSO, I think I have a related issue. I apologize if it's not. Somehow, after an upgrade (I think that's when the problem popped up) of Drupal Commerce Kickstart, I found that a term reference on my product content type seemed to get hosed. I had a product category field which was a term reference to a product category vocabulary. I first noticed the problem when my views were coming up with "an invalid vocabulary has been selected" messages. When I tried to create a new product I noticed that the product category field only had "None" for an option. When I tried to modify the settings of the field in the content type (even using the hacks described above), I can't actually change the vocabulary the field points to. It's pointed to the "Blog Category" vocabulary for some reason and grayed out so I can't change it with a message that says, "There is data for this field in the database. The field settings can no longer be changed."
I don't really think the problem is with the vocabulary since even though it says it's pointed to "Blog Category" that doesn't seem to be the case because I don't see the terms in that vocabulary when I go to create a new product. I guess I'm not 100% positive that if I could unlock those settings and change the vocabulary my problem would go away, but it would be worth trying if anyone knows how I can change the vocabulary in the term reference field settings. The field is not locked and I tried the field_ui file hack and that doesn't help.
Comment #21
rosk0While developing CRM Core we faced with same problem - users should be able to change instance settings of locked fields. While #3 @rszrama solution is preferred way of dealing with locked fields and I hope it would be implemented in D8 I created new version of patch for #2 solution - permit to change settings of instance of locked fields.
Comment #22
rosk0Comment #23
andypostActually the fix makes sense but this functionality is not covered with tests, so it needs work, but I leave status NR for others.
The same D8 does now so probably it's good to go.
Comment #24
rosk0Patch with test.
Comment #25
PavanL commentedComment #26
bisonbleu commentedHad a similar issue to #17, unable to translate the Price label (field commerce_price).
My use case: Installed Drupal in French and I'm running Commerce. I'm using entity_translation & title to translate Product types and Product Displays.
When I tried to translate the Price label of a product type, the UI showed Price as the original text and gave me the chance to translate it to English. Translate an English string to English? Hm... that's not the first time I encounter this weird issue in Commerce and elsewhere.
#16 helps fix this issue - thanks @q00p ! As suggested, I unlocked the field, changed Price to Prix (its French equivalent). Then locked back the field before translating it at
admin/commerce/products/types/product/fields/commerce_price/translateNote: when you're in the field_config table, make sure you search for field_name = 'commerce_price'. There are 'commerce_price' entries in the 'type' column. That's not what you're looking for!
Haven't tried the patch in #24 yet.
Comment #27
pacifigraphic commented#24 is running for me. Thank You!
Comment #28
rajeevkPatch of #24 is working fine.
Comment #29
andypostComment #30
gábor hojtsyCore media now faces this problem in #2831936: Add "File" MediaSource plugin.
Comment #31
vijaycs85It's a good idea to update issue summary of this issue and #2274433: Do not allow to alter Locked field via UI to talk in same language. Probably a table of all elements/properties involved and what are all allow to change and not allowed to change
Comment #32
joshmiller#24 for Drupal 7 is RTBC but I don't want to hijack a D8 effort.
Comment #33
effulgentsia commentedComment #34
wim leersLet's get this back on track.
This is what happens in Field UI when you lock a
FieldStorageConfigentity (source: #2831936-98: Add "File" MediaSource plugin).\Drupal\field\Entity\FieldStorageConfig—\Drupal\field\Entity\FieldConfigdoes not even have the concept of locking!This is caused by
\Drupal\field_ui\FieldConfigListBuilder::buildRow()doing this:Rather than just some operations becoming inaccessible.
I tried to find the root cause. This code was introduced in #1963340: Change field UI so that adding a field is a separate task, but there it was just moved from the now-removed
core/modules/field_ui/src/FieldOverview.php. This was also touched in #2287727: Rename FieldConfig to FieldStorageConfig (D8 alpha 14), #1953408: Remove ArrayAccess BC layer from field config entities (D8 alpha 4), #1549506: Edit and delete links should be hidden for locked fields (D8 alpha 1) and finally, #1792600: Refactor field_ui so common behavior for fields and display overview screens are extracted (October 5, 2012). Except, nope, that's also not the one, because it just moved it fromfield_ui_field_overview()in the now-removedfield_ui.admin.inc. Before that … drumrolls … it was #516138: Move CCK HEAD in core — the patch that brought CCK to core! That very first commit includes:So it seems this was simply an oversight from August 19, 2009?
Comment #35
wim leersApparently a Media-specific issue for this was created at #2894270: Users unable to add an extension to the file upload field. Cross-posted #34 there.
Comment #36
chr.fritschNot sure if "Storage settings" should be hidden. Thats basically editing of the storage settings. In FieldStorageConfigAccessControlHandler just removing of a FieldStorage is prevented by locking, editing is still fine.
Comment #37
wim leersI'm having trouble understanding #36. I think perhaps where you wrote , you meant to write ?
Comment #38
chr.fritschWhat i meant:
The form behind the "Storage settings" link, is basically a form to edit FieldStorageConfig. Because of FieldStorageConfigAccessControlHandler, editing a FieldStorageConfig is permitted on locked fields.
So we have multiple options:
Then we should check the edit access for the FieldStorage in FieldConfigListBuilder::getDefaultOperations
Question is, should FieldConfigListBuilder::getDefaultOperations show a "Delete" button or not? Deletion of FieldConfig is permitted on locked fields, just not on FieldStorage.
Comment #39
wim leersOh, you're totally right! Only deleting locked config is forbidden apparently.
That seems like a straight bug. So I think #38.1 makes sense.
You're right in #38.2 too, in principle, but I don't think table rows' operations automatically get access checking applied to the URLs they point to. Which is why
\Drupal\field_ui\FieldConfigListBuilder::getDefaultOperations()exists. So this is a necessary work-around.IOW: I don't think #38.1 and #38.2 are alternative options, I think they're complementary. They both are problems. But #38.1 is the bigger problem.
Comment #41
chr.fritschI think it should be something like this.
I also added the permission to the router, because the settings were still accessible by url.
Comment #43
joachim commentedIs #2274433: Do not allow to alter Locked field via UI maybe a duplicate?
Comment #53
smustgrave commentedThis does appear to be a duplicate of https://www.drupal.org/project/drupal/issues/2274433
Left a comment on the other ticket for credit to be moved over.
Comment #54
quietone commentedMoving credit to #2274433: Do not allow to alter Locked field via UI.
Comment #55
lauriiiThis is certainly touching similar aspects with #2274433: Do not allow to alter Locked field via UI but this isn't a duplicate. The other issue is about the field storage configuration, this is about the field widget settings.