Skip to:
Content

BuddyPress.org

Changeset 11114


Ignore:
Timestamp:
09/19/2016 02:40:27 AM (3 years ago)
Author:
r-a-y
Message:

Core: Refactor BP_Button class to use an easier syntax.

Previously, to use the BP_Button class, a dev would have to define
several parameters in order to render the HTML element for a button:

array(

'wrapper' => 'div',
'wrapper_id' => 'my-wrapper',
'wrapper_class' => 'my-wrapper-class',
'link_href' => 'hxxp://example.com',
'link_class' => 'my-link-class',
'link_id' => 'my-link-id',
'link_rel' => 'nofollow',
'link_title' => 'my-link-title'

)

This commit simplifies the syntax to:

array(

'parent_element' => 'div',
'parent_attr' => array(

'id' => 'my-wrapper',
'class' => 'my-wrapper-class'

),
'button_attr' => array(

'href' => 'hxxp://example.com',
'class' => 'my-link-class',
'id' => 'my-link-id',
'rel' => 'nofollow',
'title' => 'my-link-title'

)

)

The 'parent_attr' and 'button_attr' parameters can use any arbitrary
HTML attribute set as the array key.

This commit also means we are deprecating the older parameters listed in
the first example. However, we still support these parameters via backward
compatibility.

Fixes #7226.

Location:
trunk
Files:
2 edited

Legend:

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

    r11113 r11114  
    1515 *
    1616 * @since 1.2.6
     17 * @since 2.7.0 Introduced $parent_element, $parent_attr, $button_element, $button_attr as
     18 *              $args parameters.
     19 *              Deprecated $wrapper, $wrapper_id, $wrapper_class, $link_href, $link_class,
     20 *              $link_id, $link_rel, $link_title as $args params.
    1721 *
    1822 * @param array $args {
     
    2024 *
    2125 *     @type string      $id                String describing the button type.
    22  *     @type string      $component         The name of the component the button belongs to.
    23  *                                          Default: 'core'.
    24  *     @type bool        $must_be_logged_in Optional. Does the user need to be logged
    25  *                                          in to see this button? Default: true.
    26  *     @type bool        $block_self        Optional. True if the button should be hidden
    27  *                                          when a user is viewing his own profile.
    28  *                                          Default: true.
    29  *     @type string|bool $wrapper           Optional. HTML element type that should wrap
    30  *                                          the button: 'div', 'span', 'p', or 'li'.
    31  *                                          False for no wrapper at all. Default: 'div'.
    32  *     @type string      $wrapper_id        Optional. DOM ID of the button wrapper element.
    33  *                                          Default: ''.
    34  *     @type string      $wrapper_class     Optional. DOM class of the button wrapper
    35  *                                          element. Default: ''.
    36  *     @type string      $link_href         Optional. Destination link of the button.
    37  *                                          Default: ''.
    38  *     @type string      $link_class        Optional. DOM class of the button. Default: ''.
    39  *     @type string      $link_id           Optional. DOM ID of the button. Default: ''.
    40  *     @type string      $link_rel          Optional. DOM 'rel' attribute of the button.
    41  *                                          Default: ''.
    42  *     @type string      $link_title        Optional. Title attribute of the button.
    43  *                                          Default: ''.
    44  *     @type string      $link_text         Optional. Text to appear on the button.
    45  *                                          Default: ''.
     26 *     @type string      $component         The name of the component the button belongs to. Default: 'core'.
     27 *     @type bool        $must_be_logged_in Optional. Does the user need to be logged in to see this button? Default:
     28 *                                          true.
     29 *     @type bool        $block_self        Optional. True if the button should be hidden when a user is viewing his
     30 *                                          own profile. Default: true.
     31 *     @type string      $parent_element    Optional. Parent element to wrap button around. Default: 'div'.
     32 *     @type array       $parent_attr       Optional. Element attributes for parent element. Set whatever attributes
     33 *                                          like 'id', 'class' as array keys.
     34 *     @type string      $button_element    Optional. Button element. Default: 'a'.
     35 *     @type array       $button_attr       Optional. Button attributes. Set whatever attributes like 'id', 'class' as
     36 *                                          array keys.
     37 *     @type string      $link_text         Optional. Text to appear on the button. Default: ''.
     38 *     @type string|bool $wrapper           Deprecated. Use $parent_element instead.
     39 *     @type string      $wrapper_id        Deprecated. Use $parent_attr and set 'id' as array key.
     40 *     @type string      $wrapper_class     Deprecated. Use $parent_attr and set 'class' as array key.
     41 *     @type string      $link_href         Deprecated. Use $button_attr and set 'href' as array key.
     42 *     @type string      $link_class        Deprecated. Use $button_attr and set 'class' as array key.
     43 *     @type string      $link_id           Deprecated. Use $button_attr and set 'id' as array key.
     44 *     @type string      $link_rel          Deprecated. Use $button_attr and set 'rel' as array key.
     45 *     @type string      $link_title        Deprecated. Use $button_attr and set 'title' as array key.
    4646 * }
    4747 */
     
    8181
    8282    /**
     83     * Parent element to wrap button around.
     84     *
     85     * @since 2.7.0
     86     *
     87     * @var string Default: 'div'.
     88     */
     89    public $parent_element = 'div';
     90
     91    /**
     92     * Element attributes for parent element.
     93     *
     94     * @since 2.7.0
     95     *
     96     * @var array Set whatever attributes like 'id', 'class' as array key.
     97     */
     98    public $parent_attr = array();
     99
     100    /** Button ****************************************************************/
     101
     102    /**
     103     * Button element.
     104     *
     105     * @since 2.7.0
     106     *
     107     * @var string Default: 'a'.
     108     */
     109    public $button_element = 'a';
     110
     111    /**
     112     * Button attributes.
     113     *
     114     * @since 2.7.0
     115     *
     116     * @var array Set whatever attributes like 'id', 'href' as array key.
     117     */
     118    public $button_attr = array();
     119
     120    /**
     121     * The contents of the button link.
     122     *
     123     * @var string
     124     */
     125    public $link_text = '';
     126
     127    /** HTML result
     128     *
     129     * @var string
     130     */
     131    public $contents = '';
     132
     133    /** Deprecated ***********************************************************/
     134
     135    /**
    83136     * The type of DOM element to use for a wrapper.
    84137     *
    85      * @var string|bool 'div', 'span', 'p', 'li', or false for no wrapper.
    86      */
    87     public $wrapper = 'div';
     138     * @deprecated 2.7.0 Use $parent_element instead.
     139     *
     140     * @var string|bool
     141     */
     142    public $wrapper = '';
    88143
    89144    /**
    90145     * The DOM class of the button wrapper.
    91146     *
     147     * @deprecated 2.7.0 Set 'class' key in $parent_attr instead.
     148     *
    92149     * @var string
    93150     */
     
    97154     * The DOM ID of the button wrapper.
    98155     *
     156     * @deprecated 2.7.0 Set 'id' key in $parent_attr instead.
     157     *
    99158     * @var string
    100159     */
    101160    public $wrapper_id = '';
    102161
    103     /** Button ****************************************************************/
    104 
    105162    /**
    106163     * The destination link of the button.
    107164     *
     165     * @deprecated 2.7.0 Set 'href' key in $button_attr instead.
     166     *
    108167     * @var string
    109168     */
     
    113172     * The DOM class of the button link.
    114173     *
     174     * @deprecated 2.7.0 Set 'class' key in $button_attr instead.
     175     *
    115176     * @var string
    116177     */
     
    120181     * The DOM ID of the button link.
    121182     *
     183     * @deprecated 2.7.0 Set 'id' key in $button_attr instead.
     184     *
    122185     * @var string
    123186     */
     
    127190     * The DOM rel value of the button link.
    128191     *
     192     * @deprecated 2.7.0 Set 'rel' key in $button_attr instead.
     193     *
    129194     * @var string
    130195     */
     
    134199     * Title of the button link.
    135200     *
     201     * @deprecated 2.7.0 Set 'title' key in $button_attr instead.
     202     *
    136203     * @var string
    137204     */
    138205    public $link_title = '';
    139206
    140     /**
    141      * The contents of the button link.
    142      *
    143      * @var string
    144      */
    145     public $link_text = '';
    146 
    147     /** HTML result
    148      *
    149      * @var string
    150      */
    151     public $contents = '';
    152 
    153207    /** Methods ***************************************************************/
    154208
     
    164218        $r = wp_parse_args( $args, get_class_vars( __CLASS__ ) );
    165219
    166         // Required button properties.
    167         $this->id                = $r['id'];
    168         $this->component         = $r['component'];
    169         $this->must_be_logged_in = (bool) $r['must_be_logged_in'];
    170         $this->block_self        = (bool) $r['block_self'];
    171         $this->wrapper           = $r['wrapper'];
    172 
    173         // $id and $component are required
    174         if ( empty( $r['id'] ) || empty( $r['component'] ) )
    175             return false;
    176 
    177         // No button if component is not active.
    178         if ( ! bp_is_active( $this->component ) )
    179             return false;
    180 
    181         // No button for guests if must be logged in.
    182         if ( true == $this->must_be_logged_in && ! is_user_logged_in() )
    183             return false;
    184 
    185         // The block_self property.
    186         if ( true == $this->block_self ) {
    187             // No button if you are the current user in a members loop
    188             // This condition takes precedence, because members loops
    189             // can be found on user profiles.
    190             if ( bp_get_member_user_id() ) {
    191                 if ( is_user_logged_in() && bp_loggedin_user_id() == bp_get_member_user_id() ) {
    192                     return false;
    193                 }
    194 
    195             // No button if viewing your own profile (and not in
    196             // a members loop).
    197             } elseif ( bp_is_my_profile() ) {
    198                 return false;
    199             }
    200         }
    201 
    202         // Wrapper properties.
    203         if ( false !== $this->wrapper ) {
    204 
    205             // Wrapper ID.
    206             if ( !empty( $r['wrapper_id'] ) ) {
    207                 $this->wrapper_id    = ' id="' . $r['wrapper_id'] . '"';
    208             }
    209 
    210             // Wrapper class.
    211             if ( !empty( $r['wrapper_class'] ) ) {
    212                 $this->wrapper_class = ' class="generic-button ' . $r['wrapper_class'] . '"';
    213             } else {
    214                 $this->wrapper_class = ' class="generic-button"';
    215             }
    216 
    217             // Set before and after.
    218             $before = '<' . $r['wrapper'] . $this->wrapper_class . $this->wrapper_id . '>';
    219             $after  = '</' . $r['wrapper'] . '>';
    220 
    221         // No wrapper.
    222         } else {
    223             $before = $after = '';
    224         }
    225 
    226         // Link properties.
     220        // Backward compatibility with deprecated parameters.
     221        $r = $this->backward_compatibility_args( $r );
     222
     223        // Deprecated. Subject to removal in a future release.
     224        $this->wrapper = $r['wrapper'];
    227225        if ( !empty( $r['link_id']    ) ) $this->link_id    = ' id="' .    $r['link_id']    . '"';
    228226        if ( !empty( $r['link_href']  ) ) $this->link_href  = ' href="' .  $r['link_href']  . '"';
     
    232230        if ( !empty( $r['link_text']  ) ) $this->link_text  =              $r['link_text'];
    233231
     232        // Required button properties.
     233        $this->id                = $r['id'];
     234        $this->component         = $r['component'];
     235        $this->must_be_logged_in = (bool) $r['must_be_logged_in'];
     236        $this->block_self        = (bool) $r['block_self'];
     237
     238        // $id and $component are required and component must be active.
     239        if ( empty( $r['id'] ) || empty( $r['component'] ) || ! bp_is_active( $this->component ) ) {
     240            return false;
     241        }
     242
     243        // No button for guests if must be logged in.
     244        if ( true == $this->must_be_logged_in && ! is_user_logged_in() ) {
     245            return false;
     246        }
     247
     248        // The block_self property.
     249        if ( true == $this->block_self ) {
     250            /*
     251             * No button if you are the current user in a members loop.
     252             *
     253             * This condition takes precedence, because members loops can be found on user
     254             * profiles.
     255             */
     256            if ( bp_get_member_user_id() ) {
     257                if ( is_user_logged_in() && bp_loggedin_user_id() == bp_get_member_user_id() ) {
     258                    return false;
     259                }
     260
     261            // No button if viewing your own profile (and not in a members loop).
     262            } elseif ( bp_is_my_profile() ) {
     263                return false;
     264            }
     265        }
     266
     267        // Should we use a parent element?
     268        if ( ! empty( $r['parent_element'] ) ) {
     269            if ( ! isset( $r['parent_attr']['class'] ) ) {
     270                $r['parent_attr']['class'] = '';
     271            }
     272
     273            // Always add 'generic-button' class.
     274            if ( false === strpos( $r['parent_attr']['class'], 'generic-button' ) ) {
     275                if ( ! empty( $r['parent_attr']['class'] ) ) {
     276                    $r['parent_attr']['class'] .= ' ';
     277                }
     278                $r['parent_attr']['class'] .= 'generic-button';
     279            }
     280
     281            // Render parent element attributes.
     282            $parent_elem = new BP_Core_HTML_Element( array(
     283                'element' => $r['parent_element'],
     284                'attr'    => $r['parent_attr']
     285            ) );
     286
     287            // Set before and after.
     288            $before = $parent_elem->get( 'open_tag' );
     289            $after  = $parent_elem->get( 'close_tag' );
     290
     291        // No parent element.
     292        } else {
     293            $before = $after = '';
     294        }
     295
     296        // Button properties.
     297        $button = '';
     298        if ( ! empty( $r['button_element'] ) ) {
     299            $button = new BP_Core_HTML_Element( array(
     300                'element'    => $r['button_element'],
     301                'attr'       => $r['button_attr'],
     302                'inner_html' => ! empty( $r['link_text'] ) ? $r['link_text'] : ''
     303            ) );
     304            $button = $button->contents();
     305        }
     306
    234307        // Build the button.
    235         $this->contents = $before . '<a'. $this->link_href . $this->link_title . $this->link_id . $this->link_rel . $this->link_class . '>' . $this->link_text . '</a>' . $after;
     308        $this->contents = $before . $button . $after;
    236309
    237310        /**
     
    253326    }
    254327
     328
     329    /**
     330     * Provide backward compatibility for deprecated button arguments.
     331     *
     332     * @since 2.7.0.
     333     *
     334     * @param  array $r See {@link BP_Button} class for full documentation.
     335     * @return array
     336     */
     337    protected function backward_compatibility_args( $r = array() ) {
     338        // Array of deprecated arguments.
     339        $backpat_args = array(
     340            'wrapper', 'wrapper_class', 'wrapper_id',
     341            'link_href', 'link_class', 'link_id', 'link_rel', 'link_title'
     342        );
     343
     344        foreach ( $backpat_args as $prop ) {
     345            if ( empty( $r[ $prop ] ) ) {
     346                continue;
     347            }
     348
     349            $parent = $child = false;
     350            $sep    = strpos( $prop, '_' );
     351
     352            // Check if this is an attribute.
     353            if ( false !== $sep ) {
     354                $child  = true;
     355                $parent = substr( $prop, 0, $sep );
     356            } else {
     357                $parent = $prop;
     358            }
     359
     360            if ( 'wrapper' === $parent ) {
     361                $parent = 'parent';
     362            } else {
     363                $parent = 'button';
     364            }
     365
     366            // Set element.
     367            if ( false === $child ) {
     368                $r[ "{$parent}_element" ] = $r[ $prop ];
     369
     370            // Set attributes.
     371            } elseif ( true === $child ) {
     372                $new_prop = substr( $prop, strpos( $prop, '_' ) +1 );
     373                if ( empty( $r[ "{$parent}_attr" ] ) ) {
     374                    $r[ "{$parent}_attr" ] = array();
     375                }
     376
     377                if ( empty( $r[ "{$parent}_attr" ][ $new_prop ] ) ) {
     378                    $r[ "{$parent}_attr" ][ $new_prop ] = $r[ $prop ];
     379                }
     380            }
     381        }
     382
     383        return $r;
     384    }
     385
     386
    255387    /**
    256388     * Return the markup for the generated button.
  • trunk/tests/phpunit/testcases/core/class-bp-button.php

    r9819 r11114  
    163163        $GLOBALS['members_template'] = null;
    164164    }
     165
     166    /**
     167     * @ticket BP7226
     168     */
     169    public function test_bp_button_new_args() {
     170        $b = new BP_Button( array(
     171            'id' => 'foo',
     172            'component' => 'members',
     173            'block_self' => false,
     174            'must_be_logged_in' => false,
     175            'parent_element' => 'section',
     176            'parent_attr' => array(
     177                'class' => 'section-class',
     178                'id' => 'section-id',
     179                'data-parent' => 'foo',
     180            ),
     181            'button_element' => 'button',
     182            'button_attr' => array(
     183                'autofocus' => 'autofocus',
     184                'type' => 'submit',
     185                'name' => 'my-button'
     186            )
     187        ) );
     188
     189        $this->assertNotFalse( strpos( $b->contents, '<section ' ) );
     190        $this->assertNotFalse( strpos( $b->contents, 'class="section-class ' ) );
     191        $this->assertNotFalse( strpos( $b->contents, 'id="section-id"' ) );
     192        $this->assertNotFalse( strpos( $b->contents, 'data-parent="foo"' ) );
     193        $this->assertNotFalse( strpos( $b->contents, '<button ' ) );
     194        $this->assertNotFalse( strpos( $b->contents, 'autofocus="autofocus"' ) );
     195        $this->assertNotFalse( strpos( $b->contents, 'type="submit"' ) );
     196        $this->assertNotFalse( strpos( $b->contents, 'name="my-button"' ) );
     197    }
     198
     199    /**
     200     * @ticket BP7226
     201     */
     202    public function test_bp_button_deprecated_args_should_still_render() {
     203        $b = new BP_Button( array(
     204            'id' => 'foo',
     205            'component' => 'members',
     206            'block_self' => false,
     207            'must_be_logged_in' => false,
     208            'wrapper' => 'section',
     209            'wrapper_class' => 'section-class',
     210            'wrapper_id' => 'section-id',
     211            'link_href' => 'http://example.com',
     212            'link_class' => 'link-class',
     213            'link_id' => 'link-id',
     214            'link_rel' => 'nofollow',
     215            'link_title' => 'link-title'
     216        ) );
     217
     218        $this->assertNotFalse( strpos( $b->contents, '<section ' ) );
     219        $this->assertNotFalse( strpos( $b->contents, 'class="section-class ' ) );
     220        $this->assertNotFalse( strpos( $b->contents, 'id="section-id"' ) );
     221        $this->assertNotFalse( strpos( $b->contents, 'href="http://example.com"' ) );
     222        $this->assertNotFalse( strpos( $b->contents, 'class="link-class"' ) );
     223        $this->assertNotFalse( strpos( $b->contents, 'id="link-id"' ) );
     224        $this->assertNotFalse( strpos( $b->contents, 'rel="nofollow"' ) );
     225        $this->assertNotFalse( strpos( $b->contents, 'title="link-title"' ) );
     226    }
     227
     228    /**
     229     * @ticket BP7226
     230     */
     231    public function test_bp_button_new_element_attrs_have_precedence_over_deprecated_element_attrs() {
     232        $b = new BP_Button( array(
     233            'id' => 'foo',
     234            'component' => 'members',
     235            'block_self' => false,
     236            'must_be_logged_in' => false,
     237            'button_element' => 'button',
     238            'button_attr' => array(
     239                'class' => 'new-class',
     240            ),
     241            'link_class' => 'old-class'
     242        ) );
     243
     244        $this->assertNotFalse( strpos( $b->contents, '<button class="new-class"' ) );
     245    }
     246
     247    /**
     248     * @ticket BP7226
     249     */
     250    public function test_bp_button_new_element_attrs_should_not_render_for_empty_attrs() {
     251        $b = new BP_Button( array(
     252            'id' => 'foo',
     253            'component' => 'members',
     254            'block_self' => false,
     255            'must_be_logged_in' => false,
     256            'button_element' => 'button',
     257            'button_attr' => array(
     258                'class' => '',
     259            ),
     260        ) );
     261
     262        $this->assertFalse( strpos( $b->contents, '<button class=""' ) );
     263    }
    165264}
Note: See TracChangeset for help on using the changeset viewer.