Browse code

[Update] Added image + image deletion when uploading an image

Sebastian Zoglowek authored on26/02/2022 03:08:49
Showing2 changed files
... ...
@@ -1,33 +1,57 @@
1 1
 <?php
2
+
3
+declare(strict_types=1);
4
+
2 5
 /*
3 6
  * This file is part of Oveleon ContaoMemberExtension Bundle.
4 7
  *
5
- * (c) https://www.oveleon.de/
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/>
6 14
  */
15
+
7 16
 namespace Oveleon\ContaoMemberExtensionBundle;
8 17
 
9 18
 use Contao\Config;
19
+use Contao\CoreBundle\Monolog\ContaoContext;
10 20
 use Contao\Dbafs;
11 21
 use Contao\File;
12 22
 use Contao\FilesModel;
13 23
 use Contao\Frontend;
14
-use Contao\FrontendUser;
15 24
 use Contao\MemberModel;
16 25
 use Contao\StringUtil;
26
+use Contao\System;
17 27
 use Contao\Validator;
28
+use Psr\Log\LogLevel;
18 29
 
19
-/**
20
- * Class Member
21
- *
22
- * @author Fabian Ekert <fabian@oveleon.de>
23
- * @author Daniele Sciannimanica <https://github.com/doishub>
24
- */
25 30
 class Member extends Frontend
26 31
 {
27 32
     /**
33
+     * MemberAvatar file name
34
+     *
35
+     * @var string
36
+     */
37
+    protected $avatarName = 'memberAvatar';
38
+
39
+    /**
40
+     * Create avatar for a member | Registration
41
+     *
42
+     * @param int          $userId
43
+     * @param array        $arrData
44
+     */
45
+    public function createAvatar($userId, $arrData)
46
+    {
47
+        $objMember = MemberModel::findById($userId);
48
+        $this->updateAvatar($objMember, $arrData);
49
+    }
50
+
51
+    /**
28 52
      * Update avatar of member
29 53
      *
30
-     * @param FrontendUser $objUser
54
+     * @param MemberModel  $objMember
31 55
      * @param array        $arrData
32 56
      */
33 57
     public function updateAvatar($objUser, $arrData)
... ...
@@ -41,6 +65,7 @@ class Member extends Frontend
41 65
 
42 66
         $file = $_SESSION['FILES']['avatar'];
43 67
         $maxlength_kb = $this->getMaximumUploadSize();
68
+        $maxlength_kb_readable = $this->getReadableSize($maxlength_kb);
44 69
 
45 70
         // Sanitize the filename
46 71
         try
... ...
@@ -50,6 +75,7 @@ class Member extends Frontend
50 75
         catch (\InvalidArgumentException $e)
51 76
         {
52 77
             // ToDo: Fehler: Dateiname beinhaltet unzulässige Zeichen
78
+            $this->addError($GLOBALS['TL_LANG']['ERR']['filename']);
53 79
 
54 80
             return;
55 81
         }
... ...
@@ -58,17 +84,37 @@ class Member extends Frontend
58 84
         if (!Validator::isValidFileName($file['name']))
59 85
         {
60 86
             // ToDo: Fehler: Dateiname beinhaltet unzulässige Zeichen
61
-
87
+            $this->addError($GLOBALS['TL_LANG']['ERR']['filename']);
62 88
             return;
63 89
         }
64 90
 
65 91
         // File was not uploaded
66
-        // ToDo
92
+        // ToDo: File was not uploaded
93
+        if (!is_uploaded_file($file['tmp_name']))
94
+        {
95
+            if ($file['error'] == 1 || $file['error'] == 2)
96
+            {
97
+                $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['filesize'], $maxlength_kb_readable));
98
+            }
99
+            elseif ($file['error'] == 3)
100
+            {
101
+                $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['filepartial'], $file['name']));
102
+            }
103
+            elseif ($file['error'] > 0)
104
+            {
105
+                $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['fileerror'], $file['error'], $file['name']));
106
+            }
107
+
108
+            unset($_FILES[$this->strName]);
109
+
110
+            return;
111
+        }
67 112
 
68 113
         // File is too big
69 114
         if ($file['size'] > $maxlength_kb)
70 115
         {
71 116
             // ToDo: Fehler: Datei zu groß
117
+            $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['filesize'], $maxlength_kb_readable));
72 118
             unset($_SESSION['FILES']['avatar']);
73 119
 
74 120
             return;
... ...
@@ -81,6 +127,7 @@ class Member extends Frontend
81 127
         if (!\in_array($objFile->extension, $uploadTypes))
