json.inc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <?php
  2. /**
  3. * @file
  4. * Support for migration from JSON sources.
  5. */
  6. /**
  7. * Implementation of MigrateList, for retrieving a list of IDs to be migrated
  8. * from a JSON object.
  9. */
  10. class MigrateListJSON extends MigrateList {
  11. /**
  12. * A URL pointing to an JSON object containing a list of IDs to be processed.
  13. *
  14. * @var string
  15. */
  16. protected $listUrl;
  17. protected $httpOptions;
  18. public function __construct($list_url, $http_options = array()) {
  19. parent::__construct();
  20. $this->listUrl = $list_url;
  21. $this->httpOptions = $http_options;
  22. }
  23. /**
  24. * Our public face is the URL we're getting items from
  25. *
  26. * @return string
  27. */
  28. public function __toString() {
  29. return $this->listUrl;
  30. }
  31. /**
  32. * Load the JSON at the given URL, and return an array of the IDs found within it.
  33. *
  34. * @return array
  35. */
  36. public function getIdList() {
  37. migrate_instrument_start("Retrieve $this->listUrl");
  38. if (empty($this->httpOptions)) {
  39. $json = file_get_contents($this->listUrl);
  40. }
  41. else {
  42. $response = drupal_http_request($this->listUrl, $this->httpOptions);
  43. $json = $response->data;
  44. }
  45. migrate_instrument_stop("Retrieve $this->listUrl");
  46. if ($json) {
  47. $data = drupal_json_decode($json);
  48. if ($data) {
  49. return $this->getIDsFromJSON($data);
  50. }
  51. }
  52. Migration::displayMessage(t('Loading of !listurl failed:',
  53. array('!listurl' => $this->listUrl)));
  54. return NULL;
  55. }
  56. /**
  57. * Given an array generated from JSON, parse out the IDs for processing
  58. * and return them as an array. The default implementation assumes the IDs are
  59. * simply the values of the top-level elements - in most cases, you will need
  60. * to override this to reflect your particular JSON structure.
  61. *
  62. * @param array $data
  63. *
  64. * @return array
  65. */
  66. protected function getIDsFromJSON(array $data) {
  67. return $data;
  68. }
  69. /**
  70. * Return a count of all available IDs from the source listing. The default
  71. * implementation assumes the count of top-level elements reflects the number
  72. * of IDs available - in many cases, you will need to override this to reflect
  73. * your particular JSON structure.
  74. */
  75. public function computeCount() {
  76. $count = 0;
  77. if (empty($this->httpOptions)) {
  78. $json = file_get_contents($this->listUrl);
  79. }
  80. else {
  81. $response = drupal_http_request($this->listUrl, $this->httpOptions);
  82. $json = $response->data;
  83. }
  84. if ($json) {
  85. $data = drupal_json_decode($json);
  86. if ($data) {
  87. $count = count($data);
  88. }
  89. }
  90. return $count;
  91. }
  92. }
  93. /**
  94. * Implementation of MigrateItem, for retrieving a parsed JSON object given
  95. * an ID provided by a MigrateList class.
  96. */
  97. class MigrateItemJSON extends MigrateItem {
  98. /**
  99. * A URL pointing to a JSON object containing the data for one item to be
  100. * migrated.
  101. *
  102. * @var string
  103. */
  104. protected $itemUrl;
  105. protected $httpOptions;
  106. public function __construct($item_url, $http_options) {
  107. parent::__construct();
  108. $this->itemUrl = $item_url;
  109. $this->httpOptions = $http_options;
  110. }
  111. /**
  112. * Implementors are expected to return an object representing a source item.
  113. *
  114. * @param mixed $id
  115. *
  116. * @return stdClass
  117. */
  118. public function getItem($id) {
  119. $item_url = $this->constructItemUrl($id);
  120. // Get the JSON object at the specified URL
  121. $json = $this->loadJSONUrl($item_url);
  122. if ($json) {
  123. return $json;
  124. }
  125. else {
  126. $migration = Migration::currentMigration();
  127. $message = t('Loading of !objecturl failed:', array('!objecturl' => $item_url));
  128. $migration->getMap()->saveMessage(
  129. array($id), $message, MigrationBase::MESSAGE_ERROR);
  130. return NULL;
  131. }
  132. }
  133. /**
  134. * The default implementation simply replaces the :id token in the URL with
  135. * the ID obtained from MigrateListJSON. Override if the item URL is not
  136. * so easily expressed from the ID.
  137. *
  138. * @param mixed $id
  139. */
  140. protected function constructItemUrl($id) {
  141. return str_replace(':id', $id, $this->itemUrl);
  142. }
  143. /**
  144. * Default JSON loader - just pull and decode. This can be overridden for
  145. * preprocessing of JSON (removal of unwanted elements, caching of JSON if the
  146. * source service is slow, etc.)
  147. */
  148. protected function loadJSONUrl($item_url) {
  149. if (empty($this->httpOptions)) {
  150. $json = file_get_contents($item_url);
  151. }
  152. else {
  153. $response = drupal_http_request($item_url, $this->httpOptions);
  154. $json = $response->data;
  155. }
  156. return json_decode($json);
  157. }
  158. }