Completed
Branch FET/reg-form-builder/main (d111d3)
by
unknown
44:41 queued 35:38
created

RegForm::generateSubsections()   D

Complexity

Conditions 15
Paths 12

Size

Total Lines 106

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 15
nc 12
nop 0
dl 0
loc 106
rs 4.7333
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace EventEspresso\core\domain\services\registration\form\v1;
4
5
use DomainException;
6
use EE_Checkbox_Multi_Input;
7
use EE_Error;
8
use EE_Form_Input_Base;
9
use EE_Form_Section_HTML;
10
use EE_Form_Section_Proper;
11
use EE_Line_Item_Display;
12
use EE_Question;
13
use EE_Registration;
14
use EE_Registration_Config;
15
use EE_SPCO_Reg_Step_Attendee_Information;
16
use EE_Template_Layout;
17
use EEH_Autoloader;
18
use EEH_Line_Item;
19
use EventEspresso\core\exceptions\EntityNotFoundException;
20
use EventEspresso\core\exceptions\InvalidDataTypeException;
21
use EventEspresso\core\exceptions\InvalidInterfaceException;
22
use EventEspresso\core\services\loaders\LoaderFactory;
23
use InvalidArgumentException;
24
use ReflectionException;
25
26
/**
27
 * Class RegForm
28
 *
29
 * @author  Brent Christensen
30
 * @package EventEspresso\core\domain\services\registration\form
31
 * @since   $VID:$
32
 */
33
class RegForm extends EE_Form_Section_Proper
34
{
35
36
    /**
37
     * @var bool
38
     */
39
    private $print_copy_info = false;
40
41
    /**
42
     * @var EE_Registration_Config
43
     */
44
    public $reg_config;
45
46
    /**
47
     * @var int
48
     */
49
    protected $reg_form_count = 0;
50
51
    /**
52
     * @var EE_SPCO_Reg_Step_Attendee_Information
53
     */
54
    public $reg_step;
55
56
    /**
57
     * @var array
58
     */
59
    private $template_args = [];
60
61
62
    /**
63
     * RegForm constructor.
64
     *
65
     * @param EE_SPCO_Reg_Step_Attendee_Information $reg_step
66
     * @param EE_Registration_Config                $reg_config
67
     * @throws ReflectionException
68
     * @throws EE_Error
69
     */
70
    public function __construct(
71
        EE_SPCO_Reg_Step_Attendee_Information $reg_step,
72
        EE_Registration_Config $reg_config
73
    ) {
74
        $this->reg_step   = $reg_step;
75
        $this->reg_config = $reg_config;
76
        LoaderFactory::getShared(CountryOptions::class, [$this->reg_step->checkout->action]);
77
        LoaderFactory::getShared(StateOptions::class, [$this->reg_step->checkout->action]);
78
        parent::__construct(
79
            [
80
                'name'            => $this->reg_step->reg_form_name(),
81
                'html_id'         => $this->reg_step->reg_form_name(),
82
                'subsections'     => $this->generateSubsections(),
83
                'layout_strategy' => new EE_Template_Layout(
84
                    [
85
                        'layout_template_file' => $this->reg_step->template(), // layout_template
86
                        'template_args'        => $this->template_args,
87
                    ]
88
                ),
89
            ]
90
        );
91
    }
92
93
94
    /**
95
     * @return bool
96
     */
97
    public function printCopyInfo(): bool
98
    {
99
        return $this->print_copy_info;
100
    }
101
102
103
    /**
104
     * @return void
105
     */
106
    public function enablePrintCopyInfo(): void
107
    {
108
        $this->print_copy_info = true;
109
    }
110
111
112
    /**
113
     * @return int
114
     */
115
    public function regFormCount(): int
116
    {
117
        return $this->reg_form_count;
118
    }
119
120
121
    /**
122
     * @param EE_Registration $registration
123
     * @param EE_Question     $question
124
     * @return EE_Form_Input_Base
125
     * @throws EE_Error
126
     * @throws ReflectionException
127
     */
128
    public function regFormQuestion(EE_Registration $registration, EE_Question $question): EE_Form_Input_Base
129
    {
130
        /** @var RegFormQuestionFactory $reg_form_question_factory */
131
        $reg_form_question_factory = LoaderFactory::getShared(RegFormQuestionFactory::class);
132
        return $reg_form_question_factory->create($registration, $question);
133
    }
134
135
136
    /**
137
     * @return EE_Form_Section_Proper[]
138
     * @throws DomainException
139
     * @throws EE_Error
140
     * @throws InvalidArgumentException
141
     * @throws ReflectionException
142
     * @throws EntityNotFoundException
143
     * @throws InvalidDataTypeException
144
     * @throws InvalidInterfaceException
145
     */
146
    private function generateSubsections(): array
147
    {
148
        // Init reg forms count.
149
        $this->reg_form_count = 0;
150
151
        $primary_registrant = null;
152
        // autoload Line_Item_Display classes
153
        EEH_Autoloader::register_line_item_display_autoloaders();
154
        $Line_Item_Display = new EE_Line_Item_Display();
155
        // calculate taxes
156
        $Line_Item_Display->display_line_item(
157
            $this->reg_step->checkout->cart->get_grand_total(),
158
            ['set_tax_rate' => true]
159
        );
160
        $extra_inputs_section = $this->reg_step->reg_step_hidden_inputs();
161
        $this->addPrivacyConsentCheckbox($extra_inputs_section);
162
        $subsections = [
163
            'default_hidden_inputs' => $extra_inputs_section,
164
        ];
165
166
        $this->template_args = [
167
            'revisit'       => $this->reg_step->checkout->revisit,
168
            'registrations' => [],
169
            'ticket_count'  => [],
170
        ];
171
        // grab the saved registrations from the transaction
172
        $registrations = $this->reg_step->checkout->transaction->registrations(
173
            $this->reg_step->checkout->reg_cache_where_params
174
        );
175
        if ($registrations) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $registrations of type EE_Base_Class[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
176
            foreach ($registrations as $registration) {
177
                // can this registration be processed during this visit ?
178
                if (
179
                    $registration instanceof EE_Registration
180
                    && $this->reg_step->checkout->visit_allows_processing_of_this_registration($registration)
181
                ) {
182
                    $reg_url_link = $registration->reg_url_link();
183
                    /** @var RegistrationForm $registrant_form */
184
                    $registrant_form = LoaderFactory::getNew(
185
                        RegistrationForm::class,
186
                        [
187
                            $registration,
188
                            $this->reg_step->checkout->admin_request,
189
                            $this->reg_config->copyAttendeeInfo(),
190
                            [$this, 'enablePrintCopyInfo'],
191
                        ]
192
                    );
193
                    // Increment the reg forms number if form is valid.
194
                    if ($registrant_form->hasQuestions()) {
195
                        $this->reg_form_count++;
196
                        $subsections[ $reg_url_link ] = $registrant_form;
197
                    } else {
198
                        // or just add a blank section if there are no questions
199
                        $subsections[ $reg_url_link ] = new EE_Form_Section_HTML();
200
                    }
201
202
                    $this->template_args['registrations'][ $reg_url_link ]                = $registration;
203
                    $this->template_args['ticket_count'][ $registration->ticket()->ID() ] = isset(
204
                        $this->template_args['ticket_count'][ $registration->ticket()->ID() ]
205
                    )
206
                        ? $this->template_args['ticket_count'][ $registration->ticket()->ID() ] + 1
207
                        : 1;
208
                    $ticket_line_item
209
                                                                                          = EEH_Line_Item::get_line_items_by_object_type_and_IDs(
210
                        $this->reg_step->checkout->cart->get_grand_total(),
211
                        'Ticket',
212
                        [$registration->ticket()->ID()]
213
                    );
214
                    $ticket_line_item                                                     = is_array($ticket_line_item)
215
                        ? reset($ticket_line_item)
216
                        : $ticket_line_item;
217
                    $this->template_args['ticket_line_item'][ $registration->ticket()->ID() ]
218
                                                                                          = $Line_Item_Display->display_line_item($ticket_line_item);
219
                    if ($registration->is_primary_registrant()) {
220
                        $primary_registrant = $reg_url_link;
221
                    }
222
                }
223
            }
224
225
            if ($primary_registrant && count($registrations) > 1) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $primary_registrant of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
226
                $copy_options['spco_copy_attendee_chk'] = $this->print_copy_info
0 ignored issues
show
Coding Style Comprehensibility introduced by
$copy_options was never initialized. Although not strictly required by PHP, it is generally a good practice to add $copy_options = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
227
                    ? new CopyAttendeeInfoForm($registrations, $this->reg_step->slug())
228
                    : new AutoCopyAttendeeInfoForm($this->reg_step->slug());
229
                // generate hidden input
230
                if (
231
                    isset($subsections[ $primary_registrant ])
232
                    && $subsections[ $primary_registrant ] instanceof EE_Form_Section_Proper
233
                ) {
234
                    $subsections[ $primary_registrant ]->add_subsections(
0 ignored issues
show
Bug introduced by
The method add_subsections does only exist in EE_Form_Section_Proper, but not in EE_Form_Section_HTML.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
235
                        $copy_options,
236
                        'primary_registrant',
237
                        false
238
                    );
239
                }
240
            }
241
        }
242
243
        // Set the registration form template (default: one form per ticket details table).
244
        // We decide the template to used based on the number of forms.
245
        $template = $this->reg_form_count > 1
246
            ? SPCO_REG_STEPS_PATH . $this->reg_step->slug() . '/attendee_info_main.template.php'
247
            : SPCO_REG_STEPS_PATH . $this->reg_step->slug() . '/attendee_info_single.template.php';
248
        $this->reg_step->setTemplate($template);
249
250
        return $subsections;
251
    }
