Skip to content

Commit 0d47d1f

Browse files
authored
Merge pull request #399 from RedaktionsNetzwerk-Deutschland/bugfix/facebook-api-24th-oct
Fix Facebook API October 24th changes
2 parents 58d2295 + 9e6a47b commit 0d47d1f

File tree

12 files changed

+98
-26
lines changed

12 files changed

+98
-26
lines changed

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,18 +324,19 @@ $client->setSettings([
324324
$embed = new Embed(new Crawler($client));
325325
```
326326

327-
If you need to pass settings to your detectors, you can use the `setSettings` method:
327+
If you need to pass settings to your detectors, you can add settings to the `ExtractorFactory`:
328328

329329
```php
330-
//Create the extractor
331-
$info = $embed->get($url);
330+
use Embed\Embed;
332331

333-
$info->setSettings([
332+
$embed = new Embed();
333+
$embed->setSettings([
334334
'oembed:query_parameters' => [], //Extra parameters send to oembed
335335
'twitch:parent' => 'example.com', //Required to embed twitch videos as iframe
336336
'facebook:token' => '1234|5678', //Required to embed content from Facebook
337337
'instagram:token' => '1234|5678', //Required to embed content from Instagram
338338
]);
339+
$info = $embed->get($url);
339340
```
340341

341342
Note: The built-in detectors does not require settings. This feature is only for convenience if you create a specific detector that requires settings.

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"php": "^7.4",
2828
"ext-curl": "*",
2929
"ext-dom": "*",
30+
"ext-json": "*",
3031
"ext-mbstring": "*",
3132
"composer/ca-bundle": "^1.0",
3233
"oscarotero/html-parser": "^0.1.4",

demo/index.php

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,16 @@
66

77
function getUrl(): ?string
88
{
9-
$url = $_GET['url'] ?? null;
9+
$skipParams = ['url', 'settings'];
10+
$url = getParam('url');
1011

11-
if (empty($url)) {
12+
if (!$url) {
1213
return null;
1314
}
1415

1516
//fix for unescaped urls
1617
foreach ($_GET as $name => $value) {
17-
if ($name === 'url') {
18+
if (in_array($name, $skipParams, true)) {
1819
continue;
1920
}
2021

@@ -24,6 +25,17 @@ function getUrl(): ?string
2425
return $url;
2526
}
2627

28+
function getParam(string $paramName): ?string
29+
{
30+
return $_GET[$paramName] ?? null;
31+
}
32+
33+
function getJsonSettings(): array
34+
{
35+
$jsonString = getParam('settings') ?: '{}';
36+
return json_decode($jsonString, true, 512, JSON_THROW_ON_ERROR);
37+
}
38+
2739
function getEscapedUrl(): ?string
2840
{
2941
$url = getUrl();
@@ -120,7 +132,6 @@ function printCode(?string $code, bool $asHtml = true): void
120132
'cms' => 'printText',
121133
'language' => 'printText',
122134
'languages' => 'printArray',
123-
'cms' => 'printText',
124135
];
125136
?>
126137

@@ -143,7 +154,7 @@ function printCode(?string $code, bool $asHtml = true): void
143154
form { background: #EEE; border-bottom: solid 1px #DDD; color: #666; padding: 3em 1.5em; }
144155
fieldset { border: none; padding: 0; }
145156
label { display: block; cursor: pointer; font-weight: bold; }
146-
input[type="url"] { border: none; background: white; border-radius: 2px; box-sizing: border-box; width: 100%; margin: 5px 0; font-size: 1.3em; padding: 0.5em; color: #666; }
157+
input[type="url"], textarea { border: none; background: white; border-radius: 2px; box-sizing: border-box; min-width: 100%; margin: 5px 0; font-size: 1.3em; padding: 0.5em; color: #666; }
147158
button, summary { font-size: 1.6rem; font-weight: bold; font-family: Arial; background: yellowgreen; border: none; border-radius: 3px; padding: 0.3em 1em; cursor: pointer; margin-top: 5px; }
148159
button:hover, summary:hover { background: black; color: white; }
149160
details {
@@ -154,7 +165,7 @@ function printCode(?string $code, bool $asHtml = true): void
154165
width: max-content;
155166
margin: auto;
156167
}
157-
168+
.helptext { font-weight: normal; font-size: 0.75em; }
158169
/* result */
159170
main { padding: 1.5em; }
160171
main h1, main h2 { font-size: 2em; color: #666; letter-spacing: -0.02em; }
@@ -173,6 +184,19 @@ function printCode(?string $code, bool $asHtml = true): void
173184
<span>Url to test:</span>
174185
<input type="url" name="url" autofocus placeholder="http://" value="<?php echo getEscapedUrl(); ?>">
175186
</label>
187+
<label>
188+
<span>Settings:</span>
189+
<?php
190+
$placeholderJson = json_encode(['instagram:token' => null], JSON_PRETTY_PRINT);
191+
$currentJson = getJsonSettings();
192+
?>
193+
<textarea name="settings" rows="3" placeholder='<?php echo $placeholderJson; ?>'><?php
194+
echo !empty($currentJson)
195+
? json_encode($currentJson, JSON_PRETTY_PRINT | JSON_FORCE_OBJECT)
196+
: '';
197+
?></textarea>
198+
<span class="helptext">Add settings like "instagram:token", "facebook:token", ...</span>
199+
</label>
176200
</fieldset>
177201

178202
<fieldset class="action">
@@ -182,7 +206,7 @@ function printCode(?string $code, bool $asHtml = true): void
182206
</fieldset>
183207
</form>
184208

185-
<?php if (getUrl()): ?>
209+
<?php if (getUrl()) : ?>
186210
<main>
187211
<h1>Result:</h1>
188212

@@ -193,10 +217,16 @@ function printCode(?string $code, bool $asHtml = true): void
193217
'Accept-Language' => 'en-US,en;q=0.2',
194218
'Cache-Control' => 'max-age=0,no-cache',
195219
]);
220+
221+
$embed->setSettings(
222+
array_merge(
223+
[
224+
'twitch:parent' => $_SERVER['SERVER_NAME'] === 'localhost' ? null : $_SERVER['SERVER_NAME'],
225+
],
226+
getJsonSettings()
227+
)
228+
);
196229
$info = $embed->get(getUrl());
197-
$info->setSettings([
198-
'twitch:parent' => $_SERVER['SERVER_NAME'] === 'localhost' ? null : $_SERVER['SERVER_NAME'],
199-
]);
200230
} catch (Exception $exception) {
201231
echo '<pre>';
202232
echo $exception;
@@ -206,7 +236,7 @@ function printCode(?string $code, bool $asHtml = true): void
206236
?>
207237

208238
<table>
209-
<?php foreach ($detectors as $name => $fn): ?>
239+
<?php foreach ($detectors as $name => $fn) : ?>
210240
<tr>
211241
<th><?php echo $name; ?></th>
212242
<td><?php $fn($info->$name); ?></td>
@@ -250,7 +280,7 @@ function printCode(?string $code, bool $asHtml = true): void
250280
</tr>
251281
</table>
252282

253-
<?php if (method_exists($info, 'getApi')): ?>
283+
<?php if (method_exists($info, 'getApi')) : ?>
254284
<h2>API data</h2>
255285

256286
<table>

phpunit.xml.dist

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<phpunit bootstrap="vendor/autoload.php"
2+
<phpunit
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.4/phpunit.xsd"
5+
bootstrap="vendor/autoload.php"
36
backupGlobals="false"
47
backupStaticAttributes="false"
58
colors="true"

src/Adapters/Facebook/OEmbed.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ protected function detectEndpoint(): ?UriInterface
2626

2727
return $this->extractor->getCrawler()
2828
->createUri($this->getEndpointByPath($uri->getPath()))
29-
->withQuery($queryParameters);
29+
->withQuery(http_build_query($queryParameters));
3030
}
3131

3232
private function getEndpointByPath(string $path): string

src/Adapters/Instagram/OEmbed.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ protected function detectEndpoint(): ?UriInterface
2424

2525
return $this->extractor->getCrawler()
2626
->createUri(self::ENDPOINT)
27-
->withQuery($queryParameters);
27+
->withQuery(http_build_query($queryParameters));
2828
}
2929
}

src/ApiTrait.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
trait ApiTrait
1111
{
12-
private Extractor $extractor;
12+
protected Extractor $extractor;
1313
private array $data;
1414

1515
public function __construct(Extractor $extractor)

src/Embed.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ public function getExtractorFactory(): ExtractorFactory
5757
return $this->extractorFactory;
5858
}
5959

60+
public function setSettings(array $settings): void
61+
{
62+
$this->extractorFactory->setSettings($settings);
63+
}
64+
6065
private function extract(RequestInterface $request, ResponseInterface $response, bool $redirect = true): Extractor
6166
{
6267
$uri = $this->crawler->getResponseUri($response) ?: $request->getUri();

src/Extractor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class Extractor
6262
private Crawler $crawler;
6363

6464
private Document $document;
65-
private OEmbed $oembed;
65+
protected OEmbed $oembed;
6666
private LinkedData $linkedData;
6767
private Metas $metas;
6868

src/ExtractorFactory.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ class ExtractorFactory
3333
'twitch.tv' => Adapters\Twitch\Extractor::class,
3434
];
3535
private array $customDetectors = [];
36+
private array $settings;
37+
38+
public function __construct(?array $settings = [])
39+
{
40+
$this->settings = $settings ?? [];
41+
}
3642

3743
public function createExtractor(UriInterface $uri, RequestInterface $request, ResponseInterface $response, Crawler $crawler): Extractor
3844
{
@@ -41,7 +47,9 @@ public function createExtractor(UriInterface $uri, RequestInterface $request, Re
4147

4248
$class = $this->adapters[$host] ?? $this->default;
4349

50+
/** @var Extractor $extractor */
4451
$extractor = new $class($uri, $request, $response, $crawler);
52+
$extractor->setSettings($this->settings);
4553

4654
foreach ($this->customDetectors as $name => $detector) {
4755
$extractor->addDetector($name, new $detector($extractor));
@@ -69,4 +77,9 @@ public function setDefault(string $class): void
6977
{
7078
$this->default = $class;
7179
}
80+
81+
public function setSettings(array $settings): void
82+
{
83+
$this->settings = $settings;
84+
}
7285
}

tests/PagesTest.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ public function testPages()
3333
$this->assertEmbed('http://www.hookem.com/story/texas-shortstop-joe-baker-arrested-public-intoxication/');
3434
$this->assertEmbed('http://i.imgur.com/X6rkCc5.jpg');
3535
$this->assertEmbed('https://infogr.am/7743c36a-f3ca-4465-9a80-a8abbd5d8dc4');
36-
$this->assertEmbed('https://www.instagram.com/p/ySl7G9tO_q/');
3736
$this->assertEmbed('http://output.jsbin.com/vonesu/10');
3837
$this->assertEmbed('http://jsfiddle.net/zhm5rjnz/');
3938
$this->assertEmbed('https://www.kickstarter.com/projects/1452363698/good-seed-craft-veggie-burgers');
@@ -91,7 +90,11 @@ public function testArchiveOrg()
9190

9291
public function testInstagram()
9392
{
94-
$this->assertEmbed('http://instagram.com/p/ySl7G9tO_q/');
93+
if (getenv('INSTAGRAM_TOKEN') ?? false) {
94+
$this->assertEmbed('http://instagram.com/p/ySl7G9tO_q/');
95+
} else {
96+
self::markTestSkipped('Environment variable `INSTAGRAM_TOKEN` must be provided to test instagram. See https://developers.facebook.com/docs/instagram/oembed/');
97+
}
9598
}
9699

97100
public function testMeetup()
@@ -127,8 +130,12 @@ public function testFlickr()
127130

128131
public function testFacebook()
129132
{
130-
$this->assertEmbed('https://www.facebook.com/permalink.php?story_fbid=827163017327807&id=149460691764713');
131-
$this->assertEmbed('https://www.facebook.com/acolono/videos/10154107990797381/');
133+
if (getenv('FACEBOOK_TOKEN') ?? false) {
134+
$this->assertEmbed('https://www.facebook.com/permalink.php?story_fbid=827163017327807&id=149460691764713');
135+
$this->assertEmbed('https://www.facebook.com/acolono/videos/10154107990797381/');
136+
} else {
137+
self::markTestSkipped('Environment variable `FACEBOOK_TOKEN` must be provided to test facebook. See https://developers.facebook.com/docs/plugins/oembed');
138+
}
132139
}
133140

134141
public function testGithub()

tests/PagesTestCase.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Datetime;
88
use Embed\Embed;
99
use Embed\Extractor;
10+
use Embed\ExtractorFactory;
1011
use Embed\Http\Crawler;
1112
use JsonSerializable;
1213
use PHPUnit\Framework\TestCase;
@@ -50,7 +51,7 @@ private static function getEmbed(): Embed
5051
$dispatcher = new FileClient(__DIR__.'/cache');
5152
$dispatcher->setMode(static::CACHE);
5253

53-
return self::$embed = new Embed(new Crawler($dispatcher));
54+
return self::$embed = new Embed(new Crawler($dispatcher), self::getExtractorFactory());
5455
}
5556

5657
protected function assertEmbed(string $url)
@@ -65,6 +66,7 @@ protected function assertEmbed(string $url)
6566
if (!$expected || static::FIXTURES === 1) {
6667
self::writeData($uri, $data);
6768
echo PHP_EOL."Save fixture: {$url}";
69+
$this->markTestSkipped('Skipped assertion for '.$url);
6870
} else {
6971
$this->assertEquals($expected, $data, $url);
7072
}
@@ -133,4 +135,14 @@ private static function convert($value)
133135

134136
return $value;
135137
}
138+
139+
private static function getExtractorFactory()
140+
{
141+
$settings = [
142+
'instagram:token' => $_ENV['INSTAGRAM_TOKEN'] ?? null,
143+
'facebook:token' => $_ENV['FACEBOOK_TOKEN'] ?? null,
144+
];
145+
146+
return new ExtractorFactory($settings);
147+
}
136148
}

0 commit comments

Comments
 (0)