| 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.