DynamicActionTrait::normalize()   B
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 25
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 25
ccs 0
cts 22
cp 0
rs 8.439
cc 5
eloc 16
nc 4
nop 1
crap 30
1
<?php
2
3
namespace Majora\Framework\Domain\Action;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use Symfony\Component\PropertyAccess\PropertyAccess;
7
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
8
9
/**
10
 * Provides methods to use into action which are hydrated by forms
11
 */
12
trait DynamicActionTrait
13
{
14
    /**
15
     * @var ArrayCollection
16
     */
17
    protected $attributes;
18
19
    /**
20
     * @var PropertyAccessorInterface
21
     */
22
    private $propertyAccessor;
23
24
    /**
25
     * Magic call implementation which forward to dynamic getter / setter
26
     */
27
    public function __call($method, $arguments)
28
    {
29
        switch (true) {
30
31
            // accessor ?
32 View Code Duplication
            case strpos($method, 'get') === 0 :
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
33
                return $this->_get(lcfirst(preg_filter(
34
                    '/^get(.+)/', '$1', $method
35
                )));
36
37
            // mutator ?
38 View Code Duplication
            case strpos($method, 'set') === 0 :
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
39
                return $this->_set(
40
                    lcfirst(preg_filter('/^set(.+)/', '$1', $method)),
41
                    $arguments[0]
42
                );
43
44
            default:
45
                throw new \BadMethodCallException(sprintf('Method %s::%s() doesnt exists.',
46
                    get_class($this),
47
                    $method
48
                ));
49
        }
50
    }
51
52
    /**
53
     * Return attribute map
54
     *
55
     * @return ArrayCollection
56
     */
57
    private function getAttributes()
58
    {
59
        $this->attributes = $this->attributes ?: new ArrayCollection();
60
61
        return $this->attributes;
62
    }
63
64
    /**
65
     * Return internal property accessor
66
     *
67
     * @return PropertyAccessorInterface
68
     */
69
    private function getPropertyAccessor()
70
    {
71
        $this->propertyAccessor = $this->propertyAccessor ?:
72
            PropertyAccess::createPropertyAccessor()
73
        ;
74
75
        return $this->propertyAccessor;
76
    }
77
78
    /**
79
     * Returns data under given key, null if undefined
80
     *
81
     * @param string $key
82
     *
83
     * @return mixed
84
     */
85
    protected function _get($key)
86
    {
87
        return $this->getAttributes()->get($key);
88
    }
89
90
    /**
91
     * Tests if given key exists
92
     *
93
     * @param string $key
94
     *
95
     * @return boolean
96
     */
97
    protected function _has($key)
98
    {
99
        return $this->getAttributes()->containsKey($key);
100
    }
101
102
    /**
103
     * Stores given key as given value
104
     *
105
     * @param string $key
106
     * @param mixed  $value
107
     *
108
     * @return self
109
     */
110
    protected function _set($key, $value)
111
    {
112
        $this->getAttributes()->set($key, $value);
113
114
        return $this;
115
    }
116
117
    /**
118
     * Define given field on given object, if accessible
119
     *
120
     * @param mixed  $object
121
     * @param string $field
122
     *
123
     * @return mixed|null
124
     */
125
    protected function setIfDefined($object, $field)
126
    {
127
        $propertyAccessor = $this->getPropertyAccessor();
128
        if (!$this->_has($field)) {
129
            return $propertyAccessor->isReadable($object, $field) ?
130
                $propertyAccessor->getValue($object, $field) :
131
                null
132
            ;
133
        }
134
135
        $propertyAccessor->setValue(
136
            $object,
137
            $field,
138
            $value = $this->_get($field)
139
        );
140
141
        return $value;
142
    }
143
144
    /**
145
     * @see NormalizableInterface::getScopes()
146
     */
147
    public static function getScopes()
148
    {
149
        return array();
150
    }
151
152
    /**
153
     * @see NormalizableInterface::normalize()
154
     */
155
    public function normalize($scope = 'default')
156
    {
157
        $data = $this->getAttributes()->toArray();
158
159
        $scopes = $this->getScopes();
160
        if(empty($scopes[$scope])) {
161
            return $data;
162
        }
163
164
        $normalizedData = array();
165
        $propertyAccessor = PropertyAccess::createPropertyAccessor();
166
        foreach ($scopes[$scope] as $field) {
167
            $normalizedData[$field] = $propertyAccessor->isReadable(
168
                    $data,
169
                    $propertyPath = strpos($field, '[') === 0 ?
170
                        $field :
171
                        sprintf('[%s]', $field)
172
                ) ?
173
                $propertyAccessor->getValue($data, $propertyPath) :
174
                null
175
            ;
176
        }
177
178
        return $normalizedData;
179
    }
180
181
    /**
182
     * @see NormalizableInterface::denormalize()
183
     */
184
    public function denormalize(array $objectData)
185
    {
186
        foreach ($objectData as $key => $value) {
187
            $this->_set($key, $value);
188
        }
189
190
        return $this;
191
    }
192
193
    /**
194
     * @see SerializableInterface::serialize()
195
     */
196
    public function serialize($scope = 'default', PropertyAccessorInterface $propertyAccessor = null)
0 ignored issues
show
Unused Code introduced by
The parameter $propertyAccessor is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
197
    {
198
        @trigger_error(sprintf('The method %s() is deprecated and will be removed in 2.0. Use normalize() instead.', __METHOD__), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
199
200
        return $this->normalize($scope);
201
    }
202
203
    /**
204
     * @see SerializableInterface::deserialize()
205
     */
206
    public function deserialize(array $data, PropertyAccessorInterface $propertyAccessor = null)
0 ignored issues
show
Unused Code introduced by
The parameter $propertyAccessor is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
207
    {
208
        @trigger_error(sprintf('The method %s() is deprecated and will be removed in 2.0. Use denormalize() instead.', __METHOD__), E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
209
210
        return $this->denormalize($data);
211
    }
212
}
213