Thanks to visit codestin.com
Credit goes to github.com

Skip to content
94 changes: 83 additions & 11 deletions tripal/src/Services/TripalPublish.php
Original file line number Diff line number Diff line change
Expand Up @@ -620,9 +620,12 @@ protected function insertEntities($matches, $titles) {
* An associative array of entities
*
* @return array
* An associative array of matched entities keyed by the
* entity_id with a value of the entity id. This is an
* associative array to take advantage of quick lookups.
* An associative array of the following format:
* [entity_id] =>
* [field delta] =>
* [property key] => [value]
* indicating which datastore records we already have values published for.
* Only required property types will be listed.
*/
protected function findFieldItems($field_name, $entities) {
$database = \Drupal::database();
Expand All @@ -635,10 +638,19 @@ protected function findFieldItems($field_name, $entities) {
$this->setItemsHandled(0);
$this->setTotalItems($num_batches);

// We also want to put the required field values in the return lookup array.
$required_property_column_names = [];
$mapping = [];
foreach (array_keys($this->required_types[$field_name]) as $key) {
$required_property_column_names[] = $field_name . '_' . $key;
$mapping[ $field_name . '_' . $key ] = $key;
}

$items = [];

$sql = "
SELECT entity_id FROM {" . $field_table . "}\n
SELECT entity_id, delta, " . implode(', ', $required_property_column_names) . "\n
FROM {" . $field_table . "}\n
WHERE bundle = :bundle\n
AND entity_id IN (:entity_ids[])\n";

Expand All @@ -652,15 +664,20 @@ protected function findFieldItems($field_name, $entities) {
$total++;
$i++;

// If we've reached the size of the batch then let's do the insert.
// If we've reached the size of the batch then let's do the query.
if ($i == $batch_size or $total == $num_matches) {
$args = [
':bundle' => $this->bundle,
':entity_ids[]' => $batch_ids
];
$results = $database->query($sql, $args);
while ($result = $results->fetchAssoc()) {
$items[$result['entity_id']] = $result['entity_id'];
// Compile required property values.
$required_property_values = [];
foreach ($mapping as $column_name => $key) {
$required_property_values[$key] = $result[$column_name];
}
$items[$result['entity_id']][$result['delta']] = $required_property_values;
}
$this->setItemsHandled($batch_num);
$batch_num++;
Expand All @@ -671,6 +688,7 @@ protected function findFieldItems($field_name, $entities) {
$batch_ids = [];
}
}

return $items;
}

Expand Down Expand Up @@ -709,7 +727,12 @@ protected function countFieldMatches(string $field_name, array $matches) : int {
* @param array $entities
* An associative array that maps entity titles to their keys.
* @param array $existing
* An associative array of entities that already have an existing item for this field.
* An associative array of the following format:
* [entity_id] =>
* [field delta] =>
* [property key] => [value]
* indicating which datastore records we already have values published for.
* Only required property types will be listed.
*/
protected function insertFieldItems($field_name, $matches, $titles, $entities, $existing) {

Expand Down Expand Up @@ -739,6 +762,11 @@ protected function insertFieldItems($field_name, $matches, $titles, $entities, $
$sql = '';
$args = [];

// In order to check if there is a published field entry for this datastore record,
// we will want to check the required property type values. Here we are getting
// that list since it is contant for this field.
$required_property_keys = array_keys($this->required_types[$field_name]);

// Iterate through the matches.
foreach ($matches as $match) {
$title = $titles[$total];
Expand All @@ -749,11 +777,19 @@ protected function insertFieldItems($field_name, $matches, $titles, $entities, $
$j++;
$total++;

// No need to add items to those that are already published.
if (array_key_exists($entity_id, $existing)) {
// Check if we have an existing entry for this particular datastore record.
if (isset($delta, $existing[$entity_id])) {
/** @debug
$required_property_values = [];
foreach ($required_property_keys as $key) {
$required_property_values[$key] = $match[$field_name][$delta][$key]['value']->getValue();
}
print "SKIPPING: Not publishing $entity_id|$delta because the required property values are already published:" . print_r($required_property_values, TRUE);
*/
continue;
}

// @debug print "-- PUBLISHING: $entity_id|$delta " . print_r($required_property_values, TRUE);
// Add items to those that are not already published.
$sql .= "(:bundle_$j, :deleted_$j, :entity_id_$j, :revision_id_$j, :langcode_$j, :delta_$j, ";
$args[":bundle_$j"] = $this->bundle;
Expand All @@ -762,10 +798,11 @@ protected function insertFieldItems($field_name, $matches, $titles, $entities, $
$args[":revision_id_$j"] = 1;
$args[":langcode_$j"] = 'und';
$args[":delta_$j"] = $delta;
foreach (array_keys($this->required_types[$field_name]) as $key) {
foreach ($required_property_keys as $key) {
$value = $match[$field_name][$delta][$key]['value']->getValue();
$placeholder = ':' . $field_name . '_'. $key . '_' . $j;
$sql .= $placeholder . ', ';
$args[$placeholder] = $match[$field_name][$delta][$key]['value']->getValue();
$args[$placeholder] = $value;
}
$sql = rtrim($sql, ", ");
$sql .= "),\n";
Expand Down Expand Up @@ -847,6 +884,24 @@ public function publish($filters = []) {
$this->logger->notice("Step 1 of 6: Find matching records... ");
$matches = $this->storage->findValues($search_values);

/* @debug matches array *
print "\nDebuggin Matches after findValues():\n";
foreach ($matches as $entity_id => $lvl1) {
foreach ($lvl1 as $field_name => $lvl2) {
if ($field_name == 'contact_project') {
foreach ($lvl2 as $delta => $lvl3) {
$debug_values = [];
foreach ($lvl3 as $key => $valueobj) {
$debug_values[$key] = $valueobj['value']->getValue();
}
print "Match $entity_id|$field_name|$delta: " . print_r($debug_values, TRUE);
}
}
}
}
* */


$this->logger->notice("Step 2 of 6: Generate page titles...");
$titles = $this->getEntityTitles($matches);

Expand All @@ -857,6 +912,23 @@ public function publish($filters = []) {
// need to publish these matches.
list($new_matches, $new_titles) = $this->excludeExisting($matches, $titles, $existing);

/* @debug matches array
print "\nDebuggin Matches after exclude existing:\n";
foreach ($matches as $entity_id => $lvl1) {
foreach ($lvl1 as $field_name => $lvl2) {
if ($field_name == 'contact_project') {
foreach ($lvl2 as $delta => $lvl3) {
$debug_values = [];
foreach ($lvl3 as $key => $valueobj) {
$debug_values[$key] = $valueobj['value']->getValue();
}
print "Match $entity_id|$field_name|$delta: " . print_r($debug_values, TRUE);
}
}
}
}
*/

// Note: entities are not tied to any storage backend. An entity
// references an "object". The information about that object
// is in the form of fields and can come from any number of data storage
Expand Down
20 changes: 19 additions & 1 deletion tripal_chado/src/Plugin/TripalStorage/ChadoStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,13 @@ public function findValues($values) {
// Build the ChadoRecords object.
$this->records = new ChadoRecords($this->field_debugger, $this->logger, $this->connection);
$this->buildChadoRecords($values, TRUE);
/** @debug
print "Checking records after buildChadoRecords():\n";
$records_array_debug = $this->records->getRecordsArray();
foreach ($records_array_debug as $table_name => $lvl1) {
print "Chado storage $table_name: " . print_r($lvl1, true);
}
*/

// Start an array to keep track of the results we find.
// Each element in this array will be a clone of the full $values array
Expand All @@ -319,6 +326,11 @@ public function findValues($values) {
// Now for each matching base record we need to select
// the ancillary tables.
foreach ($matches as $match) {
/* @debug
$records_array_debug = $match->getRecordsArray();
foreach ($records_array_debug as $table_name => $lvl1) {
print "Chado storage $table_name: " . print_r($lvl1, true);
}*/

// Clone the value array for this match.
$new_values = $this->cloneValues($values);
Expand Down Expand Up @@ -574,6 +586,8 @@ protected function buildChadoRecords($values, bool $is_find = FALSE) {
$prop_type = $this->getPropertyType($field_name, $key);
$prop_storage_settings = $prop_type->getStorageSettings();

// @debug if ($field_name == 'contact_project') { print "$field_name|$delta|$key: " . print_r($prop_storage_settings, TRUE); }

// Make sure we have an action for this property.
if (!array_key_exists('action', $prop_storage_settings)) {
$this->logger->error($this->t('Cannot store the property, @field.@prop ("@label"), in Chado. The property is missing an action in the property settings: @settings',
Expand Down Expand Up @@ -605,7 +619,6 @@ protected function buildChadoRecords($values, bool $is_find = FALSE) {
$context['delta'] = $delta;
$context['action'] = $action;


// Get the path array for this field and add any joins if any are needed.
if (array_key_exists('path', $prop_storage_settings)) {

Expand Down Expand Up @@ -830,6 +843,11 @@ protected function handleStoreLink(array $context, StoragePropertyValue $prop_va
$this->records->addColumn($elements, TRUE);

$this->records->addCondition($elements);

// If this is a find then we want to add the join as well.
if ($context['is_find']) {
$this->handleJoins($context['path_array'], $context);
}
}

/**
Expand Down
2 changes: 1 addition & 1 deletion tripal_chado/src/TripalStorage/ChadoRecords.php
Original file line number Diff line number Diff line change
Expand Up @@ -1655,7 +1655,7 @@ public function findRecords(string $base_table, string $table_alias) {
// Get informatino about this Chado table.
$chado_table = $this->getTableFromAlias($base_table, $table_alias);

// Iterate through each item of the table and perform an insert.
// Iterate through each item of the table...
$items = $this->getTableItems($base_table, $table_alias);
foreach ($items as $delta => $record) {

Expand Down