This is an automated email from the ASF dual-hosted git repository.

matthiasblaesing pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans-tools.git


The following commit(s) were added to refs/heads/master by this push:
     new 4a88fd3  Improve image upload handling for PP3
     new 1158393  Merge pull request #55 from 
matthiasblaesing/improve_image_upload
4a88fd3 is described below

commit 4a88fd3c11717a99ae1b5cd924742b2f538c952a
Author: Matthias Bläsing <mblaes...@doppel-helix.eu>
AuthorDate: Thu Nov 10 20:47:23 2022 +0100

    Improve image upload handling for PP3
    
    - Allow the user/admin to remove an existing image
    - Prepare the fileselector with a list of relevant files
    - Remove old images
    - Unify naming of uploaded images
---
 .../Application/config/module.config.php.dist      |  6 ++
 .../src/Application/Controller/AdminController.php | 58 +++++++++++++----
 .../Application/Controller/PluginController.php    | 74 ++++++++++++++++++----
 .../Application/view/application/admin/edit.phtml  |  2 +-
 .../view/application/plugin/_plugin-form.phtml     | 11 +++-
 .../view/application/plugin/confirm.phtml          |  2 +-
 .../Application/view/application/plugin/edit.phtml |  2 +-
 7 files changed, 126 insertions(+), 29 deletions(-)

diff --git a/pp3/module/Application/config/module.config.php.dist 
b/pp3/module/Application/config/module.config.php.dist
index 32f514b..36bae75 100755
--- a/pp3/module/Application/config/module.config.php.dist
+++ b/pp3/module/Application/config/module.config.php.dist
@@ -36,6 +36,12 @@ return array(
         'dtdPath' => 
'http://localhost/checkout/pp3/public/dtd/autoupdate-catalog-2_8.dtd',
         'downloadBaseUrl' => 'http://localhost/pp3/catalogue/download'
     ),
