Index: /changelog
===================================================================
--- /changelog	(revision 7840)
+++ /changelog	(revision 7841)
@@ -425,4 +425,5 @@
 - Feature: Template je Variante fÃŒr Downloadplus anpassbar
 - Feature: parallele Erstellung eines Dokumentes ohne Vorlage (Briefbogenfunktion)
+- Feature: Globale Bilder in globalen Variationen
 - Bugfix: Anzeige von Name/Titel in den Passwort Vergessen Mails
 - Bugfix: KundenzusammenfÃŒgen funktioniert wieder
Index: /lib/wpsg_imagehandler.class.php
===================================================================
--- /lib/wpsg_imagehandler.class.php	(revision 7840)
+++ /lib/wpsg_imagehandler.class.php	(revision 7841)
@@ -34,10 +34,9 @@
 			
 			$arAttachmentIDs = $this->getAttachmentIDs($product_key, $vari_id, $all);
-				
+
 			if (wpsg_isSizedArray($arAttachmentIDs)) {
 
-                // return array_values($arAttachmentIDs)[0];
-
                 $arValues = array_values($arAttachmentIDs);
+
                 return $arValues[0];
 
@@ -119,6 +118,5 @@
 		 * @throws \wpsg\Exception
 		 */
-		public function getAttachmentIDs($product_key, $vari_id = false, $all = false)
-		{
+		public function getAttachmentIDs($product_key, $vari_id = false, $all = false) {
 			
 			$product_id = $this->shop->getProduktID($product_key);
@@ -142,6 +140,5 @@
 			$postids = $this->db->fetchOne("SELECT `postids` FROM `".WPSG_TBL_PRODUCTS."` WHERE `id` = '".wpsg_q($product_id)."' ");
 						
-			if (strpos($postids, ',') !== false)
-			{
+			if (strpos($postids, ',') !== false) {
 				
 				$arPostIDsOrder = explode(',', $postids);
@@ -156,17 +153,14 @@
 				
 			}  
-			 
+
 			// Jetzt sind in $arAttachmentIDs alle Bilder dieses Produktes
-			if ($this->shop->hasMod('wpsg_mod_productvariants') && $this->shop->callMod('wpsg_mod_productvariants', 'isVariantsProductKey', array($product_key)))
-			{
-			
+			if ($this->shop->hasMod('wpsg_mod_productvariants') && $this->shop->callMod('wpsg_mod_productvariants', 'isVariantsProductKey', array($product_key))) {
+
 				// Bei einem Variantenprodukt muss ich jetzt noch filtern ...
 				$arVariInfo = $this->shop->callMod('wpsg_mod_productvariants', 'getVariantenInfoArray', array($product_key));
-				
+
 				return array_values($arVariInfo['images']);
                                 
-			}
-			else if ($this->shop->hasMod('wpsg_mod_productvariants') && wpsg_isSizedInt($vari_id))
-			{
+			} else if ($this->shop->hasMod('wpsg_mod_productvariants') && wpsg_isSizedInt($vari_id)) {
 
 				// Daten der Produktvariation laden
@@ -185,5 +179,11 @@
 				
 				$arAttachmentIDsProductVari = explode(',', $images);
-				
+
+				// Globale Bilder hinzufÃŒgen
+				$vari_images = $this->shop->get_option('wpsg_mod_productvariants_global_images');
+				if (!is_array($vari_images)) $vari_images = [];
+
+				if (isset($vari_images[intval($vari_id)])) $arAttachmentIDs = array_merge($arAttachmentIDs, $vari_images[intval($vari_id)]);
+
 				// Die Elemente, in der Reihenfolge aus $arAttachmentIDs. die auch in $arAttachmentIDsProductVari enthalten sind
 				$arAttachmentIDsIntersect = array_intersect($arAttachmentIDsProductVari, $arAttachmentIDs);
@@ -193,12 +193,9 @@
 				$arAttachmentIDs = $arAttachmentIDsIntersect + $arDiff;
 				 	
-				if ($all === true)
-				{
+				if ($all === true) {
 					
 					return array_values($arAttachmentIDs);
 					
-				}
-				else
-				{
+				} else {
 					
 					// Jetzt noch aus der Reihenfolge die gesetzten filtern					
@@ -217,6 +214,25 @@
 				}
 				
+			} else if ($this->shop->hasMod('wpsg_mod_productvariants') && $this->shop->callMod('wpsg_mod_productvariants', 'isVariantsProduct', array($product_key))) {
+
+				// Globale Bilder hinzufÃŒgen
+				$vari_data = $this->shop->callMod('wpsg_mod_productvariants', 'getVariants', [$this->shop->getProduktID($product_key), true, true, true]);
+
+				foreach ($vari_data as $variant_id => $variant_data) {
+
+					foreach ($variant_data['arVariation'] as $variation_id => $variation_data) {
+
+						$arAttachmentIDs = wpsg_trim(array_unique(array_merge(
+							$arAttachmentIDs, explode(',', $variation_data['images_set'])
+						)));
+
+					}
+
+				}
+
 			}
-			
+
+			$arAttachmentIDs = array_filter($arAttachmentIDs, function($attachment_id) { return get_post_status($attachment_id) === 'publish'; });
+
 			return array_values($arAttachmentIDs); 
 			
Index: /mods/wpsg_mod_downloadplus.class.php
===================================================================
--- /mods/wpsg_mod_downloadplus.class.php	(revision 7840)
+++ /mods/wpsg_mod_downloadplus.class.php	(revision 7841)
@@ -738,10 +738,9 @@
 						FROM 
 							`".WPSG_TBL_PDFINDIV."` 
-						WHERE 
-							`file` = '".wpsg_q($v[1])."' AND
+						WHERE
 							`p_key` = '".wpsg_q($v[0])."' AND
 							`o_id` = '".wpsg_q($order_id)."' AND
 							`product_index` = '".wpsg_q($v[2])."'
-					");
+					"); // `file` = '".wpsg_q($v[1])."' AND
 
 	                if (!wpsg_isSizedInt($db_indiv['id'])) {
Index: /mods/wpsg_mod_orderupload.class.php
===================================================================
--- /mods/wpsg_mod_orderupload.class.php	(revision 7840)
+++ /mods/wpsg_mod_orderupload.class.php	(revision 7841)
@@ -266,12 +266,9 @@
 		} // public function order_ajax() 
 		
-		public function basket_save_done(&$o_id, &$k_id, &$oBasket)
-		{
-			
-			if (wpsg_isSizedArray($_SESSION['wpsg']['wpsg_mod_orderupload']))
-			{
-				
-				foreach ($_SESSION['wpsg']['wpsg_mod_orderupload'] as $k => $ou)
-				{
+		public function basket_save_done(&$o_id, &$k_id, &$oBasket) {
+			
+			if (wpsg_isSizedArray($_SESSION['wpsg']['wpsg_mod_orderupload'])) {
+				
+				foreach ($_SESSION['wpsg']['wpsg_mod_orderupload'] as $k => $ou) {
 					 
 					$path_target = $this->getSavePath($o_id);
@@ -293,10 +290,11 @@
 		} // public function basket_save_done($o_id, $k_id)
 		
-		public function order_view_sidebar(&$order_id) 
-		{ 
-	 
-			$arFiles = scandir($this->getSavePath($order_id));
-			 
-			foreach ($arFiles as $k => $v) { if (in_array($v, array('.', '..', '.htaccess', '.htpasswd'))) { unset($arFiles[$k]); } }
+		public function order_view_sidebar(&$order_id) {
+
+			$path = $this->getSavePath($order_id);
+
+			$arFiles = scandir($path);
+
+			foreach ($arFiles as $k => $v) { if (in_array($v, array('.', '..', '.htaccess', '.htpasswd')) || is_dir($path.$v)) {  unset($arFiles[$k]); } }
 			
 			if (sizeof($arFiles) <= 0) return;
@@ -358,6 +356,6 @@
                         $arFilesUploaded = $this->getProductUploads($_REQUEST['order_id'], $_REQUEST['product_index']);
                         if (sizeof($arFilesUploaded) >= $oProduct->wpsg_mod_orderupload_set) { $this->shop->addFrontendError(wpsg_translate(__('Sie haben die maximale Anzahl an Dateien (#1#) fÃŒr dieses Produkt erreicht.', 'wpsg'), $oProduct->wpsg_mod_orderupload_set)); break; }
-                        
-                        move_uploaded_file($f, $path.$_FILES['file']['name'][$k]); 
+
+                        move_uploaded_file($f, $path.$_FILES['file']['name'][$k]);
                         
                     }
@@ -421,5 +419,5 @@
 
             $arUploadedFiles = $this->getProductUploads($order_id, $product_index);
-            
+
             if (wpsg_isSizedArray($arUploadedFiles)) {
 
@@ -449,5 +447,5 @@
             $this->shop->view['wpsg_mod_orderupload']['product_id'] = $product_id;
             $this->shop->view['wpsg_mod_orderupload']['arFiles'] = $this->getProductUploads($order_id, $product_index);
-		    
+
 		    return $this->shop->render(WPSG_PATH_VIEW.'/mods/mod_orderupload/basket_row_upload_target.phtml', false);
 		     
@@ -513,5 +511,5 @@
             
             $path = $this->getProductStoragePath($order_id, $product_index);
-            
+
             foreach (scandir($path) as $file) {
                 
Index: /mods/wpsg_mod_productvariants.class.php
===================================================================
--- /mods/wpsg_mod_productvariants.class.php	(revision 7840)
+++ /mods/wpsg_mod_productvariants.class.php	(revision 7841)
@@ -128,6 +128,5 @@
 		} // public function settings_save()
 
-		public function be_ajax()
-		{
+		public function be_ajax() {
 
 			$action = $_REQUEST['subaction'].'Action';
@@ -1163,5 +1162,5 @@
 			
 			$vp_data = $this->getVariants($product_id, true, true, true);
-									
+
 			$this->shop->view['vp_data'] = $vp_data;
 			$this->shop->view['vp_info'] = $this->getVariantenInfoArray($product_key);
@@ -1278,15 +1277,12 @@
 		} // private function admin_addAction()
 
-		private function admin_editAction()
-		{
-
-			$_REQUEST['product_id'] = wpsg_sinput("key", $_REQUEST['product_id']);
-			$_REQUEST['variant_id'] = wpsg_sinput("key", $_REQUEST['variant_id']);
+		private function admin_editAction() {
+
+			$_REQUEST['product_id'] = intval($_REQUEST['product_id']);
+			$_REQUEST['variant_id'] = intval($_REQUEST['variant_id']);
 
 			$this->shop->view['product_id'] = wpsg_getStr($_REQUEST['product_id'], '0');
 			$this->shop->view['variant'] = $this->getVariant($_REQUEST['variant_id']);
 			$this->shop->view['arVariation'] = $this->getVariationOfVariant($_REQUEST['variant_id'], $_REQUEST['product_id']);
-
-			//die(wpsg_debug($this->shop->view['arVariation']));
 
 			die($this->shop->render(WPSG_PATH_VIEW.'/mods/mod_productvariants/admin_edit.phtml'));
@@ -1522,4 +1518,52 @@
 		} // private function admin_inlineEditAction()
 
+		private function admin_removeImageAction() {
+
+			$vari_images = $this->shop->get_option('wpsg_mod_productvariants_global_images');
+			if (!is_array($vari_images)) $vari_images = [];
+
+			$vari_id = intval($_REQUEST['vari_id']);
+
+			if (!isset($vari_images[$vari_id]) || !is_array($vari_images[$vari_id])) $vari_images[$vari_id] = [];
+
+			$vari_images[$vari_id] = array_filter($vari_images[$vari_id], function($e) {
+
+				return intval($e) !== intval($_REQUEST['attachment_id']);
+
+			});
+
+			$this->shop->update_option('wpsg_mod_productvariants_global_images', $vari_images);
+
+			exit;
+
+		}
+
+		private function admin_uploadAction() {
+
+			$vari_images = $this->shop->get_option('wpsg_mod_productvariants_global_images');
+			if (!is_array($vari_images)) $vari_images = [];
+
+			$vari_id = intval($_REQUEST['vari_id']);
+
+			if (!wpsg_isSizedInt($vari_id)) exit;
+
+			if (!is_array($vari_images[$vari_id])) $vari_images[$vari_id] = [];
+
+			foreach ($_REQUEST['arAtt'] as $a) {
+
+				$post_id = intval($a);
+
+				if ($post_id > 0) $vari_images[$vari_id][] = $post_id;
+
+			}
+
+			$vari_images[$vari_id] = array_unique($vari_images[$vari_id]);
+
+			$this->shop->update_option('wpsg_mod_productvariants_global_images', $vari_images);
+
+			$this->admin_editAction();
+
+		}
+
 		/**
 		 * Gibt einen Array zurÃŒck, bei denen die SchlÃŒssel die Varianten sind und die Werte die gewÃ€hlten Variationen
@@ -1553,6 +1597,5 @@
 		 * @param Integer $variant_id ID der Variante
 		 */
-		public function getVariationOfVariant($variant_id, $product_id = false, $arProductFilter = array())
-		{
+		public function getVariationOfVariant($variant_id, $product_id = false, $arProductFilter = array()) {
 
 			$strQuerySELECT = "";
@@ -1561,6 +1604,5 @@
 			$strQueryHAVING = "";
 
-			if (wpsg_isSizedArray($arProductFilter))
-			{
+			if (wpsg_isSizedArray($arProductFilter)) {
 
 				//return array($strQuerySELECT, $strQueryWHERE, $strQueryJOIN, $strQueryHAVING, $strQueryORDER);
@@ -1941,10 +1983,11 @@
 			", "id");
 
-			foreach ($arData as $k => $v)
-			{
+			$vari_images = $this->shop->get_option('wpsg_mod_productvariants_global_images');
+			if (!is_array($vari_images)) $vari_images = [];
+
+			foreach ($arData as $k => $v) {
 
 				if ($onlyActive === true && !wpsg_isSizedInt($v['count_active'])) unset($arData[$k]);
-				else
-				{
+				else {
 
 					$arData[$k]['type_label'] = self::$arTypeLabel[$arData[$k]['type']];
@@ -1972,5 +2015,25 @@
 								VI.`pos` ASC
 						", "variation_id");
- 
+
+						array_walk($arData[$k]['arVariation'], function(&$e) use ($vari_images) {
+
+							if (isset($vari_images[intval($e['variation_id'])])) {
+
+								$images = explode(',', $e['images']);
+								$images_set = explode(',', $e['images_set']);
+
+								$images = array_merge($images, $vari_images[intval($e['variation_id'])]);
+								$images_set = array_merge($images_set, $vari_images[intval($e['variation_id'])]);
+
+								$images = array_unique($images);
+								$images_set = array_unique($images_set);
+
+								$e['images'] = implode(',', $images);
+								$e['images_set'] = implode(',', $images_set);
+
+							}
+
+						});
+
 					}
 				}
@@ -2068,6 +2131,5 @@
 		 * Liest die Informationen anhand eines VariantenschlÃŒssels aus
 		 */
-		public function getVariantenInfoArray($product_key)
-		{
+		public function getVariantenInfoArray($product_key) {
 
 			$produkt_id = $this->shop->getProduktID($product_key);
@@ -2087,7 +2149,9 @@
 			// kein Produkt-Key dann keine Weiterarbeit nÃ¶tig
 			if (is_numeric($product_key)) {
+
 				$arReturn['key'] = '';
 				$arReturn['akey'] = '';
 				$arReturn['images'] = array();
+
 				return $arReturn;
 
@@ -2100,7 +2164,22 @@
 			$arImagesProduct = $this->shop->imagehandler->getAttachmentIDs($produkt_id);
 			$arImages = $arImagesProduct;
-	
-			foreach ($arVari as $var_key)
-			{
+
+			/** Globale Varianten kÃ¶nnten auch erlaubte Bilder haben */
+			$vari_images = $this->shop->get_option('wpsg_mod_productvariants_global_images');
+			if (!is_array($vari_images)) $vari_images = [];
+
+			foreach ($arVari as $k => $var_key) {
+
+				$var_value = intval(preg_replace('/(.*)\:/', '', $var_key));
+
+				if (isset($vari_images[$var_value])) {
+
+					$arImages = array_unique(array_merge($arImages, $vari_images[$var_value]));
+
+				}
+
+			}
+
+			foreach ($arVari as $var_key) {
 
 				$var_id = preg_replace('/\:(.*)/', '', $var_key);
@@ -2111,8 +2190,8 @@
 				/* Bilder dieser Variation */
 				$arImagesVariation = explode(',', @$vp_data[$var_id]['arVariation'][$var_value]['images_set']);
-				
+
 				/* Schnittmenge */
 				$arImages = array_intersect($arImages, $arImagesVariation);
-				
+
 				$r = array(
 					'vari_id' => $var_value,
@@ -2124,6 +2203,5 @@
 				);
 
-				if ($this->shop->hasMod('wpsg_mod_weight') && wpsg_isSizedInt($vp_data[$var_id]['arVariation'][$var_value]['weight']))
-				{
+				if ($this->shop->hasMod('wpsg_mod_weight') && wpsg_isSizedInt($vp_data[$var_id]['arVariation'][$var_value]['weight'])) {
 
 					$r['weight'] = $vp_data[$var_id]['arVariation'][$var_value]['weight'];
@@ -2132,6 +2210,5 @@
 				}
 
-				if ($this->shop->hasMod('wpsg_mod_fuellmenge') && wpsg_isSizedInt($vp_data[$var_id]['arVariation'][$var_value]['fmenge']))
-				{
+				if ($this->shop->hasMod('wpsg_mod_fuellmenge') && wpsg_isSizedInt($vp_data[$var_id]['arVariation'][$var_value]['fmenge'])) {
 
 					$r['fmenge'] = $vp_data[$var_id]['arVariation'][$var_value]['fmenge'];
Index: /mods/wpsg_mod_productvars.class.php
===================================================================
--- /mods/wpsg_mod_productvars.class.php	(revision 7840)
+++ /mods/wpsg_mod_productvars.class.php	(revision 7841)
@@ -406,5 +406,5 @@
 		public function basket_row(&$p, $i)
 		{
-			if ($this->shop->get_option('wpsg_mod_productvars_showBasket') != '1')
+			if ($this->shop->get_option('wpsg_mod_productvars_showBasket') === '1')
 			{ 
 				$produkt_id = $this->shop->basket->getProduktDBID($p['id']);
Index: /views/css/admin.css
===================================================================
--- /views/css/admin.css	(revision 7840)
+++ /views/css/admin.css	(revision 7841)
@@ -67,4 +67,5 @@
 #wpsg-bs .wpsg_msg_wrap { margin-right:20px; }
 #wpsg-bs .d-flex { display:flex; }
+#wpsg-bs .justify-content-between { justify-content:space-between; }
 #wpsg-bs .w-100 { width:100%; }
 #wpsg-bs .justify-content_center { justify-content:center; }
@@ -386,4 +387,8 @@
 .wpsg_mod_productvariants_table_variants .col_id { width:50px; }
 .wpsg_mod_productvariants_table_variation .col_action { text-align:right; width:75px; }
+.wpsg_mod_productvariants_table_variation .wpsg_mod_productvariants_remove_global_vari_image { position:relative; text-decoration:none; display:inline-block; }
+.wpsg_mod_productvariants_table_variation .wpsg_mod_productvariants_remove_global_vari_image > span { color:#FFFFFF; background-color:rgba(0, 0, 0, 0.5); position:absolute; left:0; top:0; width:100%; height:100%; display:none; justify-content:center; align-items:center; }
+.wpsg_mod_productvariants_table_variation .wpsg_mod_productvariants_remove_global_vari_image:hover > span { display:flex; }
+.wpsg_mod_productvariants_table_variation .wpsg_mod_productvariants_remove_global_vari_image img { max-width:25px; max-height:25px; }
 .wpsg_mod_productvariants_table_variation tbody:nth-child(even) td { background-color:#F9F9F9; }
 .wpsg_mod_productvariants_table_variation .col_id { width:50px; }
Index: /views/mods/mod_downloadplus/settings_edit_templates.phtml
===================================================================
--- /views/mods/mod_downloadplus/settings_edit_templates.phtml	(revision 7840)
+++ /views/mods/mod_downloadplus/settings_edit_templates.phtml	(revision 7841)
@@ -47,5 +47,8 @@
 
 		<div class="form-group form-group-sm has-feedback">
-			<label class="col-sm-6 control-label" for="wpsg_mod_downloadplus_filename"><?php echo __('Name des Templates', 'wpsg'); ?></label>
+			<label class="col-sm-6 control-label label-copy" for="wpsg_mod_downloadplus_filename">
+                <a href="#" title="<?php echo __('Template kopieren', 'wpsg'); ?>" @click="copyTemplate()"><span class="wpsg-glyphicon glyphicon glyphicon-copy"></span></a>
+                <span><?php echo __('Name des Templates', 'wpsg'); ?></span>
+            </label>
 			<div class="col-sm-6">
 				<div class="wpsg_field_wrap wpsg_field_wrap_template_name">
@@ -180,4 +183,6 @@
     #wpsg_dp_templates_app .file_wrap .file { display:flex; gap:1rem; justify-content:flex-end; align-items:center; }
     #wpsg_dp_templates_app .file_wrap .file .wpsg-glyphicon { margin-right:8px; }
+    #wpsg_dp_templates_app .label-copy { display:flex; justify-content:space-between; }
+    #wpsg_dp_templates_app .label-copy .glyphicon  { font-size:14px; }
 
 </style>
@@ -221,4 +226,17 @@
 	        },
 
+            copyTemplate: function() {
+
+        		if (!confirm('<?php echo __('Sind Sie sich sicher, dass sie das Template kopieren mÃ¶chten?', 'wpsg'); ?>')) return false;
+
+                let new_template = JSON.parse(JSON.stringify(this.template));
+
+                new_template.name += ' (Kopie)';
+
+                this.arTemplates.push(new_template);
+                this.template = new_template;
+
+            },
+
             removeTemplate: function() {
 
Index: /views/mods/mod_productgroups/list.phtml
===================================================================
--- /views/mods/mod_productgroups/list.phtml	(revision 7840)
+++ /views/mods/mod_productgroups/list.phtml	(revision 7841)
@@ -22,14 +22,30 @@
 	<div class="wpsg_pgruppen_list_produkte">	
 		<?php for ($i = 0; $i < $showP && $i < sizeof($g['produkte']); $i ++) { ?>
-			<?php $image = array_rand($g['produkte'][$i]['bilder']); ?>
-			<?php if ($image >= 0 && is_int($image)) { ?>
-			<div class="wpsg_pgruppen_list_image">
-				
-				<a href="<?php echo $g['produkte'][$i]['url'] ?>">
-					<?php echo wp_get_attachment_image($g['produkte'][$i]['bilder'][0], 'thumbnail', false, array()); ?>
-				</a>
-				 
-			</div>
-			<?php } ?>
+
+            <?
+
+            $lagerbestand = $this->callMod('wpsg_mod_stock', 'getBestand', [$g['produkte'][$i]['id']]);
+
+            ?>
+
+            <?php if ($lagerbestand <= 0) { ?>
+
+                Ausverkauft ...
+
+            <?php } else { ?>
+
+                <?php $image = array_rand($g['produkte'][$i]['bilder']); ?>
+                <?php if ($image >= 0 && is_int($image)) { ?>
+                <div class="wpsg_pgruppen_list_image">
+
+                    <a href="<?php echo $g['produkte'][$i]['url'] ?>">
+                        <?php echo wp_get_attachment_image($g['produkte'][$i]['bilder'][0], 'thumbnail', false, array()); ?>
+                    </a>
+
+                </div>
+                <?php } ?>
+
+            <?php } ?>
+
 		<?php } ?>
 		<div style="clear:both;"></div>			
Index: /views/mods/mod_productindex/layouts/list.phtml
===================================================================
--- /views/mods/mod_productindex/layouts/list.phtml	(revision 7840)
+++ /views/mods/mod_productindex/layouts/list.phtml	(revision 7841)
@@ -102,5 +102,5 @@
 
 					<div class="wpsg_mod_productindex_fmenge">
-						<?php if ($this->hasMod('wpsg_mod_fuellmenge') && $this->get_option('wpsg_mod_fuellmenge_showProductindex_fmenge') == '1') {Â ?>
+						<?php if ($this->hasMod('wpsg_mod_fuellmenge') && $this->get_option('wpsg_mod_fuellmenge_showProductindex_fmenge') == '1') { ?>
 							<?php if (($p['fmenge']) > '0') { ?>
 								<?php echo wpsg_translate(__('FÃŒllmenge: #1#', 'wpsg'), wpsg_ff($p['fmenge'], $p['feinheit'])); ?>
Index: /views/mods/mod_productvariants/admin_edit.phtml
===================================================================
--- /views/mods/mod_productvariants/admin_edit.phtml	(revision 7840)
+++ /views/mods/mod_productvariants/admin_edit.phtml	(revision 7841)
@@ -6,7 +6,19 @@
 
 ?>
- 
+
 <input type="hidden" id="wpsg_mod_productvariants_product_id" value="<?php echo $this->view['product_id']; ?>" />
 <input type="hidden" id="wpsg_mod_productvariants_var_id" value="<?php echo $this->view['variant']['id']; ?>" />
+
+<script>
+
+    var wpframe; var wpsg_mod_productvariants_vari_id = 0;
+    var metaBox = jQuery('#meta-box-id.postbox');
+
+    var addImgLink = metaBox.find('.upload-custom-img');
+    var delImgLink = metaBox.find('.delete-custom-img');
+    var imgContainer = metaBox.find('.custom-img-container');
+    var imgIdInput = metaBox.find('.custom-img-id');
+
+</script>
 
 <?php if (wpsg_isSizedArray($this->view['arVariation'])) { ?>
@@ -50,5 +62,9 @@
       		</tr>
     	</thead>
-    	<?php $i = 0; foreach ($this->view['arVariation'] as $vari) { $i ++; ?>
+    	<?php $i = 0; foreach ($this->view['arVariation'] as $vari) { $i ++;
+
+		    $vari_id = intval($vari['id']);
+
+	    ?>
     	<tbody id="vari_<?php echo $vari['id']; ?>">
     		<tr>    		
@@ -181,29 +197,120 @@
     			
     		</tr>
-    		 
-			<?php if (wpsg_isSizedInt($this->view['product_id'])) { ?>
+
     		<tr class="wpsg_mod_productvariants_productimage_row">
     			<td class="col_active">&nbsp;</td>
    				<?php 
-				 
-					$arAttachmentIDs = $this->imagehandler->getAttachmentIDs($this->view['product_id'], $vari['id'], true);
+
+                    if (wpsg_isSizedInt($this->view['product_id'])) {
+
+                        $arAttachmentIDs = $this->imagehandler->getAttachmentIDs($this->view['product_id'], $vari['id'], true);
+
+                    } else {
+
+                        $vari_images = $this->get_option('wpsg_mod_productvariants_global_images');
+                        if (!is_array($vari_images)) $vari_images = [];
+
+                        $arAttachmentIDs = ((isset($vari_images[$vari_id]))?$vari_images[$vari_id]:[]);
+
+                    }
 					
 				?>
 				<td class="ui-sortable" colspan="<?php echo $colspan; ?>"  id="wpsg_images_productimage_<?php echo $this->view['variant']['id']; ?>_<?php echo $vari['id']; ?>" >
-			 
-					<?php foreach ($arAttachmentIDs as $attachment_id) { ?>
+
+                    <div class="d-flex justify-content-between w-100">
+
+                        <div>
+                            <?php foreach ($arAttachmentIDs as $attachment_id) { $attachment_id = intval($attachment_id); ?>
+
+                                <?php if (wpsg_isSizedInt($this->view['product_id'])) { ?>
+
+                                    <a href="#" class="<?php echo ((in_array($attachment_id, explode(",", $vari['images_set'])))?'mark':''); ?> pic" id="<?php echo $attachment_id; ?>" onclick="return wpsg_vp_vari_setPic(this, <?php echo $this->view['variant']['id']; ?>, <?php echo $vari['id'] ?>, '<?php echo $attachment_id; ?>', <?php echo $this->view['product_id']; ?>);">
+                                        <?php echo wp_get_attachment_image($attachment_id, array(25, 25), true); ?>
+                                    </a>
+
+                                <?php } else { ?>
+
+                                    <a href="#" class="pic wpsg_mod_productvariants_remove_global_vari_image"
+                                        data-variant_id="<?php echo intval($_REQUEST['variant_id']); ?>"
+                                        data-variation_id="<?php echo $vari['id']; ?>"
+                                        data-attachment_id="<?php echo $attachment_id; ?>"
+                                    >
+                                        <?php echo wp_get_attachment_image($attachment_id, array(25, 25), true); ?>
+                                        <span><span class="glyphicon glyphicon-trash"></span></span>
+                                    </a>
+
+                                <?php } ?>
+
+                            <?php } ?>
+                        </div>
+
+                        <?php if (!wpsg_isSizedInt($this->view['product_id'])) { ?>
+                        <div>
+
+                            <input id="media_upload_<?php echo $vari['id']; ?>" value="<?php echo __('Mediathek', 'wpsg'); ?>" class="button" type="button" />
+
+                        </div>
+                        <?php } ?>
+
+                    </div>
 					
-						<a href="#" class="<?php echo ((in_array($attachment_id, explode(",", $vari['images_set'])))?'mark':''); ?> pic" id="<?php echo $attachment_id; ?>" onclick="return wpsg_vp_vari_setPic(this, <?php echo $this->view['variant']['id']; ?>, <?php echo $vari['id'] ?>, '<?php echo $attachment_id; ?>', <?php echo $this->view['product_id']; ?>);">
-							
-							<?php echo wp_get_attachment_image($attachment_id, array(25, 25), true); ?>
-							
-						</a>
-						
-					<?php } ?>
-					
-					<script type="text/javascript">
+					<script>
 
 						jQuery(document).ready(function() {   
-			   				 
+
+							<?php if (intval($this->view['product_id']) <= 0) { ?>
+							document.getElementById('media_upload_<?php echo $vari['id']; ?>').addEventListener('click', (event) => {
+
+								event.preventDefault();
+
+								wpsg_mod_productvariants_vari_id = <?php echo $vari['id']; ?>;
+
+								if (wpframe !== undefined) { wpframe.open(); return; }
+
+								wpframe = wp.media.frames.file_frame = wp.media({
+                                    title: "<?php echo __('AuswÃ€hlen oder Hochladen von Medien', 'wpsg'); ?>",
+                                    button: { text: "<?php echo __('Medien benutzen', 'wpsg'); ?>" },
+                                    multiple: true
+					            });
+
+								wpframe.on('select', () => {
+
+									let arAtt = [];
+				                    let attachments = wpframe.state().get('selection').map((attachment) => {
+
+                                        attachment.toJSON();
+
+                                        arAtt.push(attachment.id);
+
+                                        return attachment;
+
+				                    });
+
+				                    jQuery('#wpsg_mod_productvariants_dialog_modal .modal-body').html('<img src="<?php echo WPSG_URL; ?>views/gfx/ajax-loader.gif" alt="<?php echo __('Bitte warten ...', 'wpsg'); ?>" />');
+
+				                    jQuery.ajax({
+                                        url: '<?php echo WPSG_URL_WP; ?>wp-admin/admin.php?page=wpsg-Admin&action=module&modul=wpsg_mod_productvariants&subaction=admin_upload&noheader=1',
+                                        async: true,
+                                        data: {
+                                            product_id: '<?php echo intval($_REQUEST['product_id']); ?>',
+                                            variant_id: '<?php echo intval($_REQUEST['variant_id']); ?>',
+                                            vari_id: wpsg_mod_productvariants_vari_id,
+                                            arAtt: arAtt
+                                        },
+                                        success: function(data) {
+
+                                            jQuery('#wpsg_mod_productvariants_dialog_modal .modal-body').html(data);
+
+                                        }
+                                    });
+
+                                });
+
+								wpframe.open();
+
+                            });
+							<?php } ?>
+
+							<?php if (intval($this->view['product_id']) > 0) { ?>
 					   		jQuery('#wpsg_images_productimage_<?php echo $this->view['variant']['id']; ?>_<?php  echo $vari['id']; ?>').sortable( {
 								items: 'a',
@@ -233,5 +340,6 @@
 																				 
 								}			
-							} ).disableSelection(); 
+							} ).disableSelection();
+					   		<?php } ?>
 
 			   			} );
@@ -242,5 +350,4 @@
 				 				
     		</tr>
-			<?php } ?>
 
     	</tbody>
@@ -249,5 +356,5 @@
     </table>
 
-	<script type="text/javascript">/* <![CDATA[ */
+	<script>
 
 	function wpsg_vp_vari_setPic(htmlElement, var_id, vari_id, attachment_id, product_id)
@@ -335,6 +442,30 @@
 		jQuery('#wpsg_mod_productvariants_variation_add_button').hide();
 		<?php } ?>	
-			
-	/* ]]> */</script> 
+
+        jQuery('.wpsg_mod_productvariants_remove_global_vari_image').on('click', function() {
+
+            let el = jQuery(this);
+
+            event.preventDefault();
+
+            if (!confirm('<?php echo __('Sind Sie sich sicher?', 'wpsg'); ?>')) return;
+
+            el.remove();
+
+            jQuery.ajax({
+                url: '<?php echo WPSG_URL_WP; ?>wp-admin/admin.php?page=wpsg-Admin&action=module&modul=wpsg_mod_productvariants&subaction=admin_removeImage&noheader=1',
+                async: true,
+                data: {
+                    product_id: 0,
+                    variant_id: el.data('variant_id'),
+                    vari_id: el.data('variation_id'),
+                    attachment_id: el.data('attachment_id')
+                },
+                success: function(data) { }
+            });
+
+        });
+
+	</script>
     
     <?php if (!wpsg_isSizedInt($this->view['product_id'])) { ?>
@@ -346,5 +477,5 @@
 	<?php echo __('Bisher keine Variationen der Variante angelegt.', 'wpsg'); ?>
 
-	<script type="text/javascript">/* <![CDATA[ */
+	<script>
 
 		<?php if (wpsg_isSizedInt($this->view['variant']['product_id']) || !wpsg_isSizedInt($this->view['product_id'])) { ?>
@@ -354,5 +485,6 @@
 		<?php } ?>
 
-	/* ]]> */</script>
+    </script>
 
 <?php } ?>
+
Index: /views/mods/mod_productvariants/admin_html.phtml
===================================================================
--- /views/mods/mod_productvariants/admin_html.phtml	(revision 7840)
+++ /views/mods/mod_productvariants/admin_html.phtml	(revision 7841)
@@ -41,5 +41,5 @@
 </div>
 
-<script type="text/javascript">/* <![CDATA[ */
+<script>
 
 	function wpsg_mod_productvariants_del(variant_id)
@@ -134,6 +134,5 @@
 	} // function wpsg_mod_productvariants_edit(variant_id)
 
-	function wpsg_mod_productvariants_variation_add()
-	{
+	function wpsg_mod_productvariants_variation_add() {
 
 		var variant_id = jQuery('#wpsg_mod_productvariants_var_id').val();
@@ -164,5 +163,5 @@
         return false;
 		
-	} // function wpsg_mod_productvariants_variation_add()
+	}
 	
 	function wpsg_mod_productvariants_add()
@@ -270,3 +269,3 @@
 	} // function wpsg_mod_productvariants_show()
 
-/* ]]> */</script>
+</script>
Index: /views/mods/mod_productvariants/admin_show.phtml
===================================================================
--- /views/mods/mod_productvariants/admin_show.phtml	(revision 7840)
+++ /views/mods/mod_productvariants/admin_show.phtml	(revision 7841)
@@ -48,5 +48,5 @@
     			<td class="col_action">
     			
-    				<script type="text/javascript">/* <![CDATA[ */
+    				<script>
 
     					<?php if ((wpsg_isSizedInt($this->view['product_id']) && $this->view['product_id'] == $var['product_id']) || (!wpsg_isSizedInt($var['product_id']) && !wpsg_isSizedInt($this->view['product_id']))) { ?>
@@ -70,5 +70,5 @@
 						<?php } ?>		
 		
-					/* ]]> */</script>
+					</script>
     			
     				<a href="#" class="wpsg-glyphlink-td" title="<?php echo __('Variante bearbeiten', 'wpsg'); ?>" onclick="return wpsg_mod_productvariants_edit(<?php echo $var['id']; ?>);"><span class="glyphicon glyphicon-pencil"></span></a>
@@ -86,5 +86,5 @@
     <p class="wpsg_hinweis"><?php echo __('Reihenfolge kann mittels Drag&Drop verÃ€ndert werden.', 'wpsg'); ?></p>
     
-    <script>/* <![CDATA[ */
+    <script>
 
 	    jQuery('.wpsg_mod_productvariants_table_variants tbody').sortable( {
@@ -109,5 +109,5 @@
 		} );
 
-    /* ]]> */</script>
+    </script>
 
 <?php } else { ?>
Index: /views/produkttemplates/standard.phtml
===================================================================
--- /views/produkttemplates/standard.phtml	(revision 7840)
+++ /views/produkttemplates/standard.phtml	(revision 7841)
@@ -44,5 +44,5 @@
 			/* Array mit allen AttachmentIDs der Produktbilder */
 			$arAttachmentIDsAll = $this->imagehandler->getAttachmentIDs($this->view['data']['product_id']);
-		
+
 		?>
 
