SpecialItemByTitle::switchForm()   B
last analyzed

Complexity

Conditions 7
Paths 12

Size

Total Lines 58

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 58
rs 7.983
c 0
b 0
f 0
cc 7
nc 12
nop 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Wikibase\Repo\Specials;
4
5
use Html;
6
use HTMLForm;
7
use Psr\Log\LoggerInterface;
8
use Site;
9
use SiteLookup;
10
use Wikibase\Lib\LanguageNameLookup;
11
use Wikibase\Lib\Store\EntityTitleLookup;
12
use Wikibase\Lib\Store\SiteLinkLookup;
13
use Wikibase\Repo\SiteLinkTargetProvider;
14
use Wikibase\Repo\WikibaseRepo;
15
16
/**
17
 * Enables accessing items by providing the identifier of a site and the title
18
 * of the corresponding page on that site.
19
 *
20
 * @license GPL-2.0-or-later
21
 * @author Jeroen De Dauw < [email protected] >
22
 * @author Daniel Kinzler
23
 */
24
class SpecialItemByTitle extends SpecialWikibasePage {
25
26
	/**
27
	 * @var EntityTitleLookup
28
	 */
29
	private $titleLookup;
30
31
	/**
32
	 * @var LanguageNameLookup
33
	 */
34
	private $languageNameLookup;
35
36
	/**
37
	 * @var SiteLookup
38
	 */
39
	private $sites;
40
41
	/**
42
	 * @var SiteLinkLookup
43
	 */
44
	private $siteLinkLookup;
45
46
	/**
47
	 * @var SiteLinkTargetProvider
48
	 */
49
	private $siteLinkTargetProvider;
50
51
	/**
52
	 * @var LoggerInterface
53
	 */
54
	private $logger;
55
56
	/**
57
	 * site link groups
58
	 *
59
	 * @var string[]
60
	 */
61
	private $groups;
62
63
	/**
64
	 * @see SpecialWikibasePage::__construct
65
	 *
66
	 * @param EntityTitleLookup $titleLookup
67
	 * @param LanguageNameLookup $languageNameLookup
68
	 * @param SiteLookup $siteLookup
69
	 * @param SiteLinkLookup $siteLinkLookup
70
	 * @param SiteLinkTargetProvider $siteLinkTargetProvider
71
	 * @param LoggerInterface $logger
72
	 * @param string[] $siteLinkGroups
73
	 */
74
	public function __construct(
75
		EntityTitleLookup $titleLookup,
76
		LanguageNameLookup $languageNameLookup,
77
		SiteLookup $siteLookup,
78
		SiteLinkLookup $siteLinkLookup,
79
		SiteLinkTargetProvider $siteLinkTargetProvider,
80
		LoggerInterface $logger,
81
		array $siteLinkGroups
82
	) {
83
		parent::__construct( 'ItemByTitle', '', true );
84
85
		$this->titleLookup = $titleLookup;
86
		$this->languageNameLookup = $languageNameLookup;
87
		$this->sites = $siteLookup;
88
		$this->siteLinkLookup = $siteLinkLookup;
89
		$this->siteLinkTargetProvider = $siteLinkTargetProvider;
90
		$this->logger = $logger;
91
		$this->groups = $siteLinkGroups;
92
	}
93
94
	public static function factory(): self {
95
		$wikibaseRepo = WikibaseRepo::getDefaultInstance();
96
97
		$siteLinkTargetProvider = new SiteLinkTargetProvider(
98
			$wikibaseRepo->getSiteLookup(),
99
			$wikibaseRepo->getSettings()->getSetting( 'specialSiteLinkGroups' )
100
		);
101
102
		return new self(
103
			$wikibaseRepo->getEntityTitleLookup(),
104
			new LanguageNameLookup(),
105
			$wikibaseRepo->getSiteLookup(),
106
			$wikibaseRepo->getStore()->newSiteLinkStore(),
107
			$siteLinkTargetProvider,
108
			$wikibaseRepo->getLogger(),
109
			$wikibaseRepo->getSettings()->getSetting( 'siteLinkGroups' )
110
		);
111
	}
112
113
	/**
114
	 * @see SpecialWikibasePage::execute
115
	 *
116
	 * @param string|null $subPage
117
	 */
118
	public function execute( $subPage ) {
119
		parent::execute( $subPage );
120
121
		// Setup
122
		$request = $this->getRequest();
123
		$parts = ( $subPage === '' ) ? [] : explode( '/', $subPage, 2 );
124
		$site = trim( $request->getVal( 'site', $parts[0] ?? '' ) );
125
		$page = trim( $request->getVal( 'page', $parts[1] ?? '' ) );
126
127
		$itemContent = null;
0 ignored issues
show
Unused Code introduced by
$itemContent is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
128
129
		// If there are enough data, then try to lookup the item content
130
		if ( $site !== '' && $page !== '' ) {
131
			// FIXME: This code is duplicated in ItemByTitleHelper::getItemId!
132
			// Try to get a item content
133
			$siteId = $this->stringNormalizer->trimToNFC( $site ); // no stripping of underscores here!
134
			$pageName = $this->stringNormalizer->trimToNFC( $page );
135
136
			if ( !$this->sites->getSite( $siteId ) ) {
137
				// HACK: If the site ID isn't known, add "wiki" to it; this allows the wikipedia
138
				// subdomains to be used to refer to wikipedias, instead of requiring their
139
				// full global id to be used.
140
				// @todo: Ideally, if the site can't be looked up by global ID, we
141
				// should try to look it up by local navigation ID.
142
				// Support for this depends on bug T50934.
143
				$siteId .= 'wiki';
144
			}
145
146
			$itemId = $this->siteLinkLookup->getItemIdForLink( $siteId, $pageName );
147
148
			// Do we have an item content, and if not can we try harder?
149
			if ( $itemId === null ) {
150
				// Try harder by requesting normalization on the external site
151
				$siteObj = $this->sites->getSite( $siteId );
152
				if ( $siteObj instanceof Site ) {
0 ignored issues
show
Bug introduced by
The class Site does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
153
					$pageName = $siteObj->normalizePageName( $page );
154
					if ( is_string( $pageName ) ) { // T191634
155
						$itemId = $this->siteLinkLookup->getItemIdForLink( $siteId, $pageName );
156
					}
157
				}
158
			}
159
160
			// Redirect to the item page if we found its content
161
			if ( $itemId !== null ) {
162
				$title = $this->titleLookup->getTitleForId( $itemId );
163
				$query = $request->getValues();
164
				unset( $query['title'] );
165
				unset( $query['site'] );
166
				unset( $query['page'] );
167
				$itemUrl = $title->getFullURL( $query );
168
				$this->getOutput()->redirect( $itemUrl );
169
				return;
170
			}
171
		}
172
173
		// If there is no item content post the switch form
174
		$this->switchForm( $site, $page );
175
	}
176
177
	/**
178
	 * Return options for the site input field.
179
	 *
180
	 * @return array
181
	 */
182
	private function getSiteOptions() {
183
		$options = [];
184
		foreach ( $this->siteLinkTargetProvider->getSiteList( $this->groups ) as $site ) {
185
			$siteId = $site->getGlobalId();
186
			$languageName = $this->languageNameLookup->getName( $site->getLanguageCode() );
187
			$options["$languageName ($siteId)"] = $siteId;
188
		}
189
		return $options;
190
	}
191
192
	/**
193
	 * Output a form to allow searching for a page
194
	 *
195
	 * @param string $siteId
196
	 * @param string $page
197
	 */
198
	private function switchForm( $siteId, $page ) {
199
		$siteExists = $siteId
200
			&& $this->siteLinkTargetProvider->getSiteList( $this->groups )->hasSite( $siteId );
201
202
		$this->logger->debug(
203
			'{method}: Site {siteId} exists: {siteExists}',
204
			[
205
				'method' => __METHOD__,
206
				'siteId' => $siteId,
207
				'siteExists' => var_export( $siteExists, true ),
208
			]
209
		);
210
211
		$formDescriptor = [
212
			'site' => [
213
				'name' => 'site',
214
				'default' => $siteId,
215
				'type' => 'combobox',
216
				'options' => $this->getSiteOptions(),
217
				'id' => 'wb-itembytitle-sitename',
218
				'size' => 12,
219
				'label-message' => 'wikibase-itembytitle-lookup-site'
220
			],
221
			'page' => [
222
				'name' => 'page',
223
				'default' => $page ?: '',
224
				'type' => 'text',
225
				'id' => 'pagename',
226
				'size' => 36,
227
				'label-message' => 'wikibase-itembytitle-lookup-page'
228
			]
229
		];
230
231
		HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() )
232
			->setId( 'wb-itembytitle-form1' )
233
			->setMethod( 'get' )
234
			->setSubmitID( 'wb-itembytitle-submit' )
235
			->setSubmitTextMsg( 'wikibase-itembytitle-submit' )
236
			->setWrapperLegendMsg( 'wikibase-itembytitle-lookup-fieldset' )
237
			->setSubmitCallback( function () {// no-op
238
			} )->show();
239
240
		if ( $siteId && !$siteExists ) {
241
			$this->showErrorHTML( $this->msg( 'wikibase-itembytitle-error-site' )->parse() );
242
		} elseif ( $siteExists && $page ) {
243
			$this->showErrorHTML( $this->msg( 'wikibase-itembytitle-error-item' )->parse() );
244
245
			$createLink = $this->getTitleFor( 'NewItem' );
246
			$this->getOutput()->addHTML(
247
				Html::openElement( 'div' )
248
				. $this->msg(
249
					'wikibase-itembytitle-create',
250
					$createLink->getFullURL( [ 'site' => $siteId, 'page' => $page ] )
251
				)->parse()
252
				. Html::closeElement( 'div' )
253
			);
254
		}
255
	}
256
257
}
258