252
253
254
    /**
255
     * @param EE_Form_Section_Proper $extra_inputs_section
256
     * @throws EE_Error
257
     */
258
    private function addPrivacyConsentCheckbox(EE_Form_Section_Proper $extra_inputs_section)
259
    {
260
        // if this isn't a revisit, and they have the privacy consent box enabled, add it
261
        if (! $this->reg_step->checkout->revisit && $this->reg_config->isConsentCheckboxEnabled()) {
262
            $extra_inputs_section->add_subsections(
263
                [
264
                    'consent_box' => new EE_Form_Section_Proper(
265
                        [
266
                            'layout_strategy' =>
267
                                new EE_Template_Layout(
268
                                    [
269
                                        'input_template_file' => SPCO_REG_STEPS_PATH
270
                                                                 . $this->reg_step->slug()
271
                                                                 . '/privacy_consent.template.php',
272
                                    ]
273
                                ),
274
                            'subsections'     => [
275
                                'consent' => new EE_Checkbox_Multi_Input(
276
                                    [
277
                                        'consent' => $this->reg_config->getConsentCheckboxLabelText(),
278
                                    ],
279
                                    [
280
                                        'required'                          => true,
281
                                        'required_validation_error_message' => esc_html__(
282
                                            'You must consent to these terms in order to register.',
283
                                            'event_espresso'
284
                                        ),
285
                                        'html_label_text'                   => '',
286
                                    ]
287
                                ),
288
                            ],
289
                        ]
290
                    ),
291
                ],
292
                null,
293
                false
294
            );
295
        }
296
    }
297
}
298