Problem/Motivation

The Image Style config entity would need to implement ThirdPartySettingsInterface if we want to allow contrib modules to store module specific metadata to the image styles. See use case in the OP.

Proposed resolution

Implement ThirdPartySettingsInterface and ThirdPartySettingsTrait in ImageStyle.

Remaining tasks

Agree approach.
Review patch.

User interface changes

None

API changes

None

Original report by @mondrake

Updated: Comment #0

Problem/Motivation

In Drupal 7, I can add an extra column to the {image_styles} table to store some metadata specific for my module, working with hook_schema_alter and db_add_field.

When the image style is loaded, the content of that column is added to the image style array and I can get/set the information I need. and this is stored back in the db.

Now, this seems not possible in D8. I can implement a mymodule_entity_presave hook and set a variable within the entity, but it does not get flushed in the config file. If I understand correctly, this is because ConfigStorageController::save requires the entity to provide the properties to be saved via ConfigEntityBase::getExportProperties, but only those declared public in the ImageStyle class (+effects) are actually saved to config (based on ReflectionClass).

So if I want to add a property to an existing class I would have to extend the ImageStyle class. But I would like to just 'hook' in the core one, not build an entirely new one.

Is there any suggestion? or am I missing some pieces?

Proposed resolution

Remaining tasks

User interface changes

API changes

Files: 
CommentFileSizeAuthor
#22 interdiff_20-22.txt567 bytesmondrake
#22 2084985-22.patch6.55 KBmondrake
PASSED: [[SimpleTest]]: [PHP 5.4 MySQL] 75,852 pass(es). View
#20 2084985-20.patch6 KBmondrake
FAILED: [[SimpleTest]]: [PHP 5.4 MySQL] 75,610 pass(es), 1 fail(s), and 0 exception(s). View

Comments

mondrake’s picture

Title: Can contrib extend core ConfigEntities (specifically, ImageStyles)? » Can contrib extend a core ConfigEntity (specifically, ImageStyle)?
Issue tags: +Configuration system, +Configurables

tagging

mondrake’s picture

tagging

mondrake’s picture

tim.plunkett’s picture

Title: Can contrib extend a core ConfigEntity (specifically, ImageStyle)? » Modules cannot add data to ConfigEntity exports without swapping out the entity class
Component: entity system » configuration entity system
Category: support » bug
Issue tags: +Needs tests

Yes, the base implementation of getExportProperties() only picks up public properties, and all of the overridden implementations call that and then loop through a specific set of protected properties.

FilterFormat and ImageStyle are unique in that they call actual methods in there, to get their plugin configuration.

Assuming this is a behavior we want to continue supporting, this is a bug.

claudiu.cristea’s picture

I can see 2 solutions:

  1. Invoking an alter hook from getExportProperties() and pass the entity (so that hook implementations will know the source) and properties list to be altered
  2. More straight (not necessary more elegant) . Adding a public property in ConfigEntityBase (as 'status' is now), acting like storage and initialized to an empty array. Modules can read/write/delete data from that storage. Being public will always be saved and restored.
swentel’s picture

So how do we make this work with the config schema's then ?

heyrocker’s picture

This feels like a won't fix to me, and personally I've always felt that using hook_schema_alter() was tantamount to hacking core. We have made the explicit decision not to implement alters anywhere in the configuration chain. I'm not a fan of creating a dumping ground for random configuration either. There is a solution now, it is solid architecturally. This seems like a won't fix.

claudiu.cristea’s picture

I only partially agree with @heyrocker, on hook_schema_alter(), but I disagree on "won't fix". Configurables should allow contrib modules to add new properties without extending the class. If 2 modules will need to add new properties to the same configurable, extending the class is not a solution.

As #1497374: Switch from Field-based storage to Entity-based storage is now in, we can take into consideration next approach:

  • Allow configurables to be fieldable as there are also entities.
  • Wait! I'm not referring to Field UI or providing UI fields like field_*.
  • New fields should be provided by modules, in code (typed data, schema, so on...).
  • The entity storage controller to use the same storage for fields as the main configurable (YAML, etc.)
mondrake’s picture

From reading #2005434: Let 3rd party modules store extra configuration in EntityDisplay, it looks to me this issue is quite related to that - here is a more general need rather than being widget/formatter specific.

In #2005434: Let 3rd party modules store extra configuration in EntityDisplay, the part of the proposed solution

