Upgrading from ActiveX/Java Uploader 6 in PHP

This topic highlights major API changes between versions 6 and 8 of ActiveX/Java Uploader and illustrates how to migrate a Web site to new version of the product. ActiveX/Java Uploader 8 has new client and server side APIs:

  • New client API utilizes JSON notation to configure ActiveX/Java Uploader client-side instead of addParam methods.
  • JavaScript object model became more comprehensive.
  • New server-side PHP classes allow inserting uploader to a Web page and receiving uploaded files.

The Changes in ActiveX/Java Uploader PHP API between Versions 6 and 8 and Changes in ActiveX/Java Uploader JavaScript API between Versions 6 and 8 topics provide lists of API changes between ActiveX/Java Uploader 6 and 8 versions.

In this topic we will create two small Web sites where users can upload images using ActiveX/Java Uploader 6 and 8. The applications will have similar functionality, and we will see how to implement the same set of features using both uploaders and what the differences between them are. Here is the list of ActiveX/Java Uploader features coming into play in our sample applications:

Creating ActiveX/Java Uploader Instance

To embed ActiveX/Java Uploader in a web page you have to create an uploader class instance and specify its identifier via the id parameter as follows:

JavaScript
var u = $au.uploader({
    id: 'Uploader1',
//...
});

Applying License Key

As you can see from the code snippet below, format of license keys has changed in ActiveX/Java Uploader 8. License key(s) are set through the uploader.licenseKey property, if you have several keys, they should be separated with semicolons. Take into account that now ActiveX/Java Uploader Express does not allow to specify multiple license keys, if you need to specify several ones, you need to upgrade your edition.

JavaScript
var u = $au.uploader({
//...
    licenseKey: 'XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXXX;YYYYY-YYYYY-YYYYY-YYYYY-YYYYY-YYYYYY',
//...
});

For more information about licensing see the Registering ActiveX/Java Uploader topic.

Defining Private-label-specific Settings

If you use private-label version of ActiveX/Java Uploader you need to specify your custom ActiveX/Java Uploader cab and jar files and your version number.

Use the activeXControl.codeBase, activeXControl.codeBase64, and javaControl.codeBase properties to setup URLs (absolute or relative) to cab and jar files respectively. Pay attention to the fact that in contrast to version 6 ActiveX/Java Uploader 8 requires filename in URLs specified in the codeBase properties.

The minimum required version of ActiveX/Java Uploader control can be set using the javaControl.version and activeXControl.version properties.

To customize Java class name use the javaControl.className property.

ActiveX control CLSID and PROGID you can set via the activeXControl.classId and activeXControl.progId respectively.

Important

All the information you need to specify using these properties will be provided to you by Aurigma, Inc. If some parameters were not sent, you should use default values.

