Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
63.16% covered (warning)
63.16%
24 / 38
40.00% covered (danger)
40.00%
2 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
RelationshipStatisticsCount
63.16% covered (warning)
63.16%
24 / 38
40.00% covered (danger)
40.00%
2 / 5
13.05
0.00% covered (danger)
0.00%
0 / 1
 create
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 defineOptions
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 buildOptionsForm
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 query
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 getRelationshipTypeOptions
94.74% covered (success)
94.74%
18 / 19
0.00% covered (danger)
0.00%
0 / 1
4.00
1<?php
2
3declare(strict_types=1);
4
5namespace Drupal\crm\Plugin\views\sort;
6
7use Drupal\Core\Entity\EntityTypeManagerInterface;
8use Drupal\Core\Form\FormStateInterface;
9use Drupal\Core\StringTranslation\TranslatableMarkup;
10use Drupal\views\Attribute\ViewsSort;
11use Drupal\views\Plugin\views\sort\SortPluginBase;
12use Symfony\Component\DependencyInjection\ContainerInterface;
13
14/**
15 * Sort handler for relationship statistics count.
16 */
17#[ViewsSort("crm_relationship_statistics_count")]
18class RelationshipStatisticsCount extends SortPluginBase {
19
20  /**
21   * The entity type manager.
22   *
23   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
24   */
25  protected EntityTypeManagerInterface $entityTypeManager;
26
27  /**
28   * {@inheritdoc}
29   */
30  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
31    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
32    $instance->entityTypeManager = $container->get('entity_type.manager');
33    return $instance;
34  }
35
36  /**
37   * {@inheritdoc}
38   */
39  protected function defineOptions() {
40    $options = parent::defineOptions();
41    $options['relationship_type'] = ['default' => ''];
42    return $options;
43  }
44
45  /**
46   * {@inheritdoc}
47   */
48  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
49    parent::buildOptionsForm($form, $form_state);
50
51    $form['relationship_type'] = [
52      '#type' => 'select',
53      '#title' => $this->t('Relationship type'),
54      '#description' => $this->t('Select the relationship type to sort by. Leave empty to sort by any relationship count.'),
55      '#options' => ['' => $this->t('- Any -')] + $this->getRelationshipTypeOptions(),
56      '#default_value' => $this->options['relationship_type'],
57    ];
58  }
59
60  /**
61   * {@inheritdoc}
62   */
63  public function query(): void {
64    $this->ensureMyTable();
65
66    $type_key = $this->options['relationship_type'] ?? '';
67
68    // If a specific relationship type is selected, add a condition.
69    if ($type_key) {
70      $this->query->addWhere(0, "$this->tableAlias.relationship_statistics_value", $type_key);
71    }
72
73    // Add the order by clause.
74    $this->query->addOrderBy($this->tableAlias, 'relationship_statistics_count', $this->options['order']);
75  }
76
77  /**
78   * Gets the relationship type options for the settings form.
79   *
80   * @return array
81   *   An array of options keyed by type key.
82   */
83  protected function getRelationshipTypeOptions(): array {
84    $options = [];
85
86    try {
87      $types = $this->entityTypeManager
88        ->getStorage('crm_relationship_type')
89        ->loadMultiple();
90
91      foreach ($types as $type) {
92        if ($type->get('asymmetric')) {
93          // For asymmetric relationships, add both positions.
94          $label_a = $type->get('label_a') ?? $type->label();
95          $label_b = $type->get('label_b') ?? $type->label();
96          $options[$type->id() . ':a'] = new TranslatableMarkup('@type: @label', [
97            '@type' => $type->label(),
98            '@label' => $label_a,
99          ]);
100          $options[$type->id() . ':b'] = new TranslatableMarkup('@type: @label', [
101            '@type' => $type->label(),
102            '@label' => $label_b,
103          ]);
104        }
105        else {
106          // For symmetric relationships, use the main label.
107          $options[$type->id()] = $type->label();
108        }
109      }
110    }
111    catch (\Exception $e) {
112      // Return empty options if entity type manager fails.
113    }
114
115    return $options;
116  }
117
118}