Browse Source

Separated orphan resolution so that it is Chado indpendnet

Stephen Ficklin 6 years ago
parent
commit
d3b2bb9a6b

+ 91 - 0
tripal/api/tripal.entities.api.inc

@@ -1649,3 +1649,94 @@ function tripal_update_entity($bundle_name, $values) {
 
 
 }
+
+
+/**
+ * Removes orphaned entities.
+ * 
+ * An orphaned entity can occur if the module that created the entity 
+ * unknowingly lost its underlying record in its data store.  Such a case 
+ * could happen if someone directly removed the record from the data store 
+ * outside of the module's control. This function allows each module
+ * to report if any orphans are missing for a given bundle type.
+ * 
+ * @param integer $bundle_id
+ *   The numeric ID of the bundle.
+ * @param TripalJob $job
+ *   (Optional). If this function is executed via the Tripal Jobs system then
+ *   this argument is provided.
+ */
+function tripal_unpublish_orphans(int $bundle_id, TripalJob $job = NULL) {
+  $bundlec = entity_get_controller('TripalBundle');
+  $ids = $bundlec->deleteOrphans($bundle_id, $job);
+}
+
+/**
+ * A hook for modules to delete details for orphaned entities.
+ * 
+ * This hook is called by the TripalBundleController.  Modules that create
+ * entities should use this hook to clean up entities that are orphaned. The
+ * list of $ids passed should be entities who are already known to
+ * be orphaned. These IDs are found by the TripalBundleController using the
+ * results from the hook_bundle_find_orphans() function. 
+ * 
+ * An implementation of this hook should not try to clean up the entity itself,
+ * but rather it should only clean up it's own records used to manage the 
+ * relationship between the entity and the underlying data that the
+ * module provides.
+ * 
+ * An orphaned entity can occur if the module that created the entity 
+ * unknowingly lost its underlying record in its data store.  Such a case 
+ * could happen if someone directly removed the record from the data store 
+ * outside of the module's control. This function allows each module
+ * to report if any orphans are missing for a given bundle type.
+ * 
+ * @param TripalBundle $bundle
+ *   A TripalBundle object for the bundle whose entities are orphaned.
+ * @param array $ids
+ *   A list of entity IDs known to be orphaned.
+ * @param TripalJob $job
+ *   An optional Tripal Job object. This is provided when this function is
+ *   called using the Tripal Jobs system.  Implementors of this hook can
+ *   use the addItemsHandled() function to indicate how many entities were
+ *   cleaned up.
+ * @return integer
+ *   The number of entitites that were cleaned up.
+ */
+function hook_bundle_delete_orphans(TripalBundle $bundle, array $ids, TripalJob $job = NULL) { 
+
+    // See the tripal_chado_bundle_delete_orphans() function for an example.
+    
+}
+
+/**
+ * A hook for modules to report on oprhaned entities.
+ * 
+ * An orphaned entity can occur if the module that created the entity 
+ * unknowingly lost its underlying record in its data store.  Such a case 
+ * could happen if someone directly removed the record from the data store 
+ * outside of the module's control. This function allows each module
+ * to report if any orphans are missing for a given bundle type.
+ * 
+ * @param TripalBunldle $bundle
+ *   A TripalBundle object for the bundle that should be checked for 
+ *   orphaned entities.
+ * @param bool $count
+ *   TRUE if the function should return only the number of orphaned entities.
+ *   FALSE if the function should return the list of orphned entities.
+ * @param integer $offset
+ *   For paging of entities set this to the offset within the total count.
+ * @param integer $limit
+ *   For paging of entities set this to the total number to return.
+ *   
+ * @return array|bool
+ *  If $count == FALSE then an array of all entity IDs that are orphaned. If
+ *  $count == TRUE then a single integer count value is returned.
+ */
+function hook_bundle_find_orphans(TripalBundle $bundle, bool $count = FALSE, 
+  int $offset = 0, int $limit = 10) {
+  
+    // See the tripal_chado_bundle_find_orphans() function for an example.  
+  
+}
+

+ 110 - 0
tripal/includes/TripalBundleController.inc

@@ -117,4 +117,114 @@ class TripalBundleController extends EntityAPIControllerExportable {
       return FALSE;
     }
   }
