Index: branches/5.1.x/core/units/helpers/file_helper.php
===================================================================
--- branches/5.1.x/core/units/helpers/file_helper.php	(revision 14390)
+++ branches/5.1.x/core/units/helpers/file_helper.php	(revision 14391)
@@ -1,397 +1,400 @@
 <?php
 /**
 * @version	$Id$
 * @package	In-Portal
 * @copyright	Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
 * @license      GNU/GPL
 * In-Portal is Open Source software.
 * This means that this software may have been modified pursuant
 * the GNU General Public License, and as distributed it includes
 * or is derivative of works licensed under the GNU General Public License
 * or other free or open source software licenses.
 * See http://www.in-portal.org/license for copyright notices and details.
 */
 
 	defined('FULL_PATH') or die('restricted access!');
 
 	class FileHelper extends kHelper {
 
 		/**
 		 * Puts existing item images (from subitem) to virtual fields (in main item)
 		 *
 		 * @param kCatDBItem $object
 		 */
 		function LoadItemFiles(&$object)
 		{
 			$max_file_count = $this->Application->ConfigValue($object->Prefix.'_MaxImageCount'); // file count equals to image count (temporary measure)
 
 			$sql = 'SELECT *
 					FROM '.TABLE_PREFIX.'ItemFiles
 					WHERE ResourceId = '.$object->GetDBField('ResourceId').'
 					ORDER BY FileId ASC
 					LIMIT 0, '.(int)$max_file_count;
 			$item_files = $this->Conn->Query($sql);
 
 			$file_counter = 1;
 			foreach ($item_files as $item_file) {
 				$file_path = $item_file['FilePath'];
 				$object->SetDBField('File'.$file_counter, $file_path);
 				$object->SetOriginalField('File'.$file_counter, $file_path);
 				$object->Fields['File'.$file_counter]['original_field'] = $item_file['FileName'];
 				$file_counter++;
 			}
 		}
 
 		/**
 		 * Saves newly uploaded images to external image table
 		 *
 		 * @param kCatDBItem $object
 		 */
 		function SaveItemFiles(&$object)
 		{
 			$table_name = $this->Application->getUnitOption('#file', 'TableName');
 			$max_file_count = $this->Application->getUnitOption($object->Prefix, 'FileCount'); // $this->Application->ConfigValue($object->Prefix.'_MaxImageCount');
 
 			$this->CheckFolder(FULL_PATH . ITEM_FILES_PATH);
 
 			$i = 0;
 			while ($i < $max_file_count) {
 				$field = 'File'.($i + 1);
 				$field_options = $object->GetFieldOptions($field);
 
 				$file_path = $object->GetDBField($field);
 				if ($file_path) {
 					if (isset($field_options['original_field'])) {
 						$key_clause = 'FileName = '.$this->Conn->qstr($field_options['original_field']).' AND ResourceId = '.$object->GetDBField('ResourceId');
 
 						if ($object->GetDBField('Delete'.$field)) {
 							// if item was cloned, then new filename is in db (not in $image_src)
 							$sql = 'SELECT FilePath
 									FROM '.$table_name.'
 									WHERE '.$key_clause;
 							$file_path = $this->Conn->GetOne($sql);
 							if (@unlink(FULL_PATH.ITEM_FILES_PATH.$file_path)) {
 								$sql = 'DELETE FROM '.$table_name.'
 										WHERE '.$key_clause;
 								$this->Conn->Query($sql);
 							}
 						}
 						else {
 							// image record found -> update
 							$fields_hash = Array (
 								'FilePath' => $file_path,
 							);
 
 							$this->Conn->doUpdate($fields_hash, $table_name, $key_clause);
 						}
 					}
 					else {
 						// record not found -> create
 						$fields_hash = Array (
 							'ResourceId' => $object->GetDBField('ResourceId'),
 							'FileName' => $field,
 							'Status' => STATUS_ACTIVE,
 							'FilePath' => $file_path,
 						);
 
 						$this->Conn->doInsert($fields_hash, $table_name);
 						$field_options['original_field'] = $field;
 						$object->SetFieldOptions($field, $field_options);
 					}
 				}
 				$i++;
 			}
 		}
 
 		/**
 		 * Preserves cloned item images/files to be rewrited with original item images/files
 		 *
 		 * @param Array $field_values
 		 */
 		function PreserveItemFiles(&$field_values)
 		{
 			foreach ($field_values as $field_name => $field_value) {
 				if (!is_array($field_value)) continue;
 
 				if (isset($field_value['upload']) && ($field_value['error'] == UPLOAD_ERR_NO_FILE)) {
 					// this is upload field, but nothing was uploaded this time
 					unset($field_values[$field_name]);
 				}
 			}
 		}
 
 		/**
 		 * Determines what image/file fields should be created (from post or just dummy fields for 1st upload)
 		 *
 		 * @param string $prefix
 		 * @param bool $is_image
 		 */
 		function createItemFiles($prefix, $is_image = false)
 		{
 			$items_info = $this->Application->GetVar($prefix);
 			if ($items_info) {
 				list ($id, $fields_values) = each($items_info);
 				$this->createUploadFields($prefix, $fields_values, $is_image);
 			}
 			else {
 				$this->createUploadFields($prefix, Array(), $is_image);
 			}
 		}
 
 		/**
 		 * Dynamically creates virtual fields for item for each image/file field in submit
 		 *
 		 * @param string $prefix
 		 * @param Array $fields_values
 		 * @param bool $is_image
 		 */
 		function createUploadFields($prefix, $fields_values, $is_image = false)
 		{
 			$field_options = Array (
 				'type'			=>	'string',
 				'max_len'		=>	240,
 				'default'		=>	'',
 			);
 
 			if ($is_image) {
 				$field_options['formatter'] = 'kPictureFormatter';
 				$field_options['include_path'] = 1;
 				$field_options['allowed_types'] = Array ('image/jpeg', 'image/pjpeg', 'image/png', 'image/x-png', 'image/gif', 'image/bmp');
 				$field_prefix = 'Image';
 			}
 			else {
 				$field_options['formatter'] = 'kUploadFormatter';
 				$field_options['upload_dir'] = ITEM_FILES_PATH;
 				$field_options['allowed_types'] = Array ('application/pdf', 'application/msexcel', 'application/msword', 'application/mspowerpoint');
 				$field_prefix = 'File';
 			}
 
 			$fields = $this->Application->getUnitOption($prefix, 'Fields');
 			$virtual_fields = $this->Application->getUnitOption($prefix, 'VirtualFields');
 
 			$image_count = 0;
 			foreach ($fields_values as $field_name => $field_value) {
 				if (preg_match('/^('.$field_prefix.'[\d]+|Primary'.$field_prefix.')$/', $field_name)) {
 					$fields[$field_name] = $field_options;
 					$virtual_fields[$field_name] = $field_options;
 					$this->_createCustomFields($prefix, $field_name, $virtual_fields, $is_image);
 
 					$image_count++;
 				}
 			}
 
 			if (!$image_count) {
 				// no images found in POST -> create default image fields
 				$image_count = $this->Application->ConfigValue($prefix.'_MaxImageCount');
 
 				if ($is_image) {
 					$created_count = 1;
 					$image_names = Array ('Primary' . $field_prefix => '');
 
 					while ($created_count < $image_count) {
 						$image_names[$field_prefix . $created_count] = '';
 						$created_count++;
 					}
 				}
 				else {
 					$created_count = 0;
 					$image_names = Array ();
 
 					while ($created_count < $image_count) {
 						$image_names[$field_prefix . ($created_count + 1)] = '';
 						$created_count++;
 					}
 				}
 
-				$this->createUploadFields($prefix, $image_names, $is_image);
+				if ($created_count) {
+					$this->createUploadFields($prefix, $image_names, $is_image);
+				}
+
 				return ;
 			}
 
 			$this->Application->setUnitOption($prefix, $field_prefix.'Count', $image_count);
 			$this->Application->setUnitOption($prefix, 'Fields', $fields);
 			$this->Application->setUnitOption($prefix, 'VirtualFields', $virtual_fields);
 		}
 
 		/**
 		 * Adds ability to create more virtual fields associated with main image/file
 		 *
 		 * @param string $prefix
 		 * @param string $field_name
 		 * @param Array $virtual_fields
 		 */
 		function _createCustomFields($prefix, $field_name, &$virtual_fields, $is_image)
 		{
 			$virtual_fields['Delete' . $field_name] = Array ('type' => 'int', 'default' => 0);
 
 			if ($is_image) {
 				$virtual_fields[$field_name . 'Alt'] = Array ('type' => 'string', 'default' => '');
 			}
 		}
 
 		/**
 		 * Downloads file to user
 		 *
 		 * @param string $filename
 		 */
 		function DownloadFile($filename)
 		{
 			$content_type = function_exists('mime_content_type') ? mime_content_type($filename) : 'application/octet-stream';
 
 			header('Content-type: '.$content_type);
 			header('Content-Disposition: attachment; filename="'.basename($filename).'"');
 			header('Content-Length: '.filesize($filename));
 			readfile($filename);
 			flush();
 		}
 
 		/**
 		 * Creates folder with given $path
 		 *
 		 * @param string $path
 		 * @return bool
 		 */
 		function CheckFolder($path)
 		{
 			$result = true;
 
 			if (!file_exists($path) || !is_dir($path)) {
 				$parent_path = preg_replace('#/[^/]+/?$#', '', $path);
 				$result = $this->CheckFolder($parent_path);
 
 				if ($result) {
 					$result = mkdir($path);
 
 					if ($result) {
 						chmod($path, 0777);
 
 						// don't commit any files from created folder
 						if (file_exists(FULL_PATH . '/CVS')) {
 							$cvsignore = fopen($path . '/.cvsignore', 'w');
 							fwrite($cvsignore, '*.*');
 							fclose($cvsignore);
 							chmod($path . '/.cvsignore', 0777);
 						}
 					}
 					else {
 						trigger_error('Cannot create directory "<strong>' . $path . '</strong>"', E_USER_WARNING);
 						return false;
 					}
 				}
 			}
 
 			return $result;
 		}
 
 		/**
 		 * Copies all files and directories from $source to $destination directory. Create destination directory, when missing.
 		 *
 		 * @param string $source
 		 * @param string $destination
 		 * @return bool
 		 */
 		function copyFolderRecursive($source, $destination)
 		{
 			if ( substr($source, -1) == DIRECTORY_SEPARATOR ) {
 				$source = substr($source, 0, -1);
 				$destination .= DIRECTORY_SEPARATOR . basename($source);
 			}
 
 			$dir = opendir($source);
 			$result = $this->CheckFolder($destination);
 
 			if (!$result || !is_resource($dir)) {
 				// failed to create target directory OR failed to open source directory
 				return false;
 			}
 
 			while ( false !== ($file = readdir($dir)) ) {
 				if ($file == '.' || $file == '..') {
 					continue;
 				}
 
 				if ( is_dir($source . DIRECTORY_SEPARATOR . $file) ) {
 					$result = $this->copyFolderRecursive($source . DIRECTORY_SEPARATOR . $file, $destination . DIRECTORY_SEPARATOR . $file);
 				}
 				else {
 					$result = copy($source . DIRECTORY_SEPARATOR . $file, $destination . DIRECTORY_SEPARATOR . $file);
 				}
 
 				if (!$result) {
 					trigger_error('Cannot create file/directory "<strong>' . $destination . DIRECTORY_SEPARATOR . $file . '</strong>"', E_USER_WARNING);
 					break;
 				}
 			}
 
 			closedir($dir);
 
 			return $result;
 		}
 
 		/**
 		 * Copies all files from $source to $destination directory. Create destination directory, when missing.
 		 *
 		 * @param string $source
 		 * @param string $destination
 		 * @return bool
 		 */
 		function copyFolder($source, $destination)
 		{
 			if ( substr($source, -1) == DIRECTORY_SEPARATOR ) {
 				$source = substr($source, 0, -1);
 				$destination .= DIRECTORY_SEPARATOR . basename($source);
 			}
 
 			$dir = opendir($source);
 			$result = $this->CheckFolder($destination);
 
 			if (!$result || !is_resource($dir)) {
 				// failed to create target directory OR failed to open source directory
 				return false;
 			}
 
 			while ( false !== ($file = readdir($dir)) ) {
 				if ($file == '.' || $file == '..' || !is_file($source . DIRECTORY_SEPARATOR . $file)) {
 					continue;
 				}
 
 				$result = copy($source . DIRECTORY_SEPARATOR . $file, $destination . DIRECTORY_SEPARATOR . $file);
 
 				if (!$result) {
 					trigger_error('Cannot create file "<strong>' . $destination . DIRECTORY_SEPARATOR . $file . '</strong>"', E_USER_WARNING);
 					break;
 				}
 			}
 
 			closedir($dir);
 
 			return $result;
 		}
 
 		/**
 		 * Transforms given path to file into it's url, where each each component is encoded (excluding domain and protocol)
 		 *
 		 * @param string $url
 		 * @return string
 		 */
 		function pathToUrl($url)
 		{
 			$url = str_replace(DIRECTORY_SEPARATOR, '/', preg_replace('/^' . preg_quote(FULL_PATH, '/') . '(.*)/', '\\1', $url, 1));
 			$url = implode('/', array_map('rawurlencode', explode('/', $url)));
 
 			return rtrim($this->Application->BaseURL(), '/') . $url;
 		}
 
 		/**
 		 * Transforms given url to path to it
 		 *
 		 * @param string $url
 		 * @return string
 		 */
 		function urlToPath($url)
 		{
 			$base_url = rtrim($this->Application->BaseURL(), '/');
 			$path = preg_replace('/^' . preg_quote($base_url, '/') . '(.*)/', FULL_PATH . '\\1', $url);
 
 			return str_replace('/', DIRECTORY_SEPARATOR, rawurldecode($path));
 		}
 	}
\ No newline at end of file