First pass at async upload, multi-upload, and gallery feature. Modified names from patch. Hat tip: tellyworth, skeltoac.

git-svn-id: http://svn.automattic.com/wordpress/trunk@6659 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
matt 2008-01-25 19:21:11 +00:00
parent f9ba9a3802
commit f529123061
15 changed files with 2323 additions and 24 deletions

28
wp-admin/async-upload.php Normal file
View File

@ -0,0 +1,28 @@
<?php
/* This accepts file uploads from swfupload or other asynchronous upload methods.
*/
if ( defined('ABSPATH') )
require_once( ABSPATH . 'wp-config.php');
else
require_once('../wp-config.php');
// Flash often fails to send cookies with the POST or upload, so we need to pass it in GET or POST instead
if ( empty($_COOKIE[AUTH_COOKIE]) && !empty($_REQUEST['auth_cookie']) )
$_COOKIE[AUTH_COOKIE] = $_REQUEST['auth_cookie'];
unset($current_user);
require_once('admin.php');
header('Content-Type: text/plain');
$id = media_handle_upload('async-upload', $_REQUEST['post_id']);
if (is_wp_error($id)) {
echo '<div id="media-upload-error">'.wp_specialchars($id->get_error_message()).'</div>';
exit;
}
$type = $_REQUEST['type'];
echo apply_filters("async_upload_{$type}", $id);
?>

View File

