ああ!年末がー今年がーー

なんやかんやで、もう11月。

前回のエントリーから1カ月以上も空けてしまった・・

取引先企業様方のおかげさまで、忙しくしてました。

今回は、暴露ネタ。
年内の予定について

  • ケータイポイントラリー企画
    加盟店に掲示されているQRコードを読み取って、ポイントラリーしちゃう企画
    モバイル向けだけど、willcomにもちゃっかり対応。
    QRコード生成、iモードIDの利用、携帯端末情報の利用、とかとか。
    完全スクラッチ開発。12月リリース予定。
  • アクセスカウンター、アクセスランキングASPサービス企画
    忍者ツールズとか、ゼロツールズみたいな企画。
    統合的なサービスを提供する上で、フレームワークはとても大切って感じた。
    時すでに遅し、こちらもフルスクラッチ開発。(一部、旧ソースの使いまわしあり)
  • ウェブサイトリニューアル
    現在改装中であるクライアント様店舗のホームページリニューアル。
    12月1日オープンなのに、いまだ全く情報なし。あせる・・・
  • ウェブサイトリニューアルその2
    以前にWordPressで作ったクライアント企業様のホームページリニューアル。
    特に不満を言われてるわけではないですが、これといって成果が出ていないようなので、システムも合わせてリニューアルする予定。
    着手は、上の開発リリース後の12月中旬ごろからかな?クリスマス前くらいに納品できたらOK。
  • 自社ウェブサイト制作
    ええ、自社ホームページの制作です。
    IT企業でありながら、自社のホームページがindex.htmlの1枚だけなんです。
    過去には、Zen Cart でホームページを作ったり、WordPressにしてみたり、MODxを使ったりして何度かのリニューアルを行っていたのですが、今は、このような有様。
    キチンとつくろう。

一人会社って、気軽だけど、プレッシャーもあって大変。
特に手数の多い作業が詰まってくると、息抜きのタイミングを失う・・

しかし、社員を雇うには、もうちょっと資金繰りに余裕が無いとできないな。

やっぱ、なにかB2Cビジネスを立ち上げないと、今の不安定なキャッシュフローから抜け出せない気がする。

WordPress On Zencart

WordPress On Zencart を使ってて、パンくずリスト(Breadcrumbs)とページタイトル(title)がどうも、うまく変化していなくて、いつもブログのタイトルだけになってしまっていたので、修正。

includes/languages/japanese/wordpress.php

修正前

if($woz_install){
    $cat_id = htmlspecialchars($_GET[‘cat’],ENT_QUOTES);
    if ( !empty($cat_id) ) {
            // category exclusion
            if ( !stristr($cat,’-‘) )
                $zen_heading_title[] = get_the_category_by_ID($cat_id);
    }

    $p_id = htmlspecialchars($_GET[‘p’],ENT_QUOTES);
    if ( !empty($p_id) ) {
            $zen_heading_title[] = $wpdb->get_var("SELECT post_title FROM $wpdb->posts  WHERE ID = $p_id");
    }

    define(‘NAVBAR_TITLE’, implode(BREAD_CRUMBS_SEPARATOR, $zen_heading_title));
    define(‘WOZ_HOME_ADDRESS’, ‘/?’);
}else{
    define(‘NAVBAR_TITLE’, ‘Error:not found [ABSPATH]’.ABSPATH);
}

修正後

if($woz_install){
    if(isset($_GET[‘cat’])){
    $cat_id = htmlspecialchars($_GET[‘cat’],ENT_QUOTES);
    if ( !empty($cat_id) ) {
            // category exclusion
            if ( !stristr($cat,’-‘) )
                $zen_heading_title[] = get_the_category_by_ID($cat_id);
    }
    }
    if(isset($_GET[‘p’])){
    $p_id = htmlspecialchars($_GET[‘p’],ENT_QUOTES);
    if ( !empty($p_id) ) {
            $zen_heading_title[] = $wpdb->get_var("SELECT post_title FROM $wpdb->posts  WHERE ID = $p_id");
    }
    }
    if(isset($_GET[‘page_id’])){
    $p_id = htmlspecialchars($_GET[‘page_id’],ENT_QUOTES);
    if ( !empty($p_id) ) {
            $zen_heading_title[] = $wpdb->get_var("SELECT post_title FROM $wpdb->posts  WHERE ID = $p_id");
    }
    }

    define(‘NAVBAR_TITLE’, implode(BREAD_CRUMBS_SEPARATOR, $zen_heading_title));
    define(‘WOZ_HOME_ADDRESS’, ‘/?’);
}else{
    define(‘NAVBAR_TITLE’, ‘Error:not found [ABSPATH]’.ABSPATH);
}