+    'imageTypes' => array (
+        'svg',
+        'png',
+        'jpg',
+        'jpeg'
+    ),
     'loginConfig' => array (
         array(
             'id' => 'github',
diff --git 
a/pp3/module/Application/src/Application/Controller/AdminController.php 
b/pp3/module/Application/src/Application/Controller/AdminController.php
index 546a77d..366ce20 100644
--- a/pp3/module/Application/src/Application/Controller/AdminController.php
+++ b/pp3/module/Application/src/Application/Controller/AdminController.php
@@ -588,23 +588,37 @@ NetBeans development team
                         $this->params()->fromPost('license'),
                         $this->params()->fromPost('description'),
                         $this->params()->fromPost('short_description'),
-                        $this->params()->fromPost('category')
+                        $this->params()->fromPost('category'),
+                        $this->params()->fromPost('homepage'),
+                        array_key_exists('image-file', $_FILES) ? 
$_FILES['image-file'] : false
                 );
                 if ($validatedData) {
                     $plugin->setName($validatedData['name']);
                     $plugin->setLicense($validatedData['license']);
                     $plugin->setDescription($validatedData['description']);
                     
$plugin->setShortDescription($validatedData['short_description']);
+                    $plugin->setHomepage($validatedData['homepage']);
                     $plugin->setLastUpdatedAt(new \DateTime('now'));
 
+                    $imageDir = $this->_config['pp3']['catalogSavepath'] . 
'/plugins/' . $plugin->getId();
+
+                    $oldImage = $plugin->getImage();
+
                     // save image
-                    $im = 
$this->handleImgUpload($this->_config['pp3']['catalogSavepath'] . '/plugins/' . 
$plugin->getId());
+                    $im = $this->handleImgUpload($validatedData, $imageDir);
                     if ($im) {
                         $plugin->setImage($im);
                     }
 
+                    if($this->params()->fromPost('image-file-delete') == 
'true') {
+                        $plugin->setImage(null);
+                    }
 
-                    // categ
+                    if($oldImage && $oldImage != $plugin->getImage()) {
+                        unlink($imageDir . '/' . $oldImage);
+                    }
+
+                    // category
                     $plugin->removeCategories();
                     $this->_pluginRepository->persist($plugin);
                     $cat = 
$this->_categoryRepository->find($validatedData['category']);
@@ -637,14 +651,29 @@ NetBeans development team
         return new ViewModel(array(
             'plugin' => $plugin,
             'categories' => 
$this->_categoryRepository->getAllCategoriesSortByName(),
-            'activeTab' => $activeTab
+            'activeTab' => $activeTab,
+            'imageTypes' => $this->_config['imageTypes']
         ));
     }
 
-    private function _validateAndCleanPluginData($name, $license, 
$description, $shortDescription, $category) {
-        if (empty($name) || empty($license) || empty($category) || 
empty($shortDescription)) {
+    private function _validateAndCleanPluginData($name, $license, 
$description, $shortDescription, $category, $homepage, $imageFileData) {
+        $fileType = false;
+        if($imageFileData && $imageFileData['size'] > 0) {
+            $baseName = basename(strtolower($imageFileData['name']));
+            $pathInfo = pathinfo($baseName);
+            $imageFileNameType = $pathInfo["extension"];
+            foreach($this->_config['imageTypes'] as $imageType) {
+                if($imageFileNameType == $imageType) {
+                    $fileType = $imageType;
+                    break;
+                }
+            }
+        }
+
+        if (empty($name) || empty($license) || empty($category) || 
empty($shortDescription) || ($imageFileData && $imageFileData['size'] > 0 && 
(!$fileType))) {
             return false;
         }
+
         $config = HTMLPurifier_Config::createDefault();
         $purifier = new HTMLPurifier($config);
         return  array(
@@ -652,7 +681,9 @@ NetBeans development team
             'license' => $purifier->purify($license),
             'description' => $purifier->purify($description),
             'short_description' => $purifier->purify($shortDescription),
-            'category' => $category
+            'category' => $category,
+            'homepage' => $purifier->purify($homepage),
+            'image' => $fileType ? ['tmp_name' => $imageFileData['tmp_name'], 
'name' => 'image.' . $fileType] : false
         );
     }
 
@@ -673,16 +704,19 @@ NetBeans development team
         return $response;
     }
 
-    private function handleImgUpload($imgFolder) {
-        $tmp_name = $_FILES["image-file"]["tmp_name"];
+    private function handleImgUpload($validatedData, $imgFolder) {
+        if(! $validatedData['image']) {
+            return false;
+        }
+        $tmp_name = $validatedData['image']['tmp_name'];
         // basename() may prevent filesystem traversal attacks;
         // further validation/sanitation of the filename may be appropriate
-        $name = basename($_FILES["image-file"]["name"]);
+        $name = $validatedData['image']['name'];
         if(!file_exists($imgFolder)) {
             mkdir($imgFolder, 0777, true);
         }
         if(move_uploaded_file($tmp_name, $imgFolder.'/'.$name)) {
-            return $name; 
-        }        
+            return $name;
+        }
     }
 }
diff --git 
a/pp3/module/Application/src/Application/Controller/PluginController.php 
b/pp3/module/Application/src/Application/Controller/PluginController.php
index bdb6cef..01ff0b7 100644
--- a/pp3/module/Application/src/Application/Controller/PluginController.php
+++ b/pp3/module/Application/src/Application/Controller/PluginController.php
@@ -84,17 +84,20 @@ class PluginController extends AuthenticatedController {
         ));        
     }
 
