Browse code

Update

Benjamin Roth authored on15/08/2023 15:29:18
Showing9 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,25 @@
1
+<?php
2
+
3
+/*
4
+ * This file is part of contao-weinanlieferung-bundle.
5
+ *
6
+ * (c) vonRotenberg
7
+ *
8
+ * @license commercial
9
+ */
10
+
11
+use Contao\CoreBundle\DataContainer\PaletteManipulator;
12
+
13
+PaletteManipulator::create()
14
+    ->addLegend('wa_config_legend','global_legend')
15
+    ->addField('vr_wa_uploadFolderSRC','wa_config_legend',PaletteManipulator::POSITION_APPEND)
16
+    ->applyToPalette('root','tl_page')
17
+    ->applyToPalette('rootfallback','tl_page');
18
+
19
+
20
+$GLOBALS['TL_DCA']['tl_page']['fields']['vr_wa_uploadFolderSRC'] = array(
21
+    'exclude'    => true,
22
+    'inputType'  => 'fileTree',
23
+    'eval'       => array('fieldType'=>'radio', 'files'=>false, 'mandatory'=>true, 'tl_class'=>'clr'),
24
+    'sql'        => "binary(16) NULL"
25
+);
... ...
@@ -10,6 +10,7 @@
10 10
 
11 11
 use Contao\DC_Table;
12 12
 use Contao\DataContainer;
13
+use Contao\Config;
13 14
 
14 15
 $GLOBALS['TL_DCA']['tl_vr_wa_reservation'] = array
15 16
 (
... ...
@@ -39,6 +40,12 @@ $GLOBALS['TL_DCA']['tl_vr_wa_reservation'] = array
39 40
             'sql'        => "int(10) unsigned NOT NULL default '0'",
40 41
             'relation'   => array('type' => 'belongsTo', 'load' => 'lazy')
41 42
         ),
43
+        'rootid'         => array
44
+        (
45
+            'foreignKey' => 'tl_page.title',
46
+            'sql'        => "int(10) unsigned NOT NULL default '0'",
47
+            'relation'   => array('type' => 'belongsTo', 'load' => 'lazy')
48
+        ),
42 49
         'tstamp'      => array
43 50
         (
44 51
             'sql' => "int(10) unsigned NOT NULL default '0'"
... ...
@@ -60,5 +67,23 @@ $GLOBALS['TL_DCA']['tl_vr_wa_reservation'] = array
60 67
             'sql'       => "blob NULL",
61 68
             'relation'   => array('type' => 'hasMany', 'load' => 'lazy')
62 69
         ),
70
+        'upload' => array
71
+        (
72
+            'exclude'                 => true,
73
+            'inputType'               => 'fileTree',
74
+            'eval'                    => array('filesOnly'=>true, 'fieldType'=>'radio', 'tl_class'=>'clr', 'extensions'=>Config::get('allowedDownload')),
75
+            'sql'                     => "binary(16) NULL"
76
+        ),
77
+        'filename' => array
78
+        (
79
+            'exclude'                 => true,
80
+            'inputType'               => 'text',
81
+            'eval'                    => array
82
+            (
83
+                'maxlength' => 255,
84
+                'decodeEntities'=>true
85
+            ),
86
+            'sql'                     => "varchar(255) BINARY NOT NULL default ''"
87
+        ),
63 88
     )
64 89
 );
... ...
@@ -11,6 +11,8 @@
11 11
 use Contao\DC_Table;
12 12
 use Contao\DataContainer;
13 13
 
14
+\Contao\System::loadLanguageFile('default');
15
+
14 16
 $GLOBALS['TL_DCA']['tl_vr_wa_slot'] = array
15 17
 (
16 18
 
17 19
new file mode 100644
... ...
@@ -0,0 +1,14 @@
1
+<?php
2
+
3
+/**
4
+ * This file is part of contao-weinanlieferung-bundle.
5
+ *
6
+ * (c) vonRotenberg
7
+ *
8
+ * @license commercial
9
+ */
10
+
11
+$GLOBALS['TL_LANG']['tl_page']['vr_wa_uploadFolderSRC'][0] = 'Upload-Ordner';
12
+$GLOBALS['TL_LANG']['tl_page']['vr_wa_uploadFolderSRC'][1] = 'Hier werden die hochgeladenen Dateien abgelegt.';
13
+
14
+$GLOBALS['TL_LANG']['tl_page']['wa_config_legend'] = 'Weinanlieferung-Einstellungen';
0 15
new file mode 100644
... ...
@@ -0,0 +1,12 @@
1
+<?php
2
+
3
+/**
4
+ * This file is part of contao-weinanlieferung-bundle.
5
+ *
6
+ * (c) vonRotenberg
7
+ *
8
+ * @license commercial
9
+ */
10
+
11
+$GLOBALS['TL_LANG']['MSC']['wa_sorte'] = 'Grape variety';
12
+$GLOBALS['TL_LANG']['MSC']['wa_leseart'] = 'Harvest type';
... ...
@@ -59,8 +59,11 @@
59 59
 
60 60
             <div class="frame__body">
61 61
                 <h4>Reservieren</h4>
62
+                {% if toast is defined %}
63
+                  {{ toast|raw }}
64
+                {% endif %}
62 65
                 {% if buchen.buchbar %}
63
-                    <form hx-post="/_ajax/vr_wa/v1/slot?do=reservate">
66
+                    <form hx-post="/_ajax/vr_wa/v1/slot?do=reservate" enctype="multipart/form-data">
64 67
                         <input type="hidden" name="id" value="{{ id }}">
65 68
                         <fieldset>
66 69
                             <label for="res-behaelter">Liefernde Behältermenge</label>
... ...
@@ -78,6 +81,10 @@
78 81
                             {% endfor %}
79 82
                         </fieldset>
80 83
                         <fieldset>
84
+                            <label for="res-upload">Dateianhang</label>
85
+                            <input type="file" id="res-upload" name="upload">
86
+                        </fieldset>
87
+                        <fieldset>
81 88
                             <button type="submit">Reservieren</button>
82 89
                         </fieldset>
83 90
                     </form>
... ...
@@ -31,6 +31,16 @@
31 31
                     </div>
32 32
                 {% endfor %}
33 33
             </div>
34
+        {% else %}
35
+            <div class="placeholder">
36
+                <h6 class="placeholder-title">Sie haben noch keine Anlieferungszeiten reserviert</h6>
37
+                <div class="placeholder-subtitle">Sobald Sie Anlieferungszeiten reserviert haben, werden diese hier aufgelistet.</div>
38
+                <div class="placeholder-commands u-center">
39
+                    <div class="m-1">
40
+                        <a href="{{ insert_tag('link_url::2') }}" class="btn btn-info">Zur Reservierung</a>
41
+                    </div>
42
+                </div>
43
+            </div>
34 44
         {% endif %}
35 45
     {% endblock %}
36 46
 
... ...
@@ -1,35 +1,37 @@
1 1
 <div hx-get="{{ insert_tag('env::request') }}" hx-headers='{"VR-Ajax": "WaSlotsModule"}' hx-trigger="updateWaList from:body, updateWaBooking from:body" class="{{ class }} content-wrapper block"{{ cssID }}{% if style is defined and style is not empty %} style="{{ style }}"{% endif %}>
2 2
 
3 3
     {% block filter %}
4
-        <form hx-get="{{ insert_tag('env::request') }}" hx-push-url="true" hx-headers='{"VR-Ajax": "WaSlotsModule"}' hx-trigger="change, submit" hx-target="closest .content-wrapper" class="filter">
5
-            <div class="row">
6
-                <div class="col-md-3 kapazitaet">
7
-                    <select name="filter_kapazitaet">
8
-                        <option value="">-</option>
9
-                        {% for option in filter.kapazitaet.options %}
10
-                            <option value="{{ option }}"{% if filter.kapazitaet.selected is defined and filter.kapazitaet.selected == option %} selected{% endif %}>{{ option }}</option>
11
-                        {% endfor %}
12
-                    </select>
13
-                </div>
14
-                <div class="col-md-3 sorte">
15
-                    <select name="filter_sorte">
16
-                        <option value="">-</option>
17
-                        {% for key, option in filter.sorte.options %}
18
-                            <option value="{{ key }}"{% if filter.sorte.selected is defined and filter.sorte.selected == key %} selected{% endif %}>{{ option }}</option>
19
-                        {% endfor %}
20
-                    </select>
21
-                </div>
22
-                <div class="col-md-3 leseart">
23
-                    <select name="filter_leseart">
24
-                        <option value="">-</option>
25
-                        {% for key, option in filter.leseart.options %}
26
-                            <option value="{{ key }}"{% if filter.leseart.selected is defined and filter.leseart.selected == key %} selected{% endif %}>{{ option }}</option>
27
-                        {% endfor %}
28
-                    </select>
4
+        {% if days is defined and days|length %}
5
+            <form hx-get="{{ insert_tag('env::request') }}" hx-push-url="true" hx-headers='{"VR-Ajax": "WaSlotsModule"}' hx-trigger="change, submit" hx-target="closest .content-wrapper" class="filter">
6
+                <div class="row">
7
+                    <div class="col-md-3 kapazitaet">
8
+                        <select name="filter_kapazitaet">
9
+                            <option value="">-</option>
10
+                            {% for option in filter.kapazitaet.options %}
11
+                                <option value="{{ option }}"{% if filter.kapazitaet.selected is defined and filter.kapazitaet.selected == option %} selected{% endif %}>{{ option }}</option>
12
+                            {% endfor %}
13
+                        </select>
14
+                    </div>
15
+                    <div class="col-md-3 sorte">
16
+                        <select name="filter_sorte">
17
+                            <option value="">-</option>
18
+                            {% for key, option in filter.sorte.options %}
19
+                                <option value="{{ key }}"{% if filter.sorte.selected is defined and filter.sorte.selected == key %} selected{% endif %}>{{ option }}</option>
20
+                            {% endfor %}
21
+                        </select>
22
+                    </div>
23
+                    <div class="col-md-3 leseart">
24
+                        <select name="filter_leseart">
25
+                            <option value="">-</option>
26
+                            {% for key, option in filter.leseart.options %}
27
+                                <option value="{{ key }}"{% if filter.leseart.selected is defined and filter.leseart.selected == key %} selected{% endif %}>{{ option }}</option>
28
+                            {% endfor %}
29
+                        </select>
30
+                    </div>
31
+                    <div class="col submit"><button class="u-block w-100p">Filter übernehmen</button></div>
29 32
                 </div>
30
-                <div class="col submit"><button class="u-block w-100p">Filter übernehmen</button></div>
31
-            </div>
32
-        </form>
33
+            </form>
34
+        {% endif %}
33 35
     {% endblock %}
34 36
 
35 37
     {% block content %}
... ...
@@ -62,6 +64,11 @@
62 64
                     </div>
63 65
                 {% endfor %}
64 66
             </div>
67
+        {% else %}
68
+            <div class="placeholder">
69
+                <h6 class="placeholder-title">Derzeit sind keine buchbaren Anlieferungszeiten verfügbar</h6>
70
+                <div class="placeholder-subtitle">Sie können uns auch gerne anrufen.</div>
71
+            </div>
65 72
         {% endif %}
66 73
     {% endblock %}
67 74
 
... ...
@@ -16,6 +16,8 @@ use Contao\Controller;
16 16
 use Contao\CoreBundle\Controller\AbstractController;
17 17
 use Contao\CoreBundle\Framework\ContaoFramework;
18 18
 use Contao\CoreBundle\Security\Authentication\Token\TokenChecker;
19
+use Contao\FormFileUpload;
20
+use Contao\Frontend;
19 21
 use Contao\FrontendUser;
20 22
 use Contao\Input;
21 23
 use Contao\StringUtil;
... ...
@@ -88,7 +90,7 @@ class SlotAjaxController extends AbstractController
88 90
         return new Response('',500);
89 91
     }
