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;
}
Related
I'm trying to Verifying that requests originate from Office for the web by using proof keys
I have read this resource many times but still do not know how to implement it in PHP.
I tried the code below it didn't seem to solve the problem, I do not know what to do next.
Can someone give me a suggestion?
$rsa = new Crypt_RSA();
$modulus = new Math_BigInteger(base64_decode($modulus), 256);
$exponent = new Math_BigInteger(base64_decode($exponent), 256);
$rsa->loadKey(array('n' => $modulus, 'e' => $exponent));
$rsa->setPublicKey();
$publicKey = $rsa->getPublicKey();
I understand that verifying WOPI proof key is quite complicated to implement while extracting programming logic from their explanation in the document is challenging.
Unfortunately, I'm not a PHP developer. However, I'd like to share my production C# code in case it could help.
private async Task<bool> ValidateWopiProof(HttpContext context)
{
// Make sure the request has the correct headers
if (!context.Request.Headers.ContainsKey(WopiRequestHeader.PROOF) ||
!context.Request.Headers.ContainsKey(WopiRequestHeader.TIME_STAMP))
return false;
// TimestampOlderThan20Min
var timeStamp = long.Parse(context.Request.Headers[WopiRequestHeader.TIME_STAMP].ToString());
var timeStampDateTime = new DateTime(timeStamp, DateTimeKind.Utc);
if ((DateTime.UtcNow - timeStampDateTime).TotalMinutes > 20)
return false;
// Set the requested proof values
var requestProof = context.Request.Headers[WopiRequestHeader.PROOF];
var requestProofOld = String.Empty;
if (context.Request.Headers.ContainsKey(WopiRequestHeader.PROOF_OLD))
requestProofOld = context.Request.Headers[WopiRequestHeader.PROOF_OLD];
// Get the WOPI proof info from Wopi discovery
var wopiProofPublicKey = await _wopiDiscovery.GetWopiProof();
// Encode the values into bytes
var accessTokenBytes = Encoding.UTF8.GetBytes(context.Request.Query["access_token"].ToString());
var hostUrl = GetAbsolouteUrl(context);
var hostUrlBytes = Encoding.UTF8.GetBytes(hostUrl.ToUpperInvariant());
var timeStampBytes = BitConverter.GetBytes(Convert.ToInt64(context.Request.Headers[WopiRequestHeader.TIME_STAMP])).Reverse().ToArray();
// Build expected proof
List<byte> expected = new List<byte>(
4 + accessTokenBytes.Length +
4 + hostUrlBytes.Length +
4 + timeStampBytes.Length);
// Add the values to the expected variable
expected.AddRange(BitConverter.GetBytes(accessTokenBytes.Length).Reverse().ToArray());
expected.AddRange(accessTokenBytes);
expected.AddRange(BitConverter.GetBytes(hostUrlBytes.Length).Reverse().ToArray());
expected.AddRange(hostUrlBytes);
expected.AddRange(BitConverter.GetBytes(timeStampBytes.Length).Reverse().ToArray());
expected.AddRange(timeStampBytes);
byte[] expectedBytes = expected.ToArray();
return (VerifyProofKeys(expectedBytes, requestProof, wopiProofPublicKey.Value) ||
VerifyProofKeys(expectedBytes, requestProofOld, wopiProofPublicKey.Value) ||
VerifyProofKeys(expectedBytes, requestProof, wopiProofPublicKey.OldValue));
}
private string GetAbsolouteUrl(HttpContext context)
{
var url = $"{_wopiUrlService.ApiAddress.TrimEnd('/')}{context.Request.Path}{context.Request.QueryString}";
return url.Replace(":44300", "").Replace(":443", "");
}
private bool VerifyProofKeys(byte[] expectedProof, string proofFromRequest, string discoPublicKey)
{
using (RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider())
{
try
{
rsaProvider.ImportCspBlob(Convert.FromBase64String(discoPublicKey));
return rsaProvider.VerifyData(expectedProof, "SHA256", Convert.FromBase64String(proofFromRequest));
}
catch (FormatException)
{
return false;
}
catch (CryptographicException)
{
return false;
}
}
}
This implementation follows the document spec. For the method _wopiDiscovery.GetWopiProof(), I just get proof-key section from Wopi Discovery.
.
#Rachanee is your solution working? I have the same code but validation is failing.
You can find a WOPI Proof Validator in PHP, in this package: https://github.com/Champs-Libres/wopi-lib/
This package is a helper for integrating WOPI protocol in PHP applications.
It contains a WOPI Proof Validator service that you can use out of the box.
I have been following a flash tutorial online and I have created a simple flash interface. I am trying to retrieve data from my SQL database via a PHP file and display. I get the following error when I compile:
Error #1009: Cannot access a property or method of a null object reference
var variables1:URLVariables = new URLVariables();
var varSend1:URLRequest = new URLRequest("databaseCall.php");
varSend1.method = URLRequestMethod.POST;
varSend1.data = variables1;
var varLoader1:URLLoader=new URLLoader();
varLoader1.dataFormat = URLLoaderDataFormat.VARIABLES;
varLoader1.addEventListener(Event.COMPLETE,completeHandler1);
variables1.comType = "requestEntries";
varLoader1.load(varSend1);
function completeHandler1(event:Event):void{
if(event.target.data.returnBody ==""){
gbOutput_txt.text = "No data coming through";
} else{
gbOutput_txt.condenseWhite = true;
gbOutput_txt.htmlText = "" +event.target.data.returnBody;
}
}
My code exactly matches the code that is used within the tutorial. I have modified the php file to simply return "" so the issue almost definitely lies within the action script...I think :S The compiler falls over when he completeHandler1 function is called. What do you think could be causing this?
Thanks in advance.
You need to declare the completeHandler1 function before you attempt to use it anywhere else.
Here is your code modified to describe what I am talking about.
var variables1:URLVariables = new URLVariables();
var varSend1:URLRequest = new URLRequest("databaseCall.php");
varSend1.method = URLRequestMethod.POST;
varSend1.data = variables1;
function completeHandler1(event:Event):void{
if(event.target.data.returnBody ==""){
gbOutput_txt.text = "No data coming through";
} else{
gbOutput_txt.condenseWhite = true;
gbOutput_txt.htmlText = "" +event.target.data.returnBody;
}
}
var varLoader1:URLLoader=new URLLoader();
varLoader1.dataFormat = URLLoaderDataFormat.VARIABLES;
varLoader1.addEventListener(Event.COMPLETE,completeHandler1);
variables1.comType = "requestEntries";
varLoader1.load(varSend1);
Give this a try and let me know if it works.
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);
}
}
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
I'm using Actionscript 2.0 in combination with PHP, now I can make a call to my PHP file and receive data but apparently I have to use that data immediately, I cannot use it to fill my class variables.
This is what I want :
class user {
var lastname:String;
function user(in_ID:Number){
var ontvang:LoadVars = new LoadVars();
var zend:LoadVars = new LoadVars();
zend.ID = in_ID;
zend.sendAndLoad("http://localhost/Services/getUser.php", ontvang, "POST");
ontvang.onLoad = function(success:Boolean) {
if (success) {
lastname = ontvang.lastname;
} else {
lastname = 'error';
}
};
}
}
I've found out that this is a big issue in AS2, I found this post to work around it if you're loading XML data but I can't seem to get it to work with LoadVars :
http://www.actionscript.org/forums/showthread.php3?t=144046
Any help would be appreciated ..
When your onLoad handler is called, it is being called as if it were a member function of the LoadVars instance, and not your user instance.
There are several ways around this, one is to use Delegate.create() to create a function which will work as intended, for example:
import mx.utils.Delegate;
class user {
var lastname:String;
var ontvang:LoadVars;
function user(in_ID:Number){
ontvang = new LoadVars();
var zend:LoadVars = new LoadVars();
zend.ID = in_ID;
ontvang.onLoad = Delegate.create(this, onLoad);
zend.sendAndLoad("http://localhost/Services/getUser.php", ontvang, "POST");
};
}
function onLoad(success:Boolean) : Void
{
if (success) {
lastname = ontvang.lastname;
} else {
lastname = 'error';
}
}
}
Don't forget that the load is asynchronous - when you create one of your user objects, the member variables won't be immediately available. What you may need to do is let your user object be capable of signaling its readiness much like LoadVars does, (e.g. with a callback function provided by the caller) so that your app is driven by by these asynchronous events.