AsyncToken return basic string? - php

I'm trying to develop a Flex Mobile / PHP application, and I'm running into some trouble with the AsyncToken... Does it not just return a basic string?
For example... I'm wanting to just return a simple string result from my request - right now, it's going to return a basic output string from the method that's implemented. The backend part works (PHP), I've done all of that... It's this that's giving me some problems:
import mx.rpc.AsyncResponder;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
protected function button_clickHandler(event:MouseEvent):void
{
loginResult.token = user_service.login();
loginResult.token.addResponder(new AsyncResponder(onResult,onFault));
}
public function onResult(event:ResultEvent, token:Object):void
{
// what would i do here??
}
public function onFault(event:FaultEvent,token:Object):void
{
txtResult.text = event.fault.faultDetail;
}
It's pretty straightforward - any suggestions, or recommendations would surely help! Thank you!

Easy enough. The ResultEvent#result property contains the value returned by the remote service. All you need to do is cast it to the right type (since it is an Object by default).
For instance, handling your service method that returns a String:
public function onResult(event:ResultEvent):void {
var s:String = event.result as String;
}
Same goes for other types:
var a:Array = event.result as Array;
Or even more complex custom classes:
var instance:MyClass = event.result as MyClass;
Note that this last example will only work with AMF remoting; you have to have the same class definition on the client side and on the server side; and you have to let them know of each other's existence by using the [RemoteClass(alias="net.riastar.MyClass")] metadata tag on your AS class definition. How you have to handle this on the server side depends on the language used there.

Related

Include simple fields based on context in Fractal

I am using the Fractal library to transform a Book object into JSON by using a simple transformer:
class BookTransformer extends \League\Fractal\TransformerAbstract
{
public function transform(Book $book)
{
return [
'name' => $book->getName()
// ...
];
}
}
And I am performing the transformation as follows.
$book = new Book('My Awesome Book');
$resource = new \League\Fractal\Resource\Item($book, new BookTransformer());
$fractal = new \League\Fractal\Manager();
$fractal->setSerializer(new \League\Fractal\Serializer\ArraySerializer());
$json = $fractal->createData($resource)->toJson();
This works great. However, I have certain fields on my Book object that should not always be included, because this depends on the context the transformation is done in. In my particular use case, the JSON returned to AJAX requests from my public website should not include sensitive information, while this should be the case when the data is requested from an admin backend.
So, let's say that a book has a topSecretValue field, which is a string. This field should not be included in one transformation, but should be included in another. I took a look at transformer includes, and played around with it, but this only works with resources. In my case, I need to somehow include different fields (not resources) for different contexts. I have been digging around and could not find anything in the Fractal library that could help me, but maybe I am missing something?
I came up with a working solution, but it is not the prettiest the world has ever seen. By having a BaseBookTransformer that transforms fields that should always be included, I can extend this transformer to add fields for other contexts, e.g. AdminBookTransformer or TopSecretValueBookTransformer, something like the below.
class AdminBookTransformer extends BookTransformer
{
public function transform(Book $book)
{
$arr = parent::transform($book);
$arr['author'] = $book->getTopSecretValue();
return $arr;
}
}
This works fine, although it is not as "clean" as using includes (if it were possible), because I have to actually use a different transformer.
So the question is: is there anything in Fractal that enables me to accomplish this in a simpler/cleaner way, or is there a better way to do it, be it the Fractal way or not?

How to get data back from a command bus?

I'm fairly new to domain driven design concepts and I've run into a problem with returning proper responses in an API while using a command bus with commands and command handlers for the domain logic.
Let's say we’re building an application with a domain driven design approach. We have a back end and front end portion. The back end has all of our domain logic with an exposed API. The front end uses the API to make requests to the application.
We're building our domain logic with commands and command handlers mapped to a command bus. Under our Domain directory we have a command for creating a post resource called CreatePostCommand. It's mapped to its handler CreatePostCommandHandler via the command bus.
final class CreatePostCommand
{
private $title;
private $content;
public function __construct(string $title, string $content)
{
$this->title = $title;
$this->content= $content;
}
public function getTitle() : string
{
return $this->title;
}
public function getContent() : string
{
return $this->content;
}
}
final class CreatePostCommandHandler
{
private $postRepository;
public function __construct(PostRepository $postRepository)
{
$this->postRepository = $postRepository;
}
public function handle(Command $command)
{
$post = new Post($command->getTitle(), $command->getContent());
$this->postRepository->save($post);
}
}
In our API we have an endpoint for creating a post. This is routed the createPost method in a PostController under our Application directory.
final class PostController
{
private $commandBus;
public function __construct(CommandBus $commandBus)
{
$this->commandBus = $commandBus;
}
public function createPost($req, $resp)
{
$command = new CreatePostCommand($command->getTitle(), $command->getContent());
$this->commandBus->handle($command);
// How do we get the data of our newly created post to the response here?
return $resp;
}
}
Now in our createPost method we want to return the data of our newly created post in our response object so our front end application can know about the newly created resource. This is troublesome since we know that by definition the command bus should not return any data. So now we're stuck in a confusing position where we don't know how to add our new post to the response object.
I'm not sure how to proceed with this problem from here, several questions come to mind:
Is there an elegant way to return the post's data in the response?
Am I incorrectly implementing the Command/CommandHandler/CommandBus pattern?
Is this simply just the wrong use case for the Command/CommandHandler/CommandBus pattern?
First, notice that if we wire the controller directly to the command handler, we face a similar problem:
public function createPost($req, $resp)
{
$command = new CreatePostCommand($command->getTitle(), $command->getContent());
$this->createPostCommandHandler->handle($command);
// How do we get the data of our newly created post to the response here?
return $resp;
}
The bus is introducing a layer of indirection, allowing you to decouple the controller from the event handler, but the problem you are running into is more fundamental.
I'm not sure how to proceed with this problem from here
TL;DR - tell the domain what identifiers to use, rather than asking the domain what identifier was used.
public function createPost($req, $resp)
{
// TADA
$command = new CreatePostCommand($req->getPostId()
, $command->getTitle(), $command->getContent());
$this->createPostCommandHandler->handle($command);
// happy path: redirect the client to the correct url
$this->redirectTo($resp, $postId)
}
In short, the client, rather than the domain model or the persistence layer, owns the responsibility of generating the id of the new entity. The application component can read the identifier in the command itself, and use that to coordinate the next state transition.
The application, in this implementation, is simply translating the message from the DTO representation to the domain representation.
An alternative implementation uses the command identifier, and derives from that command the identities that will be used
$command = new CreatePostCommand(
$this->createPostId($req->getMessageId())
, $command->getTitle(), $command->getContent());
Named UUIDs are a common choice in the latter case; they are deterministic, and have small collision probabilities.
Now, that answer is something of a cheat -- we've really only demonstrated that we don't need a result from the command handler in this case.
In general, we would prefer to have one; Post/Redirect/Get is a good idiom to use for updating the domain model, but when the client gets the resource, we want to make sure they are getting a version that includes the edits they just made.
If your reads and writes are using the same book of record, this isn't a problem -- whatever you read is always the most recent version available.
However, cqrs is a common architectural pattern in domain driven design, in which case the write model (handling the post) will redirect to the read model -- which is usually publishing stale data. So you may want to include a minimum version in the get request, so that the handler knows to refresh its stale cache.
Is there an elegant way to return the post's data in the response?
There's an example in the code sample you provided with your question:
public function createPost($req, $resp)
Think about it: $req is a representation of the http request message, which is roughly analogous to your command, and $resp is essentially a handle to a data structure that you can write your result into.
In other words, pass a callback or a result handle with your command, and let the command handler fill in the details.
Of course, that depends on your bus supporting callbacks; not guaranteed.
Another possibility, which doesn't require changing the signature of your command handler, is to arrange that the controller subscribes to events published by the command handler. You coordinate a correlation id between the command and the event, and use that to pull up the result event that you need.
The specifics don't matter very much -- the event generated when processing the command could be written to a message bus, or copied into a mailbox, or....
I am using this approach and I am returning command results. However, this is a solution which works only if the command handlers are part of the same process. Basically, I'm using a mediator, the controller and the command handler get an instance of it (usually as a constructor dependency).
Pseudo code controller
var cmd= new MyCommand();
var listener=mediator.GetListener(cmd.Id);
bus.Send(cmd);
//wait until we get a result or timeout
var result=listener.Wait();
return result;
Pseudo code command handler function
var result= new CommandResult();
add some data here
mediator.Add(result,cmd.Id);
That's how you get immediate feedback. However, this shouldn't be used to implement a business process.
Btw, this has nothing to do with DDD, it's basically a message driven CQS approach which can be and it is used in a DDD app.

