Ticket #7226: 7226.ray.03.patch
File 7226.ray.03.patch, 18.1 KB (added by , 8 years ago) |
---|
-
src/bp-core/classes/class-bp-button.php
14 14 * API to create BuddyPress buttons. 15 15 * 16 16 * @since 1.2.6 17 * @since 2.7.0 Introduced $parent_element, $parent_attr, $button_element, $button_attr as 18 * $args parameters. Deprecated $wrapper, $wrapper_id, $wrapper_class, 19 * $link_href, $link_class, $link_id, $link_rel, $link_title as $args params. 17 20 * 18 21 * @param array $args { 19 22 * Array of arguments. 20 23 * 21 24 * @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: ''. 25 * @type string $component The name of the component the button belongs to. Default: 'core'. 26 * @type bool $must_be_logged_in Optional. Does the user need to be logged in to see this button? Default: 27 * true. 28 * @type bool $block_self Optional. True if the button should be hidden when a user is viewing his 29 * own profile. Default: true. 30 * @type string $parent_element Optional. Parent element to wrap button around. Default: 'div'. 31 * @type array $parent_attr Optional. Element attributes for parent element. Set whatever attributes 32 * like 'id', 'class' as array keys. 33 * @type string $button_element Optional. Button element. Default: 'a'. 34 * @type array $button_attr Optional. Button attributes. Set whatever attributes like 'id', 'class' as 35 * array keys. 36 * @type string $link_text Optional. Text to appear on the button. Default: ''. 37 * @type string|bool $wrapper Deprecated. Use $parent_element instead. 38 * @type string $wrapper_id Deprecated. Use $parent_attr and set 'id' as array key. 39 * @type string $wrapper_class Deprecated. Use $parent_attr and set 'class' as array key. 40 * @type string $link_href Deprecated. Use $button_attr and set 'href' as array key. 41 * @type string $link_class Deprecated. Use $button_attr and set 'class' as array key. 42 * @type string $link_id Deprecated. Use $button_attr and set 'id' as array key. 43 * @type string $link_rel Deprecated. Use $button_attr and set 'rel' as array key. 44 * @type string $link_title Deprecated. Use $button_attr and set 'title' as array key. 46 45 * } 47 46 */ 48 47 class BP_Button { … … 80 79 /** Wrapper ***************************************************************/ 81 80 82 81 /** 82 * Parent element to wrap button around. 83 * 84 * @since 2.7.0 85 * 86 * @var string Default: 'div'. 87 */ 88 public $parent_element = 'div'; 89 90 /** 91 * Element attributes for parent element. 92 * 93 * @since 2.7.0 94 * 95 * @var array Set whatever attributes like 'id', 'class' as array key. 96 */ 97 public $parent_attr = array(); 98 99 /** Button ****************************************************************/ 100 101 /** 102 * Button element. 103 * 104 * @since 2.7.0 105 * 106 * @var string Default: 'a'. 107 */ 108 public $button_element = 'a'; 109 110 /** 111 * Button attributes. 112 * 113 * @since 2.7.0 114 * 115 * @var array Set whatever attributes like 'id', 'href' as array key. 116 */ 117 public $button_attr = array(); 118 119 /** 120 * The contents of the button link. 121 * 122 * @var string 123 */ 124 public $link_text = ''; 125 126 /** HTML result 127 * 128 * @var string 129 */ 130 public $contents = ''; 131 132 /** Deprecated ***********************************************************/ 133 134 /** 83 135 * The type of DOM element to use for a wrapper. 84 136 * 85 * @var string|bool 'div', 'span', 'p', 'li', or false for no wrapper. 137 * @deprecated 2.7.0 Use $parent_element instead. 138 * 139 * @var string|bool 86 140 */ 87 public $wrapper = ' div';141 public $wrapper = ''; 88 142 89 143 /** 90 144 * The DOM class of the button wrapper. 91 145 * 146 * @deprecated 2.7.0 Set 'class' key in $parent_attr instead. 147 * 92 148 * @var string 93 149 */ 94 150 public $wrapper_class = ''; … … 96 152 /** 97 153 * The DOM ID of the button wrapper. 98 154 * 155 * @deprecated 2.7.0 Set 'id' key in $parent_attr instead. 156 * 99 157 * @var string 100 158 */ 101 159 public $wrapper_id = ''; 102 160 103 /** Button ****************************************************************/104 105 161 /** 106 162 * The destination link of the button. 107 163 * 164 * @deprecated 2.7.0 Set 'href' key in $button_attr instead. 165 * 108 166 * @var string 109 167 */ 110 168 public $link_href = ''; … … 112 170 /** 113 171 * The DOM class of the button link. 114 172 * 173 * @deprecated 2.7.0 Set 'class' key in $button_attr instead. 174 * 115 175 * @var string 116 176 */ 117 177 public $link_class = ''; … … 119 179 /** 120 180 * The DOM ID of the button link. 121 181 * 182 * @deprecated 2.7.0 Set 'id' key in $button_attr instead. 183 * 122 184 * @var string 123 185 */ 124 186 public $link_id = ''; … … 126 188 /** 127 189 * The DOM rel value of the button link. 128 190 * 191 * @deprecated 2.7.0 Set 'rel' key in $button_attr instead. 192 * 129 193 * @var string 130 194 */ 131 195 public $link_rel = ''; … … 133 197 /** 134 198 * Title of the button link. 135 199 * 136 * @var string 137 */ 138 public $link_title = ''; 139 140 /** 141 * The contents of the button link. 142 * 143 * @var string 144 */ 145 public $link_text = ''; 146 147 /** HTML result 200 * @deprecated 2.7.0 Set 'title' key in $button_attr instead. 148 201 * 149 202 * @var string 150 203 */ 151 public $ contents= '';204 public $link_title = ''; 152 205 153 206 /** Methods ***************************************************************/ 154 207 … … 163 216 164 217 $r = wp_parse_args( $args, get_class_vars( __CLASS__ ) ); 165 218 219 // Backward compatibility with deprecated parameters. 220 $r = $this->backward_compatibility_args( $r ); 221 222 // Deprecated. Subject to removal in a future release. 223 $this->wrapper = $r['wrapper']; 224 if ( !empty( $r['link_id'] ) ) $this->link_id = ' id="' . $r['link_id'] . '"'; 225 if ( !empty( $r['link_href'] ) ) $this->link_href = ' href="' . $r['link_href'] . '"'; 226 if ( !empty( $r['link_title'] ) ) $this->link_title = ' title="' . $r['link_title'] . '"'; 227 if ( !empty( $r['link_rel'] ) ) $this->link_rel = ' rel="' . $r['link_rel'] . '"'; 228 if ( !empty( $r['link_class'] ) ) $this->link_class = ' class="' . $r['link_class'] . '"'; 229 if ( !empty( $r['link_text'] ) ) $this->link_text = $r['link_text']; 230 166 231 // Required button properties. 167 232 $this->id = $r['id']; 168 233 $this->component = $r['component']; 169 234 $this->must_be_logged_in = (bool) $r['must_be_logged_in']; 170 235 $this->block_self = (bool) $r['block_self']; 171 $this->wrapper = $r['wrapper'];172 173 // $id and $component are required174 if ( empty( $r['id'] ) || empty( $r['component'] ) )175 return false;176 236 177 // No button if component is notactive.178 if ( ! bp_is_active( $this->component ) )237 // $id and $component are required and component must be active. 238 if ( empty( $r['id'] ) || empty( $r['component'] ) || ! bp_is_active( $this->component ) ) { 179 239 return false; 240 } 180 241 181 242 // No button for guests if must be logged in. 182 if ( true == $this->must_be_logged_in && ! is_user_logged_in() ) 243 if ( true == $this->must_be_logged_in && ! is_user_logged_in() ) { 183 244 return false; 245 } 184 246 185 247 // The block_self property. 186 248 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. 249 /* 250 * No button if you are the current user in a members loop. 251 * 252 * This condition takes precedence, because members loops can be found on user 253 * profiles. 254 */ 190 255 if ( bp_get_member_user_id() ) { 191 256 if ( is_user_logged_in() && bp_loggedin_user_id() == bp_get_member_user_id() ) { 192 257 return false; 193 258 } 194 259 195 // No button if viewing your own profile (and not in 196 // a members loop). 260 // No button if viewing your own profile (and not in a members loop). 197 261 } elseif ( bp_is_my_profile() ) { 198 262 return false; 199 263 } 200 264 } 201 265 202 // Wrapper properties. 203 if ( false !== $this->wrapper ) { 266 // Should we use a parent element? 267 $parent_elem = sanitize_html_class( $r['parent_element'] ); 268 if ( ! empty( $parent_elem ) ) { 269 if ( ! isset( $r['parent_attr']['class'] ) ) { 270 $r['parent_attr']['class'] = ''; 271 } 204 272 205 // Wrapper ID. 206 if ( !empty( $r['wrapper_id'] ) ) { 207 $this->wrapper_id = ' id="' . $r['wrapper_id'] . '"'; 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'; 208 279 } 209 280 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"'; 281 // Render parent element attributes. 282 $parent_attr = ''; 283 foreach( $r['parent_attr'] as $attr => $val ) { 284 $parent_attr .= sprintf( '%s="%s" ', sanitize_html_class( $attr ), esc_attr( $val ) ); 215 285 } 216 286 217 287 // Set before and after. 218 $before = '<' . $r['wrapper'] . $this->wrapper_class . $this->wrapper_id . '>';219 $after = '</' . $r['wrapper'] . '>';288 $before = sprintf( '<%1$s %2$s>', $parent_elem, $parent_attr ); 289 $after = sprintf( '</%s>', $parent_elem ); 220 290 221 // No wrapper.291 // No parent element. 222 292 } else { 223 293 $before = $after = ''; 224 294 } 225 295 226 // Link properties. 227 if ( !empty( $r['link_id'] ) ) $this->link_id = ' id="' . $r['link_id'] . '"'; 228 if ( !empty( $r['link_href'] ) ) $this->link_href = ' href="' . $r['link_href'] . '"'; 229 if ( !empty( $r['link_title'] ) ) $this->link_title = ' title="' . $r['link_title'] . '"'; 230 if ( !empty( $r['link_rel'] ) ) $this->link_rel = ' rel="' . $r['link_rel'] . '"'; 231 if ( !empty( $r['link_class'] ) ) $this->link_class = ' class="' . $r['link_class'] . '"'; 232 if ( !empty( $r['link_text'] ) ) $this->link_text = $r['link_text']; 296 // Button properties. 297 $button = ''; 298 $button_elem = sanitize_html_class( $r['button_element'] ); 299 if ( ! empty( $button_elem ) ) { 300 // Render button attributes. 301 $button_attr = ''; 302 foreach( $r['button_attr'] as $attr => $val ) { 303 if ( 'href' === $attr || 'formaction' === $attr || 'src' === $attr ) { 304 $val = esc_url( $val ); 305 } else { 306 $val = esc_attr( $val ); 307 } 308 309 $button_attr .= sprintf( '%s="%s" ', sanitize_html_class( $attr ), $val ); 310 } 311 312 // <input> / <img> is self-closing. 313 if ( 'input' === $button_elem || 'img' === $button_elem ) { 314 $button = sprintf( '<%1$s %2$s />', 315 $button_elem, 316 $button_attr 317 ); 318 319 // All other elements. 320 } else { 321 $button = sprintf( '<%1$s %2$s>%3$s</%1$s>', 322 $button_elem, 323 $button_attr, 324 ! empty( $r['link_text'] ) ? $r['link_text'] : '' 325 ); 326 } 327 } 233 328 234 329 // 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;330 $this->contents = $before . $button . $after; 236 331 237 332 /** 238 333 * Filters the button based on class parameters. … … 241 336 * allows button to be manipulated externally. 242 337 * 243 338 * @since 1.2.6 339 * @since 2.7.0 Added $r as a parameter. 244 340 * 245 341 * @param string $contents HTML being used for the button. 246 342 * @param BP_Button $this Current BP_Button instance. 247 343 * @param string $before HTML appended before the actual button. 248 344 * @param string $after HTML appended after the actual button. 345 * @param array $r Parsed button arguments. 249 346 */ 250 $this->contents = apply_filters( 'bp_button_' . $this->component . '_' . $this->id, $this->contents, $this, $before, $after ); 347 $this->contents = apply_filters( 'bp_button_' . $this->component . '_' . $this->id, $this->contents, $this, $before, $after, $r ); 348 } 349 350 /** 351 * Provide backward compatibility for deprecated button arguments. 352 * 353 * @since 2.7.0. 354 * 355 * @param array $r See {@link BP_Button} class for full documentation. 356 * @return array 357 */ 358 protected function backward_compatibility_args( $r = array() ) { 359 // Array of deprecated arguments. 360 $backpat_args = array( 361 'wrapper', 'wrapper_class', 'wrapper_id', 362 'link_href', 'link_class', 'link_id', 'link_rel', 'link_title' 363 ); 364 365 foreach ( $backpat_args as $prop ) { 366 if ( empty( $r[ $prop ] ) ) { 367 continue; 368 } 369 370 $parent = $child = false; 371 $sep = strpos( $prop, '_' ); 372 373 // Check if this is an attribute. 374 if ( false !== $sep ) { 375 $child = true; 376 $parent = substr( $prop, 0, $sep ); 377 } else { 378 $parent = $prop; 379 } 380 381 if ( 'wrapper' === $parent ) { 382 $parent = 'parent'; 383 } else { 384 $parent = 'button'; 385 } 386 387 // Set element. 388 if ( false === $child ) { 389 $r[ "{$parent}_element" ] = $r[ $prop ]; 390 391 // Set attributes. 392 } elseif ( true === $child ) { 393 $new_prop = substr( $prop, strpos( $prop, '_' ) +1 ); 394 if ( empty( $r[ "{$parent}_attr" ] ) ) { 395 $r[ "{$parent}_attr" ] = array(); 396 } 397 398 if ( empty( $r[ "{$parent}_attr" ][ $new_prop ] ) ) { 399 $r[ "{$parent}_attr" ][ $new_prop ] = $r[ $prop ]; 400 } 401 } 402 } 403 404 return $r; 251 405 } 252 406 253 407 /** -
tests/phpunit/testcases/core/class-bp-button.php
162 162 // clean up 163 163 $GLOBALS['members_template'] = null; 164 164 } 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 } 165 246 }