You are here

public function ReservationConflicts::getErrors in MERCI (Manage Equipment Reservations, Checkout and Inventory) 8.2

Overrides ReservationConflictsInterface::getErrors

File

src/ReservationConflicts.php, line 104
Contains \Drupal\merci\ReservationConflicts. Abstraction of the selection logic of an entity reference field.

Class

ReservationConflicts
A null implementation of EntityReference_SelectionHandler.

Namespace

Drupal\merci

Code

public function getErrors($delta = NULL) {
  if ($this->errors === NULL) {
    $this
      ->validate();
    $entity = $this->entity;
    $entity_type = $this->entity
      ->getEntityTypeId();
    $errors = array();

    // Determine if reserving too many of the same item.
    // How many of each item are we trying to reserve?
    if ($entity
      ->hasField($this->parent_quantity_field)) {
      $quantity_reserved = $entity
        ->get($this->parent_quantity_field)->value;
    }
    else {
      $quantity_reserved = 1;
    }

    // How many times was the item selected?
    foreach ($entity
      ->get($this->item_field) as $delta => $resource) {
      $item_id = $resource->target_id;
      if (empty($item_id)) {
        continue;
      }
      if (empty($item_count[$item_id])) {
        $item_count[$item_id] = 0;
      }
      $item_count[$item_id] += $quantity_reserved;
      if ($resource->entity
        ->hasField($this->quantity_field)) {
        $quantity_reservable = $resource->entity
          ->get($this->quantity_field)->value;
      }
      else {
        $quantity_reservable = 1;
      }

      // Did we select too many?
      if ($item_count[$item_id] > $quantity_reservable) {

        // Selected to many.
        if (!array_key_exists($delta, $errors)) {
          $errors[$delta] = array();
        }
        $parents_path = implode('][', array(
          $this->item_field,
          'und',
          $delta,
          'target_id',
        ));
        $errors[$delta][MERCI_ERROR_TOO_MANY] = t('@name: You have selected too many of the same item.  We only have @quantity available but you reserved @reserved.', array(
          '@name' => $resource->entity
            ->label(),
          '@quantity' => $quantity_reservable,
          '@reserved' => $item_count[$item_id],
        ));
      }
    }
    $total_buckets_filled = $this
      ->getTotalBucketsFilled();
    $total_buckets_filled = $total_buckets_filled ? $total_buckets_filled : array();
    $reservation_counter = array();
    foreach ($total_buckets_filled as $delta => $start_dates) {
      $conflict_errors = array();
      $resource = $entity
        ->get($this->item_field)[$delta];
      if ($resource->entity
        ->hasField($this->quantity_field)) {
        $quantity_reservable = $resource->entity
          ->get($this->quantity_field)->value;
      }
      else {
        $quantity_reservable = 1;
      }
      $item_id = $resource->target_id;
      if (empty($reservation_counter[$item_id])) {
        $reservation_counter[$item_id] = 0;
      }
      $reservation_counter[$item_id] += $quantity_reserved;
      foreach ($this->entity
        ->get($this->date_field) as $dates) {
        $used_buckets = $this
          ->getTotalBucketsFilled($delta, $dates);

        // Determine if there are conflicts for this date and item.
        if ($quantity_reservable >= $used_buckets + $reservation_counter[$item_id]) {
          continue;
        }

        // Load each conflicting entity so we can show information about it to
        // the user.
        $ids = array();
        foreach ($this
          ->getConflicts($delta, $dates) as $conflict) {
          $ids[] = $conflict->parent_id;
        }

        // Load the entities which hold the conflicting item.
        $entities = \Drupal::entityManager()
          ->getStorage($entity_type)
          ->loadMultiple($ids);
        $line_items = array();
        foreach ($entities as $id => $line_item) {
          $entity_uri = $line_item
            ->toUrl();

          //entity_uri($entity_type, $line_item);
          $entity_label = $line_item
            ->label();

          //entity_label($entity_type, $line_item);
          $line_items[] = Link::fromTextAndUrl($entity_label, $entity_uri)
            ->toString();
        }
        $date_start = $dates
          ->get('value')
          ->getValue();

        // Don't show the date repeat rule in the error message.
        // @FIXME

        //$render_dates = field_view_value($entity_type, $entity->value(), $this->date_field, $dates);
        $conflict_errors[$date_start] = t('@name is already reserved by: :items for selected dates @dates', array(
          '@name' => $resource->entity
            ->label(),
          ':items' => implode(', ', $line_items),
          '@dates' => render($render_dates),
        ));
      }
      if ($conflict_errors) {
        if (!array_key_exists($delta, $errors)) {
          $errors[$delta] = array();
        }
        $errors[$delta][MERCI_ERROR_CONFLICT] = $conflict_errors;
      }
    }
    $this->errors = $errors;
  }
  return $this->errors;
}