From acfb655f887a6f560bcb69d961dc9a9c0f555d96 Mon Sep 17 00:00:00 2001
From: Torsten Oppermann <torsten@sgalinski.de>
Date: Wed, 10 Jan 2018 14:54:07 +0100
Subject: [PATCH] [TASK] Implementing new features, fixing massive model issues

---
 Classes/Controller/JoblistController.php      |  9 ++++++
 Classes/Domain/Model/Company.php              | 19 ++++++++++++
 Classes/Domain/Model/Job.php                  |  8 ++---
 Classes/Domain/Model/JobApplication.php       | 20 +++++++++++++
 .../Domain/Repository/CompanyRepository.php   | 30 +++++++++++++++++++
 .../TCA/tx_sgjobs_domain_model_company.php    | 28 +++++++++++++++--
 ...tx_sgjobs_domain_model_job_application.php | 28 +++++++++++++++--
 Resources/Private/Language/de.locallang.xlf   |  4 +++
 Resources/Private/Language/locallang.xlf      |  3 ++
 Resources/Private/Partials/Job.html           | 10 +++----
 .../Private/Templates/Joblist/ApplyForm.html  | 19 ++++++++++++
 ext_tables.sql                                |  4 ++-
 12 files changed, 166 insertions(+), 16 deletions(-)

