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 |
); |
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(); |