Commit 165e9ede by Klimov Paul

Added ability to operate nested and complex attributes via…

Added ability to operate nested and complex attributes via `yii\authclient\BaseClient::normalizeUserAttributeMap`
parent 239d48c3
...@@ -9,6 +9,7 @@ namespace yii\authclient; ...@@ -9,6 +9,7 @@ namespace yii\authclient;
use Yii; use Yii;
use yii\base\Component; use yii\base\Component;
use yii\base\InvalidConfigException;
use yii\base\NotSupportedException; use yii\base\NotSupportedException;
use yii\helpers\Inflector; use yii\helpers\Inflector;
use yii\helpers\StringHelper; use yii\helpers\StringHelper;
...@@ -50,7 +51,23 @@ abstract class BaseClient extends Component implements ClientInterface ...@@ -50,7 +51,23 @@ abstract class BaseClient extends Component implements ClientInterface
private $_userAttributes; private $_userAttributes;
/** /**
* @var array map used to normalize user attributes fetched from external auth service * @var array map used to normalize user attributes fetched from external auth service
* in format: rawAttributeName => normalizedAttributeName * in format: normalizedAttributeName => sourceSpecification
* 'sourceSpecification' can be:
* - string, raw attribute name
* - array, pass to raw attribute value
* - callable, PHP callback, which should accept array of raw attributes and return normalized value.
*
* For example:
*
* ```php
* 'normalizeUserAttributeMap' => [
* 'about' => 'bio',
* 'language' => ['languages', 0, 'name'],
* 'fullName' => function ($attributes) {
* return $attributes['firstName'] . ' ' . $attributes['lastName'];
* },
* ],
* ```
*/ */
private $_normalizeUserAttributeMap; private $_normalizeUserAttributeMap;
/** /**
...@@ -229,14 +246,38 @@ abstract class BaseClient extends Component implements ClientInterface ...@@ -229,14 +246,38 @@ abstract class BaseClient extends Component implements ClientInterface
/** /**
* Normalize given user attributes according to [[normalizeUserAttributeMap]]. * Normalize given user attributes according to [[normalizeUserAttributeMap]].
* @param array $attributes raw attributes. * @param array $attributes raw attributes.
* @throws InvalidConfigException on incorrect normalize attribute map.
* @return array normalized attributes. * @return array normalized attributes.
*/ */
protected function normalizeUserAttributes($attributes) protected function normalizeUserAttributes($attributes)
{ {
foreach ($this->getNormalizeUserAttributeMap() as $normalizedName => $actualName) { foreach ($this->getNormalizeUserAttributeMap() as $normalizedName => $actualName) {
if (is_scalar($actualName)) {
if (array_key_exists($actualName, $attributes)) { if (array_key_exists($actualName, $attributes)) {
$attributes[$normalizedName] = $attributes[$actualName]; $attributes[$normalizedName] = $attributes[$actualName];
} }
} else {
if (is_callable($actualName)) {
$attributes[$normalizedName] = call_user_func($actualName, $attributes);
} elseif (is_array($actualName)) {
$haystack = $attributes;
$searchKeys = $actualName;
$isFound = true;
while (($key = array_shift($searchKeys)) !== null) {
if (is_array($haystack) && array_key_exists($key, $haystack)) {
$haystack = $haystack[$key];
} else {
$isFound = false;
break;
}
}
if ($isFound) {
$attributes[$normalizedName] = $haystack;
}
} else {
throw new InvalidConfigException('Invalid actual name "' . gettype($actualName) . '" specified at "' . get_class($this) . '::normalizeUserAttributeMap"');
}
}
} }
return $attributes; return $attributes;
......
...@@ -4,7 +4,7 @@ Yii Framework 2 authclient extension Change Log ...@@ -4,7 +4,7 @@ Yii Framework 2 authclient extension Change Log
2.0.0 under development 2.0.0 under development
----------------------- -----------------------
- no changes in this release. - Enh #5135: Added ability to operate nested and complex attributes via `yii\authclient\BaseClient::normalizeUserAttributeMap` (zinzinday, klimov-paul)
2.0.0-rc September 27, 2014 2.0.0-rc September 27, 2014
......
...@@ -155,7 +155,6 @@ Following predefined auth clients are available: ...@@ -155,7 +155,6 @@ Following predefined auth clients are available:
- [[yii\authclient\clients\GoogleOAuth]] - [Google](https://www.google.com/) OAuth2 client - [[yii\authclient\clients\GoogleOAuth]] - [Google](https://www.google.com/) OAuth2 client
- [[yii\authclient\clients\GoogleOpenId]] - [Google](https://www.google.com/) OpenID client - [[yii\authclient\clients\GoogleOpenId]] - [Google](https://www.google.com/) OpenID client
- [[yii\authclient\clients\LinkedIn]] - [LinkedIn](http://www.linkedin.com/) OAuth2 client - [[yii\authclient\clients\LinkedIn]] - [LinkedIn](http://www.linkedin.com/) OAuth2 client
- [[yii\authclient\clients\LinkedIn]] - [LinkedIn](http://www.linkedin.com/) OAuth2 client
- [[yii\authclient\clients\Live]] - [Microsoft Live](http://live.com/) OAuth2 client - [[yii\authclient\clients\Live]] - [Microsoft Live](http://live.com/) OAuth2 client
- [[yii\authclient\clients\Twitter]] - [Twitter](https://twitter.com/) OAuth1 client - [[yii\authclient\clients\Twitter]] - [Twitter](https://twitter.com/) OAuth1 client
- [[yii\authclient\clients\VKontakte]] - [VKontakte](http://vk.com/) OAuth2 client - [[yii\authclient\clients\VKontakte]] - [VKontakte](http://vk.com/) OAuth2 client
......
...@@ -55,25 +55,88 @@ class BaseClientTest extends TestCase ...@@ -55,25 +55,88 @@ class BaseClientTest extends TestCase
} }
/** /**
* @depends testSetGet * Data provider for [[testNormalizeUserAttributes()]]
* @return array test data
*/ */
public function testNormalizeUserAttributes() public function dataProviderNormalizeUserAttributes()
{ {
$client = new Client(); return [
[
$normalizeUserAttributeMap = [ [
'raw/name' => 'name', 'name' => 'raw/name',
'raw/email' => 'email', 'email' => 'raw/email',
]; ],
$client->setNormalizeUserAttributeMap($normalizeUserAttributeMap); [
$rawUserAttributes = [
'raw/name' => 'name value', 'raw/name' => 'name value',
'raw/email' => 'email value', 'raw/email' => 'email value',
],
[
'name' => 'name value',
'email' => 'email value',
],
],
[
[
'name' => function ($attributes) {
return $attributes['firstName'] . ' ' . $attributes['lastName'];
},
],
[
'firstName' => 'John',
'lastName' => 'Smith',
],
[
'name' => 'John Smith',
],
],
[
[
'email' => ['emails', 'prime'],
],
[
'emails' => [
'prime' => 'some@email.com'
],
],
[
'email' => 'some@email.com',
],
],
[
[
'email' => ['emails', 0],
'secondaryEmail' => ['emails', 1],
],
[
'emails' => [
'some@email.com',
],
],
[
'email' => 'some@email.com',
],
],
]; ];
}
/**
* @dataProvider dataProviderNormalizeUserAttributes
*
* @depends testSetGet
*
* @param array $normalizeUserAttributeMap
* @param array $rawUserAttributes
* @param array $expectedNormalizedUserAttributes
*/
public function testNormalizeUserAttributes($normalizeUserAttributeMap, $rawUserAttributes, $expectedNormalizedUserAttributes)
{
$client = new Client();
$client->setNormalizeUserAttributeMap($normalizeUserAttributeMap);
$client->setUserAttributes($rawUserAttributes); $client->setUserAttributes($rawUserAttributes);
$normalizedUserAttributes = $client->getUserAttributes(); $normalizedUserAttributes = $client->getUserAttributes();
$expectedNormalizedUserAttributes = array_combine(array_keys($normalizeUserAttributeMap), array_values($rawUserAttributes));
$this->assertEquals($expectedNormalizedUserAttributes, $normalizedUserAttributes); $this->assertEquals(array_merge($rawUserAttributes, $expectedNormalizedUserAttributes), $normalizedUserAttributes);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment