View source
<?php
namespace Drupal\fb_instant_articles\Form;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Facebook\Authentication\AccessToken;
use Facebook\Facebook;
use Facebook\InstantArticles\Client\Helper;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
class ApiSettingsForm extends ConfigFormBase {
protected $currentRequest;
public function __construct(ConfigFactoryInterface $config_factory, Request $current_request) {
parent::__construct($config_factory);
$this->currentRequest = $current_request;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('config.factory'), $container
->get('request_stack')
->getCurrentRequest());
}
protected function getEditableConfigNames() {
return [
'fb_instant_articles.settings',
];
}
public function getFormId() {
return 'api_settings';
}
public function buildForm(array $form, FormStateInterface $form_state) {
$form = $this
->moduleActivationBuildForm($form, $form_state);
$form = $this
->moduleConfigPublishingBuildForm($form, $form_state);
return parent::buildForm($form, $form_state);
}
protected function moduleActivationBuildForm(array $form, FormStateInterface $form_state) {
$edit_state = '';
if ($edit = $this->currentRequest
->get('edit')) {
$edit_state = $edit;
}
$config = $this
->config('fb_instant_articles.settings');
$app_id = $config
->get('app_id');
$app_secret = $config
->get('app_secret');
$access_token = trim($config
->get('access_token'));
$page_id = $config
->get('page_id');
if (empty($app_id) || empty($app_secret) || $edit_state === 'fb_app_settings') {
$form = $this
->moduleActivationFbAppSettings($form, $app_id, $app_secret);
}
elseif (empty($access_token)) {
$form = $this
->moduleActivationConnectFbAccount($form, $app_id, $app_secret);
}
elseif (empty($page_id) || $edit_state === 'fb_page') {
$form = $this
->moduleActivationSelectFbPage($form, $app_id, $app_secret, $access_token, $page_id);
}
else {
$form = $this
->moduleActivationSummary($form, $app_id, $page_id);
}
return $form;
}
protected function moduleActivationFbAppSettings(array $form, $app_id, $app_secret) {
$form['module_activation'] = [
'#type' => 'details',
'#title' => t('Module activation'),
'#description' => $this
->t('You need a Facebook App to publish Instant Articles using this module. If you already have one, input the App ID and App Secret below, which you can find by clicking on your app <a href="https://developers.facebook.com/apps">here</a>. If you don\'t, <a href="https://developers.facebook.com/apps">create one here </a> before continuing.'),
'#open' => TRUE,
];
$form['module_activation']['app_id'] = [
'#type' => 'textfield',
'#title' => $this
->t('App ID'),
'#default_value' => $app_id,
'#size' => 30,
'#element_validate' => [
[
$this,
'validateFbAppId',
],
],
];
$form['module_activation']['app_secret'] = [
'#type' => 'textfield',
'#title' => $this
->t('App Secret'),
'#default_value' => $app_secret,
'#size' => 30,
];
$form['module_activation']['next'] = [
'#type' => 'submit',
'#value' => $this
->t('Next'),
'#submit' => [
[
$this,
'fbAppDetailsSubmit',
],
],
];
return $form;
}
public function validateFbAppId(array &$form, FormStateInterface $form_state) {
$app_id = $form_state
->getValue('app_id');
if (empty($app_id)) {
$form_state
->setErrorByName('app_id', $this
->t('You must enter the App ID before proceeding.'));
}
if (!is_numeric($app_id)) {
$form_state
->setErrorByName('app_id', $this
->t('The App ID that you entered is invalid.'));
}
}
public function fbAppDetailsSubmit(array &$form, FormStateInterface $form_state) {
$this
->config('fb_instant_articles.settings')
->set('app_id', $form_state
->getValue('app_id'))
->set('app_secret', $form_state
->getValue('app_secret'))
->set('access_token', '')
->set('page_access_token', '')
->set('page_id', '')
->set('page_name', '')
->save();
$form_state
->setRedirect('fb_instant_articles.api_settings_form');
}
protected function moduleActivationConnectFbAccount(array $form, $app_id, $app_secret) {
$fb = new Facebook([
'app_id' => $app_id,
'app_secret' => $app_secret,
'default_graph_version' => 'v2.5',
]);
$permissions = [
'pages_show_list',
'pages_manage_instant_articles',
];
$helper = $fb
->getRedirectLoginHelper();
$redirect_uri = Url::fromRoute('fb_instant_articles.login_callback', [], [
'absolute' => TRUE,
])
->toString();
$login_url = $helper
->getLoginUrl($redirect_uri, $permissions);
$form['module_activation'] = [
'#type' => 'details',
'#title' => $this
->t('Module activation'),
'#open' => TRUE,
];
$form['module_activation']['app_settings'] = [
'#markup' => '
<p>' . $this
->t('Your Facebook App ID is <strong>@app_id</strong>. <a href="?edit=fb_app_settings">Update Facebook app id</a>.', [
'@app_id' => $app_id,
]) . '</p>
<p>' . $this
->t('Login to Facebook and then select the Facebook Page where you will publish Instant Articles.') . '</p>
',
];
$form['module_activation']['login_button'] = [
'#markup' => '<p>' . $this
->t('<a class="button button--secondary" href="@login_url">Login with Facebook</a>', [
'@login_url' => $login_url,
]) . '</p>',
];
return $form;
}
protected function moduleActivationSelectFbPage(array $form, $app_id, $app_secret, $access_token, $page_id) {
$fb = new Facebook([
'app_id' => $app_id,
'app_secret' => $app_secret,
'default_graph_version' => 'v2.5',
]);
$expires = time() + 60 * 60 * 2;
$access_token = new AccessToken($access_token, $expires);
$sdk_helper = new Helper($fb);
$pages = $sdk_helper
->getPagesAndTokens($access_token);
$form['module_activation'] = [
'#type' => 'details',
'#title' => t('Module activation'),
'#open' => TRUE,
];
$form['module_activation']['fb_app_settings'] = [
'#markup' => '<p>' . $this
->t('Your Facebook App ID is <strong>@app_id</strong>. <a href="?edit=fb_app_settings">Update Facebook app id</a>.', [
'@app_id' => $app_id,
]) . '</p>',
];
$page_options = [];
foreach ($pages as $page) {
$page_options[$page
->getField('id')] = $page
->getField('name');
}
$form['module_activation']['page_id'] = [
'#type' => 'select',
'#title' => $this
->t('Facebook page'),
'#description' => $this
->t('Select the Facebook page where you will publish Instant Articles.'),
'#options' => $page_options,
'#default_value' => $page_id,
];
$form['module_activation']['next'] = [
'#type' => 'submit',
'#value' => $this
->t('Next'),
'#submit' => [
[
$this,
'fbPageSubmit',
],
],
];
return $form;
}
public function fbPageSubmit(array &$form, FormStateInterface $form_state) {
$config = $this
->config('fb_instant_articles.settings');
$app_id = $config
->get('app_id');
$app_secret = $config
->get('app_secret');
$fb = new Facebook([
'app_id' => $app_id,
'app_secret' => $app_secret,
'default_graph_version' => 'v2.5',
]);
$access_token = $config
->get('access_token');
$expires = time() + 60 * 60 * 2;
$access_token = new AccessToken($access_token, $expires);
$sdk_helper = new Helper($fb);
$pages = $sdk_helper
->getPagesAndTokens($access_token);
$page_id = $form_state
->getValue('page_id');
foreach ($pages as $page) {
if ($page
->getField('id') === $page_id) {
$page_name = $page
->getField('name');
$page_access_token = $page
->getField('access_token');
break;
}
}
if (isset($page_name) && isset($page_access_token)) {
$config
->set('page_id', $page_id)
->set('page_name', $page_name)
->save();
$config
->set('page_access_token', $page_access_token)
->save();
$this
->messenger()
->addStatus('Success! This Instant Articles module has been activated.');
$form_state
->setRedirect('fb_instant_articles.api_settings_form');
}
else {
$this
->messenger()
->addError('There was an error connecting with your Facebook page. Try again.');
}
}
protected function moduleActivationSummary(array $form, $app_id, $page_id) {
$page_name = $this
->config('fb_instant_articles.settings')
->get('page_name');
$form['module_activation'] = [
'#type' => 'details',
'#title' => t('Module activation'),
'#open' => TRUE,
];
$markup = [
'<p>' . $this
->t('Your Facebook App ID is <strong>@app_id</strong>. <a href="?edit=fb_app_settings">Update Facebook app id</a>.', [
'@app_id' => $app_id,
]) . '</p>',
];
if ($page_name) {
$markup[] = '<p>' . $this
->t('Your Facebook Page is <strong>@page_name</strong>. <a href="?edit=fb_page">Update facebook page</a>.', [
'@page_name' => $page_name,
]) . '</p>';
}
elseif ($page_id) {
$markup[] = '<p>' . $this
->t('Your Facebook Page ID is <strong>@page_id</strong>. <a href="?edit=fb_page">Update facebook page</a>.', [
'@page_id' => $page_id,
]) . '</p>';
}
$form['module_activation']['fb_app_settings'] = [
'#markup' => implode('', $markup),
];
return $form;
}
protected function moduleConfigPublishingBuildForm(array $form, FormStateInterface $form_state) {
$form['module_config']['publishing'] = [
'#type' => 'details',
'#title' => $this
->t('Publishing settings'),
'#open' => TRUE,
];
$form['module_config']['publishing']['development_mode'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Development Mode'),
'#default_value' => $this
->config('fb_instant_articles.settings')
->get('development_mode'),
'#description' => $this
->t('When publishing in development, none of your articles will be made live, and they will be saved as drafts you can edit in the Instant Articles library on your Facebook Page. Whether in development mode or not, articles will not be published live until you have submitted a sample batch to Facebook and passed a one-time review.'),
];
return $form;
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$this
->config('fb_instant_articles.settings')
->set('development_mode', $form_state
->getValue('development_mode'))
->save();
parent::submitForm($form, $form_state);
}
}