Allow modules to define plan record tables that create relationships to multiple records.

This commit is contained in:
Michael Stenta 2020-05-06 13:31:09 -04:00
parent ce25c3c73f
commit 974da4e5d9
3 changed files with 85 additions and 19 deletions

View File

@ -35,15 +35,30 @@
* - entity_pk: The column name of the entity type's primary key.
* - table: The table that links the record to the plan.
* - field: The column name in the table that links to the record's PK.
* - required: It's possible for one table to maintain multiple
* relationships so this key indicates that this relationship is
* required. This defaults to TRUE, so generally you only need to set it
* to FALSE if you are adding an optional relationship to an existing
* table. This affects how the farm_plan_link_record() and
* farm_plan_link_record() functions work, and whether they will
* insert/delete rows or update them instead.
*/
function hook_farm_plan_record_relationships() {
return array(
'my_plan_asset' => array(
'label' => t('Asset'),
'entity_type' => 'farm_asset',
'entity_pk' => 'id',
'table' => 'my_plan_asset',
'field' => 'asset_id',
),
'my_plan_log' => array(
'label' => t('Log'),
'entity_type' => 'log',
'entity_pk' => 'id',
'table' => 'my_plan_log',
'table' => 'my_plan_asset',
'field' => 'log_id',
'required' => FALSE,
),
);
}

View File

@ -752,8 +752,12 @@ function farm_plan_linked_records($record_type, $plan_id) {
* The plan ID.
* @param int $record_id
* The record ID.
* @param array $primary_record
* If this is not the primary/required record type in the table, the primary
* record key/value to needed for updating the existing record.
* For example: array('asset_id' => 5)
*/
function farm_plan_link_record($record_type, $plan_id, $record_id) {
function farm_plan_link_record($record_type, $plan_id, $record_id, $primary_record = array()) {
// First, delete any existing link.
farm_plan_unlink_record($record_type, $plan_id, $record_id);
@ -770,12 +774,31 @@ function farm_plan_link_record($record_type, $plan_id, $record_id) {
$table = $relationships[$record_type]['table'];
$field = $relationships[$record_type]['field'];
// Create a new relationship record.
$record = array(
'plan_id' => $plan_id,
$field => $record_id,
);
drupal_write_record($table, $record);
// If this record type is not required, and a primary key/value is provided,
// then update the existing relationship row.
if ($relationships[$record_type]['required'] === FALSE && !empty($primary_record)) {
$primary_record_key = key($primary_record);
$primary_record_id = current($primary_record);
$record = array(
'plan_id' => $plan_id,
$primary_record_key => $primary_record_id,
$field => $record_id,
);
$primary_keys = array(
'plan_id',
$primary_record_key,
);
drupal_write_record($table, $record, $primary_keys);
}
// Otherwise create a new relationship row.
else {
$record = array(
'plan_id' => $plan_id,
$field => $record_id,
);
drupal_write_record($table, $record);
}
}
/**
@ -802,11 +825,25 @@ function farm_plan_unlink_record($record_type, $plan_id, $record_id) {
$table = $relationships[$record_type]['table'];
$field = $relationships[$record_type]['field'];
// Delete the relationship.
$query = db_delete($table);
$query->condition('plan_id', $plan_id);
$query->condition($field, $record_id);
$query->execute();
// If this record type is not required, simply update the relationship row in
// the database to remove reference to the record.
if ($relationships[$record_type]['required'] === FALSE) {
$query = db_update($table);
$query->fields(array(
$field => NULL,
));
$query->condition('plan_id', $plan_id);
$query->condition($field, $record_id);
$query->execute();
}
// Otherwise, delete the whole relationship row.
else {
$query = db_delete($table);
$query->condition('plan_id', $plan_id);
$query->condition($field, $record_id);
$query->execute();
}
}
/**
@ -817,7 +854,19 @@ function farm_plan_unlink_record($record_type, $plan_id, $record_id) {
* used to store relationships. See farm_plan.api.php.
*/
function farm_plan_record_relationships() {
return module_invoke_all('farm_plan_record_relationships');
// Ask modules for relationships.
$relationships = module_invoke_all('farm_plan_record_relationships');
// Set default values.
foreach ($relationships as &$relationship) {
if (!isset($relationship['required'])) {
$relationship['required'] = TRUE;
}
}
// Return the relationships.
return $relationships;
}
/**

View File

@ -437,10 +437,10 @@ function farm_plan_record_unlink_form($form, &$form_state, $plan, $record_type,
}
}
// If the constraint type is "table_reference" and the table is
// "farm_plan_asset", skip it.
// If the constraint type is "table_reference" and it's the table that
// defines the relationship between the plan and asset, skip it.
if (!empty($constraint['constraint']) && !empty($constraint['table'])) {
if ($constraint['constraint'] == 'table_reference' && $constraint['table'] == 'farm_plan_asset') {
if ($constraint['constraint'] == 'table_reference' && $constraint['table'] == $relationships[$record_type]['table']) {
continue;
}
}
@ -457,9 +457,11 @@ function farm_plan_record_unlink_form($form, &$form_state, $plan, $record_type,
foreach ($log_constraints as $constraint) {
// If the constraint type is "table_reference" and the table is
// "farm_plan_log", skip it.
// "farm_plan_log" OR the same table as the asset relationship table
// (indicating that it is a single table that references multiple
// different types of records), skip it.
if (!empty($constraint['constraint']) && !empty($constraint['table'])) {
if ($constraint['constraint'] == 'table_reference' && $constraint['table'] == 'farm_plan_log') {
if ($constraint['constraint'] == 'table_reference' && in_array($constraint['table'], array('farm_plan_log', $relationships[$record_type]['table']))) {
continue;
}
}