How to reflect settings updates on the front-end
- After adding the extension setting in back-end module, we have to bind it with the front-end so that when we update the settings of the extension from the back-end module, we can get the updates on front-end.
- In order to bind the settings with front-end, we need to pass the data from the controller to the template file of the front-end plugin. Update the controller files, below are the screenshots of the updated things, and after the screenshots, there is the full code of the controller files, so you can check the updated things in screenshots, and then just copy the controller file’s code and replace the existing code in your file with the latest given code.
EmployController.php
Below are the screenshots from the employeeClassesControllerEmployController.php file of the updated data for the table tx_employee_domain_model_conf.
1. Add the confRepository
2. Add confData in indexAction()
3. Add confData in detailAction()
4. Add confData in belistAction()
5. Below is the full code of the employeeClassesControllerEmployController.php file after adding the things you can see in the above screenshots:
<?php
declare(strict_types=1);
namespace CompanyEmployeeController;
use DateTime;
use TYPO3CMSExtbaseMvcControllerActionController;
use TYPO3CMSBackendTemplateModuleTemplateFactory;
use PsrHttpMessageResponseInterface;
use TYPO3CMSCoreContextContext;
use TYPO3CMSExtbaseUtilityDebuggerUtility;
use TYPO3CMSCoreUtilityGeneralUtility;
use TYPO3CMSCoreTypeContextualFeedbackSeverity;
use CompanyEmployeeDomainModelEmploy;
class EmployController extends ActionController
{
/**
* employRepository
*
* @var CompanyEmployeeDomainRepositoryEmployRepository
*/
protected $employRepository = null;
/**
* @param CompanyEmployeeDomainRepositoryEmployRepository $employRepository
*/
public function injectEmployRepository(CompanyEmployeeDomainRepositoryEmployRepository $employRepository)
{
$this->employRepository = $employRepository;
}
/**
* confRepository
*
* @var CompanyEmployeeDomainRepositoryConfRepository
*/
protected $confRepository = null;
/**
* @param CompanyEmployeeDomainRepositoryConfRepository $confRepository
*/
public function injectConfRepository(CompanyEmployeeDomainRepositoryConfRepository $confRepository)
{
$this->confRepository = $confRepository;
}
public function __construct(
protected readonly ModuleTemplateFactory $moduleTemplateFactory,
Context $context,
) {
$this->context = $context;
}
/**
* action list
*
* @return string|object|null|void
*/
public function indexAction(): ResponseInterface
{
$settings = $this->settings;
$this->view->assign('settings', $settings);
$employs = $this->employRepository->findAll();
$this->view->assign('employs', $employs);
$confData = $this->confRepository->findByUid(1);
$this->view->assign('confData', $confData);
return $this->htmlResponse();
}
/**
* action detail
*
* @return string|object|null|void
*/
public function detailAction(): ResponseInterface
{
$uid = GeneralUtility::_GP('uid');
$confData = $this->confRepository->findByUid(1);
$this->view->assign('confData', $confData);
if ($uid) {
$details = $this->employRepository->findByUid($uid);
$this->view->assign('details', $details);
} else {
$this->view->assign('details', null);
}
return $this->htmlResponse();
}
public function belistAction(): ResponseInterface
{
$employs = $this->employRepository->findAll();
$this->view->assign('employs', $employs);
$confData = $this->confRepository->findByUid(1);
$this->view->assign('confData', $confData);
$moduleTemplate = $this->moduleTemplateFactory->create($this->request)->setTitle("Employee List");
$moduleTemplate->setContent($this->view->render());
return $this->htmlResponse($moduleTemplate->renderContent());
}
public function newAction(): ResponseInterface
{
$newEmploy = new Employ();
$this->view->assign('newEmploy', $newEmploy);
$moduleTemplate = $this->moduleTemplateFactory->create($this->request)->setTitle("Add Employee");
$moduleTemplate->setContent($this->view->render());
return $this->htmlResponse($moduleTemplate->renderContent());
}
public function initializeCreateAction()
{
if ($this->arguments['newEmploy']) {
$propertyMappingConfiguration = $this->arguments['newEmploy']->getPropertyMappingConfiguration();
$propertyMappingConfiguration->allowAllProperties();
$propertyMappingConfiguration->forProperty('birthDate')->setTypeConverterOption(TYPO3CMSExtbasePropertyTypeConverterDateTimeConverter::class, TYPO3CMSExtbasePropertyTypeConverterDateTimeConverter::CONFIGURATION_DATE_FORMAT, 'Y-m-d');
$propertyMappingConfiguration->forProperty('joiningDate')->setTypeConverterOption(TYPO3CMSExtbasePropertyTypeConverterDateTimeConverter::class, TYPO3CMSExtbasePropertyTypeConverterDateTimeConverter::CONFIGURATION_DATE_FORMAT, 'Y-m-d');
$propertyMappingConfiguration->skipProperties('image');
}
}
/**
* action create
* @param Employ $newEmploy
* @return void
*/
public function createAction(Employ $newEmploy): ResponseInterface
{
$uploaded = $this->request->getUploadedFiles();
if (sizeOf($uploaded) > 0) {
$__imag = $uploaded['newEmploy']['image'];
$resourceFactory = GeneralUtility::makeInstance(TYPO3CMSCoreResourceResourceFactory::class);
$storage = $resourceFactory->getDefaultStorage();
$newFile = $storage->addFile(
$__imag->getTemporaryFileName(),
$storage->getRootLevelFolder(),
$__imag->getClientFilename()
);
$fileReference = GeneralUtility::makeInstance(CompanyEmployeeDomainModelFileReference::class);
$fileReference->setOriginalResource($newFile);
$newEmploy->addImage($fileReference);
}
$this->addFlashMessage('Employee Added successfully!!', 'Success', ContextualFeedbackSeverity::OK, true);
$this->employRepository->add($newEmploy);
$redirectPid = (int) $this->settings['listPid'];
$uriBuilder = $this->uriBuilder;
$uri = $uriBuilder
->setTargetPageUid($redirectPid)
->build();
return $this->redirectToUri($uri);
}
public function deleteAction(): ResponseInterface
{
$arguments = $this->request->getArguments();
$uid = $arguments['uid'];
if ($uid) {
$emplodata = $this->employRepository->findByUid($uid);
// DebuggerUtility::var_dump($this->employRepository);
// exit();
if ($emplodata) {
$delete = $this->employRepository->remove($emplodata);
$this->addFlashMessage('Employee Deleted Sucessfully!!', 'Done!!', ContextualFeedbackSeverity::OK, true);
} else {
$this->addFlashMessage('Employee Not Found!!', 'Invalid', ContextualFeedbackSeverity::WARNING, true);
}
} else {
$this->addFlashMessage('Employee Not Found!!', 'Invalid', ContextualFeedbackSeverity::WARNING, true);
}
return $this->redirect('belist');
}
public function editAction(): ResponseInterface
{
$arguments = $this->request->getArguments();
$uid = $arguments['uid'];
if ($uid) {
$emplodata = $this->employRepository->findByUid($uid);
if ($emplodata) {
$this->view->assign('employ', $emplodata);
$moduleTemplate = $this->moduleTemplateFactory->create($this->request)->setTitle("Edit Employee");
$moduleTemplate->setContent($this->view->render());
return $this->htmlResponse($moduleTemplate->renderContent());
} else {
$this->addFlashMessage('Employee Not Found!!', 'Invalid', ContextualFeedbackSeverity::WARNING, true);
return $this->redirect('belist');
}
} else {
$this->addFlashMessage('Employee Not Found!!', 'Invalid', ContextualFeedbackSeverity::WARNING, true);
return $this->redirect('belist');
}
}
public function initializeUpdateAction()
{
if ($this->arguments['employ']) {
$propertyMappingConfiguration = $this->arguments['employ']->getPropertyMappingConfiguration();
$propertyMappingConfiguration->allowAllProperties();
$propertyMappingConfiguration->forProperty('birthDate')->setTypeConverterOption(TYPO3CMSExtbasePropertyTypeConverterDateTimeConverter::class, TYPO3CMSExtbasePropertyTypeConverterDateTimeConverter::CONFIGURATION_DATE_FORMAT, 'Y-m-d');
$propertyMappingConfiguration->forProperty('joiningDate')->setTypeConverterOption(TYPO3CMSExtbasePropertyTypeConverterDateTimeConverter::class, TYPO3CMSExtbasePropertyTypeConverterDateTimeConverter::CONFIGURATION_DATE_FORMAT, 'Y-m-d');
$propertyMappingConfiguration->skipProperties('image');
}
}
/**
* action create
* @param Employ $employ
* @return void
*/
public function updateAction(Employ $employ): ResponseInterface
{
$uploaded = $this->request->getUploadedFiles();
if (sizeOf($uploaded) > 0) {
$oldImage = $employ->getImage();
if($oldImage){
foreach($oldImage as $im){
$employ->removeImage($im);
}
}
$__imag = $uploaded['employ']['image'];
$resourceFactory = GeneralUtility::makeInstance(TYPO3CMSCoreResourceResourceFactory::class);
$storage = $resourceFactory->getDefaultStorage();
$newFile = $storage->addFile(
$__imag->getTemporaryFileName(),
$storage->getRootLevelFolder(),
$__imag->getClientFilename()
);
$fileReference = GeneralUtility::makeInstance(CompanyEmployeeDomainModelFileReference::class);
$fileReference->setOriginalResource($newFile);
$employ->addImage($fileReference);
}
$this->employRepository->update($employ);
$this->addFlashMessage('Employee Updated successfully!!', 'Success', ContextualFeedbackSeverity::OK, true);
return $this->redirect('belist');
}
public function updatesettingAction(): ResponseInterface
{
$data = $this->request->getArgument('confData');
$existSettings = $this->confRepository->findByUid(1);
if($existSettings){
$existSettings->setImagelist($data['imagelist']);
$existSettings->setImagedetail($data['imagedetail']);
$this->confRepository->update($existSettings);
}else{
$Conff = GeneralUtility::makeInstance(CompanyEmployeeDomainModelConf::class);
$Conff->setImagelist($data['imagelist']);
$Conff->setImagedetail($data['imagedetail']);
$this->confRepository->add($Conff);
}
$this->addFlashMessage('Settings Updated successfully!!', 'Success', ContextualFeedbackSeverity::OK, true);
return $this->redirect('belist');
}
}
JobController.php
Below are the screenshots from the employeeClassesControllerJobController.php file of the updated data for the table tx_employee_domain_model_conf.
1. Add the confRepository
2. Add confData in indexAction()
3. Add confData in detailAction()
4. Below is the full code of the employeeClassesControllerJobController.php file after adding the things you can see in the above screenshots:
<?php
declare(strict_types=1);
namespace CompanyEmployeeController;
use TYPO3CMSExtbaseMvcControllerActionController;
use TYPO3CMSBackendTemplateModuleTemplateFactory;
use PsrHttpMessageResponseInterface;
use TYPO3CMSCoreContextContext;
use TYPO3CMSExtbaseUtilityDebuggerUtility;
use TYPO3CMSCoreUtilityGeneralUtility;
use CompanyEmployeeDomainModelEmploy;
use TYPO3CMSCoreTypeContextualFeedbackSeverity;
use DateTime;
class JobController extends ActionController
{
/**
* jobRepository
*
* @var CompanyEmployeeDomainRepositoryJobRepository
*/
protected $jobRepository = null;
/**
* @param CompanyEmployeeDomainRepositoryJobRepository $jobRepository
*/
public function injectJobRepository(CompanyEmployeeDomainRepositoryJobRepository $jobRepository)
{
$this->jobRepository = $jobRepository;
}
/**
* employRepository
*
* @var CompanyEmployeeDomainRepositoryEmployRepository
*/
protected $employRepository = null;
/**
* @param CompanyEmployeeDomainRepositoryEmployRepository $employRepository
*/
public function injectEmployRepository(CompanyEmployeeDomainRepositoryEmployRepository $employRepository)
{
$this->employRepository = $employRepository;
}
/**
* confRepository
*
* @var CompanyEmployeeDomainRepositoryConfRepository
*/
protected $confRepository = null;
/**
* @param CompanyEmployeeDomainRepositoryConfRepository $confRepository
*/
public function injectConfRepository(CompanyEmployeeDomainRepositoryConfRepository $confRepository)
{
$this->confRepository = $confRepository;
}
public function __construct(
protected readonly ModuleTemplateFactory $moduleTemplateFactory,
Context $context,
) {
$this->context = $context;
}
/**
* action list
*
* @return string|object|null|void
*/
public function indexAction(): ResponseInterface
{
$settings = $this->settings;
$this->view->assign('settings', $settings);
$jobs = $this->jobRepository->findAll();
$this->view->assign('jobs', $jobs);
$confData = $this->confRepository->findByUid(1);
$this->view->assign('confData', $confData);
return $this->htmlResponse();
}
/**
* action detail
*
* @return string|object|null|void
*/
public function detailAction(): ResponseInterface
{
$uid = GeneralUtility::_GP('uid');
$confData = $this->confRepository->findByUid(1);
$this->view->assign('confData', $confData);
if ($uid) {
$details = $this->jobRepository->findByUid($uid);
$this->view->assign('details', $details);
} else {
$this->view->assign('details', null);
}
return $this->htmlResponse();
}
/**
* Set TypeConverter option for image upload
*/
public function initializeCreateAction()
{
if ($this->arguments['newEmploy']) {
DebuggerUtility::var_dump($this->request->getArguments('newEmploy'));
$propertyMappingConfiguration = $this->arguments['newEmploy']->getPropertyMappingConfiguration();
$propertyMappingConfiguration->allowAllProperties();
$propertyMappingConfiguration->forProperty('birthDate')->setTypeConverterOption(TYPO3CMSExtbasePropertyTypeConverterDateTimeConverter::class, TYPO3CMSExtbasePropertyTypeConverterDateTimeConverter::CONFIGURATION_DATE_FORMAT, 'Y-m-d');
$propertyMappingConfiguration->forProperty('joiningDate')->setTypeConverterOption(TYPO3CMSExtbasePropertyTypeConverterDateTimeConverter::class, TYPO3CMSExtbasePropertyTypeConverterDateTimeConverter::CONFIGURATION_DATE_FORMAT, 'Y-m-d');
$propertyMappingConfiguration->skipProperties('image');
$propertyMappingConfiguration->skipProperties('education');
}
}
/**
* action create
* @param Employ $newEmploy
* @return void
*/
public function createAction(Employ $newEmploy): ResponseInterface
{
$requestData = $this->request->getArguments('newEmploy');
$uploaded = $this->request->getUploadedFiles();
if (sizeOf($uploaded) > 0) {
$__imag = $uploaded['newEmploy']['image'];
$resourceFactory = GeneralUtility::makeInstance(TYPO3CMSCoreResourceResourceFactory::class);
$storage = $resourceFactory->getDefaultStorage();
$newFile = $storage->addFile(
$__imag->getTemporaryFileName(),
$storage->getRootLevelFolder(),
$__imag->getClientFilename()
);
$fileReference = GeneralUtility::makeInstance(CompanyEmployeeDomainModelFileReference::class);
$fileReference->setOriginalResource($newFile);
$newEmploy->addImage($fileReference);
}
if ($requestData['newEmploy']['education']) {
$edu = $requestData['newEmploy']['education'];
$education = GeneralUtility::makeInstance(CompanyEmployeeDomainModelEducation::class);
$education->setCgpa((float) $edu['cgpa']);
$education->setRollnumber($edu['rollnumber']);
$education->setStartDate(new DateTime($edu['startDate']));
$education->setEndDate(new DateTime($edu['endDate']));
$education->setTitle($edu['title']);
$newEmploy->addEducations($education);
}
$this->employRepository->add($newEmploy);
$this->addFlashMessage('Employee Added successfully!!', 'Success', ContextualFeedbackSeverity::OK, true);
$redirectPid = (int) $this->settings['listPid'];
$uriBuilder = $this->uriBuilder;
$uri = $uriBuilder
->setTargetPageUid($redirectPid)
->build();
return $this->redirectToUri($uri);
}
}
employeeResourcesPrivateTemplatesEmployIndex.html
1. Below is the full code of the template file after updates related to the settings of back-end module, the file path is: employeeResourcesPrivateTemplatesEmployIndex.html
<div>
<div>
<div>
<f:for each="{employs}" as="emp">
<div>
<f:if condition="{confData.imagelist}">
<div>
<f:if condition="{emp.image}">
<f:for each="{emp.image}" as="img">
<f:image image="{img}" alt="{emp.firstName}" width="200c" height="200c" />
</f:for>
</f:if>
</div>
</f:if>
<div>
<div>
<p><strong>Name : </strong>{emp.firstName} {emp.lastName}</p>
</div>
<div>
<p><strong>Gender : </strong>{emp.gender == 1 ? "Male" :"Female"}</p>
</div>
<div>
<p><strong></strong>{emp.bio}</p>
</div>
<div>
<f:link.page pageUid="{settings.detailPid}" additionalParams="{uid: emp.uid}">Read More
</f:link.page>
</div>
</div>
</div>
</f:for>
</div>
</div>
</div>
In the above code, there is a condition of confData that binds the settings of the image with the template file, and the condition is
<f:if condition="{confData.imagelist}">
you will see the same condition in the below template files.
employeeResourcesPrivateTemplatesEmployDetail.html
Below is the full code of the template file: employeeResourcesPrivateTemplatesEmployDetail.html
<div>
<div>
<div>
<f:if condition="{details}">
<f:then>
<h1>{details.firstName} {details.lastName}</h1>
<f:if condition="{confData.imagedetail}">
<f:if condition="{details.image}">
<f:for each="{details.image}" as="img">
<div>
<f:image image="{img}" alt="{details.firstName}" />
</div>
</f:for>
</f:if>
</f:if>
<div>
<div>
<h3>Basic Details</h3>
<div>
<div>
<strong>First name </strong>
</div>
<div>
<p>{details.firstName}</p>
</div>
</div>
<div>
<div>
<strong>Last name </strong>
</div>
<div>
<p>{details.lastName}</p>
</div>
</div>
<div>
<div>
<strong>Gender </strong>
</div>
<div>
<p>{details.gender == 1 ? "Male":"Female"}</p>
</div>
</div>
<div>
<div>
<strong>Birth Date </strong>
</div>
<div>
<p>
<f:format.date>{details.birthDate}</f:format.date>
</p>
</div>
</div>
<div>
<div>
<strong>Joining Date </strong>
</div>
<div>
<p>
<f:format.date>{details.joiningDate}</f:format.date>
</p>
</div>
</div>
<div>
<div>
<strong>Salary </strong>
</div>
<div>
<p>{details.salary}</p>
</div>
</div>
<div>
<div>
<strong>Country </strong>
</div>
<div>
<p>{details.country}</p>
</div>
</div>
<div>
<div>
<strong>Languages </strong>
</div>
<div>
<p>{details.languages}</p>
</div>
</div>
<div>
<div>
<strong>Bio</strong>
</div>
<div>
<p>{details.bio}</p>
</div>
</div>
<div>
<div>
<strong>Experiance</strong>
</div>
<div>
<p>
<f:format.html>{details.experiance}</f:format.html>
</p>
</div>
</div>
</div>
<div>
<h3>Educations</h3>
<f:if condition="{details.educations}">
<div>
<div><strong>Title</strong></div>
<div><strong>Roll Number</strong></div>
<div><strong>CGPA</strong></div>
<div><strong>University</strong></div>
<div><strong>Start Date</strong></div>
<div><strong>End Date</strong></div>
</div>
<f:for each="{details.educations}" as="edu">
<div>
<div>
<p>{edu.title}</p>
</div>
<div>
<p>{edu.rollNumber}</p>
</div>
<div>
<p>{edu.cgpa}</p>
</div>
<div>
<p>{edu.university}</p>
</div>
<div>
<p>
<f:format.date>{edu.startDate}</f:format.date>
</p>
</div>
<div>
<p>
<f:format.date>{edu.endDate}</f:format.date>
</p>
</div>
</div>
</f:for>
</f:if>
</div>
</div>
</f:then>
<f:else>
<div>
Employee not found!!
</div>
</f:else>
</f:if>
</div>
</div>
</div>
employeeResourcesPrivateTemplatesJobIndex.html
Below is the full code of the template file:employeeResourcesPrivateTemplatesJobIndex.html
<div>
<div>
<f:flashMessages />
<div>
<f:for each="{jobs}" as="job">
<div>
<div>
<f:if condition="{confData.imagelist}">
<div>
<f:if condition="{job.bannerImage}">
<f:for each="{job.bannerImage}" as="img">
<f:image image="{img}" alt="{job.firstName}" width="400c"
height="200c" />
</f:for>
</f:if>
</div>
</f:if>
<div>
<div>
<h2>
<f:link.page pageUid="{settings.detailPid}" additionalParams="{uid: job.uid}">
{job.jobTitle}
</f:link.page>
</h2>
</div>
<div>
<div><strong>Vacancy : </strong>{job.vacancy}</div>
<div><strong>Location : </strong>{job.jobLocation }</div>
<div><strong>job type" /> : </strong>{job.jobType }</div>
<div><strong>Experience of Years : </strong>{job.yearsOfExperience }</div>
<div><strong>Working hours : </strong>{job.workingHrs }</div>
<div><strong>Working days : </strong>{job.workingDays }</div>
</div>
<div>
<div>
<f:link.page pageUid="{settings.detailPid}" additionalParams="{uid: job.uid}"
>
Apply For Job
</f:link.page>
</div>
</div>
</div>
</div>
</div>
</f:for>
</div>
</div>
</div>
employeeResourcesPrivateTemplatesJobDetail.html
Below is the full code of the template file: employeeResourcesPrivateTemplatesJobDetail.html
<div>
<div>
<div>
<f:if condition="{details}">
<f:then>
<div>
<h1>{details.jobTitle}</h1>
<f:if condition="{confData.imagedetail}">
<f:if condition="{details.bannerImage}">
<f:for each="{details.bannerImage}" as="img">
<div>
<f:image image="{img}" alt="{details.firstName}" />
</div>
</f:for>
</f:if>
</f:if>
<div>
<h3>Details</h3>
<div>
<div>
<strong>Job Title </strong>
</div>
<div>
<p>{details.jobTitle }</p>
</div>
</div>
<div>
<div>
<strong>Vacancy</strong>
</div>
<div>
<p>{details.vacancy}</p>
</div>
</div>
<div>
<div>
<strong>Job Location</strong>
</div>
<div>
<p>{details.jobLocation }</p>
</div>
</div>
<div>
<div>
<strong>Salary </strong>
</div>
<div>
<p>{details.salary}</p>
</div>
</div>
<div>
<div>
<strong>Country </strong>
</div>
<div>
<p>{details.country}</p>
</div>
</div>
<div>
<div>
<strong>jobType</strong>
</div>
<div>
<p>{details.jobType }</p>
</div>
</div>
<div>
<div>
<strong>yearsOfExperience</strong>
</div>
<div>
<p>{details.yearsOfExperience }</p>
</div>
</div>
<div>
<div>
<strong>workingHrs</strong>
</div>
<div>
<p>{details.workingHrs}</p>
</div>
</div>
<div>
<div>
<strong>workingDays</strong>
</div>
<div>
<p>{details.workingDays}</p>
</div>
</div>
<div>
<div>
<strong>jobDescription</strong>
</div>
<div>
<p>
<f:format.html>{details.jobDescription}</f:format.html>
</p>
</div>
</div>
<div>
<div>
<strong>jobRequirements</strong>
</div>
<div>
<p>
<f:format.html>{details.jobRequirements}</f:format.html>
</p>
</div>
</div>
<div>
<div>
<strong>educationQualification </strong>
</div>
<div>
<p>
<f:format.html>{details.educationQualification }</f:format.html>
</p>
</div>
</div>
<div>
<div>
<strong>perksBenefits </strong>
</div>
<div>
<p>
<f:format.html>{details.perksBenefits }</f:format.html>
</p>
</div>
</div>
</div>
</div>
<div>
<div>
<f:form action="create" enctype="multipart/form-data" name="newEmploy" object="{newEmploy}">
<h2>Apply For Job </h2>
<f:render partial="Employe/FormFields" arguments="{_all}" />
<div>
<f:form.submit value="Apply" />
</div>
</f:form>
</div>
</div>
</f:then>
<f:else>
<div>
Job not found!!
</div>
</f:else>
</f:if>
</div>
</div>
</div>
After all the above updates in controllers and templates, let’s check if the settings are working or not.