Browse code

Merge pull request #13 from oveleon/develop

Drop 4.9 Support and other changes

Sebastian Zoglowek authored on15/01/2023 17:00:37 • GitHub committed on15/01/2023 17:00:37
Showing65 changed files
... ...
@@ -10,7 +10,7 @@
10 10
 
11 11
 ---
12 12
 
13
-> Working with **Contao 4.9** and up to **Contao 4.13** (PHP ^7.4 and PHP 8)
13
+> Working with **Contao 4.13** (PHP ^8.0)
14 14
 
15 15
 ---
16 16
 
... ...
@@ -20,7 +20,7 @@ Additionally, you can display members with their details in a reader page.
20 20
 
21 21
 + [Features](#features)
22 22
 + [Installation](#installation)
23
-   + [Upgrading](#upgrading-to-version-12)
23
+   + [Upgrading (v.1.1 to >=v.1.2)](#upgrading-to-version--12)
24 24
    + [Composer](#via-composer)
25 25
    + [Contao Manager](#via-contao-manager)
26 26
 + [Initial Setup](#initial-setup)
... ...
@@ -36,7 +36,7 @@ Additionally, you can display members with their details in a reader page.
36 36
 
37 37
 ## Features
38 38
 
39
-- Compatible with Contao 4.9 and higher versions (PHP 8 Support)
39
+- Compatible with Contao 4.13 (PHP ^8.0)
40 40
 - Extends members with avatars
41 41
 - Paginated member lists
42 42
 - Member detail pages
... ...
@@ -46,8 +46,8 @@ Additionally, you can display members with their details in a reader page.
46 46
 
47 47
 ## Installation
48 48
 
49
-#### Upgrading to version 1.2
50
-> After upgrading from version 1.1 to version 1.2, make sure to edit your modules (memberlist, memberreader and avatar/profile picture) and set up the new templates.
49
+#### Upgrading to version >=1.2
50
+> After upgrading from version 1.1 to version >=1.2, make sure to edit your modules (memberlist, memberreader and avatar/profile picture) and set up the new templates.
51 51
 
52 52
 #### Via composer
53 53
 ```
... ...
@@ -72,7 +72,7 @@ detail pages.
72 72
     ![Admin View: Member overview](https://www.oveleon.de/share/github-assets/contao-member-extension-bundle/default_avatar.jpg)
73 73
     ![Admin View: Member settings](https://www.oveleon.de/share/github-assets/contao-member-extension-bundle/default_avatar_setup.jpg)
74 74
 
75
-2. To display your members, you need to setup a memberlist
75
+2. To display your members, you need to set up a memberlist
76 76
    1. Create the front end module *memberlist*
77 77
    2. Choose the member groups and the member fields that should be displayed
78 78
    3. Optionally you can set up a redirect page to your memberreader
... ...
@@ -2,13 +2,13 @@
2 2
     "name": "oveleon/contao-member-extension-bundle",
3 3
     "type": "contao-bundle",
4 4
     "description": "Member feature extension for Contao.",
5
+    "license": "MIT",
5 6
     "keywords": ["contao","member-extension-bundle"],
6 7
     "homepage": "https://oveleon.de/",
7
-    "license": "MIT",
8 8
     "authors": [
9 9
         {
10
-            "name": "Oveleon",
11
-            "homepage": "https://oveleon.de/",
10
+            "name": "Sebastian Zoglowek",
11
+            "homepage": "https://github.com/zoglo",
12 12
             "role": "Developer"
13 13
         },
14 14
         {
... ...
@@ -20,16 +20,11 @@
20 20
             "name": "Fabian Ekert",
21 21
             "homepage": "https://github.com/eki89",
22 22
             "role": "Developer"
23
-        },
24
-        {
25
-            "name": "Sebastian Zoglowek",
26
-            "homepage": "https://github.com/zoglo",
27
-            "role": "Developer"
28 23
         }
29 24
     ],
30 25
     "require": {
31
-        "php": "^7.4 || ^8.0",
32
-        "contao/core-bundle":"^4.9"
26
+        "php": "^8.0",
27
+        "contao/core-bundle": "^4.13"
33 28
     },
34 29
     "require-dev": {
35 30
         "contao/manager-plugin": "^2.3.1"
... ...
@@ -38,33 +33,28 @@
38 33
         "contao/core": "*",
39 34
         "contao/manager-plugin": "<2.0 || >=3.0"
40 35
     },
36
+    "extra": {
37
+        "branch-alias": {
38
+            "dev-master": "1.3.x-dev"
39
+        },
40
+        "contao-manager-plugin": "Oveleon\\ContaoMemberExtensionBundle\\ContaoManager\\Plugin"
41
+    },
41 42
     "autoload": {
42 43
         "psr-4": {
43 44
             "Oveleon\\ContaoMemberExtensionBundle\\": "src/"
44 45
         },
45 46
         "classmap": [
46
-            "src/Resources/contao/"
47
+            "contao/"
47 48
         ],
48 49
         "exclude-from-classmap": [
49
-            "src/Resources/contao/config/",
50
-            "src/Resources/contao/dca/",
51
-            "src/Resources/contao/languages/",
52
-            "src/Resources/contao/templates/"
50
+            "contao/config/",
51
+            "contao/dca/",
52
+            "contao/languages/",
53
+            "contao/templates/"
53 54
         ]
54 55
     },
55
-    "extra": {
56
-        "branch-alias": {
57
-            "dev-master": "1.2.x-dev"
58
-        },
59
-        "contao-manager-plugin": "Oveleon\\ContaoMemberExtensionBundle\\ContaoManager\\Plugin"
60
-    },
61
-    "config": {
62
-        "allow-plugins": {
63
-            "contao-components/installer": true,
64
-            "contao/manager-plugin": true
65
-        }
66
-    },
67 56
     "support": {
68
-        "issues": "https://github.com/oveleon/contao-member-extension-bundle/issues"
57
+        "issues": "https://github.com/oveleon/contao-member-extension-bundle/issues",
58
+        "source": "https://github.com/oveleon/contao-member-extension-bundle"
69 59
     }
70
-}
71 60
\ No newline at end of file
61
+}
72 62
new file mode 100644
... ...
@@ -0,0 +1,8 @@
1
+services:
2
+    contao_member.listener.insert_tags:
3
+        class: Oveleon\ContaoMemberExtensionBundle\EventListener\InsertTagsListener
4
+        arguments:
5
+            - '@contao.framework'
6
+        tags:
7
+          - { name: contao.hook, hook: replaceInsertTags }
8
+        public: true
0 9
new file mode 100644
... ...
@@ -0,0 +1,332 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of Oveleon ContaoMemberExtension Bundle.
7
+ *
8
+ * @package     contao-member-extension-bundle
9
+ * @license     MIT
10
+ * @author      Sebastian Zoglowek     <https://github.com/zoglo>
11
+ * @author      Daniele Sciannimanica  <https://github.com/doishub>
12
+ * @author      Fabian Ekert           <https://github.com/eki89>
13
+ * @copyright   Oveleon                <https://www.oveleon.de/>
14
+ */
15
+
16
+namespace Oveleon\ContaoMemberExtensionBundle;
17
+
18
+use Contao\Config;
19
+use Contao\CoreBundle\Monolog\ContaoContext;
20
+use Contao\Dbafs;
21
+use Contao\File;
22
+use Contao\FilesModel;
23
+use Contao\FileUpload;
24
+use Contao\Frontend;
25
+use Contao\FrontendUser;
26
+use Contao\MemberModel;
27
+use Contao\StringUtil;
28
+use Contao\System;
29
+use Contao\Validator;
30
+use Psr\Log\LogLevel;
31
+
32
+/**
33
+ * Class Member
34
+ *
35
+ * @property int $avatar UUID of the avatar
36
+ */
37
+class Member extends Frontend
38
+{
39
+    const DEFAULT_PICTURE = 'bundles/contaomemberextension/avatar.png';
40
+
41
+    /**
42
+     * MemberAvatar file name
43
+     */
44
+    protected string $avatarName = 'memberAvatar';
45
+
46
+    /**
47
+     * Create avatar for a member | Registration
48
+     */
49
+    public function createAvatar(int $userId, array $arrData): void
50
+    {
51
+        $objMember = MemberModel::findById($userId);
52
+        $this->processAvatar($objMember, $arrData);
53
+    }
54
+
55
+    /**
56
+     * Update avatar of a member | Login
57
+     */
58
+    public function updateAvatar(FrontendUser $objUser, array $arrData): void
59
+    {
60
+        $objMember = MemberModel::findById($objUser->id);
61
+        $this->processAvatar($objMember, $arrData);
62
+    }
63
+
64
+    /**
65
+     * Process avatar upload for a member
66
+     */
67
+    protected function processAvatar(MemberModel $objMember, ?array $arrData): void
68
+    {
69
+        $objMember = MemberModel::findByPk($objMember->id);
70
+
71
+        if ($objMember === null)
72
+        {
73
+            return;
74
+        }
75
+
76
+        // ToDo: remove $_SESSION when contao 4.13 support ends (Contao ^5.* is not possible with Contao 4.* support)
77
+        $file = $_SESSION['FILES']['avatar'];
78
+        $maxlength_kb = $this->getMaximumUploadSize();
79
+        $maxlength_kb_readable = $this->getReadableSize($maxlength_kb);
80
+
81
+        // Sanitize the filename
82
+        try
83
+        {
84
+            $file['name'] = StringUtil::sanitizeFileName($file['name']);
85
+        }
86
+        catch (\InvalidArgumentException $e)
87
+        {
88
+            // ToDo: add error message for invalid characters
89
+            return;
90
+        }
91
+
92
+        // Invalid file name
93
+        if (!Validator::isValidFileName($file['name']))
94
+        {
95
+            // ToDo: add error message for invalid characters
96
+            return;
97
+        }
98
+
99
+        // File was not uploaded
100
+        if (!is_uploaded_file($file['tmp_name']))
101
+        {
102
+            // ToDo: Add error messages
103
+            /*if ($file['error'] == 1 || $file['error'] == 2) { // Add error message for maximum file size }
104
+            elseif ($file['error'] == 3) { // Add error message for partial upload }
105
+            elseif ($file['error'] > 0) { // Add error message for failed upload }*/
106
+
107
+            unset($_SESSION['FILES']['avatar']);
108
+
109
+            return;
110
+        }
111
+
112
+        // File is too big
113
+        if ($file['size'] > $maxlength_kb)
114
+        {
115
+            // ToDo: add error message for maximum file size
116
+            unset($_SESSION['FILES']['avatar']);
117
+
118
+            return;
119
+        }
120
+
121
+        $objFile = new File($file['name']);
122
+        $uploadTypes = StringUtil::trimsplit(',', Config::get('validImageTypes'));
123
+
124
+        // File type is not allowed
125
+        if (!\in_array($objFile->extension, $uploadTypes))
126
+        {
127
+            // ToDo: add error message for not allowed file type
128
+            unset($_SESSION['FILES']['avatar']);
129
+
130
+            return;
131
+        }
132
+
133
+        if ($arrImageSize = @getimagesize($file['tmp_name']))
134
+        {
135
+            $intImageWidth = Config::get('imageWidth');
136
+
137
+            // Image exceeds maximum image width
138
+            if ($intImageWidth > 0 && $arrImageSize[0] > $intImageWidth) {
139
+                // ToDo: add error message for exceeding width
140
+                unset($_SESSION['FILES']['avatar']);
141
+
142
+                return;
143
+            }
144
+
145
+            $intImageHeight = Config::get('imageHeight');
146
+
147
+            // Image exceeds maximum image height
148
+            if ($intImageHeight > 0 && $arrImageSize[1] > $intImageHeight) {
149
+                // ToDo: add error message for exceeding height
150
+                unset($_SESSION['FILES']['avatar']);
151
+
152
+                return;
153
+            }
154
+        }
155
+
156
+        // Upload valid file type with no width and height -> svg
157
+
158
+        // Don't upload if no homedir is assigned
159
+        // ToDo: Create homedir?
160
+        if (!$objMember->assignDir || !$objMember->homeDir)
161
+        {
162
+            // ToDo: add error message for no homedir
163
+            return;
164
+        }
165
+
166
+        $intUploadFolder = $objMember->homeDir;
167
+
168
+        $objUploadFolder = FilesModel::findByUuid($intUploadFolder);
169
+
170
+        // The upload folder could not be found
171
+        if ($objUploadFolder === null)
172
+        {
173
+            throw new Exception("Invalid upload folder ID $intUploadFolder");
174
+        }
175
+
176
+        $strUploadFolder = $objUploadFolder->path;
177
+
178
+        // Store the file if the upload folder exists
179
+        $projectDir = System::getContainer()->getParameter('kernel.project_dir');
180
+
181
+        if (!!$strUploadFolder & is_dir($projectDir . '/' . $strUploadFolder))
182
+        {
183
+            // Delete existing avatar if it exists
184
+            $this->deleteAvatar($objMember);
185
+
186
+            $this->import('Files');
187
+
188
+            // Rename file
189
+            $file['name'] =  $this->avatarName . '.' . $objFile->extension;
190
+
191
+            // Move the file to its destination
192
+            $this->Files->move_uploaded_file($file['tmp_name'], $strUploadFolder . '/' . $file['name']);
193
+            $this->Files->chmod($strUploadFolder . '/' . $file['name'], 0666 & ~umask());
194
+
195
+            $strUuid = null;
196
+            $strFile = $strUploadFolder . '/' . $file['name'];
197
+
198
+
199
+            // Generate the DB entries
200
+            if (Dbafs::shouldBeSynchronized($strFile))
201
+            {
202
+                $objModel = FilesModel::findByPath($strFile);
203
+
204
+                if ($objModel === null)
205
+                {
206
+                    $objModel = Dbafs::addResource($strFile);
207
+                }
208
+
209
+                $strUuid = StringUtil::binToUuid($objModel->uuid);
210
+
211
+                // Update the hash of the target folder
212
+                Dbafs::updateFolderHashes($strUploadFolder);
213
+
214
+                // Update member avatar
215
+                $objMember->avatar = $objModel->uuid;
216
+                $objMember->save();
217
+            }
218
+
219
+            // Add the session entry
220
+            $_SESSION['FILES']['avatar'] = array
221
+            (
222
+                'name'     => $file['name'],
223
+                'type'     => $file['type'],
224
+                'tmp_name' => $projectDir . '/' . $strFile,
225
+                'error'    => $file['error'],
226
+                'size'     => $file['size'],
227
+                'uploaded' => true,
228
+                'uuid'     => $strUuid
229
+            );
230
+
231
+            // Add a log entry
232
+            $logger = System::getContainer()->get('monolog.logger.contao');
233
+            $logger->log(LogLevel::INFO, 'File "' . $strUploadFolder . '/' . $file['name'] . '" has been uploaded', ['contao' => new ContaoContext(__METHOD__, TL_FILES)]);
234
+        }
235
+
236
+        unset($_SESSION['FILES']['avatar']);
237
+    }
238
+
239
+    /**
240
+     * Return the maximum upload file size in bytes
241
+     */
242
+    protected function getMaximumUploadSize()
243
+    {
244
+        if ($this->maxlength > 0)
245
+        {
246
+            return $this->maxlength;
247
+        }
248
+
249
+        return FileUpload::getMaxUploadSize();
250
+    }
251
+
252
+    /**
253
+     * Parses an avatar to the template
254
+     */
255
+    public static function parseMemberAvatar(?MemberModel $objMember, &$objTemplate, ?string $imgSize): void
256
+    {
257
+        $objTemplate->addImage= true;
258
+
259
+        $objTemplate->singleSRC = self::DEFAULT_PICTURE;
260
+        $objTemplate->addFallbackImage = true;
261
+
262
+        $projectDir = System::getContainer()->getParameter('kernel.project_dir');
263
+
264
+        // Check if member avatar exists
265
+        if (null === $objMember || null === $objMember->avatar || null === ($objFile = FilesModel::findByUuid($objMember->avatar)) || !\is_file($projectDir.'/'. $objFile->path))
266
+        {
267
+            $objFile = !!($uuidDefault = Config::get('defaultAvatar')) ? FilesModel::findByUuid($uuidDefault) : null;
268
+        }
269
+
270
+        // Check if config avatar exists
271
+        if (null === $objFile || !\is_file($projectDir . '/' . $objFile->path))
272
+        {
273
+            return;
274
+        }
275
+
276
+        $objTemplate->addFallbackImage = false;
277
+        $imgSize = $imgSize ?? null;
278
+
279
+        $figureBuilder = System::getContainer()
280
+            ->get('contao.image.studio')
281
+            ->createFigureBuilder()
282
+            ->from($objFile->path)
283
+            ->setSize($imgSize)
284
+        ;
285
+
286
+        if (null !== ($figure = $figureBuilder->buildIfResourceExists()))
287
+        {
288
+            $figure->applyLegacyTemplateData($objTemplate);
289
+        }
290
+    }
291
+
292
+    /**
293
+     * Gets the url for a member avatar
294
+     */
295
+    public static function getMemberAvatarURL(?MemberModel $objMember): string
296
+    {
297
+        // ToDo: Merge logic with parseMemberAvatar
298
+        $projectDir = System::getContainer()->getParameter('kernel.project_dir');
299
+
300
+        if (null === $objMember || null === $objMember->avatar || null === ($objFile = FilesModel::findByUuid($objMember->avatar)) || !\is_file($projectDir.'/'. $objFile->path))
301
+        {
302
+            $objFile = !!($uuidDefault = Config::get('defaultAvatar')) ? FilesModel::findByUuid($uuidDefault) : null;
303
+        }
304
+
305
+        // Check if config avatar exists
306
+        if (null === $objFile || !\is_file($projectDir . '/' . $objFile->path))
307
+        {
308
+            return self::DEFAULT_PICTURE;
309
+        }
310
+
311
+        return $objFile->path;
312
+    }
313
+
314
+    /**
315
+     * Deletes an avatar
316
+     */
317
+    public static function deleteAvatar(MemberModel $objMember): void
318
+    {
319
+        if (!!$objMember->avatar)
320
+        {
321
+            $objFile = FilesModel::findByUuid($objMember->avatar) ?: '';
322
+            $projectDir = System::getContainer()->getParameter('kernel.project_dir');
323
+
324
+            // Only delete if file exists
325
+            if (!!$objFile && file_exists($projectDir . '/' . $objFile->path))
326
+            {
327
+                $file = new File($objFile->path);
328
+                $file->delete();
329
+            }
330
+        }
331
+    }
332
+}
0 333
new file mode 100644
... ...
@@ -0,0 +1,34 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of Oveleon ContaoMemberExtension Bundle.
7
+ *
8
+ * @package     contao-member-extension-bundle
9
+ * @license     MIT
10
+ * @author      Sebastian Zoglowek     <https://github.com/zoglo>
11
+ * @author      Daniele Sciannimanica  <https://github.com/doishub>
12
+ * @author      Fabian Ekert           <https://github.com/eki89>
13
+ * @copyright   Oveleon                <https://www.oveleon.de/>
14
+ */
15
+
16
+// Back end modules
17
+use Contao\ArrayUtil;
18
+
19
+$GLOBALS['BE_MOD']['system']['member_settings'] = [
20
+    'tables'            => ['tl_member_settings'],
21
+    'hideInNavigation'  => true,
22
+];
23
+
24
+// Front end modules
25
+ArrayUtil::arrayInsert($GLOBALS['FE_MOD']['user'], -1, [
26
+    'avatar'       => 'Oveleon\ContaoMemberExtensionBundle\ModuleAvatar',
27
+    'deleteAvatar' => 'Oveleon\ContaoMemberExtensionBundle\ModuleDeleteAvatar',
28
+    'memberList'   => 'Oveleon\ContaoMemberExtensionBundle\ModuleMemberList',
29
+    'memberReader' => 'Oveleon\ContaoMemberExtensionBundle\ModuleMemberReader'
30
+]);
31
+
32
+// Register hooks
33
+$GLOBALS['TL_HOOKS']['createNewUser'][] =      ['Oveleon\ContaoMemberExtensionBundle\Member', 'createAvatar'];
34
+$GLOBALS['TL_HOOKS']['updatePersonalData'][] = ['Oveleon\ContaoMemberExtensionBundle\Member', 'updateAvatar'];
0 35
new file mode 100644
... ...
@@ -0,0 +1,40 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of Oveleon ContaoMemberExtension Bundle.
7
+ *
8
+ * @package     contao-member-extension-bundle
9
+ * @license     MIT
10
+ * @author      Sebastian Zoglowek     <https://github.com/zoglo>
11
+ * @author      Daniele Sciannimanica  <https://github.com/doishub>
12
+ * @author      Fabian Ekert           <https://github.com/eki89>
13
+ * @copyright   Oveleon                <https://www.oveleon.de/>
14
+ */
15
+
16
+use Contao\Config;
17
+use Contao\CoreBundle\DataContainer\PaletteManipulator;
18
+
19
+// Extend the default palette
20
+PaletteManipulator::create()
21
+    ->addField(['avatar'], 'personal_legend', PaletteManipulator::POSITION_APPEND)
22
+    ->applyToPalette('default', 'tl_member')
23
+;
24
+
25
+// Add global operations
26
+$GLOBALS['TL_DCA']['tl_member']['list']['global_operations']['settings'] = [
27
+    'label'         => &$GLOBALS['TL_LANG']['tl_member']['settings'],
28
+    'href'          => 'do=member_settings',
29
+    'icon'          => 'edit.svg',
30
+    'attributes'    => 'onclick="Backend.getScrollOffset()" accesskey="e"'
31
+];
32
+
33
+// Add fields to tl_user
34
+$GLOBALS['TL_DCA']['tl_member']['fields']['avatar'] = [
35
+    'label'         => &$GLOBALS['TL_LANG']['tl_member']['avatar'],
36
+    'exclude'       => true,
37
+    'inputType'     => 'fileTree',
38
+    'eval'          => ['feEditable'=>true, 'feViewable'=>true, 'feGroup'=>'personal', 'fieldType'=>'radio', 'filesOnly'=>true, 'isGallery'=>true, 'extensions'=>Config::get('validImageTypes'), 'tl_class'=>'clr'],
39
+    'sql'           => "binary(16) NULL"
40
+];
0 41
new file mode 100644
... ...
@@ -0,0 +1,34 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of Oveleon ContaoMemberExtension Bundle.
7
+ *
8
+ * @package     contao-member-extension-bundle
9
+ * @license     MIT
10
+ * @author      Sebastian Zoglowek     <https://github.com/zoglo>
11
+ * @author      Daniele Sciannimanica  <https://github.com/doishub>
12
+ * @author      Fabian Ekert           <https://github.com/eki89>
13
+ * @copyright   Oveleon                <https://www.oveleon.de/>
14
+ */
15
+
16
+use Contao\Config;
17
+
18
+$GLOBALS['TL_DCA']['tl_member_settings'] = [
19
+
20
+    'config' => [
21
+        'dataContainer' => 'File',
22
+        'closed' => true
23
+    ],
24
+
25
+    'palettes' => ['default' =>'{avatar_legend},defaultAvatar;'],
26
+
27
+    'fields' => [
28
+        'defaultAvatar' => [
29
+            'label'     => &$GLOBALS['TL_LANG']['tl_member_settings']['defaultAvatar'],
30
+            'inputType' => 'fileTree',
31
+            'eval'      => ['fieldType'=>'radio', 'filesOnly'=>true, 'isGallery'=>true, 'extensions'=>Config::get('validImageTypes'), 'tl_class'=>'clr']
32
+        ]
33
+    ]
34
+];
0 35
new file mode 100644
... ...
@@ -0,0 +1,130 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of Oveleon ContaoMemberExtension Bundle.
7
+ *
8
+ * @package     contao-member-extension-bundle
9
+ * @license     MIT
10
+ * @author      Sebastian Zoglowek     <https://github.com/zoglo>
11
+ * @author      Daniele Sciannimanica  <https://github.com/doishub>
12
+ * @author      Fabian Ekert           <https://github.com/eki89>
13
+ * @copyright   Oveleon                <https://www.oveleon.de/>
14
+ */
15
+
16
+use Contao\Backend;
17
+use Contao\Controller;
18
+use Contao\System;
19
+
20
+System::loadLanguageFile('tl_member_settings');
21
+
22
+// Add palettes to tl_module
23
+$GLOBALS['TL_DCA']['tl_module']['palettes']['avatar']       = '{title_legend},name,headline,type;{source_legend},imgSize;{template_legend:hide},customTpl;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID';
24
+$GLOBALS['TL_DCA']['tl_module']['palettes']['deleteAvatar'] = '{title_legend},name,headline,type;{template_legend:hide},customTpl;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID';
25
+$GLOBALS['TL_DCA']['tl_module']['palettes']['memberList']   = '{title_legend},name,headline,type;{config_legend},ext_order,ext_orderField,numberOfItems,perPage,ext_groups,memberFields,imgSize;{redirect_legend},jumpTo;{template_legend:hide},customTpl,memberListTpl;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID';
26
+$GLOBALS['TL_DCA']['tl_module']['palettes']['memberReader'] = '{title_legend},name,headline,type;{config_legend},ext_groups,memberFields,imgSize;{template_legend:hide},customTpl,memberReaderTpl;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID';
27
+
28
+$GLOBALS['TL_DCA']['tl_module']['fields']['memberListTpl'] = [
29
+    'exclude' => true,
30
+    'inputType' => 'select',
31
+    'options_callback' => static fn () => Controller::getTemplateGroup('memberExtension_list_'),
32
+    'eval' => ['includeBlankOption'=>true, 'chosen'=>true, 'tl_class'=>'w50'],
33
+    'sql' => "varchar(64) NOT NULL default ''"
34
+];
35
+
36
+$GLOBALS['TL_DCA']['tl_module']['fields']['memberReaderTpl'] = [
37
+    'exclude' => true,
38
+    'inputType' => 'select',
39
+    'options_callback' => static fn () => Controller::getTemplateGroup('memberExtension_reader_'),
40
+    'eval' => ['includeBlankOption'=>true, 'chosen'=>true, 'tl_class'=>'w50'],
41
+    'sql' => "varchar(64) NOT NULL default ''"
42
+];
43
+
44
+$GLOBALS['TL_DCA']['tl_module']['fields']['ext_order'] = [
45
+    'exclude' => true,
46
+    'inputType' => 'select',
47
+    'options' => ['order_random', 'order_asc', 'order_desc'],
48
+    'reference' => &$GLOBALS['TL_LANG']['tl_member_settings'],
49
+    'eval' => ['tl_class'=>'w50 clr', 'includeBlankOption'=>true, 'chosen'=>true,],
50
+    'sql' => "varchar(32) NOT NULL default ''"
51
+];
52
+
53
+$GLOBALS['TL_DCA']['tl_module']['fields']['ext_orderField'] = [
54
+    'exclude' => true,
55
+    'inputType' => 'select',
56
+    'options_callback' => ['tl_module_extension', 'getViewableMemberFields'],
57
+    'eval' => ['tl_class'=>'w50', 'includeBlankOption'=>true, 'chosen'=>true,],
58
+    'sql' => "varchar(32) NOT NULL default ''"
59
+];
60
+
61
+$GLOBALS['TL_DCA']['tl_module']['fields']['memberFields'] = [
62
+    'exclude' => true,
63
+    'inputType' => 'checkboxWizard',
64
+    'options_callback' => ['tl_module_extension', 'getMemberProperties'],
65
+    'eval' => ['multiple'=>true, 'tl_class'=>'clr'],
66
+    'sql' => "blob NULL"
67
+];
68
+
69
+$GLOBALS['TL_DCA']['tl_module']['fields']['ext_groups'] = [
70
+    'exclude' => true,
71
+    'inputType' => 'checkbox',
72
+    'foreignKey' => 'tl_member_group.name',
73
+    'eval' => ['multiple'=>true, 'tl_class'=>'clr'],
74
+    'sql' => "blob NULL",
75
+    'relation' => ['type'=>'hasMany', 'load'=>'lazy']
76
+];
77
+
78
+class tl_module_extension extends Backend
79
+{
80
+    /**
81
+     * Import the back end user object
82
+     */
83
+    public function __construct()
84
+    {
85
+        parent::__construct();
86
+        $this->import('Contao\BackendUser', 'User');
87
+    }
88
+
89
+    /**
90
+     * Return all fields of table tl_member without account data
91
+     */
92
+    public function getMemberProperties(): array
93
+    {
94
+        $return = [];
95
+
96
+        Contao\System::loadLanguageFile('tl_member');
97
+        $this->loadDataContainer('tl_member');
98
+
99
+        foreach ($GLOBALS['TL_DCA']['tl_member']['fields'] as $k=>$v)
100
+        {
101
+            if (!empty($v['inputType']) && $v['inputType'] !== 'password')
102
+            {
103
+                $return[$k] = $GLOBALS['TL_DCA']['tl_member']['fields'][$k]['label'][0];
104
+            }
105
+        }
106
+
107
+        return $return;
108
+    }
109
+
110
+    /**
111
+     * Return all sortable fields of table tl_member
112
+     */
113
+    public function getViewableMemberFields(): array
114
+    {
115
+        $return = [];
116
+
117
+        Contao\System::loadLanguageFile('tl_member');
118
+        $this->loadDataContainer('tl_member');
119
+
120
+        foreach ($GLOBALS['TL_DCA']['tl_member']['fields'] as $k=>$v)
121
+        {
122
+            if (!empty($v['inputType']) && $k !== 'avatar' && isset($v['eval']['feViewable']) && $v['eval']['feViewable'] === true)
123
+            {
124
+                $return[$k] = $GLOBALS['TL_DCA']['tl_member']['fields'][$k]['label'][0] . ' ['.$k.']';
125
+            }
126
+        }
127
+
128
+        return $return;
129
+    }
130
+}
0 131
new file mode 100644
... ...
@@ -0,0 +1,22 @@
1
+<?xml version="1.0" ?><xliff version="1.1">
2
+  <file datatype="php" original="contao/languages/en/default.php" source-language="en" target-language="de">
3
+    <body>
4
+      <trans-unit id="MSC.emptyMemberList">
5
+        <source>No members could be found.</source>
6
+        <target>Es konnten keine Mitglieder gefunden werden.</target>
7
+      </trans-unit>
8
+      <trans-unit id="MSC.memberDetail">
9
+        <source>More</source>
10
+        <target>Mehr</target>
11
+      </trans-unit>
12
+      <trans-unit id="MSC.deleteAvatar">
13
+        <source>Delete avatar</source>
14
+        <target>Profilbild löschen</target>
15
+      </trans-unit>
16
+      <trans-unit id="MSC.avatarDeleted">
17
+        <source>The avatar was successfully deleted</source>
18
+        <target>Das Profilbild wurde erfolgreich gelöscht</target>
19
+      </trans-unit>
20
+    </body>
21
+  </file>
22
+</xliff>
0 23
new file mode 100644
... ...
@@ -0,0 +1,46 @@
1
+<?xml version="1.0" ?><xliff version="1.1">
2
+  <file datatype="php" original="contao/languages/en/modules.php" source-language="en" target-language="de">
3
+    <body>
4
+      <trans-unit id="MOD.member_settings.0">
5
+        <source>Member settings</source>
6
+        <target>Mitglieder-Einstellungen</target>
7
+      </trans-unit>
8
+      <trans-unit id="MOD.member_settings.1">
9
+        <source>Configure member settings</source>
10
+        <target>Mitglieder-Einstellungen vornehmen</target>
11
+      </trans-unit>
12
+      <trans-unit id="FMD.avatar.0">
13
+        <source>Profile picture / Avatar</source>
14
+        <target>Profilbild / Avatar</target>
15
+      </trans-unit>
16
+      <trans-unit id="FMD.avatar.1">
17
+        <source>Displays the profile picture of the member.</source>
18
+        <target>Zeigt das Profilbild des Mitgliedes an.</target>
19
+      </trans-unit>
20
+      <trans-unit id="FMD.deleteAvatar.0">
21
+        <source>Delete avatar</source>
22
+        <target>Profilbild löschen</target>
23
+      </trans-unit>
24
+      <trans-unit id="FMD.deleteAvatar.1">
25
+        <source>Adds a button to delete the avatar of the member.</source>
26
+        <target>Fügt eine Schaltfläche zum Löschen des Profilbildes hinzu.</target>
27
+      </trans-unit>
28
+      <trans-unit id="FMD.memberList.0">
29
+        <source>Memberlist</source>
30
+        <target>Mitgliederliste</target>
31
+      </trans-unit>
32
+      <trans-unit id="FMD.memberList.1">
33
+        <source>Displays a list of members.</source>
34
+        <target>Gibt eine Liste der Mitglieder aus.</target>
35
+      </trans-unit>
36
+      <trans-unit id="FMD.memberReader.0">
37
+        <source>Memberreader</source>
38
+        <target>Mitgliedleser</target>
39
+      </trans-unit>
40
+      <trans-unit id="FMD.memberReader.1">
41
+        <source>Displays a members details.</source>
42
+        <target>Gibt eine Details eines Mitglieds aus.</target>
43
+      </trans-unit>
44
+    </body>
45
+  </file>
46
+</xliff>
0 47
new file mode 100644
... ...
@@ -0,0 +1,22 @@
1
+<?xml version="1.0" ?><xliff version="1.1">
2
+  <file datatype="php" original="contao/languages/en/tl_member.php" source-language="en" target-language="de">
3
+    <body>
4
+      <trans-unit id="tl_member.avatar.0">
5
+        <source>Profile picture</source>
6
+        <target>Profilbild</target>
7
+      </trans-unit>
8
+      <trans-unit id="tl_member.avatar.1">
9
+        <source>Here you can choose a profile picture for the member.</source>
10
+        <target>Hier können Sie ein Profilbild für das Mitglied auswählen.</target>
11
+      </trans-unit>
12
+      <trans-unit id="tl_member.settings.0">
13
+        <source>Settings</source>
14
+        <target>Einstellungen</target>
15
+      </trans-unit>
16
+      <trans-unit id="tl_member.settings.1">
17
+        <source>Member settings</source>
18
+        <target>Mitglieder-Einstellungen</target>
19
+      </trans-unit>
20
+    </body>
21
+  </file>
22
+</xliff>
0 23
\ No newline at end of file
1 24
new file mode 100644
... ...
@@ -0,0 +1,30 @@
1
+<?xml version="1.0" ?><xliff version="1.1">
2
+  <file datatype="php" original="contao/languages/en/tl_member.php" source-language="en" target-language="de">
3
+    <body>
4
+      <trans-unit id="tl_member_settings.avatar_legend">
5
+        <source>Extended member settings</source>
6
+        <target>Erweiterte Mitgliedseinstellungen</target>
7
+      </trans-unit>
8
+      <trans-unit id="tl_member_settings.defaultAvatar.0">
9
+        <source>Default avatar</source>
10
+        <target>Standard-Profilbild</target>
11
+      </trans-unit>
12
+      <trans-unit id="tl_member_settings.defaultAvatar.1">
13
+        <source>The default avatar is displayed for members who have not uploaded their own profile picture.</source>
14
+        <target>Das Standard-Profilbild wird bei Mitgliedern angezeigt, welches kein eigenes Profilbild hochgeladen haben.</target>
15
+      </trans-unit>
16
+      <trans-unit id="tl_member_settings.order_random">
17
+        <source>Random order</source>
18
+        <target>Zufällige Reihenfolge</target>
19
+      </trans-unit>
20
+      <trans-unit id="tl_member_settings.order_asc">
21
+        <source>Ascending</source>
22
+        <target>Aufsteigend</target>
23
+      </trans-unit>
24
+      <trans-unit id="tl_member_settings.order_desc">
25
+        <source>Descending</source>
26
+        <target>Absteigend</target>
27
+      </trans-unit>
28
+    </body>
29
+  </file>
30
+</xliff>
0 31
new file mode 100644
... ...
@@ -0,0 +1,62 @@
1
+<?xml version="1.0" ?><xliff version="1.1">
2
+  <file datatype="php" original="contao/languages/en/tl_module.php" source-language="en" target-language="de">
3
+    <body>
4
+      <trans-unit id="tl_module.ext_order.0">
5
+        <source>Sort order</source>
6
+        <target>Sortierreihenfolge</target>
7
+      </trans-unit>
8
+      <trans-unit id="tl_module.ext_order.1">
9
+        <source>Here you can choose the sort order.</source>
10
+        <target>Hier können Sie die Sortierreihenfolge festlegen.</target>
11
+      </trans-unit>
12
+      <trans-unit id="tl_module.ext_orderField.0">
13
+        <source>Sorting field</source>
14
+        <target>Sortierfeld</target>
15
+      </trans-unit>
16
+      <trans-unit id="tl_module.ext_orderField.1">
17
+        <source>Here you can select the field to be sorted by.</source>
18
+        <target>Hier können Sie das Feld auswählen, nach dem sortiert werden soll.</target>
19
+      </trans-unit>
20
+      <trans-unit id="tl_module.ext_groups.0">
21
+        <source>Groups to show</source>
22
+        <target>Anzuzeigende Gruppen</target>
23
+      </trans-unit>
24
+      <trans-unit id="tl_module.ext_groups.1">
25
+        <source>Here you can select the member groups to be displayed.</source>
26
+        <target>Hier können Sie die Mitgliedergruppen auswählen, die angezeigt werden sollen.</target>
27
+      </trans-unit>
28
+      <trans-unit id="tl_module.memberFields.0">
29
+        <source>Member fields</source>
30
+        <target>Mitglieds-Felder</target>
31
+      </trans-unit>
32
+      <trans-unit id="tl_module.memberFields.1">
33
+        <source>Here you can select the member fields to be displayed.</source>
34
+        <target>Hier können Sie die auszugebenden Mitgliederfelder auswählen.</target>
35
+      </trans-unit>
36
+      <trans-unit id="tl_module.memberFields.0">
37
+        <source>Member fields</source>
38
+        <target>Mitglieds-Felder</target>
39
+      </trans-unit>
40
+      <trans-unit id="tl_module.memberFields.1">
41
+        <source>Here you can select the member fields to be output.</source>
42
+        <target>Hier können Sie die auszugebenden Mitgliederfelder auswählen.</target>
43
+      </trans-unit>
44
+      <trans-unit id="tl_module.memberListTpl.0">
45
+        <source>List template</source>
46
+        <target>Listen-Template</target>
47
+      </trans-unit>
48
+      <trans-unit id="tl_module.memberListTpl.1">
49
+        <source>Here you can set your own member list template.</source>
50
+        <target>Hier können Sie ein eigenes Mitglieder-Listen Template einstellen.</target>
51
+      </trans-unit>
52
+      <trans-unit id="tl_module.memberReaderTpl.0">
53
+        <source>Reader template</source>
54
+        <target>Leser-Template</target>
55
+      </trans-unit>
56
+      <trans-unit id="tl_module.memberReaderTpl.1">
57
+        <source>Here you can set your own member reader template.</source>
58
+        <target>Hier können Sie ein eigenes Mitglieds-Leser Template einstellen.</target>
59
+      </trans-unit>
60
+    </body>
61
+  </file>
62
+</xliff>
0 63
new file mode 100644
... ...
@@ -0,0 +1,18 @@
1
+<?xml version="1.0" ?><xliff version="1.1">
2
+  <file datatype="php" original="contao/languages/en/default.php" source-language="en">
3
+    <body>
4
+      <trans-unit id="MSC.emptyMemberList">
5
+        <source>No members could be found.</source>
6
+      </trans-unit>
7
+      <trans-unit id="MSC.memberDetail">
8
+        <source>More</source>
9
+      </trans-unit>
10
+      <trans-unit id="MSC.deleteAvatar">
11
+        <source>Delete avatar</source>
12
+      </trans-unit>
13
+      <trans-unit id="MSC.avatarDeleted">
14
+        <source>The avatar was successfully deleted</source>
15
+      </trans-unit>
16
+    </body>
17
+  </file>
18
+</xliff>
0 19
new file mode 100644
... ...
@@ -0,0 +1,36 @@
1
+<?xml version="1.0" ?><xliff version="1.1">
2
+  <file datatype="php" original="contao/languages/en/modules.php" source-language="en">
3
+    <body>
4
+      <trans-unit id="MOD.member_settings.0">
5
+        <source>Member settings</source>
6
+      </trans-unit>
7
+      <trans-unit id="MOD.member_settings.1">
8
+        <source>Configure member settings</source>
9
+      </trans-unit>
10
+      <trans-unit id="FMD.avatar.0">
11
+        <source>Avatar / profile picture</source>
12
+      </trans-unit>
13
+      <trans-unit id="FMD.avatar.1">
14
+        <source>Displays the avatar of the member.</source>
15
+      </trans-unit>
16
+      <trans-unit id="FMD.deleteAvatar.0">
17
+        <source>Delete avatar</source>
18
+      </trans-unit>
19
+      <trans-unit id="FMD.deleteAvatar.1">
20
+        <source>Adds a button to delete the avatar of the member.</source>
21
+      </trans-unit>
22
+      <trans-unit id="FMD.memberList.0">
23
+        <source>Memberlist</source>
24
+      </trans-unit>
25
+      <trans-unit id="FMD.memberList.1">
26
+        <source>Displays a list of members.</source>
27
+      </trans-unit>
28
+      <trans-unit id="FMD.memberReader.0">
29
+        <source>Memberreader</source>
30
+      </trans-unit>
31
+      <trans-unit id="FMD.memberReader.1">
32
+        <source>Displays a members details.</source>
33
+      </trans-unit>
34
+    </body>
35
+  </file>
36
+</xliff>
0 37
new file mode 100644
... ...
@@ -0,0 +1,18 @@
1
+<?xml version="1.0" ?><xliff version="1.1">
2
+  <file datatype="php" original="contao/languages/en/tl_member.php" source-language="en">
3
+    <body>
4
+      <trans-unit id="tl_member.avatar.0">
5
+        <source>Avatar</source>
6
+      </trans-unit>
7
+      <trans-unit id="tl_member.avatar.1">
8
+        <source>Here you can choose an avatar for the member.</source>
9
+      </trans-unit>
10
+      <trans-unit id="tl_member.settings.0">
11
+        <source>Settings</source>
12
+      </trans-unit>
13
+      <trans-unit id="tl_member.settings.1">
14
+        <source>Member settings</source>
15
+      </trans-unit>
16
+    </body>
17
+  </file>
18
+</xliff>
0 19
\ No newline at end of file
1 20
new file mode 100644
... ...
@@ -0,0 +1,24 @@
1
+<?xml version="1.0" ?><xliff version="1.1">
2
+  <file datatype="php" original="contao/languages/en/tl_member.php" source-language="en">
3
+    <body>
4
+      <trans-unit id="tl_member_settings.avatar_legend">
5
+        <source>Extended member settings</source>
6
+      </trans-unit>
7
+      <trans-unit id="tl_member_settings.defaultAvatar.0">
8
+        <source>Default avatar</source>
9
+      </trans-unit>
10
+      <trans-unit id="tl_member_settings.defaultAvatar.1">
11
+        <source>The default avatar is displayed for members who have not uploaded their own profile picture.</source>
12
+      </trans-unit>
13
+      <trans-unit id="tl_member_settings.order_random">
14
+        <source>Random order</source>
15
+      </trans-unit>
16
+      <trans-unit id="tl_member_settings.order_asc">
17
+        <source>Ascending</source>
18
+      </trans-unit>
19
+      <trans-unit id="tl_member_settings.order_desc">
20
+        <source>Descending</source>
21
+      </trans-unit>
22
+    </body>
23
+  </file>
24
+</xliff>
0 25
new file mode 100644
... ...
@@ -0,0 +1,48 @@
1
+<?xml version="1.0" ?><xliff version="1.1">
2
+  <file datatype="php" original="contao/languages/en/tl_module.php" source-language="en">
3
+    <body>
4
+      <trans-unit id="tl_module.ext_order.0">
5
+        <source>Sort order</source>
6
+      </trans-unit>
7
+      <trans-unit id="tl_module.ext_order.1">
8
+        <source>Here you can choose the sort order.</source>
9
+      </trans-unit>
10
+      <trans-unit id="tl_module.ext_orderField.0">
11
+        <source>Sorting field</source>
12
+      </trans-unit>
13
+      <trans-unit id="tl_module.ext_orderField.1">
14
+        <source>Here you can select the field to be sorted by.</source>
15
+      </trans-unit>
16
+      <trans-unit id="tl_module.ext_groups.0">
17
+        <source>Groups to show</source>
18
+      </trans-unit>
19
+      <trans-unit id="tl_module.ext_groups.1">
20
+        <source>Here you can select the member groups to be displayed.</source>
21
+      </trans-unit>
22
+      <trans-unit id="tl_module.memberFields.0">
23
+        <source>Member fields</source>
24
+      </trans-unit>
25
+      <trans-unit id="tl_module.memberFields.1">
26
+        <source>Here you can select the member fields to be displayed.</source>
27
+      </trans-unit>
28
+      <trans-unit id="tl_module.memberFields.0">
29
+        <source>Member fields</source>
30
+      </trans-unit>
31
+      <trans-unit id="tl_module.memberFields.1">
32
+        <source>Here you can select the member fields to be output.</source>
33
+      </trans-unit>
34
+      <trans-unit id="tl_module.memberListTpl.0">
35
+        <source>List template</source>
36
+      </trans-unit>
37
+      <trans-unit id="tl_module.memberListTpl.1">
38
+        <source>Here you can set your own member list template.</source>
39
+      </trans-unit>
40
+      <trans-unit id="tl_module.memberReaderTpl.0">
41
+        <source>Reader template</source>
42
+      </trans-unit>
43
+      <trans-unit id="tl_module.memberReaderTpl.1">
44
+        <source>Here you can set your own member reader template.</source>
45
+      </trans-unit>
46
+    </body>
47
+  </file>
48
+</xliff>
0 49
new file mode 100644
... ...
@@ -0,0 +1,87 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of Oveleon ContaoMemberExtension Bundle.
7
+ *
8
+ * @package     contao-member-extension-bundle
9
+ * @license     MIT
10
+ * @author      Sebastian Zoglowek     <https://github.com/zoglo>
11
+ * @author      Daniele Sciannimanica  <https://github.com/doishub>
12
+ * @author      Fabian Ekert           <https://github.com/eki89>
13
+ * @copyright   Oveleon                <https://www.oveleon.de/>
14
+ */
15
+
16
+namespace Oveleon\ContaoMemberExtensionBundle;
17
+
18
+use Contao\BackendTemplate;
19
+use Contao\FrontendUser;
20
+use Contao\MemberModel;
21
+use Contao\StringUtil;
22
+use Contao\System;
23
+
24
+/**
25
+ * Class ModuleAvatar
26
+ *
27
+ * @author Fabian Ekert <fabian@oveleon.de>
28
+ * @author Sebastian Zoglowek <https://github.com/zoglo>
29
+ */
30
+class ModuleAvatar extends ModuleMemberExtension
31
+{
32
+    /**
33
+     * Template.
34
+     *
35
+     * @var string
36
+     */
37
+    protected $strTemplate = 'memberExtension_avatar';
38
+
39
+    /**
40
+     * Display a wildcard in the back end
41
+     *
42
+     * @return string
43
+     */
44
+    public function generate()
45
+    {
46
+        $container = System::getContainer();
47
+        $request = System::getContainer()->get('request_stack')->getCurrentRequest();
48
+
49
+        if ($request && $container->get('contao.routing.scope_matcher')->isBackendRequest($request))
50
+        {
51
+            $objTemplate = new BackendTemplate('be_wildcard');
52
+            $objTemplate->wildcard = '### ' . $GLOBALS['TL_LANG']['FMD']['avatar'][0] . ' ###';
53
+            $objTemplate->title = $this->headline;
54
+            $objTemplate->id = $this->id;
55
+            $objTemplate->link = $this->name;
56
+            $objTemplate->href = StringUtil::specialcharsUrl(System::getContainer()->get('router')->generate('contao_backend', ['do'=>'themes', 'table'=>'tl_module', 'act'=>'edit', 'id'=>$this->id]));
57
+
58
+            return $objTemplate->parse();
59
+        }
60
+
61
+        // Return if user is not logged in
62
+        $tokenChecker = System::getContainer()->get('contao.security.token_checker');
63
+        $blnFeUserLoggedIn = $tokenChecker->hasFrontendUser();
64
+
65
+        if (!$blnFeUserLoggedIn)
66
+        {
67
+            return '';
68
+        }
69
+
70
+        $this->strTemplate = $this->customTpl ?: 'memberExtension_avatar';
71
+
72
+        return parent::generate();
73
+    }
74
+
75
+    /**
76
+     * Generate the module
77
+     */
78
+    protected function compile()
79
+    {
80
+        $objTemplate = $this->Template;
81
+
82
+        $this->import(FrontendUser::class, 'User');
83
+        $objMember = MemberModel::findByPk($this->User->id);
84
+
85
+        Member::parseMemberAvatar($objMember, $objTemplate, $this->imgSize);
86
+    }
87
+}
0 88
new file mode 100644
... ...
@@ -0,0 +1,134 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of Oveleon ContaoMemberExtension Bundle.
7
+ *
8
+ * @package     contao-member-extension-bundle
9
+ * @license     MIT
10
+ * @author      Sebastian Zoglowek     <https://github.com/zoglo>
11
+ * @author      Daniele Sciannimanica  <https://github.com/doishub>
12
+ * @author      Fabian Ekert           <https://github.com/eki89>
13
+ * @copyright   Oveleon                <https://www.oveleon.de/>
14
+ */
15
+
16
+namespace Oveleon\ContaoMemberExtensionBundle;
17
+
18
+use Contao\BackendTemplate;
19
+use Contao\Config;
20
+use Contao\FrontendUser;
21
+use Contao\Input;
22
+use Contao\MemberModel;
23
+use Contao\Module;
24
+use Contao\StringUtil;
25
+use Contao\System;
26
+
27
+/**
28
+ * Class ModuleDeleteAvatar
29
+ *
30
+ * @author Sebastian Zoglowek <https://github.com/zoglo>
31
+ */
32
+class ModuleDeleteAvatar extends Module
33
+{
34
+    /**
35
+     * Template.
36
+     *
37
+     * @var string
38
+     */
39
+    protected $strTemplate = 'memberExtension_deleteAvatar';
40
+
41
+    /**
42
+     * Display a wildcard in the back end
43
+     *
44
+     * @return string
45
+     */
46
+    public function generate()
47
+    {
48
+        $container = System::getContainer();
49
+        $request = System::getContainer()->get('request_stack')->getCurrentRequest();
50
+
51
+        if ($request && $container->get('contao.routing.scope_matcher')->isBackendRequest($request))
52
+        {
53
+            $objTemplate = new BackendTemplate('be_wildcard');
54
+            $objTemplate->wildcard = '### ' . $GLOBALS['TL_LANG']['FMD']['deleteAvatar'][0] . ' ###';
55
+            $objTemplate->title = $this->headline;
56
+            $objTemplate->id = $this->id;
57
+            $objTemplate->link = $this->name;
58
+            $objTemplate->href = StringUtil::specialcharsUrl(System::getContainer()->get('router')->generate('contao_backend', ['do'=>'themes', 'table'=>'tl_module', 'act'=>'edit', 'id'=>$this->id]));
59
+
60
+            return $objTemplate->parse();
61
+        }
62
+
63
+        // Set the item from the auto_item parameter
64
+        if (!isset($_GET['items']) && isset($_GET['auto_item']) && Config::get('useAutoItem'))
65
+        {
66
+            Input::setGet('items', Input::get('auto_item'));
67
+        }
68
+
69
+        // Return if there is no logged-in user
70
+        if (!$container->get('contao.security.token_checker')->hasFrontendUser())
71
+        {
72
+            return '';
73
+        }
74
+
75
+        $this->import(FrontendUser::class, 'User');
76
+        $objMember = MemberModel::findByPk($this->User->id);
77
+
78
+        if (null === $objMember)
79
+        {
80
+            return '';
81
+        }
82
+
83
+        // Confirmation message
84
+        $session = System::getContainer()->get('session');
85
+        $flashBag = $session->getFlashBag();
86
+
87
+        // Return if there is no flashbag message or an avatar
88
+        if (!($session->isStarted() && $flashBag->has('mod_avatar_deleted')) && !$objMember->avatar)
89
+        {
90
+            return '';
91
+        }
92
+
93
+        return parent::generate();
94
+    }
95
+
96
+    /**
97
+     * Generate the module
98
+     */
99
+    protected function compile()
100
+    {
101
+        $strFormId = 'deleteAvatar_' . $this->id;
102
+        $session = System::getContainer()->get('session');
103
+        $flashBag = $session->getFlashBag();
104
+
105
+        // Get form submit
106
+        if (Input::post('FORM_SUBMIT') == $strFormId)
107
+        {
108
+            $this->import(FrontendUser::class, 'User');
109
+            $objMember = MemberModel::findByPk($this->User->id);
110
+
111
+            // Delete avatar if it exists
112
+            if (!!$objMember->avatar)
113
+            {
114
+                Member::deleteAvatar($objMember);
115
+                // Unset avatar
116
+                $objMember->avatar = null;
117
+                $objMember->save();
118
+
119
+                // Set message for deletion feedback
120
+                $flashBag->set('mod_avatar_deleted', $GLOBALS['TL_LANG']['MSC']['avatarDeleted']);
121
+                $this->reload();
122
+            }
123
+        }
124
+
125
+        // Confirmation message
126
+        if ($session->isStarted() && $flashBag->has('mod_avatar_deleted')) {
127
+            $arrMessages = $flashBag->get('mod_avatar_deleted');
128
+            $this->Template->message = $arrMessages[0];
129
+        }
130
+
131
+        $this->Template->formId = $strFormId;
132
+        $this->Template->slabel = StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['deleteAvatar']);
133
+    }
134
+}
0 135
new file mode 100644
... ...
@@ -0,0 +1,178 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of Oveleon ContaoMemberExtension Bundle.
7
+ *
8
+ * @package     contao-member-extension-bundle
9
+ * @license     MIT
10
+ * @author      Sebastian Zoglowek     <https://github.com/zoglo>
11
+ * @author      Daniele Sciannimanica  <https://github.com/doishub>
12
+ * @author      Fabian Ekert           <https://github.com/eki89>
13
+ * @copyright   Oveleon                <https://www.oveleon.de/>
14
+ */
15
+
16
+namespace Oveleon\ContaoMemberExtensionBundle;
17
+
18
+use Contao\Config;
19
+use Contao\Date;
20
+use Contao\Environment;
21
+use Contao\MemberGroupModel;
22
+use Contao\MemberModel;
23
+use Contao\Module;
24
+use Contao\PageModel;
25
+use Contao\StringUtil;
26
+use Contao\System;
27
+
28
+/**
29
+ * Parent class for member modules.
30
+ *
31
+ * @author Daniele Sciannimanica <https://github.com/doishub>
32
+ */
33
+abstract class ModuleMemberExtension extends Module
34
+{
35
+    /**
36
+     * Parse member template
37
+     *
38
+     * @param $objMember
39
+     * @param $objTemplate
40
+     * @param $arrMemberFields
41
+     * @param $strImgSize
42
+     * @return string
43
+     */
44
+    protected function parseMemberTemplate($objMember, $objTemplate, $arrMemberFields, $strImgSize): string
45
+    {
46
+        System::loadLanguageFile('default');
47
+        System::loadLanguageFile('tl_member');
48
+        System::loadLanguageFile('countries');
49
+        System::loadLanguageFile('languages');
50
+
51
+        $arrFields = [];
52
+
53
+        foreach ($arrMemberFields as $field)
54
+        {
55
+            switch ($field)
56
+            {
57
+                /*case 'homeDir':
58
+                case 'assignDir':
59
+                    break;*/
60
+
61
+                case 'avatar':
62
+                    Member::parseMemberAvatar($objMember, $objTemplate, $strImgSize);
63
+                    break;
64
+
65
+                default:
66
+                    if ($varValue = $objMember->{$field})
67
+                    {
68
+                        if (\is_array(($arrValue = StringUtil::deserialize($varValue))))
69
+                        {
70
+                            $arrFields[$field] = implode(",", $arrValue);
71
+                        }
72
+                        else
73
+                        {
74
+                            $arrFields[$field] = $varValue;
75
+                        }
76
+                        //self::parseMemberDetails($arrFields, $field, $varValue);
77
+                    }
78
+            }
79
+        }
80
+
81
+        $objTemplate->fields = $arrFields;
82
+
83
+        if ($this->jumpTo)
84
+        {
85
+            $objTemplate->link = $this->generateMemberUrl($objMember);
86
+        }
87
+
88
+        return $objTemplate->parse();
89
+    }
90
+
91
+    /**
92
+     * Generate a URL and return it as string
93
+     *
94
+     * @param MemberModel $objMember
95
+     *
96
+     * @return string
97
+     */
98
+    protected function generateMemberUrl(MemberModel $objMember): string
99
+    {
100
+        $objPage = PageModel::findPublishedById($this->jumpTo);
101
+
102
+        if (!$objPage instanceof PageModel)
103
+        {
104
+            $strLink = StringUtil::ampersand(Environment::get('request'));
105
+        }
106
+        else
107
+        {
108
+            $params = (Config::get('useAutoItem') ? '/' : '/items/') . ($objMember->alias ?: $objMember->id);
109
+            $strLink = StringUtil::ampersand($objPage->getFrontendUrl($params));
110
+        }
111
+
112
+        return $strLink;
113
+    }
114
+
115
+    protected function parseMemberDetails(&$arrFields, $field, $value)
116
+    {
117
+        $strReturn = sprintf('<span class="label">%s: </span>',$GLOBALS['TL_LANG']['tl_member'][$field][0] ?? null);
118
+
119
+        if (!\is_array(($arrValue = StringUtil::deserialize($value))))
120
+        {
121
+            switch ($field) {
122
+                case 'gender':
123
+                    $strReturn .= $GLOBALS['TL_LANG']['MSC'][$value] ?? $value;
124
+                    break;
125
+
126
+                case 'email':
127
+                    $strEmail = StringUtil::encodeEmail($value);
128
+                    $strReturn .= '<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;' . $strEmail . '" title="' . $strEmail . '">' . preg_replace('/\?.*$/', '', $strEmail) . '</a>';
129
+                    break;
130
+
131
+                case 'phone':
132
+                case 'mobile':
133
+                case 'fax':
134
+                    $strTel = preg_replace('/[^a-z\d+]/i', '', (string)$value);
135
+                    $strReturn .= '<a href="tel:' . $strTel . '" title="' . $value . '">' . $value . '</a>';
136
+                    break;
137
+
138
+                case 'website':
139
+                    $strUrl = $value;
140
+
141
+                    if (strncmp($value, 'http://', 7) !== 0 || strncmp($value, 'https://', 8) !== 0) {
142
+                        $strUrl = 'https://' . $value;
143
+                    }
144
+
145
+                    $strReturn .= '<a href="' . $strUrl . '" title="' . $value . '" target="blank noopener" rel="noreferer">' . $value . '</a>';
146
+                    break;
147
+
148
+                case 'dateOfBirth':
149
+                    $strReturn .= Date::parse(Config::get('dateFormat'), $value) ?? $value;
150
+                    break;
151
+
152
+                case 'country':
153
+                    $strReturn .= $GLOBALS['TL_LANG']['CNT'][$value] ?? $value;
154
+                    break;
155
+
156
+                case 'language':
157
+                    $strReturn .= $GLOBALS['TL_LANG']['LNG'][$value] ?? $value;
158
+                    break;
159
+
160
+                default:
161
+                    $strReturn .= $value;
162
+            }
163
+        }
164
+        else if ('groups' === $field)
165
+        {
166
+            $arrReturn = [];
167
+
168
+            foreach ($arrValue as $value)
169
+            {
170
+                $arrReturn[] = MemberGroupModel::findById($value)->name;
171
+            }
172
+
173
+            $strReturn .= implode(", ", $arrReturn);
174
+        }
175
+
176
+        $arrFields[$field] = $strReturn;
177
+    }
178
+}
0 179
new file mode 100644
... ...
@@ -0,0 +1,228 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of Oveleon ContaoMemberExtension Bundle.
7
+ *
8
+ * @package     contao-member-extension-bundle
9
+ * @license     MIT
10
+ * @author      Sebastian Zoglowek     <https://github.com/zoglo>
11
+ * @author      Daniele Sciannimanica  <https://github.com/doishub>
12
+ * @author      Fabian Ekert           <https://github.com/eki89>
13
+ * @copyright   Oveleon                <https://www.oveleon.de/>
14
+ */
15
+
16
+namespace Oveleon\ContaoMemberExtensionBundle;
17
+
18
+use Contao\BackendTemplate;
19
+use Contao\Config;
20
+use Contao\CoreBundle\Exception\PageNotFoundException;
21
+use Contao\Date;
22
+use Contao\Environment;
23
+use Contao\FrontendTemplate;
24
+use Contao\Input;
25
+use Contao\MemberModel;
26
+use Contao\Model\Collection;
27
+use Contao\Pagination;
28
+use Contao\StringUtil;
29
+use Contao\System;
30
+
31
+/**
32
+ * Class ModuleMemberList
33
+ *
34
+ * @property string $ext_order order of list items
35
+ * @property string ext_orderField order field for list items
36
+ * @property string $ext_groups considered member groups
37
+ * @property string $memberFields Fields to be displayed
38
+ * @property string $memberListTpl Frontend list template
39
+ */
40
+class ModuleMemberList extends ModuleMemberExtension
41
+{
42
+
43
+    /**
44
+     * Template
45
+     * @var string
46
+     */
47
+    protected $strTemplate = 'mod_memberList';
48
+
49
+    /**
50
+     * Template
51
+     * @var string
52
+     */
53
+    protected $strMemberTemplate = 'memberExtension_list_default';
54
+
55
+    /**
56
+     * Display a wildcard in the back end
57
+     *
58
+     * @return string
59
+     */
60
+    public function generate()
61
+    {
62
+        $container = System::getContainer();
63
+        $request = System::getContainer()->get('request_stack')->getCurrentRequest();
64
+
65
+        if ($request && $container->get('contao.routing.scope_matcher')->isBackendRequest($request))
66
+        {
67
+            $objTemplate = new BackendTemplate('be_wildcard');
68
+            $objTemplate->wildcard = '### ' . $GLOBALS['TL_LANG']['FMD']['memberList'][0] . ' ###';
69
+            $objTemplate->title = $this->headline;
70
+            $objTemplate->id = $this->id;
71
+            $objTemplate->link = $this->name;
72
+            $objTemplate->href = StringUtil::specialcharsUrl(System::getContainer()->get('router')->generate('contao_backend', ['do'=>'themes', 'table'=>'tl_module', 'act'=>'edit', 'id'=>$this->id]));
73
+
74
+            return $objTemplate->parse();
75
+        }
76
+
77
+        return parent::generate();
78
+    }
79
+
80
+    /**
81
+     * Generate the module
82
+     */
83
+    protected function compile()
84
+    {
85
+        $limit = null;
86
+        $offset = 0;
87
+
88
+        $arrGroups = StringUtil::deserialize($this->ext_groups);
89
+
90
+        if (empty($arrGroups) || !\is_array($arrGroups))
91
+        {
92
+            $this->Template->empty = $GLOBALS['TL_LANG']['MSC']['emptyMemberList'];
93
+            return;
94
+        }
95
+
96
+        $objTemplate = new FrontendTemplate($this->memberListTpl ?: $this->strMemberTemplate);
97
+
98
+        $objMembers = $this->getMembers();
99
+
100
+        $intTotal = 0;
101
+
102
+        $arrMembers = [];
103
+
104
+        if (null !== $objMembers)
105
+        {
106
+            while($objMembers->next())
107
+            {
108
+                $objMember = $objMembers->current();
109
+
110
+                if (!$this->checkMemberGroups($arrGroups, $objMember))
111
+                {
112
+                    continue;
113
+                }
114
+
115
+                $intTotal += 1;
116
+
117
+                $arrMemberFields = StringUtil::deserialize($this->memberFields, true);
118
+                $objTemplate->setData($objMember->row());
119
+
120
+                $arrMembers[] = $this->parseMemberTemplate($objMember, $objTemplate, $arrMemberFields, $this->imgSize);
121
+            }
122
+        }
123
+
124
+        $total = $intTotal - $offset;
125
+
126
+        if ($this->numberOfItems > 0)
127
+        {
128
+            $limit = $this->numberOfItems;
129
+        }
130
+
131
+        if ($this->perPage > 0 && (!isset($limit) || $this->numberOfItems > $this->perPage))
132
+        {
133
+            if (isset($limit))
134
+            {
135
+                $total = min($limit, $total);
136
+            }
137
+
138
+            $id = 'page_n' . $this->id;
139
+            $page = Input::get($id) ?? 1;
140
+
141
+            if ($page < 1 || $page > max(ceil($total/$this->perPage), 1))
142
+            {
143
+                throw new PageNotFoundException('Page not found: ' . Environment::get('uri'));
144
+            }
145
+
146
+            $limit = $this->perPage;
147
+            $offset += (max($page, 1) - 1) * $this->perPage;
148
+            $skip = 0;
149
+
150
+            if ($offset + $limit > $total + $skip)
151
+            {
152
+                $limit = $total + $skip - $offset;
153
+            }
154
+
155
+            $arrMembers = \array_slice($arrMembers, $offset, ((int) $limit ?: $intTotal), true);
156
+
157
+            $objPagination = new Pagination($total, $this->perPage, Config::get('maxPaginationLinks'), $id);
158
+            $this->Template->pagination = $objPagination->generate("\n  ");
159
+        }
160
+
161
+        if (empty($arrMembers))
162
+        {
163
+            $this->Template->empty = $GLOBALS['TL_LANG']['MSC']['emptyMemberList'];
164
+        }
165
+
166
+        $this->Template->members = $arrMembers;
167
+    }
168
+
169
+    /**
170
+     * Checks whether a member is in any given group
171
+     *
172
+     * @param array $arrGroups
173
+     * @param MemberModel $objMember
174
+     * @return bool
175
+     */
176
+    private function checkMemberGroups(array $arrGroups, MemberModel $objMember): bool
177
+    {
178
+        if (empty($arrGroups))
179
+        {
180
+            return false;
181
+        }
182
+
183
+        $arrMemberGroups = StringUtil::deserialize($objMember->groups);
184
+
185
+        if (!\is_array($arrMemberGroups) || !\count(array_intersect($arrGroups, $arrMemberGroups)))
186
+        {
187
+            return false;
188
+        }
189
+
190
+        return true;
191
+    }
192
+
193
+    /**
194
+     * Get members
195
+     *
196
+     * @return Collection|MemberModel|null
197
+     */
198
+    private function getMembers()
199
+    {
200
+        $t = MemberModel::getTable();
201
+        $time = Date::floorToMinute();
202
+
203
+        $arrColumns = ["$t.disable='' AND ($t.start='' OR $t.start<='$time') AND ($t.stop='' OR $t.stop>'$time') "];
204
+        $arrOptions = ['order' => ''];
205
+
206
+        if (!!$this->ext_orderField)
207
+        {
208
+            $arrOptions['order'] .= "$t.$this->ext_orderField ";
209
+        }
210
+
211
+        switch ($this->ext_order)
212
+        {
213
+            case 'order_random':
214
+                $arrOptions['order'] = "RAND()";
215
+                break;
216
+
217
+            case 'order_desc':
218
+                $arrOptions['order'] .= "DESC";
219
+                break;
220
+
221
+            case 'order_asc':
222
+            default:
223
+                break;
224
+        }
225
+
226
+        return MemberModel::findBy($arrColumns, null, $arrOptions);
227
+    }
228
+}
0 229
new file mode 100644
... ...
@@ -0,0 +1,114 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of Oveleon ContaoMemberExtension Bundle.
7
+ *
8
+ * @package     contao-member-extension-bundle
9
+ * @license     MIT
10
+ * @author      Sebastian Zoglowek     <https://github.com/zoglo>
11
+ * @author      Daniele Sciannimanica  <https://github.com/doishub>
12
+ * @author      Fabian Ekert           <https://github.com/eki89>
13
+ * @copyright   Oveleon                <https://www.oveleon.de/>
14
+ */
15
+
16
+namespace Oveleon\ContaoMemberExtensionBundle;
17
+
18
+use Contao\BackendTemplate;
19
+use Contao\Config;
20
+use Contao\CoreBundle\Exception\PageNotFoundException;
21
+use Contao\Environment;
22
+use Contao\FrontendTemplate;
23
+use Contao\Input;
24
+use Contao\MemberModel;
25
+use Contao\StringUtil;
26
+use Contao\System;
27
+
28
+/**
29
+ * Class ModuleMemberList
30
+ * 
31
+ * @property string $ext_groups considered member groups
32
+ * @property string $memberFields Fields to be displayed
33
+ * @property string $memberReaderTpl Frontend reader template
34
+ */
35
+class ModuleMemberReader extends ModuleMemberExtension
36
+{
37
+
38
+    /**
39
+     * Template
40
+     * @var string
41
+     */
42
+    protected $strTemplate = 'mod_memberReader';
43
+
44
+    /**
45
+     * Template
46
+     * @var string
47
+     */
48
+    protected $strMemberTemplate = 'memberExtension_reader_full';
49
+
50
+    /**
51
+     * Display a wildcard in the back end
52
+     *
53
+     * @return string
54
+     */
55
+    public function generate()
56
+    {
57
+        $container = System::getContainer();
58
+        $request = System::getContainer()->get('request_stack')->getCurrentRequest();
59
+
60
+        if ($request && $container->get('contao.routing.scope_matcher')->isBackendRequest($request))
61
+        {
62
+            $objTemplate = new BackendTemplate('be_wildcard');
63
+            $objTemplate->wildcard = '### ' . $GLOBALS['TL_LANG']['FMD']['memberList'][0] . ' ###';
64
+            $objTemplate->title = $this->headline;
65
+            $objTemplate->id = $this->id;
66
+            $objTemplate->link = $this->name;
67
+            $objTemplate->href = StringUtil::specialcharsUrl(System::getContainer()->get('router')->generate('contao_backend', ['do'=>'themes', 'table'=>'tl_module', 'act'=>'edit', 'id'=>$this->id]));
68
+
69
+            return $objTemplate->parse();
70
+        }
71
+
72
+        // Set the item from the auto_item parameter
73
+        if (!isset($_GET['items']) && isset($_GET['auto_item']) && Config::get('useAutoItem'))
74
+        {
75
+            Input::setGet('items', Input::get('auto_item'));
76
+        }
77
+
78
+        return parent::generate();
79
+    }
80
+
81
+    /**
82
+     * Generate the module
83
+     */
84
+    protected function compile()
85
+    {
86
+        $this->Template->referer = 'javascript:history.go(-1)';
87
+        $this->Template->back = $GLOBALS['TL_LANG']['MSC']['goBack'];
88
+
89
+        // Get the member
90
+        $objMember = MemberModel::findByIdOrAlias(Input::get('items'));
91
+
92
+        // The member does not exist and is not deactivated
93
+        if ($objMember === null || $objMember->disable)
94
+        {
95
+            throw new PageNotFoundException('Page not found: ' . Environment::get('uri'));
96
+        }
97
+
98
+        // Check for group intersection
99
+        $arrGroups = StringUtil::deserialize($this->ext_groups);
100
+        $memberGroups = StringUtil::deserialize($objMember->groups);
101
+
102
+        if (empty($arrGroups) || !\is_array($arrGroups) || !\count(array_intersect($arrGroups, $memberGroups)))
103
+        {
104
+            throw new PageNotFoundException('Page not found: ' . Environment::get('uri'));
105
+        }
106
+
107
+        $arrMemberFields = StringUtil::deserialize($this->memberFields, true);
108
+
109
+        $objTemplate = new FrontendTemplate($this->memberReaderTpl ?: $this->strMemberTemplate);
110
+        $objTemplate->setData($objMember->row());
111
+
112
+        $this->Template->member = $this->parseMemberTemplate($objMember, $objTemplate, $arrMemberFields, $this->imgSize);
113
+    }
114
+}
0 115
new file mode 100644
... ...
@@ -0,0 +1,8 @@
1
+<figure class="image_container">
2
+
3
+  <?php if($this->addFallbackImage): ?>
4
+    <img src="<?= $this->singleSRC; ?>" width="200" height="200" itemprop="image">
5
+  <?php else: ?>
6
+    <?php $this->insert('picture_default', $this->picture); ?>
7
+  <?php endif; ?>
8
+</figure>
0 9
new file mode 100644
... ...
@@ -0,0 +1,7 @@
1
+<?php $this->extend('block_searchable'); ?>
2
+
3
+<?php $this->block('content'); ?>
4
+
5
+<?php $this->insert('memberExtension_image', $this->arrData); ?>
6
+
7
+<?php $this->endblock(); ?>
0 8
new file mode 100644
... ...
@@ -0,0 +1,23 @@
1
+<?php $this->extend('block_unsearchable'); ?>
2
+
3
+<?php $this->block('content'); ?>
4
+
5
+<!-- indexer::stop -->
6
+
7
+  <?php if ($this->message): ?>
8
+    <p class="tl_confirm"><?= $this->message ?></p>
9
+  <?php else: ?>
10
+    <form id="<?= $this->formId ?>" method="post">
11
+      <div class="formbody">
12
+        <input type="hidden" name="FORM_SUBMIT" value="<?= $this->formId ?>">
13
+        <input type="hidden" name="REQUEST_TOKEN" value="{{request_token}}">
14
+        <div class="widget widget-submit">
15
+          <button type="submit" class="submit"><?= $this->slabel ?></button>
16
+        </div>
17
+      </div>
18
+    </form>
19
+  <?php endif; ?>
20
+
21
+<!-- indexer::continue -->
22
+
23
+<?php $this->endblock(); ?>
0 24
new file mode 100644
... ...
@@ -0,0 +1,16 @@
1
+<div class="member_list_default">
2
+
3
+  <?php if($this->addImage): ?>
4
+    <?php $this->insert('memberExtension_image', $this->arrData); ?>
5
+  <?php endif; ?>
6
+
7
+  <ul>
8
+    <?php foreach ($this->fields as $k => $v): ?>
9
+      <li class="<?= $k ?>"><?= $v ?></li>
10
+    <?php endforeach; ?>
11
+  </ul>
12
+
13
+  <?php if($this->link): ?>
14
+    <a href="<?=$this->link?>"><?=$GLOBALS['TL_LANG']['MSC']['memberDetail']?></a>
15
+  <?php endif; ?>
16
+</div>
0 17
new file mode 100644
... ...
@@ -0,0 +1,12 @@
1
+<div class="member_reader_full">
2
+
3
+  <?php if($this->addImage): ?>
4
+    <?php $this->insert('memberExtension_image', $this->arrData); ?>
5
+  <?php endif; ?>
6
+
7
+  <ul>
8
+    <?php foreach ($this->fields as $k => $v): ?>
9
+      <li class="<?= $k ?>"><?= $v ?></li>
10
+    <?php endforeach; ?>
11
+  </ul>
12
+</div>
0 13
new file mode 100644
... ...
@@ -0,0 +1,14 @@
1
+<?php $this->extend('block_unsearchable'); ?>
2
+
3
+<?php $this->block('content'); ?>
4
+
5
+<?php if (empty($this->members)): ?>
6
+    <p class="empty message"><?=$this->empty?></p>
7
+<?php else: ?>
8
+    <?php foreach ($this->members as $member): ?>
9
+      <?=$member?>
10
+    <?php endforeach; ?>
11
+    <?= $this->pagination ?>
12
+<?php endif; ?>
13
+
14
+<?php $this->endblock(); ?>
0 15
new file mode 100644
... ...
@@ -0,0 +1,11 @@
1
+<?php $this->extend('block_unsearchable'); ?>
2
+
3
+<?php $this->block('content'); ?>
4
+
5
+<?=$this->member?>
6
+
7
+<!-- indexer::stop -->
8
+<p class="back"><a href="<?= $this->referer ?>" title="<?= $this->back ?>"><?= $this->back ?></a></p>
9
+<!-- indexer::continue -->
10
+
11
+<?php $this->endblock(); ?>
0 12
new file mode 100644
1 13
Binary files /dev/null and b/public/avatar.png differ
... ...
@@ -7,10 +7,10 @@ declare(strict_types=1);
7 7
  *
8 8
  * @package     contao-member-extension-bundle
9 9
  * @license     MIT
10
- * @author      Daniele Sciannimanica   <https://github.com/doishub>
11
- * @author      Fabian Ekert            <https://github.com/eki89>
12
- * @author      Sebastian Zoglowek      <https://github.com/zoglo>
13
- * @copyright   Oveleon                 <https://www.oveleon.de/>
10
+ * @author      Sebastian Zoglowek     <https://github.com/zoglo>
11
+ * @author      Daniele Sciannimanica  <https://github.com/doishub>
12
+ * @author      Fabian Ekert           <https://github.com/eki89>
13
+ * @copyright   Oveleon                <https://www.oveleon.de/>
14 14
  */
15 15
 
16 16
 namespace Oveleon\ContaoMemberExtensionBundle\ContaoManager;
... ...
@@ -7,10 +7,10 @@ declare(strict_types=1);
7 7
  *
8 8
  * @package     contao-member-extension-bundle
9 9
  * @license     MIT
10
- * @author      Daniele Sciannimanica   <https://github.com/doishub>
11
- * @author      Fabian Ekert            <https://github.com/eki89>
12
- * @author      Sebastian Zoglowek      <https://github.com/zoglo>
13
- * @copyright   Oveleon                 <https://www.oveleon.de/>
10
+ * @author      Sebastian Zoglowek     <https://github.com/zoglo>
11
+ * @author      Daniele Sciannimanica  <https://github.com/doishub>
12
+ * @author      Fabian Ekert           <https://github.com/eki89>
13
+ * @copyright   Oveleon                <https://www.oveleon.de/>
14 14
  */
15 15
 
16 16
 namespace Oveleon\ContaoMemberExtensionBundle;
... ...
@@ -19,4 +19,8 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
19 19
 
20 20
 class ContaoMemberExtensionBundle extends Bundle
21 21
 {
22
-}
23 22
\ No newline at end of file
23
+    public function getPath(): string
24
+    {
25
+        return \dirname(__DIR__);
26
+    }
27
+}
... ...
@@ -1,13 +1,16 @@
1 1
 <?php
2 2
 
3
-/**
4
- * Procuna
3
+/*
4
+ * This file is part of Oveleon ContaoMemberExtension Bundle.
5 5
  *
6
- * @link      https://www.oveleon.de/
7
- * @copyright Copyright (c) 2021  Oveleon GbR (https://www.oveleon.de)
6
+ * @package     contao-member-extension-bundle
7
+ * @license     MIT
8
+ * @author      Sebastian Zoglowek     <https://github.com/zoglo>
9
+ * @author      Daniele Sciannimanica  <https://github.com/doishub>
10
+ * @author      Fabian Ekert           <https://github.com/eki89>
11
+ * @copyright   Oveleon                <https://www.oveleon.de/>
8 12
  */
9 13
 
10
-
11 14
 namespace Oveleon\ContaoMemberExtensionBundle\DependencyInjection;
12 15
 
13 16
 use Symfony\Component\Config\FileLocator;
... ...
@@ -21,7 +24,7 @@ class ContaoMemberExtensionExtension extends Extension
21 24
     {
22 25
         $loader = new YamlFileLoader(
23 26
             $container,
24
-            new FileLocator(__DIR__.'/../Resources/config')
27
+            new FileLocator(__DIR__.'/../../config')
25 28
         );
26 29
 
27 30
         $loader->load('listener.yml');
... ...
@@ -7,10 +7,10 @@ declare(strict_types=1);
7 7
  *
8 8
  * @package     contao-member-extension-bundle
9 9
  * @license     MIT
10
- * @author      Daniele Sciannimanica   <https://github.com/doishub>
11
- * @author      Fabian Ekert            <https://github.com/eki89>
12
- * @author      Sebastian Zoglowek      <https://github.com/zoglo>
13
- * @copyright   Oveleon                 <https://www.oveleon.de/>
10
+ * @author      Sebastian Zoglowek     <https://github.com/zoglo>
11
+ * @author      Daniele Sciannimanica  <https://github.com/doishub>
12
+ * @author      Fabian Ekert           <https://github.com/eki89>
13
+ * @copyright   Oveleon                <https://www.oveleon.de/>
14 14
  */
15 15
 
16 16
 namespace Oveleon\ContaoMemberExtensionBundle\EventListener;
... ...
@@ -60,15 +60,16 @@ class InsertTagsListener
60 60
         $this->framework->initialize();
61 61
         $tokenChecker = System::getContainer()->get('contao.security.token_checker');
62 62
 
63
-        if($elements[1] !== 'member')
63
+        if ($elements[1] !== 'member')
64 64
         {
65 65
             return '';
66 66
         }
67 67
 
68
-        switch ($elements[2]) {
68
+        switch ($elements[2])
69
+        {
69 70
 
70 71
             case 'current':
71
-                if(!$tokenChecker->hasFrontendUser())
72
+                if (!$tokenChecker->hasFrontendUser())
72 73
                 {
73 74
                     return '';
74 75
                 }
... ...
@@ -76,7 +77,7 @@ class InsertTagsListener
76 77
                 break;
77 78
 
78 79
             default:
79
-                if(!\is_numeric($elements[2]))
80
+                if (!\is_numeric($elements[2]))
80 81
                 {
81 82
                     return '';
82 83
                 }
... ...
@@ -90,10 +91,14 @@ class InsertTagsListener
90 91
         {
91 92
             case 'avatar':
92 93
             {
93
-                $strImgSize = $this->convertImgSize($elements[3]);
94
+                if (isset($elements[3]))
95
+                {
96
+                    $strImgSize = $this->convertImgSize($elements[3]);
97
+                }
98
+
94 99
                 $objTemplate = new FrontendTemplate('memberExtension_image');
95 100
 
96
-                Member::parseMemberAvatar($objMember, $objTemplate, $strImgSize);
101
+                Member::parseMemberAvatar($objMember, $objTemplate, $strImgSize ?? null);
97 102
 
98 103
                 return $objTemplate->parse();
99 104
             }
... ...
@@ -124,7 +129,7 @@ class InsertTagsListener
124 129
             ResizeConfiguration::MODE_CROP,
125 130
         ];
126 131
 
127
-        if(!!$mode && in_array($mode, $arrValidModes, true))
132
+        if (!!$mode && in_array($mode, $arrValidModes, true))
128 133
         {
129 134
             $arrSizes[] = $mode;
130 135
         }
131 136
deleted file mode 100644
... ...
@@ -1,8 +0,0 @@
1
-services:
2
-    contao_member.listener.insert_tags:
3
-        class: Oveleon\ContaoMemberExtensionBundle\EventListener\InsertTagsListener
4
-        arguments:
5
-            - '@contao.framework'
6
-        tags:
7
-          - { name: contao.hook, hook: replaceInsertTags }
8
-        public: true
9 0
deleted file mode 100644
... ...
@@ -1,351 +0,0 @@
1
-<?php
2
-
3
-declare(strict_types=1);
4
-
5
-/*
6
- * This file is part of Oveleon ContaoMemberExtension Bundle.
7
- *
8
- * @package     contao-member-extension-bundle
9
- * @license     MIT
10
- * @author      Daniele Sciannimanica   <https://github.com/doishub>
11
- * @author      Fabian Ekert            <https://github.com/eki89>
12
- * @author      Sebastian Zoglowek      <https://github.com/zoglo>
13
- * @copyright   Oveleon                 <https://www.oveleon.de/>
14
- */
15
-
16
-namespace Oveleon\ContaoMemberExtensionBundle;
17
-
18
-use Contao\Config;
19
-use Contao\CoreBundle\Monolog\ContaoContext;
20
-use Contao\Dbafs;
21
-use Contao\File;
22
-use Contao\FilesModel;
23
-use Contao\FileUpload;
24
-use Contao\Frontend;
25
-use Contao\FrontendUser;
26
-use Contao\MemberModel;
27
-use Contao\StringUtil;
28
-use Contao\System;
29
-use Contao\Validator;
30
-use Psr\Log\LogLevel;
31
-
32
-
33
-/**
34
- * Class Member
35
- *
36
- * @property int $avatar UUID of the avatar
37
- */
38
-class Member extends Frontend
39
-{
40
-    const DEFAULT_PICTURE = 'bundles/contaomemberextension/avatar.png';
41
-
42
-    /**
43
-     * MemberAvatar file name
44
-     *
45
-     * @var string
46
-     */
47
-    protected $avatarName = 'memberAvatar';
48
-
49
-    /**
50
-     * Create avatar for a member | Registration
51
-     *
52
-     * @param int   $userId
53
-     * @param array $arrData
54
-     *
55
-     * @return void
56
-     */
57
-    public function createAvatar(int $userId, array $arrData): void
58
-    {
59
-        $objMember = MemberModel::findById($userId);
60
-        $this->processAvatar($objMember, $arrData);
61
-    }
62
-
63
-    /**
64
-     * Update avatar of a member | Login
65
-     *
66
-     * @param FrontendUser  $objUser
67
-     * @param array         $arrData
68
-     *
69
-     * @return void
70
-     */
71
-    public function updateAvatar(FrontendUser $objUser, $arrData): void
72
-    {
73
-        $objMember = MemberModel::findById($objUser->id);
74
-        $this->processAvatar($objMember, $arrData);
75
-    }
76
-
77
-    /**
78
-     * Process avatar upload for a member
79
-     *
80
-     * @param MemberModel   $objMember
81
-     * @param array         $arrData
82
-     *
83
-     * @return void
84
-     */
85
-    protected function processAvatar(MemberModel $objMember, ?array $arrData): void
86
-    {
87
-        $objMember = MemberModel::findByPk($objMember->id);
88
-
89
-        if ($objMember === null)
90
-        {
91
-            return;
92
-        }
93
-
94
-        $file = $_SESSION['FILES']['avatar'];
95
-        $maxlength_kb = $this->getMaximumUploadSize();
96
-        $maxlength_kb_readable = $this->getReadableSize($maxlength_kb);
97
-
98
-        // Sanitize the filename
99
-        try
100
-        {
101
-            $file['name'] = StringUtil::sanitizeFileName($file['name']);
102
-        }
103
-        catch (\InvalidArgumentException $e)
104
-        {
105
-            // ToDo: add error message for invalid characters
106
-            return;
107
-        }
108
-
109
-        // Invalid file name
110
-        if (!Validator::isValidFileName($file['name']))
111
-        {
112
-            // ToDo: add error message for invalid characters
113
-            return;
114
-        }
115
-
116
-        // File was not uploaded
117
-        if (!is_uploaded_file($file['tmp_name']))
118
-        {
119
-            // ToDo: Add error messages
120
-            /*if ($file['error'] == 1 || $file['error'] == 2) { // Add error message for maximum file size }
121
-            elseif ($file['error'] == 3) { // Add error message for partial upload }
122
-            elseif ($file['error'] > 0) { // Add error message for failed upload }*/
123
-
124
-            unset($_SESSION['FILES']['avatar']);
125
-
126
-            return;
127
-        }
128
-
129
-        // File is too big
130
-        if ($file['size'] > $maxlength_kb)
131
-        {
132
-            // ToDo: add error message for maximum file size
133
-            unset($_SESSION['FILES']['avatar']);
134
-
135
-            return;
136
-        }
137
-
138
-        $objFile = new File($file['name']);
139
-        $uploadTypes = StringUtil::trimsplit(',', \Config::get('validImageTypes'));
140
-
141
-        // File type is not allowed
142
-        if (!\in_array($objFile->extension, $uploadTypes))
143
-        {
144
-            // ToDo: add error message for not allowed file type
145
-            unset($_SESSION['FILES']['avatar']);
146
-
147
-            return;
148
-        }
149
-
150
-        if ($arrImageSize = @getimagesize($file['tmp_name']))
151
-        {
152
-            $intImageWidth = Config::get('imageWidth');
153
-
154
-            // Image exceeds maximum image width
155
-            if ($intImageWidth > 0 && $arrImageSize[0] > $intImageWidth) {
156
-                // ToDo: add error message for exceeding width
157
-                unset($_SESSION['FILES']['avatar']);
158
-
159
-                return;
160
-            }
161
-
162
-            $intImageHeight = Config::get('imageHeight');
163
-
164
-            // Image exceeds maximum image height
165
-            if ($intImageHeight > 0 && $arrImageSize[1] > $intImageHeight) {
166
-                // ToDo: add error message for exceeding height
167
-                unset($_SESSION['FILES']['avatar']);
168
-
169
-                return;
170
-            }
171
-        }
172
-
173
-        // Upload valid file type with no width and height -> svg
174
-
175
-        // Don't upload if no homedir is assigned
176
-        if (!$objMember->assignDir || !$objMember->homeDir)
177
-        {
178
-            // ToDo: add error message for no homedir
179
-            return;
180
-        }
181
-
182
-        $intUploadFolder = $objMember->homeDir;
183
-
184
-        $objUploadFolder = FilesModel::findByUuid($intUploadFolder);
185
-
186
-        // The upload folder could not be found
187
-        if ($objUploadFolder === null)
188
-        {
189
-            throw new \Exception("Invalid upload folder ID $intUploadFolder");
190
-        }
191
-
192
-        $strUploadFolder = $objUploadFolder->path;
193
-
194
-        // Store the file if the upload folder exists
195
-        $projectDir = System::getContainer()->getParameter('kernel.project_dir');
196
-
197
-        if (!!$strUploadFolder & is_dir($projectDir . '/' . $strUploadFolder))
198
-        {
199
-            // Delete existing avatar if it exists
200
-            $this->deleteAvatar($objMember);
201
-
202
-            $this->import('Files');
203
-
204
-            // Rename file
205
-            $file['name'] =  $this->avatarName . '.' . $objFile->extension;
206
-
207
-            // Move the file to its destination
208
-            $this->Files->move_uploaded_file($file['tmp_name'], $strUploadFolder . '/' . $file['name']);
209
-            $this->Files->chmod($strUploadFolder . '/' . $file['name'], 0666 & ~umask());
210
-
211
-            $strUuid = null;
212
-            $strFile = $strUploadFolder . '/' . $file['name'];
213
-
214
-
215
-            // Generate the DB entries
216
-            if (Dbafs::shouldBeSynchronized($strFile))
217
-            {
218
-                $objModel = FilesModel::findByPath($strFile);
219
-
220
-                if ($objModel === null)
221
-                {
222
-                    $objModel = Dbafs::addResource($strFile);
223
-                }
224
-
225
-                $strUuid = StringUtil::binToUuid($objModel->uuid);
226
-
227
-                // Update the hash of the target folder
228
-                Dbafs::updateFolderHashes($strUploadFolder);
229
-
230
-                // Update member avatar
231
-                $objMember->avatar = $objModel->uuid;
232
-                $objMember->save();
233
-            }
234
-
235
-            // Add the session entry
236
-            $_SESSION['FILES']['avatar'] = array
237
-            (
238
-                'name'     => $file['name'],
239
-                'type'     => $file['type'],
240
-                'tmp_name' => $projectDir . '/' . $strFile,
241
-                'error'    => $file['error'],
242
-                'size'     => $file['size'],
243
-                'uploaded' => true,
244
-                'uuid'     => $strUuid
245
-            );
246
-
247
-            // Add a log entry
248
-            $logger = System::getContainer()->get('monolog.logger.contao');
249
-            $logger->log(LogLevel::INFO, 'File "' . $strUploadFolder . '/' . $file['name'] . '" has been uploaded', array('contao' => new ContaoContext(__METHOD__, TL_FILES)));
250
-        }
251
-
252
-        unset($_SESSION['FILES']['avatar']);
253
-    }
254
-
255
-    /**
256
-     * Return the maximum upload file size in bytes
257
-     *
258
-     * @return string
259
-     */
260
-    protected function getMaximumUploadSize()
261
-    {
262
-        if ($this->maxlength > 0)
263
-        {
264
-            return $this->maxlength;
265
-        }
266
-
267
-        return FileUpload::getMaxUploadSize();
268
-    }
269
-
270
-    /**
271
-     * Parses an avatar to the template
272
-     *
273
-     * @param MemberModel|null $objMember
274
-     * @param $objTemplate
275
-     * @param $strImgSize
276
-     * @return void
277
-     */
278
-    public static function parseMemberAvatar(?MemberModel $objMember, &$objTemplate, $strImgSize)
279
-    {
280
-        $objTemplate->addImage= true;
281
-
282
-        $objTemplate->singleSRC = self::DEFAULT_PICTURE;
283
-        $objTemplate->addFallbackImage = true;
284
-
285
-        $projectDir = System::getContainer()->getParameter('kernel.project_dir');
286
-
287
-        // Check if member avatar exists
288
-        if(null === $objMember || null === $objMember->avatar || null === ($objFile = FilesModel::findByUuid($objMember->avatar)) || !\is_file($projectDir.'/'.$objFile->path))
289
-        {
290
-            $objFile = !!($uuidDefault = Config::get('defaultAvatar')) ? FilesModel::findByUuid($uuidDefault) : null;
291
-        }
292
-
293
-        // Check if config avatar exists
294
-        if (null === $objFile || !\is_file($projectDir . '/' . $objFile->path))
295
-        {
296
-            return;
297
-        }
298
-
299
-        $objTemplate->addFallbackImage = false;
300
-        $arrData = ['singleSRC'=>$objFile->path, 'size'=>$strImgSize];
301
-
302
-        //ToDo: Change to FigureBuilder in the future
303
-        $objTemplate->addImageToTemplate($objTemplate, $arrData, null, null, $objFile);
304
-    }
305
-
306
-    /**
307
-     * Gets the url for a member avatar
308
-     *
309
-     * @param MemberModel|null $objMember
310
-     * @return string
311
-     */
312
-    public static function getMemberAvatarURL(?MemberModel $objMember): string
313
-    {
314
-        // ToDo: Merge logic with parseMemberAvatar
315
-        $projectDir = System::getContainer()->getParameter('kernel.project_dir');
316
-
317
-        if(null === $objMember || null === $objMember->avatar || null === ($objFile = FilesModel::findByUuid($objMember->avatar)) || !\is_file($projectDir.'/'. $objFile->path))
318
-        {
319
-            $objFile = !!($uuidDefault = Config::get('defaultAvatar')) ? FilesModel::findByUuid($uuidDefault) : null;
320
-        }
321
-
322
-        // Check if config avatar exists
323
-        if (null === $objFile || !\is_file($projectDir . '/' . $objFile->path))
324
-        {
325
-            return self::DEFAULT_PICTURE;
326
-        }
327
-
328
-        return $objFile->path;
329
-    }
330
-
331
-    /**
332
-     * @param MemberModel $objMember
333
-     *
334
-     * @return void
335
-     */
336
-    public static function deleteAvatar(MemberModel $objMember): void
337
-    {
338
-        if(!!$objMember->avatar)
339
-        {
340
-            $objFile = FilesModel::findByUuid($objMember->avatar) ?: '';
341
-            $projectDir = System::getContainer()->getParameter('kernel.project_dir');
342
-
343
-            // Only delete if file exists
344
-            if (!!$objFile && file_exists($projectDir . '/' . $objFile->path))
345
-            {
346
-                $file = new File($objFile->path);
347
-                $file->delete();
348
-            }
349
-        }
350
-    }
351
-}
352 0
deleted file mode 100644
... ...
@@ -1,44 +0,0 @@
1
-<?php
2
-
3
-declare(strict_types=1);
4
-
5
-/*
6
- * This file is part of Oveleon ContaoMemberExtension Bundle.
7
- *
8
- * @package     contao-member-extension-bundle
9
- * @license     MIT
10
- * @author      Daniele Sciannimanica   <https://github.com/doishub>
11
- * @author      Fabian Ekert            <https://github.com/eki89>
12
- * @author      Sebastian Zoglowek      <https://github.com/zoglo>
13
- * @copyright   Oveleon                 <https://www.oveleon.de/>
14
- */
15
-
16
-// Back end modules
17
-use Contao\System;
18
-
19
-$GLOBALS['BE_MOD']['system']['member_settings'] = array
20
-(
21
-    'tables'            => ['tl_member_settings'],
22
-    'hideInNavigation'  => true,
23
-);
24
-
25
-// Front end modules
26
-// ToDo: Change to ArrayUtil::arrayInsert in the future
27
-array_insert($GLOBALS['FE_MOD']['user'], -1, [
28
-    'avatar'       => 'Oveleon\ContaoMemberExtensionBundle\ModuleAvatar',
29
-    'deleteAvatar' => 'Oveleon\ContaoMemberExtensionBundle\ModuleDeleteAvatar',
30
-    'memberList'   => 'Oveleon\ContaoMemberExtensionBundle\ModuleMemberList',
31
-    'memberReader' => 'Oveleon\ContaoMemberExtensionBundle\ModuleMemberReader'
32
-]);
33
-
34
-// Register hooks
35
-$GLOBALS['TL_HOOKS']['createNewUser'][] = ['Oveleon\ContaoMemberExtensionBundle\Member', 'createAvatar'];
36
-$GLOBALS['TL_HOOKS']['updatePersonalData'][] = ['Oveleon\ContaoMemberExtensionBundle\Member', 'updateAvatar'];
37
-
38
-// Style sheet
39
-$request = System::getContainer()->get('request_stack')->getCurrentRequest();
40
-
41
-if ($request && System::getContainer()->get('contao.routing.scope_matcher')->isBackendRequest($request))
42
-{
43
-    $GLOBALS['TL_CSS'][] = 'bundles/contaomemberextension/style.css|static';
44
-}
45 0
deleted file mode 100644
... ...
@@ -1,39 +0,0 @@
1
-<?php
2
-
3
-declare(strict_types=1);
4
-
5
-/*
6
- * This file is part of Oveleon ContaoMemberExtension Bundle.
7
- *
8
- * @package     contao-member-extension-bundle
9
- * @license     MIT
10
- * @author      Daniele Sciannimanica   <https://github.com/doishub>
11
- * @author      Fabian Ekert            <https://github.com/eki89>
12
- * @author      Sebastian Zoglowek      <https://github.com/zoglo>
13
- * @copyright   Oveleon                 <https://www.oveleon.de/>
14
- */
15
-
16
-// Extend the default palette
17
-Contao\CoreBundle\DataContainer\PaletteManipulator::create()
18
-    ->addField(['avatar'], 'personal_legend', Contao\CoreBundle\DataContainer\PaletteManipulator::POSITION_APPEND)
19
-    ->applyToPalette('default', 'tl_member')
20
-;
21
-
22
-// Add global operations
23
-array_insert($GLOBALS['TL_DCA']['tl_member']['list']['global_operations'], 0, [
24
-    'settings' => [
25
-        'label' => &$GLOBALS['TL_LANG']['tl_member']['settings'],
26
-        'href' => 'do=member_settings',
27
-        'icon' => 'edit.svg',
28
-        'attributes' => 'onclick="Backend.getScrollOffset()" accesskey="e"'
29
-    ]
30
-]);
31
-
32
-// Add fields to tl_user
33
-$GLOBALS['TL_DCA']['tl_member']['fields']['avatar'] = [
34
-    'label' => &$GLOBALS['TL_LANG']['tl_member']['avatar'],
35
-    'exclude' => true,
36
-    'inputType' => 'fileTree',
37
-    'eval' => ['feEditable'=>true, 'feViewable'=>true, 'feGroup'=>'personal', 'fieldType'=>'radio', 'filesOnly'=>true, 'isGallery'=>true, 'extensions'=>Config::get('validImageTypes'), 'tl_class'=>'clr'],
38
-    'sql' => "binary(16) NULL"
39
-];
40 0
deleted file mode 100644
... ...
@@ -1,34 +0,0 @@
1
-<?php
2
-
3
-declare(strict_types=1);
4
-
5
-/*
6
- * This file is part of Oveleon ContaoMemberExtension Bundle.
7
- *
8
- * @package     contao-member-extension-bundle
9
- * @license     MIT
10
- * @author      Daniele Sciannimanica   <https://github.com/doishub>
11
- * @author      Fabian Ekert            <https://github.com/eki89>
12
- * @author      Sebastian Zoglowek      <https://github.com/zoglo>
13
- * @copyright   Oveleon                 <https://www.oveleon.de/>
14
- */
15
-$GLOBALS['TL_DCA']['tl_member_settings'] = [
16
-
17
-	// Config
18
-	'config' => [
19
-		'dataContainer' => 'File',
20
-		'closed' => true
21
-	],
22
-
23
-	// Palettes
24
-	'palettes' => ['default' =>'{avatar_legend},defaultAvatar;'],
25
-
26
-	// Fields
27
-	'fields' => [
28
-		'defaultAvatar' => [
29
-            'label' => &$GLOBALS['TL_LANG']['tl_member_settings']['defaultAvatar'],
30
-            'inputType' => 'fileTree',
31
-            'eval' => array('fieldType'=>'radio', 'filesOnly'=>true, 'isGallery'=>true, 'extensions'=>Config::get('validImageTypes'), 'tl_class'=>'clr')
32
-		]
33
-	]
34
-];
35 0
deleted file mode 100644
... ...
@@ -1,154 +0,0 @@
1
-<?php
2
-
3
-declare(strict_types=1);
4
-
5
-/*
6
- * This file is part of Oveleon ContaoMemberExtension Bundle.
7
- *
8
- * @package     contao-member-extension-bundle
9
- * @license     MIT
10
- * @author      Daniele Sciannimanica   <https://github.com/doishub>
11
- * @author      Fabian Ekert            <https://github.com/eki89>
12
- * @author      Sebastian Zoglowek      <https://github.com/zoglo>
13
- * @copyright   Oveleon                 <https://www.oveleon.de/>
14
- */
15
-
16
-use Contao\Backend;
17
-use Contao\Controller;
18
-use Contao\System;
19
-
20
-System::loadLanguageFile('tl_member_settings');
21
-
22
-// Add palettes to tl_module
23
-// ToDo: Change to ArrayUtil::arrayInsert in the future
24
-array_insert($GLOBALS['TL_DCA']['tl_module']['palettes'], 0, [
25
-    'avatar' => '{title_legend},name,headline,type;{source_legend},imgSize;{template_legend:hide},customTpl;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID',
26
-    'deleteAvatar' => '{title_legend},name,headline,type;{template_legend:hide},customTpl;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID',
27
-    'memberList' => '{title_legend},name,headline,type;{config_legend},ext_order,ext_orderField,numberOfItems,perPage,ext_groups,memberFields,imgSize;{redirect_legend},jumpTo;{template_legend:hide},customTpl,memberListTpl;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID',
28
-    'memberReader' => '{title_legend},name,headline,type;{config_legend},ext_groups,memberFields,imgSize;{template_legend:hide},customTpl,memberReaderTpl;{protected_legend:hide},protected;{expert_legend:hide},guests,cssID'
29
-]);
30
-
31
-$GLOBALS['TL_DCA']['tl_module']['fields']['memberListTpl'] = [
32
-    'exclude' => true,
33
-    'inputType' => 'select',
34
-    'options_callback' => static fn () => Controller::getTemplateGroup('memberExtension_list_'),
35
-    'eval' => ['includeBlankOption'=>true, 'chosen'=>true, 'tl_class'=>'w50'],
36
-    'sql' => "varchar(64) NOT NULL default ''"
37
-];
38
-
39
-$GLOBALS['TL_DCA']['tl_module']['fields']['memberReaderTpl'] = [
40
-    'exclude' => true,
41
-    'inputType' => 'select',
42
-    'options_callback' => static fn () => Controller::getTemplateGroup('memberExtension_reader_'),
43
-    'eval' => ['includeBlankOption'=>true, 'chosen'=>true, 'tl_class'=>'w50'],
44
-    'sql' => "varchar(64) NOT NULL default ''"
45
-];
46
-
47
-$GLOBALS['TL_DCA']['tl_module']['fields']['ext_order'] = [
48
-    'exclude' => true,
49
-    'inputType' => 'select',
50
-    'options' => ['order_random', 'order_asc', 'order_desc'],
51
-    'reference' => &$GLOBALS['TL_LANG']['tl_member_settings'],
52
-    'eval' => ['tl_class'=>'w50 clr', 'includeBlankOption'=>true, 'chosen'=>true,],
53
-    'sql' => "varchar(32) NOT NULL default ''"
54
-];
55
-
56
-$GLOBALS['TL_DCA']['tl_module']['fields']['ext_orderField'] = [
57
-    'exclude' => true,
58
-    'inputType' => 'select',
59
-    'options_callback' => ['tl_module_extension', 'getViewableMemberFields'],
60
-    'eval' => ['tl_class'=>'w50', 'includeBlankOption'=>true, 'chosen'=>true,],
61
-    'sql' => "varchar(32) NOT NULL default ''"
62
-];
63
-
64
-$GLOBALS['TL_DCA']['tl_module']['fields']['memberFields'] = [
65
-    'exclude' => true,
66
-    'inputType' => 'checkboxWizard',
67
-    'options_callback' => ['tl_module_extension', 'getMemberProperties'],
68
-    'eval' => ['multiple'=>true, 'tl_class'=>'clr'],
69
-    'sql' => "blob NULL"
70
-];
71
-
72
-$GLOBALS['TL_DCA']['tl_module']['fields']['ext_groups'] = [
73
-    'exclude' => true,
74
-    'inputType' => 'checkbox',
75
-    'foreignKey' => 'tl_member_group.name',
76
-    'eval' => ['multiple'=>true, 'tl_class'=>'clr'],
77
-    'sql' => "blob NULL",
78
-    'relation' => ['type'=>'hasMany', 'load'=>'lazy']
79
-];
80
-
81
-class tl_module_extension extends Backend
82
-{
83
-    /**
84
-     * Import the back end user object
85
-     */
86
-    public function __construct()
87
-    {
88
-        parent::__construct();
89
-        $this->import('Contao\BackendUser', 'User');
90
-    }
91
-
92
-    /**
93
-     * Check permissions to edit the table
94
-     *
95
-     * @throws Contao\CoreBundle\Exception\AccessDeniedException
96
-     */
97
-    public function checkPermission()
98
-    {
99
-        if ($this->User->isAdmin)
100
-        {
101
-            return;
102
-        }
103
-
104
-        if (!$this->User->hasAccess('modules', 'themes')) {
105
-            throw new Contao\CoreBundle\Exception\AccessDeniedException('Not enough permissions to access the front end modules module.');
106
-        }
107
-    }
108
-
109
-    /**
110
-     * Return all fields of table tl_member without account data
111
-     *
112
-     * @return array
113
-     */
114
-    public function getMemberProperties()
115
-    {
116
-        $return = [];
117
-
118
-        Contao\System::loadLanguageFile('tl_member');
119
-        $this->loadDataContainer('tl_member');
120
-
121
-        foreach ($GLOBALS['TL_DCA']['tl_member']['fields'] as $k=>$v)
122
-        {
123
-            if (!empty($v['inputType']) && $v['inputType'] !== 'password')
124
-            {
125
-                $return[$k] = $GLOBALS['TL_DCA']['tl_member']['fields'][$k]['label'][0];
126
-            }
127
-        }
128
-
129
-        return $return;
130
-    }
131
-
132
-    /**
133
-     * Return all sortable fields of table tl_member
134
-     *
135
-     * @return array
136
-     */
137
-    public function getViewableMemberFields()
138
-    {
139
-        $return = [];
140
-
141
-        Contao\System::loadLanguageFile('tl_member');
142
-        $this->loadDataContainer('tl_member');
143
-
144
-        foreach ($GLOBALS['TL_DCA']['tl_member']['fields'] as $k=>$v)
145
-        {
146
-            if (!empty($v['inputType']) && $v['eval']['feViewable'] === true && $k !== 'avatar')
147
-            {
148
-                $return[$k] = $GLOBALS['TL_DCA']['tl_member']['fields'][$k]['label'][0] . ' ['.$k.']';
149
-            }
150
-        }
151
-
152
-        return $return;
153
-    }
154
-}
155 0
deleted file mode 100644
... ...
@@ -1,22 +0,0 @@
1
-<?xml version="1.0" ?><xliff version="1.1">
2
-  <file datatype="php" original="src/Resources/contao/languages/en/default.php" source-language="en" target-language="de">
3
-    <body>
4
-      <trans-unit id="MSC.emptyMemberList">
5
-        <source>No members could be found.</source>
6
-        <target>Es konnten keine Mitglieder gefunden werden.</target>
7
-      </trans-unit>
8
-      <trans-unit id="MSC.memberDetail">
9
-        <source>More</source>
10
-        <target>Mehr</target>
11
-      </trans-unit>
12
-      <trans-unit id="MSC.deleteAvatar">
13
-        <source>Delete avatar</source>
14
-        <target>Profilbild löschen</target>
15
-      </trans-unit>
16
-      <trans-unit id="MSC.avatarDeleted">
17
-        <source>The avatar was successfully deleted</source>
18
-        <target>Das Profilbild wurde erfolgreich gelöscht</target>
19
-      </trans-unit>
20
-    </body>
21
-  </file>
22
-</xliff>
23 0
deleted file mode 100644
... ...
@@ -1,46 +0,0 @@
1
-<?xml version="1.0" ?><xliff version="1.1">
2
-  <file datatype="php" original="src/Resources/contao/languages/en/modules.php" source-language="en" target-language="de">
3
-    <body>
4
-      <trans-unit id="MOD.member_settings.0">
5
-        <source>Member settings</source>
6
-        <target>Mitglieder-Einstellungen</target>
7
-      </trans-unit>
8
-      <trans-unit id="MOD.member_settings.1">
9
-        <source>Configure member settings</source>
10
-        <target>Mitglieder-Einstellungen vornehmen</target>
11
-      </trans-unit>
12
-      <trans-unit id="FMD.avatar.0">
13
-        <source>Profile picture / Avatar</source>
14
-        <target>Profilbild / Avatar</target>
15
-      </trans-unit>
16
-      <trans-unit id="FMD.avatar.1">
17
-        <source>Displays the profile picture of the member.</source>
18
-        <target>Zeigt das Profilbild des Mitgliedes an.</target>
19
-      </trans-unit>
20
-      <trans-unit id="FMD.deleteAvatar.0">
21
-        <source>Delete avatar</source>
22
-        <target>Profilbild löschen</target>
23
-      </trans-unit>
24
-      <trans-unit id="FMD.deleteAvatar.1">
25
-        <source>Adds a button to delete the avatar of the member.</source>
26
-        <target>Fügt eine Schaltfläche zum Löschen des Profilbildes hinzu.</target>
27
-      </trans-unit>
28
-      <trans-unit id="FMD.memberList.0">
29
-        <source>Memberlist</source>
30
-        <target>Mitgliederliste</target>
31
-      </trans-unit>
32
-      <trans-unit id="FMD.memberList.1">
33
-        <source>Displays a list of members.</source>
34
-        <target>Gibt eine Liste der Mitglieder aus.</target>
35
-      </trans-unit>
36
-      <trans-unit id="FMD.memberReader.0">
37
-        <source>Memberreader</source>
38
-        <target>Mitgliedleser</target>
39
-      </trans-unit>
40
-      <trans-unit id="FMD.memberReader.1">
41
-        <source>Displays a members details.</source>
42
-        <target>Gibt eine Details eines Mitglieds aus.</target>
43
-      </trans-unit>
44
-    </body>
45
-  </file>
46
-</xliff>
47 0
deleted file mode 100644
... ...
@@ -1,22 +0,0 @@
1
-<?xml version="1.0" ?><xliff version="1.1">
2
-  <file datatype="php" original="src/Resources/contao/languages/en/tl_member.php" source-language="en" target-language="de">
3
-    <body>
4
-      <trans-unit id="tl_member.avatar.0">
5
-        <source>Profile picture</source>
6
-        <target>Profilbild</target>
7
-      </trans-unit>
8
-      <trans-unit id="tl_member.avatar.1">
9
-        <source>Here you can choose a profile picture for the member.</source>
10
-        <target>Hier können Sie ein Profilbild für das Mitglied auswählen.</target>
11
-      </trans-unit>
12
-      <trans-unit id="tl_member.settings.0">
13
-        <source>Settings</source>
14
-        <target>Einstellungen</target>
15
-      </trans-unit>
16
-      <trans-unit id="tl_member.settings.1">
17
-        <source>Member settings</source>
18
-        <target>Mitglieder-Einstellungen</target>
19
-      </trans-unit>
20
-    </body>
21
-  </file>
22
-</xliff>
23 0
\ No newline at end of file
24 1
deleted file mode 100644
... ...
@@ -1,30 +0,0 @@
1
-<?xml version="1.0" ?><xliff version="1.1">
2
-  <file datatype="php" original="src/Resources/contao/languages/en/tl_member.php" source-language="en" target-language="de">
3
-    <body>
4
-      <trans-unit id="tl_member_settings.avatar_legend">
5
-        <source>Extended member settings</source>
6
-        <target>Erweiterte Mitgliedseinstellungen</target>
7
-      </trans-unit>
8
-      <trans-unit id="tl_member_settings.defaultAvatar.0">
9
-        <source>Default avatar</source>
10
-        <target>Standard-Profilbild</target>
11
-      </trans-unit>
12
-      <trans-unit id="tl_member_settings.defaultAvatar.1">
13
-        <source>The default avatar is displayed for members who have not uploaded their own profile picture.</source>
14
-        <target>Das Standard-Profilbild wird bei Mitgliedern angezeigt, welches kein eigenes Profilbild hochgeladen haben.</target>
15
-      </trans-unit>
16
-      <trans-unit id="tl_member_settings.order_random">
17
-        <source>Random order</source>
18
-        <target>Zufällige Reihenfolge</target>
19
-      </trans-unit>
20
-      <trans-unit id="tl_member_settings.order_asc">
21
-        <source>Ascending</source>
22
-        <target>Aufsteigend</target>
23
-      </trans-unit>
24
-      <trans-unit id="tl_member_settings.order_desc">
25
-        <source>Descending</source>
26
-        <target>Absteigend</target>
27
-      </trans-unit>
28
-    </body>
29
-  </file>
30
-</xliff>
31 0
deleted file mode 100644
... ...
@@ -1,62 +0,0 @@
1
-<?xml version="1.0" ?><xliff version="1.1">
2
-  <file datatype="php" original="src/Resources/contao/languages/en/tl_module.php" source-language="en" target-language="de">
3
-    <body>
4
-      <trans-unit id="tl_module.ext_order.0">
5
-        <source>Sort order</source>
6
-        <target>Sortierreihenfolge</target>
7
-      </trans-unit>
8
-      <trans-unit id="tl_module.ext_order.1">
9
-        <source>Here you can choose the sort order.</source>
10
-        <target>Hier können Sie die Sortierreihenfolge festlegen.</target>
11
-      </trans-unit>
12
-      <trans-unit id="tl_module.ext_orderField.0">
13
-        <source>Sorting field</source>
14
-        <target>Sortierfeld</target>
15
-      </trans-unit>
16
-      <trans-unit id="tl_module.ext_orderField.1">
17
-        <source>Here you can select the field to be sorted by.</source>
18
-        <target>Hier können Sie das Feld auswählen, nach dem sortiert werden soll.</target>
19
-      </trans-unit>
20
-      <trans-unit id="tl_module.ext_groups.0">
21
-        <source>Groups to show</source>
22
-        <target>Anzuzeigende Gruppen</target>
23
-      </trans-unit>
24
-      <trans-unit id="tl_module.ext_groups.1">
25
-        <source>Here you can select the member groups to be displayed.</source>
26
-        <target>Hier können Sie die Mitgliedergruppen auswählen, die angezeigt werden sollen.</target>
27
-      </trans-unit>
28
-      <trans-unit id="tl_module.memberFields.0">
29
-        <source>Member fields</source>
30
-        <target>Mitglieds-Felder</target>
31
-      </trans-unit>
32
-      <trans-unit id="tl_module.memberFields.1">
33
-        <source>Here you can select the member fields to be displayed.</source>
34
-        <target>Hier können Sie die auszugebenden Mitgliederfelder auswählen.</target>
35
-      </trans-unit>
36
-      <trans-unit id="tl_module.memberFields.0">
37
-        <source>Member fields</source>
38
-        <target>Mitglieds-Felder</target>
39
-      </trans-unit>
40
-      <trans-unit id="tl_module.memberFields.1">
41
-        <source>Here you can select the member fields to be output.</source>
42
-        <target>Hier können Sie die auszugebenden Mitgliederfelder auswählen.</target>
43
-      </trans-unit>
44
-      <trans-unit id="tl_module.memberListTpl.0">
45
-        <source>List template</source>
46
-        <target>Listen-Template</target>
47
-      </trans-unit>
48
-      <trans-unit id="tl_module.memberListTpl.1">
49
-        <source>Here you can set your own member list template.</source>
50
-        <target>Hier können Sie ein eigenes Mitglieder-Listen Template einstellen.</target>
51
-      </trans-unit>
52
-      <trans-unit id="tl_module.memberReaderTpl.0">
53
-        <source>Reader template</source>
54
-        <target>Leser-Template</target>
55
-      </trans-unit>
56
-      <trans-unit id="tl_module.memberReaderTpl.1">
57
-        <source>Here you can set your own member reader template.</source>
58
-        <target>Hier können Sie ein eigenes Mitglieds-Leser Template einstellen.</target>
59
-      </trans-unit>
60
-    </body>
61
-  </file>
62
-</xliff>
63 0
deleted file mode 100644
... ...
@@ -1,18 +0,0 @@
1
-<?xml version="1.0" ?><xliff version="1.1">
2
-  <file datatype="php" original="src/Resources/contao/languages/en/default.php" source-language="en">
3
-    <body>
4
-      <trans-unit id="MSC.emptyMemberList">
5
-        <source>No members could be found.</source>
6
-      </trans-unit>
7
-      <trans-unit id="MSC.memberDetail">
8
-        <source>More</source>
9
-      </trans-unit>
10
-      <trans-unit id="MSC.deleteAvatar">
11
-        <source>Delete avatar</source>
12
-      </trans-unit>
13
-      <trans-unit id="MSC.avatarDeleted">
14
-        <source>The avatar was successfully deleted</source>
15
-      </trans-unit>
16
-    </body>
17
-  </file>
18
-</xliff>
19 0
deleted file mode 100644
... ...
@@ -1,36 +0,0 @@
1
-<?xml version="1.0" ?><xliff version="1.1">
2
-  <file datatype="php" original="src/Resources/contao/languages/en/modules.php" source-language="en">
3
-    <body>
4
-      <trans-unit id="MOD.member_settings.0">
5
-        <source>Member settings</source>
6
-      </trans-unit>
7
-      <trans-unit id="MOD.member_settings.1">
8
-        <source>Configure member settings</source>
9
-      </trans-unit>
10
-      <trans-unit id="FMD.avatar.0">
11
-        <source>Avatar / profile picture</source>
12
-      </trans-unit>
13
-      <trans-unit id="FMD.avatar.1">
14
-        <source>Displays the avatar of the member.</source>
15
-      </trans-unit>
16
-      <trans-unit id="FMD.deleteAvatar.0">
17
-        <source>Delete avatar</source>
18
-      </trans-unit>
19
-      <trans-unit id="FMD.deleteAvatar.1">
20
-        <source>Adds a button to delete the avatar of the member.</source>
21
-      </trans-unit>
22
-      <trans-unit id="FMD.memberList.0">
23
-        <source>Memberlist</source>
24
-      </trans-unit>
25
-      <trans-unit id="FMD.memberList.1">
26
-        <source>Displays a list of members.</source>
27
-      </trans-unit>
28
-      <trans-unit id="FMD.memberReader.0">
29
-        <source>Memberreader</source>
30
-      </trans-unit>
31
-      <trans-unit id="FMD.memberReader.1">
32
-        <source>Displays a members details.</source>
33
-      </trans-unit>
34
-    </body>
35
-  </file>
36
-</xliff>
37 0
deleted file mode 100644
... ...
@@ -1,18 +0,0 @@
1
-<?xml version="1.0" ?><xliff version="1.1">
2
-  <file datatype="php" original="src/Resources/contao/languages/en/tl_member.php" source-language="en">
3
-    <body>
4
-      <trans-unit id="tl_member.avatar.0">
5
-        <source>Avatar</source>
6
-      </trans-unit>
7
-      <trans-unit id="tl_member.avatar.1">
8
-        <source>Here you can choose an avatar for the member.</source>
9
-      </trans-unit>
10
-      <trans-unit id="tl_member.settings.0">
11
-        <source>Settings</source>
12
-      </trans-unit>
13
-      <trans-unit id="tl_member.settings.1">
14
-        <source>Member settings</source>
15
-      </trans-unit>
16
-    </body>
17
-  </file>
18
-</xliff>
19 0
\ No newline at end of file
20 1
deleted file mode 100644
... ...
@@ -1,24 +0,0 @@
1
-<?xml version="1.0" ?><xliff version="1.1">
2
-  <file datatype="php" original="src/Resources/contao/languages/en/tl_member.php" source-language="en">
3
-    <body>
4
-      <trans-unit id="tl_member_settings.avatar_legend">
5
-        <source>Extended member settings</source>
6
-      </trans-unit>
7
-      <trans-unit id="tl_member_settings.defaultAvatar.0">
8
-        <source>Default avatar</source>
9
-      </trans-unit>
10
-      <trans-unit id="tl_member_settings.defaultAvatar.1">
11
-        <source>The default avatar is displayed for members who have not uploaded their own profile picture.</source>
12
-      </trans-unit>
13
-      <trans-unit id="tl_member_settings.order_random">
14
-        <source>Random order</source>
15
-      </trans-unit>
16
-      <trans-unit id="tl_member_settings.order_asc">
17
-        <source>Ascending</source>
18
-      </trans-unit>
19
-      <trans-unit id="tl_member_settings.order_desc">
20
-        <source>Descending</source>
21
-      </trans-unit>
22
-    </body>
23
-  </file>
24
-</xliff>
25 0
deleted file mode 100644
... ...
@@ -1,48 +0,0 @@
1
-<?xml version="1.0" ?><xliff version="1.1">
2
-  <file datatype="php" original="src/Resources/contao/languages/en/tl_module.php" source-language="en">
3
-    <body>
4
-      <trans-unit id="tl_module.ext_order.0">
5
-        <source>Sort order</source>
6
-      </trans-unit>
7
-      <trans-unit id="tl_module.ext_order.1">
8
-        <source>Here you can choose the sort order.</source>
9
-      </trans-unit>
10
-      <trans-unit id="tl_module.ext_orderField.0">
11
-        <source>Sorting field</source>
12
-      </trans-unit>
13
-      <trans-unit id="tl_module.ext_orderField.1">
14
-        <source>Here you can select the field to be sorted by.</source>
15
-      </trans-unit>
16
-      <trans-unit id="tl_module.ext_groups.0">
17
-        <source>Groups to show</source>
18
-      </trans-unit>
19
-      <trans-unit id="tl_module.ext_groups.1">
20
-        <source>Here you can select the member groups to be displayed.</source>
21
-      </trans-unit>
22
-      <trans-unit id="tl_module.memberFields.0">
23
-        <source>Member fields</source>
24
-      </trans-unit>
25
-      <trans-unit id="tl_module.memberFields.1">
26
-        <source>Here you can select the member fields to be displayed.</source>
27
-      </trans-unit>
28
-      <trans-unit id="tl_module.memberFields.0">
29
-        <source>Member fields</source>
30
-      </trans-unit>
31
-      <trans-unit id="tl_module.memberFields.1">
32
-        <source>Here you can select the member fields to be output.</source>
33
-      </trans-unit>
34
-      <trans-unit id="tl_module.memberListTpl.0">
35
-        <source>List template</source>
36
-      </trans-unit>
37
-      <trans-unit id="tl_module.memberListTpl.1">
38
-        <source>Here you can set your own member list template.</source>
39
-      </trans-unit>
40
-      <trans-unit id="tl_module.memberReaderTpl.0">
41
-        <source>Reader template</source>
42
-      </trans-unit>
43
-      <trans-unit id="tl_module.memberReaderTpl.1">
44
-        <source>Here you can set your own member reader template.</source>
45
-      </trans-unit>
46
-    </body>
47
-  </file>
48
-</xliff>
49 0
deleted file mode 100644
... ...
@@ -1,88 +0,0 @@
1
-<?php
2
-
3
-declare(strict_types=1);
4
-
5
-/*
6
- * This file is part of Oveleon ContaoMemberExtension Bundle.
7
- *
8
- * @package     contao-member-extension-bundle
9
- * @license     MIT
10
- * @author      Daniele Sciannimanica   <https://github.com/doishub>
11
- * @author      Fabian Ekert            <https://github.com/eki89>
12
- * @author      Sebastian Zoglowek      <https://github.com/zoglo>
13
- * @copyright   Oveleon                 <https://www.oveleon.de/>
14
- */
15
-
16
-namespace Oveleon\ContaoMemberExtensionBundle;
17
-
18
-use Contao\BackendTemplate;
19
-use Contao\Config;
20
-use Contao\FilesModel;
21
-use Contao\FrontendUser;
22
-use Contao\MemberModel;
23
-use Contao\Module;
24
-use Contao\System;
25
-
26
-/**
27
- * Class ModuleAvatar
28
- *
29
- * @author Fabian Ekert <fabian@oveleon.de>
30
- * @author Sebastian Zoglowek <https://github.com/zoglo>
31
- */
32
-class ModuleAvatar extends ModuleMemberExtension
33
-{
34
-    /**
35
-     * Template.
36
-     *
37
-     * @var string
38
-     */
39
-    protected $strTemplate = 'memberExtension_avatar';
40
-
41
-    /**
42
-     * Return a wildcard in the back end
43
-     *
44
-     * @return string
45
-     */
46
-    public function generate()
47
-    {
48
-        $request = System::getContainer()->get('request_stack')->getCurrentRequest();
49
-
50
-        if ($request && System::getContainer()->get('contao.routing.scope_matcher')->isBackendRequest($request))
51
-        {
52
-            $objTemplate = new BackendTemplate('be_wildcard');
53
-            $objTemplate->wildcard = '### ' . mb_strtoupper($GLOBALS['TL_LANG']['FMD']['avatar'][0], 'UTF-8') . ' ###';
54
-            $objTemplate->title = $this->headline;
55
-            $objTemplate->id = $this->id;
56
-            $objTemplate->link = $this->name;
57
-            $objTemplate->href = 'contao/main.php?do=themes&amp;table=tl_module&amp;act=edit&amp;id=' . $this->id;
58
-
59
-            return $objTemplate->parse();
60
-        }
61
-
62
-        // Return if user is not logged in
63
-        $tokenChecker = System::getContainer()->get('contao.security.token_checker');
64
-        $blnFeUserLoggedIn = $tokenChecker->hasFrontendUser();
65
-
66
-        if (!$blnFeUserLoggedIn)
67
-        {
68
-            return '';
69
-        }
70
-
71
-        $this->strTemplate = $this->customTpl ?: 'memberExtension_avatar';
72
-
73
-        return parent::generate();
74
-    }
75
-
76
-    /**
77
-     * Generate the module
78
-     */
79
-    protected function compile()
80
-    {
81
-        $objTemplate = $this->Template;
82
-
83
-        $this->import(FrontendUser::class, 'User');
84
-        $objMember = MemberModel::findByPk($this->User->id);
85
-
86
-        Member::parseMemberAvatar($objMember, $objTemplate, $this->imgSize);
87
-    }
88
-}
89 0
deleted file mode 100644
... ...
@@ -1,135 +0,0 @@
1
-<?php
2
-
3
-declare(strict_types=1);
4
-
5
-/*
6
- * This file is part of Oveleon ContaoMemberExtension Bundle.
7
- *
8
- * @package     contao-member-extension-bundle
9
- * @license     MIT
10
- * @author      Daniele Sciannimanica   <https://github.com/doishub>
11
- * @author      Fabian Ekert            <https://github.com/eki89>
12
- * @author      Sebastian Zoglowek      <https://github.com/zoglo>
13
- * @copyright   Oveleon                 <https://www.oveleon.de/>
14
- */
15
-
16
-namespace Oveleon\ContaoMemberExtensionBundle;
17
-
18
-use Contao\BackendTemplate;
19
-use Contao\Config;
20
-use Contao\FrontendUser;
21
-use Contao\Input;
22
-use Contao\MemberModel;
23
-use Contao\Module;
24
-use Contao\StringUtil;
25
-use Contao\System;
26
-
27
-/**
28
- * Class ModuleDeleteAvatar
29
- *
30
- * @author Sebastian Zoglowek <https://github.com/zoglo>
31
- */
32
-class ModuleDeleteAvatar extends Module
33
-{
34
-    /**
35
-     * Template.
36
-     *
37
-     * @var string
38
-     */
39
-    protected $strTemplate = 'memberExtension_deleteAvatar';
40
-
41
-    /**
42
-     * Return a wildcard in the back end
43
-     *
44
-     * @return string
45
-     */
46
-    public function generate()
47
-    {
48
-        $container = System::getContainer();
49
-
50
-        $request = System::getContainer()->get('request_stack')->getCurrentRequest();
51
-
52
-        if ($request && System::getContainer()->get('contao.routing.scope_matcher')->isBackendRequest($request))
53
-        {
54
-            $objTemplate = new BackendTemplate('be_wildcard');
55
-            $objTemplate->wildcard = '### ' . mb_strtoupper($GLOBALS['TL_LANG']['FMD']['deleteAvatar'][0] ?? '', 'UTF-8') . ' ###';
56
-            $objTemplate->title = $this->headline;
57
-            $objTemplate->id = $this->id;
58
-            $objTemplate->link = $this->name;
59
-            $objTemplate->href = 'contao/main.php?do=themes&amp;table=tl_module&amp;act=edit&amp;id=' . $this->id;
60
-
61
-            return $objTemplate->parse();
62
-        }
63
-
64
-        // Set the item from the auto_item parameter
65
-        if (!isset($_GET['items']) && isset($_GET['auto_item']) && Config::get('useAutoItem'))
66
-        {
67
-            Input::setGet('items', Input::get('auto_item'));
68
-        }
69
-
70
-        // Return if there is no logged-in user
71
-        if (!$container->get('contao.security.token_checker')->hasFrontendUser())
72
-        {
73
-            return '';
74
-        }
75
-
76
-        $this->import(FrontendUser::class, 'User');
77
-        $objMember = MemberModel::findByPk($this->User->id);
78
-
79
-        if(null === $objMember)
80
-        {
81
-            return '';
82
-        }
83
-
84
-        // Confirmation message
85
-        $session = System::getContainer()->get('session');
86
-        $flashBag = $session->getFlashBag();
87
-
88
-        // Return if there is no flashbag message or an avatar
89
-        if (!($session->isStarted() && $flashBag->has('mod_avatar_deleted')) && !$objMember->avatar)
90
-        {
91
-            return '';
92
-        }
93
-
94
-        return parent::generate();
95
-    }
96
-
97
-    /**
98
-     * Generate the module
99
-     */
100
-    protected function compile()
101
-    {
102
-        $strFormId = 'deleteAvatar_' . $this->id;
103
-        $session = System::getContainer()->get('session');
104
-        $flashBag = $session->getFlashBag();
105
-
106
-        // Get form submit
107
-        if (Input::post('FORM_SUBMIT') == $strFormId)
108
-        {
109
-            $this->import(FrontendUser::class, 'User');
110
-            $objMember = MemberModel::findByPk($this->User->id);
111
-
112
-            // Delete avatar if it exists
113
-            if(!!$objMember->avatar)
114
-            {
115
-                Member::deleteAvatar($objMember);
116
-                // Unset avatar
117
-                $objMember->avatar = null;
118
-                $objMember->save();
119
-
120
-                // Set message for deletion feedback
121
-                $flashBag->set('mod_avatar_deleted', $GLOBALS['TL_LANG']['MSC']['avatarDeleted']);
122
-                $this->reload();
123
-            }
124
-        }
125
-
126
-        // Confirmation message
127
-        if($session->isStarted() && $flashBag->has('mod_avatar_deleted')) {
128
-            $arrMessages = $flashBag->get('mod_avatar_deleted');
129
-            $this->Template->message = $arrMessages[0];
130
-        }
131
-
132
-        $this->Template->formId = $strFormId;
133
-        $this->Template->slabel = StringUtil::specialchars($GLOBALS['TL_LANG']['MSC']['deleteAvatar']);
134
-    }
135
-}
136 0
deleted file mode 100644
... ...
@@ -1,178 +0,0 @@
1
-<?php
2
-
3
-declare(strict_types=1);
4
-
5
-/*
6
- * This file is part of Oveleon ContaoMemberExtension Bundle.
7
- *
8
- * @package     contao-member-extension-bundle
9
- * @license     MIT
10
- * @author      Daniele Sciannimanica   <https://github.com/doishub>
11
- * @author      Fabian Ekert            <https://github.com/eki89>
12
- * @author      Sebastian Zoglowek      <https://github.com/zoglo>
13
- * @copyright   Oveleon                 <https://www.oveleon.de/>
14
- */
15
-
16
-namespace Oveleon\ContaoMemberExtensionBundle;
17
-
18
-use Contao\Config;
19
-use Contao\Date;
20
-use Contao\Environment;
21
-use Contao\MemberGroupModel;
22
-use Contao\MemberModel;
23
-use Contao\Module;
24
-use Contao\PageModel;
25
-use Contao\StringUtil;
26
-use Contao\System;
27
-
28
-/**
29
- * Parent class for member modules.
30
- *
31
- * @author Daniele Sciannimanica <https://github.com/doishub>
32
- */
33
-abstract class ModuleMemberExtension extends Module
34
-{
35
-    /**
36
-     * Parse member template
37
-     *
38
-     * @param $objMember
39
-     * @param $objTemplate
40
-     * @param $arrMemberFields
41
-     * @param $strImgSize
42
-     * @return string
43
-     */
44
-    protected function parseMemberTemplate($objMember, $objTemplate, $arrMemberFields, $strImgSize): string
45
-    {
46
-        System::loadLanguageFile('default');
47
-        System::loadLanguageFile('tl_member');
48
-        System::loadLanguageFile('countries');
49
-        System::loadLanguageFile('languages');
50
-
51
-        $arrFields = [];
52
-
53
-        foreach ($arrMemberFields as $field)
54
-        {
55
-            switch($field)
56
-            {
57
-                /*case 'homeDir':
58
-                case 'assignDir':
59
-                    break;*/
60
-
61
-                case 'avatar':
62
-                    Member::parseMemberAvatar($objMember, $objTemplate, $strImgSize);
63
-                    break;
64
-
65
-                default:
66
-                    if($varValue = $objMember->{$field})
67
-                    {
68
-                        if (\is_array(($arrValue = StringUtil::deserialize($varValue))))
69
-                        {
70
-                            $arrFields[$field] = implode(",", $arrValue);
71
-                        }
72
-                        else
73
-                        {
74
-                            $arrFields[$field] = $varValue;
75
-                        }
76
-                        //self::parseMemberDetails($arrFields, $field, $varValue);
77
-                    }
78
-            }
79
-        }
80
-
81
-        $objTemplate->fields = $arrFields;
82
-
83
-        if($this->jumpTo)
84
-        {
85
-            $objTemplate->link = $this->generateMemberUrl($objMember);
86
-        }
87
-
88
-        return $objTemplate->parse();
89
-    }
90
-
91
-    /**
92
-     * Generate a URL and return it as string
93
-     *
94
-     * @param MemberModel $objMember
95
-     *
96
-     * @return string
97
-     */
98
-    protected function generateMemberUrl(MemberModel $objMember): string
99
-    {
100
-        $objPage = PageModel::findPublishedById($this->jumpTo);
101
-
102
-        if (!$objPage instanceof PageModel)
103
-        {
104
-            $strLink = ampersand(Environment::get('request'));
105
-        }
106
-        else
107
-        {
108
-            $params = (Config::get('useAutoItem') ? '/' : '/items/') . ($objMember->alias ?: $objMember->id);
109
-            $strLink = ampersand($objPage->getFrontendUrl($params));
110
-        }
111
-
112
-        return $strLink;
113
-    }
114
-
115
-    protected function parseMemberDetails(&$arrFields, $field, $value)
116
-    {
117
-        $strReturn = sprintf('<span class="label">%s: </span>',$GLOBALS['TL_LANG']['tl_member'][$field][0] ?? null);
118
-
119
-        if (!\is_array(($arrValue = StringUtil::deserialize($value))))
120
-        {
121
-            switch ($field) {
122
-                case 'gender':
123
-                    $strReturn .= $GLOBALS['TL_LANG']['MSC'][$value] ?? $value;
124
-                    break;
125
-
126
-                case 'email':
127
-                    $strEmail = StringUtil::encodeEmail($value);
128
-                    $strReturn .= '<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;' . $strEmail . '" title="' . $strEmail . '">' . preg_replace('/\?.*$/', '', $strEmail) . '</a>';
129
-                    break;
130
-
131
-                case 'phone':
132
-                case 'mobile':
133
-                case 'fax':
134
-                    $strTel = preg_replace('/[^a-z\d+]/i', '', (string)$value);
135
-                    $strReturn .= '<a href="tel:' . $strTel . '" title="' . $value . '">' . $value . '</a>';
136
-                    break;
137
-
138
-                case 'website':
139
-                    $strUrl = $value;
140
-
141
-                    if (strncmp($value, 'http://', 7) !== 0 || strncmp($value, 'https://', 8) !== 0) {
142
-                        $strUrl = 'https://' . $value;
143
-                    }
144
-
145
-                    $strReturn .= '<a href="' . $strUrl . '" title="' . $value . '" target="blank noopener" rel="noreferer">' . $value . '</a>';
146
-                    break;
147
-
148
-                case 'dateOfBirth':
149
-                    $strReturn .= Date::parse(Config::get('dateFormat'), $value) ?? $value;
150
-                    break;
151
-
152
-                case 'country':
153
-                    $strReturn .= $GLOBALS['TL_LANG']['CNT'][$value] ?? $value;
154
-                    break;
155
-
156
-                case 'language':
157
-                    $strReturn .= $GLOBALS['TL_LANG']['LNG'][$value] ?? $value;
158
-                    break;
159
-
160
-                default:
161
-                    $strReturn .= $value;
162
-            }
163
-        }
164
-        else if ('groups' === $field)
165
-        {
166
-            $arrReturn = [];
167
-
168
-            foreach ($arrValue as $value)
169
-            {
170
-                $arrReturn[] = MemberGroupModel::findById($value)->name;
171
-            }
172
-
173
-            $strReturn .= implode(", ", $arrReturn);
174
-        }
175
-
176
-        $arrFields[$field] = $strReturn;
177
-    }
178
-}
179 0
deleted file mode 100644
... ...
@@ -1,223 +0,0 @@
1
-<?php
2
-
3
-declare(strict_types=1);
4
-
5
-/*
6
- * This file is part of Oveleon ContaoMemberExtension Bundle.
7
- *
8
- * @package     contao-member-extension-bundle
9
- * @license     MIT
10
- * @author      Daniele Sciannimanica   <https://github.com/doishub>
11
- * @author      Fabian Ekert            <https://github.com/eki89>
12
- * @author      Sebastian Zoglowek      <https://github.com/zoglo>
13
- * @copyright   Oveleon                 <https://www.oveleon.de/>
14
- */
15
-
16
-namespace Oveleon\ContaoMemberExtensionBundle;
17
-
18
-use Contao\BackendTemplate;
19
-use Contao\Config;
20
-use Contao\CoreBundle\Exception\PageNotFoundException;
21
-use Contao\Environment;
22
-use Contao\FrontendTemplate;
23
-use Contao\Input;
24
-use Contao\MemberModel;
25
-use Contao\Model\Collection;
26
-use Contao\Pagination;
27
-use Contao\StringUtil;
28
-use Contao\System;
29
-
30
-/**
31
- * Class ModuleMemberList
32
- *
33
- * @property string $ext_order order of list items
34
- * @property string ext_orderField order field for list items
35
- * @property string $ext_groups considered member groups
36
- * @property string $memberFields Fields to be displayed
37
- * @property string $memberListTpl Frontend list template
38
- */
39
-class ModuleMemberList extends ModuleMemberExtension
40
-{
41
-
42
-	/**
43
-	 * Template
44
-	 * @var string
45
-	 */
46
-	protected $strTemplate = 'mod_memberList';
47
-
48
-	/**
49
-	 * Template
50
-	 * @var string
51
-	 */
52
-	protected $strMemberTemplate = 'memberExtension_list_default';
53
-
54
-	/**
55
-	 * Return a wildcard in the back end
56
-	 *
57
-	 * @return string
58
-	 */
59
-	public function generate()
60
-	{
61
-        $request = System::getContainer()->get('request_stack')->getCurrentRequest();
62
-
63
-        if ($request && System::getContainer()->get('contao.routing.scope_matcher')->isBackendRequest($request))
64
-        {
65
-            $objTemplate = new BackendTemplate('be_wildcard');
66
-			$objTemplate->wildcard = '### ' . mb_strtoupper($GLOBALS['TL_LANG']['FMD']['memberList'][0], 'UTF-8') . ' ###';
67
-			$objTemplate->title = $this->headline;
68
-			$objTemplate->id = $this->id;
69
-			$objTemplate->link = $this->name;
70
-			$objTemplate->href = 'contao/main.php?do=themes&amp;table=tl_module&amp;act=edit&amp;id=' . $this->id;
71
-
72
-			return $objTemplate->parse();
73
-		}
74
-
75
-		return parent::generate();
76
-	}
77
-
78
-	/**
79
-	 * Generate the module
80
-	 */
81
-	protected function compile()
82
-	{
83
-        $limit = null;
84
-        $offset = 0;
85
-
86
-        $arrGroups = StringUtil::deserialize($this->ext_groups);
87
-
88
-        if(empty($arrGroups) || !\is_array($arrGroups))
89
-        {
90
-            $this->Template->empty = $GLOBALS['TL_LANG']['MSC']['emptyMemberList'];
91
-            return;
92
-        }
93
-
94
-        $objTemplate = new FrontendTemplate($this->memberListTpl ?: $this->strMemberTemplate);
95
-
96
-        $objMembers = $this->getMembers();
97
-
98
-        $intTotal = 0;
99
-
100
-        $arrMembers = [];
101
-
102
-        if(null !== $objMembers)
103
-        {
104
-            while($objMembers->next())
105
-            {
106
-                $objMember = $objMembers->current();
107
-
108
-                if(!$this->checkMemberGroups($arrGroups, $objMember))
109
-                {
110
-                    continue;
111
-                }
112
-
113
-                $intTotal += 1;
114
-
115
-                $arrMemberFields = StringUtil::deserialize($this->memberFields, true);
116
-                $objTemplate->setData($objMember->row());
117
-
118
-                $arrMembers[] = $this->parseMemberTemplate($objMember, $objTemplate, $arrMemberFields, $this->imgSize);
119
-            }
120
-        }
121
-
122
-        $total = $intTotal - $offset;
123
-
124
-        if ($this->numberOfItems > 0)
125
-        {
126
-            $limit = $this->numberOfItems;
127
-        }
128
-
129
-        if ($this->perPage > 0 && (!isset($limit) || $this->numberOfItems > $this->perPage))
130
-        {
131
-            if (isset($limit))
132
-            {
133
-                $total = min($limit, $total);
134
-            }
135
-
136
-            $id = 'page_n' . $this->id;
137
-            $page = Input::get($id) ?? 1;
138
-
139
-            if ($page < 1 || $page > max(ceil($total/$this->perPage), 1))
140
-            {
141
-                throw new PageNotFoundException('Page not found: ' . Environment::get('uri'));
142
-            }
143
-
144
-            $limit = $this->perPage;
145
-            $offset += (max($page, 1) - 1) * $this->perPage;
146
-            $skip = 0;
147
-
148
-            if ($offset + $limit > $total + $skip)
149
-            {
150
-                $limit = $total + $skip - $offset;
151
-            }
152
-
153
-            $arrMembers = \array_slice($arrMembers, $offset, ((int) $limit ?: $intTotal), true);
154
-
155
-            $objPagination = new Pagination($total, $this->perPage, Config::get('maxPaginationLinks'), $id);
156
-            $this->Template->pagination = $objPagination->generate("\n  ");
157
-        }
158
-
159
-        if(empty($arrMembers))
160
-        {
161
-            $this->Template->empty = $GLOBALS['TL_LANG']['MSC']['emptyMemberList'];
162
-        }
163
-
164
-        $this->Template->members = $arrMembers;
165
-	}
166
-
167
-    /**
168
-     * Checks whether a member is in any given group
169
-     *
170
-     * @param array $arrGroups
171
-     * @param MemberModel $objMember
172
-     * @return bool
173
-     */
174
-    private function checkMemberGroups(array $arrGroups, MemberModel $objMember): bool
175
-    {
176
-        if(empty($arrGroups))
177
-        {
178
-            return false;
179
-        }
180
-
181
-        $arrMemberGroups = StringUtil::deserialize($objMember->groups);
182
-
183
-        if(!\is_array($arrMemberGroups) || !\count(array_intersect($arrGroups, $arrMemberGroups)))
184
-        {
185
-            return false;
186
-        }
187
-
188
-        return true;
189
-    }
190
-
191
-    /**
192
-     * Get members
193
-     *
194
-     * @return Collection|MemberModel|null
195
-     */
196
-    private function getMembers()
197
-    {
198
-        $arrOptions = [];
199
-        $t = MemberModel::getTable();
200
-
201
-        if (!!$this->ext_orderField)
202
-        {
203
-            $arrOptions['order'] .= "$t.$this->ext_orderField ";
204
-        }
205
-
206
-        switch ($this->ext_order)
207
-        {
208
-            case 'order_random':
209
-                $arrOptions['order'] = "RAND()";
210
-                break;
211
-
212
-            case 'order_desc':
213
-                $arrOptions['order'] .= "DESC";
214
-                break;
215
-
216
-            case 'order_asc':
217
-            default:
218
-                break;
219
-        }
220
-
221
-        return MemberModel::findBy(["$t.disable=''"], null, $arrOptions);
222
-    }
223
-}
224 0
deleted file mode 100644
... ...
@@ -1,113 +0,0 @@
1
-<?php
2
-
3
-declare(strict_types=1);
4
-
5
-/*
6
- * This file is part of Oveleon ContaoMemberExtension Bundle.
7
- *
8
- * @package     contao-member-extension-bundle
9
- * @license     MIT
10
- * @author      Daniele Sciannimanica   <https://github.com/doishub>
11
- * @author      Fabian Ekert            <https://github.com/eki89>
12
- * @author      Sebastian Zoglowek      <https://github.com/zoglo>
13
- * @copyright   Oveleon                 <https://www.oveleon.de/>
14
- */
15
-
16
-namespace Oveleon\ContaoMemberExtensionBundle;
17
-
18
-use Contao\BackendTemplate;
19
-use Contao\Config;
20
-use Contao\CoreBundle\Exception\PageNotFoundException;
21
-use Contao\Environment;
22
-use Contao\FrontendTemplate;
23
-use Contao\Input;
24
-use Contao\MemberModel;
25
-use Contao\StringUtil;
26
-use Contao\System;
27
-
28
-/**
29
- * Class ModuleMemberList
30
- * 
31
- * @property string $ext_groups considered member groups
32
- * @property string $memberFields Fields to be displayed
33
- * @property string $memberReaderTpl Frontend reader template
34
- */
35
-class ModuleMemberReader extends ModuleMemberExtension
36
-{
37
-
38
-	/**
39
-	 * Template
40
-	 * @var string
41
-	 */
42
-	protected $strTemplate = 'mod_memberReader';
43
-
44
-	/**
45
-	 * Template
46
-	 * @var string
47
-	 */
48
-	protected $strMemberTemplate = 'memberExtension_reader_full';
49
-
50
-	/**
51
-	 * Return a wildcard in the back end
52
-	 *
53
-	 * @return string
54
-	 */
55
-	public function generate()
56
-	{
57
-        $request = System::getContainer()->get('request_stack')->getCurrentRequest();
58
-
59
-        if ($request && System::getContainer()->get('contao.routing.scope_matcher')->isBackendRequest($request))
60
-        {
61
-            $objTemplate = new BackendTemplate('be_wildcard');
62
-			$objTemplate->wildcard = '### ' . mb_strtoupper($GLOBALS['TL_LANG']['FMD']['memberList'][0], 'UTF-8') . ' ###';
63
-			$objTemplate->title = $this->headline;
64
-			$objTemplate->id = $this->id;
65
-			$objTemplate->link = $this->name;
66
-			$objTemplate->href = 'contao/main.php?do=themes&amp;table=tl_module&amp;act=edit&amp;id=' . $this->id;
67
-
68
-			return $objTemplate->parse();
69
-		}
70
-
71
-        // Set the item from the auto_item parameter
72
-        if (!isset($_GET['items']) && isset($_GET['auto_item']) && Config::get('useAutoItem'))
73
-        {
74
-            Input::setGet('items', Input::get('auto_item'));
75
-        }
76
-
77
-		return parent::generate();
78
-	}
79
-
80
-	/**
81
-	 * Generate the module
82
-	 */
83
-	protected function compile()
84
-	{
85
-        $this->Template->referer = 'javascript:history.go(-1)';
86
-        $this->Template->back = $GLOBALS['TL_LANG']['MSC']['goBack'];
87
-
88
-        // Get the member
89
-        $objMember = MemberModel::findByIdOrAlias(Input::get('items'));
90
-
91
-        // The member does not exist and is not deactivated
92
-        if ($objMember === null || $objMember->disable)
93
-        {
94
-            throw new PageNotFoundException('Page not found: ' . Environment::get('uri'));
95
-        }
96
-
97
-        // Check for group intersection
98
-        $arrGroups = StringUtil::deserialize($this->ext_groups);
99
-        $memberGroups = StringUtil::deserialize($objMember->groups);
100
-
101
-        if (empty($arrGroups) || !\is_array($arrGroups) || !\count(array_intersect($arrGroups, $memberGroups)))
102
-        {
103
-            throw new PageNotFoundException('Page not found: ' . Environment::get('uri'));
104
-        }
105
-
106
-        $arrMemberFields = StringUtil::deserialize($this->memberFields, true);
107
-
108
-        $objTemplate = new FrontendTemplate($this->memberReaderTpl ?: $this->strMemberTemplate);
109
-        $objTemplate->setData($objMember->row());
110
-
111
-        $this->Template->member = $this->parseMemberTemplate($objMember, $objTemplate, $arrMemberFields, $this->imgSize);
112
-	}
113
-}
114 0
deleted file mode 100644
... ...
@@ -1,8 +0,0 @@
1
-<figure class="image_container">
2
-
3
-  <?php if($this->addFallbackImage): ?>
4
-    <img src="<?= $this->singleSRC; ?>" width="200" height="200" itemprop="image">
5
-  <?php else: ?>
6
-    <?php $this->insert('picture_default', $this->picture); ?>
7
-  <?php endif; ?>
8
-</figure>
9 0
deleted file mode 100644
... ...
@@ -1,7 +0,0 @@
1
-<?php $this->extend('block_searchable'); ?>
2
-
3
-<?php $this->block('content'); ?>
4
-
5
-<?php $this->insert('memberExtension_image', $this->arrData); ?>
6
-
7
-<?php $this->endblock(); ?>
8 0
deleted file mode 100644
... ...
@@ -1,23 +0,0 @@
1
-<?php $this->extend('block_unsearchable'); ?>
2
-
3
-<?php $this->block('content'); ?>
4
-
5
-<!-- indexer::stop -->
6
-
7
-  <?php if ($this->message): ?>
8
-    <p class="tl_confirm"><?= $this->message ?></p>
9
-  <?php else: ?>
10
-    <form id="<?= $this->formId ?>" method="post">
11
-      <div class="formbody">
12
-        <input type="hidden" name="FORM_SUBMIT" value="<?= $this->formId ?>">
13
-        <input type="hidden" name="REQUEST_TOKEN" value="{{request_token}}">
14
-        <div class="widget widget-submit">
15
-          <button type="submit" class="submit"><?= $this->slabel ?></button>
16
-        </div>
17
-      </div>
18
-    </form>
19
-  <?php endif; ?>
20
-
21
-<!-- indexer::continue -->
22
-
23
-<?php $this->endblock(); ?>
24 0
deleted file mode 100644
... ...
@@ -1,16 +0,0 @@
1
-<div class="member_list_default">
2
-
3
-  <?php if($this->addImage): ?>
4
-    <?php $this->insert('memberExtension_image', $this->arrData); ?>
5
-  <?php endif; ?>
6
-
7
-  <ul>
8
-    <?php foreach ($this->fields as $k => $v): ?>
9
-      <li class="<?= $k ?>"><?= $v ?></li>
10
-    <?php endforeach; ?>
11
-  </ul>
12
-
13
-  <?php if($this->link): ?>
14
-    <a href="<?=$this->link?>"><?=$GLOBALS['TL_LANG']['MSC']['memberDetail']?></a>
15
-  <?php endif; ?>
16
-</div>
17 0
deleted file mode 100644
... ...
@@ -1,12 +0,0 @@
1
-<div class="member_reader_full">
2
-
3
-  <?php if($this->addImage): ?>
4
-    <?php $this->insert('memberExtension_image', $this->arrData); ?>
5
-  <?php endif; ?>
6
-
7
-  <ul>
8
-    <?php foreach ($this->fields as $k => $v): ?>
9
-      <li class="<?= $k ?>"><?= $v ?></li>
10
-    <?php endforeach; ?>
11
-  </ul>
12
-</div>
13 0
deleted file mode 100644
... ...
@@ -1,14 +0,0 @@
1
-<?php $this->extend('block_unsearchable'); ?>
2
-
3
-<?php $this->block('content'); ?>
4
-
5
-<?php if (empty($this->members)): ?>
6
-    <p class="empty message"><?=$this->empty?></p>
7
-<?php else: ?>
8
-    <?php foreach ($this->members as $member): ?>
9
-      <?=$member?>
10
-    <?php endforeach; ?>
11
-    <?= $this->pagination ?>
12
-<?php endif; ?>
13
-
14
-<?php $this->endblock(); ?>
15 0
deleted file mode 100644
... ...
@@ -1,11 +0,0 @@
1
-<?php $this->extend('block_unsearchable'); ?>
2
-
3
-<?php $this->block('content'); ?>
4
-
5
-<?=$this->member?>
6
-
7
-<!-- indexer::stop -->
8
-<p class="back"><a href="<?= $this->referer ?>" title="<?= $this->back ?>"><?= $this->back ?></a></p>
9
-<!-- indexer::continue -->
10
-
11
-<?php $this->endblock(); ?>
12 0
deleted file mode 100644
13 1
Binary files a/src/Resources/public/avatar.png and /dev/null differ
14 2
deleted file mode 100644
... ...
@@ -1,3 +0,0 @@
1
-.navigation.member_settings {
2
-  display: none !important;
3
-}