list.inc 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <?php
  2. /**
  3. * @file
  4. * Support for migration from sources with distinct means of listing items to
  5. * import and obtaining the items themselves.
  6. *
  7. * TODO: multiple-field source keys
  8. */
  9. /**
  10. * Extend the MigrateList class to provide a means to obtain a list of IDs to
  11. * be migrated from a given source (e.g., MigrateListXML extends MigrateList to
  12. * obtain a list of IDs from an XML document).
  13. */
  14. abstract class MigrateList {
  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. /**
  38. * Extend the MigrateItem class to provide a means to obtain the data for a
  39. * given migratable item given its ID as provided by the MigrateList class.
  40. */
  41. abstract class MigrateItem {
  42. public function __construct() {}
  43. /**
  44. * Implementors are expected to return an object representing a source item.
  45. *
  46. * @param mixed $id
  47. *
  48. * @return stdClass
  49. */
  50. abstract public function getItem($id);
  51. }
  52. /**
  53. * Implementation of MigrateSource, providing the semantics of iterating over
  54. * IDs provided by a MigrateList and retrieving data from a MigrateItem.
  55. */
  56. class MigrateSourceList extends MigrateSource {
  57. /**
  58. * MigrateList object used to obtain ID lists.
  59. *
  60. * @var MigrateList
  61. */
  62. protected $listClass;
  63. /**
  64. * MigrateItem object used to obtain the source object for a given ID.
  65. *
  66. * @var MigrateItem
  67. */
  68. protected $itemClass;
  69. /**
  70. * Iterator of IDs from the listing class.
  71. *
  72. * @var Iterator
  73. */
  74. protected $idIterator;
  75. /**
  76. * List of available source fields.
  77. *
  78. * @var array
  79. */
  80. protected $fields = array();
  81. /**
  82. * Simple initialization.
  83. */
  84. public function __construct(MigrateList $list_class, MigrateItem $item_class, $fields = array(),
  85. $options = array()) {
  86. parent::__construct($options);
  87. $this->listClass = $list_class;
  88. $this->itemClass = $item_class;
  89. $this->fields = $fields;
  90. }
  91. /**
  92. * Return a string representing the source.
  93. *
  94. * @return string
  95. */
  96. public function __toString() {
  97. return (string) $this->listClass;
  98. }
  99. /**
  100. * Returns a list of fields available to be mapped from the source query.
  101. * Since we can't reliably figure out what "fields" are in the source,
  102. * it's up to the implementing Migration constructor to fill them in.
  103. *
  104. * @return array
  105. * Keys: machine names of the fields (to be passed to addFieldMapping)
  106. * Values: Human-friendly descriptions of the fields.
  107. */
  108. public function fields() {
  109. return $this->fields;
  110. }
  111. /**
  112. * It's the list class that knows how many records are available, so ask it.
  113. *
  114. * @return int
  115. */
  116. public function computeCount() {
  117. // @API: Support old count method for now.
  118. if (method_exists($this->listClass, 'computeCount')) {
  119. return $this->listClass->computeCount();
  120. }
  121. else {
  122. return $this->listClass->count();
  123. }
  124. }
  125. /**
  126. * Implementation of MigrateSource::performRewind().
  127. *
  128. * @return void
  129. */
  130. public function performRewind() {
  131. // If there isn't a specific ID list passed in, get it from the list class.
  132. if ($this->idList) {
  133. $this->idsToProcess = $this->idList;
  134. }
  135. else {
  136. $this->idsToProcess = $this->listClass->getIdList();
  137. }
  138. $this->idIterator = ($this->idsToProcess instanceof Iterator) ?
  139. $this->idsToProcess : new ArrayIterator($this->idsToProcess);
  140. $this->idIterator->rewind();
  141. }
  142. /**
  143. * Implementation of MigrateSource::getNextRow().
  144. *
  145. * @return null|stdClass
  146. */
  147. public function getNextRow() {
  148. $row = NULL;
  149. while ($this->idIterator->valid()) {
  150. $ids = $this->idIterator->current();
  151. $this->idIterator->next();
  152. // Skip empty IDs
  153. if (empty($ids)) {
  154. continue;
  155. }
  156. // Got a good ID, get the data and get out.
  157. $row = $this->itemClass->getItem($ids);
  158. if ($row) {
  159. // No matter what $ids is, be it a string, integer, object, or array, we
  160. // cast it to an array so that it can be properly mapped to the source
  161. // keys as specified by the map. This is done after getItem is called so
  162. // that the ItemClass doesn't have to care about this requirement.
  163. $ids = (array) $ids;
  164. foreach (array_keys($this->activeMap->getSourceKey()) as $key_name) {
  165. // Grab the first id and advance the array cursor. Then save the ID
  166. // using the map source key - it will be used for mapping.
  167. list(, $id) = each($ids);
  168. $row->$key_name = $id;
  169. }
  170. }
  171. break;
  172. }
  173. return $row;
  174. }
  175. }