Saving a bytearray with php received from Flex Air app - apache-flex

I have an Air application with remote service in codeigniter.
I'm trying to save a bytearray that I received from the Air app
but when I save the data I get empty files with the correct filename.
So there must be something wrong with my bytearray or the way I save the data.
Does anyone have an idea what I'm doing wrong?
I've debugged the Arraycollection I sent and the bytearray is definitely in there.
public function uploadImage($image)
{
foreach($image as $img)
{
$file = $img['name'];
$data = new ByteArray($img['bytes']);
file_put_contents( $_SERVER['DOCUMENT_ROOT'] . '/uploads/test/' .$file, $data);
}
}

Ok for those who are interested in the solution, aparrently I just had to change this $data = new ByteArray($img['bytes']); into this $data = $img['bytes’]->data;

Related

PHPExcel different behavior on different systems

I have PHPExcel on localhost and on server.
When I try to read xlsx file on localhost - all ok, but when I try to read same file on server - all cells with cyrillic words are empty.
All systems have same PHPExcel and PHP versions.
What could be the problem?
Thanks!
The problem with this file is that it was created by an application that doesn't recognise case-sensitivity in filenames.
The rels table indicates that the Shared Strings table (where all the text string values for the workbook are stored) is called sharedStrings.xml, but the actual file in the zip is called SharedStrings.xml. A file generated by MS Excel itself uses the correct case in the filename, so I'm guessing that this file was created using some third-party tool or library. MS Excel is clearly more forgiving about case-sensitivity in filenames, allowing it to read the zip regardless.
I can probably fix this by using
$zip->getFromIndex(
$zip->locateName('sharedStrings.xml', ZIPARCHIVE::FL_NOCASE);
);
rather than
$zip->getFromName('sharedStrings.xml');
but it will take me a couple of days to implement the fix
EDIT
Somewhere around line 310 of the /PHPExcel/Reader/Excel2007.php file is the getFromZipArchive() method that can be changed to read:
private function getFromZipArchive($archive, $fileName = '')
{
// Root-relative paths
if (strpos($fileName, '//') !== false) {
$fileName = substr($fileName, strpos($fileName, '//') + 1);
}
$fileName = PHPExcel_Shared_File::realpath($fileName);
// Apache POI fixes
$contents = $archive->getFromIndex(
$archive->locateName($fileName, ZIPARCHIVE::FL_NOCASE)
);
if ($contents === false) {
$contents = $archive->getFromIndex(
$archive->locateName(substr($fileName, 1), ZIPARCHIVE::FL_NOCASE)
);
}
return $contents;
}
and will then be able to access the Shared String file case-insensitively

Mocking a GuzzleHttp response

How should I mock a Guzzle response properly. When testing a parser I'm writing, the test html is contained in files. In my PHPUnit tests I'm doing file_read_contents and passing the result into my method. Occasionally the HTML will link to a seperate file. I can mock this response like so:
public function testAlgo()
{
$mock = new MockAdapter(function() {
$mockhtml = file_get_contents($this->dir . '/HTML/authorship-test-cases/h-card_with_u-url_that_is_also_rel-me.html');
$stream = Stream\create($mockhtml);
return new Response(200, array(), $stream);
});
$html = file_get_contents($this->dir . '/HTML/authorship-test-cases/h-entry_with_rel-author_pointing_to_h-card_with_u-url_that_is_also_rel-me.html');
$parser = new Parser();
$parser->parse($html, $adaptor = $mock);
Then in my actual method, when I make the guzzle request this code works:
try {
if($adapter) {
$guzzle = new \GuzzleHttp\Client(['adapter' => $adapter]);
} else {
$guzzle = new \GuzzleHttp\Client();
}
$response = $guzzle->get($authorPage);
So obviously this isn't ideal. Does anyone know of a better way of doing this?
$html = (string) $response->getBody();
EDIT: I'm now using the __construct() methid to set up a default Guzzle Client. Then a using a second function that can be called by tests to replace the Client with a new Client that has the mock adapter. I'm not sure if this is the best way to do things.
You can use the MockPlugin API, like so:
$plugin = new MockPlugin();
$plugin->addResponse(__DIR__.'/twitter_200_response.txt');
The txt file then contains everything from your response, including headers.
There are also good approaches available here: http://www.sitepoint.com/unit-testing-guzzlephp/
Also there are articles found here: http://guzzle3.readthedocs.io/testing/unit-testing.html

Adobe AIR. Local network error

For example, in local network, when Adobe Air is reading files from local server (\\Server\storage\) and network will be in down for a second, Air becomes eat a lot of memory and it is increasing up to 1GB (while normal memory use is 100 kb or less).
Just reading file with File('file path on local server'); from unstable network can cause this error.
Have anybody seen that in projects?
private function init() : void
{
file = new File("\\Server\dragracing\results.txt");
fileStream = new FileStream();
fileStream.addEventListener( Event.COMPLETE, fileComplete );
fileStream.openAsync( file, FileMode.READ );
}
private function fileComplete( event : Event ):void
{
fileContents = fileStream.readMultiByte( fileStream.bytesAvailable, ISO_CS );
.....
}
]]>
Have you tried closing the FileStream in the fileComplete method? Call the close method to make that happen.
private function fileComplete( event : Event ):void
{
fileContents = fileStream.readMultiByte( fileStream.bytesAvailable, ISO_CS );
fileStream.close();
.....
}
Also, based on your code it does not appear that you are ever actually reading information in from the file. from the file; so it is not clear the complete method will ever execute. There are plenty of methods used to read information in using the FileStream class.

how to send byte array to server in flash builder (Flex 4)

I have a video file in my local system.I am using windows XP in my system. Now i want to send this video file byte array to server in Flash Builder (Flex 4). I am using PHP at server end.
How can i do this? Please guide
Thanks
Socket.writeBytes() will do what you need.
Via this link:
.
// serialization
var serializedSound:ByteArray;
serializedSound = serializeSound(sound);
serializedSound.position = 0;
// unserialization
var newSound:Sound = new Sound();
newSound.addEventListener(SampleDataEvent.SAMPLE_DATA, deserialize);
newSound.play();
function serializeSound(sound:Sound):ByteArray
{
var result:ByteArray = new ByteArray();
while( sound.extract(result, 8192) ){
result.position = result.length;
}
return result;
}
function deserialize(e:SampleDataEvent):void
{
for ( var c:int=0; c<8192; c++ ) {
if(serializedSound.bytesAvailable < 2) break;
e.data.writeFloat(serializedSound.readFloat());
e.data.writeFloat(serializedSound.readFloat());
}
}
Do you need just sending the bytearray to PHP or also getting the bytearray?
For sending the bytearray you can use Zend_AMF:
http://framework.zend.com/download/amf
It will handle all the conversion, and in php you will get the bytearray as a string through a variable (I use variable reference as: &$file to save some memory on calling of method)
Here is some code snippet it can help you:
Sending ByteArray to Zend_Amf
For getting the ByteArray you can use the FileReference load() method to get all the bytearray of a local file.
You do know that creating a ByteArray of the video in Flex is literally storing that video to memory right? Any kind of large or uncompressed video would use an enormous amount of client side memory which could cause errors if Flash hits its memory limit.
I don't think you're going about this the right way. What I recommend you do is instead just upload the video to the server which the server than then access the bytes within it. If you want to upload the video to the server, look at this tutorial here which shows how to upload the file from Flex and a PHP script to get and store the file: http://livedocs.adobe.com/flex/3/html/17_Networking_and_communications_7.html#118972
From here, PHP could then access the bytes if you are so inclined.
AS3 Code:
uploadURL = new URLRequest();
uploadURL.url = "upload.php?fileName=videotrack";
uploadURL.contentType = 'application/octet-stream';
uploadURL.method = URLRequestMethod.POST;
uploadURL.data = rawBytes;
urlLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, completeHandler);
urlLoader.load(uploadURL);
rawBytes is the byte array that you want to upload to the server.
PHP Code
$fileName = $_REQUEST['fileName'] . ".mp3";
$fp = fopen( $fileName, 'wb' );
fwrite( $fp, $GLOBALS[ 'HTTP_RAW_POST_DATA' ] );
fclose( $fp );
I've used a .mp3 extension because my byte array was data from a mp3 file, but you can set the extension to whatever type of file your byte array represents.