Mockery: Testing chained method calls with different return values (here: Symfony ProcessBuilder)

I'm trying to test a method that creates 2+ Process objects (also see API docs) using Symfony's ProcessBuilder and I've run into problems when trying to return different mock process objects. In fact, I'm a bit unsure about whether Mockery can even do this.
Is it possible to choose the value in Mockery's andReturn() based on the call chain of an object (including arguments)?
Ideally I'm looking for something like this:
<?php
$processBuilderMock
->shouldReceive('setPrefix("test")->add("-f")->getProcess')
->andReturn($testProcess);
Full example:
The following code creates a file /tmp/dummy if it does not exist. It uses the two commands test -f /tmp/dummy and touch /tmp/dummy for that (I know it's a dumb example).
<?php
class Toggler
{
public function toggleFile(ProcessBuilder $builder)
{
$testProcess = $builder
->setPrefix('test')->setArguments(array('-f', '/tmp/dummy'))
->getProcess();
$testProcess->run();
if (!$testProcess->isSuccessful()) { // (a)
$touchProcess = $builder
->setPrefix('touch')->setArguments(array('/tmp/dummy'))
->getProcess();
$touchProcess->run();
return $touchProcess->isSuccessful(); // (b)
} else {
// ...
}
}
}
To test all cases, I need to be able to mock the Process objects for the corresponding commands test and touch (here: $testProcess and $touchProcess). Ideally, the test code for this would look like this:
<?php
public function testToggleFileFileDoesNotExist()
{
$testProcess = \Mockery::mock('\Symfony\Component\Process\Process');
$testProcess->shouldReceive('isSuccessful')->andReturn(false); // (a)
$testProcess->shouldReceive('run');
$touchProcess = \Mockery::mock('\Symfony\Component\Process\Process');
$touchProcess->shouldReceive('isSuccessful')->andReturn(false); // (b)
$touchProcess->shouldReceive('run');
$builder = \Mockery::mock('\Symfony\Component\Process\ProcessBuilder');
$builder->shouldReceive('setPrefix("test")->getProcess')->andReturn($testProcess); // (c) Doesn't work!
$builder->shouldReceive('setPrefix("touch")->getProcess')->andReturn($touchProcess); // (c) Doesn't work!
$toggler = new Toggler();
$this->assertTrue($toggler->toggleFile($builder)); // see (b)
}
However, since Mockery does not allow arguments in the call chain, I'm a bit lost on how to test such a scenario. Any ideas?
This is slightly terrible, but you could try entering each step of the call chain separately and having it return the mock $builder. Which process is returned at the end would depend on the order of the calls.
$builder->shouldRecieve('setPrefix')->with('test')->andReturn($builder);
$builder->shouldRecieve('setPrefix')->with('touch')->andReturn($builder);
$builder->shouldRecieve('getProcess')
->andReturnValues(array($testProcess, $touchProcess));
This feels very messy, but it's the only way I've been able to find so far. (If you came up with anything better since posting this, I'd be curious to see.)

Issue passing element into method

For my own amusement, I am creating a XML reader class that utilizes PHP's SimpleXMLElement class. Eventually I will port this over to CodeIgniter as a library so I can utilize it in future applications. However, for now I am testing it using vanilla PHP. My end goal is to be able to traverse XML documents. For now, I am looking at this feed: http://rubygems.org/gems/sass/versions.atom.
The issue
I am having difficulties passing information into my own count() method. Here is the method:
public function count($element) {
$this->element = $element;
return $this->xml->element->count();
}
The idea of the method above is to allow anyone to pass in an object and it would return an int that identifies the number of children that particular element has. Normally, this would work:
$xml->title->count(); // returns 1, for example
What has been Tried
echo $xml->count('entry'); // always results in 0
public function count($element) {
return $this->xml->$element->count();
}
echo $xml->count('entry'); // still results in 0
echo $xml->count($xml->entry); // Undefined property
The Question
What is the correct approach to doing this? Any guidance would be appreciated! Here is the class in its entirety: http://pastebin.com/VjhjGcaR
Having the count() method like:
public function count($element) {
return $this->xml->$element->count();
}
And using it like:
echo $xml->count('entry');
Will print 201 with the ATOM file in your example.
Did you really just try it with foo? If so, that explains the zero results.

Parse PHP Session in Javascript

I have recently gone into extending my site using node.js and have come to realisation I need a session handler for my PHP sessions. Now everything was cool and dandy and node.js reads the php sessions and can propogate it's own session with the php ones. I am using database sessions so the session data gets saved into a field in the database.
I have however found a slight problem. I am attempting to read the session data into node.js and it's really quite a strange string. I have been able to get the strucutre of each session variable down to:
'field_name'|'type':'length':'value';
Now on certain strings the value field can be missing on other strings the length can be missing (when a variable is Null). The type can also be more than b, s, i; it can also be N (NULL).
I had originally thought up of a huge translator for JS but this just somehow seems a very wrong way to do it.
Has anyone here tried to extract php session variables in JS before and is there any kind of script that could help? Maybe there is a formatting thing I can use on PHP side to make my life a lot easier in node.js?
Edit: the Schema looks like:
{ _id: { id: 'L:\u00c1\u009d\u008e\u00ad\u000e}<\u0002\u0000\u0000' }
, session_id: 'a2clfnjhopv1srs5k5elgbfjv5'
, user_id: 0
, session_data: 'logged|b:0;uid|i:0;server_key|N;AUTH_TIER2|b:0;email|s:0:"";cheese|s:6:"cheese";'
, active: 1
, expires: 1278920567
}
This is the mongo db record for a user session. The field needing to be translated is session_data. There is some kind of formatting error when pasting it in since stackoverflow wont format that as code when I try and make it for some reason.
I tried to JSONfy the field before but it lost it's types and didn't read Null entries etc so I stopped that
Thanks,
I'm relatively sure PHP uses the serialize and unserialize functions to handle session data.
There is a JavaScript implementation of unserialize in PHP.JS, you can find it here: http://phpjs.org/functions/unserialize
Here is a session_decode function based on the unserialize function of phpjs:
https://github.com/vianneyb/phpjs/blob/master/functions/var/session_decode.js
works for me!
Just to reply with the way I've found: force PHP to use JSON instead :
Use the class below, with session_set_save_handler to store data as JSON and let PHP still using his own system.
Link this class using this function at the beginning of each script you use session :
http://php.net/manual/ru/function.session-set-save-handler.php
PS : here the class use memcache to store JSON resulting object, on Node.JS, use a memcache object, and retrieve like this :
get the PHPSESSID from cookies
use that characters string to bring a key from memcached with "sessions/id" where id is the key and session just the string (see class below).
Now you should have only JSON in memcache, so it's becoming a simple game with Node.JS to work with.
PS : of course you can work with/improve this, you can also use this not only with memcache (a db for example)
<?php
/**
* This class is used to store session data with memcache, it store in json the session to be used more easily in Node.JS
*/
class memcacheSessionHandler{
private static $lifetime = 0;
private static $memcache = null;
public function __construct(){
self::$memcache = new Memcache();
self::$memcache->addServer('localhost', 11211);
}
public function __destruct(){
session_write_close();
self::$memcache->close();
self::$memcache = null;
}
public static function open(){
self::$lifetime = ini_get('session.gc_maxlifetime');
return true;
}
public static function read($id){
$tmp = $_SESSION;
$_SESSION = json_decode(self::$memcache->get("sessions/{$id}"), true);
$new_data = session_encode();
$_SESSION = $tmp;
return $new_data;
}
public static function write($id, $data){
$tmp = $_SESSION;
session_decode($data);
$new_data = $_SESSION;
$_SESSION = $tmp;
return self::$memcache->set("sessions/{$id}", json_encode($new_data), 0, self::$lifetime);
}
public static function destroy($id){
return self::$memcache->delete("sessions/{$id}");
}
public static function gc(){
return true;
}
public static function close(){
return true;
}
}
?>
I had the same problem. I needed to integrate php with node.js. I used js-php-unserialize to do this. The use is pretty straightforward.
var PHPUnserialize = require('php-unserialize');
console.log(PHPUnserialize.unserializeSession(yourData));
For example if you
var yourData = 'A|s:1:"B";userID|s:24:"53d620475e746b37648b4567";';
you will get this result:
{
A: 'B',
userID: '53d620475e746b37648b4567'
}

Categories