MC4WP_Request

Class MC4WP_Request.

Defined (1)

The class is defined in the following location(s).

/includes/class-request.php  
  1. abstract class MC4WP_Request implements iMC4WP_Request { 
  2.  
  3. /** 
  4. * @var string 
  5. */ 
  6. protected $mailchimp_error = ''; 
  7.  
  8. /** 
  9. * @var MC4WP_Form 
  10. */ 
  11. protected $form; 
  12.  
  13. /** 
  14. * @var string 
  15. */ 
  16. public $form_element_id = ''; 
  17.  
  18. /** 
  19. * @var string 
  20. */ 
  21. protected $message_type = ''; 
  22.  
  23. /** 
  24. * @var bool 
  25. */ 
  26. public $success = false; 
  27.  
  28. /** 
  29. * @var array 
  30. */ 
  31. public $internal_data = array(); 
  32.  
  33. /** 
  34. * @var array 
  35. */ 
  36. public $user_data = array(); 
  37.  
  38.  
  39. /** 
  40. * Constructor 
  41. * @param array $data 
  42. */ 
  43. public function __construct( array $data ) { 
  44.  
  45. // find fields prefixed with _mc4wp_ 
  46. $this->internal_data = $this->get_internal_data( $data ); 
  47.  
  48. // normalize user data 
  49. $this->user_data = $this->normalize_data( $data ); 
  50.  
  51. // store number of submitted form 
  52. $this->form_element_id = (string) $this->internal_data['form_element_id']; 
  53.  
  54. // get form 
  55. $this->form = MC4WP_Form::get( $this ); 
  56.  
  57. /** 
  58. * @param $data 
  59. * @return array 
  60. */ 
  61. public function get_internal_data( &$data ) { 
  62. $config = array(); 
  63.  
  64. foreach( $data as $key => $value ) { 
  65. if( stripos( $key, '_mc4wp_' ) === 0 ) { 
  66.  
  67. // remove data from array 
  68. unset( $data[$key] ); 
  69.  
  70. $key = substr( $key, 7 ); 
  71. $config[ $key ] = $value; 
  72.  
  73. return $config; 
  74.  
  75. /** 
  76. * @param array $data 
  77. * @return array 
  78. */ 
  79. protected function normalize_data( array $data ) { 
  80.  
  81. // uppercase all data keys 
  82. $data = array_change_key_case( $data, CASE_UPPER ); 
  83.  
  84. // strip slashes on everything 
  85. $data = stripslashes_deep( $data ); 
  86.  
  87. // sanitize all scalar values 
  88. $data = $this->sanitize_deep( $data ); 
  89.  
  90. /** 
  91. * @filter `mc4wp_form_data` 
  92. * @expects array 
  93. */ 
  94. $data = apply_filters( 'mc4wp_form_data', $data ); 
  95.  
  96. return (array) $data; 
  97.  
  98. /** 
  99. * @param $value 
  100. * @return array|string 
  101. */ 
  102. public function sanitize_deep( $value ) { 
  103.  
  104. if ( is_scalar( $value ) ) { 
  105. $value = sanitize_text_field( $value ); 
  106. } elseif( is_array( $value ) ) { 
  107. $value = array_map( array( $this, 'sanitize_deep' ), $value ); 
  108. } elseif ( is_object($value) ) { 
  109. $vars = get_object_vars( $value ); 
  110. foreach ($vars as $key=>$data) { 
  111. $value->{$key} = $this->sanitize_deep( $data ); 
  112.  
  113. return $value; 
  114.  
  115. /** 
  116. * Validates the request 
  117. * - Nonce validity 
  118. * - Honeypot 
  119. * - Captcha 
  120. * - Email address 
  121. * - Lists (POST and options) 
  122. * - Additional validation using a filter. 
  123. * @return bool 
  124. */ 
  125. public function validate() { 
  126.  
  127. $validator = new MC4WP_Form_Validator( $this->internal_data, $this->user_data ); 
  128.  
  129. // validate nonce 
  130. if( ! $validator->validate_nonce() ) { 
  131. $this->message_type = 'invalid_nonce'; 
  132. return false; 
  133.  
  134. // ensure honeypot was given but not filled 
  135. if( ! $validator->validate_honeypot() ) { 
  136. $this->message_type = 'spam'; 
  137. return false; 
  138.  
  139. // check timestamp difference, token should be generated at least 2 seconds before form submit 
  140. if( ! $validator->validate_timestamp() ) { 
  141. $this->message_type = 'spam'; 
  142. return false; 
  143.  
  144. // check if captcha was present and valid 
  145. if( ! $validator->validate_captcha() ) { 
  146. $this->message_type = 'invalid_captcha'; 
  147. return false; 
  148.  
  149. // validate email 
  150. if( ! $validator->validate_email() ) { 
  151. $this->message_type = 'invalid_email'; 
  152. return false; 
  153.  
  154. // validate selected or submitted lists 
  155. if( ! $validator->validate_lists( $this->get_lists() ) ) { 
  156. $this->message_type = 'no_lists_selected'; 
  157. return false; 
  158.  
  159. // run custom validation (using filter) 
  160. $custom_validation = $validator->custom_validation(); 
  161. if( $custom_validation !== true ) { 
  162. $this->message_type = $custom_validation; 
  163. return false; 
  164.  
  165. // finally, return true 
  166. return true; 
  167.  
  168. /** 
  169. * Get the final Redirect URL with replaced variables 
  170. * @return string 
  171. */ 
  172. protected function get_redirect_url() { 
  173. $additional_replacements = array( 
  174. '{form_id}' => $this->form->ID,  
  175. '{form_element}' => $this->form_element_id,  
  176. '{email}' => urlencode( $this->user_data['EMAIL'] ) 
  177. ); 
  178. $url = MC4WP_Tools::replace_variables( $this->form->settings['redirect'], $additional_replacements ); 
  179. return $url; 
  180.  
  181. /** 
  182. * Send HTTP response 
  183. */ 
  184. public function respond() { 
  185.  
  186. // do stuff on success, non-AJAX only 
  187. if( $this->success ) { 
  188.  
  189. /** 
  190. * @action mc4wp_form_success 
  191. * Use to hook into successful form sign-ups 
  192. * @param int $form_id The ID of the submitted form (PRO ONLY) 
  193. * @param string $email The email of the subscriber 
  194. * @param array $data Additional list fields, like FNAME etc (if any) 
  195. */ 
  196. do_action( 'mc4wp_form_success', 0, $this->user_data['EMAIL'], $this->user_data ); 
  197.  
  198. // check if we want to redirect the visitor 
  199. if ( ! empty( $this->form->settings['redirect'] ) ) { 
  200. wp_redirect( $this->get_redirect_url() ); 
  201. exit; 
  202.  
  203. } else { 
  204.  
  205. /** 
  206. * @action mc4wp_form_error_{ERROR_CODE} 
  207. * Use to hook into various sign-up errors. Hook names are: 
  208. * - mc4wp_form_error_error General errors 
  209. * - mc4wp_form_error_invalid_email Invalid email address 
  210. * - mc4wp_form_error_already_subscribed Email is already on selected list(s) 
  211. * - mc4wp_form_error_required_field_missing One or more required fields are missing 
  212. * - mc4wp_form_error_no_lists_selected No MailChimp lists were selected 
  213. * @param int $form_id The ID of the submitted form (PRO ONLY) 
  214. * @param string $email The email of the subscriber 
  215. * @param array $data Additional list fields, like FNAME etc (if any) 
  216. */ 
  217. do_action( 'mc4wp_form_error_' . $this->message_type, 0, $this->user_data['EMAIL'], $this->user_data ); 
  218.  
  219.  
  220.  
  221. /** 
  222. * Get MailChimp List(s) to subscribe to 
  223. * @return array Array of selected MailChimp lists 
  224. */ 
  225. public function get_lists() { 
  226.  
  227. $lists = $this->form->settings['lists']; 
  228.  
  229. // get lists from form, if set. 
  230. if( isset( $this->internal_data['lists'] ) && ! empty( $this->internal_data['lists'] ) ) { 
  231.  
  232. $lists = $this->internal_data['lists']; 
  233.  
  234. // make sure lists is an array 
  235. if( ! is_array( $lists ) ) { 
  236. $lists = sanitize_text_field( $lists ); 
  237. $lists = array( $lists ); 
  238.  
  239.  
  240. // allow plugins to alter the lists to subscribe to 
  241. $lists = apply_filters( 'mc4wp_lists', $lists ); 
  242.  
  243. return (array) $lists; 
  244.  
  245. /** 
  246. * Returns the HTML for success or error messages 
  247. * @return string 
  248. */ 
  249. public function get_response_html( ) { 
  250.  
  251. // get all form messages 
  252. $messages = $this->form->get_messages(); 
  253.  
  254. // retrieve correct message 
  255. $message = ( isset( $messages[ $this->message_type ] ) ) ? $messages[ $this->message_type ] : $messages['error']; 
  256.  
  257. // replace variables in message text 
  258. $message['text'] = MC4WP_Tools::replace_variables( $message['text'], array(), array_values( $this->get_lists() ) ); 
  259.  
  260. $html = '<div class="mc4wp-alert mc4wp-' . esc_attr( $message['type'] ) . '">' . $message['text'] . '</div>'; 
  261.  
  262. // show additional MailChimp API errors to administrators 
  263. if( ! $this->success && current_user_can( 'manage_options' ) ) { 
  264.  
  265. if( '' !== $this->mailchimp_error ) { 
  266. $html .= '<div class="mc4wp-alert mc4wp-error"><strong>Admin notice:</strong> '. $this->mailchimp_error . '</div>'; 
  267.  
  268. return $html; 
  269.