Problem/Motivation
The config entity machine_name
(also called id
) property may form a part of a config entity's file name -- the yml file that represents an instance of the entity. The file name length is limited to 255 characters by most operating systems. To be safe, we limit the name to 250 characters and leave 5 for a file extension. The file name is potentially composed of 5 pieces. Each part may therefore only consume 20% of the available characters, so the config entity machine_name
can therefore only be a maximum of 50 characters long.
Here is an example of an config entity machine_name
in Core using the entity.view_mode.node.teaser.yml
config entity.
id: node.teaser
label: Teaser
status: true
cache: true
targetEntityType: node
Proposed resolution
We need to look at imposing limits at install, import and the through the UI. Machine names for config entities are often created through forms.
Config entities with a machine_name
greater than 50 characters must:
- Fail installation
- Prevent the owning module from installing as well.
This will keep contrib authors from creating config entity types with config_prefix greater than 50 characters and discourage adding them to D.O.
When creating a config entity, such as a field or a content type, through a form with a machine_name
candidate greater than 50 characters, the form must:
- Fail validation
- Inform the user that the machine_name must be short than 50 characters.
Some config entities already impose machine_name
length limits. Check for existing constants while working on this issue.
User interface changes
machine_name
fields will fail validation if they contain a string greater than 50 characters.
API changes
Perhaps additional methods.
Original report by @jessebeach
Comment | File | Size | Author |
---|---|---|---|
#45 | taxonomy.png | 80.8 KB | jessebeach |
#42 | config-2220757-42-interdiff.txt | 3.42 KB | zserno |
#42 | config-2220757-42.patch | 5.58 KB | zserno |
#37 | interdiff.txt | 2.14 KB | xjm |
#37 | config-2220757-37.patch | 5.24 KB | xjm |
Comments
Comment #1
BerdirThe problem here and in other related issues (like comment bundle length) are composite ID's where the ID is not the same as the machine name entered in the UI.
The ID of a field instance is created based on 3 parts: $this->entity_type . '.' . $this->bundle . '.' . $this->field->name
If you want to limit the ID of config entities, and have an entity type and a bundle on that with each 25 characters, it's impossible to create fields for that.
Bundles are usually fairly short, but comment is an interesting example where the bundle consists of the field id of it's comment field.
So for example he comment_body field instance on nodes has an ID like this: "comment.node__comment.comment_body". Those are all very short, so it's only 34 characters, but let's assume that we're going to add a comment field named comment to a commerce_order_line_item entity. That's already 54 and too long. We could shorten the field name to just body, because we no longer need to separate it from the node body field by name, which would work for this, but with the default field prefix, you get "comment.commerce_order_line_item__comment.field_", which is 48 characters, which leaves users exactly 2 characters to name their fields on comments on commerce order line items ;)
Comment #2
alexpottRe #1 I don't think we should apply a general rule - also I took this issue to be proposing that in the case of fields and their instances it'd be the
$this->field->name
part that would be limited. As this is already limited to 32 nothing needs to be done for fields / field instances.Comment #3
xjmIsn't this a duplicate of #1191434: Standardize entity type is a maximum of 32 characters (not 64 or 128)? The point of declaring it at the entity level is that it then propagates down to all child classes, including config entities and fields.
Comment #4
BerdirIt's related but not the same.
*Some* config entities have ID's that relate to entity types or bundles, but most don't. This is about a default verification/validation for everyhting.. views, actions, blocks... as I understand it?
#2: Hm, maybe, but that can't be enforced globally/by default then as we don't know which property we need to check (instead of just id()) and it would theoretically mean that a field instance ID could be 132 characters (or at least 3 * 32, if we limit bundle and entity_type to 32 as proposed by @xjm there).
Comment #5
jhodgdonBut... Looking at #2120003: [META] Create sensible limits for the maximum length of configuration object filename components, the point is to limit **each part (between the "."s) of the configuration file name** to 50 characters, not the whole thing.
So in the case of a field instance config or field config, you have:
(field config): field .field .node .field_my_entered_machine_name
(instance config): field .instance .node .article .field_my_entered_machine_name
Each part of this is limited to 50 characters:
- The module name "field", OK.
- The config ID, "field" or "instance", OK.
- The entity type, "node", OK.
- The entity bundle, "article", OK.
- The field's machine name, which we need to limit to 50 characters (including the "field_" which the Field UI module puts in there).
Comment #1 here seems to think that the whole thing node.body or node.article.body is limited to 50 characters, but that is not the proposal. The proposal is (unless I am mistaken) that the machine name itself -- the part that the user enters + the standard field_ prefix from Field UI, needs to be 50 characters or less. This doesn't sound like a huge problem?
Comment #6
BerdirOk, yes, that seems fine, I misunderstood that a bit.
We have a different understanding of name component I guess. For me, the config entity ID is a single component, because it can not be separated further. That it uses "." is basically an implementation detail, it could also be a different character. And nothing is stopping me from creating an entity type that has 4 parts that make up the ID?
So for the way I understand it, we should say that a config entity ID must not be longer than 149 characters (shouldn't we include the "." in our calculations too, 50 always includes the "." as well?) , and is free to split that up.
Which means that for a field_instance, we know that with with the decision in #1709960: declare a maximum length for entity and bundle machine names to limit entity type and bundle to 32, entity_type.bundle. can have a maximal length of 32 + 1 + 32 + 1 => 66, Which means that field names could be up to 84 characters long and we'd still be good. And since they are already limited to 32 characters, we're all set and someone could even come up with a config entity that is entity_type.bundle.field_name.whatever ;)
And a view could have a machine name that is up to 149 characters long.
Comment #7
jessebeach CreditAttribution: jessebeach commentedClosed as a duplicate of #1862600: Entity type names/IDs are not properly namespaced by owner (e.g., taxonomy.term vs. taxonomy_term).
Comment #8
jessebeach CreditAttribution: jessebeach commentedDerp, sorry, wrong issue. #7 was incorrect.
Comment #9
jessebeach CreditAttribution: jessebeach commentedKeep in mind that if entity and bundle machine names have an upper limit of 50 chars each, that leaves 28 chars for the instance name in the following classes:
EntityViewDisplay
EntityFormDisplay
FieldInstanceConfig
The instance name being something like "default" or "teaser" or "search_result".
Field names are also then limited to 28 characters as well.
#1709960: declare a maximum length for entity and bundle machine names
Comment #10
xjmRe. #4, right, sorry, I was confusing two issues. So this issue is about specifying a maximum length for
Config::$id
, e.g. in:views.view.frontpage.yml
field.instance.node.article.default.yml
entity.form_display.node.article.default.yml
The following parts would be the part capped for this issue in each case:
frontpage
node.article.default
node.article.default
The goal of #1862600: Entity type names/IDs are not properly namespaced by owner (e.g., taxonomy.term vs. taxonomy_term) is to change it so that the entity type ID becomes a compound of
module_name.what_we_currently_call_config_prefix_in_the_entity_but_not_the_method_name
, e.g.views.view
ornode.article
. Ifmodule_name
is capped at 50 (as it is in HEAD), then we would need the combination ofwhat_we_currently_call_config_prefix_in_the_entity_but_not_the_method_name
and the ID to add up to 200 characters max. If we makewhat_we_currently_call_config_prefix_in_the_entity_but_not_the_method_name
32 characters as proposed in #2120003: [META] Create sensible limits for the maximum length of configuration object filename components, then that would leave168166 characters for the rest. (Edit: taking into account the dots.)Comment #11
xjmComment #12
alexpottComment #13
jessebeach CreditAttribution: jessebeach commented200 seems like a typo here. Is that what you meant xjm?
Comment #14
drifter CreditAttribution: drifter commentedSo if I understand correctly, a config name can be up to 250 characters, of which 50 characters is the module name, 32 characters is the prefix, and the rest (up to 166 characters) is the ID (sometimes called machine name).
I'm new to this so this could be the wrong place to put this, but here's a check that raises an exception before saving the config entity if the limit is exceeded.
Comment #15
drifter CreditAttribution: drifter commentedAlso trying to add a test for this...
Comment #16
Karol Haltenberger CreditAttribution: Karol Haltenberger commentedTesting for Config entity "prefix" length (83) and "id" length (166) in ConfigStorageController::save()
This patch includes the changes from 2220757-15.patch
Comment #17
BerdirNot sure if we want to copy the documentation from ConfigBase. Maybe just add a @see to it?
The description should also not be wider than 80 characters.
Just discussed this with @alexpott and we wondering who and where this check should live.
We thought that it makes more sense that ConfigStorageController::save() does this because this is a storage limitation. For example, @timplunkett right now is working on a key value storage which has only allows 128 character long ID's, so he needs a different check. And someone could experiment with a different storage controller in contrib that allows longer ID's.
We have a separate issue for this, this shouldn't be checked here.
Actually we have the check here as well? Why both? :)
Comment nitpick: Should have a space after //, start with an uppercase character, not be longer than 180 characters and end with a ".".
Comment #18
Karol Haltenberger CreditAttribution: Karol Haltenberger commentedconfig entity id length checking in ConfigStorageController::save() only
checking is based on an optional constant MAX_ID_LENGTH introduced to the storage service (see Drupal\Core\Config\FileStorage)
Comments / descriptions updated
Comment #19
BerdirSorry, maybe I wasn't clear. The constant has to live in the config entity storage controller, *not* in the config storage. I was talking about a different entity storage controller, not a different config storage. So the dynamic stuff there isn't necessary, just use your own constant.
This also needs a test, you should probably extend ConfigEntityTest::testCRUD().
Comment #21
Karol Haltenberger CreditAttribution: Karol Haltenberger commentedConstant moved back and value corrected
As for the tests, I'll try to write some as soon as I learn how :)
Comment #22
BerdirI'm in the Margrathea room in Szeged if you're here, happy to show you how to get started with tests.
Comment #23
Karol Haltenberger CreditAttribution: Karol Haltenberger commentedFirst attempt at tests.
Comment #24
jessebeach CreditAttribution: jessebeach commentedPlease remove this extra line in your next patch.
Comment #25
jessebeach CreditAttribution: jessebeach commentedMention this defaults to 8 characters in a comment.
The message should just be: "config_test entity with ID length @len was saved."
Maybe just pass through the Exception message?
Use the message: "config_test entity with ID length @len was saved."
Just pass through the exception message.
"config_test entity saved successfully despite having an ID that exceeds the maximum length of @len"
Although I love enthusiasm, too, let's keep the messages fairly neutral :)
"config_test entity with an id length of @len failed to save"
Replace instances of
@len
in my comments with the length of the ID that was generated.Looking good so far!
Comment #26
Karol Haltenberger CreditAttribution: Karol Haltenberger commented- Updated the patch with the recent class name changes.
- Changed the comments to the proposed ones, with some modifications.
- Using the actual constant from the class rather than fixed lengths.
Comment #27
xjmThanks @Karol Haltenberger! Can you be sure to post interdiffs when you create new patches? See: https://drupal.org/documentation/git/interdiff
Comment #28
BerdirWe just discussed that this should use the exception class from #2220739: Custom block types can be 64 characters long but the custom_block only supports 32. (ConfigEntityIdLengthException)
Note that #1709960: declare a maximum length for entity and bundle machine names will add and use the same exception class, but we can continue by adding it to both issues, then we can simply re-roll the other one once one is in. No need to postpone issues.
Comment #29
jessebeach CreditAttribution: jessebeach commentedComment #30
xjmI'll reroll to add it, plus clean up the following nitpicky things. :)
Wrapping a bit early.
Needs periods at the end of sentences. Also could be wrapped into one comment.
Usually we don't use abbreviations like "idlen". Also, this variable does not store an ID length, it stores a configuration entity object, so we could call it something like
$test_config_entity
.Also need periods. :)
Comment #31
xjmAttached uses the new exception class and cleans up the things in #30. I also tested it manually!
Installing with default config with a too-long ID
Trying to synch config with a too-long ID
Comment #32
xjmLet's actually attach the patch, eh?
Comment #33
xjmComment #34
xjm@berdir said he was +1 with the current version of the patch, and suggested we let @jessebeach take a final look at it as well.
Comment #35
jessebeach CreditAttribution: jessebeach commentedI'll have a look tonight/tomorrow morning after the closing dinner event. I'd like to do some manual testing as well as code review.
Comment #36
xjmI found another couple non-blocking coding standards cleanups.
Should start with a verb.
There should be spaces around the
+
.Grammatically, there should either be a comma after @max, or no comma after @len.
Patched patch inc.
Comment #37
xjmComment #38
BerdirIn the config prefix issue (ConfigEntityType::PREFIX_LENGTH), we added an explanation why the prefix is limited to 83, we should probably do the inverse here.
Would be easier to just make 8 or something else explicit instead of a long explanation....
Comment #39
zserno CreditAttribution: zserno commentedAccording to https://drupal.org/node/1709960#comment-8631877, please put ConfigEntityIdLengthException in Drupal\Core\Config\Entity\Exception. See latest patch there as an example.
Comment #40
jessebeach CreditAttribution: jessebeach commentedRerolling and addressing feedback now.
Comment #41
jessebeach CreditAttribution: jessebeach commentedzserno has been working on this. I'm unassigning myself.
Comment #42
zserno CreditAttribution: zserno commentedThanks jessebeach. Rerolled according to feedback at #38 and #39.
Comment #43
xjm+1, all that looks good to me.
Comment #44
jessebeach CreditAttribution: jessebeach commentedSo, setting
FieldConfig::NAME_MAX_LENGTH
to some high value, like 10000, let's me create a field name with more than the intended limit of 32 chars. Saving the field yields a database error:Now, changing the
FieldConfig
NAME_MAX_LENGTH
constant is a contrived scenario. I don't think we need to code to this case in this issue. I just wanted to mention that becauseFieldConfig
does its table creation inpre-save
, we never get to the bundle checks we introduce in this issue.Comment #45
jessebeach CreditAttribution: jessebeach commentedA taxonomy vocabulary with a 170 character name throws our
\Core\Config\Entity\Exception\ConfigEntityIdLengthException
.Yay!
Comment #46
jessebeach CreditAttribution: jessebeach commentedAlright, the clicky-clicky testing has convinced me.
Comment #47
webchickThat is the weirdest, most arbitrary limit for something I've ever seen, and leaves another weird, arbitrary limit (83) to work with. And unfortunately, the docs that are here do not in any way help me to understand how we arrived at that limit, and why we shouldn't change that some day in the future to something less weird and arbitrary.
Asking around in IRC, xjm said that this was arrived at because 50 was reserved for the module name, 32 for the entity ID, plus a dot. I think we could really do to explain this to people because I can't be the only one who sees this and goes "Huh?!"
xjm spun off a sub-issue for this, as well as to unify the docs of these constants more generally: #2229931: Improve documentation related to config object filename component limits
The only other very minor thing here is we don't generally abbreviate things so all the places that are @len should be @length. Fixed on commit.
Committed and pushed to 8.x. Thanks!