So the plan would be to add an 'extra' entry, next to 'settings', in each component in EntityDisplay objects. This would act as a free for all dumping ground for 3rd party "settings". The content of this entry would need to be keyed by module name, so that we can build config schemas.

would be pretty much what I fancy for ConfigEntity objects here.

I'm sorry I can't contribute more...

tim.plunkett’s picture

Issue tags: +Configuration schema

After #2256679: Use config schema to determine which config entity properties to export regardless of whether they are public or protected went in, the schema wins out here.

I've already had needs for extending the schema from contrib in page_manager, that could be the way forward.

mondrake’s picture

Looks like #2224761-95: Add a generic way to add third party configuration on configuration entities and implement for field configuration is going to introduce a generic capability for modules to store information in ConfigEntities via the ThirdPartySettingsInterface?

mondrake’s picture

Title: Modules cannot add data to ConfigEntity exports without swapping out the entity class » Implement ThirdPartySettingsInterface in ImageStyle
Category: Bug report » Feature request
Issue summary: View changes
Status: Active » Needs review
Related issues: +#2224761: Add a generic way to add third party configuration on configuration entities and implement for field configuration
FileSize
1.51 KB
FAILED: [[SimpleTest]]: [PHP 5.4 MySQL] 75,610 pass(es), 1 fail(s), and 0 exception(s). View

Status: Needs review » Needs work

The last submitted patch, 12: 2084985-12.patch, failed testing.

mondrake’s picture

Issue tags: -Needs tests
FileSize
966 bytes
2.46 KB
PASSED: [[SimpleTest]]: [PHP 5.4 MySQL] 75,611 pass(es). View

Fixed test to check against 'third_party_settings' array elements too.

mondrake’s picture

Status: Needs work » Needs review
slashrsm’s picture

Status: Needs review » Needs work

Looks good. One comment.

+++ b/core/modules/image/src/Entity/ImageStyle.php
@@ -48,7 +50,9 @@
-class ImageStyle extends ConfigEntityBase implements ImageStyleInterface, EntityWithPluginBagsInterface {
+class ImageStyle extends ConfigEntityBase implements ImageStyleInterface, EntityWithPluginBagsInterface, ThirdPartySettingsInterface {
+
+  use ThirdPartySettingsTrait;
 

Let's make ImageStyleInterface extend ThirdPartySettingsIntefrace instead extending it directly.

mondrake’s picture

Status: Needs work » Needs review
FileSize
1.5 KB
2.92 KB
PASSED: [[SimpleTest]]: [PHP 5.4 MySQL] 75,609 pass(es). View

OK

slashrsm’s picture

Status: Needs review » Reviewed & tested by the community

RTBC if green.

Berdir’s picture

Do we need some more tests that this actually works? We can see that it shows up in the schema, so that's good. We're almost only just re-using standard functionality now, so I'm not sure.

Maybe just add or extend a kernel test that creates an image style with the API, adds a third party setting, saves and loads it again?

In #2324121: NodeType's settings array was meant to be able to store information from mutliple modules, we have an actual use case for this that I was able to convert.

mondrake’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
3.08 KB
6 KB
FAILED: [[SimpleTest]]: [PHP 5.4 MySQL] 75,610 pass(es), 1 fail(s), and 0 exception(s). View

Implemented a presave hook in image_module_test that adds an arbitrary third party setting to image style entities, and added in the image style admin test a check to see that that gets actually done.

Status: Needs review » Needs work

The last submitted patch, 20: 2084985-20.patch, failed testing.

mondrake’s picture

Status: Needs work » Needs review
FileSize
6.55 KB
PASSED: [[SimpleTest]]: [PHP 5.4 MySQL] 75,852 pass(es). View
567 bytes

Uhm... let's see

mondrake’s picture

OK, green. The problem in #20 was that 'image_module_test' was marked as a Core module, not a Testing one, so it got installed in the ConfigImportAllTest, and likely was adding third party settings to the shipped image styles that ended up in the update list. Changed the module's package from 'Core' to 'Testing' fixed that (I see other test modules have the same setting, so this maybe this was a leftover of the removal of the 'hidden' attribute in the info.yml file).

slashrsm’s picture

Status: Needs review » Reviewed & tested by the community

Looks good to me.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 73b0592 and pushed to 8.0.x. Thanks!

  • alexpott committed 73b0592 on 8.0.x
    Issue #2084985 by mondrake: Added Implement ThirdPartySettingsInterface...

Status: Fixed » Closed (fixed)

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