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