|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* (c) Kitodo. Key to digital objects e.V. <[email protected]> |
|
4
|
|
|
* |
|
5
|
|
|
* This file is part of the Kitodo and TYPO3 projects. |
|
6
|
|
|
* |
|
7
|
|
|
* @license GNU General Public License version 3 or later. |
|
8
|
|
|
* For the full copyright and license information, please read the |
|
9
|
|
|
* LICENSE.txt file that was distributed with this source code. |
|
10
|
|
|
*/ |
|
11
|
|
|
|
|
12
|
|
|
use Kitodo\Dlf\Common\Helper; |
|
13
|
|
|
use Kitodo\Dlf\Common\Solr; |
|
14
|
|
|
|
|
15
|
|
|
/** |
|
16
|
|
|
* Update class 'ext_update' for the 'dlf' extension |
|
17
|
|
|
* |
|
18
|
|
|
* @author Sebastian Meyer <[email protected]> |
|
19
|
|
|
* @package TYPO3 |
|
20
|
|
|
* @subpackage dlf |
|
21
|
|
|
* @access public |
|
22
|
|
|
*/ |
|
23
|
|
|
class ext_update { |
|
24
|
|
|
/** |
|
25
|
|
|
* This holds the output ready to return |
|
26
|
|
|
* |
|
27
|
|
|
* @var string |
|
28
|
|
|
* @access protected |
|
29
|
|
|
*/ |
|
30
|
|
|
protected $content = ''; |
|
31
|
|
|
|
|
32
|
|
|
/** |
|
33
|
|
|
* Triggers the update option in the extension manager |
|
34
|
|
|
* |
|
35
|
|
|
* @access public |
|
36
|
|
|
* |
|
37
|
|
|
* @return boolean Should the update option be shown? |
|
38
|
|
|
*/ |
|
39
|
|
|
public function access() { |
|
40
|
|
|
if (count($this->getMetadataConfig())) { |
|
41
|
|
|
return TRUE; |
|
42
|
|
|
} elseif ($this->oldIndexRelatedTableNames()) { |
|
43
|
|
|
return TRUE; |
|
44
|
|
|
} elseif ($this->solariumSolrUpdateRequired()) { |
|
45
|
|
|
return TRUE; |
|
46
|
|
|
} elseif (count($this->oldFormatClasses())) { |
|
47
|
|
|
return TRUE; |
|
48
|
|
|
} |
|
49
|
|
|
return FALSE; |
|
50
|
|
|
} |
|
51
|
|
|
|
|
52
|
|
|
/** |
|
53
|
|
|
* Get all outdated metadata configuration records |
|
54
|
|
|
* |
|
55
|
|
|
* @access protected |
|
56
|
|
|
* |
|
57
|
|
|
* @return array Array of UIDs of outdated records |
|
58
|
|
|
*/ |
|
59
|
|
|
protected function getMetadataConfig() { |
|
60
|
|
|
$uids = []; |
|
61
|
|
|
// check if tx_dlf_metadata.xpath exists anyhow |
|
62
|
|
|
$fieldsInDatabase = $GLOBALS['TYPO3_DB']->admin_get_fields('tx_dlf_metadata'); |
|
63
|
|
|
if (!in_array('xpath', array_keys($fieldsInDatabase))) { |
|
64
|
|
|
return $uids; |
|
65
|
|
|
} |
|
66
|
|
|
// Get all records with outdated configuration. |
|
67
|
|
|
$result = $GLOBALS['TYPO3_DB']->exec_SELECTquery( |
|
68
|
|
|
'tx_dlf_metadata.uid AS uid', |
|
69
|
|
|
'tx_dlf_metadata', |
|
70
|
|
|
'tx_dlf_metadata.format=0' |
|
71
|
|
|
.' AND NOT tx_dlf_metadata.xpath=""' |
|
72
|
|
|
.Helper::whereClause('tx_dlf_metadata'), |
|
73
|
|
|
'', |
|
74
|
|
|
'', |
|
75
|
|
|
'' |
|
76
|
|
|
); |
|
77
|
|
|
if ($GLOBALS['TYPO3_DB']->sql_num_rows($result)) { |
|
78
|
|
|
while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) { |
|
79
|
|
|
$uids[] = intval($resArray['uid']); |
|
80
|
|
|
} |
|
81
|
|
|
} |
|
82
|
|
|
return $uids; |
|
83
|
|
|
} |
|
84
|
|
|
|
|
85
|
|
|
/** |
|
86
|
|
|
* The main method of the class |
|
87
|
|
|
* |
|
88
|
|
|
* @access public |
|
89
|
|
|
* |
|
90
|
|
|
* @return string The content that is displayed on the website |
|
91
|
|
|
*/ |
|
92
|
|
|
public function main() { |
|
93
|
|
|
// Load localization file. |
|
94
|
|
|
$GLOBALS['LANG']->includeLLFile('EXT:dlf/Resources/Private/Language/FlashMessages.xml'); |
|
95
|
|
|
// Update the metadata configuration. |
|
96
|
|
|
if (count($this->getMetadataConfig())) { |
|
97
|
|
|
$this->updateMetadataConfig(); |
|
98
|
|
|
} |
|
99
|
|
|
if ($this->oldIndexRelatedTableNames()) { |
|
100
|
|
|
$this->renameIndexRelatedColumns(); |
|
101
|
|
|
} |
|
102
|
|
|
if ($this->solariumSolrUpdateRequired()) { |
|
103
|
|
|
$this->doSolariumSolrUpdate(); |
|
104
|
|
|
} |
|
105
|
|
|
if (count($this->oldFormatClasses())) { |
|
106
|
|
|
$this->updateFormatClasses(); |
|
107
|
|
|
} |
|
108
|
|
|
return $this->content; |
|
109
|
|
|
} |
|
110
|
|
|
|
|
111
|
|
|
/** |
|
112
|
|
|
* Check for old format classes |
|
113
|
|
|
* |
|
114
|
|
|
* @access protected |
|
115
|
|
|
* |
|
116
|
|
|
* @return boolean true if old format classes exist |
|
117
|
|
|
*/ |
|
118
|
|
|
protected function oldFormatClasses() { |
|
119
|
|
|
$oldRecords = []; |
|
120
|
|
|
// Get all records with outdated configuration. |
|
121
|
|
|
$result = $GLOBALS['TYPO3_DB']->exec_SELECTquery( |
|
122
|
|
|
'tx_dlf_formats.uid AS uid,tx_dlf_formats.type AS type', |
|
123
|
|
|
'tx_dlf_formats', |
|
124
|
|
|
'tx_dlf_formats.class NOT LIKE "%\\\\\\\\%"' // We are looking for a single backslash... |
|
125
|
|
|
.Helper::whereClause('tx_dlf_formats'), |
|
126
|
|
|
'', |
|
127
|
|
|
'', |
|
128
|
|
|
'' |
|
129
|
|
|
); |
|
130
|
|
|
while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) { |
|
131
|
|
|
$oldRecords[$resArray['uid']] = $resArray['type']; |
|
132
|
|
|
} |
|
133
|
|
|
return $oldRecords; |
|
134
|
|
|
} |
|
135
|
|
|
|
|
136
|
|
|
/** |
|
137
|
|
|
* Check for old index related colums |
|
138
|
|
|
* |
|
139
|
|
|
* @access protected |
|
140
|
|
|
* |
|
141
|
|
|
* @return boolean TRUE if old index related columns exist |
|
142
|
|
|
*/ |
|
143
|
|
|
protected function oldIndexRelatedTableNames() { |
|
144
|
|
|
$result = $GLOBALS['TYPO3_DB']->exec_SELECTquery( |
|
145
|
|
|
'column_name', |
|
146
|
|
|
'INFORMATION_SCHEMA.COLUMNS', |
|
147
|
|
|
'TABLE_NAME = "tx_dlf_metadata"', |
|
148
|
|
|
'', |
|
149
|
|
|
'', |
|
150
|
|
|
'' |
|
151
|
|
|
); |
|
152
|
|
|
while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) { |
|
153
|
|
|
if ($resArray['column_name'] == 'tokenized' |
|
154
|
|
|
|| $resArray['column_name'] == 'stored' |
|
155
|
|
|
|| $resArray['column_name'] == 'indexed' |
|
156
|
|
|
|| $resArray['column_name'] == 'boost' |
|
157
|
|
|
|| $resArray['column_name'] == 'autocomplete') { |
|
158
|
|
|
return TRUE; |
|
159
|
|
|
} |
|
160
|
|
|
} |
|
161
|
|
|
} |
|
162
|
|
|
|
|
163
|
|
|
/** |
|
164
|
|
|
* Copy the data of the old index related columns to the new columns |
|
165
|
|
|
* |
|
166
|
|
|
* @access protected |
|
167
|
|
|
* |
|
168
|
|
|
* @return void |
|
169
|
|
|
*/ |
|
170
|
|
|
protected function renameIndexRelatedColumns() { |
|
171
|
|
|
$sqlQuery = 'UPDATE tx_dlf_metadata' |
|
172
|
|
|
.' SET `index_tokenized` = `tokenized`' |
|
173
|
|
|
.', `index_stored` = `stored`' |
|
174
|
|
|
.', `index_indexed` = `indexed`' |
|
175
|
|
|
.', `index_boost` = `boost`' |
|
176
|
|
|
.', `index_autocomplete` = `autocomplete`'; |
|
177
|
|
|
// Copy the content of the old tables to the new ones |
|
178
|
|
|
$result = $GLOBALS['TYPO3_DB']->sql_query($sqlQuery); |
|
179
|
|
View Code Duplication |
if ($result) { |
|
|
|
|
|
|
180
|
|
|
Helper::addMessage( |
|
181
|
|
|
$GLOBALS['LANG']->getLL('update.copyIndexRelatedColumnsOkay', TRUE), |
|
182
|
|
|
$GLOBALS['LANG']->getLL('update.copyIndexRelatedColumns', TRUE), |
|
183
|
|
|
\TYPO3\CMS\Core\Messaging\FlashMessage::OK |
|
184
|
|
|
); |
|
185
|
|
|
} else { |
|
186
|
|
|
Helper::addMessage( |
|
187
|
|
|
$GLOBALS['LANG']->getLL('update.copyIndexRelatedColumnsNotOkay', TRUE), |
|
188
|
|
|
$GLOBALS['LANG']->getLL('update.copyIndexRelatedColumns', TRUE), |
|
189
|
|
|
\TYPO3\CMS\Core\Messaging\FlashMessage::WARNING |
|
190
|
|
|
); |
|
191
|
|
|
} |
|
192
|
|
|
$this->content .= Helper::renderFlashMessages(); |
|
193
|
|
|
} |
|
194
|
|
|
|
|
195
|
|
|
/** |
|
196
|
|
|
* Update all outdated format records |
|
197
|
|
|
* |
|
198
|
|
|
* @access protected |
|
199
|
|
|
* |
|
200
|
|
|
* @return void |
|
201
|
|
|
*/ |
|
202
|
|
|
protected function updateFormatClasses() { |
|
203
|
|
|
$oldRecords = $this->oldFormatClasses(); |
|
204
|
|
|
$newValues = [ |
|
205
|
|
|
'ALTO' => 'Kitodo\\\\Dlf\\\\Format\\\\Alto', // Those are effectively single backslashes |
|
206
|
|
|
'MODS' => 'Kitodo\\\\Dlf\\\\Format\\\\Mods', |
|
207
|
|
|
'TEIHDR' => 'Kitodo\\\\Dlf\\\\Format\\\\TeiHeader' |
|
208
|
|
|
]; |
|
209
|
|
|
foreach ($oldRecords as $uid => $type) { |
|
210
|
|
|
$sqlQuery = 'UPDATE tx_dlf_formats SET class="'.$newValues[$type].'" WHERE uid='.$uid; |
|
211
|
|
|
$GLOBALS['TYPO3_DB']->sql_query($sqlQuery); |
|
212
|
|
|
} |
|
213
|
|
|
Helper::addMessage( |
|
214
|
|
|
$GLOBALS['LANG']->getLL('update.FormatClassesOkay', TRUE), |
|
215
|
|
|
$GLOBALS['LANG']->getLL('update.FormatClasses', TRUE), |
|
216
|
|
|
\TYPO3\CMS\Core\Messaging\FlashMessage::OK |
|
217
|
|
|
); |
|
218
|
|
|
$this->content .= Helper::renderFlashMessages(); |
|
219
|
|
|
} |
|
220
|
|
|
|
|
221
|
|
|
/** |
|
222
|
|
|
* Update all outdated metadata configuration records |
|
223
|
|
|
* |
|
224
|
|
|
* @access protected |
|
225
|
|
|
* |
|
226
|
|
|
* @return void |
|
227
|
|
|
*/ |
|
228
|
|
|
protected function updateMetadataConfig() { |
|
229
|
|
|
$metadataUids = $this->getMetadataConfig(); |
|
230
|
|
|
if (!empty($metadataUids)) { |
|
231
|
|
|
$data = []; |
|
232
|
|
|
// Get all old metadata configuration records. |
|
233
|
|
|
$result = $GLOBALS['TYPO3_DB']->exec_SELECTquery( |
|
234
|
|
|
'tx_dlf_metadata.uid AS uid,tx_dlf_metadata.pid AS pid,tx_dlf_metadata.cruser_id AS cruser_id,tx_dlf_metadata.encoded AS encoded,tx_dlf_metadata.xpath AS xpath,tx_dlf_metadata.xpath_sorting AS xpath_sorting', |
|
235
|
|
|
'tx_dlf_metadata', |
|
236
|
|
|
'tx_dlf_metadata.uid IN ('.implode(',', $metadataUids).')' |
|
237
|
|
|
.Helper::whereClause('tx_dlf_metadata'), |
|
238
|
|
|
'', |
|
239
|
|
|
'', |
|
240
|
|
|
'' |
|
241
|
|
|
); |
|
242
|
|
|
while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) { |
|
243
|
|
|
$newId = uniqid('NEW'); |
|
244
|
|
|
// Copy record to new table. |
|
245
|
|
|
$data['tx_dlf_metadataformat'][$newId] = [ |
|
246
|
|
|
'pid' => $resArray['pid'], |
|
247
|
|
|
'cruser_id' => $resArray['cruser_id'], |
|
248
|
|
|
'parent_id' => $resArray['uid'], |
|
249
|
|
|
'encoded' => $resArray['encoded'], |
|
250
|
|
|
'xpath' => $resArray['xpath'], |
|
251
|
|
|
'xpath_sorting' => $resArray['xpath_sorting'] |
|
252
|
|
|
]; |
|
253
|
|
|
// Add reference to old table. |
|
254
|
|
|
$data['tx_dlf_metadata'][$resArray['uid']]['format'] = $newId; |
|
255
|
|
|
} |
|
256
|
|
|
if (!empty($data)) { |
|
257
|
|
|
// Process datamap. |
|
258
|
|
|
$substUids = Helper::processDBasAdmin($data); |
|
259
|
|
|
unset ($data); |
|
260
|
|
View Code Duplication |
if (!empty($substUids)) { |
|
|
|
|
|
|
261
|
|
|
Helper::addMessage( |
|
262
|
|
|
$GLOBALS['LANG']->getLL('update.metadataConfigOkay', TRUE), |
|
263
|
|
|
$GLOBALS['LANG']->getLL('update.metadataConfig', TRUE), |
|
264
|
|
|
\TYPO3\CMS\Core\Messaging\FlashMessage::OK |
|
265
|
|
|
); |
|
266
|
|
|
} else { |
|
267
|
|
|
Helper::addMessage( |
|
268
|
|
|
$GLOBALS['LANG']->getLL('update.metadataConfigNotOkay', TRUE), |
|
269
|
|
|
$GLOBALS['LANG']->getLL('update.metadataConfig', TRUE), |
|
270
|
|
|
\TYPO3\CMS\Core\Messaging\FlashMessage::WARNING |
|
271
|
|
|
); |
|
272
|
|
|
} |
|
273
|
|
|
$this->content .= Helper::renderFlashMessages(); |
|
274
|
|
|
} |
|
275
|
|
|
} |
|
276
|
|
|
} |
|
277
|
|
|
|
|
278
|
|
|
/** |
|
279
|
|
|
* Check all configured Solr cores |
|
280
|
|
|
* |
|
281
|
|
|
* @access protected |
|
282
|
|
|
* |
|
283
|
|
|
* @return boolean |
|
284
|
|
|
*/ |
|
285
|
|
|
protected function solariumSolrUpdateRequired() { |
|
286
|
|
|
// Get all Solr cores that were not deleted. |
|
287
|
|
|
$result = $GLOBALS['TYPO3_DB']->exec_SELECTquery( |
|
288
|
|
|
'index_name', |
|
289
|
|
|
'tx_dlf_solrcores', |
|
290
|
|
|
'deleted=0', |
|
291
|
|
|
'', |
|
292
|
|
|
'', |
|
293
|
|
|
'' |
|
294
|
|
|
); |
|
295
|
|
|
while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) { |
|
296
|
|
|
// Instantiate search object. |
|
297
|
|
|
$solr = Solr::getInstance($resArray['index_name']); |
|
298
|
|
|
if (!$solr->ready) { |
|
|
|
|
|
|
299
|
|
|
return TRUE; |
|
300
|
|
|
} |
|
301
|
|
|
} |
|
302
|
|
|
return FALSE; |
|
303
|
|
|
} |
|
304
|
|
|
|
|
305
|
|
|
/** |
|
306
|
|
|
* Create all configured Solr cores |
|
307
|
|
|
* |
|
308
|
|
|
* @access protected |
|
309
|
|
|
* |
|
310
|
|
|
* @return void |
|
311
|
|
|
*/ |
|
312
|
|
|
protected function doSolariumSolrUpdate() { |
|
313
|
|
|
// Get all Solr cores that were not deleted. |
|
314
|
|
|
$result = $GLOBALS['TYPO3_DB']->exec_SELECTquery( |
|
315
|
|
|
'index_name', |
|
316
|
|
|
'tx_dlf_solrcores', |
|
317
|
|
|
'deleted=0', |
|
318
|
|
|
'', |
|
319
|
|
|
'', |
|
320
|
|
|
'' |
|
321
|
|
|
); |
|
322
|
|
|
while ($resArray = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) { |
|
323
|
|
|
// Instantiate search object. |
|
324
|
|
|
$solr = Solr::getInstance($resArray['index_name']); |
|
325
|
|
|
if (!$solr->ready) { |
|
|
|
|
|
|
326
|
|
|
$conf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['dlf']); |
|
327
|
|
|
$solrInfo = Solr::getSolrConnectionInfo(); |
|
328
|
|
|
// Prepend username and password to hostname. |
|
329
|
|
View Code Duplication |
if ($solrInfo['username'] |
|
|
|
|
|
|
330
|
|
|
&& $solrInfo['password']) { |
|
331
|
|
|
$host = $solrInfo['username'].':'.$solrInfo['password'].'@'.$solrInfo['host']; |
|
332
|
|
|
} else { |
|
333
|
|
|
$host = $solrInfo['host']; |
|
334
|
|
|
} |
|
335
|
|
|
$context = stream_context_create([ |
|
336
|
|
|
'http' => [ |
|
337
|
|
|
'method' => 'GET', |
|
338
|
|
|
'user_agent' => ($conf['useragent'] ? $conf['useragent'] : ini_get('user_agent')) |
|
339
|
|
|
] |
|
340
|
|
|
]); |
|
341
|
|
|
// Build request for adding new Solr core. |
|
342
|
|
|
// @see http://wiki.apache.org/solr/CoreAdmin |
|
343
|
|
|
$url = $solrInfo['scheme'].'://'.$host.':'.$solrInfo['port'].'/'.$solrInfo['path'].'/admin/cores?wt=xml&action=CREATE&name='.$resArray['index_name'].'&instanceDir='.$resArray['index_name'].'&dataDir=data&configSet=dlf'; |
|
344
|
|
|
$response = @simplexml_load_string(file_get_contents($url, FALSE, $context)); |
|
345
|
|
|
// Process response. |
|
346
|
|
|
if ($response) { |
|
347
|
|
|
$status = $response->xpath('//lst[@name="responseHeader"]/int[@name="status"]'); |
|
348
|
|
|
if ($status |
|
349
|
|
|
&& $status[0] == 0) { |
|
350
|
|
|
continue; |
|
351
|
|
|
} |
|
352
|
|
|
} |
|
353
|
|
|
Helper::addMessage( |
|
354
|
|
|
$GLOBALS['LANG']->getLL('update.solariumSolrUpdateNotOkay', TRUE), |
|
355
|
|
|
sprintf($GLOBALS['LANG']->getLL('update.solariumSolrUpdate', TRUE), $resArray['index_name']), |
|
356
|
|
|
\TYPO3\CMS\Core\Messaging\FlashMessage::ERROR |
|
357
|
|
|
); |
|
358
|
|
|
$this->content .= Helper::renderFlashMessages(); |
|
359
|
|
|
return; |
|
360
|
|
|
} |
|
361
|
|
|
} |
|
362
|
|
|
Helper::addMessage( |
|
363
|
|
|
$GLOBALS['LANG']->getLL('update.solariumSolrUpdateOkay', TRUE), |
|
364
|
|
|
$GLOBALS['LANG']->getLL('update.solariumSolrUpdate', TRUE), |
|
365
|
|
|
\TYPO3\CMS\Core\Messaging\FlashMessage::OK |
|
366
|
|
|
); |
|
367
|
|
|
$this->content .= Helper::renderFlashMessages(); |
|
368
|
|
|
} |
|
369
|
|
|
} |
|
370
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.