-    private function handleImgUpload($imgFolder) {
-        $tmp_name = $_FILES["image-file"]["tmp_name"];
+    private function handleImgUpload($validatedData, $imgFolder) {
+        if(! $validatedData['image']) {
+            return false;
+        }
+        $tmp_name = $validatedData['image']['tmp_name'];
         // basename() may prevent filesystem traversal attacks;
         // further validation/sanitation of the filename may be appropriate
-        $name = basename($_FILES["image-file"]["name"]);
+        $name = $validatedData['image']['name'];
         if(!file_exists($imgFolder)) {
             mkdir($imgFolder, 0777, true);
         }
         if(move_uploaded_file($tmp_name, $imgFolder.'/'.$name)) {
-            return $name; 
-        }        
+            return $name;
+        }
     }
 
     public function indexAction() {
@@ -159,7 +162,8 @@ class PluginController extends AuthenticatedController {
                 $this->params()->fromPost('description'),
                 $this->params()->fromPost('short_description'),
                 $this->params()->fromPost('category'),
-                $this->params()->fromPost('homepage')
+                $this->params()->fromPost('homepage'),
+                array_key_exists('image-file', $_FILES) ? 
$_FILES['image-file'] : false
             );
             if ($validatedData) {
                 $user = 
$this->_userRepository->find($this->getAuthenticatedUserId());
@@ -185,12 +189,24 @@ class PluginController extends AuthenticatedController {
                         $plugin->addCategory($cat2);
                     }
                 }
+
+                $imageDir = $this->_config['pp3']['catalogSavepath'] . 
'/plugins/' . $plugin->getId();
+
+                $oldImage = $plugin->getImage();
+
                 // save image
-                $im = 
$this->handleImgUpload($this->_config['pp3']['catalogSavepath'].'/plugins/'.$plugin->getId());
-                if ($im) {                    
+                $im = $this->handleImgUpload($validatedData, $imageDir);
+                if ($im) {
                     $plugin->setImage($im);
                 }
 
+                if($this->params()->fromPost('image-file-delete') == 'true') {
+                    $plugin->setImage(null);
+                }
+
+                if($oldImage && $oldImage != $plugin->getImage()) {
+                    unlink($imageDir . '/' . $oldImage);
+                }
 
                 $this->_pluginRepository->persist($plugin);
                 
$this->flashMessenger()->setNamespace('success')->addMessage('Plugin 
registered.');
@@ -209,6 +225,8 @@ class PluginController extends AuthenticatedController {
         return new ViewModel([
             'plugin' => $plugin,
             'categories' => 
$this->_categoryRepository->getAllCategoriesSortByName(),
+            'imageTypes' => $this->_config['imageTypes'],
+            'editMode' => false
         ]);
     }
 
@@ -270,7 +288,8 @@ class PluginController extends AuthenticatedController {
                         $this->params()->fromPost('description'),
                         $this->params()->fromPost('short_description'),
                         $this->params()->fromPost('category'),
-                        $this->params()->fromPost('homepage')
+                        $this->params()->fromPost('homepage'),
+                        array_key_exists('image-file', $_FILES) ? 
$_FILES['image-file'] : false
                 );
                 if ($validatedData) {
                     $plugin->setName($validatedData['name']);
@@ -280,12 +299,24 @@ class PluginController extends AuthenticatedController {
                     $plugin->setHomepage($validatedData['homepage']);
                     $plugin->setLastUpdatedAt(new \DateTime('now'));
 
+                    $imageDir = $this->_config['pp3']['catalogSavepath'] . 
'/plugins/' . $plugin->getId();
+
+                    $oldImage = $plugin->getImage();
+
                     // save image
-                    $im = 
$this->handleImgUpload($this->_config['pp3']['catalogSavepath'] . '/plugins/' . 
$plugin->getId());
+                    $im = $this->handleImgUpload($validatedData, $imageDir);
                     if ($im) {
                         $plugin->setImage($im);
                     }
 
+                    if($this->params()->fromPost('image-file-delete') == 
'true') {
+                        $plugin->setImage(null);
+                    }
+
+                    if($oldImage && $oldImage != $plugin->getImage()) {
+                        unlink($imageDir . '/' . $oldImage);
+                    }
+
                     // categ
                     $plugin->removeCategories();
                     $this->_pluginRepository->persist($plugin);
@@ -320,7 +351,9 @@ class PluginController extends AuthenticatedController {
         return new ViewModel(array(
             'plugin' => $plugin,
             'categories' => 
$this->_categoryRepository->getAllCategoriesSortByName(),
-            'activeTab' => $activeTab
+            'activeTab' => $activeTab,
+            'imageTypes' => $this->_config['imageTypes'],
+            'editMode' => true
         ));
     }
 
@@ -348,10 +381,24 @@ class PluginController extends AuthenticatedController {
         }
     }
 
-    private function _validateAndCleanPluginData($name, $license, 
$description, $shortDescription, $category, $homepage) {
-        if (empty($name) || empty($license) || empty($category) || 
empty($shortDescription)) {
+    private function _validateAndCleanPluginData($name, $license, 
$description, $shortDescription, $category, $homepage, $imageFileData) {
+        $fileType = false;
+        if($imageFileData && $imageFileData['size'] > 0) {
+            $baseName = basename(strtolower($imageFileData['name']));
+            $pathInfo = pathinfo($baseName);
+            $imageFileNameType = $pathInfo["extension"];
+            foreach($this->_config['imageTypes'] as $imageType) {
+                if($imageFileNameType == $imageType) {
+                    $fileType = $imageType;
+                    break;
+                }
+            }
+        }
+
+        if (empty($name) || empty($license) || empty($category) || 
empty($shortDescription) || ($imageFileData && $imageFileData['size'] > 0 && 
(!$fileType))) {
             return false;
         }
+
         $config = HTMLPurifier_Config::createDefault();
         $purifier = new HTMLPurifier($config);
         return  array(
@@ -361,6 +408,7 @@ class PluginController extends AuthenticatedController {
             'short_description' => $purifier->purify($shortDescription),
             'category' => $category,
             'homepage' => $purifier->purify($homepage),
+            'image' => $fileType ? ['tmp_name' => $imageFileData['tmp_name'], 
'name' => 'image.' . $fileType] : false
         );
     }
 
diff --git a/pp3/module/Application/view/application/admin/edit.phtml 
b/pp3/module/Application/view/application/admin/edit.phtml
index 2a51f1a..c852635 100644
--- a/pp3/module/Application/view/application/admin/edit.phtml
+++ b/pp3/module/Application/view/application/admin/edit.phtml
@@ -30,7 +30,7 @@
             <div class="row">
                 <div class="col col-sm-6">
                     <form method="post" action="" class="needs-validation" 
enctype="multipart/form-data">
-                        <?= 
$this->partial('application/plugin/_plugin-form.phtml', array('plugin' => 
$this->plugin, 'categories' => $this->categories)); ?>
+                        <?= 
$this->partial('application/plugin/_plugin-form.phtml', array('plugin' => 
$this->plugin, 'categories' => $this->categories, 
'imageTypes'=>$this->imageTypes, 'editMode' => true)); ?>
                         <a class="btn btn-secondary" href="<?= 
$this->url('admin') ?>" role="button">Return</a>
                         <button type="submit" class="btn btn-primary">Save 
Plugin</button>
                     </form>
diff --git a/pp3/module/Application/view/application/plugin/_plugin-form.phtml 
b/pp3/module/Application/view/application/plugin/_plugin-form.phtml
index f8b438a..11c1e3f 100644
--- a/pp3/module/Application/view/application/plugin/_plugin-form.phtml
+++ b/pp3/module/Application/view/application/plugin/_plugin-form.phtml
@@ -65,5 +65,14 @@
     </div>
     <div class="form-group">
         <label for="image-file">Image</label>
-        <input type="file" name="image-file" id="image-file">
+        <?php
+            $imageTypes = implode(array_map(function($a) {return '.' . $a;}, 
$this->imageTypes), ',');
+        ?>
+        <input type="file" name="image-file" id="image-file" accept="<?php 
echo $imageTypes ?>">
+        <?php if ($this->editMode) { ?>
+        <p>
+            <input type="checkbox" name="image-file-delete" 
id="image-file-delete" value="true">
+            <label for="image-file-delete" style="font-weight: normal">Remove 
Image</label>
+        </p>
+        <?php } ?>
     </div>
diff --git a/pp3/module/Application/view/application/plugin/confirm.phtml 
b/pp3/module/Application/view/application/plugin/confirm.phtml
index fd0ca5e..c8acf1f 100644
--- a/pp3/module/Application/view/application/plugin/confirm.phtml
+++ b/pp3/module/Application/view/application/plugin/confirm.phtml
@@ -23,7 +23,7 @@
         <div class="col col-sm-6">
             <?= $this->partial('layout/flash.phtml'); ?>
             <form method="post" action="" class="needs-validation" 
enctype="multipart/form-data">
-            <?= $this->partial('application/plugin/_plugin-form.phtml', 
array('plugin' => $this->plugin, 'categories'=>$this->categories)); ?>
+            <?= $this->partial('application/plugin/_plugin-form.phtml', 
array('plugin' => $this->plugin, 'categories'=>$this->categories, 
'imageTypes'=>$this->imageTypes, 'editMode' => false)); ?>
             <a class="btn btn-secondary" href="../plugin/" 
role="button">Cancel</a>
             <button type="submit" class="btn btn-primary">Save Plugin</button>
             </form>
diff --git a/pp3/module/Application/view/application/plugin/edit.phtml 
b/pp3/module/Application/view/application/plugin/edit.phtml
index abeeedd..2eec7c6 100644
--- a/pp3/module/Application/view/application/plugin/edit.phtml
+++ b/pp3/module/Application/view/application/plugin/edit.phtml
@@ -30,7 +30,7 @@
             <div class="row">
                 <div class="col col-sm-6">
                     <form method="post" action="" class="needs-validation" 
enctype="multipart/form-data">
-                        <?= 
$this->partial('application/plugin/_plugin-form.phtml', array('plugin' => 
$this->plugin, 'categories' => $this->categories)); ?>
+                        <?= 
$this->partial('application/plugin/_plugin-form.phtml', array('plugin' => 
$this->plugin, 'categories' => $this->categories, 
'imageTypes'=>$this->imageTypes, 'editMode' => true)); ?>
                         <a class="btn btn-secondary" href="../plugin/list" 
role="button">Return</a>
                         <button type="submit" class="btn btn-primary">Save 
Plugin</button>
                     </form>


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org
For additional commands, e-mail: commits-h...@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists

Reply via email to