JavaScript
var u = $au.uploader({
//...
    javaControl: {codeBase: 'Scripts/MyUploader7.jar', version: '7.0.11',
        className: 'com.mycompany.myuploader.MyUploader.class'},
    activeXControl: {codeBase: 'Scripts/MyUploader7.cab', codeBase64: 'Scripts/MyUploader7_x64.cab', 
        version: '7.0.11', progId: 'MyCompany.MyUploader',
        classId: 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'},
//...
});

For more information see the Using Private-label Version of ActiveX/Java Uploader Using Private-label Version of ActiveX/Java Uploader PHP Using Private-label Version of ActiveX/Java Uploader JavaScript topic.

Customizing User Interface

User interface customization API has been changed in new version. Now every visual element is represented by a class in client API, and its settings are presented via properties of these classes. Find the complete list of properties aimed to customize user interface in the Customizing Appearance in ActiveX/Java Uploader topic.

Pane Layout

Now instead of two- and three-pane layouts we have introduced one layout which combines benefits of both. The user can expand/collapse different panels: upload list and/or file tree can be hidden. One-pane layout is supported also, it has minimal "drop-box" user interface.

Each pane is reproduced by corresponding object in API: folderPane, treePane, uploadPane. Panes settings can be customized through properties of these objects.

Quick overview of new approaches in user interface can be found in the Layouts article.

Custom Buttons

As you know ActiveX/Java Uploader allows to change appearance of standard buttons for better integration with customers' Web sites. Button settings are specified through specially formatted strings containing information on where to find button icons, their dimensions, etc. The format of the string stays the same as in version 6. In our sample we will change appearance of the Upload button.

JavaScript
var u = $au.uploader({
//...

    //Set one-pane layout
    paneLayout: 'OnePane',
    
    //Define custom "Upload" button
    uploadButtonImageFormat: "Width=82;Height=25;UrlNormal='../Images/UploadNormal.png';" 
        + "UrlNormalFocused='../Images/UploadNormalFocused.png';UrlHover='../Images/UploadHover.png';"
        + "UrlHoverFocused='../Images/UploadHoverFocused.png';UrlPressed='../Images/UploadPressed.png';"
        + "UrlDisabled='../Images/UploadDisabled.png'",
//...
});

To customize buttons of Image editor and Description editor use the properties of corresponding classes.

Specifying Action URL and Redirect URL

Specify an URL to a server page where ActiveX/Java Uploader posts all selected files via the actionUrl property. That page should contain server code which saves files to necessary folders server-side.

To redirect a user to another page after upload is successfully completed use the redirectUrl property.

For more information see the Configuring Common Upload Settings in ActiveX/Java Uploader topic.

JavaScript
var u = $au.uploader({
//...
    uploadSettings: {actionUrl: 'upload.php', redirectUrl: 'gallery.php'},
//...
});

Configuring Files to Upload

New concept of converters were added to version 8. A converter defines how ActiveX/Java Uploader preprocesses files client-side before upload. You can specify uploading original files, creating thumbnails of specified dimensions and quality, or ZIP format compression via the converter.mode.

The following code configures uploader to send original files:

JavaScript
var u = $au.uploader({
//...
    converters: [{ mode: '*.*=SourceFile'}],
//...
});

For more information see the Configuring Files to be Uploaded in ActiveX/Java Uploader topic.

Thumbnails

To upload transformed (e.g. resized or watermarked) images you should specify a converter in thumbnail mode. Thumbnail parameters are specified through the set of converter.thumbnailXXX properties.

The following sample illustrates how to configure a 120x120 thumbnail converter:

JavaScript
var u = $au.uploader({
//...
    converters: [{ mode: '*.*=Thumbnail', thumbnailWidth: 120, thumbnailHeight: 120}],
//...
});

Often it is useful to upload a source file along with a thumbnail. You can do it by combining converters from the previous two samples, like this:

JavaScript
var u = $au.uploader({
//...
    converters: [
        //Add sourceFile converter
        { mode: '*.*=SourceFile'},
        //Add thumbnail converter
        { mode: '*.*=Thumbnail', thumbnailWidth: 120, thumbnailHeight: 120}
    ],
//...
});

To know more see the Uploading Images section.

Watermarks

Watermarks are specified through the converter.thumbnailWatermark property and can be applied only to the converters which generate thumbnails.

The following sample shows how to create a converter generating a watermarked thumbnail:

JavaScript
var u = $au.uploader({
//...
    converters: [{ mode: '*.*=Thumbnail', thumbnailWidth: 800, thumbnailHeight: 600, 
        thumbnailJpegQuality: 80, thumbnailFitMode: 'Fit',
        //Configure watermark
        thumbnailWatermark: 'Opacity=100;ImageUrl=../Images/Watermark.png;'
            + 'ImageWidth=155;ImageHeight=30;Position=BottomRight;'}],
//...
});

You can find a full review of ActiveX/Java Uploader watermarking capabilities in the Applying Watermarks via ActiveX/Java Uploader article.

Defining Quality Meter

The quality meter is now represented by a separate class, qualityMeter. Quality indicators parameters are set using the formats property via specially formatted string. See the code snippet below illustrating how to adjust quality meter.

JavaScript
var u = $au.uploader({
//...
    paneItem: {qualityMeter: { formats: '4 x 6,1800,1200,1.5;5 x 7,2100,1500,1.5;'
        +'8 x 10,3000,2400,1.5;16 x 20,4000,3200,2;30 x 20,6000,4000,2'}},
//...
});

For more information see the Using Quality Meter topic.

Modifying Application Behavior at Run-time

Handling Client-side Events

ActiveX/Java Uploader 8 exposes a number of JavaScript events which are fired on different uploader activities. This way, you can add additional logic to your Web page, and display custom progress bar, for example. As well, you can use events to modify ActiveX/Java Uploader settings at run-time based on selected files or user input. You can find the complete list of client-side events in the reference. To set an event handler use the uploader.events property like follows:

JavaScript
var u = $au.uploader({
//...
    events: { beforeUpload: Uploader1_BeforeUpload },
//...
});

Changing Converter Settings at Run-time

In our example we will examine how to reinitialize thumbnail settings at run-time. We subscribe to BeforeUpload event and add event handler function to the code. In the function we firstly find the appropriate thumbnail to modify. As you can see from code snippet below, we get access to converters by 0-based indices. Thus, we get the first of converters as follows: $au.uploader('uploader1').converters().get(0), where uploader1 is the uploader.id. After we got the converter, we change its settings.

The following snippet changes thumbnail size at run-time according to paper size format chosen beforehand:

JavaScript
function Uploader1_BeforeUpload() {

    var size = paperSize.split('x');
    var pixelWidth = size[1] * 300;
    var pixelHeight = size[0] * 300;
    
    //Get the second converter
    var converter = $au.uploader('uploader1').converters().get(1);
    
    //Specify thumbnail size
    converter.thumbnailWidth(pixelWidth);
    converter.thumbnailHeight(pixelHeight);
}

Adding Converter at Run-time

The previous paragraph shows how to change the existing converter, but sometimes there is a necessity to create a new one. For instance, if your Web site accepts thumbnails and you want to give a user an option to upload source image as well. In fact, the only difference from changing existing converter is that you should use converters.add() method to create a new converter. After that you can access it via the converters.get(Number) method. The following BeforeUpload event handler adds the SourceFile converter:

JavaScript
function Uploader1_BeforeUpload() {

    if (uploadSourceFile){
    
        //Add new converter
        uploader.converters().add();
        
        //The "count" method returns the number of converters actually contained in the collection
        var convertersCount = uploader.converters().count();
        
        //Get the newly created converter, which is the last in converters collection
        var converter = uploader.converters().get(convertersCount);
        
        //Specify converter mode
        converter.mode("*.*=SourceFile");
    }
}

For more information see the Using JavaScript API topic.

Rendering ActiveX/Java Uploader Control

After you configured ActiveX/Java Uploader control, use the uploader.writeHtml() method to render it, like follows:

JavaScript
<script type="text/javascript" src="Scripts/aurigma.uploader.js">  </script>
<script type="text/javascript">

var u = $au.uploader({
    id: 'Uploader1',
    licenseKey: 'XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXXX;YYYYY-YYYYY-YYYYY-YYYYY-YYYYY-YYYYYY',
//...
});

//Render ActiveX/Java Uploader control
u.writeHtml();

</script>

Handling Upload on Server

To get uploaded files and data on server side with previous version of the uploader the common approach was to obtain them through the $_FILES and $_POST super global arrays, like follows:

PHP
<?php

//Specify folders to save files to
$absCatalogPath = realpath("../Catalog/") . "/";
$absGalleryPath = realpath("../Gallery/") . "/";
$absThumbnailsPath = realpath("../Gallery/Thumbnails/") . "/";

//Get number of uploaded files
$fileCount = $_POST ["FileCount"];

//Iterate through all uploaded files
for ($i = 1; $i <= $fileCount; $i++)
{

    //Get the name of source file field
    $sourceFileField = "SourceFile_" . $i;
    
    //Check if the source file was uploaded
    if ($_FILES[$sourceFileField]['size']) {
    
        //Get name of the source file
        $fileName = $_FILES[$sourceFileField]['name'];
        
        //Save the source file with SourceFileName name
        move_uploaded_file($_FILES[$sourceFileField]['tmp_name'], $absCatalogPath . "/" . $fileName);
    }

    //Get the name of the first thumbnail field
    $thumbnail1Field = "Thumbnail1_" . $i;
    
    //Check if the first thumbnail was uploaded
    if ($_FILES[$thumbnail1Field]['size'])
    
        //Save the first thumbnail with SourceFileName.jpg name
        move_uploaded_file($_FILES[$thumbnail1Field]['tmp_name'], $absGalleryPath . $fileName . ".jpg");

    //Get the name of the second thumbnail field
    $thumbnail2Field = "Thumbnail2_" . $i;
    
    //Check if the second thumbnail was uploaded
    if ($_FILES[$thumbnail2Field]['size'])
    
        //Save the second thumbnail with SourceFileName.jpg name
        move_uploaded_file($_FILES[$thumbnail2Field]['tmp_name'], $absThumbnailsPath . $fileName . ".jpg");
}
?>

Now you can use ActiveX/Java Uploader PHP which provides rich possibilities for handling uploaded files and data, including fully automated assembling files from chunks and packages. It means that you can operate on uploaded files regardless of packages they were sent in and handle upload session as a whole even if files were uploaded by chunks. For more information about upload files by chunks and packages see the Sending All Files at Once or in Several Parts in ActiveX/Java Uploader topic.

The Saving Uploaded Files in ActiveX/Java Uploader PHP article gives full overview of methods you can use to save uploaded files on the server side, including the one wich parses POST requests using PHP predefined "superglobals" ($_FILES and $_POST).

Our application uses the UploadHandler class to manage uploaded files. Here, we specify the callback function through the UploadHandler.AllFilesUploadedCallback property. This function is called as soon as all files were successfully uploaded and gives access to uploaded files via array passed as the function argument. You can grab files from this array and do whatever you need: save them to disk or data base, update information on your Web site, etc. You can see how to perform this in the code sample below.

PHP
<?php
require_once "ImageUploaderPHP/UploadHandler.class.php";

//Create UploadHandler instance
$handler = new UploadHandler();

//Set the "saveAllUploadedFiles" function as a callback function
//which is called when the whole upload session completes
$handler->setAllFilesUploadedCallback("saveAllUploadedFiles");

//Enable processing of ActiveX/Java Uploader requests
$handler->processRequest();

//Callback function set previously
//$uploadedFiles is an array of UploadedFile objects
//Each UploadedFile contains all the converted files and metadata related to one user-selected file
function saveAllUploadedFiles($uploadedFiles) {

    //Specify folders to save files to
    $absCatalogPath = realpath("../Catalog/") . "/";
    $absGalleryPath = realpath("../Gallery/") . "/";
    $absThumbnailsPath = realpath("../Gallery/Thumbnails/") . "/";

    //Iterate through all uploaded files
    foreach ($uploadedFiles as $uploadedFile)
    {
        //Get all converted files generated for current uploaded file
        $convertedFiles = $uploadedFile->getConvertedFiles();
        
        //Get the first converted file 
        //accordingly to our converters set it is a source file
        $sourceFile = $convertedFiles[0];
        
        //Save this converted file with SourceFileName name
        $sourceFile->moveTo($absCatalogPath . "/" . $uploadedFile->getSourceName());
        
        //Get the second converted file 
        //accordingly to our converters set it is a watermarked thumbnail
        $thumbnail1 = $convertedFiles[1];
        
        //Save this converted file with SourceFileName.jpg name
        $thumbnail1->moveTo($absGalleryPath . "/" . $uploadedFile->getSourceName() . ".jpg");
        
        //Get the third converted file 
        //accordingly to our converters set it is a thumbnail configured at run-time
        $thumbnail2 = $convertedFiles[2];
        
        //Save this converted file with SourceFileName.jpg name 
        $thumbnail2->moveTo($absThumbnailsPath . "/" . $uploadedFile->getSourceName() . ".jpg");
    }
}
?>

Complete Code of Application with ActiveX/Java Uploader 8

index.html:

JavaScript
<script type="text/javascript" src="scripts/aurigma.uploader.js">  </script>
<script type="text/javascript">

var u = $au.uploader({

    //Specify the id of this Uploader instance
    id: 'uploader1',
    
    //Set width and height of ActiveX/Java Uploader control
    width: 650,    height: 450,
    
    //Apply license keys, semicolon is used to separate several keys
    licenseKey: 'XXXXX-XXXXX-XXXXX-XXXXX-XXXXX-XXXXXX;YYYYY-YYYYY-YYYYY-YYYYY-YYYYY-YYYYYY',
    
    //Private-label-specific settings
    //Set codeBase and minimum required version of java control
    javaControl: {codeBase: 'Scripts/ImageUploader7.jar', version: '7.0.11' },
    //Set codeBase and minimum required version of activeX control
    activeXControl: {codeBase: 'Scripts/ImageUploader7.cab', version: '7.0.11' },
    
    //Specify one-pane layout
    paneLayout: 'OnePane',
    
    //Define custom "Upload" button
    uploadButtonImageFormat: "Width=82;Height=25;UrlNormal='../Images/UploadNormal.png';" 
        + "UrlNormalFocused='../Images/UploadNormalFocused.png';UrlHover='../Images/UploadHover.png';"
        + "UrlHoverFocused='../Images/UploadHoverFocused.png';UrlPressed='../Images/UploadPressed.png';"
        + "UrlDisabled='../Images/UploadDisabled.png'",
        
    //Specify a page containing server code to handle uploaded files (actionUrl)
    uploadSettings: {actionUrl: 'upload.php'},
    
    //Add two converters
    converters: [
        //The first one uploads a source file itself
        { mode: '*.*=SourceFile'},
        //The second converter creates a 800x600 thumbnail
        { mode: '*.*=Thumbnail', thumbnailWidth: 800, thumbnailHeight: 600, 
            thumbnailJpegQuality: 60, thumbnailFitMode: 'Fit',
            //watermarked with the "Watermark.png" image
            thumbnailWatermark: 'Opacity=100;ImageUrl=../Images/Watermark.png;'
                + 'ImageWidth=155;ImageHeight=30;Position=BottomRight;'}],
                
    //Configure quality meter
    paneItem: {qualityMeter: { formats: '4 x 6,1800,1200,1.5;5 x 7,2100,1500,1.5;'
        +'8 x 10,3000,2400,1.5;16 x 20,4000,3200,2;30 x 20,6000,4000,2'}},
        
    //Set the "Uploader1_BeforeUpload" function as a beforeUpload event handler
    events: { beforeUpload: Uploader1_BeforeUpload }
})

//Render ActiveX/Java Uploader control
u.writeHtml();

var paperSize = '4x6';

//BeforeUpload event handler
function Uploader1_BeforeUpload() {

    var size = paperSize.split('x');
    var pixelWidth = size[1] * 300;
    var pixelHeight = size[0] * 300;
    
    //Get reference to the Uploader instance
    var uploader = $au.uploader('uploader1');
    
    //Add new converter
    uploader.converters().add();
    
    //The "count" method returns the number of converters actually contained in the collection
    var convertersCount = uploader.converters().count();
    
    //Get the newly created converter, which is the last in converters collection
    var converter = uploader.converters().get(convertersCount-1);
    
    //Specify converter settings
    converter.mode("*.*=Thumbnail");
    converter.thumbnailFitMode("Fit");
    converter.thumbnailWidth(pixelWidth);
    converter.thumbnailHeight(pixelHeight);
    converter.thumbnailJpegQuality("80");
}
</script>

upload.php:

PHP
<?php
require_once "ImageUploaderPHP/UploadHandler.class.php";

//Create UploadHandler instance
$handler = new UploadHandler();

//Set the "saveAllUploadedFiles" function as a callback function
//which is called when the whole upload session completes
$handler->setAllFilesUploadedCallback("saveAllUploadedFiles");

//Enable processing of ActiveX/Java Uploader requests
$handler->processRequest();

//Callback function set previously
//$uploadedFiles is an array of UploadedFile objects
//Each UploadedFile contains all the converted files and metadata related to one user-selected file
function saveAllUploadedFiles($uploadedFiles) {

    //Specify folders to save files to
    $absCatalogPath = realpath("../Catalog/") . "/";
    $absGalleryPath = realpath("../Gallery/") . "/";
    $absThumbnailsPath = realpath("../Gallery/Thumbnails/") . "/";

    //Iterate through all uploaded files
    foreach ($uploadedFiles as $uploadedFile)
    {
        //Get all converted files generated for current uploaded file
        $convertedFiles = $uploadedFile->getConvertedFiles();
        
        //Get the first converted file 
        //accordingly to our converters set it is a source file
        $sourceFile = $convertedFiles[0];
        
        //Save this converted file with SourceFileName name
        $sourceFile->moveTo($absCatalogPath . "/" . $uploadedFile->getSourceName());
        
        //Get the second converted file 
        //accordingly to our converters set it is a watermarked thumbnail
        $thumbnail1 = $convertedFiles[1];
        
        //Save this converted file with SourceFileName.jpg name
        $thumbnail1->moveTo($absGalleryPath . "/" . $uploadedFile->getSourceName() . ".jpg");
        
        //Get the third converted file 
        //accordingly to our converters set it is a thumbnail configured at run-time
        $thumbnail2 = $convertedFiles[2];
        
        //Save this converted file with SourceFileName.jpg name 
        $thumbnail2->moveTo($absThumbnailsPath . "/" . $uploadedFile->getSourceName() . ".jpg");
    }
}
?>

Complete Code of Application with ActiveX/Java Uploader 6.5

index.html:

JavaScript
<script type="text/javascript" src="scripts/iuembed.js">  </script>
<script type="text/javascript">

//Specify the id of this ActiveX/Java Uploader instance, and size of ActiveX/Java Uploader control
var iu = new ImageUploaderWriter("ImageUploader1", 650, 450);

//Apply license keys, semicolon is used to separate several keys
iu.addParam("LicenseKey", "XXXXX-XXXXX-XXXXX-XXXXX-XXXXX;YYYYY-YYYYY-YYYYY-YYYYY-YYYYY");

//Private-label-specific settings
//Set code base and minimum required version of activeX control
iu.activeXControlCodeBase = "ImageUploader6.cab";
iu.activeXControlVersion = "6,5,1,0";

//Set code base, filename and minimum required version of java control
iu.javaAppletCodeBase = "Scripts/";
iu.javaAppletJarFileName = "ImageUploader6.jar";
iu.javaAppletVersion = "6.5.1.0";

//Specify one-pane layout
iu.addParam("PaneLayout", "OnePane");

//Define custom "Upload" button
iu.addParam("ButtonSendImageFormat", "Width=82;Height=25;UrlDisabled='../Images/UploadDisabled.png';"
    + "UrlNormal='../Images/UploadNormal.png';UrlNormalFocused='../Images/UploadNormalFocused.png';"
    + "UrlHover='../Images/UploadHover.png';UrlHoverFocused='../Images/UploadHoverFocused.png';"
    + "UrlPressed='../Images/UploadPressed.png'");

//Specify a page containing server code to handle uploaded files
iu.addParam("Action", "upload.php");

//Configure the first thumbnail settings
iu.addParam("UploadThumbnail1FitMode", "Fit");
iu.addParam("UploadThumbnail1Width", "800");
iu.addParam("UploadThumbnail1Height", "600");
iu.addParam("UploadThumbnail1JpegQuality", "60");

//Set thumbnail watermark
iu.addParam("UploadThumbnail1Watermark", "opacity=100;ImageUrl=../Images/Watermark.png;"
    + "ImageWidth=155;ImageHeight=30;Position=BottomRight;");
    
//Configure quality meter
iu.addParam("QualityMeterFormats", "4 x 6,1800,1200,1.5;5 x 7,2100,1500,1.5;"
    + "8 x 10,3000,2400,1.5;16 x 20,4000,3200,2;30 x 20,6000,4000,2");
    
//Set the "Uploader1_BeforeUpload" function as a beforeUpload event handler
iu.addEventListener("BeforeUpload", "ImageUploader1_BeforeUpload");

//Render ActiveX/Java Uploader control
iu.writeHtml();

var paperSize = '4x6';

//BeforeUpload event handler
function ImageUploader1_BeforeUpload() {

    var size = paperSize.split('x');
    var pixelWidth = size[1] * 300;
    var pixelHeight = size[0] * 300;
    
    //Get reference to the ActiveX/Java Uploader instance
    imageUploader1 = getImageUploader('ImageUploader1');
    
    //Specify the second converter settings
    imageUploader1.setUploadThumbnail2FitMode("Fit");
    imageUploader1.setUploadThumbnail2Width(pixelWidth);
    imageUploader1.setUploadThumbnail2Height(pixelHeight);
    imageUploader1.setUploadThumbnail2JpegQuality("80");
}
</script>

upload.php:

PHP
<?php

//Specify folders to save files to
$absCatalogPath = realpath("../Catalog/") . "/";
$absGalleryPath = realpath("../Gallery/") . "/";
$absThumbnailsPath = realpath("../Gallery/Thumbnails/") . "/";

//Get number of uploaded files
$fileCount = $_POST ["FileCount"];

//Iterate through all uploaded files
for ($i = 1; $i <= $fileCount; $i++)
{

    //Get the name of source file field
    $sourceFileField = "SourceFile_" . $i;
    
    //Check if the source file was uploaded
    if ($_FILES[$sourceFileField]['size']) {
    
        //Get name of the source file
        $fileName = $_FILES[$sourceFileField]['name'];
        
        //Save the source file with SourceFileName name
        move_uploaded_file($_FILES[$sourceFileField]['tmp_name'], $absCatalogPath . "/" . $fileName);
    }

    //Get the name of the first thumbnail field
    $thumbnail1Field = "Thumbnail1_" . $i;
    
    //Check if the first thumbnail was uploaded
    if ($_FILES[$thumbnail1Field]['size'])
    
        //Save the first thumbnail with SourceFileName.jpg name
        move_uploaded_file($_FILES[$thumbnail1Field]['tmp_name'], $absGalleryPath . $fileName . ".jpg");

    //Get the name of the second thumbnail field
    $thumbnail2Field = "Thumbnail2_" . $i;
    
    //Check if the second thumbnail was uploaded
    if ($_FILES[$thumbnail2Field]['size'])
    
        //Save the second thumbnail with SourceFileName.jpg name
        move_uploaded_file($_FILES[$thumbnail2Field]['tmp_name'], $absThumbnailsPath . $fileName . ".jpg");
}
?>

See Also

Manual