Skip to content
This repository was archived by the owner on Jan 13, 2022. It is now read-only.

Commit 23eafab

Browse files
committed
Merge pull request #573 from nickma42/birthday-behavior
Implementing new Birthday class to handle Graph API response variations
2 parents 69b363d + e4e6df7 commit 23eafab

File tree

5 files changed

+229
-5
lines changed

5 files changed

+229
-5
lines changed

docs/Birthday.fbmd

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<card>
2+
# Birthday for the Facebook SDK for PHP
3+
4+
Extends `\DateTime` and represents a user's birthday returned from the Graph API which can be returned omitting certain information.
5+
6+
Users may opt not to share birth day or month, or may not share birth year. Possible returns:
7+
8+
* MM/DD/YYYY
9+
* MM/DD
10+
* YYYY
11+
</card>
12+
13+
<card>
14+
## Facebook\GraphNodes\Birthday {#overview}
15+
16+
After retrieving a GraphUser from the Graph API, the `getBirthday()` method will return the birthday in the form of a `Facebook\GraphNodes\Birthday` entity which indicates which aspects of the birthday the user opted to share.
17+
18+
The `Facebook\GraphNodes\Birthday` entity extends `DateTime` so `format` may be used to present the information appropriately depending on what information it contains.
19+
20+
Usage:
21+
22+
~~~~
23+
$fb = new Facebook\Facebook(\* *\);
24+
// Returns a `Facebook\FacebookResponse` object
25+
$response = $fb->get('/me');
26+
27+
// Get the response typed as a GraphUser
28+
$user = $response->getGraphUser();
29+
30+
// Gets birthday value, assume Graph return was format MM/DD
31+
$birthday = $user->getBirthday();
32+
33+
var_dump($birthday);
34+
// class Facebook\GraphNodes\Birthday ...
35+
36+
var_dump($birthday->hasDate());
37+
// true
38+
39+
var_dump($birthday->hasYear());
40+
// false
41+
42+
var_dump($birthday->format('m/d'));
43+
// 03/21
44+
~~~~
45+
</card>
46+
47+
<card>
48+
## Instance Methods {#instance-methods}
49+
50+
### hasDate() {#has-date}
51+
~~~~
52+
public boolean hasDate()
53+
~~~~
54+
Returns whether or not the birthday object contains the day and month of birth.
55+
</card>
56+
57+
<card>
58+
### hasYear() {#has-year}
59+
~~~~
60+
public boolean hasYear()
61+
~~~~
62+
Returns whether or not the birthday object contains the year of birth.
63+
</card>

docs/GraphNode.fbmd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,9 @@ Returns the `link` property for the user as a string if present.
166166

167167
### getBirthday() {#user-getbirthday}
168168
~~~~
169-
public \DateTime|null getBirthday()
169+
public \Facebook\GraphNodes\Birthday|null getBirthday()
170170
~~~~
171-
Returns the `birthday` property for the user as a `\DateTime` if present.
171+
Returns the `birthday` property for the user as a [`Facebook\GraphNodes\Birthday`](/docs/php/Birthday) if present.
172172

173173
### getLocation() {#user-getlocation}
174174
~~~~
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
/**
3+
* Copyright 2016 Facebook, Inc.
4+
*
5+
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
6+
* use, copy, modify, and distribute this software in source code or binary
7+
* form for use in connection with the web services and APIs provided by
8+
* Facebook.
9+
*
10+
* As with any software that integrates with the Facebook platform, your use
11+
* of this software is subject to the Facebook Developer Principles and
12+
* Policies [http://developers.facebook.com/policy/]. This copyright notice
13+
* shall be included in all copies or substantial portions of the software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21+
* DEALINGS IN THE SOFTWARE.
22+
*
23+
*/
24+
namespace Facebook\GraphNodes;
25+
26+
use DateTime;
27+
28+
/**
29+
* Birthday object to handle various Graph return formats
30+
*
31+
* @package Facebook
32+
*/
33+
class Birthday extends DateTime
34+
{
35+
/**
36+
* @var bool
37+
*/
38+
private $hasDate = false;
39+
40+
/**
41+
* @var bool
42+
*/
43+
private $hasYear = false;
44+
45+
/**
46+
* Parses Graph birthday format to set indication flags, possible values:
47+
*
48+
* MM/DD/YYYY
49+
* MM/DD
50+
* YYYY
51+
*
52+
* @link https://developers.facebook.com/docs/graph-api/reference/user
53+
*
54+
* @param string $date
55+
*/
56+
public function __construct($date)
57+
{
58+
$parts = explode('/', $date);
59+
60+
$this->hasYear = count($parts) === 3 || count($parts) === 1;
61+
$this->hasDate = count($parts) === 3 || count($parts) === 2;
62+
63+
parent::__construct($date);
64+
}
65+
66+
/**
67+
* Returns whether date object contains birth day and month
68+
*
69+
* @return bool
70+
*/
71+
public function hasDate()
72+
{
73+
return $this->hasDate;
74+
}
75+
76+
/**
77+
* Returns whether date object contains birth year
78+
*
79+
* @return bool
80+
*/
81+
public function hasYear()
82+
{
83+
return $this->hasYear;
84+
}
85+
}

