Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Civi/Api4/Generic/ExportAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,10 @@ private function shouldUsePseudoconstant(string $entityType, array $field) {
return TRUE;
}
// Options generated by a callback function tend to be stable,
// and the :name property may not be reliable. Use plain value.
if ($daoName && !empty($daoName::getSupportedFields()[$field['name']]['pseudoconstant']['callback'])) {
// and the :name property may not be reliable. Use plain value,
// unless the field has explicitly opted in as portable.
$pseudoconstant = $daoName ? ($daoName::getSupportedFields()[$field['name']]['pseudoconstant'] ?? []) : [];
if (!empty($pseudoconstant['callback']) && empty($pseudoconstant['portable'])) {
return FALSE;
}
// Options with numeric keys probably refer to auto-increment keys
Expand Down
1 change: 1 addition & 0 deletions Civi/Api4/PriceField.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@
*/
class PriceField extends Generic\DAOEntity {
use Generic\Traits\SortableEntity;
use Generic\Traits\ManagedEntity;

}
1 change: 1 addition & 0 deletions Civi/Api4/PriceFieldValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@
*/
class PriceFieldValue extends Generic\DAOEntity {
use Generic\Traits\SortableEntity;
use Generic\Traits\ManagedEntity;

}
1 change: 1 addition & 0 deletions Civi/Api4/PriceSet.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@
* @package Civi\Api4
*/
class PriceSet extends Generic\DAOEntity {
use Generic\Traits\ManagedEntity;

}
1 change: 1 addition & 0 deletions Civi/Api4/PriceSetEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@
* @package Civi\Api4
*/
class PriceSetEntity extends Generic\DAOEntity {
use Generic\Traits\ManagedEntity;

}
2 changes: 2 additions & 0 deletions schema/Price/PriceSet.entityType.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@
'serialize' => CRM_Core_DAO::SERIALIZE_SEPARATOR_BOOKEND,
'pseudoconstant' => [
'callback' => ['CRM_Price_BAO_PriceSet', 'getExtendsOptions'],
// Set portable=TRUE if pseudoconstants in callback don't change across different sites
'portable' => TRUE,
],
],
'financial_type_id' => [
Expand Down
38 changes: 38 additions & 0 deletions tests/phpunit/api/v4/Entity/ManagedEntityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
use Civi\Api4\Navigation;
use Civi\Api4\OptionGroup;
use Civi\Api4\OptionValue;
use Civi\Api4\PriceSet;
use Civi\Api4\SavedSearch;
use Civi\Test;
use Civi\Test\CiviEnvBuilder;
Expand Down Expand Up @@ -736,6 +737,43 @@ public function testExportAndCreateGroup(): void {
$this->assertGreaterThan($original['id'], $created['id']);
}

/**
* PriceSet.extends stores a serialized array of civicrm_component ids, which are not
* portable across sites. Exporting should use the `:name` pseudoconstant (component
* names like `CiviEvent`) instead, and importing should resolve those names back to
* the correct local component ids.
*
* @throws \CRM_Core_Exception
*/
public function testExportAndCreatePriceSetWithPortableExtends(): void {
$original = PriceSet::create(FALSE)
->addValue('name', 'my_managed_price_set')
->addValue('title', 'My Managed Price Set')
->addValue('extends:name', ['CiviEvent'])
->addValue('financial_type_id:name', 'Donation')
->execute()->single();

$export = PriceSet::export(FALSE)
->setId($original['id'])
->execute()->single();

// The export should use the portable `:name` syntax, not the raw (non-portable) component id.
$this->assertEquals(['CiviEvent'], $export['params']['values']['extends:name']);
$this->assertArrayNotHasKey('extends', $export['params']['values']);

PriceSet::delete(FALSE)->addWhere('id', '=', $original['id'])->execute();

$this->_managedEntities = [
['module' => 'civicrm'] + $export,
];
CRM_Core_ManagedEntities::singleton(TRUE)->reconcile();

$created = $this->getTestRecord('PriceSet', ['name' => $original['name']]);

$this->assertEquals($original['extends'], $created['extends']);
$this->assertEquals($original['financial_type_id'], $created['financial_type_id']);
}

/**
* Tests a scenario where a record may already exist and we want to make it a managed entity.
*
Expand Down