|
2 | 2 |
|
3 | 3 | namespace Nowo\DoctrineEncryptBundle\Command; |
4 | 4 |
|
| 5 | +use Nowo\DoctrineEncryptBundle\Encryptors\EncryptorRegistry; |
5 | 6 | use Symfony\Component\Console\Attribute\AsCommand; |
6 | 7 | use Symfony\Component\Console\Input\InputInterface; |
7 | | -// attributes |
8 | 8 | use Symfony\Component\Console\Output\OutputInterface; |
9 | 9 |
|
10 | 10 | /** |
11 | | - * Console command that lists entities and the count of encrypted properties per entity. |
| 11 | + * Console command that lists entities, their encrypted properties with config, and the configured encryptor configs. |
12 | 12 | */ |
13 | 13 | #[AsCommand( |
14 | 14 | name: 'doctrine:encrypt:status', |
|
19 | 19 | class DoctrineEncryptStatusCommand extends AbstractCommand |
20 | 20 | { |
21 | 21 | /** |
22 | | - * Outputs each entity and its encrypted property count, then a total summary. |
| 22 | + * Config name => [path, encryptor_class]; used to show encryptor class in configured configs. |
| 23 | + * |
| 24 | + * @var array<string, array{path: string|null, encryptor_class: string}> |
| 25 | + */ |
| 26 | + private array $keyPaths; |
| 27 | + |
| 28 | + /** |
| 29 | + * @param array<string, array{path: string|null, encryptor_class: string}> $keyPaths |
| 30 | + */ |
| 31 | + public function __construct( |
| 32 | + \Doctrine\ORM\EntityManagerInterface $entityManager, |
| 33 | + \Nowo\DoctrineEncryptBundle\Mapping\AttributeReader $attributeReader, |
| 34 | + \Nowo\DoctrineEncryptBundle\Subscribers\DoctrineEncryptSubscriber $subscriber, |
| 35 | + ?\Nowo\DoctrineEncryptBundle\Encryptors\EncryptorInterface $defaultEncryptor = null, |
| 36 | + ?EncryptorRegistry $encryptorRegistry = null, |
| 37 | + array $keyPaths = [] |
| 38 | + ) { |
| 39 | + parent::__construct($entityManager, $attributeReader, $subscriber, $defaultEncryptor, $encryptorRegistry); |
| 40 | + $this->keyPaths = $keyPaths; |
| 41 | + } |
| 42 | + |
| 43 | + /** |
| 44 | + * Outputs each entity with its encrypted properties and config, then a summary and the configured configs. |
23 | 45 | * |
24 | 46 | * @param InputInterface $input Console input |
25 | 47 | * @param OutputInterface $output Console output |
26 | 48 | * @return int Command::SUCCESS |
27 | 49 | */ |
28 | 50 | protected function execute(InputInterface $input, OutputInterface $output): int |
29 | 51 | { |
30 | | - $metaDataArray = $this->entityManager->getMetadataFactory()->getAllMetadata(); |
| 52 | + $defaultConfigName = $this->encryptorRegistry?->getDefaultName() ?? 'default'; |
31 | 53 |
|
| 54 | + $metaDataArray = $this->entityManager->getMetadataFactory()->getAllMetadata(); |
| 55 | + $entitiesWithEncryption = 0; |
32 | 56 | $totalCount = 0; |
| 57 | + |
33 | 58 | foreach ($metaDataArray as $metaData) { |
34 | 59 | if (isset($metaData->isMappedSuperclass) && $metaData->isMappedSuperclass) { |
35 | 60 | continue; |
36 | 61 | } |
37 | 62 |
|
38 | | - $count = 0; |
39 | | - $encryptedPropertiesCount = count($this->getEncryptionableProperties($metaData)); |
40 | | - if ($encryptedPropertiesCount > 0) { |
41 | | - $totalCount += $encryptedPropertiesCount; |
42 | | - $count += $encryptedPropertiesCount; |
43 | | - } |
| 63 | + $propertiesWithConfig = $this->getEncryptionablePropertiesWithConfig($metaData, $defaultConfigName); |
| 64 | + $count = count($propertiesWithConfig); |
44 | 65 |
|
45 | 66 | if ($count > 0) { |
46 | | - $output->writeln(sprintf('<info>%s</info> has <info>%d</info> properties which are encrypted.', $metaData->name, $count)); |
| 67 | + $entitiesWithEncryption++; |
| 68 | + $totalCount += $count; |
| 69 | + $output->writeln(sprintf('<info>%s</info> has <info>%d</info> encrypted property(ies):', $metaData->name, $count)); |
| 70 | + foreach ($propertiesWithConfig as ['property' => $property, 'config' => $config]) { |
| 71 | + $output->writeln(sprintf(' - <comment>%s</comment> (config: <comment>%s</comment>)', $property->getName(), $config)); |
| 72 | + } |
47 | 73 | } else { |
48 | 74 | $output->writeln(sprintf('<info>%s</info> has no properties which are encrypted.', $metaData->name)); |
49 | 75 | } |
50 | 76 | } |
51 | 77 |
|
52 | 78 | $output->writeln(''); |
53 | | - $output->writeln(sprintf('<info>%d</info> entities found which are containing <info>%d</info> encrypted properties.', count($metaDataArray), $totalCount)); |
| 79 | + $output->writeln(sprintf( |
| 80 | + '<info>%d</info> entit(y/ies) with encryption, <info>%d</info> encrypted properties in total (out of <info>%d</info> entities).', |
| 81 | + $entitiesWithEncryption, |
| 82 | + $totalCount, |
| 83 | + count($metaDataArray) |
| 84 | + )); |
| 85 | + |
| 86 | + $this->outputConfiguredConfigs($output, $defaultConfigName); |
| 87 | + |
54 | 88 | return AbstractCommand::SUCCESS; |
55 | 89 | } |
| 90 | + |
| 91 | + private function outputConfiguredConfigs(OutputInterface $output, string $defaultConfigName): void |
| 92 | + { |
| 93 | + $output->writeln(''); |
| 94 | + $output->writeln('<info>Configured encryptor configs:</info>'); |
| 95 | + |
| 96 | + if ($this->encryptorRegistry === null) { |
| 97 | + $output->writeln(' (registry not available)'); |
| 98 | + return; |
| 99 | + } |
| 100 | + |
| 101 | + $configNames = $this->encryptorRegistry->getConfigNames(); |
| 102 | + // Exclude the 'default' alias when there are other configs (so we don't list "default" and "personal_data" when default is personal_data) |
| 103 | + $namesToShow = array_values(array_filter($configNames, static fn (string $name): bool => $name !== 'default' || count($configNames) === 1)); |
| 104 | + |
| 105 | + if (count($namesToShow) === 0) { |
| 106 | + $output->writeln(' (none)'); |
| 107 | + return; |
| 108 | + } |
| 109 | + |
| 110 | + $keyPaths = $this->keyPaths; |
| 111 | + foreach ($namesToShow as $name) { |
| 112 | + $encryptorClass = $keyPaths[$name]['encryptor_class'] ?? null; |
| 113 | + $label = $encryptorClass ? sprintf('%s (%s)', $name, $encryptorClass) : $name; |
| 114 | + $defaultLabel = $name === $defaultConfigName ? ' [default]' : ''; |
| 115 | + $output->writeln(sprintf(' - %s%s', $label, $defaultLabel)); |
| 116 | + } |
| 117 | + } |
56 | 118 | } |
0 commit comments