Created
October 6, 2016 13:32
-
-
Save Renrhaf/3b94fd5fd538f92722a3a612ed28b1ef to your computer and use it in GitHub Desktop.
AFOUND-850
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 2c123e42a8abcd09d6509c2b8975cb9cb52740f1 Mon Sep 17 00:00:00 2001 | |
From: Renrhaf <[email protected]> | |
Date: Thu, 6 Oct 2016 15:28:55 +0200 | |
Subject: [PATCH] AFOUND-850: adding a cleaning module | |
--- | |
modules/custom/foundation_cleaning/README.md | 9 + | |
.../foundation_cleaning.admin.inc | 191 +++++++++++++++++++++ | |
.../foundation_cleaning/foundation_cleaning.info | 8 + | |
.../foundation_cleaning/foundation_cleaning.module | 73 ++++++++ | |
4 files changed, 281 insertions(+) | |
create mode 100644 modules/custom/foundation_cleaning/README.md | |
create mode 100644 modules/custom/foundation_cleaning/foundation_cleaning.admin.inc | |
create mode 100644 modules/custom/foundation_cleaning/foundation_cleaning.info | |
create mode 100644 modules/custom/foundation_cleaning/foundation_cleaning.module | |
diff --git a/modules/custom/foundation_cleaning/README.md b/modules/custom/foundation_cleaning/README.md | |
new file mode 100644 | |
index 0000000..e42f816 | |
--- /dev/null | |
+++ b/modules/custom/foundation_cleaning/README.md | |
@@ -0,0 +1,9 @@ | |
+ARTE Foundation Cleaning | |
+======================== | |
+ | |
+This modules offers helpers and drush commands for cleaning purposes. | |
+ | |
+Configuration | |
+------------- | |
+ | |
+Enable the module and go to page admin/config/cleaning to see possible actions. | |
\ No newline at end of file | |
diff --git a/modules/custom/foundation_cleaning/foundation_cleaning.admin.inc b/modules/custom/foundation_cleaning/foundation_cleaning.admin.inc | |
new file mode 100644 | |
index 0000000..e4d643e | |
--- /dev/null | |
+++ b/modules/custom/foundation_cleaning/foundation_cleaning.admin.inc | |
@@ -0,0 +1,191 @@ | |
+<?php | |
+ | |
+/** | |
+ * @file | |
+ * Admin page callbacks for the Foundation Cleaning module. | |
+ */ | |
+ | |
+/** | |
+ * Display a form to fix atoms with duplicated base id. | |
+ */ | |
+function foundation_cleaning_opa_duplicates_form($form) { | |
+ $header = array('Base id', 'Atoms'); | |
+ $rows = array(); | |
+ | |
+ $base_ids = _foundation_cleaning_opa_duplicated(); | |
+ foreach ($base_ids as $base_id) { | |
+ $row = array($base_id, null); | |
+ // Load atoms with this base id. | |
+ $sids = scald_search(array('base_id' => $base_id)); | |
+ if (!empty($sids)) { | |
+ $atoms = scald_atom_load_multiple($sids); | |
+ $texts = array(); | |
+ foreach ($atoms as $atom) { | |
+ $atom_link = l($atom->title, 'atom/' . $atom->sid); | |
+ // Load nodes linked to this atom. | |
+ $nids = scald_index_get_nodes($atom->sid); | |
+ if (!empty($nids)) { | |
+ $nodes = node_load_multiple($nids); | |
+ $texts2 = array(); | |
+ foreach ($nodes as $node) { | |
+ $texts2[] = l($node->title, 'node/' . $node->nid); | |
+ } | |
+ $atom_link .= ' (nodes: ' . join(' / ', $texts2) . ')'; | |
+ } | |
+ $texts[] = $atom_link; | |
+ } | |
+ $row[1] = join('<br/>', $texts); | |
+ } | |
+ $rows[] = $row; | |
+ } | |
+ | |
+ if (!empty($rows)) { | |
+ $form['count'] = array( | |
+ '#type' => 'markup', | |
+ '#markup' => '<h3>Summary</h3>' . t('There are @count base ids with more than one atom.', array('@count' => count($base_ids))) . '<br/>' | |
+ ); | |
+ | |
+ $form['submit'] = array( | |
+ '#type' => 'submit', | |
+ '#value' => t('Resolve all duplicates') | |
+ ); | |
+ | |
+ $form['details'] = array( | |
+ '#type' => 'markup', | |
+ '#markup' => '<h3>Details</h3>' . theme('table', array('header' => $header, 'rows' => $rows)) | |
+ ); | |
+ } else { | |
+ $form['count'] = array( | |
+ '#type' => 'markup', | |
+ '#markup' => '<h3>Summary</h3>' . t('There are no duplicates.') | |
+ ); | |
+ } | |
+ | |
+ return $form; | |
+} | |
+ | |
+/** | |
+ * Submit callback for "foundation_cleaning_opa_duplicates_form" | |
+ */ | |
+function foundation_cleaning_opa_duplicates_form_submit() { | |
+ $operations = array(); | |
+ | |
+ $base_ids = _foundation_cleaning_opa_duplicated(); | |
+ foreach ($base_ids as $base_id) { | |
+ $operations[] = array('foundation_cleaning_opa_fix_duplicates', array($base_id)); | |
+ } | |
+ | |
+ $batch = array( | |
+ 'operations' => $operations, | |
+ 'finished' => 'foundation_cleaning_opa_fix_duplicates_finished', | |
+ 'title' => t('Resolve duplicates of "base_id" for scald atoms'), | |
+ 'file' => drupal_get_path('module', 'foundation_cleaning') . '/foundation_cleaning.admin.inc', | |
+ ); | |
+ | |
+ batch_set($batch); | |
+} | |
+ | |
+/** | |
+ * Batch action to resolve conflict with duplicated base id. | |
+ */ | |
+function foundation_cleaning_opa_fix_duplicates($base_id, &$context) { | |
+ $data = array(); | |
+ | |
+ // Loads atoms and nodes. | |
+ $sids = scald_search(array('base_id' => $base_id)); | |
+ if (!empty($sids)) { | |
+ $atoms = scald_atom_load_multiple($sids); | |
+ foreach ($atoms as $atom) { | |
+ $data[$atom->sid] = array('atom' => $atom, 'nodes' => array()); | |
+ $nids = scald_index_get_nodes($atom->sid); | |
+ if (!empty($nids)) { | |
+ $nodes = node_load_multiple($nids); | |
+ $data[$atom->sid]['nodes'] = $nodes; | |
+ } | |
+ } | |
+ } | |
+ | |
+ // Detect which atom to keep. | |
+ $sid_to_keep = null; | |
+ foreach ($data as $sid => $atom_data) { | |
+ if (count($atom_data['nodes']) > 0 || is_null($sid_to_keep)) { | |
+ $sid_to_keep = $sid; // Keep newest atom with nodes. | |
+ } | |
+ } | |
+ | |
+ // Delete other atoms and replace them by the one we keep. | |
+ foreach ($data as $sid => $atom_data) { | |
+ if ($sid == $sid_to_keep) { | |
+ continue; // Do not modify the atom and nodes linked to the one to keep. | |
+ } | |
+ | |
+ // Fix nodes using the atom which will be deleted. | |
+ foreach ($atom_data['nodes'] as $node) { | |
+ $instances = field_info_instances('node', $node->type); | |
+ foreach ($instances as $field_name => $instance) { | |
+ $field = field_info_field($field_name); | |
+ $analyse_field = FALSE; | |
+ | |
+ // Detect atom in reference fields. | |
+ if ($field['module'] == 'atom_reference' && $field['storage']['type'] == 'field_sql_storage') { | |
+ $analyse_field = TRUE; | |
+ } | |
+ | |
+ // Detect atoms embedded in text fields. | |
+ if ((isset($instance['settings']['mee_enabled']) && $instance['settings']['mee_enabled']) | |
+ || (isset($instance['settings']['dnd_enabled']) && $instance['settings']['dnd_enabled']) | |
+ ) { | |
+ $analyse_field = TRUE; | |
+ } | |
+ | |
+ // Fix atoms used in this field. | |
+ if ($analyse_field) { | |
+ foreach (field_available_languages('node', $field) as $langcode) { | |
+ $values = field_get_items('node', $node, $field_name, $langcode); | |
+ if (!empty($values)) { | |
+ foreach ($values as $i => $value) { | |
+ // Atom references. | |
+ if (isset($value['sid']) && $value['sid'] == $sid) { | |
+ $node->{$field_name}[$langcode][$i]['sid'] = $sid_to_keep; | |
+ } | |
+ | |
+ // Text scanning. | |
+ if (isset($value['value'])) { | |
+ $text = str_replace($sid, $sid_to_keep, $value['value']); | |
+ $node->{$field_name}[$langcode][$i]['value'] = $text; | |
+ $node->{$field_name}[$langcode][$i]['safe_value'] = $text; | |
+ | |
+ if (isset($value['summary']) && strlen($value['summary']) > 0) { | |
+ $summary = str_replace($sid, $sid_to_keep, $value['summary']); | |
+ $node->{$field_name}[$langcode][$i]['summary'] = $summary; | |
+ $node->{$field_name}[$langcode][$i]['safe_summary'] = $summary; | |
+ } | |
+ } | |
+ } | |
+ } | |
+ } | |
+ } | |
+ } | |
+ | |
+ node_save($node); | |
+ watchdog('foundation_cleaning', 'Modified node @nid', array('@nid' => $node->nid)); | |
+ } | |
+ | |
+ scald_atom_delete($sid); | |
+ watchdog('foundation_cleaning', 'Deleted atom @sid', array('@sid' => $sid)); | |
+ } | |
+ | |
+ $context['results'][] = $base_id; | |
+ $context['message'] = t('Updated atoms with base ID @id', array('@id' => $base_id)); | |
+} | |
+ | |
+/** | |
+ * Batch finish callback for opa duplicates fix. | |
+ */ | |
+function foundation_cleaning_opa_fix_duplicates_finished($success, $results, $operations) { | |
+ if ($success) { | |
+ drupal_set_message(t('Fixed @amount duplicates base ids.', array('@amount' => count($results)))); | |
+ } else { | |
+ drupal_set_message(t('Error while trying to fix duplicates...'), 'error'); | |
+ } | |
+} | |
\ No newline at end of file | |
diff --git a/modules/custom/foundation_cleaning/foundation_cleaning.info b/modules/custom/foundation_cleaning/foundation_cleaning.info | |
new file mode 100644 | |
index 0000000..a264c29 | |
--- /dev/null | |
+++ b/modules/custom/foundation_cleaning/foundation_cleaning.info | |
@@ -0,0 +1,8 @@ | |
+name = ARTE Foundation Cleaning | |
+description = Cleaning helpers for our platforms | |
+core = 7.x | |
+package = ARTE Foundation | |
+version = 7.x-1.0 | |
+ | |
+dependencies[] = scald | |
+dependencies[] = scald_index | |
\ No newline at end of file | |
diff --git a/modules/custom/foundation_cleaning/foundation_cleaning.module b/modules/custom/foundation_cleaning/foundation_cleaning.module | |
new file mode 100644 | |
index 0000000..4329821 | |
--- /dev/null | |
+++ b/modules/custom/foundation_cleaning/foundation_cleaning.module | |
@@ -0,0 +1,73 @@ | |
+<?php | |
+ | |
+/** | |
+ * Foundation cleaning module. | |
+ */ | |
+ | |
+/** | |
+ * Implements hook_menu(). | |
+ */ | |
+function foundation_cleaning_menu() { | |
+ $items = array(); | |
+ | |
+ $items['admin/config/cleaning'] = array( | |
+ 'title' => 'ARTE Cleaning', | |
+ 'description' => 'Administer ARTE Cleaning', | |
+ 'page callback' => '_foundation_cleaning_admin_page', | |
+ 'access arguments' => array('access administration pages') | |
+ ); | |
+ | |
+ $items['admin/config/cleaning/opa/duplicates'] = array( | |
+ 'title' => 'ARTE OPA cleaning duplicates', | |
+ 'description' => 'ARTE OPA cleaning atoms with duplicates base id (em)', | |
+ 'page callback' => 'drupal_get_form', | |
+ 'page arguments' => array('foundation_cleaning_opa_duplicates_form'), | |
+ 'access arguments' => array('administer foundation cleaning settings'), | |
+ 'file' => 'foundation_cleaning.admin.inc', | |
+ 'type' => MENU_NORMAL_ITEM, | |
+ ); | |
+ | |
+ return $items; | |
+} | |
+ | |
+/** | |
+ * Menu callback for cleaning admin page. | |
+ */ | |
+function _foundation_cleaning_admin_page() { | |
+ module_load_include('admin.inc', 'system'); | |
+ return system_admin_menu_block_page(); | |
+} | |
+ | |
+/** | |
+ * Implements hook_permission(). | |
+ */ | |
+function foundation_cleaning_permission() { | |
+ return array( | |
+ 'administer foundation cleaning settings' => array( | |
+ 'title' => t('Administer foundation cleaning settings'), | |
+ 'description' => t('Perform administration tasks for foundation cleaning module.'), | |
+ ), | |
+ ); | |
+} | |
+ | |
+/** | |
+ * Helper function to returns the list of atoms with duplicated base ids. | |
+ */ | |
+function _foundation_cleaning_opa_duplicated() { | |
+ $base_ids = array(); | |
+ | |
+ $query = db_select('scald_atoms', 'sa') | |
+ ->fields('sa', array('base_id', 'provider')) | |
+ ->condition('sa.provider', array('scald_apios_migrate', 'scald_opa')) | |
+ ->condition('sa.base_id', '', '!=') | |
+ ->groupBy('sa.base_id'); | |
+ $query->addExpression('COUNT(base_id)', 'basecount'); | |
+ $query->havingCondition('basecount', 1, '>'); | |
+ $result = $query->execute(); | |
+ | |
+ foreach ($result as $row) { | |
+ $base_ids[] = $row->base_id; | |
+ } | |
+ | |
+ return $base_ids; | |
+} | |
\ No newline at end of file |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment