3
votes

Can anyone help me decode why this doesnt work?

$cssid = preg_replace("/'/", "", $cssid);

Trying to strip the single quote marks from some html...

Thanks! H

EDIT This is the full function - it's designed to rebuild the Drupal menu using images, and it applies CSS classes to each item, allowing you to select the image you want. Stripping out spaces and apostrophes needs to be done or the CSS selector fails.

The title of the menu item causing all this problem is:

What's new

Pretty innocuous you'd think. (Except for that single ')

function primary_links_add_icons() {
  $links = menu_primary_links();
  $level_tmp = explode('-', key($links));
  $level = $level_tmp[0];
  $output = "<ul class=\"links-$level\">\n";   
  if ($links) {
    foreach ($links as $link) {
        $link = l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment']);
        $cssid = str_replace(' ', '_', strip_tags($link));
        $cssid = str_replace('\'', '', $cssid);
        /*$link = preg_replace('#(<a.*?>).*?(</a>)#', '$1$2', $link);*/
        $output .= '<li id="'.$cssid.'">' . $link .'</li>';
    };
    $output .= '</ul>';
  }
  return $output;
}

EDIT the saga continues...

I notice that I get the following error in PHPMYADMIN:

The mbstring PHP extension was not found and you seem to be using a multibyte charset. Without the mbstring extension phpMyAdmin is unable to split strings correctly and it may result in unexpected results.

I wonder whether this has something to do with it?

In any case the the SQL code is:

('primary-links', 951, 0, 'http://www.google.com', '', 'What''s New',

And this displays in FireBug once it's been rendered as:

<li id="What's_New">

I've created a menu item called "What@s New" and the str_replace() will work on that just fine, so it's ALL about this goddam apostrophe. I think I agree, the expression works, but it has to be an encoding problem. It really is a proper, common, apostrophe and not one of the variants, but for some reason PHP is absolutely unable to recognise it as such.

EDIT oh god oh god - it's Drupal again... It appears that the function l() which formats all the links is completely impervious to having it's output rewritten?! Whatever the case, this code works...

function primary_links_add_icons() {
  $links = menu_primary_links();
  $level_tmp = explode('-', key($links));
  $level = $level_tmp[0];
  $output = "<ul class=\"links-$level\">\n";   
  if ($links) {
    foreach ($links as $link) {
        $link['title'] = str_replace('\'', '', $link['title']);
        $link = l($link['title'], $link['href'], $link['attributes'], $link['query'], $link['fragment']);
        $cssid = str_replace(' ', '_', strip_tags($link));      
        /*$link = preg_replace('#(<a.*?>).*?(</a>)#', '$1$2', $link);*/
        $output .= '<li id="'.$cssid.'">' . $link .'</li>';
    };
    $output .= '</ul>';
  }
  return $output;
}

2 hours later and I can carry on theming this site...

Thank you so much for all your suggestions, I'm going to point the drupal snippet authors at this post so hopefully other people will benefit from it too.

5
So $link contains What's new, right? Are you sure it’s an ' (U+0027) and not something similar looking like ` (U+0060), ´ (U+00B4), (U+2018), (U+2019) or (U+201B)? - Gumbo
yeah, i've typed and retyped it. I might go into the database and see if the character encoding is messing this up somehow though. - MrFidge
Like Gumbo says, are you sure it is a ' ... you should test your functions not with live data (very error prone!) but with self made data first; which you know will work. If that works, fire it on your live data.. see what happens. - Jake
That code works for me... $cssid gets a value Whats_new. - Ilari Kajaste
I'm betting some sort of encoding problem. The character will turn out not to be an apostrophe -- agh, I have to use cut&paste to get that word correct every single time I use it! :) - Ilari Kajaste

5 Answers

2
votes

CSS image replacement is a much more commonly chosen way for menu item replacing:

First install: Menu Attributes module to be able to assing css id's for every menu item. (these attributes can be set from the menu item edit page on admin panel)

Then use css image replacement. Here is a good tutorial for this.

And this is the method i use for my sites:

    #primary-tv
{
    display: block;
    width: 90px;
    height: 0px;
    padding-top: 41px;
    background: url(images/nghtv.png);
}

This is an example for replacement with an image of 90 x 41px

And for the apostrophe replacement:

$cssid = preg_replace("&#039;","",htmlspecialchars($cssid, ENT_QUOTES));
2
votes

escape the single quote.

1
votes

Your code looks fine. But why don’t you use str_replace as you’re replacing a fixed string?

$cssid = str_replace("'", "", $cssid);
1
votes

If str_replace("'","") doesn't work, are you sure the characters you want to remove are indeed normal apostrophes (') instead of weird alternatives (’), or some weird accent marks (´`˙ ̛̉῾᾿) or single quotes (‘’) or whatnot?

Or maybe the value of $cssid gets replaced back to original by some other bug?

Maybe you're looking at the wrong output for results?

Or by a far chance, are you accidentally running a different copy of the code than the one you are editing - btw, that's really annoying when it happens! :)

1
votes

Given that it is HTML have you considered that it may be represented as &#39 rather than '?