예제 #1
0
파일: post.php 프로젝트: nxtclass/NXTClass
/**
 * Retrieve thumbnail for an attachment.
 *
 * @since 2.1.0
 *
 * @param int $post_id Attachment ID.
 * @return mixed False on failure. Thumbnail file path on success.
 */
function nxt_get_attachment_thumb_file($post_id = 0)
{
    $post_id = (int) $post_id;
    if (!($post =& get_post($post_id))) {
        return false;
    }
    if (!is_array($imagedata = nxt_get_attachment_metadata($post->ID))) {
        return false;
    }
    $file = get_attached_file($post->ID);
    if (!empty($imagedata['thumb']) && ($thumbfile = str_replace(basename($file), $imagedata['thumb'], $file)) && file_exists($thumbfile)) {
        return apply_filters('nxt_get_attachment_thumb_file', $thumbfile, $post->ID);
    }
    return false;
}
예제 #2
0
								<div class="entry-caption"><?php 
        if (!empty($post->post_excerpt)) {
            the_excerpt();
        }
        ?>
</div>
								<?php 
        the_content();
        ?>
							</div>

							<p class="postmetadata">
								<?php 
        if (nxt_attachment_is_image()) {
            $metadata = nxt_get_attachment_metadata();
            printf(__('Full size is %s pixels', 'buddypress'), sprintf('<a href="%1$s" title="%2$s">%3$s &times; %4$s</a>', nxt_get_attachment_url(), esc_attr(__('Link to full size image', 'buddypress')), $metadata['width'], $metadata['height']));
        }
        ?>
								&nbsp;
							</p>
						</div>

					</div>

					<?php 
        do_action('bp_after_blog_post');
        ?>

					<?php 
        comments_template();
예제 #3
0
파일: media.php 프로젝트: nxtclass/NXTClass
/**
 * Retrieve HTML form for modifying the image attachment.
 *
 * @since 2.5.0
 *
 * @param int $attachment_id Attachment ID for modification.
 * @param string|array $args Optional. Override defaults.
 * @return string HTML form for attachment.
 */
