Skip to:
Content

BuddyPress.org

Changeset 13175


Ignore:
Timestamp:
12/11/2021 12:00:16 PM (5 years ago)
Author:
imath
Message:

Introduce a new method to the BP Attachment API to add file revisions

The BP_Attachment::add_revision() method is primarily used by the BP_Attachment_Avatar class to keep the history of previously uploaded user avatars (and potentially other objects avatar).

When a user uploads a new avatar, the previously uploaded one is moved inside an history subdirectory of the user's avatar directory. This avatars history is then available for the new_avatar activities to display the avatar the user had at the time these were published.

Props vapvarun, oztaser

See #8581

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-core/classes/class-bp-attachment-avatar.php

    r12588 r13175  
    200200         *
    201201         * @param array $args Array of arguments for the cropping.
    202          * @return array The cropped avatars (full and thumb).
     202         * @return array The cropped avatars (full, thumb and the timestamp).
    203203         */
    204204        public function crop( $args = array() ) {
     
    256256                /**
    257257                 * Check that the new avatar doesn't have the same name as the
    258                  * old one before deleting
     258                 * old one before moving the previous one into history.
    259259                 */
    260260                if ( ! empty( $existing_avatar ) && $existing_avatar !== $this->url . $relative_path ) {
    261                         bp_core_delete_existing_avatar( array( 'object' => $args['object'], 'item_id' => $args['item_id'], 'avatar_path' => $avatar_folder_dir ) );
     261                        // Add a new revision for the existing avatar.
     262                        $avatars = bp_attachments_list_directory_files( $avatar_folder_dir );
     263
     264                        if ( $avatars ) {
     265                                foreach ( $avatars as $avatar_file ) {
     266                                        if ( ! isset( $avatar_file->name, $avatar_file->id, $avatar_file->path ) ) {
     267                                                continue;
     268                                        }
     269
     270                                        $is_full  = preg_match( "/-bpfull/", $avatar_file->name );
     271                                        $is_thumb = preg_match( "/-bpthumb/", $avatar_file->name );
     272
     273                                        if ( $is_full || $is_thumb ) {
     274                                                $revision = $this->add_revision(
     275                                                        'avatar',
     276                                                        array(
     277                                                                'file_abspath' => $avatar_file->path,
     278                                                                'file_id'      => $avatar_file->id,
     279                                                        )
     280                                                );
     281
     282                                                if ( is_wp_error( $revision ) ) {
     283                                                        error_log( $revision->get_error_message() );
     284                                                }
     285                                        }
     286                                }
     287                        }
    262288                }
    263289
     
    273299                // Get the file extension.
    274300                $data = @getimagesize( $absolute_path );
    275                 $ext  = $data['mime'] == 'image/png' ? 'png' : 'jpg';
     301                $ext  = $data['mime'] === 'image/png' ? 'png' : 'jpg';
    276302
    277303                $args['original_file'] = $absolute_path;
    278304                $args['src_abs']       = false;
    279                 $avatar_types = array( 'full' => '', 'thumb' => '' );
     305
     306                $avatar_types = array(
     307                        'full'  => '',
     308                        'thumb' => '',
     309                );
     310                $timestamp   = bp_core_current_time( true, 'timestamp' );
    280311
    281312                foreach ( $avatar_types as $key_type => $type ) {
     
    288319                        }
    289320
    290                         $filename         = wp_unique_filename( $avatar_folder_dir, uniqid() . "-bp{$key_type}.{$ext}" );
     321                        $filename         = wp_unique_filename( $avatar_folder_dir, $timestamp . "-bp{$key_type}.{$ext}" );
    291322                        $args['dst_file'] = $avatar_folder_dir . '/' . $filename;
    292323
     
    297328                @unlink( $absolute_path );
    298329
    299                 // Return the full and thumb cropped avatars.
    300                 return $avatar_types;
     330                // Return the full, thumb cropped avatars and the timestamp.
     331                return array_merge(
     332                        $avatar_types,
     333                        array(
     334                                'timestamp' => $timestamp,
     335                        )
     336                );
    301337        }
    302338
     
    383419                                3 => __( 'There was a problem deleting your profile photo. Please try again.', 'buddypress' ),
    384420                                4 => __( 'Your profile photo was deleted successfully!', 'buddypress' ),
     421                                5 => __( 'Your profile photo was recycled successfully!', 'buddypress' ),
     422                                6 => __( 'The profile photo was permanently deleted successfully!', 'buddypress' ),
    385423                        );
    386424                } elseif ( ! empty( $group_id ) ) {
     
    401439                                3 => __( 'There was a problem deleting the group profile photo. Please try again.', 'buddypress' ),
    402440                                4 => __( 'The group profile photo was deleted successfully!', 'buddypress' ),
     441                                5 => __( 'The group profile photo was recycled successfully!', 'buddypress' ),
     442                                6 => __( 'The group profile photo was permanently deleted successfully!', 'buddypress' ),
    403443                        );
    404444                } else {
  • trunk/src/bp-core/classes/class-bp-attachment.php

    r13108 r13175  
    561561
    562562        /**
     563         * Adds a new revision of a file.
     564         *
     565         * @since 10.0.0
     566         *
     567         * @param string $attachment_type The attachement type (eg: avatar).
     568         * @param array $args {
     569         *     @type string $file_abspath The source file (absolute path) for the attachment.
     570         *     @type string $file_id      Optional. The file ID to use as a suffix for the revision directory.
     571         * }
     572         * @return object|WP_Error An object informing about the URL an Path to a revision file, a WP_Error object on failure.
     573         */
     574        public function add_revision( $attachment_type, $args = array() ) {
     575                $r = bp_parse_args(
     576                        $args,
     577                        array(
     578                                'file_abspath' => '',
     579                                'file_id'      => '',
     580                        ),
     581                        'attachment_' . $attachment_type . '_add_revision'
     582                );
     583
     584                if ( ! $r['file_abspath'] ) {
     585                        return new WP_Error( 'missing_parameter', __( 'The absolute path to your file is missing.', 'buddypress' ) );
     586
     587                        // Make sure it's coming from an uploaded file.
     588                } elseif ( false === strpos( $r['file_abspath'], $this->upload_path ) ) {
     589                        return new WP_Error( 'forbidden_path', __( 'The absolute path to your file is not allowed.', 'buddypress' ) );
     590
     591                } else {
     592                        $filepath = $r['file_abspath'];
     593                }
     594
     595                $dirname  = trailingslashit( dirname( $filepath ) );
     596                $filename = sanitize_file_name( wp_basename( $filepath ) );
     597
     598                if ( ! $r['file_id'] ) {
     599                        $r['file_id'] = $filename;
     600                }
     601
     602                $file_id = wp_hash( $r['file_id'] );
     603
     604                // Set the revision name & dir.
     605                $revision_name = '';
     606                $revision_dir  = $dirname . '._revisions_' . $file_id;
     607
     608                // Avatars and Cover Images are specific attachments.
     609                if ( 'avatar' === $attachment_type || 'cover_image' === $attachment_type ) {
     610                        $revision_dir  = $dirname . 'history';
     611                }
     612
     613                // Create the revision directory if it doesn't exist yet.
     614                if ( ! is_dir( $revision_dir ) ) {
     615                        mkdir( $revision_dir );
     616                }
     617
     618                $revision_name = wp_unique_filename( $revision_dir, $filename );
     619                $revision_path = trailingslashit( $revision_dir ) . $revision_name;
     620
     621                if ( ! rename( $filepath, $revision_path ) ) {
     622                        return new WP_Error( 'adding_revision_failed', __( 'An unexpected error occured while adding the revision.', 'buddypress' ) );
     623                }
     624
     625                return (object) array(
     626                        'url'  => str_replace( trailingslashit( $this->upload_path ), trailingslashit( $this->url ), $revision_path ),
     627                        'path' => $revision_path,
     628                );
     629        }
     630
     631        /**
    563632         * Get full data for an image
    564633         *
  • trunk/tests/phpunit/testcases/core/class-bp-attachment.php

    r12840 r13175  
    407407        }
    408408
     409        /**
     410         * @group add_revision
     411         */
     412        public function test_bp_attachment_add_revision() {
     413                if ( false === _wp_image_editor_choose() || version_compare( phpversion(), '7.0' , '<' ) ) {
     414                        $this->markTestSkipped( 'This test requires PHP >= 7.0 and to have a valid image editor that is compatible with WordPress.' );
     415                }
     416
     417                $image = BP_TESTS_DIR . 'assets/upside-down.jpg';
     418
     419                $attachment = new BPTest_Attachment_Extension(
     420                        array(
     421                                'base_dir'   => 'add_revision',
     422                                'action'     => 'attachment_action',
     423                                'file_input' => 'attachment_file_input',
     424                        )
     425                );
     426
     427                $abs_path_copy = $attachment->upload_path . '/upside-down.jpg';
     428                copy( $image, $abs_path_copy );
     429
     430                $revision = $attachment->add_revision(
     431                        'media',
     432                        array(
     433                                'file_abspath' => $abs_path_copy,
     434                                'file_id'      => 'media',
     435                        )
     436                );
     437
     438                $this->assertFalse( file_exists( $abs_path_copy ) );
     439                $this->assertTrue( file_exists( $revision->path ) );
     440
     441                // Cleanup
     442                @unlink( $revision->path );
     443                @rmdir( dirname( $revision->path ) );
     444                $this->clean_files( 'add_revision' );
     445        }
     446
     447        /**
     448         * @group add_revision
     449         * @group avatars
     450         */
     451        public function test_bp_attachment_add_avatar_history() {
     452                if ( false === _wp_image_editor_choose() || version_compare( phpversion(), '7.0' , '<' ) ) {
     453                        $this->markTestSkipped( 'This test requires PHP >= 7.0 and to have a valid image editor that is compatible with WordPress.' );
     454                }
     455
     456                $image = BP_TESTS_DIR . 'assets/upside-down.jpg';
     457
     458                $attachment = new BPTest_Attachment_Extension(
     459                        array(
     460                                'base_dir'   => 'add_history',
     461                                'action'     => 'attachment_action',
     462                                'file_input' => 'attachment_file_input',
     463                        )
     464                );
     465
     466                $abs_path_copy = $attachment->upload_path . '/upside-down.jpg';
     467                copy( $image, $abs_path_copy );
     468
     469                $revision = $attachment->add_revision(
     470                        'avatar',
     471                        array(
     472                                'file_abspath' => $abs_path_copy,
     473                                'file_id'      => 'avatar',
     474                        )
     475                );
     476
     477                $this->assertFalse( file_exists( $abs_path_copy ) );
     478                $this->assertTrue( file_exists( $revision->path ) );
     479                $this->assertSame( $attachment->url . '/history/upside-down.jpg', $revision->url );
     480
     481                // Cleanup
     482                @unlink( $revision->path );
     483                @rmdir( dirname( $revision->path ) );
     484                $this->clean_files( 'add_history' );
     485        }
     486
    409487        public function limit_to_50px( $max_width ) {
    410488                return 50;
Note: See TracChangeset for help on using the changeset viewer.