|
25 | 25 |
|
26 | 26 | class IntegritaFile extends Controllo |
27 | 27 | { |
| 28 | + protected const GLOBAL_BATCH_SIZE = 100; |
| 29 | + |
28 | 30 | public function getName() |
29 | 31 | { |
30 | 32 | return tr('Integrità file allegati'); |
@@ -106,36 +108,9 @@ public function execute($record, $params = []) |
106 | 108 | $action = $params['action'] ?? ''; |
107 | 109 |
|
108 | 110 | if ($action === 'remove_orphan_file' && $record['tipo'] === 'file_orfano') { |
109 | | - $file_path = base_dir().'/files/'.$record['percorso_completo']; |
110 | | - |
111 | | - if (file_exists($file_path)) { |
112 | | - if (unlink($file_path)) { |
113 | | - return tr('File _FILE_ rimosso con successo', ['_FILE_' => $record['nome_file']]); |
114 | | - } |
115 | | - |
116 | | - return tr('Errore nella rimozione del file _FILE_', ['_FILE_' => $record['nome_file']]); |
117 | | - } |
118 | | - |
119 | | - return tr('File _FILE_ non trovato', ['_FILE_' => $record['nome_file']]); |
| 111 | + return $this->removeOrphanFile($record)['message']; |
120 | 112 | } elseif ($action === 'remove_orphan_record' && $record['tipo'] === 'file_mancante') { |
121 | | - // Estraggo l'ID del record dal campo id (formato: missing_file_123) |
122 | | - $upload_id = str_replace('missing_file_', '', $record['id']); |
123 | | - |
124 | | - try { |
125 | | - $upload = Upload::find($upload_id); |
126 | | - if ($upload) { |
127 | | - $upload->delete(); |
128 | | - |
129 | | - return tr('Record _FILE_ rimosso dal database con successo', ['_FILE_' => $record['nome_file']]); |
130 | | - } |
131 | | - |
132 | | - return tr('Record _FILE_ non trovato nel database', ['_FILE_' => $record['nome_file']]); |
133 | | - } catch (\Exception $e) { |
134 | | - return tr('Errore nella rimozione del record _FILE_: _ERROR_', [ |
135 | | - '_FILE_' => $record['nome_file'], |
136 | | - '_ERROR_' => $e->getMessage(), |
137 | | - ]); |
138 | | - } |
| 113 | + return $this->removeOrphanRecord($record)['message']; |
139 | 114 | } |
140 | 115 |
|
141 | 116 | return tr('Azione non supportata per questo tipo di record'); |
@@ -182,87 +157,135 @@ public function solveGlobal($params = []) |
182 | 157 | } |
183 | 158 | } |
184 | 159 | } elseif ($action === 'remove_all_both') { |
185 | | - // Esegui entrambe le operazioni a blocchi di 100 per evitare timeout |
| 160 | + $limit = !empty($params['limit']) ? (int) $params['limit'] : self::GLOBAL_BATCH_SIZE; |
| 161 | + $limit = $limit > 0 ? $limit : self::GLOBAL_BATCH_SIZE; |
186 | 162 |
|
187 | | - // Separa i record per tipo |
188 | | - $orphan_files = []; |
189 | | - $orphan_records = []; |
| 163 | + $pending_records = $this->getPendingGlobalRecords(); |
| 164 | + $total_before = count($pending_records); |
| 165 | + $batch = array_slice($pending_records, 0, $limit); |
190 | 166 |
|
191 | | - foreach ($this->results as $record) { |
| 167 | + $processed_files = 0; |
| 168 | + $processed_records = 0; |
| 169 | + |
| 170 | + foreach ($batch as $record) { |
192 | 171 | if ($record['tipo'] === 'file_orfano') { |
193 | | - $orphan_files[] = $record; |
| 172 | + $result = $this->removeOrphanFile($record); |
| 173 | + $results[$record['id']] = $result['message']; |
| 174 | + if ($result['success']) { |
| 175 | + ++$processed_files; |
| 176 | + } |
194 | 177 | } elseif ($record['tipo'] === 'file_mancante') { |
195 | | - $orphan_records[] = $record; |
| 178 | + $result = $this->removeOrphanRecord($record); |
| 179 | + $results[$record['id']] = $result['message']; |
| 180 | + if ($result['success']) { |
| 181 | + ++$processed_records; |
| 182 | + } |
196 | 183 | } |
197 | 184 | } |
198 | 185 |
|
199 | | - $batch_size = 100; |
200 | | - $processed_files = 0; |
201 | | - $processed_records = 0; |
| 186 | + $this->results = []; |
| 187 | + $this->check(); |
| 188 | + $remaining = count($this->getPendingGlobalRecords()); |
| 189 | + $resolved_in_batch = max(0, $total_before - $remaining); |
| 190 | + |
| 191 | + return [ |
| 192 | + 'batch_size' => $limit, |
| 193 | + 'processed' => count($batch), |
| 194 | + 'processed_files' => $processed_files, |
| 195 | + 'processed_records' => $processed_records, |
| 196 | + 'resolved_in_batch' => $resolved_in_batch, |
| 197 | + 'remaining' => $remaining, |
| 198 | + 'more' => $remaining > 0, |
| 199 | + 'results' => $results, |
| 200 | + 'summary' => tr('Blocco completato: _FILES_ file e _RECORDS_ record rimossi con successo. Record ancora da verificare: _REMAINING_.', [ |
| 201 | + '_FILES_' => $processed_files, |
| 202 | + '_RECORDS_' => $processed_records, |
| 203 | + '_REMAINING_' => $remaining, |
| 204 | + ]), |
| 205 | + 'total_before' => $total_before, |
| 206 | + ]; |
| 207 | + } |
202 | 208 |
|
203 | | - // 1. Rimuovi file orfani a blocchi |
204 | | - $file_batches = array_chunk($orphan_files, $batch_size); |
205 | | - foreach ($file_batches as $batch) { |
206 | | - foreach ($batch as $record) { |
207 | | - $file_path = base_dir().'/files/'.$record['percorso_completo']; |
| 209 | + return $results; |
| 210 | + } |
208 | 211 |
|
209 | | - if (file_exists($file_path)) { |
210 | | - if (unlink($file_path)) { |
211 | | - ++$processed_files; |
212 | | - $results[$record['id']] = tr('File _FILE_ rimosso con successo', ['_FILE_' => $record['nome_file']]); |
213 | | - } else { |
214 | | - $results[$record['id']] = tr('Errore nella rimozione del file _FILE_', ['_FILE_' => $record['nome_file']]); |
215 | | - } |
216 | | - } else { |
217 | | - $results[$record['id']] = tr('File _FILE_ non trovato', ['_FILE_' => $record['nome_file']]); |
218 | | - } |
219 | | - } |
| 212 | + /** |
| 213 | + * Restituisce i record ancora correggibili globalmente, dando priorità ai file orfani. |
| 214 | + */ |
| 215 | + protected function getPendingGlobalRecords() |
| 216 | + { |
| 217 | + $orphan_files = []; |
| 218 | + $orphan_records = []; |
220 | 219 |
|
221 | | - // Pausa breve tra i blocchi per evitare sovraccarico |
222 | | - if (count($file_batches) > 1) { |
223 | | - usleep(100000); // 0.1 secondi |
224 | | - } |
| 220 | + foreach ($this->results as $record) { |
| 221 | + if ($record['tipo'] === 'file_orfano') { |
| 222 | + $orphan_files[] = $record; |
| 223 | + } elseif ($record['tipo'] === 'file_mancante') { |
| 224 | + $orphan_records[] = $record; |
225 | 225 | } |
| 226 | + } |
226 | 227 |
|
227 | | - // 2. Rimuovi record orfani a blocchi |
228 | | - $record_batches = array_chunk($orphan_records, $batch_size); |
229 | | - foreach ($record_batches as $batch) { |
230 | | - foreach ($batch as $record) { |
231 | | - $upload_id = str_replace('missing_file_', '', $record['id']); |
232 | | - |
233 | | - try { |
234 | | - $upload = Upload::find($upload_id); |
235 | | - if ($upload) { |
236 | | - $upload->delete(); |
237 | | - ++$processed_records; |
238 | | - $results[$record['id']] = tr('Record _FILE_ rimosso dal database con successo', ['_FILE_' => $record['nome_file']]); |
239 | | - } else { |
240 | | - $results[$record['id']] = tr('Record _FILE_ non trovato nel database', ['_FILE_' => $record['nome_file']]); |
241 | | - } |
242 | | - } catch (\Exception $e) { |
243 | | - $results[$record['id']] = tr('Errore nella rimozione del record _FILE_: _ERROR_', [ |
244 | | - '_FILE_' => $record['nome_file'], |
245 | | - '_ERROR_' => $e->getMessage(), |
246 | | - ]); |
247 | | - } |
248 | | - } |
| 228 | + return array_merge($orphan_files, $orphan_records); |
| 229 | + } |
249 | 230 |
|
250 | | - // Pausa breve tra i blocchi per evitare sovraccarico del database |
251 | | - if (count($record_batches) > 1) { |
252 | | - usleep(100000); // 0.1 secondi |
253 | | - } |
| 231 | + /** |
| 232 | + * Rimuove un file orfano dal filesystem. |
| 233 | + */ |
| 234 | + protected function removeOrphanFile($record) |
| 235 | + { |
| 236 | + $file_path = base_dir().'/files/'.$record['percorso_completo']; |
| 237 | + |
| 238 | + if (file_exists($file_path)) { |
| 239 | + if (unlink($file_path)) { |
| 240 | + return [ |
| 241 | + 'success' => true, |
| 242 | + 'message' => tr('File _FILE_ rimosso con successo', ['_FILE_' => $record['nome_file']]), |
| 243 | + ]; |
254 | 244 | } |
255 | 245 |
|
256 | | - // Aggiungi un messaggio di riepilogo |
257 | | - if ($processed_files > 0 || $processed_records > 0) { |
258 | | - $results['summary'] = tr('Operazione completata: _FILES_ file e _RECORDS_ record rimossi con successo', [ |
259 | | - '_FILES_' => $processed_files, |
260 | | - '_RECORDS_' => $processed_records, |
261 | | - ]); |
262 | | - } |
| 246 | + return [ |
| 247 | + 'success' => false, |
| 248 | + 'message' => tr('Errore nella rimozione del file _FILE_', ['_FILE_' => $record['nome_file']]), |
| 249 | + ]; |
263 | 250 | } |
264 | 251 |
|
265 | | - return $results; |
| 252 | + return [ |
| 253 | + 'success' => false, |
| 254 | + 'message' => tr('File _FILE_ non trovato', ['_FILE_' => $record['nome_file']]), |
| 255 | + ]; |
| 256 | + } |
| 257 | + |
| 258 | + /** |
| 259 | + * Rimuove un record orfano dal database. |
| 260 | + */ |
| 261 | + protected function removeOrphanRecord($record) |
| 262 | + { |
| 263 | + $upload_id = str_replace('missing_file_', '', $record['id']); |
| 264 | + |
| 265 | + try { |
| 266 | + $upload = Upload::find($upload_id); |
| 267 | + if ($upload) { |
| 268 | + $upload->delete(); |
| 269 | + |
| 270 | + return [ |
| 271 | + 'success' => true, |
| 272 | + 'message' => tr('Record _FILE_ rimosso dal database con successo', ['_FILE_' => $record['nome_file']]), |
| 273 | + ]; |
| 274 | + } |
| 275 | + |
| 276 | + return [ |
| 277 | + 'success' => false, |
| 278 | + 'message' => tr('Record _FILE_ non trovato nel database', ['_FILE_' => $record['nome_file']]), |
| 279 | + ]; |
| 280 | + } catch (\Exception $e) { |
| 281 | + return [ |
| 282 | + 'success' => false, |
| 283 | + 'message' => tr('Errore nella rimozione del record _FILE_: _ERROR_', [ |
| 284 | + '_FILE_' => $record['nome_file'], |
| 285 | + '_ERROR_' => $e->getMessage(), |
| 286 | + ]), |
| 287 | + ]; |
| 288 | + } |
266 | 289 | } |
267 | 290 |
|
268 | 291 | /** |
|
0 commit comments