Completed
Branch FET/reg-form-builder/extract-a... (6e8a58)
by
unknown
35:36 queued 25:38
created

verifyCriticalAttendeeDetailsAreSetAndValidateEmail()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
nc 6
nop 2
dl 0
loc 38
rs 8.3786
c 0
b 0
f 0
1
<?php
2
3
namespace EventEspresso\core\domain\services\registration\form\v1;
4
5
use EE_Answer;
6
use EE_Error;
7
use EE_Registration;
8
use EEM_Attendee;
9
use EventEspresso\core\exceptions\InvalidDataTypeException;
10
use EventEspresso\core\exceptions\InvalidInterfaceException;
11
use InvalidArgumentException;
12
use ReflectionException;
13
14
class RegFormInputHandler
15
{
16
17
    /**
18
     * @var EEM_Attendee
19
     */
20
    private $attendee_model;
21
22
    /**
23
     * @var string
24
     */
25
    private $checkout_reg_url_link;
26
27
    /**
28
     * @var RegistrantData
29
     */
30
    private $registrant_data;
31
32
    /**
33
     * @var array
34
     */
35
    private $required_questions;
36
37
38
    /**
39
     * RegFormHandler constructor.
40
     */
41
    public function __construct(
42
        string $checkout_reg_url_link,
43
        array $required_questions,
44
        EEM_Attendee $attendee_model,
45
        RegistrantData $registrant_data
46
    ) {
47
        $this->attendee_model        = $attendee_model;
48
        $this->checkout_reg_url_link = $checkout_reg_url_link;
49
        $this->registrant_data       = $registrant_data;
50
        $this->required_questions    = $required_questions;
51
    }
52
53
54
    /**
55
     * @param EE_Registration  $registration
56
     * @param string           $reg_url_link
57
     * @param int|string       $form_input
58
     * @param float|int|string $input_value
59
     * @return bool
60
     * @throws EE_Error
61
     * @throws ReflectionException
62
     */
63
    public function processFormInput(
64
        EE_Registration $registration,
65
        string $reg_url_link,
66
        $form_input,
67
        $input_value
68
    ): bool {
69
        // check for critical inputs
70
        if (! $this->verifyCriticalAttendeeDetailsAreSetAndValidateEmail($form_input, $input_value)) {
71
            return false;
72
        }
73
        $input_value = $this->registrant_data->saveOrCopyPrimaryRegistrantData(
74
            $reg_url_link,
75
            $form_input,
76
            $input_value
77
        );
78 View Code Duplication
        if (! $this->saveRegistrationFormInput($registration, $reg_url_link, $form_input, $input_value)) {
79
            EE_Error::add_error(
80
                sprintf(
81
                    esc_html_x(
82
                        'Unable to save registration form data for the form input: "%1$s" with the submitted value: "%2$s"',
83
                        'Unable to save registration form data for the form input: "form input name" with the submitted value: "form input value"',
84
                        'event_espresso'
85
                    ),
86
                    $form_input,
87
                    $input_value
88
                ),
89
                __FILE__,
90
                __FUNCTION__,
91
                __LINE__
92
            );
93
            return false;
94
        }
95
        return true;
96
    }
97
98
99
    /**
100
     * @param EE_Registration  $registration
101
     * @param string           $reg_url_link
102
     * @param int|string       $form_input
103
     * @param float|int|string $input_value
104
     * @return bool
105
     * @throws EE_Error
106
     * @throws InvalidArgumentException
107
     * @throws InvalidDataTypeException
108
     * @throws InvalidInterfaceException
109
     * @throws ReflectionException
110
     */
111
    private function saveRegistrationFormInput(
112
        EE_Registration $registration,
113
        string $reg_url_link,
114
        $form_input = '',
115
        $input_value = ''
116
    ): bool {
117
        // If email_confirm is sent it's not saved
118
        if ((string) $form_input === 'email_confirm') {
119
            return true;
120
        }
121
        // allow for plugins to hook in and do their own processing of the form input.
122
        // For plugins to bypass normal processing here, they just need to return a truthy value.
123
        if (
124
            apply_filters(
125
                'FHEE__EE_SPCO_Reg_Step_Attendee_Information___save_registration_form_input',
126
                false,
127
                $registration,
128
                $form_input,
129
                $input_value,
130
                $this
131
            )
132
        ) {
133
            return true;
134
        }
135
        /*
136
         * $answer_cache_id is the key used to find the EE_Answer we want
137
         * @see https://events.codebasehq.com/projects/event-espresso/tickets/10477
138
         */
139
        $answer_cache_id   = $this->checkout_reg_url_link
140
            ? $form_input . '-' . $reg_url_link
141
            : $form_input;
142
        $registrant_answer = $this->registrant_data->getRegistrantAnswer($reg_url_link, $answer_cache_id);
143
        $answer_is_obj     = $registrant_answer instanceof EE_Answer;
144
        // rename form_inputs if they are EE_Attendee properties
145
        switch ((string) $form_input) {
146
            case 'state':
147
            case 'STA_ID':
148
                $attendee_property = true;
149
                $form_input        = 'STA_ID';
150
                break;
151
152
            case 'country':
153
            case 'CNT_ISO':
154
                $attendee_property = true;
155
                $form_input        = 'CNT_ISO';
156
                break;
157
158
            default:
159
                $ATT_input         = 'ATT_' . $form_input;
160
                $attendee_property = $this->attendee_model->has_field($ATT_input);
161
                $form_input        = $attendee_property
162
                    ? 'ATT_' . $form_input
163
                    : $form_input;
164
        }
165
166
        // if this form input has a corresponding attendee property
167
        if ($attendee_property) {
168
            $this->registrant_data->addRegistrantDataValue($reg_url_link, $form_input, $input_value);
169
            if ($answer_is_obj) {
170
                // and delete the corresponding answer since we won't be storing this data in that object
171
                $registration->_remove_relation_to($registrant_answer, 'Answer');
172
                $registrant_answer->delete_permanently();
173
            }
174
            return true;
175
        }
176
        if ($answer_is_obj) {
177
            // save this data to the answer object
178
            $registrant_answer->set_value($input_value);
179
            $result = $registrant_answer->save();
180
            return $result !== false;
181
        }
182
        foreach ($this->registrant_data->registrantAnswers($reg_url_link) as $answer) {
183
            if ($answer instanceof EE_Answer && $answer->question_ID() === $answer_cache_id) {
184
                $answer->set_value($input_value);
185
                $result = $answer->save();
186
                return $result !== false;
187
            }
188
        }
189
        return false;
190
    }
191
192
193
    /**
194
     * @param int|string       $form_input
195
     * @param float|int|string $input_value
196
     * @return boolean
197
     */
198
    private function verifyCriticalAttendeeDetailsAreSetAndValidateEmail(
199
        $form_input = '',
200
        $input_value = ''
201
    ): bool {
202
        if (empty($input_value)) {
203
            // if the form input isn't marked as being required, then just return
204
            if (! isset($this->required_questions[ $form_input ]) || ! $this->required_questions[ $form_input ]) {
205
                return true;
206
            }
207
            switch ($form_input) {
208
                case 'fname':
209
                    EE_Error::add_error(
210
                        esc_html__('First Name is a required value.', 'event_espresso'),
211
                        __FILE__,
212
                        __FUNCTION__,
213
                        __LINE__
214
                    );
215
                    return false;
216
                case 'lname':
217
                    EE_Error::add_error(
218
                        esc_html__('Last Name is a required value.', 'event_espresso'),
219
                        __FILE__,
220
                        __FUNCTION__,
221
                        __LINE__
222
                    );
223
                    return false;
224
                case 'email':
225
                    EE_Error::add_error(
226
                        esc_html__('Please enter a valid email address.', 'event_espresso'),
227
                        __FILE__,
228
                        __FUNCTION__,
229
                        __LINE__
230
                    );
231
                    return false;
232
            }
233
        }
234
        return true;
235
    }
236
}
237