Skip to:
Content

BuddyPress.org

Changeset 11114


Ignore:
Timestamp:
09/19/2016 02:40:27 AM (10 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.