Skip to:
Content

Ticket #7157: 7157.patch

File 7157.patch, 39.0 KB (added by imath, 18 months ago)
  • src/bp-core/admin/bp-core-admin-functions.php

    diff --git src/bp-core/admin/bp-core-admin-functions.php src/bp-core/admin/bp-core-admin-functions.php
    index 39b54b2..c996e09 100644
    function bp_core_get_admin_tabs( $active_tab = '' ) { 
    438438                        'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-settings' ), 'admin.php' ) ), 
    439439                        'name' => __( 'Options', 'buddypress' ) 
    440440                ), 
     441                '3' => array( 
     442                        'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bp-theme-packages' ), 'admin.php' ) ), 
     443                        'name' => __( 'Template Pack', 'buddypress' ) 
     444                ), 
    441445        ); 
    442446 
    443447        // If forums component is active, add additional tab. 
    function bp_core_get_admin_tabs( $active_tab = '' ) { 
    447451                wp_enqueue_script( 'thickbox' ); 
    448452                wp_enqueue_style( 'thickbox' ); 
    449453 
    450                 $tabs['3'] = array( 
     454                $tabs['4'] = array( 
    451455                        'href' => bp_get_admin_url( add_query_arg( array( 'page' => 'bb-forums-setup'  ), 'admin.php' ) ), 
    452456                        'name' => __( 'Forums', 'buddypress' ) 
    453457                ); 
  • src/bp-core/admin/bp-core-admin-theme-packages.php

    diff --git src/bp-core/admin/bp-core-admin-theme-packages.php src/bp-core/admin/bp-core-admin-theme-packages.php
    index e69de29..855306b 100644
     
     1<?php 
     2/** 
     3 * BuddyPress Theme Packages. 
     4 * 
     5 * @package BuddyPress 
     6 * @subpackage Core 
     7 * @since 2.7.0 
     8 */ 
     9 
     10// Exit if accessed directly. 
     11defined( 'ABSPATH' ) || exit; 
     12 
     13/** 
     14 * Get the possible Theme Packages locations 
     15 * 
     16 * @since  2.7.0 
     17 * 
     18 * @return array An associative array containing possible dirs and urls. 
     19 */ 
     20function bp_core_admin_get_theme_packages_locations() { 
     21        $bp = buddypress(); 
     22 
     23        /** 
     24         * Filter here to add your custom location. 
     25         * 
     26         * @since  2.7.0 
     27         * 
     28         * @param  array $value An associative array containing possible dirs and urls. 
     29         */ 
     30        return (array) apply_filters( 'bp_core_admin_get_theme_packages_locations', array( 
     31                'wp-content' => array( 
     32                        'dir' => WP_CONTENT_DIR . '/bp-templates', 
     33                        'url' => content_url() . '/bp-templates', 
     34                        'id'  => 'wp-content', 
     35                ), 
     36                'bp-core'   => array( 
     37                        'dir' => $bp->plugin_dir . 'bp-templates', 
     38                        'url' => $bp->plugin_url . 'bp-templates', 
     39                        'id'  => 'bp-core', 
     40                ), 
     41        ) ); 
     42} 
     43 
     44/** 
     45 * Scan possible locations to find Temmplate Packs. 
     46 * 
     47 * @since  2.7.0 
     48 * 
     49 * @return array The found Template Packs in the available locations. 
     50 */ 
     51function bp_core_admin_get_theme_packages() { 
     52        $locations      = bp_core_admin_get_theme_packages_locations(); 
     53        $theme_packages = array(); 
     54 
     55        if ( empty( $locations ) ) { 
     56                return $theme_packages; 
     57        } 
     58 
     59        // Loop through locations to get the available template packs. 
     60        foreach( $locations as $location ) { 
     61                if ( ! is_dir( $location['dir'] ) ) { 
     62                        continue; 
     63                } 
     64 
     65                $dirs = scandir( $location['dir'] ); 
     66 
     67                foreach ( $dirs as $dir ) { 
     68                        if ( 0 === strpos( $dir, '.' ) ) { 
     69                                continue; 
     70                        } 
     71 
     72                        // Avoid duplicates. 
     73                        if ( isset( $theme_packages[ $dir ] ) || ! is_dir( $location['dir'] . '/' . $dir ) ) { 
     74                                continue; 
     75                        } 
     76 
     77                        $find_bp_functions = scandir( $location['dir'] . '/' . $dir ); 
     78 
     79                        // The Template pack must have a 'buddypress-functions.php' 
     80                        if ( ! array_search( 'buddypress-functions.php', $find_bp_functions ) ) { 
     81                                continue; 
     82                        } 
     83 
     84                        $tp      = new stdClass(); 
     85                        $tp->dir = trailingslashit( $location['dir'] ) . $dir; 
     86                        $tp->url = trailingslashit( $location['url'] ) . wp_basename( $tp->dir ); 
     87 
     88                        $theme_packages[ $dir ] = $tp; 
     89                } 
     90        } 
     91 
     92        return $theme_packages; 
     93} 
     94 
     95/** 
     96 * Translates the Theme Package Tags in the header of 
     97 * the bootstrap file (buddypress-functions.php). 
     98 * 
     99 * @since  2.7.0 
     100 * 
     101 * @param  object $theme_package The Template Pack Data to translate. 
     102 * @return object                The translated data. 
     103 */ 
     104function bp_core_admin_translate_theme_package_header( $theme_package = null ) { 
     105        if ( ! empty( $theme_package->text_domain ) ) { 
     106                if ( ! empty( $theme_package->domain_path ) && ! empty( $theme_package->dir ) ) { 
     107                        $locale      = apply_filters( 'buddypress_locale', get_locale(), $theme_package->text_domain ); 
     108                        $mofile      = $theme_package->dir . $theme_package->domain_path . sprintf( '%1$s-%2$s.mo', $theme_package->text_domain, $locale ); 
     109                        $translation = load_textdomain( $theme_package->text_domain, $mofile ); 
     110                } 
     111 
     112                if ( ! empty( $translation ) ) { 
     113                        foreach ( array( 'name', 'version', 'description', 'author', 'link', 'supports' ) as $field ) { 
     114                                $theme_package->{$field} = translate( $theme_package->{$field}, $theme_package->text_domain ); 
     115                        } 
     116                } 
     117        } 
     118 
     119        // Allowed tags for Name, author, version and desciption firlds 
     120        $allowed_tags = $allowed_tags_no_links = array( 
     121                'abbr'    => array( 'title' => true ), 
     122                'acronym' => array( 'title' => true ), 
     123                'code'    => true, 
     124                'em'      => true, 
     125                'strong'  => true, 
     126        ); 
     127        $allowed_tags['a'] = array( 'href' => true, 'title' => true ); 
     128 
     129        // Sanitize fields 
     130        $theme_package->name        = wp_kses( $theme_package->name,    $allowed_tags_no_links ); 
     131        $theme_package->author      = wp_kses( $theme_package->author,  $allowed_tags ); 
     132        $theme_package->version     = wp_kses( $theme_package->version, $allowed_tags ); 
     133        $theme_package->description = wptexturize( wp_kses( $theme_package->description, $allowed_tags ) ); 
     134        $theme_package->link        = esc_url( $theme_package->link ); 
     135        $theme_package->supports    = esc_html( $theme_package->supports ); 
     136 
     137        if ( isset( $theme_package->wp_required_version ) ) { 
     138                $theme_package->wp_required_version = esc_html( $theme_package->wp_required_version ); 
     139        } 
     140 
     141        if ( isset( $theme_package->bp_required_version ) ) { 
     142                $theme_package->bp_required_version = esc_html( $theme_package->bp_required_version ); 
     143        } 
     144 
     145        return $theme_package; 
     146} 
     147 
     148/** 
     149 * Gets the translated Theme Packages. 
     150 * 
     151 * @since  2.7.0 
     152 * 
     153 * @return array the translated Theme Packages. 
     154 */ 
     155function bp_core_admin_get_translated_theme_packages() { 
     156        $theme_packages = bp_core_admin_get_theme_packages(); 
     157 
     158        if ( empty( $theme_packages ) ) { 
     159                return $theme_packages; 
     160        } 
     161 
     162        foreach( $theme_packages as $theme_package_id => $theme_package ) { 
     163                if ( 'bp-legacy' === $theme_package_id ) { 
     164                        $headers = array( 
     165                                'id'          => 'legacy', 
     166                                'name'        => __( 'BuddyPress Legacy', 'buddypress' ), 
     167                                'version'     => bp_get_version(), 
     168                                'description' => __( 'The BuddyPress legacy template pack', 'buddypress' ), 
     169                                'author'      => __( 'The BuddyPress community', 'buddypress' ), 
     170                                'link'        => 'https://buddypress.org', 
     171                                'supports'    => _x( 
     172                                        'activity, blogs, friends, groups, messages, notifications, retired-forums, settings, xprofile', 
     173                                        'comma separated list of supported components', 
     174                                        'buddypress' 
     175                                ), 
     176                                'text_domain' => 'buddypress', 
     177                        ); 
     178                } else { 
     179                        $headers = get_file_data( $theme_package->dir . '/buddypress-functions.php', array( 
     180                                'id'                  => 'Template Pack ID', 
     181                                'name'                => 'Template Pack Name', 
     182                                'version'             => 'Version', 
     183                                'wp_required_version' => 'WP required version', 
     184                                'bp_required_version' => 'BP required version', 
     185                                'description'         => 'Description', 
     186                                'author'              => 'Author', 
     187                                'link'                => 'Template Pack Link', 
     188                                'supports'            => 'Template Pack Supports', 
     189                                'text_domain'         => 'Text Domain', 
     190                                'domain_path'         => 'Domain Path' 
     191                        ) ); 
     192                } 
     193 
     194                // The 'buddypress-functions.php' file musts contain headers 
     195                if ( empty( $headers ) ) { 
     196                        unset( $theme_packages[ $theme_package_id ] ); 
     197                        continue; 
     198                } 
     199 
     200                // Add the found headers 
     201                foreach ( $headers as $tag => $value ) { 
     202                        $theme_packages[ $theme_package_id ]->{$tag} = $value; 
     203                } 
     204 
     205                // Finally translate headers 
     206                $theme_packages[ $theme_package_id ] = bp_core_admin_translate_theme_package_header( $theme_packages[ $theme_package_id ] ); 
     207        } 
     208 
     209        return $theme_packages; 
     210} 
     211 
     212/** 
     213 * Displays the Template Packs Table's header & footer. 
     214 * 
     215 * @since  2.7.0 
     216 * 
     217 * @return string HTML Output. 
     218 */ 
     219function bp_core_admin_theme_packages_get_head() { 
     220        $table_head = array_fill_keys( array( 'head', 'foot' ), array( 
     221                'cb'          => '&nbsp;', 
     222                'name'        => __( 'Name', 'buddypress' ), 
     223                'description' => __( 'Description', 'buddypress' ), 
     224                'actions'     => __( 'Actions', 'buddypress' ), 
     225        ) ); 
     226 
     227        foreach ( $table_head as $kh => $columns ) { 
     228                printf( '<t%1$s>%2$s<tr>%3$s', $kh, "\n\t", "\n" ); 
     229 
     230                foreach ( $columns as $kc => $column ) { 
     231                        if ( 'cb' === $kc ) { 
     232                                printf( 
     233                                        '%1$s<td id="%2$s-%3$s" class="manage-column column-%2$s check-column">%4$s</td>%5$s', 
     234                                        "\t\t", 
     235                                        $kc, 
     236                                        $kh, 
     237                                        esc_html( $column ), 
     238                                        "\n" 
     239                                ); 
     240                        } else { 
     241                                printf( 
     242                                        '<th id="%2$s-%3$s" class="manage-column column-%2$s">%4$s</th>%5$s', 
     243                                        "\t\t", 
     244                                        $kc, 
     245                                        $kh, 
     246                                        esc_html( $column ), 
     247                                        "\n" 
     248                                ); 
     249                        } 
     250                } 
     251 
     252                printf( '%1$s</tr>%2$s<t%3$s>', "\t", "\n", $kh ); 
     253        } 
     254} 
     255 
     256/** 
     257 * Format Template Pack's metas for display. 
     258 * 
     259 * @since  2.7.0 
     260 * 
     261 * @param  object $theme_package The Theme Package we need to get metas for. 
     262 * @return string HTML Output. 
     263 */ 
     264function bp_core_admin_theme_package_metas( $theme_package = null ) { 
     265        $metas = array(); 
     266 
     267        if ( ! empty( $theme_package->version ) ) { 
     268                $metas[] = sprintf( _x( 'Version %s', 'Version of the Template Pack', 'buddypress' ), esc_html( $theme_package->version ) ); 
     269        } 
     270 
     271        if ( ! empty( $theme_package->author ) ) { 
     272                $metas[] = sprintf( _x( 'By %s', 'Name of the author of the Template Pack.', 'buddypress' ), esc_html( $theme_package->author ) ); 
     273        } 
     274 
     275        if ( ! empty( $theme_package->link ) ) { 
     276                $metas[] = sprintf( '<a href="%1$s">%2$s</a>', 
     277                        esc_url( $theme_package->link ), 
     278                        __( 'Visit Template Pack site', 'buddypress' ) 
     279                ); 
     280        } 
     281 
     282        if ( empty( $metas ) ) { 
     283                return; 
     284        } 
     285 
     286        echo join( ' | ', $metas ); 
     287} 
     288 
     289/** 
     290 * Sets Template Pack's warnings. 
     291 * 
     292 * @since  2.7.0 
     293 * 
     294 * @param  object $theme_package The Theme Package we need to set warnings for. 
     295 * @return string HTML Output. 
     296 */ 
     297function bp_core_admin_theme_package_set_warnings( $theme_packages = array() ) { 
     298        if ( empty( $theme_packages ) ) { 
     299                return $theme_packages; 
     300        } 
     301 
     302        $wp_version        = bp_get_major_wp_version(); 
     303        $bp_version        = bp_get_version(); 
     304        $active_components = array_intersect( array_keys( buddypress()->active_components ), bp_core_get_packaged_component_ids() ); 
     305        $retired_forums    = array_search( 'forums', $active_components ); 
     306 
     307        if ( $retired_forums ) { 
     308                $active_components[ $retired_forums ] = 'retired-forums'; 
     309        } 
     310 
     311        foreach ( $theme_packages as $ktp => $theme_package ) { 
     312                $theme_packages[ $ktp ]->warnings = array(); 
     313                if ( ! empty( $theme_package->bp_required_version ) && version_compare( $bp_version, $theme_package->bp_required_version, '<' ) ) { 
     314                        $theme_packages[ $ktp ]->warnings[] = sprintf( __( 'BuddyPress required version is %s.', 'buddypress' ), $theme_package->bp_required_version ); 
     315                } 
     316 
     317                if ( ! empty( $theme_package->wp_required_version ) && version_compare( $wp_version, $theme_package->wp_required_version, '<' ) ) { 
     318                        $theme_packages[ $ktp ]->warnings[] = sprintf( __( 'WordPress required version is %s.', 'buddypress' ), $theme_package->wp_required_version ); 
     319                } 
     320 
     321                if ( ! empty( $theme_package->supports ) ) { 
     322                        $supported_components = array_map( 'trim', explode( ',', $theme_package->supports ) ); 
     323 
     324                        // This component is often forgotten. 
     325                        if ( ! array_search( 'members', $supported_components ) ) { 
     326                                $supported_components[] = 'members'; 
     327                        } 
     328 
     329                        $no_support = array_diff( $active_components, $supported_components ); 
     330 
     331                        if ( ! empty( $no_support ) ) { 
     332                                $theme_packages[ $ktp ]->warnings[] = sprintf( __( 'No support is provided for the following component(s): %s.', 'buddypress' ), join( ', ', $no_support ) ); 
     333                        } 
     334                } 
     335        } 
     336 
     337        return $theme_packages; 
     338} 
     339 
     340/** 
     341 * Displays the Template Packs Table's body. 
     342 * 
     343 * @since  2.7.0 
     344 * 
     345 * @return string HTML Output. 
     346 */ 
     347function bp_core_admin_theme_packages_get_body() { 
     348        $theme_packages  = bp_core_admin_get_translated_theme_packages(); 
     349        $current         = bp_get_theme_package_id(); 
     350        $theme_packages  = bp_core_admin_theme_package_set_warnings( $theme_packages ); 
     351        $customizer_args = array( 
     352                'url'    => rawurlencode( bp_loggedin_user_domain() ), 
     353                'return' => esc_url( add_query_arg( 'page', 'bp-theme-packages', bp_get_admin_url( 'admin.php' ) ) ), 
     354        ); 
     355        ?> 
     356 
     357        <tbody id="the-list"> 
     358 
     359                <?php if ( empty( $theme_packages ) ) : ?> 
     360 
     361                        <tr class="no-items"> 
     362                                <td class="colspanchange" colspan="4"><?php esc_html_e( 'No template packs found.', 'buddypress' ); ?></td> 
     363                        </tr> 
     364 
     365                <?php else : foreach( $theme_packages as $theme_package ) : 
     366                        $class           = 'active'; 
     367                        $activation_link = ''; 
     368                        $no_compatibity  = ! empty( $theme_package->warnings ); 
     369 
     370                        if ( $theme_package->id !== $current ) { 
     371                                $class = 'inactive'; 
     372                                $activation_link = wp_nonce_url( add_query_arg( array( 
     373                                        'page'    => 'bp-theme-packages', 
     374                                        'action'  => 'activate', 
     375                                        'package' => rawurlencode( $theme_package->dir ) 
     376                                ), bp_get_admin_url( 'admin.php' ) ), 'bp-theme-packages-activate' ); 
     377 
     378                                $customizer_args['bp_template_pack'] = wp_basename( $theme_package->dir ); 
     379                        } 
     380 
     381                        $customizer_link = add_query_arg( $customizer_args, admin_url( 'customize.php' ) ); 
     382                ?> 
     383 
     384                        <tr id="<?php echo esc_attr( $theme_package->id ); ?>" class="<?php echo esc_attr( $theme_package->id ) . ' ' . esc_attr( $class ); ?>"> 
     385                                        <th scope="row" class="check-column"> 
     386                                                <input type="checkbox" id="bp_theme_package-<?php echo esc_attr( $theme_package->id ); ?>" name="bp_theme_package[packages][]" value="<?php echo esc_attr( $theme_package->dir );?>"<?php echo ( $theme_package->id === 'legacy' || $theme_package->id === $current ) ? 'disabled' : ''; ?> /> 
     387                                        </th> 
     388 
     389                                        <td class="plugin-title" style="width: 190px;"> 
     390                                                <span></span> 
     391 
     392                                                <label for="bp_theme_package-<?php echo esc_attr( $theme_package->id ); ?>"> 
     393                                                        <strong><?php echo esc_html( $theme_package->name ); ?></strong> 
     394                                                </label> 
     395 
     396                                                <div class="row-actions-visible"></div> 
     397                                        </td> 
     398 
     399                                        <td class="column-description desc"> 
     400                                                <div class="plugin-description"> 
     401                                                        <p><?php echo esc_html( $theme_package->description ); ?></p> 
     402                                                </div> 
     403 
     404                                                <div class="active second plugin-version-author-uri"> 
     405                                                        <?php bp_core_admin_theme_package_metas( $theme_package ); ?> 
     406                                                </div> 
     407 
     408                                                <?php if ( $no_compatibity ) : ?> 
     409 
     410                                                        <div class="attention"> 
     411 
     412                                                                <?php echo join( '<br/>', array_map( 'esc_html', $theme_package->warnings ) ); ?> 
     413 
     414                                                        </div> 
     415 
     416                                                <?php endif; ?> 
     417                                        </td> 
     418 
     419                                        <td class="column-actions desc"> 
     420                                                <?php if ( $no_compatibity ) : ?> 
     421                                                        <?php esc_html_e( 'Not compatible', 'buddypress' ); ?> 
     422                                                <?php elseif ( ! empty( $activation_link ) ) : ?> 
     423                                                        <a href="<?php echo esc_url( $activation_link ); ?>" class="button button-primary"><?php esc_html_e( 'Activate', 'buddypress' ); ?></a> 
     424                                                        <a href="<?php echo esc_url( $customizer_link ); ?>" class="button button-secondary"><?php esc_html_e( 'Preview', 'buddypress' ); ?></a> 
     425                                                <?php else : ?> 
     426                                                        <a href="<?php echo esc_url( $customizer_link ); ?>" class="button button-secondary"><?php esc_html_e( 'Customize', 'buddypress' ); ?></a> 
     427                                                <?php endif; ?> 
     428 
     429                                        </td> 
     430                                </tr> 
     431 
     432 
     433                <?php endforeach; endif; ?> 
     434 
     435        </tbody> 
     436        <?php 
     437} 
     438 
     439/** 
     440 * Requests the filesystem credentials. 
     441 * 
     442 * NB: if FTP credentials are necessary, we will let Site Owners 
     443 * Install or delete Template Packs using their FTP access. 
     444 * 
     445 * @since  2.7.0 
     446 * 
     447 * @return bool True if we can manipulate the filesystem. False otherwise. 
     448 */ 
     449function bp_core_admin_theme_packages_has_credentials() { 
     450        global $wp_filesystem; 
     451 
     452        ob_start(); 
     453        $credentials = request_filesystem_credentials( self_admin_url(), '', false, WP_CONTENT_DIR ); 
     454        ob_end_clean(); 
     455 
     456        // Try to see if we can have direct access to the filesystem. 
     457        if ( false === $credentials || ! WP_Filesystem( $credentials, WP_CONTENT_DIR ) ) { 
     458                return false; 
     459        } 
     460 
     461        return true; 
     462} 
     463 
     464/** 
     465 * Returns feedback messages to inform the site owner. 
     466 * 
     467 * @since  2.7.0 
     468 * 
     469 * @return array The list of feedback messages. 
     470 */ 
     471function bp_core_admin_theme_packages_feedbacks() { 
     472        /** 
     473         * Filter here to add your own feedback messages. 
     474         * 
     475         * @since  2.7.0 
     476         * 
     477         * @param array $value The list of feedback messages. 
     478         */ 
     479        return apply_filters( 'bp_core_admin_theme_packages_feedbacks', array( 
     480                'installed'            => __( 'Template pack successfully installed.', 'buddypress' ), 
     481                'activated'            => __( 'Template pack successfully activated.', 'buddypress' ), 
     482                'deleted'              => __( 'Template pack(s) successfully deleted.', 'buddypress' ), 
     483                'missing_archive'      => __( 'The Template Pack zip Archive could not be found.', 'buddypress' ), 
     484                'credentials_required' => __( 'We were, not able to access your file system.', 'buddypress' ), 
     485                'mkdir_failed'         => __( 'We were, not able to create the "bp-templates" directory in "wp-content".', 'buddypress' ), 
     486                'incompatible_archive' => __( 'The Template Pack could not be installed.', 'buddypress' ), 
     487                'activation_error'     => __( 'The Template Pack could not be activated.', 'buddypress' ), 
     488                'deletion_error'       => __( 'The Template Pack could not be deleted.', 'buddypress' ), 
     489                // Will be used in case 'credentials_required', 'mkdir_failed' and 'incompatible_archive' 
     490                'how_to'               => __( 'You can use your FTP access to add a "bp-templates" subdirectory to your "wp-content" directory. Once done you will be able to put in it the unzipped Template Pack.', 'buddypress' ) . ' ' . 
     491                                          __( 'If you need to delete a Template Pack, make sure to activate another one before using your FTP access to remove its directory.', 'buddypress' ), 
     492        ) ); 
     493} 
     494 
     495/** 
     496 * Manage the actions the site owner requested. 
     497 * Possible actions are Upload & Install, delete or activate a Template Pack. 
     498 * 
     499 * @since  2.7.0 
     500 */ 
     501function bp_core_admin_theme_packages_load() { 
     502        // Enqueue the script for the toggle upload support. 
     503        wp_enqueue_script( 'plugin-install' ); 
     504 
     505        // Bail if it's not a BP Theme Package form. 
     506        if ( empty( $_POST['bp_theme_package'] ) && empty( $_GET['action'] ) ) { 
     507                return; 
     508        } 
     509 
     510        // Get the action 
     511        $action = bp_admin_list_table_current_bulk_action(); 
     512 
     513        // Build the redirect args. 
     514        $query_arg = array( 'page' => 'bp-theme-packages' ); 
     515 
     516        // Handle Template Pack uploads. 
     517        if ( 'bp_theme_package_upload' === $action ) { 
     518                // Check the nonce. 
     519                check_admin_referer( 'bp-theme-packages-upload' ); 
     520 
     521                if ( ! buddypress()->do_autoload ) { 
     522                        require dirname( __FILE__ ) . '/classes/class-bp-attachment-theme-package.php'; 
     523                } 
     524 
     525                // In multisite, we need to temporarly remove some filters. 
     526                if ( is_multisite() ) { 
     527                        remove_filter( 'upload_mimes',      'check_upload_mimes'       ); 
     528                        remove_filter( 'upload_size_limit', 'upload_size_limit_filter' ); 
     529                } 
     530 
     531                $zip  = new BP_Attachment_Theme_Package(); 
     532                $file = $zip->upload( $_FILES ); 
     533 
     534                // Put Multisite filters back. 
     535                if ( is_multisite() ) { 
     536                        add_filter( 'upload_mimes',      'check_upload_mimes'       ); 
     537                        add_filter( 'upload_size_limit', 'upload_size_limit_filter' ); 
     538                } 
     539 
     540                // Upload errors 
     541                if ( ! empty( $file['error'] ) ) { 
     542                        buddypress()->admin->errors = $file['error']; 
     543                        return; 
     544                } 
     545 
     546                // Extract the Archive 
     547                $extracted = $zip->extract(); 
     548 
     549                if ( ! is_wp_error( $extracted ) ) { 
     550                        $query_arg['status'] = 'installed'; 
     551 
     552                // File System errors 
     553                } else { 
     554                        $query_arg['status'] = $extracted->get_error_code(); 
     555                } 
     556 
     557        // User chose to delete one or more uploaded Template Pack 
     558        } elseif ( 'delete' === $action ) { 
     559                global $wp_filesystem; 
     560 
     561                // Check the nonce. 
     562                check_admin_referer( 'bp-theme-packages-delete' ); 
     563 
     564                if ( empty( $_POST['bp_theme_package']['packages'] ) || ! is_array( $_POST['bp_theme_package']['packages'] ) ) { 
     565                        $query_arg['status'] = 'deletion_error'; 
     566                } else { 
     567                        if ( ! bp_core_admin_theme_packages_has_credentials() ) { 
     568                                $query_arg['status'] = 'credentials_required'; 
     569                        } else { 
     570                                $packages = array_map( 'wp_unslash', $_POST['bp_theme_package']['packages'] ); 
     571 
     572                                foreach( $packages as $package ) { 
     573                                        $wp_filesystem->delete( $package, true ); 
     574                                } 
     575 
     576                                $query_arg['status'] = 'deleted'; 
     577                        } 
     578                } 
     579        } elseif ( 'activate' === $action && ! empty( $_GET['package'] ) ) { 
     580                // Check the nonce. 
     581                check_admin_referer( 'bp-theme-packages-activate' ); 
     582 
     583                $theme_package_dir  = wp_unslash( $_GET['package'] ); 
     584                $theme_package_name = wp_basename( $theme_package_dir ); 
     585 
     586                // Bail if we can't activate the Template Pack due to some missing informations. 
     587                if ( ! is_dir( $theme_package_dir ) || ! file_exists( $theme_package_dir . '/buddypress-functions.php' ) ) { 
     588                        $query_arg['status'] = 'activation_error'; 
     589 
     590                // Process to the activation. 
     591                } else { 
     592 
     593                        // It's legacy we need to delete the Template pack Data. 
     594                        if ( 'bp-legacy' === $theme_package_name ) { 
     595                                $theme_package_data = array( 
     596                                        'id' => 'legacy', 
     597                                ); 
     598 
     599                                bp_delete_option( '_bp_theme_package_data' ); 
     600                                $query_arg['status'] = 'activated'; 
     601 
     602                        // Else try to build the Template Pack data thanks to the buddypress-functions.php's header. 
     603                        } else { 
     604                                $theme_package_data = get_file_data( $theme_package_dir . '/buddypress-functions.php', array( 
     605                                        'id'                  => 'Template Pack ID', 
     606                                        'name'                => 'Template Pack Name', 
     607                                        'version'             => 'Version', 
     608                                        'wp_required_version' => 'WP required version', 
     609                                        'bp_required_version' => 'BP required version' 
     610                                ) ); 
     611 
     612                                // Bail if we don't have the Theme Package ID 
     613                                if ( empty( $theme_package_data['id'] ) ) { 
     614                                        $query_arg['status'] = 'activation_error'; 
     615 
     616                                // Find the components support and the Theme Package URL. 
     617                                } else { 
     618                                        if ( ! empty( $theme_package_data['support'] ) ) { 
     619                                                $theme_package_data['support'] = array_map( 'trim', explode( ',', $theme_package_data['support'] ) ); 
     620                                        } 
     621 
     622                                        $theme_package_data['dir'] = $theme_package_dir; 
     623                                        $locations                 = bp_core_admin_get_theme_packages_locations(); 
     624                                        $locations_dir             = wp_list_pluck( bp_core_admin_get_theme_packages_locations(), 'dir', 'id' ); 
     625                                        $url_key                   = array_search( dirname( $theme_package_dir ), $locations_dir ); 
     626 
     627                                        // Bail if we don't have the Theme Package URL 
     628                                        if ( empty( $url_key ) ) { 
     629                                                $query_arg['status'] = 'activation_error'; 
     630 
     631                                        // Finally update the Theme Package Data option. 
     632                                        } else { 
     633                                                $theme_package_data['url'] = trailingslashit( $locations[ $url_key ]['url'] ) . $theme_package_name; 
     634 
     635                                                bp_update_option( '_bp_theme_package_data', $theme_package_data ); 
     636                                                $query_arg['status'] = 'activated'; 
     637                                        } 
     638                                } 
     639                        } 
     640 
     641                        // Update the Theme Package ID 
     642                        bp_update_option( '_bp_theme_package_id', $theme_package_data['id'] ); 
     643                } 
     644 
     645        } else { 
     646                /** 
     647                 * Hook here to run your custom actions 
     648                 * 
     649                 * @since 2.7.0 
     650                 * 
     651                 * @param $action the current Template Pack action. 
     652                 */ 
     653                do_action( 'bp_core_admin_theme_packages_load', $action ); 
     654        } 
     655 
     656        wp_safe_redirect( add_query_arg( $query_arg, bp_get_admin_url( 'admin.php' ) ) ); 
     657        exit(); 
     658} 
     659 
     660/** 
     661 * Main UI to Manage the Template Packs. 
     662 * 
     663 * @since  2.7.0 
     664 * 
     665 * @return string HTML Output. 
     666 */ 
     667function bp_core_admin_theme_packages() { 
     668        $bp = buddypress(); 
     669 
     670        ?> 
     671        <div class="wrap"> 
     672 
     673                <h1><?php _e( 'BuddyPress Settings', 'buddypress' ); ?> </h1> 
     674 
     675                <h2 class="nav-tab-wrapper"><?php bp_core_admin_tabs( __( 'Template Pack', 'buddypress' ) ); ?></h2> 
     676 
     677                <?php 
     678                // User feedbacks 
     679                if ( isset( $_GET['status'] ) || ! empty( $bp->admin->errors ) ) { 
     680                        // Defaults to an error. 
     681                        $type    = 'error'; 
     682                        $how_to  = ''; 
     683 
     684                        if ( ! empty( $bp->admin->errors ) ) { 
     685                                $feedback = $bp->admin->errors; 
     686                        } else { 
     687                                $feedbacks = bp_core_admin_theme_packages_feedbacks(); 
     688 
     689                                // Success! 
     690                                if ( 'installed' === $_GET['status'] || 'activated' === $_GET['status'] || 'deleted' === $_GET['status'] ) { 
     691                                        $type = 'updated'; 
     692                                } 
     693 
     694                                if ( 'credentials_required' === $_GET['status'] || 'mkdir_failed' === $_GET['status'] 
     695                                 || 'incompatible_archive' === $_GET['status'] || 'deletion_error' === $_GET['status'] ) { 
     696                                        $how_to = sprintf( '<p class="description">%s</p>', esc_html( $feedbacks['how_to'] ) ); 
     697                                } 
     698 
     699                                $feedback = $feedbacks[ $_GET['status'] ]; 
     700                        } 
     701 
     702                        // Display the feedback message. 
     703                        printf( 
     704                                '<div id="message" class="%1$s notice is-dismissible"><p>%2$s</p>%3$s</div>', 
     705                                $type, 
     706                                esc_html( $feedback ), 
     707                                $how_to 
     708                        ); 
     709                } 
     710                ;?> 
     711 
     712                <div class="upload-plugin-wrap"> 
     713                        <div class="upload-plugin"> 
     714                                <p class="install-help"><?php esc_html_e( 'If you have a Template Pack in a .zip format, you may install/upgrade it by uploading it here.', 'buddypress' ); ?></p> 
     715                                <form method="post" enctype="multipart/form-data" class="wp-upload-form" action="<?php echo esc_url( add_query_arg( array( 'page' => 'bp-theme-packages', 'action' => 'upload' ), bp_get_admin_url( 'admin.php' ) ) ); ?>"> 
     716                                        <?php wp_nonce_field( 'bp-theme-packages-upload' ); ?> 
     717                                        <label class="screen-reader-text" for="pluginzip"><?php esc_html_e( 'Template Pack zip file', 'buddypress' ); ?></label> 
     718                                        <input type="file" name="zip" id="zip"> 
     719                                        <input type="hidden" name="action" id="bp-theme-package-action" value="bp_theme_package_upload" /> 
     720                                        <input type="submit" name="bp_theme_package[upload]" id="install-plugin-submit" class="button" value="<?php esc_attr_e( 'Install Now', 'buddypress' ); ?>" disabled=""> 
     721                                </form> 
     722                        </div> 
     723                </div> 
     724 
     725                <form action="<?php echo esc_url( add_query_arg( array( 'page' => 'bp-theme-packages' ), bp_get_admin_url( 'admin.php' ) ) ); ?>" method="post" id="bp-core-admin-theme-packages-form"> 
     726                        <div class="tablenav top"> 
     727                                <div class="alignleft actions bulkactions"> 
     728                                        <label for="bulk-action-selector-top" class="screen-reader-text">Select bulk action</label> 
     729                                        <select name="action" id="bulk-action-selector-top"> 
     730                                                <option value="-1"><?php esc_html_e( 'Bulk Actions', 'buddypress' ); ?></option> 
     731                                                <option value="delete">Delete</option> 
     732                                        </select> 
     733                                        <button class="secondary-action button" type="submit" name="bp_theme_package[submit]"> 
     734                                                <span><?php esc_html_e( 'Apply', 'buddypress' ); ?></span> 
     735                                        </button> 
     736                                </div> 
     737                                <div class="alignleft actions"> 
     738                                        <button class="secondary-action button upload-view-toggle"> 
     739                                                <span><?php esc_html_e( 'Upload', 'buddypress' ); ?></span> 
     740                                        </button> 
     741                                </div> 
     742                                <br class="clear"> 
     743                        </div> 
     744 
     745                        <table class="widefat plugins" cellspacing="0"> 
     746 
     747                                <?php bp_core_admin_theme_packages_get_head() ;?> 
     748 
     749                                <?php bp_core_admin_theme_packages_get_body() ;?> 
     750 
     751                        </table> 
     752 
     753                        <?php wp_nonce_field( 'bp-theme-packages-delete' ); ?> 
     754 
     755                </form> 
     756        </div> 
     757        <?php 
     758} 
  • src/bp-core/bp-core-theme-compatibility.php

    diff --git src/bp-core/bp-core-theme-compatibility.php src/bp-core/bp-core-theme-compatibility.php
    index ea83317..f282d0d 100644
    function bp_theme_compat_loop_end( $query ) { 
    991991        unset( $bp->theme_compat->is_page_toggled ); 
    992992} 
    993993add_action( 'loop_end', 'bp_theme_compat_loop_end' ); 
     994 
     995/** 
     996 * Are we currently previewing a Template Pack in the customizer? 
     997 * 
     998 * @since  2.7.0 
     999 * 
     1000 * @return bool|string False if no Template Pack is being previewed. 
     1001 *                     The Template Pack folder's name otherwise. 
     1002 */ 
     1003function bp_theme_compat_is_theme_package_preview() { 
     1004        $retval = false; 
     1005 
     1006        if ( empty( $_POST['wp_customize'] ) ) { 
     1007                return $retval; 
     1008        } 
     1009 
     1010        $preview_uri = parse_url( bp_get_referer_path() ); 
     1011 
     1012        // Ultimate check. 
     1013        if ( false === strpos( $preview_uri['path'], 'customize.php' ) ) { 
     1014                return $retval; 
     1015        } 
     1016 
     1017        // Is there a template pack to preview ? 
     1018        $vars = wp_parse_args( $preview_uri['query'], array() ); 
     1019 
     1020        $theme_package_key = ''; 
     1021        if ( ! empty( $vars['bp_template_pack'] ) ) { 
     1022                $theme_package_key = sanitize_key( $vars['bp_template_pack'] ); 
     1023        } 
     1024 
     1025        // Set the Theme Package Key being previewed 
     1026        if ( $theme_package_key ) { 
     1027                $retval = $theme_package_key; 
     1028        } 
     1029 
     1030        return $retval; 
     1031} 
     1032 
     1033/** 
     1034 * Eventually set the Template Pack ID to the one being previewed 
     1035 * into the customizer. 
     1036 * 
     1037 * @since  2.7.0 
     1038 * 
     1039 * @param  bool   $retval False. 
     1040 * @return string         The theme compat ID. 
     1041 */ 
     1042function bp_theme_compat_set_preview_theme_compat_id( $retval = false ) { 
     1043        $bp = buddypress(); 
     1044 
     1045        if ( ! empty( $bp->theme_compat->theme_package_previewed['id'] ) ) { 
     1046                $retval = $bp->theme_compat->theme_package_previewed['id']; 
     1047        } 
     1048 
     1049        return $retval; 
     1050} 
     1051 
     1052/** 
     1053 * Eventually set the Template Pack Date to the ones being previewed 
     1054 * into the customizer. 
     1055 * 
     1056 * @since  2.7.0 
     1057 * 
     1058 * @param  string $retval False. 
     1059 * @return string         The theme compat Data. 
     1060 */ 
     1061function bp_theme_compat_set_preview_theme_compat_data( $retval = false ) { 
     1062        $bp = buddypress(); 
     1063 
     1064        if ( ! empty( $bp->theme_compat->theme_package_previewed ) ) { 
     1065                $retval = $bp->theme_compat->theme_package_previewed; 
     1066        } 
     1067 
     1068        return $retval; 
     1069} 
     1070 
     1071/** 
     1072 * Set the Theme Package preview for the customizer. 
     1073 * 
     1074 * @since  2.7.0 
     1075 */ 
     1076function bp_theme_compat_set_theme_package_preview() { 
     1077        $theme_package = bp_theme_compat_is_theme_package_preview(); 
     1078 
     1079        // We're not previewing a Template Pack. 
     1080        if ( ! $theme_package ) { 
     1081                return; 
     1082        } 
     1083 
     1084        // Now we are sure to preview a Template pack, load the Admin file. 
     1085        require_once( trailingslashit( buddypress()->plugin_dir ) . 'bp-core/admin/bp-core-admin-theme-packages.php' ); 
     1086 
     1087        // Get all available Theme packages 
     1088        $theme_packages = bp_core_admin_get_translated_theme_packages(); 
     1089 
     1090        // If we're not finding the Theme Package stop! 
     1091        if ( empty( $theme_packages[ $theme_package ] ) ) { 
     1092                return; 
     1093        } 
     1094 
     1095        // Set the global to use in filters 
     1096        buddypress()->theme_compat->theme_package_previewed = array( 
     1097                'id'      => $theme_packages[ $theme_package ]->id, 
     1098                'name'    => $theme_packages[ $theme_package ]->name, 
     1099                'version' => $theme_packages[ $theme_package ]->version, 
     1100                'dir'     => $theme_packages[ $theme_package ]->dir, 
     1101                'url'     => $theme_packages[ $theme_package ]->url, 
     1102        ); 
     1103 
     1104        // Prefilter options used to load the Template Pack 
     1105        add_filter( 'pre_option__bp_theme_package_id', 'bp_theme_compat_set_preview_theme_compat_id', 10, 1 ); 
     1106 
     1107        if ( 'bp-legacy' !== $theme_package ) { 
     1108                add_filter( 'pre_option__bp_theme_package_data', 'bp_theme_compat_set_preview_theme_compat_data' ); 
     1109        } 
     1110} 
     1111add_action( 'bp_register_theme_packages', 'bp_theme_compat_set_theme_package_preview', 5 ); 
  • src/bp-core/classes/class-bp-admin.php

    diff --git src/bp-core/classes/class-bp-admin.php src/bp-core/classes/class-bp-admin.php
    index 5946130..6e0b604 100644
    class BP_Admin { 
    121121                        require( $this->admin_dir . 'bp-core-admin-classes.php'    ); 
    122122                } 
    123123 
    124                 require( $this->admin_dir . 'bp-core-admin-actions.php'    ); 
    125                 require( $this->admin_dir . 'bp-core-admin-settings.php'   ); 
    126                 require( $this->admin_dir . 'bp-core-admin-functions.php'  ); 
    127                 require( $this->admin_dir . 'bp-core-admin-components.php' ); 
    128                 require( $this->admin_dir . 'bp-core-admin-slugs.php'      ); 
    129                 require( $this->admin_dir . 'bp-core-admin-tools.php'      ); 
     124                require( $this->admin_dir . 'bp-core-admin-actions.php'        ); 
     125                require( $this->admin_dir . 'bp-core-admin-settings.php'       ); 
     126                require( $this->admin_dir . 'bp-core-admin-functions.php'      ); 
     127                require( $this->admin_dir . 'bp-core-admin-components.php'     ); 
     128                require( $this->admin_dir . 'bp-core-admin-slugs.php'          ); 
     129                require( $this->admin_dir . 'bp-core-admin-tools.php'          ); 
     130                require( $this->admin_dir . 'bp-core-admin-theme-packages.php' ); 
    130131        } 
    131132 
    132133        /** 
    class BP_Admin { 
    270271                        'bp_core_admin_settings' 
    271272                ); 
    272273 
     274                $hooks[] = add_submenu_page( 
     275                        $this->settings_page, 
     276                        __( 'BuddyPress Template Pack', 'buddypress' ), 
     277                        __( 'BuddyPress Template Pack', 'buddypress' ), 
     278                        $this->capability, 
     279                        'bp-theme-packages', 
     280                        'bp_core_admin_theme_packages' 
     281                ); 
     282 
    273283                // For consistency with non-Multisite, we add a Tools menu in 
    274284                // the Network Admin as a home for our Tools panel. 
    275285                if ( is_multisite() && bp_core_do_network_admin() ) { 
    class BP_Admin { 
    327337 
    328338                foreach( $hooks as $hook ) { 
    329339                        add_action( "admin_head-$hook", 'bp_core_modify_admin_menu_highlight' ); 
     340 
     341                        if ( false !== strpos( $hook, 'bp-theme-packages' ) ) { 
     342                                add_action( "load-{$hook}", 'bp_core_admin_theme_packages_load' ); 
     343                        } 
    330344                } 
    331345        } 
    332346 
    class BP_Admin { 
    524538        public function admin_head() { 
    525539 
    526540                // Settings pages. 
    527                 remove_submenu_page( $this->settings_page, 'bp-page-settings' ); 
    528                 remove_submenu_page( $this->settings_page, 'bp-settings'      ); 
     541                remove_submenu_page( $this->settings_page, 'bp-page-settings'  ); 
     542                remove_submenu_page( $this->settings_page, 'bp-settings'       ); 
     543                remove_submenu_page( $this->settings_page, 'bp-theme-packages' ); 
    529544 
    530545                // Network Admin Tools. 
    531546                remove_submenu_page( 'network-tools', 'network-tools' ); 
  • src/bp-core/classes/class-bp-attachment-theme-package.php

    diff --git src/bp-core/classes/class-bp-attachment-theme-package.php src/bp-core/classes/class-bp-attachment-theme-package.php
    index e69de29..02c73af 100644
     
     1<?php 
     2/** 
     3 * Core Theme Package attachment class. 
     4 * 
     5 * @package BuddyPress 
     6 * @subpackage Core 
     7 * @since 2.7.0 
     8 */ 
     9 
     10// Exit if accessed directly. 
     11defined( 'ABSPATH' ) || exit; 
     12 
     13/** 
     14 * BP Attachment Theme Package class. 
     15 * 
     16 * Extends BP Attachment to manage the Theme Package uploads. 
     17 * 
     18 * @since 2.7.0 
     19 */ 
     20class BP_Attachment_Theme_Package extends BP_Attachment { 
     21        /** 
     22         * The constuctor. 
     23         * 
     24         * @since 2.7.0 
     25         */ 
     26        public function __construct() { 
     27                // Allowed theme package types & upload size. 
     28                $allowed_types        = array( 'zip' ); 
     29                $max_upload_file_size = bp_attachments_get_max_upload_file_size( 'theme_package' ); 
     30 
     31                parent::__construct( array( 
     32                        'action'                => 'bp_theme_package_upload', 
     33                        'file_input'            => 'zip', 
     34                        'original_max_filesize' => $max_upload_file_size, 
     35                        'base_dir'              => bp_attachments_uploads_dir_get( 'dir' ), 
     36                        'allowed_mime_types'    => $allowed_types, 
     37 
     38                        // Specific errors for cover images. 
     39                        'upload_error_strings'  => array( 
     40                                11  => sprintf( __( 'That zip archive is too big. Please upload one smaller than %s', 'buddypress' ), size_format( $max_upload_file_size ) ), 
     41                                12  => sprintf( __( 'Please upload only this file type: %s.', 'buddypress' ), reset( $allowed_types ) ), 
     42                        ), 
     43                ) ); 
     44        } 
     45 
     46        /** 
     47         * Theme Package specific rules. 
     48         * 
     49         * @since 2.7.0 
     50         * 
     51         * @param array $file The temporary file attributes (before it has been moved). 
     52         * @return array $file The file with extra errors if needed. 
     53         */ 
     54        public function validate_upload( $file = array() ) { 
     55                // Bail if already an error. 
     56                if ( ! empty( $file['error'] ) ) { 
     57                        return $file; 
     58                } 
     59 
     60                // File size is too big. 
     61                if ( $file['size'] > $this->original_max_filesize ) { 
     62                        $file['error'] = 11; 
     63 
     64                // File is of invalid type. 
     65                } elseif ( ! bp_attachments_check_filetype( $file['tmp_name'], $file['name'], array( 'zip' => 'application/zip' ) ) ) { 
     66                        $file['error'] = 12; 
     67                } 
     68 
     69                // Return with error code attached. 
     70                return $file; 
     71        } 
     72 
     73        /** 
     74         * Set the directory when uploading a file. 
     75         * 
     76         * @since 2.7.0 
     77         * 
     78         * @param array $upload_dir The original Uploads dir. 
     79         * @return array $value Upload data (path, url, basedir...). 
     80         */ 
     81        public function upload_dir_filter( $upload_dir = array() ) { 
     82 
     83                // Set the subdir. 
     84                $subdir  = '/bp-templates'; 
     85 
     86                /** 
     87                 * Filters the Theme Package upload directory. 
     88                 * 
     89                 * @since 2.7.0 
     90                 * 
     91                 * @param array $value      Array containing the path, URL, and other helpful settings. 
     92                 * @param array $upload_dir The original Uploads dir. 
     93                 */ 
     94                return apply_filters( 'bp_attachments_theme_package_upload_dir', array( 
     95                        'path'    => $this->upload_path . $subdir, 
     96                        'url'     => $this->url . $subdir, 
     97                        'subdir'  => $subdir, 
     98                        'basedir' => $this->upload_path, 
     99                        'baseurl' => $this->url, 
     100                        'error'   => false 
     101                ), $upload_dir ); 
     102        } 
     103 
     104        /** 
     105         * Extract the content of the Tempate Pack archive to 
     106         * /wp-content/bp-templates. 
     107         * 
     108         * @since  2.7.0 
     109         * 
     110         * @param  string $zip Absolute path to the uploaded zip archive. 
     111         * @return WP_Error|string      An error if something went wrong during the process. 
     112         *                              Abolute path to the Template Pack dir otherwise. 
     113         */ 
     114        public function extract( $zip = '' ) { 
     115                global $wp_filesystem; 
     116 
     117                if ( empty( $zip ) && ! empty( $this->attachment['file'] ) ) { 
     118                        $zip = $this->attachment['file']; 
     119                } 
     120 
     121                if ( ! file_exists( $zip ) ) { 
     122                        return new WP_Error( 'missing_archive' ); 
     123                } 
     124 
     125                if ( ! bp_core_admin_theme_packages_has_credentials() ) { 
     126                        // Unlink the zip from the uploads. 
     127                        unlink( $zip ); 
     128 
     129                        return new WP_Error( 'credentials_required' ); 
     130                } 
     131 
     132                // The Theme Packages destination is at the root of /wp-content 
     133                $theme_packages_destination = WP_CONTENT_DIR . '/bp-templates'; 
     134 
     135                // Create the BP Templates Dir if it doesn't exit already. 
     136                if ( ! $wp_filesystem->exists( $theme_packages_destination ) ) { 
     137                        if ( ! $wp_filesystem->mkdir( $theme_packages_destination, FS_CHMOD_DIR ) ) { 
     138                                return new WP_Error( 'mkdir_failed' ); 
     139                        } 
     140                } 
     141 
     142                // Set the Theme Package directory 
     143                $theme_package_dir = $theme_packages_destination . '/' . basename( basename( $zip, '.tmp' ), '.zip' ); 
     144 
     145                // Clean up any existing Theme Package. 
     146                if ( $wp_filesystem->is_dir( $theme_package_dir ) ) { 
     147                        $wp_filesystem->delete( $theme_package_dir, true ); 
     148                } 
     149 
     150                // Extract the Theme Package 
     151                $result = unzip_file( $zip, $theme_packages_destination ); 
     152 
     153                // Once extracted, delete the zip. 
     154                unlink( $zip ); 
     155 
     156                if ( is_wp_error( $result ) ) { 
     157 
     158                        $wp_filesystem->delete( $theme_package_dir, true ); 
     159                        if ( 'incompatible_archive' === $result->get_error_code() ) { 
     160                                return new WP_Error( 'incompatible_archive' ); 
     161                        } 
     162                        return $result; 
     163                } 
     164 
     165                return $theme_package_dir; 
     166        } 
     167} 
  • src/bp-loader.php

    diff --git src/bp-loader.php src/bp-loader.php
    index 1d05b96..94df8a3 100644
    class BuddyPress { 
    560560                        'BP_Admin'                     => 'core', 
    561561                        'BP_Attachment_Avatar'         => 'core', 
    562562                        'BP_Attachment_Cover_Image'    => 'core', 
     563                        'BP_Attachment_Theme_Package'  => 'core', 
    563564                        'BP_Attachment'                => 'core', 
    564565                        'BP_Button'                    => 'core', 
    565566                        'BP_Component'                 => 'core', 
    class BuddyPress { 
    756757                        'url'     => trailingslashit( $this->themes_url . '/bp-legacy' ) 
    757758                ) ); 
    758759 
     760                if ( 'legacy' !== bp_get_theme_package_id() ) { 
     761                        $theme_package_data = bp_get_option( '_bp_theme_package_data', array() ); 
     762 
     763                        // Check the Theme Package dir is set and exits before registering it. 
     764                        if ( ! empty( $theme_package_data['dir'] ) && is_dir( $theme_package_data['dir'] ) ) { 
     765                                bp_register_theme_package( $theme_package_data ); 
     766                        } 
     767                } 
     768 
    759769                // Register the basic theme stack. This is really dope. 
    760770                bp_register_template_stack( 'get_stylesheet_directory', 10 ); 
    761771                bp_register_template_stack( 'get_template_directory',   12 );