Skip to:
Content

BuddyPress.org

Ticket #6278: 6278.10.patch

File 6278.10.patch, 14.9 KB (added by imath, 4 years ago)
  • src/bp-core/classes/class-bp-attachment-avatar.php

    diff --git src/bp-core/classes/class-bp-attachment-avatar.php src/bp-core/classes/class-bp-attachment-avatar.php
    index 389e546..5ea1bd1 100644
    class BP_Attachment_Avatar extends BP_Attachment { 
    2828         * @uses BP_Attachment::__construct()
    2929         */
    3030        public function __construct() {
     31                // Allowed avatar types
     32                $allowed_types = bp_core_get_allowed_avatar_types();
     33
    3134                parent::__construct( array(
    3235                        'action'                => 'bp_avatar_upload',
    3336                        'file_input'            => 'file',
    class BP_Attachment_Avatar extends BP_Attachment { 
    3639                        // Specific errors for avatars
    3740                        'upload_error_strings'  => array(
    3841                                9  => sprintf( __( 'That photo is too big. Please upload one smaller than %s', 'buddypress' ), size_format( bp_core_avatar_original_max_filesize() ) ),
    39                                 10 => __( 'Please upload only JPG, GIF or PNG photos.', 'buddypress' ),
     42                                10 => sprintf( _n( 'Please upload only this file type: %s.', 'Please upload only these file types: %s.', count( $allowed_types ), 'buddypress' ), self::get_avatar_types( $allowed_types ) ),
    4043                        ),
    4144                ) );
    4245        }
    4346
    4447        /**
     48         * Gets the available avatar types
     49         *
     50         * @since BuddyPress (2.3.0)
     51         * @return string comma separated list of allowed avatar types
     52         */
     53        public static function get_avatar_types( $allowed_types = array() ) {
     54                $types = array_map( 'strtoupper', $allowed_types );
     55                $comma = _x( ',', 'avatar types separator', 'buddypress' );
     56                return join( $comma . ' ', $types );
     57        }
     58
     59        /**
    4560         * Set Upload Dir data for avatars
    4661         *
    4762         * @since BuddyPress (2.3.0)
  • src/bp-core/classes/class-bp-attachment.php

    diff --git src/bp-core/classes/class-bp-attachment.php src/bp-core/classes/class-bp-attachment.php
    index 4d6365d..e4e625f 100644
    abstract class BP_Attachment { 
    219219                 */
    220220                add_filter( "{$this->action}_prefilter", array( $this, 'validate_upload' ), 10, 1 );
    221221
     222                /**
     223                 * The above dynamic filter was introduced in WordPress 4.0, as we support WordPress
     224                 * back to 3.6, we need to also use the pre 4.0 static filter and remove it after
     225                 * the upload was processed.
     226                 */
     227                add_filter( 'wp_handle_upload_prefilter', array( $this, 'validate_upload' ), 10, 1 );
     228
    222229                // Set Default overrides
    223230                $overrides = array(
    224231                        'action'               => $this->action,
    abstract class BP_Attachment { 
    265272                // Restore WordPress Uploads data
    266273                remove_filter( 'upload_dir', $upload_dir_filter, 10, 0 );
    267274
     275                // Remove the pre WordPress 4.0 static filter
     276                remove_filter( 'wp_handle_upload_prefilter', array( $this, 'validate_upload' ), 10, 1 );
     277
    268278                // Finally return the uploaded file or the error
    269279                return $this->attachment;
    270280        }
  • tests/phpunit/assets/attachment-extensions.php

    diff --git tests/phpunit/assets/attachment-extensions.php tests/phpunit/assets/attachment-extensions.php
    index e69de29..9981683 100644
     
     1<?php
     2/**
     3 * The following implementations of BP_Attachment act as dummy plugins
     4 * for our unit tests
     5 */
     6class BPTest_Attachment_Extension extends BP_Attachment {
     7        public function __construct( $args = array() ) {
     8                return parent::__construct( $args );
     9        }
     10}
  • tests/phpunit/includes/testcase.php

    diff --git tests/phpunit/includes/testcase.php tests/phpunit/includes/testcase.php
    index d14fe76..e44248c 100644
    class BP_UnitTestCase extends WP_UnitTestCase { 
    423423                global $wpdb;
    424424                $wpdb->query( 'COMMIT;' );
    425425        }
     426
     427        /**
     428         * Clean up created directories/files
     429         */
     430        public function rrmdir( $dir ) {
     431                // Make sure we are only removing files/dir from uploads
     432                if ( 0 !== strpos( $dir, bp_core_avatar_upload_path() ) ) {
     433                        return;
     434                }
     435
     436                $d = glob( $dir . '/*' );
     437
     438                if ( ! empty( $d ) ) {
     439                        foreach ( $d as $file ) {
     440                                if ( is_dir( $file ) ) {
     441                                        $this->rrmdir( $file );
     442                                } else {
     443                                        @unlink( $file );
     444                                }
     445                        }
     446                }
     447
     448                @rmdir( $dir );
     449        }
    426450}
  • tests/phpunit/testcases/core/avatars.php

    diff --git tests/phpunit/testcases/core/avatars.php tests/phpunit/testcases/core/avatars.php
    index 9fab304..89b477b 100644
    class BP_Tests_Avatars extends BP_UnitTestCase { 
    1616                $this->rrmdir( bp_core_avatar_upload_path() . '/' . $avatar_dir );
    1717        }
    1818
    19         private function rrmdir( $dir ) {
    20                 $d = glob( $dir . '/*' );
    21 
    22                 if ( empty( $d ) ) {
    23                         return;
    24                 }
    25 
    26                 foreach ( $d as $file ) {
    27                         if ( is_dir( $file ) ) {
    28                                 $this->rrmdir( $file );
    29                         } else {
    30                                 @unlink( $file );
    31                         }
    32                 }
    33 
    34                 @rmdir( $dir );
    35         }
    36 
    3719        /**
    3820         * @ticket BP4948
    3921         */
  • tests/phpunit/testcases/core/class-bp-attachment.php

    diff --git tests/phpunit/testcases/core/class-bp-attachment.php tests/phpunit/testcases/core/class-bp-attachment.php
    index e69de29..7ffd358 100644
     
     1<?php
     2
     3include_once BP_TESTS_DIR . 'assets/attachment-extensions.php';
     4
     5/**
     6 * @group bp_attachments
     7 * @group BP_Attachment
     8 */
     9class BP_Tests_BP_Attachment_TestCases extends BP_UnitTestCase {
     10        private $upload_results;
     11        private $image_file;
     12
     13        public function setUp() {
     14                parent::setUp();
     15                add_filter( 'bp_attachment_upload_overrides', array( $this, 'filter_overrides' ),  10, 1 );
     16                add_filter( 'bp_attachment_upload_dir',       array( $this, 'filter_upload_dir' ), 10, 1 );
     17                add_filter( 'xprofile_avatar_upload_dir',     array( $this, 'filter_upload_dir' ), 10, 1 );
     18                add_filter( 'groups_avatar_upload_dir',       array( $this, 'filter_upload_dir' ), 10, 1 );
     19                $this->upload_results = array();
     20                $this->image_file = trailingslashit( buddypress()->plugin_dir ) . 'bp-core/images/mystery-man.jpg';
     21        }
     22
     23        public function tearDown() {
     24                parent::tearDown();
     25                remove_filter( 'bp_attachment_upload_overrides', array( $this, 'filter_overrides' ),  10, 1 );
     26                remove_filter( 'bp_attachment_upload_dir',       array( $this, 'filter_upload_dir' ), 10, 1 );
     27                remove_filter( 'xprofile_avatar_upload_dir',     array( $this, 'filter_upload_dir' ), 10, 1 );
     28                remove_filter( 'groups_avatar_upload_dir',       array( $this, 'filter_upload_dir' ), 10, 1 );
     29                $this->upload_results = array();
     30                $this->image_file = '';
     31        }
     32
     33        public function filter_overrides( $overrides ) {
     34                $overrides['upload_error_handler'] = array( $this, 'upload_error_handler' );
     35
     36                // Don't test upload for WordPress < 4.0
     37                $overrides['test_upload'] = false;
     38                return $overrides;
     39        }
     40
     41        public function filter_upload_dir( $upload_dir ) {
     42                $upload_dir['error'] = 'fake_upload_success';
     43
     44                $this->upload_results = array(
     45                        'new_file' => $upload_dir['path'] . '/mystery-man.jpg',
     46                        'url'      => $upload_dir['url'] . '/mystery-man.jpg',
     47                );
     48
     49                return $upload_dir;
     50        }
     51
     52        /**
     53         * To avoid copying files in tests, we're faking a succesfull uploads
     54         * as soon as all the test_form have been executed in _wp_handle_upload
     55         */
     56        public function upload_error_handler( &$file, $message ) {
     57                if ( 'fake_upload_success' !== $message ) {
     58                        return array( 'error' => $message );
     59                } else {
     60                        return array(
     61                                'file' => $this->upload_results['new_file'],
     62                                'url'  => $this->upload_results['url'],
     63                                'type' => 'image/jpeg',
     64                        );
     65                }
     66        }
     67
     68        private function clean_files( $basedir = 'attachment_base_dir' ) {
     69                $upload_dir = bp_upload_dir();
     70
     71                $this->rrmdir( $upload_dir['basedir'] . '/' . $basedir );
     72        }
     73
     74        private function clean_avatars( $type = 'user' ) {
     75                if ( 'user' === $type ) {
     76                        $avatar_dir = 'avatars';
     77                } elseif ( 'group' === $type ) {
     78                        $avatar_dir = 'group-avatars';
     79                }
     80
     81                $this->rrmdir( bp_core_avatar_upload_path() . '/' . $avatar_dir );
     82        }
     83
     84        public function max_filesize() {
     85                return 1000;
     86        }
     87
     88        public function test_bp_attachment_construct_missing_required_parameter() {
     89                $reset_files = $_FILES;
     90                $reset_post = $_POST;
     91
     92                $_FILES['file'] = array(
     93                        'name'     => 'mystery-man.jpg',
     94                        'type'     => 'image/jpeg',
     95                        'error'    => 0,
     96                        'size'     => 1000
     97                );
     98
     99                $attachment_class = new BPTest_Attachment_Extension();
     100                $upload = $attachment_class->upload( $_FILES );
     101
     102                $this->assertTrue( empty( $upload ) );
     103
     104                $_FILES = $reset_files;
     105                $_POST = $reset_post;
     106        }
     107
     108        public function test_bp_attachment_set_upload_dir() {
     109                $upload_dir = bp_upload_dir();
     110
     111                $attachment_class = new BPTest_Attachment_Extension( array(
     112                        'action'     => 'attachment_action',
     113                        'file_input' => 'attachment_file_input'
     114                ) );
     115
     116                $this->assertSame( $attachment_class->upload_dir, bp_upload_dir() );
     117
     118                $attachment_class = new BPTest_Attachment_Extension( array(
     119                        'action'     => 'attachment_action',
     120                        'file_input' => 'attachment_file_input',
     121                        'base_dir'   => 'attachment_base_dir',
     122                ) );
     123
     124                $this->assertTrue( file_exists( $upload_dir['basedir'] . '/attachment_base_dir'  ) );
     125
     126                // clean up
     127                $this->clean_files();
     128        }
     129
     130        /**
     131         * @group upload
     132         */
     133        public function test_bp_attachment_upload() {
     134                $reset_files = $_FILES;
     135                $reset_post = $_POST;
     136
     137                $attachment_class = new BPTest_Attachment_Extension( array(
     138                        'action'                => 'attachment_action',
     139                        'file_input'            => 'attachment_file_input',
     140                        'base_dir'                  => 'attachment_base_dir',
     141                        'original_max_filesize' => 1000,
     142                ) );
     143
     144                $_POST['action'] = $attachment_class->action;
     145                $_FILES[ $attachment_class->file_input ] = array(
     146                        'tmp_name' => $this->image_file,
     147                        'name'     => 'mystery-man.jpg',
     148                        'type'     => 'image/jpeg',
     149                        'error'    => 0,
     150                        'size'     => filesize( $this->image_file ),
     151                );
     152
     153                // Error: file size
     154                $upload = $attachment_class->upload( $_FILES );
     155                $this->assertFalse( empty( $upload['error'] ) );
     156
     157                $attachment_class->allowed_mime_types    = array( 'pdf' );
     158                $attachment_class->original_max_filesize = false;
     159
     160                // Error: file type
     161                $upload = $attachment_class->upload( $_FILES );
     162                $this->assertFalse( empty( $upload['error'] ) );
     163
     164                $attachment_class->allowed_mime_types = array();
     165
     166                // Success
     167                $upload = $attachment_class->upload( $_FILES );
     168                $this->assertEquals( $upload['file'], $attachment_class->upload_path . '/mystery-man.jpg' );
     169
     170                // clean up!
     171                $_FILES = $reset_files;
     172                $_POST = $reset_post;
     173                $this->clean_files();
     174        }
     175
     176        /**
     177         * @group upload
     178         * @group avatar
     179         */
     180        public function test_bp_attachment_avatar_user_upload() {
     181                $reset_files = $_FILES;
     182                $reset_post = $_POST;
     183                $bp = buddypress();
     184                $displayed_user = $bp->displayed_user;
     185                $bp->displayed_user = new stdClass;
     186
     187                $u1 = $this->factory->user->create();
     188                $bp->displayed_user->id = $u1;
     189
     190                // Upload the file
     191                $avatar_attachment = new BP_Attachment_Avatar();
     192                $_POST['action'] = $avatar_attachment->action;
     193                $_FILES[ $avatar_attachment->file_input ] = array(
     194                        'tmp_name' => $this->image_file,
     195                        'name'     => 'mystery-man.jpg',
     196                        'type'     => 'image/jpeg',
     197                        'error'    => 0,
     198                        'size'     => filesize( $this->image_file )
     199                );
     200
     201                /* No error */
     202                $user_avatar = $avatar_attachment->upload( $_FILES, 'xprofile_avatar_upload_dir' );
     203                $this->assertEquals( $user_avatar['file'], $bp->avatar->upload_path . '/avatars/' . $u1 .'/mystery-man.jpg' );
     204
     205                /* File size error */
     206                add_filter( 'bp_core_avatar_original_max_filesize', array( $this, 'max_filesize' ) );
     207
     208                $user_avatar = $avatar_attachment->upload( $_FILES, 'xprofile_avatar_upload_dir' );
     209
     210                remove_filter( 'bp_core_avatar_original_max_filesize', array( $this, 'max_filesize' ) );
     211                $this->assertFalse( empty( $user_avatar['error'] ) );
     212
     213                /* File type error */
     214                $_FILES[ $avatar_attachment->file_input ]['name'] = 'buddypress_logo.pdf';
     215                $_FILES[ $avatar_attachment->file_input ]['type'] = 'application/pdf';
     216
     217                $user_avatar = $avatar_attachment->upload( $_FILES, 'xprofile_avatar_upload_dir' );
     218                $this->assertFalse( empty( $user_avatar['error'] ) );
     219
     220                // clean up!
     221                $bp->displayed_user = $displayed_user;
     222                $this->clean_avatars();
     223                $_FILES = $reset_files;
     224                $_POST = $reset_post;
     225        }
     226
     227        /**
     228         * @group upload
     229         * @group avatar
     230         */
     231        public function test_bp_attachment_avatar_group_upload() {
     232                $bp = buddypress();
     233                $reset_files = $_FILES;
     234                $reset_post = $_POST;
     235                $reset_current_group = $bp->groups->current_group;
     236
     237                $g = $this->factory->group->create();
     238
     239                $bp->groups->current_group = groups_get_group( array(
     240                        'group_id'        => $g,
     241                        'populate_extras' => true,
     242                ) );
     243
     244                // Upload the file
     245                $avatar_attachment = new BP_Attachment_Avatar();
     246                $_POST['action'] = $avatar_attachment->action;
     247                $_FILES[ $avatar_attachment->file_input ] = array(
     248                        'tmp_name' => $this->image_file,
     249                        'name'     => 'mystery-man.jpg',
     250                        'type'     => 'image/jpeg',
     251                        'error'    => 0,
     252                        'size'     => filesize( $this->image_file )
     253                );
     254
     255                $group_avatar = $avatar_attachment->upload( $_FILES, 'groups_avatar_upload_dir' );
     256                $this->assertEquals( $group_avatar['file'], $bp->avatar->upload_path . '/group-avatars/' . $g .'/mystery-man.jpg' );
     257
     258                // clean up!
     259                $this->clean_avatars( 'group' );
     260                $bp->groups->current_group = $reset_current_group;
     261                $_FILES = $reset_files;
     262                $_POST = $reset_post;
     263        }
     264
     265        /**
     266         * @group crop
     267         */
     268        public function test_bp_attachment_crop() {
     269                $crop_args = array(
     270                        'original_file' => $this->image_file,
     271                        'crop_x'        => 0,
     272                        'crop_y'        => 0,
     273                        'crop_w'        => 150,
     274                        'crop_h'        => 150,
     275                        'dst_w'         => 150,
     276                        'dst_h'         => 150,
     277                );
     278
     279                $attachment_class = new BPTest_Attachment_Extension( array(
     280                        'action'                => 'attachment_action',
     281                        'file_input'            => 'attachment_file_input',
     282                        'base_dir'                  => 'attachment_base_dir',
     283                ) );
     284
     285                $cropped = $attachment_class->crop( $crop_args );
     286
     287                // Image must come from the upload basedir
     288                $this->assertTrue( is_wp_error( $cropped ) );
     289
     290                $crop_args['original_file'] = $attachment_class->upload_path . '/mystery-man.jpg';
     291
     292                // Image must stay in the upload basedir
     293                $crop_args['dst_file'] = BP_TESTS_DIR . 'assets/error.jpg';
     294                $cropped = $attachment_class->crop( $crop_args );
     295
     296                // Image must stay in the upload basedir
     297                $this->assertTrue( is_wp_error( $cropped ) );
     298
     299                // clean up!
     300                $this->clean_files();
     301        }
     302}
  • tests/phpunit/testcases/core/functions.php

    diff --git tests/phpunit/testcases/core/functions.php tests/phpunit/testcases/core/functions.php
    index 41d77a3..9dad780 100644
    class BP_Tests_Core_Functions extends BP_UnitTestCase { 
    598598                        date_default_timezone_set( $tz_backup );
    599599                }
    600600        }
     601
     602        /**
     603         * @group bp_attachments
     604         * @group bp_upload_dir
     605         */
     606        public function test_bp_upload_dir_ms() {
     607                if ( ! is_multisite() ) {
     608                        $this->markTestSkipped( __METHOD__ . ' is a multisite-only test.' );
     609                }
     610
     611                $expected_upload_dir = wp_upload_dir();
     612
     613                $b = $this->factory->blog->create();
     614
     615                switch_to_blog( $b );
     616
     617                $tested_upload_dir = bp_upload_dir();
     618
     619                restore_current_blog();
     620
     621                $this->assertSame( $expected_upload_dir, $tested_upload_dir );
     622        }
    601623}