タイポくさい気もするんですが、$_GET[‘p’] のところ。
実際のサイトでは、?page_id=*** というふうに $_GET[‘page_id’] を使って、ページIDを表示しているんで、修正前のコードだと、ページタイトルが取得できずに、ブログタイトルだけが、パンくずや、タイトルに送られていたんですね。

そこで、 $_GET[‘page_id’] があった場合は、それをページIDとしてページタイトルを取得するように修正しました。

Coming Soon: Zen Cart v2.0.0 – Zen Cart Support

Zen Cart の次期バージョンがついに V.2.0.0 にメジャーバージョンアップ!らしいです。

早ければ、来年1月にもパブリックベータ版としてリリースされる予定だそうです。
従来の V.1.3 系と大きく異なりテンプレートシステムを含めて大幅に見直されているらしいです。

特に目立った(気になった)ポイント

  • シンプルになったテンプレート!
    非常に煩雑な現行のテンプレートシステムを一新するようです。
  • オーバーライドは健在!
    コアを触ることなくサイトを更新可能なオーバーライドはv.2でも健在らしいです。
  • 標準で UTF-8 をサポート!
    ネイティブ言語として UTF-8 をサポートするそう。
  • PHP 5.2 & MySQL 4.1 以上
    もはや PHP 4 は、切り捨ててます。

他にも従来モジュールに頼っていた部分のいくつかをコアに導入されているみたいです。

Coming Soon: Zen Cart v2.0.0 – Zen Cart Support

more_information はいらない子?

Zen Cart には、固定ページを作成するために Information と more_information という二つのサイドボックスが用意されているのですが。

S-Page さんの WordPress on ZenCart を使うようになってからは、more_information は「いらない子」なのかなと思うようになってきています。

Zen Cart のサイドボックス「more_information」でページを追加するには、languages、modules、templates、html_includesと、いくつものファイルを更新・追加しなければいけないのですが、WordPress on ZenCart を入れておけば、WordPress側でページ追加するだけで、いとも簡単にページ追加できちゃいます。

項目の並べ替えも、WordPress 側で制御できるので、メンテナンスも楽々です。

MODxの時(WordPress Integrator)は、WordPress のページを表示するのに、不安定な部分があり、大丈夫かなと思ったのですが、この WordPress on ZenCart は、非常に動作も安定していて安心して使えてます。

※WordPress Integrator では、MODx で404エラーの場合に WordPress を読み込むトリガーを動かしていたのですが、この404エラーを判別するパースタイムがサーバーによって、非常に遅かったりすることがある。

非表示のカテゴリーをつくる Zen Cart [hideCategories]

カテゴリーリストから見えないカテゴリーをつくるモジュール。

例えば、メール会員用の商品カテゴリーを作って、普通にアクセスした場合はカテゴリーリストに表示されず、メールマガジンなどに記載された「商品ページへの直リンク」でアクセスさせるなどができます。

あまり、一般的には使われないモジュールかもしれませんね。

今回、受注しているサイトがこんな機能が必要だったので、日本語ファイルを作ってみました。

hideCategories (本家ZenCart.com)

モジュール概要

  • カテゴリー編集画面にラジオボタン追加(管理画面)
    カテゴリー編集画面の下に「標準」「メインメニューから非表示」「非表示(おすすめ、新商品リストからも非表示(直リンクのみ有効))」の3つのラジオボタンが追加されます。

Ci081030210718

  カテゴリーBOX おすすめ、新商品 直リンク
標準
メインメニューから非表示 ×
非表示
(おすすめ、新商品リストからも非表示(直リンクのみ有効))
× ×

なお、検索結果には表示されます。

今回使用したのは、「医薬品の個人輸入代行」のECサイトです。

