Browse code

Update

Benjamin Roth authored on26/07/2023 21:23:35
Showing6 changed files
... ...
@@ -13,5 +13,8 @@ declare(strict_types=1);
13 13
 /**
14 14
  * Palettes
15 15
  */
16
-$GLOBALS['TL_DCA']['tl_content']['palettes']['secureDownloads'] = '{type_legend},type,headline;{source_legend},sortBy,metaIgnore;{template_legend:hide},customTpl;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID,space;{invisible_legend:hide},invisible,start,stop';
16
+
17
+use vonRotenberg\MemberfilesBundle\Controller\Frontend\ContentElement\SecureDownloadsController;
18
+
19
+$GLOBALS['TL_DCA']['tl_content']['palettes'][SecureDownloadsController::TYPE] = '{type_legend},type,headline;{source_legend},sortBy,metaIgnore;{template_legend:hide},customTpl;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID,space;{invisible_legend:hide},invisible,start,stop';
17 20
 
... ...
@@ -20,6 +20,7 @@ $GLOBALS['TL_DCA']['tl_member_secureDownloads'] = array
20 20
         'dataContainer' => 'Table',
21 21
         'ptable' => 'tl_member',
22 22
         'closed' => true,
23
+        'doNotCopyRecords' => true,
23 24
         'sql' => array
