link_orcid-1.0.0-rc1/src/Controller/OrcidController.php

src/Controller/OrcidController.php
<?php

declare(strict_types=1);

namespace Drupal\link_orcid\Controller;

use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\Url;
use Drupal\link_orcid\OrcidClient;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Symfony\Component\HttpFoundation\Request;

/**
 * Controller for ORCID OAuth flow.
 */
final class OrcidController implements ContainerInjectionInterface {
  use StringTranslationTrait;

  public function __construct(
    private readonly OrcidClient $client,
    private readonly MessengerInterface $messenger,
    private readonly AccountProxyInterface $currentUser,
    private readonly EntityTypeManagerInterface $entityTypeManager,
    private readonly ConfigFactoryInterface $configFactory,
  ) {}

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container): static {
    return new static(
      $container->get('link_orcid.client'),
      $container->get('messenger'),
      $container->get('current_user'),
      $container->get('entity_type.manager'),
      $container->get('config.factory'),
    );
  }

  /**
   * Redirect to ORCID authorize endpoint.
   */
  public function start(Request $request): TrustedRedirectResponse {
    $state = bin2hex(random_bytes(16));
    $request->getSession()->set('link_orcid_state', $state);
    $redirect_uri = Url::fromRoute('link_orcid.oauth_callback', [], ['absolute' => TRUE])->toString();
    $auth_url = $this->client->getAuthorizeRedirect($state, $redirect_uri);
    return new TrustedRedirectResponse($auth_url);
  }

  /**
   * OAuth callback handler.
   */
  public function callback(Request $request): RedirectResponse {
    $code = $request->query->get('code');
    $state = $request->query->get('state');
    $saved_state = $request->getSession()->get('link_orcid_state');

    if (!$code || !$state || !$saved_state || !hash_equals((string) $saved_state, (string) $state)) {
      $this->messenger->addError($this->t('Missing or invalid parameters from ORCID.'));
      return $this->redirectToProfile();
    }

    try {
      $redirect_uri = Url::fromRoute('link_orcid.oauth_callback', [], ['absolute' => TRUE])->toString();
      $result = $this->client->exchangeCodeForToken((string) $code, (string) $state, $redirect_uri);
      if (!$result || empty($result['orcid'])) {
        $this->messenger->addError($this->t('Failed to link your ORCID.'));
        return $this->redirectToProfile();
      }

      $this->client->saveCurrentUserOrcid($result['orcid']);
      $this->messenger->addStatus($this->t('Your ORCID has been linked: @orcid', ['@orcid' => $result['orcid']]));
    }
    catch (\Throwable $e) {
      $this->messenger->addError($this->t('ORCID linking failed: @msg', ['@msg' => $e->getMessage()]));
    }

    return $this->redirectToProfile();
  }

  /**
   * Redirect to current user's profile edit page.
   */
  private function redirectToProfile(): RedirectResponse {
    $user_id = $this->currentUser->id();
    $url = Url::fromRoute('entity.user.edit_form', ['user' => $user_id])->toString();
    return new RedirectResponse($url);
  }

  /**
   * Unlink ORCID from current user.
   */
  public function unlink(): RedirectResponse {
    $user_id = $this->currentUser->id();
    $config = $this->configFactory->get('link_orcid.settings');
    $field = (string) $config->get('user_field');
    $user = $this->entityTypeManager->getStorage('user')->load($user_id);
    if ($user && $field && $user->hasField($field)) {
      $user->set($field, NULL);
      $user->save();
      $this->messenger->addStatus($this->t('Your ORCID has been unlinked.'));
    }
    else {
      $this->messenger->addError($this->t('Could not unlink ORCID.'));
    }
    return $this->redirectToProfile();
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc