PluginProbe ʕ •ᴥ•ʔ
WP STAGING – WordPress Backups, Restore, Migration & Clone / trunk
WP STAGING – WordPress Backups, Restore, Migration & Clone vtrunk
4.11.1 4.11.0 4.10.0 4.9.5 4.9.4 4.9.3 4.9.2 4.9.1 4.9.0 4.8.1 trunk 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.10.0 3.2.0 3.3.1 3.3.2 3.3.3 3.4.1 3.4.3 3.5.0 3.6.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.8.7 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4 4.0.0 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.7.2 4.7.3 4.8.0
wp-staging / Framework / Filesystem / DiskWriteCheck.php
wp-staging / Framework / Filesystem Last commit date
Filters 6 days ago Scanning 6 days ago AbstractFileObject.php 6 days ago AbstractFilesystemScanner.php 6 days ago DebugLogReader.php 6 days ago DirectoryListing.php 6 days ago DirectorySize.php 6 days ago DiskWriteCheck.php 6 days ago FileObject.php 6 days ago Filesystem.php 6 days ago FilesystemExceptions.php 5 years ago FilesystemScanner.php 6 days ago FilesystemScannerDto.php 6 days ago FilterableDirectoryIterator.php 6 days ago LegacyFileRulesTrait.php 6 days ago LogCleanup.php 6 days ago LogFiles.php 6 days ago MissingFileException.php 3 years ago OPcache.php 6 days ago PartIdentifier.php 6 days ago PathChecker.php 6 days ago PathIdentifier.php 6 days ago Permissions.php 6 days ago WpUploadsFolderSymlinker.php 6 days ago
DiskWriteCheck.php
150 lines
1 <?php
2
3 namespace WPStaging\Framework\Filesystem;
4
5 use WPStaging\Framework\Adapter\Directory;
6 use WPStaging\Framework\Facades\Hooks;
7 use WPStaging\Framework\Job\Exception\DiskNotWritableException;
8
9 class DiskWriteCheck
10 {
11
12 const OPTION_DISK_WRITABLE_FAILED = 'wpstg_disk_writable_check_failed';
13
14
15 const FILTER_FILESYSTEM_DISABLED_DISK_FREE_SPACE_CHECK = 'wpstg.filesystem.disableDiskFreeSpaceCheck';
16
17 protected $directory;
18
19 protected $filesystem;
20
21 protected $reservedMemory;
22
23 public function __construct(Filesystem $filesystem, Directory $directory)
24 {
25 $this->directory = $directory;
26 $this->filesystem = $filesystem;
27
28 $this->reservedMemory = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
29 }
30
31
32
33
34
35
36
37
38 public function checkPathCanStoreEnoughBytes($path, $bytesToStore)
39 {
40
41 if (Hooks::applyFilters(self::FILTER_FILESYSTEM_DISABLED_DISK_FREE_SPACE_CHECK, false)) {
42 throw new \RuntimeException();
43 }
44
45
46 if (!function_exists('disk_free_space')) {
47 throw new \RuntimeException('The disk_free_space function is not available.');
48 }
49
50 $path = untrailingslashit($path);
51
52 clearstatcache();
53 if (!file_exists($path)) {
54 throw new \RuntimeException('The given path does not exist.');
55 }
56
57 if (is_link($path)) {
58 throw new \RuntimeException('The given path must be a directory.');
59 }
60
61 if (!is_dir($path)) {
62 throw new \RuntimeException('The path must be a directory.');
63 }
64
65 $freeSpaceInBytes = @disk_free_space($path);
66
67 if ($freeSpaceInBytes === false) {
68 $message = '';
69 $error = error_get_last();
70
71 if (is_array($error) && array_key_exists('message', $error)) {
72 $message = $error['message'];
73 }
74
75 throw new \RuntimeException($message);
76 }
77
78 if (!is_numeric($freeSpaceInBytes)) {
79 throw new \RuntimeException('disk_free_space returned an unexpected result');
80 }
81
82 if ($freeSpaceInBytes - $bytesToStore < 0) {
83 throw DiskNotWritableException::willExceedFreeDiskSpace(abs($freeSpaceInBytes - $bytesToStore));
84 }
85 }
86
87
88
89
90 public function hasDiskWriteTestFailed()
91 {
92 if (get_option(self::OPTION_DISK_WRITABLE_FAILED) === 'fail') {
93 throw DiskNotWritableException::diskNotWritable();
94 }
95 }
96
97
98
99
100
101
102 public function testDiskIsWriteable()
103 {
104 $destination = $this->directory->getPluginUploadsDirectory() . '.wpstgDiskWriteCheck';
105
106 if (file_exists($destination)) {
107 unlink($destination);
108 }
109
110
111 if (@file_put_contents($destination, $this->reservedMemory)) {
112 unlink($destination);
113
114 delete_option(self::OPTION_DISK_WRITABLE_FAILED);
115
116 return true;
117 }
118
119
120 $result = $this->setLowLevelDiskFullFlag();
121
122 $this->filesystem->delete($this->directory->getCacheDirectory());
123
124
125 if (!$result) {
126 $result = $this->setLowLevelDiskFullFlag();
127 }
128
129 $this->filesystem->delete($this->directory->getTmpDirectory());
130
131
132 if (!$result) {
133 $result = $this->setLowLevelDiskFullFlag();
134
135 if (!$result) {
136 \WPStaging\functions\debug_log('WP STAGING DiskWriteCheck failed and could not update the option in the database.');
137 }
138 }
139
140 throw DiskNotWritableException::diskNotWritable();
141 }
142
143 protected function setLowLevelDiskFullFlag()
144 {
145 global $wpdb;
146
147 return $wpdb->query($wpdb->prepare("INSERT INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`)", self::OPTION_DISK_WRITABLE_FAILED, 'fail', 'no'));
148 }
149 }
150