PHP/Actionscript 3 multiple file upload with progress indicator - php

I am trying to upload image files to my server using AS3 and PHP, and at the moment I am succeeding in uploading multiple files and restricting it to images only, but since I am new to Flash and AS3, I am finding it difficult to figure out how to have a loader bar show when the files are being uploaded, as well as executing a function once all files have been uploaded to go to a specified frame.
Here is my code thus far,
AS3:
import flash.net.FileReferenceList;
import flash.events.Event;
import flash.net.URLRequest;
import flash.net.FileReference;
var fileRef:FileReferenceList = new FileReferenceList();
fileRef = new FileReferenceList();
fileRef.browse(new Array( new FileFilter( "Images (*.jpg, *.jpeg, *.gif, *.png)", "*.jpg;*.jpeg;*.gif;*.png" )));
fileRef.addEventListener(Event.SELECT, fileSelectHandler);
var uploadURL:URLRequest = new URLRequest();
var uploadPhotoScript:String = "http://127.0.0.1/upload.php";
uploadURL.url = uploadPhotoScript;
function fileSelectHandler(event:Event):void {
for each(var fileToUpload:FileReference in fileRef.fileList){
uploadSingleFile(fileToUpload);
}
}
function uploadSingleFile(file:FileReference):void {
file.upload(uploadURL);
file.addEventListener(Event.COMPLETE, completeHandler);
}
function completeHandler(event:Event):void {
trace("upload complete");
}
PHP:
if(!empty($_FILES)){
$tmpfile = $_FILES['Filedata']['tmp_name'];
$targetfile = dirname(__FILE__) . '/' . $_FILES['Filedata']['name'];
move_uploaded_file($tmpfile, $targetfile);
}
my questions are,
1: how can I display a percentage or a uploading bar indicating the progress of the files being uploaded?
2: How can I launch a callback function after ALL files have been uploaded successfully?
3: How can I make the file browser appear on click, and not upon loading the flash file?
If you guys could post a link or two to good tutorials/resources or some advice, maybe even a code snippet or two that would be a great help as I am very new to Actionscript 3.
Thanx in advance!

To answer your questions in sequence:
1: You can use the ProgressEvent to display file upload progress. Since the File will be the dispatcher of the event, you can access the FileReference that has dispatched the progress as e.currentTarget inside the event, and from here you can access the unique properties of that file reference so you can accurately update the visual upload progress for that specific file. For example:
function uploadSingleFile(file:FileReference):void {
file.addEventListener(ProgressEvent.PROGRESS, onUploadProgress);
file.upload(uploadURL);
file.addEventListener(Event.COMPLETE, completeHandler);
}
function onUploadProgress(e:ProgressEvent):void
{
var f:FileReference = e.currentTarget as FileReference;
var fileName:String = f.name; //Now I know which file it is, I can update accordingly
var progress:Number = (e.bytesLoaded / e.bytesTotal) * 100; //shows percent, you might want to round this off using Math.round(number);
}
2: In order to launch a callback after ALL files are loaded, you'd do this by storing the number of files initially selected, then adding a callback specifically to each item and as they complete, decrement the total count until it is 0, at which time you'll know all files have been uploaded:
var totalFiles:int = 0;
function fileSelectHandler(event:Event):void {
for each(var fileToUpload:FileReference in fileRef.fileList){
++totalFiles;
uploadSingleFile(fileToUpload);
}
}
function uploadSingleFile(file:FileReference):void {
file.addEventListener(ProgressEvent.PROGRESS, onUploadProgress);
file.addEventListener(Event.COMPLETE, onFileUploadComplete);
file.upload(uploadURL);
file.addEventListener(Event.COMPLETE, completeHandler);
}
function onFileUploadComplete(e:Event):void
{
--totalFiles;
if(totalFiles == 0){
//All files have been uploaded
}
}
3: To make the browser appear onClick, simply add a MouseEvent.MOUSE_DOWN listener to an object or button of some kind, or even the stage, whatever. Like so:
var uploadButton:Button = new Button(); // Note this will require the Button component to be included in your library in flash CS
uploadButton.label = "Upload Files";
uploadButton.width = 150; //Or whatever;
uploadButton.x = (stage.stageWidth * .5) - (uploadButton.width * .5);
uploadButton.y = (stage.stageHeight * .5) - (uploadButton.height * .5);
stage.addChild(uploadButton);
uploadButton.addEventListener(MouseEvent.MOUSE_DOWN, onUploadClicked);
function onUploadClicked(e:MouseEvent):void
{
var fileRef:FileReferenceList = new FileReferenceList();
fileRef = new FileReferenceList();
fileRef.browse(new Array( new FileFilter( "Images (*.jpg, *.jpeg, *.gif, *.png)", "*.jpg;*.jpeg;*.gif;*.png" )));
fileRef.addEventListener(Event.SELECT, fileSelectHandler);
}
And finally about the tutorials etc, I'd recommend http://gotoandlearn.com for learning flash. I would also recommend just checking out the AS3 docs, as all of this nfo can be gleaned from just looking up the class in question, FileReferenceList. Please note I've done this code off of the top of my head in here so I had no IDE checking or anything. However it should work just fine. Hope this helps. :)
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/FileReferenceList.html
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/FileReference.html#upload()
http://adobe.com/go/as3lr