薬事法の関連上、サイト上に「医薬品の広告」が禁止されているので、「医薬品名で検索」または、「問い合わせがあった」場合のみ商品を提供することが許可されるとの事でした。

[dm]2[/dm]

まったく一からカスタマイズを行わないといけないかなーと思ってたら、海外では既に実用化されていたり、もっともっと勉強しないといけないですね。

2009-3-12 追記::

このモジュールでは、サイトマップのリストに非表示のカテゴリーが表示されてしまうバグがあります。

includes/classes/site_map.php ファイルの下記部分を修正して下さい。
function zen_SiteMapTree 内のコードを下記の様に書き換えます。

 

function zen_SiteMapTree($load_from_database = true) {
global $languages_id, $db;
$this->data = array();
$categories_query = "select c.categories_id, cd.categories_name, c.parent_id
from " . TABLE_CATEGORIES . " c, " . TABLE_CATEGORIES_DESCRIPTION . " cd
where c.categories_id = cd.categories_id
and cd.language_id = '" . (int)$_SESSION['languages_id'] . "'
and c.categories_status != '0'
order by c.parent_id, c.sort_order, cd.categories_name";
$categories = $db->Execute($categories_query);
while (!$categories->EOF) {

// Begin hideCategories code
$hide_status = $db->Execute("select visibility_status
FROM " . TABLE_HIDE_CATEGORIES . "
WHERE categories_id = " . $categories->fields['categories_id'] . "
LIMIT 1");
if ($hide_status->fields['visibility_status'] < 1) {
// End hideCategories code
$this->data[$categories->fields['parent_id']][$categories->fields['categories_id']] = array('name' => $categories->fields['categories_name'], 'count' => 0);
// Begin hideCategories code
}
// End hideCategories code
$categories->MoveNext();
}
}

一般価格と会員価格 Zen Cart [Group Pricing(per Item)]

ゲストユーザーには、一般小売価格を表示しておき、会員登録すると「会員向けの価格」を表示。

日本語フォーラムでも何度か取り上げられていた話題ですが、本家Zen Cart .comの方に、いい感じのモジュールがあったので、日本語ファイルをつくってみた。

Group Pricing (per Item)

モジュール概要

  • 割引グループを機能拡張
    Group Pricing用の割引グループを4つまで設定可能。
    デフォルトでは、グループごとに割引%での設定しかできなかったのが「グループごとの『会員価格』」を「商品ごと」に設定できるようになります。
  • 商品価格の項目拡張
    商品価格の設定をデフォルトの1個の他に、割引グループごとに4個の設定項目を追加。 「これがやりたかった」まさにそんな機能!商品に複数の価格を設定でき、割引グループに応じて表示価格を設定できます。

インストール自体は、割と簡単。おまけにアンインストール用のSQLも付属しているので、安心感(信頼感)高いです。
(国産リソースには、まだこの辺が足りなくて、アンインストールに四苦八苦する事が多い)

ただし、今現在のバージョン(V.1.3.1)は、最近のMySQLインジェクション関係のパッチが当たってないので、その辺をZen Cart に導入済みの物と比較して編集が必要です。

私の場合、ゲスト購入モジュールも導入しているので、ゲストには、「一般価格で販売」会員には、「会員価格で販売」ができるように、登録時のデフォルトグループを Group Pricing の割引グループになるように修正。

登録時のデフォルト割引グループ設定

includes/modules/YOUR_TEMPLATE/create_account.php

zen_db_perform(TABLE_CUSTOMERS, $sql_data_array);

という行の直前に、

$sql_data_array[‘customers_group_pricing’] = 1;

の行を追加。(1は、設定したい割引グループID)

結果、サイトの表示は・・

(ゲスト(未ログイン)の時)
Ci081018194135 
一般価格:29,800円
会員価格:ログインして下さい。

(会員ログインしている時)
Ci081018194208 
一般価格:29,800円
会員価格:22,000円

なんて感じの表現が可能になりました。
(ログイン時の「一般価格」を表示するには、function_price.php をちょこっといじる必要があります)

管理画面ではこんな感じ

Ci081022155500

一般価格の下に4種類の会員価格設定欄があるのが分かると思います。
これが、それぞれの割引グループでログインした際の商品価格になります。

インストールしたベースの Zen Cart は bigmouse さんとこの Zen Cart v.1.3.8a です。

Zen Cart でのリンクを記述する方法(おさらい)

Zen Cart 内でリンクを記述する時は、 html_output.php にある zen_href_link() を使用します。

HTMLテンプレート内に記述する方法は、以下の通り。

<?php echo zen_href_link(‘PAGENAME’,’QUERYSTRING’,'{SSL | NONSSL}’); ?>

  • PAGENAME
    ページ名、Zen Cart 内のURLでいうと、/index.php?main_page=contact_us の「contact_us」の部分。
    ちなみに、filenames.php などで、定数(define(‘FILENAME_***’,’***’); とか)が指定されている場合は、定数を記述する事も可能。
  • QUERYSTRING
    zen_href_link ファンクションで展開されたURLの最後にQUERYSTRINGを追加する場合に使用。
    例えば、指定したページの<a name="link1"></a>にページ内リンクしたい場合に「#link1」と記述しておく。
  • {SSL | NONSSL}
    SSL が有効な場合に SSL でアクセスするかどうか。
    NONSSL を指定した場合は、常に http:// でリンクする事になり、 SSL を指定すれば、SSL が有効な場合に https:// でリンクするようになる。

例1: 利用規約ページ(conditions)の第5条(<a name="jou_5">)にリンクする場合。

<a href="<?php echo zen_href_link(‘conditions’,’#jou_5′,’NONSSL’); ?>">利用規約 第5条</a>

例2: ログインページ(login)にリンクする場合。

<a href="<?php echo zen_href_link(‘login’,”,’SSL’); ?>">ログインはこちら</a>

例3: ページ内リンクするだけなら、こういった方法も

<a href="<?php echo zen_href_link(‘conditions’,”,’NONSSL’); ?>#jou_5">利用規約 第5条</a>

インフォメーションに項目追加

ZenCartには、「インフォメーション」と「追加情報」があり、「定番ページの編集」でページの編集ができます。

今回は、S-Pageのhiraさんの「定番ページのタイトルの編集モジュール」を使いつつ、インフォメーションに項目を追加してみます。

今回は、aboutus というページを作ってみます。
URLはhttp://~~~~~.com/index.php?main_page=aboutus といった感じに。

includes/modules/pages/aboutus/header_php.php を作成
header_php.php 内の FILENAME_DEFINE_***** を変更。
$define_page = zen_get_file_directory(DIR_FS_DEFINE_PAGES_DATA . $_SESSION[‘language’] . ‘/html_includes/’, FILENAME_DEFINE_ABOUTUS, ‘false’);

includes/modules/sideboxes/YOUR_TEMPLATE/information.php を編集。
if(DEFINE_TITLE_INFORMATION_ABOUTUS != ”){
$information[] = ‘<a href="’ . zen_href_link(FILENAME_ABOUTUS) . ‘">’ . DEFINE_TITLE_INFORMATION_ABOUTUS . ‘</a>’;
}
適当なところに記述するのですが、メニューの並び替えもここで記述された順になるので、サイトのメニューレイアウトに合わせて編集。

includes/languages/japanese/extra_definitions/YOUR_TEMPLATE/define_title.php を編集。
define(‘DEFINE_TITLE_INFORMATION_ABOUTUS’, $define_title[‘define_aboutus.php’]);

includes/languages/japanese/html_includes/YOUR_TEMPLATE/define_aboutus.php を作成
(内容は管理画面で編集するので、とりあえずこのまま)

includes/languages/japanese/html_includes/define_aboutus.php も作成。
YOUR_TEMPLATE でオーバーライドするのですが、html_includes 直下にもファイルを置いておかないと管理画面(admin)でリスト表示されません。
※html_includes 以下のファイルは、パーミッション(ファイル属性)を666に設定忘れずに!

includes/languages/japanese/YOUR_TEMPLATE/aboutus.php を作成
define(‘NAVBAR_TITLE’, DEFINE_TITLE_INFORMATION_ABOUTUS);
define(‘HEADING_TITLE’, $ini_heading_title[‘define_aboutus.php’]);
define(‘TEXT_INFORMATION’, ”);

includes/extra_datafiles/extra_filename.php を編集。
define(‘FILENAME_ABOUTUS’, ‘aboutus’);
define(‘FILENAME_DEFINE_ABOUTUS’, ‘define_aboutus’);

includes/extra_datafiles/define_titles_data/ 以下のファイルを編集。
[define_titles.php]
define_abutus.php="会社概要"
[define_headings.php]
define_aboutus.php="運営会社について"
englishフォルダも内容に応じて編集、今回は日本語のみの運用なので、japaneseフォルダのみ。

includes/templates/YOUR_TEMPLATE/templates/tpl_aboutus_default.php を編集。

【まとめ】 ★・・既存ファイル更新 ☆・・新規作成

/includes
├ /extra_datafiles/extra_filename.php ★
│ ├ /define_titles_data/japanese/define_titles.php ★
│ └ /define_titles_data/japanese/define_heading_title.php ★
├ /languages
├ └/japanese
├ ├ /extra_definitions/YOUR_TEMPLATE/define_titles.php ★
├ ├ /html_includes/define_aboutus.php ☆
├ ├ /html_includes/YOUR_TEMPLATE/define_aboutus.php ☆
├ └ /YOUR_TEMPLATE/aboutus.php ☆
├ /modules
├ ├ /pages/aboutus/header_php.php ☆
├ └ /sideboxes/YOUR_TEMPLATE/information.php ★
└ /templates/YOUR_TEMPLATE/templates/tpl_aboutus_default.php ☆

今回は、「インフォメーション」に項目を追加したのですが、「追加情報(more_information)」に項目を追加したい場合は、/modules/sideboxes/information.php を more_information.php に置き換えて編集すればOKだと思います。

追記::
定番ページ関連で、これも使える。
WordPressの「最近の投稿」をZen-Cartの定番ページに表示する方法

いろんな Zen Cart モジュールを試す

非常に多彩なモジュールが公開されている Zen Cart なんですが。

公式が1.3.0.2なので、公開モジュールのほとんどがEUC-JPであったり、PHP5に対応していなかったりします。

ま、ようは文字コードとPHPのバージョンの問題だったりするので、ソースを見て修正すれば、そのほとんどが使用できちゃうんですね。

あと、最近ハマりかけたのが、「有料モジュール」だからと安心していたら、単純なPHPの記述ミスがあったりした事です。

[解決]時々出る「Syntax error」on KAGOYAサーバー

KAGOYAサーバー(専用サーバー50)で、Zen Cart のテストサイトをアップしているんですが、しばらく何ともなかったのに、突然アクセスしづらくなってしまったんですね。

何か新しいモジュールを入れて、それが原因であれば、そこを取り除くのですが、今回の場合、セットアップ済みの複数サイトが同時に同じ現象に見舞われてしまい、標準インストールのままのサイト(zc_installすら削除してない)までアクセスしづらい状況になってしまったんですね。

アクセスしづらいというのは、更新ボタンを押せば、なんとか表示するけど、次のページへリンクするとまたエラーが出るといった感じです。

Zen Cart ではないんですが、同様のPHPを使ったCMSで同じ現象に悩んでいた方がいたみたいです。

KAGOYAでOpenPNEの設定にハマル

自分は SAKURA なんですが、相棒が KAGOYA でして、OpenPNE の設定でかなり長期間悩んでいました。一緒になってネット検索などをしているとここに当たりました。
酔生夢死: KAGOYAでOPENPNEその後
http://blogs.dion.ne.jp/php/archives/6159089.html
ここによると、ちゃんと「OpenPNE セットアップガイド」通りにやっても管理画面でエラーが出るとのこと。
たしかに、Syntax error が出ました。このエラーから文字コードか OpenPNE のバグかといろいろ探っていたのですが、KAGOYA そのものの問題でした。

KAGOYAでOPENPNEその後

ちなみに環境としてはカゴヤの共用プランに独自ドメインという仕様。
インストールというかセットアップに関しては前回述べた通り、session.auto_startとmbstring.encoding_translationのデフォルト設定によりうまくいかないので、こいつをhtaccessでポチッとな、とするだけ。

結果、KAGOYAのデフォルトPHP設定で「mbstring.encoding_translation」と「session.auto_start」がONになっているのが、問題だったというわけ。

kagoya_php_setting

  • mbstring.encoding_translation = OFF
  • session.auto_start = OFF
  • register_globals = OFF