files.inc 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <?php
  2. /**
  3. * @file
  4. * Support for migration from files sources.
  5. */
  6. /**
  7. * Implementation of MigrateList, for retrieving a list of IDs to be migrated
  8. * from a directory listing. Each item is a file, it's ID is the path.
  9. */
  10. class MigrateListFiles extends MigrateList {
  11. protected $listDirs;
  12. protected $baseDir;
  13. protected $fileMask;
  14. protected $directoryOptions;
  15. /**
  16. * Constructor.
  17. *
  18. * @param $list_dirs
  19. * Array of directory paths that will be scanned for files. No trailing
  20. * slash. For example:
  21. * array(
  22. * '/var/html_source/en/news',
  23. * '/var/html_source/fr/news',
  24. * '/var/html_source/zh/news',
  25. * );
  26. * @param $base_dir
  27. * The base dir is the part of the path that will be excluded when making
  28. * an ID for each file. To continue the example from above, you want base_dir
  29. * to be = '/var/html_source', so that the files will have IDs in the format
  30. * '/en/news/news_2011_03_4.html'.
  31. * @param $file_mask
  32. * Passed on and used to filter for certain types of files. Use a regular
  33. * expression, for example '/(.*\.htm$|.*\.html$)/i' to match all .htm and
  34. * .html files, case insensitive.
  35. * @param $options
  36. * Options that will be passed on to file_scan_directory(). See docs of that
  37. * core Drupal function for more information.
  38. */
  39. public function __construct($list_dirs, $base_dir, $file_mask = NULL, $options = array()) {
  40. parent::__construct();
  41. $this->listDirs = $list_dirs;
  42. $this->baseDir = $base_dir;
  43. $this->fileMask = $file_mask;
  44. $this->directoryOptions = $options;
  45. }
  46. /**
  47. * Our public face is the directories we're getting items from.
  48. */
  49. public function __toString() {
  50. if (is_array($this->listDirs)) {
  51. return implode(',', $this->listDirs);
  52. }
  53. else {
  54. return $this->listDirs;
  55. }
  56. }
  57. /**
  58. * Retrieve a list of files based on parameters passed for the migration.
  59. */
  60. public function getIdList() {
  61. $files = array();
  62. foreach ($this->listDirs as $dir) {
  63. migrate_instrument_start("Retrieve $dir");
  64. $files = array_merge(file_scan_directory($dir, $this->fileMask, $this->directoryOptions), $files);
  65. migrate_instrument_stop("Retrieve $dir");
  66. }
  67. if (isset($files)) {
  68. return $this->getIDsFromFiles($files);
  69. }
  70. Migration::displayMessage(t('Loading of !listuri failed:', array('!listuri' => $this->listUri)));
  71. return NULL;
  72. }
  73. /**
  74. * Given an array generated from file_scan_directory(), parse out the IDs for
  75. * processing and return them as an array.
  76. */
  77. protected function getIDsFromFiles(array $files) {
  78. $ids = array();
  79. foreach ($files as $file) {
  80. $ids[] = str_replace($this->baseDir, '', (string) $file->uri);
  81. }
  82. return array_unique($ids);
  83. }
  84. /**
  85. * Return a count of all available IDs from the source listing.
  86. */
  87. public function computeCount() {
  88. $count = 0;
  89. $files = $this->getIdList();
  90. if ($files) {
  91. $count = count($files);
  92. }
  93. return $count;
  94. }
  95. }
  96. /**
  97. * Implementation of MigrateItem, for retrieving a file from the file system
  98. * based on source directory and an ID provided by a MigrateList class.
  99. */
  100. class MigrateItemFile extends MigrateItem {
  101. protected $baseDir;
  102. protected $getContents;
  103. /**
  104. * Constructor.
  105. *
  106. * @param $base_dir
  107. * The base directory from which all file paths are calculated.
  108. * @param $get_contents
  109. * TRUE if we should try load the contents of each file (in the case
  110. * of a text file), or FALSE if we just want to confirm it exists (binary).
  111. */
  112. public function __construct($base_dir, $get_contents = TRUE) {
  113. parent::__construct();
  114. $this->baseDir = $base_dir;
  115. $this->getContents = $get_contents;
  116. }
  117. /**
  118. * Return an object representing a file.
  119. *
  120. * @param $id
  121. * The file id, which is the file URI.
  122. *
  123. * @return object
  124. * The item object for migration.
  125. */
  126. public function getItem($id) {
  127. $item_uri = $this->baseDir . $id;
  128. // Get the file data at the specified URI
  129. $data = $this->loadFile($item_uri);
  130. if (is_string($data)) {
  131. $return = new stdClass;
  132. $return->filedata = $data;
  133. return $return;
  134. }
  135. elseif ($data === TRUE) {
  136. $return = new stdClass;
  137. return $return;
  138. }
  139. else {
  140. $migration = Migration::currentMigration();
  141. $message = t('Loading of !objecturi failed:', array('!objecturi' => $item_uri));
  142. $migration->getMap()->saveMessage(
  143. array($id), $message, MigrationBase::MESSAGE_ERROR);
  144. return NULL;
  145. }
  146. }
  147. /**
  148. * Default file loader.
  149. */
  150. protected function loadFile($item_uri) {
  151. // Only try load the contents if we have this flag set.
  152. if ($this->getContents) {
  153. $data = file_get_contents($item_uri);
  154. }
  155. else {
  156. $data = file_exists($item_uri);
  157. }
  158. return $data;
  159. }
  160. }