multiitems.inc 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <?php
  2. /**
  3. * @file
  4. * Support for migration from sources where data spans multiple lines
  5. * (ex. xml, json) and IDs for the items are part of each item and multiple
  6. * items reside in a single file.
  7. */
  8. /**
  9. * Extend the MigrateItems class to provide a means to obtain a list of IDs to
  10. * be migrated from a given source (e.g., MigrateItemsXML extends MigrateItem to
  11. * obtain a list of IDs from an XML document). This class also provides a means
  12. * to obtain the data for a given migratable item given its ID.
  13. */
  14. abstract class MigrateItems {
  15. public function __construct() {}
  16. /**
  17. * Implementors are expected to return a string representing where the listing
  18. * is obtained from (a URL, file directory, etc.)
  19. *
  20. * @return string
  21. */
  22. abstract public function __toString();
  23. /**
  24. * Implementors are expected to return an array of unique IDs, suitable for
  25. * passing to the MigrateItem class to retrieve the data for a single item.
  26. *
  27. * @return Mixed, iterator or array
  28. */
  29. abstract public function getIdList();
  30. /**
  31. * Implementors are expected to return a count of IDs available to be migrated.
  32. *
  33. * @return int
  34. */
  35. abstract public function computeCount();
  36. /**
  37. * Implementors are expected to return an object representing a source item.
  38. *
  39. * @param mixed $id
  40. *
  41. * @return stdClass
  42. */
  43. abstract public function getItem($id);
  44. }
  45. /**
  46. * Implementation of MigrateItems, for providing a list of IDs and for
  47. * retrieving a parsed XML document given an ID from this list.
  48. */
  49. /**
  50. * Implementation of MigrateSource, providing the semantics of iterating over
  51. * IDs provided by a MigrateItems and retrieving data from a MigrateItems.
  52. */
  53. class MigrateSourceMultiItems extends MigrateSource {
  54. /**
  55. * MigrateItems object used to obtain the list of IDs and source for
  56. * all objects.
  57. *
  58. * @var MigrateItems
  59. */
  60. protected $itemsClass;
  61. /**
  62. * List of available source fields.
  63. *
  64. * @var array
  65. */
  66. protected $fields = array();
  67. /**
  68. * Iterator of IDs from the listing class.
  69. *
  70. * @var Iterator
  71. */
  72. protected $idIterator;
  73. /**
  74. * List of item IDs to iterate.
  75. *
  76. * @var array
  77. */
  78. protected $idsToProcess = array();
  79. /**
  80. * Simple initialization.
  81. */
  82. public function __construct(MigrateItems $items_class, $fields = array(), $options = array()) {
  83. parent::__construct($options);
  84. $this->itemsClass = $items_class;
  85. $this->fields = $fields;
  86. }
  87. /**
  88. * Return a string representing the source.
  89. *
  90. * @return string
  91. */
  92. public function __toString() {
  93. return (string) $this->itemsClass;
  94. }
  95. /**
  96. * Returns a list of fields available to be mapped from the source query.
  97. * Since we can't reliably figure out what "fields" are in the source,
  98. * it's up to the implementing Migration constructor to fill them in.
  99. *
  100. * @return array
  101. * Keys: machine names of the fields (to be passed to addFieldMapping)
  102. * Values: Human-friendly descriptions of the fields.
  103. */
  104. public function fields() {
  105. return $this->fields;
  106. }
  107. /**
  108. * It's the list class that knows how many records are available, so ask it.
  109. *
  110. * @return int
  111. */
  112. public function computeCount() {
  113. // @API: Support old count method for now.
  114. if (method_exists($this->itemsClass, 'computeCount')) {
  115. return $this->itemsClass->computeCount();
  116. }
  117. else {
  118. return $this->itemsClass->count();
  119. }
  120. }
  121. /**
  122. * Implementation of MigrateSource::performRewind().
  123. *
  124. * @return void
  125. */
  126. public function performRewind() {
  127. // If there isn't a specific ID list passed in, get it from the list class.
  128. if ($this->idList) {
  129. $this->idsToProcess = $this->idList;
  130. }
  131. else {
  132. $this->idsToProcess = $this->itemsClass->getIdList();
  133. }
  134. $this->idIterator = ($this->idsToProcess instanceof Iterator) ?
  135. $this->idsToProcess : new ArrayIterator($this->idsToProcess);
  136. $this->idIterator->rewind();
  137. }
  138. /**
  139. * Implementation of MigrateSource::getNextRow().
  140. *
  141. * @return null|stdClass
  142. */
  143. public function getNextRow() {
  144. $row = NULL;
  145. while ($this->idIterator->valid()) {
  146. $id = $this->idIterator->current();
  147. $this->idIterator->next();
  148. // Skip empty IDs
  149. if (empty($id)) {
  150. continue;
  151. }
  152. // Got a good ID, get the data and get out.
  153. $row = $this->itemsClass->getItem($id);
  154. if ($row) {
  155. // Save the ID using the map source key - it will be used for mapping
  156. $sourceKey = $this->activeMap->getSourceKey();
  157. $key_name = key($sourceKey);
  158. $row->$key_name = $id;
  159. }
  160. break;
  161. }
  162. return $row;
  163. }
  164. }