symfonyStyleFactory = $symfonyStyleFactory; $this->fileParser = $fileParser; $this->extensionCheck = $extensionCheck; } protected function configure(): void { $this ->setDescription('Checks extensions...') ->setHelp('This command allows you to check your extensions...') ->setDefinition( new InputDefinition([ new InputArgument(self::ARG_DIRECTORY, InputArgument::OPTIONAL, "The directory to scan", "./"), new InputOption(self::OPT_EXCLUDE, null, InputArgument::OPTIONAL | InputOption::VALUE_IS_ARRAY, "Exclude specific extensions", []), ]) ); } protected function execute(InputInterface $input, OutputInterface $output): int { $io = ($this->symfonyStyleFactory)($input, $output); $io->section("Analyzing Files"); $scanDir = $input->getArgument(self::ARG_DIRECTORY); if (empty($scanDir) || !\is_string($scanDir)) { $scanDir = './'; } $excludedExtensionOpts = $input->getOption(self::OPT_EXCLUDE); $excludedExtensions = []; if (is_array($excludedExtensionOpts) && !empty($excludedExtensionOpts)) { foreach ($excludedExtensionOpts as $excludedExtensionOpt) { $extensions = explode(",", $excludedExtensionOpt); foreach ($extensions as $extension) { $excludedExtensions[] = \strtolower(trim($extension)); } } $this->extensionCheck->setExcludedExtenstions($excludedExtensions); } $this->fileParser->scanForFiles($scanDir); $fileCount = $this->fileParser->getFileCount(); $io->text(sprintf('Files: %d', $fileCount)); $io->newLine(); $progressBar = $this->getStyledProgressBar($output, $fileCount); $progressBar->start(); [$classes, $functions, $constants] = $this->fileParser->parseFiles( $this->getProgressBarClosure($progressBar) ); $progressBar->finish(); $io->newLine(2); $io->text("Calls to check:"); $io->text(sprintf( "%d Classes, %d Functions, %d Constants", count($classes), count($functions), count($constants) )); $io->section("Checking Extension Usages"); $io->text(sprintf('Loaded Extensions: %d', $this->extensionCheck->getLoadedExtensionsCount())); if (!empty($excludedExtensions)) { $io->text(sprintf("Excluded Extensions: %s", implode(", ", $excludedExtensions))); } $io->newLine(); $totalUsagesToCheck = count($classes) + count($functions); $progressBar = $this->getStyledProgressBar($output, $totalUsagesToCheck); $progressBar->start(); $usedExtensions = $this->extensionCheck->checkUsages( $classes, $functions, $constants, $this->getProgressBarClosure($progressBar) ); $progressBar->finish(); $io->newLine(2); $unusedExtensions = $this->extensionCheck->getUnused(array_keys($usedExtensions)); $io->text(sprintf( "%d Used, %d Unused", count($usedExtensions), count($unusedExtensions) )); $io->section("Result"); $io->text("Used Extensions:"); $tmp = array_keys($usedExtensions); natcasesort($tmp); foreach ($tmp as $usedExtension) { $reason = $usedExtensions[$usedExtension]; $io->text(sprintf( ' %s %s [Usage: %s]', "\u{2713}", $usedExtension, implode(", ", array_keys($reason)) )); } $io->newLine(); $io->text("Unused Extensions:"); foreach ($unusedExtensions as $unusedExtension) { $io->text(sprintf( ' %s %s', "\u{2717}", $unusedExtension )); } return Command::SUCCESS; } private function getProgressBarClosure(ProgressBar $progressBar): Closure { return function () use ($progressBar) { $progressBar->advance(); }; } private function getStyledProgressBar(OutputInterface $output, int $maxValue): ProgressBar { $progressBar = new ProgressBar($output, $maxValue); $progressBar->setBarCharacter('='); $progressBar->setEmptyBarCharacter(' '); $progressBar->setProgressCharacter('>'); return $progressBar; } }