wp_kses_hair

Builds an attribute list from string containing attributes.

Description

(array) wp_kses_hair( (string) $attr, (array) $allowed_protocols ); 

This function does a lot of work. It parses an attribute list into an array with attribute data, and tries to do the right thing even if it gets weird input. It will add quotes around attribute values that don't have any quotes or apostrophes around them, to make it easier to produce HTML code that will conform to W3C's HTML specification. It will also remove bad URL protocols from attribute values. It also reduces duplicate attributes by using the attribute defined first (foo='bar' foo='baz' will result in foo='bar').

Returns (array)

List of attributes after parsing

Parameters (2)

0. $attr (string)
Attribute list from HTML element to closing HTML element tag
1. $allowed_protocols (array)
Allowed protocols to keep

Usage

  1. if ( !function_exists( 'wp_kses_hair' ) ) { 
  2. require_once ABSPATH . WPINC . '/kses.php'; 
  3.  
  4. // Attribute list from HTML element to closing HTML element tag 
  5. $attr = ''; 
  6.  
  7. // Allowed protocols to keep 
  8. $allowed_protocols = array(); 
  9.  
  10. // NOTICE! Understand what this does before running. 
  11. $result = wp_kses_hair($attr, $allowed_protocols); 
  12.  

Defined (1)

The function is defined in the following location(s).

/wp-includes/kses.php  
  1. function wp_kses_hair($attr, $allowed_protocols) { 
  2. $attrarr = array(); 
  3. $mode = 0; 
  4. $attrname = ''; 
  5. $uris = array('xmlns', 'profile', 'href', 'src', 'cite', 'classid', 'codebase', 'data', 'usemap', 'longdesc', 'action'); 
  6.  
  7. // Loop through the whole attribute list 
  8.  
  9. while (strlen($attr) != 0) { 
  10. $working = 0; // Was the last operation successful? 
  11.  
  12. switch ($mode) { 
  13. case 0 : // attribute name, href for instance 
  14.  
  15. if ( preg_match('/^([-a-zA-Z:]+)/', $attr, $match ) ) { 
  16. $attrname = $match[1]; 
  17. $working = $mode = 1; 
  18. $attr = preg_replace( '/^[-a-zA-Z:]+/', '', $attr ); 
  19.  
  20. break; 
  21.  
  22. case 1 : // equals sign or valueless ("selected") 
  23.  
  24. if (preg_match('/^\s*=\s*/', $attr)) // equals sign 
  25. $working = 1; 
  26. $mode = 2; 
  27. $attr = preg_replace('/^\s*=\s*/', '', $attr); 
  28. break; 
  29.  
  30. if (preg_match('/^\s+/', $attr)) // valueless 
  31. $working = 1; 
  32. $mode = 0; 
  33. if(false === array_key_exists($attrname, $attrarr)) { 
  34. $attrarr[$attrname] = array ('name' => $attrname, 'value' => '', 'whole' => $attrname, 'vless' => 'y'); 
  35. $attr = preg_replace('/^\s+/', '', $attr); 
  36.  
  37. break; 
  38.  
  39. case 2 : // attribute value, a URL after href= for instance 
  40.  
  41. if (preg_match('%^"([^"]*)"(\s+|/?$)%', $attr, $match)) 
  42. // "value" 
  43. $thisval = $match[1]; 
  44. if ( in_array(strtolower($attrname), $uris) ) 
  45. $thisval = wp_kses_bad_protocol($thisval, $allowed_protocols); 
  46.  
  47. if(false === array_key_exists($attrname, $attrarr)) { 
  48. $attrarr[$attrname] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname=\"$thisval\"", 'vless' => 'n'); 
  49. $working = 1; 
  50. $mode = 0; 
  51. $attr = preg_replace('/^"[^"]*"(\s+|$)/', '', $attr); 
  52. break; 
  53.  
  54. if (preg_match("%^'([^']*)'(\s+|/?$)%", $attr, $match)) 
  55. // 'value' 
  56. $thisval = $match[1]; 
  57. if ( in_array(strtolower($attrname), $uris) ) 
  58. $thisval = wp_kses_bad_protocol($thisval, $allowed_protocols); 
  59.  
  60. if(false === array_key_exists($attrname, $attrarr)) { 
  61. $attrarr[$attrname] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname='$thisval'", 'vless' => 'n'); 
  62. $working = 1; 
  63. $mode = 0; 
  64. $attr = preg_replace("/^'[^']*'(\s+|$)/", '', $attr); 
  65. break; 
  66.  
  67. if (preg_match("%^([^\s\"']+)(\s+|/?$)%", $attr, $match)) 
  68. // value 
  69. $thisval = $match[1]; 
  70. if ( in_array(strtolower($attrname), $uris) ) 
  71. $thisval = wp_kses_bad_protocol($thisval, $allowed_protocols); 
  72.  
  73. if(false === array_key_exists($attrname, $attrarr)) { 
  74. $attrarr[$attrname] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname=\"$thisval\"", 'vless' => 'n'); 
  75. // We add quotes to conform to W3C's HTML spec. 
  76. $working = 1; 
  77. $mode = 0; 
  78. $attr = preg_replace("%^[^\s\"']+(\s+|$)%", '', $attr); 
  79.  
  80. break; 
  81. } // switch 
  82.  
  83. if ($working == 0) // not well formed, remove and try again 
  84. $attr = wp_kses_html_error($attr); 
  85. $mode = 0; 
  86. } // while 
  87.  
  88. if ($mode == 1 && false === array_key_exists($attrname, $attrarr)) 
  89. // special case, for when the attribute list ends with a valueless 
  90. // attribute like "selected" 
  91. $attrarr[$attrname] = array ('name' => $attrname, 'value' => '', 'whole' => $attrname, 'vless' => 'y'); 
  92.  
  93. return $attrarr;