|
11 | 11 | use OCA\Libresign\Db\File as FileEntity; |
12 | 12 | use OCA\Libresign\Service\FileService; |
13 | 13 | use OCA\Libresign\Service\Policy\Provider\DocMdp\FilePolicy\DocMdpFilePolicyApplier; |
| 14 | +use OCA\Libresign\Service\Policy\Provider\FilePolicy\Contract\IFilePolicyApplier; |
14 | 15 | use OCA\Libresign\Service\Policy\Provider\Footer\FilePolicy\FooterFilePolicyApplier; |
| 16 | +use OCA\Libresign\Service\Policy\Provider\PolicyProviders; |
15 | 17 | use OCA\Libresign\Service\Policy\Provider\Signature\FilePolicy\SignatureFlowFilePolicyApplier; |
16 | 18 | use OCP\IL10N; |
17 | 19 |
|
18 | 20 | class FilePolicyApplier { |
19 | | - private readonly SignatureFlowFilePolicyApplier $signatureFlowApplier; |
20 | | - private readonly DocMdpFilePolicyApplier $docMdpApplier; |
21 | | - private readonly FooterFilePolicyApplier $footerApplier; |
| 21 | + /** @var list<IFilePolicyApplier> */ |
| 22 | + private readonly array $appliers; |
22 | 23 |
|
23 | 24 | public function __construct( |
24 | 25 | private readonly PolicyService $policyService, |
25 | 26 | private readonly FileService $fileService, |
26 | 27 | private readonly IL10N $l10n, |
27 | 28 | ) { |
28 | | - $this->signatureFlowApplier = new SignatureFlowFilePolicyApplier($this->policyService, $this->fileService, $this->l10n); |
29 | | - $this->docMdpApplier = new DocMdpFilePolicyApplier($this->policyService, $this->fileService); |
30 | | - $this->footerApplier = new FooterFilePolicyApplier($this->policyService, $this->fileService, $this->l10n); |
| 29 | + $this->appliers = $this->discoverAppliers(); |
31 | 30 | } |
32 | 31 |
|
33 | 32 | /** |
34 | 33 | * Apply all policies to a freshly built FileEntity before the first insert. |
35 | 34 | */ |
36 | 35 | public function applyAll(FileEntity $file, array $data): void { |
37 | | - $this->applySignatureFlow($file, $data); |
38 | | - $this->applyDocMdpLevel($file, $data); |
39 | | - $this->applyFooterPolicy($file, $data); |
| 36 | + foreach ($this->appliers as $applier) { |
| 37 | + $applier->apply($file, $data); |
| 38 | + } |
40 | 39 | } |
41 | 40 |
|
42 | 41 | /** |
43 | 42 | * Re-evaluate and persist signature_flow + docmdp on an existing file. |
44 | 43 | * Use this when updating a file located by UUID. |
45 | 44 | */ |
46 | 45 | public function syncCoreFlowPolicies(FileEntity $file, array $data): void { |
47 | | - $this->syncSignatureFlow($file, $data); |
48 | | - $this->syncDocMdpLevel($file, $data); |
| 46 | + foreach ($this->appliers as $applier) { |
| 47 | + if ($applier->supportsCoreFlowSync()) { |
| 48 | + $applier->sync($file, $data); |
| 49 | + } |
| 50 | + } |
49 | 51 | } |
50 | 52 |
|
51 | 53 | /** |
52 | 54 | * Re-evaluate and persist all three policies on an existing file. |
53 | 55 | * Use this when updating a file located by node ID. |
54 | 56 | */ |
55 | 57 | public function syncAllPolicies(FileEntity $file, array $data): void { |
56 | | - $this->syncSignatureFlow($file, $data); |
57 | | - $this->syncDocMdpLevel($file, $data); |
58 | | - $this->syncFooterPolicy($file, $data); |
| 58 | + foreach ($this->appliers as $applier) { |
| 59 | + $applier->sync($file, $data); |
| 60 | + } |
59 | 61 | } |
60 | 62 |
|
61 | 63 | private function applySignatureFlow(FileEntity $file, array $data): void { |
62 | | - $this->signatureFlowApplier->apply($file, $data); |
| 64 | + $this->getApplierByClass(SignatureFlowFilePolicyApplier::class)->apply($file, $data); |
63 | 65 | } |
64 | 66 |
|
65 | 67 | private function syncSignatureFlow(FileEntity $file, array $data): void { |
66 | | - $this->signatureFlowApplier->sync($file, $data); |
| 68 | + $this->getApplierByClass(SignatureFlowFilePolicyApplier::class)->sync($file, $data); |
67 | 69 | } |
68 | 70 |
|
69 | 71 | private function applyDocMdpLevel(FileEntity $file, array $data): void { |
70 | | - $this->docMdpApplier->apply($file, $data); |
| 72 | + $this->getApplierByClass(DocMdpFilePolicyApplier::class)->apply($file, $data); |
71 | 73 | } |
72 | 74 |
|
73 | 75 | private function syncDocMdpLevel(FileEntity $file, array $data): void { |
74 | | - $this->docMdpApplier->sync($file, $data); |
| 76 | + $this->getApplierByClass(DocMdpFilePolicyApplier::class)->sync($file, $data); |
75 | 77 | } |
76 | 78 |
|
77 | 79 | private function applyFooterPolicy(FileEntity $file, array $data): void { |
78 | | - $this->footerApplier->apply($file, $data); |
| 80 | + $this->getApplierByClass(FooterFilePolicyApplier::class)->apply($file, $data); |
79 | 81 | } |
80 | 82 |
|
81 | 83 | private function syncFooterPolicy(FileEntity $file, array $data): void { |
82 | | - $this->footerApplier->sync($file, $data); |
| 84 | + $this->getApplierByClass(FooterFilePolicyApplier::class)->sync($file, $data); |
| 85 | + } |
| 86 | + |
| 87 | + /** @return list<IFilePolicyApplier> */ |
| 88 | + private function discoverAppliers(): array { |
| 89 | + $appliers = []; |
| 90 | + |
| 91 | + foreach (PolicyProviders::BY_KEY as $providerClass) { |
| 92 | + $applierClass = $this->buildFileApplierClassFromProvider($providerClass); |
| 93 | + if ($applierClass === null || !class_exists($applierClass)) { |
| 94 | + continue; |
| 95 | + } |
| 96 | + |
| 97 | + $instance = new $applierClass($this->policyService, $this->fileService, $this->l10n); |
| 98 | + if (!$instance instanceof IFilePolicyApplier) { |
| 99 | + continue; |
| 100 | + } |
| 101 | + |
| 102 | + $appliers[] = $instance; |
| 103 | + } |
| 104 | + |
| 105 | + return $appliers; |
| 106 | + } |
| 107 | + |
| 108 | + /** @param class-string $providerClass */ |
| 109 | + private function buildFileApplierClassFromProvider(string $providerClass): ?string { |
| 110 | + $lastSeparator = strrpos($providerClass, '\\'); |
| 111 | + if ($lastSeparator === false) { |
| 112 | + return null; |
| 113 | + } |
| 114 | + |
| 115 | + $namespace = substr($providerClass, 0, $lastSeparator); |
| 116 | + $shortName = substr($providerClass, $lastSeparator + 1); |
| 117 | + $baseName = str_ends_with($shortName, 'Policy') |
| 118 | + ? substr($shortName, 0, -strlen('Policy')) |
| 119 | + : $shortName; |
| 120 | + |
| 121 | + return $namespace . '\\FilePolicy\\' . $baseName . 'FilePolicyApplier'; |
| 122 | + } |
| 123 | + |
| 124 | + /** @param class-string<IFilePolicyApplier> $class */ |
| 125 | + private function getApplierByClass(string $class): IFilePolicyApplier { |
| 126 | + foreach ($this->appliers as $applier) { |
| 127 | + if ($applier instanceof $class) { |
| 128 | + return $applier; |
| 129 | + } |
| 130 | + } |
| 131 | + |
| 132 | + throw new \RuntimeException(sprintf('File policy applier "%s" not registered.', $class)); |
83 | 133 | } |
84 | 134 | } |
0 commit comments