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

RegForm::printCopyInfo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace EventEspresso\core\domain\services\registration\form\v1;
4
5
use DomainException;
6
use EE_Error;
7
use EE_Form_Input_Base;
8
use EE_Form_Section_HTML;
9
use EE_Form_Section_Proper;
10
use EE_Line_Item_Display;
11
use EE_Question;
12
use EE_Registration;
13
use EE_Registration_Config;
14
use EE_SPCO_Reg_Step_Attendee_Information;
15
use EE_Template_Layout;
16
use EEH_Autoloader;
17
use EEH_Line_Item;
18
use EventEspresso\core\exceptions\EntityNotFoundException;
19
use EventEspresso\core\exceptions\InvalidDataTypeException;
20
use EventEspresso\core\exceptions\InvalidInterfaceException;
21
use EventEspresso\core\services\loaders\LoaderFactory;
22
use InvalidArgumentException;
23
use ReflectionException;
24
25
/**
26
 * Class RegForm
27
 *
28
 * @author  Brent Christensen
29
 * @package EventEspresso\core\domain\services\registration\form
30
 * @since   $VID:$
31
 */
32
class RegForm extends EE_Form_Section_Proper
33
{
34
35
    /**
36
     * @var bool
37
     */
38
    private $print_copy_info = false;
39
40
    /**
41
     * @var EE_Registration_Config
42
     */
43
    public $reg_config;
44
45
    /**
46
     * @var int
47
     */
48
    protected $reg_form_count = 0;
49
50
    /**
51
     * @var EE_SPCO_Reg_Step_Attendee_Information
52
     */
53
    public $reg_step;
54
55
    /**
56
     * @var array
57
     */
58
    private $required_questions = [];
59
60
    /**
61
     * @var array
62
     */
63
    private $template_args = [];
64
65
66
    /**
67
     * RegForm constructor.
68
     *
69
     * @param EE_SPCO_Reg_Step_Attendee_Information $reg_step
70
     * @param EE_Registration_Config                $reg_config
71
     * @throws ReflectionException
72
     * @throws EE_Error
73
     */
74
    public function __construct(
75
        EE_SPCO_Reg_Step_Attendee_Information $reg_step,
76
        EE_Registration_Config $reg_config
77
    ) {
78
        $this->reg_step   = $reg_step;
79
        $this->reg_config = $reg_config;
80
        // setup some classes so that they are ready for loading during construction of other classes
81
        LoaderFactory::getShared(CountryOptions::class, [$this->reg_step->checkout->action]);
82
        LoaderFactory::getShared(StateOptions::class, [$this->reg_step->checkout->action]);
83
        LoaderFactory::getShared(RegFormQuestionFactory::class, [[$this, 'addRequiredQuestion']]);
84
        parent::__construct(
85
            [
86
                'name'            => $this->reg_step->reg_form_name(),
87
                'html_id'         => $this->reg_step->reg_form_name(),
88
                'subsections'     => $this->generateSubsections(),
89
                'layout_strategy' => new EE_Template_Layout(
90
                    [
91
                        'layout_template_file' => $this->reg_step->template(), // layout_template
92
                        'template_args'        => $this->template_args,
93
                    ]
94
                ),
95
            ]
96
        );
97
    }
98
99
100
    /**
101
     * @return void
102
     */
103
    public function enablePrintCopyInfo(): void
104
    {
105
        $this->print_copy_info = true;
106
    }
107
108
109
    /**
110
     * @return bool
111
     */
112
    public function printCopyInfo(): bool
113
    {
114
        return $this->print_copy_info;
115
    }
116
117
118
    /**
119
     * @return int
120
     */
121
    public function regFormCount(): int
122
    {
123
        return $this->reg_form_count;
124
    }
125
126
127
    /**
128
     * @return array
129
     */
130
    public function requiredQuestions(): array
131
    {
132
        return $this->required_questions;
133
    }
134
135
136
    /**
137
     * @param string $identifier
138
     * @param string $required_question
139
     */
140
    public function addRequiredQuestion(string $identifier, string $required_question): void
141
    {
142
        $this->required_questions[ $identifier] = $required_question;
143
    }
144
145
146
    /**
147
     * @return EE_Form_Section_Proper[]
148
     * @throws DomainException
149
     * @throws EE_Error
150
     * @throws InvalidArgumentException
151
     * @throws ReflectionException
152
     * @throws EntityNotFoundException
153
     * @throws InvalidDataTypeException
154
     * @throws InvalidInterfaceException
155
     */
156
    private function generateSubsections(): array
157
    {
158
        // Init reg forms count.
159
        $this->reg_form_count = 0;
160
161
        $primary_registrant = null;
162
        // autoload Line_Item_Display classes
163
        EEH_Autoloader::register_line_item_display_autoloaders();
164
        $Line_Item_Display = new EE_Line_Item_Display();
165
        // calculate taxes
166
        $Line_Item_Display->display_line_item(
167
            $this->reg_step->checkout->cart->get_grand_total(),
168
            ['set_tax_rate' => true]
169
        );
170
        $extra_inputs_section = $this->reg_step->reg_step_hidden_inputs();
171
        $this->addPrivacyConsentCheckbox($extra_inputs_section);
172
        $subsections = [
173
            'default_hidden_inputs' => $extra_inputs_section,
174
        ];
175
176
        $this->template_args = [
177
            'revisit'       => $this->reg_step->checkout->revisit,
178
            'registrations' => [],
179
            'ticket_count'  => [],
180
        ];
181
        // grab the saved registrations from the transaction
182
        $registrations = $this->reg_step->checkout->transaction->registrations(
183
            $this->reg_step->checkout->reg_cache_where_params
184
        );
185
        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...
186
            foreach ($registrations as $registration) {
187
                // can this registration be processed during this visit ?
188
                if (
189
                    $registration instanceof EE_Registration
190
                    && $this->reg_step->checkout->visit_allows_processing_of_this_registration($registration)
191
                ) {
192
                    $reg_url_link = $registration->reg_url_link();
193
                    /** @var RegistrantForm $registrant_form */
194
                    $registrant_form = LoaderFactory::getNew(
195
                        RegistrantForm::class,
196
                        [
197
                            $registration,
198
                            $this->reg_step->checkout->admin_request,
199
                            $this->reg_config->copyAttendeeInfo(),
200
                            [$this, 'enablePrintCopyInfo'],
201
                        ]
202
                    );
203
                    // Increment the reg forms number if form is valid.
204
                    if ($registrant_form->hasQuestions()) {
205
                        $this->reg_form_count++;
206
                        $subsections[ $reg_url_link ] = $registrant_form;
207
                    } else {
208
                        // or just add a blank section if there are no questions
209
                        $subsections[ $reg_url_link ] = new EE_Form_Section_HTML();
210
                    }
211
212
                    $this->template_args['registrations'][ $reg_url_link ]                = $registration;
213
                    $this->template_args['ticket_count'][ $registration->ticket()->ID() ] = isset(
214
                        $this->template_args['ticket_count'][ $registration->ticket()->ID() ]
215
                    )
216
                        ? $this->template_args['ticket_count'][ $registration->ticket()->ID() ] + 1
217
                        : 1;
218
                    $ticket_line_item = EEH_Line_Item::get_line_items_by_object_type_and_IDs(
219
                        $this->reg_step->checkout->cart->get_grand_total(),
220
                        'Ticket',
221
                        [$registration->ticket()->ID()]
222
                    );
223
                    $ticket_line_item = is_array($ticket_line_item)
224
                        ? reset($ticket_line_item)
225
                        : $ticket_line_item;
226
                    $this->template_args['ticket_line_item'][ $registration->ticket()->ID() ] =
227
                        $Line_Item_Display->display_line_item($ticket_line_item);
228
                    if ($registration->is_primary_registrant()) {
229
                        $primary_registrant = $reg_url_link;
230
                    }
231
                }
232
            }
233
234
            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...
235
                if (
236
                    isset($subsections[ $primary_registrant ])
237
                    && $subsections[ $primary_registrant ] instanceof EE_Form_Section_Proper
238
                ) {
239
                    $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...
240
                        ? new CopyAttendeeInfoForm($registrations, $this->reg_step->slug())
241
                        : new AutoCopyAttendeeInfoForm($this->reg_step->slug());
242
                    $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...
243
                        $copy_options,
244
                        'primary_registrant',
245
                        false
246
                    );
247
                }
248
            }
