Status.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <?php
  2. /**
  3. * Copyright © 2013-2017 Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Update;
  7. /**
  8. * Class which provides access to the current status of the Magento updater application.
  9. *
  10. * Each job is using this class to share information about its current status.
  11. * Current status can be seen on the updater app web page.
  12. */
  13. class Status
  14. {
  15. /**
  16. * Path to a file, which content is displayed on the updater web page.
  17. *
  18. * @var string
  19. */
  20. protected $statusFilePath;
  21. /**
  22. * Path to a log file, which contains all the information displayed on the web page.
  23. *
  24. * Note that it can be cleared only manually, it is not cleared by clear() method.
  25. *
  26. * @var string
  27. */
  28. protected $logFilePath;
  29. /**
  30. * Path to a flag, which exists when updater app is running.
  31. *
  32. * @var string
  33. */
  34. protected $updateInProgressFlagFilePath;
  35. /**
  36. * Path to a flag, which exists when error occurred during updater app execution.
  37. *
  38. * @var string
  39. */
  40. protected $updateErrorFlagFilePath;
  41. /**
  42. * PSR-3 compliant logger
  43. *
  44. * @var \Psr\Log\LoggerInterface
  45. */
  46. private $logger;
  47. /**
  48. * Initialize.
  49. *
  50. * @param string|null $statusFilePath
  51. * @param string|null $logFilePath
  52. * @param string|null $updateInProgressFlagFilePath
  53. * @param string|null $updateErrorFlagFilePath
  54. */
  55. public function __construct(
  56. $statusFilePath = null,
  57. $logFilePath = null,
  58. $updateInProgressFlagFilePath = null,
  59. $updateErrorFlagFilePath = null
  60. ) {
  61. $this->statusFilePath = $statusFilePath ? $statusFilePath : MAGENTO_BP . '/var/.update_status.txt';
  62. $this->logFilePath = $logFilePath ? $logFilePath : MAGENTO_BP . '/var/log/update.log';
  63. $this->updateInProgressFlagFilePath = $updateInProgressFlagFilePath
  64. ? $updateInProgressFlagFilePath
  65. : MAGENTO_BP . '/var/.update_in_progress.flag';
  66. $this->updateErrorFlagFilePath = $updateErrorFlagFilePath
  67. ? $updateErrorFlagFilePath
  68. : MAGENTO_BP . '/var/.update_error.flag';
  69. $updateLoggerFactory = new UpdateLoggerFactory($this->logFilePath);
  70. $this->logger = $updateLoggerFactory->create();
  71. }
  72. /**
  73. * Get current updater application status.
  74. *
  75. * @return string
  76. */
  77. public function get()
  78. {
  79. if (file_exists($this->statusFilePath)) {
  80. return $this->hideSensitiveData(file_get_contents($this->statusFilePath));
  81. }
  82. return '';
  83. }
  84. /**
  85. * Add status update.
  86. *
  87. * Add information to a temporary file which is used for status display on a web page and to a permanent status log.
  88. *
  89. * @param string $text
  90. * @param string $severity
  91. * @return $this
  92. * @throws \RuntimeException
  93. */
  94. public function add($text, $severity = \Psr\Log\LogLevel::INFO)
  95. {
  96. $this->logger->log($severity, $text);
  97. $currentUtcTime = '[' . date('Y-m-d H:i:s T', time()) . '] ';
  98. $text = $currentUtcTime . $text;
  99. $this->writeMessageToFile($text, $this->statusFilePath);
  100. return $this;
  101. }
  102. /**
  103. * Add status update to show progress
  104. *
  105. * @param string $text
  106. * @return $this
  107. * @throws \RuntimeException
  108. */
  109. public function addWithoutNewLine($text)
  110. {
  111. $this->writeMessageToFile($text, $this->logFilePath, false);
  112. $this->writeMessageToFile($text, $this->statusFilePath, false);
  113. return $this;
  114. }
  115. /**
  116. * Hide sensitive data before it will be showed on a web page
  117. *
  118. * @param string $text
  119. * @return string
  120. */
  121. private function hideSensitiveData($text)
  122. {
  123. $text = preg_replace("/(Module) '(\w+)_(\w+)'/", "$1 '$2_******'", $text);
  124. $text = preg_replace('#' . MAGENTO_BP . '#', '{magento_root}', $text);
  125. return $text;
  126. }
  127. /**
  128. * Write status information to the file.
  129. *
  130. * @param string $text
  131. * @param string $filePath
  132. * @param bool $newline
  133. * @return $this
  134. * @throws \RuntimeException
  135. */
  136. protected function writeMessageToFile($text, $filePath, $newline = true)
  137. {
  138. $isNewFile = !file_exists($filePath);
  139. if (!$isNewFile && file_get_contents($filePath)) {
  140. $text = $newline ? PHP_EOL . "{$text}" :"{$text}";
  141. }
  142. if (false === file_put_contents($filePath, $text, FILE_APPEND)) {
  143. throw new \RuntimeException(sprintf('Cannot add status information to "%s"', $filePath));
  144. }
  145. if ($isNewFile) {
  146. chmod($filePath, 0777);
  147. }
  148. return $this;
  149. }
  150. /**
  151. * Clear current status text.
  152. *
  153. * Note that this method does not clear status information from the permanent status log.
  154. *
  155. * @return $this
  156. * @throws \RuntimeException
  157. */
  158. public function clear()
  159. {
  160. if (!file_exists($this->statusFilePath)) {
  161. return $this;
  162. } else if (false === file_put_contents($this->statusFilePath, '')) {
  163. throw new \RuntimeException(sprintf('Cannot clear status information from "%s"', $this->statusFilePath));
  164. }
  165. return $this;
  166. }
  167. /**
  168. * Check if updater application is running.
  169. *
  170. * @return bool
  171. */
  172. public function isUpdateInProgress()
  173. {
  174. return file_exists($this->updateInProgressFlagFilePath);
  175. }
  176. /**
  177. * Set current updater app status: true if update is in progress, false otherwise.
  178. *
  179. * @param bool $isInProgress
  180. * @return $this
  181. */
  182. public function setUpdateInProgress($isInProgress = true)
  183. {
  184. return $this->setFlagValue($this->updateInProgressFlagFilePath, $isInProgress);
  185. }
  186. /**
  187. * Check if error has occurred during updater application execution.
  188. *
  189. * @return bool
  190. */
  191. public function isUpdateError()
  192. {
  193. return file_exists($this->updateErrorFlagFilePath);
  194. }
  195. /**
  196. * Set current updater app status: true if error occurred during update app execution, false otherwise.
  197. *
  198. * @param bool $isErrorOccurred
  199. * @return $this
  200. */
  201. public function setUpdateError($isErrorOccurred = true)
  202. {
  203. return $this->setFlagValue($this->updateErrorFlagFilePath, $isErrorOccurred);
  204. }
  205. /**
  206. * Create flag in case when value is set to 'true', remove it if value is set to 'false'.
  207. *
  208. * @param string $pathToFlagFile
  209. * @param bool $value
  210. * @throws \RuntimeException
  211. * @return $this
  212. */
  213. protected function setFlagValue($pathToFlagFile, $value)
  214. {
  215. if ($value) {
  216. $updateInProgressFlagFile = fopen($pathToFlagFile, 'w');
  217. if (!$updateInProgressFlagFile) {
  218. throw new \RuntimeException(sprintf('"%s" cannot be created.', $pathToFlagFile));
  219. }
  220. fclose($updateInProgressFlagFile);
  221. } else if (file_exists($pathToFlagFile)) {
  222. unlink($pathToFlagFile);
  223. }
  224. return $this;
  225. }
  226. }