These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | use SMW\ApplicationFactory; |
||
4 | use SMW\NumberFormatter; |
||
5 | use SMW\Message; |
||
6 | use SMW\DataValues\UnitConversionFetcher; |
||
7 | |||
8 | /** |
||
9 | * @ingroup SMWDataValues |
||
10 | */ |
||
11 | |||
12 | /** |
||
13 | * This datavalue implements unit support custom units, for which users have |
||
14 | * provided linear conversion factors within the wiki. Those user settings |
||
15 | * are retrieved from a property page associated with this object. |
||
16 | * |
||
17 | * @author Markus Krötzsch |
||
18 | * @ingroup SMWDataValues |
||
19 | */ |
||
20 | class SMWQuantityValue extends SMWNumberValue { |
||
21 | |||
22 | /** |
||
23 | * Array with format (canonical unit ID string) => (conversion factor) |
||
24 | * @var float[]|bool |
||
25 | */ |
||
26 | protected $m_unitfactors = false; |
||
27 | |||
28 | /** |
||
29 | * Array with format (normalised unit string) => (canonical unit ID string) |
||
30 | * @var string[]|bool |
||
31 | */ |
||
32 | protected $m_unitids = false; |
||
33 | |||
34 | /** |
||
35 | * Ordered array of (normalized) units that should be displayed in tooltips, etc. |
||
36 | * @var string[]|bool |
||
37 | */ |
||
38 | protected $m_displayunits = false; |
||
39 | |||
40 | /** |
||
41 | * Main unit in canonical form (recognised by the conversion factor 1) |
||
42 | * @var string|bool |
||
43 | */ |
||
44 | protected $m_mainunit = false; |
||
45 | |||
46 | 20 | protected function convertToMainUnit( $number, $unit ) { |
|
47 | 20 | $this->initConversionData(); |
|
48 | |||
49 | 20 | if ( array_key_exists( $unit, $this->m_unitids ) ) { |
|
50 | 19 | $this->m_unitin = $this->m_unitids[$unit]; |
|
51 | 19 | assert( '$this->m_unitfactors[$this->m_unitin] != 0 /* Should be filtered by initConversionData() */' ); |
|
52 | 19 | $this->m_dataitem = new SMWDINumber( $number / $this->m_unitfactors[$this->m_unitin], $this->m_typeid ); |
|
53 | 19 | return true; |
|
54 | } else { // unsupported unit |
||
55 | 7 | return false; |
|
56 | } |
||
57 | } |
||
58 | |||
59 | 11 | protected function makeConversionValues() { |
|
60 | 11 | if ( $this->m_unitvalues !== false ) { |
|
61 | return; // do this only once |
||
62 | } |
||
63 | |||
64 | 11 | $this->m_unitvalues = array(); |
|
65 | |||
66 | 11 | if ( !$this->isValid() ) { |
|
67 | return; |
||
68 | } |
||
69 | |||
70 | 11 | $this->initDisplayData(); |
|
71 | |||
72 | 11 | if ( count( $this->m_displayunits ) == 0 ) { // no display units, just show all |
|
73 | 9 | foreach ( $this->m_unitfactors as $unit => $factor ) { |
|
74 | 9 | if ( $unit !== '' ) { // filter out the empty fallback unit that is always there |
|
75 | 9 | $this->m_unitvalues[$unit] = $this->m_dataitem->getNumber() * $factor; |
|
76 | } |
||
77 | } |
||
78 | } else { |
||
79 | 3 | foreach ( $this->m_displayunits as $unit ) { |
|
80 | /// NOTE We keep non-ID units unless the input unit is used, so display units can be used to pick |
||
81 | /// the preferred form of a unit. Doing this requires us to recompute the conversion values whenever |
||
82 | /// the m_unitin changes. |
||
83 | 3 | $unitkey = ( $this->m_unitids[$unit] == $this->m_unitin ) ? $this->m_unitids[$unit] : $unit; |
|
84 | 3 | $this->m_unitvalues[$unitkey] = $this->m_dataitem->getNumber() * $this->m_unitfactors[$this->m_unitids[$unit]]; |
|
85 | } |
||
86 | } |
||
87 | 11 | } |
|
88 | |||
89 | 6 | protected function makeUserValue() { |
|
90 | 6 | $printunit = false; // the normalised string of a known unit to use for printouts |
|
91 | |||
92 | // Check if a known unit is given as outputformat: |
||
93 | 6 | if ( ( $this->m_outformat ) && ( $this->m_outformat != '-' ) && |
|
94 | 6 | ( $this->m_outformat != '-n' ) && ( $this->m_outformat != '-u' ) ) { // first try given output unit |
|
95 | 2 | $wantedunit = $this->normalizeUnit( $this->m_outformat ); |
|
96 | 2 | if ( array_key_exists( $wantedunit, $this->m_unitids ) ) { |
|
97 | 2 | $printunit = $wantedunit; |
|
98 | } |
||
99 | } |
||
100 | |||
101 | // Alternatively, try to use the main display unit as a default: |
||
102 | 6 | if ( $printunit === false ) { |
|
103 | 6 | $this->initDisplayData(); |
|
104 | 6 | if ( count( $this->m_displayunits ) > 0 ) { |
|
105 | 3 | $printunit = reset( $this->m_displayunits ); |
|
106 | } |
||
107 | } |
||
108 | // Finally, fall back to main unit: |
||
109 | 6 | if ( $printunit === false ) { |
|
110 | 4 | $printunit = $this->getUnit(); |
|
111 | } |
||
112 | |||
113 | 6 | $asPrefix = isset( $this->prefixalUnitPreference[$printunit] ) && $this->prefixalUnitPreference[$printunit]; |
|
114 | |||
115 | 6 | $this->m_unitin = $this->m_unitids[$printunit]; |
|
116 | 6 | $this->m_unitvalues = false; // this array depends on m_unitin if displayunits were used, better invalidate it here |
|
0 ignored issues
–
show
|
|||
117 | |||
118 | 6 | $value = $this->m_dataitem->getNumber() * $this->m_unitfactors[$this->m_unitin]; |
|
119 | |||
120 | 6 | $this->m_caption = ''; |
|
121 | |||
122 | 6 | if ( $this->m_outformat != '-u' ) { // -u is the format for displaying the unit only |
|
123 | 6 | $this->m_caption .= ( ( $this->m_outformat != '-' ) && ( $this->m_outformat != '-n' ) ? $this->getLocalizedFormattedNumber( $value ) : $this->getNormalizedFormattedNumber( $value ) ); |
|
124 | } |
||
125 | |||
126 | 6 | if ( ( $printunit !== '' ) && ( $this->m_outformat != '-n' ) ) { // -n is the format for displaying the number only |
|
127 | |||
128 | 6 | $sep = ''; |
|
129 | |||
130 | 6 | if ( $this->m_outformat != '-u' ) { |
|
131 | 6 | $sep = ( $this->m_outformat != '-' ? ' ' : ' ' ); |
|
132 | } |
||
133 | |||
134 | 6 | $this->m_caption = $asPrefix ? $printunit . $sep . $this->m_caption : $this->m_caption . $sep . $printunit; |
|
135 | } |
||
136 | 6 | } |
|
137 | |||
138 | public function getUnitList() { |
||
139 | $this->initConversionData(); |
||
140 | return array_keys( $this->m_unitfactors ); |
||
141 | } |
||
142 | |||
143 | 5 | public function getUnit() { |
|
144 | 5 | $this->initConversionData(); |
|
145 | 5 | return $this->m_mainunit; |
|
0 ignored issues
–
show
|
|||
146 | } |
||
147 | |||
148 | /// The remaining functions are relatively "private" but are kept protected since |
||
149 | /// subclasses might exploit this to, e.g., "fake" conversion factors instead of |
||
150 | /// getting them from the database. A cheap way of making built-in types. |
||
151 | |||
152 | /** |
||
153 | * This method initializes $m_unitfactors, $m_unitids, and $m_mainunit. |
||
154 | */ |
||
155 | 20 | protected function initConversionData() { |
|
156 | 20 | if ( $this->m_unitids !== false ) { |
|
157 | 12 | return; // do the below only once |
|
158 | } |
||
159 | |||
160 | 20 | $unitConversionFetcher = new UnitConversionFetcher( $this ); |
|
161 | 20 | $unitConversionFetcher->fetchCachedConversionData( $this->m_property ); |
|
162 | |||
163 | 20 | if ( $unitConversionFetcher->getErrors() !== array() ) { |
|
164 | 7 | foreach ( $unitConversionFetcher->getErrors() as $error ) { |
|
165 | 7 | $this->addErrorMsg( |
|
166 | $error, |
||
167 | 7 | Message::TEXT, |
|
168 | 7 | Message::USER_LANGUAGE |
|
169 | ); |
||
170 | } |
||
171 | } |
||
172 | |||
173 | 20 | $this->m_unitids = $unitConversionFetcher->getUnitIds(); |
|
174 | 20 | $this->m_unitfactors = $unitConversionFetcher->getUnitFactors(); |
|
175 | 20 | $this->m_mainunit = $unitConversionFetcher->getMainUnit(); |
|
176 | 20 | $this->prefixalUnitPreference = $unitConversionFetcher->getPrefixalUnitPreference(); |
|
177 | 20 | } |
|
178 | |||
179 | /** |
||
180 | * This method initializes $m_displayunits. |
||
181 | */ |
||
182 | 12 | protected function initDisplayData() { |
|
183 | 12 | if ( $this->m_displayunits !== false ) { |
|
184 | 4 | return; // do the below only once |
|
185 | } |
||
186 | 12 | $this->initConversionData(); // needed to normalise unit strings |
|
187 | 12 | $this->m_displayunits = array(); |
|
188 | |||
189 | 12 | if ( is_null( $this->m_property ) || is_null( $this->m_property->getDIWikiPage() ) ) { |
|
190 | return; |
||
191 | } |
||
192 | |||
193 | 12 | $units = $this->getPropertySpecificationLookup()->getDisplayUnitsFor( |
|
194 | 12 | $this->getProperty() |
|
195 | ); |
||
196 | |||
197 | 12 | foreach ( $units as $unit ) { |
|
198 | 4 | $unit = $this->normalizeUnit( $unit ); |
|
199 | 4 | if ( array_key_exists( $unit, $this->m_unitids ) ) { |
|
200 | 4 | $this->m_displayunits[] = $unit; // do not avoid duplicates, users can handle this |
|
201 | } // note: we ignore unsuppported units -- no way to display them |
||
202 | } |
||
203 | 12 | } |
|
204 | } |
||
205 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..