Completed
Push — master ( 944e8c...873a6a )
by mw
32:14
created

TimeValueFormatter   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 241
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 43
lcom 1
cbo 6
dl 0
loc 241
rs 8.3157
c 1
b 0
f 1

7 Methods

Rating   Name   Duplication   Size   Complexity  
A isFormatterFor() 0 3 1
C format() 0 21 10
C getISO8601Date() 0 25 8
B getMediaWikiDate() 0 30 5
C getCaptionFromDataItem() 0 26 7
A getTimeString() 0 12 2
D getPreferredCaption() 0 30 10

How to fix   Complexity   

Complex Class

Complex classes like TimeValueFormatter often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use TimeValueFormatter, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace SMW\DataValues\ValueFormatters;
4
5
use SMW\Localizer;
6
use SMWDataValue as DataValue;
7
use SMWTimeValue as TimeValue;
8
use SMWDITime as DITime;
9
use RuntimeException;
10
11
/**
12
 * @license GNU GPL v2+
13
 * @since 2.4
14
 *
15
 * @author mwjames
16
 * @author Markus Krötzsch
17
 * @author Fabian Howahl
18
 * @author Terry A. Hurlbut
19
 */
20
class TimeValueFormatter extends DataValueFormatter {
21
22
	/**
23
	 * @since 2.4
24
	 *
25
	 * {@inheritDoc}
26
	 */
27
	public function isFormatterFor( DataValue $dataValue ) {
28
		return $dataValue instanceOf TimeValue;
29
	}
30
31
	/**
32
	 * @since 2.4
33
	 *
34
	 * {@inheritDoc}
35
	 */
36
	public function format( $type, $linker = null ) {
37
38
		if ( !$this->dataValue instanceOf TimeValue ) {
39
			throw new RuntimeException( "The formatter is missing a valid TimeValue object" );
40
		}
41
42
		if (
43
			$this->dataValue->isValid() &&
44
			( $type === self::WIKI_SHORT || $type === self::HTML_SHORT ) ) {
45
			return ( $this->dataValue->getCaption() !== false ) ? $this->dataValue->getCaption() : $this->getPreferredCaption();
46
		}
47
48
		if (
49
			$this->dataValue->isValid() &&
50
			( $type === self::WIKI_LONG || $type === self::HTML_LONG ) ) {
51
			return $this->getPreferredCaption();
52
		}
53
54
		// #1074
55
		return $this->dataValue->getCaption() !== false ? $this->dataValue->getCaption() : '';
56
	}
57
58
	/**
59
	 * @private
60
	 *
61
	 * Compute a string representation that largely follows the ISO8601 standard
62
	 * of representing dates. Large year numbers may have more than 4 digits,
63
	 * which is not strictly conforming to the standard. The date includes year,
64
	 * month, and day regardless of the input precision, but will only include
65
	 * time when specified.
66
	 *
67
	 * Conforming to the 2000 version of ISO8601, year 1 BC(E) is represented
68
	 * as "0000", year 2 BC(E) as "-0001" and so on.
69
	 *
70
	 * @since 2.4
71
	 *
72
	 * @param DITime $dataItem
0 ignored issues
show
Bug introduced by
There is no parameter named $dataItem. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
73
	 * @param boolean $mindefault determining whether values below the
74
	 * precision of our input should be completed with minimal or maximal
75
	 * conceivable values
76
	 *
77
	 * @return string
78
	 */
79
	public function getISO8601Date( $mindefault = true ) {
80
81
		$dataItem = $this->dataValue->getDataItemForCalendarModel( DITime::CM_GREGORIAN );
0 ignored issues
show
Bug introduced by
The method getDataItemForCalendarModel() does not exist on SMWDataValue. Did you maybe mean getDataItem()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
82
		$precision = $dataItem->getPrecision();
83
84
		$result = $dataItem->getYear() > 0 ? '' : '-';
85
		$result .= str_pad( $dataItem->getYear(), 4, "0", STR_PAD_LEFT );
86
87
		$monthnum = $precision >= DITime::PREC_YM ? $dataItem->getMonth() : ( $mindefault ? 1 : 12 );
88
		$result .= '-' . str_pad( $monthnum, 2, "0", STR_PAD_LEFT );
89
90
		$day = $dataItem->getDay();
91
92
		if ( !$mindefault && $precision < DITime::PREC_YMD ) {
93
			$day = DITime::getDayNumberForMonth( $monthnum, $dataItem->getYear(), DITime::CM_GREGORIAN );
94
		}
95
96
		$result .= '-' . str_pad( $day, 2, "0", STR_PAD_LEFT );
97
98
		if ( $precision === DITime::PREC_YMDT ) {
99
			$result .= 'T' . $this->getTimeString( ( $mindefault ? '00:00:00' : '23:59:59' ) );
100
		}
101
102
		return $result;
103
	}
104
105
	/**
106
	 * @private
107
	 *
108
	 * Use MediaWiki's date and time formatting. It can't handle all inputs
109
	 * properly, but has superior i18n support.
110
	 *
111
	 * @since 2.4
112
	 *
113
	 * @param DITime $dataItem
0 ignored issues
show
Bug introduced by
There is no parameter named $dataItem. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
114
	 *
115
	 * @return string
116
	 */
117
	public function getMediaWikiDate() {
118
119
		$dataItem = $this->dataValue->getDataItemForCalendarModel( DITime::CM_GREGORIAN );
0 ignored issues
show
Bug introduced by
The method getDataItemForCalendarModel() does not exist on SMWDataValue. Did you maybe mean getDataItem()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
120
		$precision = $dataItem->getPrecision();
121
122
		$contentLanguage = Localizer::getInstance()->getContentLanguage();
123
124
		$year = $dataItem->getYear();
125
126
		if ( $year < 0 || $year > 9999 ) {
127
			$year = '0000';
128
		}
129
130
		$year = str_pad( $year, 4, "0", STR_PAD_LEFT );
131
132
		if ( $precision <= DITime::PREC_Y ) {
133
			return $contentLanguage->formatNum( $year, true );
134
		}
135
136
		$month = str_pad( $dataItem->getMonth(), 2, "0", STR_PAD_LEFT );
137
		$day = str_pad( $dataItem->getDay(), 2, "0", STR_PAD_LEFT );
138
139
		if ( $precision <= DITime::PREC_YMD ) {
140
			return $contentLanguage->date( "$year$month$day" . '000000', false, false );
141
		}
142
143
		$time = str_replace( ':', '', $this->getTimeString() );
144
145
		return $contentLanguage->timeanddate( "$year$month$day$time", false, false );
146
	}
147
148
	/**
149
	 * @private
150
	 *
151
	 * @todo Internationalize the CE and BCE strings.
152
	 *
153
	 * Compute a suitable string to display the given date item.
154
	 *
155
	 * @note MediaWiki's date functions are not applicable for the range of
156
	 * historic dates we support.
157
	 *
158
	 * @since 2.4
159
	 *
160
	 * @param DITime $dataitem
0 ignored issues
show
Documentation introduced by
There is no parameter named $dataitem. Did you maybe mean $dataItem?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
161
	 *
162
	 * @return string
163
	 */
164
	public function getCaptionFromDataItem( DITime $dataItem ) {
165
166
		$extraneousLanguage = Localizer::getInstance()->getExtraneousLanguage();
167
168
		if ( $dataItem->getYear() > 0 ) {
169
			$cestring = '';
170
			$result = number_format( $dataItem->getYear(), 0, '.', '' ) . ( $cestring ? ( ' ' . $cestring ) : '' );
171
		} else {
172
			$bcestring = 'BC';
173
			$result = number_format( -( $dataItem->getYear() ), 0, '.', '' ) . ( $bcestring ? ( ' ' . $bcestring ) : '' );
174
		}
175
176
		if ( $dataItem->getPrecision() >= DITime::PREC_YM ) {
177
			$result = $extraneousLanguage->getMonthLabel( $dataItem->getMonth() ) . " " . $result;
178
		}
179
180
		if ( $dataItem->getPrecision() >= DITime::PREC_YMD ) {
181
			$result = $dataItem->getDay() . " " . $result;
182
		}
183
184
		if ( $dataItem->getPrecision() >= DITime::PREC_YMDT ) {
185
			$result .= " " . $this->getTimeString();
186
		}
187
188
		return $result;
189
	}
190
191
	/**
192
	 * @private
193
	 *
194
	 * Return the time as a string. The time string has the format HH:MM:SS,
195
	 * without any timezone information (see class documentation for details
196
	 * on current timezone handling).
197
	 * The parameter $default optionally specifies the value returned
198
	 * if the date is valid but has no explicitly specified time. It can
199
	 * also be set to false to detect this situation.
200
	 *
201
	 * @since  2.4
202
	 *
203
	 * @param string $default
204
	 *
205
	 * @return string
206
	 */
207
	public function getTimeString( $default = '00:00:00' ) {
208
209
		$dataItem = $this->dataValue->getDataItemForCalendarModel( DITime::CM_GREGORIAN );
0 ignored issues
show
Bug introduced by
The method getDataItemForCalendarModel() does not exist on SMWDataValue. Did you maybe mean getDataItem()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
210
211
		if ( $dataItem->getPrecision() < DITime::PREC_YMDT ) {
212
			return $default;
213
		}
214
215
		return sprintf( "%02d", $dataItem->getHour() ) . ':' .
216
		       sprintf( "%02d", $dataItem->getMinute() ) . ':' .
217
		       sprintf( "%02d", $dataItem->getSecond() );
218
	}
219
220
	/**
221
	 * Compute a suitable string to display this date, taking into account the
222
	 * output format and the preferrable calendar models for the data.
223
	 *
224
	 * @note MediaWiki's date functions are not applicable for the range
225
	 * of historic dates we support.
226
	 *
227
	 * @return string
228
	 */
229
	protected function getPreferredCaption() {
230
231
		$dataItem = $this->dataValue->getDataItem();
232
		$format = strtoupper( $this->dataValue->getOutputFormat() );
233
234
		if ( $format == 'ISO' || $this->dataValue->getOutputFormat() == '-' ) {
235
			return $this->getISO8601Date();
236
		} elseif ( $format == 'MEDIAWIKI' ) {
237
			return $this->getMediaWikiDate();
238
		} elseif ( $format == 'SORTKEY' ) {
239
			return $dataItem->getSortKey();
240
		} elseif ( $dataItem->getYear() > TimeValue::PREHISTORY && $dataItem->getPrecision() >= DITime::PREC_YM ) {
241
			// Do not convert between Gregorian and Julian if only
242
			// year is given (years largely overlap in history, but
243
			// assuming 1 Jan as the default date, the year number
244
			// would change in conversion).
245
			// Also do not convert calendars in prehistory: not
246
			// meaningful (getDataItemForCalendarModel may return null).
247
			if ( ( $format == 'JL' ) ||
248
				( $dataItem->getJD() < TimeValue::J1582
249
				  && $format != 'GR' ) ) {
250
				$model = DITime::CM_JULIAN;
251
			} else {
252
				$model = DITime::CM_GREGORIAN;
253
			}
254
			return $this->getCaptionFromDataItem( $this->dataValue->getDataItemForCalendarModel( $model ) );
0 ignored issues
show
Bug introduced by
The method getDataItemForCalendarModel() does not exist on SMWDataValue. Did you maybe mean getDataItem()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
255
		}
256
257
		return $this->getCaptionFromDataItem( $dataItem );
0 ignored issues
show
Compatibility introduced by
$dataItem of type object<SMWDataItem> is not a sub-type of object<SMWDITime>. It seems like you assume a child class of the class SMWDataItem to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
258
	}
259
260
}
261