... | ... |
@@ -0,0 +1,57 @@ |
1 |
+{% extends '@Contao/block_unsearchable' %} |
|
2 |
+ |
|
3 |
+{% block content %} |
|
4 |
+ {% if jobs is not defined %} |
|
5 |
+ <p>Es wurden keine Stellenangebote gefunden!</p> |
|
6 |
+ {% else %} |
|
7 |
+ <form class="filter" method="get"> |
|
8 |
+ <div class="formbody"> |
|
9 |
+ <input type="hidden" name="FORM_SUBMIT" value="{{ formSubmit }}"> |
|
10 |
+ <div class="widget widget-text"> |
|
11 |
+ <input type="text" name="filter_keywords" placeholder="Jobtitel" value="{{ formSetFilters.filter_keywords ?? '' }}"> |
|
12 |
+ </div> |
|
13 |
+ {% if filterVertragsarten is defined %} |
|
14 |
+ <div class="widget widget-select"> |
|
15 |
+ <select name="filter_vertragsart"> |
|
16 |
+ <option value="">Art der Anstellung</option> |
|
17 |
+ {% for vertragsart in filterVertragsarten %} |
|
18 |
+ <option value="{{ vertragsart.ObjectUuid }}"{% if formSetFilters.filter_vertragsart is defined and formSetFilters.filter_vertragsart == vertragsart.ObjectUuid %} selected{% endif %}>{{ vertragsart.Bezeichnung }}</option> |
|
19 |
+ {% endfor %} |
|
20 |
+ </select> |
|
21 |
+ </div> |
|
22 |
+ {% endif %} |
|
23 |
+ {% if filterAbteilung is defined %} |
|
24 |
+ <div class="widget widget-select"> |
|
25 |
+ <select name="filter_abteilung"> |
|
26 |
+ <option value="">Unternehmensbereich / Abteilung</option> |
|
27 |
+ {% for abteilung in filterAbteilung %} |
|
28 |
+ <option value="{{ abteilung.ObjectUuid }}"{% if formSetFilters.filter_abteilung is defined and formSetFilters.filter_abteilung == abteilung.ObjectUuid %} selected{% endif %}>{{ abteilung.Bezeichnung }}</option> |
|
29 |
+ {% endfor %} |
|
30 |
+ </select> |
|
31 |
+ </div> |
|
32 |
+ {% endif %} |
|
33 |
+ <div class="widget widget-submit"> |
|
34 |
+ <button type="submit">Suchen</button> |
|
35 |
+ </div> |
|
36 |
+ </div> |
|
37 |
+ </form> |
|
38 |
+ |
|
39 |
+ <div class="jobs"> |
|
40 |
+ <ul> |
|
41 |
+ {% for job in jobs %} |
|
42 |
+ <li> |
|
43 |
+ <h3>{{ job.Bezeichnung }}</h3> |
|
44 |
+ <div class="meta"> |
|
45 |
+ <dl> |
|
46 |
+ <dt>Einsatzort:</dt><dd>{{ job.EinsatzortPlz }} {{ job.EinsatzortOrt }}</dd> |
|
47 |
+ <dt>Vertragsart:</dt><dd>{{ job.Vertragsarten }}</dd> |
|
48 |
+ <dt>Beginn:</dt><dd>{{ job.BeginnAbSofort ? 'ab sofort' : (job.Beginn ? job.Beginn|date("d.m.Y") : '') }}</dd> |
|
49 |
+ <dt>Eintrag vom:</dt><dd>{{ job.DatumAb ? job.DatumAb|date("d.m.Y") : '' }}</dd> |
|
50 |
+ </dl> |
|
51 |
+ </div> |
|
52 |
+ </li> |
|
53 |
+ {% endfor %} |
|
54 |
+ </ul> |
|
55 |
+ </div> |
|
56 |
+ {% endif %} |
|
57 |
+{% endblock %} |
0 | 58 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,127 @@ |
1 |
+<?php |
|
2 |
+ |
|
3 |
+declare(strict_types=1); |
|
4 |
+ |
|
5 |
+/* |
|
6 |
+ * This file is part of alox bundle for Contao. |
|
7 |
+ * |
|
8 |
+ * (c) Benjamin Roth |
|
9 |
+ * |
|
10 |
+ * @license commercial |
|
11 |
+ */ |
|
12 |
+ |
|
13 |
+namespace vossmedien\AloxBundle\API; |
|
14 |
+ |
|
15 |
+use Contao\System; |
|
16 |
+use Symfony\Component\Serializer\SerializerInterface; |
|
17 |
+use Symfony\Contracts\HttpClient\HttpClientInterface; |
|
18 |
+use vossmedien\AloxBundle\Model\KatalogModel; |
|
19 |
+use vossmedien\AloxBundle\Model\StellenModel; |
|
20 |
+ |
|
21 |
+class Zvoove |
|
22 |
+{ |
|
23 |
+ /** |
|
24 |
+ * @var SerializerInterface |
|
25 |
+ */ |
|
26 |
+ protected $serializer; |
|
27 |
+ |
|
28 |
+ /** |
|
29 |
+ * @var HttpClientInterface |
|
30 |
+ */ |
|
31 |
+ protected $httpClient; |
|
32 |
+ |
|
33 |
+ protected $apiKey; |
|
34 |
+ |
|
35 |
+ protected $apiDomain; |
|
36 |
+ |
|
37 |
+ public function __construct(SerializerInterface $serializer, HttpClientInterface $httpClient) |
|
38 |
+ { |
|
39 |
+ $this->serializer = $serializer; |
|
40 |
+ $this->httpClient = $httpClient; |
|
41 |
+ |
|
42 |
+ $this->apiKey = System::getContainer()->getParameter('vossmedien_alox.zvoove.api_key'); |
|
43 |
+ $this->apiDomain = System::getContainer()->getParameter('vossmedien_alox.zvoove.api_domain'); |
|
44 |
+ } |
|
45 |
+ |
|
46 |
+ protected function getApiKey() |
|
47 |
+ { |
|
48 |
+ return $this->apiKey; |
|
49 |
+ } |
|
50 |
+ |
|
51 |
+ protected function getApiDomain() |
|
52 |
+ { |
|
53 |
+ return rtrim($this->apiDomain,'/'); |
|
54 |
+ } |
|
55 |
+ |
|
56 |
+ protected function getAuthorizeRequestHeader() |
|
57 |
+ { |
|
58 |
+ $header = [ |
|
59 |
+ 'X-ApiKey' => $this->getApiKey() |
|
60 |
+ ]; |
|
61 |
+ |
|
62 |
+ return $header; |
|
63 |
+ } |
|
64 |
+ |
|
65 |
+ protected function sendRequest(string $relEndpoint, array $options, string $method = 'GET') |
|
66 |
+ { |
|
67 |
+ $relEndpoint = '/' . ltrim($relEndpoint,'/'); |
|
68 |
+ |
|
69 |
+ return $this->httpClient->request($method,$this->getApiDomain().$relEndpoint,$options); |
|
70 |
+ } |
|
71 |
+ |
|
72 |
+ public function getStellenFiltered(array $params=[]): ?StellenModel |
|
73 |
+ { |
|
74 |
+ $options = [ |
|
75 |
+ 'headers' => $this->getAuthorizeRequestHeader() |
|
76 |
+ ]; |
|
77 |
+ |
|
78 |
+ if (count($params)) |
|
79 |
+ { |
|
80 |
+ $options['query'] = $params; |
|
81 |
+ } |
|
82 |
+ |
|
83 |
+ $response = $this->sendRequest('Stelle/GetStellenFiltered',$options); |
|
84 |
+ |
|
85 |
+ |
|
86 |
+ |
|
87 |
+ if ($response->getStatusCode() == 200) |
|
88 |
+ { |
|
89 |
+ $content = $response->getContent(); |
|
90 |
+ |
|
91 |
+ /** @var StellenModel $collection */ |
|
92 |
+ $collection = $this->serializer->deserialize($content,StellenModel::class,'json'); |
|
93 |
+ |
|
94 |
+ return $collection; |
|
95 |
+ } |
|
96 |
+ |
|
97 |
+ return null; |
|
98 |
+ } |
|
99 |
+ |
|
100 |
+ public function getKatalogByRelationName(string $entityName, string $relationName): ?KatalogModel |
|
101 |
+ { |
|
102 |
+ $options = [ |
|
103 |
+ 'headers' => $this->getAuthorizeRequestHeader(), |
|
104 |
+ 'query' => [ |
|
105 |
+ 'entityName' => $entityName, |
|
106 |
+ 'relationName' => $relationName |
|
107 |
+ ] |
|
108 |
+ ]; |
|
109 |
+ |
|
110 |
+ $response = $this->sendRequest('Katalog/GetByRelationName',$options); |
|
111 |
+ |
|
112 |
+ |
|
113 |
+ |
|
114 |
+ if ($response->getStatusCode() == 200) |
|
115 |
+ { |
|
116 |
+ $content = $response->getContent(); |
|
117 |
+ |
|
118 |
+ /** @var KatalogModel $collection */ |
|
119 |
+ $collection = $this->serializer->deserialize($content,KatalogModel::class,'json'); |
|
120 |
+ |
|
121 |
+ return $collection; |
|
122 |
+ } |
|
123 |
+ |
|
124 |
+ return null; |
|
125 |
+ } |
|
126 |
+ |
|
127 |
+} |
... | ... |
@@ -14,12 +14,12 @@ namespace vossmedien\AloxBundle\Controller\Frontend\Module; |
14 | 14 |
|
15 | 15 |
use Contao\CoreBundle\Controller\FrontendModule\AbstractFrontendModuleController; |
16 | 16 |
use Contao\CoreBundle\ServiceAnnotation\FrontendModule; |
17 |
+use Contao\Input; |
|
17 | 18 |
use Contao\ModuleModel; |
18 |
-use Contao\System; |
|
19 | 19 |
use Contao\Template; |
20 |
-use Symfony\Component\HttpClient\HttpClient; |
|
21 | 20 |
use Symfony\Component\HttpFoundation\Request; |
22 | 21 |
use Symfony\Component\HttpFoundation\Response; |
22 |
+use vossmedien\AloxBundle\API\Zvoove; |
|
23 | 23 |
|
24 | 24 |
/** |
25 | 25 |
* @FrontendModule(JoblistModuleController::TYPE, category="miscellaneous") |
... | ... |
@@ -28,24 +28,75 @@ class JoblistModuleController extends AbstractFrontendModuleController |
28 | 28 |
{ |
29 | 29 |
public const TYPE = 'alox_joblist'; |
30 | 30 |
|
31 |
+ /** |
|
32 |
+ * @var Zvoove |
|
33 |
+ */ |
|
34 |
+ protected $api; |
|
35 |
+ |
|
36 |
+ public function __construct(Zvoove $api) |
|
37 |
+ { |
|
38 |
+ $this->api = $api; |
|
39 |
+ } |
|
40 |
+ |
|
41 |
+ |
|
31 | 42 |
protected function getResponse(Template $template, ModuleModel $model, Request $request): ?Response |
32 | 43 |
{ |
33 |
- $apiKey = System::getContainer()->getParameter('vossmedien_alox.zvoove.api_key'); |
|
34 |
- $apiDomain = System::getContainer()->getParameter('vossmedien_alox.zvoove.api_domain'); |
|
44 |
+ $strFormId = 'joblist-form-' . $model->id; |
|
45 |
+ $arrSearchParams = []; |
|
46 |
+ $arrSetFilters = []; |
|
47 |
+ |
|
48 |
+ // Prepare search parameters |
|
49 |
+ if (Input::get('FORM_SUBMIT') == $strFormId) |
|
50 |
+ { |
|
51 |
+ if (Input::get('filter_keywords')) |
|
52 |
+ { |
|
53 |
+ $arrSearchParams['keywords'] = Input::get('filter_keywords'); |
|
54 |
+ $arrSetFilters['filter_keywords'] = Input::get('filter_keywords'); |
|
55 |
+ } |
|
56 |
+ |
|
57 |
+ if (Input::get('filter_vertragsart')) |
|
58 |
+ { |
|
59 |
+ $arrSearchParams['vaUuids'] = Input::get('filter_vertragsart'); |
|
60 |
+ $arrSetFilters['filter_vertragsart'] = Input::get('filter_vertragsart'); |
|
61 |
+ } |
|
62 |
+ |
|
63 |
+ if (Input::get('filter_abteilung')) |
|
64 |
+ { |
|
65 |
+ $arrSearchParams['abtUuids'] = Input::get('filter_abteilung'); |
|
66 |
+ $arrSetFilters['filter_abteilung'] = Input::get('filter_abteilung'); |
|
67 |
+ } |
|
68 |
+ } |
|
69 |
+ |
|
70 |
+ // Get (filtered) jobs |
|
71 |
+ $jobs = $this->api->getStellenFiltered($arrSearchParams); |
|
72 |
+ |
|
73 |
+ |
|
74 |
+ // Get filter options |
|
75 |
+ $filterVertragsarten = $this->api->getKatalogByRelationName('StelleVertragsart','ChildEntity'); |
|
76 |
+ $filterAbteilung = $this->api->getKatalogByRelationName('StelleAbteilung','Abteilung'); |
|
77 |
+ |
|
78 |
+ |
|
79 |
+ // Populate template vars |
|
80 |
+ if ($jobs !== null && $jobs->TotalItems > 0) |
|
81 |
+ { |
|
82 |
+ $template->jobs = $jobs; |
|
83 |
+ } |
|
35 | 84 |
|
36 |
- $httpClient = HttpClient::create(); |
|
85 |
+ if ($filterVertragsarten !== null && $filterVertragsarten->TotalItems > 0) |
|
86 |
+ { |
|
87 |
+ $template->filterVertragsarten = $filterVertragsarten; |
|
88 |
+ } |
|
37 | 89 |
|
38 |
- $header = [ |
|
39 |
- 'headers' => [ |
|
40 |
- 'X-ApiKey' => $apiKey |
|
41 |
- ] |
|
42 |
- ]; |
|
90 |
+ if ($filterAbteilung !== null && $filterAbteilung->TotalItems > 0) |
|
91 |
+ { |
|
92 |
+ $template->filterAbteilung = $filterAbteilung; |
|
93 |
+ } |
|
43 | 94 |
|
44 |
- $response = $httpClient->request('GET',$apiDomain, $header); |
|
95 |
+ $template->formSubmit = $strFormId; |
|
96 |
+ $template->formSetFilters = $arrSetFilters; |
|
45 | 97 |
|
46 |
- dump($response->getContent()); |
|
47 | 98 |
|
48 |
- return new Response(); |
|
99 |
+ return $template->getResponse(); |
|
49 | 100 |
} |
50 | 101 |
|
51 | 102 |
} |
52 | 103 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,85 @@ |
1 |
+<?php |
|
2 |
+ |
|
3 |
+declare(strict_types=1); |
|
4 |
+ |
|
5 |
+/* |
|
6 |
+ * This file is part of alox bundle for Contao. |
|
7 |
+ * |
|
8 |
+ * (c) Benjamin Roth |
|
9 |
+ * |
|
10 |
+ * @license commercial |
|
11 |
+ */ |
|
12 |
+ |
|
13 |
+namespace vossmedien\AloxBundle\Model; |
|
14 |
+ |
|
15 |
+class KatalogModel implements \ArrayAccess, \Countable, \IteratorAggregate |
|
16 |
+{ |
|
17 |
+ /** |
|
18 |
+ * @var int |
|
19 |
+ */ |
|
20 |
+ private int $TotalItems; |
|
21 |
+ |
|
22 |
+ /** |
|
23 |
+ * @var array |
|
24 |
+ */ |
|
25 |
+ private array $Items; |
|
26 |
+ |
|
27 |
+ public function __get($name) |
|
28 |
+ { |
|
29 |
+ if (isset($this->{$name}) && method_exists($this,'get'.$name)) |
|
30 |
+ { |
|
31 |
+ return $this->{'get'.$name}(); |
|
32 |
+ } |
|
33 |
+ } |
|
34 |
+ |
|
35 |
+ |
|
36 |
+ public function getItems(): array |
|
37 |
+ { |
|
38 |
+ return $this->Items; |
|
39 |
+ } |
|
40 |
+ |
|
41 |
+ public function getTotalItems(): int |
|
42 |
+ { |
|
43 |
+ return $this->TotalItems; |
|
44 |
+ } |
|
45 |
+ |
|
46 |
+ public function setItems(array $items): void |
|
47 |
+ { |
|
48 |
+ $this->Items = $items; |
|
49 |
+ } |
|
50 |
+ |
|
51 |
+ public function setTotalItems(int $total): void |
|
52 |
+ { |
|
53 |
+ $this->TotalItems = $total; |
|
54 |
+ } |
|
55 |
+ |
|
56 |
+ public function getIterator() |
|
57 |
+ { |
|
58 |
+ return new \ArrayIterator($this->Items); |
|
59 |
+ } |
|
60 |
+ |
|
61 |
+ public function offsetExists($offset) |
|
62 |
+ { |
|
63 |
+ return isset($this->Items[$offset]); |
|
64 |
+ } |
|
65 |
+ |
|
66 |
+ public function offsetGet($offset) |
|
67 |
+ { |
|
68 |
+ return $this->Items[$offset]; |
|
69 |
+ } |
|
70 |
+ |
|
71 |
+ public function offsetSet($offset, $value) |
|
72 |
+ { |
|
73 |
+ throw new \RuntimeException('This collection is immutable'); |
|
74 |
+ } |
|
75 |
+ |
|
76 |
+ public function offsetUnset($offset) |
|
77 |
+ { |
|
78 |
+ throw new \RuntimeException('This collection is immutable'); |
|
79 |
+ } |
|
80 |
+ |
|
81 |
+ public function count() |
|
82 |
+ { |
|
83 |
+ return \count($this->Items); |
|
84 |
+ } |
|
85 |
+} |
0 | 86 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,102 @@ |
1 |
+<?php |
|
2 |
+ |
|
3 |
+declare(strict_types=1); |
|
4 |
+ |
|
5 |
+/* |
|
6 |
+ * This file is part of alox bundle for Contao. |
|
7 |
+ * |
|
8 |
+ * (c) Benjamin Roth |
|
9 |
+ * |
|
10 |
+ * @license commercial |
|
11 |
+ */ |
|
12 |
+ |
|
13 |
+namespace vossmedien\AloxBundle\Model; |
|
14 |
+ |
|
15 |
+use \DateTime; |
|
16 |
+ |
|
17 |
+class StellenModel implements \ArrayAccess, \Countable, \IteratorAggregate |
|
18 |
+{ |
|
19 |
+ /** |
|
20 |
+ * @var int |
|
21 |
+ */ |
|
22 |
+ private int $TotalItems; |
|
23 |
+ |
|
24 |
+ /** |
|
25 |
+ * @var DateTime |
|
26 |
+ */ |
|
27 |
+ private DateTime $LastUpdateTime; |
|
28 |
+ |
|
29 |
+ /** |
|
30 |
+ * @var array |
|
31 |
+ */ |
|
32 |
+ private array $Items; |
|
33 |
+ |
|
34 |
+ public function __get($name) |
|
35 |
+ { |
|
36 |
+ if (isset($this->{$name}) && method_exists($this,'get'.$name)) |
|
37 |
+ { |
|
38 |
+ return $this->{'get'.$name}(); |
|
39 |
+ } |
|
40 |
+ } |
|
41 |
+ |
|
42 |
+ |
|
43 |
+ public function getItems(): array |
|
44 |
+ { |
|
45 |
+ return $this->Items; |
|
46 |
+ } |
|
47 |
+ |
|
48 |
+ public function getLastUpdateTime(): DateTime |
|
49 |
+ { |
|
50 |
+ return $this->LastUpdateTime; |
|
51 |
+ } |
|
52 |
+ |
|
53 |
+ public function getTotalItems(): int |
|
54 |
+ { |
|
55 |
+ return $this->TotalItems; |
|
56 |
+ } |
|
57 |
+ |
|
58 |
+ public function setItems(array $items): void |
|
59 |
+ { |
|
60 |
+ $this->Items = $items; |
|
61 |
+ } |
|
62 |
+ |
|
63 |
+ public function setLastUpdateTime(string $updateTime): void |
|
64 |
+ { |
|
65 |
+ $this->LastUpdateTime = new DateTime($updateTime); |
|
66 |
+ } |
|
67 |
+ |
|
68 |
+ public function setTotalItems(int $total): void |
|
69 |
+ { |
|
70 |
+ $this->TotalItems = $total; |
|
71 |
+ } |
|
72 |
+ |
|
73 |
+ public function getIterator() |
|
74 |
+ { |
|
75 |
+ return new \ArrayIterator($this->Items); |
|
76 |
+ } |
|
77 |
+ |
|
78 |
+ public function offsetExists($offset) |
|
79 |
+ { |
|
80 |
+ return isset($this->Items[$offset]); |
|
81 |
+ } |
|
82 |
+ |
|
83 |
+ public function offsetGet($offset) |
|
84 |
+ { |
|
85 |
+ return $this->Items[$offset]; |
|
86 |
+ } |
|
87 |
+ |
|
88 |
+ public function offsetSet($offset, $value) |
|
89 |
+ { |
|
90 |
+ throw new \RuntimeException('This collection is immutable'); |
|
91 |
+ } |
|
92 |
+ |
|
93 |
+ public function offsetUnset($offset) |
|
94 |
+ { |
|
95 |
+ throw new \RuntimeException('This collection is immutable'); |
|
96 |
+ } |
|
97 |
+ |
|
98 |
+ public function count() |
|
99 |
+ { |
|
100 |
+ return \count($this->Items); |
|
101 |
+ } |
|
102 |
+} |