3

Lets say I have the following $string...

<span style='text-decoration:underline; display:none;'>Some text</span>

I only want to allow the style text-decoration, so I want a PHP function like the following...

$string = stripStyles($string, array("text-decoration"));

Similar to strip_tags, but using an array instead. So $string will now be...

<span style='text-decoration:underline;'>Some text</span>

I am using Cake, so if this can be done with Sanitize then all the better.

Jeremy
  • 1
  • 85
  • 340
  • 366
jchavannes
  • 2,440
  • 1
  • 26
  • 15

1 Answers1

1

This is tricky, but you should be able to do it with DOMDocument. This should get you started, but it's likely to require some serious tweaking.

// Load your html string
$dom = new DOMDocument();
$dom->loadHTML($your_html_string);

// Get all the <span> tags
$spans = $dom->getElementsByTagName("span");

// Loop over the span tags
foreach($spans as $span) {

  // If they have a style attribute that contains "text-decoration:"
  // attempt to replace the contents of the style attribute with only the text-decoration component.
  if ($style = $span->getAttribute("style")) {
    if (preg_match('/text-decoration:([^;]*);/i', $style)) {
      $span->setAttribute("style", preg_replace('/^(.*)text-decoration:([^;]*);(.*)$/i', "text-decoration:$2;", $style);
    }
    // Otherwise, erase the style attribute
    else $span->setAttribute("style", "");
  }
}

$output = $dom->saveHTML;

It's maybe better to attempt to parse the style attributes by explode()ing on ;

// This replaces the inner contents of the foreach ($spans as $span) above...

// Instead of the preg_replace()
$styles = explode(";", $style);
$replaced_style = FALSE;
foreach ($styles as $s) {
 if (preg_match('/text-decoration/', $s) {
   $span->setAttribute("style", $s);
   $replaced_style = TRUE;
 }
 //  If a text-decoration wasn't found, empty out the style
 if (!$replaced_style) $span->setAttribute("style", "");
}
Michael Berkowski
  • 267,341
  • 46
  • 444
  • 390
  • @jchavannes you seem to want a lot – Omar Jul 22 '11 at 00:05
  • Try using xpath with `//*[@style]` if going the DOM route. – Wrikken Jul 22 '11 at 00:10
  • There is, of course, http://stackoverflow.com/questions/3650125/how-to-parse-html-with-php/ – Jared Farrish Jul 22 '11 at 00:14
  • @jchavannes The above is a large and complicated block of code, and should be more than enough to send you in the right direction if you aren't in over your head with this project requirement. Wrap it in a `function()` and replace the `getElementsByTagName()` with an xpath query as suggested in the comments if needed. – Michael Berkowski Jul 22 '11 at 00:16