249
        }
250
251
        // Set the registration form template (default: one form per ticket details table).
252
        // We decide the template to used based on the number of forms.
253
        $template = $this->reg_form_count > 1
254
            ? SPCO_REG_STEPS_PATH . $this->reg_step->slug() . '/attendee_info_main.template.php'
255
            : SPCO_REG_STEPS_PATH . $this->reg_step->slug() . '/attendee_info_single.template.php';
256
        $this->reg_step->setTemplate($template);
257
258
        return $subsections;
259
    }
260
261
262
    /**
263
     * @param EE_Form_Section_Proper $extra_inputs_section
264
     * @throws EE_Error
265
     */
266
    private function addPrivacyConsentCheckbox(EE_Form_Section_Proper $extra_inputs_section)
267
    {
268
        // if this isn't a revisit, and they have the privacy consent box enabled, add it
269
        if (! $this->reg_step->checkout->revisit && $this->reg_config->isConsentCheckboxEnabled()) {
270
            $extra_inputs_section->add_subsections(
271
                [
272
                    'consent_box' => new PrivacyConsentCheckboxForm(
273
                        $this->reg_step->slug(),
274
                        $this->reg_config->getConsentCheckboxLabelText()
275
                    )
276
                ],
277
                null,
278
                false
279
            );
280
        }
281
    }
282
}
283