Complex classes like LanguageFallbackChainFactory 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 LanguageFallbackChainFactory, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
24 | class LanguageFallbackChainFactory { |
||
25 | |||
26 | /** |
||
27 | * Fallback levels |
||
28 | */ |
||
29 | const FALLBACK_ALL = 0xff; |
||
30 | |||
31 | /** |
||
32 | * The language itself, e.g. 'en' for 'en'. |
||
33 | */ |
||
34 | const FALLBACK_SELF = 1; |
||
35 | |||
36 | /** |
||
37 | * Other compatible languages that can be translated into the requested language |
||
38 | * (and translation is automatically done), e.g. 'sr', 'sr-ec' and 'sr-el' for 'sr'. |
||
39 | */ |
||
40 | const FALLBACK_VARIANTS = 2; |
||
41 | |||
42 | /** |
||
43 | * All other language from the system fallback chain, e.g. 'de' and 'en' for 'de-formal'. |
||
44 | */ |
||
45 | const FALLBACK_OTHERS = 4; |
||
46 | |||
47 | /** @var LanguageFactory */ |
||
48 | private $languageFactory; |
||
49 | |||
50 | /** @var LanguageConverterFactory */ |
||
51 | private $languageConverterFactory; |
||
52 | |||
53 | /** @var LanguageFallback */ |
||
54 | private $languageFallback; |
||
55 | |||
56 | /** |
||
57 | * @var array[] |
||
58 | */ |
||
59 | private $languageCache = []; |
||
60 | |||
61 | /** |
||
62 | * @var array[] |
||
63 | */ |
||
64 | private $userLanguageCache = []; |
||
65 | |||
66 | public function __construct( |
||
76 | |||
77 | /** |
||
78 | * Get the fallback chain based a single language, and specified fallback level. |
||
79 | * |
||
80 | * @param Language $language |
||
81 | * @param int $mode Bitfield of self::FALLBACK_* |
||
82 | * |
||
83 | * @return TermLanguageFallbackChain |
||
84 | */ |
||
85 | public function newFromLanguage( Language $language, $mode = self::FALLBACK_ALL ) { |
||
98 | |||
99 | /** |
||
100 | * Get the fallback chain based a single language code, and specified fallback level. |
||
101 | * |
||
102 | * @param string $languageCode |
||
103 | * @param int $mode Bitfield of self::FALLBACK_* |
||
104 | * |
||
105 | * @return TermLanguageFallbackChain |
||
106 | */ |
||
107 | public function newFromLanguageCode( $languageCode, $mode = self::FALLBACK_ALL ) { |
||
120 | |||
121 | /** |
||
122 | * Build fallback chain array for a given language or validated language code. |
||
123 | * |
||
124 | * @param Language|string $language Language object or language code as string |
||
125 | * @param int $mode Bitfield of self::FALLBACK_* |
||
126 | * @param TermLanguageFallbackChain[] $chain for recursive calls |
||
127 | * @param bool[] $fetched for recursive calls |
||
128 | * |
||
129 | * @throws InvalidArgumentException |
||
130 | * @return LanguageWithConversion[] |
||
131 | */ |
||
132 | private function buildFromLanguage( $language, $mode, array $chain = [], array &$fetched = [] ) { |
||
205 | |||
206 | /** |
||
207 | * Construct the fallback chain based on a context. Currently it just uses user and language info in it. |
||
208 | * |
||
209 | * @param IContextSource $context |
||
210 | * |
||
211 | * @return TermLanguageFallbackChain |
||
212 | */ |
||
213 | public function newFromContext( IContextSource $context ) { |
||
216 | |||
217 | /** |
||
218 | * Construct the fallback chain based on a context, but ignore the language info in it and use a specified one instead. |
||
219 | * |
||
220 | * @param IContextSource $context |
||
221 | * @param string $languageCode |
||
222 | * |
||
223 | * @return TermLanguageFallbackChain |
||
224 | */ |
||
225 | public function newFromContextAndLanguageCode( IContextSource $context, $languageCode ) { |
||
228 | |||
229 | /** |
||
230 | * Construct the fallback chain based on a user and a language, currently from data provided by Extension:Babel. |
||
231 | * |
||
232 | * @param User $user |
||
233 | * @param string $languageCode |
||
234 | * |
||
235 | * @return TermLanguageFallbackChain |
||
236 | */ |
||
237 | public function newFromUserAndLanguageCode( User $user, $languageCode ) { |
||
260 | |||
261 | private function getBabel( $languageCode, $user ) { |
||
286 | |||
287 | private function getBabelCategoryNames() { |
||
301 | |||
302 | /** |
||
303 | * Build fallback chain array for a given babel array. |
||
304 | * |
||
305 | * @param array $babel |
||
306 | * |
||
307 | * @return LanguageWithConversion[] |
||
308 | */ |
||
309 | public function buildFromBabel( array $babel ) { |
||
346 | |||
347 | } |
||
348 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: