0

Is it possible to use PHP's str_replace() function to target only select DIV's within a page (identified by ID or classes for example)?

The situation: I'm using the following str_replace() function to convert all checkboxes in my Wordpress Post Editor - Categories metabox to use radio buttons instead so authors of my site can post only in one category.

The below code is working (on WP3.5.1) but it replaces the code for other checkbox elements on the same page. Is there any way to target only the category metabox?

// Select only one category on post page
if(strstr($_SERVER['REQUEST_URI'], 'wp-admin/post-new.php') || 
strstr($_SERVER['REQUEST_URI'], 'wp-admin/post.php'))
{
  ob_start('one_category_only');
}

function one_category_only($content) {
  $content = str_replace('type="checkbox" ', 'type="radio" ', $content);
  return $content;
}
j0k
  • 22,600
  • 28
  • 79
  • 90
Paul Thomson
  • 105
  • 2
  • 11

1 Answers1

0

You could either work with a regular expression to filter the content part with the ID, and then use str_replace, or you could - as in the following example - using DOMDocument and DOMXPath to scan your content and manipulate the input elements:

// test content
$content = '<div id="Whatever"><div id="YOURID"><input type="checkbox" /></div><div id="OTHER"><input type="checkbox" /></div></div>';

function one_category_only($content) {
    // create a new DOMDocument
    $dom=new domDocument;
    // load the html
    $dom->loadHTML($content);
    // remove doctype declaration, we just have a fragement...
    $dom->removeChild($dom->firstChild);  
    // use XPATH to grep the ID 
    $xpath = new DOMXpath($dom);
    // here you filter, scanning the complete content 
    // for the element with your id:
    $filtered = $xpath->query("//*[@id = 'YOURID']");
    if(count($filtered) > 0) { 
        // in case we have a hit from the xpath query,
        // scan for all input elements in this container
        $inputs = $filtered->item(0)->getElementsByTagName("input");
        foreach($inputs as $input){
            // and relpace the type attribute
            if($input->getAttribute("type") == 'checkbox') {
                $input->setAttribute("type",'radio');
            }
        }
    }
    // return the modified html
    return $dom->saveHTML();
}

// testing
echo one_category_only($content);
axel.michel
  • 5,764
  • 1
  • 15
  • 25
  • Hey Axel, thanks for providing the solution, unfortunately I'm not having much luck getting it to work. You have any idea how to make it work using regular expressions? The containing element I'm trying to target is: `
    `
    – Paul Thomson Feb 14 '13 at 05:00
  • @PaulThomson what is wrong with the XPATH? Any errors, where is the problem? Missing extensions? – axel.michel Feb 14 '13 at 06:03