Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | <?php |
||
29 | class LinkSearchPage extends QueryPage { |
||
30 | /** @var array|bool */ |
||
31 | private $mungedQuery = false; |
||
32 | |||
33 | function setParams( $params ) { |
||
34 | $this->mQuery = $params['query']; |
||
|
|||
35 | $this->mNs = $params['namespace']; |
||
36 | $this->mProt = $params['protocol']; |
||
37 | } |
||
38 | |||
39 | function __construct( $name = 'LinkSearch' ) { |
||
46 | |||
47 | function isCacheable() { |
||
50 | |||
51 | public function execute( $par ) { |
||
52 | $this->setHeaders(); |
||
53 | $this->outputHeader(); |
||
54 | |||
55 | $out = $this->getOutput(); |
||
56 | $out->allowClickjacking(); |
||
57 | |||
58 | $request = $this->getRequest(); |
||
59 | $target = $request->getVal( 'target', $par ); |
||
60 | $namespace = $request->getIntOrNull( 'namespace' ); |
||
61 | |||
62 | $protocols_list = []; |
||
63 | foreach ( $this->getConfig()->get( 'UrlProtocols' ) as $prot ) { |
||
64 | if ( $prot !== '//' ) { |
||
65 | $protocols_list[] = $prot; |
||
66 | } |
||
67 | } |
||
68 | |||
69 | $target2 = $target; |
||
70 | // Get protocol, default is http:// |
||
71 | $protocol = 'http://'; |
||
72 | $bits = wfParseUrl( $target ); |
||
73 | if ( isset( $bits['scheme'] ) && isset( $bits['delimiter'] ) ) { |
||
74 | $protocol = $bits['scheme'] . $bits['delimiter']; |
||
75 | // Make sure wfParseUrl() didn't make some well-intended correction in the |
||
76 | // protocol |
||
77 | if ( strcasecmp( $protocol, substr( $target, 0, strlen( $protocol ) ) ) === 0 ) { |
||
78 | $target2 = substr( $target, strlen( $protocol ) ); |
||
79 | } else { |
||
80 | // If it did, let LinkFilter::makeLikeArray() handle this |
||
81 | $protocol = ''; |
||
82 | } |
||
83 | } |
||
84 | |||
85 | $out->addWikiMsg( |
||
86 | 'linksearch-text', |
||
87 | '<nowiki>' . $this->getLanguage()->commaList( $protocols_list ) . '</nowiki>', |
||
88 | count( $protocols_list ) |
||
89 | ); |
||
90 | $fields = [ |
||
91 | 'target' => [ |
||
92 | 'type' => 'text', |
||
93 | 'name' => 'target', |
||
94 | 'id' => 'target', |
||
95 | 'size' => 50, |
||
96 | 'label-message' => 'linksearch-pat', |
||
97 | 'default' => $target, |
||
98 | 'dir' => 'ltr', |
||
99 | ] |
||
100 | ]; |
||
101 | View Code Duplication | if ( !$this->getConfig()->get( 'MiserMode' ) ) { |
|
102 | $fields += [ |
||
103 | 'namespace' => [ |
||
104 | 'type' => 'namespaceselect', |
||
105 | 'name' => 'namespace', |
||
106 | 'label-message' => 'linksearch-ns', |
||
107 | 'default' => $namespace, |
||
108 | 'id' => 'namespace', |
||
109 | 'all' => '', |
||
110 | 'cssclass' => 'namespaceselector', |
||
111 | ], |
||
112 | ]; |
||
113 | } |
||
114 | $hiddenFields = [ |
||
115 | 'title' => $this->getPageTitle()->getPrefixedDBkey(), |
||
116 | ]; |
||
117 | $htmlForm = HTMLForm::factory( 'ooui', $fields, $this->getContext() ); |
||
118 | $htmlForm->addHiddenFields( $hiddenFields ); |
||
119 | $htmlForm->setSubmitTextMsg( 'linksearch-ok' ); |
||
120 | $htmlForm->setWrapperLegendMsg( 'linksearch' ); |
||
121 | $htmlForm->setAction( wfScript() ); |
||
122 | $htmlForm->setMethod( 'get' ); |
||
123 | $htmlForm->prepareForm()->displayForm( false ); |
||
124 | $this->addHelpLink( 'Help:Linksearch' ); |
||
125 | |||
126 | if ( $target != '' ) { |
||
127 | $this->setParams( [ |
||
128 | 'query' => Parser::normalizeLinkUrl( $target2 ), |
||
129 | 'namespace' => $namespace, |
||
130 | 'protocol' => $protocol ] ); |
||
131 | parent::execute( $par ); |
||
132 | if ( $this->mungedQuery === false ) { |
||
133 | $out->addWikiMsg( 'linksearch-error' ); |
||
134 | } |
||
135 | } |
||
136 | } |
||
137 | |||
138 | /** |
||
139 | * Disable RSS/Atom feeds |
||
140 | * @return bool |
||
141 | */ |
||
142 | function isSyndicated() { |
||
145 | |||
146 | /** |
||
147 | * Return an appropriately formatted LIKE query and the clause |
||
148 | * |
||
149 | * @param string $query Search pattern to search for |
||
150 | * @param string $prot Protocol, e.g. 'http://' |
||
151 | * |
||
152 | * @return array |
||
153 | */ |
||
154 | static function mungeQuery( $query, $prot ) { |
||
176 | |||
177 | function linkParameters() { |
||
186 | |||
187 | public function getQueryInfo() { |
||
220 | |||
221 | /** |
||
222 | * Pre-fill the link cache |
||
223 | * |
||
224 | * @param IDatabase $db |
||
225 | * @param ResultWrapper $res |
||
226 | */ |
||
227 | function preprocessResults( $db, $res ) { |
||
230 | |||
231 | /** |
||
232 | * @param Skin $skin |
||
233 | * @param object $result Result row |
||
234 | * @return string |
||
235 | */ |
||
236 | function formatResult( $skin, $result ) { |
||
245 | |||
246 | /** |
||
247 | * Override to squash the ORDER BY. |
||
248 | * We do a truncated index search, so the optimizer won't trust |
||
249 | * it as good enough for optimizing sort. The implicit ordering |
||
250 | * from the scan will usually do well enough for our needs. |
||
251 | * @return array |
||
252 | */ |
||
253 | function getOrderFields() { |
||
256 | |||
257 | protected function getGroupName() { |
||
260 | |||
261 | /** |
||
262 | * enwiki complained about low limits on this special page |
||
263 | * |
||
264 | * @see T130058 |
||
265 | * @todo FIXME This special page should not use LIMIT for paging |
||
266 | */ |
||
267 | protected function getMaxResults() { |
||
270 | } |
||
271 |
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: