Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 85
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
CrmUserContactSyncRelation
0.00% covered (danger)
0.00%
0 / 85
0.00% covered (danger)
0.00%
0 / 6
650
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getContactIdFromUserId
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
6
 getUserIdFromContactId
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
6
 getRelationIdFromUserId
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 getRelationIdFromContactId
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 relate
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 1
272
1<?php
2
3namespace Drupal\crm\Service;
4
5use Drupal\Core\Entity\EntityTypeManagerInterface;
6use Drupal\Core\Logger\LoggerChannelInterface;
7use Drupal\Core\Session\AccountProxyInterface;
8use Drupal\crm\CrmContactInterface;
9use Drupal\crm\CrmUserContactSyncRelationInterface;
10use Drupal\user\UserInterface;
11
12/**
13 * Relation service.
14 *
15 * @package Drupal\crm
16 */
17class CrmUserContactSyncRelation implements CrmUserContactSyncRelationInterface {
18
19  /**
20   * Relation Storage.
21   *
22   * @var \Drupal\Core\Entity\EntityStorageInterface
23   */
24  protected $relationStorage;
25
26  /**
27   * Entity Storage.
28   *
29   * @var \Drupal\Core\Entity\EntityStorageInterface
30   */
31  protected $contactStorage;
32
33  /**
34   * Logger channel.
35   *
36   * @var \Drupal\Core\Logger\LoggerChannelInterface
37   */
38  protected $logger;
39
40  /**
41   * Current user.
42   *
43   * @var \Drupal\Core\Session\AccountProxyInterface
44   */
45  protected $currentUser;
46
47  /**
48   * Rules.
49   *
50   * @var \Drupal\crm\Service\CrmUserSyncRules
51   */
52  protected $rules;
53
54  /**
55   * Settings.
56   *
57   * @var \Drupal\Core\Config\Config
58   */
59  protected $settings;
60
61  /**
62   * EntityTypeManager.
63   *
64   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
65   */
66  protected $entityTypeManager;
67
68  /**
69   * Constructs a CrmCoreUserSyncRelation object.
70   *
71   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
72   *   The entity type manager.
73   * @param \Drupal\Core\Logger\LoggerChannelInterface $logger
74   *   Logger channel.
75   * @param \Drupal\user\AccountProxyInterface $current_user
76   *   The current user.
77   */
78  public function __construct(
79    EntityTypeManagerInterface $entity_type_manager,
80    LoggerChannelInterface $logger,
81    AccountProxyInterface $current_user,
82  ) {
83    $this->relationStorage = $entity_type_manager->getStorage('crm_user_contact');
84    $this->contactStorage = $entity_type_manager->getStorage('crm_contact');
85    $this->logger = $logger;
86    $this->currentUser = $current_user;
87  }
88
89  /**
90   * {@inheritdoc}
91   */
92  public function getContactIdFromUserId($user_id) {
93    $contact_id = NULL;
94
95    $rids = $this->relationStorage->getQuery()
96      ->accessCheck(TRUE)
97      ->condition('user', $user_id)
98      ->range(0, 1)
99      ->execute();
100
101    if (!empty($rids)) {
102      $relation_id = reset($rids);
103      $relation = $this->relationStorage->load($relation_id);
104      $contact_id = $relation->getContactId();
105    }
106
107    return $contact_id;
108  }
109
110  /**
111   * {@inheritdoc}
112   */
113  public function getUserIdFromContactId($contact_id) {
114    $user_id = NULL;
115
116    $rids = $this->relationStorage->getQuery()
117      ->accessCheck(TRUE)
118      ->condition('crm_contact', $contact_id)
119      ->range(0, 1)
120      ->execute();
121
122    if (!empty($rids)) {
123      $relation_id = reset($rids);
124      $relation = $this->relationStorage->load($relation_id);
125      $user_id = $relation->getUserId();
126    }
127
128    return $user_id;
129  }
130
131  /**
132   * {@inheritdoc}
133   */
134  public function getRelationIdFromUserId($user_id) {
135    $rids = $this->relationStorage->getQuery()
136      ->accessCheck(TRUE)
137      ->condition('user', $user_id)
138      ->range(0, 1)
139      ->execute();
140
141    if (!empty($rids)) {
142      return reset($rids);
143    }
144
145    return NULL;
146  }
147
148  /**
149   * {@inheritdoc}
150   */
151  public function getRelationIdFromContactId($contact_id) {
152    $rids = $this->relationStorage->getQuery()
153      ->accessCheck(TRUE)
154      ->condition('crm_contact', $contact_id)
155      ->range(0, 1)
156      ->execute();
157
158    if (!empty($rids)) {
159      return reset($rids);
160    }
161
162    return NULL;
163  }
164
165  /**
166   * {@inheritdoc}
167   */
168  public function relate(UserInterface $account, ?CrmContactInterface $person = NULL) {
169    // No contact and $account->crm_core_no_auto_sync => no sync.
170    if (empty($person) && !empty($account->crm_core_no_auto_sync)) {
171      return NULL;
172    }
173
174    if (empty($person)) {
175      if ($this->getContactIdFromUserId($account->id())) {
176        // Account already has related contact.
177        return NULL;
178      }
179
180      $contact_type = $this->rules->getContactType($account);
181      if (!$contact_type) {
182        // No rules configured on this type.
183        return NULL;
184      }
185
186      $type = $this->entityTypeManager
187        ->getStorage('crm_contact_type')
188        ->load($contact_type);
189      $fields = $type->getPrimaryFields();
190
191      if ($this->settings->get('auto_sync_user_relate') && isset($fields['email']) && !empty($fields['email'])) {
192        $matches = $this->contactStorage->loadByProperties([
193          $fields['email'] => $account->getEmail(),
194          'type' => $contact_type,
195        ]);
196        if (count($matches) === 1) {
197          $person = reset($matches);
198        }
199      }
200
201      if (empty($person)) {
202        $person = $this->contactStorage->create(['type' => $contact_type]);
203        $person->setOwnerId($this->currentUser->id());
204        // For now we just add the name.
205        $person->name->given = $account->getAccountName();
206
207        if (isset($fields['email']) && !empty($fields['email'])) {
208          $person->set($fields['email'], $account->getEmail());
209        }
210        $person->save();
211      }
212    }
213
214    // Check if contact can be synchronized to a contact.
215    if (!$this->rules->valid($account, $person)) {
216      return NULL;
217    }
218
219    // Check if crm_core_user_sync relation exists for any of endpoint.
220    if ($this->getContactIdFromUserId($account->id()) ||
221      $this->getUserIdFromContactId($person->id())) {
222      return NULL;
223    }
224    $storage = $this->relationStorage->getStorage('crm_user_contact');
225    $relation = $storage->create();
226    $relation->setUser($account);
227    $relation->setContact($person);
228    $relation->save();
229
230    $this->logger->notice('User @user @uid has been synchronized to the contact @contact_id, relation @rid has been created.', [
231      '@user' => $account->getDisplayName(),
232      '@uid' => $account->id(),
233      '@contact_id' => $person->id(),
234      '@rid' => $relation->id(),
235    ]);
236
237    return $person;
238  }
239
240}