Completed
Push — master ( 314e2a...089e57 )
by mw
84:04 queued 49:07
created

IdTaskHandler::createInfoMessageById()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 30
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 20
nc 3
nop 2
dl 0
loc 30
rs 8.5806
c 0
b 0
f 0
1
<?php
2
3
namespace SMW\MediaWiki\Specials\Admin;
4
5
use SMW\ApplicationFactory;
6
use SMW\MediaWiki\Renderer\HtmlFormRenderer;
7
use SMW\Store;
8
use SMW\Message;
9
use SMW\NamespaceManager;
10
use Html;
11
use WebRequest;
12
13
/**
14
 * @license GNU GPL v2+
15
 * @since   2.5
16
 *
17
 * @author mwjames
18
 */
19
class IdTaskHandler extends TaskHandler {
20
21
	/**
22
	 * @var Store
23
	 */
24
	private $store;
25
26
	/**
27
	 * @var HtmlFormRenderer
28
	 */
29
	private $htmlFormRenderer;
30
31
	/**
32
	 * @var OutputFormatter
33
	 */
34
	private $outputFormatter;
35
36
	/**
37
	 * @var User|null
38
	 */
39
	private $user;
40
41
	/**
42
	 * @since 2.5
43
	 *
44
	 * @param Store $store
45
	 * @param HtmlFormRenderer $htmlFormRenderer
46
	 * @param OutputFormatter $outputFormatter
47
	 */
48
	public function __construct( Store $store, HtmlFormRenderer $htmlFormRenderer, OutputFormatter $outputFormatter ) {
49
		$this->store = $store;
50
		$this->htmlFormRenderer = $htmlFormRenderer;
51
		$this->outputFormatter = $outputFormatter;
52
	}
53
54
	/**
55
	 * @since 2.5
56
	 *
57
	 * {@inheritDoc}
58
	 */
59
	public function isTaskFor( $task ) {
60
		return $task === 'idlookup';
61
	}
62
63
	/**
64
	 * @since 2.5
65
	 *
66
	 * {@inheritDoc}
67
	 */
68
	public function setUser( $user = null ) {
69
		$this->user = $user;
70
	}
71
72
	/**
73
	 * @since 2.5
74
	 *
75
	 * {@inheritDoc}
76
	 */
77
	public function getHtml() {
78
		return Html::rawElement(
79
			'li',
80
			array(),
81
			$this->getMessageAsString(
82
				array(
83
					'smw-admin-supplementary-idlookup-intro',
84
					$this->outputFormatter->getSpecialPageLinkWith( $this->getMessageAsString( 'smw-admin-supplementary-idlookup-title' ), array( 'action' => 'idlookup' ) )
85
				)
86
			)
87
		);
88
	}
89
90
	/**
91
	 * @since 2.5
92
	 *
93
	 * {@inheritDoc}
94
	 */
95
	public function handleRequest( WebRequest $webRequest ) {
96
97
		$this->outputFormatter->setPageTitle( $this->getMessageAsString( 'smw-admin-supplementary-idlookup-title' ) );
98
		$this->outputFormatter->addParentLink();
99
100
		$id = $webRequest->getText( 'id' );
101
102
		if ( $this->isEnabledFeature( SMW_ADM_DISPOSAL ) && $id > 0 && $webRequest->getText( 'dispose' ) === 'yes' ) {
103
			$this->doDispose( $id );
104
		}
105
106
		$this->outputFormatter->addHtml( $this->getForm( $webRequest, $id ) );
107
	}
108
109
	/**
110
	 * @param integer $id
111
	 * @param User|null $use
0 ignored issues
show
Bug introduced by
There is no parameter named $use. 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...
112
	 */
113
	private function doDispose( $id ) {
114
115
		$entityIdDisposerJob = ApplicationFactory::getInstance()->newJobFactory()->newEntityIdDisposerJob(
116
			\Title::newFromText( __METHOD__ )
117
		);
118
119
		$entityIdDisposerJob->dispose( $id );
120
121
		$manualEntryLogger = ApplicationFactory::getInstance()->create( 'ManualEntryLogger' );
122
		$manualEntryLogger->registerLoggableEventType( 'admin' );
123
		$manualEntryLogger->log( 'admin', $this->user, 'Special:SMWAdmin', 'Forced removal of ID '. $id );
124
	}
125
126
	private function getForm( $webRequest, $id ) {
127
128
		$message = $this->createInfoMessageById( $webRequest, $id );
129
130
		if ( $id < 1 ) {
131
			$id = null;
132
		}
133
134
		$html = $this->htmlFormRenderer
135
			->setName( 'idlookup' )
136
			->setMethod( 'get' )
137
			->addHiddenField( 'action', 'idlookup' )
138
			->addHiddenField( 'id', $id )
139
			->addParagraph( $this->getMessageAsString( 'smw-admin-idlookup-docu' ) )
140
			->addInputField(
141
				$this->getMessageAsString( 'smw-admin-objectid' ),
142
				'id',
143
				$id
144
			)
145
			->addNonBreakingSpace()
146
			->addSubmitButton( $this->getMessageAsString( 'allpagessubmit' ) )
147
			->addParagraph( $message )
148
			->getForm();
149
150
		$html .= Html::element( 'p', array(), '' );
151
152
		if ( $id > 0 && $webRequest->getText( 'dispose' ) == 'yes' ) {
153
			$message = $this->getMessageAsString( array ('smw-admin-iddispose-done', $id ) );
0 ignored issues
show
Unused Code introduced by
$message 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...
154
			$id = null;
155
		}
156
157
		if ( !$this->isEnabledFeature( SMW_ADM_DISPOSAL ) ) {
158
			return $html;
159
		}
160
161
		$html .= $this->htmlFormRenderer
162
			->setName( 'iddispose' )
163
			->setMethod( 'get' )
164
			->addHiddenField( 'action', 'idlookup' )
165
			->addHiddenField( 'id', $id )
166
			->addHeader( 'h2', $this->getMessageAsString( 'smw-admin-iddispose-title' ) )
167
			->addParagraph( $this->getMessageAsString( 'smw-admin-iddispose-docu', Message::PARSE ) )
168
			->addInputField(
169
				$this->getMessageAsString( 'smw-admin-objectid' ),
170
				'id',
171
				$id,
172
				null,
173
				20,
174
				'',
175
				true
176
			)
177
			->addNonBreakingSpace()
178
			->addSubmitButton( $this->getMessageAsString( 'allpagessubmit' ) )
179
			->addCheckbox(
180
				$this->getMessageAsString( 'smw_smwadmin_datarefreshstopconfirm', Message::ESCAPED ),
181
				'dispose',
182
				'yes'
183
			)
184
			->getForm();
185
186
		return $html . Html::element( 'p', array(), '' );
187
	}
188
189
	private function createInfoMessageById( $webRequest, &$id ) {
190
191
		if ( $webRequest->getText( 'action' ) !== 'idlookup' || $id === '' ) {
192
			return '';
193
		}
194
195
		$connection = $this->store->getConnection( 'mw.db' );
196
197
		if ( intval( $id ) ) {
198
			$condition = 'smw_id=' . intval( $id );
199
		} else {
200
			$condition = 'smw_sortkey=' . $connection->addQuotes( $id );
201
		}
202
203
		$rows = $connection->select(
204
				\SMWSql3SmwIds::TABLE_NAME,
205
				array(
206
					'smw_id',
207
					'smw_title',
208
					'smw_namespace',
209
					'smw_iw',
210
					'smw_subobject',
211
					'smw_sortkey'
212
				),
213
				$condition,
214
				__METHOD__
215
		);
216
217
		return $this->createMessageFromRows( $id, $rows );
218
	}
219
220
	private function createMessageFromRows( &$id, $rows ) {
221
222
		$references = array();
223
		$formattedRows = array();
224
		$output = '';
225
226
		if ( $rows !== array() ) {
227
			foreach ( $rows as $row ) {
228
				$id = $row->smw_id;
229
230
				$references[$id] = $this->store->getPropertyTableIdReferenceFinder()->searchAllTablesToFindAtLeastOneReferenceById(
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class SMW\Store as the method getPropertyTableIdReferenceFinder() does only exist in the following sub-classes of SMW\Store: SMWSQLStore3, SMWSparqlStore, SMW\SPARQLStore\SPARQLStore. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
231
					$id
232
				);
233
234
				$formattedRows[$id] = (array)$row;
235
			}
236
		}
237
238
		// ID is not unique
239
		if ( count( $formattedRows ) > 1 ) {
240
			$id = '';
241
		}
242
243
		if ( $formattedRows !== array() ) {
244
			$output = '<pre>' . $this->outputFormatter->encodeAsJson( $formattedRows ) . '</pre>';
245
		}
246
247
		if ( $references !== array() ) {
248
			$output .= Html::element(
249
				'p',
250
				array(),
251
				$this->getMessageAsString( array( 'smw-admin-iddispose-references', $id, count( $references ) ) )
252
			);
253
			$output .= '<pre>' . $this->outputFormatter->encodeAsJson( $references ) . '</pre>';
254
		}
255
256
		return $output;
257
	}
258
259
}
260