Skip to content

Instantly share code, notes, and snippets.

@elyobo
Created August 10, 2013 15:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elyobo/6200838 to your computer and use it in GitHub Desktop.
Save elyobo/6200838 to your computer and use it in GitHub Desktop.
<?php
use PHPUnit_Framework_TestCase as BaseTestCase;
class TestFixer extends BaseTestCase
{
public function fix(&$target, $source, $keep = false) {
if (!$source) {
return;
}
$keys = array();
$source = preg_replace_callback(
'/
# Match at start of string or &
(?:^|(?<=&))
# Exclude cases where the period is in brackets, e.g. foo[bar.blarg]
[^=&\[]*
# Affected cases: periods and spaces
(?:\.|%20)
# Keep matching until assignment, next variable, end of string or
# start of an array
[^=&\[]*
/x',
function ($key) use (&$keys) {
$keys[] = $key = base64_encode(urldecode($key[0]));
return urlencode($key);
},
$source
);
if (!$keep) {
$target = array();
}
parse_str($source, $data);
foreach ($data as $key => $val) {
// Only unprocess encoded keys
if (!in_array($key, $keys)) {
$target[$key] = $val;
continue;
}
$key = base64_decode($key);
$target[$key] = $val;
if ($keep) {
// Keep a copy in the underscore key version
$key = preg_replace('/(\.| )/', '_', $key);
$target[$key] = $val;
}
}
}
public function dataForTestFix()
{
return array(
// Simple cases
['foo=bar', ['foo' => 'bar']],
['foo=foo.bar', ['foo' => 'foo.bar']],
['foo=foo.bar[]', ['foo' => 'foo.bar[]']],
['foo[]=bar', ['foo' => ['bar']]],
['foo.bar', ['foo.bar' => '']],
['foo.bar[]', ['foo.bar' => ['']]],
['foo%20bar', ['foo bar' => '']],
['foo%20bar[]', ['foo bar' => ['']]],
['foo[foo.bar]=bar', ['foo' => ['foo.bar' => 'bar']]],
['foo[foo%20bar]=bar', ['foo' => ['foo bar' => 'bar']]],
// Simple cases with keeping
['foo=bar', ['foo' => 'bar'], true],
['foo=foo.bar', ['foo' => 'foo.bar'], true],
['foo=foo.bar[]', ['foo' => 'foo.bar[]'], true],
['foo[]=bar', ['foo' => ['bar']], true],
['foo.bar', ['foo_bar' => '', 'foo.bar' => ''], true],
['foo.bar[]', ['foo_bar' => [''], 'foo.bar' => ['']], true],
['foo%20bar', ['foo_bar' => '', 'foo bar' => ''], true],
['foo%20bar[]', ['foo_bar' => [''], 'foo bar' => ['']], true],
['foo[foo.bar]=bar', ['foo' => ['foo.bar' => 'bar']], true],
['foo[foo%20bar]=bar', ['foo' => ['foo bar' => 'bar']], true],
// Duplicates if cast to "_"
['foo.bar=blarg1&foo_bar=blarg2&foo%20bar=blarg3', ['foo.bar' => 'blarg1', 'foo_bar' => 'blarg2', 'foo bar' => 'blarg3']],
['foo.bar=blarg1&foo_bar=blarg2&foo%20bar=blarg3', ['foo_bar' => 'blarg3', 'foo.bar' => 'blarg1', 'foo bar' => 'blarg3'], true],
array(
'foo%20bar=blarg&foo[bar][blarg.bar]=bar&foo.bar=blarg&foobar.blarg[]=bar&blarg.foo&blargfoo.bar[asdf]=w00t&normal=normal',
array(
'foo bar' => 'blarg',
'foo' => array(
'bar' => array(
'blarg.bar' => 'bar',
),
),
'foo.bar' => 'blarg',
'foobar.blarg' => array('bar'),
'blarg.foo' => null,
'blargfoo.bar' => array(
'asdf' => 'w00t',
),
'normal' => 'normal',
)
),
);
}
/**
* @dataProvider dataForTestFix
*/
public function testFixWorks($string, $target, $keep = false)
{
parse_str($string, $source);
$this->fix($source, $string, $keep);
$this->assertEquals($source, $target);
}
}
@gsouf
Copy link

gsouf commented Feb 14, 2017

Thanks for sharing, implemented it in a project of mine ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment