Passed
Push — 4.x ( 17e0c5...e9b635 )
by Doug
07:44
created

UnitOfMeasureFactory::makeUnit()   D

Complexity

Conditions 35
Paths 34

Size

Total Lines 102
Code Lines 77

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 42
CRAP Score 35

Importance

Changes 0
Metric Value
eloc 77
c 0
b 0
f 0
dl 0
loc 102
ccs 42
cts 42
cp 1
rs 4.1666
cc 35
nc 34
nop 2
crap 35

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * PHPCoord.
4
 *
5
 * @author Doug Wright
6
 */
7
declare(strict_types=1);
8
9
namespace PHPCoord\UnitOfMeasure;
10
11
use PHPCoord\EPSG\Repository;
12
use PHPCoord\Exception\UnknownUnitOfMeasureException;
13
use PHPCoord\UnitOfMeasure\Angle\Angle;
14
use PHPCoord\UnitOfMeasure\Angle\ArcSecond;
15
use PHPCoord\UnitOfMeasure\Angle\Degree;
16
use PHPCoord\UnitOfMeasure\Angle\ExoticAngle;
17
use PHPCoord\UnitOfMeasure\Angle\Radian;
18
use PHPCoord\UnitOfMeasure\Length\ExoticLength;
19
use PHPCoord\UnitOfMeasure\Length\Length;
20
use PHPCoord\UnitOfMeasure\Length\Metre;
21
use PHPCoord\UnitOfMeasure\Scale\ExoticScale;
22
use PHPCoord\UnitOfMeasure\Scale\Unity;
23
use PHPCoord\UnitOfMeasure\Time\Second;
24
use PHPCoord\UnitOfMeasure\Time\Year;
25
26
class UnitOfMeasureFactory
27
{
28
    /**
29
     * @var Repository
30
     */
31
    private static $repository;
32
33
    /**
34
     * @param float|string $measurement
35
     */
36 164
    public static function makeUnit($measurement, int $epsgUnitCode): UnitOfMeasure
37
    {
38 164
        $repository = self::$repository ?? new Repository();
39 164
        $allData = $repository->getUnitsOfMeasure();
40
41 164
        if (!isset($allData[$epsgUnitCode])) {
42 1
            throw new UnknownUnitOfMeasureException($epsgUnitCode);
43
        }
44
45 163
        $unitData = $allData[$epsgUnitCode];
46
47
        /*
48
         * Common units (and those that require special handling) having discrete implementations,
49
         * try those first.
50
         */
51 163
        switch ($epsgUnitCode) {
52
            case UnitOfMeasure::EPSG_ANGLE_RADIAN_PER_SECOND:
53 1
                return new Rate(new Radian($measurement), new Second(1));
0 ignored issues
show
Bug introduced by
It seems like $measurement can also be of type string; however, parameter $angle of PHPCoord\UnitOfMeasure\Angle\Radian::__construct() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

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

53
                return new Rate(new Radian(/** @scrutinizer ignore-type */ $measurement), new Second(1));
Loading history...
54
            case UnitOfMeasure::EPSG_ANGLE_ARC_SECONDS_PER_YEAR:
55 1
                return new Rate(new ArcSecond($measurement), new Year(1));
0 ignored issues
show
Bug introduced by
It seems like $measurement can also be of type string; however, parameter $angle of PHPCoord\UnitOfMeasure\A...rcSecond::__construct() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

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

55
                return new Rate(new ArcSecond(/** @scrutinizer ignore-type */ $measurement), new Year(1));
Loading history...
56
            case UnitOfMeasure::EPSG_ANGLE_MILLIARC_SECONDS_PER_YEAR:
57 1
                return new Rate(self::makeUnit($measurement, UnitOfMeasure::EPSG_ANGLE_MILLIARC_SECOND), new Year(1));
58
            case UnitOfMeasure::EPSG_LENGTH_METRE_PER_SECOND:
59 1
                return new Rate(new Metre($measurement), new Second(1));
0 ignored issues
show
Bug introduced by
It seems like $measurement can also be of type string; however, parameter $length of PHPCoord\UnitOfMeasure\Length\Metre::__construct() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

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

59
                return new Rate(new Metre(/** @scrutinizer ignore-type */ $measurement), new Second(1));
Loading history...
60
            case UnitOfMeasure::EPSG_LENGTH_METRES_PER_YEAR:
61 1
                return new Rate(new Metre($measurement), new Year(1));
62
            case UnitOfMeasure::EPSG_LENGTH_MILLIMETRES_PER_YEAR:
63 1
                return new Rate(self::makeUnit($measurement, UnitOfMeasure::EPSG_LENGTH_MILLIMETRE), new Year(1));
64
            case UnitOfMeasure::EPSG_LENGTH_CENTIMETRES_PER_YEAR:
65 1
                return new Rate(self::makeUnit($measurement, UnitOfMeasure::EPSG_LENGTH_CENTIMETRE), new Year(1));
66
            case UnitOfMeasure::EPSG_SCALE_UNITY_PER_SECOND:
67 1
                return new Rate(new Unity($measurement), new Second(1));
0 ignored issues
show
Bug introduced by
It seems like $measurement can also be of type string; however, parameter $scale of PHPCoord\UnitOfMeasure\Scale\Unity::__construct() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

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

67
                return new Rate(new Unity(/** @scrutinizer ignore-type */ $measurement), new Second(1));
Loading history...
68
            case UnitOfMeasure::EPSG_SCALE_PARTS_PER_BILLION_PER_YEAR:
69 1
                return new Rate(self::makeUnit($measurement, UnitOfMeasure::EPSG_SCALE_PARTS_PER_BILLION), new Year(1));
70
            case UnitOfMeasure::EPSG_SCALE_PARTS_PER_MILLION_PER_YEAR:
71 1
                return new Rate(self::makeUnit($measurement, UnitOfMeasure::EPSG_SCALE_PARTS_PER_MILLION), new Year(1));
72
            case UnitOfMeasure::EPSG_ANGLE_RADIAN:
73 1
                return new Radian($measurement);
74
            case UnitOfMeasure::EPSG_ANGLE_DEGREE:
75 50
                return new Degree($measurement);
0 ignored issues
show
Bug introduced by
It seems like $measurement can also be of type string; however, parameter $angle of PHPCoord\UnitOfMeasure\Angle\Degree::__construct() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

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

75
                return new Degree(/** @scrutinizer ignore-type */ $measurement);
Loading history...
76
            case UnitOfMeasure::EPSG_ANGLE_ARC_SECOND:
77 1
                return new ArcSecond($measurement);
78
            case UnitOfMeasure::EPSG_ANGLE_DEGREE_MINUTE_SECOND:
79 1
                return Degree::fromDegreeMinuteSecond((string) $measurement);
80
            case UnitOfMeasure::EPSG_ANGLE_DEGREE_MINUTE_SECOND_HEMISPHERE:
81 1
                return Degree::fromDegreeMinuteSecondHemisphere((string) $measurement);
82
            case UnitOfMeasure::EPSG_ANGLE_HEMISPHERE_DEGREE_MINUTE_SECOND:
83 1
                return Degree::fromHemisphereDegreeMinuteSecond((string) $measurement);
84
            case UnitOfMeasure::EPSG_ANGLE_DEGREE_MINUTE:
85 1
                return Degree::fromDegreeMinute((string) $measurement);
86
            case UnitOfMeasure::EPSG_ANGLE_DEGREE_MINUTE_HEMISPHERE:
87 1
                return Degree::fromDegreeMinuteHemisphere((string) $measurement);
88
            case UnitOfMeasure::EPSG_ANGLE_HEMISPHERE_DEGREE_MINUTE:
89 1
                return Degree::fromHemisphereDegreeMinute((string) $measurement);
90
            case UnitOfMeasure::EPSG_ANGLE_DEGREE_HEMISPHERE:
91 1
                return Degree::fromDegreeHemisphere((string) $measurement);
92
            case UnitOfMeasure::EPSG_ANGLE_HEMISPHERE_DEGREE:
93 1
                return Degree::fromHemisphereDegree((string) $measurement);
94
            case UnitOfMeasure::EPSG_ANGLE_SEXAGESIMAL_DMS_S:
95 1
                return Degree::fromSexagesimalDMSS((string) $measurement);
96
            case UnitOfMeasure::EPSG_ANGLE_SEXAGESIMAL_DMS:
97 5
                return Degree::fromSexagesimalDMS((string) $measurement);
98
            case UnitOfMeasure::EPSG_ANGLE_SEXAGESIMAL_DM:
99 1
                return Degree::fromSexagesimalDM((string) $measurement);
100
            case UnitOfMeasure::EPSG_LENGTH_METRE:
101 56
                return new Metre($measurement);
102
            case UnitOfMeasure::EPSG_SCALE_UNITY:
103 1
                return new Unity($measurement);
104
            case UnitOfMeasure::EPSG_TIME_SECOND:
105 1
                return new Second($measurement);
0 ignored issues
show
Bug introduced by
It seems like $measurement can also be of type string; however, parameter $time of PHPCoord\UnitOfMeasure\Time\Second::__construct() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

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

105
                return new Second(/** @scrutinizer ignore-type */ $measurement);
Loading history...
106
            case UnitOfMeasure::EPSG_TIME_YEAR:
107 1
                return new Year($measurement);
0 ignored issues
show
Bug introduced by
It seems like $measurement can also be of type string; however, parameter $time of PHPCoord\UnitOfMeasure\Time\Year::__construct() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

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

107
                return new Year(/** @scrutinizer ignore-type */ $measurement);
Loading history...
108
        }
109
110
        /*
111
         * Check that the unit can be defined by reference to SI, if it can't it needs special handling and needs to be
112
         * in the list above
113
         */
114
        // @codeCoverageIgnoreStart
115
        if ($unitData['factor_b'] === null ||
116
            !in_array(
117
                $unitData['target_uom_code'],
118
                [
119
                    UnitOfMeasure::EPSG_ANGLE_RADIAN,
120
                    UnitOfMeasure::EPSG_LENGTH_METRE,
121
                    UnitOfMeasure::EPSG_SCALE_UNITY,
122
                    //UnitOfMeasure::EPSG_TIME_SECOND,  all time units in the DB are currently handled above
123
                ],
124
                true
125
            )
126
        ) {
127
            throw new UnknownUnitOfMeasureException($epsgUnitCode);
128
        }
129
        // @codeCoverageIgnoreEnd
130
131 110
        switch ($unitData['unit_of_meas_type']) {
132 110
            case 'angle':
133 31
                return new ExoticAngle($measurement, $unitData['unit_of_meas_name'], $unitData['factor_b'], $unitData['factor_c']);
0 ignored issues
show
Bug introduced by
It seems like $measurement can also be of type string; however, parameter $angle of PHPCoord\UnitOfMeasure\A...ticAngle::__construct() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

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

133
                return new ExoticAngle(/** @scrutinizer ignore-type */ $measurement, $unitData['unit_of_meas_name'], $unitData['factor_b'], $unitData['factor_c']);
Loading history...
134 88
            case 'length':
135 66
                return new ExoticLength($measurement, $unitData['unit_of_meas_name'], $unitData['factor_b'], $unitData['factor_c']);
0 ignored issues
show
Bug introduced by
It seems like $measurement can also be of type string; however, parameter $length of PHPCoord\UnitOfMeasure\L...icLength::__construct() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

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

135
                return new ExoticLength(/** @scrutinizer ignore-type */ $measurement, $unitData['unit_of_meas_name'], $unitData['factor_b'], $unitData['factor_c']);
Loading history...
136 22
            case 'scale':
137 22
                return new ExoticScale($measurement, $unitData['unit_of_meas_name'], $unitData['factor_b'], $unitData['factor_c']);
0 ignored issues
show
Bug introduced by
It seems like $measurement can also be of type string; however, parameter $scale of PHPCoord\UnitOfMeasure\S...ticScale::__construct() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

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

137
                return new ExoticScale(/** @scrutinizer ignore-type */ $measurement, $unitData['unit_of_meas_name'], $unitData['factor_b'], $unitData['factor_c']);
Loading history...
138
        }
139
    }
140
141 17
    public static function convertAngle(Angle $angle, int $targetEpsgUnitCode): Angle
142
    {
143 17
        $repository = static::$repository ?? new Repository();
0 ignored issues
show
Bug introduced by
Since $repository is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $repository to at least protected.
Loading history...
144 17
        $allData = $repository->getUnitsOfMeasure();
145
146 17
        if (!isset($allData[$targetEpsgUnitCode])) {
147
            throw new UnknownUnitOfMeasureException($targetEpsgUnitCode);
148
        }
149
150 17
        $targetUnitData = $allData[$targetEpsgUnitCode];
151
152 17
        return self::makeUnit($angle->asRadians()->getValue() * $targetUnitData['factor_c'] / $targetUnitData['factor_b'], $targetEpsgUnitCode);
153
    }
154
155 40
    public static function convertLength(Length $length, int $targetEpsgUnitCode): Length
156
    {
157 40
        $repository = static::$repository ?? new Repository();
0 ignored issues
show
Bug introduced by
Since $repository is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $repository to at least protected.
Loading history...
158 40
        $allData = $repository->getUnitsOfMeasure();
159
160 40
        if (!isset($allData[$targetEpsgUnitCode])) {
161
            throw new UnknownUnitOfMeasureException($targetEpsgUnitCode);
162
        }
163
164 40
        $targetUnitData = $allData[$targetEpsgUnitCode];
165
166 40
        return self::makeUnit($length->asMetres()->getValue() * $targetUnitData['factor_c'] / $targetUnitData['factor_b'], $targetEpsgUnitCode);
167
    }
168
}
169