function get_media_item($attachment_id, $args = null)
{
    global $redir_tab;
    if (($attachment_id = intval($attachment_id)) && ($thumb_url = nxt_get_attachment_image_src($attachment_id, 'thumbnail', true))) {
        $thumb_url = $thumb_url[0];
    } else {
        $thumb_url = false;
    }
    $post = get_post($attachment_id);
    $current_post_id = !empty($_GET['post_id']) ? (int) $_GET['post_id'] : 0;
    $default_args = array('errors' => null, 'send' => $current_post_id ? post_type_supports(get_post_type($current_post_id), 'editor') : true, 'delete' => true, 'toggle' => true, 'show_title' => true);
    $args = nxt_parse_args($args, $default_args);
    $args = apply_filters('get_media_item_args', $args);
    extract($args, EXTR_SKIP);
    $toggle_on = __('Show');
    $toggle_off = __('Hide');
    $filename = esc_html(basename($post->guid));
    $title = esc_attr($post->post_title);
    if ($_tags = get_the_tags($attachment_id)) {
        foreach ($_tags as $tag) {
            $tags[] = $tag->name;
        }
        $tags = esc_attr(join(', ', $tags));
    }
    $post_mime_types = get_post_mime_types();
    $keys = array_keys(nxt_match_mime_types(array_keys($post_mime_types), $post->post_mime_type));
    $type = array_shift($keys);
    $type_html = "<input type='hidden' id='type-of-{$attachment_id}' value='" . esc_attr($type) . "' />";
    $form_fields = get_attachment_fields_to_edit($post, $errors);
    if ($toggle) {
        $class = empty($errors) ? 'startclosed' : 'startopen';
        $toggle_links = "\n\t<a class='toggle describe-toggle-on' href='#'>{$toggle_on}</a>\n\t<a class='toggle describe-toggle-off' href='#'>{$toggle_off}</a>";
    } else {
        $class = '';
        $toggle_links = '';
    }
    $display_title = !empty($title) ? $title : $filename;
    // $title shouldn't ever be empty, but just in case
    $display_title = $show_title ? "<div class='filename new'><span class='title'>" . nxt_html_excerpt($display_title, 60) . "</span></div>" : '';
    $gallery = isset($_REQUEST['tab']) && 'gallery' == $_REQUEST['tab'] || isset($redir_tab) && 'gallery' == $redir_tab;
    $order = '';
    foreach ($form_fields as $key => $val) {
        if ('menu_order' == $key) {
            if ($gallery) {
                $order = "<div class='menu_order'> <input class='menu_order_input' type='text' id='attachments[{$attachment_id}][menu_order]' name='attachments[{$attachment_id}][menu_order]' value='" . esc_attr($val['value']) . "' /></div>";
            } else {
                $order = "<input type='hidden' name='attachments[{$attachment_id}][menu_order]' value='" . esc_attr($val['value']) . "' />";
            }
            unset($form_fields['menu_order']);
            break;
        }
    }
    $media_dims = '';
    $meta = nxt_get_attachment_metadata($post->ID);
    if (is_array($meta) && array_key_exists('width', $meta) && array_key_exists('height', $meta)) {
        $media_dims .= "<span id='media-dims-{$post->ID}'>{$meta['width']}&nbsp;&times;&nbsp;{$meta['height']}</span> ";
    }
    $media_dims = apply_filters('media_meta', $media_dims, $post);
    $image_edit_button = '';
    if (gd_edit_image_support($post->post_mime_type)) {
        $nonce = nxt_create_nonce("image_editor-{$post->ID}");
        $image_edit_button = "<input type='button' id='imgedit-open-btn-{$post->ID}' onclick='imageEdit.open( {$post->ID}, \"{$nonce}\" )' class='button' value='" . esc_attr__('Edit Image') . "' /> <img src='" . esc_url(admin_url('images/nxtspin_light.gif')) . "' class='imgedit-wait-spin' alt='' />";
    }
    $attachment_url = get_permalink($attachment_id);
    $item = "\n\t{$type_html}\n\t{$toggle_links}\n\t{$order}\n\t{$display_title}\n\t<table class='slidetoggle describe {$class}'>\n\t\t<thead class='media-item-info' id='media-head-{$post->ID}'>\n\t\t<tr valign='top'>\n\t\t\t<td class='A1B1' id='thumbnail-head-{$post->ID}'>\n\t\t\t<p><a href='{$attachment_url}' target='_blank'><img class='thumbnail' src='{$thumb_url}' alt='' /></a></p>\n\t\t\t<p>{$image_edit_button}</p>\n\t\t\t</td>\n\t\t\t<td>\n\t\t\t<p><strong>" . __('File name:') . "</strong> {$filename}</p>\n\t\t\t<p><strong>" . __('File type:') . "</strong> {$post->post_mime_type}</p>\n\t\t\t<p><strong>" . __('Upload date:') . "</strong> " . mysql2date(get_option('date_format'), $post->post_date) . '</p>';
    if (!empty($media_dims)) {
        $item .= "<p><strong>" . __('Dimensions:') . "</strong> {$media_dims}</p>\n";
    }
    $item .= "</td></tr>\n";
    $item .= "\n\t\t</thead>\n\t\t<tbody>\n\t\t<tr><td colspan='2' class='imgedit-response' id='imgedit-response-{$post->ID}'></td></tr>\n\t\t<tr><td style='display:none' colspan='2' class='image-editor' id='image-editor-{$post->ID}'></td></tr>\n";
    $defaults = array('input' => 'text', 'required' => false, 'value' => '', 'extra_rows' => array());
    if ($send) {
        $send = get_submit_button(__('Insert into Post'), 'button', "send[{$attachment_id}]", false);
    }
    if ($delete && current_user_can('delete_post', $attachment_id)) {
        if (!EMPTY_TRASH_DAYS) {
            $delete = "<a href='" . nxt_nonce_url("post.php?action=delete&amp;post={$attachment_id}", 'delete-attachment_' . $attachment_id) . "' id='del[{$attachment_id}]' class='delete'>" . __('Delete Permanently') . '</a>';
        } elseif (!MEDIA_TRASH) {
            $delete = "<a href='#' class='del-link' onclick=\"document.getElementById('del_attachment_{$attachment_id}').style.display='block';return false;\">" . __('Delete') . "</a>\n\t\t\t <div id='del_attachment_{$attachment_id}' class='del-attachment' style='display:none;'>" . sprintf(__('You are about to delete <strong>%s</strong>.'), $filename) . "\n\t\t\t <a href='" . nxt_nonce_url("post.php?action=delete&amp;post={$attachment_id}", 'delete-attachment_' . $attachment_id) . "' id='del[{$attachment_id}]' class='button'>" . __('Continue') . "</a>\n\t\t\t <a href='#' class='button' onclick=\"this.parentNode.style.display='none';return false;\">" . __('Cancel') . "</a>\n\t\t\t </div>";
        } else {
            $delete = "<a href='" . nxt_nonce_url("post.php?action=trash&amp;post={$attachment_id}", 'trash-attachment_' . $attachment_id) . "' id='del[{$attachment_id}]' class='delete'>" . __('Move to Trash') . "</a>\n\t\t\t<a href='" . nxt_nonce_url("post.php?action=untrash&amp;post={$attachment_id}", 'untrash-attachment_' . $attachment_id) . "' id='undo[{$attachment_id}]' class='undo hidden'>" . __('Undo') . "</a>";
        }
    } else {
        $delete = '';
    }
    $thumbnail = '';
    $calling_post_id = 0;
    if (isset($_GET['post_id'])) {
        $calling_post_id = absint($_GET['post_id']);
    } elseif (isset($_POST) && count($_POST)) {
        // Like for async-upload where $_GET['post_id'] isn't set
        $calling_post_id = $post->post_parent;
    }
    if ('image' == $type && $calling_post_id && current_theme_supports('post-thumbnails', get_post_type($calling_post_id)) && post_type_supports(get_post_type($calling_post_id), 'thumbnail') && get_post_thumbnail_id($calling_post_id) != $attachment_id) {
        $ajax_nonce = nxt_create_nonce("set_post_thumbnail-{$calling_post_id}");
        $thumbnail = "<a class='nxt-post-thumbnail' id='nxt-post-thumbnail-" . $attachment_id . "' href='#' onclick='nxtSetAsThumbnail(\"{$attachment_id}\", \"{$ajax_nonce}\");return false;'>" . esc_html__("Use as featured image") . "</a>";
    }
    if (($send || $thumbnail || $delete) && !isset($form_fields['buttons'])) {
        $form_fields['buttons'] = array('tr' => "\t\t<tr class='submit'><td></td><td class='savesend'>{$send} {$thumbnail} {$delete}</td></tr>\n");
    }
    $hidden_fields = array();
    foreach ($form_fields as $id => $field) {
        if ($id[0] == '_') {
            continue;
        }
        if (!empty($field['tr'])) {
            $item .= $field['tr'];
            continue;
        }
        $field = array_merge($defaults, $field);
        $name = "attachments[{$attachment_id}][{$id}]";
        if ($field['input'] == 'hidden') {
            $hidden_fields[$name] = $field['value'];
            continue;
        }
        $required = $field['required'] ? '<span class="alignright"><abbr title="required" class="required">*</abbr></span>' : '';
        $aria_required = $field['required'] ? " aria-required='true' " : '';
        $class = $id;
        $class .= $field['required'] ? ' form-required' : '';
        $item .= "\t\t<tr class='{$class}'>\n\t\t\t<th valign='top' scope='row' class='label'><label for='{$name}'><span class='alignleft'>{$field['label']}</span>{$required}<br class='clear' /></label></th>\n\t\t\t<td class='field'>";
        if (!empty($field[$field['input']])) {
            $item .= $field[$field['input']];
        } elseif ($field['input'] == 'textarea') {
            if (user_can_richedit()) {
                // textarea_escaped when user_can_richedit() = false
                $field['value'] = esc_textarea($field['value']);
            }
            $item .= "<textarea id='{$name}' name='{$name}' {$aria_required}>" . $field['value'] . '</textarea>';
        } else {
            $item .= "<input type='text' class='text' id='{$name}' name='{$name}' value='" . esc_attr($field['value']) . "' {$aria_required} />";
        }
        if (!empty($field['helps'])) {
            $item .= "<p class='help'>" . join("</p>\n<p class='help'>", array_unique((array) $field['helps'])) . '</p>';
        }
        $item .= "</td>\n\t\t</tr>\n";
        $extra_rows = array();
        if (!empty($field['errors'])) {
            foreach (array_unique((array) $field['errors']) as $error) {
                $extra_rows['error'][] = $error;
            }
        }
        if (!empty($field['extra_rows'])) {
            foreach ($field['extra_rows'] as $class => $rows) {
                foreach ((array) $rows as $html) {
                    $extra_rows[$class][] = $html;
                }
            }
        }
        foreach ($extra_rows as $class => $rows) {
            foreach ($rows as $html) {
                $item .= "\t\t<tr><td></td><td class='{$class}'>{$html}</td></tr>\n";
            }
        }
    }
    if (!empty($form_fields['_final'])) {
        $item .= "\t\t<tr class='final'><td colspan='2'>{$form_fields['_final']}</td></tr>\n";
    }
    $item .= "\t</tbody>\n";
    $item .= "\t</table>\n";
    foreach ($hidden_fields as $name => $value) {
        $item .= "\t<input type='hidden' name='{$name}' id='{$name}' value='" . esc_attr($value) . "' />\n";
    }
    if ($post->post_parent < 1 && isset($_REQUEST['post_id'])) {
        $parent = (int) $_REQUEST['post_id'];
        $parent_name = "attachments[{$attachment_id}][post_parent]";
        $item .= "\t<input type='hidden' name='{$parent_name}' id='{$parent_name}' value='{$parent}' />\n";
    }
    return $item;
}
예제 #4
0
파일: media.php 프로젝트: nxtclass/NXTClass
/**
 * Retrieve the image's intermediate size (resized) path, width, and height.
 *
 * The $size parameter can be an array with the width and height respectively.
 * If the size matches the 'sizes' metadata array for width and height, then it
 * will be used. If there is no direct match, then the nearest image size larger
 * than the specified size will be used. If nothing is found, then the function
 * will break out and return false.
 *
 * The metadata 'sizes' is used for compatible sizes that can be used for the
 * parameter $size value.
 *
 * The url path will be given, when the $size parameter is a string.
 *
 * If you are passing an array for the $size, you should consider using
 * add_image_size() so that a cropped version is generated. It's much more
 * efficient than having to find the closest-sized image and then having the
 * browser scale down the image.
 *
 * @since 2.5.0
 * @see add_image_size()
 *
 * @param int $post_id Attachment ID for image.
 * @param array|string $size Optional, default is 'thumbnail'. Size of image, either array or string.
 * @return bool|array False on failure or array of file path, width, and height on success.
 */
