PHPackages                             horde/service\_facebook - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. horde/service\_facebook

ActiveLibrary[API Development](/categories/api)

horde/service\_facebook
=======================

Facebook Graph API client library

v3.0.0RC1(1mo ago)103BSD-2-ClausePHPPHP ^8.1

Since Jan 9Pushed 1mo ago6 watchersCompare

[ Source](https://github.com/horde/Service_Facebook)[ Packagist](https://packagist.org/packages/horde/service_facebook)[ Docs](https://www.horde.org/libraries/Horde_Service_Facebook)[ RSS](/packages/horde-service-facebook/feed)WikiDiscussions FRAMEWORK\_6\_0 Synced 2w ago

READMEChangelog (1)Dependencies (11)Versions (10)Used By (0)

horde/service\_facebook
=======================

[](#hordeservice_facebook)

A modern PSR-4 client for Facebook's Graph API. Targets Graph v25 for now but is ready to actively support for a rolling window of prior versions once graph v26 is out. Integrates with `horde/oauth` for OAuth2/OIDC flows and `horde/jwt` for `id_token` verification.

**Status:** Partial

The legacy PSR-0 tree under `lib/Horde/Service/Facebook/` targets Facebook's REST API (retired 2020) and FQL (retired 2016) and does not work against modern Facebook.

The new PSR-4 tree under `src/` is the supported surface. New and updated code should use `Horde\Service\Facebook\FacebookApiClient`The legacy `Horde_Service_Facebook` classes are kept around to prevent code breaking on "unknown class", i.e. when it shipped the old client as a side concern and didn't really exercise facebook REST API.

Installation
------------

[](#installation)

```
composer require horde/service_facebook
```

Requires PHP 8.1+. The library is strict-PSR at runtime. Bring your own PSR-18 client (any conforming implementation. `horde/http`, Guzzle, Symfony HttpClient). Bring your own PSR-17 request and stream factories. The Facebook client wires everything through them.

Batteries-included wiring with `horde/http`:

```
composer require horde/service_facebook horde/http
```

Quick Start
-----------

[](#quick-start)

Fetch the current user's profile:

```
use Horde\Http\Client;
use Horde\Http\RequestFactory;
use Horde\Http\StreamFactory;
use Horde\OAuth\Client\AuthenticatedHttpClient;
use Horde\OAuth\Client\TokenSet;
use Horde\Service\Facebook\FacebookApiClient;

// Bearer-authenticated PSR-18 client.
$tokenSet = new TokenSet(
    accessToken: $userAccessToken,
    tokenType: 'Bearer',
    expiresAt: null,
    refreshToken: null,
    scope: null,
);
$httpClient = new AuthenticatedHttpClient(new Client(), $tokenSet);

$fb = FacebookApiClient::create(
    httpClient: $httpClient,
    requestFactory: new RequestFactory(),
    streamFactory: new StreamFactory(),
);

$me = $fb->getMe(['id', 'name', 'email']);
echo $me->name;   // "Ada Lovelace"
echo $me->email;  // "ada@example.org" (if the token holds the email scope)
```

Version Pinning
---------------

[](#version-pinning)

The default version comes from `GraphApiVersion::default()` (currently `v25.0`). To pin to an older supported version:

```
use Horde\Service\Facebook\Graph\GraphApiVersion;

$fbV24 = $fb->withVersion(GraphApiVersion::V24_0);
$events = iterator_to_array($fbV24->listMyUpcomingEvents());
```

`withVersion()` returns a **new immutable client**. The original client remains pinned to its previous version. You can hold two client instances side by side without interference.

Supported versions are exposed as enum cases:

- `GraphApiVersion::V25_0` (current default)
- `GraphApiVersion::V24_0`
- `GraphApiVersion::V23_0`
- `GraphApiVersion::V22_0`

Note: The older APIs aren't really supported - This feature is designing against a foreaseeable shift on facebook side to V26 or V27 while still supporting V25 for a reasonable time.

Attempting to pass a version the library doesn't ship is a **compile-time error**. You cannot construct an unknown enum case. Whether Meta still accepts your pinned version on the wire is Meta's business. If they reject the request you get a `GraphErrorException`like any other server error.

See [doc/VERSIONING.md](doc/VERSIONING.md) for how new Facebook versions land in the library and when old ones eventually leave.

API Methods
-----------

[](#api-methods)

The MVP surface is deliberately narrow. The endpoints Meta still supports for third-party apps on modern Graph API, plus the token-management primitives.

### `getMe(array $fields = []): User`

[](#getmearray-fields---user)

`GET /me`. Empty `$fields` defers to Meta's default projection. Include fields you want back. `email` requires the `email` scope. Name breakdown requires `public_profile`. And so on. Meta silently omits fields the token cannot see rather than raising an error, so a stripped-down response usually means a stripped-down scope grant.

### `listMyUpcomingEvents(?Cursor $cursor = null, array $fields = []): PagedIterator`

[](#listmyupcomingeventscursor-cursor--null-array-fields---pagediterator)

`GET /me/events`. Requires the `user_events` permission on the access token (App Review gated by Meta post-2018). Returns a lazy iterator over `Event` value objects. Paging is handled transparently. The iterator walks Meta's `paging.next` URLs so callers get every page or `break` out early to bound cost.

```
use Horde\Service\Facebook\Graph\Pagination\Cursor;

foreach ($fb->listMyUpcomingEvents(new Cursor(limit: 25)) as $event) {
    echo $event->name, ' @ ', $event->startTime->format('Y-m-d H:i'), "\n";
}
```

### `listMyPermissions(): list`

[](#listmypermissions-listpermission)

`GET /me/permissions`. Meta returns a small, unpaginated list. This method materialises the full array of `Permission` value objects. Each has `name()`, `status()`, and an `isGranted()` convenience.

```
foreach ($fb->listMyPermissions() as $perm) {
    if (!$perm->isGranted()) {
        echo $perm->name(), ' status: ', $perm->status(), "\n";
    }
}
```

### `revokePermission(string $permission): void`

[](#revokepermissionstring-permission-void)

`DELETE /me/permissions/{permission}`. Revokes a previously-granted scope from the current token. The token itself remains valid but loses access to the revoked scope. Meta returns `{"success":true}` on success. Anything else raises `GraphErrorException`.

### `debugToken(string $inputToken, string $appAccessToken): DebugTokenInfo`

[](#debugtokenstring-inputtoken-string-appaccesstoken-debugtokeninfo)

`GET /debug_token`. Introspects a token. The one being examined (`$inputToken`) is usually a user or client token whose fitness you want to verify. The second token (`$appAccessToken`) is your app-level token authorising the introspection call (typically `"{$appId}|{$appSecret}"`).

```
$info = $fb->debugToken($someUserToken, $appId . '|' . $appSecret);
if (!$info->isValid()) {
    // Reject the request. The caller's token is no good.
}
if ($info->expiresAt !== null && $info->expiresAt name() . ' @ ' . $event->startTime()->format('Y-m-d H:i');
}
```

When you need v25-specific fields (`rsvpStatus`, `placeName`, `coverPhotoUrl`), type-hint the concrete class directly and read the public properties OR reflect on capability interfaces

Value objects are pure data holders. They construct from decoded JSON via `::fromApiResponse(object $data): self` and have no dependency on the HTTP client, config, or version enum. That makes them independently useful for hydrating stored payloads (database rows, cache entries, replay fixtures), not only live API responses.

Profile URL Helpers
-------------------

[](#profile-url-helpers)

Two pure URL builders. No API call, no token required. For rendering Facebook profile links and profile picture URLs. Corresponds to the legacy client's `getProfileLink()` and `getThumbnail()` methods, the only members of the legacy `Users` module that ported cleanly.

```
use Horde\Service\Facebook\Graph\GraphApiVersion;
use Horde\Service\Facebook\Graph\ProfileUrls;

// Link to a user's public profile page.
$link = ProfileUrls::profileLink('12345');
// => https://www.facebook.com/12345

$link = ProfileUrls::profileLink('zuck');
// => https://www.facebook.com/zuck

// Profile picture URL. Meta serves a 302 to the actual image.
$thumb = ProfileUrls::thumbnailUrl('12345');
// => https://graph.facebook.com/v25.0/12345/picture

// With size/type options.
$thumb = ProfileUrls::thumbnailUrl('12345', GraphApiVersion::V25_0, [
    'type' => 'large',
]);
$thumb = ProfileUrls::thumbnailUrl('12345', null, [
    'width' => 200,
    'height' => 200,
]);
```

What This Library Does Not Do
-----------------------------

[](#what-this-library-does-not-do)

Explicitly out of scope for the MVP:

- Photo/video multipart upload.
- Batch requests (`/?batch=[...]`).
- The `pages_*` capability tree (page-content management is a separate product surface and will be scoped separately when a caller needs it).
- Webhooks / real-time updates.

The legacy `lib/Horde/Service/Facebook/` tree that targets these features is retained for one release cycle for backward autoload compatibility. **Do not use it in new code.** It calls endpoints Facebook no longer serves.

For the full catalog of features the library does not currently ship, including known deferrals (long-lived token exchange, batch requests) and larger capability areas (Login-with-Facebook identity mapping, Pages, Meta Business Manager), see [doc/MISSING\_FEATURES.md](doc/MISSING_FEATURES.md).

Legacy Coexistence
------------------

[](#legacy-coexistence)

The `lib/` PSR-0 tree stays in place though largely defunct. The `src/` PSR-4 tree is the supported surface. There is no forwarding between them. New callers use the PSR-4 namespace. Old callers keep syntactically correct (against dead endpoints) so no code breaks by merely depending on the classes. Still migration is due.

Migrating existing callers off `lib/`? Start with [doc/UPGRADING.md](doc/UPGRADING.md) for the class-to-class map and concrete migration examples.

Testing
-------

[](#testing)

```
composer install
phpunit
```

Uses PHPUnit 11+. Tests run against `test/unit`. Integration tests under `test/integration` require live Facebook credentials via environment variables and are excluded from the default suite.

License
-------

[](#license)

BSD-2-Clause. See `LICENSE`.

###  Health Score

47

—

FairBetter than 93% of packages

Maintenance92

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community22

Small or concentrated contributor base

Maturity64

Established project with proven stability

 Bus Factor1

Top contributor holds 52.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~840 days

Recently: every ~1023 days

Total

6

Last Release

38d ago

Major Versions

2.0.10 → v3.0.0alpha12021-07-04

PHP version history (4 changes)2.0.7PHP &gt;=5.3.0,&lt;=6.0.0alpha1

2.0.10PHP ^5.3 || ^7

v3.0.0alpha1PHP ^7

v3.0.0RC1PHP ^8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/c943a083635c28520599075eaea7ede2d743b7697b76e84d6bdc37e52cc8249b?d=identicon)[yunosh](/maintainers/yunosh)

![](https://www.gravatar.com/avatar/c931cd02664859360478593450d6c473a05bb12b209dfacfc534cd13257cc7ef?d=identicon)[ralflang](/maintainers/ralflang)

![](https://www.gravatar.com/avatar/e4f6c6771993db2ed500959b42353f6cf6a2ca0406d9617f7ae680f4504faa4a?d=identicon)[horde](/maintainers/horde)

![](https://www.gravatar.com/avatar/a7767adb66b45f2f05bcd44d49bc4e67efacd9ce05b161ce2d481d5dd6af025c?d=identicon)[mrubinsk](/maintainers/mrubinsk)

![](https://www.gravatar.com/avatar/816e2b926f25f8cd2939054c7a7173011b4303d690e25ab61bf33cf8c7cf71ae?d=identicon)[tdannhauer](/maintainers/tdannhauer)

---

Top Contributors

[![yunosh](https://avatars.githubusercontent.com/u/379318?v=4)](https://github.com/yunosh "yunosh (175 commits)")[![mrubinsk](https://avatars.githubusercontent.com/u/66822?v=4)](https://github.com/mrubinsk "mrubinsk (134 commits)")[![ralflang](https://avatars.githubusercontent.com/u/646976?v=4)](https://github.com/ralflang "ralflang (10 commits)")[![wrobel](https://avatars.githubusercontent.com/u/10232?v=4)](https://github.com/wrobel "wrobel (5 commits)")[![slusarz](https://avatars.githubusercontent.com/u/381003?v=4)](https://github.com/slusarz "slusarz (3 commits)")[![renan](https://avatars.githubusercontent.com/u/28046?v=4)](https://github.com/renan "renan (2 commits)")[![selsky](https://avatars.githubusercontent.com/u/380337?v=4)](https://github.com/selsky "selsky (1 commits)")[![KarimGeiger](https://avatars.githubusercontent.com/u/2329930?v=4)](https://github.com/KarimGeiger "KarimGeiger (1 commits)")

---

Tags

facebookoauth2graphmetaoidc

### Embed Badge

![Health badge](/badges/horde-service-facebook/health.svg)

```
[![Health](https://phpackages.com/badges/horde-service-facebook/health.svg)](https://phpackages.com/packages/horde-service-facebook)
```

###  Alternatives

[horde/horde

Horde base application

593.7k80](/packages/horde-horde)[tempest/framework

The PHP framework that gets out of your way.

2.3k37.6k21](/packages/tempest-framework)[horde/kronolith

Calendar and scheduling application

101.9k6](/packages/horde-kronolith)[telnyx/telnyx-php

Official Telnyx PHP SDK — APIs for Voice, SMS, MMS, WhatsApp, Fax, SIP Trunking, Wireless IoT, Call Control, and more. Build global communications on Telnyx's private carrier-grade network.

36826.2k2](/packages/telnyx-telnyx-php)[flow-php/flow

PHP ETL - Extract Transform Load - Data processing framework

86337.5k](/packages/flow-php-flow)[bushlanov-dev/max-bot-api-client-php

Max Bot API Client library

488.7k](/packages/bushlanov-dev-max-bot-api-client-php)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
