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 |
||
50 | class ConnectionManager implements SingletonInterface, ClearCacheActionsHookInterface |
||
51 | { |
||
52 | |||
53 | /** |
||
54 | * @var array |
||
55 | */ |
||
56 | protected static $connections = []; |
||
57 | |||
58 | /** |
||
59 | * @var \ApacheSolrForTypo3\Solr\System\Records\SystemLanguage\SystemLanguageRepository |
||
60 | */ |
||
61 | protected $systemLanguageRepository; |
||
62 | |||
63 | /** |
||
64 | * @var \ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager |
||
65 | */ |
||
66 | protected $logger = null; |
||
67 | |||
68 | /** |
||
69 | * @param SystemLanguageRepository $systemLanguageRepository |
||
70 | */ |
||
71 | 83 | public function __construct(SystemLanguageRepository $systemLanguageRepository = null) |
|
72 | { |
||
73 | 83 | $this->systemLanguageRepository = isset($systemLanguageRepository) ? $systemLanguageRepository : GeneralUtility::makeInstance(SystemLanguageRepository::class); |
|
74 | 83 | } |
|
75 | |||
76 | /** |
||
77 | * Gets a Solr connection. |
||
78 | * |
||
79 | * Instead of generating a new connection with each call, connections are |
||
80 | * kept and checked whether the requested connection already exists. If a |
||
81 | * connection already exists, it's reused. |
||
82 | * |
||
83 | * @param string $host Solr host (optional) |
||
84 | * @param int $port Solr port (optional) |
||
85 | * @param string $path Solr path (optional) |
||
86 | * @param string $scheme Solr scheme, defaults to http, can be https (optional) |
||
87 | * @param string $username Solr user name (optional) |
||
88 | * @param string $password Solr password (optional) |
||
89 | * @return SolrService A solr connection. |
||
90 | */ |
||
91 | 76 | public function getConnection($host = '', $port = 8983, $path = '/solr/', $scheme = 'http', $username = '', $password = '') |
|
92 | { |
||
93 | 76 | if (empty($host)) { |
|
94 | 1 | $this->logger = GeneralUtility::makeInstance(SolrLogManager::class, __CLASS__); |
|
95 | 1 | $this->logger->log( |
|
96 | 1 | SolrLogManager::WARNING, |
|
97 | 1 | 'ApacheSolrForTypo3\Solr\ConnectionManager::getConnection() called with empty host parameter. Using configuration from TSFE, might be inaccurate. Always provide a host or use the getConnectionBy* methods.' |
|
98 | ); |
||
99 | |||
100 | 1 | $configuration = Util::getSolrConfiguration(); |
|
101 | 1 | $host = $configuration->getSolrHost(); |
|
102 | 1 | $port = $configuration->getSolrPort(); |
|
103 | 1 | $path = $configuration->getSolrPath(); |
|
104 | 1 | $scheme = $configuration->getSolrScheme(); |
|
105 | 1 | $username = $configuration->getSolrUsername(); |
|
106 | 1 | $password = $configuration->getSolrPassword(); |
|
107 | } |
||
108 | |||
109 | 76 | $connectionHash = md5($scheme . '://' . $host . $port . $path . $username . $password); |
|
110 | 76 | if (!isset(self::$connections[$connectionHash])) { |
|
111 | 76 | $connection = $this->buildSolrService($host, $port, $path, $scheme); |
|
112 | 75 | if (trim($username) !== '') { |
|
113 | 1 | $connection->setAuthenticationCredentials($username, $password); |
|
114 | } |
||
115 | |||
116 | 75 | self::$connections[$connectionHash] = $connection; |
|
117 | } |
||
118 | |||
119 | 75 | return self::$connections[$connectionHash]; |
|
120 | } |
||
121 | |||
122 | /** |
||
123 | * Create a Solr Service instance from the passed connection configuration. |
||
124 | * |
||
125 | * @param string $host |
||
126 | * @param int $port |
||
127 | * @param string $path |
||
128 | * @param string $scheme |
||
129 | * @return SolrService|object |
||
130 | */ |
||
131 | 71 | protected function buildSolrService($host, $port, $path, $scheme) |
|
132 | { |
||
133 | 71 | return GeneralUtility::makeInstance(SolrService::class, $host, $port, $path, $scheme); |
|
134 | } |
||
135 | |||
136 | /** |
||
137 | * Creates a solr configuration from the configuration array and returns it. |
||
138 | * |
||
139 | * @param array $config The solr configuration array |
||
140 | * @return SolrService |
||
141 | */ |
||
142 | 69 | protected function getConnectionFromConfiguration(array $config) |
|
143 | { |
||
144 | 69 | return $this->getConnection( |
|
145 | 69 | $config['solrHost'], |
|
146 | 69 | $config['solrPort'], |
|
147 | 69 | $config['solrPath'], |
|
148 | 69 | $config['solrScheme'], |
|
149 | 69 | $config['solrUsername'], |
|
150 | 69 | $config['solrPassword'] |
|
151 | ); |
||
152 | } |
||
153 | |||
154 | /** |
||
155 | * Gets a Solr configuration for a page ID. |
||
156 | * |
||
157 | * @param int $pageId A page ID. |
||
158 | * @param int $language The language ID to get the connection for as the path may differ. Optional, defaults to 0. |
||
159 | * @param string $mount Comma list of MountPoint parameters |
||
160 | * @return array A solr configuration. |
||
161 | * @throws NoSolrConnectionFoundException |
||
162 | */ |
||
163 | 59 | public function getConfigurationByPageId($pageId, $language = 0, $mount = '') |
|
164 | { |
||
165 | // find the root page |
||
166 | 59 | $pageSelect = GeneralUtility::makeInstance(PageRepository::class); |
|
167 | |||
168 | /** @var Rootline $rootLine */ |
||
169 | 59 | $rootLine = GeneralUtility::makeInstance(Rootline::class, $pageSelect->getRootLine($pageId, $mount)); |
|
170 | 59 | $siteRootPageId = $rootLine->getRootPageId(); |
|
171 | |||
172 | try { |
||
173 | 59 | $solrConfiguration = $this->getConfigurationByRootPageId($siteRootPageId, $language); |
|
174 | 2 | } catch (NoSolrConnectionFoundException $nscfe) { |
|
175 | /* @var $noSolrConnectionException NoSolrConnectionFoundException */ |
||
176 | 2 | $noSolrConnectionException = GeneralUtility::makeInstance( |
|
177 | 2 | NoSolrConnectionFoundException::class, |
|
178 | 2 | $nscfe->getMessage() . ' Initial page used was [' . $pageId . ']', |
|
179 | 2 | 1275399922 |
|
180 | ); |
||
181 | 2 | $noSolrConnectionException->setPageId($pageId); |
|
182 | |||
183 | 2 | throw $noSolrConnectionException; |
|
184 | } |
||
185 | |||
186 | 58 | return $solrConfiguration; |
|
187 | } |
||
188 | |||
189 | /** |
||
190 | * Gets a Solr connection for a page ID. |
||
191 | * |
||
192 | * @param int $pageId A page ID. |
||
193 | * @param int $language The language ID to get the connection for as the path may differ. Optional, defaults to 0. |
||
194 | * @param string $mount Comma list of MountPoint parameters |
||
195 | * @return SolrService A solr connection. |
||
196 | * @throws NoSolrConnectionFoundException |
||
197 | */ |
||
198 | 59 | public function getConnectionByPageId($pageId, $language = 0, $mount = '') |
|
199 | { |
||
200 | 59 | $solrServer = $this->getConfigurationByPageId($pageId, $language, $mount); |
|
201 | 58 | $solrConnection = $this->getConnectionFromConfiguration($solrServer); |
|
202 | 58 | return $solrConnection; |
|
203 | } |
||
204 | |||
205 | /** |
||
206 | * Gets a Solr configuration for a root page ID. |
||
207 | * |
||
208 | * @param int $pageId A root page ID. |
||
209 | * @param int $language The language ID to get the configuration for as the path may differ. Optional, defaults to 0. |
||
210 | * @return array A solr configuration. |
||
211 | * @throws NoSolrConnectionFoundException |
||
212 | */ |
||
213 | 60 | public function getConfigurationByRootPageId($pageId, $language = 0) |
|
214 | { |
||
215 | 60 | $connectionKey = $pageId . '|' . $language; |
|
216 | 60 | $solrServers = $this->getAllConfigurations(); |
|
217 | |||
218 | 60 | if (isset($solrServers[$connectionKey])) { |
|
219 | 58 | $solrConfiguration = $solrServers[$connectionKey]; |
|
220 | } else { |
||
221 | /* @var $noSolrConnectionException NoSolrConnectionFoundException */ |
||
222 | 3 | $noSolrConnectionException = GeneralUtility::makeInstance( |
|
223 | 3 | NoSolrConnectionFoundException::class, |
|
224 | 'Could not find a Solr connection for root page [' |
||
225 | 3 | . $pageId . '] and language [' . $language . '].', |
|
226 | 3 | 1275396474 |
|
227 | ); |
||
228 | 3 | $noSolrConnectionException->setRootPageId($pageId); |
|
229 | 3 | $noSolrConnectionException->setLanguageId($language); |
|
230 | |||
231 | 3 | throw $noSolrConnectionException; |
|
232 | } |
||
233 | |||
234 | 58 | return $solrConfiguration; |
|
235 | } |
||
236 | |||
237 | /** |
||
238 | * Gets a Solr connection for a root page ID. |
||
239 | * |
||
240 | * @param int $pageId A root page ID. |
||
241 | * @param int $language The language ID to get the connection for as the path may differ. Optional, defaults to 0. |
||
242 | * @return SolrService A solr connection. |
||
243 | * @throws NoSolrConnectionFoundException |
||
244 | */ |
||
245 | 6 | public function getConnectionByRootPageId($pageId, $language = 0) |
|
252 | |||
253 | /** |
||
254 | * Gets all connection configurations found. |
||
255 | * |
||
256 | * @return array An array of connection configurations. |
||
257 | */ |
||
258 | 73 | public function getAllConfigurations() |
|
266 | |||
267 | /** |
||
268 | * Stores the connections in the registry. |
||
269 | * |
||
270 | * @param array $solrConfigurations |
||
271 | */ |
||
272 | 3 | protected function setAllConfigurations(array $solrConfigurations) |
|
278 | |||
279 | /** |
||
280 | * Gets all connections found. |
||
281 | * |
||
282 | * @return SolrService[] An array of initialized ApacheSolrForTypo3\Solr\SolrService connections |
||
283 | */ |
||
284 | 7 | public function getAllConnections() |
|
285 | { |
||
295 | |||
296 | /** |
||
297 | * Gets all connection configurations for a given site. |
||
298 | * |
||
299 | * @param Site $site A TYPO3 site |
||
300 | * @return array An array of Solr connection configurations for a site |
||
301 | */ |
||
302 | 22 | public function getConfigurationsBySite(Site $site) |
|
315 | |||
316 | /** |
||
317 | * Gets all connections configured for a given site. |
||
318 | * |
||
319 | * @param Site $site A TYPO3 site |
||
320 | * @return SolrService[] An array of Solr connection objects (ApacheSolrForTypo3\Solr\SolrService) |
||
321 | */ |
||
322 | 16 | public function getConnectionsBySite(Site $site) |
|
333 | |||
334 | // updates |
||
335 | |||
336 | /** |
||
337 | * Adds a menu entry to the clear cache menu to detect Solr connections. |
||
338 | * |
||
339 | * @param array $cacheActions Array of CacheMenuItems |
||
340 | * @param array $optionValues Array of AccessConfigurations-identifiers (typically used by userTS with options.clearCache.identifier) |
||
341 | */ |
||
342 | public function manipulateCacheActions(&$cacheActions, &$optionValues) |
||
355 | |||
356 | /** |
||
357 | * Updates the connections in the registry. |
||
358 | * |
||
359 | */ |
||
360 | 2 | public function updateConnections() |
|
369 | |||
370 | /** |
||
371 | * Entrypoint for the ajax request |
||
372 | */ |
||
373 | public function updateConnectionsInCacheMenu() |
||
377 | |||
378 | /** |
||
379 | * Updates the Solr connections for a specific root page ID / site. |
||
380 | * |
||
381 | * @param int $rootPageId A site root page id |
||
382 | */ |
||
383 | 1 | public function updateConnectionByRootPageId($rootPageId) |
|
404 | |||
405 | /** |
||
406 | * Finds the configured Solr connections. Also respects multi-site |
||
407 | * environments. |
||
408 | * |
||
409 | * @return array An array with connections, each connection with keys rootPageTitle, rootPageUid, solrHost, solrPort, solrPath |
||
410 | */ |
||
411 | 2 | protected function getConfiguredSolrConnections() |
|
433 | |||
434 | /** |
||
435 | * Gets the configured Solr connection for a specific root page and language ID. |
||
436 | * |
||
437 | * @param array $rootPage A root page record with at least title and uid |
||
438 | * @param int $languageId ID of a system language |
||
439 | * @return array A solr connection configuration. |
||
440 | */ |
||
441 | 3 | protected function getConfiguredSolrConnectionByRootPage(array $rootPage, $languageId) |
|
493 | |||
494 | |||
495 | |||
496 | /** |
||
497 | * Creates a human readable label from the connections' configuration. |
||
498 | * |
||
499 | * @param array $connection Connection configuration |
||
500 | * @return string Connection label |
||
501 | */ |
||
502 | 3 | protected function buildConnectionLabel(array $connection) |
|
515 | |||
516 | /** |
||
517 | * Filters duplicate connections. When detecting the configured connections |
||
518 | * this is done with a little brute force by simply combining all root pages |
||
519 | * with all languages, this method filters out the duplicates. |
||
520 | * |
||
521 | * @param array $connections An array of unfiltered connections, containing duplicates |
||
522 | * @return array An array with connections, no duplicates. |
||
523 | */ |
||
524 | 3 | protected function filterDuplicateConnections(array $connections) |
|
544 | |||
545 | /** |
||
546 | * Gets the site's root pages. The "Is root of website" flag must be set, |
||
547 | * which usually is the case for pages with pid = 0. |
||
548 | * |
||
549 | * @return array An array of (partial) root page records, containing the uid and title fields |
||
550 | */ |
||
551 | 2 | protected function getRootPages() |
|
561 | } |
||
562 |