Attachments Pro is Attachments' big brother. With it come a number of often-requested features such as:
Multiple Attachments instances on edit screens
Customizable field labels and meta box title
Unlimited number of fields per Attachment
Ability to define rules limiting the availability of Attachments on edit screens
Limit the number of Attachments that can be added
Limit Attach-able Media items by file/mime type
Shortcode support
Auto-inclusion of Attachments content within the_content()
Attachments has always been and will always be free. Attachments Pro is available now. To find out more about the new features already added, and to stay up-to-date on what's to come, have a look at the details. From there, you can make formal support and feature requests.
$b )
{
return 1;
}
else
{
return 0;
}
}
/**
* Creates the markup for the WordPress admin options page
*
* @return void
* @author Jonathan Christopher
*/
function attachments_options()
{
include 'attachments.options.php';
}
/**
* Creates the entry for Attachments Options under Settings in the WordPress Admin
*
* @return void
* @author Jonathan Christopher
*/
function attachments_menu()
{
add_options_page('Settings', 'Attachments', 'manage_options', __FILE__, 'attachments_options');
}
/**
* Inserts HTML for meta box, including all existing attachments
*
* @return void
* @author Jonathan Christopher
*/
function attachments_add()
{?>
true,
'show_ui' => true
);
$output = 'objects';
$operator = 'and';
$post_types = get_post_types( $args, $output, $operator );
foreach($post_types as $post_type)
{
if( isset( $settings['post_types'][$post_type->name] ) && $settings['post_types'][$post_type->name] )
{
add_meta_box( 'attachments_list', __( 'Attachments', 'attachments' ), 'attachments_add', $post_type->name, 'normal' );
}
}
}
}
/**
* Echos JavaScript that sets some required global variables
*
* @return void
* @author Jonathan Christopher
*/
function attachments_init_js()
{
echo '';
}
/**
* Fired when Post or Page is saved. Serializes all attachment data and saves to post_meta
*
* @param int $post_id The ID of the current post
* @return void
* @author Jonathan Christopher
* @author JR Tashjian
*/
function attachments_save($post_id)
{
// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times
if( !isset( $_POST['attachments_nonce'] ) )
{
return $post_id;
}
if( !wp_verify_nonce( $_POST['attachments_nonce'], plugin_basename(__FILE__) ) )
{
return $post_id;
}
// verify if this is an auto save routine. If it is our form has not been submitted, so we dont want
// to do anything
if( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE )
{
return $post_id;
}
// Check permissions
if( 'page' == $_POST['post_type'] )
{
if( !current_user_can( 'edit_page', $post_id ) )
{
return $post_id;
}
}
else
{
if( !current_user_can( 'edit_post', $post_id ) )
{
return $post_id;
}
}
// OK, we're authenticated: we need to find and save the data
// delete all current attachments meta
// moved outside conditional, else we can never delete all attachments
delete_post_meta( $post_id, '_attachments' );
// Since we're allowing Attachments to be sortable, we can't simply increment a counter
// we need to keep track of the IDs we're given
$attachment_ids = array();
// We'll build our array of attachments
foreach( $_POST as $key => $data )
{
// Arbitrarily using the id
if( substr($key, 0, 14) == 'attachment_id_' )
{
array_push( $attachment_ids, substr( $key, 14, strlen( $key ) ) );
}
}
// If we have attachments, there's work to do
if( !empty( $attachment_ids ) )
{
foreach ( $attachment_ids as $i )
{
if( !empty( $_POST['attachment_id_' . $i] ) )
{
$attachment_id = intval( $_POST['attachment_id_' . $i] );
$attachment_details = array(
'id' => $attachment_id,
'title' => str_replace( '"', '"', $_POST['attachment_title_' . $i] ),
'caption' => str_replace( '"', '"', $_POST['attachment_caption_' . $i] ),
'order' => intval( $_POST['attachment_order_' . $i] )
);
// serialize data and encode
$attachment_serialized = base64_encode( serialize( $attachment_details ) );
// add individual attachment
add_post_meta( $post_id, '_attachments', $attachment_serialized );
// save native Attach
$settings = get_option( ATTACHMENTS_PREFIX . 'settings' );
if( isset( $settings['post_parent'] ) && $settings['post_parent'] )
{
// need to first check to make sure we're not overwriting a native Attach
$attach_post_ref = get_post( $attachment_id );
if( $attach_post_ref->post_parent == 0 )
{
// no current Attach, we can add ours
$attach_post = array();
$attach_post['ID'] = $attachment_id;
$attach_post['post_parent'] = $post_id;
wp_update_post( $attach_post );
}
}
}
}
}
}
/**
* Returns a formatted filesize
*
* @param string $path Path to file on disk
* @return string $formatted formatted filesize
* @author Jonathan Christopher
*/
function attachments_get_filesize_formatted( $path = NULL )
{
global $units;
$formatted = '0 bytes';
if( file_exists( $path ) )
{
$bytes = intval( filesize( $path ) );
$s = $units;
$e = floor( log( $bytes ) / log( 1024 ) );
$formatted = sprintf( '%.2f ' . $s[$e], ( $bytes / pow( 1024, floor( $e ) ) ) );
}
return $formatted;
}
/**
* Retrieves all Attachments for provided Post or Page
*
* @param int $post_id (optional) ID of target Post or Page, otherwise pulls from global $post
* @return array $post_attachments
* @author Jonathan Christopher
* @author JR Tashjian
*/
function attachments_get_attachments( $post_id=null )
{
global $post;
if( $post_id==null )
{
$post_id = $post->ID;
}
// get all attachments
$existing_attachments = get_post_meta( $post_id, '_attachments', false );
// We can now proceed as normal, all legacy data should now be upgraded
$post_attachments = array();
if( is_array( $existing_attachments ) && count( $existing_attachments ) > 0 )
{
foreach ($existing_attachments as $attachment)
{
// decode and unserialize the data
$data = unserialize( base64_decode( $attachment ) );
array_push( $post_attachments, array(
'id' => stripslashes( $data['id'] ),
'name' => stripslashes( get_the_title( $data['id'] ) ),
'mime' => stripslashes( get_post_mime_type( $data['id'] ) ),
'title' => stripslashes( $data['title'] ),
'caption' => stripslashes( $data['caption'] ),
'filesize' => stripslashes( attachments_get_filesize_formatted( get_attached_file( $data['id'] ) ) ),
'location' => stripslashes( wp_get_attachment_url( $data['id'] ) ),
'order' => stripslashes( $data['order'] )
));
}
// sort attachments
if( count( $post_attachments ) > 1 )
{
usort( $post_attachments, "attachments_cmp" );
}
}
return $post_attachments;
}
/**
* Outputs Attachments JS into the footer
*
* @return void
* @author Jonathan Christopher
*/
function attachments_footer_js()
{
$uri = isset( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : NULL ;
$file = basename( parse_url( $uri, PHP_URL_PATH ) );
if( $uri && in_array( $file, array( 'post.php', 'post-new.php' ) ) )
{
// we only want this to fire on edit screens
echo '';
}
}
/**
* This is the main initialization function, it will invoke the necessary meta_box
*
* @return void
* @author Jonathan Christopher
*/
function attachments_init()
{
wp_enqueue_script( 'jquery-ui-core' );
wp_enqueue_script( 'thickbox' );
wp_enqueue_style( 'thickbox' );
wp_enqueue_style( 'attachments', WP_PLUGIN_URL . '/attachments/css/attachments.css' );
if( function_exists( 'load_plugin_textdomain' ) )
{
if( !defined('WP_PLUGIN_DIR') )
{
load_plugin_textdomain( 'attachments', str_replace( ABSPATH, '', dirname( __FILE__ ) ) );
}
else
{
load_plugin_textdomain( 'attachments', false, dirname( plugin_basename( __FILE__ ) ) );
}
}
attachments_meta_box();
}
/**
* Modifies the plugin meta line on the WP Plugins page
*
* @param $plugin_meta
* @param $plugin_file
* @return array $plugin_meta Array of plugin meta data
* @author Jonathan Christopher
*/
function attachments_filter_plugin_row_meta( $plugin_meta, $plugin_file )
{
if( strstr( $plugin_file, 'attachments/attachments.php' ) )
{
$plugin_meta[2] = 'Attachments Pro';
$plugin_meta[3] = 'Visit Iron to Iron';
return $plugin_meta;
}
else
{
return $plugin_meta;
}
}