Commit | Line | Data |
---|---|---|
56154d36 | 1 | <?php |
56154d36 TO |
2 | /* |
3 | +--------------------------------------------------------------------+ | |
a30c801b | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
56154d36 | 5 | | | |
a30c801b TO |
6 | | This work is published under the GNU AGPLv3 license with some | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
56154d36 TO |
9 | +--------------------------------------------------------------------+ |
10 | */ | |
11 | ||
12 | /** | |
13 | * "Attachment" is a pseudo-entity which represents a record in civicrm_file | |
14 | * combined with a record in civicrm_entity_file as well as the underlying | |
15 | * file content. | |
dc137cd4 | 16 | * For core fields use "entity_table", for custom fields use "field_name" |
56154d36 | 17 | * |
0b882a86 | 18 | * ``` |
dc137cd4 | 19 | * // Create an attachment for a core field |
56154d36 TO |
20 | * $result = civicrm_api3('Attachment', 'create', array( |
21 | * 'entity_table' => 'civicrm_activity', | |
22 | * 'entity_id' => 123, | |
23 | * 'name' => 'README.txt', | |
24 | * 'mime_type' => 'text/plain', | |
25 | * 'content' => 'Please to read the README', | |
26 | * )); | |
27 | * $attachment = $result['values'][$result['id']]; | |
28 | * echo sprintf("<a href='%s'>View %s</a>", $attachment['url'], $attachment['name']); | |
0b882a86 | 29 | * ``` |
56154d36 | 30 | * |
0b882a86 | 31 | * ``` |
dc137cd4 CW |
32 | * // Create an attachment for a custom file field |
33 | * $result = civicrm_api3('Attachment', 'create', array( | |
34 | * 'field_name' => 'custom_6', | |
35 | * 'entity_id' => 123, | |
36 | * 'name' => 'README.txt', | |
37 | * 'mime_type' => 'text/plain', | |
38 | * 'content' => 'Please to read the README', | |
39 | * )); | |
40 | * $attachment = $result['values'][$result['id']]; | |
41 | * echo sprintf("<a href='%s'>View %s</a>", $attachment['url'], $attachment['name']); | |
0b882a86 | 42 | * ``` |
dc137cd4 | 43 | * |
0b882a86 | 44 | * ``` |
dc137cd4 | 45 | * // Move an existing file and save as an attachment |
56154d36 TO |
46 | * $result = civicrm_api3('Attachment', 'create', array( |
47 | * 'entity_table' => 'civicrm_activity', | |
48 | * 'entity_id' => 123, | |
49 | * 'name' => 'README.txt', | |
50 | * 'mime_type' => 'text/plain', | |
51 | * 'options' => array( | |
52 | * 'move-file' => '/tmp/upload1a2b3c4d', | |
53 | * ), | |
54 | * )); | |
55 | * $attachment = $result['values'][$result['id']]; | |
56 | * echo sprintf("<a href='%s'>View %s</a>", $attachment['url'], $attachment['name']); | |
0b882a86 | 57 | * ``` |
56154d36 TO |
58 | * |
59 | * Notes: | |
60 | * - File content is not returned by default. One must specify 'return => content'. | |
61 | * - Features which deal with local file system (e.g. passing "options.move-file" | |
62 | * or returning a "path") are only valid when executed as a local API (ie | |
63 | * "check_permissions"==false) | |
64 | * | |
65 | * @package CiviCRM_APIv3 | |
56154d36 TO |
66 | */ |
67 | ||
68 | /** | |
22242c87 | 69 | * Adjust metadata for "create" action. |
56154d36 | 70 | * |
cf470720 TO |
71 | * @param array $spec |
72 | * List of fields. | |
56154d36 TO |
73 | */ |
74 | function _civicrm_api3_attachment_create_spec(&$spec) { | |
75 | $spec = array_merge($spec, _civicrm_api3_attachment_getfields()); | |
76 | $spec['name']['api.required'] = 1; | |
77 | $spec['mime_type']['api.required'] = 1; | |
56154d36 TO |
78 | $spec['entity_id']['api.required'] = 1; |
79 | $spec['upload_date']['api.default'] = 'now'; | |
80 | } | |
81 | ||
82 | /** | |
244bbdd8 | 83 | * Create an Attachment. |
56154d36 | 84 | * |
cf470720 | 85 | * @param array $params |
22242c87 | 86 | * |
a6c01b45 | 87 | * @return array |
56154d36 | 88 | * @throws API_Exception validation errors |
2e37a19f | 89 | * @see Civi\API\Subscriber\DynamicFKAuthorization |
56154d36 TO |
90 | */ |
91 | function civicrm_api3_attachment_create($params) { | |
dc137cd4 | 92 | if (empty($params['id'])) { |
210737b6 | 93 | // When creating we need either entity_table or field_name. |
cf8f0fff | 94 | civicrm_api3_verify_one_mandatory($params, NULL, ['entity_table', 'field_name']); |
dc137cd4 CW |
95 | } |
96 | ||
56154d36 TO |
97 | $config = CRM_Core_Config::singleton(); |
98 | list($id, $file, $entityFile, $name, $content, $moveFile, $isTrusted, $returnContent) = _civicrm_api3_attachment_parse_params($params); | |
99 | ||
100 | $fileDao = new CRM_Core_BAO_File(); | |
101 | $entityFileDao = new CRM_Core_DAO_EntityFile(); | |
102 | ||
103 | if ($id) { | |
ae2c7e00 | 104 | $file['id'] = $fileDao->id = $id; |
105 | ||
56154d36 TO |
106 | if (!$fileDao->find(TRUE)) { |
107 | throw new API_Exception("Invalid ID"); | |
108 | } | |
109 | ||
110 | $entityFileDao->file_id = $id; | |
111 | if (!$entityFileDao->find(TRUE)) { | |
112 | throw new API_Exception("Cannot modify orphaned file"); | |
113 | } | |
114 | } | |
115 | ||
116 | if (!$id && !is_string($content) && !is_string($moveFile)) { | |
117 | throw new API_Exception("Mandatory key(s) missing from params array: 'id' or 'content' or 'options.move-file'"); | |
118 | } | |
119 | if (!$isTrusted && $moveFile) { | |
120 | throw new API_Exception("options.move-file is only supported on secure calls"); | |
121 | } | |
122 | if (is_string($content) && is_string($moveFile)) { | |
123 | throw new API_Exception("'content' and 'options.move-file' are mutually exclusive"); | |
124 | } | |
125 | if ($id && !$isTrusted && isset($file['upload_date']) && $file['upload_date'] != CRM_Utils_Date::isoToMysql($fileDao->upload_date)) { | |
cf8f0fff | 126 | throw new API_Exception("Cannot modify upload_date" . var_export([$file['upload_date'], $fileDao->upload_date, CRM_Utils_Date::isoToMysql($fileDao->upload_date)], TRUE)); |
56154d36 TO |
127 | } |
128 | if ($id && $name && $name != CRM_Utils_File::cleanFileName($fileDao->uri)) { | |
129 | throw new API_Exception("Cannot modify name"); | |
130 | } | |
131 | ||
56154d36 | 132 | if (!$id) { |
ae2c7e00 | 133 | $file['uri'] = CRM_Utils_File::makeFileName($name); |
56154d36 | 134 | } |
ae2c7e00 | 135 | $fileDao = CRM_Core_BAO_File::create($file); |
136 | $fileDao->find(TRUE); | |
56154d36 TO |
137 | |
138 | $entityFileDao->copyValues($entityFile); | |
139 | $entityFileDao->file_id = $fileDao->id; | |
140 | $entityFileDao->save(); | |
141 | ||
142 | $path = $config->customFileUploadDir . DIRECTORY_SEPARATOR . $fileDao->uri; | |
143 | if (is_string($content)) { | |
144 | file_put_contents($path, $content); | |
145 | } | |
146 | elseif (is_string($moveFile)) { | |
a436d075 | 147 | // CRM-17432 Do not use rename() since it will break file permissions. |
cd05fc57 JB |
148 | // Also avoid move_uploaded_file() because the API can use options.move-file. |
149 | if (!copy($moveFile, $path)) { | |
cecec98e | 150 | throw new API_Exception("Cannot copy uploaded file $moveFile to $path"); |
cd05fc57 | 151 | } |
a436d075 | 152 | unlink($moveFile); |
56154d36 TO |
153 | } |
154 | ||
dc137cd4 CW |
155 | // Save custom field to entity |
156 | if (!$id && empty($params['entity_table']) && isset($params['field_name'])) { | |
cf8f0fff | 157 | civicrm_api3('custom_value', 'create', [ |
dc137cd4 CW |
158 | 'entity_id' => $params['entity_id'], |
159 | $params['field_name'] => $fileDao->id, | |
cf8f0fff | 160 | ]); |
dc137cd4 CW |
161 | } |
162 | ||
cf8f0fff | 163 | $result = [ |
21dfd5f5 | 164 | $fileDao->id => _civicrm_api3_attachment_format_result($fileDao, $entityFileDao, $returnContent, $isTrusted), |
cf8f0fff | 165 | ]; |
56154d36 TO |
166 | return civicrm_api3_create_success($result, $params, 'Attachment', 'create'); |
167 | } | |
168 | ||
169 | /** | |
22242c87 | 170 | * Adjust metadata for get action. |
56154d36 | 171 | * |
cf470720 TO |
172 | * @param array $spec |
173 | * List of fields. | |
56154d36 TO |
174 | */ |
175 | function _civicrm_api3_attachment_get_spec(&$spec) { | |
176 | $spec = array_merge($spec, _civicrm_api3_attachment_getfields()); | |
177 | } | |
178 | ||
179 | /** | |
244bbdd8 | 180 | * Get Attachment. |
dc64d047 | 181 | * |
56154d36 | 182 | * @param array $params |
dc64d047 | 183 | * |
a6c01b45 | 184 | * @return array |
72b3a70c | 185 | * per APIv3 |
56154d36 TO |
186 | * @throws API_Exception validation errors |
187 | */ | |
188 | function civicrm_api3_attachment_get($params) { | |
189 | list($id, $file, $entityFile, $name, $content, $moveFile, $isTrusted, $returnContent) = _civicrm_api3_attachment_parse_params($params); | |
190 | ||
191 | $dao = __civicrm_api3_attachment_find($params, $id, $file, $entityFile, $isTrusted); | |
cf8f0fff | 192 | $result = []; |
56154d36 TO |
193 | while ($dao->fetch()) { |
194 | $result[$dao->id] = _civicrm_api3_attachment_format_result($dao, $dao, $returnContent, $isTrusted); | |
195 | } | |
196 | return civicrm_api3_create_success($result, $params, 'Attachment', 'create'); | |
197 | } | |
198 | ||
24a70b66 | 199 | /** |
244bbdd8 | 200 | * Adjust metadata for Attachment delete action. |
22242c87 | 201 | * |
24a70b66 EM |
202 | * @param $spec |
203 | */ | |
56154d36 TO |
204 | function _civicrm_api3_attachment_delete_spec(&$spec) { |
205 | unset($spec['id']['api.required']); | |
206 | $entityFileFields = CRM_Core_DAO_EntityFile::fields(); | |
207 | $spec['entity_table'] = $entityFileFields['entity_table']; | |
208 | $spec['entity_table']['title'] = CRM_Utils_Array::value('title', $spec['entity_table'], 'Entity Table') . ' (write-once)'; | |
209 | $spec['entity_id'] = $entityFileFields['entity_id']; | |
210 | $spec['entity_id']['title'] = CRM_Utils_Array::value('title', $spec['entity_id'], 'Entity ID') . ' (write-once)'; | |
211 | } | |
212 | ||
213 | /** | |
244bbdd8 | 214 | * Delete Attachment. |
22242c87 | 215 | * |
16b10e64 | 216 | * @param array $params |
22242c87 | 217 | * |
56154d36 TO |
218 | * @return array |
219 | * @throws API_Exception | |
220 | */ | |
221 | function civicrm_api3_attachment_delete($params) { | |
222 | if (!empty($params['id'])) { | |
223 | // ok | |
224 | } | |
225 | elseif (!empty($params['entity_table']) && !empty($params['entity_id'])) { | |
226 | // ok | |
227 | } | |
228 | else { | |
229 | throw new API_Exception("Mandatory key(s) missing from params array: id or entity_table+entity_table"); | |
230 | } | |
231 | ||
232 | $config = CRM_Core_Config::singleton(); | |
233 | list($id, $file, $entityFile, $name, $content, $moveFile, $isTrusted, $returnContent) = _civicrm_api3_attachment_parse_params($params); | |
234 | $dao = __civicrm_api3_attachment_find($params, $id, $file, $entityFile, $isTrusted); | |
235 | ||
cf8f0fff CW |
236 | $filePaths = []; |
237 | $fileIds = []; | |
56154d36 | 238 | while ($dao->fetch()) { |
35671d00 | 239 | $filePaths[] = $config->customFileUploadDir . DIRECTORY_SEPARATOR . $dao->uri; |
56154d36 TO |
240 | $fileIds[] = $dao->id; |
241 | } | |
242 | ||
243 | if (!empty($fileIds)) { | |
244 | $idString = implode(',', array_filter($fileIds, 'is_numeric')); | |
245 | CRM_Core_DAO::executeQuery("DELETE FROM civicrm_entity_file WHERE file_id in ($idString)"); | |
246 | CRM_Core_DAO::executeQuery("DELETE FROM civicrm_file WHERE id in ($idString)"); | |
247 | } | |
248 | ||
249 | // unlink is non-transactional, so we do this as the last step -- just in case the other steps produce errors | |
250 | if (!empty($filePaths)) { | |
251 | foreach ($filePaths as $filePath) { | |
252 | unlink($filePath); | |
253 | } | |
254 | } | |
255 | ||
cf8f0fff | 256 | $result = []; |
56154d36 TO |
257 | return civicrm_api3_create_success($result, $params, 'Attachment', 'create'); |
258 | } | |
259 | ||
260 | /** | |
22242c87 EM |
261 | * Attachment find helper. |
262 | * | |
56154d36 TO |
263 | * @param array $params |
264 | * @param int|null $id the user-supplied ID of the attachment record | |
cf470720 TO |
265 | * @param array $file |
266 | * The user-supplied vales for the file (mime_type, description, upload_date). | |
267 | * @param array $entityFile | |
906e6120 | 268 | * The user-supplied values of the entity-file (entity_table, entity_id). |
56154d36 | 269 | * @param bool $isTrusted |
22242c87 | 270 | * |
56154d36 TO |
271 | * @return CRM_Core_DAO |
272 | * @throws API_Exception | |
273 | */ | |
274 | function __civicrm_api3_attachment_find($params, $id, $file, $entityFile, $isTrusted) { | |
cf8f0fff | 275 | foreach (['name', 'content', 'path', 'url'] as $unsupportedFilter) { |
56154d36 TO |
276 | if (!empty($params[$unsupportedFilter])) { |
277 | throw new API_Exception("Get by $unsupportedFilter is not currently supported"); | |
278 | } | |
279 | } | |
280 | ||
281 | $select = CRM_Utils_SQL_Select::from('civicrm_file cf') | |
282 | ->join('cef', 'INNER JOIN civicrm_entity_file cef ON cf.id = cef.file_id') | |
cf8f0fff | 283 | ->select([ |
56154d36 TO |
284 | 'cf.id', |
285 | 'cf.uri', | |
286 | 'cf.mime_type', | |
287 | 'cf.description', | |
288 | 'cf.upload_date', | |
7aab0058 | 289 | 'cf.created_id', |
56154d36 TO |
290 | 'cef.entity_table', |
291 | 'cef.entity_id', | |
cf8f0fff | 292 | ]); |
56154d36 TO |
293 | |
294 | if ($id) { | |
cf8f0fff | 295 | $select->where('cf.id = #id', ['#id' => $id]); |
56154d36 | 296 | } |
22242c87 | 297 | // Recall: $file is filtered by parse_params. |
56154d36 | 298 | foreach ($file as $key => $value) { |
cf8f0fff | 299 | $select->where('cf.!field = @value', [ |
56154d36 TO |
300 | '!field' => $key, |
301 | '@value' => $value, | |
cf8f0fff | 302 | ]); |
56154d36 | 303 | } |
22242c87 | 304 | // Recall: $entityFile is filtered by parse_params. |
56154d36 | 305 | foreach ($entityFile as $key => $value) { |
cf8f0fff | 306 | $select->where('cef.!field = @value', [ |
56154d36 TO |
307 | '!field' => $key, |
308 | '@value' => $value, | |
cf8f0fff | 309 | ]); |
56154d36 TO |
310 | } |
311 | if (!$isTrusted) { | |
312 | // FIXME ACLs: Add any JOIN or WHERE clauses needed to enforce access-controls for the target entity. | |
313 | // | |
314 | // The target entity is identified by "cef.entity_table" (aka $entityFile['entity_table']) and "cef.entity_id". | |
315 | // | |
316 | // As a simplification, we *require* the "get" actions to filter on a single "entity_table" which should | |
317 | // avoid the complexity of matching ACL's against multiple entity types. | |
318 | } | |
319 | ||
320 | $dao = CRM_Core_DAO::executeQuery($select->toSQL()); | |
321 | return $dao; | |
322 | } | |
323 | ||
324 | /** | |
22242c87 EM |
325 | * Attachment parsing helper. |
326 | * | |
56154d36 | 327 | * @param array $params |
22242c87 | 328 | * |
dc64d047 EM |
329 | * @return array |
330 | * (0 => int $id, 1 => array $file, 2 => array $entityFile, 3 => string $name, 4 => string $content, | |
bed98343 | 331 | * 5 => string $moveFile, 6 => $isTrusted, 7 => bool $returnContent) |
332 | * - array $file: whitelisted fields that can pass through directly to civicrm_file | |
333 | * - array $entityFile: whitelisted fields that can pass through directly to civicrm_entity_file | |
334 | * - string $name: the printable name | |
335 | * - string $moveFile: the full path to a local file whose content should be loaded | |
336 | * - bool $isTrusted: whether we trust the requester to do sketchy things (like moving files or reassigning entities) | |
337 | * - bool $returnContent: whether we are expected to return the full content of the file | |
56154d36 TO |
338 | * @throws API_Exception validation errors |
339 | */ | |
340 | function _civicrm_api3_attachment_parse_params($params) { | |
f748c073 | 341 | $id = $params['id'] ?? NULL; |
56154d36 TO |
342 | if ($id && !is_numeric($id)) { |
343 | throw new API_Exception("Malformed id"); | |
344 | } | |
345 | ||
cf8f0fff CW |
346 | $file = []; |
347 | foreach (['mime_type', 'description', 'upload_date'] as $field) { | |
56154d36 TO |
348 | if (array_key_exists($field, $params)) { |
349 | $file[$field] = $params[$field]; | |
350 | } | |
351 | } | |
352 | ||
cf8f0fff CW |
353 | $entityFile = []; |
354 | foreach (['entity_table', 'entity_id'] as $field) { | |
56154d36 TO |
355 | if (array_key_exists($field, $params)) { |
356 | $entityFile[$field] = $params[$field]; | |
357 | } | |
358 | } | |
359 | ||
dc137cd4 CW |
360 | if (empty($params['entity_table']) && isset($params['field_name'])) { |
361 | $tableInfo = CRM_Core_BAO_CustomField::getTableColumnGroup(intval(str_replace('custom_', '', $params['field_name']))); | |
362 | $entityFile['entity_table'] = $tableInfo[0]; | |
363 | } | |
364 | ||
56154d36 TO |
365 | $name = NULL; |
366 | if (array_key_exists('name', $params)) { | |
367 | if ($params['name'] != basename($params['name']) || preg_match(':[/\\\\]:', $params['name'])) { | |
368 | throw new API_Exception('Malformed name'); | |
369 | } | |
370 | $name = $params['name']; | |
371 | } | |
372 | ||
373 | $content = NULL; | |
374 | if (isset($params['content'])) { | |
375 | $content = $params['content']; | |
376 | } | |
377 | ||
378 | $moveFile = NULL; | |
379 | if (isset($params['options']['move-file'])) { | |
380 | $moveFile = $params['options']['move-file']; | |
381 | } | |
382 | elseif (isset($params['options.move-file'])) { | |
383 | $moveFile = $params['options.move-file']; | |
384 | } | |
385 | ||
386 | $isTrusted = empty($params['check_permissions']); | |
387 | ||
2e1f50d6 | 388 | $returns = $params['return'] ?? []; |
cf8f0fff | 389 | $returns = is_array($returns) ? $returns : [$returns]; |
56154d36 TO |
390 | $returnContent = in_array('content', $returns); |
391 | ||
cf8f0fff | 392 | return [$id, $file, $entityFile, $name, $content, $moveFile, $isTrusted, $returnContent]; |
56154d36 TO |
393 | } |
394 | ||
395 | /** | |
22242c87 EM |
396 | * Attachment result formatting helper. |
397 | * | |
cf470720 TO |
398 | * @param CRM_Core_DAO_File $fileDao |
399 | * Maybe "File" or "File JOIN EntityFile". | |
400 | * @param CRM_Core_DAO_EntityFile $entityFileDao | |
401 | * Maybe "EntityFile" or "File JOIN EntityFile". | |
402 | * @param bool $returnContent | |
403 | * Whether to return the full content of the file. | |
404 | * @param bool $isTrusted | |
405 | * Whether the current request is trusted to perform file-specific operations. | |
35823763 | 406 | * |
56154d36 TO |
407 | * @return array |
408 | */ | |
409 | function _civicrm_api3_attachment_format_result($fileDao, $entityFileDao, $returnContent, $isTrusted) { | |
410 | $config = CRM_Core_Config::singleton(); | |
411 | $path = $config->customFileUploadDir . DIRECTORY_SEPARATOR . $fileDao->uri; | |
412 | ||
cf8f0fff | 413 | $result = [ |
56154d36 TO |
414 | 'id' => $fileDao->id, |
415 | 'name' => CRM_Utils_File::cleanFileName($fileDao->uri), | |
416 | 'mime_type' => $fileDao->mime_type, | |
417 | 'description' => $fileDao->description, | |
418 | 'upload_date' => is_numeric($fileDao->upload_date) ? CRM_Utils_Date::mysqlToIso($fileDao->upload_date) : $fileDao->upload_date, | |
419 | 'entity_table' => $entityFileDao->entity_table, | |
420 | 'entity_id' => $entityFileDao->entity_id, | |
4994819e | 421 | 'icon' => CRM_Utils_File::getIconFromMimeType($fileDao->mime_type), |
7aab0058 | 422 | 'created_id' => $fileDao->created_id, |
cf8f0fff | 423 | ]; |
ff9aeadb | 424 | $fileHash = CRM_Core_BAO_File::generateFileHash($result['entity_id'], $result['id']); |
56154d36 | 425 | $result['url'] = CRM_Utils_System::url( |
ff9aeadb | 426 | 'civicrm/file', 'reset=1&id=' . $result['id'] . '&eid=' . $result['entity_id'] . '&fcs=' . $fileHash, |
56154d36 TO |
427 | TRUE, |
428 | NULL, | |
429 | FALSE, | |
430 | TRUE | |
431 | ); | |
432 | if ($isTrusted) { | |
433 | $result['path'] = $path; | |
434 | } | |
435 | if ($returnContent) { | |
436 | $result['content'] = file_get_contents($path); | |
437 | } | |
438 | return $result; | |
439 | } | |
440 | ||
441 | /** | |
22242c87 EM |
442 | * Attachment getfields helper. |
443 | * | |
a6c01b45 | 444 | * @return array |
72b3a70c | 445 | * list of fields (indexed by name) |
56154d36 TO |
446 | */ |
447 | function _civicrm_api3_attachment_getfields() { | |
448 | $fileFields = CRM_Core_DAO_File::fields(); | |
449 | $entityFileFields = CRM_Core_DAO_EntityFile::fields(); | |
450 | ||
cf8f0fff | 451 | $spec = []; |
56154d36 | 452 | $spec['id'] = $fileFields['id']; |
cf8f0fff | 453 | $spec['name'] = [ |
56154d36 TO |
454 | 'title' => 'Name (write-once)', |
455 | 'description' => 'The logical file name (not searchable)', | |
456 | 'type' => CRM_Utils_Type::T_STRING, | |
cf8f0fff CW |
457 | ]; |
458 | $spec['field_name'] = [ | |
dc137cd4 CW |
459 | 'title' => 'Field Name (write-once)', |
460 | 'description' => 'Alternative to "entity_table" param - sets custom field value.', | |
461 | 'type' => CRM_Utils_Type::T_STRING, | |
cf8f0fff | 462 | ]; |
56154d36 TO |
463 | $spec['mime_type'] = $fileFields['mime_type']; |
464 | $spec['description'] = $fileFields['description']; | |
465 | $spec['upload_date'] = $fileFields['upload_date']; | |
466 | $spec['entity_table'] = $entityFileFields['entity_table']; | |
d1b0d05e EM |
467 | // Would be hard to securely handle changes. |
468 | $spec['entity_table']['title'] = CRM_Utils_Array::value('title', $spec['entity_table'], 'Entity Table') . ' (write-once)'; | |
56154d36 | 469 | $spec['entity_id'] = $entityFileFields['entity_id']; |
7c31ae57 SL |
470 | // would be hard to securely handle changes |
471 | $spec['entity_id']['title'] = CRM_Utils_Array::value('title', $spec['entity_id'], 'Entity ID') . ' (write-once)'; | |
cf8f0fff | 472 | $spec['url'] = [ |
56154d36 TO |
473 | 'title' => 'URL (read-only)', |
474 | 'description' => 'URL for downloading the file (not searchable, expire-able)', | |
475 | 'type' => CRM_Utils_Type::T_STRING, | |
cf8f0fff CW |
476 | ]; |
477 | $spec['path'] = [ | |
56154d36 TO |
478 | 'title' => 'Path (read-only)', |
479 | 'description' => 'Local file path (not searchable, local-only)', | |
480 | 'type' => CRM_Utils_Type::T_STRING, | |
cf8f0fff CW |
481 | ]; |
482 | $spec['content'] = [ | |
56154d36 TO |
483 | 'title' => 'Content', |
484 | 'description' => 'File content (not searchable, not returned by default)', | |
485 | 'type' => CRM_Utils_Type::T_STRING, | |
cf8f0fff CW |
486 | ]; |
487 | $spec['created_id'] = [ | |
ae2c7e00 | 488 | 'title' => 'Created By Contact ID', |
489 | 'type' => CRM_Utils_Type::T_INT, | |
490 | 'description' => 'FK to civicrm_contact, who uploaded this file', | |
cf8f0fff | 491 | ]; |
56154d36 TO |
492 | |
493 | return $spec; | |
494 | } |