Aggiungere media privati su Wordpress
La procedura descritta è stata soppiantata dal plugin Customer Area
Per un sito da realizzare con Wordpress (su versione 3.9) mi è stata chiesta la possibilità di caricare e linkare alle pagine dei file multimediali protetti da password. Di per sé il CMS offre la possibilità di proteggere alcune pagine, ma non gli allegati stessi, per cui può accedervi chiunque abbia il link.
Dopo una breve ricerca su Google, la soluzione più accreditata pare essere caricare i file privati in una directory protetta con un file .htaccess, questo comporta il dover caricare i file manualmente sullo spazio web, il che non è molto comodo per chi non ha esperienza. Quindi ho pensato di modificare le pagine di upload di Wordpress per consentire
- una scelta grafica al momento del caricamento (il file dovrà essere pubblico o privato?);
- il caricamento nella directory di default se pubblico, o nella directory protetta se privato.
Modificare i files
Nello schema si vedono i file usati nell'operazione di salvataggio (le righe in rosso sono quelle da inserire); la pagina di caricamento è media-new.php, che comprende un form con i pulsanti Aggiungi file e Caricare. Quando si clicca su Caricare la pagina riceve le informazioni, cerca la cartella dove deve caricare i file e li salva. Per aggiungere la richiesta Pubblico/Privato bisogna modificare 3 di questi file, aggiungendo le parti evidenziate in rosso:
functions.php - wp_upload_dir()
function wp_upload_dir( $time = null , $private = false) { $siteurl = get_option( 'siteurl' ); $upload_path = trim( get_option( 'upload_path' ) ); if ( empty( $upload_path ) || 'wp-content/uploads' == $upload_path ) { $dir = WP_CONTENT_DIR . '/uploads'; } elseif ( 0 !== strpos( $upload_path, ABSPATH ) ) { // $dir is absolute, $upload_path is (maybe) relative to ABSPATH $dir = path_join( ABSPATH, $upload_path ); } else { $dir = $upload_path; } if ( !$url = get_option( 'upload_url_path' ) ) { if ( empty($upload_path) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) ) $url = WP_CONTENT_URL . '/uploads'; else $url = trailingslashit( $siteurl ) . $upload_path; } // Se è stato richiesto un upload privato varia la cartella // di salvataggio da /uploads a /uploads/privati if ($private === true) { $dir .= '/privati'; $url .= '/privati'; } [...]
}
media.php - media_upload_form()
[...]
<div id="html-upload-ui" class="hide-if-js">
<?php do_action('pre-html-upload-ui'); ?>
<p id="async-upload-wrap">
<label class="screen-reader-text" for="async-upload"><?php _e('Upload'); ?></label>
<input type="file" name="async-upload" id="async-upload" />
<!-- Bottoni caricamento privato -->
<input type="radio" name="private" value="public" checked /> Pubblico
<input type="radio" name="private" value="private"/> Privato
<?php submit_button( __( 'Upload' ), 'button', 'html-upload', false ); ?>
<a href="#" onclick="try{top.tb_remove();}catch(e){}; return false;"><?php _e('Cancel'); ?></a>
</p>
<div class="clear"></div>
<?php do_action('post-html-upload-ui'); ?>
</div>
[...]
file.php - wp_handle_upload()
function wp_handle_upload( &$file, $overrides = false, $time = null ) { // Controlla se è stato richiesto un upload privato if (isset($_POST['private'])) { if ($_POST['private'] === 'private') { $private = true; } else $private = false; } [...] // A writable uploads dir will pass this test. Again, there's no point overriding this one. if ( ! ( ( $uploads = wp_upload_dir($time, $private) ) && false === $uploads['error'] ) ) return call_user_func($upload_error_handler, $file, $uploads['error'] ); $filename = wp_unique_filename( $uploads['path'], $file['name'], $unique_filename_callback ); [...] }
Proteggere la cartella
Per proteggere la cartella bisogna creare un file .htaccess e .htpasswd al suo interno, uno contentente le informazioni per bloccare la pagina, e l'altro l'utente e la password:
.htaccess
AuthType Basic
AuthName reserved_area
AuthUserFile /var/www/wp-content/uploads/privati/.htpasswd
require valid-user
Nella riga AuthUserFile va scritto il percorso completo del file .htpasswd.
.htpasswd
La password criptata può essere generata da uno script web, ecco un esempio:
pippo:$apr1$XLL6VY2D$Ak7kgpy0EVIQDl2dqoGXm.