diff --git a/README.md b/README.md index c977df1..32f0845 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,7 @@ $parser->xml($payload); // XML > Array $parser->yaml($payload); // YAML > Array $parser->querystr($payload); // Query String > Array $parser->serialize($payload); // Serialized Object > Array +$parser->bson($payload); // BSON > Array ``` #### Parse Input/Payload (PUT/POST) @@ -109,6 +110,58 @@ $parser->only('id', 'name', 'email'); // Only return value from the selected k $parser->except('password'); // Don't return values from the selected keys. ``` +#### Mask function +The mask function processes payload data using a configuration mask, thereby returning only a selected subset of the data. +It works just like the `only` method but with the added benefit of allowing you to specify a mask in the form of an array, +this means you can generate masks on-the-fly based on system and/or user defined conditions. + +##### Demo +###### Mask +Defining the mask, masks consist of basic array structure, for this particular example we have some rules for the data +to be returned they include: + - the title of the post + - all the body's for all the comments. + +```php +$mask = [ + 'post' => [ + 'title' => '*', + 'comments' => [ + 'body' => '*' + ] + ] +]; +``` + +###### Sample Payload +```json +{ + "post": { + "title": "Hello World", + "author": "John Smith", + "comments": [ + {"body": "This is a comment", "date": "2015-02-20"}, + {"body": "This is another comment", "date": "2015-05-09"} + ] + } +} +``` + +###### Output +This is the output generated as a result of applying the mask against the sample payload provided above. + +```php +$output = [ + 'post' => [ + 'title' => 'Hello World', + 'comments' => [ + ['body' => 'This is a comment'], + ['body' => 'This is another comment'] + ] + ] +]; +``` + #### Wildcards/Special Keys (*, %, :first, :last, :index[0], :item[0]) ```php $parser = new Parser(); diff --git a/src/Parser.php b/src/Parser.php index 28eedcf..0b9a171 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -125,6 +125,37 @@ public function get($key = null, $default = null) return $default; } + /** + * Mask input data with a given mapping. + * + * @param array $mask + * + * @return array + */ + public function mask(array $mask) + { + $keys = array(); + foreach ($mask as $key => $value) { + $keys[] = $key . (is_array($value) ? $this->process_mask($value) : ''); + } + + return $this->only($keys); + } + + /** + * Recursive processor for processing user masks. + * + * @param array $mask + * + * @return string + */ + private function process_mask($mask) + { + foreach ($mask as $key => $value) { + return '.' . $key . (is_array($value) ? $this->process_item($value) : ''); + } + } + /** * Parse the HTTP payload data, autodetect format and return all data in array. * Override the format by providing a content type. diff --git a/tests/ParserTest.php b/tests/ParserTest.php index 3fe1fe4..4c6a00b 100644 --- a/tests/ParserTest.php +++ b/tests/ParserTest.php @@ -15,6 +15,21 @@ protected function tearDown() m::close(); } + /** @test */ + public function mask_payload() + { + $parser = m::mock('Nathanmac\Utilities\Parser\Parser') + ->shouldDeferMissing() + ->shouldAllowMockingProtectedMethods(); + + $parser->shouldReceive('getPayload') + ->andReturn('{"message": {"title": "Hello World", "body": "Some message content"}, "comments": [{ "title": "hello", "message": "hello world"}, {"title": "world", "message": "hello world"}]}'); + + $this->assertEquals(array("message" => array("title" => "Hello World")), $parser->mask(array('message' => array('title' => '*')))); + $this->assertEquals(array("comments" => array(array("title" => "hello", "message" => "hello world"), array("title" => "world", "message" => "hello world"))), $parser->mask(array('comments' => '*'))); + $this->assertEquals(array('posts' => null), $parser->mask(array('posts' => '*'))); + } + /** @test */ public function wildcards_with_simple_structure_json() {