gamify-1.1.x-dev/modules/userpoints/src/Plugin/rest/resource/UserpointsRestResource.php

modules/userpoints/src/Plugin/rest/resource/UserpointsRestResource.php
<?php

namespace Drupal\userpoints\Plugin\rest\resource;

use Drupal\Core\Session\AccountProxyInterface;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Drupal\rest\ModifiedResourceResponse;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\userpoints\Service\UserPointsServiceInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\userpoints\Exception\UserPointsException;
use Exception;

/**
 * Provides a resource to handle bookings.
 *
 * @RestResource(
 *   id = "userpoints_rest_resource",
 *   label = @Translation("Userpoints rest resource"),
 *   uri_paths = {
 *     "https://www.drupal.org/link-relations/create" = "/api/userpoints"
 *   }
 * )
 */
class UserpointsRestResource extends ResourceBase {

  // Method-specific required parameters.
  const REQUIRED_PARAMS = [
    'add' => ['quantity'],
    'transfer' => ['quantity', 'target_entity_id'],
  ];

  /**
   * The current user instance.
   *
   * @var \Drupal\Core\Session\AccountProxyInterface
   */
  protected $currentUser;

  /**
   * Entity Type Manager instance.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The userpoints service.
   *
   * @var \Drupal\userpoints\Service\UserPointsServiceInterface
   */
  protected $userpointsService;

  /**
   * Constructs a new BookingRestResource object.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param array $serializer_formats
   *   The available serialization formats.
   * @param \Psr\Log\LoggerInterface $logger
   *   A logger instance.
   * @param \Drupal\Core\Session\AccountProxyInterface $current_user
   *   A current user instance.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   Entity type manager.
   * @param \Drupal\userpoints\Service\UserPointsServiceInterface $userpointsService
   *   The userpoints service.
   */
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    array $serializer_formats,
    LoggerInterface $logger,
    AccountProxyInterface $current_user,
    EntityTypeManagerInterface $entityTypeManager,
    UserPointsServiceInterface $userpointsService
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger);

    $this->currentUser = $current_user;
    $this->entityTypeManager = $entityTypeManager;
    $this->userpointsService = $userpointsService;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->getParameter('serializer.formats'),
      $container->get('logger.factory')->get('userpoints'),
      $container->get('current_user'),
      $container->get('entity_type.manager'),
      $container->get('userpoints.points')
    );
  }

  /**
   * {@inheritdoc}
   */
  protected function getBaseRouteRequirements($method) {
    // We check access for every operation separately so this route itself
    // can be accessed by all.
    return [
      '_access' => 'TRUE',
    ];
  }

  /**
   * Router function really.
   *
   * @param array $data
   *   The request data.
   *
   * @return \Drupal\rest\ModifiedResourceResponse
   *   The HTTP response object.
   */
  public function post(array $data) {
    if (!isset($data['op'])) {
      throw new BadRequestHttpException('Operation "op" parameter needs to be specified.');
    }

    $method = $data['op'] . 'Operation';
    if (method_exists($this, $method)) {
      // Merge in defaults.
      $data += [
        'entity_type_id' => 'user',
        'target_entity_type_id' => 'user',
      ];

      $this->checkAccess($data);
      $this->validateInput($data);
      $output = $this->{$method}($data);
      if (in_array($data['op'], ['add', 'transfer'], TRUE)) {
        return new ModifiedResourceResponse($output);
      }
      return new ResourceResponse($output);
    }
    else {
      throw new BadRequestHttpException('Invalid operation specified in "op" parameter.');
    }
  }

  /**
   * Input validator for all operations.
   *
   * @param array $data
   *   The request data.
   */
  protected function validateInput(array &$data) {
    $required = ['entity_id', 'type'];
    if (array_key_exists($data['op'], self::REQUIRED_PARAMS)) {
      $required += self::REQUIRED_PARAMS[$data['op']];
    }

    $missing = [];
    foreach ($required as $param) {
      if (!isset($data[$param])) {
        $missing[] = $param;
      }
    }

    if (!empty($missing)) {
      throw new BadRequestHttpException(sprintf('Missing request parameters: %s.', implode(', ', $missing)));
    }

    if (!isset($data['entity']) || !($data['entity'] instanceof EntityInterface)) {
      try {
        $data['entity'] = $this->entityTypeManager->getStorage($data['entity_type_id'])->load($data['entity_id']);
      }
      catch (Exception $e) {
        throw new BadRequestHttpException($e->getMessage());
      }
      if (!$data['entity']) {
        throw new BadRequestHttpException('Entity doesn\'t exist or cannot be loaded.');
      }
    }

    // Additional validation for the transfer method.
    if ($data['op'] === 'transfer') {
      try {
        $data['target_entity'] = $this->entityTypeManager->getStorage($data['target_entity_type_id'])->load($data['target_entity_id']);
      }
      catch (Exception $e) {
        throw new BadRequestHttpException($e->getMessage());
      }
      if (!$data['target_entity']) {
        throw new BadRequestHttpException('Target entity doesn\'t exist or cannot be loaded.');
      }
    }
  }

  /**
   * Access checker function.
   *
   * @param array $data
   *   The request data.
   */
  protected function checkAccess(array &$data) {
    $access = FALSE;

    if (isset($data['type'])) {
      switch ($data['op']) {
        case 'add':
        case 'transfer':
          if ($this->currentUser->hasPermission('manage all points')) {
            $access = TRUE;
          }
          elseif ($this->currentUser->hasPermission("manage {$data['type']} points")) {
            $access = TRUE;
          }
          break;

        case 'getQuantity':
        case 'getLog':
          if ($this->currentUser->hasPermission('view all points')) {
            $access = TRUE;
          }
          elseif ($this->currentUser->hasPermission("view {$data['type']} points")) {
            $access = TRUE;
          }
          else {
            if (isset($data['entity_type_id']) && isset($data['entity_id'])) {
              try {
                $data['entity'] = $this->entityTypeManager->getStorage($data['entity_type_id'])->load($data['entity_id']);
                if ($data['entity']->getEntityTypeId() === 'user' && $data['entity']->id() === $this->currentUser->id() && $this->currentUser->hasPermission("view own {$data['type']} points")) {
                  $access = TRUE;
                }
              }
              catch (Exception $e) {
                // Just do nothing, access will not be granted.
              }
            }
          }
          break;

      }
    }

    if (!$access) {
      throw new AccessDeniedHttpException(sprintf('Access denied.'));
    }
  }

  /**
   * Get current number of points.
   *
   * @param array $data
   *   The request data.
   */
  protected function getQuantityOperation(array $data) {
    return $this->userpointsService->getPoints($data['entity'], $data['type']);
  }

  /**
   * Get log.
   *
   * @param array $data
   *   The request data.
   */
  protected function getLogOperation(array $data) {
    return $this->userpointsService->getLog($data['entity'], $data['type']);
  }

  /**
   * Add / subtract user points.
   */
  protected function addOperation($data) {
    try {
      if (!isset($data['log'])) {
        $data['log'] = '';
      }
      $this->userpointsService->addPoints($data['quantity'], $data['type'], $data['entity'], $data['log']);
    }
    catch (UserPointsException $e) {
      throw new BadRequestHttpException($e->getMessage());
    }
  }

  /**
   * Transfer user points.
   */
  protected function transferOperation($data) {
    try {
      if (!isset($data['log'])) {
        $data['log'] = '';
      }
      $this->userpointsService->transferPoints($data['quantity'], $data['type'], $data['entity'], $data['target_entity'], $data['log']);
    }
    catch (UserPointsException $e) {
      throw new BadRequestHttpException($e->getMessage());
    }
  }

}

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

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