Completed
Push — master ( 6cea70...aebf2a )
by Edgar
04:08
created

Transform   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 192
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 6
Bugs 0 Features 0
Metric Value
wmc 34
c 6
b 0
f 0
lcom 1
cbo 2
dl 0
loc 192
rs 9.2

18 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A newInstance() 0 14 3
A result() 0 4 1
A setArgumentDelimiter() 0 11 4
B rotate() 0 11 5
A translate() 0 4 1
A scale() 0 4 1
A skewX() 0 4 1
A skewY() 0 4 1
A matrix() 0 8 2
A getData() 0 4 1
A hasTransform() 0 4 1
A getTransform() 0 8 2
A addTransformSequence() 0 4 1
A buildTransformString() 0 10 2
A setTransformData() 0 12 4
A addTransformIfNeeded() 0 6 2
A shortcutBuild() 0 8 1
1
<?php
2
namespace nstdio\svg\util;
3
4
use Doctrine\Instantiator\Exception\InvalidArgumentException;
5
6
/**
7
 * Class Transform
8
 *
9
 * @package nstdio\svg\util
10
 * @author  Edgar Asatryan <[email protected]>
11
 */
12
final class Transform implements TransformInterface
13
{
14
    private $trans;
15
16
    private $data;
17
18
    private $sequence;
19
20
    private $argDelimiter = TransformInterface::ARG_DELIM_SPACE;
21
22
    /**
23
     * @var TransformMatcherInterface
24
     */
25
    private $matcher;
0 ignored issues
show
Unused Code introduced by
The property $matcher is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
26
27
    private function __construct()
28
    {
29
    }
30
31
    /**
32
     * Use this method to instantiate Transform class.
33
     *
34
     * @param                           $transformString
35
     *
36
     * @param TransformMatcherInterface $matcher
0 ignored issues
show
Documentation introduced by
Should the type for parameter $matcher not be null|TransformMatcherInterface?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
37
     *
38
     * @return Transform
39
     */
40
    public static function newInstance($transformString = null, TransformMatcherInterface $matcher = null)
41
    {
42
        $instance = new Transform();
43
        $instance->trans = $transformString;
44
        $instance->matcher = $matcher === null ? new TransformMatcher() : $matcher;
45
        $instance->sequence = $instance->matcher->makeSequence($transformString);
46
47
        foreach ($instance->sequence as $value) {
48
            $method = 'match' . ucfirst($value);
49
            $instance->data[$value] = $instance->matcher->$method($transformString);
50
        }
51
52
        return $instance;
53
    }
54
55
    /**
56
     * @inheritdoc
57
     */
58
    public function result()
59
    {
60
        return $this->trans;
61
    }
62
63
    /**
64
     * @inheritdoc
65
     */
66
    public function setArgumentDelimiter($delim)
67
    {
68
        if ($delim !== TransformInterface::ARG_DELIM_COMMA &&
69
            $delim !== TransformInterface::ARG_DELIM_COMMA_SPACE &&
70
            $delim !== TransformInterface::ARG_DELIM_SPACE
71
        ) {
72
            throw new \InvalidArgumentException("Invalid delimiter. See TransformInterface::setArgumentDelimiter documentation for valid value.");
73
        }
74
75
        $this->argDelimiter = $delim;
76
    }
77
78
    /**
79
     * @inheritdoc
80
     */
81
    public function rotate($angle, $cx = null, $cy = null)
82
    {
83
        if ($cx !== null && $cy === null) {
84
            $cy = $cx;
85
        }
86
        if ($cy !== null && $cx === null) {
87
            $cx = $cy;
88
        }
89
90
        return $this->shortcutBuild('rotate', [$angle, $cx, $cy]);
91
    }
92
93
    /**
94
     * @inheritdoc
95
     */
96
    public function translate($x, $y = null)
97
    {
98
        return $this->shortcutBuild('translate', [$x, $y]);
99
    }
100
101
    /**
102
     * @inheritdoc
103
     */
104
    public function scale($x, $y = null)
105
    {
106
        return $this->shortcutBuild('scale', [$x, $y]);
107
    }
108
109
    /**
110
     * @inheritdoc
111
     */
112
    public function skewX($x)
113
    {
114
        return $this->shortcutBuild('skewX', [$x]);
115
    }
116
117
    /**
118
     * @inheritdoc
119
     */
120
    public function skewY($y)
121
    {
122
        return $this->shortcutBuild('skewY', [$y]);
123
    }
124
125
    /**
126
     * @inheritdoc
127
     */
128
    public function matrix(array $matrix)
129
    {
130
        if (count($matrix) !== 6) {
131
            throw new InvalidArgumentException("Invalid matrix size. You must provide en array with 6 elements. " . count($matrix) . " elements given.");
132
        }
133
134
        return $this->shortcutBuild('matrix', $matrix);
135
    }
136
137
    /**
138
     * @return array
139
     */
140
    public function getData()
141
    {
142
        return $this->data;
143
    }
144
145
    private function hasTransform($transform)
146
    {
147
        return in_array($transform, $this->sequence);
148
    }
149
150
    private function getTransform($transform)
151
    {
152
        if ($this->hasTransform($transform)) {
153
            return $this->data[$transform];
154
        }
155
156
        return null;
157
    }
158
159
    private function addTransformSequence($transform)
160
    {
161
        $this->sequence[] = $transform;
162
    }
163
164
    private function buildTransformString()
165
    {
166
        $ret = '';
167
        foreach ($this->sequence as $transform) {
168
            $ret .= $transform . "(" . rtrim(implode($this->argDelimiter, $this->data[$transform])) . ") ";
169
        }
170
        $this->trans = rtrim($ret);
171
172
        return $this->trans;
173
    }
174
175
    private function setTransformData($transform, $data)
176
    {
177
        if (isset($this->data[$transform]) === true) {
178
            $oldData = $this->data[$transform];
179
            foreach ($data as $key => $item) {
180
                if ($item === null) {
181
                    $data[$key] = $oldData[$key];
182
                }
183
            }
184
        }
185
        $this->data[$transform] = $data;
186
    }
187
188
    private function addTransformIfNeeded($transform)
189
    {
190
        if ($this->getTransform($transform) === null) {
191
            $this->addTransformSequence($transform);
192
        }
193
    }
194
195
    private function shortcutBuild($transform, $data)
196
    {
197
        $this->addTransformIfNeeded($transform);
198
199
        $this->setTransformData($transform, $data);
200
201
        return $this->buildTransformString();
202
    }
203
}