Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
UploadValidator
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 1
30
0.00% covered (danger)
0.00%
0 / 1
 validateUploadedFile
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2
3declare(strict_types=1);
4/**
5 * SPDX-FileCopyrightText: 2024 LibreCode coop and contributors
6 * SPDX-License-Identifier: AGPL-3.0-or-later
7 */
8
9namespace OCA\Libresign\Controller\Traits;
10
11use OCP\AppFramework\Http;
12use OCP\AppFramework\Http\DataResponse;
13use OCP\IL10N;
14
15/**
16 * Trait for validating file uploads in controllers
17 *
18 * Provides reusable file upload validation logic with localized error messages
19 */
20trait UploadValidator {
21    protected IL10N $l10n;
22
23    /**
24     * Validate uploaded file and return error response if invalid
25     *
26     * @param array<string, mixed>|null $uploadedFile File array from IRequest::getUploadedFile()
27     * @param string $context Description for error messages (e.g., 'image', 'pdf')
28     * @return DataResponse<Http::STATUS_UNPROCESSABLE_ENTITY, array{message: string, status: 'failure'}, array<never, never>>|null DataResponse with error if invalid, null if valid
29     */
30    private function validateUploadedFile(?array $uploadedFile, string $context): ?DataResponse {
31        $phpFileUploadErrors = [
32            // TRANSLATORS Status message shown when a file upload completes successfully.
33            UPLOAD_ERR_OK => $this->l10n->t('The file was uploaded'),
34            // TRANSLATORS Error shown when an uploaded file exceeds the server maximum upload size limit.
35            UPLOAD_ERR_INI_SIZE => $this->l10n->t('The uploaded file exceeds the upload_max_filesize directive in php.ini'),
36            // TRANSLATORS Error shown when an uploaded file exceeds the maximum size allowed by the form.
37            UPLOAD_ERR_FORM_SIZE => $this->l10n->t('The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form'),
38            // TRANSLATORS Error shown when only part of the uploaded file reached the server.
39            UPLOAD_ERR_PARTIAL => $this->l10n->t('The file was only partially uploaded'),
40            // TRANSLATORS Error shown when the upload request contained no file.
41            UPLOAD_ERR_NO_FILE => $this->l10n->t('No file was uploaded'),
42            // TRANSLATORS Error shown when the server temporary folder for uploads is missing.
43            UPLOAD_ERR_NO_TMP_DIR => $this->l10n->t('Missing a temporary folder'),
44            // TRANSLATORS Error shown when the server could not write the uploaded file to disk.
45            UPLOAD_ERR_CANT_WRITE => $this->l10n->t('Could not write file to disk'),
46            // TRANSLATORS Error shown when a server extension stopped the file upload.
47            UPLOAD_ERR_EXTENSION => $this->l10n->t('A PHP extension stopped the file upload'),
48        ];
49
50        if (empty($uploadedFile)) {
51            return new DataResponse(
52                [
53                    // TRANSLATORS Error shown when LibreSign expected an uploaded file and none was present.
54                    'message' => $this->l10n->t('No file uploaded'),
55                    'status' => 'failure',
56                ],
57                Http::STATUS_UNPROCESSABLE_ENTITY
58            );
59        }
60
61        if (!empty($uploadedFile) && array_key_exists('error', $uploadedFile) && $uploadedFile['error'] !== UPLOAD_ERR_OK) {
62            return new DataResponse(
63                [
64                    'message' => $phpFileUploadErrors[$uploadedFile['error']],
65                    'status' => 'failure',
66                ],
67                Http::STATUS_UNPROCESSABLE_ENTITY
68            );
69        }
70
71        return null;
72    }
73}