PluginProbe
ANAC XML Bandi di Gara / trunk
ANAC XML Bandi di Gara vtrunk
7.8 trunk 0.1 1.0.0.1 1.0.1 1.0.2 1.0.3 1.0.4 1.1 1.1.1 1.1.2 2.0 2.0.1 2.0.2 2.0.3 2.1 2.2 2.3 2.3.1 3 3.0.1 3.1 3.1.1 3.1.2 3.1.3 All 57 releases
avcp / valid_page.php

valid_page.php in ANAC XML Bandi di Gara trunk, at valid_page.php

425 lines 26.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 function avcp_v_dataset_load() {
4 // Handle XML generation and log reset with nonce checks
5 if ( $_SERVER['REQUEST_METHOD'] === 'POST' ) {
6 if ( isset( $_POST['avcp_xmlgen_nonce'] ) && wp_verify_nonce( $_POST['avcp_xmlgen_nonce'], 'avcp_xmlgen_action' ) ) {
7 $terms = get_terms( 'annirif', array('hide_empty' => 0) );
8 foreach ( $terms as $term ) {
9 if ( isset( $_POST['XMLGEN_' . $term->name] ) ) {
10 creafilexml( $term->name );
11 echo '<div class="notice notice-success is-dismissible"><p>';
12 printf( esc_html__( 'Il seguente file .xml è generato: %s', 'avcp' ), '<b>' . esc_html( $term->name ) . '</b>' );
13 echo "</p></div>";
14 break;
15 }
16 }
17 }
18 if ( isset( $_POST['avcp_reset_log_nonce'] ) && wp_verify_nonce( $_POST['avcp_reset_log_nonce'], 'avcp_reset_log_action' ) && isset( $_POST['AVCP-RESET-LOG'] ) ) {
19 delete_option( 'anac_log' );
20 echo '<div class="notice notice-success is-dismissible"><p>' . esc_html__( 'Log eliminati', 'avcp' ) . '</p></div>';
21 }
22 }
23
24 $basexmlurl = avcp_get_basexmlurl();
25 ?>
26 <style>
27 /* Table header improvements */
28 table.widefat thead th {
29 background: #f3f4f5;
30 color: #23282d;
31 font-weight: 600;
32 text-align: left;
33 border-bottom: 2px solid #ccd0d4;
34 padding: 10px 8px;
35 }
36 table.widefat td {
37 padding: 8px;
38 vertical-align: top;
39 }
40 /* Responsive table */
41 @media (max-width: 900px) {
42 table.widefat, table.widefat thead, table.widefat tbody, table.widefat th, table.widefat td, table.widefat tr {
43 display: block;
44 }
45 table.widefat thead {
46 display: none;
47 }
48 table.widefat tr {
49 margin-bottom: 15px;
50 }
51 table.widefat td {
52 border: none;
53 position: relative;
54 padding-left: 50%;
55 }
56 table.widefat td:before {
57 position: absolute;
58 left: 10px;
59 width: 45%;
60 white-space: nowrap;
61 font-weight: bold;
62 }
63 table.widefat td:nth-of-type(1):before { content: "<?php esc_html_e('Anno', 'avcp'); ?>"; }
64 table.widefat td:nth-of-type(2):before { content: "<?php esc_html_e('Validazione XSD', 'avcp'); ?>"; }
65 table.widefat td:nth-of-type(3):before { content: "<?php esc_html_e('Versione XSD', 'avcp'); ?>"; }
66 table.widefat td:nth-of-type(4):before { content: "<?php esc_html_e('Validazione software', 'avcp'); ?>"; }
67 table.widefat td:nth-of-type(5):before { content: "<?php esc_html_e('Data generazione', 'avcp'); ?>"; }
68 table.widefat td:nth-of-type(6):before { content: "<?php esc_html_e('Azione', 'avcp'); ?>"; }
69 }
70 /* Log styling */
71 .avcp-log-list {
72 background: #fff;
73 border: 1px solid #ccd0d4;
74 padding: 10px;
75 max-height: 200px;
76 overflow-y: auto;
77 font-family: monospace;
78 font-size: 13px;
79 margin: 0;
80 white-space: pre-line;
81 }
82 </style>
83 <div class="wrap">
84 <h1><?php esc_html_e( 'Validazione', 'avcp' ); ?></h1>
85 <div class="notice notice-info" style="padding:20px;">
86 <?php esc_html_e( 'Nota: il controllo tecnico non attesta la correttezza dei dati.', 'avcp' ); ?><br>
87 <?php esc_html_e( 'Puoi controllare online i dataset con un', 'avcp' ); ?>
88 <a href="https://anac.softcare.it/Validator" target="_blank" rel="noopener"><?php esc_html_e( 'validatore esterno', 'avcp' ); ?></a>
89 <br><br>
90 <?php esc_html_e( "L'archivio dei documenti XML generati è disponibile qui:", 'avcp' ); ?>
91 <a href="<?php echo esc_url( $basexmlurl ); ?>" target="_blank" rel="noopener"><?php echo esc_html( $basexmlurl ); ?></a>
92 <br><br>
93 <strong><?php esc_html_e( 'Risorse utili:', 'avcp' ); ?></strong><br>
94 📖 <a href="<?php echo esc_url( 'https://github.com/WPGov/avcp/wiki' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Documentazione e Wiki', 'avcp' ); ?></a> |
95 💻 <a href="<?php echo esc_url( 'https://github.com/WPGov/avcp' ); ?>" target="_blank" rel="noopener"><?php esc_html_e( 'Repository GitHub', 'avcp' ); ?></a>
96 </div>
97
98 <div id="poststuff">
99 <div id="post-body" class="metabox-holder columns-2">
100 <div id="post-body-content">
101 <div class="meta-box-sortables">
102 <div class="inside">
103 <?php
104 // Check for posts without year (annirif) and collect them
105 $offending_posts = array();
106 $post_ids = get_posts( array(
107 'post_type' => 'avcp',
108 'posts_per_page' => -1,
109 'fields' => 'ids',
110 'post_status' => 'any',
111 ) );
112 if ( ! empty( $post_ids ) ) {
113 foreach ( $post_ids as $post_id ) {
114 if ( !has_term( '', 'annirif', $post_id ) ) {
115 $offending_posts[] = $post_id;
116 }
117 }
118 }
119 if ( count( $offending_posts ) > 0 ) {
120 $message = sprintf( esc_html__( 'Ci sono %d gare registrate senza anno di riferimento da correggere!', 'avcp' ), number_format_i18n( count( $offending_posts ) ) );
121 echo '<div class="notice notice-error"><p><strong>' . esc_html( $message ) . '</strong></p>';
122 echo '<ul style="margin:8px 0 12px 18px;">';
123 foreach ( $offending_posts as $id ) {
124 $title_esc = esc_html( get_the_title( $id ) );
125 if ( !$title_esc ) {
126 $title_esc = esc_html__( '(Nessun titolo)', 'avcp' );
127 }
128 echo '<li><a href="' . get_edit_post_link( $id ) . '">' . $title_esc . '</a></li>';
129 }
130 echo '</ul></div>';
131 }
132
133 $offending_ditte = array();
134 // Check for 'ditte' terms missing 'avcp_codice_fiscale' term meta and collect them
135 $ditte_terms = get_terms( array(
136 'taxonomy' => 'ditte',
137 'hide_empty' => false,
138 ) );
139 if ( ! is_wp_error( $ditte_terms ) && ! empty( $ditte_terms ) ) {
140 foreach ( $ditte_terms as $dterm ) {
141 $term_meta = get_option( "taxonomy_$dterm->term_id" );
142 $codice = ( is_array( $term_meta ) && isset( $term_meta['avcp_codice_fiscale'] ) ) ? $term_meta['avcp_codice_fiscale'] : '';
143 // Fallback: check term meta (standard WP storage)
144 if ( empty( $codice ) ) {
145 $codice = get_term_meta( $dterm->term_id, 'avcp_codice_fiscale', true );
146 }
147 if ( empty( $codice ) ) {
148 $offending_ditte[] = $dterm->term_id;
149 }
150 }
151 }
152 if ( ! empty( $offending_ditte ) && count( $offending_ditte ) > 0 ) {
153 $msg2 = sprintf( esc_html__( 'Ci sono %d ditte senza codice fiscale da correggere!', 'avcp' ), number_format_i18n( count( $offending_ditte) ) );
154 echo '<div class="notice notice-error"><p><strong>' . esc_html( $msg2 ) . '</strong></p>';
155 echo '<ul style="margin:8px 0 12px 18px;">';
156 foreach ( $offending_ditte as $id ) {
157 $name_esc = esc_html( get_term( $id )->name );
158 if ( !$name_esc ) {
159 $name_esc = esc_html__( '(Nessun nome)', 'avcp' );
160 }
161 $link_esc = esc_url( get_edit_term_link( $id, 'ditte' ) );
162 echo '<li><a href="' . $link_esc . '">' . $name_esc . '</a></li>';
163 }
164 echo '</ul></div>';
165 }
166 $terms = get_terms( 'annirif', array('hide_empty' => 0) );
167 ?>
168 <form method="post" style="overflow-x: auto;">
169 <?php wp_nonce_field( 'avcp_xmlgen_action', 'avcp_xmlgen_nonce' ); ?>
170 <table class="widefat striped">
171 <thead>
172 <tr>
173 <th><?php esc_html_e( 'Anno', 'avcp' ); ?></th>
174 <th><?php esc_html_e( 'Validazione XSD', 'avcp' ); ?> <span class="dashicons dashicons-info" title="<?php esc_attr_e( 'Verifica che il file xml sia tecnicamente corretto alle specifiche XSD', 'avcp' ); ?>"></span></th>
175 <th><?php esc_html_e( 'Versione XSD', 'avcp' ); ?></th>
176 <th><?php esc_html_e( 'Validazione software', 'avcp' ); ?> <span class="dashicons dashicons-info" title="<?php esc_attr_e( 'Verifiche aggiuntive del plugin WordPress per il controllo di alcuni campi, come ad esempio le date', 'avcp' ); ?>"></span></th>
177 <th><?php esc_html_e( 'Data generazione', 'avcp' ); ?></th>
178 <th><?php esc_html_e( 'Azione', 'avcp' ); ?></th>
179 </tr>
180 </thead>
181 <tbody>
182 <?php
183 foreach ( $terms as $term ) {
184 $file_exists = file_exists( avcp_get_basexmlpath( $term->name ) );
185 if ( ! $file_exists && $term->name < date('Y') - 2 ) {
186 continue;
187 }
188 echo '<tr>';
189 echo '<td>' . esc_html( $term->name ) . ' <a href="' . esc_url( avcp_get_basexmlurl( $term->name ) ) . '" target="_blank" title="' . esc_attr( $term->name ) . '"><span class="dashicons dashicons-external"></span></a></td>';
190
191 // XSD version
192 if ( $term->name >= 2021 ) {
193 $xsd_dir = '1_3';
194 $xsd_ver = 'v 1.3';
195 } elseif ( $term->name >= 2019 ) {
196 $xsd_dir = '1_1';
197 $xsd_ver = 'v 1.1';
198 } else {
199 $xsd_dir = '1_0';
200 $xsd_ver = 'v 1.0';
201 }
202
203 // XSD validation
204 echo '<td>';
205 $errors = false;
206 if ( $file_exists ) {
207 $xml = new DOMDocument();
208 $xml->load( avcp_get_basexmlpath( $term->name ) );
209 if ( $xml->schemaValidate( ABSPATH . '/wp-content/plugins/avcp/includes/XSD/' . $xsd_dir . '/datasetAppaltiL190.xsd' ) ) {
210 echo '<span class="dashicons dashicons-yes" title="' . esc_attr__( 'Corretto', 'avcp' ) . '"></span>';
211 } else {
212 echo '<span class="dashicons dashicons-dismiss" title="' . esc_attr__( 'Trovati errori', 'avcp' ) . '"></span>';
213 $errors = libxml_get_errors();
214 }
215 }
216 echo '</td>';
217
218 echo '<td>' . esc_html( $xsd_ver ) . '</td>';
219
220 // Software validation
221 echo '<td>';
222 if ( $file_exists ) {
223 $args = array(
224 'post_type' => 'avcp',
225 'tax_query' => array(
226 array(
227 'taxonomy' => 'annirif',
228 'field' => 'name',
229 'terms' => $term->name,
230 ),
231 ),
232 'posts_per_page' => -1,
233 );
234 $query = new WP_Query( $args );
235 $error = false;
236 if ( $query->have_posts() ) {
237 foreach ( $query->posts as $post ) {
238 $datainizio = get_post_meta( $post->ID, 'avcp_data_inizio', true );
239 $datafine = get_post_meta( $post->ID, 'avcp_data_fine', true );
240 if ( empty( $datainizio ) || empty( $datafine ) ) {
241 $error = true;
242 echo '<span class="notice-error" style="background-color:red;color:white;padding:2px;">' . esc_html__( 'Errore campo data', 'avcp' ) . '</span><br><a href="' . esc_url( get_edit_post_link( $post->ID ) ) . '">' . esc_html( get_the_title( $post->ID ) ) . '</a><hr>';
243 }
244 if ( strlen( get_the_title( $post->ID ) ) >= 250 ) {
245 $error = true;
246 echo '<span class="notice-error" style="background-color:red;color:white;padding:2px;">' . esc_html__( 'Titolo oltre 250 caratteri', 'avcp' ) . '</span><br><a href="' . esc_url( get_edit_post_link( $post->ID ) ) . '">' . esc_html( get_the_title( $post->ID ) ) . '</a><hr>';
247 }
248 }
249 }
250 if ( ! $error ) {
251 echo '<span class="dashicons dashicons-yes"></span>';
252 }
253 }
254 echo '</td>';
255
256 // Generation date
257 echo '<td>' . ( $file_exists && filemtime( avcp_get_basexmlpath( $term->name ) ) ? esc_html( date( "d/m/Y H:i", filemtime( avcp_get_basexmlpath( $term->name ) ) ) ) : '-' ) . '</td>';
258
259 // Action
260 echo '<td>';
261 if ( $term->name >= date('Y') - 2 ) {
262 echo '<input type="submit" class="button button-primary" name="XMLGEN_' . esc_attr( $term->name ) . '" value="' . esc_attr__( 'Genera', 'avcp' ) . '" />';
263 }
264 echo '</td>';
265 echo '</tr>';
266
267 // XSD errors
268 if ( $errors ) {
269 echo '<tr><td colspan="6">';
270 foreach ( $errors as $err ) {
271 print esc_html( libxml_display_error( $err ) );
272 }
273 libxml_clear_errors();
274 echo '</td></tr>';
275 }
276 }
277 ?>
278 </tbody>
279 </table>
280 </form>
281 </div>
282 </div>
283 </div>
284 <!-- Sidebar -->
285 <div id="postbox-container-1" class="postbox-container">
286 <div class="meta-box-sortables">
287 <div class="postbox">
288 <h2><span><?php esc_html_e( 'Stato server', 'avcp' ); ?></span></h2>
289 <div class="inside">
290 <p>
291 <?php
292 $dir = avcp_get_basexmlpath();
293 $file = $dir . '/index.php';
294 $system_ok = true;
295 if ( is_dir( $dir ) ) {
296 echo esc_html__( 'Presenza cartella /avcp', 'avcp' ) . '<span style="color:green;font-weight:bold;">: OK</span>';
297 } else {
298 echo esc_html__( 'Presenza cartella /avcp', 'avcp' ) . '<span style="color:red;font-weight:bold;">: NON TROVATA</span>';
299 $system_ok = false;
300 }
301 echo '<br/>';
302 if ( is_writable( $dir ) ) {
303 echo esc_html__( 'Permessi scrittura cartella /avcp', 'avcp' ) . '<span style="color:green;font-weight:bold;">: OK</span>';
304 } else {
305 echo esc_html__( 'Permessi scrittura cartella /avcp', 'avcp' ) . '<span style="color:red;font-weight:bold;">: NON CORRISPONDENTI</span>';
306 $system_ok = false;
307 }
308 echo '<br/>';
309 if ( file_exists( $file ) ) {
310 echo esc_html__( 'Presenza index.php /avcp', 'avcp' ) . '<span style="color:green;font-weight:bold;">: OK</span>';
311 } else {
312 echo esc_html__( 'Presenza index.php /avcp', 'avcp' ) . '<span style="color:red;font-weight:bold;">: NON TROVATO</span>';
313 $system_ok = false;
314 }
315 echo '<br/>';
316
317 $urlcheck = get_site_url() . '/avcp/index.php';
318 $agent = "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; pt-pt) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27";
319 if ( is_callable( 'curl_init' ) ) {
320 $ch = curl_init();
321 curl_setopt( $ch, CURLOPT_URL, $urlcheck );
322 curl_setopt( $ch, CURLOPT_USERAGENT, $agent );
323 curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
324 curl_setopt( $ch, CURLOPT_VERBOSE, false );
325 curl_setopt( $ch, CURLOPT_TIMEOUT, 5 );
326 curl_exec( $ch );
327 $httpcode = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
328 curl_close( $ch );
329 if ( $httpcode == 200 ) {
330 echo esc_html__( 'Test Accesso pubblico /avcp', 'avcp' ) . '<span style="color:green;font-weight:bold;">: OK [200]</span>';
331 } elseif ( $httpcode == 500 ) {
332 echo esc_html__( 'Test Accesso pubblico /avcp', 'avcp' ) . '<span style="color:red;font-weight:bold;">: ERRORE 500 ISE</span>';
333 $headers = @get_headers( $urlcheck );
334 echo ' - ' . esc_html( @$headers[0] );
335 $system_ok = false;
336 } else {
337 echo esc_html__( 'Test Accesso pubblico /avcp', 'avcp' ) . '<span style="color:red;font-weight:bold;">: ERRORE ' . esc_html( $httpcode ) . '</span>';
338 $headers = @get_headers( $urlcheck );
339 echo ' - ' . esc_html( @$headers[0] );
340 $system_ok = false;
341 }
342 } else {
343 echo esc_html__( 'Test Accesso pubblico /avcp', 'avcp' ) . '<span style="color:red;font-weight:bold;">: CURL_INIT MANCANTE</span>';
344 $system_ok = false;
345 }
346 if ( $system_ok ) {
347 echo '<hr><center>' . esc_html__( 'Nessun problema trovato.', 'avcp' ) . '</center>';
348 } else {
349 echo '<div class="notice notice-error"><p>' . esc_html__( 'Sono stati trovati alcuni problemi critici. Affinchè AVCP funzioni correttamente è necessario risolvere al più presto questi problemi.', 'avcp' ) . '</p></div>';
350 }
351 ?>
352 </p>
353 </div>
354 </div>
355 </div>
356 <div class="meta-box-sortables">
357 <div class="postbox">
358 <h2>
359 <form method="post" style="display:inline;">
360 <?php wp_nonce_field( 'avcp_reset_log_action', 'avcp_reset_log_nonce' ); ?>
361 <input type="submit" class="button button-primary" name="AVCP-RESET-LOG" value="<?php esc_attr_e( 'Pulisci', 'avcp' ); ?>" style="float:right;" />
362 </form>
363 <?php esc_html_e( 'Log', 'avcp' ); ?>
364 </h2>
365 <div class="inside">
366 <?php
367 $log = get_option( 'anac_log' );
368 if ( ! empty( $log ) ) {
369 // Show log as HTML, allowing only safe tags (b, strong, em, a, br)
370 $allowed_tags = array(
371 'b' => array(),
372 'strong' => array(),
373 'em' => array(),
374 'a' => array(
375 'href' => array(),
376 'title' => array(),
377 'target' => array(),
378 'rel' => array(),
379 ),
380 'br' => array(),
381 );
382 echo '<div class="avcp-log-list">' . wp_kses( $log, $allowed_tags ) . '</div>';
383 } else {
384 echo '<div class="avcp-log-list">' . esc_html__( 'Nessun log presente.', 'avcp' ) . '</div>';
385 }
386 ?>
387 </div>
388 </div>
389 </div>
390 </div>
391 <!-- #postbox-container-1 .postbox-container -->
392 </div>
393 <!-- #post-body .metabox-holder .columns-2 -->
394 <br class="clear">
395 </div>
396 <!-- #poststuff -->
397 </div>
398 <?php
399 }
400
401 function libxml_display_error( $error ) {
402 $return = "\n";
403 switch ( $error->level ) {
404 case LIBXML_ERR_WARNING:
405 $return .= "Warning $error->code: ";
406 break;
407 case LIBXML_ERR_ERROR:
408 $return .= "Error $error->code: ";
409 break;
410 case LIBXML_ERR_FATAL:
411 $return .= "Fatal Error $error->code: ";
412 break;
413 }
414 $return .= trim( $error->message );
415 if ( $error->file ) {
416 $return .= " in $error->file";
417 }
418 $return .= " on line $error->line";
419 return $return;
420 }
421
422 // Enable user error handling
423 libxml_use_internal_errors( true );
424 ?>
425