File "submission.php"

Full path: /home/kosmetik/public_html/wp-content/plugins/contact-form-7/includes/submission.php
File size: 17.79 B
MIME-type: text/x-php
Charset: utf-8

Download   Open   Edit   Advanced Editor   Back

<?php

class WPCF7_Submission
{
    private static $instance;
    private $contact_form;
    private $status = 'init';
    private $posted_data = array();
    private $posted_data_hash = null;
    private $skip_spam_check = false;
    private $uploaded_files = array();
    private $extra_attachments = array();
    private $skip_mail = false;
    private $response = '';
    private $invalid_fields = array();
    private $meta = array();
    private $consent = array();
    private $spam_log = array();
    private $result_props = array();
    public static function get_instance($contact_form = null, $args = '')
    {
        if ($contact_form instanceof WPCF7_ContactForm) {
            if (empty(self::$instance)) {
                self::$instance = new self($contact_form, $args);
                self::$instance->proceed();
                return self::$instance;
            } else {
                return null;
            }
        } else {
            if (empty(self::$instance)) {
                return null;
            } else {
                return self::$instance;
            }
        }
    }
    public static function is_restful()
    {
        return defined('REST_REQUEST') && REST_REQUEST;
    }
    private function __construct(WPCF7_ContactForm $contact_form, $args = '')
    {
        $args = wp_parse_args($args, array('skip_mail' => false));
        $this->contact_form = $contact_form;
        $this->skip_mail = (bool) $args['skip_mail'];
    }
    private function proceed()
    {
        $contact_form = $this->contact_form;
        switch_to_locale($contact_form->locale());
        $this->setup_meta_data();
        $this->setup_posted_data();
        if ($this->is('init') and !$this->validate()) {
            $this->set_status('validation_failed');
            $this->set_response($contact_form->message('validation_error'));
        }
        if ($this->is('init') and !$this->accepted()) {
            $this->set_status('acceptance_missing');
            $this->set_response($contact_form->message('accept_terms'));
        }
        if ($this->is('init') and $this->spam()) {
            $this->set_status('spam');
            $this->set_response($contact_form->message('spam'));
        }
        if ($this->is('init') and !$this->unship_uploaded_files()) {
            $this->set_status('validation_failed');
            $this->set_response($contact_form->message('validation_error'));
        }
        if ($this->is('init')) {
            $abort = !$this->before_send_mail();
            if ($abort) {
                if ($this->is('init')) {
                    $this->set_status('aborted');
                }
                if ('' === $this->get_response()) {
                    $this->set_response($contact_form->filter_message(__("Sending mail has been aborted.", 'contact-form-7')));
                }
            } elseif ($this->mail()) {
                $this->set_status('mail_sent');
                $this->set_response($contact_form->message('mail_sent_ok'));
                do_action('wpcf7_mail_sent', $contact_form);
            } else {
                $this->set_status('mail_failed');
                $this->set_response($contact_form->message('mail_sent_ng'));
                do_action('wpcf7_mail_failed', $contact_form);
            }
        }
        restore_previous_locale();
        $this->remove_uploaded_files();
    }
    public function get_status()
    {
        return $this->status;
    }
    public function set_status($status)
    {
        if (preg_match('/^[a-z][0-9a-z_]+$/', $status)) {
            $this->status = $status;
            return true;
        }
        return false;
    }
    public function is($status)
    {
        return $this->status == $status;
    }
    public function get_result()
    {
        $result = array_merge($this->result_props, array('status' => $this->get_status(), 'message' => $this->get_response()));
        if ($this->is('validation_failed')) {
            $result['invalid_fields'] = $this->get_invalid_fields();
        }
        switch ($this->get_status()) {
            case 'init':
            case 'validation_failed':
            case 'acceptance_missing':
            case 'spam':
                $result['posted_data_hash'] = '';
                break;
            default:
                $result['posted_data_hash'] = $this->get_posted_data_hash();
                break;
        }
        $result = apply_filters('wpcf7_submission_result', $result, $this);
        return $result;
    }
    public function add_result_props($args = '')
    {
        $args = wp_parse_args($args, array());
        $this->result_props = array_merge($this->result_props, $args);
        return $args;
    }
    public function get_response()
    {
        return $this->response;
    }
    public function set_response($response)
    {
        $this->response = $response;
        return true;
    }
    public function get_contact_form()
    {
        return $this->contact_form;
    }
    public function get_invalid_field($name)
    {
        if (isset($this->invalid_fields[$name])) {
            return $this->invalid_fields[$name];
        } else {
            return false;
        }
    }
    public function get_invalid_fields()
    {
        return $this->invalid_fields;
    }
    public function get_meta($name)
    {
        if (isset($this->meta[$name])) {
            return $this->meta[$name];
        }
    }
    private function setup_meta_data()
    {
        $timestamp = time();
        $remote_ip = $this->get_remote_ip_addr();
        $remote_port = isset($_SERVER['REMOTE_PORT']) ? (int) $_SERVER['REMOTE_PORT'] : '';
        $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? substr($_SERVER['HTTP_USER_AGENT'], 0, 254) : '';
        $url = $this->get_request_url();
        $unit_tag = isset($_POST['_wpcf7_unit_tag']) ? wpcf7_sanitize_unit_tag($_POST['_wpcf7_unit_tag']) : '';
        $container_post_id = isset($_POST['_wpcf7_container_post']) ? (int) $_POST['_wpcf7_container_post'] : 0;
        $current_user_id = get_current_user_id();
        $do_not_store = $this->contact_form->is_true('do_not_store');
        $this->meta = array('timestamp' => $timestamp, 'remote_ip' => $remote_ip, 'remote_port' => $remote_port, 'user_agent' => $user_agent, 'url' => $url, 'unit_tag' => $unit_tag, 'container_post_id' => $container_post_id, 'current_user_id' => $current_user_id, 'do_not_store' => $do_not_store);
        return $this->meta;
    }
    public function get_posted_data($name = '')
    {
        if (!empty($name)) {
            if (isset($this->posted_data[$name])) {
                return $this->posted_data[$name];
            } else {
                return null;
            }
        }
        return $this->posted_data;
    }
    private function setup_posted_data()
    {
        $posted_data = array_filter((array) $_POST, function ($key) {
            return '_' !== substr($key, 0, 1);
        }, ARRAY_FILTER_USE_KEY);
        $posted_data = wp_unslash($posted_data);
        $posted_data = $this->sanitize_posted_data($posted_data);
        $tags = $this->contact_form->scan_form_tags();
        foreach ((array) $tags as $tag) {
            if (empty($tag->name)) {
                continue;
            }
            $type = $tag->type;
            $name = $tag->name;
            $pipes = $tag->pipes;
            if (wpcf7_form_tag_supports($type, 'do-not-store')) {
                unset($posted_data[$name]);
                continue;
            }
            $value_orig = $value = '';
            if (isset($posted_data[$name])) {
                $value_orig = $value = $posted_data[$name];
            }
            if (WPCF7_USE_PIPE and $pipes instanceof WPCF7_Pipes and !$pipes->zero()) {
                if (is_array($value_orig)) {
                    $value = array();
                    foreach ($value_orig as $v) {
                        $value[] = $pipes->do_pipe($v);
                    }
                } else {
                    $value = $pipes->do_pipe($value_orig);
                }
            }
            if (wpcf7_form_tag_supports($type, 'selectable-values')) {
                $value = (array) $value;
                if ($tag->has_option('free_text') and isset($posted_data[$name . '_free_text'])) {
                    $last_val = array_pop($value);
                    list($tied_item) = array_slice(WPCF7_USE_PIPE ? $tag->pipes->collect_afters() : $tag->values, -1, 1);
                    list($last_val, $tied_item) = array_map(function ($item) {
                        return wpcf7_canonicalize($item, array('strto' => 'as-is'));
                    }, array($last_val, $tied_item));
                    if ($last_val === $tied_item) {
                        $value[] = sprintf('%s %s', $last_val, $posted_data[$name . '_free_text']);
                    } else {
                        $value[] = $last_val;
                    }
                    unset($posted_data[$name . '_free_text']);
                }
            }
            $value = apply_filters("wpcf7_posted_data_{$type}", $value, $value_orig, $tag);
            $posted_data[$name] = $value;
            if ($tag->has_option('consent_for:storage') and empty($posted_data[$name])) {
                $this->meta['do_not_store'] = true;
            }
        }
        $this->posted_data = apply_filters('wpcf7_posted_data', $posted_data);
        $this->posted_data_hash = $this->create_posted_data_hash();
        return $this->posted_data;
    }
    private function sanitize_posted_data($value)
    {
        if (is_array($value)) {
            $value = array_map(array($this, 'sanitize_posted_data'), $value);
        } elseif (is_string($value)) {
            $value = wp_check_invalid_utf8($value);
            $value = wp_kses_no_null($value);
        }
        return $value;
    }
    private function posted_data_hash_tick()
    {
        return ceil(time() / (HOUR_IN_SECONDS / 2));
    }
    private function create_posted_data_hash($tick = '')
    {
        if ('' === $tick) {
            $tick = $this->posted_data_hash_tick();
        }
        $hash = wp_hash(wpcf7_flat_join(array_merge(array($tick, $this->get_meta('remote_ip'), $this->get_meta('unit_tag')), $this->posted_data)), 'wpcf7_submission');
        return $hash;
    }
    public function get_posted_data_hash()
    {
        return $this->posted_data_hash;
    }
    public function verify_posted_data_hash($hash = '')
    {
        if ('' === $hash and !empty($_POST['_wpcf7_posted_data_hash'])) {
            $hash = trim($_POST['_wpcf7_posted_data_hash']);
        }
        if ('' === $hash) {
            return false;
        }
        $tick = $this->posted_data_hash_tick();
        $expected_1 = $this->create_posted_data_hash($tick);
        if (hash_equals($expected_1, $hash)) {
            return 1;
        }
        $expected_2 = $this->create_posted_data_hash($tick - 1);
        if (hash_equals($expected_2, $hash)) {
            return 2;
        }
        return false;
    }
    private function get_remote_ip_addr()
    {
        $ip_addr = '';
        if (isset($_SERVER['REMOTE_ADDR']) and WP_Http::is_ip_address($_SERVER['REMOTE_ADDR'])) {
            $ip_addr = $_SERVER['REMOTE_ADDR'];
        }
        return apply_filters('wpcf7_remote_ip_addr', $ip_addr);
    }
    private function get_request_url()
    {
        $home_url = untrailingslashit(home_url());
        if (self::is_restful()) {
            $referer = isset($_SERVER['HTTP_REFERER']) ? trim($_SERVER['HTTP_REFERER']) : '';
            if ($referer and 0 === strpos($referer, $home_url)) {
                return esc_url_raw($referer);
            }
        }
        $url = preg_replace('%(?<!:|/)/.*$%', '', $home_url) . wpcf7_get_request_uri();
        return $url;
    }
    private function validate()
    {
        if ($this->invalid_fields) {
            return false;
        }
        $result = new WPCF7_Validation();
        $tags = $this->contact_form->scan_form_tags(array('feature' => '! file-uploading'));
        foreach ($tags as $tag) {
            $type = $tag->type;
            $result = apply_filters("wpcf7_validate_{$type}", $result, $tag);
        }
        $result = apply_filters('wpcf7_validate', $result, $tags);
        $this->invalid_fields = $result->get_invalid_fields();
        return $result->is_valid();
    }
    private function accepted()
    {
        return apply_filters('wpcf7_acceptance', true, $this);
    }
    public function add_consent($name, $conditions)
    {
        $this->consent[$name] = $conditions;
        return true;
    }
    public function collect_consent()
    {
        return (array) $this->consent;
    }
    private function spam()
    {
        $spam = false;
        $skip_spam_check = apply_filters('wpcf7_skip_spam_check', $this->skip_spam_check, $this);
        if ($skip_spam_check) {
            return $spam;
        }
        if ($this->contact_form->is_true('subscribers_only') and current_user_can('wpcf7_submit', $this->contact_form->id())) {
            return $spam;
        }
        $user_agent = (string) $this->get_meta('user_agent');
        if (strlen($user_agent) < 2) {
            $spam = true;
            $this->add_spam_log(array('agent' => 'wpcf7', 'reason' => __("User-Agent string is unnaturally short.", 'contact-form-7')));
        }
        if (!$this->verify_nonce()) {
            $spam = true;
            $this->add_spam_log(array('agent' => 'wpcf7', 'reason' => __("Submitted nonce is invalid.", 'contact-form-7')));
        }
        return apply_filters('wpcf7_spam', $spam, $this);
    }
    public function add_spam_log($args = '')
    {
        $args = wp_parse_args($args, array('agent' => '', 'reason' => ''));
        $this->spam_log[] = $args;
    }
    public function get_spam_log()
    {
        return $this->spam_log;
    }
    private function verify_nonce()
    {
        if (!$this->contact_form->nonce_is_active()) {
            return true;
        }
        return wpcf7_verify_nonce($_POST['_wpnonce']);
    }
    private function before_send_mail()
    {
        $abort = false;
        do_action_ref_array('wpcf7_before_send_mail', array($this->contact_form, &$abort, $this));
        return !$abort;
    }
    private function mail()
    {
        $contact_form = $this->contact_form;
        $skip_mail = apply_filters('wpcf7_skip_mail', $this->skip_mail, $contact_form);
        if ($skip_mail) {
            return true;
        }
        $result = WPCF7_Mail::send($contact_form->prop('mail'), 'mail');
        if ($result) {
            $additional_mail = array();
            if ($mail_2 = $contact_form->prop('mail_2') and $mail_2['active']) {
                $additional_mail['mail_2'] = $mail_2;
            }
            $additional_mail = apply_filters('wpcf7_additional_mail', $additional_mail, $contact_form);
            foreach ($additional_mail as $name => $template) {
                WPCF7_Mail::send($template, $name);
            }
            return true;
        }
        return false;
    }
    public function uploaded_files()
    {
        return $this->uploaded_files;
    }
    private function add_uploaded_file($name, $file_path)
    {
        if (!wpcf7_is_name($name)) {
            return false;
        }
        $paths = (array) $file_path;
        $uploaded_files = array();
        $hash_strings = array();
        foreach ($paths as $path) {
            if (@is_file($path) and @is_readable($path)) {
                $uploaded_files[] = $path;
                $hash_strings[] = md5_file($path);
            }
        }
        $this->uploaded_files[$name] = $uploaded_files;
        if (empty($this->posted_data[$name])) {
            $this->posted_data[$name] = implode(' ', $hash_strings);
        }
    }
    private function remove_uploaded_files()
    {
        foreach ((array) $this->uploaded_files as $file_path) {
            $paths = (array) $file_path;
            foreach ($paths as $path) {
                wpcf7_rmdir_p($path);
                if ($dir = dirname($path) and false !== ($files = scandir($dir)) and !array_diff($files, array('.', '..'))) {
                    rmdir($dir);
                }
            }
        }
    }
    private function unship_uploaded_files()
    {
        $result = new WPCF7_Validation();
        $tags = $this->contact_form->scan_form_tags(array('feature' => 'file-uploading'));
        foreach ($tags as $tag) {
            if (empty($_FILES[$tag->name])) {
                continue;
            }
            $file = $_FILES[$tag->name];
            $args = array('tag' => $tag, 'name' => $tag->name, 'required' => $tag->is_required(), 'filetypes' => $tag->get_option('filetypes'), 'limit' => $tag->get_limit_option());
            $new_files = wpcf7_unship_uploaded_file($file, $args);
            if (!is_wp_error($new_files)) {
                $this->add_uploaded_file($tag->name, $new_files);
            }
            $result = apply_filters("wpcf7_validate_{$tag->type}", $result, $tag, array('uploaded_files' => $new_files));
        }
        $this->invalid_fields = $result->get_invalid_fields();
        return $result->is_valid();
    }
    public function add_extra_attachments($file_path, $template = 'mail')
    {
        if (!did_action('wpcf7_before_send_mail')) {
            return false;
        }
        $extra_attachments = array();
        foreach ((array) $file_path as $path) {
            $path = path_join(WP_CONTENT_DIR, $path);
            if (file_exists($path)) {
                $extra_attachments[] = $path;
            }
        }
        if (empty($extra_attachments)) {
            return false;
        }
        if (!isset($this->extra_attachments[$template])) {
            $this->extra_attachments[$template] = array();
        }
        $this->extra_attachments[$template] = array_merge($this->extra_attachments[$template], $extra_attachments);
        return true;
    }
    public function extra_attachments($template)
    {
        if (isset($this->extra_attachments[$template])) {
            return (array) $this->extra_attachments[$template];
        }
        return array();
    }
}