<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[BuddyPress][11114] trunk: Core: Refactor `BP_Button` class to use an easier syntax.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="http://buddypress.trac.wordpress.org/changeset/11114">11114</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"http://buddypress.trac.wordpress.org/changeset/11114","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>r-a-y</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2016-09-19 02:40:27 +0000 (Mon, 19 Sep 2016)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>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 <a href="http://buddypress.trac.wordpress.org/ticket/7226">#7226</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcbpcoreclassesclassbpbuttonphp">trunk/src/bp-core/classes/class-bp-button.php</a></li>
<li><a href="#trunktestsphpunittestcasescoreclassbpbuttonphp">trunk/tests/phpunit/testcases/core/class-bp-button.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcbpcoreclassesclassbpbuttonphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/bp-core/classes/class-bp-button.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/bp-core/classes/class-bp-button.php     2016-09-19 02:26:21 UTC (rev 11113)
+++ trunk/src/bp-core/classes/class-bp-button.php       2016-09-19 02:40:27 UTC (rev 11114)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -14,35 +14,35 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * API to create BuddyPress buttons.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 1.2.6
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @since 2.7.0 Introduced $parent_element, $parent_attr, $button_element, $button_attr as
+ *              $args parameters.
+ *              Deprecated $wrapper, $wrapper_id, $wrapper_class, $link_href, $link_class,
+ *              $link_id, $link_rel, $link_title as $args params.
</ins><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @param array $args {
</span><span class="cx" style="display: block; padding: 0 10px">  *     Array of arguments.
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  *     @type string      $id                String describing the button type.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- *     @type string      $component         The name of the component the button belongs to.
- *                                          Default: 'core'.
- *     @type bool        $must_be_logged_in Optional. Does the user need to be logged
- *                                          in to see this button? Default: true.
- *     @type bool        $block_self        Optional. True if the button should be hidden
- *                                          when a user is viewing his own profile.
- *                                          Default: true.
- *     @type string|bool $wrapper           Optional. HTML element type that should wrap
- *                                          the button: 'div', 'span', 'p', or 'li'.
- *                                          False for no wrapper at all. Default: 'div'.
- *     @type string      $wrapper_id        Optional. DOM ID of the button wrapper element.
- *                                          Default: ''.
- *     @type string      $wrapper_class     Optional. DOM class of the button wrapper
- *                                          element. Default: ''.
- *     @type string      $link_href         Optional. Destination link of the button.
- *                                          Default: ''.
- *     @type string      $link_class        Optional. DOM class of the button. Default: ''.
- *     @type string      $link_id           Optional. DOM ID of the button. Default: ''.
- *     @type string      $link_rel          Optional. DOM 'rel' attribute of the button.
- *                                          Default: ''.
- *     @type string      $link_title        Optional. Title attribute of the button.
- *                                          Default: ''.
- *     @type string      $link_text         Optional. Text to appear on the button.
- *                                          Default: ''.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ *     @type string      $component         The name of the component the button belongs to. Default: 'core'.
+ *     @type bool        $must_be_logged_in Optional. Does the user need to be logged in to see this button? Default:
+ *                                          true.
+ *     @type bool        $block_self        Optional. True if the button should be hidden when a user is viewing his
+ *                                          own profile. Default: true.
+ *     @type string      $parent_element    Optional. Parent element to wrap button around. Default: 'div'.
+ *     @type array       $parent_attr       Optional. Element attributes for parent element. Set whatever attributes
+ *                                          like 'id', 'class' as array keys.
+ *     @type string      $button_element    Optional. Button element. Default: 'a'.
+ *     @type array       $button_attr       Optional. Button attributes. Set whatever attributes like 'id', 'class' as
+ *                                          array keys.
+ *     @type string      $link_text         Optional. Text to appear on the button. Default: ''.
+ *     @type string|bool $wrapper           Deprecated. Use $parent_element instead.
+ *     @type string      $wrapper_id        Deprecated. Use $parent_attr and set 'id' as array key.
+ *     @type string      $wrapper_class     Deprecated. Use $parent_attr and set 'class' as array key.
+ *     @type string      $link_href         Deprecated. Use $button_attr and set 'href' as array key.
+ *     @type string      $link_class        Deprecated. Use $button_attr and set 'class' as array key.
+ *     @type string      $link_id           Deprecated. Use $button_attr and set 'id' as array key.
+ *     @type string      $link_rel          Deprecated. Use $button_attr and set 'rel' as array key.
+ *     @type string      $link_title        Deprecated. Use $button_attr and set 'title' as array key.
</ins><span class="cx" style="display: block; padding: 0 10px">  * }
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> class BP_Button {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -80,15 +80,72 @@
</span><span class="cx" style="display: block; padding: 0 10px">        /** Wrapper ***************************************************************/
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * Parent element to wrap button around.
+        *
+        * @since 2.7.0
+        *
+        * @var string Default: 'div'.
+        */
+       public $parent_element = 'div';
+
+       /**
+        * Element attributes for parent element.
+        *
+        * @since 2.7.0
+        *
+        * @var array Set whatever attributes like 'id', 'class' as array key.
+        */
+       public $parent_attr = array();
+
+       /** Button ****************************************************************/
+
+       /**
+        * Button element.
+        *
+        * @since 2.7.0
+        *
+        * @var string Default: 'a'.
+        */
+       public $button_element = 'a';
+
+       /**
+        * Button attributes.
+        *
+        * @since 2.7.0
+        *
+        * @var array Set whatever attributes like 'id', 'href' as array key.
+        */
+       public $button_attr = array();
+
+       /**
+        * The contents of the button link.
+        *
+        * @var string
+        */
+       public $link_text = '';
+
+       /** HTML result
+        *
+        * @var string
+        */
+       public $contents = '';
+
+       /** Deprecated ***********************************************************/
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * The type of DOM element to use for a wrapper.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * @var string|bool 'div', 'span', 'p', 'li', or false for no wrapper.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * @deprecated 2.7.0 Use $parent_element instead.
+        *
+        * @var string|bool
</ins><span class="cx" style="display: block; padding: 0 10px">          */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        public $wrapper = 'div';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public $wrapper = '';
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="cx" style="display: block; padding: 0 10px">         * The DOM class of the button wrapper.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @deprecated 2.7.0 Set 'class' key in $parent_attr instead.
+        *
</ins><span class="cx" style="display: block; padding: 0 10px">          * @var string
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public $wrapper_class = '';
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -96,15 +153,17 @@
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="cx" style="display: block; padding: 0 10px">         * The DOM ID of the button wrapper.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @deprecated 2.7.0 Set 'id' key in $parent_attr instead.
+        *
</ins><span class="cx" style="display: block; padding: 0 10px">          * @var string
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public $wrapper_id = '';
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        /** Button ****************************************************************/
-
</del><span class="cx" style="display: block; padding: 0 10px">         /**
</span><span class="cx" style="display: block; padding: 0 10px">         * The destination link of the button.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @deprecated 2.7.0 Set 'href' key in $button_attr instead.
+        *
</ins><span class="cx" style="display: block; padding: 0 10px">          * @var string
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public $link_href = '';
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -112,6 +171,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="cx" style="display: block; padding: 0 10px">         * The DOM class of the button link.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @deprecated 2.7.0 Set 'class' key in $button_attr instead.
+        *
</ins><span class="cx" style="display: block; padding: 0 10px">          * @var string
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public $link_class = '';
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -119,6 +180,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="cx" style="display: block; padding: 0 10px">         * The DOM ID of the button link.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @deprecated 2.7.0 Set 'id' key in $button_attr instead.
+        *
</ins><span class="cx" style="display: block; padding: 0 10px">          * @var string
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public $link_id = '';
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -126,6 +189,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="cx" style="display: block; padding: 0 10px">         * The DOM rel value of the button link.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @deprecated 2.7.0 Set 'rel' key in $button_attr instead.
+        *
</ins><span class="cx" style="display: block; padding: 0 10px">          * @var string
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public $link_rel = '';
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -133,23 +198,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="cx" style="display: block; padding: 0 10px">         * Title of the button link.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @deprecated 2.7.0 Set 'title' key in $button_attr instead.
+        *
</ins><span class="cx" style="display: block; padding: 0 10px">          * @var string
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public $link_title = '';
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        /**
-        * The contents of the button link.
-        *
-        * @var string
-        */
-       public $link_text = '';
-
-       /** HTML result
-        *
-        * @var string
-        */
-       public $contents = '';
-
</del><span class="cx" style="display: block; padding: 0 10px">         /** Methods ***************************************************************/
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -163,76 +217,95 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $r = wp_parse_args( $args, get_class_vars( __CLASS__ ) );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                // Backward compatibility with deprecated parameters.
+               $r = $this->backward_compatibility_args( $r );
+
+               // Deprecated. Subject to removal in a future release.
+               $this->wrapper = $r['wrapper'];
+               if ( !empty( $r['link_id']    ) ) $this->link_id    = ' id="' .    $r['link_id']    . '"';
+               if ( !empty( $r['link_href']  ) ) $this->link_href  = ' href="' .  $r['link_href']  . '"';
+               if ( !empty( $r['link_title'] ) ) $this->link_title = ' title="' . $r['link_title'] . '"';
+               if ( !empty( $r['link_rel']   ) ) $this->link_rel   = ' rel="' .   $r['link_rel']   . '"';
+               if ( !empty( $r['link_class'] ) ) $this->link_class = ' class="' . $r['link_class'] . '"';
+               if ( !empty( $r['link_text']  ) ) $this->link_text  =              $r['link_text'];
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 // Required button properties.
</span><span class="cx" style="display: block; padding: 0 10px">                $this->id                = $r['id'];
</span><span class="cx" style="display: block; padding: 0 10px">                $this->component         = $r['component'];
</span><span class="cx" style="display: block; padding: 0 10px">                $this->must_be_logged_in = (bool) $r['must_be_logged_in'];
</span><span class="cx" style="display: block; padding: 0 10px">                $this->block_self        = (bool) $r['block_self'];
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $this->wrapper           = $r['wrapper'];
</del><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                // $id and $component are required
-               if ( empty( $r['id'] ) || empty( $r['component'] ) )
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // $id and $component are required and component must be active.
+               if ( empty( $r['id'] ) || empty( $r['component'] ) || ! bp_is_active( $this->component ) ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                         return false;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                // No button if component is not active.
-               if ( ! bp_is_active( $this->component ) )
-                       return false;
-
</del><span class="cx" style="display: block; padding: 0 10px">                 // No button for guests if must be logged in.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( true == $this->must_be_logged_in && ! is_user_logged_in() )
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( true == $this->must_be_logged_in && ! is_user_logged_in() ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                         return false;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // The block_self property.
</span><span class="cx" style="display: block; padding: 0 10px">                if ( true == $this->block_self ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        // No button if you are the current user in a members loop
-                       // This condition takes precedence, because members loops
-                       // can be found on user profiles.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 /*
+                        * No button if you are the current user in a members loop.
+                        *
+                        * This condition takes precedence, because members loops can be found on user
+                        * profiles.
+                        */
</ins><span class="cx" style="display: block; padding: 0 10px">                         if ( bp_get_member_user_id() ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                if ( is_user_logged_in() && bp_loggedin_user_id() == bp_get_member_user_id() ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                        return false;
</span><span class="cx" style="display: block; padding: 0 10px">                                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        // No button if viewing your own profile (and not in
-                       // a members loop).
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 // No button if viewing your own profile (and not in a members loop).
</ins><span class="cx" style="display: block; padding: 0 10px">                         } elseif ( bp_is_my_profile() ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                return false;
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                // Wrapper properties.
-               if ( false !== $this->wrapper ) {
-
-                       // Wrapper ID.
-                       if ( !empty( $r['wrapper_id'] ) ) {
-                               $this->wrapper_id    = ' id="' . $r['wrapper_id'] . '"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // Should we use a parent element?
+               if ( ! empty( $r['parent_element'] ) ) {
+                       if ( ! isset( $r['parent_attr']['class'] ) ) {
+                               $r['parent_attr']['class'] = '';
</ins><span class="cx" style="display: block; padding: 0 10px">                         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        // Wrapper class.
-                       if ( !empty( $r['wrapper_class'] ) ) {
-                               $this->wrapper_class = ' class="generic-button ' . $r['wrapper_class'] . '"';
-                       } else {
-                               $this->wrapper_class = ' class="generic-button"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 // Always add 'generic-button' class.
+                       if ( false === strpos( $r['parent_attr']['class'], 'generic-button' ) ) {
+                               if ( ! empty( $r['parent_attr']['class'] ) ) {
+                                       $r['parent_attr']['class'] .= ' ';
+                               }
+                               $r['parent_attr']['class'] .= 'generic-button';
</ins><span class="cx" style="display: block; padding: 0 10px">                         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        // Render parent element attributes.
+                       $parent_elem = new BP_Core_HTML_Element( array(
+                               'element' => $r['parent_element'],
+                               'attr'    => $r['parent_attr']
+                       ) );
+
</ins><span class="cx" style="display: block; padding: 0 10px">                         // Set before and after.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $before = '<' . $r['wrapper'] . $this->wrapper_class . $this->wrapper_id . '>';
-                       $after  = '</' . $r['wrapper'] . '>';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $before = $parent_elem->get( 'open_tag' );
+                       $after  = $parent_elem->get( 'close_tag' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                // No wrapper.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // No parent element.
</ins><span class="cx" style="display: block; padding: 0 10px">                 } else {
</span><span class="cx" style="display: block; padding: 0 10px">                        $before = $after = '';
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                // Link properties.
-               if ( !empty( $r['link_id']    ) ) $this->link_id    = ' id="' .    $r['link_id']    . '"';
-               if ( !empty( $r['link_href']  ) ) $this->link_href  = ' href="' .  $r['link_href']  . '"';
-               if ( !empty( $r['link_title'] ) ) $this->link_title = ' title="' . $r['link_title'] . '"';
-               if ( !empty( $r['link_rel']   ) ) $this->link_rel   = ' rel="' .   $r['link_rel']   . '"';
-               if ( !empty( $r['link_class'] ) ) $this->link_class = ' class="' . $r['link_class'] . '"';
-               if ( !empty( $r['link_text']  ) ) $this->link_text  =              $r['link_text'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // Button properties.
+               $button = '';
+               if ( ! empty( $r['button_element'] ) ) {
+                       $button = new BP_Core_HTML_Element( array(
+                               'element'    => $r['button_element'],
+                               'attr'       => $r['button_attr'],
+                               'inner_html' => ! empty( $r['link_text'] ) ? $r['link_text'] : ''
+                       ) );
+                       $button = $button->contents();
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // Build the button.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $this->contents = $before . '<a'. $this->link_href . $this->link_title . $this->link_id . $this->link_rel . $this->link_class . '>' . $this->link_text . '</a>' . $after;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $this->contents = $before . $button . $after;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                /**
</span><span class="cx" style="display: block; padding: 0 10px">                 * Filters the button based on class parameters.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -252,7 +325,66 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $this->contents = apply_filters( 'bp_button_' . $this->component . '_' . $this->id, $this->contents, $this, $before, $after, $r );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px">         /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * Provide backward compatibility for deprecated button arguments.
+        *
+        * @since 2.7.0.
+        *
+        * @param  array $r See {@link BP_Button} class for full documentation.
+        * @return array
+        */
+       protected function backward_compatibility_args( $r = array() ) {
+               // Array of deprecated arguments.
+               $backpat_args = array(
+                       'wrapper', 'wrapper_class', 'wrapper_id',
+                       'link_href', 'link_class', 'link_id', 'link_rel', 'link_title'
+               );
+
+               foreach ( $backpat_args as $prop ) {
+                       if ( empty( $r[ $prop ] ) ) {
+                               continue;
+                       }
+
+                       $parent = $child = false;
+                       $sep    = strpos( $prop, '_' );
+
+                       // Check if this is an attribute.
+                       if ( false !== $sep ) {
+                               $child  = true;
+                               $parent = substr( $prop, 0, $sep );
+                       } else {
+                               $parent = $prop;
+                       }
+
+                       if ( 'wrapper' === $parent ) {
+                               $parent = 'parent';
+                       } else {
+                               $parent = 'button';
+                       }
+
+                       // Set element.
+                       if ( false === $child ) {
+                               $r[ "{$parent}_element" ] = $r[ $prop ];
+
+                       // Set attributes.
+                       } elseif ( true === $child ) {
+                               $new_prop = substr( $prop, strpos( $prop, '_' ) +1 );
+                               if ( empty( $r[ "{$parent}_attr" ] ) ) {
+                                       $r[ "{$parent}_attr" ] = array();
+                               }
+
+                               if ( empty( $r[ "{$parent}_attr" ][ $new_prop ] ) ) {
+                                       $r[ "{$parent}_attr" ][ $new_prop ] = $r[ $prop ];
+                               }
+                       }
+               }
+
+               return $r;
+       }
+
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * Return the markup for the generated button.
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 1.2.6
</span></span></pre></div>
<a id="trunktestsphpunittestcasescoreclassbpbuttonphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/testcases/core/class-bp-button.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/testcases/core/class-bp-button.php    2016-09-19 02:26:21 UTC (rev 11113)
+++ trunk/tests/phpunit/testcases/core/class-bp-button.php      2016-09-19 02:40:27 UTC (rev 11114)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -162,4 +162,103 @@
</span><span class="cx" style="display: block; padding: 0 10px">                // clean up
</span><span class="cx" style="display: block; padding: 0 10px">                $GLOBALS['members_template'] = null;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+       /**
+        * @ticket BP7226
+        */
+       public function test_bp_button_new_args() {
+               $b = new BP_Button( array(
+                       'id' => 'foo',
+                       'component' => 'members',
+                       'block_self' => false,
+                       'must_be_logged_in' => false,
+                       'parent_element' => 'section',
+                       'parent_attr' => array(
+                               'class' => 'section-class',
+                               'id' => 'section-id',
+                               'data-parent' => 'foo',
+                       ),
+                       'button_element' => 'button',
+                       'button_attr' => array(
+                               'autofocus' => 'autofocus',
+                               'type' => 'submit',
+                               'name' => 'my-button'
+                       )
+               ) );
+
+               $this->assertNotFalse( strpos( $b->contents, '<section ' ) );
+               $this->assertNotFalse( strpos( $b->contents, 'class="section-class ' ) );
+               $this->assertNotFalse( strpos( $b->contents, 'id="section-id"' ) );
+               $this->assertNotFalse( strpos( $b->contents, 'data-parent="foo"' ) );
+               $this->assertNotFalse( strpos( $b->contents, '<button ' ) );
+               $this->assertNotFalse( strpos( $b->contents, 'autofocus="autofocus"' ) );
+               $this->assertNotFalse( strpos( $b->contents, 'type="submit"' ) );
+               $this->assertNotFalse( strpos( $b->contents, 'name="my-button"' ) );
+       }
+
+       /**
+        * @ticket BP7226
+        */
+       public function test_bp_button_deprecated_args_should_still_render() {
+               $b = new BP_Button( array(
+                       'id' => 'foo',
+                       'component' => 'members',
+                       'block_self' => false,
+                       'must_be_logged_in' => false,
+                       'wrapper' => 'section',
+                       'wrapper_class' => 'section-class',
+                       'wrapper_id' => 'section-id',
+                       'link_href' => 'http://example.com',
+                       'link_class' => 'link-class',
+                       'link_id' => 'link-id',
+                       'link_rel' => 'nofollow',
+                       'link_title' => 'link-title'
+               ) );
+
+               $this->assertNotFalse( strpos( $b->contents, '<section ' ) );
+               $this->assertNotFalse( strpos( $b->contents, 'class="section-class ' ) );
+               $this->assertNotFalse( strpos( $b->contents, 'id="section-id"' ) );
+               $this->assertNotFalse( strpos( $b->contents, 'href="http://example.com"' ) );
+               $this->assertNotFalse( strpos( $b->contents, 'class="link-class"' ) );
+               $this->assertNotFalse( strpos( $b->contents, 'id="link-id"' ) );
+               $this->assertNotFalse( strpos( $b->contents, 'rel="nofollow"' ) );
+               $this->assertNotFalse( strpos( $b->contents, 'title="link-title"' ) );
+       }
+
+       /**
+        * @ticket BP7226
+        */
+       public function test_bp_button_new_element_attrs_have_precedence_over_deprecated_element_attrs() {
+               $b = new BP_Button( array(
+                       'id' => 'foo',
+                       'component' => 'members',
+                       'block_self' => false,
+                       'must_be_logged_in' => false,
+                       'button_element' => 'button',
+                       'button_attr' => array(
+                               'class' => 'new-class',
+                       ),
+                       'link_class' => 'old-class'
+               ) );
+
+               $this->assertNotFalse( strpos( $b->contents, '<button class="new-class"' ) );
+       }
+
+       /**
+        * @ticket BP7226
+        */
+       public function test_bp_button_new_element_attrs_should_not_render_for_empty_attrs() {
+               $b = new BP_Button( array(
+                       'id' => 'foo',
+                       'component' => 'members',
+                       'block_self' => false,
+                       'must_be_logged_in' => false,
+                       'button_element' => 'button',
+                       'button_attr' => array(
+                               'class' => '',
+                       ),
+               ) );
+
+               $this->assertFalse( strpos( $b->contents, '<button class=""' ) );
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre>
</div>
</div>

</body>
</html>