PluginProbe ʕ •ᴥ•ʔ
Contact Form 7 / 5.2.2
Contact Form 7 v5.2.2
6.1.6 5.0.2 5.0.3 5.0.4 5.0.5 5.1 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.2 5.2.1 5.2.2 5.3 5.3.1 5.3.2 5.4 5.4.1 5.4.2 5.5 5.5.1 5.5.2 5.5.3 5.5.4 5.5.5 5.5.6 5.5.6.1 5.6 5.6.1 5.6.2 5.6.3 5.6.4 5.7 5.7.1 5.7.2 5.7.3 5.7.4 5.7.5 5.7.5.1 5.7.6 5.7.7 5.8 5.8.1 5.8.2 5.8.3 5.8.4 5.8.5 5.8.6 5.8.7 5.9 5.9.2 5.9.3 5.9.4 5.9.5 5.9.6 5.9.7 5.9.8 6.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.0.6 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 trunk 1.1 1.10 1.10.0.1 1.10.1 1.2 1.3 1.3.1 1.3.2 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.5 1.6 1.6.1 1.7 1.7.1 1.7.2 1.7.4 1.7.5 1.7.6 1.7.6.1 1.7.7 1.7.7.1 1.7.8 1.8 1.8.0.1 1.8.0.2 1.8.0.3 1.8.0.4 1.8.1 1.8.1.1 1.9 1.9.1 1.9.2 1.9.2.1 1.9.2.2 1.9.3 1.9.4 1.9.5 1.9.5.1 2.0 2.0-beta 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1 2.1.1 2.1.2 2.2 2.2.1 2.3 2.3.1 2.4 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 3.0 3.0-beta 3.0.1 3.0.2 3.0.2.1 3.1 3.1.1 3.1.2 3.2 3.2.1 3.3 3.3.1 3.3.2 3.3.3 3.4 3.4.1 3.4.2 3.5 3.5.1 3.5.2 3.5.3 3.5.4 3.6 3.7 3.7.1 3.7.2 3.8 3.8.1 3.9 3.9-beta 3.9.1 3.9.2 3.9.3 4.0 4.0.1 4.0.2 4.0.3 4.1 4.1-beta 4.1.1 4.1.2 4.2 4.2-beta 4.2.1 4.2.2 4.3 4.3.1 4.4 4.4.1 4.4.2 4.5 4.5.1 4.6 4.6.1 4.7 4.8 4.8.1 4.9 4.9.1 4.9.2 5.0 5.0.1
contact-form-7 / includes / mail.php
contact-form-7 / includes Last commit date
css 5 years ago js 5 years ago capabilities.php 7 years ago config-validator.php 5 years ago contact-form-functions.php 5 years ago contact-form-template.php 6 years ago contact-form.php 5 years ago controller.php 7 years ago form-tag.php 5 years ago form-tags-manager.php 6 years ago formatting.php 5 years ago functions.php 5 years ago integration.php 7 years ago l10n.php 7 years ago mail.php 5 years ago pipe.php 5 years ago rest-api.php 5 years ago shortcodes.php 9 years ago special-mail-tags.php 5 years ago submission.php 5 years ago upgrade.php 7 years ago validation.php 7 years ago
mail.php
459 lines
1 <?php
2
3 class WPCF7_Mail {
4
5 private static $current = null;
6
7 private $name = '';
8 private $locale = '';
9 private $template = array();
10 private $use_html = false;
11 private $exclude_blank = false;
12
13 public static function get_current() {
14 return self::$current;
15 }
16
17 public static function send( $template, $name = '' ) {
18 self::$current = new self( $name, $template );
19 return self::$current->compose();
20 }
21
22 private function __construct( $name, $template ) {
23 $this->name = trim( $name );
24 $this->use_html = ! empty( $template['use_html'] );
25 $this->exclude_blank = ! empty( $template['exclude_blank'] );
26
27 $this->template = wp_parse_args( $template, array(
28 'subject' => '',
29 'sender' => '',
30 'body' => '',
31 'recipient' => '',
32 'additional_headers' => '',
33 'attachments' => '',
34 ) );
35
36 if ( $submission = WPCF7_Submission::get_instance() ) {
37 $contact_form = $submission->get_contact_form();
38 $this->locale = $contact_form->locale();
39 }
40 }
41
42 public function name() {
43 return $this->name;
44 }
45
46 public function get( $component, $replace_tags = false ) {
47 $use_html = ( $this->use_html && 'body' == $component );
48 $exclude_blank = ( $this->exclude_blank && 'body' == $component );
49
50 $template = $this->template;
51 $component = isset( $template[$component] ) ? $template[$component] : '';
52
53 if ( $replace_tags ) {
54 $component = $this->replace_tags( $component, array(
55 'html' => $use_html,
56 'exclude_blank' => $exclude_blank,
57 ) );
58
59 if ( $use_html
60 and ! preg_match( '%<html[>\s].*</html>%is', $component ) ) {
61 $component = $this->htmlize( $component );
62 }
63 }
64
65 return $component;
66 }
67
68 private function htmlize( $body ) {
69 if ( $this->locale ) {
70 $lang_atts = sprintf( ' %s',
71 wpcf7_format_atts( array(
72 'dir' => wpcf7_is_rtl( $this->locale ) ? 'rtl' : 'ltr',
73 'lang' => str_replace( '_', '-', $this->locale ),
74 ) )
75 );
76 } else {
77 $lang_atts = '';
78 }
79
80 $header = apply_filters( 'wpcf7_mail_html_header',
81 '<!doctype html>
82 <html xmlns="http://www.w3.org/1999/xhtml"' . $lang_atts . '>
83 <head>
84 <title>' . esc_html( $this->get( 'subject', true ) ) . '</title>
85 </head>
86 <body>
87 ', $this );
88
89 $footer = apply_filters( 'wpcf7_mail_html_footer',
90 '</body>
91 </html>', $this );
92
93 $html = $header . wpautop( $body ) . $footer;
94 return $html;
95 }
96
97 private function compose( $send = true ) {
98 $components = array(
99 'subject' => $this->get( 'subject', true ),
100 'sender' => $this->get( 'sender', true ),
101 'body' => $this->get( 'body', true ),
102 'recipient' => $this->get( 'recipient', true ),
103 'additional_headers' => $this->get( 'additional_headers', true ),
104 'attachments' => $this->attachments(),
105 );
106
107 $components = apply_filters( 'wpcf7_mail_components',
108 $components, wpcf7_get_current_contact_form(), $this
109 );
110
111 if ( ! $send ) {
112 return $components;
113 }
114
115 $subject = wpcf7_strip_newline( $components['subject'] );
116 $sender = wpcf7_strip_newline( $components['sender'] );
117 $recipient = wpcf7_strip_newline( $components['recipient'] );
118 $body = $components['body'];
119 $additional_headers = trim( $components['additional_headers'] );
120 $attachments = $components['attachments'];
121
122 $headers = "From: $sender\n";
123
124 if ( $this->use_html ) {
125 $headers .= "Content-Type: text/html\n";
126 $headers .= "X-WPCF7-Content-Type: text/html\n";
127 } else {
128 $headers .= "X-WPCF7-Content-Type: text/plain\n";
129 }
130
131 if ( $additional_headers ) {
132 $headers .= $additional_headers . "\n";
133 }
134
135 return wp_mail( $recipient, $subject, $body, $headers, $attachments );
136 }
137
138 public function replace_tags( $content, $args = '' ) {
139 if ( true === $args ) {
140 $args = array( 'html' => true );
141 }
142
143 $args = wp_parse_args( $args, array(
144 'html' => false,
145 'exclude_blank' => false,
146 ) );
147
148 return wpcf7_mail_replace_tags( $content, $args );
149 }
150
151 private function attachments( $template = null ) {
152 if ( ! $template ) {
153 $template = $this->get( 'attachments' );
154 }
155
156 $attachments = array();
157
158 if ( $submission = WPCF7_Submission::get_instance() ) {
159 $uploaded_files = $submission->uploaded_files();
160
161 foreach ( (array) $uploaded_files as $name => $path ) {
162 if ( false !== strpos( $template, "[${name}]" )
163 and ! empty( $path ) ) {
164 $attachments[] = $path;
165 }
166 }
167 }
168
169 foreach ( explode( "\n", $template ) as $line ) {
170 $line = trim( $line );
171
172 if ( '[' == substr( $line, 0, 1 ) ) {
173 continue;
174 }
175
176 $path = path_join( WP_CONTENT_DIR, $line );
177
178 if ( ! wpcf7_is_file_path_in_content_dir( $path ) ) {
179 // $path is out of WP_CONTENT_DIR
180 continue;
181 }
182
183 if ( is_readable( $path )
184 and is_file( $path ) ) {
185 $attachments[] = $path;
186 }
187 }
188
189 return $attachments;
190 }
191 }
192
193 function wpcf7_mail_replace_tags( $content, $args = '' ) {
194 $args = wp_parse_args( $args, array(
195 'html' => false,
196 'exclude_blank' => false,
197 ) );
198
199 if ( is_array( $content ) ) {
200 foreach ( $content as $key => $value ) {
201 $content[$key] = wpcf7_mail_replace_tags( $value, $args );
202 }
203
204 return $content;
205 }
206
207 $content = explode( "\n", $content );
208
209 foreach ( $content as $num => $line ) {
210 $line = new WPCF7_MailTaggedText( $line, $args );
211 $replaced = $line->replace_tags();
212
213 if ( $args['exclude_blank'] ) {
214 $replaced_tags = $line->get_replaced_tags();
215
216 if ( empty( $replaced_tags )
217 or array_filter( $replaced_tags, 'strlen' ) ) {
218 $content[$num] = $replaced;
219 } else {
220 unset( $content[$num] ); // Remove a line.
221 }
222 } else {
223 $content[$num] = $replaced;
224 }
225 }
226
227 $content = implode( "\n", $content );
228
229 return $content;
230 }
231
232 add_action( 'phpmailer_init', 'wpcf7_phpmailer_init', 10, 1 );
233
234 function wpcf7_phpmailer_init( $phpmailer ) {
235 $custom_headers = $phpmailer->getCustomHeaders();
236 $phpmailer->clearCustomHeaders();
237 $wpcf7_content_type = false;
238
239 foreach ( (array) $custom_headers as $custom_header ) {
240 $name = $custom_header[0];
241 $value = $custom_header[1];
242
243 if ( 'X-WPCF7-Content-Type' === $name ) {
244 $wpcf7_content_type = trim( $value );
245 } else {
246 $phpmailer->addCustomHeader( $name, $value );
247 }
248 }
249
250 if ( 'text/html' === $wpcf7_content_type ) {
251 $phpmailer->msgHTML( $phpmailer->Body );
252 } elseif ( 'text/plain' === $wpcf7_content_type ) {
253 $phpmailer->AltBody = '';
254 }
255 }
256
257 class WPCF7_MailTaggedText {
258
259 private $html = false;
260 private $callback = null;
261 private $content = '';
262 private $replaced_tags = array();
263
264 public function __construct( $content, $args = '' ) {
265 $args = wp_parse_args( $args, array(
266 'html' => false,
267 'callback' => null,
268 ) );
269
270 $this->html = (bool) $args['html'];
271
272 if ( null !== $args['callback']
273 and is_callable( $args['callback'] ) ) {
274 $this->callback = $args['callback'];
275 } elseif ( $this->html ) {
276 $this->callback = array( $this, 'replace_tags_callback_html' );
277 } else {
278 $this->callback = array( $this, 'replace_tags_callback' );
279 }
280
281 $this->content = $content;
282 }
283
284 public function get_replaced_tags() {
285 return $this->replaced_tags;
286 }
287
288 public function replace_tags() {
289 $regex = '/(\[?)\[[\t ]*'
290 . '([a-zA-Z_][0-9a-zA-Z:._-]*)' // [2] = name
291 . '((?:[\t ]+"[^"]*"|[\t ]+\'[^\']*\')*)' // [3] = values
292 . '[\t ]*\](\]?)/';
293
294 return preg_replace_callback( $regex, $this->callback, $this->content );
295 }
296
297 private function replace_tags_callback_html( $matches ) {
298 return $this->replace_tags_callback( $matches, true );
299 }
300
301 private function replace_tags_callback( $matches, $html = false ) {
302 // allow [[foo]] syntax for escaping a tag
303 if ( $matches[1] == '['
304 and $matches[4] == ']' ) {
305 return substr( $matches[0], 1, -1 );
306 }
307
308 $tag = $matches[0];
309 $tagname = $matches[2];
310 $values = $matches[3];
311
312 $mail_tag = new WPCF7_MailTag( $tag, $tagname, $values );
313 $field_name = $mail_tag->field_name();
314
315 $submission = WPCF7_Submission::get_instance();
316 $submitted = $submission
317 ? $submission->get_posted_data( $field_name )
318 : null;
319
320 if ( $mail_tag->get_option( 'do_not_heat' ) ) {
321 $submitted = isset( $_POST[$field_name] ) ? $_POST[$field_name] : '';
322 }
323
324 $replaced = $submitted;
325
326 if ( null !== $replaced ) {
327 if ( $format = $mail_tag->get_option( 'format' ) ) {
328 $replaced = $this->format( $replaced, $format );
329 }
330
331 $replaced = wpcf7_flat_join( $replaced );
332
333 if ( $html ) {
334 $replaced = esc_html( $replaced );
335 $replaced = wptexturize( $replaced );
336 }
337 }
338
339 if ( $form_tag = $mail_tag->corresponding_form_tag() ) {
340 $type = $form_tag->type;
341
342 $replaced = apply_filters(
343 "wpcf7_mail_tag_replaced_{$type}", $replaced,
344 $submitted, $html, $mail_tag
345 );
346 }
347
348 $replaced = apply_filters(
349 'wpcf7_mail_tag_replaced', $replaced,
350 $submitted, $html, $mail_tag
351 );
352
353 if ( null !== $replaced ) {
354 $replaced = wp_unslash( trim( $replaced ) );
355
356 $this->replaced_tags[$tag] = $replaced;
357 return $replaced;
358 }
359
360 $special = apply_filters( 'wpcf7_special_mail_tags', null,
361 $mail_tag->tag_name(), $html, $mail_tag
362 );
363
364 if ( null !== $special ) {
365 $this->replaced_tags[$tag] = $special;
366 return $special;
367 }
368
369 return $tag;
370 }
371
372 public function format( $original, $format ) {
373 $original = (array) $original;
374
375 foreach ( $original as $key => $value ) {
376 if ( preg_match( '/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/', $value ) ) {
377 $datetime = date_create( $value, wp_timezone() );
378
379 if ( false !== $datetime ) {
380 $original[$key] = wp_date( $format, $datetime->getTimestamp() );
381 }
382 }
383 }
384
385 return $original;
386 }
387 }
388
389 class WPCF7_MailTag {
390
391 private $tag;
392 private $tagname = '';
393 private $name = '';
394 private $options = array();
395 private $values = array();
396 private $form_tag = null;
397
398 public function __construct( $tag, $tagname, $values ) {
399 $this->tag = $tag;
400 $this->name = $this->tagname = $tagname;
401
402 $this->options = array(
403 'do_not_heat' => false,
404 'format' => '',
405 );
406
407 if ( ! empty( $values ) ) {
408 preg_match_all( '/"[^"]*"|\'[^\']*\'/', $values, $matches );
409 $this->values = wpcf7_strip_quote_deep( $matches[0] );
410 }
411
412 if ( preg_match( '/^_raw_(.+)$/', $tagname, $matches ) ) {
413 $this->name = trim( $matches[1] );
414 $this->options['do_not_heat'] = true;
415 }
416
417 if ( preg_match( '/^_format_(.+)$/', $tagname, $matches ) ) {
418 $this->name = trim( $matches[1] );
419 $this->options['format'] = $this->values[0];
420 }
421 }
422
423 public function tag_name() {
424 return $this->tagname;
425 }
426
427 public function field_name() {
428 return $this->name;
429 }
430
431 public function get_option( $option ) {
432 return $this->options[$option];
433 }
434
435 public function values() {
436 return $this->values;
437 }
438
439 public function corresponding_form_tag() {
440 if ( $this->form_tag instanceof WPCF7_FormTag ) {
441 return $this->form_tag;
442 }
443
444 if ( $submission = WPCF7_Submission::get_instance() ) {
445 $contact_form = $submission->get_contact_form();
446 $tags = $contact_form->scan_form_tags( array(
447 'name' => $this->name,
448 'feature' => '! zero-controls-container',
449 ) );
450
451 if ( $tags ) {
452 $this->form_tag = $tags[0];
453 }
454 }
455
456 return $this->form_tag;
457 }
458 }
459