PluginProbe ʕ •ᴥ•ʔ
WP Mail SMTP by WPForms – The Most Popular SMTP and Email Log Plugin / 4.7.0
WP Mail SMTP by WPForms – The Most Popular SMTP and Email Log Plugin v4.7.0
0.9.6 1.0.0 1.0.1 1.0.2 1.1.0 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.6.0 1.6.2 1.7.0 1.7.1 1.8.0 1.8.1 1.9.0 2.0.0 2.0.1 2.1.1 2.2.1 2.3.1 2.4.0 2.5.0 2.5.1 2.6.0 2.7.0 2.8.0 2.9.0 3.0.1 3.0.2 3.0.3 3.1.0 3.10.0 3.11.0 3.11.1 3.2.0 3.2.1 3.3.0 3.4.0 3.5.0 3.5.1 3.5.2 3.6.1 3.7.0 3.8.0 3.8.2 3.9.0 4.0.1 4.1.0 4.1.1 4.2.0 4.3.0 4.4.0 4.5.0 4.6.0 4.7.0 4.7.1 4.8.0 trunk 0.10.0 0.10.1 0.11.1 0.11.2 0.3.1 0.3.2 0.4 0.4.1 0.4.2 0.5.0 0.5.1 0.5.2 0.6 0.7 0.8 0.8.2 0.8.3 0.8.4 0.8.5 0.8.6 0.8.7 0.9.0 0.9.1 0.9.2 0.9.3 0.9.4 0.9.5
wp-mail-smtp / src / Queue / Attachments.php
wp-mail-smtp / src / Queue Last commit date
Attachments.php 6 months ago Email.php 6 months ago Migration.php 6 months ago Queue.php 6 months ago
Attachments.php
243 lines
1 <?php
2
3 namespace WPMailSMTP\Queue;
4
5 use RecursiveDirectoryIterator;
6 use RecursiveIteratorIterator;
7 use WPMailSMTP\Uploads;
8
9 /**
10 * Class Attachments.
11 *
12 * @since 4.0.0
13 */
14 class Attachments {
15
16 /**
17 * Process a list of file attachments.
18 *
19 * @since 4.0.0
20 *
21 * @param array $attachments List of attachments.
22 *
23 * @return array List of attachments.
24 */
25 public function process_attachments( $attachments ) {
26
27 $attachments = array_map(
28 function( $attachment ) {
29 [ $path, , $name, , , $is_string_attachment ] = $attachment;
30
31 $path = $this->process_attachment( $path, $name, $is_string_attachment );
32
33 if ( ! empty( $path ) ) {
34 $attachment[0] = $path;
35 }
36
37 return $attachment;
38 },
39 $attachments
40 );
41
42 return $attachments;
43 }
44
45 /**
46 * Process an attachment,obfuscating its path
47 * and storing its file on disk.
48 *
49 * @since 4.0.0
50 *
51 * @param string $path The path to obfuscate.
52 * @param string $name The name of the file at $path.
53 * @param bool $is_string_attachment Whether this attachment is a string attachment.
54 *
55 * @return string|false New path of the attachment, or false for no path.
56 */
57 private function process_attachment( $path, $name = '', $is_string_attachment = false ) {
58
59 $file_content = $this->get_attachment_file_content( $path, $is_string_attachment );
60
61 if ( $file_content === false ) {
62 return false;
63 }
64
65 if ( ! $is_string_attachment && $name === '' ) {
66 $name = wp_basename( $path );
67 }
68
69 $name = sanitize_file_name( $name );
70 $obfuscated_path = $this->store_file( $file_content, $name );
71
72 if ( empty( $obfuscated_path ) ) {
73 return $path;
74 }
75
76 return $obfuscated_path;
77 }
78
79 /**
80 * Return the contents of a given file.
81 *
82 * @since 4.0.0
83 *
84 * @param string $path The file's path.
85 * @param bool $is_string_attachment Whether this file is a string attachment.
86 *
87 * @return string File contents.
88 */
89 private function get_attachment_file_content( $path, $is_string_attachment ) {
90
91 if ( ! $is_string_attachment ) {
92 if ( ! file_exists( $path ) ) {
93 return false;
94 }
95
96 return file_get_contents( $path );
97 }
98
99 return $path;
100 }
101
102 /**
103 * Store a file.
104 *
105 * @since 4.0.0
106 *
107 * @param string $file_content The file's contents.
108 * @param string $original_filename The original file's name.
109 *
110 * @return string The file's path.
111 */
112 private function store_file( $file_content, $original_filename ) {
113
114 $uploads_directory = $this->get_uploads_directory();
115
116 if ( is_wp_error( $uploads_directory ) ) {
117 return false;
118 }
119
120 if ( ! is_dir( $uploads_directory ) ) {
121 wp_mkdir_p( $uploads_directory );
122
123 // Check if the .htaccess exists in the root upload directory, if not - create it.
124 Uploads::create_upload_dir_htaccess_file();
125
126 // Check if the index.html exists in the directories, if not - create them.
127 Uploads::create_index_html_file( Uploads::upload_dir()['path'] );
128 Uploads::create_index_html_file( $uploads_directory );
129 }
130
131 $file_extension = pathinfo( $original_filename, PATHINFO_EXTENSION );
132 $filename = wp_unique_filename( $uploads_directory, wp_generate_password( 32, false, false ) . '.' . $file_extension );
133 $uploads_directory = trailingslashit( $uploads_directory );
134
135 if ( ! is_writeable( $uploads_directory ) ) {
136 return false;
137 }
138
139 $upload_path = $uploads_directory . $filename;
140
141 if ( file_put_contents( $upload_path, $file_content ) !== false ) { // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_file_put_contents
142 return $upload_path;
143 }
144
145 return false;
146 }
147
148 /**
149 * Delete attachments, removing their files from disk.
150 *
151 * @since 4.0.0
152 *
153 * @param null|array $attachments List of attachments to cleanup, or null for all attachments.
154 * @param null|DateTime $before_datetime The datetime attachments should be older than
155 * to be removed, or null for all attachments.
156 *
157 * @return void.
158 */
159 public function delete_attachments( $attachments = null, $before_datetime = null ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh
160
161 $uploads_directory = $this->get_uploads_directory();
162
163 if (
164 is_wp_error( $uploads_directory ) ||
165 ! is_dir( $uploads_directory )
166 ) {
167 return;
168 }
169
170 $files = [];
171
172 // If no attachment list is provided, just iterate over all files in our uploads directory.
173 if ( is_null( $attachments ) ) {
174 $nodes = new RecursiveIteratorIterator(
175 new RecursiveDirectoryIterator( $uploads_directory, RecursiveDirectoryIterator::SKIP_DOTS ),
176 RecursiveIteratorIterator::CHILD_FIRST
177 );
178 $files = [];
179
180 foreach ( $nodes as $fileinfo ) {
181 if ( ! $fileinfo->isDir() ) {
182 $files[] = $fileinfo->getRealPath();
183 }
184 }
185 } else {
186 // Map attachments to their paths.
187 $files = wp_list_pluck( $attachments, 0 );
188
189 // Exclude any files that aren't in our uploads directory.
190 $files = array_filter(
191 $files,
192 function( $file ) use ( $uploads_directory ) {
193 return trailingslashit( dirname( $file ) ) === $uploads_directory;
194 }
195 );
196 }
197
198 // Skip any file that doesn't exist.
199 $files = array_filter(
200 $files,
201 function( $file ) {
202 return file_exists( $file );
203 }
204 );
205
206 if ( ! is_null( $before_datetime ) ) {
207 // Skip any file that isn't older than the provided datetime.
208 $before_timestamp = $before_datetime->getTimestamp();
209 $files = array_filter(
210 $files,
211 function( $file ) use ( $before_timestamp ) {
212 return (
213 filemtime( $file ) !== false &&
214 filemtime( $file ) < $before_timestamp
215 );
216 }
217 );
218 }
219
220 foreach ( $files as $file ) {
221 @unlink( $file );
222 }
223 }
224
225 /**
226 * Get the upload directory path.
227 *
228 * @since 4.0.0
229 *
230 * @return string|WP_Error The upload directory path.
231 */
232 private function get_uploads_directory() {
233
234 $uploads_directory = Uploads::upload_dir();
235
236 if ( is_wp_error( $uploads_directory ) ) {
237 return $uploads_directory;
238 }
239
240 return trailingslashit( trailingslashit( $uploads_directory['path'] ) . 'queue_attachments' );
241 }
242 }
243