Complex classes like ConnectionManager 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 ConnectionManager, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
46 | class ConnectionManager implements SingletonInterface, ClearCacheActionsHookInterface |
||
47 | { |
||
48 | |||
49 | /** |
||
50 | * @var array |
||
51 | */ |
||
52 | protected static $connections = []; |
||
53 | |||
54 | /** |
||
55 | * Gets a Solr connection. |
||
56 | * |
||
57 | * Instead of generating a new connection with each call, connections are |
||
58 | * kept and checked whether the requested connection already exists. If a |
||
59 | * connection already exists, it's reused. |
||
60 | * |
||
61 | * @param string $host Solr host (optional) |
||
62 | * @param int $port Solr port (optional) |
||
63 | * @param string $path Solr path (optional) |
||
64 | * @param string $scheme Solr scheme, defaults to http, can be https (optional) |
||
65 | * @param string $username Solr user name (optional) |
||
66 | * @param string $password Solr password (optional) |
||
67 | * @return SolrService A solr connection. |
||
68 | */ |
||
69 | |||
70 | 68 | public function getConnection($host = '', $port = 8983, $path = '/solr/', $scheme = 'http', $username = '', $password = '') |
|
71 | { |
||
72 | 68 | if (empty($host)) { |
|
73 | 1 | GeneralUtility::devLog( |
|
74 | 'ApacheSolrForTypo3\Solr\ConnectionManager::getConnection() called with empty |
||
75 | host parameter. Using configuration from TSFE, might be |
||
76 | inaccurate. Always provide a host or use the getConnectionBy* |
||
77 | 1 | methods.', |
|
78 | 1 | 'solr', |
|
79 | 1 | 2 |
|
80 | ); |
||
81 | |||
82 | 1 | $configuration = Util::getSolrConfiguration(); |
|
83 | 1 | $host = $configuration->getSolrHost(); |
|
84 | 1 | $port = $configuration->getSolrPort(); |
|
85 | 1 | $path = $configuration->getSolrPath(); |
|
86 | 1 | $scheme = $configuration->getSolrScheme(); |
|
87 | 1 | $username = $configuration->getSolrUsername(); |
|
88 | 1 | $password = $configuration->getSolrPassword(); |
|
89 | } |
||
90 | |||
91 | 68 | $connectionHash = md5($scheme . '://' . $host . $port . $path . $username . $password); |
|
92 | |||
93 | 68 | if (!isset(self::$connections[$connectionHash])) { |
|
94 | 68 | $connection = GeneralUtility::makeInstance(SolrService::class, $host, $port, $path, $scheme); |
|
95 | 67 | if ($username !== '') { |
|
96 | 62 | $connection->setAuthenticationCredentials($username, $password); |
|
97 | } |
||
98 | |||
99 | 67 | self::$connections[$connectionHash] = $connection; |
|
100 | } |
||
101 | |||
102 | 67 | return self::$connections[$connectionHash]; |
|
103 | } |
||
104 | |||
105 | /** |
||
106 | * Creates a solr configuration from the configuration array and returns it. |
||
107 | * |
||
108 | * @param array $config The solr configuration array |
||
109 | * @return SolrService |
||
110 | */ |
||
111 | 65 | protected function getConnectionFromConfiguration(array $config) |
|
112 | { |
||
113 | 65 | return $this->getConnection( |
|
114 | 65 | $config['solrHost'], |
|
115 | 65 | $config['solrPort'], |
|
116 | 65 | $config['solrPath'], |
|
117 | 65 | $config['solrScheme'], |
|
118 | 65 | $config['solrUsername'], |
|
119 | 65 | $config['solrPassword'] |
|
120 | ); |
||
121 | } |
||
122 | |||
123 | /** |
||
124 | * Gets a Solr configuration for a page ID. |
||
125 | * |
||
126 | * @param int $pageId A page ID. |
||
127 | * @param int $language The language ID to get the connection for as the path may differ. Optional, defaults to 0. |
||
128 | * @param string $mount Comma list of MountPoint parameters |
||
129 | * @return array A solr configuration. |
||
130 | * @throws NoSolrConnectionFoundException |
||
131 | */ |
||
132 | 56 | public function getConfigurationByPageId($pageId, $language = 0, $mount = '') |
|
133 | { |
||
134 | // find the root page |
||
135 | 56 | $pageSelect = GeneralUtility::makeInstance(PageRepository::class); |
|
136 | |||
137 | /** @var Rootline $rootLine */ |
||
138 | 56 | $rootLine = GeneralUtility::makeInstance(Rootline::class, $pageSelect->getRootLine($pageId, $mount)); |
|
139 | 56 | $siteRootPageId = $rootLine->getRootPageId(); |
|
140 | |||
141 | try { |
||
142 | 56 | $solrConfiguration = $this->getConfigurationByRootPageId($siteRootPageId, $language); |
|
143 | 1 | } catch (NoSolrConnectionFoundException $nscfe) { |
|
144 | /* @var $noSolrConnectionException NoSolrConnectionFoundException */ |
||
145 | 1 | $noSolrConnectionException = GeneralUtility::makeInstance( |
|
146 | 1 | NoSolrConnectionFoundException::class, |
|
147 | 1 | $nscfe->getMessage() . ' Initial page used was [' . $pageId . ']', |
|
148 | 1 | 1275399922 |
|
149 | ); |
||
150 | 1 | $noSolrConnectionException->setPageId($pageId); |
|
151 | |||
152 | 1 | throw $noSolrConnectionException; |
|
153 | } |
||
154 | |||
155 | 55 | return $solrConfiguration; |
|
156 | } |
||
157 | |||
158 | /** |
||
159 | * Gets a Solr connection for a page ID. |
||
160 | * |
||
161 | * @param int $pageId A page ID. |
||
162 | * @param int $language The language ID to get the connection for as the path may differ. Optional, defaults to 0. |
||
163 | * @param string $mount Comma list of MountPoint parameters |
||
164 | * @return SolrService A solr connection. |
||
165 | * @throws NoSolrConnectionFoundException |
||
166 | */ |
||
167 | 56 | public function getConnectionByPageId($pageId, $language = 0, $mount = '') |
|
168 | { |
||
169 | 56 | $solrServer = $this->getConfigurationByPageId($pageId, $language, $mount); |
|
170 | 55 | $solrConnection = $this->getConnectionFromConfiguration($solrServer); |
|
171 | 55 | return $solrConnection; |
|
172 | } |
||
173 | |||
174 | /** |
||
175 | * Gets a Solr configuration for a root page ID. |
||
176 | * |
||
177 | * @param int $pageId A root page ID. |
||
178 | * @param int $language The language ID to get the configuration for as the path may differ. Optional, defaults to 0. |
||
179 | * @return array A solr configuration. |
||
180 | * @throws NoSolrConnectionFoundException |
||
181 | */ |
||
182 | 57 | public function getConfigurationByRootPageId($pageId, $language = 0) |
|
183 | { |
||
184 | 57 | $connectionKey = $pageId . '|' . $language; |
|
185 | 57 | $solrServers = $this->getAllConfigurations(); |
|
186 | |||
187 | 57 | if (isset($solrServers[$connectionKey])) { |
|
188 | 55 | $solrConfiguration = $solrServers[$connectionKey]; |
|
189 | } else { |
||
190 | /* @var $noSolrConnectionException NoSolrConnectionFoundException */ |
||
191 | 2 | $noSolrConnectionException = GeneralUtility::makeInstance( |
|
192 | 2 | NoSolrConnectionFoundException::class, |
|
193 | 'Could not find a Solr connection for root page [' |
||
194 | 2 | . $pageId . '] and language [' . $language . '].', |
|
195 | 2 | 1275396474 |
|
196 | ); |
||
197 | 2 | $noSolrConnectionException->setRootPageId($pageId); |
|
198 | 2 | $noSolrConnectionException->setLanguageId($language); |
|
199 | |||
200 | 2 | throw $noSolrConnectionException; |
|
201 | } |
||
202 | |||
203 | 55 | return $solrConfiguration; |
|
204 | } |
||
205 | |||
206 | /** |
||
207 | * Gets a Solr connection for a root page ID. |
||
208 | * |
||
209 | * @param int $pageId A root page ID. |
||
210 | * @param int $language The language ID to get the connection for as the path may differ. Optional, defaults to 0. |
||
211 | * @return SolrService A solr connection. |
||
212 | * @throws NoSolrConnectionFoundException |
||
213 | */ |
||
214 | 6 | public function getConnectionByRootPageId($pageId, $language = 0) |
|
215 | { |
||
216 | 6 | $config = $this->getConfigurationByRootPageId($pageId, $language); |
|
217 | 6 | $solrConnection = $this->getConnectionFromConfiguration($config); |
|
218 | |||
219 | 6 | return $solrConnection; |
|
220 | } |
||
221 | |||
222 | /** |
||
223 | * Gets all connection configurations found. |
||
224 | * |
||
225 | * @return array An array of connection configurations. |
||
226 | */ |
||
227 | 67 | public function getAllConfigurations() |
|
228 | { |
||
229 | /** @var $registry Registry */ |
||
230 | 67 | $registry = GeneralUtility::makeInstance(Registry::class); |
|
231 | 67 | $solrConfigurations = $registry->get('tx_solr', 'servers', []); |
|
232 | |||
233 | 67 | return $solrConfigurations; |
|
234 | } |
||
235 | |||
236 | /** |
||
237 | * Stores the connections in the registry. |
||
238 | * |
||
239 | * @param array $solrConfigurations |
||
240 | */ |
||
241 | 3 | protected function setAllConfigurations(array $solrConfigurations) |
|
242 | { |
||
243 | /** @var $registry Registry */ |
||
244 | 3 | $registry = GeneralUtility::makeInstance(Registry::class); |
|
245 | 3 | $registry->set('tx_solr', 'servers', $solrConfigurations); |
|
246 | 3 | } |
|
247 | |||
248 | /** |
||
249 | * Gets all connections found. |
||
250 | * |
||
251 | * @return SolrService[] An array of initialized ApacheSolrForTypo3\Solr\SolrService connections |
||
252 | */ |
||
253 | 6 | public function getAllConnections() |
|
254 | { |
||
255 | 6 | $connections = []; |
|
256 | |||
257 | 6 | $solrConfigurations = $this->getAllConfigurations(); |
|
258 | 6 | foreach ($solrConfigurations as $solrConfiguration) { |
|
259 | 6 | $connections[] = $this->getConnectionFromConfiguration($solrConfiguration); |
|
260 | } |
||
261 | |||
262 | 6 | return $connections; |
|
263 | } |
||
264 | |||
265 | /** |
||
266 | * Gets all connection configurations for a given site. |
||
267 | * |
||
268 | * @param Site $site A TYPO3 site |
||
269 | * @return array An array of Solr connection configurations for a site |
||
270 | */ |
||
271 | 22 | public function getConfigurationsBySite(Site $site) |
|
272 | { |
||
273 | 22 | $solrConfigurations = []; |
|
274 | |||
275 | 22 | $allConfigurations = $this->getAllConfigurations(); |
|
276 | 22 | foreach ($allConfigurations as $configuration) { |
|
277 | 22 | if ($configuration['rootPageUid'] == $site->getRootPageId()) { |
|
278 | 22 | $solrConfigurations[] = $configuration; |
|
279 | } |
||
280 | } |
||
281 | |||
282 | 22 | return $solrConfigurations; |
|
283 | } |
||
284 | |||
285 | /** |
||
286 | * Gets all connections configured for a given site. |
||
287 | * |
||
288 | * @param Site $site A TYPO3 site |
||
289 | * @return SolrService[] An array of Solr connection objects (ApacheSolrForTypo3\Solr\SolrService) |
||
290 | */ |
||
291 | 11 | public function getConnectionsBySite(Site $site) |
|
292 | { |
||
293 | 11 | $connections = []; |
|
294 | |||
295 | 11 | $solrServers = $this->getConfigurationsBySite($site); |
|
296 | 11 | foreach ($solrServers as $solrServer) { |
|
297 | 11 | $connections[] = $this->getConnectionFromConfiguration($solrServer); |
|
298 | } |
||
299 | |||
300 | 11 | return $connections; |
|
301 | } |
||
302 | |||
303 | // updates |
||
304 | |||
305 | /** |
||
306 | * Adds a menu entry to the clear cache menu to detect Solr connections. |
||
307 | * |
||
308 | * @param array $cacheActions Array of CacheMenuItems |
||
309 | * @param array $optionValues Array of AccessConfigurations-identifiers (typically used by userTS with options.clearCache.identifier) |
||
310 | */ |
||
311 | public function manipulateCacheActions(&$cacheActions, &$optionValues) |
||
327 | |||
328 | /** |
||
329 | * Updates the connections in the registry. |
||
330 | * |
||
331 | */ |
||
332 | 2 | public function updateConnections() |
|
333 | { |
||
334 | 2 | $solrConnections = $this->getConfiguredSolrConnections(); |
|
335 | 2 | $solrConnections = $this->filterDuplicateConnections($solrConnections); |
|
336 | |||
337 | 2 | if (!empty($solrConnections)) { |
|
338 | 2 | $this->setAllConfigurations($solrConnections); |
|
339 | } |
||
340 | 2 | } |
|
341 | |||
342 | /** |
||
343 | * Entrypoint for the ajax request |
||
344 | */ |
||
345 | public function updateConnectionsInCacheMenu() |
||
346 | { |
||
347 | $this->updateConnections(); |
||
348 | } |
||
349 | |||
350 | /** |
||
351 | * Updates the Solr connections for a specific root page ID / site. |
||
352 | * |
||
353 | * @param int $rootPageId A site root page id |
||
354 | */ |
||
355 | 1 | public function updateConnectionByRootPageId($rootPageId) |
|
356 | { |
||
357 | 1 | $systemLanguages = $this->getSystemLanguages(); |
|
358 | 1 | $rootPage = GeneralUtility::makeInstance(Site::class, $rootPageId)->getRootPage(); |
|
359 | |||
360 | 1 | $updatedSolrConnections = []; |
|
361 | 1 | foreach ($systemLanguages as $languageId) { |
|
362 | 1 | $connection = $this->getConfiguredSolrConnectionByRootPage($rootPage, $languageId); |
|
363 | |||
364 | 1 | if (!empty($connection)) { |
|
365 | 1 | $updatedSolrConnections[$connection['connectionKey']] = $connection; |
|
366 | } |
||
367 | } |
||
368 | |||
369 | 1 | $solrConnections = $this->getAllConfigurations(); |
|
370 | 1 | $solrConnections = array_merge($solrConnections, $updatedSolrConnections); |
|
371 | 1 | $solrConnections = $this->filterDuplicateConnections($solrConnections); |
|
372 | 1 | $this->setAllConfigurations($solrConnections); |
|
373 | 1 | } |
|
374 | |||
375 | /** |
||
376 | * Finds the configured Solr connections. Also respects multi-site |
||
377 | * environments. |
||
378 | * |
||
379 | * @return array An array with connections, each connection with keys rootPageTitle, rootPageUid, solrHost, solrPort, solrPath |
||
380 | */ |
||
381 | 2 | protected function getConfiguredSolrConnections() |
|
403 | |||
404 | /** |
||
405 | * Gets the configured Solr connection for a specific root page and language ID. |
||
406 | * |
||
407 | * @param array $rootPage A root page record with at least title and uid |
||
408 | * @param int $languageId ID of a system language |
||
409 | * @return array A solr connection configuration. |
||
410 | */ |
||
411 | 3 | protected function getConfiguredSolrConnectionByRootPage(array $rootPage, $languageId) |
|
412 | { |
||
413 | 3 | $connection = []; |
|
414 | |||
415 | 3 | $languageId = intval($languageId); |
|
416 | 3 | GeneralUtility::_GETset($languageId, 'L'); |
|
463 | |||
464 | /** |
||
465 | * Gets the language name for a given language ID. |
||
466 | * |
||
467 | * @param int $languageId language ID |
||
468 | * @return string Language name |
||
469 | */ |
||
470 | 3 | protected function getLanguageName($languageId) |
|
488 | |||
489 | /** |
||
490 | * Creates a human readable label from the connections' configuration. |
||
491 | * |
||
492 | * @param array $connection Connection configuration |
||
493 | * @return string Connection label |
||
494 | */ |
||
495 | 3 | protected function buildConnectionLabel(array $connection) |
|
508 | |||
509 | /** |
||
510 | * Filters duplicate connections. When detecting the configured connections |
||
511 | * this is done with a little brute force by simply combining all root pages |
||
512 | * with all languages, this method filters out the duplicates. |
||
513 | * |
||
514 | * @param array $connections An array of unfiltered connections, containing duplicates |
||
515 | * @return array An array with connections, no duplicates. |
||
516 | */ |
||
517 | 3 | protected function filterDuplicateConnections(array $connections) |
|
537 | |||
538 | /** |
||
539 | * Finds the system's configured languages. |
||
540 | * |
||
541 | * @return array An array of language IDs |
||
542 | */ |
||
543 | 3 | protected function getSystemLanguages() |
|
562 | |||
563 | /** |
||
564 | * Gets the site's root pages. The "Is root of website" flag must be set, |
||
565 | * which usually is the case for pages with pid = 0. |
||
566 | * |
||
567 | * @return array An array of (partial) root page records, containing the uid and title fields |
||
568 | */ |
||
569 | 2 | protected function getRootPages() |
|
579 | } |
||
580 |