mirror of
https://github.com/werkraum-media/form_file_collection.git
synced 2024-12-22 07:56:10 +01:00
Add files to template (#2)
Allow to implement custom templates working with files, e.g. providing a thumbnail, link to full file, etc.
This commit is contained in:
parent
e635b66d36
commit
5bb586a19a
9 changed files with 222 additions and 22 deletions
3
.github/workflows/ci.yaml
vendored
3
.github/workflows/ci.yaml
vendored
|
@ -131,6 +131,9 @@ jobs:
|
|||
sleep 1
|
||||
done
|
||||
|
||||
- name: Install graphicsmagick
|
||||
run: sudo apt-get install -y graphicsmagick
|
||||
|
||||
- name: Install dependencies
|
||||
run: composer req "typo3/cms-core:${{ matrix.typo3-version }}" --prefer-dist --no-progress --no-interaction
|
||||
|
||||
|
|
|
@ -36,19 +36,29 @@ final class FileCollectionElement extends AbstractFormElement
|
|||
public function setProperty(string $key, $value): void
|
||||
{
|
||||
if ($key === 'fileCollection' && is_array($value)) {
|
||||
$this->setProperty('options', $this->getOptions($value));
|
||||
$this->setFileCollection($value);
|
||||
return;
|
||||
}
|
||||
|
||||
parent::setProperty($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string> $value
|
||||
*/
|
||||
private function setFileCollection(array $value): void
|
||||
{
|
||||
$files = $this->getFiles($value);
|
||||
$this->setProperty('files', $files);
|
||||
$this->setProperty('options', $this->getOptions($value, $files));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string> $configuration
|
||||
*
|
||||
* @return array<string, string>
|
||||
* @return FileInterface[]
|
||||
*/
|
||||
public function getOptions(array $configuration): array
|
||||
private function getFiles(array $configuration): array
|
||||
{
|
||||
$uid = (int)($configuration['uid'] ?? 0);
|
||||
$collection = $this->getRepository()->findByUid($uid);
|
||||
|
@ -60,12 +70,20 @@ final class FileCollectionElement extends AbstractFormElement
|
|||
$collection->loadContents();
|
||||
}
|
||||
|
||||
$options = [];
|
||||
foreach ($collection->getItems() as $file) {
|
||||
if (!$file instanceof FileInterface) {
|
||||
continue;
|
||||
}
|
||||
return $collection->getItems();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, string> $configuration
|
||||
* @param FileInterface[] $files
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function getOptions(array $configuration, array $files): array
|
||||
{
|
||||
$options = [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
$options = $this->addOption($configuration, $options, $file);
|
||||
}
|
||||
|
||||
|
|
33
README.rst
33
README.rst
|
@ -22,6 +22,24 @@ Use a free identifier:
|
|||
80 = EXT:form_file_collection/Configuration/Form/Setup.yaml
|
||||
}
|
||||
|
||||
No template is configured by default, choose one of the existing ones or provide your own:
|
||||
|
||||
.. code:: yaml
|
||||
|
||||
TYPO3:
|
||||
CMS:
|
||||
Form:
|
||||
prototypes:
|
||||
standard:
|
||||
formElementsDefinition:
|
||||
FileCollection:
|
||||
renderingOptions:
|
||||
# Allows to switch between different rendering like "Checkbox", "MultiCheckbox" or "RadioButton", etc.
|
||||
templateName: 'MultiCheckbox'
|
||||
|
||||
The existing templates will work out of the box.
|
||||
An additional variable `files` is added for usage within custom templates.
|
||||
|
||||
This will register a new form element type ``FileCollection`` that can be used like this:
|
||||
|
||||
.. code:: yaml
|
||||
|
@ -41,20 +59,7 @@ This will register a new form element type ``FileCollection`` that can be used l
|
|||
# Defines the property to use as label for form element.
|
||||
labelProperty: 'identifier'
|
||||
|
||||
No template is configured by default, choose one of the existing ones or provide your own:
|
||||
|
||||
.. code:: yaml
|
||||
|
||||
TYPO3:
|
||||
CMS:
|
||||
Form:
|
||||
prototypes:
|
||||
standard:
|
||||
formElementsDefinition:
|
||||
FileCollection:
|
||||
renderingOptions:
|
||||
# Allows to switch between different rendering like "Checkbox", "MultiCheckbox" or "RadioButton", etc.
|
||||
templateName: 'MultiCheckbox'
|
||||
The two options `valueProperty` and `labelProperty` are used to prepare the `options` variable used by the available default templates.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
|
16
Resources/Public/Icons/Extension.svg
Normal file
16
Resources/Public/Icons/Extension.svg
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 27.7.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="b" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#333333;}
|
||||
.st1{fill:#FFFFFF;}
|
||||
</style>
|
||||
<g id="c">
|
||||
<path class="st0" d="M16,16H0V0h16V16z"/>
|
||||
<path class="st1" d="M8.9,2.5H5.3c-0.8,0-1.4,0.6-1.4,1.4v8.2c0,0.8,0.6,1.4,1.4,1.4h5.5c0.8,0,1.4-0.6,1.4-1.4V5.7
|
||||
c0-0.2-0.1-0.4-0.2-0.5L9.4,2.7C9.2,2.6,9.1,2.5,8.9,2.5z M9,4.9V3.5l2.1,2.1H9.7C9.3,5.6,9,5.3,9,4.9z M10,7.9L7.9,10
|
||||
c-0.1,0.1-0.4,0.1-0.5,0c0,0,0,0,0,0l-1-1c-0.1-0.1-0.1-0.4,0-0.5c0.1-0.1,0.4-0.1,0.5,0l0.8,0.8l1.8-1.8c0.1-0.1,0.4-0.1,0.5,0
|
||||
C10.1,7.5,10.1,7.8,10,7.9z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 869 B |
76
Tests/Fixtures/CustomTemplate.php
Normal file
76
Tests/Fixtures/CustomTemplate.php
Normal file
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'pages' => [
|
||||
[
|
||||
'uid' => 3,
|
||||
'pid' => 1,
|
||||
'slug' => '/page-3',
|
||||
'title' => 'Page 3 Custom Template',
|
||||
],
|
||||
],
|
||||
'tt_content' => [
|
||||
[
|
||||
'uid' => 3,
|
||||
'pid' => 3,
|
||||
'header' => 'Form with custom template',
|
||||
'header_layout' => '0',
|
||||
'CType' => 'form_formframework',
|
||||
'pi_flexform' => '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<T3FlexForms>
|
||||
<data>
|
||||
<sheet index="sDEF">
|
||||
<language index="lDEF">
|
||||
<field index="settings.persistenceIdentifier">
|
||||
<value index="vDEF">EXT:form_file_collection_example/Configuration/Forms/ExampleCustomTemplate.form.yaml</value>
|
||||
</field>
|
||||
<field index="settings.overrideFinishers">
|
||||
<value index="vDEF">0</value>
|
||||
</field>
|
||||
</language>
|
||||
</sheet>
|
||||
</data>
|
||||
</T3FlexForms>
|
||||
',
|
||||
],
|
||||
],
|
||||
'sys_file' => [
|
||||
[
|
||||
'uid' => 1,
|
||||
'pid' => 0,
|
||||
'missing' => 0,
|
||||
'storage' => 1,
|
||||
'type' => 2,
|
||||
'metadata' => 0,
|
||||
'identifier' => '/Files/FirstResult.png',
|
||||
'identifier_hash' => '29b827d0daa29658d8a0d952dfd20f559bbe3bcf',
|
||||
'folder_hash' => '86d12d536195df2100a5ec04ab80c08f9bed3d31',
|
||||
'extension' => 'png',
|
||||
'mime_type' => 'image/png',
|
||||
'name' => 'FirstResult.png',
|
||||
'sha1' => 'b13f2bbf275d592534eab659c1430c2702ce31fc',
|
||||
'size' => '42383',
|
||||
],
|
||||
],
|
||||
'sys_file_collection' => [
|
||||
[
|
||||
'uid' => 1,
|
||||
'pid' => 1,
|
||||
'title' => 'Example Collection for form',
|
||||
'files' => 1,
|
||||
],
|
||||
],
|
||||
'sys_file_reference' => [
|
||||
[
|
||||
'uid' => 1,
|
||||
'pid' => 1,
|
||||
'uid_local' => 1,
|
||||
'uid_foreign' => 1,
|
||||
'tablenames' => 'sys_file_collection',
|
||||
'fieldname' => 'files',
|
||||
'sorting_foreign' => 1,
|
||||
'title' => 'Example title for form',
|
||||
'alternative' => 'Alternative',
|
||||
],
|
||||
],
|
||||
];
|
|
@ -0,0 +1,36 @@
|
|||
renderingOptions:
|
||||
submitButtonLabel: Submit
|
||||
partialRootPaths:
|
||||
20: EXT:form_file_collection_example/Resources/Private/Partials/
|
||||
type: Form
|
||||
identifier: test
|
||||
label: Test
|
||||
prototypeName: standard
|
||||
renderables:
|
||||
-
|
||||
renderingOptions:
|
||||
previousButtonLabel: 'Previous step'
|
||||
nextButtonLabel: 'Next step'
|
||||
type: Page
|
||||
identifier: page-1
|
||||
label: First Step
|
||||
renderables:
|
||||
-
|
||||
type: FileCollectionCustomTemplate
|
||||
identifier: file-collection-1
|
||||
label: 'File Collection'
|
||||
properties:
|
||||
fileCollection:
|
||||
uid: 1
|
||||
-
|
||||
defaultValue: ''
|
||||
type: Text
|
||||
identifier: text-1
|
||||
label: 'Example text field'
|
||||
-
|
||||
renderingOptions:
|
||||
previousButtonLabel: 'Previous step'
|
||||
nextButtonLabel: 'Next step'
|
||||
type: SummaryPage
|
||||
identifier: summarypage-1
|
||||
label: 'Summary step'
|
|
@ -12,3 +12,8 @@ TYPO3:
|
|||
renderingOptions:
|
||||
# Allows to switch between different rendering like "Checkbox", "MultiCheckbox" or "RadioButton", etc.
|
||||
templateName: 'MultiCheckbox'
|
||||
FileCollectionCustomTemplate:
|
||||
implementationClassName: WerkraumMedia\FormFileCollection\Form\FormElement\FileCollectionElement
|
||||
renderingOptions:
|
||||
# Use custom template, ensure it can be found within partialRootPaths
|
||||
templateName: 'Custom'
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
|
||||
data-namespace-typo3-fluid="true"
|
||||
>
|
||||
|
||||
<formvh:renderRenderable renderable="{element}">
|
||||
<f:render partial="Field/Field" arguments="{element: element}" contentAs="elementContent">
|
||||
<f:for each="{element.properties.files}" as="file" iteration="idIterator">
|
||||
<f:form.checkbox
|
||||
property="{element.identifier}"
|
||||
multiple="1"
|
||||
id="{element.uniqueIdentifier}-{idIterator.index}"
|
||||
class="{element.properties.elementClassAttribute}"
|
||||
value="{file.title}"
|
||||
errorClass="{element.properties.elementErrorClassAttribute}"
|
||||
additionalAttributes="{formvh:translateElementProperty(element: element, property: 'fluidAdditionalAttributes')}"
|
||||
/>
|
||||
{file.properties.title}
|
||||
{file.properties.description}
|
||||
<f:image image="{file}" width="100"/>
|
||||
</f:for>
|
||||
</f:render>
|
||||
</formvh:renderRenderable>
|
||||
|
||||
</html>
|
|
@ -119,4 +119,21 @@ class FormIntegrationTest extends FunctionalTestCase
|
|||
self::assertStringContainsString('value="29b827d0daa29658d8a0d952dfd20f559bbe3bcf"', $content);
|
||||
self::assertStringContainsString('<span>image/png</span>', $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function rendersCustomTemplateWithAccessToFiles(): void
|
||||
{
|
||||
$this->importPHPDataSet(__DIR__ . '/../Fixtures/CustomTemplate.php');
|
||||
|
||||
$request = new InternalRequest();
|
||||
$request = $request->withPageId(3);
|
||||
|
||||
$response = $this->executeFrontendRequest($request);
|
||||
|
||||
$content = $response->getBody()->__toString();
|
||||
self::assertStringContainsString('name="tx_form_formframework[test-3][file-collection-1][]" value="Example title for form"', $content);
|
||||
self::assertStringContainsString('<img src="/fileadmin/_processed_/2/9/csm_FirstResult_0f8fa1bb68.png" width="100" height="40" alt="Alternative" title="Example title for form" />', $content);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue