Improve phrasing and expand the section on `IFileProcessor`
authorAlexander Ebert <ebert@woltlab.com>
Wed, 9 Oct 2024 15:05:09 +0000 (17:05 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Wed, 9 Oct 2024 15:05:09 +0000 (17:05 +0200)
docs/migration/wsc60/php.md
docs/php/api/file_uploads.md

index 6a6dbf26f7fbf0f472d7158a9bcaaf7dcf1d997e..5fde877a12b98ad5389d872dc617a932234c36e7 100644 (file)
@@ -202,13 +202,12 @@ public class FooBarAction extends AbstractDatabaseObjectAction implements IMessa
 ## Migration to `FileProcessorFormField`
 
 Previously, the `UploadFormField` class was used to create file upload fields in forms.
-Now, the new `FileProcessorFormField` should be used,
-which separates file validation and processing into a dedicated class, the `IFileProcessor`.
+It is strongly recommended to use the new `FileProcessorFormField` instead which separates file validation and processing into a dedicated class, the `IFileProcessor`.
 
-Only the fileID or several fileIDs now need to be saved in the database.
-These should have a foreign key to `wcf1_file.fileID`.
+Only the fileID (or fileIDs) now need to be saved in the database.
+These should reference `wcf1_file.fileID` through a foreign key.
 
-The previously required function (`getFooUploadFiles`) to get `UploadFile[]` is no longer needed and can be removed.
+The previously required function (`getFooUploadFiles`) to retrieve `UploadFile[]` is no longer needed and can be removed.
 
 ### Example
 
@@ -216,8 +215,7 @@ In this example, the `Foo` object will store the `imageID` of the uploaded file.
 
 #### Example using `FileProcessorFormField`
 
-The form field now provides information about which `IFileProcessor` should be used for the file upload,
-by specifying the object type of `com.woltlab.wcf.file`.
+The form field now provides information about which `IFileProcessor` should be used for the file upload, by specifying the object type for the definition `com.woltlab.wcf.file`.
 
 ```PHP
 final class FooAddForm extends AbstractFormBuilderForm
@@ -244,6 +242,13 @@ final class FooAddForm extends AbstractFormBuilderForm
 
 The `objectID` in the `$context` comes from the form and corresponds to the objectID of the `FooAddForm::$formObject`.
 
+This is a rather exhaustive example and tries to cover a lot of different use cases including but not limited to fine-grained control through user group permissions.
+
+The `AbstractFileProcessor` implementation already provides a lot of sane defaults for less restricted uploads.
+For example, if your field allows arbitrary files to be uploaded, you can skip that check in `acceptUpload()` and also remove the overriden method `getAllowedFileExtensions()` because the base implementation already permits all types of files.
+
+Please see the explanation of the new [file uploads](../../php/api/file_uploads.md) to learn more.
+
 ```PHP
 final class FooImageFileProcessor extends AbstractFileProcessor
 {    
@@ -383,8 +388,7 @@ final class FooImageFileProcessor extends AbstractFileProcessor
 
 ### Migrating existing files
 
-To insert existing files into the upload pipeline,
-a `RebuildDataWorker` should be used which calls `FileEditor::createFromExistingFile()`.
+To insert existing files into the upload pipeline, a `RebuildDataWorker` should be used which calls `FileEditor::createFromExistingFile()`.
 
 #### Example for a `RebuildDataWorker`
 
index 25facc5e543e47ceab5e91744b5a486e3a055e81..6caef73684ab1b35c92028b5f38eb39038d6dd95 100644 (file)
@@ -6,17 +6,17 @@ Attachments are implemented as an extra layer on top of the upload pipeline.
 
 The most common use cases are the attachment system that relies on the WYSIWYG editor as well as the `FileProcessorFormField`.
 
-# Provide the `IFileProcessor`
+## Provide the `IFileProcessor`
 
 At the very core of each uploadable type is an implementation of `IFileProcessor` that handles the validation and handling of new files.
 
 It is strongly recommended to derive from `AbstractFileProcessor` that makes it easy to opt out of some extra features and will provide backwards compatibility with new features.
 
-## Important Methods and Features
+### Important Methods and Features
 
 Please refer to the documentation in `IFileProcessor` for an explanation of methods that are not explained here.
 
-### Thumbnails
+#### Thumbnails
 
 It is possible to automatically generate thumbnails for any uploaded file.
 The number of thumbnail variants is not limited but each thumbnail must have an identifier that is unique for your file processor.
@@ -50,7 +50,7 @@ The existing rebuild data worker for files will check the existing thumbnails ag
 
 The identifier must be stable because it is used to verify if a specific thumbnail still matches the configured settings.
 
-### Resizing Images Before Uploading
+#### Resizing Images Before Uploading
 
 You can opt-in to the resize feature by returning a custom `ResizeConfiguration` from `getResizeConfiguration`, otherwise images of arbitrary size will be accepted.
 
@@ -75,7 +75,7 @@ public function getResizeConfiguration(): ResizeConfiguration
 The `ResizeFileType` controls the output format of the resized image.
 The available options are `jpeg` and `webp` but it is also possible to keep the existing image format.
 
-### Adopting Files and Thumbnails
+#### Adopting Files and Thumbnails
 
 Files are associated with your object type after being uploaded but you possibly want to store the file id in your database table.
 This is where `adopt(File $file, array $context): void` comes into play which notifies you of the successful upload of a file while providing the context that is used to upload the file in the first place.
@@ -83,14 +83,14 @@ This is where `adopt(File $file, array $context): void` comes into play which no
 Thumbnails are generated in a separate request for performance reasons and you are being notified through `adoptThumbnail(FileThumbnail $thumbnail): void`.
 This is meant to allow you to track the thumbnail id in the database.
 
-### Tracking Downloads
+#### Tracking Downloads
 
 File downloads are handled through the `FileDownloadAction` which validates the requested file and permissions to download it.
 Every time a file is being downloaded, `trackDownload(File $file): void` is invoked to allow you to update any counters.
 
 Static images are served directly by the web server for performance reasons and it is not possible to track those accesses.
 
-## Registering the File Processor
+### Registering the File Processor
 
 The file processor is registered as an object type for `com.woltlab.wcf.file` through the `objectType.xml`:
 
@@ -109,11 +109,11 @@ The integration with the form builder enables you to focus on the file processin
 
 Please see documentation for [FileProcessorFormField](form_fields.md#fileprocessorformfield) to learn more.
 
-# Implementing an Unmanaged File Upload
+## Implementing an Unmanaged File Upload
 
 If you cannot use or want to use the existing form builder implementation you can still implement the UI yourself following this guide.
 
-## Creating the Context for New Files
+### Creating the Context for New Files
 
 The HTML element for the file upload is generated through the helper method `FileProcessor::getHtmlElement()` that expects a reference to your `IFileProcessor` as well as a context for new files.
 
@@ -137,7 +137,7 @@ final class ExampleFileProcessor extends AbstractFileProcessor {
 This code will generate a `<woltlab-core-file-upload>` HTML element that can be inserted anywhere on the page.
 You do not need to initialize any extra JavaScript to make the element work, it will be initialized dynamically.
 
-## Lifecycle of Uploaded Files
+### Lifecycle of Uploaded Files
 
 Any file that passes the pre-upload validation will be uploaded to the server.
 This will trigger the `uploadStart` event on the `<woltlab-core-file-upload>` element, exposing a `<woltlab-core-file>` element as the only detail.
@@ -150,11 +150,11 @@ A successful upload will resolve the promise without any value, you can then acc
 A failed upload will reject the `.ready` promise without any value, instead you can retrieve the error through the `.apiError` property if you want to further process it.
 The UI is automatically updated with the error message, you only need to handle the `.apiError` property if you need to inspect the root cause.
 
-## Deleting a File
+### Deleting a File
 
 You can delete a file from the UI by invoking `deleteFile()` from `WoltLabSuite/Core/Api/Files` which takes the value of `.fileId`.
 
-## Render a Previously Uploaded File
+### Render a Previously Uploaded File
 
 You can render the `<woltlab-core-file>` element through `File::toHtmlElement()`.
 This method accepts an optional list of meta data that is serialized to JSON and exposed on the `data-meta-data` property.