@ -41,6 +41,7 @@ form.media-upload-form {
display:block;
font-weight: bold;
margin-bottom: 0.5em;
margin: 0 0 0.5em 0;
}
.media-upload-form label.form-help {
@ -58,9 +59,11 @@ form.media-upload-form {
}
.media-upload-form fieldset {
width: 100%;
border: none;
text-align: justify;
margin-bottom: 1em;
margin: 0 0 1em 0;
padding: 0;
}
.media-upload-form button.button-ok {
@ -83,7 +86,8 @@ form.media-upload-form {
/* specific to the image upload form */
.media-upload-form fieldset#image-align label {
display: inline;
padding: 0 28px;
padding: 0 0 0 28px;
margin: 0 0;
}
#image-align-none-label {
@ -101,3 +105,87 @@ form.media-upload-form {
#image-align-right-label {
background: url(../images/align-right.png) no-repeat center left;
}
.pinkynail {
max-width: 40px;
max-height: 40px;
}
#multimedia-items {
border: 1px solid #c0c0c0;
border-bottom: none;
width: 623px;
}
.multimedia-item {
border-bottom: 1px solid #d0d0d0;
width: 623px;
position: relative;
}
span.filename {
position: absolute;
left: 46px;
top: 0px;
line-height: 36px;
z-index: 2;
}
.progress {
width: 623px;
height: 36px;
}
.bar {
width: 0px;
height: 36px;
background-color: #e8e8e8;
border-right: 3px solid #99d;
}
.multimedia-item .thumbnail {
}
.multimedia-item .pinkynail {
position: absolute;
top: 3px;
left: 3px;
max-width: 40px;
max-height: 40px;
}
.describe {
display: none;
border-top: 1px solid #d0d0d0;
padding: 5px;
}
.describe fieldset {
width: 470px;
float: right;
}
.describe img {
float: left;
}
.describe input[type="text"], .describe textarea {
width: 450px;
}
.describe label {
padding-right: 1em;
}
a.delete {
clear: both;
}
.describe-toggle-on, .describe-toggle-off {
line-height: 36px;
z-index: 2;
position: absolute;
top: 0px;
right: 20px;
}
.describe-toggle-off {
display: none;
}
.clickmask {
background: transparent;
position: absolute;
top: 0px;
left: 0px;
cursor: pointer;
border: none;
z-index: 10;
}

View File

@ -14,6 +14,7 @@ function image_upload_form( $action_url, $values = array(), $error = null ) {
$image_url = attribute_escape( @$values['image-url'] );
$image_title = attribute_escape( @$values['image-title'] );
$image_align = @$values['image-url'];
$post_id = $_GET['post_id'];
?>
<div id="media-upload-header">
@ -24,13 +25,55 @@ function image_upload_form( $action_url, $values = array(), $error = null ) {
<li class="last"><?php _e('Flickr'); ?></li>
</ul>
</div>
<?php if ($error) { ?>
<div id="media-upload-error">
<?php echo $error->get_error_message(); ?>
</div>
<?php } ?>
<div id="media-upload-error">
<?php if ($error) {
echo $error->get_error_message();
} ?>
</div>
<script type="text/javascript">
<!--
jQuery(document).ready(function(){
var swfu = new SWFUpload({
upload_url : "<?php echo get_option('siteurl').'/wp-admin/async-upload.php'; ?>",
flash_url : "<?php echo get_option('siteurl').'/wp-includes/js/swfupload/swfupload_f9.swf'; ?>",
file_post_name: "async-upload",
swfupload_element_id : "flash-upload-ui", // id of the element displayed when swfupload is available
degraded_element_id : "html-upload-ui", // when swfupload is unavailable
//file_types : "*.jpg;*.gif;*.png",
file_size_limit : "<?php echo wp_max_upload_size(); ?> B",
post_params : {
"post_id" : "<?php echo $post_id; ?>",
"auth_cookie" : "<?php echo $_COOKIE[AUTH_COOKIE]; ?>",
"type" : "image",
},
swfupload_loaded_handler : uploadLoadedImage,
upload_progress_handler : uploadProgressImage,
upload_success_handler : uploadSuccessImage,
upload_error_handler: uploadError,
file_queued_handler : fileQueuedImage,
file_queue_error_handler : fileQueueError,
file_dialog_complete_handler : fileDialogComplete,
custom_settings : {
progressTarget : "flash-upload-ui",
cancelButtonId : "btnCancel2"
},
debug: false,
});
document.getElementById("flash-browse-button").onclick = function () { swfu.selectFile(); };
});
//-->
</script>
<form enctype="multipart/form-data" method="post" action="<?php echo attribute_escape($action_url); ?>" id="image-upload" class="media-upload-form">
<p><label for="image-file"><?php _e('Choose image'); ?></label>
<p id="flash-upload-ui">
<label for="flash-browse-button"><?php _e('Choose image'); ?></label>
<input id="flash-browse-button" type="button" value="<?php _e('Browse'); ?>" />
<label for="image-file" class="form-help"><?php _e('Only PNG, JPG, GIF'); ?></label></p>
<p id="html-upload-ui"><label for="image-file"><?php _e('Choose image'); ?></label>
<input type="file" name="image-file" id="image-file" />
<label for="image-file" class="form-help"><?php _e('Only PNG, JPG, GIF'); ?></label></p>
<p><label for="image-alt" class="required"><?php _e('&lt;alt&gt; (required)'); ?></label>
@ -57,7 +100,7 @@ function image_upload_form( $action_url, $values = array(), $error = null ) {
<button name="image-add" id="image-add" class="button-ok" value="1"><?php _e('Add Image'); ?></button>
<a href="#" onclick="return top.tb_remove();" id="image-cancel" class="button-cancel"><?php _e('Cancel'); ?></a>
</p>
<input type="hidden" name="parent_post_id" value="<?php echo attribute_escape('parent_post_id'); ?>" />
<input type="hidden" name="post_id" value="<?php echo attribute_escape($post_id); ?>" />
<?php wp_nonce_field( 'inlineuploading' ); ?>
</form>
<?php
@ -69,15 +112,28 @@ function image_upload_handler() {
return new wp_error( 'upload_not_allowed', __('You are not allowed to upload files.') );
}
check_admin_referer('inlineuploading');
if ( empty($_POST['image-add']) ) {
// no button click, we're just displaying the form
wp_iframe( 'image_upload_form', get_option('siteurl') . '/wp-admin/media-upload.php?type=image' );
}
else {
// Add Image button was clicked
$id = image_upload_post();
check_admin_referer('inlineuploading');
// if the async flash uploader was used, the attachment has already been inserted and its ID is passed in post.
// otherwise this is a regular form post and we still have to handle the upload and create the attachment.
if ( !empty($_POST['attachment_id']) ) {
$id = intval($_POST['attachment_id']);
// store the title and alt into the attachment post
wp_update_post(array(
'ID' => $id,
'post_title' => $_POST['image-title'],
'post_content' => $_POST['image-alt'],
));
}
else {
$id = image_upload_post();
}
// if the input was invalid, redisplay the form with its current values
if ( is_wp_error($id) )
@ -88,6 +144,45 @@ function image_upload_handler() {
}
}
// this returns html to include in the single image upload form when the async flash upload has finished
// i.e. show a thumb of the image, and include the attachment id as a hidden input
function async_image_callback($id) {
$thumb_url = wp_get_attachment_thumb_url($id);
if ( empty($thumb_url) )
$thumb_url = wp_mime_type_icon($id);
if ($thumb_url) {
$out = '<p><input type="hidden" name="attachment_id" id="attachment_id" value="'.intval($id).'" />'
. '<img src="'.wp_get_attachment_thumb_url($id).'" class="pinkynail" /> '
. basename(wp_get_attachment_url($id)).'</p>';
}
else {
$out = '<p><input type="hidden" name="attachment_id" id="attachment_id" value="'.intval($id).'" />'
. basename(wp_get_attachment_url($id)).'</p>';
}
$post = get_post($id);
$title = addslashes($post->post_title);
$alt = addslashes($post->post_content);
// populate the input fields with post data (which in turn comes from exif/iptc)
$out .= <<<EOF
<script type="text/javascript">
<!--
jQuery('#image-alt').val('{$alt}').attr('disabled', false);
jQuery('#image-title').val('{$title}').attr('disabled', false);
jQuery('#image-url').attr('disabled', false);
jQuery('#image-add').attr('disabled', false);
-->
</script>
EOF;
return $out;
}
add_filter('async_upload_image', 'async_image_callback');
function image_send_to_editor($id, $alt, $title, $align, $url='') {
$img_src = wp_get_attachment_url($id);
@ -97,7 +192,7 @@ function image_send_to_editor($id, $alt, $title, $align, $url='') {
if ( isset($meta['width'], $meta['height']) )
$hwstring = ' width="'.intval($meta['width']).'" height="'.intval($meta['height']).'"';
$html = '<img src="'.attribute_escape($img_src).'" alt="'.attribute_escape($alt).'" title="'.attribute_escape($title).'"'.$hwstring.' class="align-'.attribute_escape($align).'" />';
$html = '<img src="'.attribute_escape($img_src).'" rel="attachment wp-att-'.attribute_escape($id).'" alt="'.attribute_escape($alt).'" title="'.attribute_escape($title).'"'.$hwstring.' class="align-'.attribute_escape($align).'" />';
if ( $url )
$html = '<a href="'.attribute_escape($url).'">'.$html.'</a>';
@ -153,11 +248,50 @@ function image_upload_post() {
wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );
return $id;
}
wp_redirect( get_option('siteurl') . "/wp-admin/upload.php?style=$style&tab=browse&action=view&ID=$id&post_id=$post_id");
// this handles the file upload POST itself, creating the attachment post
function media_handle_upload($file_id, $post_id, $post_data = array()) {
$overrides = array('test_form'=>false);
$file = wp_handle_upload($_FILES[$file_id], $overrides);
if ( isset($file['error']) )
return new wp_error( 'upload_error', $file['error'] );
$url = $file['url'];
$type = $file['type'];
$file = $file['file'];
$title = preg_replace('/\.[^.]+$/', '', basename($file));
$content = '';
// use image exif/iptc data for title and caption defaults if possible
if ( $image_meta = @wp_read_image_metadata($file) ) {
if ( trim($image_meta['title']) )
$title = $image_meta['title'];
if ( trim($image_meta['caption']) )
$content = $image_meta['caption'];
}
// Construct the attachment array
$attachment = array_merge( array(
'post_mime_type' => $type,
'guid' => $url,
'post_parent' => $post_id,
'post_title' => $title,
'post_content' => $content,
), $post_data );
// Save the data
$id = wp_insert_attachment($attachment, $file, $post_parent);
if ( !is_wp_error($id) ) {
wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );
}
return $id;
}
// wrap iframe content (produced by $content_func) in a doctype, html head/body etc
// any additional function args will be passed to content_func
function wp_iframe($content_func /* ... */) {
@ -194,10 +328,13 @@ if ( is_string($content_func) )
function media_buttons() { // just a placeholder for now
global $post_ID, $temp_ID;
$uploading_iframe_ID = (int) (0 == $post_ID ? $temp_ID : $post_ID);
$uploading_iframe_src = wp_nonce_url("media-upload.php?type=image&amp;&amp;post_id=$uploading_iframe_ID", 'inlineuploading');
$uploading_iframe_src = apply_filters('uploading_iframe_src', $uploading_iframe_src);
$image_upload_iframe_src = wp_nonce_url("media-upload.php?type=image&amp;post_id=$uploading_iframe_ID", 'inlineuploading');
$image_upload_iframe_src = apply_filters('image_upload_iframe_src', $image_upload_iframe_src);
$multimedia_upload_iframe_src = wp_nonce_url("media-upload.php?type=multimedia&amp;post_id=$uploading_iframe_ID", 'inlineuploading');
$multimedia_upload_iframe_src = apply_filters('multimedia_upload_iframe_src', $multimedia_upload_iframe_src);
$out = <<<EOF
<a href="{$uploading_iframe_src}&TB_iframe=true&height=500&width=460" class="thickbox">
<a href="{$multimedia_upload_iframe_src}&TB_iframe=true&height=500&width=640" class="thickbox">Multimedia</a>
<a href="{$image_upload_iframe_src}&TB_iframe=true&height=500&width=460" class="thickbox">
<img src="./images/media-buttons.gif" alt="" />
</a>
EOF;
@ -225,7 +362,214 @@ function media_admin_css() {
wp_admin_css('css/media');
}
add_action('media_upload_multimedia', 'multimedia_upload_handler');
add_action('media_upload_image', 'image_upload_handler');
add_action('admin_head_image_upload_form', 'media_admin_css');
function multimedia_upload_handler() {
if ( !current_user_can('upload_files') ) {
return new wp_error( 'upload_not_allowed', __('You are not allowed to upload files.') );
}
if ( empty($_POST) ) {
// no button click, we're just displaying the form
wp_iframe( 'multimedia_upload_form' );
} elseif ( empty($_POST['upload-button']) ) {
// Insert multimedia button was clicked
check_admin_referer('multimedia-form');
if ( !empty($_POST['attachments']) ) foreach ( $_POST['attachments'] as $attachment_id => $attachment ) {
$post = $_post = get_post($attachment_id, ARRAY_A);
$post['post_content'] = $attachment['post_content'];
$post['post_title'] = $attachment['post_title'];
if ( $post != $_post )
wp_update_post($post);
if ( $taxonomies = get_object_taxonomies('attachment') ) foreach ( $taxonomies as $t )
if ( isset($attachment[$t]) )
wp_set_object_terms($attachment_id, array_map('trim', preg_split('/,+/', $attachment[$t])), $t, false);
}
media_send_to_editor('[gallery]');
} else {
// Upload File button was clicked
$id = media_handle_upload('async-upload', $_REQUEST['post_id']);
wp_iframe( 'multimedia_upload_form' );
}
}
function get_multimedia_items( $post_id ) {
$attachments = get_children("post_parent=$post_id&post_type=attachment&orderby=\"menu_order ASC, ID ASC\"");
if ( empty($attachments) )
return '';
foreach ( $attachments as $id => $attachment ) {
$output .= "\n<div id='multimedia-item-$id' class='multimedia-item preloaded'><div id='media-upload-error-$id'></div><span class='filename'></span><div class='progress'><div class='bar'></div></div>";
$output .= get_multimedia_item($id);
$output .= " <div class='progress clickmask'></div>\n</div>";
}
return $output;
}
function get_multimedia_item( $attachment_id ) {
$thumb_url = wp_get_attachment_thumb_url( $attachment_id );
if ( empty($thumb_url) )
$thumb_url = wp_mime_type_icon( $attachment_id );
$title_label = __('Title');
$description_label = __('Description');
$tags_label = __('Tags');
$toggle_on = __('Describe &raquo;');
$toggle_off = __('Describe &laquo;');
$post = get_post($attachment_id);
$filename = basename($post->guid);
$title = attribute_escape($post->post_title);
$description = attribute_escape($post->post_content);
if ( $_tags = get_the_tags($attachment_id) ) {
foreach ( $_tags as $tag )
$tags[] = $tag->name;
$tags = attribute_escape(join(', ', $tags));
}
$delete_href = wp_nonce_url("post.php?action=delete-post&amp;post=$attachment_id", 'delete-post_' . $attachment_id);
$delete = __('Delete');
$item = "
<a class='toggle describe-toggle-on' href='#'>$toggle_on</a>
<a class='toggle describe-toggle-off' href='#'>$toggle_off</a>
<span class='filename new'>$filename</span>
<div class='slidetoggle describe'>
<img class='thumbnail' src='$thumb_url' alt='' />
<fieldset>
<p><label for='attachments[$attachment_id][post_title]'>$title_label</label><input type='text' id='attachments[$attachment_id][post_title]' name='attachments[$attachment_id][post_title]' value='$title' /></p>
<p><label for='attachments[$attachment_id][post_content]'>$description_label</label><input type='text' id='attachments[$attachment_id][post_content]' name='attachments[$attachment_id][post_content]' value='$description' /></p>
";
if ( $taxonomies = get_object_taxonomies('attachment') ) foreach ( $taxonomies as $t ) {
$tax = get_taxonomy($t);
$t_title = !empty($tax->title) ? $tax->title : $t;
if ( false === $terms = get_object_term_cache( $attachment_id, $t ) )
$_terms = wp_get_object_terms($attachment_id, $t);
if ( $_terms ) {
foreach ( $_terms as $term )
$terms[] = $term->name;
$terms = join(', ', $terms);
} else
$terms = '';
$item .= "<p><label for='attachments[$attachment_id][$t]'>$t_title</label><input type='text' id='attachments[$attachment_id][$t]' name='attachments[$attachment_id][$t]' value='$terms' /></p>\n";
}
$item .= "
</fieldset>
<p><a id='del$attachment_id' class='delete' href='$delete_href'>$delete</a></p>
</div>
";
return $item;
}
function multimedia_upload_form( $error = null ) {
$flash_action_url = get_option('siteurl') . '/wp-admin/async-upload.php?type=multimedia';
$form_action_url = get_option('siteurl') . '/wp-admin/media-upload.php?type=multimedia';
$post_id = intval($_REQUEST['post_id']);
?>
<div id="media-upload-header">
<h3>Add Images</h3>
</div>
<div id="media-upload-error">
<?php if ($error) { ?>
<?php echo $error->get_error_message(); ?>
<?php } ?>
</div>
<script type="text/javascript">
<!--
jQuery(function($){
swfu = new SWFUpload({
upload_url : "<?php echo attribute_escape( $flash_action_url ); ?>",
flash_url : "<?php echo get_option('siteurl').'/wp-includes/js/swfupload/swfupload_f9.swf'; ?>",
file_post_name: "async-upload",
file_types: "*.*",
post_params : {
"post_id" : "<?php echo $post_id; ?>",
"auth_cookie" : "<?php echo $_COOKIE[AUTH_COOKIE]; ?>",
"type" : "multimedia"
},
swfupload_element_id : "flash-upload-ui", // id of the element displayed when swfupload is available
degraded_element_id : "html-upload-ui", // when swfupload is unavailable
//upload_start_handler : uploadStart,
upload_progress_handler : uploadProgressMultimedia,
//upload_error_handler : uploadError,
upload_success_handler : uploadSuccessMultimedia,
upload_complete_handler : uploadCompleteMultimedia,
file_dialog_start_handler : fileDialogStart,
file_queued_handler : fileQueuedMultimedia,
file_queue_error_handler : fileQueueError,
file_dialog_complete_handler : fileDialogComplete,
debug: false,
});
$("#flash-browse-button").bind( "click", function(){swfu.selectFiles();});
$("#insert-multimedia").bind( "click", function(){jQuery(this).parents('form').get(0).submit();});
$(".multimedia-item.preloaded").each(function(){uploadSuccessMultimedia({id:this.id.replace(/[^0-9]/g, '')},'');jQuery('#insert-multimedia').attr('disabled', '');});
$("a.delete").bind('click',function(){$.ajax({url:'admin-ajax.php',type:'post',data:{id:this.id.replace(/del/,''),action:'delete-post',_ajax_nonce:this.href.replace(/^.*wpnonce=/,'')}});$(this).parents(".multimedia-item").eq(0).slideToggle(300, function(){$(this).remove();});return false;});
});
//-->
</script>
<p id="flash-upload-ui" style="display:none">
<input id="flash-browse-button" type="button" value="<?php _e('Choose Files'); ?>" />
<label for="image-file" class="form-help"><?php _e('Only PNG, JPG, GIF'); ?></label>
</p>
<form enctype="multipart/form-data" method="post" action="<?php echo attribute_escape($form_action_url); ?>" class="media-upload-form">
<div id="html-upload-ui">
<p><label for="async-upload"><?php _e('Choose image'); ?></label>
<input type="file" name="async-upload" id="async-upload" />
<label for="image-file" class="form-help"><?php _e('Only PNG, JPG, GIF'); ?></label>
</p>
<p>
<button id="upload-button" name="upload-button" value="1" class="button-ok"><?php _e('Add Image'); ?></button>
<a href="#" onClick="return top.tb_remove();" id="image-cancel" class="button-cancel"><?php _e('Cancel'); ?></a>
</p>
<input type="hidden" name="post_id" id="post_id" value="<?php echo $post_id; ?>" />
<br style="clear:both" />
</div>
<div id="multimedia-items">
<?php echo get_multimedia_items($post_id); ?>
</div>
<p class="submit">
<a href="#" onClick="return top.tb_remove();" id="image-cancel" class="button-cancel"><?php _e('Cancel'); ?></a>
<input type="button" class="submit" id="insert-multimedia" value="<?php _e('Insert gallery into post'); ?>" disabled="disabled" />
</p>
<?php wp_nonce_field('multimedia-form'); ?>
</form>
<?php
}
add_action('admin_head_multimedia_upload_form', 'media_admin_css');
add_filter('async_upload_multimedia', 'get_multimedia_item');
add_filter('media_upload_multimedia', 'multimedia_upload_handler');
// Any 'attachment' taxonomy will be included in the description input form for the multi uploader
// Example:
//register_taxonomy('attachment_people', 'attachment', array('title' => 'People'));
?>

View File

@ -745,10 +745,15 @@ function wp_convert_bytes_to_hr( $bytes ) {
return $size . $units[$power];
}
function wp_import_upload_form( $action ) {
function wp_max_upload_size() {
$u_bytes = wp_convert_hr_to_bytes( ini_get( 'upload_max_filesize' ) );
$p_bytes = wp_convert_hr_to_bytes( ini_get( 'post_max_size' ) );
$bytes = apply_filters( 'import_upload_size_limit', min($u_bytes, $p_bytes), $u_bytes, $p_bytes );
$bytes = apply_filters( 'upload_size_limit', min($u_bytes, $p_bytes), $u_bytes, $p_bytes );
return $bytes;
}
function wp_import_upload_form( $action ) {
$bytes = apply_filters( 'import_upload_size_limit', wp_max_upload_size() );
$size = wp_convert_bytes_to_hr( $bytes );
?>
<form enctype="multipart/form-data" id="import-upload-form" method="post" action="<?php echo attribute_escape($action) ?>">

View File

@ -1,5 +1,9 @@
<?php
require_once('admin.php');
wp_enqueue_script('swfupload');
wp_enqueue_script('swfupload-degrade');
wp_enqueue_script('swfupload-queue');
wp_enqueue_script('swfupload-handlers');
@header('Content-Type: ' . get_option('html_type') . '; charset=' . get_option('blog_charset'));

View File

@ -0,0 +1,298 @@
function fileDialogStart() {
jQuery("#media-upload-error").empty();
}
// progress and success handlers for multimedia multi uploads
function fileQueuedMultimedia(fileObj) {
// Create a progress bar containing the filename
jQuery('#multimedia-items').append('<div id="multimedia-item-' + fileObj.id + '" class="multimedia-item"><span class="filename original">' + fileObj.name + '</span><div class="progress"><div class="bar"></div></div></div>');
// Disable the submit button
jQuery('#insert-multimedia').attr('disabled', 'disabled');
}
function uploadProgressMultimedia(fileObj, bytesDone, bytesTotal) {
// Lengthen the progress bar
jQuery('#multimedia-item-' + fileObj.id + ' .bar').width(620*bytesDone/bytesTotal);
}
function uploadSuccessMultimedia(fileObj, serverData) {
// if async-upload returned an error message, place it in the multimedia item div and return
if ( serverData.match('media-upload-error') ) {
jQuery('#multimedia-item-' + fileObj.id).html(serverData);
return;
}
// Move the progress bar to 100%
jQuery('#multimedia-item-' + fileObj.id + ' .bar').remove();
// Append the HTML returned by the server -- thumbnail and form inputs
jQuery('#multimedia-item-' + fileObj.id).append(serverData);
// Clone the thumbnail as a "pinkynail" -- a tiny image to the left of the filename
jQuery('#multimedia-item-' + fileObj.id + ' .thumbnail').clone().attr('className', 'pinkynail').prependTo('#multimedia-item-' + fileObj.id);
// Replace the original filename with the new (unique) one assigned during upload
jQuery('#multimedia-item-' + fileObj.id + ' .filename.original').replaceWith(jQuery('#multimedia-item-' + fileObj.id + ' .filename.new'));
// Bind toggle function to a new mask over the progress bar area
jQuery('#multimedia-item-' + fileObj.id + ' .progress').clone().empty().addClass('clickmask').bind('click', function(){jQuery(this).siblings('.slidetoggle').slideToggle(150);jQuery(this).siblings('.toggle').toggle();}).appendTo('#multimedia-item-' + fileObj.id);
// Also bind toggle to the links
jQuery('#multimedia-item-' + fileObj.id + ' a.toggle').bind('click', function(){jQuery(this).siblings('.slidetoggle').slideToggle(150);jQuery(this).parent().eq(0).children('.toggle').toggle();jQuery(this).siblings('a.toggle').focus();return false;});
// Bind AJAX to the new Delete button
jQuery('#multimedia-item-' + fileObj.id + ' a.delete').bind('click',function(){jQuery.ajax({url:'admin-ajax.php',type:'post',data:{id:this.id.replace(/del/,''),action:'delete-post',_ajax_nonce:this.href.replace(/^.*wpnonce=/,'')}});jQuery(this).parents(".multimedia-item").eq(0).slideToggle(300, function(){jQuery(this).remove();});return false;});
}
function uploadCompleteMultimedia(fileObj) {
// If no more uploads queued, enable the submit button
if ( swfu.getStats().files_queued == 0 )
jQuery('#insert-multimedia').attr('disabled', '');
}
// progress and success handlers for single image upload
function uploadLoadedImage() {
jQuery('#image-alt').attr('disabled', true);
jQuery('#image-url').attr('disabled', true);
jQuery('#image-title').attr('disabled', true);
jQuery('#image-add').attr('disabled', true);
}
function fileQueuedImage(fileObj) {
jQuery('#flash-upload-ui').append('<div id="image-progress"><p class="filename">' + fileObj.name + '</p><div class="progress"><div class="bar"></div></div></div>');
}
function uploadProgressImage(fileObj, bytesDone, bytesTotal) {
jQuery('#image-progress .bar').width(450*bytesDone/bytesTotal);
}
function uploadSuccessImage(fileObj, serverData) {
if ( serverData.match('media-upload-error') ) {
jQuery('#media-upload-error').replaceWith(serverData);
jQuery('#image-progress').replaceWith('');
}
else {
jQuery('#media-upload-error').replaceWith('');
jQuery('#flash-upload-ui').replaceWith(serverData);
}
}
// wp-specific error handlers
// generic message
function wpQueueError(message) {
jQuery('#media-upload-error').show().text(message);
}
// file-specific message
function wpFileError(fileObj, message) {
jQuery('#media-upload-error-' + fileObj.id).show().text(message);
}
function fileQueueError(fileObj, error_code, message) {
// Handle this error separately because we don't want to create a FileProgress element for it.
if ( error_code == SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED ) {
wpQueueError(swfuploadL10n.queue_limit_exceeded);
}
else if ( error_code == SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT ) {
wpQueueError(swfuploadL10n.file_exceeds_size_limit);
}
else if ( error_code == SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE ) {
wpQueueError(swfuploadL10n.zero_byte_file);
}
else if ( error_code == SWFUpload.QUEUE_ERROR.INVALID_FILETYPE ) {
wpQueueError(swfuploadL10n.invalid_filetype);
}
else {
wpQueueError(swfuploadL10n.default_error);
}
function fileQueued(fileObj) {
try {
var txtFileName = document.getElementById("txtFileName");
txtFileName.value = fileObj.name;
} catch (e) { }
}
function fileDialogComplete(num_files_queued) {
try {
if (num_files_queued > 0) {
this.startUpload();
}
} catch (ex) {
this.debug(ex);
}
}
function uploadProgress(fileObj, bytesLoaded, bytesTotal) {
try {
var percent = Math.ceil((bytesLoaded / bytesTotal) * 100)
fileObj.id = "singlefile"; // This makes it so FileProgress only makes a single UI element, instead of one for each file
var progress = new FileProgress(fileObj, this.customSettings.progress_target);
progress.SetProgress(percent);
progress.SetStatus("Uploading...");
} catch (e) { }
}
function uploadSuccess(fileObj, server_data) {
try {
fileObj.id = "singlefile"; // This makes it so FileProgress only makes a single UI element, instead of one for each file
var progress = new FileProgress(fileObj, this.customSettings.progress_target);
progress.SetComplete();
progress.SetStatus("Complete.");
progress.ToggleCancel(false);
if (server_data === " ") {
this.customSettings.upload_successful = false;
} else {
this.customSettings.upload_successful = true;
document.getElementById("hidFileID").value = server_data;
}
} catch (e) { }
}
function uploadComplete(fileObj) {
try {
if (this.customSettings.upload_successful) {
document.getElementById("btnBrowse").disabled = "true";
uploadDone();
} else {
fileObj.id = "singlefile"; // This makes it so FileProgress only makes a single UI element, instead of one for each file
var progress = new FileProgress(fileObj, this.customSettings.progress_target);
progress.SetError();
progress.SetStatus("File rejected");
progress.ToggleCancel(false);
var txtFileName = document.getElementById("txtFileName");
txtFileName.value = "";
//validateForm();
alert("There was a problem with the upload.\nThe server did not accept it.");
}
} catch (e) { }
}
function uploadError(fileObj, error_code, message) {
// first the file specific error
if ( error_code == SWFUpload.UPLOAD_ERROR.MISSING_UPLOAD_URL ) {
wpFileError(fileObj, swfuploadL10n.missing_upload_url);
}
else if ( error_code == SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED ) {
wpFileError(fileObj, swfuploadL10n.upload_limit_exceeded);
}
else {
wpFileError(fileObj, swfuploadL10n.default_error);
}
// not sure if this is needed
fileObj.id = "singlefile"; // This makes it so FileProgress only makes a single UI element, instead of one for each file
var progress = new FileProgress(fileObj, this.customSettings.progress_target);
progress.SetError();
progress.ToggleCancel(false);
// now the general upload status
if ( error_code == SWFUpload.UPLOAD_ERROR.HTTP_ERROR ) {
wpQueueError(swfuploadL10n.http_error);
}
else if ( error_code == SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED ) {
wpQueueError(swfuploadL10n.upload_failed);
}
else if ( error_code == SWFUpload.UPLOAD_ERROR.IO_ERROR ) {
wpQueueError(swfuploadL10n.io_error);
}
else if ( error_code == SWFUpload.UPLOAD_ERROR.SECURITY_ERROR ) {
wpQueueError(swfuploadL10n.security_error);
}
else if ( error_code == SWFUpload.UPLOAD_ERROR.FILE_CANCELLED ) {
wpQueueError(swfuploadL10n.security_error);
}
}
/* ********************************************************
* Utility for displaying the file upload information
* This is not part of SWFUpload, just part of the demo
* ******************************************************** */
function FileProgress(fileObj, target_id) {
this.file_progress_id = fileObj.id;
this.fileProgressElement = document.getElementById(this.file_progress_id);
if (!this.fileProgressElement) {
this.fileProgressElement = document.createElement("div");
this.fileProgressElement.className = "progressContainer";
this.fileProgressElement.id = this.file_progress_id;
var progressCancel = document.createElement("a");
progressCancel.className = "progressCancel";
progressCancel.href = "#";
progressCancel.style.visibility = "hidden";
progressCancel.appendChild(document.createTextNode(" "));
var progressText = document.createElement("div");
progressText.className = "progressName";
progressText.appendChild(document.createTextNode(fileObj.name));
var progressBar = document.createElement("div");
progressBar.className = "progressBarInProgress";
var progressStatus = document.createElement("div");
progressStatus.className = "progressBarStatus";
progressStatus.innerHTML = "&nbsp;";
this.fileProgressElement.appendChild(progressCancel);
this.fileProgressElement.appendChild(progressText);
this.fileProgressElement.appendChild(progressStatus);
this.fileProgressElement.appendChild(progressBar);
document.getElementById(target_id).appendChild(this.fileProgressElement);
}
}
FileProgress.prototype.SetStart = function() {
this.fileProgressElement.className = "progressContainer";
this.fileProgressElement.childNodes[3].className = "progressBarInProgress";
this.fileProgressElement.childNodes[3].style.width = "";
}
FileProgress.prototype.SetProgress = function(percentage) {
this.fileProgressElement.className = "progressContainer green";
this.fileProgressElement.childNodes[3].className = "progressBarInProgress";
this.fileProgressElement.childNodes[3].style.width = percentage + "%";
}
FileProgress.prototype.SetComplete = function() {
this.fileProgressElement.className = "progressContainer blue";
this.fileProgressElement.childNodes[3].className = "progressBarComplete";
this.fileProgressElement.childNodes[3].style.width = "";
}
FileProgress.prototype.SetError = function() {
this.fileProgressElement.className = "progressContainer red";
this.fileProgressElement.childNodes[3].className = "progressBarError";
this.fileProgressElement.childNodes[3].style.width = "";
}
FileProgress.prototype.SetCancelled = function() {
this.fileProgressElement.className = "progressContainer";
this.fileProgressElement.childNodes[3].className = "progressBarError";
this.fileProgressElement.childNodes[3].style.width = "";
}
FileProgress.prototype.SetStatus = function(status) {
this.fileProgressElement.childNodes[2].innerHTML = status;
}
FileProgress.prototype.ToggleCancel = function(show, upload_obj) {
this.fileProgressElement.childNodes[0].style.visibility = show ? "visible" : "hidden";
if (upload_obj) {
var file_id = this.file_progress_id;
this.fileProgressElement.childNodes[0].onclick = function() { upload_obj.cancelUpload(file_id); return false; };
}
}

View File

@ -0,0 +1,50 @@
/*
Cookie Plug-in
This plug in automatically gets all the cookies for this site and adds them to the post_params.
Cookies are loaded only on initialization. The refreshCookies function can be called to update the post_params.
The cookies will override any other post params with the same name.
*/
var SWFUpload;
if (typeof(SWFUpload) === "function") {
SWFUpload.prototype.initSettings = function (old_initSettings) {
return function (init_settings) {
if (typeof(old_initSettings) === "function") {
old_initSettings.call(this, init_settings);
}
this.refreshCookies(false); // The false parameter must be sent since SWFUpload has not initialzed at this point
};
}(SWFUpload.prototype.initSettings);
// refreshes the post_params and updates SWFUpload. The send_to_flash parameters is optional and defaults to True
SWFUpload.prototype.refreshCookies = function (send_to_flash) {
if (send_to_flash !== false) send_to_flash = true;
// Get the post_params object
var post_params = this.getSetting("post_params");
// Get the cookies
var i, cookie_array = document.cookie.split(';'), ca_length = cookie_array.length, c, eq_index, name, value;
for(i = 0; i < ca_length; i++) {
c = cookie_array[i];
// Left Trim spaces
while (c.charAt(0) == " ") {
c = c.substring(1, c.length);
}
eq_index = c.indexOf("=");
if (eq_index > 0) {
name = c.substring(0, eq_index);
value = c.substring(eq_index+1);
post_params[name] = value;
}
}
if (send_to_flash) {
this.setPostParams(post_params);
}
};
}

View File

@ -0,0 +1,102 @@
/*
DocumentReady Plug-in
This plugin loads SWFUpload as soon as the document is ready. You should not load SWFUpload inside window.onload using this plugin.
You can also chain other functions by calling SWFUpload.DocumentReady(your function).
Warning: Embedded Ads or other scripts that overwrite window.onload or use their own document ready functions may interfer with this plugin. You
should not set window.onload when using this plugin.
Usage Example:
var swfu = new SWFUpload(your settings object);
SWFUpload.DocumentReady(function () { alert('Document Ready!'; });
*/
var SWFUpload;
if (typeof(SWFUpload) === "function") {
// Override iniSWFUpload so SWFUpload gets inited when the document is ready rather than immediately
SWFUpload.prototype.initSWFUpload = function (old_initSWFUpload) {
return function (init_settings) {
var self = this;
if (typeof(old_initSWFUpload) === "function") {
SWFUpload.DocumentReady(function () {
old_initSWFUpload.call(self, init_settings);
});
}
}
}(SWFUpload.prototype.initSWFUpload);
// The DocumentReady function adds the passed in function to
// the functions that will be executed when the document is ready/loaded
SWFUpload.DocumentReady = function (fn) {
// Add the function to the chain
SWFUpload.DocumentReady.InternalOnloadChain = function (previous_link_fn) {
return function () {
if (typeof(previous_link_fn) === "function") {
previous_link_fn();
}
fn();
};
}(SWFUpload.DocumentReady.InternalOnloadChain);
};
SWFUpload.DocumentReady.InternalOnloadChain = null;
SWFUpload.DocumentReady.Onload = function () {
// Execute the onload function chain
if (typeof(SWFUpload.DocumentReady.InternalOnloadChain) === "function") {
SWFUpload.DocumentReady.InternalOnloadChain();
}
};
SWFUpload.DocumentReady.SetupComplete = false;
/* ********************************************
This portion of the code gets executed as soon it is loaded.
It binds the proper event for executing JavaScript is
early as possible. This is a per browser function and so
some browser sniffing is used.
This solution still has the "exposed" issue (See the Global Delegation section at http://peter.michaux.ca/article/553 )
Base solution from http://dean.edwards.name/weblog/2006/06/again/ and http://dean.edwards.name/weblog/2005/09/busted/
******************************************** */
if (!SWFUpload.DocumentReady.SetupComplete) {
// for Internet Explorer (using conditional comments)
/*@cc_on @*/
/*@if (@_win32)
document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
var script = document.getElementById("__ie_onload");
script.onreadystatechange = function() {
if (this.readyState == "complete") {
SWFUpload.DocumentReady.Onload(); // call the onload handler
}
};
SWFUpload.DocumentReady.SetupComplete = true;
/*@end @*/
}
if (!SWFUpload.DocumentReady.SetupComplete && /WebKit/i.test(navigator.userAgent)) { // sniff
var _timer = setInterval(function() {
if (/loaded|complete/.test(document.readyState)) {
clearInterval(_timer);
SWFUpload.DocumentReady.Onload(); // call the onload handler
}
}, 10);
SWFUpload.DocumentReady.SetupComplete = true;
}
/* for Mozilla */
if (!SWFUpload.DocumentReady.SetupComplete && document.addEventListener) {
document.addEventListener("DOMContentLoaded", SWFUpload.DocumentReady.Onload, false);
SWFUpload.DocumentReady.SetupComplete = true;
}
/* for other browsers */
if (!SWFUpload.DocumentReady.SetupComplete) {
window.onload = SWFUpload.DocumentReady.Onload;
SWFUpload.DocumentReady.SetupComplete = true;
}
}

View File

@ -0,0 +1,63 @@
/*
SWFUpload Graceful Degradation Plug-in
This plugin allows SWFUpload to display only if it is loaded successfully. Otherwise a default form is left displayed.
Usage:
To use this plugin create two HTML containers. Each should have an ID defined. One container should hold the SWFUpload UI. The other should hold the degraded UI.
The SWFUpload container should have its CSS "display" property set to "none".
If SWFUpload loads successfully the SWFUpload container will be displayed ("display" set to "block") and the
degraded container will be hidden ("display" set to "none").
Use the settings "swfupload_element_id" and "degraded_element_id" to indicate your container IDs. The default values are "swfupload_container" and "degraded_container".
*/
var SWFUpload;
if (typeof(SWFUpload) === "function") {
SWFUpload.gracefulDegradation = {};
SWFUpload.prototype.initSettings = function (old_initSettings) {
return function (init_settings) {
if (typeof(old_initSettings) === "function") {
old_initSettings.call(this, init_settings);
}
this.addSetting("swfupload_element_id", init_settings.swfupload_element_id, "swfupload_container");
this.addSetting("degraded_element_id", init_settings.degraded_element_id, "degraded_container");
this.addSetting("user_swfUploadLoaded_handler", init_settings.swfupload_loaded_handler, SWFUpload.swfUploadLoaded);
this.swfUploadLoaded_handler = SWFUpload.gracefulDegradation.swfUploadLoaded;
};
}(SWFUpload.prototype.initSettings);
SWFUpload.gracefulDegradation.swfUploadLoaded = function () {
var swfupload_container_id, swfupload_container, degraded_container_id, degraded_container, user_swfUploadLoaded_handler;
try {
swfupload_element_id = this.getSetting("swfupload_element_id");
degraded_element_id = this.getSetting("degraded_element_id");
// Show the UI container
swfupload_container = document.getElementById(swfupload_element_id);
if (swfupload_container !== null) {
swfupload_container.style.display = "block";
// Now take care of hiding the degraded UI
degraded_container = document.getElementById(degraded_element_id);
if (degraded_container !== null) {
degraded_container.style.display = "none";
}
}
} catch (ex) {
this.debug(ex);
}
user_swfUploadLoaded_handler = this.getSetting("user_swfUploadLoaded_handler");
if (typeof(user_swfUploadLoaded_handler) === "function") {
user_swfUploadLoaded_handler.apply(this);
}
};
}

View File

@ -0,0 +1,58 @@
/*
Queue Plug-in
Features:
cancelQueue method for cancelling the entire queue.
All queued files are uploaded when startUpload() is called.
If false is returned from uploadComplete then the queue upload is stopped. If false is not returned (strict comparison) then the queue upload is continued.
*/
var SWFUpload;
if (typeof(SWFUpload) === "function") {
SWFUpload.queue = {};
SWFUpload.prototype.initSettings = function (old_initSettings) {
return function (init_settings) {
if (typeof(old_initSettings) === "function") {
old_initSettings.call(this, init_settings);
}
this.customSettings.queue_cancelled_flag = false;
this.addSetting("user_upload_complete_handler", init_settings.upload_complete_handler, SWFUpload.uploadComplete);
this.uploadComplete_handler = SWFUpload.queue.uploadComplete;
};
}(SWFUpload.prototype.initSettings);
SWFUpload.prototype.cancelQueue = function () {
var stats = this.getStats();
this.customSettings.queue_cancelled_flag = false;
if (stats.in_progress > 0) {
this.customSettings.queue_cancelled_flag = true;
}
while(stats.files_queued > 0) {
this.cancelUpload();
stats = this.getStats();
}
};
SWFUpload.queue.uploadComplete = function (file) {
var user_upload_complete_handler = this.getSetting("user_upload_complete_handler");
var continue_upload = true;
if (typeof(user_upload_complete_handler) === "function") {
continue_upload = (user_upload_complete_handler.call(this, file) === false) ? false : true;
}
if (continue_upload) {
var stats = this.getStats();
if (stats.files_queued > 0 && this.customSettings.queue_cancelled_flag === false) {
this.startUpload();
} else {
this.customSettings.queue_cancelled_flag = false;
}
}
};
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -85,6 +85,27 @@ class WP_Scripts {
$this->add( 'suggest', '/wp-includes/js/jquery/suggest.js', array('dimensions'), '1.1');
$this->add( 'schedule', '/wp-includes/js/jquery/jquery.schedule.js', array('jquery'), '20');
$this->add( 'thickbox', '/wp-includes/js/thickbox/thickbox.js', array('jquery'), '3.1');
$this->add( 'swfupload', '/wp-includes/js/swfupload/swfupload.js', false, '2.0.2');
$this->add( 'swfupload-degrade', '/wp-includes/js/swfupload/plugins/swfupload.graceful_degradation.js', array('swfupload'), '2.0.2');
$this->add( 'swfupload-queue', '/wp-includes/js/swfupload/plugins/swfupload.queue.js', array('swfupload'), '2.0.2');
$this->add( 'swfupload-handlers', '/wp-includes/js/swfupload/handlers.js', array('swfupload'), '2.0.2');
// these error messages came from the sample swfupload js, they might need changing.
$this->localize( 'swfupload-handlers', 'swfuploadL10n', array(
'queue_limit_exceeded' => 'You have attempted to queue too many files.',
'file_exceeds_size_limit' => 'The file you have selected is too big.',
'zero_byte_file' => 'The file you selected is empty. Please select another file.',
'invalid_filetype' => 'The file you choose is not an allowed file type.',
'default_error' => 'An error occurred in the upload. Please try again later.',
'missing_upload_url' => 'There was a configuration error. Please contact the server administrator.',
'upload_limit_exceeded' => 'You may only upload 1 file.',
'http_error' => 'HTTP error.',
'upload_failed' => 'Upload failed.',
'io_error' => 'IO error.',
'security_error' => 'Security error.',
'file_cancelled' => 'File cancelled.',
'upload_stopped' => 'Upload stopped.',
) );
$this->add( 'jquery-ui-tabs', '/wp-includes/js/jquery/ui.tabs.js', array('jquery'), '3' );

186
wp-includes/shortcodes.php Normal file
View File

@ -0,0 +1,186 @@
<?php
/*
An API for creating shortcode tags that support attributes and enclosed content, such as:
[shortcode /]
[shortcode foo="bar" baz="bing" /]
[shortcode foo="bar"]content[/shortcode]
tag and attrbute parsing regexp code based on the Textpattern tag parser.
To apply shortcode tags to content:
$out = do_shortcode($content);
Simplest example of a shortcode tag using the API:
// [footag foo="bar"]
function footag_func($atts) {
return "foo = {$atts[foo]}";
}
add_shortcode('footag', 'footag_func');
Example with nice attribute defaults:
// [bartag foo="bar"]
function bartag_func($atts) {
extract(shortcode_atts(array(
'foo' => 'no foo',
'baz' => 'default baz',
), $atts));
return "foo = {$foo}";
}
add_shortcode('bartag', 'bartag_func');
Example with enclosed content:
// [baztag]content[/baztag]
function baztag_func($atts, $content='') {
return "content = $content";
}
add_shortcode('baztag', 'baztag_func');
*/
$shortcode_tags = array();
function add_shortcode($tag, $func) {
global $shortcode_tags;
if ( is_callable($func) )
$shortcode_tags[$tag] = $func;
}
function remove_shortcode($tag) {
global $shortcode_tags;
unset($shortcode_tags[$tag]);
}
function remove_all_shortcodes() {
global $shortcode_tags;
$shortcode_tags = array();
}
function do_shortcode($content) {
global $shortcode_tags;
if (empty($shortcode_tags) || !is_array($shortcode_tags))
return $content;
$tagnames = array_keys($shortcode_tags);
$tagregexp = join( '|', array_map('preg_quote', $tagnames) );
$pattern = '/\[('.$tagregexp.')\b(.*?)(?:(\/))?\](?:(.+?)\[\/\1\])?/s';
return preg_replace_callback($pattern, 'do_shortcode_tag', $content);
}
function do_shortcode_tag($m) {
global $shortcode_tags;
$tag = $m[1];
$attr = shortcode_parse_atts($m[2]);
if ( isset($m[4]) ) {
// enclosing tag - extra parameter
return call_user_func($shortcode_tags[$tag], $attr, $m[4]);
} else {
// self-closing tag
return call_user_func($shortcode_tags[$tag], $attr);
}
}
function shortcode_parse_atts($text) {
$atts = array();
$pattern = '/(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*\'([^\']*)\'(?:\s|$)|(\w+)\s*=\s*([^\s\'"]+)(?:\s|$)/';
if ( preg_match_all($pattern, $text, $match, PREG_SET_ORDER) ) {
foreach ($match as $m) {
if (!empty($m[1]))
$atts[strtolower($m[1])] = stripcslashes($m[2]);
elseif (!empty($m[3]))
$atts[strtolower($m[3])] = stripcslashes($m[4]);
elseif (!empty($m[5]))
$atts[strtolower($m[5])] = stripcslashes($m[6]);
}
}
return $atts;
}
function shortcode_atts($pairs, $atts) {
$out = array();
foreach($pairs as $name => $default) {
if ( array_key_exists($name, $atts) )
$out[$name] = $atts[$name];
else
$out[$name] = $default;
}
return $out;
}
add_shortcode('gallery', 'gallery_shortcode');
function gallery_shortcode($attr) {
global $post;
// Allow plugins/themes to override the default gallery template.
$output = apply_filters('post_gallery', '', $attr);
if ( $output != '' )
return $output;
$attachments = get_children("post_parent=$post->ID&post_type=attachment&orderby=\"menu_order ASC, ID ASC\"");
/*
foreach ( $attachments as $id => $attachment ) {
$meta = get_post_custom($id);
if ( $meta ) foreach ( $meta as $k => $v )
$attachments[$id]->$k = $v;
if ( isset($attachments[$id]->_wp_attachment_metadata[0]) )
$attachments[$id]->meta = unserialize($attachments[$id]->_wp_attachment_metadata[0]);
}
*/
$output = "
<style type='text/css'>
.gallery {
width: 450px;
left: 50%;
margin: auto;
}
.gallery div {
float: left;
margin-top: 10px;
text-align: center;
width: 33%; }
.gallery img {
border: 3px solid #cfcfcf;
}
</style>
<div class='gallery'>
";
if ( !empty($attachments) ) foreach ( $attachments as $id => $attachment ) {
$src = wp_get_attachment_thumb_url($id);
$href = get_attachment_link($id);
$output .= "
<div>
<a href='$href'><img src='$src' alt='$attachment->post_title' /></a>
</div>
";
if ( ++$i % 3 == 0 )
$output .= '<br style="clear: both" />';
}
$output .= "
</div>
";
return $output;
}
add_filter('the_content', 'do_shortcode');
?>

View File

@ -256,6 +256,7 @@ require (ABSPATH . WPINC . '/script-loader.php');
require (ABSPATH . WPINC . '/taxonomy.php');
require (ABSPATH . WPINC . '/update.php');
require (ABSPATH . WPINC . '/canonical.php');
require (ABSPATH . WPINC . '/shortcodes.php');
if (strpos($_SERVER['PHP_SELF'], 'install.php') === false) {
// Used to guarantee unique hash cookies