@@ -93,9 +93,10 @@ public function __construct(
9393 protected LoggerInterface $ logger ,
9494 protected IL10N $ l10n ,
9595 private EnvelopeService $ envelopeService ,
96- private FileUploadHelper $ uploadHelper ,
96+ FileUploadHelper $ uploadHelper ,
9797 ) {
9898 $ this ->docMdpHandler = $ docMdpHandler ;
99+ $ this ->uploadHelper = $ uploadHelper ;
99100 $ this ->fileData = new stdClass ();
100101 }
101102
@@ -1011,4 +1012,87 @@ public function delete(int $fileId): void {
10111012 } catch (NotFoundException ) {
10121013 }
10131014 }
1015+
1016+ /**
1017+ * Process uploaded files with automatic rollback on error
1018+ *
1019+ * @param array $filesArray Normalized array of uploaded files
1020+ * @param IUser $user User who is uploading
1021+ * @param array $settings Upload settings
1022+ * @return list<array{fileNode: Node, name: string}>
1023+ * @throws LibresignException
1024+ */
1025+ public function processUploadedFilesWithRollback (array $ filesArray , IUser $ user , array $ settings ): array {
1026+ $ this ->validateEnvelopeConstraints ($ filesArray );
1027+
1028+ $ processedFiles = [];
1029+ $ createdNodes = [];
1030+ $ shouldRollback = true ;
1031+
1032+ try {
1033+ foreach ($ filesArray as $ uploadedFile ) {
1034+ $ fileName = pathinfo ($ uploadedFile ['name ' ], PATHINFO_FILENAME );
1035+
1036+ $ node = $ this ->getNodeFromUploadedFile ([
1037+ 'userManager ' => $ user ,
1038+ 'name ' => $ fileName ,
1039+ 'uploadedFile ' => $ uploadedFile ,
1040+ 'settings ' => $ settings ,
1041+ ]);
1042+
1043+ $ createdNodes [] = $ node ;
1044+
1045+ $ this ->validateHelper ->validateNewFile ([
1046+ 'file ' => ['fileId ' => $ node ->getId ()],
1047+ 'userManager ' => $ user ,
1048+ ]);
1049+
1050+ $ processedFiles [] = [
1051+ 'fileNode ' => $ node ,
1052+ 'name ' => $ fileName ,
1053+ ];
1054+ }
1055+
1056+ $ shouldRollback = false ;
1057+ return $ processedFiles ;
1058+ } finally {
1059+ if ($ shouldRollback ) {
1060+ $ this ->rollbackCreatedNodes ($ createdNodes );
1061+ }
1062+ }
1063+ }
1064+
1065+ /**
1066+ * @throws LibresignException
1067+ */
1068+ private function validateEnvelopeConstraints (array $ filesArray ): void {
1069+ if (count ($ filesArray ) <= 1 ) {
1070+ return ;
1071+ }
1072+
1073+ if (!$ this ->appConfig ->getValueBool (Application::APP_ID , 'envelope_enabled ' , true )) {
1074+ throw new LibresignException ($ this ->l10n ->t ('Envelope feature is disabled ' ));
1075+ }
1076+
1077+ $ maxFiles = $ this ->appConfig ->getValueInt (Application::APP_ID , 'envelope_max_files ' , 50 );
1078+ if (count ($ filesArray ) > $ maxFiles ) {
1079+ throw new LibresignException ($ this ->l10n ->t ('Maximum of %d files per envelope ' , [$ maxFiles ]));
1080+ }
1081+ }
1082+
1083+ /**
1084+ * @param Node[] $nodes
1085+ */
1086+ private function rollbackCreatedNodes (array $ nodes ): void {
1087+ foreach ($ nodes as $ node ) {
1088+ try {
1089+ $ node ->delete ();
1090+ } catch (\Exception $ deleteError ) {
1091+ $ this ->logger ->error ('Failed to rollback uploaded file ' , [
1092+ 'nodeId ' => $ node ->getId (),
1093+ 'error ' => $ deleteError ->getMessage (),
1094+ ]);
1095+ }
1096+ }
1097+ }
10141098}
0 commit comments