82 128
         {
83 129
             // ToDo: Fehler: Dateityp nicht erlaubt
130
+            $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['filetype'], $objFile->extension));
84 131
             unset($_SESSION['FILES']['avatar']);
85 132
 
86 133
             return;
... ...
@@ -91,10 +138,9 @@ class Member extends Frontend
91 138
             $intImageWidth = Config::get('imageWidth');
92 139
 
93 140
             // Image exceeds maximum image width
94
-            if ($intImageWidth > 0 && $arrImageSize[0] > $intImageWidth)
95
-            {
96
-                // ToDo: Fehler: Bild ist zu groß in der breite
97
-                unset($_SESSION['FILES']['avatar']);
141
+            if ($intImageWidth > 0 && $arrImageSize[0] > $intImageWidth) {
142
+                $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['filewidth'], $file['name'], $intImageWidth));
143
+                unset($_FILES[$this->strName]);
98 144
 
99 145
                 return;
100 146
             }
... ...
@@ -102,81 +148,91 @@ class Member extends Frontend
102 148
             $intImageHeight = Config::get('imageHeight');
103 149
 
104 150
             // Image exceeds maximum image height
105
-            if ($intImageHeight > 0 && $arrImageSize[1] > $intImageHeight)
106
-            {
107
-                // ToDo: Fehler: Bild ist zu groß in der höhe
108
-                unset($_SESSION['FILES']['avatar']);
151
+            if ($intImageHeight > 0 && $arrImageSize[1] > $intImageHeight) {
152
+                $this->addError(sprintf($GLOBALS['TL_LANG']['ERR']['fileheight'], $file['name'], $intImageHeight));
153
+                unset($_FILES[$this->strName]);
109 154
 
110 155
                 return;
111 156
             }
157
+        }
112 158
 
113
-            $_SESSION['FILES']['avatar'] = $_SESSION['FILES']['avatar'];
159
+        // Upload valid file type with no width and height -> svg
114 160
 
115
-            // Overwrite the upload folder with user's home directory
116
-            if (!$objMember->assignDir || !$objMember->homeDir)
117
-            {
118
-                return;
119
-            }
161
+        // Don't upload if no homedir is assigned
162
+        // ToDo: Add error
163
+        if (!$objMember->assignDir || !$objMember->homeDir)
164
+        {
165
+            return;
166
+        }
120 167
 
121
-            $intUploadFolder = $objMember->homeDir;
168
+        $intUploadFolder = $objMember->homeDir;
122 169
 
123
-            $objUploadFolder = FilesModel::findByUuid($intUploadFolder);
170
+        $objUploadFolder = FilesModel::findByUuid($intUploadFolder);
124 171
 
125
-            // The upload folder could not be found
126
-            if ($objUploadFolder === null)
127
-            {
128
-                throw new \Exception("Invalid upload folder ID $intUploadFolder");
129
-            }
172
+        // The upload folder could not be found
173
+        if ($objUploadFolder === null)
174
+        {
175
+            throw new \Exception("Invalid upload folder ID $intUploadFolder");
176
+        }
130 177
 
131
-            $strUploadFolder = $objUploadFolder->path;
178
+        $strUploadFolder = $objUploadFolder->path;
132 179
 
