…czyli krzaki zamiast polskich znaków diakrytycznych.

osTicket to open source’owa aplikacja wspomagająca pracę technicznej obsługi klienta. Napisana została w PHP i działa na bazie MySQL. Niewątpliwą jej zaletą jest możliwość równoległej komunikacji z klientem przez e-mail i stronę www, gdzie po podaniu adresu e-mail i numeru ticketa (zgłoszenia) można prowadzić korespondencję oraz śledzić jej historię.

problem

Na forach związanych z projektem, ale nie tylko tam, widoczne są wpisy o problemach związanych z kodowaniem polskich znaków diakrytycznych. W e-mailach wysyłanych przez system, zamiast polskich liter są tzw. krzaki.
U mnie problem pojawił się o wiele wcześniej – już w formularzu z ustawieniami. Po wpisaniu [...] zarządzania zgłoszeniami i zapisaniu, wyświetlone zostało [...] zarz?dzania zg?oszeniami. Ze sprawdzaniem kodowania w e-mailach wolałem zaczekać.

diagnoza

Ww. efekty mogą wystąpić ponieważ:

  • strona zadeklarowane ma złe kodowanie, np. iso8859-1
  • jest różnica między kodowaniem bazy, a kodowaniem komunikacji baza-strona
  • są błędy w skryptach formatujących tekst na stronę i treść e-maili

Wszystkie templatki i strony były jednak w utf-8, skryptów nie chciało mi się sprawdzać. Winną okazała się baza, a w zasadzie metody porównywania napisów. Skrypt SQL wypełniający bazę, nie określa metod, więc domyślnie utworzony został latin1_swedish_ci zamiast utf8_general_ci.

narzędzia

Potrzebne będą:

  • dostęp do bazy – najwygodniejszy będzie przez phpMyAdmin, może być shell jak ktoś lubi
  • sensowny edytor tekstu – notatnik odpada. U mnie był to wbudowany edytor krusadera
  • kawałek miejsca na dysku

i zestaw SQL-i (tylko dla osób specyficznie postrzegających rzeczywistość…)

zmiana kodowania bazy:
ALTER DATABASE `nazwa_bazy` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci

zmiana kodowania tabel:
ALTER TABLE `nazwa_tabeli` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

zmiana kodowania poszczególnych pól:
ALTER TABLE `nazwa_tabeli` CHANGE `nazwa_pola` `nazwa_pola` VARCHAR( 30 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL

rozwiązanie

Najlepiej już przy tworzeniu bazy dla osTicketa zaznaczyć, by metodą por. napisów było utf8_general_ci.
U mnie baza, wszystkie tabele i pola miały ustawione domyślne kodowanie (szwedzkie) latin1_swedish_ci, czyli jak by nie patrzeć, inne niż utf8_general_ci. Należy to zmienić, jak poniżej:

Ci, co lubią się męczyć mogą użyć SQL-i z powyższego zestawu zmieniającego – ręcznie albo skryptem, jak kto woli. Leniwym proponuję:

  1. zrobić pełny dump bazy do .sql-a z INSERT-ami (domyślnie)
  2. zapisać go na dysku
  3. zrobić jego kopię zapasową, tak na wszelki wypadek
  4. otworzyć plik w edytorze i użyć tajemniczej funkcji „znajdź i zamień”

    wycinek dump-a przed zmianami :
    […]

    CREATE TABLE IF NOT EXISTS `ost_email` (
    `email_id` int(11) unsigned NOT NULL auto_increment,
    `noautoresp` tinyint(1) unsigned NOT NULL default '0',
    `priority_id` tinyint(3) unsigned NOT NULL default '0',
    `dept_id` tinyint(3) unsigned NOT NULL default '0',
    `email` varchar(125) NOT NULL default '',
    `name` varchar(32) NOT NULL default '',
    `created` datetime NOT NULL default '0000-00-00 00:00:00',
    `updated` datetime NOT NULL default '0000-00-00 00:00:00',
    PRIMARY KEY (`email_id`),
    UNIQUE KEY `email` (`email`),
    KEY `priority_id` (`priority_id`),
    KEY `dept_id` (`dept_id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

    […]

  5. w polu znajdź wpisać latin1
  6. w polu zamień wpisać utf8, wykonać i zapisać

    wycinek po zmianach:
    […]

    CREATE TABLE IF NOT EXISTS `ost_email` (
    `email_id` int(11) unsigned NOT NULL auto_increment,
    `noautoresp` tinyint(1) unsigned NOT NULL default '0',
    `priority_id` tinyint(3) unsigned NOT NULL default '0',
    `dept_id` tinyint(3) unsigned NOT NULL default '0',
    `email` varchar(125) NOT NULL default '',
    `name` varchar(32) NOT NULL default '',
    `created` datetime NOT NULL default '0000-00-00 00:00:00',
    `updated` datetime NOT NULL default '0000-00-00 00:00:00',
    PRIMARY KEY (`email_id`),
    UNIQUE KEY `email` (`email`),
    KEY `priority_id` (`priority_id`),
    KEY `dept_id` (`dept_id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;

    […]

  7. sprawdzić czy posiadane .sql są na pewno właściwymi ;)
  8. przejść do phpMyAdmina i SKASOWAĆ (tak, skasować) wszystkie tabele w bazie
  9. jesli baza miała inne kodowanie – zmienić kodowanie bazy na utf8_general_ci
  10. zaimportować przerobiony dump bazy

Efektem powinno być stworzenie od nowa poprawnej struktury bazy ze wszystkimi treściami. Przed importem, można przepuścić plik przez jakiś utf-konwerter, jeśli się go ma i jeśli jest sens to robić. Teraz, jeśli nie użyło się konwertera, wystarczy przeedytować templatki e-maili i wykonać testy, wszystko powinno wyświetlać się poprawnie. U mnie to wystarczyło.

Tagged with →  
Share →