function image_get_intermediate_size($post_id, $size = 'thumbnail')
{
    if (!is_array($imagedata = nxt_get_attachment_metadata($post_id))) {
        return false;
    }
    // get the best one for a specified set of dimensions
    if (is_array($size) && !empty($imagedata['sizes'])) {
        foreach ($imagedata['sizes'] as $_size => $data) {
            // already cropped to width or height; so use this size
            if ($data['width'] == $size[0] && $data['height'] <= $size[1] || $data['height'] == $size[1] && $data['width'] <= $size[0]) {
                $file = $data['file'];
                list($width, $height) = image_constrain_size_for_editor($data['width'], $data['height'], $size);
                return compact('file', 'width', 'height');
            }
            // add to lookup table: area => size
            $areas[$data['width'] * $data['height']] = $_size;
        }
        if (!$size || !empty($areas)) {
            // find for the smallest image not smaller than the desired size
            ksort($areas);
            foreach ($areas as $_size) {
                $data = $imagedata['sizes'][$_size];
                if ($data['width'] >= $size[0] || $data['height'] >= $size[1]) {
                    // Skip images with unexpectedly divergent aspect ratios (crops)
                    // First, we calculate what size the original image would be if constrained to a box the size of the current image in the loop
                    $maybe_cropped = image_resize_dimensions($imagedata['width'], $imagedata['height'], $data['width'], $data['height'], false);
                    // If the size doesn't match within one pixel, then it is of a different aspect ratio, so we skip it, unless it's the thumbnail size
                    if ('thumbnail' != $_size && (!$maybe_cropped || $maybe_cropped[4] != $data['width'] && $maybe_cropped[4] + 1 != $data['width'] || $maybe_cropped[5] != $data['height'] && $maybe_cropped[5] + 1 != $data['height'])) {
                        continue;
                    }
                    // If we're still here, then we're going to use this size
                    $file = $data['file'];
                    list($width, $height) = image_constrain_size_for_editor($data['width'], $data['height'], $size);
                    return compact('file', 'width', 'height');
                }
            }
        }
    }
    if (is_array($size) || empty($size) || empty($imagedata['sizes'][$size])) {
        return false;
    }
    $data = $imagedata['sizes'][$size];
    // include the full filesystem path of the intermediate file
    if (empty($data['path']) && !empty($data['file'])) {
        $file_url = nxt_get_attachment_url($post_id);
        $data['path'] = path_join(dirname($imagedata['file']), $data['file']);
        $data['url'] = path_join(dirname($file_url), $data['file']);
    }
    return $data;
}
예제 #5
0
 /**
  * Retrieve a media item by ID
  *
  * @since 3.1.0
  *
  * @param array $args Method parameters. Contains:
  *  - blog_id
  *  - username
  *  - password
  *  - attachment_id
  * @return array. Associative array containing:
  *  - 'date_created_gmt'
  *  - 'parent'
  *  - 'link'
  *  - 'thumbnail'
  *  - 'title'
  *  - 'caption'
  *  - 'description'
  *  - 'metadata'
  */
 function nxt_getMediaItem($args)
 {
     $this->escape($args);
     $blog_id = (int) $args[0];
     $username = $args[1];
     $password = $args[2];
     $attachment_id = (int) $args[3];
     if (!($user = $this->login($username, $password))) {
         return $this->error;
     }
     if (!current_user_can('upload_files')) {
         return new IXR_Error(403, __('You are not allowed to upload files to this site.'));
     }
     do_action('xmlrpc_call', 'nxt.getMediaItem');
     if (!($attachment = get_post($attachment_id))) {
         return new IXR_Error(404, __('Invalid attachment ID.'));
     }
     // Format page date.
     $attachment_date = mysql2date('Ymd\\TH:i:s', $attachment->post_date, false);
     $attachment_date_gmt = mysql2date('Ymd\\TH:i:s', $attachment->post_date_gmt, false);
     $link = nxt_get_attachment_url($attachment->ID);
     $thumbnail_link = nxt_get_attachment_thumb_url($attachment->ID);
     $attachment_struct = array('date_created_gmt' => new IXR_Date($attachment_date_gmt), 'parent' => $attachment->post_parent, 'link' => $link, 'thumbnail' => $thumbnail_link, 'title' => $attachment->post_title, 'caption' => $attachment->post_excerpt, 'description' => $attachment->post_content, 'metadata' => nxt_get_attachment_metadata($attachment->ID));
     return $attachment_struct;
 }
