44
55namespace Hoogi91 \Spreadsheets \Hooks ;
66
7+ use Hoogi91 \Spreadsheets \Domain \ValueObject \DsnValueObject ;
78use TYPO3 \CMS \Backend \Utility \BackendUtility ;
89use TYPO3 \CMS \Core \Database \ConnectionPool ;
910use TYPO3 \CMS \Core \DataHandling \DataHandler ;
@@ -17,10 +18,38 @@ class DataHandlerHook
1718 */
1819 private array $ records = [];
1920
21+ /**
22+ * @var array<string, array<string, array<string, array<string>>>>
23+ */
24+ private array $ activationTypes = [];
25+
2026 public function __construct (
2127 private readonly FileRepository $ fileRepository ,
2228 private readonly ConnectionPool $ connectionPool
2329 ) {
30+ foreach ($ GLOBALS ['TCA ' ] as $ table => $ tca ) {
31+ $ table = (string )$ table ;
32+ foreach ($ tca ['columns ' ] ?? [] as $ column => $ conf ) {
33+ if (
34+ isset ($ conf ['config ' ]['renderType ' ], $ conf ['config ' ]['uploadField ' ])
35+ && $ conf ['config ' ]['renderType ' ] === 'spreadsheetInput '
36+ ) {
37+ $ this ->activationTypes [$ table ]['* ' ][(string )$ conf ['config ' ]['uploadField ' ]][] = $ column ;
38+ }
39+ }
40+
41+ foreach ($ GLOBALS ['TCA ' ][$ table ]['types ' ] as $ CType => $ type ) {
42+ $ CType = (string )$ CType ;
43+ foreach ($ type ['columnsOverrides ' ] as $ column => $ conf ) {
44+ if (
45+ isset ($ conf ['config ' ]['renderType ' ], $ conf ['config ' ]['uploadField ' ])
46+ && $ conf ['config ' ]['renderType ' ] === 'spreadsheetInput '
47+ ) {
48+ $ this ->activationTypes [$ table ][$ CType ][(string )$ conf ['config ' ]['uploadField ' ]][] = $ column ;
49+ }
50+ }
51+ }
52+ }
2453 }
2554
2655 /**
@@ -37,56 +66,107 @@ public function processDatamap_afterDatabaseOperations( // @codingStandardsIgnor
3766 array $ fieldArray ,
3867 DataHandler $ dataHandler
3968 ): void {
40- // skip processing for unknown uid, wrong table, status or not updated assets
69+ // skip processing for not found uid or irrelevant status
4170 $ uid = $ dataHandler ->substNEWwithIDs [$ id ] ?? (is_int ($ id ) ? $ id : null );
42- if (
43- $ uid === null
44- || $ table !== 'tt_content '
45- || !array_key_exists ('tx_spreadsheets_assets ' , $ fieldArray )
46- || !in_array ($ status , ['new ' , 'update ' ], true )
47- ) {
71+ if ($ uid === null || !is_string ($ table ) || !in_array ($ status , ['new ' , 'update ' ], true )) {
4872 return ;
4973 }
5074
51- // skip if not spreadsheet table or bodytext is already filled
52- $ CType = $ fieldArray ['CType ' ] ?? $ this ->getBackendRecordField ($ uid , 'CType ' );
53- if (!in_array ( $ CType , [ ' spreadsheets_table ' , ' spreadsheets_tabs ' ], true )) {
75+ // ignore if handler should not process for table and/ or CType
76+ $ CType = $ fieldArray ['CType ' ] ?? $ this ->getBackendRecordField ($ uid , $ table , 'CType ' );
77+ if (!isset ( $ this -> activationTypes [ $ table ][ ' * ' ]) && ! isset ( $ this -> activationTypes [ $ table ][ $ CType ] )) {
5478 return ;
5579 }
5680
57- // truncate bodytext after update if assets have been removed
58- if ($ fieldArray ['tx_spreadsheets_assets ' ] === 0 ) {
59- if ($ status === 'update ' ) {
60- $ this ->connectionPool
61- ->getConnectionForTable ('tt_content ' )
62- ->update ('tt_content ' , ['bodytext ' => '' ], ['uid ' => $ uid ]);
81+ $ activationConfig = $ this ->activationTypes [$ table ][$ CType ] ?? $ this ->activationTypes [$ table ]['* ' ];
82+ foreach ($ activationConfig as $ uploadField => $ renderFields ) {
83+ // truncate render fields after update if assets have been removed
84+ if ($ fieldArray [$ uploadField ] === 0 ) {
85+ if ($ status === 'update ' ) {
86+ $ this ->connectionPool
87+ ->getConnectionForTable ($ table )
88+ ->update ($ table , array_fill_keys ($ renderFields , '' ), ['uid ' => $ uid ]);
89+ }
90+
91+ continue ;
6392 }
6493
65- return ;
94+ // if upload fields was filled we get it's relations and start to update all render fields if required
95+ /** @var array<FileReference> $relations */
96+ $ relations = $ this ->fileRepository ->findByRelation ($ table , $ uploadField , $ uid );
97+ foreach ($ renderFields as $ renderField ) {
98+ $ this ->setSpreadsheetValue ($ uid , $ table , $ status , $ renderField , $ relations );
99+ }
66100 }
101+ }
67102
68- /** @var array<FileReference> $relations */
69- $ relations = $ this ->fileRepository ->findByRelation ('tt_content ' , 'tx_spreadsheets_assets ' , $ uid );
103+ /**
104+ * @param int $uid UID of chart record
105+ * @param string $table Table to update
106+ * @param string $status Status of current record update
107+ * @param string $field Field to update spreadsheet value
108+ * @param array<FileReference> $relations File relations found
109+ *
110+ */
111+ private function setSpreadsheetValue (
112+ int $ uid ,
113+ string $ table ,
114+ string $ status ,
115+ string $ field ,
116+ array $ relations
117+ ): void {
70118 if (empty ($ relations )) {
71119 return ;
72120 }
73121
74- // update bodytext to default file selection
75- if (empty ($ this ->getBackendRecordField ($ uid , 'bodytext ' )) === true ) {
122+ // if backend record field is currently empty we pre-select with first relation
123+ $ fieldValue = $ this ->getBackendRecordField ($ uid , $ table , $ field );
124+ if (empty ($ fieldValue ) === true ) {
76125 $ this ->connectionPool
77- ->getConnectionForTable ('tt_content ' )
78- ->update ('tt_content ' , ['bodytext ' => 'spreadsheet:// ' . $ relations [0 ]->getUid ()], ['uid ' => $ uid ]);
126+ ->getConnectionForTable ($ table )
127+ ->update ($ table , [$ field => 'spreadsheet:// ' . $ relations [0 ]->getUid ()], ['uid ' => $ uid ]);
128+ } elseif ($ status === 'new ' && is_string ($ fieldValue )) {
129+ $ dsn = $ this ->getTranslatedSpreadsheetDsn (
130+ DsnValueObject::createFromDSN ($ fieldValue ),
131+ $ relations
132+ );
133+ if ($ dsn !== null ) {
134+ $ this ->connectionPool
135+ ->getConnectionForTable ($ table )
136+ ->update ($ table , [$ field => $ dsn ], ['uid ' => $ uid ]);
137+ }
138+ }
139+ }
140+
141+ /**
142+ * @param DsnValueObject $dsn Original DSN
143+ * @param array<FileReference> $references File relations found
144+ *
145+ */
146+ private function getTranslatedSpreadsheetDsn (DsnValueObject $ dsn , array $ references ): ?string
147+ {
148+ foreach ($ references as $ reference ) {
149+ if ($ reference ->getReferenceProperty ('l10n_parent ' ) === $ dsn ->getFileReference ()) {
150+ return str_replace (
151+ 'spreadsheet:// ' . $ dsn ->getFileReference (),
152+ 'spreadsheet:// ' . $ reference ->getUid (),
153+ $ dsn ->getDsn ()
154+ );
155+ }
79156 }
157+
158+ return null ;
80159 }
81160
82161 /**
83- * @param int $uid UID of tt_content record
162+ * @param int $uid UID of record
163+ * @param string $table Table to get record from
84164 * @param string $field Field to extract
85165 */
86- private function getBackendRecordField (int $ uid , string $ field ): mixed
166+ private function getBackendRecordField (int $ uid , string $ table , string $ field ): mixed
87167 {
88168 if (!isset ($ this ->records [$ uid ])) {
89- $ this ->records [$ uid ] = BackendUtility::getRecord (' tt_content ' , $ uid ); // @codeCoverageIgnore
169+ $ this ->records [$ uid ] = BackendUtility::getRecord ($ table , $ uid ); // @codeCoverageIgnore
90170 }
91171
92172 return $ this ->records [$ uid ][$ field ] ?? null ;
0 commit comments