diff --git a/Classes/Domain/Model/Company.php b/Classes/Domain/Model/Company.php index 9eebce28acf7e4cc236dbf510b474cd4b0b24c79..8fcc4ecaf90339c7e6e78e120101db1c83e1a2e7 100644 --- a/Classes/Domain/Model/Company.php +++ b/Classes/Domain/Model/Company.php @@ -72,6 +72,11 @@ class Company extends AbstractEntity { */ protected $contact; + /** + * @var string $identifyingUrl + */ + protected $identifyingUrl; + /** * @return string */ @@ -183,4 +188,18 @@ class Company extends AbstractEntity { public function setZip($zip) { $this->zip = $zip; } + + /** + * @return string + */ + public function getIdentifyingUrl(): string { + return $this->identifyingUrl; + } + + /** + * @param string $identifyingUrl + */ + public function setIdentifyingUrl(string $identifyingUrl): void { + $this->identifyingUrl = $identifyingUrl; + } } diff --git a/Classes/Domain/Model/Job.php b/Classes/Domain/Model/Job.php index fd1d92efae6f449315d091fc71206b535fe2f070..5736486abb7a4fb9a6107a5ebb542434982c0de8 100644 --- a/Classes/Domain/Model/Job.php +++ b/Classes/Domain/Model/Job.php @@ -102,6 +102,51 @@ class Job extends AbstractEntity { */ protected $contact; + /** + * @var bool + */ + protected $telecommutePossible = FALSE; + + /** + * @var bool + */ + protected $officeWorkPossible = TRUE; + + /** + * @var string $employmentTypes + */ + protected $employmentTypes = ''; + + /** + * @var int $datePosted + */ + protected $datePosted = 0; + + /** + * @var int $datePosted + */ + protected $validThrough = 0; + + /** + * @var string $salaryCurrency + */ + protected $salaryCurrency = 'EUR'; + + /** + * @var string $salaryUnit + */ + protected $salaryUnit = ''; + + /** + * @var string $baseSalary + */ + protected $baseSalary = ''; + + /** + * @var string $maxSalary + */ + protected $maxSalary = ''; + /** * @return string */ @@ -298,4 +343,129 @@ class Job extends AbstractEntity { $this->sorting = $sorting; } + /** + * @return bool + */ + public function getTelecommutePossible(): bool { + return $this->telecommutePossible; + } + + /** + * @param bool $telecommutePossible + */ + public function setTelecommutePossible(bool $telecommutePossible): void { + $this->telecommutePossible = $telecommutePossible; + } + + /** + * @return bool + */ + public function getOfficeWorkPossible(): bool { + return $this->officeWorkPossible; + } + + /** + * @param bool $officeWorkPossible + */ + public function setOfficeWorkPossible(bool $officeWorkPossible): void { + $this->officeWorkPossible = $officeWorkPossible; + } + + /** + * @return string + */ + public function getEmploymentTypes(): string { + return $this->employmentTypes; + } + + /** + * @param string $employmentTypes + */ + public function setEmploymentTypes(string $employmentTypes): void { + $this->employmentTypes = $employmentTypes; + } + + /** + * @return int + */ + public function getDatePosted(): int { + return $this->datePosted; + } + + /** + * @param int $datePosted + */ + public function setDatePosted(int $datePosted): void { + $this->datePosted = $datePosted; + } + + /** + * @return int + */ + public function getValidThrough(): int { + return $this->validThrough; + } + + /** + * @param int $validThrough + */ + public function setValidThrough(int $validThrough): void { + $this->validThrough = $validThrough; + } + + /** + * @return string + */ + public function getSalaryCurrency(): string { + return $this->salaryCurrency; + } + + /** + * @param string $salaryCurrency + */ + public function setSalaryCurrency(string $salaryCurrency): void { + $this->salaryCurrency = $salaryCurrency; + } + + /** + * @return string + */ + public function getSalaryUnit(): string { + return $this->salaryUnit; + } + + /** + * @param string $salaryUnit + */ + public function setSalaryUnit(string $salaryUnit): void { + $this->salaryUnit = $salaryUnit; + } + + /** + * @return string + */ + public function getBaseSalary(): string { + return $this->baseSalary; + } + + /** + * @param string $baseSalary + */ + public function setBaseSalary(string $baseSalary): void { + $this->baseSalary = $baseSalary; + } + + /** + * @return string + */ + public function getMaxSalary(): string { + return $this->maxSalary; + } + + /** + * @param string $maxSalary + */ + public function setMaxSalary(string $maxSalary): void { + $this->maxSalary = $maxSalary; + } } diff --git a/Classes/ViewHelpers/ExplodeStringViewHelper.php b/Classes/ViewHelpers/ExplodeStringViewHelper.php new file mode 100644 index 0000000000000000000000000000000000000000..1079eec26fae10b0adb3e5d02c9137cbdd66f1ab --- /dev/null +++ b/Classes/ViewHelpers/ExplodeStringViewHelper.php @@ -0,0 +1,57 @@ +<?php + +namespace SGalinski\SgJobs\ViewHelpers; + +/*************************************************************** + * Copyright notice + * + * (c) sgalinski Internet Services (https://www.sgalinski.de) + * + * All rights reserved + * + * This script is part of the AY project. The AY project is + * free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * The GNU General Public License can be found at + * http://www.gnu.org/copyleft/gpl.html. + * + * This script is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * This copyright notice MUST APPEAR in all copies of the script! + ***************************************************************/ + +use TYPO3\CMS\Core\Utility\GeneralUtility; + +/** + * Takes a string containing multiple values separated by a delimiter and returns an array of these values. + * @TODO: Replace this ViewHelper with a VHS ViewHelper when updating to TYPO3 10! + * + * Example: + * {namespace jobs=SGalinski\SgJobs\ViewHelpers} + * <jobs:explodeString string="1,2,3,4" delimiter=","/> + */ +class ExplodeStringViewHelper extends AbstractViewHelper { + /** + * Register the ViewHelper arguments + */ + public function initializeArguments(): void { + parent::initializeArguments(); + $this->registerArgument('string', 'string', 'The string to explode', TRUE); + $this->registerArgument('delimiter', 'string', 'The string separating the values in the string', TRUE); + } + + /** + * Returns the exploded array of the given string value, separated by the delimiter + * + * @return array + */ + public function render(): array { + return GeneralUtility::trimExplode($this->arguments['delimiter'], $this->arguments['string']); + } +} diff --git a/Configuration/TCA/tx_sgjobs_domain_model_company.php b/Configuration/TCA/tx_sgjobs_domain_model_company.php index 1f41cd81550ddb66733c795f4cf355dd254ae33a..27c55245c15de23b0d965e854c041af1f429b3a8 100644 --- a/Configuration/TCA/tx_sgjobs_domain_model_company.php +++ b/Configuration/TCA/tx_sgjobs_domain_model_company.php @@ -57,6 +57,8 @@ return call_user_func( '1' => [ 'showitem' => '--palette--;;sysLanguageAndHidden, job_id, zip, city, street,name, country, description, contact;;;richtext[*]:rte_transform[mode=ts], + --div--; LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:tca.seo_tab, + identifying_url, --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.access, starttime, endtime', ], ], @@ -232,8 +234,24 @@ return call_user_func( 'disabled' => FALSE, ] ], - ] - ] + ], + ], + 'identifying_url' => [ + 'exclude' => TRUE, + 'label' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.identifyingUrl', + 'config' => [ + 'type' => 'input', + 'renderType' => 'inputLink', + 'fieldControl' => [ + 'linkPopup' => [ + 'options' => [ + 'blindLinkFields' => 'class,target,title', + 'blindLinkOptions' => 'file,folder,mail,spec' + ], + ], + ], + ], + ], ], ]; }, 'sg_jobs', 'tx_sgjobs_domain_model_company' diff --git a/Configuration/TCA/tx_sgjobs_domain_model_job.php b/Configuration/TCA/tx_sgjobs_domain_model_job.php index ea83b58ab2f26ed531d2f431ade733128bf6b6b4..c568b372af4c81e3ba4e4405f16eeb3ab57aacc4 100644 --- a/Configuration/TCA/tx_sgjobs_domain_model_job.php +++ b/Configuration/TCA/tx_sgjobs_domain_model_job.php @@ -52,19 +52,24 @@ return call_user_func( ], 'interface' => [ 'showRecordFieldList' => 'sys_language_uid, l10n_parent, l10n_diffsource, hidden, pid, title, path_segment, job_id, department, hide_apply_by_email, hide_apply_by_postal, featured_offer, start_date, alternative_start_date, - company, task, qualification, description, contact', + company, task, qualification, description, contact, telecommute, employment_types, date_posted, valid_through, salary_currency, base_salary, max_salary, salary_unit,' ], 'types' => [ '1' => [ 'showitem' => '--palette--;;sysLanguageAndHidden, --palette--;;palette_title, - --palette--;;palette_title_start, - --palette--;;palette_apply_function, - department, - company, - contact, - description, - --div--; LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:tca.qualification_tab, task, qualification, - --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.access, starttime, endtime', + --palette--;;palette_title_start, + --palette--;;palette_apply_function, + department, + company, + contact, + description, + --div--; LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:tca.qualification_tab, task, qualification, + --div--; LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:tca.seo_tab, + --palette--;;palette_location_specifications, + employment_types, + --palette--;;palette_seo_dates, + --palette--;;palette_salary, + --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.access, starttime, endtime', ], ], 'palettes' => [ @@ -74,7 +79,13 @@ return call_user_func( ], 'palette_title' => ['showitem' => 'title, path_segment, job_id', 'canNotCollapse' => 1], 'palette_title_start' => ['showitem' => 'start_date, alternative_start_date', 'canNotCollapse' => 1], - 'palette_apply_function' => ['showitem' => 'hide_apply_by_email, hide_apply_by_postal, featured_offer', 'canNotCollapse' => 1] + 'palette_apply_function' => ['showitem' => 'hide_apply_by_email, hide_apply_by_postal, featured_offer', 'canNotCollapse' => 1], + 'palette_location_specifications' => ['showitem' => 'telecommute_possible, office_work_possible'], + 'palette_seo_dates' => ['showitem' => 'date_posted, valid_through'], + 'palette_salary' => [ + 'label' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:tca.salary_palette', + 'showitem' => 'salary_currency, --linebreak--, base_salary, max_salary, --linebreak--, salary_unit,' + ] ], 'columns' => [ 'sorting' => [ @@ -350,7 +361,106 @@ return call_user_func( ] ], ] - ] + ], + 'telecommute_possible' => [ + 'exclude' => TRUE, + 'l10n_mode' => 'exclude', + 'label' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.telecommutePossible', + 'config' => [ + 'type' => 'check', + ], + ], + 'office_work_possible' => [ + 'exclude' => TRUE, + 'l10n_mode' => 'exclude', + 'label' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.officeWorkPossible', + 'config' => [ + 'type' => 'check', + ], + ], + 'employment_types' => [ + 'exclude' => TRUE, + 'l10n_mode' => 'exclude', + 'label' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.employment_types', + 'config' => [ + 'type' => 'select', + 'renderType' => 'selectMultipleSideBySide', + 'items' => [ + ['LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.employment_types.full_time', 'FULL_TIME'], + ['LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.employment_types.part_time', 'PART_TIME'], + ['LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.employment_types.contractor', 'CONTRACTOR'], + ['LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.employment_types.temporary', 'TEMPORARY'], + ['LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.employment_types.intern', 'INTERN'], + ['LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.employment_types.volunteer', 'VOLUNTEER'], + ['LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.employment_types.per_diem', 'PER_DIEM'], + ['LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.employment_types.other', 'OTHER'] + ] + ] + ], + 'date_posted' => [ + 'exclude' => TRUE, + 'l10n_mode' => 'exclude', + 'label' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.date_posted', + 'config' => [ + 'type' => 'input', + 'renderType' => 'inputDateTime', + 'eval' => 'date' + ], + ], + 'valid_through' => [ + 'exclude' => TRUE, + 'l10n_mode' => 'exclude', + 'label' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.valid_through', + 'config' => [ + 'type' => 'input', + 'renderType' => 'inputDateTime', + 'eval' => 'date' + ], + ], + 'salary_currency' => [ + 'exclude' => TRUE, + 'label' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.salary_currency', + 'config' => [ + 'type' => 'input', + 'eval' => 'alpha, upper', + 'max' => 3, + 'default' => 'EUR', + ], + ], + 'salary_unit' => [ + 'exclude' => TRUE, + 'l10n_mode' => 'exclude', + 'label' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.salary_unit', + 'config' => [ + 'type' => 'select', + 'renderType' => 'selectSingle', + 'items' => [ + ['LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.salary_unit.hour', 'HOUR'], + ['LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.salary_unit.day', 'DAY'], + ['LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.salary_unit.week', 'WEEK'], + ['LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.salary_unit.month', 'MONTH'], + ['LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.salary_unit.year', 'YEAR'], + ] + ] + ], + 'base_salary' => [ + 'exclude' => TRUE, + 'label' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.base_salary', + 'config' => [ + 'type' => 'input', + 'eval' => 'double2', + 'max' => 15, + ], + ], + 'max_salary' => [ + 'exclude' => TRUE, + 'label' => 'LLL:EXT:' . $extKey . '/Resources/Private/Language/locallang_db.xlf:' . $table . '.max_salary', + 'config' => [ + 'type' => 'input', + 'eval' => 'double2', + 'max' => 15, + ], + ], ], ]; }, 'sg_jobs', 'tx_sgjobs_domain_model_job' diff --git a/Resources/Private/Language/de.locallang_db.xlf b/Resources/Private/Language/de.locallang_db.xlf index 45b8932ea68aeb8798013d4d4b0dd99b0d531837..7440d2f051bc66478635d427b1bdc724f6c07ff3 100644 --- a/Resources/Private/Language/de.locallang_db.xlf +++ b/Resources/Private/Language/de.locallang_db.xlf @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <xliff version="1.0"> - <file source-language="en" target-language="de" datatype="plaintext" original="messages" date="2019-08-06T13:19:35Z"> + <file source-language="en" target-language="de" datatype="plaintext" original="messages" date="2019-10-08T14:28:53Z"> <header> <type>database</type> <description>General language labels used in frontend and backend.</description> @@ -21,6 +21,14 @@ <source><![CDATA[Qualification & Tasks]]></source> <target><![CDATA[Qualifikation & Aufgaben]]></target> </trans-unit> + <trans-unit id="tca.salary_palette" approved="yes"> + <source><![CDATA[Salary Information. Used only if currency and base salary are set.]]></source> + <target><![CDATA[Gehaltsinformationen. Wird nur verwendet, wenn Währung und Grundgehalt festgelegt sind.]]></target> + </trans-unit> + <trans-unit id="tca.seo_tab" approved="yes"> + <source><![CDATA[SEO]]></source> + <target><![CDATA[SEO]]></target> + </trans-unit> <trans-unit id="tx_sgjobs.application_privacyPolicyPage" approved="yes"> <source><![CDATA[Privacy policy page]]></source> <target><![CDATA[Dateschutzinformationsseite]]></target> @@ -77,6 +85,10 @@ <source><![CDATA[Description]]></source> <target><![CDATA[Beschreibung]]></target> </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_company.identifyingUrl" approved="yes"> + <source><![CDATA[Link to this company's website. Should properly identify the company.]]></source> + <target><![CDATA[Link zur Website des Unternehmens. Sollte das Unternehmen eindeutig identifizieren.]]></target> + </trans-unit> <trans-unit id="tx_sgjobs_domain_model_company.job_id" approved="yes"> <source><![CDATA[Job ID]]></source> <target><![CDATA[Job ID]]></target> @@ -161,6 +173,10 @@ <source><![CDATA[Display apply by postal service section]]></source> <target><![CDATA[Bewerbung per Post einblenden]]></target> </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.base_salary" approved="yes"> + <source><![CDATA[Minimal/Base salary per pay period. Must be set greater than 0 for salary information to be embedded.]]></source> + <target><![CDATA[Minimal-/Basisgehalt pro Gehaltsperiode. Muss größer 0 gesetzt werden, damit Gehaltsinformationen hinterlegt werden.]]></target> + </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job.company" approved="yes"> <source><![CDATA[Company]]></source> <target><![CDATA[Unternehmen]]></target> @@ -169,6 +185,10 @@ <source><![CDATA[Contact]]></source> <target><![CDATA[Kontakt]]></target> </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.date_posted" approved="yes"> + <source><![CDATA[Date the job offer was posted]]></source> + <target><![CDATA[Datum der Veröffentlichung der Stellenanzeige]]></target> + </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job.department" approved="yes"> <source><![CDATA[Department]]></source> <target><![CDATA[Bereich]]></target> @@ -181,6 +201,42 @@ <source><![CDATA[Job description]]></source> <target><![CDATA[Beschreibung]]></target> </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.employment_types" approved="yes"> + <source><![CDATA[Employment Type(s)]]></source> + <target><![CDATA[Art(en) der Beschäftigung]]></target> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.employment_types.contractor" approved="yes"> + <source><![CDATA[Contractor]]></source> + <target><![CDATA[Auftragnehmer]]></target> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.employment_types.full_time" approved="yes"> + <source><![CDATA[Full time]]></source> + <target><![CDATA[Vollzeit]]></target> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.employment_types.intern" approved="yes"> + <source><![CDATA[Intern]]></source> + <target><![CDATA[Praktikant]]></target> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.employment_types.other" approved="yes"> + <source><![CDATA[Other]]></source> + <target><![CDATA[Andere]]></target> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.employment_types.part_time" approved="yes"> + <source><![CDATA[Part time]]></source> + <target><![CDATA[Teilzeit]]></target> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.employment_types.per_diem" approved="yes"> + <source><![CDATA[Per diem]]></source> + <target><![CDATA[Nach Bedarf]]></target> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.employment_types.temporary" approved="yes"> + <source><![CDATA[Temporary]]></source> + <target><![CDATA[Zeitarbeit]]></target> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.employment_types.volunteer" approved="yes"> + <source><![CDATA[Volunteer]]></source> + <target><![CDATA[Freiwillig]]></target> + </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job.featuredOffer" approved="yes"> <source><![CDATA[Featured Offer (will always show up in the job offer teaser)]]></source> <target><![CDATA[Diese Stellenausschreibung in jedem Job-Teaser anzeigen]]></target> @@ -205,10 +261,18 @@ <source><![CDATA[Location]]></source> <target><![CDATA[Arbeitsort]]></target> </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.max_salary" approved="yes"> + <source><![CDATA[Maximal salary per pay period. Set equal to base salary to embed a fixed value instead of a salary range.]]></source> + <target><![CDATA[Maximalgehalt pro Lohnperiode. Gleich dem Grundgehalt einstellen, um einen festen Wert anstelle einer Gehaltsspanne einzubetten.]]></target> + </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job.offers_page" approved="yes"> <source><![CDATA[Page that shows a list of all job offers in the frontend]]></source> <target><![CDATA[Seite auf der eine Liste aller Stellenanzeigen im Frontend angezeigt wird]]></target> </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.officeWorkPossible" approved="yes"> + <source><![CDATA[Job can be executed in the office of the specified company]]></source> + <target><![CDATA[Job kann im Büro der angegebenen Firma ausgeführt werden]]></target> + </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job.orderBy" approved="yes"> <source><![CDATA[Sorting of job offers]]></source> <target><![CDATA[Sortierung der Stellenangebote]]></target> @@ -225,6 +289,10 @@ <source><![CDATA[By creation date (latest at top)]]></source> <target><![CDATA[Nach Erstellungsdatum (neueste zuerst)]]></target> </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.path_segment" approved="yes"> + <source><![CDATA[Path Segment]]></source> + <target><![CDATA[URL-Pfad]]></target> + </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job.plugin_options" approved="yes"> <source><![CDATA[Joblist plugin options]]></source> <target><![CDATA[Joblist Plugin-Optionen]]></target> @@ -233,6 +301,34 @@ <source><![CDATA[Qualification]]></source> <target><![CDATA[Qualifikation]]></target> </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.salary_currency" approved="yes"> + <source><![CDATA[Currency code according to ISO 4217, consisting of three capital letters.]]></source> + <target><![CDATA[Währungscode nach ISO 4217, bestehend aus drei Großbuchstaben.]]></target> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.salary_unit" approved="yes"> + <source><![CDATA[Salary period]]></source> + <target><![CDATA[Gehaltsperiode]]></target> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.salary_unit.day" approved="yes"> + <source><![CDATA[Day]]></source> + <target><![CDATA[Tag]]></target> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.salary_unit.hour" approved="yes"> + <source><![CDATA[Hour]]></source> + <target><![CDATA[Stunde]]></target> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.salary_unit.month" approved="yes"> + <source><![CDATA[Month]]></source> + <target><![CDATA[Monat]]></target> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.salary_unit.week" approved="yes"> + <source><![CDATA[Week]]></source> + <target><![CDATA[Woche]]></target> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.salary_unit.year" approved="yes"> + <source><![CDATA[Year]]></source> + <target><![CDATA[Jahr]]></target> + </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job.start_date" approved="yes"> <source><![CDATA[Start date]]></source> <target><![CDATA[Einstiegsdatum]]></target> @@ -257,13 +353,17 @@ <source><![CDATA[In the frontend all job offers are listed, in which the corresponding check mark is set and additionally all, which are assigned to the locations selected here.]]></source> <target><![CDATA[Im Frontend werden alle Stellenangebote gelistet, in denen der entsprechende Haken gesetzt ist und zusätzlich alle, die den hier ausgewählten Standorten zugeordnet sind.]]></target> </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.telecommutePossible" approved="yes"> + <source><![CDATA[Job can be executed fully remotely (teleworking)]]></source> + <target><![CDATA[Job kann vollständig remote ausgeführt werden (Telearbeit)]]></target> + </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job.title" approved="yes"> <source><![CDATA[Job title]]></source> <target><![CDATA[Stellenbezeichnung]]></target> </trans-unit> - <trans-unit id="tx_sgjobs_domain_model_job.path_segment"> - <source><![CDATA[Path Segment]]></source> - <target><![CDATA[URL-Pfad]]></target> + <trans-unit id="tx_sgjobs_domain_model_job.valid_through" approved="yes"> + <source><![CDATA[Application Deadline]]></source> + <target><![CDATA[Bewerbungsschluss]]></target> </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job_application" approved="yes"> <source><![CDATA[Job application]]></source> diff --git a/Resources/Private/Language/locallang_db.xlf b/Resources/Private/Language/locallang_db.xlf index da6e419a141674537fe139441aa461644c38565b..417f391c433d977c18dd983148158efe543bbffc 100644 --- a/Resources/Private/Language/locallang_db.xlf +++ b/Resources/Private/Language/locallang_db.xlf @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <xliff version="1.0"> - <file source-language="en" datatype="plaintext" original="messages" date="2019-08-06T13:19:35Z"> + <file source-language="en" datatype="plaintext" original="messages" date="2019-10-08T14:28:53Z"> <header> <type>database</type> <description>General language labels used in frontend and backend.</description> @@ -18,6 +18,12 @@ <trans-unit id="tca.qualification_tab"> <source><![CDATA[Qualification & Tasks]]></source> </trans-unit> + <trans-unit id="tca.salary_palette"> + <source><![CDATA[Salary Information. Used only if currency and base salary are set.]]></source> + </trans-unit> + <trans-unit id="tca.seo_tab"> + <source><![CDATA[SEO]]></source> + </trans-unit> <trans-unit id="tx_sgjobs.application_privacyPolicyPage"> <source><![CDATA[Privacy policy page]]></source> </trans-unit> @@ -60,6 +66,9 @@ <trans-unit id="tx_sgjobs_domain_model_company.description"> <source><![CDATA[Description]]></source> </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_company.identifyingUrl"> + <source><![CDATA[Link to this company's website. Should properly identify the company.]]></source> + </trans-unit> <trans-unit id="tx_sgjobs_domain_model_company.job_id"> <source><![CDATA[Job ID]]></source> </trans-unit> @@ -126,12 +135,18 @@ <trans-unit id="tx_sgjobs_domain_model_job.applyByPostal"> <source><![CDATA[Display apply by postal service section]]></source> </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.base_salary"> + <source><![CDATA[Minimal/Base salary per pay period. Must be set greater than 0 for salary information to be embedded.]]></source> + </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job.company"> <source><![CDATA[Company]]></source> </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job.contact"> <source><![CDATA[Contact]]></source> </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.date_posted"> + <source><![CDATA[Date the job offer was posted]]></source> + </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job.department"> <source><![CDATA[Department]]></source> </trans-unit> @@ -141,6 +156,33 @@ <trans-unit id="tx_sgjobs_domain_model_job.description"> <source><![CDATA[Job description]]></source> </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.employment_types"> + <source><![CDATA[Employment Type(s)]]></source> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.employment_types.contractor"> + <source><![CDATA[Contractor]]></source> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.employment_types.full_time"> + <source><![CDATA[Full time]]></source> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.employment_types.intern"> + <source><![CDATA[Intern]]></source> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.employment_types.other"> + <source><![CDATA[Other]]></source> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.employment_types.part_time"> + <source><![CDATA[Part time]]></source> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.employment_types.per_diem"> + <source><![CDATA[Per diem]]></source> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.employment_types.temporary"> + <source><![CDATA[Temporary]]></source> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.employment_types.volunteer"> + <source><![CDATA[Volunteer]]></source> + </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job.featuredOffer"> <source><![CDATA[Featured Offer (will always show up in the job offer teaser)]]></source> </trans-unit> @@ -159,9 +201,15 @@ <trans-unit id="tx_sgjobs_domain_model_job.location"> <source><![CDATA[Location]]></source> </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.max_salary"> + <source><![CDATA[Maximal salary per pay period. Set equal to base salary to embed a fixed value instead of a salary range.]]></source> + </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job.offers_page"> <source><![CDATA[Page that shows a list of all job offers in the frontend]]></source> </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.officeWorkPossible"> + <source><![CDATA[Job can be executed in the office of the specified company]]></source> + </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job.orderBy"> <source><![CDATA[Sorting of job offers]]></source> </trans-unit> @@ -174,12 +222,36 @@ <trans-unit id="tx_sgjobs_domain_model_job.orderBy_3"> <source><![CDATA[By creation date (latest at top)]]></source> </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.path_segment"> + <source><![CDATA[Path Segment]]></source> + </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job.plugin_options"> <source><![CDATA[Joblist plugin options]]></source> </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job.qualification"> <source><![CDATA[Qualification]]></source> </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.salary_currency"> + <source><![CDATA[Currency code according to ISO 4217, consisting of three capital letters.]]></source> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.salary_unit"> + <source><![CDATA[Salary period]]></source> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.salary_unit.day"> + <source><![CDATA[Day]]></source> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.salary_unit.hour"> + <source><![CDATA[Hour]]></source> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.salary_unit.month"> + <source><![CDATA[Month]]></source> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.salary_unit.week"> + <source><![CDATA[Week]]></source> + </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.salary_unit.year"> + <source><![CDATA[Year]]></source> + </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job.start_date"> <source><![CDATA[Start date]]></source> </trans-unit> @@ -198,11 +270,14 @@ <trans-unit id="tx_sgjobs_domain_model_job.teaser_locations.description"> <source><![CDATA[In the frontend all job offers are listed, in which the corresponding check mark is set and additionally all, which are assigned to the locations selected here.]]></source> </trans-unit> + <trans-unit id="tx_sgjobs_domain_model_job.telecommutePossible"> + <source><![CDATA[Job can be executed fully remotely (teleworking)]]></source> + </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job.title"> <source><![CDATA[Job title]]></source> </trans-unit> - <trans-unit id="tx_sgjobs_domain_model_job.path_segment"> - <source><![CDATA[Path Segment]]></source> + <trans-unit id="tx_sgjobs_domain_model_job.valid_through"> + <source><![CDATA[Application Deadline]]></source> </trans-unit> <trans-unit id="tx_sgjobs_domain_model_job_application"> <source><![CDATA[Job application]]></source> diff --git a/Resources/Private/Partials/ApplyFormSchema.html b/Resources/Private/Partials/ApplyFormSchema.html index 706514efe206d32c183cd6af751a5356d804f8d1..14e7812ad70620d25209e6aa79f65c84458eac61 100644 --- a/Resources/Private/Partials/ApplyFormSchema.html +++ b/Resources/Private/Partials/ApplyFormSchema.html @@ -7,24 +7,64 @@ "@type": "JobPosting", "title": "{job.title}", "description": "<f:format.htmlentities>{job.description}{job.task}{job.qualification}</f:format.htmlentities>", - "identifier": "<f:uri.page pageUid="{job.pid}" absolute="TRUE"/>", - "datePosted": "{sg:date(timestamp:'{job.crdate.timestamp}', format:'%Y-%m-%d')}", + "employmentType": [ + <f:for each="{h:explodeString(string: '{job.employmentTypes}', delimiter: ',')}" as="employmentType" iteration="iterator"> + "{employmentType}"{f:if(condition: '{iterator.isLast} == FALSE', then: ',')} + </f:for> + ], + + "datePosted": "{f:format.date(date: '{f:if(condition: job.datePosted, then: job.datePosted, else: \'now\')}', format: 'Y-m-d')}", + <f:if condition="{job.validThrough}"> + "validThrough": "{f:format.date(date: job.validThrough, format: 'Y-m-d')}", + </f:if> + + <f:if condition="{job.salaryCurrency} && {job.baseSalary} > 0"> + "baseSalary": {leftBrace} + "@type": "MonetaryAmount", + "currency": "{job.salaryCurrency}", + "value": {leftBrace} + "@type": "QuantitativeValue", + <f:if condition="{job.baseSalary} === {job.maxSalary}"> + <f:then> + "value": {job.baseSalary}, + </f:then> + <f:else> + "minValue": {job.baseSalary}, + "maxValue": {job.maxSalary}, + </f:else> + </f:if> + "unitText": "{job.salaryUnit}" + {rightBrace} + {rightBrace}, + </f:if> + + <f:if condition="{job.telecommutePossible}"> + "jobLocationType": "TELECOMMUTE", + </f:if> + <f:if condition="{job.officeWorkPossible}"> + "jobLocation": {leftBrace} + "@type": "Place", + "address": {leftBrace} + "@type": "PostalAddress", + "streetAddress": "{job.company.street -> f:format.htmlentities()}", + "addressLocality": "{job.company.city -> f:format.htmlentities()}", + "postalCode": "{job.company.zip}", + "addressCountry": "{job.company.country -> f:format.htmlentities()}" + {rightBrace} + {rightBrace}, + </f:if> + + <f:comment><!-- + We need a property that is certainly included to make sure the last property never ends with a comma. + --></f:comment> "hiringOrganization": {leftBrace} "@type": "Organization", "name": "{job.company.name}", - "sameAs": "<f:uri.page pageUid="1" absolute="TRUE"/>", - "logo": "<f:uri.image src="EXT:project_theme/Resources/Public/Images/logo-inverted.svg" absolute="TRUE"/>" - {rightBrace}, - - "jobLocation": {leftBrace} - "@type": "Place", - "address": {leftBrace} - "@type": "PostalAddress", - "streetAddress": "{job.company.street}", - "addressLocality": "{job.company.city}", - "postalCode": "{job.company.zip}", - "addressCountry": "{job.company.country}" + "sameAs": "{f:uri.typolink(parameter: job.company.identifyingUrl, absolute: 'TRUE')}", + "department": {leftBrace} + "@type": "Organization", + "name": "{job.department.title}" {rightBrace} {rightBrace} {rightBrace} diff --git a/Resources/Private/Partials/JoblistListSchema.html b/Resources/Private/Partials/JoblistListSchema.html new file mode 100644 index 0000000000000000000000000000000000000000..6fe348c4dd52251e93d66113069efa677fb9a4b7 --- /dev/null +++ b/Resources/Private/Partials/JoblistListSchema.html @@ -0,0 +1,18 @@ +<f:alias map="{leftBrace: '{', rightBrace: '}'}"> + <script type="application/ld+json"> + {leftBrace} + "@context": "http://schema.org/", + "@type": "ItemList", + "itemListElement": [ + <f:for each="{jobs}" as="job" iteration="iterator"> + {leftBrace} + "@type": "ListItem", + "position": "{iterator.cycle}", + "url": "<f:uri.action pageUid="{settings.applyPage}" controller="Joblist" action="applyForm" arguments="{jobId: job.uid}" absolute="TRUE"/>" + {rightBrace}<f:if condition="{iterator.isLast} == FALSE">,</f:if> + </f:for> + ], + "numberOfItems": "{jobs->f:count()}" + {rightBrace} + </script> +</f:alias> diff --git a/Resources/Private/Templates/Joblist/Index.html b/Resources/Private/Templates/Joblist/Index.html index d63396517a6bf1d03846fb15ce7ccead0a6a6f83..fe82c6d7fbed2a8f5e9397ed70055ce4da684791 100644 --- a/Resources/Private/Templates/Joblist/Index.html +++ b/Resources/Private/Templates/Joblist/Index.html @@ -1,24 +1,7 @@ {namespace sg=SGalinski\SgJobs\ViewHelpers} <f:layout name="Default" /> <f:section name="main"> - <f:alias map="{leftBrace: '{', rightBrace: '}'}"> - <script type="application/ld+json"> - {leftBrace} - "@context": "http://schema.org/", - "@type": "ItemList", - "itemListElement": [ - <f:for each="{jobs}" as="job" iteration="iterator"> - {leftBrace} - "@type": "ListItem", - "position": "{iterator.cycle}", - "url": "<f:uri.action pageUid="{settings.applyPage}" controller="Joblist" action="applyForm" arguments="{jobId: job.uid}" absolute="TRUE"/>" - {rightBrace}<f:if condition="{iterator.isLast} == FALSE">,</f:if> - </f:for> - ], - "numberOfItems": "{jobs->f:count()}" - {rightBrace} - </script> - </f:alias> + <f:render partial="JoblistListSchema" arguments="{_all}" /> <div id="sgjobs-joblist"> <f:render diff --git a/ext_tables.sql b/ext_tables.sql index f6d4e3e94c65e1a4ab6b89cc96a1d1b2dfe04b8d..5dad26c16474f8ada59cc50954da3f815b319433 100644 --- a/ext_tables.sql +++ b/ext_tables.sql @@ -11,6 +11,15 @@ CREATE TABLE tx_sgjobs_domain_model_job ( alternative_start_date text DEFAULT '' NOT NULL, start_date int(11) unsigned DEFAULT '0' NOT NULL, company text DEFAULT '' NOT NULL, + telecommute_possible tinyint(4) unsigned DEFAULT '0' NOT NULL, + office_work_possible tinyint(4) unsigned DEFAULT '1' NOT NULL, + employment_types text DEFAULT '' NOT NULL, + date_posted int(11) unsigned DEFAULT '0' NOT NULL, + valid_through int(11) unsigned DEFAULT '0' NOT NULL, + salary_currency varchar(3) DEFAULT 'EUR' NOT NULL, + base_salary varchar(15) DEFAULT '' NOT NULL, + max_salary varchar(15) DEFAULT '' NOT NULL, + salary_unit varchar(5) DEFAULT '' NOT NULL, description text DEFAULT '' NOT NULL, department int(11) DEFAULT '0' NOT NULL, contact int(11) unsigned DEFAULT '0' NOT NULL, @@ -105,6 +114,7 @@ CREATE TABLE tx_sgjobs_domain_model_company ( description text DEFAULT '' NOT NULL, contact int(11) unsigned DEFAULT '0' NOT NULL, job_id text DEFAULT '' NOT NULL, + identifying_url varchar(255) DEFAULT '' NOT NULL, -- TYPO3 fields sorting int(11) unsigned DEFAULT '0' NOT NULL,