133
-            // Store the file if the upload folder exists
134
-            if ($strUploadFolder != '' && is_dir(TL_ROOT . '/' . $strUploadFolder))
135
-            {
136
-                $this->import('Files');
180
+        // Store the file if the upload folder exists
181
+        $projectDir = System::getContainer()->getParameter('kernel.project_dir');
137 182
 
138
-                // Move the file to its destination
139
-                $this->Files->move_uploaded_file($file['tmp_name'], $strUploadFolder . '/' . $file['name']);
140
-                $this->Files->chmod($strUploadFolder . '/' . $file['name'], Config::get('defaultFileChmod'));
183
+        if (!!$strUploadFolder & is_dir($projectDir . '/' . $strUploadFolder))
184
+        {
185
+            // Delete existing avatar if it exists
186
+            $this->deleteAvatar($objMember);
141 187
 
142
-                $strUuid = null;
143
-                $strFile = $strUploadFolder . '/' . $file['name'];
188
+            $this->import('Files');
144 189
 
145
-                // Generate the DB entries
146
-                if (Dbafs::shouldBeSynchronized($strFile))
147
-                {
148
-                    $objModel = FilesModel::findByPath($strFile);
190
+            // Rename file
191
+            $file['name'] =  $this->avatarName . '.' . $objFile->extension;
149 192
 
150
-                    if ($objModel === null)
151
-                    {
152
-                        $objModel = Dbafs::addResource($strFile);
153
-                    }
193
+            // Move the file to its destination
194
+            $this->Files->move_uploaded_file($file['tmp_name'], $strUploadFolder . '/' . $file['name']);
195
+            $this->Files->chmod($strUploadFolder . '/' . $file['name'], 0666 & ~umask());
154 196
 
155
-                    $strUuid = StringUtil::binToUuid($objModel->uuid);
197
+            $strUuid = null;
198
+            $strFile = $strUploadFolder . '/' . $file['name'];
156 199
 
157
-                    // Update the hash of the target folder
158
-                    Dbafs::updateFolderHashes($strUploadFolder);
159 200
 
160
-                    // Update member avatar
161
-                    $objMember->avatar = $objModel->uuid;
162
-                    $objMember->save();
201
+            // Generate the DB entries
202
+            if (Dbafs::shouldBeSynchronized($strFile))
203
+            {
204
+                $objModel = FilesModel::findByPath($strFile);
205
+
206
+                if ($objModel === null)
207
+                {
208
+                    $objModel = Dbafs::addResource($strFile);
163 209
                 }
164 210
 
165
-                // Add the session entry (see #6986)
166
-                $_SESSION['FILES']['avatar'] = array
167
-                (
168
-                    'name'     => $file['name'],
169
-                    'type'     => $file['type'],
170
-                    'tmp_name' => TL_ROOT . '/' . $strFile,
171
-                    'error'    => $file['error'],
172
-                    'size'     => $file['size'],
173
-                    'uploaded' => true,
174
-                    'uuid'     => $strUuid
175
-                );
176
-
177
-                // Add a log entry
178
-                $this->log('File "' . $strUploadFolder . '/' . $file['name'] . '" has been uploaded', __METHOD__, TL_FILES);
211
+                $strUuid = StringUtil::binToUuid($objModel->uuid);
212
+
213
+                // Update the hash of the target folder
214
+                Dbafs::updateFolderHashes($strUploadFolder);
215
+
216
+                // Update member avatar
217
+                $objMember->avatar = $objModel->uuid;
218
+                $objMember->save();
179 219
             }
220
+
221
+            // Add the session entry
222
+            $_SESSION['FILES']['avatar'] = array
223
+            (
224
+                'name'     => $file['name'],
225
+                'type'     => $file['type'],
226
+                'tmp_name' => $projectDir . '/' . $strFile,
227
+                'error'    => $file['error'],
228
+                'size'     => $file['size'],
229
+                'uploaded' => true,
230
+                'uuid'     => $strUuid
231
+            );
232
+
233
+            // Add a log entry
234
+            $logger = System::getContainer()->get('monolog.logger.contao');
235
+            $logger->log(LogLevel::INFO, 'File "' . $strUploadFolder . '/' . $file['name'] . '" has been uploaded', array('contao' => new ContaoContext(__METHOD__, TL_FILES)));
180 236
         }
181 237
 
182 238
         unset($_SESSION['FILES']['avatar']);
... ...
@@ -208,4 +264,30 @@ class Member extends Frontend
208 264
 
209 265
         return min($upload_max_filesize, Config::get('maxFileSize'));
210 266
     }
267
+
268
+    /**
269
+     * Add an error message
270
+     *
271
+     * @param string $strError The error message
272
+     */
273
+    public function addError($strError)
274
+    {
275
+        $this->class = 'error';
276
+        $this->arrErrors[] = $strError;
277
+    }
278
+
279
+    public function deleteAvatar($objMember)
280
+    {
281
+        if(!!$objMember->avatar)
282
+        {
283
+            $objFile = FilesModel::findByUuid($objMember->avatar) ?? '';
284
+
285
+            // Only delete existing file
286
+            if (!!$objFile && file_exists($objFile->path))
287
+            {
288
+                $file = new File($objFile->path);
289
+                $file->delete();
290
+            }
291
+        }
292
+    }
211 293
 }
... ...
@@ -2,8 +2,14 @@
2 2
 
3 3
 <?php $this->block('content'); ?>
4 4
 
5
+<?php if($this->noAvatar):?>
6
+  <figure class="image_container">
7
+    <img src="<?= $this->singleSRC; ?>" itemprop="image">
8
+  </figure>
9
+<?php else: ?>
5 10
   <figure class="image_container">
6 11
       <?php $this->insert('picture_default', $this->picture); ?>
7 12
   </figure>
13
+<?php endif; ?>
8 14
 
9 15
 <?php $this->endblock(); ?>