I have values inside an XMLList in Actionscript. Need to send these values to the DB and update it.
My actionscript code is as follows:
public static function saveUserPermList():void {
var ht:HTTPService = new HTTPService();
ht.url = Config.getServerURL();
ht.method = URLRequestMethod.POST;
//ht.resultFormat = "e4x";
ht.contentType = "text/xml";
ht.request["action"] = "saveUserPermListXML";
ht.request["pdata"] = Application.application.userPermListModel.toString();
ht.addEventListener(ResultEvent.RESULT,AdminUserList.saveUserPermListResult);
ht.send();
}
public static function saveUserPermListResult(e:ResultEvent):void {
trace(e);
}
How can I send the XMLList data to PHP? Should I add a toString() to it?
Also what should be the contentType in Flex.
How can I catch this inside PHP, pl let me know, trying to use, this way,
if($user -> isAllowedAccess()) {
header("Content-type:text/xml");
$postedData = $_POST["pdata"];
// $xmldoc = simplexml_load_string($POST['pdata']);
// echo($xmldoc);
}
No luck. Pl let me know.
The method property of HTTPService should probably be "POST", and the contentType for the request itself should probably be "application/x-www-form-urlencoded".
On the PHP side, $_POST["pdata"] would then be a string containing XML markup. You could either save that in a database directly, or first parse it into XML (via SimpleXML or DOMDocument) and do something with the contained data.
PS: I've just found this answer that seems to shed some light on the internal behavior of the HTTPService class.
Related
I try to implement a webservice Client using php and got stuck...
I'm using an existing webservice called metadataservice with a known wsdl.
I'll use wsdl2phpgenerator to create the php classes for the datatypes and the Service itself.
Using one of the Webservice Methods (addMetadataToObject), I have to send an Array of objects to the Server.
There is a base class:
class AssetInfo
{
public $dataFieldId = null;
public $dataFieldName = null;
public $dataFieldTagName = null;
public function __construct($dataFieldId, $dataFieldName, $dataFieldTagName)
{
$this->dataFieldId = $dataFieldId;
$this->dataFieldName = $dataFieldName;
$this->dataFieldTagName = $dataFieldTagName;
}
}
and a derived class Holding string values (there are also other derived classes for Longs etc.):
class StringAssetInfo extends AssetInfo
{
public $value = null;
public function __construct($dataFieldId, $dataFieldName,$dataFieldTagName, $value)
{
parent::__construct($dataFieldId, $dataFieldName, $dataFieldTagName);
$this->value = $value;
}
}
For the call of Metadataservice->addMetadataToObject there is also a addMetadataToObject defined:
class addMetadataToObject
{
public $objectId = null;
public $objectType = null;
public $assetInfos = null;
public function __construct($objectId, $objectType)
{
$this->objectId = $objectId;
$this->objectType = $objectType;
}
}
The property $assetInfos should hold an Array of AssetInfo objects. wdsl2phpgenerator creates a class for my MetadataService which is derived from SoapClient. This class provides all the avialable Methods for this Service. Here I only show the addMetadataToObject Method:
public function addMetadataToObject(addMetadataToObject $parameters)
{
return $this->__soapCall('addMetadataToObject', array($parameters));
}
My Code does:
// Define the Data
$ServiceOptions = [];
$AssetInfos = [];
$AssetInfo = new StringAssetInfo(2, "TitleName", "TitleName","New Title Name);
array_push($AssetInfos, $AssetInfo);
// Create the Service
$Service = new MetadataService($ServiceOptions, getServiceWSDL($Options, "MetadataService"));
$Service->__setSoapHeaders(getGalaxySoapHeader($Options));
$NewMetaData = new addMetadataToObject(61755, "ASSET");
$NewMetaData->assetInfos = $AssetInfos;
// Call the Service
$failedAssets = $Service->addMetadataToObject($NewMetaData);
The call throws a Soap Exception that a value could not be extracted. Which makes me wonder. I started to monitor the traffic to the Soap Server using wireshark and yes....there is no value anymore as defined in the StringAsset Info Class...Here is the Soap Body shown by wireshark:
<SOAP-ENV:Body>
<ns1:addMetadataToObject>
<objectId>61755</objectId>
<objectType>ASSET</objectType>
<assetInfos>
<dataFieldId>2</dataFieldId>
<dataFieldName>TitleName</dataFieldName>
<dataFieldTagName>TitleName</dataFieldTagName>
</assetInfos>
</ns1:addMetadataToObject>
Id</SOAP-ENV:Body>
I would expect a tag New Title Name. But ist gone. When I checked the $NewMetaData object in my Code or the $Parameter object in $Service->addMetadataToObject I can see that the property "Value" is defined and set.
For me it seems, that the call to
return $this->__soapCall('addMetadataToObject', array($parameters));
only accepts the properties of the base class AssetInfo but not the properties from the derived class StringAssetInfo.
I also changed the Code to use an Array (instead of an object) for $AssetInfo:
$AssetInfo = array("dataFieldId"=>2, "dataFieldName"=>"TitleName","dataFieldTagName"=>"TitleName, "value"=>"New Title Name");
But without any change. It seems that we have here some Kind of runtime type conversion or type alignment but I can't see the reason of this. I'm still new to webservices at all and also on php (however I have to use both for the Moment:-)
Can anybody comment or give me a hint what's happening here?
I was able to realize it by using Arrays and soapvars, Please note my comments in the code:
$ServiceOptions = [];
$AssetInfos = [];
// I have to use an Array because the Server depends on the order of the properties. I wasn't able to define expected order using the existing objects but with arrays
$AssetInfo = array("dataFieldId"=>2, "dataFieldName"=>"TitleName","dataFieldTagName"=>"TitleName, "value"=>"New Title Name");
// instead of pushing the Array directly, I create an instance of an SoapVar, pass the Array as data and set the Encoding, the expected type and the Namespace uri
array_push($AssetInfos, new SoapVar($AssetInfo, SOAP_ENC_OBJECT, "StringAssetInfo", "http://metadataservice.services.provider.com"));
array_push($AssetInfos, $AssetInfo);
// Create the Service
$Service = new MetadataService($ServiceOptions, getServiceWSDL($Options, "MetadataService"));
$Service->__setSoapHeaders(getGalaxySoapHeader($Options));
$NewMetaData = new addMetadataToObject(61755, "ASSET");
$NewMetaData->assetInfos = $AssetInfos;
// Call the Service
$failedAssets = $Service->addMetadataToObject($NewMetaData);
This produced the expected Output in the Soap Body (and also added some namespaces to the Soap envelope
<SOAP-ENV:Body>
<ns1:addMetadataToObject>
<objectId>61755</objectId>
<objectType>ASSET</objectType>
<assetInfos xsi:type="ns1:StringAssetInfo">
<dataFieldId>2</dataFieldId>
<dataFieldName>TitleName</dataFieldName>
<dataFieldTagName>TitleName</dataFieldTagName>
<value>New Titel Name 1146</value>
</assetInfos>
</ns1:addMetadataToObject>
</SOAP-ENV:Body>
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 have a Web Service in PHP that reads a XML file of albums, and simply returns it as a string to my ASP.NET web form. Now, the sending and receiving is fine.
The problem is that now I want to parse this data in order to save the new albums and other information (such as Genre, Artist, and Songs) to my database attached to my ASP.NET web site, and it's giving me a headache.
Here's the code of the Web Service client:
protected void btnGetAlbums_Click(object sender, EventArgs e)
{
phpPublisher.albums albums = new albums();
string result = albums.getAlbums();
if (String.IsNullOrEmpty(result))
{
txtResult.Text = "No albums found";
}
else
{
// parse XML
var xml = XElement.Parse(result);
var albumList = xml.Descendants("Albums")
.Elements("Album");
if (albumList.Count() > 0)
{
txtResult.Text = "Has at least 1 album!";
}
}
}
This is just very 'demo'-ish code for now, I haven't even tackled the database inserting and all that because I can't even parse the data.
If I output the xml variable in my txtResult textbox, it shows:
<Albums> <Album> <AlbumTitle>Stripped</AlbumTitle> <AlbumArtist>Christina Aguilera</AlbumArtist> <AlbumGenre>Pop</AlbumGenre> <AlbumSongs> <AlbumSong>Beautiful</AlbumSong> </AlbumSongs> </Album></Albums>
All in one line, which is incredibly frustrating. I don't know if it can even parse the data like this...what I'd like to do in the PHP side is just send a XML data object that ASP.NET could read. Is this possible?
Here's what my PHP web service function looks like (it returns a string).
function getAlbums() {
$dataSource = "albums.xml";
if(file_exists($dataSource)) {
$xml = simplexml_load_file($dataSource);
$dom = new DOMDocument('1.0');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($xml->asXML());
return $dom->saveXML();
} else {
return null;
}
}
Any help is appreciated. Thank you.
P.S. When I execute albumList.Count(), it returns 0, which means the list contains no elements, so there's a parsing error somewhere.
try
var albumList = xml.Elements("Album");
i have a problem passing ByteArray from flash (as3) to amfphp to save an image.
With old version of amfphp, all worked in the past… now, with new version i have many problem.
I'm using version 2.0.1 and the first problem is that i have to do this, for access to my info:
function SaveAsJPEG($json)
{
$string = json_encode($json);
$obj = json_decode($string);
$compressed = $obj->{'compressed'};
}
in the past i wrote only:
function SaveAsJPEG($json)
{
$compressed = $json['compressed'];
}
Anyway… now i can take all data (if i use " $json['compressed']" i receive an error) but i can't receive my ByteArray data.
From flash i write this:
var tempObj:Object = new Object();
tempObj["jpgStream "]= createBitStream(myBitmmapData); // return ByteArray
tempObj["compressed"] = false;
tempObj["dir"] = linkToSave;
tempObj["name"] = this.imageName;
So.. in my php class i receive all correct info, except "jpgStream" that seems "null".
Do you have any idea?
I think you get 'null' because of json_encode/decode. Try using
$data = (array) $json;
$compressed = $data['compressed'];
This may help http://www.silexlabs.org/amfphp/documentation/data-types/
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.