Related

Uploading An Image As A ByteArray to a Blob using AS3 & AMFPHP

I'm currently having a bit of an issue when I try to upload a photo taking using an iOS camera to a MySQL database using PHP and unfortunately have been unable to find the right help online.
Basically The User takes a photo on their iOS device and I take that raw MediaPromise and put it into a ByteArray. I then call a PHP function using AMFPHP to add the binary to a Blob in my database. But when I test the whole thing, it never seems to work. Could somebody maybe help me with this problem or at least point me in the right direction? It would be highly appreciated. Here's the code:
AS3:
var dataSource:IDataInput;
function imageSelected1(event:MediaEvent) {
var imagePromise:MediaPromise = event.data;
dataSource = imagePromise.open();
if( imagePromise.isAsync ) {
var eventSource:IEventDispatcher = dataSource as IEventDispatcher;
eventSource.addEventListener( Event.COMPLETE, onDataComplete );
}
else {
readMediaData();
}
}
// PHP Connection //
// Database //
var gw2:NetConnection = new NetConnection();
gw2.connect(connectiongoeshere);
// Responder //
var pictureresponder:Responder = new Responder(onpicture);
function onpicture(pictureobj:Object) {
gotoAndStop(1);
}
function onDataComplete( event:Event ):void {
readMediaData();
}
function readMediaData() {
var imageBytes:ByteArray = new ByteArray();
//dataSource.readBytes( imageBytes );
dataSource.readBytes(imageBytes);
gw2.call("class.setData", pictureresponder, imageBytes);
}
PHP:
function setData($ba) {
// Connecting to the database //
mysql_pconnect("hi", "hi", "hi");
mysql_select_db("hi");
$result = mysql_query("UPDATE users set profilepicture2 ='$ba->data' WHERE email= 'email#gmail.com'");
return $result;
}

Why after I uploaded an image to Azure I cannot access it?