예제 #6
0
파일: post.php 프로젝트: nxtclass/NXTClass
     }
     $title = $post_type_object->labels->edit_item;
     $post = get_post_to_edit($post_id);
     if (post_type_supports($post_type, 'comments')) {
         nxt_enqueue_script('admin-comments');
         enqueue_comment_hotkeys_js();
     }
     include './edit-form-advanced.php';
     break;
 case 'editattachment':
     check_admin_referer('update-attachment_' . $post_id);
     // Don't let these be changed
     unset($_POST['guid']);
     $_POST['post_type'] = 'attachment';
     // Update the thumbnail filename
     $newmeta = nxt_get_attachment_metadata($post_id, true);
     $newmeta['thumb'] = $_POST['thumb'];
     nxt_update_attachment_metadata($post_id, $newmeta);
 case 'editpost':
     check_admin_referer('update-' . $post_type . '_' . $post_id);
     $post_id = edit_post();
     redirect_post($post_id);
     // Send user on their way while we keep working
     exit;
     break;
 case 'trash':
     check_admin_referer('trash-' . $post_type . '_' . $post_id);
     $post =& get_post($post_id);
     if (!current_user_can($post_type_object->cap->delete_post, $post_id)) {
         nxt_die(__('You are not allowed to move this item to the Trash.'));
     }