How can I send another variable with FileReference Upload?

I have a problem with the filereference class using the upload function.
I want to send the folderLocation variable with fileReference.upload().
Below I try to describe my strategy.
var folderLocation : String = "photos/myUniqueFolder/";
private var serverSideScript:String = "http://localhost/project/phpFlexMechanism/upload.php";
urlRequest = new URLRequest(serverSideScript);
fileReferenceList.addEventListener(Event.SELECT, fileSelectedHandler);
private function fileSelectedHandler(event:Event):void {
// upload the file to the server side script
fileReference.addEventListener(Event.COMPLETE, uploadCompleteHandler);
fileReference.upload(urlRequest);
}
In PHP I use this to get the the file and uploaded
$folder = $_POST['folder'];
$tempFile = $_FILES['Filedata']['tmp_name'];
$fileName = $_FILES['Filedata']['name'];
$fileSize = $_FILES['Filedata']['size'];
move_uploaded_file($tempFile, "../user/$folder/uploadImages/" . $fileName);
But how can I send the folder through the "upload reference"?
I would think that, since you FileReference needs a URLRequest, you would be able to piggy back that information through the URLRequest itself by using the flash.net.URLVariables object.
I've not had time to test this, but have you tried:
// put this right after you instantiate urlRequest;
var urlVars:URLVariables = new URLVariables();
urlVars.targetFolder = folderLocation;
urlRequest.method = "post";
urlRequest.data = urlVar;
That should let you do:
//replace your last line with these two.
$folder = $_REQUEST[ "targetFolder" ];
move_uploaded_file($tempFile, "../user/$folder/uploadImages/" . $fileName);
in PHP.
the easiest thing you can do is just send it through with a get header in the upload function
so the code looks as follows
private var serverSideScript:String = "http://localhost/project/phpFlexMechanism/upload.php?extraVar=value&extraVarB=value2";
fileReference.upload(urlRequest);
then in the php script you just use
$_GET['extraValue']
$_GET['valueVarB']

Resources