diff --git a/Classes/Controller/JoblistController.php b/Classes/Controller/JoblistController.php
index 07f2fc0b..ccb26853 100644
--- a/Classes/Controller/JoblistController.php
+++ b/Classes/Controller/JoblistController.php
@@ -156,12 +156,18 @@ class JoblistController extends ActionController {
 		$this->view->assign('folderName', $folderName);
 
 		$job = NULL;
+
 		if (!$uid !== NULL) {
 			/** @var Job $job */
 			$job = $this->jobRepository->findByUid($uid);
 			if ($job) {
 				$GLOBALS['TSFE']->page['titlebyextension'] = $job->getTitle();
 				$GLOBALS['TSFE']->page['description'] = substr($job->getDescription(), 0, 200);
+			} else {
+				$storagePid = (int) $this->configurationManager->getConfiguration(
+					ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK
+				)['persistence']['storagePid'];
+				$this->view->assign('companies', $this->companyRepository->getAllCompanies($storagePid));
 			}
 			$this->view->assign('job', $job);
 		}
@@ -299,7 +305,10 @@ class JoblistController extends ActionController {
 
 			if ($contact !== NULL) {
 				$mailService->setToAddresses($contact->getEmail());
+			} else {
+				$mailService->setToAddresses($applyData->getCompany()->getContact()->getEmail());
 			}
+
 			$mailService->setMarkers(['application' => $applyData]);
 			$mailService->setIgnoreMailQueue(TRUE);
 
diff --git a/Classes/Domain/Model/Company.php b/Classes/Domain/Model/Company.php
index 81d30fd5..bdc6193f 100644
--- a/Classes/Domain/Model/Company.php
+++ b/Classes/Domain/Model/Company.php
@@ -57,6 +57,11 @@ class Company extends AbstractEntity {
 	 */
 	protected $description = '';
 
+	/**
+	 * @var \SGalinski\SgJobs\Domain\Model\Contact $contact
+	 */
+	protected $contact;
+	
 	/**
 	 * @return string
 	 */
@@ -126,4 +131,18 @@ class Company extends AbstractEntity {
 	public function setStreet(string $street) {
 		$this->street = $street;
 	}
+
+	/**
+	 * @return \SGalinski\SgJobs\Domain\Model\Contact
+	 */
+	public function getContact() {
+		return $this->contact;
+	}
+
+	/**
+	 * @param \SGalinski\SgJobs\Domain\Model\Contact $contact
+	 */
+	public function setContact(Contact $contact) {
+		$this->contact = $contact;
+	}
 }
diff --git a/Classes/Domain/Model/Job.php b/Classes/Domain/Model/Job.php
index 152b7fc7..df52d714 100644
--- a/Classes/Domain/Model/Job.php
+++ b/Classes/Domain/Model/Job.php
@@ -74,7 +74,7 @@ class Job extends AbstractEntity {
 	protected $startDate = 0;
 
 	/**
-	 * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\SGalinski\SgJobs\Domain\Model\Company> $company
+	 * @var \SGalinski\SgJobs\Domain\Model\Company $company
 	 */
 	protected $company = '';
 
@@ -159,16 +159,16 @@ class Job extends AbstractEntity {
 	}
 
 	/**
-	 * @return string
+	 * @return Company
 	 */
 	public function getCompany() {
 		return $this->company;
 	}
 
 	/**
-	 * @param ObjectStorage $company
+	 * @param Company $company
 	 */
-	public function setCompany(ObjectStorage $company) {
+	public function setCompany(Company $company) {
 		$this->company = $company;
 	}
 
diff --git a/Classes/Domain/Model/JobApplication.php b/Classes/Domain/Model/JobApplication.php
index 03c76e6e..e9319eb0 100644
--- a/Classes/Domain/Model/JobApplication.php
+++ b/Classes/Domain/Model/JobApplication.php
@@ -46,6 +46,12 @@ class JobApplication extends AbstractEntity {
 	 */
 	protected $jobTitle = '';
 
+	/**
+	 * @var \SGalinski\SgJobs\Domain\Model\Company $company
+	 * @validate NotEmpty
+	 */
+	protected $company;
+
 	/**
 	 * @var \SGalinski\SgJobs\Domain\Model\Job $job
 	 */
@@ -430,4 +436,18 @@ class JobApplication extends AbstractEntity {
 	public function setJob(Job $job) {
 		$this->job = $job;
 	}
+
+	/**
+	 * @return Company
+	 */
+	public function getCompany() {
+		return $this->company;
+	}
+
+	/**
+	 * @param Company $company
+	 */
+	public function setCompany(Company $company) {
+		$this->company = $company;
+	}
 }
diff --git a/Classes/Domain/Repository/CompanyRepository.php b/Classes/Domain/Repository/CompanyRepository.php
index b5fbffae..0ac97ee2 100644
--- a/Classes/Domain/Repository/CompanyRepository.php
+++ b/Classes/Domain/Repository/CompanyRepository.php
@@ -152,4 +152,34 @@ class CompanyRepository extends Repository {
 
 		return $namesArray;
 	}
+
+
+
+	/**
+	 * Returns all companies filtered by page id
+	 *
+	 * @param int $pageUid
+	 * @return mixed
+	 * @throws \InvalidArgumentException
+	 */
+	public function getAllCompanies($pageUid) {
+		$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable(
+			self::TABLENAME
+		);
+
+		$queryBuilder
+			->getRestrictions()
+			->removeAll()
+			->add(GeneralUtility::makeInstance(DeletedRestriction::class))
+			->add(GeneralUtility::makeInstance(FrontendRestrictionContainer::class));
+		$statement = $queryBuilder->select('*')->from('tx_sgjobs_domain_model_company');
+
+		$statement->where(
+			$queryBuilder->expr()->eq(
+				'pid', $queryBuilder->createNamedParameter($pageUid)
+			)
+		);
+
+		return $statement->execute();
+	}
 }
diff --git a/Configuration/TCA/tx_sgjobs_domain_model_company.php b/Configuration/TCA/tx_sgjobs_domain_model_company.php
index 0b1dcaba..e808ef80 100644
--- a/Configuration/TCA/tx_sgjobs_domain_model_company.php
+++ b/Configuration/TCA/tx_sgjobs_domain_model_company.php
@@ -8,7 +8,7 @@ return [
 		'crdate' => 'crdate',
 		'cruser_id' => 'cruser_id',
 		'dividers2tabs' => TRUE,
-		'searchFields' => 'city, country, description, name, street',
+		'searchFields' => 'city, country, description, name, street, contact',
 		'versioningWS' => 2,
 		'versioning_followPages' => TRUE,
 		'origUid' => 't3_origuid',
@@ -26,12 +26,12 @@ return [
 			'Resources/Public/Icons/tx_sgjobs_domain_model_company.svg'
 	],
 	'interface' => [
-		'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, pid, city, street name, country, description',
+		'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, pid, city, street name, country, description, contact',
 	],
 	'types' => [
 		'1' => [
 			'showitem' => '--palette--;;sysLanguageAndHidden,
-				city, street,name, country, description;;;richtext[*]:rte_transform[mode=ts],
+				city, street,name, country, description, contact;;;richtext[*]:rte_transform[mode=ts],
 				--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.access, starttime, endtime',
 		],
 	],
@@ -167,5 +167,27 @@ return [
 				'eval' => 'trim'
 			],
 		],
+		'contact' => [
+			'exclude' => 0,
+			'label' => 'LLL:EXT:sg_jobs/Resources/Private/Language/locallang_db.xlf:tx_sgjobs_domain_model_job.contact',
+			'config' => [
+				'type' => 'select',
+				'eval' => 'required',
+				'renderType' => 'selectSingle',
+				'internal_type' => 'db',
+				'foreign_table' => 'tx_sgjobs_domain_model_contact',
+				'size' => 1,
+				'maxitems' => 1,
+				'multiple' => 0,
+				'fieldControl' => [
+					'editPopup' => [
+						'disabled' => FALSE,
+					],
+					'addRecord' => [
+						'disabled' => FALSE,
+					]
+				],
+			]
+		]
 	],
 ];
\ No newline at end of file
diff --git a/Configuration/TCA/tx_sgjobs_domain_model_job_application.php b/Configuration/TCA/tx_sgjobs_domain_model_job_application.php
index 804842aa..91caf77b 100644
--- a/Configuration/TCA/tx_sgjobs_domain_model_job_application.php
+++ b/Configuration/TCA/tx_sgjobs_domain_model_job_application.php
@@ -12,7 +12,7 @@ $tx_sgjobs_domain_model_job_application = [
 		'crdate' => 'crdate',
 		'cruser_id' => 'cruser_id',
 		'dividers2tabs' => TRUE,
-		'searchFields' => 'job_id, job, job_title, gender, first_name, last_name, street, city, zip, country, nationality, education, birth_date, phone, mobile, email, message, cover_letter, certificate, cv',
+		'searchFields' => 'job_id, job, job_title, company, gender, first_name, last_name, street, city, zip, country, nationality, education, birth_date, phone, mobile, email, message, cover_letter, certificate, cv',
 		'versioningWS' => 2,
 		'versioning_followPages' => TRUE,
 		'origUid' => 't3_origuid',
@@ -30,12 +30,12 @@ $tx_sgjobs_domain_model_job_application = [
 			'Resources/Public/Icons/tx_sgjobs_domain_model_job.svg'
 	],
 	'interface' => [
-		'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, pid, job, job_id, job_title, area, start_date, alternative_start_date,
+		'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, pid, job, job_id, job_title, company, area, start_date, alternative_start_date,
 			 company, task, qualification, description, contact',
 	],
 	'types' => [
 		'1' => [
-			'showitem' => '--palette--;;sysLanguageAndHidden,job_id, job, job_title, gender, first_name, last_name, street, city, zip, 
+			'showitem' => '--palette--;;sysLanguageAndHidden,job_id, job, job_title, company, gender, first_name, last_name, street, city, zip, 
 					country, nationality, education, birth_date, phone, mobile, email, message, cover_letter, cv, certificate,
 				 	div;;richtext[*]:rte_transform[mode=ts],
 					--div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.access, starttime, endtime',
@@ -167,6 +167,28 @@ $tx_sgjobs_domain_model_job_application = [
 				'eval' => 'trim'
 			],
 		],
+		'company' => [
+			'exclude' => 0,
+			'label' => 'LLL:EXT:sg_jobs/Resources/Private/Language/locallang_db.xlf:tx_sgjobs_domain_model_job.company',
+			'config' => [
+				'type' => 'select',
+				'eval' => 'required',
+				'renderType' => 'selectSingle',
+				'internal_type' => 'db',
+				'foreign_table' => 'tx_sgjobs_domain_model_company',
+				'size' => 1,
+				'maxitems' => 1,
+				'multiple' => 0,
+				'fieldControl' => [
+					'editPopup' => [
+						'disabled' => FALSE,
+					],
+					'addRecord' => [
+						'disabled' => FALSE,
+					]
+				],
+			]
+		],
 		'gender' => [
 			'exclude' => 0,
 			'label' => 'LLL:EXT:sg_jobs/Resources/Private/Language/locallang_db.xlf:tx_sgjobs_domain_model_job_application.gender',
diff --git a/Resources/Private/Language/de.locallang.xlf b/Resources/Private/Language/de.locallang.xlf
index ececcb88..f9ead3ea 100644
--- a/Resources/Private/Language/de.locallang.xlf
+++ b/Resources/Private/Language/de.locallang.xlf
@@ -202,6 +202,10 @@
 			<source>Last name *</source>
 			<target>Nachname *</target>
 		</trans-unit>
+		<trans-unit id="frontend.apply.location" approved="yes">
+			<source>Location*</source>
+			<target>Standort*</target>
+		</trans-unit>
 		<trans-unit id="frontend.apply.message" approved="yes">
 			<source>Message</source>
 			<target>Ihre Nachricht</target>
diff --git a/Resources/Private/Language/locallang.xlf b/Resources/Private/Language/locallang.xlf
index 119ab738..2ee2be82 100644
--- a/Resources/Private/Language/locallang.xlf
+++ b/Resources/Private/Language/locallang.xlf
@@ -153,6 +153,9 @@
 		<trans-unit id="frontend.apply.last_name">
 			<source>Last name *</source>
 		</trans-unit>
+		<trans-unit id="frontend.apply.location">
+			<source>Location*</source>
+		</trans-unit>
 		<trans-unit id="frontend.apply.message">
 			<source>Message</source>
 		</trans-unit>
diff --git a/Resources/Private/Partials/Job.html b/Resources/Private/Partials/Job.html
index d87910bf..904ad622 100644
--- a/Resources/Private/Partials/Job.html
+++ b/Resources/Private/Partials/Job.html
@@ -31,14 +31,14 @@
 
 				<h3><f:translate key="frontend.location" /></h3>
 				<p>
-					{job.company.0.country} - {job.company.0.city}
+					{job.company.country} - {job.company.city}
 				</p>
 
 				<h3><f:translate key="frontend.area" /></h3>
 				<p>{job.area}</p>
 
 				<h3><f:translate key="frontend.organisation" /></h3>
-				<p>{job.company.0.name}</p>
+				<p>{job.company.name}</p>
 
 				<f:if condition="{job.task}">
 					<h3><f:translate key="frontend.task" /></h3>
@@ -64,12 +64,12 @@
 				<f:if condition="{job.contact.email} && !{job.contact.hideInFrontend}">
 					<h3><f:translate key="frontend.apply_by_mail" /></h3>
 					<p>
-						<f:for each="{job.company}" as="company">{company.name}</f:for>
+						{job.company.name}
 						<br>
 						{job.contact.firstName} {job.contact.lastName}<br>
-						<f:for each="{job.company}" as="company">{company.street}</f:for>
+						{job.company.street}
 						<br>
-						<f:for each="{job.company}" as="company">{company.city}</f:for>
+						{job.company.city}
 						<br>
 						{job.contact.email}<br>
 						{job.contact.phone}
diff --git a/Resources/Private/Templates/Joblist/ApplyForm.html b/Resources/Private/Templates/Joblist/ApplyForm.html
index 05ced8d2..d89c1b15 100644
--- a/Resources/Private/Templates/Joblist/ApplyForm.html
+++ b/Resources/Private/Templates/Joblist/ApplyForm.html
@@ -21,6 +21,7 @@
 						<f:form.hidden property="job" value="{job}" />
 						<f:form.hidden property="jobId" value="{job.jobId}" />
 						<f:form.hidden property="jobTitle" value="{job.title}" />
+						<f:form.hidden property="company" value="{job.company.uid}" />
 					</f:then>
 				</f:if>
 				<input type="hidden" name="tx_sgjobs_jobapplication[folderName]" value="{folderName}" />
@@ -51,6 +52,24 @@
 					</ul>
 				</f:if>
 
+				<f:if condition="!{job}">
+					<f:then>
+						<div class="form-group">
+							<label for="apply-company"><f:translate key="frontend.apply.company" /></label>
+							<f:form.select class="form-control" property="company" id="apply-company" multiple="0" size="1"
+								optionValueField="uid" optionLabelField="city" options="{companies}"
+							/>
+							<f:form.validationResults for="applyData.location">
+								<ul class="sg-jobs-validation-error parsley-errors-list filled">
+									<f:for each="{validationResults.errors}" as="error">
+										<li class="parsley-required">{error.message}</li>
+									</f:for>
+								</ul>
+							</f:form.validationResults>
+						</div>
+					</f:then>
+				</f:if>
+
 				<div class="form-group">
 					<label for="apply-gender"><f:translate key="frontend.apply.gender" /></label>
 					<f:form.select property="gender" id="apply-gender" class="form-control" options="{Male: '{f:translate(key: \'frontend.apply.gender.male\')}', Female: '{f:translate(key: \'frontend.apply.gender.female\')}'}" />
diff --git a/ext_tables.sql b/ext_tables.sql
index 09845360..abbe1555 100644
--- a/ext_tables.sql
+++ b/ext_tables.sql
@@ -58,6 +58,7 @@ CREATE TABLE tx_sgjobs_domain_model_company (
 	street varchar(255) DEFAULT '' NOT NULL,
 	country varchar(255) DEFAULT '' NOT NULL,
 	description text DEFAULT '' NOT NULL,
+	contact int(11) unsigned DEFAULT '0' NOT NULL,
 
 	-- TYPO3 fields
 	sorting int(11) unsigned DEFAULT '0' NOT NULL,
@@ -99,7 +100,7 @@ CREATE TABLE tx_sgjobs_domain_model_contact (
 	-- Custom fields
 	first_name varchar(255) DEFAULT '' NOT NULL,
 	last_name varchar(255) DEFAULT '' NOT NULL,
-	company varchar(255) DEFAULT '' NOT NULL,
+	company int(11) unsigned DEFAULT '0' NOT NULL,
 	city varchar(255) DEFAULT '' NOT NULL,
 	zip varchar(255) DEFAULT '' NOT NULL,
 	email varchar(255) DEFAULT '' NOT NULL,
@@ -147,6 +148,7 @@ CREATE TABLE tx_sgjobs_domain_model_job_application (
 	job_id text DEFAULT '' NOT NULL,
 	job int(11) unsigned DEFAULT '0' NOT NULL,
 	job_title text DEFAULT '' NOT NULL,
+	company text DEFAULT '' NOT NULL,
 	gender varchar(30) DEFAULT '' NOT NULL,
 	first_name text DEFAULT '' NOT NULL,
 	last_name text DEFAULT '' NOT NULL,
-- 
GitLab