Backup.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Backup\Model;
  7. use Magento\Framework\App\Filesystem\DirectoryList;
  8. use Magento\Framework\Filesystem\DriverPool;
  9. /**
  10. * Backup file item model
  11. *
  12. * @method string getPath()
  13. * @method string getName()
  14. * @method string getTime()
  15. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  16. * @api
  17. * @since 100.0.2
  18. */
  19. class Backup extends \Magento\Framework\DataObject implements \Magento\Framework\Backup\Db\BackupInterface
  20. {
  21. /**
  22. * Compress rate
  23. */
  24. const COMPRESS_RATE = 9;
  25. /**
  26. * Type of backup file
  27. *
  28. * @var string
  29. */
  30. private $_type = 'db';
  31. /**
  32. * Gz file pointer
  33. *
  34. * @var \Magento\Framework\Filesystem\File\WriteInterface
  35. */
  36. protected $_stream = null;
  37. /**
  38. * @var \Magento\Framework\Filesystem
  39. */
  40. protected $_filesystem;
  41. /**
  42. * @var \Magento\Backup\Helper\Data
  43. */
  44. protected $_helper;
  45. /**
  46. * Locale model
  47. *
  48. * @var \Magento\Framework\Locale\ResolverInterface
  49. */
  50. protected $_localeResolver;
  51. /**
  52. * Backend auth session
  53. *
  54. * @var \Magento\Backend\Model\Auth\Session
  55. */
  56. protected $_backendAuthSession;
  57. /**
  58. * @var \Magento\Framework\Encryption\EncryptorInterface
  59. */
  60. protected $_encryptor;
  61. /**
  62. * @var \Magento\Framework\Filesystem\Directory\WriteInterface
  63. */
  64. protected $varDirectory;
  65. /**
  66. * @param \Magento\Backup\Helper\Data $helper
  67. * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
  68. * @param \Magento\Backend\Model\Auth\Session $authSession
  69. * @param \Magento\Framework\Encryption\EncryptorInterface $encryptor
  70. * @param \Magento\Framework\Filesystem $filesystem
  71. * @param array $data
  72. */
  73. public function __construct(
  74. \Magento\Backup\Helper\Data $helper,
  75. \Magento\Framework\Locale\ResolverInterface $localeResolver,
  76. \Magento\Backend\Model\Auth\Session $authSession,
  77. \Magento\Framework\Encryption\EncryptorInterface $encryptor,
  78. \Magento\Framework\Filesystem $filesystem,
  79. $data = []
  80. ) {
  81. $this->_encryptor = $encryptor;
  82. parent::__construct($data);
  83. $this->_filesystem = $filesystem;
  84. $this->varDirectory = $this->_filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
  85. $this->_helper = $helper;
  86. $this->_localeResolver = $localeResolver;
  87. $this->_backendAuthSession = $authSession;
  88. }
  89. /**
  90. * Set backup time
  91. *
  92. * @param int $time
  93. * @return $this
  94. */
  95. public function setTime($time)
  96. {
  97. $this->setData('time', $time);
  98. return $this;
  99. }
  100. /**
  101. * Set backup path
  102. *
  103. * @param string $path
  104. * @return $this
  105. */
  106. public function setPath($path)
  107. {
  108. $this->setData('path', $path);
  109. return $this;
  110. }
  111. /**
  112. * Set backup name
  113. *
  114. * @param string $name
  115. * @return $this
  116. */
  117. public function setName($name)
  118. {
  119. $this->setData('name', $name);
  120. return $this;
  121. }
  122. /**
  123. * Load backup file info
  124. *
  125. * @param string $fileName
  126. * @param string $filePath
  127. * @return $this
  128. */
  129. public function load($fileName, $filePath)
  130. {
  131. $backupData = $this->_helper->extractDataFromFilename($fileName);
  132. $this->addData(
  133. [
  134. 'id' => $filePath . '/' . $fileName,
  135. 'time' => (int)$backupData->getTime(),
  136. 'path' => $filePath,
  137. 'extension' => $this->_helper->getExtensionByType($backupData->getType()),
  138. 'display_name' => $this->_helper->nameToDisplayName($backupData->getName()),
  139. 'name' => $backupData->getName(),
  140. 'date_object' => (new \DateTime())->setTimestamp($backupData->getTime()),
  141. ]
  142. );
  143. $this->setType($backupData->getType());
  144. return $this;
  145. }
  146. /**
  147. * Checks backup file exists.
  148. *
  149. * @return bool
  150. */
  151. public function exists()
  152. {
  153. return $this->varDirectory->isFile($this->_getFilePath());
  154. }
  155. /**
  156. * Return file name of backup file
  157. *
  158. * @return string
  159. */
  160. public function getFileName()
  161. {
  162. $filename = $this->getTime() . "_" . $this->getType();
  163. $backupName = $this->getName();
  164. if (!empty($backupName)) {
  165. $filename .= '_' . $backupName;
  166. }
  167. $filename .= '.' . $this->_helper->getExtensionByType($this->getType());
  168. return $filename;
  169. }
  170. /**
  171. * Sets type of file
  172. *
  173. * @param string $value
  174. * @return $this
  175. */
  176. public function setType($value = 'db')
  177. {
  178. $possibleTypes = $this->_helper->getBackupTypesList();
  179. if (!in_array($value, $possibleTypes)) {
  180. $value = $this->_helper->getDefaultBackupType();
  181. }
  182. $this->_type = $value;
  183. $this->setData('type', $this->_type);
  184. return $this;
  185. }
  186. /**
  187. * Returns type of backup file
  188. *
  189. * @return string
  190. */
  191. public function getType()
  192. {
  193. return $this->_type;
  194. }
  195. /**
  196. * Set the backup file content
  197. *
  198. * @param string &$content
  199. * @return $this
  200. * @throws \Magento\Framework\Exception\LocalizedException
  201. */
  202. public function setFile(&$content)
  203. {
  204. if (!$this->hasData('time') || !$this->hasData('type') || !$this->hasData('path')) {
  205. throw new \Magento\Framework\Exception\LocalizedException(
  206. __('Please correct the order of creation for a new backup.')
  207. );
  208. }
  209. $this->varDirectory->writeFile($this->_getFilePath(), $content);
  210. return $this;
  211. }
  212. /**
  213. * Return content of backup file
  214. *
  215. * @return string
  216. * @throws \Magento\Framework\Exception\LocalizedException
  217. */
  218. public function &getFile()
  219. {
  220. if (!$this->exists()) {
  221. throw new \Magento\Framework\Exception\LocalizedException(__('The backup file does not exist.'));
  222. }
  223. return $this->varDirectory->read($this->_getFilePath());
  224. }
  225. /**
  226. * Delete backup file
  227. *
  228. * @return $this
  229. * @throws \Magento\Framework\Exception\LocalizedException
  230. */
  231. public function deleteFile()
  232. {
  233. if (!$this->exists()) {
  234. throw new \Magento\Framework\Exception\LocalizedException(__('The backup file does not exist.'));
  235. }
  236. $this->varDirectory->delete($this->_getFilePath());
  237. return $this;
  238. }
  239. /**
  240. * Open backup file (write or read mode)
  241. *
  242. * @param bool $write
  243. * @return $this
  244. * @throws \Magento\Framework\Exception\InputException
  245. * @throws \Magento\Framework\Backup\Exception\NotEnoughPermissions
  246. */
  247. public function open($write = false)
  248. {
  249. if ($this->getPath() === null) {
  250. throw new \Magento\Framework\Exception\InputException(__('The backup file path was not specified.'));
  251. }
  252. if ($write && $this->varDirectory->isFile($this->_getFilePath())) {
  253. $this->varDirectory->delete($this->_getFilePath());
  254. }
  255. if (!$write && !$this->varDirectory->isFile($this->_getFilePath())) {
  256. throw new \Magento\Framework\Exception\InputException(
  257. __('The backup file "%1" does not exist.', $this->getFileName())
  258. );
  259. }
  260. $mode = $write ? 'wb' . self::COMPRESS_RATE : 'rb';
  261. try {
  262. /** @var \Magento\Framework\Filesystem\Directory\WriteInterface $varDirectory */
  263. $varDirectory = $this->_filesystem->getDirectoryWrite(DirectoryList::VAR_DIR, DriverPool::ZLIB);
  264. $this->_stream = $varDirectory->openFile(
  265. $this->_getFilePath(),
  266. $mode
  267. );
  268. } catch (\Magento\Framework\Exception\FileSystemException $e) {
  269. throw new \Magento\Framework\Backup\Exception\NotEnoughPermissions(
  270. __('Sorry, but we cannot read from or write to backup file "%1".', $this->getFileName())
  271. );
  272. }
  273. return $this;
  274. }
  275. /**
  276. * Get zlib handler
  277. *
  278. * @return \Magento\Framework\Filesystem\File\WriteInterface
  279. * @throws \Magento\Framework\Exception\InputException
  280. */
  281. protected function _getStream()
  282. {
  283. if ($this->_stream === null) {
  284. throw new \Magento\Framework\Exception\InputException(__('The backup file handler was unspecified.'));
  285. }
  286. return $this->_stream;
  287. }
  288. /**
  289. * Read backup uncompressed data
  290. *
  291. * @param int $length
  292. * @return string
  293. */
  294. public function read($length)
  295. {
  296. return $this->_getStream()->read($length);
  297. }
  298. /**
  299. * Check end of file.
  300. *
  301. * @return bool
  302. */
  303. public function eof()
  304. {
  305. return $this->_getStream()->eof();
  306. }
  307. /**
  308. * Write to backup file
  309. *
  310. * @param string $string
  311. * @return $this
  312. * @throws \Magento\Framework\Exception\InputException
  313. */
  314. public function write($string)
  315. {
  316. try {
  317. $this->_getStream()->write($string);
  318. } catch (\Magento\Framework\Exception\FileSystemException $e) {
  319. throw new \Magento\Framework\Exception\InputException(
  320. __('Something went wrong while writing to the backup file "%1".', $this->getFileName())
  321. );
  322. }
  323. return $this;
  324. }
  325. /**
  326. * Close open backup file
  327. *
  328. * @return $this
  329. */
  330. public function close()
  331. {
  332. $this->_getStream()->close();
  333. $this->_stream = null;
  334. return $this;
  335. }
  336. /**
  337. * Print output
  338. *
  339. * @return string
  340. */
  341. public function output()
  342. {
  343. if (!$this->exists()) {
  344. return;
  345. }
  346. /** @var \Magento\Framework\Filesystem\Directory\ReadInterface $directory */
  347. $directory = $this->_filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
  348. $directory = $directory->readFile($this->_getFilePath());
  349. return $directory;
  350. }
  351. /**
  352. * @return int|mixed
  353. */
  354. public function getSize()
  355. {
  356. if ($this->getData('size') !== null) {
  357. return $this->getData('size');
  358. }
  359. if ($this->exists()) {
  360. $this->setData('size', $this->varDirectory->stat($this->_getFilePath())['size']);
  361. return $this->getData('size');
  362. }
  363. return 0;
  364. }
  365. /**
  366. * Validate user password
  367. *
  368. * @param string $password
  369. * @return bool
  370. */
  371. public function validateUserPassword($password)
  372. {
  373. $userPasswordHash = $this->_backendAuthSession->getUser()->getPassword();
  374. return $this->_encryptor->validateHash($password, $userPasswordHash);
  375. }
  376. /**
  377. * Get file path.
  378. *
  379. * @return string
  380. */
  381. protected function _getFilePath()
  382. {
  383. return $this->varDirectory->getRelativePath($this->getPath() . '/' . $this->getFileName());
  384. }
  385. }