Helper2013022000.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <?php
  2. namespace Elgg\Upgrades;
  3. /**
  4. * Helper for data directory upgrade
  5. *
  6. * @access private
  7. */
  8. class Helper2013022000 {
  9. const RELATIONSHIP_SUCCESS = '2013022000';
  10. const RELATIONSHIP_FAILURE = '2013022000_fail';
  11. /**
  12. * @var int Site GUID
  13. */
  14. protected $siteGuid;
  15. /**
  16. * @var string DB table prefix
  17. */
  18. protected $dbPrefix;
  19. /**
  20. * @param int $siteGuid Site GUID
  21. * @param string $dbPrefix DB table prefix
  22. */
  23. public function __construct($siteGuid, $dbPrefix) {
  24. $this->siteGuid = $siteGuid;
  25. $this->dbPrefix = $dbPrefix;
  26. }
  27. /**
  28. * Get elgg_get_entities() options for fetching users who need data migration
  29. *
  30. * @return array
  31. */
  32. public function getBatchOptions() {
  33. $relationship1 = sanitise_string(self::RELATIONSHIP_SUCCESS);
  34. $relationship2 = sanitise_string(self::RELATIONSHIP_FAILURE);
  35. // find users without either relationship
  36. return array(
  37. 'type' => 'user',
  38. 'callback' => '',
  39. 'order_by' => 'e.guid',
  40. 'joins' => array(
  41. "LEFT JOIN {$this->dbPrefix}entity_relationships er1
  42. ON (e.guid = er1.guid_one
  43. AND er1.guid_two = {$this->siteGuid}
  44. AND er1.relationship = '$relationship1')
  45. ",
  46. "LEFT JOIN {$this->dbPrefix}entity_relationships er2
  47. ON (e.guid = er2.guid_one
  48. AND er2.guid_two = {$this->siteGuid}
  49. AND er2.relationship = '$relationship2')
  50. ",
  51. ),
  52. 'wheres' => array("er1.guid_one IS NULL AND er2.guid_one IS NULL"),
  53. 'limit' => false,
  54. );
  55. }
  56. /**
  57. * Get number of users who need data migration
  58. *
  59. * @return int
  60. */
  61. public function countUnmigratedUsers() {
  62. $opts = $this->getBatchOptions();
  63. $opts['count'] = true;
  64. return elgg_get_entities($opts);
  65. }
  66. /**
  67. * Get the old directory location
  68. *
  69. * @param \stdClass $user_row
  70. * @return string
  71. */
  72. public function makeMatrix($user_row) {
  73. $time_created = date('Y/m/d', $user_row->time_created);
  74. return "$time_created/$user_row->guid/";
  75. }
  76. /**
  77. * Remove directory if all users moved out of it
  78. *
  79. * @param string $dir
  80. * @return bool
  81. */
  82. public function removeDirIfEmpty($dir) {
  83. $files = scandir($dir);
  84. foreach ($files as $file) {
  85. if ($file == '..' || $file == '.') {
  86. continue;
  87. }
  88. // not empty.
  89. if (is_file("$dir/$file")) {
  90. return false;
  91. }
  92. // subdir not empty
  93. if (is_dir("$dir/$file") && !$this->removeDirIfEmpty("$dir/$file")) {
  94. return false;
  95. }
  96. }
  97. // only contains empty subdirs
  98. return rmdir($dir);
  99. }
  100. /**
  101. * Get the base directory name as int
  102. *
  103. * @param int $guid GUID of the user
  104. * @return int
  105. */
  106. public function getLowerBucketBound($guid) {
  107. $bucket_size = \Elgg\EntityDirLocator::BUCKET_SIZE;
  108. if ($guid < 1) {
  109. return false;
  110. }
  111. return (int) max(floor($guid / $bucket_size) * $bucket_size, 1);
  112. }
  113. /**
  114. * Mark the user as a successful data migration
  115. *
  116. * @param int $guid
  117. */
  118. public function markSuccess($guid) {
  119. add_entity_relationship($guid, self::RELATIONSHIP_SUCCESS, $this->siteGuid);
  120. }
  121. /**
  122. * Mark the user as having failed data migration
  123. *
  124. * @param int $guid
  125. */
  126. public function markFailure($guid) {
  127. add_entity_relationship($guid, self::RELATIONSHIP_FAILURE, $this->siteGuid);
  128. }
  129. /**
  130. * Remove the records for failed migrations
  131. */
  132. public function forgetFailures() {
  133. $relationship = sanitise_string(self::RELATIONSHIP_FAILURE);
  134. _elgg_services()->db->updateData("
  135. DELETE FROM {$this->dbPrefix}entity_relationships
  136. WHERE relationship = '$relationship'
  137. AND guid_two = {$this->siteGuid}
  138. ");
  139. }
  140. /**
  141. * Remove the records for successful migrations
  142. */
  143. public function forgetSuccesses() {
  144. $relationship = sanitise_string(self::RELATIONSHIP_SUCCESS);
  145. _elgg_services()->db->updateData("
  146. DELETE FROM {$this->dbPrefix}entity_relationships
  147. WHERE relationship = '$relationship'
  148. AND guid_two = {$this->siteGuid}
  149. ");
  150. }
  151. /**
  152. * Are there any failures on record?
  153. *
  154. * @return bool
  155. */
  156. public function hasFailures() {
  157. $relationship = sanitise_string(self::RELATIONSHIP_FAILURE);
  158. $sql = "
  159. SELECT COUNT(*) AS cnt FROM {$this->dbPrefix}entity_relationships
  160. WHERE relationship = '$relationship'
  161. AND guid_two = {$this->siteGuid}
  162. ";
  163. $row = _elgg_services()->db->getDataRow($sql);
  164. return ($row->cnt > 0);
  165. }
  166. }