votingapi.migrate.inc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <?php
  2. /**
  3. * @file
  4. * Migration support for voting api.
  5. */
  6. class MigrateDestinationVotingApiVote extends MigrateDestination {
  7. protected $importedIds = array();
  8. /**
  9. * Threshold of count of id's after which votes will be recalculated.
  10. *
  11. * @var int
  12. */
  13. protected $idRecalculationThreshold = 1000;
  14. static public function getKeySchema() {
  15. return array(
  16. 'vote_id' => array(
  17. 'type' => 'int',
  18. 'unsigned' => TRUE,
  19. 'not null' => TRUE,
  20. 'description' => 'Vote ID',
  21. ),
  22. );
  23. }
  24. /**
  25. * {@inheritdoc}
  26. */
  27. public function __toString() {
  28. return t('Voting API Vote');
  29. }
  30. /**
  31. * {@inheritdoc}
  32. */
  33. public function fields() {
  34. return array(
  35. 'vote_id' => 'Vote ID',
  36. 'entity_type' => "Entity Type (defaults to 'node')",
  37. 'entity_id' => 'Entity ID',
  38. 'value' => 'Numeric vote value',
  39. 'value_type' => "Value type (percent/points, defaults to 'percent')",
  40. 'tag' => "Tag (defaults to 'vote')",
  41. 'uid' => 'User ID',
  42. 'timestamp' => 'Timestamp',
  43. 'vote_source' => 'Vote Source IP Address hash',
  44. );
  45. }
  46. /**
  47. * {@inheritdoc}
  48. */
  49. public function import(stdClass $votingapi_vote, stdClass $row) {
  50. $updating = FALSE;
  51. $vote = array();
  52. if (isset($row->migrate_map_destid1)) {
  53. // We're updating an existing vote - start from the previous data.
  54. $votes = votingapi_select_votes(array('vote_id' => $row->migrate_map_destid1));
  55. if (count($votes)) {
  56. $vote = reset($votes);
  57. $updating = TRUE;
  58. }
  59. }
  60. if (!$updating) {
  61. unset($votingapi_vote->vote_id);
  62. }
  63. $this->prepare($votingapi_vote, $row);
  64. // Votes have to be assigned to an entity.
  65. if (empty($votingapi_vote->entity_id)) {
  66. watchdog('VotingAPI Import', 'Skipped import due to empty entity_id for vote import: @serial', array('@serial' => json_encode($row)), WATCHDOG_ERROR);
  67. return FALSE;
  68. }
  69. migrate_instrument_start('votingapi_vote_save');
  70. // Just converting $entity to an array doesn't work...
  71. $vote = array();
  72. foreach ((array) $votingapi_vote as $field => $value) {
  73. $vote[$field] = $value;
  74. }
  75. votingapi_add_votes($vote);
  76. migrate_instrument_stop('votingapi_vote_save');
  77. if (isset($vote[0]['vote_id'])) {
  78. $votingapi_vote->vote_id = $vote[0]['vote_id'];
  79. $this->complete($votingapi_vote, $row);
  80. // Store the ID in the hash as it is faster than getting uniques later.
  81. $this->importedIds[$votingapi_vote->entity_type][$votingapi_vote->entity_id] = TRUE;
  82. // If we hit the threshold of entity id's we imported, we should
  83. // recalculate to avoid excessive memory usage (and clear out the array).
  84. if (count($this->importedIds[$votingapi_vote->entity_type]) >= $this->idRecalculationThreshold) {
  85. $this->recalculateResults($votingapi_vote->entity_type, array_keys($this->importedIds[$votingapi_vote->entity_type]));
  86. $this->importedIds[$votingapi_vote->entity_type] = array();
  87. }
  88. if ($updating) {
  89. $this->numUpdated++;
  90. }
  91. else {
  92. $this->numCreated++;
  93. }
  94. return array($votingapi_vote->vote_id);
  95. }
  96. else {
  97. return FALSE;
  98. }
  99. }
  100. /**
  101. * Recalculate votes for a list of id's.
  102. *
  103. * @param string $entity_type
  104. * The entity type of the id's
  105. * @param array $ids
  106. * List of the ID's for which votes are to be recalculated.
  107. */
  108. protected function recalculateResults($entity_type, array $ids) {
  109. foreach ($ids as $entity_id) {
  110. votingapi_recalculate_results($entity_type, $entity_id, TRUE);
  111. }
  112. }
  113. /**
  114. * We're done with importing votes, recalculate the results.
  115. */
  116. public function postImport() {
  117. foreach ($this->importedIds as $entity_type => $entity_ids) {
  118. $this->recalculateResults($entity_type, array_keys($entity_ids));
  119. }
  120. }
  121. /**
  122. * Delete the provided votes and recalculate the results.
  123. *
  124. * @param array $ids
  125. * ID's to be deleted.
  126. */
  127. public function bulkRollback(array $ids) {
  128. migrate_instrument_start(__METHOD__);
  129. foreach ($ids as $id) {
  130. $votes[]['vote_id'] = $id;
  131. }
  132. votingapi_delete_votes($votes);
  133. migrate_instrument_stop(__METHOD__);
  134. }
  135. public function prepare($vote, stdClass $source_row) {
  136. $migration = Migration::currentMigration();
  137. if (method_exists($migration, 'prepare')) {
  138. $vote->migrate = array(
  139. 'machineName' => $migration->getMachineName(),
  140. );
  141. $migration->prepare($vote, $source_row);
  142. }
  143. }
  144. public function complete($entity, stdClass $source_row) {
  145. // Call any complete handler for this specific Migration.
  146. $migration = Migration::currentMigration();
  147. if (method_exists($migration, 'complete')) {
  148. try {
  149. $migration->complete($entity, $source_row);
  150. } catch (Exception $e) {
  151. // If we catch any errors here, save the messages without letting
  152. // the exception prevent the saving of the question.
  153. $migration->saveMessage($e->getMessage());
  154. }
  155. }
  156. }
  157. /**
  158. * Give handlers a shot at cleaning up before a question has been rolled back.
  159. *
  160. * @param $entity_id
  161. * ID of the entity about to be deleted..
  162. */
  163. public function prepareRollback($entity_id) {
  164. // Call any prepare handler for this specific Migration.
  165. $migration = Migration::currentMigration();
  166. if (method_exists($migration, 'prepareRollback')) {
  167. $migration->prepareRollback($entity_id);
  168. }
  169. }
  170. /**
  171. * Give handlers a shot at cleaning up after an entity has been rolled back.
  172. *
  173. * @param $entity_id
  174. * ID of the entity which has been deleted.
  175. */
  176. public function completeRollback($entity_id) {
  177. // Call any complete handler for this specific Migration.
  178. $migration = Migration::currentMigration();
  179. if (method_exists($migration, 'completeRollback')) {
  180. $migration->completeRollback($entity_id);
  181. }
  182. }
  183. }