basename = $plugin;
// Register general hooks.
add_action( 'init', array( $this, 'load_translations' ) ); // must run before admin_menu
add_action( 'admin_init', array( $this, 'admin_init' ) );
add_action( 'admin_menu', array( $this, 'admin_menu' ) );
}
function load_translations() {
// Load any translation files needed:
load_plugin_textdomain( 'add-from-server' );
}
function admin_init() {
// Register our JS & CSS
wp_register_style( 'add-from-server', plugins_url( '/add-from-server.css', __FILE__ ), array(), $this->version );
// Enqueue JS & CSS
add_action( 'load-media_page_add-from-server', array( $this, 'add_styles' ) );
add_action( 'media_upload_server', array( $this, 'add_styles' ) );
add_filter( 'plugin_action_links_' . $this->basename, array( $this, 'add_configure_link' ) );
if ( $this->user_allowed() ) {
// Add actions/filters
add_filter( 'media_upload_tabs', array( $this, 'tabs' ) );
add_action( 'media_upload_server', array( $this, 'tab_handler' ) );
}
// Register our settings:
register_setting( 'add_from_server', 'frmsvr_root', array( $this, 'sanitize_option_root' ) );
// register_setting('add-from-server', 'frmsvr_last_folder');
register_setting( 'add_from_server', 'frmsvr_uac' );
register_setting( 'add_from_server', 'frmsvr_uac_users' );
register_setting( 'add_from_server', 'frmsvr_uac_role' );
}
function admin_menu() {
if ( $this->user_allowed() ) {
add_media_page( __( 'Add From Server', 'add-from-server' ), __( 'Add From Server', 'add-from-server' ), 'read', 'add-from-server', array( $this, 'menu_page' ) );
}
add_options_page( __( 'Add From Server', 'add-from-server' ), __( 'Add From Server', 'add-from-server' ), 'manage_options', 'add-from-server-settings', array( $this, 'options_page' ) );
}
function add_configure_link( $_links ) {
$links = array();
if ( $this->user_allowed() ) {
$links[] = '' . __( 'Import Files', 'add-from-server' ) . '';
}
if ( current_user_can( 'manage_options' ) ) {
$links[] = '' . __( 'Options', 'add-from-server' ) . '';
}
return array_merge( $links, $_links );
}
// Add a tab to the media uploader:
function tabs( $tabs ) {
if ( $this->user_allowed() ) {
$tabs['server'] = __( 'Add From Server', 'add-from-server' );
}
return $tabs;
}
function add_styles() {
// Enqueue support files.
if ( 'media_upload_server' == current_filter() ) {
wp_enqueue_style( 'media' );
}
wp_enqueue_style( 'add-from-server' );
}
// Handle the actual page:
function tab_handler() {
global $body_id;
if ( !$this->user_allowed() ) {
return;
}
$body_id = 'media-upload';
iframe_header( __( 'Add From Server', 'add-from-server' ) );
$this->handle_imports();
$this->main_content();
iframe_footer();
}
function menu_page() {
if ( !$this->user_allowed() ) {
return;
}
// Handle any imports:
$this->handle_imports();
echo '
';
echo '
' . __( 'Add From Server', 'add-from-server' ) . '
';
$this->main_content();
echo '';
}
function options_page() {
if ( !current_user_can( 'manage_options' ) ) {
return;
}
include __DIR__ . '/class.add-from-server-settings.php';
$settings = new Add_From_Server_Settings( $this );
$settings->render();
}
function get_root( $context = 'use' ) {
static $static_root = null;
if ( $static_root )
return $static_root;
$root = get_option( 'frmsvr_root', false );
if ( strpos( $root, '%' ) !== false && 'raw' != $context ) {
$user = wp_get_current_user();
$root = str_replace( '%username%', $user->user_login, $root );
$root = str_replace( '%role%', $user->roles[0], $root );
}
if ( ! $root ) {
if ( '/' == substr( __FILE__, 0, 1 ) ) {
$root = '/';
} elseif ( preg_match( '!^[a-zA-Z]:!', __FILE__, $root_win_match ) ) {
$root = $root_win_match[1];
}
}
if ( strlen( $root ) > 1 ) {
$root = untrailingslashit( $root );
}
return $root;
}
function user_allowed() {
if ( !current_user_can( 'upload_files' ) ) {
return false;
}
switch ( get_option( 'frmsvr_uac', 'allusers' ) ) {
default:
case 'allusers':
return true;
case 'role':
$user = wp_get_current_user();
$roles = $user->roles;
$allowed_roles = get_option( 'frmsvr_uac_role', array() );
foreach ( $roles as $r ) {
if ( in_array( $r, $allowed_roles ) )
return true;
}
return false;
case 'listusers':
$user = wp_get_current_user();
$allowed_users = explode( "\n", get_option( 'frmsvr_uac_users', '' ) );
$allowed_users = array_map( 'trim', $allowed_users );
$allowed_users = array_filter( $allowed_users );
return in_array( $user->user_login, $allowed_users );
}
return false;
}
function sanitize_option_root($input) {
$_input = $input;
if ( 'specific' == $input ) {
$input = wp_unslash( $_POST['frmsvr_root-specified'] );
}
if ( !$this->validate_option_root( $input ) ) {
$input = get_option( 'frmsvr_root' );
}
// WP < 4.4 Compat: ucfirt
$input = ucfirst( wp_normalize_path( $input ) );
return $input;
}
function validate_option_root($o) {
if ( strpos( $o, '%' ) !== false ) {
// Ensure only valid placeholders are used:
if ( preg_match_all( '!%(.*?)%!', $o, $placeholders ) ) {
$valid_ph = array( 'username', 'role' );
foreach ( $placeholders[1] as $ph ) {
if ( !in_array( $ph, $valid_ph ) ) {
add_settings_error( 'general', 'update_failed', sprintf( __( 'The placeholder %s is not valid in the root path.', 'add-from-server' ), '%' . $ph . '%' ), 'error' );
return false;
}
}
return true;
}
}
if ( !is_dir( $o ) || !is_readable( $o ) ) {
add_settings_error( 'general', 'update_failed', __( 'The root path specified could not be read.', 'add-from-server' ), 'error' );
return false;
}
return true;
}
// Handle the imports
function handle_imports() {
if ( !empty($_POST['files']) && !empty($_POST['cwd']) ) {
check_admin_referer( 'afs_import' );
$files = wp_unslash( $_POST['files'] );
$cwd = trailingslashit( wp_unslash( $_POST['cwd'] ) );
if ( false === strpos( $cwd, $this->get_root() ) ) {
return;
}
$post_id = isset($_REQUEST['post_id']) ? absint( $_REQUEST['post_id'] ) : 0;
$import_date = isset($_REQUEST['import-date']) ? $_REQUEST['import-date'] : 'current';
$import_to_gallery = isset($_POST['gallery']) && 'on' == $_POST['gallery'];
if ( !$import_to_gallery && !isset($_REQUEST['cwd']) ) {
$import_to_gallery = true; // cwd should always be set, if it's not, and neither is gallery, this must be the first page load.
}
if ( !$import_to_gallery ) {
$post_id = 0;
}
flush();
wp_ob_end_flush_all();
foreach ( (array)$files as $file ) {
$filename = $cwd . $file;
$id = $this->handle_import_file( $filename, $post_id, $import_date );
if ( is_wp_error( $id ) ) {
echo '' . sprintf( __( '%s was not imported due to an error: %s', 'add-from-server' ), esc_html( $file ), $id->get_error_message() ) . '
';
} else {
echo '' . sprintf( __( '%s has been added to Media library', 'add-from-server' ), esc_html( $file ) ) . '
';
}
flush();
wp_ob_end_flush_all();
}
}
}
// Handle an individual file import.
function handle_import_file( $file, $post_id = 0, $import_date = 'current' ) {
set_time_limit( 0 );
// Initially, Base it on the -current- time.
$time = current_time( 'mysql', 1 );
// Next, If it's post to base the upload off:
if ( 'post' == $import_date && $post_id > 0 ) {
$post = get_post( $post_id );
if ( $post && substr( $post->post_date_gmt, 0, 4 ) > 0 ) {
$time = $post->post_date_gmt;
}
} elseif ( 'file' == $import_date ) {
$time = gmdate( 'Y-m-d H:i:s', @filemtime( $file ) );
}
// A writable uploads dir will pass this test. Again, there's no point overriding this one.
if ( !(($uploads = wp_upload_dir( $time )) && false === $uploads['error']) ) {
return new WP_Error( 'upload_error', $uploads['error'] );
}
$wp_filetype = wp_check_filetype( $file, null );
extract( $wp_filetype );
if ( (!$type || !$ext) && !current_user_can( 'unfiltered_upload' ) ) {
return new WP_Error( 'wrong_file_type', __( 'Sorry, this file type is not permitted for security reasons.', 'add-from-server' ) );
}
// Is the file allready in the uploads folder?
// WP < 4.4 Compat: ucfirt
if ( preg_match( '|^' . preg_quote( ucfirst( wp_normalize_path( $uploads['basedir'] ) ), '|' ) . '(.*)$|i', $file, $mat ) ) {
$filename = basename( $file );
$new_file = $file;
$url = $uploads['baseurl'] . $mat[1];
$attachment = get_posts( array( 'post_type' => 'attachment', 'meta_key' => '_wp_attached_file', 'meta_value' => ltrim( $mat[1], '/' ) ) );
if ( !empty($attachment) ) {
return new WP_Error( 'file_exists', __( 'Sorry, That file already exists in the WordPress media library.', 'add-from-server' ) );
}
// Ok, Its in the uploads folder, But NOT in WordPress's media library.
if ( 'file' == $import_date ) {
$time = @filemtime( $file );
if ( preg_match( "|(\d+)/(\d+)|", $mat[1], $datemat ) ) { // So lets set the date of the import to the date folder its in, IF its in a date folder.
$hour = $min = $sec = 0;
$day = 1;
$year = $datemat[1];
$month = $datemat[2];
// If the files datetime is set, and it's in the same region of upload directory, set the minute details to that too, else, override it.
if ( $time && date( 'Y-m', $time ) == "$year-$month" ) {
list($hour, $min, $sec, $day) = explode( ';', date( 'H;i;s;j', $time ) );
}
$time = mktime( $hour, $min, $sec, $month, $day, $year );
}
$time = gmdate( 'Y-m-d H:i:s', $time );
// A new time has been found! Get the new uploads folder:
// A writable uploads dir will pass this test. Again, there's no point overriding this one.
if ( !(($uploads = wp_upload_dir( $time )) && false === $uploads['error']) ) {
return new WP_Error( 'upload_error', $uploads['error'] );
}
$url = $uploads['baseurl'] . $mat[1];
}
} else {
$filename = wp_unique_filename( $uploads['path'], basename( $file ) );
// copy the file to the uploads dir
$new_file = $uploads['path'] . '/' . $filename;
if ( false === @copy( $file, $new_file ) )
return new WP_Error( 'upload_error', sprintf( __( 'The selected file could not be copied to %s.', 'add-from-server' ), $uploads['path'] ) );
// Set correct file permissions
$stat = stat( dirname( $new_file ) );
$perms = $stat['mode'] & 0000666;
@ chmod( $new_file, $perms );
// Compute the URL
$url = $uploads['url'] . '/' . $filename;
if ( 'file' == $import_date ) {
$time = gmdate( 'Y-m-d H:i:s', @filemtime( $file ) );
}
}
// Apply upload filters
$return = apply_filters( 'wp_handle_upload', array( 'file' => $new_file, 'url' => $url, 'type' => $type ) );
$new_file = $return['file'];
$url = $return['url'];
$type = $return['type'];
$title = preg_replace( '!\.[^.]+$!', '', basename( $file ) );
$content = $excerpt = '';
if ( preg_match( '#^audio#', $type ) ) {
$meta = wp_read_audio_metadata( $new_file );
if ( ! empty( $meta['title'] ) ) {
$title = $meta['title'];
}
if ( ! empty( $title ) ) {
if ( ! empty( $meta['album'] ) && ! empty( $meta['artist'] ) ) {
/* translators: 1: audio track title, 2: album title, 3: artist name */
$content .= sprintf( __( '"%1$s" from %2$s by %3$s.', 'add-from-server' ), $title, $meta['album'], $meta['artist'] );
} elseif ( ! empty( $meta['album'] ) ) {
/* translators: 1: audio track title, 2: album title */
$content .= sprintf( __( '"%1$s" from %2$s.', 'add-from-server' ), $title, $meta['album'] );
} elseif ( ! empty( $meta['artist'] ) ) {
/* translators: 1: audio track title, 2: artist name */
$content .= sprintf( __( '"%1$s" by %2$s.', 'add-from-server' ), $title, $meta['artist'] );
} else {
$content .= sprintf( __( '"%s".', 'add-from-server' ), $title );
}
} elseif ( ! empty( $meta['album'] ) ) {
if ( ! empty( $meta['artist'] ) ) {
/* translators: 1: audio album title, 2: artist name */
$content .= sprintf( __( '%1$s by %2$s.', 'add-from-server' ), $meta['album'], $meta['artist'] );
} else {
$content .= $meta['album'] . '.';
}
} elseif ( ! empty( $meta['artist'] ) ) {
$content .= $meta['artist'] . '.';
}
if ( ! empty( $meta['year'] ) )
$content .= ' ' . sprintf( __( 'Released: %d.' ), $meta['year'] );
if ( ! empty( $meta['track_number'] ) ) {
$track_number = explode( '/', $meta['track_number'] );
if ( isset( $track_number[1] ) )
$content .= ' ' . sprintf( __( 'Track %1$s of %2$s.', 'add-from-server' ), number_format_i18n( $track_number[0] ), number_format_i18n( $track_number[1] ) );
else
$content .= ' ' . sprintf( __( 'Track %1$s.', 'add-from-server' ), number_format_i18n( $track_number[0] ) );
}
if ( ! empty( $meta['genre'] ) )
$content .= ' ' . sprintf( __( 'Genre: %s.', 'add-from-server' ), $meta['genre'] );
// Use image exif/iptc data for title and caption defaults if possible.
} elseif ( 0 === strpos( $type, 'image/' ) && $image_meta = @wp_read_image_metadata( $new_file ) ) {
if ( trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) {
$title = $image_meta['title'];
}
if ( trim( $image_meta['caption'] ) ) {
$excerpt = $image_meta['caption'];
}
}
if ( $time ) {
$post_date_gmt = $time;
$post_date = $time;
} else {
$post_date = current_time( 'mysql' );
$post_date_gmt = current_time( 'mysql', 1 );
}
// Construct the attachment array
$attachment = array(
'post_mime_type' => $type,
'guid' => $url,
'post_parent' => $post_id,
'post_title' => $title,
'post_name' => $title,
'post_content' => $content,
'post_excerpt' => $excerpt,
'post_date' => $post_date,
'post_date_gmt' => $post_date_gmt
);
$attachment = apply_filters( 'afs-import_details', $attachment, $file, $post_id, $import_date );
// WP < 4.4 Compat: ucfirt
$new_file = str_replace( ucfirst( wp_normalize_path( $uploads['basedir'] ) ), $uploads['basedir'], $new_file );
// Save the data
$id = wp_insert_attachment( $attachment, $new_file, $post_id );
if ( !is_wp_error( $id ) ) {
$data = wp_generate_attachment_metadata( $id, $new_file );
wp_update_attachment_metadata( $id, $data );
}
// update_post_meta( $id, '_wp_attached_file', $uploads['subdir'] . '/' . $filename );
return $id;
}
// Create the content for the page
function main_content() {
global $pagenow;
$post_id = isset($_REQUEST['post_id']) ? intval( $_REQUEST['post_id'] ) : 0;
$import_to_gallery = isset($_POST['gallery']) && 'on' == $_POST['gallery'];
if ( !$import_to_gallery && !isset($_REQUEST['cwd']) ) {
$import_to_gallery = true; // cwd should always be set, if it's not, and neither is gallery, this must be the first page load.
}
$import_date = isset($_REQUEST['import-date']) ? $_REQUEST['import-date'] : 'current';
if ( 'upload.php' == $pagenow ) {
$url = admin_url( 'upload.php?page=add-from-server' );
} else {
$url = admin_url( 'media-upload.php?tab=server' );
}
if ( $post_id ) {
$url = add_query_arg( 'post_id', $post_id, $url );
}
$cwd = trailingslashit( get_option( 'frmsvr_last_folder' ) ?: WP_CONTENT_DIR );
if ( isset($_REQUEST['directory']) ) {
$cwd .= stripslashes( urldecode( $_REQUEST['directory'] ) );
}
if ( isset($_REQUEST['adirectory']) && empty($_REQUEST['adirectory']) ) {
$_REQUEST['adirectory'] = '/'; // For good measure.
}
if ( isset($_REQUEST['adirectory']) ) {
$cwd = stripslashes( urldecode( $_REQUEST['adirectory'] ) );
}
$cwd = preg_replace( '![^/]*/\.\./!', '', $cwd );
$cwd = preg_replace( '!//!', '/', $cwd );
if ( !is_readable( $cwd ) && is_readable( $this->get_root() . '/' . ltrim( $cwd, '/' ) ) ) {
$cwd = $this->get_root() . '/' . ltrim( $cwd, '/' );
}
if ( !is_readable( $cwd ) && get_option( 'frmsvr_last_folder' ) ) {
$cwd = get_option( 'frmsvr_last_folder' );
}
if ( !is_readable( $cwd ) ) {
$cwd = WP_CONTENT_DIR;
}
if ( strpos( $cwd, $this->get_root() ) === false ) {
$cwd = $this->get_root();
}
// WP < 4.4 Compat: ucfirt
$cwd = ucfirst( wp_normalize_path( $cwd ) );
if ( strlen( $cwd ) > 1 ) {
$cwd = untrailingslashit( $cwd );
}
if ( !is_readable( $cwd ) ) {
echo '' . __( 'Error: This users root directory is not readable. Please have your site administrator correct the Add From Server root directory settings.', 'add-from-server' ) . '
';
return;
}
update_option( 'frmsvr_last_folder', $cwd );
$files = $this->find_files( $cwd );
$parts = explode( '/', ltrim( str_replace( $this->get_root(), '/', $cwd ), '/' ) );
if ( $parts[0] != '' ) {
$parts = array_merge( (array)'', $parts );
}
// array_walk() + eAccelerator + anonymous function = bad news
foreach ( $parts as $index => &$item ) {
$this_path = implode( '/', array_slice( $parts, 0, $index + 1 ) );
$this_path = ltrim( $this_path, '/' ) ?: '/';
$item_url = add_query_arg( array( 'adirectory' => $this_path ), $url );
if ( $index == count( $parts ) - 1 ) {
$item = esc_html( $item ) . '/';
} else {
$item = sprintf( '%s/', esc_url( $item_url ), esc_html( $item ) );
}
}
$dirparts = implode( '', $parts );
?>
get_root() ) === false )
continue;
$adir = preg_replace( '!^' . preg_quote( $this->get_root(), '!' ) . '!i', '', $adir );
if ( strlen( $adir ) > 1 ) {
$adir = ltrim( $adir, '/' );
}
$durl = add_query_arg( array( 'adirectory' => rawurlencode( $adir ) ), $url );
$pieces[] = sprintf( '%s', esc_url( $durl ), esc_html( $text ) );
}
if ( !empty( $pieces ) ) {
printf( '' . __( 'Quick Jump: %s', 'add-from-server' ) . '
', implode( ' | ', $pieces ) );
}
}
function find_files( $folder ) {
if ( !is_readable( $folder ) ) {
return array();
}
return glob( rtrim( $folder, '/' ) . '/*' );
}
function language_notice( $force = false ) {
$message_english = 'Hi there!
I notice you use WordPress in a Language other than English (US), Did you know you can translate WordPress Plugins into your native language as well?
If you\'d like to help out with translating this plugin into %1$s you can head over to translate.WordPress.org and suggest translations for any languages which you know.
Thanks! Dion.';
/* translators: %1$s = The Locale (de_DE, en_US, fr_FR, he_IL, etc). %2$s = The translate.wordpress.org link to the plugin overview */
$message = __( 'Hi there!
I notice you use WordPress in a Language other than English (US), Did you know you can translate WordPress Plugins into your native language as well?
If you\'d like to help out with translating this plugin into %1$s you can head over to translate.WordPress.org and suggest translations for any languages which you know.
Thanks! Dion.', 'add-from-server' );
$locale = get_locale();
if ( function_exists( 'get_user_locale' ) ) {
$locale = get_user_locale();
}
// Don't display the message for English (Any) or what we'll assume to be fully translated localised builds.
if ( 'en_' === substr( $locale, 0, 3 ) || ( $message != $message_english && ! $force ) ) {
return false;
}
$translate_url = 'https://translate.wordpress.org/projects/wp-plugins/add-from-server/stable';
echo '
' . sprintf( nl2br( $message ), get_locale(), $translate_url ) . '
';
}
}