Skip to content

Commit f95b2f1

Browse files
committed
Merge pull request #1267 from FriendsOfSymfony/ignore_leading_underscores
ignore any number of leading underscores when converting from snake case to camel case
2 parents 9dd5276 + 612f40f commit f95b2f1

File tree

5 files changed

+81
-2
lines changed

5 files changed

+81
-2
lines changed

Normalizer/CamelKeysNormalizer.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,23 @@ private function normalizeArray(array &$data)
6969
*
7070
* @return string
7171
*/
72-
private function normalizeString($string)
72+
protected function normalizeString($string)
7373
{
7474
if (false === strpos($string, '_')) {
7575
return $string;
7676
}
7777

78-
return preg_replace_callback('/_([a-zA-Z0-9])/', function ($matches) {
78+
if (preg_match('/^(_+)(.*)/', $string, $matches)) {
79+
$underscorePrefix = $matches[1];
80+
$string = $matches[2];
81+
} else {
82+
$underscorePrefix = '';
83+
}
84+
85+
$string = preg_replace_callback('/_([a-zA-Z0-9])/', function ($matches) {
7986
return strtoupper($matches[1]);
8087
}, $string);
88+
89+
return $underscorePrefix.$string;
8190
}
8291
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the FOSRestBundle package.
5+
*
6+
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace FOS\RestBundle\Normalizer;
13+
14+
/**
15+
* Normalizes the array by changing its keys from underscore to camel case, while
16+
* leaving leading underscores unchanged.
17+
*
18+
* @author Lukas Kahwe Smith <[email protected]>
19+
*/
20+
class CamelKeysNormalizerWithLeadingUnderscore extends CamelKeysNormalizer
21+
{
22+
/**
23+
* Normalizes a string while leaving leading underscores unchanged.
24+
*
25+
* @param string $string
26+
*
27+
* @return string
28+
*/
29+
protected function normalizeString($string)
30+
{
31+
if (false === strpos($string, '_')) {
32+
return $string;
33+
}
34+
35+
$offset = strspn($string, '_');
36+
if ($offset) {
37+
$underscorePrefix = substr($string, 0, $offset);
38+
$string = substr($string, $offset);
39+
} else {
40+
$underscorePrefix = '';
41+
}
42+
43+
return $underscorePrefix.parent::normalizeString($string);
44+
}
45+
}

Resources/config/body_listener.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
<service id="fos_rest.normalizer.camel_keys" class="%fos_rest.normalizer.camel_keys.class%" />
2121

22+
<service id="fos_rest.normalizer.camel_keys_with_leading_underscore" class="FOS\RestBundle\Normalizer\CamelKeysNormalizerWithLeadingUnderscore" />
23+
2224
<service id="fos_rest.decoder.json" class="%fos_rest.decoder.json.class%" />
2325

2426
<service id="fos_rest.decoder.jsontoform" class="%fos_rest.decoder.jsontoform.class%" />

Resources/doc/body_listener.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ to camel cased ones, you can use the ``camel_keys`` array normalizer:
5656
body_listener:
5757
array_normalizer: fos_rest.normalizer.camel_keys
5858
59+
.. note::
60+
61+
If you want to ignore leading underscores, for example in ``_username`` you can
62+
instead use the ``fos_rest.normalizer.camel_keys_with_leading_underscore`` service.
63+
5964
Sometimes an array contains a key, which once normalized, will override an
6065
existing array key. For example ``foo_bar`` and ``foo_Bar`` will both lead to
6166
``fooBar``. If the normalizer receives this data, the listener will throw a

Tests/Normalizer/CamelKeysNormalizerTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace FOS\RestBundle\Tests\Normalizer;
1313

1414
use FOS\RestBundle\Normalizer\CamelKeysNormalizer;
15+
use FOS\RestBundle\Normalizer\CamelKeysNormalizerWithLeadingUnderscore;
1516

1617
class CamelKeysNormalizerTest extends \PHPUnit_Framework_TestCase
1718
{
@@ -52,4 +53,21 @@ public function normalizeProvider()
5253
),
5354
);
5455
}
56+
57+
/**
58+
* @dataProvider normalizeProvider
59+
*/
60+
public function testNormalizeLeadingUnderscore(array $array, array $expected)
61+
{
62+
$normalizer = new CamelKeysNormalizerWithLeadingUnderscore();
63+
$this->assertEquals($expected, $normalizer->normalize($array));
64+
}
65+
66+
public function normalizeProviderLeadingUnderscore()
67+
{
68+
$array = $this->normalizeProvider();
69+
$array[] = array(array('__username' => 'foo', '_password' => 'bar', '_foo_bar' => 'foobar'), array('__username' => 'foo', '_password' => 'bar', '_fooBar' => 'foobar'));
70+
71+
return $array;
72+
}
5573
}

0 commit comments

Comments
 (0)