+  
+  /**
+   * Finds any orphaned entities associated with this bundle.
+   * 
+   * An orphaned entity can occur if the module that created the entity 
+   * unknowingly lost its underlying record in its data store.  Such a case 
+   * could happen if someone directly removed the record from the data store 
+   * outside of the module's control. This function allows each module
+   * to report if any orphans are missing for a given bundle type.
+   * 
+   * @param integer $id
+   *   The ID of the bundle.
+   * @param bool $count
+   *   Set to TRUE to return only a count of orphans.
+   * @param integer $offset
+   *   For paging of entities set this to the offset within the total count.
+   * @param integer $limit
+   *   For paging of entities set this to the total number to return.
+   * 
+   * @return array|integer
+   *  If $count == FALSE then an array of all entity IDs that are orphaned. If
+   *  $count == TRUE then a single integer count value is returned.
+   */
+  public function findOrphans(int $id, bool $count = FALSE, int $offset = 0, int $limit = 0) {
+    
+    // Call the hook for modules to find their orphans
+    $bundle = tripal_load_bundle_entity(['id' => $id]);
+
+    
+    // If a count is desired, we need to sum up the values returned by all.
+    if ($count) {
+      $response = module_invoke_all('bundle_find_orphans', $bundle, TRUE);
+      $sum = 0;
+      foreach ($response as $key => $value) {
+        $sum += $value;
+      }
+      return $sum;
+    }
+    // Otherwise just return the entity ID.s
+    else {
+      $response = module_invoke_all('bundle_find_orphans', $bundle, FALSE, $offset, $limit);
+      return $response;
+    }
+  }
+  
+  
+  /**
+   * Deletes orphaned entities.
+   *
+   * An orphaned entity can occur if the module that created the entity
+   * unknowingly lost its underlying record in its data store.  Such a case
+   * could happen if someone directly removed the record from the data store
+   * outside of the module's control. This function allows each module
+   * to report if any orphans are missing for a given bundle type.
+   *
+   * 
+   * @param integer $id
+   *   The ID of the bundle.
+   * @param TripalJob $job
+   *   An optional Tripal Job object. This is provided when this function is
+   *   called using the Tripal Jobs system.  
+   * @return integer
+   *   The number of entitites that were cleaned up.
+   */
+  public function deleteOrphans(int $id, TripalJob $job = NULL) {
+    
+    $num_deleted = 0;
+    $transaction = db_transaction();
+    try {
+            
+      // Get the list of entities that need cleanup.
+      $eids = $this->findOrphans($id, FALSE, 0, 0);    
+      $num_entities = count($eids);
+  
+      // Initialize the job count.
+      if ($job) {
+        $job->logMessage('Found !num orphaned entities.', ['!num' => $num_entities]);
+        $job->setInterval(1);
+        $job->setTotalItems($num_entities);
+      }    
+      
+      // If there are no entities then just return.
+      if ($num_entities == 0) {
+        return 0;
+      }    
+      
+      // Allow the modules to cleanup their records.
+      $bundle = tripal_load_bundle_entity(['id' => $id]);
+      $response = module_invoke_all('bundle_delete_orphans', $bundle, $eids, $job);
+      
+      // Now remove the entities. 
+      $num_deleted = db_delete('tripal_entity')
+        ->condition('id', $eids, 'IN')
+        ->execute();
+    }
+    catch(Exception $e) {
+      $transaction->rollback();
+      $err_msg =  "Failed to remove orphans: " . $e->getMessage();
+      if ($job) {
+        $job->logMessage($err_msg, [], 'error');
+      }
+      else {
+        drupal_set_message($erro_msg, 'error');
+      }
+      return 0;
+    }
+    
+    return $num_deleted;
+    
+  }
 }

+ 162 - 0
tripal/includes/tripal.unpublish_orphans.inc