90 92
 
91
-    protected function renderDetails(bool $blnModal=true)
93
+    protected function renderDetails(bool $blnModal=true,string $error=null)
92 94
     {
93 95
         if (empty($_REQUEST['id']))
94 96
         {
... ...
@@ -158,6 +160,11 @@ class SlotAjaxController extends AbstractController
158 160
             'reservations' => $arrReservations
159 161
         ];
160 162
 
163
+        if (!empty($error))
164
+        {
165
+            $arrData['toast'] = $error;
166
+        }
167
+
161 168
         return $this->render('@Contao/modal_slot_details.html.twig',$arrData);
162 169
     }
163 170
 
... ...
@@ -217,6 +224,27 @@ class SlotAjaxController extends AbstractController
217 224
 
218 225
     protected function reservate()
219 226
     {
227
+        Controller::loadDataContainer('tl_vr_wa_reservation');
228
+        $arrData = [];
229
+
230
+        if (($rootPage = Frontend::getRootPageFromUrl()) !== null && !empty($rootPage->vr_wa_uploadFolderSRC))
231
+        {
232
+            $File = new FormFileUpload(\Contao\Widget::getAttributesFromDca($GLOBALS['TL_DCA']['tl_vr_wa_reservation']['fields']['upload'], 'upload'));
233
+            $File->storeFile = true;
234
+            $File->doNotOverwrite = true;
235
+            $File->uploadFolder = $rootPage->vr_wa_uploadFolderSRC;
236
+
237
+            $File->validate();
238
+
239
+            if ($File->hasErrors())
240
+            {
241
+                return $this->renderDetails(false,'<div class="toast toast--danger mx-0">' . $File->getErrorAsHTML() . '</div>');
242
+            }
243
+
244
+            $arrData['filename'] = $_SESSION['FILES'][$File->name]['name'] ?? '';
245
+            $arrData['upload'] = $_SESSION['FILES'][$File->name]['uuid'] ? StringUtil::uuidToBin($_SESSION['FILES'][$File->name]['uuid']) : null;
246
+        }
247
+
220 248
         if (empty($_REQUEST['id']) || empty(Input::post('behaelter')) || empty(Input::post('sorten')))
221 249
         {
222 250
             return new Response('Missing parameter',412);
... ...
@@ -231,14 +259,15 @@ class SlotAjaxController extends AbstractController
231 259
         }
232 260
 
233 261
         $Reservation = new WeinanlieferungReservationModel();
234
-
235
-        $Reservation->setRow([
262
+        $arrData = array_merge($arrData,[
236 263
             'pid' => $_REQUEST['id'],
264
+            'rootid' => $rootPage !== null ? $rootPage->id : '',
237 265
             'tstamp' => time(),
238 266
             'uid' => FrontendUser::getInstance()->id,
239 267
             'behaelter' => Input::post('behaelter'),
240 268
             'sorten' => $arrSorten
241 269
         ]);
270
+        $Reservation->setRow($arrData);
242 271
 
243 272
 
244 273
         $Reservation->save();