You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

254 lines
8.3 KiB

  1. <?php
  2. /**
  3. * @file
  4. * Contains sample_migration.module.
  5. */
  6. use Drupal\Core\Routing\RouteMatchInterface;
  7. use \Drupal\Core\Database\Database;
  8. /**
  9. * Implements hook_help().
  10. */
  11. function sample_migration_help($route_name, RouteMatchInterface $route_match) {
  12. switch ($route_name) {
  13. // Main module help for the sample_migration module.
  14. case 'help.page.sample_migration':
  15. $output = '';
  16. $output .= '<h3>' . t('About') . '</h3>';
  17. $output .= '<p>' . t('Sample Migrations') . '</p>';
  18. return $output;
  19. default:
  20. }
  21. }
  22. /**
  23. * Batch Process to migrate all Title Body Field Collections from Drupal 7
  24. * into the Title Body Paragraphs in Drupal 8
  25. * You can read more about Batches in Drupal 8 here:
  26. * https://api.drupal.org/api/drupal/core%21includes%21form.inc/group/batch/8.5.x
  27. *
  28. * @param [type] $context
  29. * @return void
  30. */
  31. function sample_migration_title_body_paragraphs(&$context) {
  32. $entity_type_manager = \Drupal::service('entity_type.manager');
  33. /* @var NodeStorage $node_storage */
  34. $node_storage = $entity_type_manager->getStorage('node');
  35. if (empty($context['sandbox'])) {
  36. $context['sandbox'] = [];
  37. }
  38. if (!isset($context['sandbox']['progress'])) {
  39. $context['sandbox']['progress'] = 0;
  40. $context['sandbox']['current_index'] = 0;
  41. // Load all Current Nodes type of Page
  42. $all_pages = $node_storage->loadByProperties([
  43. 'type' => 'page'
  44. ]);
  45. // Need to set a bunch of data on the sandbox key to keep it on every loop through the batch process
  46. $context['sandbox']['page_content'] = array_values($all_pages);
  47. $context['sandbox']['title_page_fc'] = sample_migration_get_title_body_field_collections();
  48. $context['sandbox']['test_paragraph_map'] = sample_migration_get_test_paragraph_content_map();
  49. $context['sandbox']['index'] = array_values($context['sandbox']['page_content']);
  50. $context['sandbox']['max'] = count($context['sandbox']['page_content']);
  51. }
  52. $limit = 10;
  53. $indexes = range($context['sandbox']['current_index'], $context['sandbox']['current_index'] + $limit);
  54. // here is each loop through the batch process
  55. foreach ($indexes as $index) {
  56. // based on index get the current field collection item I'm on
  57. // use a bunch of ifs to make sure we can proceed without breaking everything
  58. $current_result = $context['sandbox']['title_page_fc'][$index];
  59. if (!is_null($current_result)) {
  60. $d7_nid = $current_result->entity_id;
  61. if (!is_null($context['sandbox']['title_page_fc'][$index])) {
  62. $d8_nid = $context['sandbox']['test_paragraph_map'][$d7_nid]->destid1;
  63. if (!is_null($d8_nid)) {
  64. // if we made it this far it's safe to try and create a paragraph
  65. // Once the paragraph data is setup pass it to our create paragraph function
  66. $paragraph_data = [
  67. 'field_title' => $current_result->field_fc_title_value,
  68. 'field_body' => [
  69. 'value' => $current_result->field_fc_body_value,
  70. 'format' => 'full_html',
  71. ],
  72. 'field_drupal7_item_id' => $current_result->field_test_paragraphs_content_value,
  73. 'parent_type' => 'node',
  74. 'type' => 'title_body',
  75. 'status' => '1',
  76. 'parent_field_name' => 'field_content',
  77. 'parent_id' => $d8_nid
  78. ];
  79. sample_migration_create_title_body_paragraph($current_result, $paragraph_data);
  80. }
  81. }
  82. }
  83. $context['sandbox']['progress']++;
  84. $context['sandbox']['current_index'] = $index;
  85. $context['message'] = t('Now processing Paragraphs');
  86. }
  87. // Update batch on our progress.
  88. if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
  89. $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
  90. }
  91. else {
  92. $context['sandbox']['finished'] = 1;
  93. }
  94. }
  95. /**
  96. * Simple batch process finished function
  97. *
  98. * @param [type] $success
  99. * @param [type] $results
  100. * @param [type] $operations
  101. * @return void
  102. */
  103. function sample_migration_title_body_paragraphs_finished($success, $results, $operations) {
  104. $messenger = \Drupal::messenger();
  105. if ($success) {
  106. $message = t('@count Reviews were added to Groups', ['@count' => count($results)]);
  107. $messenger->addMessage($message);
  108. }
  109. else {
  110. // Something went wrong
  111. $error_operation = reset($operations);
  112. $messenger->addMessage(
  113. t('An error occurred while processing @operation with arguments : @args',
  114. [
  115. '@operation' => $error_operation[0],
  116. '@args' => print_r($error_operation[0], TRUE)
  117. ]
  118. )
  119. );
  120. }
  121. }
  122. /**
  123. * Undocumented function
  124. *
  125. * @return void
  126. */
  127. function sample_migration_get_title_body_field_collections() {
  128. Database::setActiveConnection('drupal7');
  129. $drupal7db = Database::getConnection();
  130. $query = $drupal7db->select('field_data_field_test_paragraphs_content', 'fc');
  131. $query->fields('fc', [
  132. 'entity_id',
  133. 'field_test_paragraphs_content_value',
  134. 'delta'
  135. ]);
  136. $query->innerJoin('field_collection_item', 'fci', 'fc.entity_id = fci.item_id');
  137. $query->fields('fci', [
  138. 'item_id',
  139. 'field_name',
  140. 'revision_id'
  141. ]);
  142. $query->innerJoin('field_data_field_fc_title', 'title', 'title.entity_id = fci.item_id');
  143. $query->fields('title', [
  144. 'entity_type',
  145. 'bundle',
  146. 'entity_id',
  147. 'field_fc_title_value'
  148. ]);
  149. $query->innerJoin('field_data_field_fc_body', 'body', 'body.entity_id = fci.item_id');
  150. $query->fields('body', [
  151. 'entity_type',
  152. 'field_fc_body_value',
  153. 'field_fc_body_format',
  154. 'bundle',
  155. 'entity_id'
  156. ]);
  157. $results = $query->execute()->fetchAll();
  158. Database::setActiveConnection('default');
  159. return $results;
  160. }
  161. /**
  162. * Undocumented function
  163. *
  164. * @return void
  165. */
  166. function sample_migration_get_test_paragraph_content_map() {
  167. $drupal8db = Database::getConnection();
  168. $query = $drupal8db->select('migrate_map_d7_node__test_paragraphs', 'mm');
  169. $query->fields('mm', [
  170. 'sourceid1',
  171. 'destid1'
  172. ]);
  173. $map_results = $query->execute()->fetchAllAssoc('sourceid1');
  174. return $map_results;
  175. }
  176. /**
  177. * Create / Update a paragraph based on the data passed into it
  178. *
  179. * @param [type] $current_result
  180. * @param [type] $paragraph_data
  181. * @return void
  182. */
  183. function sample_migration_create_title_body_paragraph($current_result, $paragraph_data) {
  184. $paragraph_storage = \Drupal::entityTypeManager()->getStorage('paragraph');
  185. $node_storage = \Drupal::entityTypeManager()->getStorage('node');
  186. // check if paragraph already exists, if so we need to update it
  187. // we set field_drupal7_item_id on it so we can make sure we aren't duplicating paragraphs
  188. // so we don't build a million paragraphs
  189. $existing_paragraph = $paragraph_storage->loadByProperties([
  190. 'field_drupal7_item_id' => $current_result->field_test_paragraphs_content_value
  191. ]);
  192. if (!is_null($existing_paragraph) && count($existing_paragraph)) {
  193. $this_paragraph = reset($existing_paragraph);
  194. }
  195. else {
  196. $this_paragraph = $paragraph_storage->create($paragraph_data);
  197. $this_paragraph->save();
  198. }
  199. // attach paragraph to node
  200. $parent_node = $node_storage->load($current_result->entity_id);
  201. if (!is_null($parent_node)) {
  202. // parent field name
  203. $field_name = 'field_content';
  204. // find all paragraphs already on the node so we don't add this one twice
  205. // also so we don't delete a paragraph by adding a new one
  206. $node_paragraphs = $parent_node->get($field_name)->getValue();
  207. $should_add_paragraph = true;
  208. if (count($node_paragraphs)) {
  209. foreach ($node_paragraphs as $node_paragraph) {
  210. if ($node_paragraph['target_id'] === $this_paragraph->id()) {
  211. // if this paragraph is alrady attached, there is no reason to attach it again
  212. $should_add_paragraph = false;
  213. break;
  214. }
  215. }
  216. }
  217. if ($should_add_paragraph) {
  218. // add this paragraph to the paragraphs array on the node and save it
  219. $node_paragraphs[] = [
  220. 'target_id' => $this_paragraph->id(),
  221. 'target_revision_id' => $this_paragraph->getRevisionId()
  222. ];
  223. $parent_node->set($field_name, $node_paragraphs);
  224. $parent_node->save();
  225. }
  226. }
  227. else {
  228. \Drupal::messenger()->addMessage(t("Unable to attach paragraph to content. Paragraph ID: " . $this_paragraph->id()), 'error');
  229. \Drupal::logger('joco_migrations')->error("Unable to attach paragraph to content. Paragraph ID: " . $this_paragraph->id());
  230. }
  231. }