Conditional::setDefault()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Zerg\Field;
4
5
use Zerg\Stream\AbstractStream;
6
7
/**
8
 * Conditional field can represent one of other given field or field collection depending on value of related field.
9
 *
10
 * @since 0.1
11
 * @package Zerg\Field
12
 */
13
class Conditional extends AbstractField
14
{
15
    /**
16
     * @var int|string Key of selected declaration.
17
     */
18
    protected $key;
19
20
    /**
21
     * @var array|AbstractField[] Array of possible declarations.
22
     */
23
    protected $fields;
24
25
    /**
26
     * @var array|null|AbstractField Default declaration.
27
     */
28
    protected $default;
29
30 5
    public function __construct($key, array $fields = [], $options = [])
31
    {
32 5
        if (is_array($key)) {
33 1
            $this->configure($key);
34 1
        } else {
35 5
            $this->setKey($key);
36 5
            $this->setFields($fields);
37 5
            $this->configure($options);
38
        }
39 5
    }
40
41
    /**
42
     * Resolve needed field instance and call it's parse method.
43
     *
44
     * @api
45
     * @param AbstractStream $stream Stream from which resolved field reads.
46
     * @return mixed Value returned by resolved field.
47
     */
48 2
    public function parse(AbstractStream $stream)
49
    {
50 2
        $field = $this->resolveField();
51
52 1
        return $field->parse($stream);
53
    }
54
55
    /**
56
     * Resolve value by DataSet path, choose related declaration and return field instance.
57
     *
58
     * @return AbstractField Field instance created by chosen declaration.
59
     * @throws InvalidKeyException If no one declaration is not related to resolved value and
60
     * default declaration is not presented.
61
     */
62 3
    public function resolveField()
63
    {
64 3
        $field = $this;
65
        do {
66 3
            $field = $field->resolve();
67 2
        } while ($field instanceof self);
68
69 2
        return $field;
70
    }
71
72 3
    private function resolve()
73
    {
74 3
        $key = $this->resolveProperty('key');
75
76 3
        if (isset($this->fields[$key])) {
77 2
            $field = $this->fields[$key];
78 3
        } elseif ($this->default !== null) {
79 1
            $field = $this->default;
80 1
        } else {
81 1
            throw new InvalidKeyException(
82 1
                "Value '{$key}' does not correspond to a valid conditional key. Presented keys: '" .
83 1
                implode("', '", array_keys($this->fields)) . "'"
84 1
            );
85
        }
86
87
        // get form cache
88 2
        if ($field instanceof AbstractField) {
89 1
            return $field;
90
        }
91
92 2
        $field = Factory::get($field);
93 2
        $field->setDataSet($this->getDataSet());
94
95
        // cache field instance
96 2
        if (isset($this->fields[$key])) {
97 2
            $this->fields[$key] = $field;
98 2
        } else {
99 1
            $this->default = $field;
100
        }
101
102 2
        return $field;
103
    }
104
105
    /**
106
     * @param int|string $key
107
     */
108 5
    public function setKey($key)
109
    {
110 5
        $this->key = $key;
111 5
    }
112
113
    /**
114
     * @param array|null|AbstractField $default
115
     */
116 5
    public function setDefault($default)
117
    {
118 5
        $this->default = $default;
119 5
    }
120
121
    /**
122
     * @param array|AbstractField[] $fields
123
     */
124 5
    public function setFields($fields)
125
    {
126 5
        $this->fields = $fields;
127
    }
128
}