Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
207 / 207 |
|
100.00% |
3 / 3 |
CRAP | |
100.00% |
1 / 1 |
Contact | |
100.00% |
207 / 207 |
|
100.00% |
3 / 3 |
11 | |
100.00% |
1 / 1 |
preSave | |
100.00% |
17 / 17 |
|
100.00% |
1 / 1 |
4 | |||
postSave | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
6 | |||
baseFieldDefinitions | |
100.00% |
182 / 182 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | declare(strict_types=1); |
4 | |
5 | namespace Drupal\crm\Entity; |
6 | |
7 | use Drupal\Core\Entity\Attribute\ContentEntityType; |
8 | use Drupal\Core\Entity\EntityChangedTrait; |
9 | use Drupal\Core\Entity\EntityPublishedTrait; |
10 | use Drupal\Core\Entity\EntityStorageInterface; |
11 | use Drupal\Core\Entity\EntityTypeInterface; |
12 | use Drupal\Core\Entity\RevisionableContentEntityBase; |
13 | use Drupal\Core\Entity\RevisionLogEntityTrait; |
14 | use Drupal\Core\Entity\Routing\AdminHtmlRouteProvider; |
15 | use Drupal\Core\Field\BaseFieldDefinition; |
16 | use Drupal\Core\StringTranslation\TranslatableMarkup; |
17 | use Drupal\crm\ContactAccessControlHandler; |
18 | use Drupal\crm\ContactListBuilder; |
19 | use Drupal\crm\CrmContactInterface; |
20 | use Drupal\crm\Form\ContactForm; |
21 | use Drupal\inline_entity_form\Plugin\Field\FieldWidget\InlineEntityFormComplex; |
22 | use Drupal\views\EntityViewsData; |
23 | use Drupal\Core\Entity\ContentEntityDeleteForm; |
24 | use Drupal\crm\Field\AgeFieldItemList; |
25 | |
26 | /** |
27 | * CRM contact. |
28 | * |
29 | * A contact can be a person, an organization, a household, etc. |
30 | */ |
31 | #[ContentEntityType( |
32 | id: 'crm_contact', |
33 | label: new TranslatableMarkup('CRM Contact'), |
34 | label_collection: new TranslatableMarkup('CRM Contacts'), |
35 | label_singular: new TranslatableMarkup('crm contact'), |
36 | label_plural: new TranslatableMarkup('crm contacts'), |
37 | label_count: [ |
38 | 'singular' => '@count crm contact', |
39 | 'plural' => '@count crm contacts', |
40 | ], |
41 | bundle_label: new TranslatableMarkup('Contact type'), |
42 | handlers: [ |
43 | 'list_builder' => ContactListBuilder::class, |
44 | 'views_data' => EntityViewsData::class, |
45 | 'access' => ContactAccessControlHandler::class, |
46 | 'form' => [ |
47 | 'default' => ContactForm::class, |
48 | 'delete' => ContentEntityDeleteForm::class, |
49 | ], |
50 | 'route_provider' => [ |
51 | 'html' => AdminHtmlRouteProvider::class, |
52 | ], |
53 | ], |
54 | base_table: 'crm_contact', |
55 | revision_table: 'crm_contact_revision', |
56 | show_revision_ui: TRUE, |
57 | bundle_entity_type: 'crm_contact_type', |
58 | field_ui_base_route: 'entity.crm_contact_type.edit_form', |
59 | translatable: FALSE, |
60 | admin_permission: 'administer crm', |
61 | entity_keys: [ |
62 | 'id' => 'id', |
63 | 'revision' => 'revision_id', |
64 | 'bundle' => 'bundle', |
65 | 'label' => 'name', |
66 | 'uuid' => 'uuid', |
67 | 'status' => 'status', |
68 | 'published' => 'status', |
69 | ], |
70 | revision_metadata_keys: [ |
71 | 'revision_user' => 'revision_uid', |
72 | 'revision_created' => 'revision_timestamp', |
73 | 'revision_log_message' => 'revision_log', |
74 | ], |
75 | links: [ |
76 | 'add-page' => '/crm/contact/add', |
77 | 'add-form' => '/crm/contact/add/{crm_contact_type}', |
78 | 'canonical' => '/crm/contact/{crm_contact}', |
79 | 'edit-form' => '/crm/contact/{crm_contact}/edit', |
80 | 'delete-form' => '/crm/contact/{crm_contact}/delete', |
81 | 'collection' => '/admin/content/crm/contact', |
82 | ], |
83 | )] |
84 | class Contact extends RevisionableContentEntityBase implements CrmContactInterface { |
85 | use EntityChangedTrait; |
86 | use EntityPublishedTrait; |
87 | use RevisionLogEntityTrait; |
88 | |
89 | /** |
90 | * {@inheritdoc} |
91 | */ |
92 | public function preSave(EntityStorageInterface $storage) { |
93 | parent::preSave($storage); |
94 | $this->setNewRevision(); |
95 | |
96 | // If type is person, set the label field to the name field. |
97 | if ($this->bundle() == 'person' && $this->hasField('full_name')) { |
98 | $name_array = $this->get('full_name')->getValue(); |
99 | if (empty($name_array)) { |
100 | return; |
101 | } |
102 | $name_array = $name_array[0]; |
103 | $name_array['preferred'] = $this->get('preferred_name')->value; |
104 | $name_array['alternative'] = array_map(function ($alias) { |
105 | return $alias['value']; |
106 | }, $this->get('aliases')->getValue()); |
107 | $name_array['alternative'] = implode(', ', $name_array['alternative']); |
108 | $name_format = $this->bundle->entity->getThirdPartySetting('crm', 'name_format') ?? 'default'; |
109 | |
110 | $name_formatter = \Drupal::service('name.formatter'); |
111 | $formatted_name = $name_formatter->format($name_array, $name_format); |
112 | |
113 | $formatted_name = html_entity_decode($formatted_name, ENT_QUOTES | ENT_HTML5, 'UTF-8'); |
114 | $this->set('name', $formatted_name); |
115 | |
116 | } |
117 | |
118 | } |
119 | |
120 | /** |
121 | * {@inheritdoc} |
122 | */ |
123 | public function postSave(EntityStorageInterface $storage, $update = TRUE) { |
124 | parent::postSave($storage, $update); |
125 | |
126 | $detail_fields = ['emails', 'telephones', 'addresses']; |
127 | foreach ($detail_fields as $detail_field) { |
128 | if (!$this->hasField($detail_field)) { |
129 | continue; |
130 | } |
131 | foreach ($this->get($detail_field) as $item) { |
132 | $detail = $item->entity; |
133 | if ($detail && $detail->get('crm_contact')->isEmpty()) { |
134 | $detail->set('crm_contact', $this->id()); |
135 | $detail->save(); |
136 | } |
137 | } |
138 | |
139 | } |
140 | } |
141 | |
142 | /** |
143 | * {@inheritdoc} |
144 | */ |
145 | public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { |
146 | $fields = parent::baseFieldDefinitions($entity_type); |
147 | |
148 | $fields['name'] = BaseFieldDefinition::create('string') |
149 | ->setRevisionable(TRUE) |
150 | ->setLabel(t('Name')) |
151 | ->setRequired(TRUE) |
152 | ->setSetting('max_length', 255) |
153 | ->setDisplayOptions('form', [ |
154 | 'type' => 'string_textfield', |
155 | 'weight' => -5, |
156 | ]) |
157 | ->setDisplayConfigurable('form', TRUE) |
158 | ->setDisplayOptions('view', [ |
159 | 'label' => 'hidden', |
160 | 'type' => 'string', |
161 | 'weight' => -5, |
162 | ]) |
163 | ->setDisplayConfigurable('view', TRUE); |
164 | |
165 | $fields['emails'] = BaseFieldDefinition::create('entity_reference') |
166 | ->setLabel(t('Emails')) |
167 | ->setRevisionable(TRUE) |
168 | ->setCardinality(-1) |
169 | ->setSetting('target_type', 'crm_contact_detail') |
170 | ->setSetting('handler_settings', ['target_bundles' => ['email']]) |
171 | ->setDisplayConfigurable('form', TRUE) |
172 | ->setDisplayOptions('form', [ |
173 | 'type' => 'inline_entity_form_complex', |
174 | 'weight' => 8, |
175 | 'settings' => [ |
176 | 'allow_new' => TRUE, |
177 | 'allow_existing' => FALSE, |
178 | 'removed_reference' => InlineEntityFormComplex::REMOVED_DELETE, |
179 | 'match_operator' => 'CONTAINS', |
180 | 'allow_duplicate' => FALSE, |
181 | 'form_mode' => 'default', |
182 | 'override_labels' => TRUE, |
183 | 'label_singular' => t('email'), |
184 | 'label_plural' => t('emails'), |
185 | 'collapsible' => FALSE, |
186 | 'collapsed' => FALSE, |
187 | 'revision' => TRUE, |
188 | ], |
189 | ]) |
190 | ->setDisplayConfigurable('view', TRUE) |
191 | ->setDisplayOptions('view', [ |
192 | 'label' => 'hidden', |
193 | 'type' => 'entity_reference_entity_view', |
194 | 'weight' => -5, |
195 | 'settings' => [ |
196 | 'view_mode' => 'default', |
197 | 'link' => FALSE, |
198 | ], |
199 | ]); |
200 | |
201 | $fields['telephones'] = BaseFieldDefinition::create('entity_reference') |
202 | ->setLabel(t('Telephones')) |
203 | ->setRevisionable(TRUE) |
204 | ->setCardinality(-1) |
205 | ->setSetting('target_type', 'crm_contact_detail') |
206 | ->setSetting('handler_settings', ['target_bundles' => ['telephone']]) |
207 | ->setDisplayConfigurable('form', TRUE) |
208 | ->setDisplayOptions('form', [ |
209 | 'type' => 'inline_entity_form_complex', |
210 | 'weight' => 9, |
211 | 'settings' => [ |
212 | 'allow_new' => TRUE, |
213 | 'allow_existing' => FALSE, |
214 | 'removed_reference' => InlineEntityFormComplex::REMOVED_DELETE, |
215 | 'match_operator' => 'CONTAINS', |
216 | 'allow_duplicate' => FALSE, |
217 | 'form_mode' => 'default', |
218 | 'override_labels' => TRUE, |
219 | 'label_singular' => t('telephone'), |
220 | 'label_plural' => t('telephones'), |
221 | 'collapsible' => FALSE, |
222 | 'collapsed' => FALSE, |
223 | 'revision' => TRUE, |
224 | ], |
225 | ]) |
226 | ->setDisplayConfigurable('view', TRUE) |
227 | ->setDisplayOptions('view', [ |
228 | 'label' => 'hidden', |
229 | 'type' => 'entity_reference_entity_view', |
230 | 'weight' => -5, |
231 | 'settings' => [ |
232 | 'view_mode' => 'default', |
233 | 'link' => FALSE, |
234 | ], |
235 | ]); |
236 | |
237 | $fields['addresses'] = BaseFieldDefinition::create('entity_reference') |
238 | ->setLabel('Addresses') |
239 | ->setRevisionable(TRUE) |
240 | ->setCardinality(-1) |
241 | ->setSetting('target_type', 'crm_contact_detail') |
242 | ->setSetting('handler_settings', ['target_bundles' => ['address']]) |
243 | ->setDisplayConfigurable('form', TRUE) |
244 | ->setDisplayOptions('form', [ |
245 | 'type' => 'inline_entity_form_complex', |
246 | 'weight' => 10, |
247 | 'settings' => [ |
248 | 'allow_new' => TRUE, |
249 | 'allow_existing' => FALSE, |
250 | 'removed_reference' => InlineEntityFormComplex::REMOVED_DELETE, |
251 | 'match_operator' => 'CONTAINS', |
252 | 'allow_duplicate' => FALSE, |
253 | 'form_mode' => 'default', |
254 | 'override_labels' => TRUE, |
255 | 'label_singular' => t('address'), |
256 | 'label_plural' => t('addresses'), |
257 | 'collapsible' => FALSE, |
258 | 'collapsed' => FALSE, |
259 | 'revision' => TRUE, |
260 | ], |
261 | ]) |
262 | ->setDisplayConfigurable('view', TRUE) |
263 | ->setDisplayOptions('view', [ |
264 | 'label' => 'hidden', |
265 | 'type' => 'entity_reference_entity_view', |
266 | 'weight' => 0, |
267 | 'settings' => [ |
268 | 'view_mode' => 'default', |
269 | 'link' => FALSE, |
270 | ], |
271 | ]); |
272 | |
273 | $fields['status'] = BaseFieldDefinition::create('boolean') |
274 | ->setLabel(t('Status')) |
275 | ->setDescription(t('A boolean indicating whether the contact is active.')) |
276 | ->setDefaultValue(TRUE) |
277 | ->setDisplayOptions('form', [ |
278 | 'type' => 'boolean_checkbox', |
279 | 'settings' => [ |
280 | 'display_label' => TRUE, |
281 | ], |
282 | 'weight' => 120, |
283 | ]) |
284 | ->setSetting('on_label', 'Status') |
285 | ->setDisplayConfigurable('form', TRUE); |
286 | |
287 | $fields['start_date'] = BaseFieldDefinition::create('datetime') |
288 | ->setLabel(t('Start Date')) |
289 | ->setDescription(t('When the contact starts.')) |
290 | ->setRevisionable(TRUE) |
291 | ->setSettings([ |
292 | 'datetime_type' => 'date', |
293 | ]) |
294 | ->setDefaultValue('') |
295 | ->setDisplayConfigurable('form', TRUE) |
296 | ->setDisplayConfigurable('view', TRUE) |
297 | ->setRevisionable(TRUE); |
298 | |
299 | $fields['end_date'] = BaseFieldDefinition::create('datetime') |
300 | ->setLabel(t('End Date')) |
301 | ->setDescription(t('When the contact ends.')) |
302 | ->setRevisionable(TRUE) |
303 | ->setSettings([ |
304 | 'datetime_type' => 'date', |
305 | ]) |
306 | ->setDefaultValue('') |
307 | ->setDisplayConfigurable('form', TRUE) |
308 | ->setDisplayConfigurable('view', TRUE) |
309 | ->setRevisionable(TRUE); |
310 | |
311 | $fields['age'] = BaseFieldDefinition::create('integer') |
312 | ->setLabel(t('Age')) |
313 | ->setDescription(t('The age of the contact.')) |
314 | ->setComputed(TRUE) |
315 | ->setClass(AgeFieldItemList::class) |
316 | ->setDisplayConfigurable('form', FALSE) |
317 | ->setDisplayConfigurable('view', TRUE); |
318 | |
319 | $fields['created'] = BaseFieldDefinition::create('created') |
320 | ->setLabel(t('Created on')) |
321 | ->setDescription(t('The time that the contact was created.')) |
322 | ->setDisplayOptions('view', [ |
323 | 'label' => 'above', |
324 | 'type' => 'timestamp', |
325 | 'weight' => 20, |
326 | ]) |
327 | ->setDisplayConfigurable('form', TRUE) |
328 | ->setDisplayOptions('form', [ |
329 | 'type' => 'datetime_timestamp', |
330 | 'weight' => 20, |
331 | ]) |
332 | ->setDisplayConfigurable('view', TRUE); |
333 | |
334 | $fields['changed'] = BaseFieldDefinition::create('changed') |
335 | ->setLabel(t('Changed')) |
336 | ->setDescription(t('The time that the contact was last edited.')); |
337 | |
338 | return $fields; |
339 | } |
340 | |
341 | } |