Skip to content

Instantly share code, notes, and snippets.

@Renrhaf
Created October 6, 2016 13:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Renrhaf/3b94fd5fd538f92722a3a612ed28b1ef to your computer and use it in GitHub Desktop.
Save Renrhaf/3b94fd5fd538f92722a3a612ed28b1ef to your computer and use it in GitHub Desktop.
AFOUND-850
From 2c123e42a8abcd09d6509c2b8975cb9cb52740f1 Mon Sep 17 00:00:00 2001
From: Renrhaf <quentin.fahrner@actency.fr>
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