diff --git a/Civi/Api4/Service/Spec/Provider/FileGetSpecProvider.php b/Civi/Api4/Service/Spec/Provider/FileGetSpecProvider.php index 517eb61aeb0..06cadb99c2d 100644 --- a/Civi/Api4/Service/Spec/Provider/FileGetSpecProvider.php +++ b/Civi/Api4/Service/Spec/Provider/FileGetSpecProvider.php @@ -105,10 +105,10 @@ public static function renderFileUrl(array $idField, Api4SelectQuery $query): st } } if (isset($entityIdField)) { - return "CONCAT('civicrm/file?reset=1&id=', $idField[sql_name], '&eid=', $entityIdField[sql_name])"; + return "CONCAT('civicrm/file?reset=1&id=', {$idField['sql_name']}, '&eid=', {$entityIdField['sql_name']})"; } - // Guess we couldn't find an `entity_id` in the query. This function could probably be improved. - return "NULL"; + // Couldn't find an `entity_id` in the query so add a subquery instead. + return "CONCAT('civicrm/file?reset=1&id=', {$idField['sql_name']}, '&eid=', (SELECT `entity_id` FROM `civicrm_entity_file` WHERE `file_id` = {$idField['sql_name']} LIMIT 1))"; } public static function renderFileIsImage(array $mimeTypeField, Api4SelectQuery $query): string { diff --git a/ext/afform/core/Civi/Api4/Action/Afform/AbstractProcessor.php b/ext/afform/core/Civi/Api4/Action/Afform/AbstractProcessor.php index 65a8df1763a..537b830f2d9 100644 --- a/ext/afform/core/Civi/Api4/Action/Afform/AbstractProcessor.php +++ b/ext/afform/core/Civi/Api4/Action/Afform/AbstractProcessor.php @@ -323,7 +323,7 @@ public function getJoinResult(array $afEntity, string $joinEntity, array $join, } /** - * Delegated by loadEntity to call API.get and fill in additioal info + * Delegated by loadEntity to call API.get and fill in additional info * * @param string $afEntityName * e.g. Individual1 @@ -343,10 +343,14 @@ private function apiGet($afEntityName, $apiEntityName, $entityFields, string $ke // Fill additional info about file fields $fileFields = $this->getFileFields($apiEntityName, $entityFields); foreach ($fileFields as $fieldName => $fieldDefn) { + $select = ['file_name', 'icon']; + if ($this->canViewFileAttachments($afEntityName)) { + $select[] = 'url'; + } foreach ($result as &$item) { if (!empty($item[$fieldName])) { $fileInfo = File::get(FALSE) - ->addSelect('file_name', 'icon') + ->setSelect($select) ->addWhere('id', '=', $item[$fieldName]) ->execute()->first(); $item[$fieldName] = $fileInfo; @@ -356,6 +360,11 @@ private function apiGet($afEntityName, $apiEntityName, $entityFields, string $ke return $result; } + private function canViewFileAttachments(string $afEntityName): bool { + $afEntity = $this->_formDataModel->getEntity($afEntityName); + return ($afEntity['security'] === 'FBAC' || \CRM_Core_Permission::check('access uploaded files')); + } + protected static function getFileFields($entityName, $entityFields): array { if (!$entityFields) { return []; diff --git a/ext/afform/core/ang/af/fields/DisplayOnly.html b/ext/afform/core/ang/af/fields/DisplayOnly.html index 7d4a6964710..e5ceaccc53c 100644 --- a/ext/afform/core/ang/af/fields/DisplayOnly.html +++ b/ext/afform/core/ang/af/fields/DisplayOnly.html @@ -1 +1,13 @@ -{{dataProvider.getFieldData()[$ctrl.fieldName]}} + + + + {{ dataProvider.getFieldData()[$ctrl.fieldName].file_name }} + + + + {{ dataProvider.getFieldData()[$ctrl.fieldName].file_name }} + + + + {{ dataProvider.getFieldData()[$ctrl.fieldName] }} + diff --git a/ext/afform/core/ang/af/fields/File.html b/ext/afform/core/ang/af/fields/File.html index 61447da1323..c9486b16431 100644 --- a/ext/afform/core/ang/af/fields/File.html +++ b/ext/afform/core/ang/af/fields/File.html @@ -1,6 +1,12 @@ - - {{ dataProvider.getFieldData()[$ctrl.fieldName].file_name }} + + + {{ dataProvider.getFieldData()[$ctrl.fieldName].file_name }} + + + + {{ dataProvider.getFieldData()[$ctrl.fieldName].file_name }} + diff --git a/tests/phpunit/api/v4/Custom/CustomFileTest.php b/tests/phpunit/api/v4/Custom/CustomFileTest.php new file mode 100644 index 00000000000..6f005cce75f --- /dev/null +++ b/tests/phpunit/api/v4/Custom/CustomFileTest.php @@ -0,0 +1,75 @@ +setValues([ + 'title' => 'FileFields', + 'extends' => 'Individual', + ])->execute()->single(); + $field = CustomField::create()->setValues([ + 'label' => 'TestMyFile', + 'custom_group_id.name' => 'FileFields', + 'html_type' => 'File', + 'data_type' => 'File', + ])->execute()->single(); + + $fieldName = 'FileFields.TestMyFile'; + + $contact = $this->createTestRecord('Individual'); + + // FIXME: Use Api4 when available + $file = civicrm_api3('Attachment', 'create', [ + // The mismatch between entity id and entity table feels very wrong but that's how core does it for now + 'entity_id' => $contact['id'], + 'entity_table' => $group['table_name'], + 'mime_type' => 'text/plain', + 'name' => 'test123.txt', + 'content' => 'Hello World 123', + ]); + + civicrm_api4('Individual', 'update', [ + 'values' => [ + 'id' => $contact['id'], + $fieldName => $file['id'], + ], + 'checkPermissions' => FALSE, + ]); + + $file = File::get(FALSE) + ->addSelect('id', 'file_name', 'url') + ->addWhere('id', '=', $file['id']) + ->execute()->single(); + + $this->assertEquals('test123.txt', $file['file_name']); + $this->assertStringContainsString("id={$file['id']}&eid={$contact['id']}&fcs=", $file['url']); + } + +}