Wiki-Quellcode von FileUploader
Zuletzt geändert von admin am 2025/02/23 19:33
Verstecke letzte Bearbeiter
| author | version | line-number | content |
|---|---|---|---|
| |
1.1 | 1 | {{velocity output="false"}} |
| 2 | #macro (createAttachment $fileName) | ||
| 3 | #set ($document = $doc) | ||
| 4 | #if ("$!request.document" != '') | ||
| 5 | #set ($document = $xwiki.getDocument($request.document)) | ||
| 6 | #end | ||
| 7 | #if ($document && $document.hasAccessLevel('edit')) | ||
| 8 | ## If the attachment is uploaded to a new document then make sure we create the document with the right default | ||
| 9 | ## locale. See CKEDITOR-316: Document translations are created when uploading a file from the WYSIWYG editor in a | ||
| 10 | ## multi-language wiki. The following code replicates the behavior of the Upload action, but it has the desired | ||
| 11 | ## effect only on XWiki 11.9+ | ||
| 12 | #if ($document.isNew()) | ||
| 13 | #set ($rootLocale = $services.localization.toLocale('')) | ||
| 14 | #set ($discard = $document.setLocale($rootLocale)) | ||
| 15 | #if ($rootLocale.equals($document.getDefaultLocale())) | ||
| 16 | #set ($discard = $document.setDefaultLocale($xwiki.getLocalePreference())) | ||
| 17 | #end | ||
| 18 | ## We also need to make sure the new document is created with the right syntax (e.g. the one coming from the | ||
| 19 | ## template used to create the document rather than the default wiki syntax). | ||
| 20 | #if ("$!request.syntax" != '') | ||
| 21 | #set ($discard = $document.setSyntaxId($request.syntax)) | ||
| 22 | #end | ||
| 23 | #end | ||
| 24 | ## FIXME: Get the file content as an input stream instead of a byte array, but for this we need to expose | ||
| 25 | ## getFileItemInputStream in the public API of the fileupload plugin (or use a script service). | ||
| 26 | #set ($bytes = $xwiki.fileupload.getFileItemData('upload')) | ||
| 27 | #if (!$bytes) | ||
| 28 | ## Empty file (unfortunately getFileItemData returns null instead of an empty byte array). | ||
| 29 | #set ($bytes = []) | ||
| 30 | #end | ||
| 31 | #set ($discard = $document.addAttachment($fileName, $bytes)) | ||
| 32 | #set ($discard = $document.save($services.localization.render('core.comment.uploadAttachmentComment', [$fileName]))) | ||
| 33 | #sendSuccess($document $fileName) | ||
| 34 | #else | ||
| 35 | ## Forbidden | ||
| 36 | #sendError(403 'You are not allowed to perform this action.') | ||
| 37 | #end | ||
| 38 | #end | ||
| 39 | |||
| 40 | ## Old way of uploading, with a save of the document for each upload. | ||
| 41 | #macro (handleUploadRequest) | ||
| 42 | #set ($fileName = $xwiki.fileupload.getFileName('upload')) | ||
| 43 | #if ("$!fileName" != '') | ||
| 44 | #if ($services.csrf.isTokenValid($request.form_token)) | ||
| 45 | ## Note: This is not useful anymore and files are expected to have their definitive name on upload. | ||
| 46 | ## Kept for legacy. | ||
| 47 | #if ($fileName.startsWith('__fileCreatedFromDataURI__.')) | ||
| 48 | ## We need to generate a new name so that we don't overwrite existing attachments. | ||
| 49 | #set ($extension = $stringtool.substringAfter($fileName, '.')) | ||
| 50 | #set ($fileName = "${datetool.date.time}-${mathtool.random(100, 1000)}.$extension") | ||
| 51 | #end | ||
| 52 | #createAttachment($fileName) | ||
| 53 | #else | ||
| 54 | #sendError(403 "$services.localization.render('ckeditor.upload.error.csrf')") | ||
| 55 | #end | ||
| 56 | #else | ||
| 57 | ## Bad Request | ||
| 58 | #sendError(400 "$services.localization.render('ckeditor.upload.error.emptyReturn')") | ||
| 59 | #end | ||
| 60 | #end | ||
| 61 | |||
| 62 | ## New way of handling attachment without saving immediately the document. | ||
| 63 | #macro (handleTemporaryUploadRequest) | ||
| 64 | #if ($services.csrf.isTokenValid($request.form_token)) | ||
| 65 | #set ($document = $doc) | ||
| 66 | #if ("$!request.document" != '') | ||
| 67 | #set ($document = $xwiki.getDocument($request.document)) | ||
| 68 | #end | ||
| 69 | #set ($reference = $document.documentReference) | ||
| 70 | #try('uploadTemporaryAttachmentException') | ||
| 71 | #if ("$!request.filename" != '') | ||
| 72 | ## If the filename is explicitly provided, no need to recompute it. | ||
| 73 | #set ($fileName = $request.filename) | ||
| 74 | #else | ||
| 75 | #set ($fileName = $request.getPart('upload').getSubmittedFileName()) | ||
| 76 | ## Note: this is not useful anymore and files are expected to have their definitive name on upload. | ||
| 77 | ## Kept for legacy. | ||
| 78 | #if ($fileName.startsWith('__fileCreatedFromDataURI__.')) | ||
| 79 | ## We need to generate a new name so that we don't overwrite existing attachments. | ||
| 80 | #set ($extension = $stringtool.substringAfter($fileName, '.')) | ||
| 81 | #set ($fileName = "${datetool.date.time}-${mathtool.random(100, 1000)}.$extension") | ||
| 82 | #end | ||
| 83 | #end | ||
| 84 | #set ($attachment = $services.temporaryAttachments.uploadTemporaryAttachment($reference, 'upload', $fileName)) | ||
| 85 | #end | ||
| 86 | #if ($attachment) | ||
| 87 | #sendSuccess($document, $attachment.filename) | ||
| 88 | #elseif ("$!uploadTemporaryAttachmentException" != '') | ||
| 89 | ## The exception is wrapped in an org.apache.velocity.exception.MethodInvocationException | ||
| 90 | #set ($validationException = $uploadTemporaryAttachmentException.cause) | ||
| 91 | #if ($validationException.translationKey) | ||
| 92 | #sendError(400 "$services.localization.render($validationException.translationKey, $validationException.translationParameters)") | ||
| 93 | #else | ||
| 94 | #sendError(400 "$services.localization.render('ckeditor.upload.error.emptyReturn')") | ||
| 95 | #end | ||
| 96 | #else | ||
| 97 | #sendError(400 "$services.localization.render('ckeditor.upload.error.emptyReturn')") | ||
| 98 | #end | ||
| 99 | #else | ||
| 100 | #sendError(403 "$services.localization.render('ckeditor.upload.error.csrf')") | ||
| 101 | #end | ||
| 102 | #end | ||
| 103 | |||
| 104 | #macro (sendSuccess $document $fileName) | ||
| 105 | #set ($url = $document.getAttachmentURL($fileName)) | ||
| 106 | #set ($attachmentReference = $services.model.createAttachmentReference($document.documentReference, $fileName)) | ||
| 107 | #set ($resourceReference = { | ||
| 108 | 'type': 'attach', | ||
| 109 | 'reference': $services.model.serialize($attachmentReference, $document.documentReference) | ||
| 110 | }) | ||
| 111 | #set ($discard = $response.setContentType('application/json')) | ||
| 112 | #if ($request.initiator == 'filetools') | ||
| 113 | $jsontool.serialize({ | ||
| 114 | 'uploaded': 1, | ||
| 115 | 'fileName': $fileName, | ||
| 116 | 'url': $url, | ||
| 117 | 'resourceReference': $resourceReference | ||
| 118 | }) | ||
| 119 | #else | ||
| 120 | ## JSON expected by the filebrowser plugin. | ||
| 121 | $jsontool.serialize({ | ||
| 122 | 'uploaded': 1, | ||
| 123 | 'url': $url, | ||
| 124 | 'fileName': $fileName, | ||
| 125 | 'message': { | ||
| 126 | 'resourceReference': $resourceReference | ||
| 127 | } | ||
| 128 | }) | ||
| 129 | #end | ||
| 130 | #end | ||
| 131 | |||
| 132 | #macro (sendError $code $message) | ||
| 133 | #set ($discard = $response.setContentType('application/json')) | ||
| 134 | ## The filetools plugin doesn't display the proper message if we call sendError() or setStatus() on the response. | ||
| 135 | #if ($request.initiator != 'filetools') | ||
| 136 | #set ($discard = $response.setStatus($code)) | ||
| 137 | #end | ||
| 138 | $jsontool.serialize({ | ||
| 139 | 'uploaded': 0, | ||
| 140 | 'error': { | ||
| 141 | 'number': $code, | ||
| 142 | 'message': $message | ||
| 143 | } | ||
| 144 | }) | ||
| 145 | #end | ||
| 146 | {{/velocity}} | ||
| 147 | |||
| 148 | {{velocity wiki="false"}} | ||
| 149 | #if ($xcontext.action == 'get') | ||
| 150 | ## We fallback on the old mechanism also in case of editing a translation to avoid any problem. | ||
| 151 | ## See: XWIKI-20034 | ||
| 152 | #set ($document = $tdoc) | ||
| 153 | #if ("$!request.document" != '') | ||
| 154 | #set ($document = $xwiki.getDocument($request.document)) | ||
| 155 | #end | ||
| 156 | ## Special handling if we're editing a translation that does not exist yet: in such case we cannot rely on $document.isTranslation because the context $tdoc | ||
| 157 | ## automatically fallback on the default locale in view mode, and we're getting this through a /get/ request. | ||
| 158 | ## See: XWIKI-20537 | ||
| 159 | #set ($isNewTranslation = false) | ||
| 160 | #if ($document.locale == "" && $services.localization.currentLocale != $services.localization.defaultLocale) | ||
| 161 | #set ($docRefWithLocale = $services.model.createDocumentReference($document.documentReference, $services.localization.currentLocale)) | ||
| 162 | #set ($isNewTranslation = $xwiki.getDocument($docRefWithLocale).isNew()) | ||
| 163 | #end | ||
| 164 | #if ($request.getHeader('X-XWiki-Temporary-Attachment-Support') == 'true' && !$document.isTranslation() && !$isNewTranslation) | ||
| 165 | #handleTemporaryUploadRequest() | ||
| 166 | #else | ||
| 167 | #handleUploadRequest() | ||
| 168 | #end | ||
| 169 | #end | ||
| 170 | {{/velocity}} |