예제 #7
0
/**
 * {@internal Missing Short Description}}
 *
 * @since 2.0.0
 *
 * @param unknown_type $id
 * @return unknown
 */
function the_attachment_links($id = false)
{
    $id = (int) $id;
    $post =& get_post($id);
    if ($post->post_type != 'attachment') {
        return false;
    }
    $icon = nxt_get_attachment_image($post->ID, 'thumbnail', true);
    $attachment_data = nxt_get_attachment_metadata($id);
    $thumb = isset($attachment_data['thumb']);
    ?>
<form id="the-attachment-links">
<table>
	<col />
	<col class="widefat" />
	<tr>
		<th scope="row"><?php 
    _e('URL');
    ?>
</th>
		<td><textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><?php 
    echo esc_textarea(nxt_get_attachment_url());
    ?>
</textarea></td>
	</tr>
<?php 
    if ($icon) {
        ?>
	<tr>
		<th scope="row"><?php 
        $thumb ? _e('Thumbnail linked to file') : _e('Image linked to file');
        ?>
</th>
		<td><textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php 
        echo nxt_get_attachment_url();
        ?>
"><?php 
        echo $icon;
        ?>
</a></textarea></td>
	</tr>
	<tr>
		<th scope="row"><?php 
        $thumb ? _e('Thumbnail linked to page') : _e('Image linked to page');
        ?>
</th>
		<td><textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php 
        echo get_attachment_link($post->ID);
        ?>
" rel="attachment nxt-att-<?php 
        echo $post->ID;
        ?>
"><?php 
        echo $icon;
        ?>
</a></textarea></td>
	</tr>
<?php 
    } else {
        ?>
	<tr>
		<th scope="row"><?php 
        _e('Link to file');
        ?>
</th>
		<td><textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php 
        echo nxt_get_attachment_url();
        ?>
" class="attachmentlink"><?php 
        echo basename(nxt_get_attachment_url());
        ?>
</a></textarea></td>
	</tr>
	<tr>
		<th scope="row"><?php 
        _e('Link to page');
        ?>
</th>
		<td><textarea rows="1" cols="40" type="text" class="attachmentlinks" readonly="readonly"><a href="<?php 
        echo get_attachment_link($post->ID);
        ?>
" rel="attachment nxt-att-<?php 
        echo $post->ID;
        ?>
"><?php 
        the_title();
        ?>
</a></textarea></td>
	</tr>
<?php 
    }
    ?>
</table>
</form>
<?php 
}
예제 #8
0
function nxt_save_image($post_id)
{
    $return = new stdClass();
    $success = $delete = $scaled = $nocrop = false;
    $post = get_post($post_id);
    @ini_set('memory_limit', apply_filters('admin_memory_limit', nxt_MAX_MEMORY_LIMIT));
    $img = load_image_to_edit($post_id, $post->post_mime_type);
    if (!is_resource($img)) {
        $return->error = esc_js(__('Unable to create new image.'));
        return $return;
    }
    $fwidth = !empty($_REQUEST['fwidth']) ? intval($_REQUEST['fwidth']) : 0;
    $fheight = !empty($_REQUEST['fheight']) ? intval($_REQUEST['fheight']) : 0;
    $target = !empty($_REQUEST['target']) ? preg_replace('/[^a-z0-9_-]+/i', '', $_REQUEST['target']) : '';
    $scale = !empty($_REQUEST['do']) && 'scale' == $_REQUEST['do'];
    if ($scale && $fwidth > 0 && $fheight > 0) {
        $sX = imagesx($img);
        $sY = imagesy($img);
        // check if it has roughly the same w / h ratio
        $diff = round($sX / $sY, 2) - round($fwidth / $fheight, 2);
        if (-0.1 < $diff && $diff < 0.1) {
            // scale the full size image
            $dst = nxt_imagecreatetruecolor($fwidth, $fheight);
            if (imagecopyresampled($dst, $img, 0, 0, 0, 0, $fwidth, $fheight, $sX, $sY)) {
                imagedestroy($img);
                $img = $dst;
                $scaled = true;
            }
        }
        if (!$scaled) {
            $return->error = esc_js(__('Error while saving the scaled image. Please reload the page and try again.'));
            return $return;
        }
    } elseif (!empty($_REQUEST['history'])) {
        $changes = json_decode(stripslashes($_REQUEST['history']));
        if ($changes) {
            $img = image_edit_apply_changes($img, $changes);
        }
    } else {
        $return->error = esc_js(__('Nothing to save, the image has not changed.'));
        return $return;
    }
    $meta = nxt_get_attachment_metadata($post_id);
    $backup_sizes = get_post_meta($post->ID, '_nxt_attachment_backup_sizes', true);
    if (!is_array($meta)) {
        $return->error = esc_js(__('Image data does not exist. Please re-upload the image.'));
        return $return;
    }
    if (!is_array($backup_sizes)) {
        $backup_sizes = array();
    }
    // generate new filename
    $path = get_attached_file($post_id);
    $path_parts = pathinfo($path);
    $filename = $path_parts['filename'];
    $suffix = time() . rand(100, 999);
    if (defined('IMAGE_EDIT_OVERWRITE') && IMAGE_EDIT_OVERWRITE && isset($backup_sizes['full-orig']) && $backup_sizes['full-orig']['file'] != $path_parts['basename']) {
        if ('thumbnail' == $target) {
            $new_path = "{$path_parts['dirname']}/{$filename}-temp.{$path_parts['extension']}";
        } else {
            $new_path = $path;
        }
    } else {
        while (true) {
            $filename = preg_replace('/-e([0-9]+)$/', '', $filename);
            $filename .= "-e{$suffix}";
            $new_filename = "{$filename}.{$path_parts['extension']}";
            $new_path = "{$path_parts['dirname']}/{$new_filename}";
            if (file_exists($new_path)) {
                $suffix++;
            } else {
                break;
            }
        }
    }
    // save the full-size file, also needed to create sub-sizes
    if (!nxt_save_image_file($new_path, $img, $post->post_mime_type, $post_id)) {
        $return->error = esc_js(__('Unable to save the image.'));
        return $return;
    }
    if ('nothumb' == $target || 'all' == $target || 'full' == $target || $scaled) {
        $tag = false;
        if (isset($backup_sizes['full-orig'])) {
            if ((!defined('IMAGE_EDIT_OVERWRITE') || !IMAGE_EDIT_OVERWRITE) && $backup_sizes['full-orig']['file'] != $path_parts['basename']) {
                $tag = "full-{$suffix}";
            }
        } else {
            $tag = 'full-orig';
        }
        if ($tag) {
            $backup_sizes[$tag] = array('width' => $meta['width'], 'height' => $meta['height'], 'file' => $path_parts['basename']);
        }
        $success = update_attached_file($post_id, $new_path);
        $meta['file'] = _nxt_relative_upload_path($new_path);
        $meta['width'] = imagesx($img);
        $meta['height'] = imagesy($img);
        list($uwidth, $uheight) = nxt_constrain_dimensions($meta['width'], $meta['height'], 128, 96);
        $meta['hwstring_small'] = "height='{$uheight}' width='{$uwidth}'";
        if ($success && ('nothumb' == $target || 'all' == $target)) {
            $sizes = get_intermediate_image_sizes();
            if ('nothumb' == $target) {
                $sizes = array_diff($sizes, array('thumbnail'));
            }
        }
        $return->fw = $meta['width'];
        $return->fh = $meta['height'];
    } elseif ('thumbnail' == $target) {
        $sizes = array('thumbnail');
        $success = $delete = $nocrop = true;
    }
    if (isset($sizes)) {
        foreach ($sizes as $size) {
            $tag = false;
            if (isset($meta['sizes'][$size])) {
                if (isset($backup_sizes["{$size}-orig"])) {
                    if ((!defined('IMAGE_EDIT_OVERWRITE') || !IMAGE_EDIT_OVERWRITE) && $backup_sizes["{$size}-orig"]['file'] != $meta['sizes'][$size]['file']) {
                        $tag = "{$size}-{$suffix}";
                    }
                } else {
                    $tag = "{$size}-orig";
                }
                if ($tag) {
                    $backup_sizes[$tag] = $meta['sizes'][$size];
                }
            }
            $crop = $nocrop ? false : get_option("{$size}_crop");
            $resized = image_make_intermediate_size($new_path, get_option("{$size}_size_w"), get_option("{$size}_size_h"), $crop);
            if ($resized) {
                $meta['sizes'][$size] = $resized;
            } else {
                unset($meta['sizes'][$size]);
            }
        }
    }
    if ($success) {
        nxt_update_attachment_metadata($post_id, $meta);
        update_post_meta($post_id, '_nxt_attachment_backup_sizes', $backup_sizes);
        if ($target == 'thumbnail' || $target == 'all' || $target == 'full') {
            $file_url = nxt_get_attachment_url($post_id);
            if ($thumb = $meta['sizes']['thumbnail']) {
                $return->thumbnail = path_join(dirname($file_url), $thumb['file']);
            } else {
                $return->thumbnail = "{$file_url}?w=128&h=128";
            }
        }
    } else {
        $delete = true;
    }
    if ($delete) {
        $delpath = apply_filters('nxt_delete_file', $new_path);
        @unlink($delpath);
    }
    imagedestroy($img);
    $return->msg = esc_js(__('Image saved'));
    return $return;
}