@@ -0,0 +1,162 @@
+<?php
+
+/**
+ * Unpublish orphaned entities form.
+ *
+ * @param $form
+ * @param $form_state
+ */
+function tripal_unpublish_orphans_form($form, &$form_state) {
+
+  // Get the list of bundles.
+  $bundles = [];
+  $query = '
+    SELECT bundle_id, data_table, label
+    FROM {chado_bundle} CB
+      INNER JOIN {tripal_bundle} TB ON TB.id = CB.bundle_id
+    ORDER BY label
+  ';
+  $results = db_select('tripal_bundle', 'tb')
+    ->fields('tb')
+    ->orderBy('label')
+    ->execute();
+  while ($bundle = $results->fetchObject()) {
+    $bundles[$bundle->id] = $bundle->label;
+  }
+  drupal_set_title('Unpublish Orphaned Content');
+  
+  $form['description'] = [
+    '#type' => 'markup',
+    '#markup' => t('Sometimes published content can become orphaned. This can
+      occur if someone deletes records directly from the underlying data store
+      yet Tripal is not aware of it.  Here, you can unpublish orphaned content
+      '),
+  ];
+
+  if (empty($bundles)) {
+    $form['message'] = [
+      '#type' => 'markup',
+      '#markup' => t("No orphaned content detected."),
+    ];
+
+    return $form;
+  }
+
+  $form['bundles'] = [
+    '#title' => t('Content type'),
+    '#type' => 'select',
+    '#options' => $bundles,
+    '#empty_option' => t('-- Select a Content Type --'),
+    '#description' => t('Select a Tripal content type to find orphaned content.'),
+    '#ajax' => [
+      'callback' => 'tripal_unpublish_orphans_form_callback',
+      'wrapper' => 'bundle_info_fieldset_wrapper',
+    ],
+  ];
+
+  $form['bundle_info_fieldset'] = [
+    '#type' => 'fieldset',
+    '#title' => 'Search Results',
+    '#states' => [
+      'invisible' => [
+        'select[name="bundles"]' => ['value' => ''],
+      ],
+    ],
+    '#collapsible' => FALSE,
+    '#prefix' => '<div id="bundle_info_fieldset_wrapper">',
+    '#suffix' => '</div>',
+  ];
+
+  $selected_bundle_id = isset($form_state['values']['bundles']) ? $form_state['values']['bundles'] : NULL;
+  if ($selected_bundle_id) {
+    $bundlec = entity_get_controller('TripalBundle');
+    $count = $bundlec->findOrphans($selected_bundle_id, TRUE);
+    $name = $bundles[$selected_bundle_id];
+    $form['bundle_info_fieldset']['message'] = [
+      '#type' => 'markup',
+      '#markup' => t('<p><strong>There are ' . $count . ' orphaned entities in the ' . $name . ' bundle.</strong></p>'),
+    ];
+
+    if ($count > 0) {
+      $form['bundle_info_fieldset']['example_table'] = [
+        '#type' => 'markup',
+        '#prefix' => t('The following is a subset of the records that will be unpublished. Only a maximum of 10 records are shown.'),
+        '#markup' => tripal_chado_missing_records_table($bundlec, $selected_bundle_id),
+      ];
+
+      $form['bundle_info_fieldset']['submit'] = [
+        '#type' => 'submit',
+        '#value' => 'Unpublish Orphaned Entities',
+      ];
+    }
+  }
+
+  return $form;
+}
+
+/**
+ * Validate form entries.
+ *
+ * @param array $form
+ * @param array $form_state
+ */
+function tripal_unpublish_orphans_form_validate($form, &$form_state) {
+  $bundle_id = isset($form_state['values']['bundles']) ? $form_state['values']['bundles'] : NULL;
+
+   if (empty($bundle_id) || !is_numeric($bundle_id)) {
+     form_set_error('bundles', t('Please select a valid bundle.'));
+   }
+}
+
+/**
+ * Process unpublish form.
+ *
+ * @param array $form
+ * @param array $form_state
+ */
+function tripal_unpublish_orphans_form_submit($form, &$form_state) {
+  global $user;
+  $bundle_id = isset($form_state['values']['bundles']) ? $form_state['values']['bundles'] : NULL;
+  tripal_add_job('Delete Orphaned Entities', 'tripal_chado',
+    'tripal_unpublish_orphans', [$bundle_id], $user->uid, 10, $includes);
+
+  drupal_set_message('Job submitted');
+}
+
+
+/**
+ * Ajax callback for this form.
+ *
+ * @param array $form
+ *
+ * @return array
+ */
+function tripal_unpublish_orphans_form_callback($form) {
+  return $form['bundle_info_fieldset'];
+}
+
+/**
+ * Create a table populated with examples of records that would get deleted.
+ *
+ * @param TripalBundleController $bundlec
+ * @param int $selected_bundle_id
+ *
+ * @return string
+ */
+function tripal_chado_missing_records_table(TripalBundleController $bundlec, int $selected_bundle_id) {
+  $ids = $bundlec->findOrphans($selected_bundle_id, FALSE, 0, 10);
+  $entities = tripal_load_entity('TripalEntity', $ids);
+
+  return theme('table', [
+    'header' => [
+      'Entity ID',
+      'Title'
+    ],
+    'rows' => array_map(function ($entity) {
+      return [
+        $entity->id,
+        l($entity->title, 'bio_data/' . $entity->id),
+      ];
+    }, $entities),
+  ]);
+}

+ 5 - 1
tripal_chado/api/tripal_chado.query.api.inc

@@ -1627,7 +1627,11 @@ function chado_select_record_check_value_type(&$op, &$value, $type) {
  * Will use a chado persistent connection if it already exists.
  *
  * @param $sql
- *   The sql statement to execute
+ *   The sql statement to execute. When referencing tables in chado, table names
+ *   should be surrounded by curly brackets (e.g. { and }). If Drupal tables
+ *   need to be included in the query, surround those by sqaure brackets
+ *   (e.g. [ and ]).  This follows Drupal conventions for resolving table names.
+ *   It also supports a multi-chado installation.
  *
  * @param $args
  *   The array of arguments, with the same structure as passed to

+ 60 - 0
tripal_chado/includes/tripal_chado.bundle.inc

@@ -138,3 +138,63 @@ function tripal_chado_bundle_delete($bundle) {
     ->execute();
 }
 
+/**
+ * Implements hook_bundle_find_orphans(). 
+ *
+ */
+function tripal_chado_bundle_find_orphans($bundle, $count = FALSE, $offset = 0, $limit = 10) {
+  $chado_bundle_table = chado_get_bundle_entity_table($bundle);
+  $schema = chado_get_schema($bundle->data_table);
+  $primary_key = $schema['primary key'][0];
+  
+  $select = "CT.entity_id";
+  if ($count) {
+    $select = "count(*) as count";
+  }
+  $qlimit = '';
+  if (!$count and $limit) {
+    $qlimit = "LIMIT $limit OFFSET $offset ";
+  }
+  // Get the count 
+  $query = "
+    SELECT $select  
+    FROM [$chado_bundle_table] CT
+      LEFT JOIN {" . $bundle->data_table . "} BT ON CT.record_id = BT.$primary_key
+    WHERE BT.$primary_key IS NULL
+    $qlimit
+  ";
+
+  $results = chado_query($query);
+  if ($count) {
+   $num_orphans = (int) $results->fetchField();
+   return $num_orphans;
+  }
+  else {
+    $ids = [];
+    while ($entity_id = $results->fetchField()) {
+      $ids[] = $entity_id;
+    }
+    return $ids;
+  }
+}
+
+/**
+ * Implements hook_bundle_delete_orphans(). 
+ */
+function tripal_chado_bundle_delete_orphans(TripalBundle $bundle, array $ids, TripalJob $job = NULL) {
+  
+  $chado_bundle_table = chado_get_bundle_entity_table($bundle);
+  $schema = chado_get_schema($bundle->data_table);
+  $primary_key = $schema['primary key'][0];
+  
+  $num_deleted = db_delete($chado_bundle_table)
+    ->condition('entity_id', $ids, 'IN')
+    ->execute();
+  
+  if ($job) {
+    $job->addItemsHandled($num_deleted);
+    $job->logMessage("Removed !num orphaned entities", ['!num' => $num_deleted]);
+  }    
+   
+  return $num_deleted;
+}

+ 0 - 90
tripal_chado/includes/tripal_chado.entity.inc

@@ -362,93 +362,3 @@ function tripal_chado_entity_view_alter(&$build) {
   }
 }
 
-/**
- * Job callback to perform the deletion of orphaned entities.
- *
- * @param int $bundle_id
- *
- * @throws \Exception
- */
-function tripal_chado_delete_orphaned_entities($bundle_id) {
-  $bundle = db_query('SELECT bundle_id, data_table 
-             FROM {chado_bundle} CB WHERE bundle_id = :id',
-    [':id' => $bundle_id])->fetchObject();
-
-  $bundle_table = db_escape_table("chado_bio_data_{$bundle->bundle_id}");
-  $chado_table = db_escape_table($bundle->data_table);
-  $schema = chado_get_schema($chado_table);
-  $primary_key = is_array($schema) ? $schema['primary key'][0] : NULL;
-
-  $count = (int) db_query('SELECT count(*) FROM {' . $bundle_table . '} BT
-                        LEFT JOIN {chado.' . $chado_table . '} CT ON BT.record_id = CT.' . $primary_key . '
-                        WHERE CT.' . $primary_key . ' IS NULL')->fetchField();
-
-  if ($count === 0) {
-    print "Unable to find any orphaned entities.\n";
-    return;
-  }
-
-  print "Found $count orphaned entities.\n";
-
-  $chunk = 500;
-  $progress = 0;
-  print "Progress: {$progress}%; Memory: " . number_format(memory_get_usage()) . " bytes\r";
-
-  for ($i = 0; $i < $count; $i += $chunk) {
-    // Get a chunk of orphaned entities
-    $entities = db_query('SELECT entity_id FROM {' . $bundle_table . '} BT
-                          LEFT JOIN {chado}.' . $chado_table . ' CT ON BT.record_id = CT.' . $primary_key . '
-                          WHERE CT.' . $primary_key . ' IS NULL 
-                          ORDER BY entity_id desc
-                          LIMIT :limit', [
-      ':limit' => $chunk,
-    ])->fetchAll();
-
-    // Extract entity ids
-    $ids = array_map(function ($entity) {
-      return (int) $entity->entity_id;
-    }, $entities);
-
-    // Tell the user that selected entities are not present
-    if (empty($ids)) {
-      tripal_report_error('tripal_chado', TRIPAL_ERROR,
-        'Unable to find selected entities while attempting to delete orphaned entities.');
-      continue;
-    }
-
-    // Many warnings get printed when deleting an entity that has no
-    // associated chado record which make it really hard to follow progress.
-    // Therefore, let's suppress any output from the delete function. Errors
-    // are still detected when the delete function returns false.
-    $errors = [];
-    ob_start(function ($buffer) {
-      unset($buffer);
-    });
-    putenv('TRIPAL_SUPPRESS_ERRORS=true');
-    try {
-      // This will trigger all needed hooks
-      /** @var \TripalEntityController $controller */
-      $controller = entity_get_controller('TripalEntity');
-      if ($controller->delete($ids) === FALSE) {
-        $errors[] = "\nFailed to delete chunk {$i}/{$count}!\n";
-      }
-      $controller->resetCache($ids);
-    } catch (Exception $exception) {
-      $errors[] = "\nERROR: " . $exception->getMessage()."\n";
-    }
-    putenv('TRIPAL_SUPPRESS_ERRORS=false');
-    ob_end_clean();
-    
-    // Print collected errors if any.
-    foreach($errors as $error) {
-      print $error;
-    }
-
-    // Report progress
-    $progress = number_format(($i + $chunk) / $count * 100, 2);
-    print "Progress: {$progress}%; Memory: " . number_format(memory_get_usage()) . " bytes\r";
-  }
-
-  print "Progress: 100%; Memory: " . number_format(memory_get_usage()) . " bytes\n";
-  print "Done.\n";
-}

+ 0 - 217
tripal_chado/includes/tripal_chado.unpublish_form.inc

@@ -1,217 +0,0 @@
-<?php
-
-/**
- * Unpublish orphaned entities form.
- *
- * @param $form
- * @param $form_state
- */
-function tripal_chado_unpublish_form($form, &$form_state) {
-  $bundles = tripal_chado_get_orphaned_bundles();
-
-  drupal_set_title('Unpublish Orphaned Content');
-  
-  $form['description'] = [
-    '#type' => 'markup',
-    '#markup' => t('Sometimes published content can become orphaned. This can
-      occur if someone deletes records directly from the underlying data store
-      yet Tripal is not aware of it.  Here, you can unpublish orphaned content
-      '),
-  ];
-
-  if (empty($bundles)) {
-    $form['message'] = [
-      '#type' => 'markup',
-      '#markup' => t("No orphaned content detected."),
-    ];
-
-    return $form;
-  }
-
-  $form['bundles'] = [
-    '#title' => t('Content type'),
-    '#type' => 'select',
-    '#options' => $bundles,
-    '#empty_option' => t('-- Select a Content Type --'),
-    '#description' => t('Select a Tripal content type to find orphaned content.'),
-    '#ajax' => [
-      'callback' => 'tripal_chado_unpublish_form_callback',
-      'wrapper' => 'bundle_info_fieldset_wrapper',
-    ],
-  ];
-
-  $form['bundle_info_fieldset'] = [
-    '#type' => 'fieldset',
-    '#title' => 'Search Results',
-    '#states' => [
-      'invisible' => [
-        'select[name="bundles"]' => ['value' => ''],
-      ],
-    ],
-    '#collapsible' => FALSE,
-    '#prefix' => '<div id="bundle_info_fieldset_wrapper">',
-    '#suffix' => '</div>',
-  ];
-
-  $selected_bundle_id = isset($form_state['values']['bundles']) ? $form_state['values']['bundles'] : NULL;
-  if ($selected_bundle_id) {
-    $count = tripal_chado_get_orphaned_counts_for_bundle($selected_bundle_id);
-    $name = $bundles[$selected_bundle_id];
-    $form['bundle_info_fieldset']['message'] = [
-      '#type' => 'markup',
-      '#markup' => t('<p><strong>There are ' . $count . ' orphaned entities in the ' . $name . ' bundle.</strong></p>'),
-    ];
-
-    if ($count > 0) {
-      $form['bundle_info_fieldset']['example_table'] = [
-        '#type' => 'markup',
-        '#prefix' => t('The following is a subset of the records that will be unpublished. Only a maximum of 10 records are shown.'),
-        '#markup' => tripal_chado_missing_records_table($selected_bundle_id),
-      ];
-
-      $form['bundle_info_fieldset']['submit'] = [
-        '#type' => 'submit',
-        '#value' => 'Unpublish Orphaned Entities',
-      ];
-    }
-  }
-
-  return $form;
-}
-
-/**
- * Validate form entries.
- *
- * @param array $form
- * @param array $form_state
- */
-function tripal_chado_unpublish_form_validate($form, &$form_state) {
-  $bundle_id = isset($form_state['values']['bundles']) ? $form_state['values']['bundles'] : NULL;
-
-  if (empty($bundle_id) || !is_numeric($bundle_id)) {
-    form_set_error('bundles', t('Please select a valid bundle.'));
-  }
-}
-
-/**
- * Process unpublish form.
- *
- * @param array $form
- * @param array $form_state
- */
-function tripal_chado_unpublish_form_submit($form, &$form_state) {
-  global $user;
-  $bundle_id = isset($form_state['values']['bundles']) ? $form_state['values']['bundles'] : NULL;
-  tripal_add_job('Delete Orphaned Entities', 'tripal_chado',
-    'tripal_chado_delete_orphaned_entities', [$bundle_id], $user->uid, 10);
-
-  drupal_set_message('Job submitted successfully!');
-//   drupal_set_message('WARNING: It is expected to see a few tripal_chado errors
-//    while the job is executing. The errors can be safely ignored.', 'warning');
-}
-
-/**
- * Get a list of bundles keyed by bundle id.
- *
- * @return array
- */
-function tripal_chado_get_orphaned_bundles() {
-  $bundles = db_query('SELECT bundle_id, data_table, label 
-             FROM {chado_bundle} CB
-             INNER JOIN {tripal_bundle} TB ON TB.id = CB.bundle_id
-             ORDER BY label')->fetchAll();
-
-  $mapped = [];
-
-  foreach ($bundles as $bundle) {
-    $mapped[$bundle->bundle_id] = "{$bundle->label}";
-  }
-
-  return $mapped;
-}
-
-/**
- * Get the count of orphaned entities per bundle.
- *
- * @param int $bundle
- *
- * @return int
- */
-function tripal_chado_get_orphaned_counts_for_bundle($bundle_id) {
-  // Get the bundle
-  $bundle = db_query('SELECT bundle_id, data_table, label 
-             FROM {chado_bundle} CB
-             INNER JOIN {tripal_bundle} TB ON TB.id = CB.bundle_id
-             WHERE bundle_id = :id', [':id' => $bundle_id])->fetchObject();
-
-  $bundle_table = db_escape_table("chado_bio_data_{$bundle->bundle_id}");
-  $chado_table = db_escape_table($bundle->data_table);
-  $schema = chado_get_schema($chado_table);
-  $primary_key = is_array($schema) ? $schema['primary key'][0] : NULL;
-  $count = 0;
-
-  // Get the count
-  if ($primary_key) {
-    $count = db_query('SELECT count(*) FROM {' . $bundle_table . '} BT
-                        LEFT JOIN {chado.' . $chado_table . '} CT ON BT.record_id = CT.' . $primary_key . '
-                        WHERE CT.' . $primary_key . ' IS NULL')->fetchField();
-  }
-
-  return (int) $count;
-}
-
-/**
- * Ajax callback for this form.
- *
- * @param array $form
- *
- * @return array
- */
-function tripal_chado_unpublish_form_callback($form) {
-  return $form['bundle_info_fieldset'];
-}
-
-/**
- * Create a table populated with examples of records that would get deleted.
- *
- * @param $bundle_id
- *
- * @return string
- * @throws \Exception
- */
-function tripal_chado_missing_records_table($bundle_id) {
-  // Get the bundle
-  $bundle = db_query('SELECT bundle_id, data_table, label 
-             FROM {chado_bundle} CB
-             INNER JOIN {tripal_bundle} TB ON TB.id = CB.bundle_id
-             WHERE bundle_id = :id', [':id' => $bundle_id])->fetchObject();
-
-  $bundle_table = db_escape_table("chado_bio_data_{$bundle->bundle_id}");
-  $chado_table = db_escape_table($bundle->data_table);
-  $schema = chado_get_schema($chado_table);
-  $primary_key = is_array($schema) ? $schema['primary key'][0] : NULL;
-
-  $entities = db_query('SELECT TE.title, TE.id, BT.record_id FROM {' . $bundle_table . '} BT
-                        LEFT JOIN {chado.' . $chado_table . '} CT ON BT.record_id = CT.' . $primary_key . '
-                        LEFT JOIN {tripal_entity} TE ON TE.id = BT.entity_id
-                        WHERE CT.' . $primary_key . ' IS NULL
-                        ORDER BY BT.entity_id ASC
-                        LIMIT 10')->fetchAll();
-
-  return theme('table', [
-    'header' => [
-      'Entity ID',
-      'Title',
-      'Chado Table',
-      str_replace('_', ' ', $primary_key),
-    ],
-    'rows' => array_map(function ($entity) use ($chado_table) {
-      return [
-        $entity->id,
-        l($entity->title, 'bio_data/' . $entity->id),
-        $chado_table,
-        $entity->record_id,
-      ];
-    }, $entities),
-  ]);
-}

+ 3 - 3
tripal_chado/tripal_chado.module

@@ -217,10 +217,10 @@ function tripal_chado_menu() {
     'title' => 'Unpublish Orphaned Content',
     'description' => t('Unpublish content that has no associated records in the data store.'),
     'page callback' => 'drupal_get_form',
-    'page arguments' => ['tripal_chado_unpublish_form'],
+    'page arguments' => ['tripal_unpublish_orphans_form'],
     'access arguments' => ['administer tripal'],
-    'file' => 'includes/tripal_chado.unpublish_form.inc',
-    'file path' => drupal_get_path('module', 'tripal_chado'),
+    'file' => 'includes/tripal.unpublish_orphans.inc',
+    'file path' => drupal_get_path('module', 'tripal'),
     'type' => MENU_LOCAL_ACTION,
     'weight' => 3
   ];