I'm developing a Universal App for Windows Phone 8.1 but I'm using a PHP Page to get recognize some patterns from an Image that I uploaded to my service.
I have discovered that after I uploaded X image to Azure, I cannot use it. I'm using WebMatrix to develop my PHP Page and when I refresh it, it doesn't show me the images that I uploaded however when I try to publish something and I select the option: "Delete files on the remote server that are not on my computer." I can see my images. This is an example of my PHP code:
$uploaddir = getcwd();
$uploadfile = $uploaddir . "/" . basename($_FILES['userfile']['name']);
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
chmod($uploadfile, 0755);
$Test = new Display($_FILES['userfile']['name']);
echo '{"result": "' . $Test->getNumber($_REQUEST['color'], false) . '"}';
//unlink($uploadfile);
} else {
echo '{"result": "-1"}';
}
I'd like to know what could be my bug because I don't understand why I can access from the URL, too to the bit I cannot use it, maybe it's how I assigned the permissions but with or without the chmod, it doesn't change at all. I have even tried other hostings and the problem is the same when I enter the File Manager, there are only my PHP files and it doesn't allow me to manage the image.
This is my Windows Phone code to upload the Image if it's necessary:
byte[] ConvertBitmapToByteArray()
{
WriteableBitmap bmp = bitmap;
using (Stream stream = bmp.PixelBuffer.AsStream())
{
MemoryStream memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
}
public async Task<string> Upload()
{
try
{
using (var client = new HttpClient())
{
using (var content =
new MultipartFormDataContent())
{
byte[] data = ConvertBitmapToByteArray();
using (var stream = new InMemoryRandomAccessStream())
{
// encoder *outputs* to stream
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, stream);
// encoder's input is the bitmap's pixel data
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight,
(uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight, 96, 96, data);
await encoder.FlushAsync();
content.Add(new StreamContent(stream.AsStream()), "userfile", fileNewImage);
using (
var message =
await client.PostAsync("http://xplace.com/uploadtest.php", content))
{
var input = await message.Content.ReadAsStringAsync();
return input;
}
}
}
}
}
catch (Exception ex)
{
return null;
}
}
Thanks for your worthy knowledge and experience.
Create a blob storage account, and add a public container. In your action to save the file, store the file in you blob storage container. Then you can access the image as you would with any other image.
Here is a tutorial on Azure: http://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-blobs/
Also, you cannot create folders in a container, but you could use a naming convention on the blobrefname to create the idea of a container. Also, you can attach a domain to the cloud service if you want the URL to have a certain look.
READ YOUR QUESTION AGAIN - And it looks like it's more on the client side.
Here is what I usually do to attach a file to a MultipartFormDataContent:
MultipartFormDataContent content = new MultipartFormDataContent();
FileInfo info = new FileInfo(currFileLoc);
string contentMediaType = null;
//This is a Dictionary<string, string> that takes in the file
//extension, and returns the media type (e.g. "image/jpeg")
GlobalVariables.ApprovedMediaTypes.TryGetValue(
info.Extension.ToLower()
, out contentMediaType);
//If the dictionary doesn't return a result
//then it's not a supported file type
if (contentMediaType == null)
throw new Exception(
String.Format("The file \"{0}\" is an unsupported file type."
, info.Name));
ByteArrayContent currFile = new ByteArrayContent(File.ReadAllByte(currFileLoc));
currFile.Headers.ContentType = new MediaTypeWithQualityHeaderValue(contentMediaType);
content.Add(currFile, currFileLoc, currFileLoc);
The I make my call. Maybe you found another option with blob storage. Finally, if you load large files, you may want to look into uploading in chunks.

How to get blob image from mysql to as3 with php and addChild it in a way of getting byteArray and converting it to image?

