Browse code

Initial commit

Benjamin Roth authored on01/06/2023 13:12:27
Showing16 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,17 @@
1
+# EditorConfig is awesome: http://EditorConfig.org
2
+
3
+# top-most EditorConfig file
4
+root = true
5
+
6
+# Unix-style newlines with a newline ending every file
7
+[*]
8
+end_of_line = lf
9
+insert_final_newline = true
10
+trim_trailing_whitespace = true
11
+
12
+[*.{php,twig,yml}]
13
+indent_style = space
14
+indent_size = 4
15
+
16
+[*.{html5,svg,min.css,min.js}]
17
+insert_final_newline = false
0 18
new file mode 100644
... ...
@@ -0,0 +1,17 @@
1
+# Composer
2
+/composer.lock
3
+/composer.phar
4
+/vendor/
5
+
6
+# Node
7
+/node_modules/
8
+
9
+# PhpUnit
10
+/.phpunit.result.cache
11
+/phpunit.xml
12
+
13
+# Tools
14
+/tools/*/vendor
15
+
16
+# IDE
17
+/.idea/
0 18
new file mode 100644
... ...
@@ -0,0 +1,25 @@
1
+# Job application bundle for Dacore utilizing Softgarden API
2
+
3
+Provides an application form module for job offers which will be sent over softgarden API.
4
+
5
+This module is co-developed and provided by [Kommunikation vonRotenberg](https://www.vonrotenberg.de.de) and [Vossmedien](https://www.vossmedien.de).
6
+
7
+**Authors:**
8
+Benjamin Roth [benjamin@esales-media.de]
9
+Christian Voss [christian@vossmedien.de]
10
+
11
+
12
+## System requirements
13
+- Contao CMS >= 4.13.x
14
+
15
+
16
+## Installation
17
+Install the bundle via Composer:
18
+
19
+```
20
+composer require vossmedien/dacore-bundle
21
+```
22
+
23
+
24
+## License
25
+Commercial license
0 26
new file mode 100644
... ...
@@ -0,0 +1,45 @@
1
+{
2
+  "name":"vossmedien/dacore-bundle",
3
+  "description":"Job application bundle for Dacore utilizing Softgarden API",
4
+  "keywords":["contao", "dacore", "softgarden","api"],
5
+  "type":"contao-bundle",
6
+  "license":"commercial",
7
+  "authors":[
8
+    {
9
+      "name": "Benjamin Roth",
10
+      "homepage": "https://www.vonrotenberg.de"
11
+    },
12
+    {
13
+      "name": "Christian Voss",
14
+      "homepage": "https://www.vossmedien.de"
15
+    }
16
+  ],
17
+  "require":{
18
+    "php": "^7.4 || ^8.0",
19
+    "contao/core-bundle": "^4.13",
20
+    "symfony/http-client": "^5.4",
21
+    "symfony/serializer": "^5.4",
22
+    "codefog/contao-haste": "^4.25"
23
+  },
24
+  "require-dev": {
25
+    "contao/manager-plugin": "^2.0"
26
+  },
27
+  "conflict": {
28
+    "contao/manager-plugin": "<2.0 || >=3.0"
29
+  },
30
+  "autoload": {
31
+    "psr-4": {
32
+      "vossmedien\\DacoreBundle\\": "src/"
33
+    }
34
+  },
35
+  "config": {
36
+    "allow-plugins": {
37
+      "contao-components/installer": true,
38
+      "contao/manager-plugin": true,
39
+      "contao-community-alliance/composer-plugin": true
40
+    }
41
+  },
42
+  "extra":{
43
+    "contao-manager-plugin": "vossmedien\\DacoreBundle\\ContaoManager\\Plugin"
44
+  }
45
+}
0 46
new file mode 100644
... ...
@@ -0,0 +1,4 @@
1
+vossmedien_dacore:
2
+    softgarden:
3
+        client_id: '6f4e1019-5c4d-4b1a-a9b4-a8f3c54dfb8f'
4
+        api_domain: 'https://api.softgarden.io/api/rest/v3/frontend/'
0 5
new file mode 100644
... ...
@@ -0,0 +1,10 @@
1
+services:
2
+    _defaults:
3
+        autowire: true
4
+        autoconfigure: true
5
+        public: false
6
+
7
+    vossmedien\DacoreBundle\:
8
+        resource: ../src
9
+        exclude: ../src/{VossmedienDacoreBundle.php,ContaoManager,Entity,Migrations,Model,Resources,Tests,Widget}
10
+
0 11
new file mode 100644
... ...
@@ -0,0 +1,21 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of dacore bundle for Contao.
7
+ *
8
+ * (c) Benjamin Roth
9
+ *
10
+ * @license commercial
11
+ */
12
+
13
+use vossmedien\DacoreBundle\Controller\Frontend\Module\JoblistModuleController;
14
+use vossmedien\DacoreBundle\Controller\Frontend\Module\JobSearchModuleController;
15
+use vossmedien\DacoreBundle\Controller\Frontend\Module\JobReaderModuleController;
16
+use vossmedien\DacoreBundle\Controller\Frontend\Module\JobApplicationFormController;
17
+
18
+$GLOBALS['TL_DCA']['tl_module']['palettes'][JobApplicationFormController::TYPE] = '{title_legend},name,type;{dacore_form_legend},form;{redirect_legend},jumpTo;{template_legend:hide},customTpl;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID';
19
+$GLOBALS['TL_DCA']['tl_module']['palettes'][JoblistModuleController::TYPE] = '{title_legend},name,type;{alox_legend},jumpTo,perPage;{template_legend:hide},customTpl;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID';
20
+$GLOBALS['TL_DCA']['tl_module']['palettes'][JobSearchModuleController::TYPE] = '{title_legend},name,type;{aloxSearch_legend},jumpTo;{template_legend:hide},customTpl;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID';
21
+$GLOBALS['TL_DCA']['tl_module']['palettes'][JobReaderModuleController::TYPE] = '{title_legend},name,type;{aloxReader_legend},overviewPage;{template_legend:hide},customTpl;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID';
0 22
new file mode 100644
... ...
@@ -0,0 +1,25 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of dacore bundle for Contao.
7
+ *
8
+ * (c) Benjamin Roth
9
+ *
10
+ * @license commercial
11
+ */
12
+
13
+use vossmedien\DacoreBundle\Controller\Frontend\Module\JoblistModuleController;
14
+use vossmedien\DacoreBundle\Controller\Frontend\Module\JobSearchModuleController;
15
+use vossmedien\DacoreBundle\Controller\Frontend\Module\JobReaderModuleController;
16
+use vossmedien\DacoreBundle\Controller\Frontend\Module\JobApplicationFormController;
17
+
18
+$GLOBALS['TL_LANG']['FMD'][JobApplicationFormController::TYPE][0] = 'Dacore Bewerbungsformular';
19
+$GLOBALS['TL_LANG']['FMD'][JobApplicationFormController::TYPE][1] = 'Erzeugt ein Formular für Bewerbungen.';
20
+$GLOBALS['TL_LANG']['FMD'][JoblistModuleController::TYPE][0] = 'Alox Job Liste';
21
+$GLOBALS['TL_LANG']['FMD'][JoblistModuleController::TYPE][1] = 'Gibt eine Liste mit Jobs aus.';
22
+$GLOBALS['TL_LANG']['FMD'][JobSearchModuleController::TYPE][0] = 'Alox Job Suchmaske';
23
+$GLOBALS['TL_LANG']['FMD'][JobSearchModuleController::TYPE][1] = 'Gibt eine Suchmaske aus, die auf eine Joblistenseite verlinkt werden kann.';
24
+$GLOBALS['TL_LANG']['FMD'][JobReaderModuleController::TYPE][0] = 'Alox Job Reader';
25
+$GLOBALS['TL_LANG']['FMD'][JobReaderModuleController::TYPE][1] = 'Gibt Details zu einem Stellenangebot aus.';
0 26
new file mode 100644
... ...
@@ -0,0 +1,17 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of dacore bundle for Contao.
7
+ *
8
+ * (c) Benjamin Roth
9
+ *
10
+ * @license commercial
11
+ */
12
+
13
+
14
+$GLOBALS['TL_LANG']['tl_module']['dacore_form_legend'] = 'Bewerbungsformular';
15
+$GLOBALS['TL_LANG']['tl_module']['alox_legend'] = 'Listen-Konfiguration';
16
+$GLOBALS['TL_LANG']['tl_module']['aloxSearch_legend'] = 'Such-Konfiguration';
17
+$GLOBALS['TL_LANG']['tl_module']['aloxReader_legend'] = 'Detailkonfiguration';
0 18
new file mode 100644
... ...
@@ -0,0 +1,6 @@
1
+{% extends '@Contao/block_unsearchable' %}
2
+
3
+{% block content %}
4
+    {{ form }}
5
+
6
+{% endblock %}
0 7
new file mode 100644
... ...
@@ -0,0 +1,174 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of dacore bundle for Contao.
7
+ *
8
+ * (c) Benjamin Roth
9
+ *
10
+ * @license commercial
11
+ */
12
+
13
+namespace vossmedien\DacoreBundle\API;
14
+
15
+use Contao\System;
16
+use Symfony\Component\Serializer\SerializerInterface;
17
+use Symfony\Contracts\HttpClient\HttpClientInterface;
18
+use vossmedien\DacoreBundle\Model\KatalogModel;
19
+use vossmedien\DacoreBundle\Model\StelleModel;
20
+use vossmedien\DacoreBundle\Model\StellenModel;
21
+
22
+class Softgarden
23
+{
24
+    /**
25
+     * @var SerializerInterface
26
+     */
27
+    protected $serializer;
28
+
29
+    /**
30
+     * @var HttpClientInterface
31
+     */
32
+    protected $httpClient;
33
+
34
+    protected $clientId;
35
+
36
+    protected $apiDomain;
37
+
38
+    public function __construct(SerializerInterface $serializer, HttpClientInterface $httpClient)
39
+    {
40
+        $this->serializer = $serializer;
41
+        $this->httpClient = $httpClient;
42
+
43
+        $this->clientId = System::getContainer()->getParameter('vossmedien_dacore.softgarden.client_id');
44
+        $this->apiDomain = System::getContainer()->getParameter('vossmedien_dacore.softgarden.api_domain');
45
+    }
46
+
47
+    protected function getClientId()
48
+    {
49
+        return $this->clientId;
50
+    }
51
+
52
+    protected function getApiDomain()
53
+    {
54
+        return rtrim($this->apiDomain,'/');
55
+    }
56
+
57
+    protected function getBasicAuthorization()
58
+    {
59
+        return [$this->getClientId(),''];
60
+    }
61
+
62
+    protected function sendRequest(string $relEndpoint, array $options, string $method = 'GET')
63
+    {
64
+        $relEndpoint = '/' . ltrim($relEndpoint,'/');
65
+
66
+        return $this->httpClient->request($method,$this->getApiDomain().$relEndpoint,$options);
67
+    }
68
+
69
+    public function testApiRequest()
70
+    {
71
+        $options = [
72
+            'auth_basic' => $this->getBasicAuthorization(),
73
+            'headers' => ['Content-Type: application/json']
74
+        ];
75
+
76
+        $response = $this->sendRequest('jobslist/102581_extern',$options);
77
+
78
+        if ($response->getStatusCode() == 200)
79
+        {
80
+            $content = $response->getContent();
81
+
82
+            return json_decode($content);
83
+        }
84
+
85
+        return null;
86
+    }
87
+
88
+    public function getStellenFiltered(array $params=[]): ?StellenModel
89
+    {
90
+        $options = [
91
+            'headers' => $this->getAuthorizeRequestHeader()
92
+        ];
93
+
94
+        if (count($params))
95
+        {
96
+            $options['query'] = $params;
97
+        }
98
+
99
+        $response = $this->sendRequest('Stelle/GetStellenFiltered',$options);
100
+
101
+
102
+
103
+        if ($response->getStatusCode() == 200)
104
+        {
105
+            $content = $response->getContent();
106
+
107
+            /** @var StellenModel $collection */
108
+            $collection = $this->serializer->deserialize($content,StellenModel::class,'json');
109
+
110
+            return $collection;
111
+        }
112
+
113
+        return null;
114
+    }
115
+
116
+    public function getStelleById(string $uuid, array $params=[]): ?StelleModel
117
+    {
118
+        $options = [
119
+            'headers' => $this->getAuthorizeRequestHeader(),
120
+            'query' => [
121
+                'stelleUuid' => $uuid
122
+            ]
123
+        ];
124
+
125
+        if (count($params))
126
+        {
127
+            $options['query'] = array_merge($options['query'],$params);
128
+        }
129
+
130
+        $response = $this->sendRequest('Stelle/GetStelleById',$options);
131
+
132
+
133
+
134
+        if ($response->getStatusCode() == 200)
135
+        {
136
+            $content = $response->getContent();
137
+
138
+            /** @var StelleModel $model */
139
+            $model = $this->serializer->deserialize($content,StelleModel::class,'json');
140
+
141
+            return $model;
142
+        }
143
+
144
+        return null;
145
+    }
146
+
147
+    public function getKatalogByRelationName(string $entityName, string $relationName): ?KatalogModel
148
+    {
149
+        $options = [
150
+            'headers' => $this->getAuthorizeRequestHeader(),
151
+            'query' => [
152
+                'entityName' => $entityName,
153
+                'relationName' => $relationName
154
+            ]
155
+        ];
156
+
157
+        $response = $this->sendRequest('Katalog/GetByRelationName',$options);
158
+
159
+
160
+
161
+        if ($response->getStatusCode() == 200)
162
+        {
163
+            $content = $response->getContent();
164
+
165
+            /** @var KatalogModel $collection */
166
+            $collection = $this->serializer->deserialize($content,KatalogModel::class,'json');
167
+
168
+            return $collection;
169
+        }
170
+
171
+        return null;
172
+    }
173
+
174
+}
0 175
new file mode 100644
... ...
@@ -0,0 +1,33 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of dacore bundle for Contao.
7
+ *
8
+ * (c) Benjamin Roth
9
+ *
10
+ * @license commercial
11
+ */
12
+
13
+namespace vossmedien\DacoreBundle\ContaoManager;
14
+
15
+use Contao\CoreBundle\ContaoCoreBundle;
16
+use Contao\ManagerPlugin\Bundle\BundlePluginInterface;
17
+use Contao\ManagerPlugin\Bundle\Config\BundleConfig;
18
+use Contao\ManagerPlugin\Bundle\Parser\ParserInterface;
19
+use vossmedien\DacoreBundle\VossmedienDacoreBundle;
20
+
21
+class Plugin implements BundlePluginInterface
22
+{
23
+    /**
24
+     * {@inheritdoc}
25
+     */
26
+    public function getBundles(ParserInterface $parser): array
27
+    {
28
+        return [
29
+            BundleConfig::create(VossmedienDacoreBundle::class)
30
+                ->setLoadAfter([ContaoCoreBundle::class]),
31
+        ];
32
+    }
33
+}
0 34
new file mode 100644
... ...
@@ -0,0 +1,60 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of dacore bundle for Contao.
7
+ *
8
+ * (c) Benjamin Roth
9
+ *
10
+ * @license commercial
11
+ */
12
+
13
+namespace vossmedien\DacoreBundle\Controller\Frontend\Module;
14
+
15
+use Contao\CoreBundle\Controller\FrontendModule\AbstractFrontendModuleController;
16
+use Contao\CoreBundle\ServiceAnnotation\FrontendModule;
17
+use Contao\ModuleModel;
18
+use Contao\PageModel;
19
+use Contao\Template;
20
+use Haste\Form\Form;
21
+use Symfony\Component\HttpFoundation\Request;
22
+use Symfony\Component\HttpFoundation\Response;
23
+use vossmedien\DacoreBundle\API\Softgarden;
24
+
25
+/**
26
+ * @FrontendModule(JobApplicationFormController::TYPE, category="miscellaneous")
27
+ */
28
+class JobApplicationFormController extends AbstractFrontendModuleController
29
+{
30
+    public const TYPE = 'dacore_jobapplication';
31
+
32
+    /**
33
+     * @var Softgarden
34
+     */
35
+    protected $api;
36
+
37
+    public function __construct(Softgarden $api)
38
+    {
39
+        $this->api = $api;
40
+    }
41
+
42
+
43
+    protected function getResponse(Template $template, ModuleModel $model, Request $request): ?Response
44
+    {
45
+        $strFormId = 'jobapplication-form';
46
+
47
+        $Form = new Form($strFormId,'POST', function($objHaste) {
48
+            return \Input::post('FORM_SUBMIT') === $objHaste->getFormId();
49
+        });
50
+
51
+        $Form->addFieldsFromFormGenerator($model->form, function(&$strField, &$arrDca) {
52
+            return true;
53
+        });
54
+
55
+        $template->form = $Form->generate();
56
+
57
+        return $template->getResponse();
58
+    }
59
+
60
+}
0 61
new file mode 100644
... ...
@@ -0,0 +1,42 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of dacore bundle for Contao.
7
+ *
8
+ * (c) Benjamin Roth
9
+ *
10
+ * @license commercial
11
+ */
12
+
13
+namespace vossmedien\DacoreBundle\DependencyInjection;
14
+
15
+use Symfony\Component\Config\Definition\Builder\TreeBuilder;
16
+use Symfony\Component\Config\Definition\ConfigurationInterface;
17
+
18
+class Configuration implements ConfigurationInterface
19
+{
20
+    public function getConfigTreeBuilder(): TreeBuilder
21
+    {
22
+        $treeBuilder = new TreeBuilder('vossmedien_dacore');
23
+        $treeBuilder
24
+            ->getRootNode()
25
+            ->children()
26
+                ->arrayNode('softgarden')
27
+                    ->addDefaultsIfNotSet()
28
+                    ->children()
29
+                        ->scalarNode('client_id')
30
+                            ->info('Your Softgarden client ID.')
31
+                        ->end()
32
+                        ->scalarNode('api_domain')
33
+                            ->info('Your Softgarden API domain.')
34
+                        ->end()
35
+                    ->end()
36
+                ->end()
37
+            ->end()
38
+        ;
39
+
40
+        return $treeBuilder;
41
+    }
42
+}
0 43
new file mode 100644
... ...
@@ -0,0 +1,34 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of dacore bundle for Contao.
7
+ *
8
+ * (c) Benjamin Roth
9
+ *
10
+ * @license commercial
11
+ */
12
+
13
+namespace vossmedien\DacoreBundle\DependencyInjection;
14
+
15
+use Symfony\Component\Config\FileLocator;
16
+use Symfony\Component\DependencyInjection\ContainerBuilder;
17
+use Symfony\Component\DependencyInjection\Extension\Extension;
18
+use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
19
+
20
+class VossmedienDacoreExtension extends Extension
21
+{
22
+    public function load(array $configs, ContainerBuilder $container): void
23
+    {
24
+        $config = $this->processConfiguration(new Configuration(), $configs);
25
+
26
+        foreach($config['softgarden'] as $key=>$val)
27
+        {
28
+            $container->setParameter('vossmedien_dacore.softgarden.'.$key,$val);
29
+        }
30
+
31
+        $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../../config'));
32
+        $loader->load('services.yml');
33
+    }
34
+}
0 35
new file mode 100644
... ...
@@ -0,0 +1,23 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of dacore bundle for Contao.
7
+ *
8
+ * (c) Benjamin Roth
9
+ *
10
+ * @license commercial
11
+ */
12
+
13
+namespace vossmedien\DacoreBundle;
14
+
15
+use Symfony\Component\HttpKernel\Bundle\Bundle;
16
+
17
+class VossmedienDacoreBundle extends Bundle
18
+{
19
+    public function getPath(): string
20
+    {
21
+        return \dirname(__DIR__);
22
+    }
23
+}