├── .gitignore
├── Resources
├── translations
│ ├── .gitkeep
│ ├── routes.en.po
│ └── zikulaformiculamodule.en.po
├── views
│ ├── Form
│ │ ├── 0
│ │ │ ├── userFooter.html.twig
│ │ │ ├── userHeader.html.twig
│ │ │ ├── adminMail.html.twig
│ │ │ ├── userMail.html.twig
│ │ │ ├── userError.html.twig
│ │ │ ├── userMail.txt.twig
│ │ │ ├── adminMail.txt.twig
│ │ │ ├── userForm.html.twig
│ │ │ └── userConfirm.html.twig
│ │ ├── 1
│ │ │ ├── userFooter.html.twig
│ │ │ ├── userHeader.html.twig
│ │ │ ├── userMail.html.twig
│ │ │ ├── adminMail.html.twig
│ │ │ ├── userError.html.twig
│ │ │ ├── adminMail.txt.twig
│ │ │ ├── userMail.txt.twig
│ │ │ ├── userConfirm.html.twig
│ │ │ └── userForm.html.twig
│ │ ├── 2
│ │ │ ├── userFooter.html.twig
│ │ │ ├── userHeader.html.twig
│ │ │ ├── adminMail.html.twig
│ │ │ ├── userMail.html.twig
│ │ │ ├── userError.html.twig
│ │ │ ├── userMail.txt.twig
│ │ │ ├── adminMail.txt.twig
│ │ │ ├── userForm.html.twig
│ │ │ └── userConfirm.html.twig
│ │ └── 3
│ │ │ ├── userFooter.html.twig
│ │ │ ├── userHeader.html.twig
│ │ │ ├── adminMail.html.twig
│ │ │ ├── userMail.html.twig
│ │ │ ├── userError.html.twig
│ │ │ ├── adminMail.txt.twig
│ │ │ ├── userMail.txt.twig
│ │ │ ├── userConfirm.html.twig
│ │ │ └── userForm.html.twig
│ ├── ContentType
│ │ └── formEdit.html.twig
│ ├── Include
│ │ └── spamCheck.html.twig
│ ├── Contact
│ │ ├── delete.html.twig
│ │ ├── edit.html.twig
│ │ └── view.html.twig
│ ├── Submission
│ │ ├── delete.html.twig
│ │ ├── view.html.twig
│ │ └── display.html.twig
│ └── Config
│ │ └── config.html.twig
├── public
│ ├── fonts
│ │ ├── vera.ttf
│ │ ├── arial.ttf
│ │ ├── freesans.ttf
│ │ ├── quickhand.ttf
│ │ └── quickhand_readme.txt
│ └── js
│ │ └── ZikulaFormiculaModule.Config.js
├── config
│ ├── routing.yaml
│ └── services.yaml
└── docs
│ └── credits.txt
├── .github
└── dependabot.yml
├── ZikulaFormiculaModule.php
├── composer.lock
├── Entity
├── Repository
│ ├── ContactRepository.php
│ └── SubmissionRepository.php
├── ContactEntity.php
└── SubmissionEntity.php
├── zikula.manifest.json
├── DependencyInjection
└── ZikulaFormiculaExtension.php
├── .styleci.yml
├── composer.json
├── Form
└── Type
│ ├── DeleteContactType.php
│ ├── DeleteSubmissionType.php
│ ├── EditContactType.php
│ ├── UserSubmissionType.php
│ └── ConfigType.php
├── Menu
└── ExtensionMenu.php
├── Twig
└── Extension
│ └── FormiculaCaptchaExtension.php
├── ContentType
├── Form
│ └── Type
│ │ └── FormType.php
└── FormType.php
├── HookSubscriber
└── FormUiHooksSubscriber.php
├── Traits
└── StandardFieldsTrait.php
├── Helper
├── EnvironmentHelper.php
└── CaptchaHelper.php
├── Controller
├── ConfigController.php
├── SubmissionController.php
└── ContactController.php
├── FormiculaModuleInstaller.php
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/
2 |
--------------------------------------------------------------------------------
/Resources/translations/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Resources/views/Form/0/userFooter.html.twig:
--------------------------------------------------------------------------------
1 | {# empty footer #}
2 |
--------------------------------------------------------------------------------
/Resources/views/Form/1/userFooter.html.twig:
--------------------------------------------------------------------------------
1 | {# empty footer #}
2 |
--------------------------------------------------------------------------------
/Resources/views/Form/2/userFooter.html.twig:
--------------------------------------------------------------------------------
1 | {# empty footer #}
2 |
--------------------------------------------------------------------------------
/Resources/views/Form/3/userFooter.html.twig:
--------------------------------------------------------------------------------
1 | {# empty footer #}
2 |
--------------------------------------------------------------------------------
/Resources/views/ContentType/formEdit.html.twig:
--------------------------------------------------------------------------------
1 | {{ form_row(form) }}
2 |
--------------------------------------------------------------------------------
/Resources/public/fonts/vera.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zikula-modules/Formicula/HEAD/Resources/public/fonts/vera.ttf
--------------------------------------------------------------------------------
/Resources/public/fonts/arial.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zikula-modules/Formicula/HEAD/Resources/public/fonts/arial.ttf
--------------------------------------------------------------------------------
/Resources/public/fonts/freesans.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zikula-modules/Formicula/HEAD/Resources/public/fonts/freesans.ttf
--------------------------------------------------------------------------------
/Resources/public/fonts/quickhand.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zikula-modules/Formicula/HEAD/Resources/public/fonts/quickhand.ttf
--------------------------------------------------------------------------------
/Resources/config/routing.yaml:
--------------------------------------------------------------------------------
1 | zikulaformiculamodule:
2 | resource: "@ZikulaFormiculaModule/Controller"
3 | type: annotation
4 |
--------------------------------------------------------------------------------
/Resources/views/Form/1/userHeader.html.twig:
--------------------------------------------------------------------------------
1 | {{ pageSetVar('title', 'Apply online'|trans) }}
2 |
{% trans %}Apply online{% endtrans %}
3 | {{ showflashes() }}
4 |
--------------------------------------------------------------------------------
/Resources/views/Form/0/userHeader.html.twig:
--------------------------------------------------------------------------------
1 | {{ pageSetVar('title', 'Contact our team'|trans) }}
2 | {% trans %}Contact our team{% endtrans %}
3 | {{ showflashes() }}
4 |
--------------------------------------------------------------------------------
/Resources/views/Form/2/userHeader.html.twig:
--------------------------------------------------------------------------------
1 | {{ pageSetVar('title', 'Contact our team'|trans) }}
2 | {% trans %}Contact our team{% endtrans %}
3 | {{ showflashes() }}
4 |
--------------------------------------------------------------------------------
/Resources/views/Form/3/userHeader.html.twig:
--------------------------------------------------------------------------------
1 | {{ pageSetVar('title', 'Make a reservation'|trans) }}
2 | {% trans %}Make a reservation{% endtrans %}
3 | {{ showflashes() }}
4 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 |
2 | version: 2
3 | updates:
4 | - package-ecosystem: "composer"
5 | directory: "/"
6 | schedule:
7 | interval: "daily"
8 |
9 | - package-ecosystem: "github-actions"
10 | directory: "/"
11 | schedule:
12 | interval: "daily"
13 |
--------------------------------------------------------------------------------
/Resources/views/Form/0/adminMail.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {% trans %}New contact{% endtrans %}
5 |
6 |
7 |
8 |
9 | {{ include('@ZikulaFormiculaModule/Form/0/adminMail.txt.twig')|nl2br }}
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Resources/views/Form/0/userMail.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {% trans %}Contact our team{% endtrans %}
5 |
6 |
7 |
8 |
9 | {{ include('@ZikulaFormiculaModule/Form/0/userMail.txt.twig')|nl2br }}
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Resources/views/Form/1/userMail.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {% trans %}Apply online!{% endtrans %}
5 |
6 |
7 |
8 |
9 | {{ include('@ZikulaFormiculaModule/Form/1/userMail.txt.twig')|nl2br }}
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Resources/views/Form/2/adminMail.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {% trans %}New contact{% endtrans %}
5 |
6 |
7 |
8 |
9 | {{ include('@ZikulaFormiculaModule/Form/2/adminMail.txt.twig')|nl2br }}
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Resources/views/Form/2/userMail.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {% trans %}Contact our team{% endtrans %}
5 |
6 |
7 |
8 |
9 | {{ include('@ZikulaFormiculaModule/Form/2/userMail.txt.twig')|nl2br }}
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Resources/views/Form/1/adminMail.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {% trans %}New application{% endtrans %}
5 |
6 |
7 |
8 |
9 | {{ include('@ZikulaFormiculaModule/Form/1/adminMail.txt.twig')|nl2br }}
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Resources/views/Form/3/adminMail.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {% trans %}New rental request{% endtrans %}
5 |
6 |
7 |
8 |
9 | {{ include('@ZikulaFormiculaModule/Form/3/adminMail.txt.twig')|nl2br }}
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Resources/views/Form/3/userMail.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {% trans %}Make a reservation{% endtrans %}
5 |
6 |
7 |
8 |
9 | {{ include('@ZikulaFormiculaModule/Form/3/userMail.txt.twig')|nl2br }}
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Resources/views/Form/0/userError.html.twig:
--------------------------------------------------------------------------------
1 | {{ include('@ZikulaFormiculaModule/Form/0/userHeader.html.twig') }}
2 |
3 |
4 | {% trans %}There is an error in your input.{% endtrans %}
5 |
6 | {% trans %}Go back to the form{% endtrans %}
7 |
8 |
9 |
10 | {{ include('@ZikulaFormiculaModule/Form/0/userFooter.html.twig') }}
11 |
--------------------------------------------------------------------------------
/Resources/views/Form/1/userError.html.twig:
--------------------------------------------------------------------------------
1 | {{ include('@ZikulaFormiculaModule/Form/1/userHeader.html.twig') }}
2 |
3 |
4 | {% trans %}There is an error in your input.{% endtrans %}
5 |
6 | {% trans %}Go back to the form{% endtrans %}
7 |
8 |
9 |
10 | {{ include('@ZikulaFormiculaModule/Form/1/userFooter.html.twig') }}
11 |
--------------------------------------------------------------------------------
/Resources/views/Form/2/userError.html.twig:
--------------------------------------------------------------------------------
1 | {{ include('@ZikulaFormiculaModule/Form/2/userHeader.html.twig') }}
2 |
3 |
4 | {% trans %}There is an error in your input.{% endtrans %}
5 |
6 | {% trans %}Go back to the form{% endtrans %}
7 |
8 |
9 |
10 | {{ include('@ZikulaFormiculaModule/Form/2/userFooter.html.twig') }}
11 |
--------------------------------------------------------------------------------
/Resources/views/Form/3/userError.html.twig:
--------------------------------------------------------------------------------
1 | {{ include('@ZikulaFormiculaModule/Form/3/userHeader.html.twig') }}
2 |
3 |
4 | {% trans %}There is an error in your input.{% endtrans %}
5 |
6 | {% trans %}Go back to the form{% endtrans %}
7 |
8 |
9 |
10 | {{ include('@ZikulaFormiculaModule/Form/3/userFooter.html.twig') }}
11 |
--------------------------------------------------------------------------------
/ZikulaFormiculaModule.php:
--------------------------------------------------------------------------------
1 | =7.2.5",
17 | "ext-gd": "*"
18 | },
19 | "platform-dev": [],
20 | "plugin-api-version": "2.0.0"
21 | }
22 |
--------------------------------------------------------------------------------
/Resources/views/Include/spamCheck.html.twig:
--------------------------------------------------------------------------------
1 | {% if enableSpamCheck %}
2 |
13 | {% endif %}
14 |
--------------------------------------------------------------------------------
/Entity/Repository/ContactRepository.php:
--------------------------------------------------------------------------------
1 | =3.0.0 <4.0.0",
15 | "composerpath": "composer.json",
16 | "description": "Template-driven form mailer.",
17 | "keywords": [
18 | ]
19 | },
20 | "urls": {
21 | "version": "",
22 | "docs": "",
23 | "demo": "",
24 | "download": "https://github.com/zikula-modules/Formicula/releases",
25 | "issues": "https://github.com/zikula-modules/Formicula/issues"
26 | },
27 | "dependencies": [
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/Resources/public/js/ZikulaFormiculaModule.Config.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 | $(document).ready(function() {
3 | if (!$('#zikulaformiculamodule_config_enableSpamCheck').prop('checked')) {
4 | $('#formiculaSpamCheckDetails').addClass('d-none');
5 | }
6 | $('#zikulaformiculamodule_config_enableSpamCheck').change(function() {
7 | $('#formiculaSpamCheckDetails').toggleClass('d-none', !$('#zikulaformiculamodule_config_enableSpamCheck').prop('checked'));
8 | });
9 |
10 | if (!$('#zikulaformiculamodule_config_storeSubmissionData').prop('checked')) {
11 | $('#formiculaDataStorageDetails').addClass('d-none');
12 | }
13 | $('#zikulaformiculamodule_config_storeSubmissionData').change(function(){
14 | $('#formiculaDataStorageDetails').toggleClass('d-none', !$('#zikulaformiculamodule_config_storeSubmissionData').prop('checked'));
15 | });
16 | });
17 | })(jQuery)
18 |
--------------------------------------------------------------------------------
/DependencyInjection/ZikulaFormiculaExtension.php:
--------------------------------------------------------------------------------
1 | load('services.yaml');
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/.styleci.yml:
--------------------------------------------------------------------------------
1 | preset: symfony
2 | risky: true
3 |
4 | enabled:
5 | - alpha_ordered_imports
6 | - cast_spaces
7 | - combine_consecutive_issets
8 | - combine_consecutive_unsets
9 | - concat_with_spaces
10 | - declare_strict_types
11 | - escape_implicit_backslashes
12 | - explicit_indirect_variable
13 | - explicit_string_variable
14 | - mb_str_functions
15 | - multiline_comment_opening_closing
16 | - no_null_property_initialization
17 | - no_php4_constructor
18 | - no_useless_else
19 | - php_unit_mock
20 | - php_unit_namespaced
21 | - php_unit_set_up_tear_down_visibility
22 | - random_api_migration
23 | - strict_comparison
24 | - ternary_to_null_coalescing
25 |
26 | disabled:
27 | - cast_spaces
28 | - concat_without_spaces
29 | - function_declaration
30 | - native_constant_invocation_symfony
31 | - native_function_invocation_symfony
32 | - no_blank_lines_after_phpdoc
33 | - no_blank_lines_after_throw
34 | - php_unit_fqcn_annotation
35 | - phpdoc_align
36 | - phpdoc_scalar
37 | - phpdoc_separation
38 | - phpdoc_summary
39 | - phpdoc_to_comment
40 | - pre_increment
41 | - single_quote
42 | - trailing_comma_in_multiline_array
43 | - unalign_double_arrow
44 | - unalign_equals
45 |
--------------------------------------------------------------------------------
/Resources/docs/credits.txt:
--------------------------------------------------------------------------------
1 | // ----------------------------------------------------------------------
2 | // vpContact module for Rogue 0.711
3 | // Copyright (c) 2002 by
4 | // http://www.beginner-ag.de/postnuke
5 | // ----------------------------------------------------------------------
6 | //
7 | // Formicula 0.1 - 0.3
8 | // Smartyfied version for use with pnRender by Frank Schummertz, Jim Hadfield
9 | // (in fact this an 80% rewrite of the older vpContact code)
10 | // frank.schummertz@landseer-stuttgart.de
11 | // jim@snowbankih.com
12 | // http://snowbankih.tzo.com
13 | // ----------------------------------------------------------------------
14 | //
15 | // Formicula 0.5
16 | // store contacts in seperate contacts table (like vpContact)
17 | // reiner.maiwald@freenet.de
18 | //
19 | // Formicula 0.6 - 1.0
20 | // frank.schummertz@landseer-stuttgart.de
21 | //
22 | // Thanks to Carsten Volmer for extensive testing.
23 | // French translation by Christophe Beaujean (yokav)
24 | //
25 | // Formicula 2.0
26 | // frank.schummertz@landseer-stuttgart.de
27 | // Stylesheet adjustments by Carsten Volmer
28 | //
29 | // Formicula 3.0
30 | // updated for Zikula 1.3
31 | // Carsten Volmer, Axel Guckelberger, Erik Spaan
32 | //
33 | // Formicula 4.0
34 | // updated for Zikula 1.4
35 | // Axel Guckelberger
36 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "zikula/formicula-module",
3 | "version": "6.0.1",
4 | "description": "Template-driven form mailer.",
5 | "type": "zikula-module",
6 | "license": "LGPL-3.0+",
7 | "authors": [
8 | {
9 | "name": "Zikula",
10 | "homepage": "https://ziku.la/"
11 | }
12 | ],
13 | "autoload": {
14 | "psr-4": { "Zikula\\FormiculaModule\\": "" }
15 | },
16 | "require": {
17 | "php": ">=7.2.5",
18 | "ext-gd": "*"
19 | },
20 | "extra": {
21 | "zikula": {
22 | "class": "Zikula\\FormiculaModule\\ZikulaFormiculaModule",
23 | "core-compatibility": ">=3.0.0 <4.0.0",
24 | "displayname": "Formicula",
25 | "url": "formicula",
26 | "oldnames": ["Formicula"],
27 | "icon": "far fa-check-square",
28 | "capabilities": {
29 | "admin": {
30 | "route": "zikulaformiculamodule_contact_view"
31 | },
32 | "user": {
33 | "route": "zikulaformiculamodule_user_index"
34 | }
35 | },
36 | "securityschema": {
37 | "ZikulaFormiculaModule::": "Form ID:Contact ID:"
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Resources/views/Form/0/userMail.txt.twig:
--------------------------------------------------------------------------------
1 | {% trans with {'%s%': userData.uname} %}Hello %s%!{% endtrans %}
2 |
3 | {% trans %}Thank you for the comments posted from our website. The sent data is:{% endtrans %}
4 |
5 | {% trans %}Your Name{% endtrans %}: {{ userData.name }}
6 | {% if modVars.showCompany and userData.company %}
7 | {% trans %}Company{% endtrans %}: {{ userData.company }}
8 | {% endif %}
9 | {% trans %}Email{% endtrans %}: {{ userData.emailAddress }}
10 | {% if modVars.showPhone and userData.phone %}
11 | {% trans %}Phone number{% endtrans %}: {{ userData.phone }}
12 | {% endif %}
13 | {% if modVars.showUrl and userData.url %}
14 | {% trans %}Website{% endtrans %}: {{ userData.url }}
15 | {% endif %}
16 | {% if modVars.showLocation and userData.location %}
17 | {% trans %}Location{% endtrans %}: {{ userData.location }}
18 | {% endif %}
19 |
20 | {% for field in customFields %}
21 | {{ field.name }}: {{ field.data }}
22 | {% endfor %}
23 | {% if modVars.showComment and userData.comment %}
24 |
25 | {% trans %}Comment{% endtrans %}:
26 | {{ userData.comment }}
27 | {% endif %}
28 | {% if modVars.showFileAttachment and userData.fileUpload %}
29 |
30 | {% trans %}Attached file{% endtrans %}: {{ userData.fileUpload }}
31 | {% endif %}
32 |
33 | {% trans %}We will respond to your email address as soon as possible.{% endtrans %}
34 |
35 | {% trans with {'%s%': siteName} %}The %s% team{% endtrans %}
36 |
--------------------------------------------------------------------------------
/Resources/views/Form/2/userMail.txt.twig:
--------------------------------------------------------------------------------
1 | {% trans with {'%s%': userData.uname} %}Hello %s%!{% endtrans %}
2 |
3 | {% trans %}Thank you for the comments posted from our website. The sent data is:{% endtrans %}
4 |
5 | {% trans %}Your name{% endtrans %}: {{ userData.name }}
6 | {% if modVars.showCompany and userData.company %}
7 | {% trans %}Company{% endtrans %}: {{ userData.company }}
8 | {% endif %}
9 | {% trans %}Email{% endtrans %}: {{ userData.emailAddress }}
10 | {% if modVars.showPhone and userData.phone %}
11 | {% trans %}Phone number{% endtrans %}: {{ userData.phone }}
12 | {% endif %}
13 | {% if modVars.showUrl and userData.url %}
14 | {% trans %}Website{% endtrans %}: {{ userData.url }}
15 | {% endif %}
16 | {% if modVars.showLocation and userData.location %}
17 | {% trans %}Location{% endtrans %}: {{ userData.location }}
18 | {% endif %}
19 |
20 | {% for field in customFields %}
21 | {{ field.name }}: {{ field.data }}
22 | {% endfor %}
23 | {% if modVars.showComment and userData.comment %}
24 |
25 | {% trans %}Comment{% endtrans %}:
26 | {{ userData.comment }}
27 | {% endif %}
28 | {% if modVars.showFileAttachment and userData.fileUpload %}
29 |
30 | {% trans %}Attached file{% endtrans %}: {{ userData.fileUpload }}
31 | {% endif %}
32 |
33 | {% trans %}We will respond to your email address as soon as possible.{% endtrans %}
34 |
35 | {% trans with {'%s%': siteName} %}The %s% team{% endtrans %}
36 |
--------------------------------------------------------------------------------
/Resources/views/Contact/delete.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% trans %}Delete contact{% endtrans %}
4 | {{ pageSetVar('title', 'Delete contact'|trans) }}
5 |
6 |
7 | {{ form_start(form) }}
8 | {{ form_errors(form) }}
9 |
10 |
11 | {% trans %}Confirmation prompt{% endtrans %}
12 | {% trans with { '%s%': contact.name } %}Do you really want to delete contact '%s%'?{% endtrans %}
13 |
14 | {{ form_row(form.cid) }}
15 |
16 |
17 | {% trans %}Contact information{% endtrans %}
18 |
24 |
30 |
31 |
32 |
38 |
39 | {{ form_end(form) }}
40 |
--------------------------------------------------------------------------------
/Resources/views/Form/0/adminMail.txt.twig:
--------------------------------------------------------------------------------
1 | {% trans %}Hello!{% endtrans %}
2 |
3 | {% trans %}A visitor of to your web site used the form for contact and sent the following:{% endtrans %}
4 |
5 | {% trans %}Form #{% endtrans %}: {{ form }}
6 | {% trans %}Contact{% endtrans %}: {{ contact.name }}
7 | {% trans %}Name{% endtrans %}: {{ userData.name }}
8 | {% if modVars.showCompany and userData.company %}
9 | {% trans %}Company{% endtrans %}: {{ userData.company }}
10 | {% endif %}
11 | {% trans %}Email{% endtrans %}: {{ userData.emailAddress }}
12 | {% if modVars.showPhone and userData.phone %}
13 | {% trans %}Phone number{% endtrans %}: {{ userData.phone }}
14 | {% endif %}
15 | {% if modVars.showUrl and userData.url %}
16 | {% trans %}Website{% endtrans %}: {{ userData.url }}
17 | {% endif %}
18 | {% if modVars.showLocation and userData.location %}
19 | {% trans %}Location{% endtrans %}: {{ userData.location }}
20 | {% endif %}
21 |
22 | {% for field in customFields %}
23 | {{ field.name }}: {{ field.data }}
24 | {% endfor %}
25 | {% if modVars.showComment and userData.comment %}
26 |
27 | {% trans %}Comment{% endtrans %}:
28 | {{ userData.comment }}
29 | {% endif %}
30 | {% if modVars.showFileAttachment and userData.fileUpload %}
31 |
32 | {% trans %}Attached file{% endtrans %}: {{ userData.fileUpload }}
33 | {% endif %}
34 |
35 | {% trans %}The user has the following IP address/hostname:{% endtrans %} {{ ipAddress }} / {{ hostName }}
36 |
--------------------------------------------------------------------------------
/Resources/views/Form/2/adminMail.txt.twig:
--------------------------------------------------------------------------------
1 | {% trans %}Hello!{% endtrans %}
2 |
3 | {% trans %}A visitor of to your web site used the form for contact and sent the following:{% endtrans %}
4 |
5 | {% trans %}Form #{% endtrans %}: {{ form }}
6 | {% trans %}Contact{% endtrans %}: {{ contact.name }}
7 | {% trans %}Name{% endtrans %}: {{ userData.name }}
8 | {% if modVars.showCompany and userData.company %}
9 | {% trans %}Company{% endtrans %}: {{ userData.company }}
10 | {% endif %}
11 | {% trans %}Email{% endtrans %}: {{ userData.emailAddress }}
12 | {% if modVars.showPhone and userData.phone %}
13 | {% trans %}Phone number{% endtrans %}: {{ userData.phone }}
14 | {% endif %}
15 | {% if modVars.showUrl and userData.url %}
16 | {% trans %}Website{% endtrans %}: {{ userData.url }}
17 | {% endif %}
18 | {% if modVars.showLocation and userData.location %}
19 | {% trans %}Location{% endtrans %}: {{ userData.location }}
20 | {% endif %}
21 |
22 | {% for field in customFields %}
23 | {{ field.name }}: {{ field.data }}
24 | {% endfor %}
25 | {% if modVars.showComment and userData.comment %}
26 |
27 | {% trans %}Comment{% endtrans %}:
28 | {{ userData.comment }}
29 | {% endif %}
30 | {% if modVars.showFileAttachment and userData.fileUpload %}
31 |
32 | {% trans %}Attached file{% endtrans %}: {{ userData.fileUpload }}
33 | {% endif %}
34 |
35 | {% trans %}The user has the following IP address/hostname:{% endtrans %} {{ ipAddress }} / {{ hostName }}
36 |
--------------------------------------------------------------------------------
/Resources/views/Form/3/adminMail.txt.twig:
--------------------------------------------------------------------------------
1 | {% trans %}Hello!{% endtrans %}
2 |
3 | {% trans %}A visitor to your website made a new rental request and sent the following:{% endtrans %}
4 |
5 | {% trans %}Form #{% endtrans %}: {{ form }}
6 | {% trans %}Contact{% endtrans %}: {{ contact.name }}
7 | {% trans %}Name{% endtrans %}: {{ userData.name }}
8 | {% if modVars.showCompany and userData.company %}
9 | {% trans %}Company{% endtrans %}: {{ userData.company }}
10 | {% endif %}
11 | {% trans %}Email{% endtrans %}: {{ userData.emailAddress }}
12 | {% if modVars.showPhone and userData.phone %}
13 | {% trans %}Phone number{% endtrans %}: {{ userData.phone }}
14 | {% endif %}
15 | {% if modVars.showUrl and userData.url %}
16 | {% trans %}Website{% endtrans %}: {{ userData.url }}
17 | {% endif %}
18 | {% if modVars.showLocation and userData.location %}
19 | {% trans %}Location{% endtrans %}: {{ userData.location }}
20 | {% endif %}
21 |
22 | {% for field in customFields %}
23 | {{ field.name }}: {{ field.data }}
24 | {% endfor %}
25 | {% if modVars.showComment and userData.comment %}
26 |
27 | {% trans %}Comment{% endtrans %}:
28 | {{ userData.comment }}
29 | {% endif %}
30 | {% if modVars.showFileAttachment and userData.fileUpload %}
31 |
32 | {% trans %}Attached file{% endtrans %}: {{ userData.fileUpload }}
33 | {% endif %}
34 |
35 | {% trans %}The user has the following IP address/hostname:{% endtrans %} {{ ipAddress }} / {{ hostName }}
36 |
--------------------------------------------------------------------------------
/Resources/views/Form/1/adminMail.txt.twig:
--------------------------------------------------------------------------------
1 | {% trans %}Hello!{% endtrans %}
2 |
3 | {% trans %}A visitor of to your web site used the form for contact and sent the following:{% endtrans %}
4 |
5 | {% trans %}Form #{% endtrans %}: {{ form }}
6 | {% trans %}Contact{% endtrans %}: {{ contact.name }}
7 | {% trans %}Name{% endtrans %}: {{ userData.name }}
8 | {% if modVars.showCompany and userData.company %}
9 | {% trans %}Company{% endtrans %}: {{ userData.company }}
10 | {% endif %}
11 | {% trans %}Email{% endtrans %}: {{ userData.emailAddress }}
12 | {% if modVars.showPhone and userData.phone %}
13 | {% trans %}Phone number'{% endtrans %}: {{ userData.phone }}
14 | {% endif %}
15 | {% if modVars.showUrl and userData.url %}
16 | {% trans %}Website{% endtrans %}: {{ userData.url }}
17 | {% endif %}
18 | {% if modVars.showLocation and userData.location %}
19 | {% trans %}Location{% endtrans %}: {{ userData.location }}
20 | {% endif %}
21 |
22 | {% for field in customFields %}
23 | {{ field.name }}: {{ field.data }}
24 | {% endfor %}
25 | {% if modVars.showComment and userData.comment %}
26 |
27 | {% trans %}Comment{% endtrans %}:
28 | {{ userData.comment }}
29 | {% endif %}
30 | {% if modVars.showFileAttachment and userData.fileUpload %}
31 |
32 | {% trans %}Attached file{% endtrans %}: {{ userData.fileUpload }}
33 | {% endif %}
34 |
35 | {% trans %}The user has the following IP address/hostname:{% endtrans %} {{ ipAddress }} / {{ hostName }}
36 |
--------------------------------------------------------------------------------
/Resources/views/Form/1/userMail.txt.twig:
--------------------------------------------------------------------------------
1 | {% trans with {'%s%': userData.uname} %}Hello %s%!{% endtrans %}
2 |
3 | {% trans %}This data was sent to us:{% endtrans %}
4 |
5 | {% trans %}Your name{% endtrans %}: {{ userData.name }}
6 | {% if modVars.showCompany and userData.company %}
7 | {% trans %}Company{% endtrans %}: {{ userData.company }}
8 | {% endif %}
9 | {% trans %}Email{% endtrans %}: {{ userData.emailAddress }}
10 | {% if modVars.showPhone and userData.phone %}
11 | {% trans %}Phone number{% endtrans %}: {{ userData.phone }}
12 | {% endif %}
13 | {% if modVars.showUrl and userData.url %}
14 | {% trans %}Website{% endtrans %}: {{ userData.url }}
15 | {% endif %}
16 | {% if modVars.showLocation and userData.location %}
17 | {% trans %}Location{% endtrans %}: {{ userData.location }}
18 | {% endif %}
19 |
20 | {% for field in customFields %}
21 | {{ field.name }}: {{ field.data }}
22 | {% endfor %}
23 | {% if modVars.showComment and userData.comment %}
24 |
25 | {% trans %}Comment{% endtrans %}:
26 | {{ userData.comment }}
27 | {% endif %}
28 | {% if modVars.showFileAttachment and userData.fileUpload %}
29 |
30 | {% trans %}Attached file{% endtrans %}: {{ userData.fileUpload }}
31 | {% endif %}
32 |
33 | {% trans %}Thanks for applying, we will keep your data strictly confidential.{% endtrans %}
34 |
35 | {% trans %}We will respond to your email address as soon as possible.{% endtrans %}
36 |
37 | {% trans with {'%s%': siteName} %}The %s% team{% endtrans %}
38 |
--------------------------------------------------------------------------------
/Form/Type/DeleteContactType.php:
--------------------------------------------------------------------------------
1 | add('cid', HiddenType::class)
30 | ->add('delete', SubmitType::class, [
31 | 'label' => 'Delete',
32 | 'icon' => 'fa-trash-alt',
33 | 'attr' => [
34 | 'class' => 'btn-danger'
35 | ]
36 | ])
37 | ->add('cancel', SubmitType::class, [
38 | 'label' => 'Cancel',
39 | 'icon' => 'fa-times'
40 | ])
41 | ;
42 | }
43 |
44 | public function getBlockPrefix()
45 | {
46 | return 'zikulaformiculamodule_deletecontact';
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Form/Type/DeleteSubmissionType.php:
--------------------------------------------------------------------------------
1 | add('sid', HiddenType::class)
30 | ->add('delete', SubmitType::class, [
31 | 'label' => 'Delete',
32 | 'icon' => 'fa-trash-alt',
33 | 'attr' => [
34 | 'class' => 'btn-danger'
35 | ]
36 | ])
37 | ->add('cancel', SubmitType::class, [
38 | 'label' => 'Cancel',
39 | 'icon' => 'fa-times'
40 | ])
41 | ;
42 | }
43 |
44 | public function getBlockPrefix()
45 | {
46 | return 'zikulaformiculamodule_deletesubmission';
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Resources/views/Form/3/userMail.txt.twig:
--------------------------------------------------------------------------------
1 | {% trans with {'%s%': userData.uname} %}Hello %s%!{% endtrans %}
2 |
3 | {% trans %}Thank you for your reservation.{% endtrans %}
4 |
5 | {% trans %}Kind regards{% endtrans %}
6 | {{ siteName }}
7 |
8 | {% trans %}This data was sent to us:{% endtrans %}
9 |
10 | {% trans %}Your name{% endtrans %}: {{ userData.name }}
11 | {% if modVars.showCompany and userData.company %}
12 | {% trans %}Company{% endtrans %}: {{ userData.company }}
13 | {% endif %}
14 | {% trans %}Email{% endtrans %}: {{ userData.emailAddress }}
15 | {% if modVars.showPhone and userData.phone %}
16 | {% trans %}Phone number{% endtrans %}: {{ userData.phone }}
17 | {% endif %}
18 | {% if modVars.showUrl and userData.url %}
19 | {% trans %}Website{% endtrans %}: {{ userData.url }}
20 | {% endif %}
21 | {% if modVars.showLocation and userData.location %}
22 | {% trans %}Location{% endtrans %}: {{ userData.location }}
23 | {% endif %}
24 |
25 | {% for field in customFields %}
26 | {{ field.name }}: {{ field.data }}
27 | {% endfor %}
28 | {% if modVars.showComment and userData.comment %}
29 |
30 | {% trans %}Comment{% endtrans %}:
31 | {{ userData.comment }}
32 | {% endif %}
33 | {% if modVars.showFileAttachment and userData.fileUpload %}
34 |
35 | {% trans %}Attached file{% endtrans %}: {{ userData.fileUpload }}
36 | {% endif %}
37 |
38 | {% trans %}We will respond to your email address as soon as possible.{% endtrans %}
39 |
40 | {% trans with {'%s%': siteName} %}The %s% team{% endtrans %}
41 |
--------------------------------------------------------------------------------
/Resources/translations/routes.en.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "Content-Type: text/plain; charset=UTF-8\n"
4 | "Content-Transfer-Encoding: 8bit\n"
5 | "Language: en\n"
6 |
7 | msgid "doc"
8 | msgstr "/installdoc/{name}"
9 | msgid "fos_js_routing_js"
10 | msgstr "/js/routing.{_format}"
11 | msgid "guiteebmainztheme_ajax_getsearchsuggestions"
12 | msgstr "/ajax/getSearchSuggestions"
13 | msgid "home"
14 | msgstr "/"
15 | msgid "install"
16 | msgstr "/install/{stage}"
17 | msgid "liip_imagine_filter"
18 | msgstr "/media/cache/resolve/{filter}/{path}"
19 | msgid "liip_imagine_filter_runtime"
20 | msgstr "/media/cache/resolve/{filter}/rc/{hash}/{path}"
21 | msgid "upgrade"
22 | msgstr "/upgrade/{stage}"
23 | msgid "zikula_hook_hook_changeproviderareaorder"
24 | msgstr "/hooks/changeorder"
25 | msgid "zikula_hook_hook_edit"
26 | msgstr "/hooks/{moduleName}"
27 | msgid "zikula_hook_hook_togglesubscribeareastatus"
28 | msgstr "/hooks/togglestatus"
29 | msgid "zikula_workflow_editor_index"
30 | msgstr "/editor/index"
31 | msgid "zikulaformiculamodule_config_clearcache"
32 | msgstr "/config/clearcache"
33 | msgid "zikulaformiculamodule_config_config"
34 | msgstr "/config/config"
35 | msgid "zikulaformiculamodule_contact_delete"
36 | msgstr "/contact/delete"
37 | msgid "zikulaformiculamodule_contact_edit"
38 | msgstr "/contact/edit"
39 | msgid "zikulaformiculamodule_contact_view"
40 | msgstr "/contact/view"
41 | msgid "zikulaformiculamodule_submission_delete"
42 | msgstr "/submission/delete"
43 | msgid "zikulaformiculamodule_submission_display"
44 | msgstr "/submission/display"
45 | msgid "zikulaformiculamodule_submission_view"
46 | msgstr "/submission/view"
47 | msgid "zikulaformiculamodule_user_index"
48 | msgstr "/"
--------------------------------------------------------------------------------
/Resources/views/Contact/edit.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ mode == 'create' ? 'Add contact'|trans : 'Edit contact'|trans }}
4 | {{ pageSetVar('title', mode == 'create' ? 'Add contact'|trans : 'Edit contact'|trans) }}
5 |
6 |
7 | {{ form_start(form) }}
8 | {{ form_errors(form) }}
9 |
10 |
11 | {% trans %}Basic contact information{% endtrans %}
12 | {{ form_row(form.name) }}
13 | {{ form_row(form.email) }}
14 | {{ form_row(form.public) }}
15 |
16 |
17 | {% trans %}User confirmation email data{% endtrans %}
18 | {{ form_row(form.senderName) }}
19 | {{ form_row(form.senderEmail) }}
20 | {{ form_row(form.sendingSubject) }}
21 |
22 |
{% trans %}You can use the following placeholders within the subject:{% endtrans %}
23 |
24 | %s = {% trans %}Site name{% endtrans %}
25 | %l = {% trans %}Site slogan{% endtrans %}
26 | %u = {% trans %}Site url{% endtrans %}
27 | %c = {% trans %}Contact\'s sender name{% endtrans %}
28 | %n<num> = {% trans %}User defined field name #num{% endtrans %}
29 | %d<num> = {% trans %}User defined field data #num{% endtrans %}
30 |
31 |
32 |
33 |
34 |
40 |
41 | {{ form_end(form) }}
42 |
--------------------------------------------------------------------------------
/Menu/ExtensionMenu.php:
--------------------------------------------------------------------------------
1 | factory->createItem('formiculaAdminMenu');
24 | if ($this->permissionApi->hasPermission($this->getBundleName() . '::', '::', ACCESS_ADMIN)) {
25 | $menu->addChild('View contacts', [
26 | 'route' => 'zikulaformiculamodule_contact_view',
27 | ])->setAttribute('icon', 'fas fa-users');
28 | $menu->addChild('Add contact', [
29 | 'route' => 'zikulaformiculamodule_contact_edit',
30 | ])->setAttribute('icon', 'fas fa-user-plus');
31 | $menu->addChild('View submissions', [
32 | 'route' => 'zikulaformiculamodule_submission_view',
33 | ])->setAttribute('icon', 'fas fa-envelope');
34 | $menu->addChild('Settings', [
35 | 'route' => 'zikulaformiculamodule_config_config',
36 | ])->setAttribute('icon', 'fas fa-wrench');
37 | $menu->addChild('Clear captcha image cache', [
38 | 'route' => 'zikulaformiculamodule_config_clearcache',
39 | ])->setAttribute('icon', 'fas fa-eraser');
40 | }
41 |
42 | return 0 === $menu->count() ? null : $menu;
43 | }
44 |
45 | public function getBundleName(): string
46 | {
47 | return 'ZikulaFormiculaModule';
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Twig/Extension/FormiculaCaptchaExtension.php:
--------------------------------------------------------------------------------
1 | captchaHelper = $captchaHelper;
30 | }
31 |
32 | public function getFunctions()
33 | {
34 | return [
35 | new TwigFunction('zikulaformiculamodule_simpleCaptcha', [$this, 'simpleCaptcha'], ['is_safe' => ['html']])
36 | ];
37 | }
38 |
39 | /**
40 | * The zikulaformiculamodule_simpleCaptcha function adds a simplecaptcha image to a form.
41 | *
42 | * Example:
43 | * {{ zikulaformiculamodule_simpleCaptcha(font='quikhand', size=14, bgColour='ffffff', fgColour='000000') }}
44 | *
45 | * @param string $font Name of font to use (arial, freesans, quickhand, vera)
46 | * @param int $size Font size
47 | * @param string $bgColour Background colour (hex code without the # char)
48 | * @param string $fgColour Foreground colour (hex code without the # char)
49 | *
50 | * @return string The image markup
51 | */
52 | public function simpleCaptcha($font = 'quickhand', $size = 14, $bgColour = 'ffffff', $fgColour = '000000'): string
53 | {
54 | return $this->captchaHelper->createCaptcha($font, $size, $bgColour, $fgColour);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Resources/views/Form/0/userForm.html.twig:
--------------------------------------------------------------------------------
1 | {{ include('@ZikulaFormiculaModule/Form/0/userHeader.html.twig') }}
2 | {{ form_start(form) }}
3 | {{ form_errors(form) }}
4 |
5 | {% trans %}Mandatory fields are indicated with an asterisk.{% endtrans %}
6 |
7 |
8 | {% trans %}Contact our team{% endtrans %}
9 | {{ form_row(form.form) }}
10 | {{ form_row(form.adminFormat) }}
11 | {% if modVars.sendConfirmationToUser and not modVars.showUserFormat %}
12 | {{ form_row(form.userFormat) }}
13 | {% endif %}
14 | {{ form_row(form.cid) }}
15 | {{ form_row(form.name) }}
16 | {% if modVars.showCompany %}
17 | {{ form_row(form.company) }}
18 | {% endif %}
19 | {{ form_row(form.emailAddress) }}
20 | {% if modVars.showPhone %}
21 | {{ form_row(form.phone) }}
22 | {% endif %}
23 | {% if modVars.showUrl %}
24 | {{ form_row(form.url) }}
25 | {% endif %}
26 | {% if modVars.showLocation %}
27 | {{ form_row(form.location) }}
28 | {% endif %}
29 | {% if modVars.showComment %}
30 | {{ form_row(form.comment) }}
31 | {% endif %}
32 | {% if modVars.sendConfirmationToUser and modVars.showUserFormat %}
33 | {{ form_row(form.userFormat) }}
34 | {% endif %}
35 | {% if modVars.showFileAttachment %}
36 | {{ form_row(form.fileUpload) }}
37 | {% endif %}
38 |
39 | {% if enableSpamCheck %}
40 | {{ include('@ZikulaFormiculaModule/Include/spamCheck.html.twig') }}
41 | {% endif %}
42 |
43 |
44 | {% set hooks = notifyDisplayHooks(eventName='zikulaformiculamodule.ui_hooks.forms.form_edit') %}
45 | {% if hooks is iterable and hooks|length > 0 %}
46 | {% for area, hook in hooks %}
47 | {{ hook|raw }}
48 | {% endfor %}
49 | {% endif %}
50 |
51 |
56 |
57 | {{ form_end(form) }}
58 |
59 | {{ include('@ZikulaFormiculaModule/Form/0/userFooter.html.twig') }}
60 |
--------------------------------------------------------------------------------
/Resources/views/Form/2/userForm.html.twig:
--------------------------------------------------------------------------------
1 | {{ include('@ZikulaFormiculaModule/Form/2/userHeader.html.twig') }}
2 | {{ form_start(form) }}
3 | {{ form_errors(form) }}
4 |
5 | {% trans %}Mandatory fields are indicated with an asterisk.{% endtrans %}
6 |
7 |
8 | {% trans %}Contact our team{% endtrans %}
9 | {{ form_row(form.form) }}
10 | {{ form_row(form.adminFormat) }}
11 | {% if modVars.sendConfirmationToUser and not modVars.showUserFormat %}
12 | {{ form_row(form.userFormat) }}
13 | {% endif %}
14 | {{ form_row(form.cid) }}
15 | {{ form_row(form.name) }}
16 | {% if modVars.showCompany %}
17 | {{ form_row(form.company) }}
18 | {% endif %}
19 | {{ form_row(form.emailAddress) }}
20 | {% if modVars.showPhone %}
21 | {{ form_row(form.phone) }}
22 | {% endif %}
23 | {% if modVars.showUrl %}
24 | {{ form_row(form.url) }}
25 | {% endif %}
26 | {% if modVars.showLocation %}
27 | {{ form_row(form.location) }}
28 | {% endif %}
29 | {% if modVars.showComment %}
30 | {{ form_row(form.comment) }}
31 | {% endif %}
32 | {% if modVars.sendConfirmationToUser and modVars.showUserFormat %}
33 | {{ form_row(form.userFormat) }}
34 | {% endif %}
35 | {% if modVars.showFileAttachment %}
36 | {{ form_row(form.fileUpload) }}
37 | {% endif %}
38 |
39 | {% if enableSpamCheck %}
40 | {{ include('@ZikulaFormiculaModule/Include/spamCheck.html.twig') }}
41 | {% endif %}
42 |
43 |
44 | {% set hooks = notifyDisplayHooks(eventName='zikulaformiculamodule.ui_hooks.forms.form_edit') %}
45 | {% if hooks is iterable and hooks|length > 0 %}
46 | {% for area, hook in hooks %}
47 | {{ hook|raw }}
48 | {% endfor %}
49 | {% endif %}
50 |
51 |
56 |
57 | {{ form_end(form) }}
58 |
59 | {{ include('@ZikulaFormiculaModule/Form/2/userFooter.html.twig') }}
60 |
--------------------------------------------------------------------------------
/Resources/views/Submission/delete.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% trans %}Delete form submission{% endtrans %}
4 | {{ pageSetVar('title', 'Delete form submission'|trans) }}
5 |
6 |
7 | {{ form_start(form) }}
8 | {{ form_errors(form) }}
9 |
10 |
11 | {% trans %}Confirmation prompt{% endtrans %}
12 | {% trans with { '%s%': submission.name } %}Do you really want to delete form submission '%s%'?{% endtrans %}
13 |
14 | {{ form_row(form.sid) }}
15 |
16 |
17 | {% trans %}Submission information{% endtrans %}
18 |
24 |
30 |
36 |
42 |
43 |
44 |
50 |
51 | {{ form_end(form) }}
52 |
--------------------------------------------------------------------------------
/Resources/views/Contact/view.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% trans %}View contacts{% endtrans %}
4 | {{ pageSetVar('title', 'View contacts'|trans) }}
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | {% trans %}ID{% endtrans %}
17 | {% trans %}Name{% endtrans %}
18 | {% trans %}Email{% endtrans %}
19 | {% trans %}Public{% endtrans %}
20 | {% trans %}Actions{% endtrans %}
21 |
22 |
23 |
24 | {% for contact in contacts %}
25 |
26 | {{ contact.cid }}
27 | {{ contact.name }}
28 | {{ contact.email }}
29 | {{ contact.public|yesNo }}
30 |
31 | {% if contact.allowEdit %}
32 |
33 | {% endif %}
34 | {% if contact.allowDelete %}
35 |
36 | {% endif %}
37 |
38 |
39 | {% else %}
40 |
41 | {% trans %}No contacts found.{% endtrans %}
42 |
43 | {% endfor %}
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Resources/views/Submission/view.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% trans %}View form submissions{% endtrans %}
4 | {{ pageSetVar('title', 'View form submissions'|trans) }}
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | {% trans %}ID{% endtrans %}
18 | {% trans %}Form #{% endtrans %}
19 | {% trans %}Contact ID{% endtrans %}
20 | {% trans %}Date{% endtrans %}
21 | {% trans %}Name{% endtrans %}
22 | {% trans %}Actions{% endtrans %}
23 |
24 |
25 |
26 | {% for submission in submissions %}
27 |
28 | {{ submission.sid }}
29 | {{ submission.form }}
30 | {{ submission.cid }}
31 | {{ submission.createdDate|format_date('short', 'short') }}
32 | {{ submission.name }}
33 |
34 |
35 |
36 |
37 |
38 | {% else %}
39 |
40 | {% trans %}No submissions found.{% endtrans %}
41 |
42 | {% endfor %}
43 |
44 |
45 | {{ adminFooter() }}
46 |
--------------------------------------------------------------------------------
/ContentType/Form/Type/FormType.php:
--------------------------------------------------------------------------------
1 | setTranslator($translator);
41 | $this->contactRepository = $contactRepository;
42 | }
43 |
44 | public function buildForm(FormBuilderInterface $builder, array $options)
45 | {
46 | $allContacts = $this->contactRepository->findBy([], ['name' => 'ASC']);
47 | $contactChoices = [];
48 | $contactChoices[$this->trans('All public contacts or form default')] = -1;
49 |
50 | // only use public contacts
51 | foreach ($allContacts as $contact) {
52 | if (!$contact->isPublic()) {
53 | continue;
54 | }
55 |
56 | $contactChoices[$contact->getName()] = $contact->getCid();
57 | }
58 |
59 | $builder
60 | ->add('form', IntegerType::class, [
61 | 'label' => $this->trans('Form #')
62 | ])
63 | ->add('contact', ChoiceType::class, [
64 | 'label' => $this->trans('Show contact'),
65 | 'choices' => $contactChoices
66 | ])
67 | ;
68 | }
69 |
70 | /**
71 | * {@inheritdoc}
72 | */
73 | public function getBlockPrefix()
74 | {
75 | return 'zikulaformiculamodule_contenttype_form';
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/Resources/views/Config/config.html.twig:
--------------------------------------------------------------------------------
1 | {{ pageAddAsset('javascript', zasset('@ZikulaFormiculaModule:js/ZikulaFormiculaModule.Config.js')) }}
2 |
3 |
4 | {% trans %}Settings{% endtrans %}
5 | {{ pageSetVar('title', 'Formicula settings'|trans) }}
6 |
7 |
8 | {{ form_start(form) }}
9 | {{ form_errors(form) }}
10 |
11 |
12 | {% trans %}General settings{% endtrans %}
13 | {{ form_row(form.defaultForm) }}
14 | {{ form_row(form.showCompany) }}
15 | {{ form_row(form.showPhone) }}
16 | {{ form_row(form.showUrl) }}
17 | {{ form_row(form.showLocation) }}
18 | {{ form_row(form.showComment) }}
19 |
20 |
21 | {% trans %}File upload settings{% endtrans %}
22 | {{ form_row(form.showFileAttachment) }}
23 | {{ form_row(form.uploadDirectory) }}
24 | {{ form_row(form.deleteUploadedFiles) }}
25 |
26 |
27 | {% trans %}Email and confirmation settings{% endtrans %}
28 | {{ form_row(form.sendConfirmationToUser) }}
29 | {{ form_row(form.defaultAdminFormat) }}
30 | {{ form_row(form.defaultUserFormat) }}
31 | {{ form_row(form.showUserFormat) }}
32 | {{ form_row(form.useContactsAsSender) }}
33 |
34 |
35 | {% trans %}Spam check settings{% endtrans %}
36 | {% trans %}For your information: There are better spam check modules out there. For example the Zikula Captcha module which can be hooked to Formicula. If you want to use this module, then please do not forget to add the required permissions for the Captcha module, too.{% endtrans %}
37 | {{ form_row(form.enableSpamCheck) }}
38 |
46 | {{ form_row(form.excludeSpamCheck) }}
47 |
48 |
49 | {% trans %}Form submission storage{% endtrans %}
50 | {{ form_row(form.storeSubmissionData) }}
51 |
52 | {{ form_row(form.storeSubmissionDataForms) }}
53 |
54 |
55 |
56 |
62 |
63 | {{ form_end(form) }}
64 |
--------------------------------------------------------------------------------
/HookSubscriber/FormUiHooksSubscriber.php:
--------------------------------------------------------------------------------
1 | translator = $translator;
36 | }
37 |
38 | /**
39 | * {@inheritdoc}
40 | */
41 | public function getOwner(): string
42 | {
43 | return 'ZikulaFormiculaModule';
44 | }
45 |
46 | /**
47 | * {@inheritdoc}
48 | */
49 | public function getCategory(): string
50 | {
51 | return UiHooksCategory::NAME;
52 | }
53 |
54 | /**
55 | * {@inheritdoc}
56 | */
57 | public function getTitle(): string
58 | {
59 | return $this->translator->trans('Form ui hooks subscriber');
60 | }
61 |
62 | /**
63 | * {@inheritdoc}
64 | */
65 | public function getEvents(): array
66 | {
67 | return [
68 | // Display hook for view/display templates.
69 | //UiHooksCategory::TYPE_DISPLAY_VIEW => 'zikulaformiculamodule.ui_hooks.forms.display_view',
70 | // Display hook for create/edit forms.
71 | UiHooksCategory::TYPE_FORM_EDIT => 'zikulaformiculamodule.ui_hooks.forms.form_edit',
72 | // Validate input from an item to be edited.
73 | UiHooksCategory::TYPE_VALIDATE_EDIT => 'zikulaformiculamodule.ui_hooks.forms.validate_edit',
74 | // Perform the final update actions for an edited item.
75 | //UiHooksCategory::TYPE_PROCESS_EDIT => 'zikulaformiculamodule.ui_hooks.forms.process_edit',
76 | // Validate input from an item to be deleted.
77 | //UiHooksCategory::TYPE_VALIDATE_DELETE => 'zikulaformiculamodule.ui_hooks.forms.validate_delete',
78 | // Perform the final delete actions for a deleted item.
79 | //UiHooksCategory::TYPE_PROCESS_DELETE => 'zikulaformiculamodule.ui_hooks.forms.process_delete'
80 | ];
81 | }
82 |
83 | public function getAreaName(): string
84 | {
85 | return 'subscriber.zikulaformiculamodule.ui_hooks.forms';
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/Traits/StandardFieldsTrait.php:
--------------------------------------------------------------------------------
1 | createdBy;
62 | }
63 |
64 | public function setCreatedBy(UserEntity $createdBy = null): void
65 | {
66 | if ($this->createdBy !== $createdBy) {
67 | $this->createdBy = $createdBy;
68 | }
69 | }
70 |
71 | public function getCreatedDate(): ?DateTimeInterface
72 | {
73 | return $this->createdDate;
74 | }
75 |
76 | public function setCreatedDate(DateTimeInterface $createdDate = null): void
77 | {
78 | if ($this->createdDate !== $createdDate) {
79 | $this->createdDate = $createdDate;
80 | }
81 | }
82 |
83 | public function getUpdatedBy(): ?UserEntity
84 | {
85 | return $this->updatedBy;
86 | }
87 |
88 | public function setUpdatedBy(UserEntity $updatedBy = null): void
89 | {
90 | if ($this->updatedBy !== $updatedBy) {
91 | $this->updatedBy = $updatedBy;
92 | }
93 | }
94 |
95 | public function getUpdatedDate(): ?DateTimeInterface
96 | {
97 | return $this->updatedDate;
98 | }
99 |
100 | public function setUpdatedDate(DateTimeInterface $updatedDate = null): void
101 | {
102 | if ($this->updatedDate !== $updatedDate) {
103 | $this->updatedDate = $updatedDate;
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/Form/Type/EditContactType.php:
--------------------------------------------------------------------------------
1 | add('name', TextType::class, [
34 | 'label' => 'Contact name',
35 | 'attr' => [
36 | 'maxlength' => 100
37 | ]
38 | ])
39 | ->add('email', TextType::class, [
40 | 'label' => 'Email address(es)',
41 | 'attr' => [
42 | 'maxlength' => 200
43 | ],
44 | 'help' => 'You may enter a single address or a comma separated list of addresses.'
45 | ])
46 | ->add('public', CheckboxType::class, [
47 | 'label' => 'Public',
48 | 'required' => false
49 | ])
50 | ->add('senderName', TextType::class, [
51 | 'label' => 'Sender name',
52 | 'required' => false,
53 | 'attr' => [
54 | 'maxlength' => 100
55 | ]
56 | ])
57 | ->add('senderEmail', EmailType::class, [
58 | 'label' => 'Sender email address',
59 | 'required' => false,
60 | 'attr' => [
61 | 'maxlength' => 100
62 | ]
63 | ])
64 | ->add('sendingSubject', TextType::class, [
65 | 'label' => 'Subject',
66 | 'required' => false,
67 | 'attr' => [
68 | 'maxlength' => 150
69 | ]
70 | ])
71 | ->add('save', SubmitType::class, [
72 | 'label' => 'Save',
73 | 'icon' => 'fa-check',
74 | 'attr' => [
75 | 'class' => 'btn-success'
76 | ]
77 | ])
78 | ->add('cancel', SubmitType::class, [
79 | 'label' => 'Cancel',
80 | 'icon' => 'fa-times'
81 | ])
82 | ;
83 | }
84 |
85 | public function getBlockPrefix()
86 | {
87 | return 'zikulaformiculamodule_editcontact';
88 | }
89 |
90 | public function configureOptions(OptionsResolver $resolver)
91 | {
92 | $resolver->setDefaults([
93 | 'data_class' => ContactEntity::class,
94 | ]);
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/Resources/views/Form/0/userConfirm.html.twig:
--------------------------------------------------------------------------------
1 | {{ include('@ZikulaFormiculaModule/Form/0/userHeader.html.twig') }}
2 |
3 |
4 | {% trans %}Thank you for your questions/comments to our website!{% endtrans %}
5 | {% trans %}We will reply as soon as possible.{% endtrans %}
6 |
7 |
8 |
9 | {% trans %}This data was sent to us:{% endtrans %}
10 |
11 |
12 |
13 |
14 |
15 |
16 | {% trans %}Field{% endtrans %}
17 | {% trans %}Value{% endtrans %}
18 |
19 |
20 |
21 |
22 | {% trans %}Your name{% endtrans %}
23 | {{ userData.name }}
24 |
25 | {% if modVars.showCompany and userData.company %}
26 |
27 | {% trans %}Company{% endtrans %}
28 | {{ userData.company }}
29 |
30 | {% endif %}
31 |
32 | {% trans %}Email{% endtrans %}
33 | {{ userData.emailAddress }}
34 |
35 | {% if modVars.showPhone and userData.phone %}
36 |
37 | {% trans %}Phone number{% endtrans %}
38 | {{ userData.phone }}
39 |
40 | {% endif %}
41 | {% if modVars.showUrl and userData.url %}
42 |
43 | {% trans %}Website{% endtrans %}
44 | {{ userData.url }}
45 |
46 | {% endif %}
47 | {% if modVars.showLocation and userData.location %}
48 |
49 | {% trans %}Location{% endtrans %}
50 | {{ userData.location }}
51 |
52 | {% endif %}
53 | {% for field in customFields %}
54 |
55 | {{ field.name }}
56 | {{ field.data }}
57 |
58 | {% endfor %}
59 | {% if modVars.showComment and userData.comment %}
60 |
61 |
62 | {{ userFormat == 'html' ? userData.comment : userData.comment|nl2br }}
63 |
64 | {% endif %}
65 | {% if modVars.showFileAttachment and userData.fileUpload %}
66 |
67 | {% trans %}Attached file{% endtrans %}
68 | {{ userData.fileUpload }}
69 |
70 | {% endif %}
71 |
72 |
73 |
74 | {% if modVars.sendConfirmationToUser %}
75 |
76 | {% if sentToUser %}
77 | {% trans %}Confirmation of your submission will be emailed to you in a few minutes.{% endtrans %}
78 | {% else %}
79 | {% trans %}There was an internal error when sending confirmation mail to you.{% endtrans %}
80 | {% endif %}
81 |
82 | {% endif %}
83 |
84 | {{ include('@ZikulaFormiculaModule/Form/0/userFooter.html.twig') }}
85 |
--------------------------------------------------------------------------------
/Resources/views/Form/1/userConfirm.html.twig:
--------------------------------------------------------------------------------
1 | {{ include('@ZikulaFormiculaModule/Form/1/userHeader.html.twig') }}
2 |
3 |
4 | {% trans %}Thanks for applying, we will keep your data strictly confidential.{% endtrans %}
5 |
6 | {% trans %}This data was sent to us:{% endtrans %}
7 |
8 |
9 | {% trans %}This data was sent to us:{% endtrans %}
10 |
11 |
12 |
13 |
14 |
15 |
16 | {% trans %}Field{% endtrans %}
17 | {% trans %}Value{% endtrans %}
18 |
19 |
20 |
21 |
22 | {% trans %}Your name{% endtrans %}
23 | {{ userData.name }}
24 |
25 | {% if modVars.showCompany and userData.company %}
26 |
27 | {% trans %}Company{% endtrans %}
28 | {{ userData.company }}
29 |
30 | {% endif %}
31 |
32 | {% trans %}Email{% endtrans %}
33 | {{ userData.emailAddress }}
34 |
35 | {% if modVars.showPhone and userData.phone %}
36 |
37 | {% trans %}Phone number{% endtrans %}
38 | {{ userData.phone }}
39 |
40 | {% endif %}
41 | {% if modVars.showUrl and userData.url %}
42 |
43 | {% trans %}Website{% endtrans %}
44 | {{ userData.url }}
45 |
46 | {% endif %}
47 | {% if modVars.showLocation and userData.location %}
48 |
49 | {% trans %}Location{% endtrans %}
50 | {{ userData.location }}
51 |
52 | {% endif %}
53 | {% for field in customFields %}
54 |
55 | {{ field.name }}
56 | {{ field.data }}
57 |
58 | {% endfor %}
59 | {% if modVars.showComment and userData.comment %}
60 |
61 |
62 | {{ userFormat == 'html' ? userData.comment : userData.comment|nl2br }}
63 |
64 | {% endif %}
65 | {% if modVars.showFileAttachment and userData.fileUpload %}
66 |
67 | {% trans %}Attached file{% endtrans %}
68 | {{ userData.fileUpload }}
69 |
70 | {% endif %}
71 |
72 |
73 |
74 | {% if modVars.sendConfirmationToUser %}
75 |
76 | {% if sentToUser %}
77 | {% trans %}Confirmation of your submission will be emailed to you in a few minutes.{% endtrans %}
78 | {% else %}
79 | {% trans %}There was an internal error when sending confirmation mail to you.{% endtrans %}
80 | {% endif %}
81 |
82 | {% endif %}
83 |
84 | {{ include('@ZikulaFormiculaModule/Form/1/userFooter.html.twig') }}
85 |
--------------------------------------------------------------------------------
/Resources/views/Form/2/userConfirm.html.twig:
--------------------------------------------------------------------------------
1 | {{ include('@ZikulaFormiculaModule/Form/2/userHeader.html.twig') }}
2 |
3 |
4 | {% trans %}Thank you for your questions/comments to our website!{% endtrans %}
5 | {% trans %}We will reply as soon as possible.{% endtrans %}
6 |
7 | {% trans %}This data was sent to us:{% endtrans %}
8 |
9 |
10 | {% trans %}This data was sent to us:{% endtrans %}
11 |
12 |
13 |
14 |
15 |
16 |
17 | {% trans %}Field{% endtrans %}
18 | {% trans %}Value{% endtrans %}
19 |
20 |
21 |
22 |
23 | {% trans %}Your name{% endtrans %}
24 | {{ userData.name }}
25 |
26 | {% if modVars.showCompany and userData.company %}
27 |
28 | {% trans %}Company{% endtrans %}
29 | {{ userData.company }}
30 |
31 | {% endif %}
32 |
33 | {% trans %}Email{% endtrans %}
34 | {{ userData.emailAddress }}
35 |
36 | {% if modVars.showPhone and userData.phone %}
37 |
38 | {% trans %}Phone number{% endtrans %}
39 | {{ userData.phone }}
40 |
41 | {% endif %}
42 | {% if modVars.showUrl and userData.url %}
43 |
44 | {% trans %}Website{% endtrans %}
45 | {{ userData.url }}
46 |
47 | {% endif %}
48 | {% if modVars.showLocation and userData.location %}
49 |
50 | {% trans %}Location{% endtrans %}
51 | {{ userData.location }}
52 |
53 | {% endif %}
54 | {% for field in customFields %}
55 |
56 | {{ field.name }}
57 | {{ field.data }}
58 |
59 | {% endfor %}
60 | {% if modVars.showComment and userData.comment %}
61 |
62 |
63 | {{ userFormat == 'html' ? userData.comment : userData.comment|nl2br }}
64 |
65 | {% endif %}
66 | {% if modVars.showFileAttachment and userData.fileUpload %}
67 |
68 | {% trans %}Attached file{% endtrans %}
69 | {{ userData.fileUpload }}
70 |
71 | {% endif %}
72 |
73 |
74 |
75 | {% if modVars.sendConfirmationToUser %}
76 |
77 | {% if sentToUser %}
78 | {% trans %}Confirmation of your submission will be emailed to you in a few minutes.{% endtrans %}
79 | {% else %}
80 | {% trans %}There was an internal error when sending confirmation mail to you.{% endtrans %}
81 | {% endif %}
82 |
83 | {% endif %}
84 |
85 | {{ include('@ZikulaFormiculaModule/Form/2/userFooter.html.twig') }}
86 |
--------------------------------------------------------------------------------
/Resources/views/Form/3/userConfirm.html.twig:
--------------------------------------------------------------------------------
1 | {{ include('@ZikulaFormiculaModule/Form/3/userHeader.html.twig') }}
2 |
3 |
4 |
{% trans with { '%s%': userData.uname } %}Thank you %s% for your reservation.{% endtrans %}
5 |
{% trans with { '%s%': userData.uemail } %}An email with the filled in data will be sent to our and your email address (%s%). We will reply as soon as possible.{% endtrans %}
6 |
7 | {% trans %}This data was sent to us:{% endtrans %}
8 |
9 |
10 | {% trans %}This data was sent to us:{% endtrans %}
11 |
12 |
13 |
14 |
15 |
16 |
17 | {% trans %}Field{% endtrans %}
18 | {% trans %}Value{% endtrans %}
19 |
20 |
21 |
22 |
23 | {% trans %}Your name{% endtrans %}
24 | {{ userData.name }}
25 |
26 | {% if modVars.showCompany and userData.company %}
27 |
28 | {% trans %}Company{% endtrans %}
29 | {{ userData.company }}
30 |
31 | {% endif %}
32 |
33 | {% trans %}Email{% endtrans %}
34 | {{ userData.emailAddress }}
35 |
36 | {% if modVars.showPhone and userData.phone %}
37 |
38 | {% trans %}Phone number{% endtrans %}
39 | {{ userData.phone }}
40 |
41 | {% endif %}
42 | {% if modVars.showUrl and userData.url %}
43 |
44 | {% trans %}Website{% endtrans %}
45 | {{ userData.url }}
46 |
47 | {% endif %}
48 | {% if modVars.showLocation and userData.location %}
49 |
50 | {% trans %}Location{% endtrans %}
51 | {{ userData.location }}
52 |
53 | {% endif %}
54 | {% for field in customFields %}
55 |
56 | {{ field.name }}
57 | {{ field.data }}
58 |
59 | {% endfor %}
60 | {% if modVars.showComment and userData.comment %}
61 |
62 |
63 | {{ userFormat == 'html' ? userData.comment : userData.comment|nl2br }}
64 |
65 | {% endif %}
66 | {% if modVars.showFileAttachment and userData.fileUpload %}
67 |
68 | {% trans %}Attached file{% endtrans %}
69 | {{ userData.fileUpload }}
70 |
71 | {% endif %}
72 |
73 |
74 |
75 | {% if modVars.sendConfirmationToUser %}
76 |
77 | {% if sentToUser %}
78 | {% trans %}Confirmation of your submission will be emailed to you in a few minutes.{% endtrans %}
79 | {% else %}
80 | {% trans %}There was an internal error when sending confirmation mail to you.{% endtrans %}
81 | {% endif %}
82 |
83 | {% endif %}
84 |
85 | {{ include('@ZikulaFormiculaModule/Form/3/userFooter.html.twig') }}
86 |
--------------------------------------------------------------------------------
/ContentType/FormType.php:
--------------------------------------------------------------------------------
1 | translator->trans('Formicula form');
50 | }
51 |
52 | /**
53 | * {@inheritdoc}
54 | */
55 | public function getDescription(): string
56 | {
57 | return $this->translator->trans('Display a specific Formicula form.');
58 | }
59 |
60 | /**
61 | * {@inheritdoc}
62 | */
63 | public function getDefaultData(): array
64 | {
65 | return [
66 | 'form' => 0,
67 | 'contact' => -1
68 | ];
69 | }
70 |
71 | /**
72 | * {@inheritdoc}
73 | */
74 | public function displayView(): string
75 | {
76 | $this->data = $this->getData();
77 | if (null === $this->data['form'] || (int) ($this->data['form']) < 0) {
78 | return '';
79 | }
80 |
81 | $attributes = [
82 | '_controller' => 'Zikula\FormiculaModule\Controller\UserController::index',
83 | '_route' => 'zikulaformiculamodule_user_index'
84 | ];
85 |
86 | $subRequest = $this->requestStack->getCurrentRequest()->duplicate([
87 | 'form' => (int) $this->data['form'],
88 | 'cid' => $this->data['contact']
89 | ], null, $attributes);
90 |
91 | $response = $this->httpKernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
92 |
93 | return $response->getContent();
94 | }
95 |
96 | /**
97 | * {@inheritdoc}
98 | */
99 | public function displayEditing(): string
100 | {
101 | $this->data = $this->getData();
102 | if (null === $this->data['form'] || (int) ($this->data['form']) < 0) {
103 | return $this->translator->trans('No form selected.');
104 | }
105 |
106 | if ($this->data['contact'] > 0) {
107 | $output = '' . $this->translator->trans('The Formicula form #%num% is shown here with only contact %con%', ['%num%' => $this->data['form'], '%con%' => $this->data['contact']]) . '
';
108 | } else {
109 | $output = '' . $this->translator->trans('The Formicula form #%num% is shown here with all contacts', ['%num%' => $this->data['form']]) . '
';
110 | }
111 |
112 | return $output;
113 | }
114 |
115 | /**
116 | * {@inheritdoc}
117 | */
118 | public function getEditFormClass(): string
119 | {
120 | return EditFormType::class;
121 | }
122 |
123 | /**
124 | * @required
125 | */
126 | public function setRequestStack(RequestStack $requestStack)
127 | {
128 | $this->requestStack = $requestStack;
129 | }
130 |
131 | /**
132 | * @required
133 | */
134 | public function setHttpKernel(HttpKernelInterface $httpKernel)
135 | {
136 | $this->httpKernel = $httpKernel;
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/Helper/EnvironmentHelper.php:
--------------------------------------------------------------------------------
1 | kernel = $kernel;
57 | $this->translator = $translator;
58 | $this->variableApi = $variableApi;
59 | $this->requestStack = $requestStack;
60 | $this->cacheDirectory = $cacheDir;
61 | }
62 |
63 | /**
64 | * Checks some environment aspects and sets error messages.
65 | */
66 | public function check(): void
67 | {
68 | $request = $this->requestStack->getCurrentRequest();
69 | $flashBag = null !== $request ? $request->getSession()->getFlashBag() : null;
70 | if (null === $flashBag) {
71 | return;
72 | }
73 |
74 | if (null === $this->kernel->getModule('ZikulaMailerModule')) {
75 | $flashBag->add('error', $this->translator->trans('Mailer module is not available - unable to send emails!'));
76 | }
77 |
78 | if (false === $this->variableApi->get('ZikulaFormiculaModule', 'enableSpamCheck', true)) {
79 | return;
80 | }
81 |
82 | if (!function_exists('imagettfbbox')
83 | || (!(imagetypes() && IMG_PNG) && !(imagetypes() && IMG_JPG) && !(imagetypes() && IMG_GIF))
84 | ) {
85 | $flashBag->add('status', $this->translator->trans('There are no image function available - Captchas have been disabled.'));
86 | $this->variableApi->set('ZikulaFormiculaModule', 'enableSpamCheck', false);
87 | }
88 |
89 | if (!file_exists($this->cacheDirectory) || !is_writable($this->cacheDirectory)) {
90 | $flashBag->add('status', $this->translator->trans('Formicula cache directory does not exist or is not writable - Captchas have been disabled.'));
91 | $this->variableApi->set('ZikulaFormiculaModule', 'enableSpamCheck', false);
92 | } elseif (!file_exists($this->cacheDirectory . '/.htaccess')) {
93 | $flashBag->add('status', $this->translator->trans('Formicula cache directory does not contain the required .htaccess file - Captchas have been disabled.'));
94 | $this->variableApi->set('ZikulaFormiculaModule', 'enableSpamCheck', false);
95 | }
96 | }
97 |
98 | public function clearCache(): void
99 | {
100 | if (!file_exists($this->cacheDirectory) || !is_writable($this->cacheDirectory)) {
101 | return;
102 | }
103 |
104 | $files = (new Finder())->files()->in($this->cacheDirectory)
105 | ->notName(['.htaccess', 'index.htm', 'index.html'])
106 | ;
107 | foreach ($files as $file) {
108 | unlink($file->getRealPath());
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/Resources/views/Submission/display.html.twig:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% trans %}View submitted form data{% endtrans %}
4 | {{ pageSetVar('title', 'View submitted form data'|trans) }}
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | {% trans %}Date{% endtrans %}
17 | {% trans %}Name{% endtrans %}
18 | {% trans %}IP address{% endtrans %}
19 | {% trans %}Hostname{% endtrans %}
20 | {% trans %}Contact ID{% endtrans %}
21 |
22 |
23 |
24 |
25 | {{ submission.createdDate|format_date('short', 'short') }}
26 | {{ submission.name }}
27 | {{ submission.ipAddress }}
28 | {{ submission.hostName }}
29 | {{ submission.cid }}
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | {% trans %}Website{% endtrans %}
43 | {% trans %}Company{% endtrans %}
44 | {% trans %}Phone number{% endtrans %}
45 | {% trans %}Location{% endtrans %}
46 |
47 |
48 |
49 |
50 | {% if submission.url != '' %}{{ submission.url }} {% else %}{% trans %}None{% endtrans %}{% endif %}
51 | {{ submission.company|default('None'|trans) }}
52 | {{ submission.phoneNumber|default('None'|trans) }}
53 | {{ submission.location|default('None'|trans) }}
54 |
55 |
56 |
57 | {% if submission.customData|length > 0 %}
58 |
59 | {% trans %}Custom fields{% endtrans %}
60 |
61 |
62 |
63 |
64 |
65 | {% trans %}Name{% endtrans %}
66 | {% trans %}Value{% endtrans %}
67 |
68 |
69 |
70 | {% for key, value in submission.customData %}
71 |
72 | {{ key }}
73 | {{ value }}
74 |
75 | {% endfor %}
76 |
77 |
78 | {% endif %}
79 | {% if submission.comment != '' %}
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | {{ submission.comment|safeHtml|nl2br }}
92 |
93 |
94 |
95 | {% endif %}
96 |
--------------------------------------------------------------------------------
/Controller/ConfigController.php:
--------------------------------------------------------------------------------
1 | environmentHelper = $environmentHelper;
51 | }
52 |
53 | /**
54 | * @Route("/config")
55 | * @Template("@ZikulaFormiculaModule/Config/config.html.twig")
56 | * @Theme("admin")
57 | */
58 | public function config(Request $request, string $cacheDir): array
59 | {
60 | // check necessary environment
61 | $this->environmentHelper->check();
62 |
63 | $modVars = $this->getVars();
64 |
65 | // scan the templates folder for installed forms
66 | $templateDirectory = __DIR__ . '/../Resources/views/Form/';
67 | $formChoices = [];
68 | $finder = new Finder();
69 |
70 | foreach ($finder->directories()->in($templateDirectory)->sortByName() as $directory) {
71 | $finder2 = new Finder();
72 | $finder2->files()->in($directory->getRealPath());
73 | $formNumber = $directory->getFilename();
74 | $label = $this->trans(
75 | 'Form #%num% containing %count% templates',
76 | [
77 | '%num%' => $formNumber,
78 | '%count%' => count($finder2)
79 | ]
80 | );
81 | $formChoices[$label] = $formNumber;
82 | }
83 |
84 | $form = $this->createForm(
85 | ConfigType::class,
86 | $modVars,
87 | [
88 | 'formChoices' => $formChoices
89 | ]
90 | );
91 | $form->handleRequest($request);
92 | if ($form->isSubmitted() && $form->isValid()) {
93 | if ($form->get('save')->isClicked()) {
94 | $formData = $form->getData();
95 |
96 | if (!empty($formData['uploadDirectory']) && !is_writable($formData['uploadDirectory'])) {
97 | $this->addFlash('error', 'The webserver cannot write into the upload directory!');
98 | } else {
99 | // remove spaces in the comma separated forms lists
100 | $formData['excludeSpamCheck'] = preg_replace('/\s*/m', '', $formData['excludeSpamCheck']);
101 | $formData['storeSubmissionDataForms'] = preg_replace('/\s*/m', '', $formData['storeSubmissionDataForms']);
102 |
103 | $this->setVars($formData);
104 |
105 | $this->addFlash('status', 'Done! Configuration updated.');
106 | }
107 | } elseif ($form->get('cancel')->isClicked()) {
108 | $this->addFlash('status', 'Operation cancelled.');
109 | }
110 | }
111 |
112 | $templateParameters = array_merge($modVars, [
113 | 'form' => $form->createView(),
114 | 'cacheDirectory' => $cacheDir
115 | ]);
116 |
117 | return $templateParameters;
118 | }
119 |
120 | /**
121 | * Clear image cache.
122 | *
123 | * @Route("/clearcache")
124 | * @Theme("admin")
125 | */
126 | public function clearCache(): RedirectResponse
127 | {
128 | $this->environmentHelper->clearCache();
129 | $this->addFlash('status', 'The captcha image cache has been cleared.');
130 |
131 | return $this->redirectToRoute('zikulaformiculamodule_contact_view');
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/Controller/SubmissionController.php:
--------------------------------------------------------------------------------
1 | submissionRepository = $submissionRepository;
55 | $this->environmentHelper = $environmentHelper;
56 | }
57 |
58 | /**
59 | * Shows a list of submissions.
60 | *
61 | * @Route("/view")
62 | * @PermissionCheck("admin")
63 | * @Template("@ZikulaFormiculaModule/Submission/view.html.twig")
64 | * @Theme("admin")
65 | */
66 | public function view(Request $request)
67 | {
68 | // check necessary environment
69 | $this->environmentHelper->check();
70 |
71 | $submissions = $this->submissionRepository->findBy([], ['sid' => 'DESC']);
72 |
73 | return [
74 | 'submissions' => $submissions
75 | ];
76 | }
77 |
78 | /**
79 | * Shows a specific form submission.
80 | *
81 | * @Route("/display")
82 | * @PermissionCheck("admin")
83 | * @Template("@ZikulaFormiculaModule/Submission/display.html.twig")
84 | * @Theme("admin")
85 | */
86 | public function display(Request $request)
87 | {
88 | // check necessary environment
89 | $this->environmentHelper->check();
90 |
91 | $submissionId = $request->query->getInt('sid', -1);
92 | $submission = $this->submissionRepository->find($submissionId);
93 | if (false === $submission) {
94 | $this->addFlash('error', 'Form submission could not be found.');
95 |
96 | return $this->redirectToRoute('zikulaformiculamodule_submission_view');
97 | }
98 |
99 | return [
100 | 'submission' => $submission
101 | ];
102 | }
103 |
104 | /**
105 | * Deletes an existing submit from the database.
106 | *
107 | * @Route("/delete")
108 | * @PermissionCheck("delete")
109 | * @Template("@ZikulaFormiculaModule/Submission/delete.html.twig")
110 | * @Theme("admin")
111 | */
112 | public function delete(Request $request)
113 | {
114 | // check necessary environment
115 | $this->environmentHelper->check();
116 |
117 | $entityManager = $this->getDoctrine()->getManager();
118 | $submissionId = $request->query->getInt('sid', -1);
119 |
120 | $submission = $this->submissionRepository->find($submissionId);
121 | if (false === $submission) {
122 | $this->addFlash('error', 'Form submission could not be found.');
123 |
124 | return $this->redirectToRoute('zikulaformiculamodule_submission_view');
125 | }
126 |
127 | $form = $this->createForm(DeleteSubmissionType::class, $submission);
128 | $form->handleRequest($request);
129 | if ($form->isSubmitted() && $form->isValid()) {
130 | if ($form->get('delete')->isClicked()) {
131 | $submission = $form->getData();
132 | $entityManager->remove($submission);
133 | $entityManager->flush();
134 | $this->addFlash('status', 'Done! Submission deleted.');
135 | } elseif ($form->get('cancel')->isClicked()) {
136 | $this->addFlash('status', 'Operation cancelled.');
137 | }
138 |
139 | return $this->redirectToRoute('zikulaformiculamodule_submission_view');
140 | }
141 |
142 | return [
143 | 'form' => $form->createView(),
144 | 'submission' => $submission
145 | ];
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/Form/Type/UserSubmissionType.php:
--------------------------------------------------------------------------------
1 | add('form', HiddenType::class)
39 | ->add('adminFormat', HiddenType::class)
40 | ;
41 | if ($modVars['sendConfirmationToUser'] && !$modVars['showUserFormat']) {
42 | $builder->add('userFormat', HiddenType::class);
43 | }
44 | $builder
45 | ->add('cid', ChoiceType::class, [
46 | 'label' => 'Contact',
47 | 'choices' => $options['contactChoices'],
48 | 'expanded' => false,
49 | 'multiple' => false
50 | ])
51 | ->add('name', TextType::class, [
52 | 'label' => 'Your name',
53 | 'attr' => [
54 | 'maxlength' => 150
55 | ]
56 | ])
57 | ;
58 | if ($modVars['showCompany']) {
59 | $builder->add('company', TextType::class, [
60 | 'label' => 'Company',
61 | 'required' => false,
62 | 'attr' => [
63 | 'maxlength' => 150
64 | ]
65 | ]);
66 | }
67 | $builder->add('emailAddress', EmailType::class, [
68 | 'label' => 'Email address',
69 | 'attr' => [
70 | 'maxlength' => 150,
71 | 'placeholder' => 'Enter a valid email address'
72 | ]
73 | ]);
74 | if ($modVars['showPhone']) {
75 | $builder->add('phone', TextType::class, [
76 | 'label' => 'Phone number',
77 | 'required' => false,
78 | 'attr' => [
79 | 'maxlength' => 50
80 | ]
81 | ]);
82 | }
83 | if ($modVars['showUrl']) {
84 | $builder->add('url', UrlType::class, [
85 | 'label' => 'Website',
86 | 'attr' => [
87 | 'maxlength' => 150,
88 | 'placeholder' => 'Enter a valid url'
89 | ],
90 | 'required' => false
91 | ]);
92 | }
93 | if ($modVars['showLocation']) {
94 | $builder->add('location', TextType::class, [
95 | 'label' => 'Location',
96 | 'required' => false,
97 | 'attr' => [
98 | 'maxlength' => 150
99 | ]
100 | ]);
101 | }
102 | if ($modVars['sendConfirmationToUser'] && $modVars['showUserFormat']) {
103 | $builder->add('userFormat', ChoiceType::class, [
104 | 'label' => 'Email confirmation format',
105 | 'choices' => [
106 | 'HTML' => 'html',
107 | 'Text' => 'plain',
108 | 'None' => 'none'
109 | ],
110 | 'expanded' => false,
111 | 'multiple' => false
112 | ]);
113 | }
114 | if ($modVars['showComment']) {
115 | $builder->add('comment', TextareaType::class, [
116 | 'label' => 'Comment',
117 | 'attr' => [
118 | 'placeholder' => 'Enter your comments here'
119 | ]
120 | ]);
121 | }
122 | if ($modVars['showFileAttachment']) {
123 | $builder->add('fileUpload', FileType::class, [
124 | 'label' => 'Attach a file',
125 | 'required' => false
126 | ]);
127 | }
128 | $builder->add('submit', SubmitType::class, [
129 | 'label' => 'Send',
130 | 'icon' => 'fa-check',
131 | 'attr' => [
132 | 'class' => 'btn-success'
133 | ]
134 | ]);
135 | }
136 |
137 | public function getBlockPrefix()
138 | {
139 | return 'zikulaformiculamodule_usersubmission';
140 | }
141 |
142 | public function configureOptions(OptionsResolver $resolver)
143 | {
144 | $resolver->setDefaults([
145 | 'modVars' => [],
146 | 'contactChoices' => []
147 | ]);
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/Entity/ContactEntity.php:
--------------------------------------------------------------------------------
1 | name = '';
102 | $this->email = '';
103 | $this->public = false;
104 | $this->senderName = '';
105 | $this->senderEmail = '';
106 | $this->sendingSubject = '';
107 | }
108 |
109 | /**
110 | * Gets the id of the contact.
111 | */
112 | public function getCid(): ?int
113 | {
114 | return $this->cid;
115 | }
116 |
117 | /**
118 | * Sets the id for the contact.
119 | */
120 | public function setCid(int $cid): void
121 | {
122 | $this->cid = $cid;
123 | }
124 |
125 | /**
126 | * Gets the name of the contact.
127 | */
128 | public function getName(): string
129 | {
130 | return $this->name;
131 | }
132 |
133 | /**
134 | * Sets the name for the contact.
135 | */
136 | public function setName(string $name): void
137 | {
138 | $this->name = $name;
139 | }
140 |
141 | /**
142 | * Gets the email address of the contact.
143 | */
144 | public function getEmail(): string
145 | {
146 | return $this->email;
147 | }
148 |
149 | /**
150 | * Sets the email address for the contact.
151 | */
152 | public function setEmail(string $email): void
153 | {
154 | $this->email = $email;
155 | }
156 |
157 | /**
158 | * Gets the public flag of the contact.
159 | */
160 | public function isPublic(): bool
161 | {
162 | return $this->public;
163 | }
164 |
165 | /**
166 | * Sets the public flag for the contact.
167 | */
168 | public function setPublic(bool $public): void
169 | {
170 | if (is_bool($public)) {
171 | $this->public = $public;
172 | }
173 | }
174 |
175 | /**
176 | * Gets the sender name of the contact.
177 | */
178 | public function getSenderName(): string
179 | {
180 | return $this->senderName;
181 | }
182 |
183 | /**
184 | * Sets the sender name for the contact.
185 | */
186 | public function setSenderName(string $senderName): void
187 | {
188 | $this->senderName = $senderName;
189 | }
190 |
191 | /**
192 | * Gets the sender email address of the contact.
193 | */
194 | public function getSenderEmail(): string
195 | {
196 | return $this->senderEmail;
197 | }
198 |
199 | /**
200 | * Sets the sender email address for the contact.
201 | */
202 | public function setSenderEmail(string $senderEmail): void
203 | {
204 | $this->senderEmail = $senderEmail;
205 | }
206 |
207 | /**
208 | * Gets the sending subject of the contact.
209 | */
210 | public function getSendingSubject(): string
211 | {
212 | return $this->sendingSubject;
213 | }
214 |
215 | /**
216 | * Sets the sending subject for the contact.
217 | */
218 | public function setSendingSubject(string $subject): void
219 | {
220 | $this->sendingSubject = $subject;
221 | }
222 | }
223 |
--------------------------------------------------------------------------------
/Resources/views/Form/1/userForm.html.twig:
--------------------------------------------------------------------------------
1 | {{ include('@ZikulaFormiculaModule/Form/1/userHeader.html.twig') }}
2 | {{ form_start(form) }}
3 | {{ form_errors(form) }}
4 |
5 | {% trans %}Mandatory fields are indicated with an asterisk.{% endtrans %}
6 |
7 |
8 | {% trans %}Apply online{% endtrans %}
9 | {{ form_row(form.form) }}
10 | {{ form_row(form.adminFormat) }}
11 | {% if modVars.sendConfirmationToUser and not modVars.showUserFormat %}
12 | {{ form_row(form.userFormat) }}
13 | {% endif %}
14 |
15 | {{ form_row(form.cid) }}
16 |
17 |
25 | {{ form_row(form.name) }}
26 |
34 | {% if modVars.showCompany %}
35 | {{ form_row(form.company) }}
36 | {% endif %}
37 | {{ form_row(form.emailAddress) }}
38 | {% if modVars.showLocation %}
39 |
47 | {{ form_row(form.location, {label: 'Zip City'|trans}) }}
48 | {% endif %}
49 |
57 |
65 | {% if modVars.showPhone %}
66 | {{ form_row(form.phone) }}
67 | {% endif %}
68 | {% if modVars.showUrl %}
69 | {{ form_row(form.url) }}
70 | {% endif %}
71 | {% if modVars.showComment %}
72 | {{ form_row(form.comment) }}
73 | {% endif %}
74 | {% if modVars.sendConfirmationToUser and modVars.showUserFormat %}
75 | {{ form_row(form.userFormat) }}
76 | {% endif %}
77 | {% if modVars.showFileAttachment %}
78 | {{ form_row(form.fileUpload) }}
79 | {% endif %}
80 |
81 | {% if enableSpamCheck %}
82 | {{ include('@ZikulaFormiculaModule/Include/spamCheck.html.twig') }}
83 | {% endif %}
84 |
85 |
86 | {% set hooks = notifyDisplayHooks(eventName='zikulaformiculamodule.ui_hooks.forms.form_edit') %}
87 | {% if hooks is iterable and hooks|length > 0 %}
88 | {% for area, hook in hooks %}
89 | {{ hook|raw }}
90 | {% endfor %}
91 | {% endif %}
92 |
93 |
98 |
99 | {{ form_end(form) }}
100 |
101 | {{ include('@ZikulaFormiculaModule/Form/1/userFooter.html.twig') }}
102 |
103 | {% set customScript %}
104 |
111 | {% endset %}
112 | {{ pageAddAsset('footer', customScript) }}
113 |
--------------------------------------------------------------------------------
/Form/Type/ConfigType.php:
--------------------------------------------------------------------------------
1 | add('defaultForm', ChoiceType::class, [
33 | 'label' => 'Default form',
34 | 'choices' => $options['formChoices'],
35 | 'expanded' => false,
36 | 'multiple' => false,
37 | 'help' => 'This form is used when no form is specified.'
38 | ])
39 | ->add('showCompany', CheckboxType::class, [
40 | 'label' => 'Show company',
41 | 'required' => false
42 | ])
43 | ->add('showPhone', CheckboxType::class, [
44 | 'label' => 'Show phone number',
45 | 'required' => false
46 | ])
47 | ->add('showUrl', CheckboxType::class, [
48 | 'label' => 'Show url',
49 | 'required' => false
50 | ])
51 | ->add('showLocation', CheckboxType::class, [
52 | 'label' => 'Show location',
53 | 'required' => false
54 | ])
55 | ->add('showComment', CheckboxType::class, [
56 | 'label' => 'Show comments textarea',
57 | 'required' => false
58 | ])
59 | ->add('showFileAttachment', CheckboxType::class, [
60 | 'label' => 'Show file attachment',
61 | 'required' => false
62 | ])
63 | ->add('uploadDirectory', TextType::class, [
64 | 'label' => 'Directory for uploaded files',
65 | 'attr' => [
66 | 'maxlength' => 150
67 | ]
68 | ])
69 | ->add('deleteUploadedFiles', CheckboxType::class, [
70 | 'label' => 'Delete uploaded file(s) after sending',
71 | 'required' => false
72 | ])
73 | ->add('sendConfirmationToUser', CheckboxType::class, [
74 | 'label' => 'Send confirmation email to user',
75 | 'required' => false
76 | ])
77 | ->add('defaultAdminFormat', ChoiceType::class, [
78 | 'label' => 'Default email format for admin emails',
79 | 'choices' => [
80 | 'HTML' => 'html',
81 | 'Plain text' => 'plain'
82 | ],
83 | 'expanded' => false,
84 | 'multiple' => false
85 | ])
86 | ->add('defaultUserFormat', ChoiceType::class, [
87 | 'label' => 'Default email format for user emails',
88 | 'choices' => [
89 | 'HTML' => 'html',
90 | 'Plain text' => 'plain',
91 | 'None' => 'none'
92 | ],
93 | 'expanded' => false,
94 | 'multiple' => false
95 | ])
96 | ->add('showUserFormat', CheckboxType::class, [
97 | 'label' => 'Show user email format selector',
98 | 'required' => false
99 | ])
100 | ->add('useContactsAsSender', CheckboxType::class, [
101 | 'label' => 'Use contact mail addresses as sender',
102 | 'required' => false,
103 | 'help' => 'Disable this if you experience problems with your SMTP server'
104 | ])
105 | ->add('enableSpamCheck', CheckboxType::class, [
106 | 'label' => 'Activate simple spam check',
107 | 'required' => false,
108 | 'alert' => ['Make sure you the necessary form fields are available, see the docs for more information. This option will be turned off by Formicula automatically if no PHP functions for creating images are available.' => 'info']
109 | ])
110 | ->add('excludeSpamCheck', TextType::class, [
111 | 'label' => 'Do not use spam check in these forms',
112 | 'required' => false,
113 | 'attr' => [
114 | 'maxlength' => 40
115 | ],
116 | 'help' => 'Enter comma separated list of form ids or leave empty for using the spam check in all forms.'
117 | ])
118 | ->add('storeSubmissionData', CheckboxType::class, [
119 | 'label' => 'Store submitted data in database',
120 | 'required' => false
121 | ])
122 | ->add('storeSubmissionDataForms', TextType::class, [
123 | 'label' => 'Only store submissions from these forms',
124 | 'required' => false,
125 | 'attr' => [
126 | 'maxlength' => 40
127 | ],
128 | 'help' => 'Enter comma separated list of form ids or leave empty for storing all forms.'
129 | ])
130 | ->add('save', SubmitType::class, [
131 | 'label' => 'Save',
132 | 'icon' => 'fa-check',
133 | 'attr' => [
134 | 'class' => 'btn-success'
135 | ]
136 | ])
137 | ->add('cancel', SubmitType::class, [
138 | 'label' => 'Cancel',
139 | 'icon' => 'fa-times'
140 | ])
141 | ;
142 | }
143 |
144 | public function getBlockPrefix()
145 | {
146 | return 'zikulaformiculamodule_config';
147 | }
148 |
149 | public function configureOptions(OptionsResolver $resolver)
150 | {
151 | $resolver->setDefaults([
152 | 'formChoices' => []
153 | ]);
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/Controller/ContactController.php:
--------------------------------------------------------------------------------
1 | contactRepository = $contactRepository;
57 | $this->environmentHelper = $environmentHelper;
58 | }
59 |
60 | /**
61 | * Show a list of contacts.
62 | *
63 | * @Route("/view")
64 | * @PermissionCheck("admin")
65 | * @Template("@ZikulaFormiculaModule/Contact/view.html.twig")
66 | * @Theme("admin")
67 | */
68 | public function view(): array
69 | {
70 | // check necessary environment
71 | $this->environmentHelper->check();
72 |
73 | $allContacts = $this->contactRepository->findBy([], ['cid' => 'ASC']);
74 |
75 | // only use those contacts where we have the necessary rights for
76 | $visibleContacts = [];
77 | foreach ($allContacts as $contact) {
78 | $contactId = $contact->getCid();
79 | if (!$this->hasPermission('ZikulaFormiculaModule::', ":${contactId}:", ACCESS_EDIT)) {
80 | continue;
81 | }
82 |
83 | $contactArray = $contact->toArray();
84 | $contactArray['allowEdit'] = true;
85 | $contactArray['allowDelete'] = $this->hasPermission('ZikulaFormiculaModule::', ":${contactId}:", ACCESS_DELETE);
86 | $visibleContacts[] = $contactArray;
87 | }
88 |
89 | return [
90 | 'contacts' => $visibleContacts
91 | ];
92 | }
93 |
94 | /**
95 | * Allows adding and editing contacts.
96 | *
97 | * @Route("/edit")
98 | * @PermissionCheck("admin")
99 | * @Template("@ZikulaFormiculaModule/Contact/edit.html.twig")
100 | * @Theme("admin")
101 | */
102 | public function edit(Request $request)
103 | {
104 | // check necessary environment
105 | $this->environmentHelper->check();
106 |
107 | $entityManager = $this->getDoctrine()->getManager();
108 | $contactId = $request->query->getInt('cid', 0);
109 |
110 | if ($contactId < 1) {
111 | $mode = 'create';
112 | $contact = new ContactEntity();
113 | $contact->setPublic(true);
114 | } else {
115 | $mode = 'edit';
116 | $contact = $this->contactRepository->find($contactId);
117 | if (false === $contact) {
118 | $this->addFlash('error', 'Contact could not be found.');
119 |
120 | return $this->redirectToRoute('zikulaformiculamodule_contact_view');
121 | }
122 | }
123 |
124 | $form = $this->createForm(EditContactType::class, $contact);
125 | $form->handleRequest($request);
126 | if ($form->isSubmitted() && $form->isValid()) {
127 | $valid = true;
128 | if ($form->get('save')->isClicked()) {
129 | $contact = $form->getData();
130 |
131 | // email addresses can be a comma separated string, split and check separately
132 | $mailAddress = $contact->getEmail();
133 | $mailAddress = preg_replace('/\s*/m', '', $mailAddress); // remove spaces
134 | $addresses = explode(',', $mailAddress);
135 | foreach ($addresses as $address) {
136 | if (false === filter_var($address, FILTER_VALIDATE_EMAIL)) {
137 | $this->addFlash('error', $this->trans('Error! Incorrect email address [%s%] supplied.', ['%s%' => $address]));
138 | $valid = false;
139 | break;
140 | }
141 | }
142 | if ($valid) {
143 | $contact->setEmail($mailAddress);
144 |
145 | $entityManager->persist($contact);
146 | $entityManager->flush();
147 | if ('create' === $mode) {
148 | $this->addFlash('status', 'Done! Contact created.');
149 | } else {
150 | $this->addFlash('status', 'Done! Contact updated.');
151 | }
152 | }
153 | } elseif ($form->get('cancel')->isClicked()) {
154 | $this->addFlash('status', 'Operation cancelled.');
155 | }
156 |
157 | if ($valid) {
158 | return $this->redirectToRoute('zikulaformiculamodule_contact_view');
159 | }
160 | }
161 |
162 | return [
163 | 'form' => $form->createView(),
164 | 'mode' => $mode,
165 | 'contact' => $contact
166 | ];
167 | }
168 |
169 | /**
170 | * Deletes an existing contact from the database.
171 | *
172 | * @Route("/delete")
173 | * @PermissionCheck("delete")
174 | * @Template("@ZikulaFormiculaModule/Contact/delete.html.twig")
175 | * @Theme("admin")
176 | */
177 | public function delete(Request $request)
178 | {
179 | // check necessary environment
180 | $this->environmentHelper->check();
181 |
182 | $entityManager = $this->getDoctrine()->getManager();
183 | $contactId = $request->query->getInt('cid', 0);
184 |
185 | $contact = $this->contactRepository->find($contactId);
186 | if (false === $contact) {
187 | $this->addFlash('error', 'Contact could not be found.');
188 |
189 | return $this->redirectToRoute('zikulaformiculamodule_contact_view');
190 | }
191 |
192 | $form = $this->createForm(DeleteContactType::class, $contact);
193 | $form->handleRequest($request);
194 | if ($form->isSubmitted() && $form->isValid()) {
195 | if ($form->get('delete')->isClicked()) {
196 | $contact = $form->getData();
197 | $entityManager->remove($contact);
198 | $entityManager->flush();
199 | $this->addFlash('status', 'Done! Contact deleted.');
200 | } elseif ($form->get('cancel')->isClicked()) {
201 | $this->addFlash('status', 'Operation cancelled.');
202 | }
203 |
204 | return $this->redirectToRoute('zikulaformiculamodule_contact_view');
205 | }
206 |
207 | return [
208 | 'form' => $form->createView(),
209 | 'contact' => $contact
210 | ];
211 | }
212 | }
213 |
--------------------------------------------------------------------------------
/FormiculaModuleInstaller.php:
--------------------------------------------------------------------------------
1 | cacheDirectory = $cacheDir;
59 | $this->uploadDirectory = str_replace('cache', 'uploads', $cacheDir);
60 | }
61 |
62 | public function install(): bool
63 | {
64 | $this->schemaTool->create($this->entities);
65 |
66 | $variableApi = $this->getVariableApi();
67 |
68 | // create a contact for the webmaster
69 | $contact = new ContactEntity();
70 | $contact->setName($this->trans('Webmaster'));
71 | $contact->setEmail($variableApi->get('ZConfig', 'adminmail'));
72 | $contact->setPublic(true);
73 | $contact->setSenderName($contact->getName());
74 | $contact->setSenderEmail($contact->getEmail());
75 | $contact->setSendingSubject($this->trans('Your mail to %s'));
76 | $this->entityManager->persist($contact);
77 | $this->entityManager->flush();
78 |
79 | // try to create required directories
80 | $this->createCacheDirectory();
81 | $this->createUploadDirectory();
82 |
83 | $this->setVars($this->getDefaultSettings());
84 |
85 | // initialisation successful
86 | return true;
87 | }
88 |
89 | public function upgrade($oldVersion): bool
90 | {
91 | switch ($oldVersion) {
92 | case '4.0.0':
93 | case '4.0.1':
94 | // nothing to do
95 | case '4.0.2':
96 | // fields have changed: createdUserId becomes createdBy, updatedUserId becomes updatedBy
97 | $connection = $this->entityManager->getConnection();
98 | $tableName = 'submission';
99 | $sql = '
100 | ALTER TABLE `formicula_' . $tableName . '`
101 | CHANGE `createdUserId` `createdBy` INT(11) DEFAULT NULL
102 | ';
103 | $stmt = $connection->prepare($sql);
104 | $stmt->execute();
105 |
106 | $sql = '
107 | ALTER TABLE `formicula_' . $tableName . '`
108 | CHANGE `updatedUserId` `updatedBy` INT(11) DEFAULT NULL
109 | ';
110 | $stmt = $connection->prepare($sql);
111 | $stmt->execute();
112 | // no break
113 | case '5.0.0':
114 | // added forgotten company field
115 | try {
116 | $this->schemaTool->update([
117 | SubmissionEntity::class
118 | ]);
119 | } catch (\Exception $exception) {
120 | $this->addFlash('error', $this->trans('Doctrine Exception') . ': ' . $exception->getMessage());
121 |
122 | return false;
123 | }
124 | case '5.0.1':
125 | $this->setVar('uploadDirectory', $this->uploadDirectory);
126 | // no break
127 | case '5.0.2':
128 | // nothing yet
129 | }
130 |
131 | // Update successful
132 | return true;
133 | }
134 |
135 | public function uninstall(): bool
136 | {
137 | $this->schemaTool->drop($this->entities);
138 |
139 | $this->delVars();
140 |
141 | if (is_dir($this->cacheDirectory)) {
142 | $fs = new Filesystem();
143 | try {
144 | $fs->remove($this->cacheDirectory);
145 | } catch (IOExceptionInterface $exception) {
146 | $this->addFlash(
147 | 'error',
148 | $this->trans(
149 | 'An error occurred while removing the cache directory at %s%.',
150 | ['%s%' => $this->cacheDirectory]
151 | )
152 | );
153 | }
154 | }
155 |
156 | // upload directory is currently not deleted, since the files may still be of interest
157 |
158 | return true;
159 | }
160 |
161 | private function createCacheDirectory(): void
162 | {
163 | $fs = new Filesystem();
164 | try {
165 | if (!$fs->exists($this->cacheDirectory)) {
166 | $fs->mkdir($this->cacheDirectory);
167 | $fs->chmod($this->cacheDirectory, 0777);
168 | }
169 | } catch (IOExceptionInterface $exception) {
170 | $this->addFlash(
171 | 'error',
172 | $this->trans(
173 | 'An error occurred while creating the cache directory at %s%.',
174 | ['%s%' => $this->cacheDirectory]
175 | )
176 | );
177 | }
178 |
179 | try {
180 | if ($fs->exists($this->cacheDirectory . '/.htaccess')) {
181 | return;
182 | }
183 | $fs->dumpFile($this->cacheDirectory . '/.htaccess', 'SetEnvIf Request_URI "\.gif$" object_is_gif=gif
184 | SetEnvIf Request_URI "\.png$" object_is_png=png
185 | SetEnvIf Request_URI "\.jpg$" object_is_jpg=jpg
186 | SetEnvIf Request_URI "\.jpeg$" object_is_jpeg=jpeg
187 | Order deny,allow
188 | Deny from all
189 | Allow from env=object_is_gif
190 | Allow from env=object_is_png
191 | Allow from env=object_is_jpg
192 | Allow from env=object_is_jpeg
193 | ');
194 | $this->addFlash(
195 | 'status',
196 | $this->trans('Successfully created the cache directory with a .htaccess file in it.')
197 | );
198 | } catch (IOExceptionInterface $exception) {
199 | $this->addFlash(
200 | 'error',
201 | $this->trans(
202 | 'Could not create .htaccess file in %s%, please refer to the manual before using the module!',
203 | ['%s%' => $this->cacheDirectory]
204 | )
205 | );
206 | }
207 | }
208 |
209 | private function createUploadDirectory(): void
210 | {
211 | $fs = new Filesystem();
212 | try {
213 | if (!$fs->exists($this->uploadDirectory)) {
214 | $fs->mkdir($this->uploadDirectory);
215 | $fs->chmod($this->uploadDirectory, 0777);
216 | }
217 | } catch (IOExceptionInterface $exception) {
218 | $this->addFlash(
219 | 'error',
220 | $this->trans(
221 | 'An error occurred while creating the upload directory at %s%.',
222 | ['%s%' => $this->uploadDirectory]
223 | )
224 | );
225 | }
226 | }
227 |
228 | private function getDefaultSettings(): array
229 | {
230 | return [
231 | 'defaultForm' => 0,
232 | 'showCompany' => true,
233 | 'showPhone' => true,
234 | 'showUrl' => true,
235 | 'showLocation' => true,
236 | 'showComment' => true,
237 |
238 | 'showFileAttachment' => false,
239 | 'uploadDirectory' => $this->uploadDirectory,
240 | 'deleteUploadedFiles' => true,
241 |
242 | 'sendConfirmationToUser' => true,
243 | 'defaultAdminFormat' => 'html',
244 | 'defaultUserFormat' => 'html',
245 | 'showUserFormat' => true,
246 | 'useContactsAsSender' => true,
247 |
248 | 'enableSpamCheck' => true,
249 | 'excludeSpamCheck' => '',
250 | 'storeSubmissionData' => false,
251 | 'storeSubmissionDataForms' => ''
252 | ];
253 | }
254 | }
255 |
--------------------------------------------------------------------------------
/Entity/SubmissionEntity.php:
--------------------------------------------------------------------------------
1 | form = 0;
147 | $this->cid = 0;
148 | $this->ipAddress = '';
149 | $this->hostName = '';
150 | $this->name = '';
151 | $this->email = '';
152 | $this->phoneNumber = '';
153 | $this->company = '';
154 | $this->url = '';
155 | $this->location = '';
156 | $this->comment = '';
157 | $this->customData = [];
158 | }
159 |
160 | /**
161 | * Gets the id of the submission.
162 | */
163 | public function getSid(): ?int
164 | {
165 | return $this->sid;
166 | }
167 |
168 | /**
169 | * Sets the id for the submission.
170 | */
171 | public function setSid(int $sid): void
172 | {
173 | $this->sid = $sid;
174 | }
175 |
176 | /**
177 | * Gets the id of the form.
178 | */
179 | public function getForm(): int
180 | {
181 | return $this->form;
182 | }
183 |
184 | /**
185 | * Sets the form id for the submission.
186 | */
187 | public function setForm(int $form): void
188 | {
189 | $this->form = $form;
190 | }
191 |
192 | /**
193 | * Gets the contact id of the submission.
194 | */
195 | public function getCid(): int
196 | {
197 | return $this->cid;
198 | }
199 |
200 | /**
201 | * Sets the contact id for the submission.
202 | */
203 | public function setCid(int $cid): void
204 | {
205 | $this->cid = $cid;
206 | }
207 |
208 | /**
209 | * Gets the ip address of the submission.
210 | */
211 | public function getIpAddress(): string
212 | {
213 | return $this->ipAddress;
214 | }
215 |
216 | /**
217 | * Sets the ip address for the submission.
218 | */
219 | public function setIpAddress(string $ipAddress): void
220 | {
221 | $this->ipAddress = $ipAddress;
222 | }
223 |
224 | /**
225 | * Gets the host name of the submission.
226 | */
227 | public function getHostName(): string
228 | {
229 | return $this->hostName;
230 | }
231 |
232 | /**
233 | * Sets the host name for the submission.
234 | */
235 | public function setHostName(string $hostName): void
236 | {
237 | $this->hostName = $hostName;
238 | }
239 |
240 | /**
241 | * Gets the name of the submission.
242 | */
243 | public function getName(): string
244 | {
245 | return $this->name;
246 | }
247 |
248 | /**
249 | * Sets the name for the submission.
250 | */
251 | public function setName(string $name): void
252 | {
253 | $this->name = $name;
254 | }
255 |
256 | /**
257 | * Gets the email address of the submission.
258 | */
259 | public function getEmail(): string
260 | {
261 | return $this->email;
262 | }
263 |
264 | /**
265 | * Sets the email address for the submission.
266 | */
267 | public function setEmail(string $email): void
268 | {
269 | $this->email = $email;
270 | }
271 |
272 | /**
273 | * Gets the phone number of the submission.
274 | */
275 | public function getPhoneNumber(): string
276 | {
277 | return $this->phoneNumber;
278 | }
279 |
280 | /**
281 | * Sets the phone number for the submission.
282 | */
283 | public function setPhoneNumber(string $phoneNumber): void
284 | {
285 | $this->phoneNumber = $phoneNumber;
286 | }
287 |
288 | /**
289 | * Alias for easier form handling.
290 | */
291 | public function setPhone(string $phoneNumber): void
292 | {
293 | $this->setPhoneNumber($phoneNumber);
294 | }
295 |
296 | /**
297 | * Gets the company of the submission.
298 | */
299 | public function getCompany(): string
300 | {
301 | return $this->company;
302 | }
303 |
304 | /**
305 | * Sets the company for the submission.
306 | */
307 | public function setCompany(string $company): void
308 | {
309 | $this->company = $company;
310 | }
311 |
312 | /**
313 | * Gets the url of the submission.
314 | */
315 | public function getUrl(): string
316 | {
317 | return $this->url;
318 | }
319 |
320 | /**
321 | * Sets the url for the submission.
322 | */
323 | public function setUrl(string $url): void
324 | {
325 | $this->url = $url;
326 | }
327 |
328 | /**
329 | * Gets the location of the submission.
330 | */
331 | public function getLocation(): string
332 | {
333 | return $this->location;
334 | }
335 |
336 | /**
337 | * Sets the location for the submission.
338 | */
339 | public function setLocation(string $location): void
340 | {
341 | $this->location = $location;
342 | }
343 |
344 | /**
345 | * Gets the comment of the submission.
346 | *
347 | * @return string the submission's comment
348 | */
349 | public function getComment()
350 | {
351 | return $this->comment;
352 | }
353 |
354 | /**
355 | * Sets the comment for the submission.
356 | */
357 | public function setComment(string $comment): void
358 | {
359 | $this->comment = $comment;
360 | }
361 |
362 | /**
363 | * Gets the custom data of the submission.
364 | */
365 | public function getCustomData(): array
366 | {
367 | return $this->customData;
368 | }
369 |
370 | /**
371 | * Sets the custom data for the submission.
372 | */
373 | public function setCustomData(array $customData = []): void
374 | {
375 | $this->customData = $customData;
376 | }
377 |
378 | /**
379 | * Adds a value to the submission's custom data.
380 | */
381 | public function addCustomData(string $key = '', string $value = ''): void
382 | {
383 | if ('' !== $key) {
384 | $this->customData[$key] = $value;
385 | }
386 | }
387 | }
388 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Deprecated
2 |
3 | This module has been deprecated as part of [Zikula 4 slimming diet](https://github.com/zikula/core/blob/main/ZIKULA-4.0.md).
4 |
5 | # Formicula Zikula Module
6 |
7 | A template-driven form mailer for Zikula.
8 | Formicula is a highly configurable contact mailer solution for Zikula Application Framework.
9 | You can create any kind of contact form with any number contact fields by changing templates.
10 | Forms can be controlled by permissions.
11 | It also supports multiple, permission controlled recipients, configurable notification emails, a simple captcha for spam protection, hooks to the Captcha module, javascript form validation and file uploads.
12 |
13 | ## Main branch
14 |
15 | The 6.0.x versions in the `main` branch target Zikula 3.0+.
16 |
17 | ## Older versions
18 |
19 | See [releases](https://github.com/zikula-modules/Formicula/releases).
20 |
21 | ## Installation
22 |
23 | 1. Extract the files to your Zikula `extensions` directory.
24 | 2. Initialize and activate Formicula in the extensions administration.
25 | 3. During installation, Formicula tries to create a `public/formicula/cache` directory containing a `.htaccess` file.
26 | If this fails (should happen very rarely), you will be notified and have to create them on your own:
27 | a) Create a directory `public/formicula/cache` and make it writable for the web server (e.g. `chmod 777`).
28 | b) Create a `.htacess` file within that directory containing the following lines to allow access to the
29 | images created for the captcha:
30 | ```
31 | SetEnvIf Request_URI "\.gif$" object_is_gif=gif
32 | SetEnvIf Request_URI "\.png$" object_is_png=png
33 | SetEnvIf Request_URI "\.jpg$" object_is_jpg=jpg
34 | Order deny,allow
35 | Deny from all
36 | Allow from env=object_is_gif
37 | Allow from env=object_is_png
38 | Allow from env=object_is_jpg
39 | ```
40 | 4. Create some contact names/topics with respective email adresses in the Formicula admin setion.
41 | Upon installation, Formicula creates a default contact with the admins mail address.
42 | 5. Add a basic permission rule, e.g.
43 | Unregistered (group) | ZikulaFormiculaModule::.* | .* | comment
44 | This enables unregistered users to use all existing forms. In a default installation
45 | the users group has a generic comment permission to do the same.
46 | 6. Add a link to your main menu using `/contact` as URL (whereby _contact_ corresponds
47 | to the module name defined for Formicula in the extensions list).
48 | This uses form 0. To call a specific form id use `/contact/?form=`
49 | e.g. `/contact/?form=5` to use form #5
50 | In the distribution package you will find sample forms 0, 1, 2 and 3.
51 | 0 is a normal contact form and form #1 and beyond are more extensive forms.
52 |
53 | ## Configuration
54 |
55 | - Show xxx: quick configuration enable/disable some fields in the userform. These fields may be (read: surely will be) removed in future versions.
56 | - Send confirmation email to user: Tick this to send an confirmation mail to the user directory for uploaded files: Uploaded files get stored here. Make sure this directory is secured with a `.htaccess` file!
57 | - Delete file after sending: does what it says when ticked.
58 | - Activate spamcheck: shows a little captcha in the form
59 |
60 | ## Contacts
61 |
62 | Each contact consists of several information:
63 |
64 | - Contact name or Topic: The name that is shown to the user in the form, e.g. Webmaster
65 | - Email: The email to send the data to
66 | - Public: tick this to make the contact available for use.
67 | - Sender name: senders name as used in the users confirmation mail
68 | - Sender email: senders email address as used in the users confirmation mail, e.g noreply@example.com
69 | - Subject: enter a static subject or use these placeholders:
70 | - %s = sitename
71 | - %l = slogan
72 | - %u = site url
73 | - %c = contact name
74 | - %n = user defined field name
75 | - %d = user defined field data
76 |
77 | ## Using own contacts
78 |
79 | It is possible to pass own contacts to formicula instead using the formicula database. To do this by a link
80 | you have to call the addSessionOwncontacts function in the User-API. This function will return you
81 | an integer which you should append with the index 'owncontacts' to the URL pointing to formicula.
82 | If you want to embed your form you can pass the owncontacts directly to the form by adding
83 | the owncontacts array to your arguments array.
84 |
85 | The owncontacts array should contain the following values (per item) in both cases:
86 | - name the contact full name (required)
87 | - sname the contact secure name wich will be send to the submitter (optional)
88 | - email the contact email (required)
89 | - semail the contact email wich will be send to the submiter (optional)
90 | - ssubject the subject of the confirmation mail (optional)
91 |
92 | ## Templates
93 |
94 | Everything you want to do with the form is handled in the templates.
95 | Store them in Resources/views/Form/
96 | The '#' at the beginning of the template designates the number of form.
97 |
98 | The templates for the forms are named as follows:
99 | - The form with the input fields: `Form/#/userForm.html.twig`
100 | - The page with the confirmation after submitting the data: `Form/#/userConfirm.html.twig`
101 | - The page with error messages after submitting data: `Form/#/userError.html.twig`
102 | - The user's confirmation mail in text format: `Form/#/userMail.txt.twig`
103 | - The user's confirmation mail in html format: `Form/#/userMail.html.twig`
104 | - The admin mail in text format: `Form/#/adminMail.txt.twig`
105 | - The admin mail in html format: `Form/#/adminmail.html.twig`
106 |
107 | This is the email that the admin gets after the user sends submits the userform.
108 |
109 | ## Standard fields
110 |
111 | The standard fields to be used in forms are under userdata
112 |
113 | - userdata[uname]: the users name (mandatory)
114 | - userdata[uemail]: the users name (mandatory)
115 | - userdata[url]: the users homepage (optional)
116 | - userdata[location], userdata[phone], userdata[company]: these are obvious... (optional)
117 | - userdata[comment]: normally a textarea for entering free text. Since 0.6 this is not longer a mandatory field! HTML is stripped from the comments to avoid spam. In addition, the comment is send to Zikula's internal censor function. If the result differs from the original comment, the submission is also treated as spam and not sent. This results in an error message.
118 | - captcha: mandatory if spamcheck feature is enabled, see 0_userform.html for an example
119 |
120 | ## Custom fields
121 |
122 | You can add as many custom fields to your form as you want.
123 | This makes it easy to create e.g. an online job application form if needed.
124 |
125 | This makes it necessary to send certain information from the form page to the module.
126 | The custom fields are numbered in old versions and an associative array in newer versions.
127 |
128 | These are:
129 |
130 | - custom[fieldname][name] (hidden field) name of the custom field
131 | can be used in the confirmation email
132 | - custom[fieldname][mandatory] (hidden field) set to 1 if this is a mandatory field.
133 | Formicula checks this and shows an errormessage when this field is not filled
134 | - custom[fieldname][data] (any kind of input field) the data with fieldname
135 | the payload
136 |
137 | Example:
138 |
139 | ```
140 | {% trans %}foobar{% endtrans %}
141 |
142 |
143 |
144 | ```
145 |
146 | ## Permissions
147 |
148 | To use a form you need the right to COMMENT.
149 |
150 | Unregistered | ZikulaFormiculaModule:: | .* | comment
151 | all unregistered users are allowed to use all forms and write to all contacts
152 |
153 | Unregistered | ZikulaFormiculaModule:: | 0:: | comment
154 | all unregistered users are allowed to use form 0 with all existing contacts.
155 |
156 | Users | ZikulaFormiculaModule:: | 1:(2|3): | comment
157 | all members of the group Users are allowed to use form 1 and write to contact 2 and 3.
158 |
159 | ## Use external information in the forms
160 |
161 | You can use external information in the form by sending them in the url used to call
162 | the form. These data are send in an associative array addinfo where the key is the name.
163 |
164 | With
165 |
166 | `/contact/?form=2&addinfo[tid]=4&addinfo[pid]=17`
167 |
168 | you send two different information to the form 2 which can used in the userform template (in
169 | this `example 2_userform.html`) with
170 |
171 | {{ addinfo.tid }} => 4
172 | {{ addinfo.pid }} => 17
173 |
174 | As you can see you can use this to e.g. load data from Pagesetter in the userform template.
175 |
176 | ## Client side input validation
177 |
178 | The supplied templates use a html5 input validation with webshims lib polyfill fallback.
179 |
180 | ## Captcha
181 |
182 | The simplecaptcha plugins adds an image with a very basic math equation (3 number from 1 to 2
183 | and either +, - or *) to the form if the spam check is enabled. If the user enters a wrong
184 | value, Formicula redirects back to the page where it came from.
185 |
186 | Formicula tries to create images in this order: gif, jpg, png.
187 | If all these image types are not supported by your server, captchas are deactivated, in this
188 | case Formicula turns the configuration option "Activate spamcheck" off.
189 | Please refer to for more information.
190 |
191 | Formicula also supports ztemp-directories located outside the websites root directory. In this case
192 | (when the temp directory points to an absolute path) the image is delivered by an internal
193 | function and not linked directly.
194 |
--------------------------------------------------------------------------------
/Helper/CaptchaHelper.php:
--------------------------------------------------------------------------------
1 | translator = $translator;
75 | $this->variableApi = $variableApi;
76 | $this->permissionApi = $permissionApi;
77 | $this->environmentHelper = $environmentHelper;
78 | $this->router = $router;
79 | $this->requestStack = $requestStack;
80 | $this->projectDirectory = $projectDir;
81 | $this->cacheDirectory = $cacheDir;
82 | }
83 |
84 | /**
85 | * Determines whether the spam check is active for a certain form.
86 | */
87 | public function isSpamCheckEnabled(int $form = 0): bool
88 | {
89 | $enableSpamCheck = $this->variableApi->get('ZikulaFormiculaModule', 'enableSpamCheck', true);
90 | if ($enableSpamCheck) {
91 | $excludeSpamCheck = explode(',', $this->variableApi->get('ZikulaFormiculaModule', 'excludeSpamCheck', ''));
92 | if (is_array($excludeSpamCheck) && array_key_exists($form, array_flip($excludeSpamCheck))) {
93 | $enableSpamCheck = false;
94 | }
95 | }
96 |
97 | return $enableSpamCheck;
98 | }
99 |
100 | /**
101 | * Determines whether a given captcha code is correct or not.
102 | */
103 | public function isCaptchaValid(array $operands = [], int $captcha = 0): bool
104 | {
105 | $captchaValid = false;
106 | if (!is_array($operands)) {
107 | return $captchaValid;
108 | }
109 |
110 | $op1 = (int) $operands['x'];
111 | $op2 = (int) $operands['y'];
112 | $op3 = (int) $operands['v'];
113 |
114 | switch ($operands['z'] . '-' . $operands['w']) {
115 | case '0-0':
116 | $captchaValid = ($op1 + $op2 + $op3 === $captcha);
117 | break;
118 | case '0-1':
119 | $captchaValid = ($op1 + $op2 - $op3 === $captcha);
120 | break;
121 | case '1-0':
122 | $captchaValid = ($op1 - $op2 + $op3 === $captcha);
123 | break;
124 | case '1-1':
125 | $captchaValid = ($op1 - $op2 - $op3 === $captcha);
126 | break;
127 | default:
128 | // $captchaValid is false
129 | }
130 |
131 | return $captchaValid;
132 | }
133 |
134 | /**
135 | * Creates a captcha image and returns it's markup code.
136 | *
137 | * based on imagetext (c) guite.de which is
138 | * based on imagetext (c) Christoph Erdmann
139 | *
140 | * @param string $font Name of font to use (arial, freesans, quickhand, vera)
141 | * @param int $size Font size
142 | * @param string $bgColour Background colour (hex code without the # char)
143 | * @param string $fgColour Foreground colour (hex code without the # char)
144 | *
145 | * @return string The image markup
146 | */
147 | public function createCaptcha(
148 | string $font = 'quickhand',
149 | int $size = 14,
150 | string $bgColour = 'ffffff',
151 | string $fgColour = '000000'
152 | ): string {
153 | // check which image types are supported
154 | $freetype = function_exists('imagettfbbox');
155 | if ($freetype && (imagetypes() && IMG_PNG)) {
156 | $imageType = '.png';
157 | $createImageFunction = 'imagepng';
158 | } elseif ($freetype && (imagetypes() && IMG_JPG)) {
159 | $imageType = '.jpg';
160 | $createImageFunction = 'imagejpeg';
161 | } elseif ($freetype && (imagetypes() && IMG_GIF)) {
162 | $imageType = '.gif';
163 | $createImageFunction = 'imagegif';
164 | } else {
165 | // no image functions available
166 | $this->variableApi->set('ZikulaFormiculaModule', 'enableSpamCheck', false);
167 | if ($this->permissionApi->hasPermission('ZikulaFormiculaModule::', '.*', ACCESS_ADMIN)) {
168 | // admin permission, show error messages
169 | return '' . $this->translator->trans('There are no image function available - Captchas have been disabled.') . '
';
170 | }
171 |
172 | // return silently
173 | return '';
174 | }
175 |
176 | // catch wrong input
177 | if (empty($font) || !is_numeric($size) || $size < 1 || empty($bgColour) || empty($fgColour)) {
178 | return '';
179 | }
180 |
181 | $fontPath = $this->getFontPath($font);
182 | if (!file_exists($fontPath) || !is_readable($fontPath)) {
183 | return '';
184 | }
185 |
186 | $operands = $this->determineOperands();
187 |
188 | $m = ['+', '-'];
189 |
190 | $request = $this->requestStack->getCurrentRequest();
191 | if (null !== $request) {
192 | // store the numbers in a session var
193 | $request->getSession()->set('formiculaCaptcha', serialize($operands));
194 | }
195 |
196 | // create the text for the image
197 | $exerciseText = $operands['x'] . ' ' . $m[$operands['z']] . ' ' . $operands['y'] . ' ' . $m[$operands['w']] . ' ' . $operands['v'] . ' =';
198 |
199 | // hash the params for cache filename
200 | $hash = hash('sha256', $font . $size . $bgColour . $fgColour . $exerciseText);
201 | // create uri of image
202 | $imagePath = $this->cacheDirectory . '/' . $hash . $imageType;
203 |
204 | // create the image if it does not already exist
205 | if (!file_exists($imagePath)) {
206 | // we create a larger picture than needed, this makes it looking better at the end
207 | $multi = 4;
208 | // get the textsize in the image
209 | $bbox = imagettfbbox($size * $multi, 0, $fontPath, $exerciseText);
210 | $xcorr = 0 - $bbox[6]; // northwest X
211 | $ycorr = 0 - $bbox[7]; // northwest Y
212 | $box['left'] = $bbox[6] + $xcorr;
213 | $box['height'] = abs($bbox[5]) + abs($bbox[1]);
214 | $box['width'] = abs($bbox[2]) + abs($bbox[0]);
215 | $box['top'] = abs($bbox[5]);
216 |
217 | // create the image
218 | $im = imagecreate($box['width'], $box['height']);
219 |
220 | $bgcolor = $this->hexToRgb($im, $bgColour);
221 | $fgcolor = $this->hexToRgb($im, $fgColour);
222 |
223 | // add the text to the image
224 | imagettftext($im, $size * $multi, 0, $box['left'], $box['top'], $fgcolor, $fontPath, $exerciseText);
225 |
226 | // resize the image now
227 | $finalWidth = (int) round($box['width'] / $multi);
228 | $finalHeight = (int) round($box['height'] / $multi);
229 | $ds = imagecreatetruecolor($finalWidth, $finalHeight);
230 |
231 | $bgcolor2 = $this->hexToRgb($ds, $bgColour);
232 | imagefill($ds, 0, 0, $bgcolor2);
233 | imagecopyresampled($ds, $im, 0, $box['left'], 0, 0, (int) ($box['width'] / $multi), (int) ($box['height'] / $multi), $box['width'], $box['height']);
234 | imagetruecolortopalette($ds, false, 256);
235 | imagepalettecopy($ds, $im);
236 | imagecolortransparent($ds, $bgcolor);
237 |
238 | // write the file
239 | $createImageFunction($ds, $imagePath);
240 | imagedestroy($im);
241 | imagedestroy($ds);
242 | } else {
243 | // file already exists, calculate image size
244 | $imageData = getimagesize($imagePath);
245 | $finalWidth = $imageData[0];
246 | $finalHeight = $imageData[1];
247 | }
248 |
249 | $relativeImagePath = str_replace($this->projectDirectory, '', $imagePath);
250 |
251 | return ' ';
252 | }
253 |
254 | /**
255 | * Returns the path to a given font.
256 | *
257 | * @param string $font Name of font to use
258 | *
259 | * @return string Path to the font file
260 | */
261 | private function getFontPath(string $font): string
262 | {
263 | $absolutePath = dirname(__DIR__);
264 | $fontPath = $absolutePath . '/Resources/public/fonts/' . $font . '.ttf';
265 |
266 | return $fontPath;
267 | }
268 |
269 | /**
270 | * Determines random numbers for the calculation.
271 | *
272 | * @return array Random math exercise operands
273 | */
274 | private function determineOperands(): array
275 | {
276 | $x = mt_rand(1, 10);
277 | $y = mt_rand(1, 10);
278 | $z = mt_rand(0, 1); /* 0=+, 1=- */
279 | $v = mt_rand(1, 10);
280 | $w = mt_rand(0, 1); /* 0=+, 1=- */
281 |
282 | // turn minus into plus when x=y
283 | if (1 === $z && $y === $x) {
284 | $z = 0;
285 | }
286 |
287 | // turn minus into plus when y=v
288 | if (1 === $w && $v === $y) {
289 | $w = 0;
290 | }
291 |
292 | // make sure that x>y if z=1 (minus)
293 | if (1 === $z && $y > $x) {
294 | $tmp = $x;
295 | $x = $y;
296 | $y = $tmp;
297 | }
298 |
299 | // turn minus into plus when v>x-y or v>x+y
300 | if (1 === $w && (1 === $z && $v > ($x - $y)) || (0 === $z && $v > ($x + $y))) {
301 | $w = 0;
302 | }
303 |
304 | return [
305 | 'x' => $x,
306 | 'y' => $y,
307 | 'z' => $z,
308 | 'v' => $v,
309 | 'w' => $w
310 | ];
311 | }
312 |
313 | /**
314 | * Converts a hex colour code into rgb values.
315 | *
316 | * @param resource $image The image resource
317 | * @param string $hexCode Colour hex code without the # char
318 | *
319 | * @return integer colour id determined by resulting rgb values
320 | */
321 | private function hexToRgb($image, string $hexCode): int
322 | {
323 | sscanf($hexCode, "%2x%2x%2x", $red, $green, $blue);
324 |
325 | return imagecolorallocate($image, $red, $green, $blue);
326 | }
327 | }
328 |
--------------------------------------------------------------------------------
/Resources/views/Form/3/userForm.html.twig:
--------------------------------------------------------------------------------
1 | {{ include('@ZikulaFormiculaModule/Form/3/userHeader.html.twig') }}
2 |
3 | {{ form_start(form) }}
4 | {{ form_errors(form) }}
5 |
6 | {% trans %}Mandatory fields are indicated with an asterisk.{% endtrans %}
7 |
8 |
9 | {% trans %}Make a reservation{% endtrans %}
10 | {{ form_row(form.form) }}
11 | {{ form_row(form.adminFormat) }}
12 | {% if modVars.sendConfirmationToUser and not modVars.showUserFormat %}
13 | {{ form_row(form.userFormat) }}
14 | {% endif %}
15 |
16 | {{ form_row(form.cid) }}
17 |
18 |
19 | {% trans %}Personal data{% endtrans %}
20 | {{ form_row(form.name) }}
21 |
29 | {% if modVars.showCompany %}
30 | {{ form_row(form.company) }}
31 | {% endif %}
32 | {% if modVars.showLocation %}
33 |
41 | {{ form_row(form.location, {label: 'Zip City'|trans}) }}
42 | {% endif %}
43 | {{ form_row(form.emailAddress) }}
44 | {% if modVars.showPhone %}
45 | {{ form_row(form.phone) }}
46 | {% endif %}
47 | {% if modVars.showUrl %}
48 | {{ form_row(form.url) }}
49 | {% endif %}
50 |
58 |
71 |
72 | {% trans %}Rental data{% endtrans %}
73 |
86 |
94 |
102 |
110 |
111 | {% trans %}Included extras{% endtrans %}
112 |
128 |
129 | {% trans %}Finish and send{% endtrans %}
130 | {% if modVars.showComment %}
131 | {{ form_row(form.comment, { required: false }) }}
132 | {% endif %}
133 | {% if modVars.sendConfirmationToUser and modVars.showUserFormat %}
134 | {{ form_row(form.userFormat) }}
135 | {% endif %}
136 | {% if modVars.showFileAttachment %}
137 | {{ form_row(form.fileUpload) }}
138 | {% endif %}
139 |
153 |
165 |
166 | {% if enableSpamCheck %}
167 | {{ include('@ZikulaFormiculaModule/Include/spamCheck.html.twig') }}
168 | {% endif %}
169 |
170 |
171 | {% set hooks = notifyDisplayHooks(eventName='zikulaformiculamodule.ui_hooks.forms.form_edit') %}
172 | {% if hooks is iterable and hooks|length > 0 %}
173 | {% for area, hook in hooks %}
174 | {{ hook|raw }}
175 | {% endfor %}
176 | {% endif %}
177 |
178 |
183 |
184 | {{ form_end(form) }}
185 |
186 | {{ include('@ZikulaFormiculaModule/Form/3/userFooter.html.twig') }}
187 |
188 | {% set customScript %}
189 |
196 | {% endset %}
197 | {{ pageAddAsset('footer', customScript) }}
198 |
--------------------------------------------------------------------------------
/Resources/translations/zikulaformiculamodule.en.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "Content-Type: text/plain; charset=UTF-8\n"
4 | "Content-Transfer-Encoding: 8bit\n"
5 | "Language: en\n"
6 |
7 | msgid "(to prevent spam)"
8 | msgstr "(to prevent spam)"
9 | msgid "- Make a choice -"
10 | msgstr "- Make a choice -"
11 | msgid "A visitor of to your web site used the form for contact and sent the following:"
12 | msgstr "A visitor of to your web site used the form for contact and sent the following:"
13 | msgid "A visitor to your website made a new rental request and sent the following:"
14 | msgstr "A visitor to your website made a new rental request and sent the following:"
15 | msgid "Actions"
16 | msgstr "Actions"
17 | msgid "Activate simple spam check"
18 | msgstr "Activate simple spam check"
19 | msgid "Add contact"
20 | msgstr "Add contact"
21 | msgid "Agree with terms and conditions"
22 | msgstr "Agree with terms and conditions"
23 | msgid "All public contacts or form default"
24 | msgstr "All public contacts or form default"
25 | msgid "Amount of persons"
26 | msgstr "Amount of persons"
27 | msgid "An email with the filled in data will be sent to our and your email address (%s). We will reply as soon as possible."
28 | msgstr "An email with the filled in data will be sent to our and your email address (%s). We will reply as soon as possible."
29 | msgid "An error occurred while creating the cache directory at %s."
30 | msgstr "An error occurred while creating the cache directory at %s."
31 | msgid "An error occurred while removing the cache directory at %s."
32 | msgstr "An error occurred while removing the cache directory at %s."
33 | msgid "Apply as"
34 | msgstr "Apply as"
35 | msgid "Apply online"
36 | msgstr "Apply online"
37 | msgid "Apply online!"
38 | msgstr "Apply online!"
39 | msgid "Attach a file"
40 | msgstr "Attach a file"
41 | msgid "Attached file"
42 | msgstr "Attached file"
43 | msgid "Basic contact information"
44 | msgstr "Basic contact information"
45 | msgid "Cache directory"
46 | msgstr "Cache directory"
47 | msgid "Cancel"
48 | msgstr "Cancel"
49 | msgid "Clear captcha image cache"
50 | msgstr "Clear captcha image cache"
51 | msgid "Comment"
52 | msgstr "Comment"
53 | msgid "Company"
54 | msgstr "Company"
55 | msgid "Confirmation of your submission will be emailed to you in a few minutes."
56 | msgstr "Confirmation of your submission will be emailed to you in a few minutes."
57 | msgid "Confirmation prompt"
58 | msgstr "Confirmation prompt"
59 | msgid "Contact"
60 | msgstr "Contact"
61 | msgid "Contact ID"
62 | msgstr "Contact ID"
63 | msgid "Contact could not be found."
64 | msgstr "Contact could not be found."
65 | msgid "Contact form"
66 | msgstr "Contact form"
67 | msgid "Contact information"
68 | msgstr "Contact information"
69 | msgid "Contact name"
70 | msgstr "Contact name"
71 | msgid "Contact our team"
72 | msgstr "Contact our team"
73 | msgid "Contact's sender name"
74 | msgstr "Contact's sender name"
75 | msgid "Could not create .htaccess file in %s, please refer to the manual before using the module!"
76 | msgstr "Could not create .htaccess file in %s, please refer to the manual before using the module!"
77 | msgid "Custom fields"
78 | msgstr "Custom fields"
79 | msgid "Date"
80 | msgstr "Date"
81 | msgid "Date of birth"
82 | msgstr "Date of birth"
83 | msgid "Default email format for admin emails"
84 | msgstr "Default email format for admin emails"
85 | msgid "Default email format for user emails"
86 | msgstr "Default email format for user emails"
87 | msgid "Default form"
88 | msgstr "Default form"
89 | msgid "Delete"
90 | msgstr "Delete"
91 | msgid "Delete contact"
92 | msgstr "Delete contact"
93 | msgid "Delete form submission"
94 | msgstr "Delete form submission"
95 | msgid "Delete uploaded file(s) after sending"
96 | msgstr "Delete uploaded file(s) after sending"
97 | msgid "Desired salary"
98 | msgstr "Desired salary"
99 | msgid "Directory for uploaded files"
100 | msgstr "Directory for uploaded files"
101 | msgid "Disable this if you experience problems with your SMTP server"
102 | msgstr "Disable this if you experience problems with your SMTP server"
103 | msgid "Display a specific Formicula form."
104 | msgstr "Display a specific Formicula form."
105 | msgid "Do not use spam check in these forms"
106 | msgstr "Do not use spam check in these forms"
107 | msgid "Do you really want to delete contact '%s'?"
108 | msgstr "Do you really want to delete contact '%s'?"
109 | msgid "Do you really want to delete form submission '%s'?"
110 | msgstr "Do you really want to delete form submission '%s'?"
111 | msgid "Done! Contact created."
112 | msgstr "Done! Contact created."
113 | msgid "Done! Contact deleted."
114 | msgstr "Done! Contact deleted."
115 | msgid "Done! Contact updated."
116 | msgstr "Done! Contact updated."
117 | msgid "Done! Module configuration updated."
118 | msgstr "Done! Module configuration updated."
119 | msgid "Done! Submission deleted."
120 | msgstr "Done! Submission deleted."
121 | msgid "Edit contact"
122 | msgstr "Edit contact"
123 | msgid "Email"
124 | msgstr "Email"
125 | msgid "Email address"
126 | msgstr "Email address"
127 | msgid "Email address(es)"
128 | msgstr "Email address(es)"
129 | msgid "Email and confirmation settings"
130 | msgstr "Email and confirmation settings"
131 | msgid "Email confirmation format"
132 | msgstr "Email confirmation format"
133 | msgid "Email: %1$s - UID: %2$s"
134 | msgstr "Email: %1$s - UID: %2$s"
135 | msgid "End of rental period"
136 | msgstr "End of rental period"
137 | msgid "Enter a valid email address"
138 | msgstr "Enter a valid email address"
139 | msgid "Enter a valid url"
140 | msgstr "Enter a valid url"
141 | msgid "Enter comma separated list of form ids or leave empty for storing all forms."
142 | msgstr "Enter comma separated list of form ids or leave empty for storing all forms."
143 | msgid "Enter comma separated list of form ids or leave empty for using the spam check in all forms."
144 | msgstr "Enter comma separated list of form ids or leave empty for using the spam check in all forms."
145 | msgid "Enter your comments here"
146 | msgstr "Enter your comments here"
147 | msgid "Entry date"
148 | msgstr "Entry date"
149 | msgid "Error! Could not store your submission into the database."
150 | msgstr "Error! Could not store your submission into the database."
151 | msgid "Error! Incorrect email address [%s] supplied."
152 | msgstr "Error! Incorrect email address [%s] supplied."
153 | msgid "Error! No or incorrect email address supplied."
154 | msgstr "Error! No or incorrect email address supplied."
155 | msgid "Error! No or invalid name given."
156 | msgstr "Error! No or invalid name given."
157 | msgid "Error! No value given for mandatory field \"%s\"."
158 | msgstr "Error! No value given for mandatory field \"%s\"."
159 | msgid "Extra 1"
160 | msgstr "Extra 1"
161 | msgid "Extra 2"
162 | msgstr "Extra 2"
163 | msgid "Extra 3"
164 | msgstr "Extra 3"
165 | msgid "Female"
166 | msgstr "Female"
167 | msgid "Field"
168 | msgstr "Field"
169 | msgid "File upload settings"
170 | msgstr "File upload settings"
171 | msgid "Finish and send"
172 | msgstr "Finish and send"
173 | msgid "For your information: There are better spam check modules out there. For example the Zikula Captcha module which can be hooked to Formicula. If you want to use this module, then please do not forget to add the required permissions for the Captcha module, too."
174 | msgstr "For your information: There are better spam check modules out there. For example the Zikula Captcha module which can be hooked to Formicula. If you want to use this module, then please do not forget to add the required permissions for the Captcha module, too."
175 | msgid "Form #"
176 | msgstr "Form #"
177 | msgid "Form #%1$s containing %2$s templates"
178 | msgstr "Form #%1$s containing %2$s templates"
179 | msgid "Form submission could not be found."
180 | msgstr "Form submission could not be found."
181 | msgid "Form submission storage"
182 | msgstr "Form submission storage"
183 | msgid "Form ui hooks subscriber"
184 | msgstr "Form ui hooks subscriber"
185 | msgid "Formicula cache directory does not contain the required .htaccess file - Captchas have been disabled."
186 | msgstr "Formicula cache directory does not contain the required .htaccess file - Captchas have been disabled."
187 | msgid "Formicula cache directory does not exist or is not writable - Captchas have been disabled."
188 | msgstr "Formicula cache directory does not exist or is not writable - Captchas have been disabled."
189 | msgid "Formicula form"
190 | msgstr "Formicula form"
191 | msgid "Formicula settings"
192 | msgstr "Formicula settings"
193 | msgid "Gender"
194 | msgstr "Gender"
195 | msgid "General settings"
196 | msgstr "General settings"
197 | msgid "Go back to the form"
198 | msgstr "Go back to the form"
199 | msgid "HTML"
200 | msgstr "HTML"
201 | msgid "Hello %s!"
202 | msgstr "Hello %s!"
203 | msgid "Hello!"
204 | msgstr "Hello!"
205 | msgid "Hostname"
206 | msgstr "Hostname"
207 | msgid "How did you find us?"
208 | msgstr "How did you find us?"
209 | msgid "ID"
210 | msgstr "ID"
211 | msgid "IP address"
212 | msgstr "IP address"
213 | msgid "Identification card number"
214 | msgstr "Identification card number"
215 | msgid "Included extras"
216 | msgstr "Included extras"
217 | msgid "Kind regards"
218 | msgstr "Kind regards"
219 | msgid "Location"
220 | msgstr "Location"
221 | msgid "Mailer module is not available - unable to send emails!"
222 | msgstr "Mailer module is not available - unable to send emails!"
223 | msgid "Make a reservation"
224 | msgstr "Make a reservation"
225 | msgid "Make sure you the necessary form fields are available, see the docs for more information. This option will be turned off by Formicula automatically if no PHP functions for creating images are available."
226 | msgstr "Make sure you the necessary form fields are available, see the docs for more information. This option will be turned off by Formicula automatically if no PHP functions for creating images are available."
227 | msgid "Male"
228 | msgstr "Male"
229 | msgid "Mandatory fields are indicated with an asterisk."
230 | msgstr "Mandatory fields are indicated with an asterisk."
231 | msgid "Math"
232 | msgstr "Math"
233 | msgid "Name"
234 | msgstr "Name"
235 | msgid "New application"
236 | msgstr "New application"
237 | msgid "New contact"
238 | msgstr "New contact"
239 | msgid "New rental request"
240 | msgstr "New rental request"
241 | msgid "No contacts found."
242 | msgstr "No contacts found."
243 | msgid "No form selected."
244 | msgstr "No form selected."
245 | msgid "No submissions found."
246 | msgstr "No submissions found."
247 | msgid "None"
248 | msgstr "None"
249 | msgid "Only store submissions from these forms"
250 | msgstr "Only store submissions from these forms"
251 | msgid "Operation cancelled."
252 | msgstr "Operation cancelled."
253 | msgid "Otherwise"
254 | msgstr "Otherwise"
255 | msgid "Personal data"
256 | msgstr "Personal data"
257 | msgid "Phone number"
258 | msgstr "Phone number"
259 | msgid "Plain text"
260 | msgstr "Plain text"
261 | msgid "Please enter a valid date (mm/dd/yyyy)."
262 | msgstr "Please enter a valid date (mm/dd/yyyy)."
263 | msgid "Please solve this calculation"
264 | msgstr "Please solve this calculation"
265 | msgid "Public"
266 | msgstr "Public"
267 | msgid "Rental data"
268 | msgstr "Rental data"
269 | msgid "Save"
270 | msgstr "Save"
271 | msgid "Send"
272 | msgstr "Send"
273 | msgid "Send confirmation email to user"
274 | msgstr "Send confirmation email to user"
275 | msgid "Sender email address"
276 | msgstr "Sender email address"
277 | msgid "Sender name"
278 | msgstr "Sender name"
279 | msgid "Settings"
280 | msgstr "Settings"
281 | msgid "Show comments textarea"
282 | msgstr "Show comments textarea"
283 | msgid "Show company"
284 | msgstr "Show company"
285 | msgid "Show contact"
286 | msgstr "Show contact"
287 | msgid "Show file attachment"
288 | msgstr "Show file attachment"
289 | msgid "Show location"
290 | msgstr "Show location"
291 | msgid "Show phone number"
292 | msgstr "Show phone number"
293 | msgid "Show url"
294 | msgstr "Show url"
295 | msgid "Show user email format selector"
296 | msgstr "Show user email format selector"
297 | msgid "Site name"
298 | msgstr "Site name"
299 | msgid "Site slogan"
300 | msgstr "Site slogan"
301 | msgid "Site url"
302 | msgstr "Site url"
303 | msgid "Spam check settings"
304 | msgstr "Spam check settings"
305 | msgid "Start of rental period"
306 | msgstr "Start of rental period"
307 | msgid "Store submitted data in database"
308 | msgstr "Store submitted data in database"
309 | msgid "Street"
310 | msgstr "Street"
311 | msgid "Subject"
312 | msgstr "Subject"
313 | msgid "Submission information"
314 | msgstr "Submission information"
315 | msgid "Successfully created the cache directory with a .htaccess file in it."
316 | msgstr "Successfully created the cache directory with a .htaccess file in it."
317 | msgid "Text"
318 | msgstr "Text"
319 | msgid "Thank you %s for your reservation."
320 | msgstr "Thank you %s for your reservation."
321 | msgid "Thank you for the comments posted from our website. The sent data is:"
322 | msgstr "Thank you for the comments posted from our website. The sent data is:"
323 | msgid "Thank you for your questions/comments to our website!"
324 | msgstr "Thank you for your questions/comments to our website!"
325 | msgid "Thank you for your reservation."
326 | msgstr "Thank you for your reservation."
327 | msgid "Thanks for applying, we will keep your data strictly confidential."
328 | msgstr "Thanks for applying, we will keep your data strictly confidential."
329 | msgid "The %s team"
330 | msgstr "The %s team"
331 | msgid "The Formicula form #%1$s is shown here with only contact %2$s"
332 | msgstr "The Formicula form #%1$s is shown here with only contact %2$s"
333 | msgid "The Formicula form #%s is shown here with all contacts"
334 | msgstr "The Formicula form #%s is shown here with all contacts"
335 | msgid "The calculation to prevent spam was incorrect. Please try again."
336 | msgstr "The calculation to prevent spam was incorrect. Please try again."
337 | msgid "The captcha image cache has been cleared."
338 | msgstr "The captcha image cache has been cleared."
339 | msgid "The user has the following IP address/hostname:"
340 | msgstr "The user has the following IP address/hostname:"
341 | msgid "The validation of the hooked security module was incorrect. Please try again."
342 | msgstr "The validation of the hooked security module was incorrect. Please try again."
343 | msgid "The webserver cannot write into this directory!"
344 | msgstr "The webserver cannot write into this directory!"
345 | msgid "There are no image function available - Captchas have been disabled."
346 | msgstr "There are no image function available - Captchas have been disabled."
347 | msgid "There is an error in your input."
348 | msgstr "There is an error in your input."
349 | msgid "There was an error sending the confirmation email to your email address."
350 | msgstr "There was an error sending the confirmation email to your email address."
351 | msgid "There was an error sending the email to our contact."
352 | msgstr "There was an error sending the email to our contact."
353 | msgid "There was an internal error when sending confirmation mail to you."
354 | msgstr "There was an internal error when sending confirmation mail to you."
355 | msgid "This data was sent to us:"
356 | msgstr "This data was sent to us:"
357 | msgid "This form is used when no form is specified."
358 | msgstr "This form is used when no form is specified."
359 | msgid "Type 1"
360 | msgstr "Type 1"
361 | msgid "Type 2"
362 | msgstr "Type 2"
363 | msgid "Type 3"
364 | msgstr "Type 3"
365 | msgid "Type of vehicle"
366 | msgstr "Type of vehicle"
367 | msgid "Use contact mail addresses as sender"
368 | msgstr "Use contact mail addresses as sender"
369 | msgid "User confirmation email data"
370 | msgstr "User confirmation email data"
371 | msgid "User defined field data #num"
372 | msgstr "User defined field data #num"
373 | msgid "User defined field name #num"
374 | msgstr "User defined field name #num"
375 | msgid "Value"
376 | msgstr "Value"
377 | msgid "View contacts"
378 | msgstr "View contacts"
379 | msgid "View form submission"
380 | msgstr "View form submission"
381 | msgid "View form submissions"
382 | msgstr "View form submissions"
383 | msgid "View submissions"
384 | msgstr "View submissions"
385 | msgid "View submitted form data"
386 | msgstr "View submitted form data"
387 | msgid "Visit website"
388 | msgstr "Visit website"
389 | msgid "We will reply as soon as possible."
390 | msgstr "We will reply as soon as possible."
391 | msgid "We will respond to your email address as soon as possible."
392 | msgstr "We will respond to your email address as soon as possible."
393 | msgid "Web Location 1"
394 | msgstr "Web Location 1"
395 | msgid "Web Location 2"
396 | msgstr "Web Location 2"
397 | msgid "Web Location 3"
398 | msgstr "Web Location 3"
399 | msgid "Webmaster"
400 | msgstr "Webmaster"
401 | msgid "Website"
402 | msgstr "Website"
403 | msgid "Yes"
404 | msgstr "Yes"
405 | msgid "Yes, I agree with the Terms and Conditions "
406 | msgstr "Yes, I agree with the Terms and Conditions "
407 | msgid "You can use the following placeholders within the subject:"
408 | msgstr "You can use the following placeholders within the subject:"
409 | msgid "You may enter a single address or a comma separated list of addresses."
410 | msgstr "You may enter a single address or a comma separated list of addresses."
411 | msgid "Your Name"
412 | msgstr "Your Name"
413 | msgid "Your mail to %s"
414 | msgstr "Your mail to %s"
415 | msgid "Your name"
416 | msgstr "Your name"
417 | msgid "Zip City"
418 | msgstr "Zip City"
--------------------------------------------------------------------------------