Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 48 |
|
0.00% |
0 / 6 |
CRAP | |
0.00% |
0 / 1 |
AppArchiver | |
0.00% |
0 / 48 |
|
0.00% |
0 / 6 |
182 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getDirectory | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getFiles | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
backup | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
2 | |||
rotate | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
12 | |||
sendLatestArchive | |
0.00% |
0 / 25 |
|
0.00% |
0 / 1 |
42 |
1 | <?php |
2 | |
3 | declare(strict_types=1); |
4 | |
5 | namespace PeServer\App\Models\Domain; |
6 | |
7 | use Exception; |
8 | use PeServer\App\Models\AppConfiguration; |
9 | use PeServer\App\Models\AppDatabaseConnection; |
10 | use PeServer\App\Models\AppMailer; |
11 | use PeServer\Core\Archiver; |
12 | use PeServer\Core\Binary; |
13 | use PeServer\Core\Collection\Arr; |
14 | use PeServer\Core\Environment; |
15 | use PeServer\Core\IO\Directory; |
16 | use PeServer\Core\IO\File; |
17 | use PeServer\Core\IO\Path; |
18 | use PeServer\Core\Log\ILogger; |
19 | use PeServer\Core\Log\ILoggerFactory; |
20 | use PeServer\Core\Mail\Attachment; |
21 | use PeServer\Core\Mail\EmailAddress; |
22 | use PeServer\Core\Mail\EmailMessage; |
23 | use PeServer\Core\Mvc\ILogicFactory; |
24 | use PeServer\Core\Text; |
25 | use PeServer\Core\Throws\InvalidOperationException; |
26 | use PeServer\Core\Utc; |
27 | use ZipArchive; |
28 | |
29 | class AppArchiver |
30 | { |
31 | #region define |
32 | |
33 | /** 保持ファイル数。 */ |
34 | private const MAX_COUNT = 180; |
35 | |
36 | #endregion |
37 | |
38 | #region property |
39 | |
40 | private ILogger $logger; |
41 | |
42 | #endregion |
43 | |
44 | public function __construct( |
45 | private Environment $environment, |
46 | private AppConfiguration $config, |
47 | private AppMailer $mailer, |
48 | ILoggerFactory $loggerFactory, |
49 | ) { |
50 | $this->logger = $loggerFactory->createLogger($this); |
51 | } |
52 | |
53 | public function getDirectory(): string |
54 | { |
55 | return $this->config->setting->cache->backup; |
56 | } |
57 | |
58 | /** |
59 | * アーカイブファイル一覧の取得。 |
60 | * |
61 | * @return string[] |
62 | */ |
63 | public function getFiles(): array |
64 | { |
65 | return Directory::find($this->getDirectory(), '*.zip'); |
66 | } |
67 | |
68 | public function backup(): int |
69 | { |
70 | $revision = $this->environment->getRevision(); |
71 | $fileName = Utc::create()->format('Y-m-d\_His') . "_{$revision}.zip"; |
72 | $filePath = Path::combine($this->getDirectory(), $fileName); |
73 | Directory::createParentDirectoryIfNotExists($filePath); |
74 | |
75 | $zipArchive = new ZipArchive(); |
76 | $zipArchive->open($filePath, ZipArchive::CREATE | ZipArchive::EXCL); |
77 | |
78 | //DB保存 |
79 | $databasePath = AppDatabaseConnection::getSqliteFilePath($this->config->setting->persistence->default->connection); |
80 | $zipArchive->addFile($databasePath, Path::getFileName($databasePath)); |
81 | // 設定ファイル保存 |
82 | $settingName = Path::setEnvironmentName('setting.json', $this->environment->get()); |
83 | $settingPath = Path::combine($this->config->settingDirectoryPath, $settingName); |
84 | $zipArchive->addFile($settingPath, $settingName); |
85 | |
86 | $zipArchive->close(); |
87 | |
88 | return File::getFileSize($filePath); |
89 | } |
90 | |
91 | public function rotate(): void |
92 | { |
93 | $backupFiles = $this->getFiles(); |
94 | $logCount = Arr::getCount($backupFiles); |
95 | if ($logCount <= self::MAX_COUNT) { |
96 | return; |
97 | } |
98 | |
99 | $length = $logCount - self::MAX_COUNT; |
100 | for ($i = 0; $i < $length; $i++) { |
101 | File::removeFile($backupFiles[$i]); |
102 | } |
103 | } |
104 | |
105 | public function sendLatestArchive(string $subject, bool $ignoreError): void |
106 | { |
107 | $backupFiles = $this->getFiles(); |
108 | if (Arr::isNullOrEmpty($backupFiles)) { |
109 | if ($ignoreError) { |
110 | return; |
111 | } |
112 | throw new InvalidOperationException(); |
113 | } |
114 | |
115 | $backupFilePath = $backupFiles[count($backupFiles) - 1]; |
116 | $backupFileName = Path::getFileName($backupFilePath); |
117 | assert(!Text::isNullOrWhiteSpace($backupFileName)); |
118 | |
119 | $this->mailer->subject = "[Backup] {$subject} {$backupFileName}"; |
120 | $this->mailer->setMessage(new EmailMessage( |
121 | "バックアップ実施" |
122 | )); |
123 | $this->mailer->attachments[] = new Attachment( |
124 | $backupFileName, |
125 | File::readContent($backupFilePath) |
126 | ); |
127 | |
128 | foreach ($this->config->setting->config->address->notify->maintenance as $email) { |
129 | $this->mailer->toAddresses = [ |
130 | new EmailAddress($email), |
131 | ]; |
132 | |
133 | try { |
134 | $this->mailer->send(); |
135 | } catch (Exception $ex) { |
136 | $this->logger->error($ex); |
137 | if (!$ignoreError) { |
138 | throw $ex; |
139 | } |
140 | } |
141 | } |
142 | } |
143 | } |