| Conditions | 38 | 
| Paths | > 20000 | 
| Total Lines | 179 | 
| Lines | 0 | 
| Ratio | 0 % | 
| Changes | 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 // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase | ||
| 164 | 	protected function execute( InputInterface $input, OutputInterface $output ) { | ||
| 165 | 		try { | ||
| 166 | $dir = Config::changesDir(); | ||
| 167 | 			if ( ! is_dir( $dir ) ) { | ||
| 168 | Utils::error_clear_last(); | ||
| 169 | 				if ( ! quietCall( 'mkdir', $dir, 0775, true ) ) { | ||
| 170 | $err = error_get_last(); | ||
| 171 | 					$output->writeln( "<error>Could not create directory $dir: {$err['message']}</>" ); | ||
| 172 | return 1; | ||
| 173 | } | ||
| 174 | } | ||
| 175 | |||
| 176 | $isInteractive = $input->isInteractive(); | ||
| 177 | |||
| 178 | // Determine the changelog entry filename. | ||
| 179 | $filename = $input->getOption( 'filename' ); | ||
| 180 | 			if ( null === $filename ) { | ||
| 181 | $filename = $this->getDefaultFilename( $output ); | ||
| 182 | } | ||
| 183 | 			if ( $isInteractive ) { | ||
| 184 | $question = new Question( "Name your change file <info>[default: $filename]</> > ", $filename ); | ||
| 185 | $question->setValidator( array( $this, 'validateFilename' ) ); | ||
| 186 | $filename = $this->getHelper( 'question' )->ask( $input, $output, $question ); | ||
| 187 | 				if ( null === $filename ) { // non-interactive. | ||
| 188 | $output->writeln( 'Got EOF when attempting to query user, aborting.', OutputInterface::VERBOSITY_VERBOSE ); // @codeCoverageIgnore | ||
| 189 | return 1; | ||
| 190 | } | ||
| 191 | 			} else { | ||
| 192 | 				if ( null === $input->getOption( 'filename' ) ) { | ||
| 193 | $output->writeln( "Using default filename \"$filename\".", OutputInterface::VERBOSITY_VERBOSE ); | ||
| 194 | } | ||
| 195 | 				if ( file_exists( "$dir/$filename" ) && $input->getOption( 'filename-auto-suffix' ) ) { | ||
| 196 | $i = 2; | ||
| 197 | 					while ( file_exists( "$dir/$filename#$i" ) ) { | ||
| 198 | $i++; | ||
| 199 | } | ||
| 200 | $output->writeln( "File \"$filename\" already exists. Creating \"$filename#$i\" instead.", OutputInterface::VERBOSITY_VERBOSE ); | ||
| 201 | $filename = "$filename#$i"; | ||
| 202 | } | ||
| 203 | 				try { | ||
| 204 | $this->validateFilename( $filename ); | ||
| 205 | 				} catch ( \RuntimeException $ex ) { | ||
| 206 | 					$output->writeln( "<error>{$ex->getMessage()}</>" ); | ||
| 207 | return 1; | ||
| 208 | } | ||
| 209 | } | ||
| 210 | |||
| 211 | $contents = ''; | ||
| 212 | |||
| 213 | // Determine the change significance and add to the file contents. | ||
| 214 | $significance = $input->getOption( 'significance' ); | ||
| 215 | 			if ( null !== $significance ) { | ||
| 216 | $significance = strtolower( $significance ); | ||
| 217 | } | ||
| 218 | 			if ( $isInteractive ) { | ||
| 219 | $question = new ChoiceQuestion( 'Significance of the change, in the style of semantic versioning.', self::$significances, $significance ); | ||
| 220 | $significance = $this->getHelper( 'question' )->ask( $input, $output, $question ); | ||
| 221 | 				if ( null === $significance ) { // non-interactive. | ||
| 222 | $output->writeln( 'Got EOF when attempting to query user, aborting.', OutputInterface::VERBOSITY_VERBOSE ); // @codeCoverageIgnore | ||
| 223 | return 1; | ||
| 224 | } | ||
| 225 | 			} else { | ||
| 226 | 				if ( null === $significance ) { | ||
| 227 | $output->writeln( '<error>Significance must be specified in non-interactive mode.</>' ); | ||
| 228 | return 1; | ||
| 229 | } | ||
| 230 | 				if ( ! isset( self::$significances[ $significance ] ) ) { | ||
| 231 | $output->writeln( "<error>Significance value \"$significance\" is not valid.</>" ); | ||
| 232 | return 1; | ||
| 233 | } | ||
| 234 | } | ||
| 235 | $contents .= "Significance: $significance\n"; | ||
| 236 | |||
| 237 | // Determine the change type and add to the file contents, if applicable. | ||
| 238 | $types = Config::types(); | ||
| 239 | 			if ( $types ) { | ||
| 240 | $type = $input->getOption( 'type' ); | ||
| 241 | 				if ( null !== $type ) { | ||
| 242 | $type = strtolower( $type ); | ||
| 243 | } | ||
| 244 | 				if ( $isInteractive ) { | ||
| 245 | $question = new ChoiceQuestion( 'Type of change.', $types, $type ); | ||
| 246 | $type = $this->getHelper( 'question' )->ask( $input, $output, $question ); | ||
| 247 | 					if ( null === $type ) { // non-interactive. | ||
| 248 | $output->writeln( 'Got EOF when attempting to query user, aborting.', OutputInterface::VERBOSITY_VERBOSE ); // @codeCoverageIgnore | ||
| 249 | return 1; | ||
| 250 | } | ||
| 251 | 				} else { | ||
| 252 | 					if ( null === $type ) { | ||
| 253 | $output->writeln( '<error>Type must be specified in non-interactive mode.</>' ); | ||
| 254 | return 1; | ||
| 255 | } | ||
| 256 | 					if ( ! isset( $types[ $type ] ) ) { | ||
| 257 | $output->writeln( "<error>Type \"$type\" is not valid.</>" ); | ||
| 258 | return 1; | ||
| 259 | } | ||
| 260 | } | ||
| 261 | $contents .= "Type: $type\n"; | ||
| 262 | 			} elseif ( null !== $input->getOption( 'type' ) ) { | ||
| 263 | $output->writeln( '<warning>This project does not use types. Do not specify --type.</>' ); | ||
| 264 | } | ||
| 265 | |||
| 266 | // Determine the changelog entry and add to the file contents. | ||
| 267 | $entry = $input->getOption( 'entry' ); | ||
| 268 | 			if ( $isInteractive ) { | ||
| 269 | 				if ( 'patch' === $significance ) { | ||
| 270 | $question = new Question( "Changelog entry. May be left empty if this change is particularly insignificant.\n > ", (string) $entry ); | ||
| 271 | 				} else { | ||
| 272 | $question = new Question( "Changelog entry. May not be empty.\n > ", $entry ); | ||
| 273 | $question->setValidator( | ||
| 274 | 						function ( $v ) { | ||
| 275 | 							if ( trim( $v ) === '' ) { | ||
| 276 | throw new \RuntimeException( 'An empty changelog entry is only allowed when the significance is "patch".' ); | ||
| 277 | } | ||
| 278 | return $v; | ||
| 279 | } | ||
| 280 | ); | ||
| 281 | } | ||
| 282 | $entry = $this->getHelper( 'question' )->ask( $input, $output, $question ); | ||
| 283 | 				if ( null === $entry ) { | ||
| 284 | $output->writeln( 'Got EOF when attempting to query user, aborting.', OutputInterface::VERBOSITY_VERBOSE ); // @codeCoverageIgnore | ||
| 285 | return 1; | ||
| 286 | } | ||
| 287 | 			} else { | ||
| 288 | 				if ( null === $entry ) { | ||
| 289 | $output->writeln( '<error>Entry must be specified in non-interactive mode.</>' ); | ||
| 290 | return 1; | ||
| 291 | } | ||
| 292 | 				if ( 'patch' !== $significance && '' === $entry ) { | ||
| 293 | $output->writeln( '<error>An empty changelog entry is only allowed when the significance is "patch".</>' ); | ||
| 294 | return 1; | ||
| 295 | } | ||
| 296 | } | ||
| 297 | |||
| 298 | // Ask if a change comment is desired, if they left the change entry itself empty. | ||
| 299 | $comment = (string) $input->getOption( 'comment' ); | ||
| 300 | 			if ( $isInteractive && '' === $entry ) { | ||
| 301 | $question = new Question( "You omitted the changelog entry, which is fine. But please comment as to why no entry is needed.\n > ", $comment ); | ||
| 302 | $comment = $this->getHelper( 'question' )->ask( $input, $output, $question ); | ||
| 303 | 				if ( null === $comment ) { | ||
| 304 | $output->writeln( 'Got EOF when attempting to query user, aborting.', OutputInterface::VERBOSITY_VERBOSE ); // @codeCoverageIgnore | ||
| 305 | return 1; // @codeCoverageIgnore | ||
| 306 | } | ||
| 307 | } | ||
| 308 | $comment = trim( preg_replace( '/\s+/', ' ', $comment ) ); | ||
| 309 | 			if ( '' !== $comment ) { | ||
| 310 | $contents .= "Comment: $comment\n"; | ||
| 311 | } | ||
| 312 | |||
| 313 | $contents .= "\n$entry"; | ||
| 314 | |||
| 315 | // Ok! Write the file. | ||
| 316 | // Use fopen/fwrite/fclose instead of file_put_contents because the latter doesn't support 'x'. | ||
| 317 | $output->writeln( | ||
| 318 | "<info>Creating changelog entry $dir/$filename:\n" . preg_replace( '/^/m', ' ', $contents ) . '</>', | ||
| 319 | OutputInterface::VERBOSITY_DEBUG | ||
| 320 | ); | ||
| 321 | $contents .= "\n"; | ||
| 322 | Utils::error_clear_last(); | ||
| 323 | $fp = quietCall( 'fopen', "$dir/$filename", 'x' ); | ||
| 324 | if ( ! $fp || | ||
| 325 | quietCall( 'fwrite', $fp, $contents ) !== strlen( $contents ) || | ||
| 326 | ! quietCall( 'fclose', $fp ) | ||
| 327 | 			) { | ||
| 328 | // @codeCoverageIgnoreStart | ||
| 329 | $err = error_get_last(); | ||
| 330 | 				$output->writeln( "<error>Failed to write file \"$dir/$filename\": {$err['message']}.</>" ); | ||
| 331 | quietCall( 'fclose', $fp ); | ||
| 332 | quietCall( 'unlink', "$dir/$filename" ); | ||
| 333 | return 1; | ||
| 334 | // @codeCoverageIgnoreEnd | ||
| 335 | } | ||
| 336 | |||
| 337 | return 0; | ||
| 338 | 		} catch ( MissingInputException $ex ) { // @codeCoverageIgnore | ||
| 339 | $output->writeln( 'Got EOF when attempting to query user, aborting.', OutputInterface::VERBOSITY_VERBOSE ); // @codeCoverageIgnore | ||
| 340 | return 1; // @codeCoverageIgnore | ||
| 341 | } | ||
| 342 | } | ||
| 343 | } | ||
| 344 | 
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)or! empty(...)instead.