Skip to content

Support PriceSet as ManagedEntity - #35329

Open
mattwire wants to merge 2 commits into
civicrm:masterfrom
mattwire:pricesetmanaged
Open

Support PriceSet as ManagedEntity#35329
mattwire wants to merge 2 commits into
civicrm:masterfrom
mattwire:pricesetmanaged

Conversation

@mattwire

@mattwire mattwire commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

Overview

There are two issues

  1. The "extends" field maps to a component ID: Now supported via f3e5d6a
  [
    'name' => 'PriceSet_rain_forest_cup_youth_soccer_tournament',
    'entity' => 'PriceSet',
    'cleanup' => 'unused',
    'update' => 'unmodified',
    'params' => [
      'version' => 4,
      'values' => [
        'name' => 'rain_forest_cup_youth_soccer_tournament',
        'title' => E::ts('Rain-forest Cup Youth Soccer Tournament'),
        'extends' => ['1'],
        'financial_type_id.name' => 'Campaign Contribution',
        'is_quick_config' => TRUE,
      ],
      'match' => ['name'],
    ],
  ],

ie. that extends field should map to component names for portability.

  1. Export doesn't support dynamic foreign keys for export: - see Api4 - Support portable export/import for dynamic foreign keys #36338
  [
    'name' => 'PriceSet_rain_forest_cup_youth_soccer_tournament_PriceSetEntity_1',
    'entity' => 'PriceSetEntity',
    'cleanup' => 'unused',
    'update' => 'unmodified',
    'params' => [
      'version' => 4,
      'values' => [
        'entity_table' => 'civicrm_event',
        'entity_id' => 3,
        'price_set_id.name' => 'rain_forest_cup_youth_soccer_tournament',
      ],
      'match' => ['entity_table', 'entity_id'],
    ],
  ],

ie. entity_id should map to name instead of id for portability.

Before

No support for PriceSets as managed entities

After

Support for PricesSets as managed entities

Technical Details

Adds ManagedEntity trait.

Comments

@Coleman @ufundo Any thoughts on how to solve the above?

@civibot

civibot Bot commented Apr 6, 2026

Copy link
Copy Markdown

🤖 Thank you for contributing to CiviCRM! ❤️ We will need to test and review this PR. 👷

Introduction for new contributors...
  • If this is your first PR, an admin will greenlight automated testing with the command ok to test or add to whitelist.
  • A series of tests will automatically run. You can see the results at the bottom of this page (if there are any problems, it will include a link to see what went wrong).
  • A demo site will be built where anyone can try out a version of CiviCRM that includes your changes.
  • If this process needs to be repeated, an admin will issue the command test this please to rerun tests and build a new demo site.
  • Before this PR can be merged, it needs to be reviewed. Please keep in mind that reviewers are volunteers, and their response time can vary from a few hours to a few weeks depending on their availability and their knowledge of this particular part of CiviCRM.
  • A great way to speed up this process is to "trade reviews" with someone - find an open PR that you feel able to review, and leave a comment like "I'm reviewing this now, could you please review mine?" (include a link to yours). You don't have to wait for a response to get started (and you don't have to stop at one!) the more you review, the faster this process goes for everyone 😄
  • To ensure that you are credited properly in the final release notes, please add yourself to contributor-key.yml
  • For more information about contributing, see CONTRIBUTING.md.
Quick links for reviewers...

➡️ Online demo of this PR 🔗

@civibot civibot Bot added the master label Apr 6, 2026
@ufundo

ufundo commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

extends field should map to component names for portability.

I think ideally extends would just contain an entity name - that would make it more extensible, and allow you to pay for anything (Goats anyone?). That feels doable.

Export doesn't support dynamic foreign keys for export... entity_id should map to name instead of id for portability.

That seems good though complex. No guarantee in general that the targeted entity has a name. So maybe some alternate syntax would be in order?

@mattwire

Copy link
Copy Markdown
Contributor Author

extends field should map to component names for portability.

I think ideally extends would just contain an entity name - that would make it more extensible, and allow you to pay for anything (Goats anyone?). That feels doable.

Export doesn't support dynamic foreign keys for export... entity_id should map to name instead of id for portability.

That seems good though complex. No guarantee in general that the targeted entity has a name. So maybe some alternate syntax would be in order?

Personally I'd like to get rid of the dependency on PriceSet and PriceSetEntity altogether for linking entities. It's just that's how it is at the moment (for events anyway). I did start a bit of work in that direction but didn't get very far yet. The idea though would be to link PriceFieldValue (or PriceField) directly via dynamic entity_id/entity_table so you can link a price to any entity - that would work much better for things like Formbuilder payments and shopping cart.

I wanted to get what we have working for export first though. Eg. supporting dynamic foreign key for export/import would open up quite a few more entities (and the possible future "PriceFieldValueEntity") to being portable on export/import.

@ufundo

ufundo commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Personally I'd like to get rid of the dependency on PriceSet and PriceSetEntity altogether for linking entities

Yep makes sense, I think there's general support for that.

link PriceFieldValue (or PriceField) directly via dynamic entity_id/entity_table

My vote would be for Price Field from a FormBuilder perspective. I be keen to avoid entity_table if we can in favour of the entity name, so we can support table-less entities.

Not sure about the short term answer though sorry 🤔

PriceSet.extends stores a serialized array of civicrm_component ids,
which are not portable across sites. ExportAction previously excluded
all callback-based pseudoconstants from `:name` export on the
assumption their option lists are unstable, but PriceSet's
getExtendsOptions() callback returns stable component names
(CiviEvent, CiviContribute, CiviMember) that are safe to rely on.

Add an explicit 'portable' => TRUE opt-in flag that a field's
pseudoconstant can set to override the default exclusion, and use it
for PriceSet.extends so PriceSet.export() emits `extends:name`
instead of a raw, non-portable component id.
@mattwire

Copy link
Copy Markdown
Contributor Author

Once #36338 is merged this will support fully portable PriceSetEntity export/import

@colemanw

Copy link
Copy Markdown
Member

@mattwire done

@mattwire
mattwire marked this pull request as ready for review August 8, 2026 21:37
@mattwire

mattwire commented Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

@colemanw This one should be good to go if you're happy with it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants