contacts_events-8.x-1.x-dev/modules/teams/src/TeamQueries.php

modules/teams/src/TeamQueries.php
<?php

namespace Drupal\contacts_events_teams;

use Drupal\contacts_events\Entity\Event;
use Drupal\contacts_events\Entity\TicketInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;

/**
 * Queries related to teams and applications.
 *
 * @package Drupal\contacts_events_teams
 */
class TeamQueries {

  /**
   * Entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * TeamQueries constructor.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   Entity type manager.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * Get the team counts for an event.
   *
   * @param \Drupal\contacts_events\Entity\Event $event
   *   The event.
   *
   * @return array
   *   Containing:
   *   - public: The number of public teams.
   *   - private: The number of private teams.
   *   - total: The total number of teams.
   */
  public function getTeamCounts(Event $event) {
    $team_storage = $this->entityTypeManager->getStorage('c_events_team');

    $stats = [
      'public' => 0,
      'private' => 0,
      'total' => 0,
    ];

    // Query teams for the event, grouped by visibility.
    $query = $team_storage->getAggregateQuery();
    $query->aggregate('id', 'COUNT');
    $query->groupBy('public');
    $query->condition('event', $event->id());
    foreach ($query->execute() as $row) {
      $stats[$row['public'] ? 'public' : 'private'] = $row['id_count'];
      $stats['total'] += $row['id_count'];
    }

    return $stats;
  }

  /**
   * Gets overally team application statistics by sub-category.
   *
   * @param \Drupal\contacts_events\Entity\Event $event
   *   The event.
   *
   * @return array
   *   An array of counts of applications in each status, keyed by top level
   *   then 2nd level category. A team directly in a top level category will
   *   have the top level as the 2nd level category key.
   */
  public function getTeamAppStatsBySubCategory(Event $event) {
    $stats = [];

    // Grouped by category.
    $query = $this->entityTypeManager
      ->getStorage('c_events_team_app')
      ->getAggregateQuery();
    $query->condition('event', $event->id());
    $query->condition('state', 'archived', '!=');
    $query->aggregate('id', 'COUNT');
    $query->groupBy('team.entity.category');
    $query->groupBy('state');

    $categories = $this->entityTypeManager
      ->getStorage('taxonomy_term')
      ->loadTree('contacts_events_teams');

    $parentage = [];
    foreach ($categories as $category) {
      if ($category->depth < 2) {
        $parent = $category;
      }
      $parentage[$category->tid] = $parent->tid;
    }

    foreach ($query->execute() as $row) {
      $tid = $parentage[$row['category']];
      $stats[$tid][$row['state']] = ($stats[$tid][$row['state']] ?? 0) + $row['id_count'];
    }

    // Query tickets that don't have a team application yet to get not started
    // counts.
    $query = $this->entityTypeManager
      ->getStorage('contacts_ticket')
      ->getAggregateQuery();
    // EntityQuery can't handle reverse entity references, so use a tag which
    // will add it to the SQL directly.
    // @see contacts_events_teams_query_contacts_events_teams_tickets_without_apps_alter
    $query->addTag('contacts_events_teams_tickets_without_apps');
    $query->condition('event', $event->id());
    $query->condition('is_team_ticket', TRUE);
    $query->condition('order_item.entity.state', 'team_app_in_progress');
    $query->aggregate('id', 'COUNT');
    $query->groupBy('team.entity.category');
    foreach ($query->execute() as $row) {
      $tid = $parentage[$row['category']];
      $stats[$tid]['not_started'] = ($stats[$tid]['not_started'] ?? 0) + $row['id_count'];
    }
    return $stats;
  }

  /**
   * Helper method that gets the team application for a ticket.
   *
   * @param \Drupal\contacts_events\Entity\TicketInterface $ticket
   *   The ticket.
   *
   * @return \Drupal\contacts_events_teams\Entity\TeamApplication|null
   *   The team application instance, or NULL if there isn't one.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function getTeamApplicationForTicket(TicketInterface $ticket) {
    $storage = $this->entityTypeManager->getStorage('c_events_team_app');
    $query = $storage->getQuery();
    $query->accessCheck(TRUE);
    $query->condition('ticket', $ticket->id());
    $query->condition('state', ['archived', 'rejected_notified'], 'NOT IN');
    $ids = $query->execute();

    if (count($ids) > 1) {
      throw new \Exception('Expected 1 team app per ticket - found ' . count($ids));
    }

    if (count($ids) === 0) {
      return NULL;
    }

    return $storage->load(reset($ids));
  }

}

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

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