Skip to:
Content

BuddyPress.org

Changeset 9758


Ignore:
Timestamp:
04/16/2015 10:45:58 PM (4 years ago)
Author:
imath
Message:

Avatar UI: Add Ajax functions to upload/crop/capture and delete avatars. Enqueue the needed Avatar scripts and css.

bp_core_avatar_scripts() will enqueue the scripts only if editing an avatar on front-end and if the user avatar uploads are not disabled. The hooks to maximize backward theme compatibility are localized in this function.

See #6290

Location:
trunk/src/bp-core
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-core/bp-core-avatars.php

    r9757 r9758  
    721721
    722722/**
     723 * Ajax delete an avatar for a given object and item id
     724 *
     725 * @since  BuddyPress (2.3.0)
     726 *
     727 * @return  string a json object containing success data if the avatar was deleted
     728 *                 error message otherwise
     729 */
     730function bp_avatar_ajax_delete() {
     731    // Bail if not a POST action
     732    if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) ) {
     733        wp_send_json_error();
     734    }
     735
     736    $avatar_data = $_POST;
     737
     738    if ( empty( $avatar_data['object'] ) || empty( $avatar_data['item_id'] ) ) {
     739        wp_send_json_error();
     740    }
     741
     742    $nonce = 'bp_delete_avatar_link';
     743    if ( 'group' === $avatar_data['object'] ) {
     744        $nonce = 'bp_group_avatar_delete';
     745    }
     746
     747    // Check the nonce
     748    check_admin_referer( $nonce, 'nonce' );
     749
     750    // Capability check
     751    if ( ! bp_attachments_current_user_can( 'edit_avatar', $avatar_data ) ) {
     752        wp_send_json_error();
     753    }
     754
     755    // Handle delete
     756    if ( bp_core_delete_existing_avatar( array( 'item_id' => $avatar_data['item_id'], 'object' => $avatar_data['object'] ) ) ) {
     757        $return = array(
     758            'avatar' => html_entity_decode( bp_core_fetch_avatar( array(
     759                'object'  => $avatar_data['object'],
     760                'item_id' => $avatar_data['item_id'],
     761                'html'    => false,
     762                'type'    => 'full',
     763            ) ) ),
     764            'feedback_code' => 4,
     765            'item_id'       => $avatar_data['item_id'],
     766        );
     767
     768        wp_send_json_success( $return );
     769    } else {
     770        wp_send_json_error( array(
     771            'feedback_code' => 3,
     772        ) );
     773    }
     774}
     775add_action( 'wp_ajax_bp_avatar_delete', 'bp_avatar_ajax_delete' );
     776
     777/**
    723778 * Handle avatar uploading.
    724779 *
     
    797852
    798853    return true;
     854}
     855
     856/**
     857 * Ajax upload an avatar
     858 *
     859 * @since BuddyPress (2.3.0)
     860 *
     861 * @return  string a json object containing success data if the upload succeeded
     862 *                 error message otherwise
     863 */
     864function bp_avatar_ajax_upload() {
     865    // Bail if not a POST action
     866    if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) ) {
     867        wp_die();
     868    }
     869
     870    /**
     871     * Sending the json response will be different if
     872     * the current Plupload runtime is html4
     873     */
     874    $is_html4 = false;
     875    if ( ! empty( $_POST['html4' ] ) ) {
     876        $is_html4 = true;
     877    }
     878
     879    // Check the nonce
     880    check_admin_referer( 'bp-uploader' );
     881
     882    // Init the BuddyPress parameters
     883    $bp_params = array();
     884
     885    // We need it to carry on
     886    if ( ! empty( $_POST['bp_params' ] ) ) {
     887        $bp_params = $_POST['bp_params' ];
     888    } else {
     889        bp_attachments_json_response( false, $is_html4 );
     890    }
     891
     892    // We need the object to set the uploads dir filter
     893    if ( empty( $bp_params['object'] ) ) {
     894        bp_attachments_json_response( false, $is_html4 );
     895    }
     896
     897    // Capability check
     898    if ( ! bp_attachments_current_user_can( 'edit_avatar', $bp_params ) ) {
     899        bp_attachments_json_response( false, $is_html4 );
     900    }
     901
     902    $bp = buddypress();
     903    $bp_params['upload_dir_filter'] = '';
     904    $needs_reset = array();
     905
     906    if ( 'user' === $bp_params['object'] && bp_is_active( 'xprofile' ) ) {
     907        $bp_params['upload_dir_filter'] = 'xprofile_avatar_upload_dir';
     908
     909        if ( ! bp_displayed_user_id() && ! empty( $bp_params['item_id'] ) ) {
     910            $needs_reset = array( 'key' => 'displayed_user', 'value' => $bp->displayed_user );
     911            $bp->displayed_user->id = $bp_params['item_id'];
     912        }
     913    } elseif ( 'group' === $bp_params['object'] && bp_is_active( 'groups' ) ) {
     914        $bp_params['upload_dir_filter'] = 'groups_avatar_upload_dir';
     915
     916        if ( ! bp_get_current_group_id() && ! empty( $bp_params['item_id'] ) ) {
     917            $needs_reset = array( 'component' => 'groups', 'key' => 'current_group', 'value' => $bp->groups->current_group );
     918            $bp->groups->current_group = groups_get_group( array(
     919                'group_id'        => $bp_params['item_id'],
     920                'populate_extras' => false,
     921            ) );
     922        }
     923    } else {
     924        /**
     925         * Filter here to deal with other components
     926         *
     927         * @since BuddyPress (2.3.0)
     928         *
     929         * @var array $bp_params the BuddyPress Ajax parameters
     930         */
     931        $bp_params = apply_filters( 'bp_core_avatar_ajax_upload_params', $bp_params );
     932    }
     933
     934    if ( ! isset( $bp->avatar_admin ) ) {
     935        $bp->avatar_admin = new stdClass();
     936    }
     937
     938    // Upload the avatar
     939    $avatar = bp_core_avatar_handle_upload( $_FILES, $bp_params['upload_dir_filter'] );
     940
     941    // Reset objects
     942    if ( ! empty( $needs_reset ) ) {
     943        if ( ! empty( $needs_reset['component'] ) ) {
     944            $bp->{$needs_reset['component']}->{$needs_reset['key']} = $needs_reset['value'];
     945        } else {
     946            $bp->{$needs_reset['key']} = $needs_reset['value'];
     947        }
     948    }
     949
     950    if ( empty( $avatar ) ) {
     951        // Default upload error
     952        $message = array();
     953
     954        // Intercept the template message and remove it
     955        if ( ! empty( $bp->template_message ) ) {
     956            // Set the feedback message
     957            $message = array(
     958                'type'    => 'upload_error',
     959                'message' => $bp->template_message,
     960            );
     961
     962            // Remove template message.
     963            $bp->template_message      = false;
     964            $bp->template_message_type = false;
     965            @setcookie( 'bp-message', false, time() - 1000, COOKIEPATH );
     966            @setcookie( 'bp-message-type', false, time() - 1000, COOKIEPATH );
     967        }
     968
     969        bp_attachments_json_response( false, $is_html4, $message );
     970    }
     971
     972    if ( empty( $bp->avatar_admin->image->file ) ) {
     973        bp_attachments_json_response( false, $is_html4 );
     974    }
     975
     976    $uploaded_image = @getimagesize( $bp->avatar_admin->image->file );
     977
     978    // Set the name of the file
     979    $name = $_FILES['file']['name'];
     980    $name_parts = pathinfo( $name );
     981    $name = trim( substr( $name, 0, - ( 1 + strlen( $name_parts['extension'] ) ) ) );
     982
     983    if ( 'user' === $bp_params['object'] ) {
     984        do_action( 'xprofile_avatar_uploaded' );
     985    }
     986
     987    // Finally return the avatar to the editor
     988    bp_attachments_json_response( true, $is_html4, array(
     989        'name'      => $name,
     990        'url'       => $bp->avatar_admin->image->url,
     991        'width'     => $uploaded_image[0],
     992        'height'    => $uploaded_image[1],
     993    ) );
     994}
     995add_action( 'wp_ajax_bp_avatar_upload', 'bp_avatar_ajax_upload' );
     996
     997 /**
     998 * Handle avatar webcam capture.
     999 *
     1000 * @since BuddyPress (2.3.0)
     1001 *
     1002 * @param string $data base64 encoded image.
     1003 * @param int $item_id.
     1004 * @return bool True on success, false on failure.
     1005 */
     1006function bp_avatar_handle_capture( $data = '', $item_id = 0 ) {
     1007    if ( empty( $data ) || empty( $item_id ) ) {
     1008        return false;
     1009    }
     1010
     1011    $avatar_dir = bp_core_avatar_upload_path() . '/avatars';
     1012
     1013    // It's not a regular upload, we may need to create this folder
     1014    if ( ! file_exists( $avatar_dir ) ) {
     1015        if ( ! wp_mkdir_p( $avatar_dir ) ) {
     1016            return false;
     1017        }
     1018    }
     1019
     1020    $avatar_folder_dir = apply_filters( 'bp_core_avatar_folder_dir', $avatar_dir . '/' . $item_id, $item_id, 'user', 'avatars' );
     1021
     1022    // It's not a regular upload, we may need to create this folder
     1023    if( ! is_dir( $avatar_folder_dir ) ) {
     1024        if ( ! wp_mkdir_p( $avatar_folder_dir ) ) {
     1025            return false;
     1026        }
     1027    }
     1028
     1029    $original_file = $avatar_folder_dir . '/webcam-capture-' . $item_id . '.png';
     1030
     1031    if ( file_put_contents( $original_file, $data ) ) {
     1032        $avatar_to_crop = str_replace( bp_core_avatar_upload_path(), '', $original_file );
     1033
     1034        // Crop to default values
     1035        $crop_args = array( 'item_id' => $item_id, 'original_file' => $avatar_to_crop, 'crop_x' => 0, 'crop_y' => 0 );
     1036
     1037        do_action( 'xprofile_avatar_uploaded' );
     1038
     1039        return bp_core_avatar_handle_crop( $crop_args );
     1040    } else {
     1041        return false;
     1042    }
    7991043}
    8001044
     
    8701114
    8711115/**
     1116 * Ajax set an avatar for a given object and item id
     1117 *
     1118 * @since BuddyPress (2.3.0)
     1119 *
     1120 * @return  string a json object containing success data if the crop/capture succeeded
     1121 *                 error message otherwise
     1122 */
     1123function bp_avatar_ajax_set() {
     1124    // Bail if not a POST action
     1125    if ( 'POST' !== strtoupper( $_SERVER['REQUEST_METHOD'] ) ) {
     1126        wp_send_json_error();
     1127    }
     1128
     1129    // Check the nonce
     1130    check_admin_referer( 'bp_avatar_cropstore', 'nonce' );
     1131
     1132    $avatar_data = wp_parse_args( $_POST, array(
     1133        'crop_w' => bp_core_avatar_full_width(),
     1134        'crop_h' => bp_core_avatar_full_height(),
     1135        'crop_x' => 0,
     1136        'crop_y' => 0
     1137    ) );
     1138
     1139    if ( empty( $avatar_data['object'] ) || empty( $avatar_data['item_id'] ) || empty( $avatar_data['original_file'] ) ) {
     1140        wp_send_json_error();
     1141    }
     1142
     1143    // Capability check
     1144    if ( ! bp_attachments_current_user_can( 'edit_avatar', $avatar_data ) ) {
     1145        wp_send_json_error();
     1146    }
     1147
     1148    if ( ! empty( $avatar_data['type'] ) && 'camera' === $avatar_data['type'] && 'user' === $avatar_data['object'] ) {
     1149        $webcam_avatar = false;
     1150
     1151        if ( ! empty( $avatar_data['original_file'] ) ) {
     1152            $webcam_avatar = str_replace( array( 'data:image/png;base64,', ' ' ), array( '', '+' ), $avatar_data['original_file'] );
     1153            $webcam_avatar = base64_decode( $webcam_avatar );
     1154        }
     1155
     1156        if ( ! bp_avatar_handle_capture( $webcam_avatar, $avatar_data['item_id'] ) ) {
     1157            wp_send_json_error( array(
     1158                'feedback_code' => 1
     1159            ) );
     1160
     1161        } else {
     1162            $return = array(
     1163                'avatar' => html_entity_decode( bp_core_fetch_avatar( array(
     1164                    'object'  => $avatar_data['object'],
     1165                    'item_id' => $avatar_data['item_id'],
     1166                    'html'    => false,
     1167                    'type'    => 'full',
     1168                ) ) ),
     1169                'feedback_code' => 2,
     1170                'item_id'       => $avatar_data['item_id'],
     1171            );
     1172
     1173            do_action( 'xprofile_screen_change_avatar' );
     1174
     1175            wp_send_json_success( $return );
     1176        }
     1177
     1178        return;
     1179    }
     1180
     1181    $original_file = str_replace( bp_core_avatar_url(), '', $avatar_data['original_file'] );
     1182
     1183    // Set avatars dir & feedback part
     1184    if ( 'user' === $avatar_data['object'] ) {
     1185        $avatar_dir = 'avatars';
     1186
     1187    // Defaults to object-avatars dir
     1188    } else {
     1189        $avatar_dir = sanitize_key( $avatar_data['object'] ) . '-avatars';
     1190    }
     1191
     1192    // Crop args
     1193    $r = array(
     1194        'item_id'       => $avatar_data['item_id'],
     1195        'object'        => $avatar_data['object'],
     1196        'avatar_dir'    => $avatar_dir,
     1197        'original_file' => $original_file,
     1198        'crop_w'        => $avatar_data['crop_w'],
     1199        'crop_h'        => $avatar_data['crop_h'],
     1200        'crop_x'        => $avatar_data['crop_x'],
     1201        'crop_y'        => $avatar_data['crop_y']
     1202    );
     1203
     1204    // Handle crop
     1205    if ( bp_core_avatar_handle_crop( $r ) ) {
     1206        $return = array(
     1207            'avatar' => html_entity_decode( bp_core_fetch_avatar( array(
     1208                'object'  => $avatar_data['object'],
     1209                'item_id' => $avatar_data['item_id'],
     1210                'html'    => false,
     1211                'type'    => 'full',
     1212            ) ) ),
     1213            'feedback_code' => 2,
     1214            'item_id'       => $avatar_data['item_id'],
     1215        );
     1216
     1217        if ( 'user' === $avatar_data['object'] ) {
     1218            do_action( 'xprofile_screen_change_avatar' );
     1219        }
     1220
     1221        wp_send_json_success( $return );
     1222    } else {
     1223        wp_send_json_error( array(
     1224            'feedback_code' => 1,
     1225        ) );
     1226    }
     1227}
     1228add_action( 'wp_ajax_bp_avatar_set', 'bp_avatar_ajax_set' );
     1229
     1230/**
    8721231 * Replace default WordPress avatars with BP avatars, if available.
    8731232 *
     
    14561815 *
    14571816 * If the "avatar templates" are not including the new template tag, this will
    1458  * help users to get the avatar UI and inform the most curious that their
    1459  * templates are out of date.
     1817 * help users to get the avatar UI.
    14601818 *
    14611819 * @since  BuddyPress (2.3.0)
  • trunk/src/bp-core/bp-core-cssjs.php

    r9754 r9758  
    121121
    122122/**
     123 * Enqueues the css and js required by the Avatar UI
     124 *
     125 * @since  BuddyPress (2.3.0)
     126 */
     127function bp_core_avatar_scripts() {
     128    if ( ! bp_avatar_is_front_edit() ) {
     129        return false;
     130    }
     131
     132    // Enqueue the Attachments scripts for the Avatar UI
     133    bp_attachments_enqueue_scripts( 'BP_Attachment_Avatar' );
     134
     135    // Add Some actions for Theme backcompat
     136    add_action( 'bp_after_profile_avatar_upload_content', 'bp_avatar_template_check' );
     137    add_action( 'bp_after_group_admin_content',           'bp_avatar_template_check' );
     138    add_action( 'bp_after_group_avatar_creation_step',    'bp_avatar_template_check' );
     139}
     140add_action( 'bp_enqueue_scripts', 'bp_core_avatar_scripts' );
     141
     142/**
    123143 * Enqueues jCrop library and hooks BP's custom cropper JS.
    124144 */
Note: See TracChangeset for help on using the changeset viewer.