/src/Backup/Target.php

https://github.com/sebastianfeldmann/phpbu · PHP · 460 lines · 183 code · 44 blank · 233 comment · 10 complexity · fdcf2eaf039820ef1f301c29d24d950d MD5 · raw file

  1. <?php
  2. namespace phpbu\App\Backup;
  3. use phpbu\App\Backup\File\Local;
  4. use phpbu\App\Exception;
  5. use phpbu\App\Util;
  6. use SplFileInfo;
  7. /**
  8. * Backup Target class.
  9. *
  10. * @package phpbu
  11. * @subpackage Backup
  12. * @author Sebastian Feldmann <sebastian@phpbu.de>
  13. * @copyright Sebastian Feldmann <sebastian@phpbu.de>
  14. * @license https://opensource.org/licenses/MIT The MIT License (MIT)
  15. * @link https://phpbu.de/
  16. * @since Class available since Release 1.0.0
  17. */
  18. class Target
  19. {
  20. /**
  21. * Path object.
  22. *
  23. * @var Path
  24. */
  25. private $path;
  26. /**
  27. * Backup filename.
  28. *
  29. * @var string
  30. */
  31. private $filename;
  32. /**
  33. * Filename with potential date placeholders like %d.
  34. *
  35. * @var string
  36. */
  37. private $filenameRaw;
  38. /**
  39. * List of custom file suffixes f.e. 'tar'
  40. *
  41. * @var string[]
  42. */
  43. private $fileSuffixes = [];
  44. /**
  45. * Indicates if the filename changes over time.
  46. *
  47. * @var bool
  48. */
  49. private $filenameIsChanging = false;
  50. /**
  51. * Target MIME type
  52. *
  53. * @var string
  54. */
  55. private $mimeType = 'text/plain';
  56. /**
  57. * Size in bytes
  58. *
  59. * @var int
  60. */
  61. private $size;
  62. /**
  63. * Should the file be compressed.
  64. *
  65. * @var bool
  66. */
  67. private $compress = false;
  68. /**
  69. * File compression.
  70. *
  71. * @var \phpbu\App\Backup\Target\Compression
  72. */
  73. private $compression;
  74. /**
  75. * Should the file be encrypted.
  76. *
  77. * @var bool
  78. */
  79. private $crypt = false;
  80. /**
  81. * File crypter.
  82. *
  83. * @var \phpbu\App\Backup\Crypter
  84. */
  85. private $crypter;
  86. /**
  87. * Constructor.
  88. *
  89. * @param string $path
  90. * @param string $filename
  91. * @param integer $time
  92. */
  93. public function __construct($path, $filename, $time = null)
  94. {
  95. $this->path = new Path($path, $time);
  96. $this->setFile($filename, $time);
  97. }
  98. /**
  99. * Filename setter.
  100. *
  101. * @param string $file
  102. * @param int $time
  103. */
  104. public function setFile($file, $time = null)
  105. {
  106. $this->filenameRaw = $file;
  107. if (Util\Path::isContainingPlaceholder($file)) {
  108. $this->filenameIsChanging = true;
  109. $file = Util\Path::replaceDatePlaceholders($file, $time);
  110. }
  111. $this->filename = $file;
  112. }
  113. /**
  114. * Append another suffix to the filename.
  115. *
  116. * @param string $suffix
  117. */
  118. public function appendFileSuffix(string $suffix): void
  119. {
  120. $this->fileSuffixes[] = $suffix;
  121. }
  122. /**
  123. * Remove last file suffix if it matches
  124. *
  125. * @param string $suffix
  126. */
  127. public function removeFileSuffix(string $suffix): void
  128. {
  129. $lastIndex = count($this->fileSuffixes) - 1;
  130. if ($this->fileSuffixes[$lastIndex] === $suffix) {
  131. unset($this->fileSuffixes[$lastIndex]);
  132. }
  133. }
  134. /**
  135. * Checks if the backup target directory is writable.
  136. * Creates the Directory if it doesn't exist.
  137. *
  138. * @throws \phpbu\App\Exception
  139. */
  140. public function setupPath()
  141. {
  142. // if directory doesn't exist, create it
  143. if (!is_dir($this->path->getPath())) {
  144. $reporting = error_reporting();
  145. error_reporting(0);
  146. $created = mkdir($this->path->getPath(), 0755, true);
  147. error_reporting($reporting);
  148. if (!$created) {
  149. throw new Exception(sprintf('cant\'t create directory: %s', $this->path->getPath()));
  150. }
  151. }
  152. if (!is_writable($this->path->getPath())) {
  153. throw new Exception(sprintf('no write permission for directory: %s', $this->path->getPath()));
  154. }
  155. }
  156. /**
  157. * Target file MIME type setter.
  158. *
  159. * @param string $mime
  160. */
  161. public function setMimeType(string $mime)
  162. {
  163. $this->mimeType = $mime;
  164. }
  165. /**
  166. * Return the path to the backup file.
  167. *
  168. * @return Path
  169. */
  170. public function getPath() : Path
  171. {
  172. return $this->path;
  173. }
  174. /**
  175. * Return the name to the backup file.
  176. *
  177. * @param bool $plain
  178. * @return string
  179. */
  180. public function getFilename(bool $plain = false) : string
  181. {
  182. return $this->filename . $this->getFilenameSuffix($plain);
  183. }
  184. /**
  185. * Return the name of the backup file without compressor or encryption suffix.
  186. *
  187. * @return string
  188. */
  189. public function getFilenamePlain() : string
  190. {
  191. return $this->getFilename(true);
  192. }
  193. /**
  194. * Return the raw name of the backup file incl. date placeholder.
  195. *
  196. * @param bool $plain
  197. * @return string
  198. */
  199. public function getFilenameRaw($plain = false) : string
  200. {
  201. return $this->filenameRaw . $this->getFilenameSuffix($plain);
  202. }
  203. /**
  204. * Return custom file suffix like '.tar'.
  205. *
  206. * @param bool $plain
  207. * @return string
  208. */
  209. public function getFilenameSuffix($plain = false) : string
  210. {
  211. return $this->getSuffixToAppend() . ($plain ? '' : $this->getCompressionSuffix() . $this->getCrypterSuffix());
  212. }
  213. /**
  214. * Return added suffixes.
  215. *
  216. * @return string
  217. */
  218. public function getSuffixToAppend() : string
  219. {
  220. return count($this->fileSuffixes) ? '.' . implode('.', $this->fileSuffixes) : '';
  221. }
  222. /**
  223. * Return the compressor suffix.
  224. *
  225. * @return string
  226. */
  227. public function getCompressionSuffix() : string
  228. {
  229. return $this->shouldBeCompressed() ? '.' . $this->compression->getSuffix() : '';
  230. }
  231. /**
  232. * Return the crypter suffix.
  233. *
  234. * @return string
  235. */
  236. public function getCrypterSuffix() : string
  237. {
  238. return $this->shouldBeEncrypted() ? '.' . $this->crypter->getSuffix() : '';
  239. }
  240. /**
  241. * Return file MIME type.
  242. *
  243. * @return string
  244. */
  245. public function getMimeType() : string
  246. {
  247. $mimeType = $this->mimeType;
  248. if ($this->shouldBeCompressed()) {
  249. $mimeType = $this->compression->getMimeType();
  250. }
  251. return $mimeType;
  252. }
  253. /**
  254. * Size setter.
  255. *
  256. * @param int $size
  257. */
  258. public function setSize(int $size)
  259. {
  260. $this->size = $size;
  261. }
  262. /**
  263. * Return the actual file size in bytes.
  264. *
  265. * @return int
  266. * @throws \phpbu\App\Exception
  267. */
  268. public function getSize() : int
  269. {
  270. if (null === $this->size) {
  271. if (!file_exists($this)) {
  272. throw new Exception(sprintf('target file \'%s\' doesn\'t exist', $this->getFilename()));
  273. }
  274. $this->size = filesize($this);
  275. }
  276. return $this->size;
  277. }
  278. /**
  279. * Target file exists already.
  280. *
  281. * @param bool $plain
  282. * @return bool
  283. */
  284. public function fileExists(bool $plain = false) : bool
  285. {
  286. return file_exists($this->getPathname($plain));
  287. }
  288. /**
  289. * Return as backup file object.
  290. *
  291. * @return \phpbu\App\Backup\File\Local
  292. */
  293. public function toFile() : Local
  294. {
  295. return new Local(new SplFileInfo($this->getPathname()));
  296. }
  297. /**
  298. * Return path and filename of the backup file.
  299. *
  300. * @param bool $plain
  301. * @return string
  302. */
  303. public function getPathname(bool $plain = false) : string
  304. {
  305. return $this->path->getPath() . DIRECTORY_SEPARATOR . $this->getFilename($plain);
  306. }
  307. /**
  308. * Return path and plain filename of the backup file.
  309. *
  310. * @return string
  311. */
  312. public function getPathnamePlain() : string
  313. {
  314. return $this->getPathname(true);
  315. }
  316. /**
  317. * Filename configured with any date placeholders.
  318. *
  319. * @return bool
  320. */
  321. public function hasChangingFilename() : bool
  322. {
  323. return $this->filenameIsChanging;
  324. }
  325. /**
  326. * Disable file compression.
  327. */
  328. public function disableCompression()
  329. {
  330. $this->compress = false;
  331. }
  332. /**
  333. * Enable file compression.
  334. *
  335. * @throws \phpbu\App\Exception
  336. */
  337. public function enableCompression()
  338. {
  339. if (null == $this->compression) {
  340. throw new Exception('can\'t enable compression without a compressor');
  341. }
  342. $this->compress = true;
  343. }
  344. /**
  345. * Compression setter.
  346. *
  347. * @param \phpbu\App\Backup\Target\Compression $compression
  348. */
  349. public function setCompression(Target\Compression $compression)
  350. {
  351. $this->compression = $compression;
  352. $this->compress = true;
  353. }
  354. /**
  355. * Compressor getter.
  356. *
  357. * @return \phpbu\App\Backup\Target\Compression
  358. */
  359. public function getCompression() : Target\Compression
  360. {
  361. return $this->compression;
  362. }
  363. /**
  364. * Is a compressor set?
  365. *
  366. * @return bool
  367. */
  368. public function shouldBeCompressed() : bool
  369. {
  370. return $this->compress !== false;
  371. }
  372. /**
  373. * Crypter setter.
  374. *
  375. * @param \phpbu\App\Backup\Crypter $crypter
  376. */
  377. public function setCrypter(Crypter $crypter)
  378. {
  379. $this->crypter = $crypter;
  380. $this->crypt = true;
  381. }
  382. /**
  383. * Crypter getter.
  384. *
  385. * @return \phpbu\App\Backup\Crypter
  386. */
  387. public function getCrypter() : Crypter
  388. {
  389. return $this->crypter;
  390. }
  391. /**
  392. * Disable file encryption.
  393. */
  394. public function disableEncryption()
  395. {
  396. $this->crypt = false;
  397. }
  398. /**
  399. * Is a crypter set?
  400. *
  401. * @return bool
  402. */
  403. public function shouldBeEncrypted() : bool
  404. {
  405. return $this->crypt !== false;
  406. }
  407. /**
  408. * Magic to string method.
  409. *
  410. * @return string
  411. */
  412. public function __toString() : string
  413. {
  414. return $this->getPathname();
  415. }
  416. }