-
Notifications
You must be signed in to change notification settings - Fork 3
/
RemoteEntityProfileInterface.php
351 lines (323 loc) · 11.2 KB
/
RemoteEntityProfileInterface.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
<?php
/*
* Copyright (C) 2023 SYSTOPIA GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation in version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types = 1);
namespace Civi\RemoteTools\EntityProfile;
use Civi\RemoteTools\Api4\Query\Comparison;
use Civi\RemoteTools\Api4\Query\ConditionInterface;
use Civi\RemoteTools\EntityProfile\Authorization\GrantResult;
use Civi\RemoteTools\Form\FormSpec\FormSpec;
/**
* A profile for a remote entity that is mapped to one APIv4 entity. Custom
* implementations should set name, entity name, and remote entity name in
* public class constants (NAME, ENTITY_NAME, REMOTE_ENTITY_NAME) and be
* registered in the service container like this:
* $container->autowire(MyRemoteEntityProfile::class)
* ->addTag(MyRemoteEntityProfile::SERVICE_TAG);
*
* Instead of the constants mentioned above the values can be provided as tag
* attributes of the service with lower cased constant name as key.
*
* Additionally, a custom handler class might be specified with the constant
* HANDLER_CLASS (or lower cased as tag attribute). The constructor must have an
* argument named $profile. All other arguments have to be autowireable.
*
* This class shall not be implemented directly, but AbstractRemoteEntityProfile,
* AbstractReadOnlyRemoteEntityProfile, or AbstractRemoteEntityProfileDecorator
* should be extended instead.
*
* Most methods have a parameter named $contactId. This contains the remote
* contact ID resolved to a CiviCRM contact ID or NULL if no remote contact ID
* was given.
*
* @see \Civi\RemoteTools\Api4\AbstractRemoteEntity
* @see \Civi\RemoteTools\EntityProfile\AbstractRemoteEntityProfile
* @see \Civi\RemoteTools\EntityProfile\AbstractReadOnlyRemoteEntityProfile
* @see \Civi\RemoteTools\EntityProfile\Traits\ConstProfileMetadataTrait
*/
interface RemoteEntityProfileInterface {
public const SERVICE_TAG = 'remote_tools.entity_profile';
/**
* @return string The name of the internal entity.
*
* @api
*/
public function getEntityName(): string;
/**
* @return string The name of the profile.
*
* @api
*/
public function getName(): string;
/**
* @return string The name of the remote entity.
*
* @api
*/
public function getRemoteEntityName(): string;
/**
* @return bool
* Check permissions on CiviCRM API calls. The check will be applied to the
* API user not to the resolved remote contact. For this reason FALSE is
* recommended in most cases, so the API user just needs permission to
* access the remote API.
*
* @api
*/
public function isCheckApiPermissions(?int $contactId): bool;
/**
* Fields only available as remote field should be handled in
* convertRemoteFieldComparison(). The comparison cannot be applied on the
* API result because it contradicts pagination.
*
* @phpstan-param array<string, array<string, mixed>> $entityFields
* Fields indexed by field name.
*
* @phpstan-return array<string, array<string, mixed>>
* Fields indexed by field name.
*
* @see convertRemoteFieldComparison()
*
* @api
*/
public function getRemoteFields(array $entityFields, ?int $contactId): array;
/**
* Convert a comparison of a remote only field to an APIv4 condition. If NULL
* is returned, no condition will be applied.
*
* @param \Civi\RemoteTools\Api4\Query\Comparison $comparison
*
* @api
*/
public function convertRemoteFieldComparison(Comparison $comparison, ?int $contactId): ?ConditionInterface;
/**
* @param string $fieldName
* The complete field name, e.g. contact_id.display_name.
* @param string $joinFieldName
* The name of the joined field, e.g. contact_id. This method is only
* called, if the joined field is part of the remote fields.
*
* @return bool TRUE if the implicit join is allowed.
*
* @see getRemoteFields()
*
* @api
*/
public function isImplicitJoinAllowed(string $fieldName, string $joinFieldName, ?int $contactId): bool;
/**
* @phpstan-param array<string> $select
* The proposed select field names. Contains only "allowed" values on get,
* e.g. no implicit joins that are not allowed.
* @phpstan-param 'delete'|'get'|'update' $actionName
* @phpstan-param array<string> $remoteSelect
* The field names from the remote request if action is "get", empty array
* otherwise.
*
* @phpstan-return array<string>
* The field names to select. In most cases just $select or $select with
* additional field names, e.g. if required to decide if update/delete is
* allowed, or if there's no 1:1 mapping between entity fields and remote
* fields. If fields are added it is ensured that the records returned on
* "get" only contain remote fields or allowed implicit joins.
*
* @see getRemoteFields()
* @see isImplicitJoinAllowed()
*
* @api
*/
public function getSelectFieldNames(array $select, string $actionName, array $remoteSelect, ?int $contactId): array;
/**
* @phpstan-param 'delete'|'get'|'update' $actionName
*
* @return \Civi\RemoteTools\Api4\Query\ConditionInterface
* Conditions applied to "where".
*
* @api
*/
public function getFilter(string $actionName, ?int $contactId): ?ConditionInterface;
/**
* Might be used to restrict access using related entities.
*
* @phpstan-param 'delete'|'get'|'update' $actionName
*
* @phpstan-return list<\Civi\RemoteTools\Api4\Query\Join>
* Joins added to the query.
*
* @api
*/
public function getJoins(string $actionName, ?int $contactId): array;
/**
* @phpstan-param array<string, mixed> $entityValues
* @phpstan-param array<string> $select
* Selected field names. Maybe empty on create or update.
*
* @phpstan-return array<string, mixed>
*
* @api
*/
public function convertToRemoteValues(array $entityValues, array $select, ?int $contactId): array;
/**
* If isCreateGranted() always returns deny, this method won't be called and
* might throw a \BadMethodCallException.
*
* @phpstan-param array<int|string, mixed> $arguments
* @phpstan-param array<string, array<string, mixed>> $entityFields
* Entity fields indexed by name.
*
* @see getFieldLoadOptionsForFormSpec()
* @see isCreateGranted()
*
* @api
*/
public function getCreateFormSpec(array $arguments, array $entityFields, ?int $contactId): FormSpec;
/**
* If isUpdateGranted() always returns deny, this method won't be called and
* might throw a \BadMethodCallException.
*
* @phpstan-param array<string, mixed> $entityValues
* Should be used for default values in form spec.
* @phpstan-param array<string, array<string, mixed>> $entityFields
* Entity fields indexed by name.
*
* @see getFieldLoadOptionsForFormSpec()
* @see isUpdateGranted()
*
* @api
*/
public function getUpdateFormSpec(array $entityValues, array $entityFields, ?int $contactId): FormSpec;
/**
* @phpstan-return bool|array<string>
* Value for the 'loadOptions' parameter when fetching entity fields that
* are passed to the form spec creation methods. FALSE if no options are
* required, TRUE to get options as id-label-pairs, or an array of the
* required option properties.
*
* @see getCreateFormSpec()
* @see getUpdateFormSpec()
*
* @api
*/
public function getFieldLoadOptionsForFormSpec();
/**
* @phpstan-param array<int|string, mixed> $arguments
*
* @api
*/
public function isCreateGranted(array $arguments, ?int $contactId): GrantResult;
/**
* @phpstan-param array<string, mixed> $entityValues
*
* @api
*/
public function isDeleteGranted(array $entityValues, ?int $contactId): GrantResult;
/**
* @phpstan-param array<string, mixed>|null $entityValues
* If NULL, entity to update was not found. The update won't be granted in
* that case, anyway, but the implementation might want to override the
* message in that case.
*
* @api
*/
public function isUpdateGranted(?array $entityValues, ?int $contactId): GrantResult;
/**
* @phpstan-param array<string, mixed> $newValues
* @phpstan-param array<string, mixed>|null $oldValues
* NULL on create.
* @phpstan-param array<string, mixed> $formData
*
* @return string
* The message that is shown when an entity was successfully inserted or
* updated.
*
* @api
*/
public function getSaveSuccessMessage(
array $newValues,
?array $oldValues,
array $formData,
?int $contactId
): string;
/**
* Called before the entity is created.
*
* @phpstan-param array<int|string, mixed> $arguments
* @phpstan-param array<string, mixed> $entityValues
* The values going to be inserted. Can be modified.
* @phpstan-param array<string, array<string, mixed>> $entityFields
* Entity fields indexed by name.
* @param \Civi\RemoteTools\Form\FormSpec\FormSpec $formSpec
* @param int|null $contactId
*/
public function onPreCreate(
array $arguments,
array &$entityValues,
array $entityFields,
FormSpec $formSpec,
?int $contactId
): void;
/**
* Called after the entity was created.
*
* @phpstan-param array<int|string, mixed> $arguments
* @phpstan-param array<string, mixed> $entityValues
* @phpstan-param array<string, array<string, mixed>> $entityFields
* Entity fields indexed by name.
* @param \Civi\RemoteTools\Form\FormSpec\FormSpec $formSpec
* @param int|null $contactId
*/
public function onPostCreate(
array $arguments,
array $entityValues,
array $entityFields,
FormSpec $formSpec,
?int $contactId
): void;
/**
* Called before the entity is created.
*
* @phpstan-param array<string, mixed> $newValues
* The values going to be updated. Can be modified.
* @phpstan-param array<string, mixed> $oldValues
* @phpstan-param array<string, array<string, mixed>> $entityFields
* Entity fields indexed by name.
* @param \Civi\RemoteTools\Form\FormSpec\FormSpec $formSpec
* @param int|null $contactId
*/
public function onPreUpdate(
array &$newValues,
array $oldValues,
array $entityFields,
FormSpec $formSpec,
?int $contactId
): void;
/**
* Called after the entity was created.
*
* @phpstan-param array<string, mixed> $newValues
* @phpstan-param array<string, mixed> $oldValues
* @phpstan-param array<string, array<string, mixed>> $entityFields
* Entity fields indexed by name.
* @param \Civi\RemoteTools\Form\FormSpec\FormSpec $formSpec
* @param int|null $contactId
*/
public function onPostUpdate(
array $newValues,
array $oldValues,
array $entityFields,
FormSpec $formSpec,
?int $contactId
): void;
}