24 25
         (
25 26
             'keys' => array
... ...
@@ -93,7 +94,7 @@ $GLOBALS['TL_DCA']['tl_member_secureDownloads'] = array
93 94
         (
94 95
             'foreignKey' => 'tl_files.name',
95 96
             'sql' => "binary(16) NULL",
96
-            'relation' => array('type' => 'belongsTo', 'load' => 'eager', 'field' => 'uuid')
97
+            'relation' => array('type' => 'belongsTo', 'load' => 'lazy', 'field' => 'uuid')
97 98
         ),
98 99
         'tstamp' => array
99 100
         (
... ...
@@ -8,8 +8,10 @@
8 8
  * @license LGPL-3.0+
9 9
  */
10 10
 
11
-$GLOBALS['TL_LANG']['CTE']['secureDownloads'][0] = 'Sichere Downloads';
12
-$GLOBALS['TL_LANG']['CTE']['secureDownloads'][1] = 'Sichere Downloads für Mitglieder';
11
+use vonRotenberg\MemberfilesBundle\Controller\Frontend\ContentElement\SecureDownloadsController;
12
+
13
+$GLOBALS['TL_LANG']['CTE'][SecureDownloadsController::TYPE][0] = 'Sichere Downloads';
14
+$GLOBALS['TL_LANG']['CTE'][SecureDownloadsController::TYPE][1] = 'Sichere Downloads für Mitglieder';
13 15
 
14 16
 /**
15 17
  * Misc
16 18
deleted file mode 100644
... ...
@@ -1,15 +0,0 @@
1
-<?php
2
-
3
-/**
4
- * Pagelist for Contao
5
- *
6
- * Copyright (c) 2015 Benjamin Roth
7
- *
8
- * @license LGPL-3.0+
9
- */
10
-
11
-/**
12
- * Frontend modules
13
- */
14
-$GLOBALS['TL_LANG']['FMD']['pagelist'][0] = 'Seitenliste';
15
-$GLOBALS['TL_LANG']['FMD']['pagelist'][1] = 'Erzeugt eine Linkliste mit Unterseiten.';
16 0
\ No newline at end of file
17 1
new file mode 100644
... ...
@@ -0,0 +1,20 @@
1
+{% extends '@Contao/block_unsearchable' %}
2
+
3
+{% block content %}
4
+    {% import "@ContaoCore/Image/Studio/_macros.html.twig" as studio %}
5
+
6
+    <ul>
7
+        {% for file in files %}
8
+            <li class="download-element ext-{{ file.extension }}">
9
+                {% if file.previews is defined %}
10
+                    {% for preview in file.previews %}
11
+                        {{- studio.figure(preview, { attr: { class: ('image_container') }}) -}}
12
+                    {% endfor %}
13
+                {% endif %}
14
+                <a href="{{ file.href }}" title="{{ file.title }}" type="{{ file.mime }}">{{ file.link}} <span class="size">({{ file.filesize }})</span></a>
15
+            </li>
16
+        {% endfor %}
17
+    </ul>
18
+
19
+{% endblock %}
20
+
0 21
new file mode 100644
... ...
@@ -0,0 +1,269 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of eSales Media SinglereisenBundle
7
+ *
8
+ * (c) Benjamin Roth
9
+ *
10
+ * @license proprietary
11
+ */
12
+
13
+namespace vonRotenberg\MemberfilesBundle\Controller\Frontend\ContentElement;
14
+
15
+use Contao\Config;
16
+use Contao\ContentModel;
17
+use Contao\Controller;
18
+use Contao\CoreBundle\Controller\ContentElement\AbstractContentElementController;
19
+use Contao\CoreBundle\ServiceAnnotation\ContentElement;
20
+use Contao\Environment;
21
+use Contao\File;
22
+use Contao\FilesModel;
23
+use Contao\FrontendUser;
24
+use Contao\Image;
25
+use Contao\Input;
26
+use Contao\StringUtil;
27
+use Contao\System;
28
+use Contao\Template;
29
+use Doctrine\DBAL\Connection;
30
+use Symfony\Component\HttpFoundation\Request;
31
+use Symfony\Component\HttpFoundation\Response;
32
+use vonRotenberg\MemberfilesBundle\Model\SecureDownloadsModel;
33
+
34
+/**
35
+ * @ContentElement(SecureDownloadsController::TYPE, category="files")
36
+ */
37
+class SecureDownloadsController extends AbstractContentElementController
38
+{
39
+    public const TYPE = 'secure_downloads';
40
+
41
+    /** @var Connection */
42
+    protected $db;
43
+
44
+    protected $User;
45
+
46
+    public function __construct(Connection $db)
47
+    {
48
+        if (!System::getContainer()->get('contao.security.token_checker')->hasFrontendUser())
49
+        {
50
+            return new Response('',403);
51
+        }
52
+
53
+        $this->db = $db;
54
+        $this->User = FrontendUser::getInstance();
55
+    }
56
+
57
+
58
+    protected function getResponse(Template $template, ContentModel $model, Request $request): Response
59
+    {
60
+        // Handle file requests
61
+        if (
62
+            ($path = Input::get('file', true)) !== null
63
+            && ($File = FilesModel::findByPath($path)) !== null
64
+            && ($SecFile = $SecFile = SecureDownloadsModel::findBy(["uuid = ?"],[$File->uuid])) !== null
65
+        )
66
+        {
67
+            if ($SecFile->pid == $this->User->id)
68
+            {
69
+                Controller::sendFileToBrowser($path);
70
+            } else {
71
+                return new Response('',403);
72
+            }
73
+        }
74
+
75
+        $objPage = $this->getPageModel();
76
+        $allowedDownload = StringUtil::trimsplit(',', strtolower(\Config::get('allowedDownload')));
77
+        $UserFiles = $this->db->executeQuery("SELECT uuid FROM tl_member_secureDownloads WHERE pid = ?",[$this->User->id]);
78
+
79
+        // Return if there are no files
80
+        if ($UserFiles->rowCount() < 1)
81
+        {
82
+            return new Response();
83
+        }
84
+
85
+        $arrUuid = $UserFiles->fetchFirstColumn();
86
+
87
+        if (($objFiles = FilesModel::findMultipleByUuids($arrUuid)) === null)
88
+        {
89
+            return new Response();
90
+        }
91
+
92
+        while ($objFiles->next())
93
+        {
94
+            // Continue if the files has been processed or does not exist
95
+            if (isset($files[$objFiles->path]) || !file_exists(TL_ROOT . '/' . $objFiles->path))
96
+            {
97
+                continue;
98
+            }
99
+
100
+            // Single files
101
+            if ($objFiles->type == 'file')
102
+            {
103
+                $File = new File($objFiles->path);
104
+
105
+                if (!in_array($File->extension, $allowedDownload) || preg_match('/^meta(_[a-z]{2})?\.txt$/', $File->basename))
106
+                {
107
+                    continue;
108
+                }
109
+
110
+                $arrMeta = $objFiles->current()->getMetaData($objPage->language);
111
+
112
+                if (empty($arrMeta))
113
+                {
114
+                    if ($model->metaIgnore)
115
+                    {
116
+                        continue;
117
+                    }
118
+                    elseif (($objPage->rootFallbackLanguage !== null && ($arrMeta = $objFiles->current()->getMetaData($objPage->rootFallbackLanguage)) === null) || $arrMeta === null)
119
+                    {
120
+                        $arrMeta = [];
121
+                    }
122
+                }
123
+
124
+                // Use the file name as title if none is given
125
+                if (empty($arrMeta['title']))
126
+                {
127
+                    $arrMeta['title'] = StringUtil::specialchars($File->basename);
128
+                }
129
+
130
+                $strHref = Environment::get('request');
131
+
132
+                // Remove an existing file parameter (see #5683)
133
+                if (preg_match('/(&(amp;)?|\?)file=/', $strHref))
134
+                {
135
+                    $strHref = preg_replace('/(&(amp;)?|\?)file=[^&]+/', '', $strHref);
136
+                }
137
+
138
+                $strHref .= ((Config::get('disableAlias') || strpos($strHref, '?') !== false) ? '&amp;' : '?') . 'file=' . System::urlEncode($objFiles->path);
139
+
140
+                // Add the image
141
+                $files[$objFiles->path] = array
142
+                (
143
+                    'id'        => $objFiles->id,
144
+                    'uuid'      => $objFiles->uuid,
145
+                    'name'      => $File->basename,
146
+                    'title'     => StringUtil::specialchars(sprintf($GLOBALS['TL_LANG']['MSC']['download'], $File->basename)),
147
+                    'link'      => $arrMeta['title'] ?? '',
148
+                    'caption'   => $arrMeta['caption'] ?? '',
149
+                    'href'      => $strHref,
150
+                    'filesize'  => System::getReadableSize($File->filesize, 1),
151
+                    'icon'      => Image::getPath($File->icon),
152
+                    'mime'      => $File->mime,
153
+                    'meta'      => $arrMeta,
154
+                    'extension' => $File->extension,
155
+                    'path'      => $File->dirname,
156
+                    'mtime'     => $File->mtime
157
+                );
158
+
159
+                $auxDate[] = $File->mtime;
160
+            }
161
+
162
+            // Folders
163
+            else
164
+            {
165
+                $objSubfiles = FilesModel::findByPid($objFiles->uuid);
166
+
167
+                if ($objSubfiles === null)
168
+                {
169
+                    continue;
170
+                }
171
+
172
+                while ($objSubfiles->next())
173
+                {
174
+                    // Skip subfolders
175
+                    if ($objSubfiles->type == 'folder')
176
+                    {
177
+                        continue;
178
+                    }
179
+
180
+                    $File = new File($objSubfiles->path);
181
+
182
+                    if (!in_array($File->extension, $allowedDownload) || preg_match('/^meta(_[a-z]{2})?\.txt$/', $File->basename))
183
+                    {
184
+                        continue;
185
+                    }
186
+
187
+                    $arrMeta = $objSubfiles->current()->getMetaData($objPage->language);
188
+
189
+                    if (empty($arrMeta))
190
+                    {
191
+                        if ($model->metaIgnore)
192
+                        {
193
+                            continue;
194
+                        }
195
+                        elseif (($objPage->rootFallbackLanguage !== null && ($arrMeta = $objSubfiles->current()->getMetaData($objPage->rootFallbackLanguage)) === null) || $arrMeta === null)
196
+                        {
197
+                            $arrMeta = [];
198
+                        }
199
+                    }
200
+
201
+                    // Use the file name as title if none is given
202
+                    if (empty($arrMeta['title']))
203
+                    {
204
+                        $arrMeta['title'] = StringUtil::specialchars($File->basename);
205
+                    }
206
+
207
+                    $strHref = Environment::get('request');
208
+
209
+                    // Remove an existing file parameter (see #5683)
210
+                    if (preg_match('/(&(amp;)?|\?)file=/', $strHref))
211
+                    {
212
+                        $strHref = preg_replace('/(&(amp;)?|\?)file=[^&]+/', '', $strHref);
213
+                    }
214
+
215
+                    $strHref .= ((Config::get('disableAlias') || strpos($strHref, '?') !== false) ? '&amp;' : '?') . 'file=' . System::urlEncode($objSubfiles->path);
216
+
217
+                    // Add the image
218
+                    $files[$objSubfiles->path] = array
219
+                    (
220
+                        'id'        => $objSubfiles->id,
221
+                        'uuid'      => $objSubfiles->uuid,
222
+                        'name'      => $File->basename,
223
+                        'title'     => StringUtil::specialchars(sprintf($GLOBALS['TL_LANG']['MSC']['download'], $File->basename)),
224
+                        'link'      => $arrMeta['title'] ?? '',
225
+                        'caption'   => $arrMeta['caption'] ?? '',
226
+                        'href'      => $strHref,
227
+                        'filesize'  => System::getReadableSize($File->filesize, 1),
228
+                        'icon'      => Image::getPath($File->icon),
229
+                        'mime'      => $File->mime,
230
+                        'meta'      => $arrMeta,
231
+                        'extension' => $File->extension,
232
+                        'path'      => $File->dirname
233
+                    );
234
+
235
+                    $auxDate[] = $File->mtime;
236
+                }
237
+            }
238
+        }
239
+
240
+        // Sort array
241
+        switch ($model->sortBy)
242
+        {
243
+            default:
244
+            case 'name_asc':
245
+                uksort($files, 'basename_natcasecmp');
246
+                break;
247
+
248
+            case 'name_desc':
249
+                uksort($files, 'basename_natcasercmp');
250
+                break;
251
+
252
+            case 'date_asc':
253
+                array_multisort($files, SORT_NUMERIC, $auxDate, SORT_ASC);
254
+                break;
255
+
256
+            case 'date_desc':
257
+                array_multisort($files, SORT_NUMERIC, $auxDate, SORT_DESC);
258
+                break;
259
+
260
+            case 'random':
261
+                shuffle($files);
262
+                break;
263
+        }
264
+
265
+        $template->files = array_values($files);
266
+
267
+        return $template->getResponse();
268
+    }
269
+}