0 && class_exists('GFForms') ? 'gravity' : 'native'; } public static function in_use_note($competition_id) { $gf = class_exists('AIEO_Competition_CPT') ? (int) get_post_meta((int) $competition_id, AIEO_Competition_CPT::META_GF, true) : 0; if ('gravity' === self::form_in_use($competition_id)) { $form = class_exists('GFAPI') ? GFAPI::get_form($gf) : null; $title = is_array($form) && '' !== (string) ($form['title'] ?? '') ? (string) $form['title'] : '#' . $gf; return sprintf(__('Entries come through the linked Gravity Forms form “%s”.', 'ai-eshop-optimizer'), $title); } if ($gf > 0) { return sprintf(__('Gravity Forms is inactive, so the competition’s built-in entry form takes the entries (first and last name, e-mail, the newsletter box and the terms). Form #%d takes them again once Gravity Forms is active.', 'ai-eshop-optimizer'), $gf); } return __('No Gravity Forms form is linked, so the competition’s built-in entry form takes the entries: first and last name, e-mail, the newsletter box and the terms. Entrants the shop does not know confirm their entry by e-mail.', 'ai-eshop-optimizer'); } public static function native_entry_id($email) { return self::NATIVE_BASE + (int) hexdec(substr(md5('aieo-comp-native|' . strtolower(trim((string) $email))), 0, 15)); } private static function words() { return array( 'button' => __('Enter the competition', 'ai-eshop-optimizer'), 'sending' => __('Sending…', 'ai-eshop-optimizer'), 'check' => __('Please correct the highlighted fields.', 'ai-eshop-optimizer'), 'network' => __('The request could not be sent. Please check your connection and try again.', 'ai-eshop-optimizer'), 'pending' => __('Thank you for entering. We have sent you an e-mail: confirm your address with its link to take part in the draw.', 'ai-eshop-optimizer'), 'confirmed' => __('Thank you: your entry is confirmed and takes part in the draw.', 'ai-eshop-optimizer'), 'already' => __('You have already entered this competition with this e-mail address, and your entry takes part in the draw.', 'ai-eshop-optimizer'), 'closed' => __('This competition is not taking entries now.', 'ai-eshop-optimizer'), ); } public static function render($competition_id) { $cid = (int) $competition_id; if (class_exists('AIEO_Form_Render')) { AIEO_Form_Render::register_assets(); wp_enqueue_style(AIEO_Form_Render::STYLE); if (function_exists('wp_enqueue_script_module')) { wp_enqueue_script_module(AIEO_Form_Render::MODULE); } } $w = self::words(); $base = 'aieo-comp-entry-' . $cid; $req = ''; $text = static function ($key, $type, $label, $autocomplete, $required, $missing, $invalid, $width) use ($base, $req) { $id = $base . '-' . $key; $extra = 'email' === $type ? ' inputmode="email" spellcheck="false"' : ''; return '
' . '' . '' . '
'; }; $pre = class_exists('AIEO_Competition_Participants') ? AIEO_Competition_Participants::consent_preticked() : true; $html = '
'; $html .= '
'; $html .= '
'; $html .= '
'; $html .= $text('first_name', 'text', __('First name', 'ai-eshop-optimizer'), 'given-name', true, __('Your first name, please.', 'ai-eshop-optimizer'), '', 'aieo-form__half'); $html .= $text('last_name', 'text', __('Last name', 'ai-eshop-optimizer'), 'family-name', false, '', '', 'aieo-form__half'); $html .= $text('email', 'email', __('E-mail', 'ai-eshop-optimizer'), 'email', true, __('Your e-mail address, please: the confirmation is sent there.', 'ai-eshop-optimizer'), __('An e-mail address like name@example.com, please.', 'ai-eshop-optimizer'), 'aieo-form__full'); if (class_exists('AIEO_Competition_Participants')) { $cid_id = $base . '-consent'; $html .= '
' . '' . '' . '' . '' . '' . '
'; } $terms_id = $base . '-terms'; $terms_url = class_exists('AIEO_Competition_CPT') ? AIEO_Competition_CPT::terms_url($cid) : ''; $terms_text = '' !== $terms_url ? sprintf( esc_html__('I accept the %1$sterms of this competition%2$s.', 'ai-eshop-optimizer'), '', ' ' . esc_html__('(opens in a new tab)', 'ai-eshop-optimizer') . '' ) : esc_html__('I accept the terms of this competition.', 'ai-eshop-optimizer'); $html .= '
' . '' . '' . '
'; $html .= ''; $html .= '
'; $html .= '
'; $result = self::posted_result($cid); $html .= '

' . ($result ? esc_html($result['message']) : '') . '

'; $html .= '' . '' . '' . '' . '' . (class_exists('AIEO_Form_Submit') ? AIEO_Form_Submit::captcha_field() : ''); $html .= '
'; return $html; } public static function ajax_submit() { $r = self::process(self::submission()); $payload = array('message' => $r['message'], 'errors' => $r['errors']); if ($r['ok']) { wp_send_json_success($payload); } wp_send_json_error($payload); } public static function post_submit() { $post = self::submission(); $r = self::process($post); $cid = isset($post['aieo_competition_id']) ? absint($post['aieo_competition_id']) : 0; $page = $cid > 0 ? (string) get_permalink($cid) : ''; $back = '' !== $page ? $page : (class_exists('AIEO_Form_Submit') ? AIEO_Form_Submit::referer() : ''); $back = '' !== $back ? wp_validate_redirect($back, home_url('/')) : home_url('/'); $url = add_query_arg(self::RESULT_ARG, $r['ok'] ? ('' !== $r['code'] ? $r['code'] : 'pending') : ('' !== $r['code'] ? $r['code'] : 'error'), remove_query_arg(self::RESULT_ARG, $back)); wp_safe_redirect($url . '#aieo-comp-entry-' . $cid); exit; } private static function submission() { if (!isset($_POST['aieo_form_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['aieo_form_nonce'])), AIEO_Form_Submit::NONCE)) { $keep = array(); foreach (array('aieo_competition_id', 'aieo_form_website', 'aieo_form_ts', 'elapsed') as $key) { if (isset($_POST[$key]) && is_scalar($_POST[$key])) { $keep[$key] = sanitize_text_field(wp_unslash((string) $_POST[$key])); } } return $keep; } return (array) map_deep(wp_unslash($_POST), 'sanitize_textarea_field'); } public static function process(array $post) { $w = self::words(); $out = array('ok' => false, 'message' => '', 'errors' => array(), 'code' => '', 'participant_id' => 0); $cid = isset($post['aieo_competition_id']) ? absint($post['aieo_competition_id']) : 0; if (!self::open($cid)) { $out['code'] = 'closed'; $out['message'] = $w['closed']; return $out; } if (AIEO_Form_Submit::is_bot()) { return self::refuse($out, 'refused'); } $silent = array('ok' => true, 'message' => $w['pending'], 'errors' => array(), 'code' => '', 'participant_id' => 0); if (!empty($post['aieo_form_website']) || AIEO_Form_Submit::elapsed($post) < AIEO_Form_Submit::MIN_SECONDS) { return $silent; } $nonce = isset($post['aieo_form_nonce']) && is_scalar($post['aieo_form_nonce']) ? sanitize_text_field((string) $post['aieo_form_nonce']) : ''; if (!wp_verify_nonce($nonce, AIEO_Form_Submit::NONCE)) { return self::refuse($out, 'expired'); } if (!AIEO_Form_Submit::rate_ok('comp_ip', AIEO_Form_Submit::IP_LIMIT, AIEO_Form_Submit::IP_WINDOW)) { return self::refuse($out, 'rate'); } $captcha = AIEO_Form_Submit::captcha_check(); if (is_wp_error($captcha)) { $out['code'] = 'captcha'; $out['message'] = $captcha->get_error_message(); return $out; } $v = self::validate(isset($post['aieo_form']) && is_array($post['aieo_form']) ? $post['aieo_form'] : array()); if ($v['errors']) { $out['errors'] = $v['errors']; $out['code'] = 'invalid'; $out['message'] = $w['check']; return $out; } $email = $v['values']['email']; if (!AIEO_Form_Submit::rate_ok('comp_email', AIEO_Form_Submit::EMAIL_LIMIT, AIEO_Form_Submit::EMAIL_WINDOW, strtolower($email))) { return self::refuse($out, 'rate'); } $once = isset($post['aieo_form_once']) ? preg_replace('/[^A-Za-z0-9-]/', '', (string) $post['aieo_form_once']) : ''; $seen = '' !== $once ? 'aieo_comp_once_' . md5($cid . '|' . $once) : ''; if ('' !== $seen && get_transient($seen)) { return $silent; } AIEO_Competition_Participants::maybe_install(); $key = self::native_entry_id($email); $prev = AIEO_Competition_Participants::find_entry($cid, $key); if ($prev && 'pending' !== $prev['status']) { return array('ok' => true, 'message' => $w['already'], 'errors' => array(), 'code' => 'already', 'participant_id' => $prev['participant_id']); } $entry = AIEO_Competition_Participants::record_entry($cid, $key, $email, $v['values']['first_name'], $v['values']['last_name']); if ($entry['participant_id'] <= 0) { return self::refuse($out, 'error'); } if ('' !== $seen) { set_transient($seen, $entry['participant_id'], AIEO_Form_Submit::ONCE_WINDOW); } do_action('aieo_submission', array( 'provider' => 'competition', 'goal_key' => 'competition_entry', 'entry_id' => $entry['participant_id'], 'surface' => 'competition_' . $cid, 'email' => $email, 'page_url' => AIEO_Form_Submit::referer(), 'source_key' => 'comp:' . $entry['participant_id'], )); $confirmed = 'confirmed' === $entry['status']; return array('ok' => true, 'message' => $confirmed ? $w['confirmed'] : $w['pending'], 'errors' => array(), 'code' => $confirmed ? 'confirmed' : 'pending', 'participant_id' => $entry['participant_id']); } public static function validate(array $in) { $first = mb_substr(trim(sanitize_text_field((string) ($in['first_name'] ?? ''))), 0, self::NAME_MAX); $last = mb_substr(trim(sanitize_text_field((string) ($in['last_name'] ?? ''))), 0, self::NAME_MAX); $email = sanitize_email((string) ($in['email'] ?? '')); $errors = array(); if ('' === $first) { $errors['first_name'] = __('Your first name, please.', 'ai-eshop-optimizer'); } if ('' === trim((string) ($in['email'] ?? ''))) { $errors['email'] = __('Your e-mail address, please: the confirmation is sent there.', 'ai-eshop-optimizer'); } elseif (!is_email($email)) { $errors['email'] = __('An e-mail address like name@example.com, please.', 'ai-eshop-optimizer'); } if ('1' !== (string) ($in['terms'] ?? '')) { $errors['terms'] = __('Accept the competition’s terms to enter.', 'ai-eshop-optimizer'); } return array('values' => array('first_name' => $first, 'last_name' => $last, 'email' => $email), 'errors' => $errors); } private static function open($cid) { if ($cid <= 0 || !class_exists('AIEO_Competition_CPT') || !class_exists('AIEO_Competition_Participants') || !class_exists('AIEO_Form_Submit')) { return false; } $post = get_post($cid); return $post && AIEO_Competition_CPT::POST_TYPE === $post->post_type && 'publish' === $post->post_status && 'live' === AIEO_Competition_CPT::schedule_state($cid) && 'native' === self::form_in_use($cid); } private static function refuse(array $out, $code) { $out['code'] = (string) $code; $out['message'] = AIEO_Form_Submit::error_message($code); return $out; } private static function posted_result($cid) { $code = isset($_GET[self::RESULT_ARG]) ? sanitize_key(wp_unslash($_GET[self::RESULT_ARG])) : ''; if ('' === $code) { return null; } $w = self::words(); if (in_array($code, array('pending', 'confirmed', 'already'), true)) { return array('state' => 'ok', 'message' => $w[$code]); } if ('closed' === $code) { return array('state' => 'error', 'message' => $w['closed']); } return array('state' => 'error', 'message' => 'invalid' === $code ? $w['check'] : AIEO_Form_Submit::error_message($code)); } } }