tripal_chado.unpublish_form.inc 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <?php
  2. /**
  3. * Unpublish orphaned entities form.
  4. *
  5. * @param $form
  6. * @param $form_state
  7. */
  8. function tripal_chado_unpublish_form($form, &$form_state) {
  9. $bundles = tripal_chado_get_orphaned_bundles();
  10. drupal_set_title('Unpublish Orphaned Content');
  11. $form['description'] = [
  12. '#type' => 'markup',
  13. '#markup' => t('Sometimes published content can become orphaned. This can
  14. occur if someone deletes records directly from the underlying data store
  15. yet Tripal is not aware of it. Here, you can unpublish orphaned content
  16. '),
  17. ];
  18. if (empty($bundles)) {
  19. $form['message'] = [
  20. '#type' => 'markup',
  21. '#markup' => t("No orphaned content detected."),
  22. ];
  23. return $form;
  24. }
  25. $form['bundles'] = [
  26. '#title' => t('Content type'),
  27. '#type' => 'select',
  28. '#options' => $bundles,
  29. '#empty_option' => t('-- Select a Content Type --'),
  30. '#description' => t('Select a Tripal content type to find orphaned content.'),
  31. '#ajax' => [
  32. 'callback' => 'tripal_chado_unpublish_form_callback',
  33. 'wrapper' => 'bundle_info_fieldset_wrapper',
  34. ],
  35. ];
  36. $form['bundle_info_fieldset'] = [
  37. '#type' => 'fieldset',
  38. '#title' => 'Search Results',
  39. '#states' => [
  40. 'invisible' => [
  41. 'select[name="bundles"]' => ['value' => ''],
  42. ],
  43. ],
  44. '#collapsible' => FALSE,
  45. '#prefix' => '<div id="bundle_info_fieldset_wrapper">',
  46. '#suffix' => '</div>',
  47. ];
  48. $selected_bundle_id = isset($form_state['values']['bundles']) ? $form_state['values']['bundles'] : NULL;
  49. if ($selected_bundle_id) {
  50. $count = tripal_chado_get_orphaned_counts_for_bundle($selected_bundle_id);
  51. $name = $bundles[$selected_bundle_id];
  52. $form['bundle_info_fieldset']['message'] = [
  53. '#type' => 'markup',
  54. '#markup' => t('<p><strong>There are ' . $count . ' orphaned entities in the ' . $name . ' bundle.</strong></p>'),
  55. ];
  56. if ($count > 0) {
  57. $form['bundle_info_fieldset']['example_table'] = [
  58. '#type' => 'markup',
  59. '#prefix' => t('The following is a subset of the records that will be unpublished. Only a maximum of 10 records are shown.'),
  60. '#markup' => tripal_chado_missing_records_table($selected_bundle_id),
  61. ];
  62. $form['bundle_info_fieldset']['submit'] = [
  63. '#type' => 'submit',
  64. '#value' => 'Unpublish Orphaned Entities',
  65. ];
  66. }
  67. }
  68. return $form;
  69. }
  70. /**
  71. * Validate form entries.
  72. *
  73. * @param array $form
  74. * @param array $form_state
  75. */
  76. function tripal_chado_unpublish_form_validate($form, &$form_state) {
  77. $bundle_id = isset($form_state['values']['bundles']) ? $form_state['values']['bundles'] : NULL;
  78. if (empty($bundle_id) || !is_numeric($bundle_id)) {
  79. form_set_error('bundles', t('Please select a valid bundle.'));
  80. }
  81. }
  82. /**
  83. * Process unpublish form.
  84. *
  85. * @param array $form
  86. * @param array $form_state
  87. */
  88. function tripal_chado_unpublish_form_submit($form, &$form_state) {
  89. global $user;
  90. $bundle_id = isset($form_state['values']['bundles']) ? $form_state['values']['bundles'] : NULL;
  91. tripal_add_job('Delete Orphaned Entities', 'tripal_chado',
  92. 'tripal_chado_delete_orphaned_entities', [$bundle_id], $user->uid, 10);
  93. drupal_set_message('Job submitted successfully!');
  94. // drupal_set_message('WARNING: It is expected to see a few tripal_chado errors
  95. // while the job is executing. The errors can be safely ignored.', 'warning');
  96. }
  97. /**
  98. * Get a list of bundles keyed by bundle id.
  99. *
  100. * @return array
  101. */
  102. function tripal_chado_get_orphaned_bundles() {
  103. $bundles = db_query('SELECT bundle_id, data_table, label
  104. FROM {chado_bundle} CB
  105. INNER JOIN {tripal_bundle} TB ON TB.id = CB.bundle_id
  106. ORDER BY label')->fetchAll();
  107. $mapped = [];
  108. foreach ($bundles as $bundle) {
  109. $mapped[$bundle->bundle_id] = "{$bundle->label}";
  110. }
  111. return $mapped;
  112. }
  113. /**
  114. * Get the count of orphaned entities per bundle.
  115. *
  116. * @param int $bundle
  117. *
  118. * @return int
  119. */
  120. function tripal_chado_get_orphaned_counts_for_bundle($bundle_id) {
  121. // Get the bundle
  122. $bundle = db_query('SELECT bundle_id, data_table, label
  123. FROM {chado_bundle} CB
  124. INNER JOIN {tripal_bundle} TB ON TB.id = CB.bundle_id
  125. WHERE bundle_id = :id', [':id' => $bundle_id])->fetchObject();
  126. $bundle_table = db_escape_table("chado_bio_data_{$bundle->bundle_id}");
  127. $chado_table = db_escape_table($bundle->data_table);
  128. $schema = chado_get_schema($chado_table);
  129. $primary_key = is_array($schema) ? $schema['primary key'][0] : NULL;
  130. $count = 0;
  131. // Get the count
  132. if ($primary_key) {
  133. $count = db_query('SELECT count(*) FROM {' . $bundle_table . '} BT
  134. LEFT JOIN {chado.' . $chado_table . '} CT ON BT.record_id = CT.' . $primary_key . '
  135. WHERE CT.' . $primary_key . ' IS NULL')->fetchField();
  136. }
  137. return (int) $count;
  138. }
  139. /**
  140. * Ajax callback for this form.
  141. *
  142. * @param array $form
  143. *
  144. * @return array
  145. */
  146. function tripal_chado_unpublish_form_callback($form) {
  147. return $form['bundle_info_fieldset'];
  148. }
  149. /**
  150. * Create a table populated with examples of records that would get deleted.
  151. *
  152. * @param $bundle_id
  153. *
  154. * @return string
  155. * @throws \Exception
  156. */
  157. function tripal_chado_missing_records_table($bundle_id) {
  158. // Get the bundle
  159. $bundle = db_query('SELECT bundle_id, data_table, label
  160. FROM {chado_bundle} CB
  161. INNER JOIN {tripal_bundle} TB ON TB.id = CB.bundle_id
  162. WHERE bundle_id = :id', [':id' => $bundle_id])->fetchObject();
  163. $bundle_table = db_escape_table("chado_bio_data_{$bundle->bundle_id}");
  164. $chado_table = db_escape_table($bundle->data_table);
  165. $schema = chado_get_schema($chado_table);
  166. $primary_key = is_array($schema) ? $schema['primary key'][0] : NULL;
  167. $entities = db_query('SELECT TE.title, TE.id, BT.record_id FROM {' . $bundle_table . '} BT
  168. LEFT JOIN {chado.' . $chado_table . '} CT ON BT.record_id = CT.' . $primary_key . '
  169. LEFT JOIN {tripal_entity} TE ON TE.id = BT.entity_id
  170. WHERE CT.' . $primary_key . ' IS NULL
  171. ORDER BY BT.entity_id ASC
  172. LIMIT 10')->fetchAll();
  173. return theme('table', [
  174. 'header' => [
  175. 'Entity ID',
  176. 'Title',
  177. 'Chado Table',
  178. str_replace('_', ' ', $primary_key),
  179. ],
  180. 'rows' => array_map(function ($entity) use ($chado_table) {
  181. return [
  182. $entity->id,
  183. l($entity->title, 'bio_data/' . $entity->id),
  184. $chado_table,
  185. $entity->record_id,
  186. ];
  187. }, $entities),
  188. ]);
  189. }