From f346b95c14c778c3db9d0f864aeda919859293cd Mon Sep 17 00:00:00 2001
From: Torsten Oppermann <torsten@sgalinski.de>
Date: Mon, 23 Apr 2018 10:18:16 +0200
Subject: [PATCH] [TASK] Checking for file size, preserving form values

---
 Classes/Controller/JoblistController.php      | 51 ++++++++++++++++++-
 .../TypoScript/Frontend/constants.ts          |  2 +
 Configuration/TypoScript/Frontend/setup.ts    |  1 +
 3 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/Classes/Controller/JoblistController.php b/Classes/Controller/JoblistController.php
index 5840f7d7..651fbdc0 100644
--- a/Classes/Controller/JoblistController.php
+++ b/Classes/Controller/JoblistController.php
@@ -39,11 +39,15 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
 use TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException;
+use TYPO3\CMS\Extbase\Mvc\Request;
 
 /**
  * The joblist plugin controller
  */
 class JoblistController extends ActionController {
+	// the array key for the error message in the post array
+	const ERROR_KEY_IN_POST = 'error';
+
 	/**
 	 * @var \SGalinski\SgJobs\Domain\Repository\CompanyRepository
 	 * @inject
@@ -133,6 +137,10 @@ class JoblistController extends ActionController {
 	 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentNameException
 	 */
 	public function applyFormAction(JobApplication $applyData = NULL, $error = NULL, $jobId = NULL) {
+		if ($error === NULL && isset($_POST[self::ERROR_KEY_IN_POST])) {
+			$error = $_POST[self::ERROR_KEY_IN_POST];
+		}
+
 		if ($error !== NULL && $error !== '') {
 			$this->view->assign('internalError', $error);
 			$this->request->setArgument('error', NULL);
@@ -189,6 +197,7 @@ class JoblistController extends ActionController {
 		}
 
 		$this->view->assign('applyData', $applyData);
+		$this->view->assign('maxFileSize', $this->settings['allowedMaxFileSize']);
 	}
 
 	/**
@@ -204,9 +213,23 @@ class JoblistController extends ActionController {
 			$uniqueFolderName = $this->request->getArgument('folderName');
 		} catch (NoSuchArgumentException $exception) {
 			$exceptionMessage = 'Eine Datei konnte nicht hochgeladen werden. Ist diese eventuell zu groß?';
-			$this->redirect('applyForm', NULL, NULL, ['error' => $exceptionMessage]);
+
+			$_POST[self::ERROR_KEY_IN_POST] = $exceptionMessage;
+			$this->forwardToReferringRequest();
+			exit;
+		}
+
+		/** @var array $applyDataArray */
+		$applyDataArray = $this->request->getArgument('applyData');
+
+		$exceptionMessage = 'Bitte beachten Sie die maximale Upload Größe von '
+			. (int) ($this->settings['allowedMaxFileSize'] / 1000) . 'MB';
+		if (!$this->checkFileSizes($applyDataArray)) {
+			$_POST[self::ERROR_KEY_IN_POST] = $exceptionMessage;
+			$this->forwardToReferringRequest();
 			exit;
 		}
+
 		$propertyMappingConfiguration = $this->arguments->getArgument('applyData')->getPropertyMappingConfiguration();
 		$propertyMappingConfiguration->forProperty('job')->allowAllProperties();
 
@@ -457,4 +480,30 @@ class JoblistController extends ActionController {
 			$this->redirect('applyForm', NULL, NULL, ['error' => $exception->getMessage()]);
 		}
 	}
+
+	/**
+	 * checks for allowed maximum file sizes
+	 *
+	 * @param array $applyData
+	 * @return bool
+	 */
+	private function checkFileSizes(array $applyData): bool {
+		$coverLetterSize = (int) $applyData['coverLetter']['size'] / 1000;
+		$cvSize = (int) $applyData['cv']['size'] / 1000;
+		$certificateSize = (int) $applyData['certificate']['size'] / 1000;
+		$allowedMaxFileSize = (int) $this->settings['allowedMaxFileSize'];
+
+		if ($allowedMaxFileSize === 0) {
+			return TRUE;
+		}
+
+		if ($allowedMaxFileSize < $coverLetterSize
+			|| $allowedMaxFileSize < $cvSize
+			|| $allowedMaxFileSize < $certificateSize) {
+
+			return FALSE;
+		}
+
+		return TRUE;
+	}
 }
diff --git a/Configuration/TypoScript/Frontend/constants.ts b/Configuration/TypoScript/Frontend/constants.ts
index f991c3f5..8a85b59f 100644
--- a/Configuration/TypoScript/Frontend/constants.ts
+++ b/Configuration/TypoScript/Frontend/constants.ts
@@ -17,6 +17,8 @@ plugin.tx_sgjobs {
 		allowedFileExtensions = pdf
 		# cat=plugin.tx_sgjobs/other; type=string; label=Allowed mime types for uploads in the Fluid template (comma separated)
 		allowedMimeTypes = application/pdf
+		# cat=plugin.tx_sgjobs/other; type=string; label=Allowed maximum file size for uploads in kB
+		allowedMaxFileSize = 5000
 	}
 
 	pagebrowser.settings {
diff --git a/Configuration/TypoScript/Frontend/setup.ts b/Configuration/TypoScript/Frontend/setup.ts
index ab78a406..c0e6406d 100644
--- a/Configuration/TypoScript/Frontend/setup.ts
+++ b/Configuration/TypoScript/Frontend/setup.ts
@@ -24,6 +24,7 @@ plugin.tx_sgjobs {
 	settings {
 		allowedFileExtensions = {$plugin.tx_sgjobs.settings.allowedFileExtensions}
 		allowedMimeTypes = {$plugin.tx_sgjobs.settings.allowedMimeTypes}
+		allowedMaxFileSize = {$plugin.tx_sgjobs.settings.allowedMaxFileSize}
 	}
 
 	features {
-- 
GitLab