Passed
Push — 4.x ( bd875a...fa991c )
by Doug
17:17 queued 12:22
created

UnitOfMeasureFactory::makeUnit()   D

Complexity

Conditions 35
Paths 34

Size

Total Lines 102
Code Lines 77

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 69
CRAP Score 35

Importance

Changes 0
Metric Value
eloc 77
dl 0
loc 102
c 0
b 0
f 0
ccs 69
cts 69
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 implements UnitOfMeasureIds
27
{
28
    /** @var Repository */
29
    private static $repository;
30
31
    /**
32
     * @param float|string $measurement
33
     */
34 7005
    public static function makeUnit($measurement, int $epsgUnitCode): UnitOfMeasure
35
    {
36 7005
        $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...
37 7005
        $allData = $repository->getUnitsOfMeasure(true);
0 ignored issues
show
Unused Code introduced by
The call to PHPCoord\EPSG\Repository::getUnitsOfMeasure() has too many arguments starting with true. ( Ignorable by Annotation )

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

37
        /** @scrutinizer ignore-call */ 
38
        $allData = $repository->getUnitsOfMeasure(true);

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...
38
39 7005
        if (!isset($allData[$epsgUnitCode])) {
40 1
            throw new UnknownUnitOfMeasureException($epsgUnitCode);
41
        }
42
43 7004
        $unitData = $allData[$epsgUnitCode];
44
45
        /*
46
         * Common units (and those that require special handling) having discrete implementations,
47
         * try those first.
48
         */
49
        switch ($epsgUnitCode) {
50 7004
            case self::EPSG_ANGLE_RADIAN_PER_SECOND:
51 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

51
                return new Rate(new Radian(/** @scrutinizer ignore-type */ $measurement), new Second(1));
Loading history...
52 7003
            case self::EPSG_ANGLE_ARC_SECONDS_PER_YEAR:
53 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

53
                return new Rate(new ArcSecond(/** @scrutinizer ignore-type */ $measurement), new Year(1));
Loading history...
54 7002
            case self::EPSG_ANGLE_MILLIARC_SECONDS_PER_YEAR:
55 1
                return new Rate(self::makeUnit($measurement, self::EPSG_ANGLE_MILLIARC_SECOND), new Year(1));
56 7002
            case self::EPSG_LENGTH_METRE_PER_SECOND:
57 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

57
                return new Rate(new Metre(/** @scrutinizer ignore-type */ $measurement), new Second(1));
Loading history...
58 7001
            case self::EPSG_LENGTH_METRES_PER_YEAR:
59 1
                return new Rate(new Metre($measurement), new Year(1));
60 7000
            case self::EPSG_LENGTH_MILLIMETRES_PER_YEAR:
61 1
                return new Rate(self::makeUnit($measurement, self::EPSG_LENGTH_MILLIMETRE), new Year(1));
62 7000
            case self::EPSG_LENGTH_CENTIMETRES_PER_YEAR:
63 1
                return new Rate(self::makeUnit($measurement, self::EPSG_LENGTH_CENTIMETRE), new Year(1));
64 7000
            case self::EPSG_SCALE_UNITY_PER_SECOND:
65 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

65
                return new Rate(new Unity(/** @scrutinizer ignore-type */ $measurement), new Second(1));
Loading history...
66 6999
            case self::EPSG_SCALE_PARTS_PER_BILLION_PER_YEAR:
67 1
                return new Rate(self::makeUnit($measurement, self::EPSG_SCALE_PARTS_PER_BILLION), new Year(1));
68 6999
            case self::EPSG_SCALE_PARTS_PER_MILLION_PER_YEAR:
69 1
                return new Rate(self::makeUnit($measurement, self::EPSG_SCALE_PARTS_PER_MILLION), new Year(1));
70 6999
            case self::EPSG_ANGLE_RADIAN:
71 1
                return new Radian($measurement);
72 6998
            case self::EPSG_ANGLE_DEGREE:
73 6692
                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

73
                return new Degree(/** @scrutinizer ignore-type */ $measurement);
Loading history...
74 6995
            case self::EPSG_ANGLE_ARC_SECOND:
75 1
                return new ArcSecond($measurement);
76 6994
            case self::EPSG_ANGLE_DEGREE_MINUTE_SECOND:
77 1
                return Degree::fromDegreeMinuteSecond((string) $measurement);
78 6993
            case self::EPSG_ANGLE_DEGREE_MINUTE_SECOND_HEMISPHERE:
79 1
                return Degree::fromDegreeMinuteSecondHemisphere((string) $measurement);
80 6992
            case self::EPSG_ANGLE_HEMISPHERE_DEGREE_MINUTE_SECOND:
81 1
                return Degree::fromHemisphereDegreeMinuteSecond((string) $measurement);
82 6991
            case self::EPSG_ANGLE_DEGREE_MINUTE:
83 1
                return Degree::fromDegreeMinute((string) $measurement);
84 6990
            case self::EPSG_ANGLE_DEGREE_MINUTE_HEMISPHERE:
85 1
                return Degree::fromDegreeMinuteHemisphere((string) $measurement);
86 6989
            case self::EPSG_ANGLE_HEMISPHERE_DEGREE_MINUTE:
87 1
                return Degree::fromHemisphereDegreeMinute((string) $measurement);
88 6988
            case self::EPSG_ANGLE_DEGREE_HEMISPHERE:
89 1
                return Degree::fromDegreeHemisphere((string) $measurement);
90 6987
            case self::EPSG_ANGLE_HEMISPHERE_DEGREE:
91 1
                return Degree::fromHemisphereDegree((string) $measurement);
92 6986
            case self::EPSG_ANGLE_SEXAGESIMAL_DMS_S:
93 1
                return Degree::fromSexagesimalDMSS((string) $measurement);
94 6985
            case self::EPSG_ANGLE_SEXAGESIMAL_DMS:
95 105
                return Degree::fromSexagesimalDMS((string) $measurement);
96 6972
            case self::EPSG_ANGLE_SEXAGESIMAL_DM:
97 1
                return Degree::fromSexagesimalDM((string) $measurement);
98 6971
            case self::EPSG_LENGTH_METRE:
99 6812
                return new Metre($measurement);
100 213
            case self::EPSG_SCALE_UNITY:
101 1
                return new Unity($measurement);
102 212
            case self::EPSG_TIME_SECOND:
103 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

103
                return new Second(/** @scrutinizer ignore-type */ $measurement);
Loading history...
104 211
            case self::EPSG_TIME_YEAR:
105 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

105
                return new Year(/** @scrutinizer ignore-type */ $measurement);
Loading history...
106
        }
107
108
        /*
109
         * Check that the unit can be defined by reference to SI, if it can't it needs special handling and needs to be
110
         * in the list above
111
         */
112
        // @codeCoverageIgnoreStart
113
        if ($unitData['factor_b'] === null ||
114
            !in_array(
115
                $unitData['target_uom_code'],
116
                [
117
                    self::EPSG_ANGLE_RADIAN,
118
                    self::EPSG_LENGTH_METRE,
119
                    self::EPSG_SCALE_UNITY,
120
                    //self::EPSG_TIME_SECOND,  all time units in the DB are currently handled above
121
                ],
122
                true
123
            )
124
        ) {
125
            throw new UnknownUnitOfMeasureException($epsgUnitCode);
126
        }
127
        // @codeCoverageIgnoreEnd
128
129 210
        switch ($unitData['unit_of_meas_type']) {
130 210
            case 'angle':
131 64
                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

131
                return new ExoticAngle(/** @scrutinizer ignore-type */ $measurement, $unitData['unit_of_meas_name'], $unitData['factor_b'], $unitData['factor_c']);
Loading history...
132 147
            case 'length':
133 137
                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

133
                return new ExoticLength(/** @scrutinizer ignore-type */ $measurement, $unitData['unit_of_meas_name'], $unitData['factor_b'], $unitData['factor_c']);
Loading history...
134 10
            case 'scale':
135 10
                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

135
                return new ExoticScale(/** @scrutinizer ignore-type */ $measurement, $unitData['unit_of_meas_name'], $unitData['factor_b'], $unitData['factor_c']);
Loading history...
136
        }
137
    }
138
139 5
    public static function convertAngle(Angle $angle, int $targetEpsgUnitCode): Angle
140
    {
141 5
        $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...
142 5
        $allData = $repository->getUnitsOfMeasure(true);
0 ignored issues
show
Unused Code introduced by
The call to PHPCoord\EPSG\Repository::getUnitsOfMeasure() has too many arguments starting with true. ( Ignorable by Annotation )

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

142
        /** @scrutinizer ignore-call */ 
143
        $allData = $repository->getUnitsOfMeasure(true);

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...
143
144 5
        if (!isset($allData[$targetEpsgUnitCode])) {
145
            throw new UnknownUnitOfMeasureException($targetEpsgUnitCode);
146
        }
147
148 5
        $targetUnitData = $allData[$targetEpsgUnitCode];
149
150 5
        return self::makeUnit($angle->asRadians()->getValue() * $targetUnitData['factor_c'] / $targetUnitData['factor_b'], $targetEpsgUnitCode);
151
    }
152
153 16
    public static function convertLength(Length $length, int $targetEpsgUnitCode): Length
154
    {
155 16
        $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...
156 16
        $allData = $repository->getUnitsOfMeasure(true);
0 ignored issues
show
Unused Code introduced by
The call to PHPCoord\EPSG\Repository::getUnitsOfMeasure() has too many arguments starting with true. ( Ignorable by Annotation )

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

156
        /** @scrutinizer ignore-call */ 
157
        $allData = $repository->getUnitsOfMeasure(true);

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...
157
158 16
        if (!isset($allData[$targetEpsgUnitCode])) {
159
            throw new UnknownUnitOfMeasureException($targetEpsgUnitCode);
160
        }
161
162 16
        $targetUnitData = $allData[$targetEpsgUnitCode];
163
164 16
        return self::makeUnit($length->asMetres()->getValue() * $targetUnitData['factor_c'] / $targetUnitData['factor_b'], $targetEpsgUnitCode);
165
    }
166
}
167