You are here:  » Encoding Issue


Encoding Issue

Submitted by Keeop on Fri, 2015-05-08 10:41 in

Hi David,

Need some help with an encoding issue. I have several sites, all based on the same code but which seem to be behaving differently with regards to encoding. In my database, the '£' symbol is being written as '£' which I believe is how UTF-8 encoding works. I have UTF-8 encoding set on all my sites yet some display the value as '£' and others as '£' - very confusing! Any ideas on where else to check for any descrepencies? The sites are pulling the data from the same database/table and I have changed the properties of this table to use UTF-8 encoding too. Any ideas please?

Cheers.
Keeop

Submitted by support on Fri, 2015-05-08 12:29

Hi Keeop,

If the codebase is identical it is probably down to the tables not being in utf8 / utf8_general_ci collation for the installations where the characters are being displayed incorrectly, which could happen if there is a difference between new and upgraded installations.

The following script will convert all tables to utf8 / utf8_general_ci - create as dbmod.php and upload to the top level folder of an installation exhibiting the problem and then browse to dbmod.php to apply the changes.

<?php
  set_time_limit
(0);
  require(
"includes/common.php");
  
database_queryModify($sql,$result);
  
$sql "SHOW TABLES LIKE '".$config_databaseTablePrefix."%'";
  
database_querySelect($sql,$rows);
  foreach(
$rows as $row)
  {
    
$table array_pop($row);
    
$sql "ALTER TABLE `".$table."`
            CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci"
;
    print 
$sql."\n";
    
database_queryModify($sql,$result);
  }
  print 
"Done.\n";
?>

Hope this helps!

Cheers,
David.
--
PriceTapestry.com

Submitted by Keeop on Mon, 2015-05-11 11:54

Hi David,

Thanks for this and I'll probably implement this across the DBs. However, in this case, I found the issue was down to the sites running under IIS using different versions of PHP and the coding wasn't set properly in the php.ini of the dodgy sites - doh!

Speaking of PHP though, since I've gone through the sites and ensured they'r eall running v5.4, I'm having some problems with import filters. Specifically, any filter that uses comma delimited values to check on, such as the Selective Import filter (http://www.pricetapestry.com/node/400) or DropUnless (http://www.pricetapestry.com/node/167). Has anything changed with any of these commands over time with respect to the PHP version? They seem to work OK with single values but not with comma separated.

Cheers.
Keeop

Submitted by support on Mon, 2015-05-11 14:54

Hello Keeop,

I've reviewed the code suggested in both forum topics you mentioned and I can't see anything that is either PHP or Price Tapestry version specific, so what I would suggest is making sure that PHP error reporting is turned up to the max and see if that reveals anything...

Easiest way is to edit config.advanced.php and add the following code to the very end of the file, just before the closing PHP tag:

  error_reporting(E_ALL);
  ini_set('display_errors','on');

If that does reveal something but you're not sure where the problem lies let me know what is displayed - or of course if it makes no difference, and I'll check it out further with you...

Cheers,
David.
--
PriceTapestry.com

Submitted by Keeop on Mon, 2015-05-11 15:14

Hi David,

It's not erroring from what I can tell, just not working ;-)

I was wondering, for example, if the strpos format had changed? Just looking at the code and we have this:

$filter_dropRecordFlag = (strpos($filter_data["text"],$text) === FALSE);

To me, this looks like the strpos parameters are the wrong way around - i.e. it's looking for the field text in the filter text? Shouldn't this be the other way around? Having said that, I can' imagine that they'd reverse the parameters so it must be just my misunderstanding! Anyway, using the exact code from the SelectiveImport filter mentioned earlier (apart from using stripos instead of strpos), the filter only imports the records that much the first item in the comma delimted list. I'm sure it used to work for multiples. I've debugged directly after the call to the filters in admin.php so it must be the filter code.

Cheers.
Keeop

Submitted by Keeop on Mon, 2015-05-11 15:32

Actually, doesn't import any records at all using the stock SelectiveImport - I've changed it around a little and my version just imports the first entry in any comma separated list. So, the standard one is not working at all whereas I'm sure it used to.

Cheers.
Keeop

Submitted by support on Mon, 2015-05-11 15:35

Hi Keeop,

You're absolutely correct, i've updated the code here accordingly;

    $filter_dropRecordFlag = (strpos($text,$filter_data["text"]) === FALSE);

Cheers,
David.
--
PriceTapestry.com

Submitted by Keeop on Mon, 2015-05-11 20:02

Hi David,

I've changed it around but still can't get it to work. Here's my version which does import the first value in a comma separated list:

function filter_selectiveImportExec($filter_data,$text)
  {
    global $filter_dropRecordFlag;
    if($filter_dropRecordFlag)
    {
      return $text;
    }
    $parts = explode(",",$filter_data["text"]);
    foreach($parts as $words)
    {
      $filter_dropRecordFlag = (stripos($text,$words) === FALSE);
      return $text;
    }
  }

Any ideas please? I have tried the code from one of the other filters but this doesn't work either:

function filter_dropRecordUnlessExec($filter_data,$text)
  {
    global $filter_dropRecordFlag;
    if($filter_dropRecordFlag)
    {
      return $text;
    }
    $parts = explode(",",$filter_data["text"]);
    foreach($parts as $k=>$v) $parts2[$v] = 1;
    $filter_dropRecordFlag = (!isset($parts2[$text]));
    return $text;
  }

Again, this seems to work if there is only one value.

Cheers.
Keeop

Submitted by support on Tue, 2015-05-12 08:03

Hello Keeop,

Use the following replacement of the filter_selectiveImportExec() function:

  function filter_selectiveImportExec($filter_data,$text)
  {
    global $filter_dropRecordFlag;
    if($filter_dropRecordFlag)
    {
      return $text;
    }
    $parts = explode(",",$filter_data["text"]);
    $filter_dropRecordFlag = TRUE;
    foreach($parts as $word)
    {
      if (strpos($text,$word)!==FALSE)
      {
        $filter_dropRecordFlag = FALSE;
        break;
      }
    }
    return $text;
  }

Hope this helps!

Cheers,
David.
--
PriceTapestry.com

Submitted by Keeop on Tue, 2015-05-12 08:11

Thanks David - seems to work a treat!

Cheers.
Keeop