Form::offsetSet()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 2
dl 0
loc 6
ccs 0
cts 4
cp 0
crap 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Anax\HTMLForm;
4
5
use Psr\Container\ContainerInterface;
6
7
/**
8
 * A utility class to easy creating and handling of forms
9
 */
10
class Form implements \ArrayAccess
11
{
12
    /**
13
     * @var array $form       settings for the form
14
     * @var array $elements   all form elements
15
     * @var array $output     messages to display together with the form
16
     * @var array $sessionKey key values for the session
17
     */
18
    protected $form;
19
    protected $elements;
20
    protected $output;
21
    protected $sessionKey;
22
23
    /**
24
     * @var boolean $rememberValues remember values in the session.
25
     */
26
    protected $rememberValues;
27
28
    /**
29
     * @var Anax\DI\DIInterface $di the DI service container.
0 ignored issues
show
Bug introduced by
The type Anax\HTMLForm\Anax\DI\DIInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
30
     */
31
    protected $di;
32
33
34
35
    /**
36
     * Constructor injects with DI container.
37
     *
38
     * @param Anax\DI\DIInterface $di a service container
39
     */
40 6
    public function __construct(ContainerInterface $di)
41
    {
42 6
        $this->di = $di;
0 ignored issues
show
Documentation Bug introduced by
It seems like $di of type Psr\Container\ContainerInterface is incompatible with the declared type Anax\HTMLForm\Anax\DI\DIInterface of property $di.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
43 6
    }
44
45
46
47
    /**
48
     * Implementing ArrayAccess for this->elements
49
     */
50
    public function offsetSet($offset, $value)
51
    {
52
        if (is_null($offset)) {
53
            $this->elements[] = $value;
54
        } else {
55
            $this->elements[$offset] = $value;
56
        }
57
    }
58
59
    public function offsetExists($offset)
60
    {
61
        return isset($this->elements[$offset]);
62
    }
63
64
    public function offsetUnset($offset)
65
    {
66
        unset($this->elements[$offset]);
67
    }
68
69
    public function offsetGet($offset)
70
    {
71
        return isset($this->elements[$offset])
72
            ? $this->elements[$offset]
73
            : null;
74
    }
75
76
77
78
    /**
79
     * Add a form element
80
     *
81
     * @param array $form     details for the form
82
     * @param array $elements all the elements
83
     *
84
     * @return $this
85
     */
86 6
    public function create($form = [], $elements = [])
87
    {
88
        $defaults = [
89
            // Always have an id
90 6
            "id" => "anax/htmlform",
91
92
            // Use a default class on <form> to ease styling
93
            "class" => "htmlform",
94
95
            // Wrap fields within <fieldset>
96
            "use_fieldset"  => true,
97
98
            // Use legend for fieldset, set it to string value
99
            "legend"        => null,
100
101
            // Default wrapper element around form elements
102
            "wrapper-element" => "p",
103
104
            // Use a <br> after the label, where suitable
105
            "br-after-label" => true,
106
107
            // Default is to always encode values
108
            "escape-values" => true,
109
        ];
110 6
        $this->form = array_merge($defaults, $form);
111
112 6
        $this->elements = [];
113 6
        if (!empty($elements)) {
114 4
            foreach ($elements as $key => $element) {
115 4
                $this->elements[$key] = FormElementFactory::create($key, $element);
116 4
                $this->elements[$key]->setDefault([
117 4
                    "wrapper-element" => $this->form["wrapper-element"],
118 4
                    "br-after-label"  => $this->form["br-after-label"],
119 4
                    "escape-values"   => $this->form["escape-values"],
120
                ]);
121
            }
122
        }
123
124
        // Default values for <output>
125 6
        $this->output = [];
126
127
        // Setting keys used in the session
128 6
        $generalKey = "anax/htmlform-" . $this->form["id"] . "#";
129 6
        $this->sessionKey = [
130 6
            "save"      => $generalKey . "save",
131 6
            "output"    => $generalKey . "output",
132 6
            "failed"    => $generalKey . "failed",
133 6
            "remember"  => $generalKey . "remember",
134
        ];
135
136 6
        return $this;
137
    }
138
139
140
141
    /**
142
     * Add a form element
143
     *
144
     * @param FormElement $element the formelement to add.
145
     *
146
     * @return $this
147
     */
148
    public function addElement($element)
149
    {
150
        $name = $element;
151
        if (isset($this->elements[$name])) {
152
            throw new Exception("Form element '$name' already exists, do not add it twice.");
153
        }
154
        $this[$element['name']] = $name;
155
        return $this;
156
    }
157
158
159
160
    /**
161
     * Get a form element
162
     *
163
     * @param string $name the name of the element.
164
     *
165
     * @return \Anax\HTMLForm\FormElement
166
     */
167
    public function getElement($name)
168
    {
169
        if (!isset($this->elements[$name])) {
170
            throw new Exception("Form element '$name' is not found.");
171
        }
172
        return $this->elements[$name];
173
    }
174
175
176
177
    /**
178
     * Remove an form element
179
     *
180
     * @param string $name the name of the element.
181
     *
182
     * @return $this
183
     */
184
    public function removeElement($name)
185
    {
186
        if (!isset($this->elements[$name])) {
187
            throw new Exception("Form element '$name' is not found.");
188
        }
189
        unset($this->elements[$name]);
190
        return $this;
191
    }
192
193
194
195
    /**
196
     * Set validation to a form element
197
     *
198
     * @param string $element the name of the formelement to add validation rules to.
199
     * @param array  $rules   array of validation rules.
200
     *
201
     * @return $this
202
     */
203
    public function setValidation($element, $rules)
204
    {
205
        $this[$element]['validation'] = $rules;
206
        return $this;
207
    }
208
209
210
211
    /**
212
     * Add output to display to the user for what happened whith the form and
213
     * optionally add a CSS class attribute.
214
     *
215
     * @param string $str   the string to add as output.
216
     * @param string $class a class attribute to set.
217
     *
218
     * @return $this.
0 ignored issues
show
Documentation Bug introduced by
The doc comment $this. at position 0 could not be parsed: Unknown type name '$this.' at position 0 in $this..
Loading history...
219
     */
220
    public function addOutput($str, $class = null)
221
    {
222
        $key     = $this->sessionKey["output"];
223
        $session = $this->di->get("session");
224
        $output  = $session->get($key);
225
226
        $output["message"] = isset($output["message"])
227
            ? $output["message"] . " $str"
228
            : $str;
229
230
        if ($class) {
231
            $output["class"] = $class;
232
        }
233
        $session->set($key, $output);
234
235
        return $this;
236
    }
237
238
239
240
    /**
241
     * Set a CSS class attribute for the <output> element.
242
     *
243
     * @param string $class a class attribute to set.
244
     *
245
     * @return $this.
0 ignored issues
show
Documentation Bug introduced by
The doc comment $this. at position 0 could not be parsed: Unknown type name '$this.' at position 0 in $this..
Loading history...
246
     */
247
    public function setOutputClass($class)
248
    {
249
        $key     = $this->sessionKey["output"];
250
        $session = $this->di->get("session");
251
        $output  = $session->get($key);
252
        $output["class"] = $class;
253
        $session->set($key, $output);
254
        return $this;
255
    }
256
257
258
259
    /**
260
     * Remember current values in session, useful for storing values of
261
     * current form when submitting it.
262
     *
263
     * @return $this.
0 ignored issues
show
Documentation Bug introduced by
The doc comment $this. at position 0 could not be parsed: Unknown type name '$this.' at position 0 in $this..
Loading history...
264
     */
265
    public function rememberValues()
266
    {
267
        $this->rememberValues = true;
268
        return $this;
269
    }
270
271
272
273
274
    /**
275
     * Get value of a form element and respect settings of escaped or
276
     * raw value.
277
     *
278
     * @param string $name the name of the formelement.
279
     *
280
     * @return mixed the value of the element.
281
     */
282
    public function value($name)
283
    {
284
        return isset($this->elements[$name])
285
            ? $this->elements[$name]->value()
286
            : null;
287
    }
288
289
290
291
    /**
292
     * Get escaped value of a form element.
293
     *
294
     * @param string $name the name of the formelement.
295
     *
296
     * @return mixed the value of the element.
297
     */
298 4
    public function escValue($name)
299
    {
300 4
        return isset($this->elements[$name])
301 4
            ? $this->elements[$name]->getEscapedValue()
302 4
            : null;
303
    }
304
305
306
307
    /**
308
     * Get raw value of a form element.
309
     *
310
     * @param string $name the name of the formelement.
311
     *
312
     * @return mixed the value of the element.
313
     */
314 4
    public function rawValue($name)
315
    {
316 4
        return isset($this->elements[$name])
317 4
            ? $this->elements[$name]->getRawValue()
318 4
            : null;
319
    }
320
321
322
323
    /**
324
     * Check if a element is checked
325
     *
326
     * @param string $name the name of the formelement.
327
     *
328
     * @return mixed the value of the element.
329
     */
330
    public function checked($name)
331
    {
332
        return isset($this->elements[$name])
333
            ? $this->elements[$name]->checked()
334
            : null;
335
    }
336
337
338
339
    /**
340
     * Return HTML for the form.
341
     *
342
     * @param array $options with options affecting the form output.
343
     *
344
     * @return string with HTML for the form.
345
     */
346 2
    public function getHTML($options = [])
347
    {
348
        $defaults = [
349
            // Only return the start of the form element
350 2
            'start'         => false,
351
352
            // Layout all elements in one column
353
            'columns'       => 1,
354
355
            // Layout consequtive buttons as one element wrapped in <p>
356
            'use_buttonbar' => true,
357
        ];
358 2
        $options = array_merge($defaults, $options);
359
360 2
        $form = array_merge($this->form, $options);
361 2
        $id      = isset($form['id'])      ? " id='{$form['id']}'" : null;
362 2
        $class   = isset($form['class'])   ? " class='{$form['class']}'" : null;
363 2
        $name    = isset($form['name'])    ? " name='{$form['name']}'" : null;
364 2
        $action  = isset($form['action'])  ? " action='{$form['action']}'" : null;
365 2
        $method  = isset($form['method'])  ? " method='{$form['method']}'" : " method='post'";
366 2
        $enctype = isset($form['enctype']) ? " enctype='{$form['enctype']}'" : null;
367 2
        $cformId = isset($form['id'])      ? "{$form['id']}" : null;
368
369 2
        if ($options['start']) {
370
            return "<form{$id}{$class}{$name}{$action}{$method}>\n";
371
        }
372
373 2
        $fieldsetStart  = '<fieldset>';
374 2
        $legend         = null;
375 2
        $fieldsetEnd    = '</fieldset>';
376 2
        if (!$form['use_fieldset']) {
377
            $fieldsetStart = $fieldsetEnd = null;
378
        }
379
380 2
        if ($form['use_fieldset'] && $form['legend']) {
381
            $legend = "<legend>{$form['legend']}</legend>";
382
        }
383
384 2
        $elementsArray  = $this->getHTMLForElements($options);
385 2
        $elements       = $this->getHTMLLayoutForElements($elementsArray, $options);
386 2
        $output         = $this->getOutput();
387
388
        $html = <<< EOD
389 2
\n<form{$id}{$class}{$name}{$action}{$method}{$enctype}>
390 2
<input type="hidden" name="anax/htmlform-id" value="$cformId" />
391 2
{$fieldsetStart}
392 2
{$legend}
393 2
{$elements}
394 2
{$output}
395 2
{$fieldsetEnd}
396
</form>\n
397
EOD;
398
399 2
        return $html;
400
    }
401
402
403
404
    /**
405
     * Return HTML for the elements
406
     *
407
     * @param array $options with options affecting the form output.
408
     *
409
     * @return array with HTML for the formelements.
410
     */
411 2
    public function getHTMLForElements($options = [])
412
    {
413
        $defaults = [
414 2
            "use_buttonbar" => true,
415
        ];
416 2
        $options = array_merge($defaults, $options);
417
418 2
        $elements = [];
419 2
        $buttonbarStarted = false;
420 2
        foreach ($this->elements as $element) {
421
            if ($options["use_buttonbar"]) {
422
                if ($element->isButton() && !$buttonbarStarted) {
423
                    $buttonbarStarted = true;
424
                    $elements[] = [
425
                        "name" => "buttonbar start",
426
                        "html" => "\n<p class=\"buttonbar\">\n"
427
                    ];
428
                } elseif ($buttonbarStarted && !$element->isButton()) {
429
                    $buttonbarStarted = false;
430
                    $elements[] = [
431
                        "name" => "buttonbar end",
432
                        "html" => "\n</p>\n"
433
                    ];
434
                }
435
            }
436
437
            $elements[] = [
438
                "name" => $element["name"],
439
                "html" => $element->getHTML()
440
            ];
441
        }
442
443 2
        if ($buttonbarStarted) {
444
            $elements[] = [
445
                "name" => "buttonbar end",
446
                "html" => "\n</p>\n"
447
            ];
448
        }
449
450 2
        return $elements;
451
    }
452
453
454
455
456
    /**
457
     * Place the elements according to a layout and return the HTML
458
     *
459
     * @param array $elements as returned from GetHTMLForElements().
460
     * @param array $options  with options affecting the layout.
461
     *
462
     * @return array with HTML for the formelements.
463
     */
464 2
    public function getHTMLLayoutForElements($elements, $options = [])
465
    {
466
        $defaults = [
467 2
            'columns' => 1,
468
            'wrap_at_element' => false,  // Wraps column in equal size or at the set number of elements
469
        ];
470 2
        $options = array_merge($defaults, $options);
471
472 2
        $html = null;
473 2
        if ($options['columns'] === 1) {
474 2
            foreach ($elements as $element) {
475 2
                $html .= $element['html'];
476
            }
477
        } elseif ($options['columns'] === 2) {
478
            $buttonbar = null;
479
            $col1 = null;
480
            $col2 = null;
481
482
            $end = end($elements);
483
            if ($end['name'] == 'buttonbar') {
484
                $end = array_pop($elements);
485
                $buttonbar = "<div class='cform-buttonbar'>\n{$end['html']}</div>\n";
486
            }
487
488
            $size = count($elements);
489
            $wrapAt = $options['wrap_at_element'] ? $options['wrap_at_element'] : round($size/2);
490
            for ($i=0; $i<$size; $i++) {
491
                if ($i < $wrapAt) {
492
                    $col1 .= $elements[$i]['html'];
493
                } else {
494
                    $col2 .= $elements[$i]['html'];
495
                }
496
            }
497
498
            $html = <<<EOD
499
<div class='cform-columns-2'>
500
<div class='cform-column-1'>
501
{$col1}
502
</div>
503
<div class='cform-column-2'>
504
{$col2}
505
</div>
506
{$buttonbar}</div>
507
EOD;
508
        }
509
510 2
        return $html;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $html also could return the type string which is incompatible with the documented return type array.
Loading history...
511
    }
512
513
514
515
    /**
516
     * Get an array with all elements that failed validation together with their id and validation message.
517
     *
518
     * @return array with elements that failed validation.
519
     */
520
    public function getValidationErrors()
521
    {
522
        $errors = [];
523
        foreach ($this->elements as $name => $element) {
524
            if ($element['validation-pass'] === false) {
525
                $errors[$name] = [
526
                    'id' => $element->GetElementId(),
527
                    'label' => $element['label'],
528
                    'message' => implode(' ', $element['validation-messages'])
529
                ];
530
            }
531
        }
532
        return $errors;
533
    }
534
535
536
537
    /**
538
     * Get output messages as <output>.
539
     *
540
     * @return string|null with the complete <output> element or null if no output.
541
     */
542 2
    public function getOutput()
543
    {
544 2
        $output = $this->output;
545 2
        $message = isset($output["message"]) && !empty($output["message"])
546
            ? $output["message"]
547 2
            : null;
548
549 2
        $class = isset($output["class"]) && !empty($output["class"])
550
            ? " class=\"{$output["class"]}\""
551 2
            : null;
552
553 2
        return $message
554
            ? "<output{$class}>{$message}</output>"
555 2
            : null;
556
    }
557
558
559
560
    /**
561
     * Init all element with values from session, clear all and fill in with values from the session.
562
     *
563
     * @param array $values retrieved from session
564
     *
565
     * @return void
566
     */
567
    protected function initElements($values)
568
    {
569
        // First clear all
570
        foreach ($this->elements as $key => $val) {
571
            // Do not reset value for buttons
572
            if (in_array($this[$key]['type'], array('submit', 'reset', 'button'))) {
573
                continue;
574
            }
575
576
            // Reset the value
577
            $this[$key]['value'] = null;
578
579
            // Checkboxes must be cleared
580
            if (isset($this[$key]['checked'])) {
581
                $this[$key]['checked'] = false;
582
            }
583
        }
584
585
        // Now build up all values from $values (session)
586
        foreach ($values as $key => $val) {
587
            // Take care of arrays as values (multiple-checkbox)
588
            if (isset($val['values'])) {
589
                $this[$key]['checked'] = $val['values'];
590
                //$this[$key]['values']  = $val['values'];
591
            } elseif (isset($val['value'])) {
592
                $this[$key]['value'] = $val['value'];
593
            }
594
595
            if ($this[$key]['type'] === 'checkbox') {
596
                $this[$key]['checked'] = true;
597
            } elseif ($this[$key]['type'] === 'radio') {
598
                $this[$key]['checked'] = $val['value'];
599
            }
600
601
            // Keep track on validation messages if set
602
            if (isset($val['validation-messages'])) {
603
                $this[$key]['validation-messages'] = $val['validation-messages'];
604
                $this[$key]['validation-pass'] = false;
605
            }
606
        }
607
    }
608
609
610
611
    /**
612
     * Check if a form was submitted and perform validation and call callbacks.
613
     * The form is stored in the session if validation or callback fails. The
614
     * page should then be redirected to the original form page, the form
615
     * will populate from the session and should be rendered again.
616
     * Form elements may remember their value if 'remember' is set and true.
617
     *
618
     * @param callable $callIfSuccess handler to call if function returns true.
619
     * @param callable $callIfFail    handler to call if function returns true.
620
     *
621
     * @throws \Anax\HTMLForm\Exception
622
     *
623
     * @return boolean|null $callbackStatus if submitted&validates, false if
624
     *                                      not validate, null if not submitted.
625
     *                                      If submitted the callback function
626
     *                                      will return the actual value which
627
     *                                      should be true or false.
628
     */
629
    public function check($callIfSuccess = null, $callIfFail = null)
630
    {
631
        $remember = null;
632
        $validates = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $validates is dead and can be removed.
Loading history...
633
        $callbackStatus = null;
634
        $values = [];
635
636
        // Remember flash output messages in session
637
        $output = $this->sessionKey["output"];
638
        $session = $this->di->get("session");
639
        $this->output = $session->getOnce($output, []);
640
641
        // Check if this was a post request
642
        $requestMethod = $this->di->get("request")->getServer("REQUEST_METHOD");
643
        if ($requestMethod !== "POST") {
644
            // Its not posted, but check if values should be used from session
645
            $failed   = $this->sessionKey["failed"];
646
            $remember = $this->sessionKey["remember"];
647
            $save     = $this->sessionKey["save"];
648
649
            if ($session->has($failed)) {
650
                // Read form data from session if the previous post failed
651
                // during validation.
652
                $this->InitElements($session->getOnce($failed));
653
            } elseif ($session->has($remember)) {
654
                // Read form data from session if some form elements should
655
                // be remembered
656
                foreach ($session->getOnce($remember) as $key => $val) {
657
                    $this[$key]['value'] = $val['value'];
658
                }
659
            } elseif ($session->has($save)) {
660
                // Read form data from session,
661
                // useful during test where the original form is displayed
662
                // with its posted values
663
                $this->InitElements($session->getOnce($save));
664
            }
665
666
            return null;
667
        }
668
669
        $request = $this->di->get("request");
670
        $formid = $request->getPost("anax/htmlform-id");
671
        // Check if its a form we are dealing with
672
        if (!$formid) {
673
            return null;
674
        }
675
676
        // Check if its this form that was posted
677
        if ($this->form["id"] !== $formid) {
678
            return null;
679
        }
680
681
        // This form was posted, process it
682
        $session->delete($this->sessionKey["failed"]);
683
        $validates = true;
684
        foreach ($this->elements as $element) {
685
            $elementName = $element['name'];
686
            $elementType = $element['type'];
687
688
            $postElement = $request->getPost($elementName);
689
            if ($postElement) {
690
                // The form element has a value set
691
                // Multiple choices comes in the form of an array
692
                if (is_array($postElement)) {
693
                    $values[$elementName]['values'] = $element['checked'] = $postElement;
694
                } else {
695
                    $values[$elementName]['value'] = $element['value'] = $postElement;
696
                }
697
698
                // If the element is a password, do not remember.
699
                if ($elementType === 'password') {
700
                    $values[$elementName]['value'] = null;
701
                }
702
703
                // If the element is a checkbox, set its value of checked.
704
                if ($elementType === 'checkbox') {
705
                    $element['checked'] = true;
706
                }
707
708
                // If the element is a radio, set the value to checked.
709
                if ($elementType === 'radio') {
710
                    $element['checked'] = $element['value'];
711
                }
712
713
                // Do validation of form element
714
                if (isset($element['validation'])) {
715
                    $element['validation-pass'] = $element->Validate($element['validation'], $this);
716
717
                    if ($element['validation-pass'] === false) {
718
                        $values[$elementName] = [
719
                            'value' => $element['value'],
720
                            'validation-messages' => $element['validation-messages']
721
                        ];
722
                        $validates = false;
723
                    }
724
                }
725
726
                // Hmmm.... Why did I need this remember thing?
727
                if (isset($element['remember'])
728
                    && $element['remember']
729
                ) {
730
                    $values[$elementName] = ['value' => $element['value']];
731
                    $remember = true;
732
                }
733
734
                // Carry out the callback if the form element validates
735
                // Hmmm, what if the element with the callback is not the last element?
736
                if (isset($element['callback'])
737
                    && $validates
738
                ) {
739
                    if (isset($element['callback-args'])) {
740
                        $callbackStatus = call_user_func_array(
741
                            $element['callback'],
742
                            array_merge([$this]),
743
                            $element['callback-args']
0 ignored issues
show
Unused Code introduced by
The call to call_user_func_array() has too many arguments starting with $element['callback-args']. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

743
                        $callbackStatus = /** @scrutinizer ignore-call */ call_user_func_array(

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
744
                        );
745
                    } else {
746
                        $callbackStatus = call_user_func($element['callback'], $this);
747
                    }
748
                }
749
            } else {
750
                // The form element has no value set
751
752
                // Set element to null, then we know it was not set.
753
                //$element['value'] = null;
754
                //echo $element['type'] . ':' . $elementName . ':' . $element['value'] . '<br>';
755
756
                // If the element is a checkbox, clear its value of checked.
757
                if ($element['type'] === 'checkbox'
758
                    || $element['type'] === 'checkbox-multiple'
759
                ) {
760
                    $element['checked'] = false;
761
                }
762
763
                // Do validation even when the form element is not set?
764
                // Duplicate code, revise this section and move outside
765
                // this if-statement?
766
                if (isset($element['validation'])) {
767
                    $element['validation-pass'] = $element->Validate($element['validation'], $this);
768
769
                    if ($element['validation-pass'] === false) {
770
                        $values[$elementName] = [
771
                            'value' => $element['value'], 'validation-messages' => $element['validation-messages']
772
                        ];
773
                        $validates = false;
774
                    }
775
                }
776
            }
777
        }
778
779
        // Prepare if data should be stored in the session during redirects
780
        // Did form validation or the callback fail?
781
        if ($validates === false
782
            || $callbackStatus === false
783
        ) {
784
            $session->set($this->sessionKey["failed"], $values);
785
        } elseif ($remember) {
786
            // Hmmm, why do I want to use this
787
            $session->set($this->sessionKey["remember"], $values);
788
        }
789
790
        if ($this->rememberValues) {
791
            // Remember all posted values
792
            $session->set($this->sessionKey["save"], $values);
793
        }
794
795
        // Lets se what the return value should be
796
        $ret = $validates
797
            ? $callbackStatus
798
            : $validates;
799
800
801
        if ($ret === true && isset($callIfSuccess)) {
802
            // Use callback for success, if defined
803
            if (!is_callable($callIfSuccess)) {
804
                throw new Exception("Form, success-method is not callable.");
805
            }
806
            call_user_func_array($callIfSuccess, [$this]);
807
        } elseif ($ret === false && isset($callIfFail)) {
808
            // Use callback for fail, if defined
809
            if (!is_callable($callIfFail)) {
810
                throw new Exception("Form, success-method is not callable.");
811
            }
812
            call_user_func_array($callIfFail, [$this]);
813
        }
814
815
        return $ret;
816
    }
817
}
818