How to get blob image from mysql to as3 with php and addChild it in a way of getting byteArray and converting it to image?
this is php:
if($RequestType == 'Select'){
while($row=mysql_fetch_assoc($results)){
$arrdata[]=$row;
}
foreach($arrdata as $key=>$value){
$output[$key] = $arrdata[$key];
$output[$key]['png'] = base64_encode($arrdata[$key]['png']);
}
header('Content-type: application/json');
print(json_encode($output));
i've already got something like this, but longer:
VBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAC4jAAAuIwF4pT92AAAYxUlEQVR42u1bB3Sc1ZWe8k/vvfem6aPpGk2RZjQzGrVRl6xiyZZkWS4gFxyDGyEsxjE1gVBTSGAdQg4keyCxF4NsY1pCDARsBwiE4pBsIJjN7nKWgM3eJ7/hTDhUIyJyNj7nHh3P/DP/f79373e/e98b0oUXXkj6/2ykfwLwTwAW58br1q0j9fX1UQcGBpgjw0Pcy
(In this I'm assuming you have already handled the HTTP request result)
To transform a base64 encoded image to a DisplayObject, you first need to decode the Base64 to a ByteArray then use the Loader class to load the image content, listening for the Loader's Event.COMPLETE event to dispatch. Once you've got that event Loader.content will contain a DisplayObject that you can add to the screen using addChild().
Example: (EDIT: Added an Array to keep track of loaded objects in order they were requested and altered function to calls to cope)
private var countLoadedImages:int = 0;//track how many images have loaded
private var arrImageLoaders:Array = new Array();//store loaders for call back
public function loadImageFromBase64(yourBase64:String):void
{
var base64:Base64Decoder = new Base64Decoder();
base64.decode(yourBase64);//decode your image
var data:ByteArray = base64.toByteArray();//convert to byte array
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoadComplete);
arrImageLoaders.push(loader.contentLoaderInfo);//add to array in order func was called
loader.loadBytes(data);//hand over to Loader
}
protected function onLoadComplete(event:Event):void
{
countLoadedImages++;
event.target.removeEventListener(Event.COMPLETE,onLoadComplete);
if (countLoadedImages == arrImageLoaders.length)
{
allImagesLoaded();
}
}
protected function allImagesLoaded():void
{
var contentLoaderInfo:LoaderInfo
for (var x:int = 0; x<arrImageLoaders.length; x++)
{
contentLoaderInfo = arrImageLoaders[x] as LoaderInfo;
addChild(contentLoaderInfo.content);
}
}

jQuery File Upload 'undefined' image url

I'm using a plugin called jQuery file upload to upload images to a page. Currently it uploads with the original image name as the file name (IMG_1234). I need a specific format for the image name on the server (eg 1.123456.jpg)
I found this PHP code that works for changing the image name:
class CustomUploadHandler extends UploadHandler
{
protected function trim_file_name($name, $type) {
$name = time()."_1";
$name = parent::trim_file_name($name, $type);
return $name;
}
}
When I upload an image, it is named correctly, but the link for the image preview is undefined. This prevents me from deleting the image via the plugin.
The variable data.url is undefined... If I go back to the original code that doesn't rename the image, everything works fine.
Has anyone had any experience with this plugin that could help? Thanks!
EDIT:
I've found part of the problem at least...the function to return the download link (which is also used for deletion) is giving the original file name, not the updated one. I am really new to PHP classes, so I'm not sure where the variable originates and how to fix it. I'd really appreciate any help I can get!
Here's the PHP code for that function:
protected function get_download_url($file_name, $version = null, $direct = false) {
if (!$direct && $this->options['download_via_php']) {
$url = $this->options['script_url']
.$this->get_query_separator($this->options['script_url'])
.'file='.rawurlencode($file_name);
// The `$file_name` variable is the original image name (`IMG_1234`), and not the renamed file.
if ($version) {
$url .= '&version='.rawurlencode($version);
}
return $url.'&download=1';
}
if (empty($version)) {
$version_path = '';
} else {
$version_url = #$this->options['image_versions'][$version]['upload_url'];
if ($version_url) {
return $version_url.$this->get_user_path().rawurlencode($file_name);
}
$version_path = rawurlencode($version).'/';
}
return $this->options['upload_url'].$this->get_user_path()
.$version_path.rawurlencode($file_name);
}
EDIT 2: I think it has something to do with 'param_name' => 'files', in the options. Anyone know what that does?
Fixed it by editing the trim_file_name function inside UploadHandler.php instead of extending the class in index.php.

php, data not updating after form post in zend?

this might be a bit of a novice question and here is my situation:
i have a upload form for uploading images. and in my editAction i do:
if ($request->isPost()) {
if (isset($_POST['upload_picture']) && $formImageUpload->isValid($_POST)) {
//here i will add the picture name to my database and save the file to the disk.
}
}
$picVal = $this->getmainPic(); // here i do a simple fetch all and get the picture that was just uploaded
$this->view->imagepath = $picVal;
what happens is that the newly uploaded picture doesn't show. I checked the database and the dick and the file is there.
im thinking the problem might be the order of the requests or something similar.
any ideas?
edit: another thing is that in order to make the new image come up i have to do a SHIFT+F5 and not only press the browser refresh button
edit2: more code
i first call the upload to disk function then if that returns success addthe file to the database
$x = $this->uploadToDiskMulty($talentFolderPath, $filename)
if($x == 'success'){
$model->create($data);
}
the upload function
public function uploadToDiskMulty($talentFolderPath, $filename)
{
// create the transfer adapter
// note that setDestiation is deprecated, instead use the Rename filter
$adapter = new Zend_File_Transfer_Adapter_Http();
$adapter->addFilter('Rename', array(
'target' => $filename,
'overwrite' => true
));
// try to receive one file
if ($adapter->receive($talentFolderPath)) {
$message = "success";
} else {
$message = "fail";
}
return $message;
}
If the picture only appears when you do SHIFT+F5 that means it's a caching problem. Your browser doesn't fetch the image when you upload it. Do you use the same file name?

Categories