| Conditions | 39 |
| Paths | > 20000 |
| Total Lines | 199 |
| Code Lines | 122 |
| Lines | 10 |
| Ratio | 5.03 % |
| Changes | 1 | ||
| Bugs | 0 | Features | 0 |
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:
If many parameters/temporary variables are present:
| 1 | <?php |
||
| 106 | function showIndirectLinks( $level, $target, $limit, $from = 0, $back = 0 ) { |
||
| 107 | $out = $this->getOutput(); |
||
| 108 | $dbr = wfGetDB( DB_SLAVE ); |
||
| 109 | |||
| 110 | $hidelinks = $this->opts->getValue( 'hidelinks' ); |
||
| 111 | $hideredirs = $this->opts->getValue( 'hideredirs' ); |
||
| 112 | $hidetrans = $this->opts->getValue( 'hidetrans' ); |
||
| 113 | $hideimages = $target->getNamespace() != NS_FILE || $this->opts->getValue( 'hideimages' ); |
||
| 114 | |||
| 115 | $fetchlinks = ( !$hidelinks || !$hideredirs ); |
||
| 116 | |||
| 117 | // Build query conds in concert for all three tables... |
||
| 118 | $conds['pagelinks'] = [ |
||
|
|
|||
| 119 | 'pl_namespace' => $target->getNamespace(), |
||
| 120 | 'pl_title' => $target->getDBkey(), |
||
| 121 | ]; |
||
| 122 | $conds['templatelinks'] = [ |
||
| 123 | 'tl_namespace' => $target->getNamespace(), |
||
| 124 | 'tl_title' => $target->getDBkey(), |
||
| 125 | ]; |
||
| 126 | $conds['imagelinks'] = [ |
||
| 127 | 'il_to' => $target->getDBkey(), |
||
| 128 | ]; |
||
| 129 | |||
| 130 | $namespace = $this->opts->getValue( 'namespace' ); |
||
| 131 | $invert = $this->opts->getValue( 'invert' ); |
||
| 132 | $nsComparison = ( $invert ? '!= ' : '= ' ) . $dbr->addQuotes( $namespace ); |
||
| 133 | View Code Duplication | if ( is_int( $namespace ) ) { |
|
| 134 | $conds['pagelinks'][] = "pl_from_namespace $nsComparison"; |
||
| 135 | $conds['templatelinks'][] = "tl_from_namespace $nsComparison"; |
||
| 136 | $conds['imagelinks'][] = "il_from_namespace $nsComparison"; |
||
| 137 | } |
||
| 138 | |||
| 139 | View Code Duplication | if ( $from ) { |
|
| 140 | $conds['templatelinks'][] = "tl_from >= $from"; |
||
| 141 | $conds['pagelinks'][] = "pl_from >= $from"; |
||
| 142 | $conds['imagelinks'][] = "il_from >= $from"; |
||
| 143 | } |
||
| 144 | |||
| 145 | if ( $hideredirs ) { |
||
| 146 | $conds['pagelinks']['rd_from'] = null; |
||
| 147 | } elseif ( $hidelinks ) { |
||
| 148 | $conds['pagelinks'][] = 'rd_from is NOT NULL'; |
||
| 149 | } |
||
| 150 | |||
| 151 | $queryFunc = function ( IDatabase $dbr, $table, $fromCol ) use ( |
||
| 152 | $conds, $target, $limit |
||
| 153 | ) { |
||
| 154 | // Read an extra row as an at-end check |
||
| 155 | $queryLimit = $limit + 1; |
||
| 156 | $on = [ |
||
| 157 | "rd_from = $fromCol", |
||
| 158 | 'rd_title' => $target->getDBkey(), |
||
| 159 | 'rd_interwiki = ' . $dbr->addQuotes( '' ) . ' OR rd_interwiki IS NULL' |
||
| 160 | ]; |
||
| 161 | $on['rd_namespace'] = $target->getNamespace(); |
||
| 162 | // Inner LIMIT is 2X in case of stale backlinks with wrong namespaces |
||
| 163 | $subQuery = $dbr->selectSQLText( |
||
| 164 | [ $table, 'redirect', 'page' ], |
||
| 165 | [ $fromCol, 'rd_from' ], |
||
| 166 | $conds[$table], |
||
| 167 | __CLASS__ . '::showIndirectLinks', |
||
| 168 | // Force JOIN order per T106682 to avoid large filesorts |
||
| 169 | [ 'ORDER BY' => $fromCol, 'LIMIT' => 2 * $queryLimit, 'STRAIGHT_JOIN' ], |
||
| 170 | [ |
||
| 171 | 'page' => [ 'INNER JOIN', "$fromCol = page_id" ], |
||
| 172 | 'redirect' => [ 'LEFT JOIN', $on ] |
||
| 173 | ] |
||
| 174 | ); |
||
| 175 | return $dbr->select( |
||
| 176 | [ 'page', 'temp_backlink_range' => "($subQuery)" ], |
||
| 177 | [ 'page_id', 'page_namespace', 'page_title', 'rd_from', 'page_is_redirect' ], |
||
| 178 | [], |
||
| 179 | __CLASS__ . '::showIndirectLinks', |
||
| 180 | [ 'ORDER BY' => 'page_id', 'LIMIT' => $queryLimit ], |
||
| 181 | [ 'page' => [ 'INNER JOIN', "$fromCol = page_id" ] ] |
||
| 182 | ); |
||
| 183 | }; |
||
| 184 | |||
| 185 | if ( $fetchlinks ) { |
||
| 186 | $plRes = $queryFunc( $dbr, 'pagelinks', 'pl_from' ); |
||
| 187 | } |
||
| 188 | |||
| 189 | if ( !$hidetrans ) { |
||
| 190 | $tlRes = $queryFunc( $dbr, 'templatelinks', 'tl_from' ); |
||
| 191 | } |
||
| 192 | |||
| 193 | if ( !$hideimages ) { |
||
| 194 | $ilRes = $queryFunc( $dbr, 'imagelinks', 'il_from' ); |
||
| 195 | } |
||
| 196 | |||
| 197 | if ( ( !$fetchlinks || !$plRes->numRows() ) |
||
| 198 | && ( $hidetrans || !$tlRes->numRows() ) |
||
| 199 | && ( $hideimages || !$ilRes->numRows() ) |
||
| 200 | ) { |
||
| 201 | if ( 0 == $level ) { |
||
| 202 | if ( !$this->including() ) { |
||
| 203 | $out->addHTML( $this->whatlinkshereForm() ); |
||
| 204 | |||
| 205 | // Show filters only if there are links |
||
| 206 | if ( $hidelinks || $hidetrans || $hideredirs || $hideimages ) { |
||
| 207 | $out->addHTML( $this->getFilterPanel() ); |
||
| 208 | } |
||
| 209 | $errMsg = is_int( $namespace ) ? 'nolinkshere-ns' : 'nolinkshere'; |
||
| 210 | $out->addWikiMsg( $errMsg, $this->target->getPrefixedText() ); |
||
| 211 | $out->setStatusCode( 404 ); |
||
| 212 | } |
||
| 213 | } |
||
| 214 | |||
| 215 | return; |
||
| 216 | } |
||
| 217 | |||
| 218 | // Read the rows into an array and remove duplicates |
||
| 219 | // templatelinks comes second so that the templatelinks row overwrites the |
||
| 220 | // pagelinks row, so we get (inclusion) rather than nothing |
||
| 221 | if ( $fetchlinks ) { |
||
| 222 | foreach ( $plRes as $row ) { |
||
| 223 | $row->is_template = 0; |
||
| 224 | $row->is_image = 0; |
||
| 225 | $rows[$row->page_id] = $row; |
||
| 226 | } |
||
| 227 | } |
||
| 228 | if ( !$hidetrans ) { |
||
| 229 | foreach ( $tlRes as $row ) { |
||
| 230 | $row->is_template = 1; |
||
| 231 | $row->is_image = 0; |
||
| 232 | $rows[$row->page_id] = $row; |
||
| 233 | } |
||
| 234 | } |
||
| 235 | if ( !$hideimages ) { |
||
| 236 | foreach ( $ilRes as $row ) { |
||
| 237 | $row->is_template = 0; |
||
| 238 | $row->is_image = 1; |
||
| 239 | $rows[$row->page_id] = $row; |
||
| 240 | } |
||
| 241 | } |
||
| 242 | |||
| 243 | // Sort by key and then change the keys to 0-based indices |
||
| 244 | ksort( $rows ); |
||
| 245 | $rows = array_values( $rows ); |
||
| 246 | |||
| 247 | $numRows = count( $rows ); |
||
| 248 | |||
| 249 | // Work out the start and end IDs, for prev/next links |
||
| 250 | if ( $numRows > $limit ) { |
||
| 251 | // More rows available after these ones |
||
| 252 | // Get the ID from the last row in the result set |
||
| 253 | $nextId = $rows[$limit]->page_id; |
||
| 254 | // Remove undisplayed rows |
||
| 255 | $rows = array_slice( $rows, 0, $limit ); |
||
| 256 | } else { |
||
| 257 | // No more rows after |
||
| 258 | $nextId = false; |
||
| 259 | } |
||
| 260 | $prevId = $from; |
||
| 261 | |||
| 262 | // use LinkBatch to make sure, that all required data (associated with Titles) |
||
| 263 | // is loaded in one query |
||
| 264 | $lb = new LinkBatch(); |
||
| 265 | foreach ( $rows as $row ) { |
||
| 266 | $lb->add( $row->page_namespace, $row->page_title ); |
||
| 267 | } |
||
| 268 | $lb->execute(); |
||
| 269 | |||
| 270 | if ( $level == 0 ) { |
||
| 271 | if ( !$this->including() ) { |
||
| 272 | $out->addHTML( $this->whatlinkshereForm() ); |
||
| 273 | $out->addHTML( $this->getFilterPanel() ); |
||
| 274 | $out->addWikiMsg( 'linkshere', $this->target->getPrefixedText() ); |
||
| 275 | |||
| 276 | $prevnext = $this->getPrevNext( $prevId, $nextId ); |
||
| 277 | $out->addHTML( $prevnext ); |
||
| 278 | } |
||
| 279 | } |
||
| 280 | $out->addHTML( $this->listStart( $level ) ); |
||
| 281 | foreach ( $rows as $row ) { |
||
| 282 | $nt = Title::makeTitle( $row->page_namespace, $row->page_title ); |
||
| 283 | |||
| 284 | if ( $row->rd_from && $level < 2 ) { |
||
| 285 | $out->addHTML( $this->listItem( $row, $nt, $target, true ) ); |
||
| 286 | $this->showIndirectLinks( |
||
| 287 | $level + 1, |
||
| 288 | $nt, |
||
| 289 | $this->getConfig()->get( 'MaxRedirectLinksRetrieved' ) |
||
| 290 | ); |
||
| 291 | $out->addHTML( Xml::closeElement( 'li' ) ); |
||
| 292 | } else { |
||
| 293 | $out->addHTML( $this->listItem( $row, $nt, $target ) ); |
||
| 294 | } |
||
| 295 | } |
||
| 296 | |||
| 297 | $out->addHTML( $this->listEnd() ); |
||
| 298 | |||
| 299 | if ( $level == 0 ) { |
||
| 300 | if ( !$this->including() ) { |
||
| 301 | $out->addHTML( $prevnext ); |
||
| 302 | } |
||
| 303 | } |
||
| 304 | } |
||
| 305 | |||
| 558 |
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.
Let’s take a look at an example:
As you can see in this example, the array
$myArrayis initialized the first time when the foreach loop is entered. You can also see that the value of thebarkey is only written conditionally; thus, its value might result from a previous iteration.This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.