[TASK] Ext:form - Add update option to saveToDatabase finisher
[Packages/TYPO3.CMS.git] / typo3 / sysext / form / Classes / Domain / Finishers / SaveToDatabaseFinisher.php
1 <?php
2 declare(strict_types=1);
3 namespace TYPO3\CMS\Form\Domain\Finishers;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17
18 use TYPO3\CMS\Core\Database\ConnectionPool;
19 use TYPO3\CMS\Core\Utility\GeneralUtility;
20 use TYPO3\CMS\Extbase\Domain\Model\FileReference;
21 use TYPO3\CMS\Form\Domain\Finishers\Exception\FinisherException;
22 use TYPO3\CMS\Form\Domain\Model\FormElements\FormElementInterface;
23
24 /**
25 * This finisher saves the data from a submitted form into
26 * a database table.
27 *
28 * Scope: frontend
29 */
30 class SaveToDatabaseFinisher extends AbstractFinisher
31 {
32
33 /**
34 * @var array
35 */
36 protected $defaultOptions = [
37 'table' => null,
38 'mode' => 'insert',
39 'whereClause' => [],
40 'elements' => [],
41 ];
42
43 /**
44 * Executes this finisher
45 * @see AbstractFinisher::execute()
46 *
47 * @return void
48 * @throws FinisherException
49 */
50 protected function executeInternal()
51 {
52 if (
53 $this->options['mode'] === 'update'
54 && empty($this->options['whereClause'])
55 ) {
56 throw new FinisherException(
57 'An empty option "whereClause" is not allowed in update mode.',
58 1480469086
59 );
60 }
61
62 $table = $this->parseOption('table');
63 $elementsConfiguration = $this->parseOption('elements');
64
65 $databaseConnection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($table);
66 $schemaManager = $databaseConnection->getSchemaManager();
67
68 if ($schemaManager->tablesExist([$table]) === false) {
69 throw new FinisherException('The table "' . $table . '" does not exist.', 1476362091);
70 }
71
72 $databaseColumns = $schemaManager->listTableColumns($table);
73 foreach ($elementsConfiguration as $elementIdentifier => $elementConfiguration) {
74 if (!array_key_exists($elementConfiguration['mapOnDatabaseColumn'], $databaseColumns)) {
75 throw new FinisherException(
76 'The column "' . $elementConfiguration['mapOnDatabaseColumn'] . '" does not exist in table "' . $table . '".',
77 1476362572
78 );
79 }
80 }
81
82 $formRuntime = $this->finisherContext->getFormRuntime();
83
84 $insertData = [];
85 foreach ($this->finisherContext->getFormValues() as $elementIdentifier => $elementValue) {
86 if (
87 $elementValue === null
88 && isset($elementsConfiguration[$elementIdentifier])
89 && isset($elementsConfiguration[$elementIdentifier]['skipIfValueIsNull'])
90 && $elementsConfiguration[$elementIdentifier]['skipIfValueIsNull'] === true
91 ) {
92 continue;
93 }
94
95 $element = $formRuntime->getFormDefinition()->getElementByIdentifier($elementIdentifier);
96 if (
97 !$element instanceof FormElementInterface
98 || !isset($elementsConfiguration[$elementIdentifier])
99 || !isset($elementsConfiguration[$elementIdentifier]['mapOnDatabaseColumn'])
100 ) {
101 continue;
102 }
103
104 if ($elementValue instanceof FileReference) {
105 if (isset($elementsConfiguration[$elementIdentifier]['saveFileIdentifierInsteadOfUid'])) {
106 $saveFileIdentifierInsteadOfUid = (bool)$elementsConfiguration[$elementIdentifier]['saveFileIdentifierInsteadOfUid'];
107 } else {
108 $saveFileIdentifierInsteadOfUid = false;
109 }
110
111 if ($saveFileIdentifierInsteadOfUid) {
112 $elementValue = $elementValue->getOriginalResource()->getCombinedIdentifier();
113 } else {
114 $elementValue = $elementValue->getOriginalResource()->getProperty('uid_local');
115 }
116 }
117 $insertData[$elementsConfiguration[$elementIdentifier]['mapOnDatabaseColumn']] = $elementValue;
118 }
119
120 if (!empty($insertData)) {
121 if ($this->options['mode'] === 'update') {
122 $databaseConnection->update(
123 $table,
124 $insertData,
125 $this->options['whereClause']
126 );
127 } else {
128 $databaseConnection->insert($table, $insertData);
129 }
130 }
131 }
132 }