/includes/submission.php

  1. <?php 
  2.  
  3. class WPCF7_Submission { 
  4.  
  5. private static $instance; 
  6.  
  7. private $contact_form; 
  8. private $status = 'init'; 
  9. private $posted_data = array(); 
  10. private $uploaded_files = array(); 
  11. private $skip_mail = false; 
  12. private $response = ''; 
  13. private $invalid_fields = array(); 
  14. private $meta = array(); 
  15.  
  16. private function __construct() {} 
  17.  
  18. public static function get_instance( WPCF7_ContactForm $contact_form = null ) { 
  19. if ( empty( self::$instance ) ) { 
  20. if ( null == $contact_form ) { 
  21. return null; 
  22.  
  23. self::$instance = new self; 
  24. self::$instance->contact_form = $contact_form; 
  25. self::$instance->skip_mail = $contact_form->in_demo_mode(); 
  26. self::$instance->setup_posted_data(); 
  27. self::$instance->submit(); 
  28. } elseif ( null != $contact_form ) { 
  29. return null; 
  30.  
  31. return self::$instance; 
  32.  
  33. public function get_status() { 
  34. return $this->status; 
  35.  
  36. public function is( $status ) { 
  37. return $this->status == $status; 
  38.  
  39. public function get_response() { 
  40. return $this->response; 
  41.  
  42. public function get_invalid_field( $name ) { 
  43. if ( isset( $this->invalid_fields[$name] ) ) { 
  44. return $this->invalid_fields[$name]; 
  45. } else { 
  46. return false; 
  47.  
  48. public function get_invalid_fields() { 
  49. return $this->invalid_fields; 
  50.  
  51. public function get_posted_data( $name = '' ) { 
  52. if ( ! empty( $name ) ) { 
  53. if ( isset( $this->posted_data[$name] ) ) { 
  54. return $this->posted_data[$name]; 
  55. } else { 
  56. return null; 
  57.  
  58. return $this->posted_data; 
  59.  
  60. private function setup_posted_data() { 
  61. $posted_data = (array) $_POST; 
  62. $posted_data = array_diff_key( $posted_data, array( '_wpnonce' => '' ) ); 
  63. $posted_data = $this->sanitize_posted_data( $posted_data ); 
  64.  
  65. $tags = $this->contact_form->scan_form_tags(); 
  66.  
  67. foreach ( (array) $tags as $tag ) { 
  68. if ( empty( $tag['name'] ) ) { 
  69. continue; 
  70.  
  71. $name = $tag['name']; 
  72. $value = ''; 
  73.  
  74. if ( isset( $posted_data[$name] ) ) { 
  75. $value = $posted_data[$name]; 
  76.  
  77. $pipes = $tag['pipes']; 
  78.  
  79. if ( WPCF7_USE_PIPE 
  80. && $pipes instanceof WPCF7_Pipes 
  81. && ! $pipes->zero() ) { 
  82. if ( is_array( $value) ) { 
  83. $new_value = array(); 
  84.  
  85. foreach ( $value as $v ) { 
  86. $new_value[] = $pipes->do_pipe( wp_unslash( $v ) ); 
  87.  
  88. $value = $new_value; 
  89. } else { 
  90. $value = $pipes->do_pipe( wp_unslash( $value ) ); 
  91.  
  92. $posted_data[$name] = $value; 
  93.  
  94. $this->posted_data = apply_filters( 'wpcf7_posted_data', $posted_data ); 
  95.  
  96. return $this->posted_data; 
  97.  
  98. private function sanitize_posted_data( $value ) { 
  99. if ( is_array( $value ) ) { 
  100. $value = array_map( array( $this, 'sanitize_posted_data' ), $value ); 
  101. } elseif ( is_string( $value ) ) { 
  102. $value = wp_check_invalid_utf8( $value ); 
  103. $value = wp_kses_no_null( $value ); 
  104.  
  105. return $value; 
  106.  
  107. private function submit() { 
  108. if ( ! $this->is( 'init' ) ) { 
  109. return $this->status; 
  110.  
  111. $this->meta = array( 
  112. 'remote_ip' => $this->get_remote_ip_addr(),  
  113. 'user_agent' => isset( $_SERVER['HTTP_USER_AGENT'] ) 
  114. ? substr( $_SERVER['HTTP_USER_AGENT'], 0, 254 ) : '',  
  115. 'url' => preg_replace( '%(?<!:|/)/.*$%', '',  
  116. untrailingslashit( home_url() ) ) . wpcf7_get_request_uri(),  
  117. 'timestamp' => current_time( 'timestamp' ),  
  118. 'unit_tag' => 
  119. isset( $_POST['_wpcf7_unit_tag'] ) ? $_POST['_wpcf7_unit_tag'] : '',  
  120. ); 
  121.  
  122. $contact_form = $this->contact_form; 
  123.  
  124. if ( ! $this->validate() ) { // Validation error occured 
  125. $this->status = 'validation_failed'; 
  126. $this->response = $contact_form->message( 'validation_error' ); 
  127.  
  128. } elseif ( ! $this->accepted() ) { // Not accepted terms 
  129. $this->status = 'acceptance_missing'; 
  130. $this->response = $contact_form->message( 'accept_terms' ); 
  131.  
  132. } elseif ( $this->spam() ) { // Spam! 
  133. $this->status = 'spam'; 
  134. $this->response = $contact_form->message( 'spam' ); 
  135.  
  136. } elseif ( $this->mail() ) { 
  137. $this->status = 'mail_sent'; 
  138. $this->response = $contact_form->message( 'mail_sent_ok' ); 
  139.  
  140. do_action( 'wpcf7_mail_sent', $contact_form ); 
  141.  
  142. } else { 
  143. $this->status = 'mail_failed'; 
  144. $this->response = $contact_form->message( 'mail_sent_ng' ); 
  145.  
  146. do_action( 'wpcf7_mail_failed', $contact_form ); 
  147.  
  148. $this->remove_uploaded_files(); 
  149.  
  150. return $this->status; 
  151.  
  152. private function get_remote_ip_addr() { 
  153. if ( isset( $_SERVER['REMOTE_ADDR'] ) 
  154. && WP_Http::is_ip_address( $_SERVER['REMOTE_ADDR'] ) ) { 
  155. return $_SERVER['REMOTE_ADDR']; 
  156.  
  157. return ''; 
  158.  
  159. private function validate() { 
  160. if ( $this->invalid_fields ) { 
  161. return false; 
  162.  
  163. require_once WPCF7_PLUGIN_DIR . '/includes/validation.php'; 
  164. $result = new WPCF7_Validation(); 
  165.  
  166. $tags = $this->contact_form->scan_form_tags(); 
  167.  
  168. foreach ( $tags as $tag ) { 
  169. $type = $tag['type']; 
  170. $result = apply_filters( "wpcf7_validate_{$type}", $result, $tag ); 
  171.  
  172. $result = apply_filters( 'wpcf7_validate', $result, $tags ); 
  173.  
  174. $this->invalid_fields = $result->get_invalid_fields(); 
  175.  
  176. return $result->is_valid(); 
  177.  
  178. private function accepted() { 
  179. return apply_filters( 'wpcf7_acceptance', true ); 
  180.  
  181. private function spam() { 
  182. $spam = false; 
  183.  
  184. $user_agent = (string) $this->get_meta( 'user_agent' ); 
  185.  
  186. if ( strlen( $user_agent ) < 2 ) { 
  187. $spam = true; 
  188.  
  189. if ( WPCF7_VERIFY_NONCE && ! $this->verify_nonce() ) { 
  190. $spam = true; 
  191.  
  192. if ( $this->blacklist_check() ) { 
  193. $spam = true; 
  194.  
  195. return apply_filters( 'wpcf7_spam', $spam ); 
  196.  
  197. private function verify_nonce() { 
  198. return wpcf7_verify_nonce( $_POST['_wpnonce'], $this->contact_form->id() ); 
  199.  
  200. private function blacklist_check() { 
  201. $target = wpcf7_array_flatten( $this->posted_data ); 
  202. $target[] = $this->get_meta( 'remote_ip' ); 
  203. $target[] = $this->get_meta( 'user_agent' ); 
  204.  
  205. $target = implode( "\n", $target ); 
  206.  
  207. return wpcf7_blacklist_check( $target ); 
  208.  
  209. /** Mail */ 
  210.  
  211. private function mail() { 
  212. $contact_form = $this->contact_form; 
  213.  
  214. do_action( 'wpcf7_before_send_mail', $contact_form ); 
  215.  
  216. $skip_mail = $this->skip_mail || ! empty( $contact_form->skip_mail ); 
  217. $skip_mail = apply_filters( 'wpcf7_skip_mail', $skip_mail, $contact_form ); 
  218.  
  219. if ( $skip_mail ) { 
  220. return true; 
  221.  
  222. $result = WPCF7_Mail::send( $contact_form->prop( 'mail' ), 'mail' ); 
  223.  
  224. if ( $result ) { 
  225. $additional_mail = array(); 
  226.  
  227. if ( ( $mail_2 = $contact_form->prop( 'mail_2' ) ) && $mail_2['active'] ) { 
  228. $additional_mail['mail_2'] = $mail_2; 
  229.  
  230. $additional_mail = apply_filters( 'wpcf7_additional_mail',  
  231. $additional_mail, $contact_form ); 
  232.  
  233. foreach ( $additional_mail as $name => $template ) { 
  234. WPCF7_Mail::send( $template, $name ); 
  235.  
  236. return true; 
  237.  
  238. return false; 
  239.  
  240. public function uploaded_files() { 
  241. return $this->uploaded_files; 
  242.  
  243. public function add_uploaded_file( $name, $file_path ) { 
  244. $this->uploaded_files[$name] = $file_path; 
  245.  
  246. if ( empty( $this->posted_data[$name] ) ) { 
  247. $this->posted_data[$name] = basename( $file_path ); 
  248.  
  249. public function remove_uploaded_files() { 
  250. foreach ( (array) $this->uploaded_files as $name => $path ) { 
  251. wpcf7_rmdir_p( $path ); 
  252. @rmdir( dirname( $path ) ); // remove parent dir if it's removable (empty). 
  253.  
  254. public function get_meta( $name ) { 
  255. if ( isset( $this->meta[$name] ) ) { 
  256. return $this->meta[$name]; 
.