jsonapi_extras-8.x-3.16/modules/jsonapi_defaults/src/Controller/EntityResource.php

modules/jsonapi_defaults/src/Controller/EntityResource.php
<?php

namespace Drupal\jsonapi_defaults\Controller;

use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Logger\LoggerChannelInterface;
use Drupal\jsonapi\Controller\EntityResource as JsonApiEntityResource;
use Drupal\jsonapi\Query\OffsetPage;
use Drupal\jsonapi\Query\Sort;
use Drupal\jsonapi\ResourceType\ResourceType;
use Drupal\jsonapi_defaults\JsonapiDefaultsInterface;
use Drupal\jsonapi_extras\Entity\JsonapiResourceConfig;
use Symfony\Component\HttpFoundation\Request;

/**
 * Overrides jsonapi module EntityResource controller.
 */
class EntityResource extends JsonApiEntityResource {

  /**
   * The jsonapi defaults service.
   *
   * @var \Drupal\jsonapi_defaults\JsonapiDefaultsInterface
   */
  protected JsonapiDefaultsInterface $jsonapiDefaults;

  /**
   * The logger service.
   *
   * @var \Drupal\Core\Logger\LoggerChannelInterface
   */
  protected LoggerChannelInterface $logger;

  /**
   * Sets the jsonapi defaults service.
   *
   * @param \Drupal\jsonapi_defaults\JsonapiDefaultsInterface $jsonapiDefaults
   *   The JsonapiDefaults object.
   *
   * @return $this
   */
  public function setJsonapiDefaults(JsonapiDefaultsInterface $jsonapiDefaults): static {
    $this->jsonapiDefaults = $jsonapiDefaults;
    return $this;
  }

  /**
   * Sets the logger.
   *
   * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $loggerFactory
   *   The logger factory.
   *
   * @return $this
   */
  public function setLogger(LoggerChannelFactoryInterface $loggerFactory): static {
    $this->logger = $loggerFactory->get('jsonapi_defaults');
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  protected function getJsonApiParams(Request $request, ResourceType $resource_type) {
    try {
      $resourceConfig = $this->jsonapiDefaults->getResourceConfigFromRequest($request);
    }
    catch (\LengthException $e) {
      $this->logger->error($e);
      $resourceConfig = NULL;
    }

    if (!$resourceConfig instanceof JsonapiResourceConfig) {
      return parent::getJsonApiParams($request, $resource_type);
    }

    $default_filter_input = $resourceConfig->getThirdPartySetting(
      'jsonapi_defaults',
      'default_filter',
      []
    );

    $default_sorting_input = $resourceConfig->getThirdPartySetting(
      'jsonapi_defaults',
      'default_sorting',
      []
    );

    $default_filter = [];
    $default_sorting = [];

    foreach ($default_filter_input as $key => $value) {
      if (substr($key, 0, 6) === 'filter') {
        $key = str_replace('filter:', '', $key);
        // @todo Replace this with use of the NestedArray utility.
        $this->setFilterValue($default_filter, $key, $value);
      }
    }

    foreach ($default_sorting_input as $key => $value) {
      if (substr($key, 0, 4) === 'sort') {
        $key = str_replace('sort:', '', $key);
        // @todo Replace this with use of the NestedArray utility.
        $this->setFilterValue($default_sorting, $key, $value);
      }
    }

    $filters = array_merge(
      $default_filter,
      $request->query->all('filter')
    );

    $sort = [];
    if ($request->query->has('sort')) {
      $sort = Sort::createFromQueryParameter($request->query->all()['sort'])->fields();
    }
    $sorting = array_merge($default_sorting, $sort);

    if (!empty($filters)) {
      $request->query->set('filter', $filters);
    }

    if (!empty($sorting)) {
      $request->query->set('sort', $sorting);
    }

    // Implements overridden page limits.
    $params = parent::getJsonApiParams($request, $resource_type);
    $this->setPageLimit($request, $resourceConfig, $params);
    return $params;
  }

  /**
   * {@inheritdoc}
   */
  public function getIncludes(Request $request, $data) {
    if (!$request->get('_on_relationship')) {
      try {
        $resourceConfig = $this->jsonapiDefaults->getResourceConfigFromRequest($request);
      }
      catch (\LengthException $e) {
        $this->logger->error($e);
        $resourceConfig = NULL;
      }

      if (!$resourceConfig) {
        return parent::getIncludes($request, $data);
      }

      $defaultIncludes = $resourceConfig->getThirdPartySetting(
        'jsonapi_defaults',
        'default_include',
        []
      );

      if (!empty($defaultIncludes) && $request->query->get('include') === NULL) {
        $includes = array_unique(array_filter(array_merge($defaultIncludes)));
        $request->query->set('include', implode(',', $includes));
      }
    }

    return parent::getIncludes($request, $data);
  }

  /**
   * Set filter into nested array.
   *
   * @param array $arr
   *   The default filter.
   * @param string $path
   *   The filter path.
   * @param mixed $value
   *   The filter value.
   */
  private function setFilterValue(array &$arr, $path, $value) {
    $keys = explode('#', $path);

    foreach ($keys as $key) {
      $arr = &$arr[$key];
    }

    $arr = $value;
  }

  /**
   * Get amount of items displayed per page considering the request query.
   *
   * Fall back to the JSON:API standard value of 50 if not customized.
   *
   * @param array $page_params
   *   The values of the page query parameter of the request.
   * @param \Drupal\jsonapi_extras\Entity\JsonapiResourceConfig $resource_config
   *   This resource's config entity.
   *
   * @return int
   *   Max number of items.
   */
  protected function determinePageLimit(array $page_params, JsonapiResourceConfig $resource_config) {
    $query_limit = !empty($page_params['limit']) ? (int) $page_params['limit'] : OffsetPage::SIZE_MAX;
    $page_limit = $resource_config->getThirdPartySetting(
      'jsonapi_defaults',
      'page_limit'
    ) ?: OffsetPage::SIZE_MAX;
    return min($query_limit, (int) $page_limit);
  }

  /**
   * Sets a jsonapi parameter for the page limit if applicable.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request object.
   * @param \Drupal\jsonapi_extras\Entity\JsonapiResourceConfig $resource_config
   *   The resource config entity to check for an override of the page limit.
   * @param array $params
   *   The parameters passed to jsonapi, passed by reference.
   */
  protected function setPageLimit(Request $request, JsonapiResourceConfig $resource_config, array &$params) {
    if ($request->query->has('page')) {
      $page_params = $request->query->all('page');
      $offset = array_key_exists(OffsetPage::OFFSET_KEY, $page_params) ? (int) $page_params[OffsetPage::OFFSET_KEY] : OffsetPage::DEFAULT_OFFSET;
      $params[OffsetPage::KEY_NAME] = new OffsetPage(
        $offset,
        $this->determinePageLimit($page_params, $resource_config)
      );
    }
  }

}

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

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