src/Facebook/GraphNodes/GraphNode.php

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,11 @@ public function castItems(array $data)
6262
foreach ($data as $k => $v) {
6363
if ($this->shouldCastAsDateTime($k)
6464
&& (is_numeric($v)
65-
|| $k === 'birthday'
6665
|| $this->isIso8601DateString($v))
6766
) {
6867
$items[$k] = $this->castToDateTime($v);
68+
} elseif ($k === 'birthday') {
69+
$items[$k] = $this->castToBirthday($v);
6970
} else {
7071
$items[$k] = $v;
7172
}
@@ -149,7 +150,6 @@ public function shouldCastAsDateTime($key)
149150
'backdated_time',
150151
'issued_at',
151152
'expires_at',
152-
'birthday',
153153
'publish_time'
154154
], true);
155155
}
@@ -173,6 +173,18 @@ public function castToDateTime($value)
173173
return $dt;
174174
}
175175

176+
/**
177+
* Casts a birthday value from Graph to Birthday
178+
*
179+
* @param string $value
180+
*
181+
* @return Birthday
182+
*/
183+
public function castToBirthday($value)
184+
{
185+
return new Birthday($value);
186+
}
187+
176188
/**
177189
* Getter for $graphObjectMap.
178190
*

tests/GraphNodes/GraphUserTest.php

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,25 @@ public function setUp()
4242
public function testDatesGetCastToDateTime()
4343
{
4444
$dataFromGraph = [
45-
'birthday' => '1984-01-01',
45+
'updated_time' => '2016-04-26 13:22:05',
46+
];
47+
48+
$this->responseMock
49+
->shouldReceive('getDecodedBody')
50+
->once()
51+
->andReturn($dataFromGraph);
52+
$factory = new GraphNodeFactory($this->responseMock);
53+
$graphNode = $factory->makeGraphUser();
54+
55+
$updatedTime = $graphNode->getField('updated_time');
56+
57+
$this->assertInstanceOf('DateTime', $updatedTime);
58+
}
59+
60+
public function testBirthdaysGetCastToBirthday()
61+
{
62+
$dataFromGraph = [
63+
'birthday' => '1984/01/01',
4664
];
4765

4866
$this->responseMock
@@ -54,7 +72,53 @@ public function testDatesGetCastToDateTime()
5472

5573
$birthday = $graphNode->getBirthday();
5674

75+
// Test to ensure BC
5776
$this->assertInstanceOf('DateTime', $birthday);
77+
78+
$this->assertInstanceOf('\\Facebook\\GraphNodes\\Birthday', $birthday);
79+
$this->assertTrue($birthday->hasDate());
80+
$this->assertTrue($birthday->hasYear());
81+
$this->assertEquals('1984/01/01', $birthday->format('Y/m/d'));
82+
}
83+
84+
public function testBirthdayCastHandlesDateWithoutYear()
85+
{
86+
$dataFromGraph = [
87+
'birthday' => '03/21',
88+
];
89+
90+
$this->responseMock
91+
->shouldReceive('getDecodedBody')
92+
->once()
93+
->andReturn($dataFromGraph);
94+
$factory = new GraphNodeFactory($this->responseMock);
95+
$graphNode = $factory->makeGraphUser();
96+
97+
$birthday = $graphNode->getBirthday();
98+
99+
$this->assertTrue($birthday->hasDate());
100+
$this->assertFalse($birthday->hasYear());
101+
$this->assertEquals('03/21', $birthday->format('m/d'));
102+
}
103+
104+
public function testBirthdayCastHandlesYearWithoutDate()
105+
{
106+
$dataFromGraph = [
107+
'birthday' => '1984',
108+
];
109+
110+
$this->responseMock
111+
->shouldReceive('getDecodedBody')
112+
->once()
113+
->andReturn($dataFromGraph);
114+
$factory = new GraphNodeFactory($this->responseMock);
115+
$graphNode = $factory->makeGraphUser();
116+
117+
$birthday = $graphNode->getBirthday();
118+
119+
$this->assertTrue($birthday->hasYear());
120+
$this->assertFalse($birthday->hasDate());
121+
$this->assertEquals('1984', $birthday->format('Y'));
58122
}
59123

60124
public function testPagePropertiesWillGetCastAsGraphPageObjects()

0 commit comments

Comments
 (0)