Skip to content

Commit

Permalink
Fix issue with dot notation in only/except functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Nathan Macnamara committed Jul 17, 2014
1 parent 2ba95f5 commit 32afd76
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 87 deletions.
171 changes: 85 additions & 86 deletions src/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,14 @@ public function only($keys)
{
$keys = is_array($keys) ? $keys : func_get_args();

return array_only($this->payload(), $keys) + array_fill_keys($keys, null);
$input = $this->payload();

$results = array();
foreach ($keys as $key) {
$results = array_merge($results, $this->_buildArray(explode('.', $key), $this->get($key)));
}

return $results;
}

public function except($keys)
Expand All @@ -40,8 +47,9 @@ public function except($keys)

$results = $this->payload();

foreach ($keys as $key) array_forget($results, $key);

foreach ($keys as $key) {
$this->_removeValue($results, $key);
}
return $results;
}

Expand All @@ -53,7 +61,7 @@ public function has($key)

foreach ($keys as $value)
{
if ($this->hasValue($value, $results) === false)
if ($this->_hasValue($value, $results) === false)
return false;
}
return true;
Expand All @@ -64,63 +72,11 @@ public function get($key = null, $default = null)
$results = $this->payload();

if ($this->has($key)) {
return $this->getValue($key, $results);
return $this->_getValue($key, $results);
}
return $default;
}

private function getValue($key, $data)
{
return $this->_RecursiveGetValue(array_reverse(explode('.', $key)), $data);
}

private function _RecursiveGetValue($route, $data)
{
$key = array_pop($route);

if (!isset($data[$key]))
return false;

if (count($route) <= 0)
{
if (is_bool($data[$key]))
return $data[$key];

if ($data[$key] === '')
return false;

return $data[$key];
}

return $this->_RecursiveGetValue($route, $data[$key]);
}

private function hasValue($key, $data)
{
return $this->_RecursiveHasValue(array_reverse(explode('.', $key)), $data);
}

private function _RecursiveHasValue($route, $data)
{
$key = array_pop($route);

if (!isset($data[$key]))
return false;

if (count($route) <= 0)
{
if (is_bool($data[$key]))
return true;

if ($data[$key] === '')
return false;

return true;
}

return $this->_RecursiveHasValue($route, $data[$key]);
}

/**
* Alias to the payload function.
*
Expand All @@ -134,13 +90,8 @@ public function all()
public function payload($format = false)
{
if ($format !== false)
{
if (isset($this->supported_formats[$format]))
{
return $this->{$this->supported_formats[$format]}($this->_payload());
}
throw new ParserException('Invalid Or Unsupported Format');
}
return $this->{$this->_format()}($this->_payload());
}

Expand Down Expand Up @@ -227,41 +178,87 @@ public function yaml($string)
}
return array();
}
}

class ParserException extends Exception {}
/**
* Return a value from the array identified from the key.
*
* @param $key
* @param $data
* @return mixed
*/
private function _getValue($key, $data)
{
$keys = explode('.', $key);

while (count($keys) > 1)
{
$key = array_shift($keys);

if ( ! isset($data[$key]) || ! is_array($data[$key]))
{
return false;
}

$data =& $data[$key];
}

return ($data[array_shift($keys)]);
}

/**
* Array contains a value identified from the key, returns bool
*
* @param $key
* @param $data
* @return bool
*/
private function _hasValue($key, $data)
{
$keys = explode('.', $key);

while (count($keys) > 0)
{
$key = array_shift($keys);

if (!isset($data[$key]))
return false;

if (is_bool($data[$key]))
return true;

if ($data[$key] === '')
return false;

$data =& $data[$key];
}
return true;
}

/**
* Helper Functions
*
* http://laravel.com/api/4.2/Illuminate/Http/Request.html
*/
if ( ! function_exists('array_only'))
{
/**
* Get a subset of the items from the given array.
* Build the array structure for value.
*
* @param array $array
* @param array $keys
* @return array
* @param $route
* @param null $data
* @return array|null
*/
function array_only($array, $keys)
private function _buildArray($route, $data = null)
{
return array_intersect_key($array, array_flip((array) $keys));
$key = array_pop($route);
$data = array($key => $data);
if (count($route) == 0)
{
return $data;
}
return $this->_buildArray($route, $data);
}
}

if ( ! function_exists('array_forget'))
{
/**
* Remove an array item from a given array using "dot" notation.
* Remove a value identified from the key
*
* @param array $array
* @param string $key
* @return void
* @param $array
* @param $key
*/
function array_forget(&$array, $key)
private function _removeValue(&$array, $key)
{
$keys = explode('.', $key);

Expand All @@ -279,4 +276,6 @@ function array_forget(&$array, $key)

unset($array[array_shift($keys)]);
}
}
}

class ParserException extends Exception {}
7 changes: 6 additions & 1 deletion tests/ParserPHPTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,15 @@ public function return_value_for_multi_level_key()
->method('_payload')
->will($this->returnValue('{"id": 123, "note": {"headers": {"to": "[email protected]", "from": "[email protected]"}, "body": "Hello World"}}'));


$this->assertEquals('123', $parser->get('id'));
$this->assertEquals('Hello World', $parser->get('note.body'));
$this->assertEquals('[email protected]', $parser->get('note.headers.to'));
$this->assertTrue($parser->has('note.headers.to'));

$this->assertEquals(array('id' => 123, 'note' => array('headers' => array('from' => '[email protected]'), 'body' => 'Hello World')), $parser->except('note.headers.to'));
$this->assertEquals(array('id' => 123, 'note' => array('headers' => array('to' => '[email protected]', 'from' => '[email protected]'))), $parser->except('note.body'));

$this->assertEquals(array('id' => 123, 'status' => null, 'note' => array('body' => 'Hello World')), $parser->only('note.body', 'id', 'status'));
}

/** @test */
Expand Down

0 comments on commit 32afd76

Please sign in to comment.