{"id":362,"date":"2011-09-18T01:09:20","date_gmt":"2011-09-18T00:09:20","guid":{"rendered":"http:\/\/www.aymericlamboley.fr\/blog\/?p=362"},"modified":"2014-11-01T15:02:29","modified_gmt":"2014-11-01T14:02:29","slug":"build-an-email-form-in-as3-and-php-with-infinite-attachements","status":"publish","type":"post","link":"http:\/\/www.aymericlamboley.fr\/blog\/build-an-email-form-in-as3-and-php-with-infinite-attachements\/","title":{"rendered":"Build an email form in AS3 and PHP with infinite attachements"},"content":{"rendered":"<p>Hey everyone!<br \/>\nI&#8217;m very pleased to attend to Aymeric&#8217;s blog, I hope it\u00a0will not be the first and last time!<\/p>\n<p>So, today, we will see how to build a simple, but efficient, email form with infinite attachement files in AS3 and PHP.<\/p>\n<p><!--more--><\/p>\n<p><strong>Setting up :<\/strong><\/p>\n<p>Before starting to code, we have to wonder how will be our tree structure, even it&#8217;s pretty simple. \u00a0On big projects, obviously bigger than this one, you can easily spend many hours on your tree structure.\u00a0Here is what I suggest :<\/p>\n<p><a href=\"http:\/\/www.aymericlamboley.fr\/blog\/wp-content\/uploads\/2011\/09\/arborescence.png\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-full wp-image-366\" src=\"http:\/\/www.aymericlamboley.fr\/blog\/wp-content\/uploads\/2011\/09\/arborescence.png\" alt=\"\" width=\"161\" height=\"227\" \/><\/a><\/p>\n<p>Simple, again. A &#8220;php&#8221; directory, with your php files (yeah, call me Cptn. Obvious), with a sub-directory where you will move your temporary uploaded files.<\/p>\n<p><strong>Let&#8217;s start coding!<\/strong><\/p>\n<p>On your stage, create 4 dynamic textfields :<\/p>\n<ol>\n<li>subject<\/li>\n<li>email<\/li>\n<li>message<\/li>\n<li>alert (we will fill it with some alert message)<\/li>\n<\/ol>\n<p>Create 2 buttons :<\/p>\n<ol>\n<li>_send (on click, we will send the email)<\/li>\n<li>_attachement (on click, we will add a new attachement)<\/li>\n<\/ol>\n<p>Here is the <em>Main<\/em> class file, it&#8217;s full of comments, so just read it \ud83d\ude42<\/p>\n<pre lang=\"actionscript3\" line=\"1\">package  {\r\n\timport flash.display.MovieClip;\r\n\timport flash.display.Sprite;\r\n\timport flash.display.StageScaleMode;\r\n\timport flash.display.StageAlign;\r\n\timport flash.events.Event;\r\n\timport flash.events.DataEvent;\r\n\timport flash.events.MouseEvent;\r\n\timport flash.events.ProgressEvent;\r\n\timport flash.net.FileReference;\r\n\timport flash.net.FileReferenceList;\r\n\timport flash.net.URLLoader;\r\n\timport flash.net.URLRequest;\r\n\timport flash.net.URLRequestMethod;\r\n\timport flash.net.URLVariables;\r\n\timport flash.net.URLLoaderDataFormat;\r\n\t\r\n\t\/**\r\n\t * ...\r\n\t * @author Pierrick Pluchon\r\n\t *\/\r\n\tpublic class Main extends Sprite{\r\n\r\n\t\t\/\/List of files \r\n\t\tprivate var pendingFiles:Vector.<FileReference>;\r\n\t\t\/\/List of unique filenames\r\n\t\tprivate var uniqueFileNames:Vector.<String>;\r\n\t\tprivate var myFileReferenceList:FileReferenceList;\r\n\t\t\/\/clip with filename\r\n\t\tprivate var attachedFile:MovieClip;\r\n\t\t\/\/\r\n\t\tprivate var attachedList:Vector.<MovieClip>;\r\n\t\tprivate var emailRequest:URLRequest;\r\n\t\tprivate var uploadRequest:URLRequest;\r\n\t\tprivate var variables:URLVariables;\r\n\t\tprivate var loader:URLLoader;\r\n\t\t\/\/if there is somes files attached\r\n\t\tprivate var filesAttached:Boolean = false;\r\n\t\t\/\/ Boolean : if the form is ready to be send (ie: no files still being uploaded)\r\n\t\tprivate var readyToSend:Boolean = true;\r\n\t\t\/\/Number of files currently uploaded\r\n\t\tprivate var nbFilesUploaded:uint = 0;\r\n\t\tprivate var nbCurrentFiles:uint;\r\n\t\tprivate var nbTotalFiles:uint;\r\n\t\t\r\n\t\t\/\/Max size for uploading files\r\n\t\t\/\/ 2Mo is the standard limit on many hosters\r\n\t\tprivate const MAX_SIZE:uint = 2000 * 1024; \r\n\t\t\r\n\t\t\r\n\t\tpublic function Main() {\r\n\t\t\t\/\/ constructor code\r\n\t\t\tif (stage) init();\r\n\t\t\telse this.addEventListener(Event.ADDED_TO_STAGE, init);\r\n\t\t}\r\n\t\t\r\n\t\tprivate function init(e:Event = null):void\r\n\t\t{\r\n\t\t\tif (e != null) this.removeEventListener(Event.ADDED_TO_STAGE, init);\r\n\t\t\tstage.align = StageAlign.TOP_LEFT;\r\n\t\t\tstage.scaleMode = StageScaleMode.NO_SCALE;\r\n\t\t\tuploadRequest = new URLRequest(\"php\/upload.php\");\r\n\t\t\tuploadRequest.method = URLRequestMethod.POST;\r\n\t\t\tmyFileReferenceList = new FileReferenceList();\r\n\t\t\t\/\/ Set a vector of whole filereference objects\r\n\t\t\tpendingFiles = new Vector.<FileReference>();\r\n\t\t\t\/\/Set a vector for whole files clip\r\n\t\t\tattachedList = new Vector.<MovieClip>();\r\n\t\t\t\/\/Set a vector for whole unique file names (returned by PHP);\r\n\t\t\tuniqueFileNames = new Vector.<String>();\r\n\t\t\tinitFormListeners();\r\n\t\t\t\/\/Set the focus on the first field : subject\r\n\t\t\tstage.focus = subject;\r\n\t\t}\r\n\t\t\r\n\t\tprivate function initFormListeners():void\r\n\t\t{\r\n\t\t\t\/\/Files manager events\r\n\t\t\tmyFileReferenceList.addEventListener(Event.SELECT, onSelect);\r\n\t\t\tmyFileReferenceList.addEventListener(Event.CANCEL, onCancel);\r\n\t\t\t\/\/User Interface Events\r\n\t\t\t_send.buttonMode = true;\r\n\t\t\t_send.addEventListener(MouseEvent.CLICK, sendHandler);\r\n\t\t\t_attachement.buttonMode = true;\r\n\t\t\t_attachement.addEventListener(MouseEvent.CLICK, browseFiles);\r\n\t\t}\r\n\t\t\r\n\t\tprivate function browseFiles(e:MouseEvent):void\r\n\t\t{\r\n\t\t\t\/\/ Open the browse window\r\n\t\t\tmyFileReferenceList.browse();\r\n\t\t}\r\n\t\t\r\n\t\tprivate function onSelect(e:Event):void\r\n\t\t{\r\n\t\t\tvar file:FileReference;\r\n\t\t\t\/\/Get the whole number of files\r\n\t\t\tnbTotalFiles = myFileReferenceList.fileList.length + nbCurrentFiles;\r\n\t\t\tfor (var i:uint = 0; i < myFileReferenceList.fileList.length; i++) \r\n\t\t\t{\r\n\t\t\t\tfile = FileReference(myFileReferenceList.fileList[i]);\r\n\t\t\t\tattachedFile = new AttachedFile();\r\n\t\t\t\tthis.addChild(attachedFile);\r\n\t\t\t\tattachedFile.x = _attachement.x;\r\n\t\t\t\tattachedFile.y = _attachement.y + _attachement.height + (attachedFile.height * nbCurrentFiles)\r\n\t\t\t\tattachedList.push(attachedFile);\r\n\t\t\t\taddPendingFile(file);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tprivate function addPendingFile(file:FileReference):void {\r\n\t\t\tnbCurrentFiles++;\r\n\t\t\tpendingFiles.push(file);\r\n\t\t\tif (file.size < MAX_SIZE)\r\n\t\t\t{\r\n\t\t\t\t\/\/Set events for tracking upload\r\n\t\t\t\tfile.addEventListener(Event.COMPLETE, completeHandler);\r\n\t\t\t\tfile.addEventListener(ProgressEvent.PROGRESS, progressHandler);\r\n\t\t\t\tfile.addEventListener ( DataEvent.UPLOAD_COMPLETE_DATA, onUploadComplete );\r\n\t\t\t\t\/\/And then start upload\r\n\t\t\t\tfile.upload(uploadRequest);\r\n\t\t\t\treadyToSend = false;\r\n\t\t\t} \r\n\t\t\t\telse \r\n\t\t\t{\r\n\t\t\t\t\/\/Then the file is too big\r\n\t\t\t\tvar id:uint = pendingFiles.indexOf(file);\r\n\t\t\t\tattachedList[id].filename.text = \"File too big\";\r\n\t\t\t\t\/\/Since the las element is too big, remove it\r\n\t\t\t\tpendingFiles.pop();\r\n\t\t\t\t\/\/ And replace it by null\r\n\t\t\t\tpendingFiles.push(null);\r\n\t\t\t\tnbFilesUploaded++;\r\n\t\t\t}\r\n\t\t}\r\n\t\t\t\t\r\n\t\tprivate function progressHandler(e:ProgressEvent):void\r\n\t\t{\r\n\t\t\t\/\/Get the id of the current FileRefence in pendingFiles\r\n\t\t\tvar id:uint = pendingFiles.indexOf(e.currentTarget);\r\n\t\t\tvar pct:uint = e.bytesLoaded * 100 \/ e.bytesTotal;\r\n\t\t\tattachedList[id].filename.text = \"Uploading :\" + String(pct)+\"%\";\r\n\t\t}\r\n\t\t\r\n\t\t\/\/Execute when a file has been uploaded\r\n\t\tprivate function completeHandler(e:Event):void\r\n\t\t{\r\n\t\t\t\r\n\t\t}\r\n\t\t\r\n\t\t\/\/Executes on server response after upload\r\n\t\tprivate function onUploadComplete(e:DataEvent):void\r\n\t\t{\r\n\t\t\tfilesAttached = true;\r\n\t\t\tnbFilesUploaded++;\r\n\t\t\tif (nbFilesUploaded == nbTotalFiles)\r\n\t\t\t{\r\n\t\t\t\treadyToSend = true;\r\n\t\t\t}\r\n\t\t\t\/\/Get the unique fileName returned by PHP\r\n\t\t\tvar response:URLVariables = new URLVariables(e.data);\r\n\t\t\tvar fileName:String = response.fileName;\r\n\t\t\t\/\/Get the id of the current FileRefence in pendingFiles\r\n\t\t\tvar id:uint = pendingFiles.indexOf(e.currentTarget);\r\n\t\t\t\/\/The set the filename in the textfield\r\n\t\t\tattachedList[id].filename.text = fileName;\r\n\t\t\tuniqueFileNames.push(fileName);\r\n\t\t}\r\n\t\t\r\n\t\tprivate function onCancel(e:Event):void\r\n\t\t{\r\n\t\t\t\r\n\t\t}\r\n\t\t\r\n\t\tprivate function sendHandler(e:MouseEvent):void\r\n\t\t{\r\n\t\t\tif (isValidForm())\r\n\t\t\t{\r\n\t\t\t\tif (readyToSend)\r\n\t\t\t\t{\r\n\t\t\t\t\t\/\/Set a new URLLoader \r\n\t\t\t\t\tloader= new URLLoader();  \r\n\t\t\t\t\temailRequest = new URLRequest(\"php\/send.php\");  \r\n\t\t\t\t\t\/\/ Set the method to POST (we will get these var with the $_POST  array in php\r\n\t\t\t\t\temailRequest.method = URLRequestMethod.POST;\r\n\t\t\t\t\tvariables = new URLVariables();  \r\n\t\t\t\t\tvariables.email = email.text;  \r\n\t\t\t\t\tvariables.message = message.text;  \r\n\t\t\t\t\tvariables.subject = subject.text;\r\n\t\t\t\t\tfor (var i:uint = 0; i < uniqueFileNames.length; i++)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\/\/for every pendingFiles\r\n\t\t\t\t\t\t\/\/set a new property to variables with the filename\r\n\t\t\t\t\t\tvariables[\"myUploadedFile\" + String(i)] = uniqueFileNames[i];\r\n\t\t\t\t\t}\r\n\t\t\t\t\temailRequest.data = variables;\r\n\t\t\t\t\tloader.addEventListener(Event.COMPLETE, onResponse);\r\n\t\t\t\t\tloader.load(emailRequest);  \r\n\t\t\t\t\t\r\n\t\t\t\t} \r\n\t\t\t\t\telse \r\n\t\t\t\t{\r\n\t\t\t\t\talert.text = \"Files are still uploading\";\r\n\t\t\t\t}\r\n\t\t\t} \r\n\t\t\t\telse \r\n\t\t\t{\r\n\t\t\t\talert.text = \"Please fill the form correctly\";\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t\/\/ On server response\r\n\t\t\/\/ Displays an alert depending on the server response\r\n\t\tprivate function onResponse(e:Event):void\r\n\t\t{\r\n\t\t\tif (e.target.data == \"1\") alert.text = \"Your mail has been sent\";\r\n\t\t\telse alert.text = \"An error occured while sending your mail\";\r\n\t\t\tresetForm();\r\n\t\t}\r\n\t\t\r\n\t\t\/\/Simply resets the form and removes files name\r\n\t\tprivate function resetForm():void\r\n\t\t{\r\n\t\t\tsubject.text=\"\";\r\n\t\t\tmessage.text=\"\";\r\n\t\t\temail.text=\"\";\r\n\t\t\t\/\/if(filesAttached)\r\n\t\t\t\/\/{\r\n\t\t\t\tvar i:uint=attachedList.length;\r\n\t\t\t\twhile(i--)\r\n\t\t\t\t{\r\n\t\t\t\t\tthis.removeChild(attachedList[i])\r\n\t\t\t\t}\r\n\t\t\t\/\/}\r\n\t\t}\r\n\t\t\r\n\t\t\/\/ Check if all field are filled\r\n\t\tprivate function isValidForm():Boolean\r\n\t\t{\r\n\t\t\tif (subject.text!=\"\" &#038;&#038; message.text!=\"\" &#038;&#038; isValidEmail(email.text)==true) return true;\r\n\t\t\telse return false;\r\n\t\t}\r\n\t\t\r\n\t\t\/\/Regexp for checking email\r\n\t\tfunction isValidEmail(email:String):Boolean {\r\n\t\t\tvar emailExpression:RegExp = \/^[a-z][\\w.-]+@\\w[\\w.-]+\\.[\\w.-]*[a-z][a-z]$\/i;\r\n\t\t\treturn emailExpression.test(email);\r\n\t\t}\r\n\r\n\r\n\t}\r\n\t\r\n}<\/pre>\n<p>Here is the main idea : for every selected files, we create a new FileReference object (thanks to the fileList property of FileReferenceList) and we upload it.<\/p>\n<p>The trick is simply to wait the \"upload complete event\" (aka \"DataEvent.UPLOAD_COMPLETE_DATA\") and get the unique filename generate by php. Then, we simply have to give to the other php file (aka \"send.php\") this unique filename.<br \/>\n<em>upload.php<\/em> (remember, it must be in your php directory):<\/p>\n<pre lang=\"php\" line=\"1\"><?php\r\n$mimeArray = array('application\/msword', 'application\/word', 'application\/pdf', 'image\/gif', 'image\/jpeg', 'image\/png');\r\n$file = $_FILES[\"Filedata\"]; \r\nif ( isset ( $file  ) ) \r\n{\r\n\t\/\/Get the mime type of the uploaded file\r\n\t$mime = mime_content_type($file ['tmp_name']);\r\n\tif(in_array($mime, $mimeArray) )\r\n\t{\r\n\t\t$fileName = getName($file ['name']); \r\n\t\tmove_uploaded_file ( $file ['tmp_name'], \"mailing\/\".$fileName); \r\n\t\techo \"fileName=\".$fileName;\r\n\t}\r\n}\r\n\r\n\/\/Return a unique filename\r\nfunction getName($name)\r\n{\r\n\t$filename=\"mailing\/\".$name;\r\n\tif(file_exists($filename))\r\n\t{\r\n\t\t\/\/If the filename exists, adding \"-\" in front of it\r\n\t\t$name = \"-\".$name;\r\n\t\treturn getName($name);\r\n\t}\r\n\t\treturn ($name);\r\n}\r\n?><\/pre>\n<p><em>send.php<\/em> (still in your php directory):<\/p>\n<pre lang=\"php\" line=\"1\"><?php\r\n\r\n\/\/ email fields: to, from, subject, and so on\r\n$to = \"youradress@domain.com\";\r\n$from = $_POST['email'];\r\n\r\n$message =  $_POST['message'];\r\n$headers = \"From: $from\";\r\n$subject = $_POST['subject'];\r\n \r\n\/\/ array with filenames to be sent as attachment\r\n$files = array(); \r\n foreach($_POST as $key => $value)\r\n {\r\n\tif(stristr($key, \"myUploadedFile\"))array_push($files, $value);\r\n }\r\n\/\/ boundary \r\n$semi_rand = md5(time()); \r\n$mime_boundary = \"==Multipart_Boundary_x{$semi_rand}x\"; \r\n \r\n\/\/ headers for attachment \r\n$headers .= \"\\nMIME-Version: 1.0\\n\" . \"Content-Type: multipart\/mixed;\\n\" . \" boundary=\\\"{$mime_boundary}\\\"\"; \r\n \r\n\/\/ multipart boundary \r\n$message = \"This is a multi-part message in MIME format.\\n\\n\" . \"--{$mime_boundary}\\n\" . \"Content-Type: text\/plain; charset=\\\"iso-8859-1\\\"\\n\" . \"Content-Transfer-Encoding: 7bit\\n\\n\" . $message . \"\\n\\n\"; \r\n$message .= \"--{$mime_boundary}\\n\";\r\n \r\n\/\/ preparing attachments\r\nfor($x=0;$x<count($files);$x++){\r\n\t$file = fopen(\"mailing\/\".$files[$x],\"rb\");\r\n\t$data = fread($file,filesize(\"mailing\/\".$files[$x]));\r\n\tfclose($file);\r\n\t$data = chunk_split(base64_encode($data));\r\n\t$message .= \"Content-Type: {\\\"application\/octet-stream\\\"};\\n\" . \" name=\\\"$files[$x]\\\"\\n\" . \r\n\t\"Content-Disposition: attachment;\\n\" . \" filename=\\\"$files[$x]\\\"\\n\" . \r\n\t\"Content-Transfer-Encoding: base64\\n\\n\" . $data . \"\\n\\n\";\r\n\t$message .= \"--{$mime_boundary}\\n\";\r\n}\r\n \r\n\/\/ send email\r\n$ok = @mail($to, $subject, $message, $headers);\r\n\r\n\/\/For every file attached\r\nforeach($files as  $file)\r\n{\r\n\t\/\/delete it\r\n\tunlink(\"mailing\/\".$file);\r\n}\r\nif ($ok) { \r\n\techo \"1\"; \r\n} else { \r\n\techo \"0\"; \r\n} \r\n \r\n?><\/pre>\n<p>On line 4, please set your correct email! Moreover, when you will upload your php files on the server, don't forget to set the chmod to 777 (read, write, execute) of you tmp directory (here, it's named \"mailing\"). Otherwise, you won't be able to upload any file!<\/p>\n<p>You can download the files <a href=\"http:\/\/www.aymericlamboley.fr\/blog\/wp-content\/uploads\/2011\/09\/emailForm_as3.zip\"><strong>here<\/strong><\/a>.<\/p>\n<p>Any question? comment below!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey everyone! I&#8217;m very pleased to attend to Aymeric&#8217;s blog, I hope it\u00a0will not be the first and last time! So, today, we will see how to build a simple, but efficient, email form with infinite attachement files in AS3 and PHP.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[4,44],"tags":[20,15,78,80,77,79],"_links":{"self":[{"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/posts\/362"}],"collection":[{"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/comments?post=362"}],"version-history":[{"count":51,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/posts\/362\/revisions"}],"predecessor-version":[{"id":1292,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/posts\/362\/revisions\/1292"}],"wp:attachment":[{"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/media?parent=362"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/categories?post=362"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/tags?post=362"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}