/**
 * Ajax Upload and set a cover image
 *
 * @since  2.4.0
 *
 * @return  string|null A json object containing success data if the upload succeeded
 *                      error message otherwise.
 */
function bp_attachments_cover_image_ajax_upload()
{
    // Bail if not a POST action
    if ('POST' !== strtoupper($_SERVER['REQUEST_METHOD'])) {
        wp_die();
    }
    /**
     * Sending the json response will be different if
     * the current Plupload runtime is html4
     */
    $is_html4 = false;
    if (!empty($_POST['html4'])) {
        $is_html4 = true;
    }
    // Check the nonce
    check_admin_referer('bp-uploader');
    // Init the BuddyPress parameters
    $bp_params = array();
    // We need it to carry on
    if (!empty($_POST['bp_params'])) {
        $bp_params = bp_parse_args($_POST['bp_params'], array('object' => 'user', 'item_id' => bp_loggedin_user_id()), 'attachments_cover_image_ajax_upload');
    } else {
        bp_attachments_json_response(false, $is_html4);
    }
    // We need the object to set the uploads dir filter
    if (empty($bp_params['object'])) {
        bp_attachments_json_response(false, $is_html4);
    }
    // Capability check
    if (!bp_attachments_current_user_can('edit_cover_image', $bp_params)) {
        bp_attachments_json_response(false, $is_html4);
    }
    $bp = buddypress();
    $needs_reset = array();
    // Member's cover image
    if ('user' === $bp_params['object']) {
        $object_data = array('dir' => 'members', 'component' => 'xprofile');
        if (!bp_displayed_user_id() && !empty($bp_params['item_id'])) {
            $needs_reset = array('key' => 'displayed_user', 'value' => $bp->displayed_user);
            $bp->displayed_user->id = $bp_params['item_id'];
        }
        // Group's cover image
    } elseif ('group' === $bp_params['object']) {
        $object_data = array('dir' => 'groups', 'component' => 'groups');
        if (!bp_get_current_group_id() && !empty($bp_params['item_id'])) {
            $needs_reset = array('component' => 'groups', 'key' => 'current_group', 'value' => $bp->groups->current_group);
            $bp->groups->current_group = groups_get_group(array('group_id' => $bp_params['item_id'], 'populate_extras' => false));
        }
        // Other object's cover image
    } else {
        $object_data = apply_filters('bp_attachments_cover_image_object_dir', array(), $bp_params['object']);
    }
    // Stop here in case of a missing parameter for the object
    if (empty($object_data['dir']) || empty($object_data['component'])) {
        bp_attachments_json_response(false, $is_html4);
    }
    $cover_image_attachment = new BP_Attachment_Cover_Image();
    $uploaded = $cover_image_attachment->upload($_FILES);
    // Reset objects
    if (!empty($needs_reset)) {
        if (!empty($needs_reset['component'])) {
            $bp->{$needs_reset['component']}->{$needs_reset['key']} = $needs_reset['value'];
        } else {
            $bp->{$needs_reset['key']} = $needs_reset['value'];
        }
    }
    if (!empty($uploaded['error'])) {
        // Upload error response
        bp_attachments_json_response(false, $is_html4, array('type' => 'upload_error', 'message' => sprintf(__('Upload Failed! Error was: %s', 'buddypress'), $uploaded['error'])));
    }
    // Default error message
    $error_message = __('There was a problem uploading the cover image.', 'buddypress');
    // Get BuddyPress Attachments Uploads Dir datas
    $bp_attachments_uploads_dir = bp_attachments_uploads_dir_get();
    // The BP Attachments Uploads Dir is not set, stop.
    if (!$bp_attachments_uploads_dir) {
        bp_attachments_json_response(false, $is_html4, array('type' => 'upload_error', 'message' => $error_message));
    }
    $cover_subdir = $object_data['dir'] . '/' . $bp_params['item_id'] . '/cover-image';
    $cover_dir = trailingslashit($bp_attachments_uploads_dir['basedir']) . $cover_subdir;
    if (!is_dir($cover_dir)) {
        // Upload error response
        bp_attachments_json_response(false, $is_html4, array('type' => 'upload_error', 'message' => $error_message));
    }
    /**
     * Generate the cover image so that it fit to feature's dimensions
     *
     * Unlike the Avatar, Uploading and generating the cover image is happening during
     * the same Ajax request, as we already instantiated the BP_Attachment_Cover_Image
     * class, let's use it.
     */
    $cover = bp_attachments_cover_image_generate_file(array('file' => $uploaded['file'], 'component' => $object_data['component'], 'cover_image_dir' => $cover_dir), $cover_image_attachment);
    if (!$cover) {
        // Upload error response
        bp_attachments_json_response(false, $is_html4, array('type' => 'upload_error', 'message' => $error_message));
    }
    // Build the url to the file
    $cover_url = trailingslashit($bp_attachments_uploads_dir['baseurl']) . $cover_subdir . '/' . $cover['cover_basename'];
    // Init Feedback code, 1 is success
    $feedback_code = 1;
    // 0 is the size warning
    if ($cover['is_too_small']) {
        $feedback_code = 0;
    }
    // Set the name of the file
    $name = $_FILES['file']['name'];
    $name_parts = pathinfo($name);
    $name = trim(substr($name, 0, -(1 + strlen($name_parts['extension']))));
    /**
     * Fires if the new cover image was successfully uploaded.
     *
     * The dynamic portion of the hook will be xprofile in case of a user's
     * cover image, groups in case of a group's cover image. For instance:
     * Use add_action( 'xprofile_cover_image_uploaded' ) to run your specific
     * code once the user has set his cover image.
     *
     * @since 2.4.0
     *
     * @param int $item_id Inform about the item id the cover image was set for.
     */
    do_action($object_data['component'] . '_cover_image_uploaded', (int) $bp_params['item_id']);
    // Finally return the cover image url to the UI
    bp_attachments_json_response(true, $is_html4, array('name' => $name, 'url' => $cover_url, 'feedback_code' => $feedback_code));
}
 /**
  * @group upload
  * @group cover_images
  */
 public function test_bp_attachment_upload_dir_filter_arg()
 {
     $reset_files = $_FILES;
     $reset_post = $_POST;
     $attachment_class = new BPTest_Attachment_Extension(array('action' => 'attachment_action', 'file_input' => 'attachment_file_input', 'base_dir' => 'attachment_base_dir', 'upload_dir_filter_args' => 1));
     $_POST['action'] = $attachment_class->action;
     $_FILES[$attachment_class->file_input] = array('tmp_name' => $this->image_file, 'name' => 'mystery-man.jpg', 'type' => 'image/jpeg', 'error' => 0, 'size' => filesize($this->image_file));
     // Simulate an upload
     $attachment_class->upload($_FILES);
     // Remove the filter used to fake uploads
     remove_filter('upload_dir', array($this, 'filter_upload_dir'), 20, 1);
     $this->assertSame($attachment_class->original_upload_dir, wp_upload_dir());
     // Restore the filter used to fake uploads
     add_filter('upload_dir', array($this, 'filter_upload_dir'), 20, 1);
     $this->assertTrue(1 === $attachment_class->upload_dir_filter_args);
     $cover_image_class = new BP_Attachment_Cover_Image();
     // Simulate an upload
     $cover_image_class->upload($_FILES);
     // Should be empty
     $this->assertEmpty($this->original_upload_dir);
     $this->assertTrue(0 === $cover_image_class->upload_dir_filter_args);
     $_FILES = $reset_files;
     $_POST = $reset_post;
 }