ElggUpgrade.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. <?php
  2. /**
  3. * Upgrade object for upgrades that need to be tracked
  4. * and listed in the admin area.
  5. *
  6. * @todo Expand for all upgrades to be \ElggUpgrade subclasses.
  7. */
  8. /**
  9. * Represents an upgrade that runs outside of the upgrade.php script.
  10. * These are listed in admin/upgrades and allow for ajax upgrades.
  11. *
  12. * @note The "upgrade_url" private setting originally stored the full URL, but
  13. * was changed to hold the relative path from the site URL for #6838
  14. *
  15. * @package Elgg.Admin
  16. * @access private
  17. */
  18. class ElggUpgrade extends \ElggObject {
  19. private $requiredProperties = array(
  20. 'title',
  21. 'description',
  22. 'upgrade_url',
  23. );
  24. /**
  25. * Do not use.
  26. *
  27. * @access private
  28. * @var callable
  29. */
  30. public $_callable_egefps = 'elgg_get_entities_from_private_settings';
  31. /**
  32. * Set subtype to upgrade
  33. *
  34. * @return null
  35. */
  36. public function initializeAttributes() {
  37. parent::initializeAttributes();
  38. $this->attributes['subtype'] = 'elgg_upgrade';
  39. // unowned
  40. $this->attributes['site_guid'] = 0;
  41. $this->attributes['container_guid'] = 0;
  42. $this->attributes['owner_guid'] = 0;
  43. $this->is_completed = 0;
  44. }
  45. /**
  46. * Mark this upgrade as completed
  47. *
  48. * @return bool
  49. */
  50. public function setCompleted() {
  51. $this->setCompletedTime();
  52. return $this->is_completed = true;
  53. }
  54. /**
  55. * Has this upgrade completed?
  56. *
  57. * @return bool
  58. */
  59. public function isCompleted() {
  60. return (bool) $this->is_completed;
  61. }
  62. /**
  63. * Sets an upgrade URL path
  64. *
  65. * @param string $path Set the URL path (without site URL) for the upgrade page
  66. * @return void
  67. * @throws InvalidArgumentException
  68. */
  69. public function setPath($path) {
  70. if (!$path) {
  71. throw new InvalidArgumentException('Invalid value for URL path.');
  72. }
  73. $path = ltrim($path, '/');
  74. if ($this->getUpgradeFromPath($path)) {
  75. throw new InvalidArgumentException('Upgrade URL paths must be unique.');
  76. }
  77. $this->upgrade_url = $path;
  78. }
  79. /**
  80. * Returns a normalized URL for the upgrade page.
  81. *
  82. * @return string
  83. */
  84. public function getURL() {
  85. return elgg_normalize_url($this->upgrade_url);
  86. }
  87. /**
  88. * Sets the timestamp for when the upgrade completed.
  89. *
  90. * @param int $time Timestamp when upgrade finished. Defaults to now.
  91. * @return bool
  92. */
  93. public function setCompletedTime($time = null) {
  94. if (!$time) {
  95. $time = time();
  96. }
  97. return $this->completed_time = $time;
  98. }
  99. /**
  100. * Gets the time when the upgrade completed.
  101. *
  102. * @return string
  103. */
  104. public function getCompletedTime() {
  105. return $this->completed_time;
  106. }
  107. /**
  108. * Require an upgrade page.
  109. *
  110. * @return mixed
  111. * @throws UnexpectedValueException
  112. */
  113. public function save() {
  114. foreach ($this->requiredProperties as $prop) {
  115. if (!$this->$prop) {
  116. throw new UnexpectedValueException("ElggUpgrade objects must have a value for the $prop property.");
  117. }
  118. }
  119. return parent::save();
  120. }
  121. /**
  122. * Set a value as private setting or attribute.
  123. *
  124. * Attributes include title and description.
  125. *
  126. * @param string $name Name of the attribute or private_setting
  127. * @param mixed $value Value to be set
  128. * @return void
  129. */
  130. public function __set($name, $value) {
  131. if (array_key_exists($name, $this->attributes)) {
  132. parent::__set($name, $value);
  133. } else {
  134. $this->setPrivateSetting($name, $value);
  135. }
  136. }
  137. /**
  138. * Get an attribute or private setting value
  139. *
  140. * @param string $name Name of the attribute or private setting
  141. * @return mixed
  142. */
  143. public function __get($name) {
  144. // See if its in our base attribute
  145. if (array_key_exists($name, $this->attributes)) {
  146. return parent::__get($name);
  147. }
  148. return $this->getPrivateSetting($name);
  149. }
  150. /**
  151. * Find an ElggUpgrade object by the unique URL path
  152. *
  153. * @param string $path The Upgrade URL path (after site URL)
  154. * @return ElggUpgrade|false
  155. */
  156. public function getUpgradeFromPath($path) {
  157. $path = ltrim($path, '/');
  158. if (!$path) {
  159. return false;
  160. }
  161. // test for full URL values (used at 1.9.0)
  162. $options = array(
  163. 'type' => 'object',
  164. 'subtype' => 'elgg_upgrade',
  165. 'private_setting_name' => 'upgrade_url',
  166. 'private_setting_value' => elgg_normalize_url($path),
  167. );
  168. $upgrades = call_user_func($this->_callable_egefps, $options);
  169. /* @var ElggUpgrade[] $upgrades */
  170. if ($upgrades) {
  171. // replace URL with path (we can't use setPath due to recursion)
  172. $upgrades[0]->upgrade_url = $path;
  173. return $upgrades[0];
  174. }
  175. $options['private_setting_value'] = $path;
  176. $upgrades = call_user_func($this->_callable_egefps, $options);
  177. if ($upgrades) {
  178. return $upgrades[0];
  179. }
  180. return false;
  181. }
  182. }