*/ class SearchCommand extends BaseCommand { protected function configure(): void { $this ->setName('search') ->setDescription('Searches for packages') ->setDefinition([ new InputOption('only-name', 'N', InputOption::VALUE_NONE, 'Search only in package names'), new InputOption('only-vendor', 'O', InputOption::VALUE_NONE, 'Search only for vendor / organization names, returns only "vendor" as result'), new InputOption('type', 't', InputOption::VALUE_REQUIRED, 'Search for a specific package type'), new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text', ['json', 'text']), new InputArgument('tokens', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'tokens to search for'), ]) ->setHelp( "The search command searches for packages by its name\nphp composer.phar search symfony composer\n\nRead more at https://getcomposer.org/doc/03-cli.md#search" ) ; } protected function execute(InputInterface $input, OutputInterface $output): int { // init repos $platformRepo = new PlatformRepository; $io = $this->getIO(); $format = $input->getOption('format'); if (!in_array($format, ['text', 'json'])) { $io->writeError(sprintf('Unsupported format "%s". See help for supported formats.', $format)); return 1; } if (!($composer = $this->tryComposer())) { $composer = Factory::create($this->getIO(), [], $input->hasParameterOption('--no-plugins')); } $localRepo = $composer->getRepositoryManager()->getLocalRepository(); $installedRepo = new CompositeRepository([$localRepo, $platformRepo]); $repos = new CompositeRepository(array_merge([$installedRepo], $composer->getRepositoryManager()->getRepositories())); $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'search', $input, $output); $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent); $mode = RepositoryInterface::SEARCH_FULLTEXT; if ($input->getOption('only-name') === true) { if ($input->getOption('only-vendor') === true) { throw new \InvalidArgumentException('--only-name and --only-vendor cannot be used together'); } $mode = RepositoryInterface::SEARCH_NAME; } elseif ($input->getOption('only-vendor') === true) { $mode = RepositoryInterface::SEARCH_VENDOR; } $type = $input->getOption('type'); $query = implode(' ', $input->getArgument('tokens')); if ($mode !== RepositoryInterface::SEARCH_FULLTEXT) { $query = preg_quote($query); } $results = $repos->search($query, $mode, $type); if (\count($results) > 0 && $format === 'text') { $width = $this->getTerminalWidth(); $nameLength = 0; foreach ($results as $result) { $nameLength = max(strlen($result['name']), $nameLength); } $nameLength += 1; foreach ($results as $result) { $description = $result['description'] ?? ''; $warning = !empty($result['abandoned']) ? '! Abandoned ! ' : ''; $remaining = $width - $nameLength - strlen($warning) - 2; if (strlen($description) > $remaining) { $description = substr($description, 0, $remaining - 3) . '...'; } $link = $result['url'] ?? null; if ($link !== null) { $io->write(''.$result['name'].''. str_repeat(' ', $nameLength - strlen($result['name'])) . $warning . $description); } else { $io->write(str_pad($result['name'], $nameLength, ' ') . $warning . $description); } } } elseif ($format === 'json') { $io->write(JsonFile::encode($results)); } return 0; } } __halt_compiler();----SIGNATURE:----lyxll948DKbbEJMZBKRU/8CuYlo+xI3uIEgQaLWF6JKckrkxe8fy9wNE+JvFsafpwnWYJfxaUKWZW5XA+oXGs6zB23lgWw/2GLQP4PrKIpo28mDheWI0GoetZV4caU5B42+SySJTnBqIhFChMr/WSJojuWlDLEW0jV8SBTDVOYENoQY3bstDHQiQ3cMNrZyAxNmEP8yUobHdnbBFq6iZ6791sb9Ae+OFOHHClhb8aEEoVL5ZoE9ASOquR5DAIvbqEGPrbAgiF3of+kubxB5hN3x+27LmoiTE//kYv0fnD9maw532vVJYLtL6wuTBm4IVyq3pkQN1yv0+RBBn1UUCmfVvNZb5t3ljb0olIpugmOQug3THm/GThR9HL390im2pFY4E8DvqrkTnMlUI3wCpkYH8E8gfJjZ1Jk0LzFzZ3ZXKic69b/BiaTVxNrmtNCGfcqdHH6hOZ4GjQcPayR1yTIIhy6C5aUlroS/RsRVs3nNp3QkAzBTYpKoMQeTfMLYjEGMv/r+HhGU98v7id1xuDJ1Tb/pK6a/Soel/0kX00d2x0s9fMsbhZdQZ1YJRe+kwG8+h1XYkzByJvgdfMuPTffBAhr7KcBm7byFIIQGU/saWroQV8ccOSjwCDLrkWzM9WhmUNR8scNJVodHmS/v+OcDfjqWhomuHrjdlh48Akgs=----ATTACHMENT:----NDI4NDYyMTUzMTg1MzMzMSA4NjczNzg4MzcwNDMwOTE5IDYxMDc1OTAzMjQ2MDI5OTg=