Commit 87f45862 authored by Jonas Götze's avatar Jonas Götze
Browse files

[WIP][FEATURE] Add a form to submit new events in the frontend. A new event is...

[WIP][FEATURE] Add a form to submit new events in the frontend. A new event is disabled by default and has to be enabled (=reviewed) by a team member. Once a frontend user has an event that has been approved, his future events are approved by default.
parent 9e33d9d2
<?php
namespace T3o\T3orgLayout\Domain\Finishers;
/*
* This file is part of the TYPO3 project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License, either version 3
* of the License, or (at your option) any later version.
*
* For the full copyright and license information, please read the LICENSE
* file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Form\Domain\Finishers\Exception\FinisherException;
/**
* Class SaveToDatabaseFinisher
*/
class T3oSaveToDatabaseFinisher extends \TYPO3\CMS\Form\Domain\Finishers\SaveToDatabaseFinisher
{
/**
* Executes this finisher
* @see AbstractFinisher::execute()
*
* @throws FinisherException
*/
protected function executeInternal()
{
$options = [];
if (isset($this->options['table'])) {
$options[] = $this->options;
} else {
$options = $this->options;
}
$isLoggedInUser = GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect(
'frontend.user',
'isLoggedIn'
);
foreach ($options as $optionKey => $option) {
$this->options = $option;
$userdataOptions = $this->parseOption('userdata');
if ($userdataOptions !== null) {
$userdata = [];
foreach ($userdataOptions as $userdataKey => $defaultValue) {
$userdata[$userdataKey] = $defaultValue;
if (
$userdataKey !== 'password' &&
$isLoggedInUser
) {
if ($userdataKey === '__newEventStatus') {
$table = 'tx_sfeventmgt_domain_model_event';
$databaseConnection = GeneralUtility::makeInstance(ConnectionPool::class)
->getConnectionForTable($table);
$userdata[$userdataKey] = $databaseConnection->count(
'author_fe_user',
$table,
[
'author_fe_user' => $GLOBALS['TSFE']->fe_user->user['uid']
]
) > 0 ? 0 : 1;
}
if (isset($GLOBALS['TSFE']->fe_user->user[$userdataKey])) {
$userdata[$userdataKey] = $GLOBALS['TSFE']->fe_user->user[$userdataKey];
}
}
}
$this->finisherContext->getFinisherVariableProvider()->add(
$this->shortFinisherIdentifier,
'feuser',
$userdata
);
}
$this->process($optionKey);
}
}
}
<?php
namespace T3o\T3orgLayout\Domain\Model\FormElements;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\Restriction\FrontendRestrictionContainer;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Form\Domain\Model\FormElements\GenericFormElement;
class SystemCategoryOptions extends GenericFormElement
{
public function setProperty(string $key, $value)
{
if ($key === 'systemCategory' && is_array($value) && isset($value['uid'])) {
$this->setProperty('options', $this->getOptions($value['uid'],$value['exclude'] ?? ''));
return;
}
parent::setProperty($key, $value);
}
/**
* @param int $uid
* @param string $exclude csv list of excluded IDs
* @return array
*/
protected function getOptions(int $uid, string $exclude = '') : array
{
$options = [];
$excludeIds = GeneralUtility::intExplode(',',$exclude,true);
foreach ($this->getCategoriesForUid($uid, $excludeIds) as $category) {
$options[$category['uid']] = $category['title'];
}
asort($options);
return $options;
}
protected function getCategoriesForUid(int $uid, array $excludeIds = []) : array
{
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('sys_category');
$queryBuilder->setRestrictions(
GeneralUtility::makeInstance(FrontendRestrictionContainer::class)
);
$queryBuilder
->select('*')
->from('sys_category')
->where(
$queryBuilder->expr()->eq(
'parent',
$queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
)
);
if (!empty($excludeIds)) {
$queryBuilder->andWhere(
$queryBuilder->expr()->notIn(
'uid',
$excludeIds
)
);
}
return $queryBuilder
->execute()
->fetchAll();
}
}
......@@ -52,6 +52,27 @@ $GLOBALS['TCA']['tx_sfeventmgt_domain_model_event']['columns']['skills'] = [
'',
'after:program'
);
$GLOBALS['TCA']['tx_sfeventmgt_domain_model_event']['columns']['author_fe_user'] = [
'exclude' => 0,
'label' => 'submitted by FE User',
'config' => [
'type' => 'group',
'internal_type' => 'db',
'readOnly' => true,
'default' => 0,
'minitems' => 0,
'maxitems' => 1,
'size' => 1,
'foreign_table' => 'fe_users',
'allowed' => 'fe_users'
],
];
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes(
'tx_sfeventmgt_domain_model_event',
'author_fe_user',
'',
'after:room'
);
// modify slug to prefix startdate
$GLOBALS['TCA']['tx_sfeventmgt_domain_model_event']['columns']['slug']['config']['generatorOptions']['postModifiers'][] = \T3o\T3orgLayout\Hook\DataHandlerHook::class . '->modifySlug';
......
plugin.tx_form {
view {
templateRootPaths.20 = EXT:t3org_layout/Resources/Private/Templates/Form/
partialRootPaths.20 = EXT:t3org_layout/Resources/Private/Templates/Form/
layoutRootPaths.20 = EXT:t3org_layout/Resources/Private/Templates/Form/
}
settings {
yamlConfigurations {
1604402548 = EXT:t3org_layout/Configuration/Yaml/Form/Settings.yaml
}
}
}
module.tx_form {
settings {
yamlConfigurations {
1604402548 = EXT:t3org_layout/Configuration/Yaml/Form/Settings.yaml
}
}
}
TYPO3:
CMS:
Form:
persistenceManager:
allowSaveToExtensionPaths: false
allowDeleteFromExtensionPaths: false
allowedExtensionPaths:
1604402548: EXT:t3org_layout/Resources/Private/Forms/
prototypes:
standard:
finishersDefinition:
T3oSaveToDatabase:
implementationClassName: 'T3o\T3orgLayout\Domain\Finishers\T3oSaveToDatabaseFinisher'
formElementsDefinition:
SingleSelectWithSystemCategory:
__inheritances:
10: 'TYPO3.CMS.Form.prototypes.standard.formElementsDefinition.SingleSelect'
implementationClassName: 'T3o\T3orgLayout\Domain\Model\FormElements\SystemCategoryOptions'
renderingOptions:
templateName: 'SingleSelect'
Form:
renderingOptions:
templateRootPaths:
120: 'EXT:t3org_layout/Resources/Private/Templates/Form/'
partialRootPaths:
120: 'EXT:t3org_layout/Resources/Private/Partials/Form/'
layoutRootPaths:
120: 'EXT:t3org_layout/Resources/Private/Layouts/Form/'
renderingOptions:
submitButtonLabel: Submit
type: Form
identifier: eventSubmission
label: 'Event Submission'
prototypeName: standard
finishers:
-
identifier: T3oSaveToDatabase
options:
-
table: 'tx_sfeventmgt_domain_model_event'
mode: insert
userdata:
uid: 0
__newEventStatus: 1
databaseColumnMappings:
pid:
value: 180
hidden:
value: '{T3oSaveToDatabase.feuser.__newEventStatus}'
author_fe_user:
value: '{T3oSaveToDatabase.feuser.uid}'
crdate:
value: '{__currentTimestamp}'
tstamp:
value: '{__currentTimestamp}'
elements:
fileupload:
mapOnDatabaseColumn: 'image'
title:
mapOnDatabaseColumn: 'title'
startdate:
mapOnDatabaseColumn: 'startdate'
enddate:
mapOnDatabaseColumn: 'enddate'
teaser:
mapOnDatabaseColumn: 'teaser'
description:
mapOnDatabaseColumn: 'description'
link:
mapOnDatabaseColumn: 'link'
program:
mapOnDatabaseColumn: 'program'
room:
mapOnDatabaseColumn: 'room'
-
table: sys_file_reference
mode: insert
elements:
image:
mapOnDatabaseColumn: 'uid_local'
skipIfValueIsEmpty: true
databaseColumnMappings:
table_local:
value: 'sys_file'
tablenames:
value: 'tx_sfeventmgt_domain_model_event'
fieldname:
value: 'image'
tstamp:
value: '{__currentTimestamp}'
crdate:
value: '{__currentTimestamp}'
uid_foreign:
value: '{T3oSaveToDatabase.insertedUids.0}'
-
table: sys_category_record_mm
mode: insert
elements:
category:
mapOnDatabaseColumn: 'uid_local'
databaseColumnMappings:
tablenames:
value: 'tx_sfeventmgt_domain_model_event'
fieldname:
value: 'category'
uid_foreign:
value: '{T3oSaveToDatabase.insertedUids.0}'
-
options:
subject: 'new Event submitted on typo3.org'
recipients:
t3o@typo3.org: 'TYPO3 T3O team'
senderAddress: noreply@typo3.org
senderName: typo3.org
addHtmlPart: true
attachUploads: false
useFluidEmail: false
title: 'new Event submitted on typo3.org'
#templateName: 'EventSubmission{@format}.html'
identifier: EmailToReceiver
-
options:
message: 'Thank You!'
identifier: Confirmation
renderables:
-
renderingOptions:
previousButtonLabel: 'Previous step'
nextButtonLabel: 'Next step'
type: Page
identifier: page-1
label: Step
renderables:
-
defaultValue: ''
type: Text
identifier: title
label: Title
properties:
elementDescription: 'Enter a descriptive title for the event'
fluidAdditionalAttributes:
required: required
validators:
-
identifier: NotEmpty
-
type: GridRow
identifier: gridrow-1
label: 'Grid: Row'
renderables:
-
defaultValue: ''
properties:
fluidAdditionalAttributes:
step: 1
required: required
elementDescription: 'The date this event starts'
type: Date
identifier: startdate
label: 'Start date'
validators:
-
identifier: NotEmpty
-
defaultValue: ''
properties:
fluidAdditionalAttributes:
min: ''
max: ''
step: 1
required: required
elementDescription: 'The date this event ends'
type: Date
identifier: enddate
label: 'End date'
validators:
-
identifier: NotEmpty
-
defaultValue: ''
type: Textarea
identifier: teaser
label: Teaser
properties:
elementDescription: 'short description'
-
defaultValue: ''
type: Textarea
identifier: description
label: Description
properties:
elementDescription: 'full description of the event'
-
defaultValue: ''
type: Url
identifier: link
label: Link
properties:
elementDescription: 'link to an event site'
-
defaultValue: ''
type: Textarea
identifier: program
label: 'Program / Schedule'
-
properties:
systemCategory:
uid: 34
exclude: 36
prependOptionLabel: 'Please select...'
fluidAdditionalAttributes:
required: required
type: SingleSelectWithSystemCategory
identifier: category
label: 'Category'
-
defaultValue: ''
type: Text
identifier: room
label: Room
properties:
elementDescription: 'room name or number'
-
properties:
saveToFileMount: '1:/user_upload/'
allowedMimeTypes:
- image/jpeg
- image/png
type: ImageUpload
identifier: image
label: Images
......@@ -2,7 +2,8 @@
# Table structure for table 'tx_sfeventmgt_domain_model_event'
#
CREATE TABLE tx_sfeventmgt_domain_model_event (
skills text
skills text,
author_fe_user int(11) DEFAULT '0' NOT NULL
);
#
......
......@@ -2,6 +2,8 @@
@import 'EXT:t3org_layout/Configuration/TypoScript/Ext/'
@import 'EXT:t3org_layout/Configuration/TypoScript/Cache.typoscript'
@import 'EXT:t3org_layout/Configuration/TypoScript/Includes/'
# Let table allow all classes
lib.parseFunc_RTE.externalBlocks.table.stdWrap.HTMLparser.tags.table.fixAttrib.class >
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment