<?php
|
/**
|
* Facebook Integration
|
* Handles Facebook posts, page information, events, and OAuth authentication
|
*/
|
|
namespace JVBase\integrations\services;
|
use Exception;
|
use JVBase\integrations\Admin;
|
use JVBase\integrations\Instance;
|
use JVBase\integrations\Integrations;
|
use JVBase\integrations\OAuth;
|
use JVBase\integrations\OAuthCredentials;
|
use JVBase\integrations\OAuthURLs;
|
use JVBase\integrations\Requests;
|
use JVBase\integrations\SyncDefaults;
|
use JVBase\integrations\SyncFrom;
|
use JVBase\integrations\SyncTo;
|
use JVBase\integrations\UserConnection;
|
use WP_Error;
|
|
if (!defined('ABSPATH')) {
|
exit;
|
}
|
|
class Facebook extends Integrations
|
{
|
use Admin,
|
Instance,
|
OAuth,
|
UserConnection,
|
Requests,
|
SyncFrom,
|
SyncTo,
|
SyncDefaults;
|
|
protected function __construct()
|
{
|
$this->service_name = 'facebook';
|
$this->title = 'Facebook';
|
$this->icon = 'facebook-logo';
|
|
$this->apiVersion = 'v25.0';
|
|
$this->canSync = [
|
'create' => true,
|
'update' => true,
|
'delete' => true
|
];
|
|
$this->defineFields();
|
$this->defineInstructions();
|
$this->defineOAuth();
|
$this->defineActions();
|
|
$this->baseUrl = 'https://graph.facebook.com/'.$this->apiVersion;
|
$this->baseOAuthUrl = 'https://www.facebook.com/'.$this->apiVersion;
|
|
parent::__construct();
|
}
|
|
protected function defineFields():void
|
{
|
$client_id = $this->addField(
|
'client_id',
|
'App ID',
|
'text',
|
'manage_options'
|
);
|
$client_id->setRequired();
|
$client_id->setHint('Your Facebook App ID from developers.facebook.com');
|
|
$client_secret = $this->addField(
|
'client_secret',
|
'App Secret',
|
'text',
|
'manage_options'
|
);
|
$client_secret->setRequired();
|
$client_secret->setSubType('password');
|
|
$pages = $this->addField('pages', 'Pages', 'select', [$this, 'testUserCanConnect']);
|
$pages->setHidden();
|
$pages->setOptions($this->getPageOptions());
|
|
$page = $this->addField('page_id', 'Connect to Page', 'select', [$this, 'testUserCanConnect']);
|
$page->setOptions($this->loadCredentials()['pages']??[]);
|
$page->setHint('Select the page you want to connect this site to.');
|
}
|
public function testUserCanConnect():bool
|
{
|
$user = get_current_user_id();
|
return $this->userCanConnect($user);
|
}
|
protected function getPageOptions():array
|
{
|
return $this->loadCredentials()['pages']??[];
|
}
|
protected function defineInstructions():void
|
{
|
|
}
|
protected function defineActions():void
|
{
|
$this->addAction(
|
'Select Page',
|
[$this, 'handleSelectPage'],
|
'select_page',
|
'plugs-connected'
|
);
|
|
$this->addAction(
|
'Fetch Pages',
|
[$this, 'getPages'],
|
'fetch_pages',
|
'download-simple'
|
);
|
}
|
public function defineOAuth():void
|
{
|
$this->oauth = new OAuthURLs(
|
'https://www.facebook.com/'.$this->apiVersion.'/dialog/oauth',
|
'https://graph.facebook.com/'.$this->apiVersion.'/oauth/access_token',
|
'https://graph.facebook.com/'.$this->apiVersion.'/me/permissions'
|
);
|
$this->oathScopes = [
|
'pages_show_list',
|
'business_management',
|
'pages_manage_metadata',
|
'pages_manage_posts'
|
];
|
}
|
public function getServiceDescription():string
|
{
|
return 'Connect your Facebook Page to share posts, events, and engage with your audience.';
|
}
|
protected function initialize(): void
|
{
|
// TODO: Implement initialize() method.
|
}
|
|
protected function refreshAccessToken(OAuthCredentials $credentials): array
|
{
|
return $this->response(false, 'Not set up yet');
|
}
|
|
protected function getRequestHeaders(): array
|
{
|
return [
|
'Content-Type' => 'application/json',
|
'Accept' => 'application/json'
|
];
|
}
|
|
|
protected function handleResponse(\WP_Error|array $response, string $method, string $endpoint): array
|
{
|
if (is_wp_error($response) && $response->get_error_message() === 'rate_limit_exceeded') {
|
return $this->response(false, 'Rate limit exceeded');
|
}
|
|
$endpoint = str_replace($this->baseUrl, '', $endpoint);
|
return match ($endpoint) {
|
'/me/accounts?access_token='.$this->getAccessToken() => $this->handleGetPagesResponse($response, $method),
|
default => $this->response(false, 'Unhandled Response for ' . $endpoint . ' endpoint, with method: ' . $method),
|
};
|
}
|
/************************************************************
|
* UTILITY METHODS
|
************************************************************/
|
protected function getPageID():string|false
|
{
|
return $this->loadCredentials()['page_id']??false;
|
}
|
protected function getClientID():string|false
|
{
|
return $this->loadCredentials()['client_id']??false;
|
}
|
protected function getClientSecret():string|false
|
{
|
return $this->loadCredentials()['client_secret']??false;
|
}
|
|
protected function getFBUserID():string|false
|
{
|
$cred = $this->loadCredentials();
|
if ($this->isSetUp() && !array_key_exists('user_id', $cred)) {
|
$resp = $this->getRequest(
|
$this->baseUrl.'/me?access_token='.$cred['access_token'],
|
);
|
if ($resp && !is_wp_error($resp)) {
|
$tmp['user_id'] = $resp['id'];
|
$tmp['user_name'] = $resp['name'];
|
|
$this->saveCredentials($tmp, false);
|
}
|
$cred = array_merge($cred, $tmp);
|
}
|
return $cred['user_id']??false;
|
}
|
public function getPages():array|false
|
{
|
if (!$this->getAccessToken()) {
|
return false;
|
}
|
|
try {
|
return $this->getRequest(
|
$this->apiBase.'/me/accounts?access_token='.$this->getAccessToken(),
|
);
|
} catch (Exception $e) {
|
$this->logError(
|
'getPages',
|
'Failed to load pages',
|
[
|
'error' => $e->getMessage(),
|
]
|
);
|
}
|
return [];
|
}
|
protected function handleGetPagesResponse(WP_Error|array $response, string $method):array
|
{
|
$options = [];
|
foreach ($response as $page) {
|
if (array_key_exists('id', $page) && array_key_exists('name', $page)) {
|
$options[$page['id']] = $page['name'];
|
}
|
}
|
if (!empty($options)) {
|
$this->saveCredentials(['pages' => $options]);
|
}
|
return $this->response(true, 'Found pages', $options);
|
}
|
|
/************************************************************
|
* ACTIONS
|
************************************************************/
|
public function handleSelectPage(array $data):array
|
{
|
if (empty($data['page_id']??'')) {
|
return $this->response(false, 'No page selected.');
|
}
|
|
$cred = [
|
'page_id' => sanitize_text_field($data['page_id']),
|
];
|
return $this->saveCredentials($cred, false);
|
}
|
|
public function handleFetchPages():array
|
{
|
try {
|
$pages = $this->getPages();
|
if (!$pages) {
|
return $this->response(false, 'No pages found');
|
}
|
|
return $this->response(
|
true,
|
sprintf('Found %d page(s)', count($pages)),
|
$pages
|
);
|
} catch (Exception $e) {
|
return $this->response(false, 'Failed to fetch pages: '.$e->getMessage());
|
}
|
}
|
|
protected function setContentTypes(): void
|
{
|
// TODO: Implement setContentTypes() method.
|
}
|
|
protected function formatForService(int $itemID, string $type = 'post'): array
|
{
|
return [];
|
}
|
}
|