雨ときどき晴れ

最近は C# や Blazor やってます。Raspberry Pi で Node-RED も活用できるようになりました。

ロリポップにMySQLを使わないWordPressをインストールしてみた。

ナウでヤングなレンタルサーバーロリポップ
ロリポップには月額105円から使えるコロリプランと月額263円〜のロリポプランがあります。

今回はテスト用にロリポプランに契約、ブログ用にWordPressをインストールしようと考えました。
しかし、ロリポプランではデータベース(MySQL)は1つしか使えません。
そうすると、複数WordPressをインストールしたり、他のデータベースを利用するソフトが
インストールできなくなってしまいます。


ということで、この問題を回避するために
MySQLを使わないWordPressのインストールをやってみました。
方法としては、MySQLの代わりにSQLiteを使います。

設定情報

WordPressをダウンロード

まず、公式サイトからWordPressをダウンロードします。
WordPress › 日本語
今回は、「WordPress 3.0.1」をダウンロードしました。

WordPressをサーバーにコピー

ダウンロードしたZIPファイルを解凍したものをサーバーにコピーします。

  • コピー先:/blog/
  • コピーするフォルダ:wordpress


なお、ロリポップへのFTPSによるコピーでは、

  • ソフト:WinSCP
    • ファイル数:775、サイズ:11.0MB
    • コピー時間:5分14秒(切断6回)

という状況でした。
何回か切断するみたいなので気長にコピーしてみましょう。
WinSCPには再接続を自動で行う機能があるため、基本的には何もしなくても無事コピーできました。

SQLiteを使うための設定

「wp-contents」フォルダ内に「database」フォルダを作成します。
「database」のパーミッションは「777」にしておきます。

  • 作成する場所:/blog/wordpress/wp-contents/database


「wp-config-sample.php」をコピーして、「wp-config.php」を作成します。

また、作成した「wp-config.php」に下記の設定を追加しておきます。

/** データベースの照合順序 (ほとんどの場合変更する必要はありません) */
define('DB_COLLATE', '');

/** SQLite用に追加 */
define('DB_TYPE', 'sqlite');

SQLiteで動作させるためのプラグインをインストール

WordPressSQLiteで動作させるために必要な
「PDO (SQLite) For Wordpress」というプラグインを下記のサイトからダウンロードします。
WordPress › PDO (SQLite) For WordPress « WordPress Plugins
今回は、「PDO (SQLite) For Wordpress Version 2.7.0」をダウンロードしました。


ダウンロードしたZIPファイルを解凍し、サーバーにコピーします。

  • コピー先:/blog/wordpress/wp-contents/
  • コピーするファイル:dp.php
  • コピーするフォルダ:pdo

WordPressをインストールする

必要なファイルが揃ったため、WordPressのトップページにアクセスしてみます。


しかし、ここでエラー発生。

Warning: set_time_limit() [function.set-time-limit]: Cannot set time limit in safe mode in /home/users/○○○/blog/wordpress/wp-content/pdo/PDOEngine.php on line 63

Warning: Cannot modify header information - headers already sent by (output started at /home/users/○○○/blog/wordpress/wp-content/pdo/PDOEngine.php:63) in /home/users/○○○/blog/wordpress/wp-includes/pluggable.php on line 890

エラー内容は「PHPがセーフモードで動作しているからダメ」と言っているようです。


対応としては、
ロリポップ!ユーザー専用ページから「WEBツール」→「php.iniの設定」ページにて、
「safe_mode」の設定を「On」→「Off」に変更してみました。

設定変更後、再度トップページにアクセスしたところ、インストール画面が表示されました。

この画面で必要項目を入力後、次のページに移動するとインストールが完了します。


そして、ログインページにアクセスしてみます。
ここでもエラー発生。

Fatal error: Maximum execution time of 30 seconds exceeded in /home/users/○○○/blog/wordpress/wp-content/pdo/PDOEngine.php on line 451 

なんだか、タイムアウトしたらしい。
とりあえず、再度アクセスしてみるとログインページが表示されました。

ということで、無事インストールが完了しました。
WordPressってインストール簡単でステキですよね。

EC-CUBE で商品ごとに指定した個数以上購入すると送料無料になるようにしてみた。

通販サイトのキャンペーンで「この商品は送料無料!」や「3個購入で送料無料!」みたいな表記を
しているサイトって、見たことありますか?


ボクは、見たことありますよー。
EC-CUBEには、「5,000円以上購入すると送料無料」や「購入した商品数の合計が3個以上だと送料無料」のような
機能が使用可能です。
ただ、「PS3を3台購入すると送料無料(笑)」のようにある商品に限定した設定はできません。


なので、現在使用中のEC-CUBEにその機能を実装してみたいと思います。

変更したデータベースのテーブル

dtb_products
列名 Null 既定値 説明
deliv_free_floor int Null許可 0 送料無料にする個数の下限値(送料無料にしない場合は0)

上記の列を追加します。

変更したPHPファイル

  • /data/class/pages/admin/products/LC_Page_Admin_Products_Product.php
  • /data/class/db/dbfactory/SC_DB_DBFactory_MYSQL.php
  • /data/class/helper/SC_Helper_DB.php

※この変更はデータベースがMySQLであることを前提としています。

/data/class/pages/admin/products/LC_Page_Admin_Products_Product.php

管理ページの「商品管理」→「商品登録」でデータベースに登録する関係のところ
387行目くらい

/* 商品の登録 */
function lfRegistProduct($arrList) {
    $objQuery = new SC_Query();
    $objDb = new SC_Helper_DB_Ex();
    $objQuery->begin();

    // 配列の添字を定義
    // deliv_free_floor を追加
    $checkArray = array("name", "status", "product_flag",
                        "main_list_comment", "main_comment", "point_rate",
                        "deliv_fee", "comment1", "comment2", "comment3",
                        "comment4", "comment5", "comment6", "main_list_comment",
                        "sale_limit", "sale_unlimited", "deliv_date_id", "note",
			"deliv_free_floor");
    $arrList = SC_Utils_Ex::arrayDefineIndexes($arrList, $checkArray);

400行目くらい

    // INSERTする値を作成する。
    $sqlval['name'] = $arrList['name'];
    $sqlval['status'] = $arrList['status'];
    $sqlval['product_flag'] = $arrList['product_flag'];
    $sqlval['main_list_comment'] = $arrList['main_list_comment'];
    $sqlval['main_comment'] = $arrList['main_comment'];
    $sqlval['point_rate'] = $arrList['point_rate'];
    $sqlval['deliv_fee'] = $arrList['deliv_fee'];
    $sqlval['deliv_free_floor'] = $arrList['deliv_free_floor'];	// deliv_free_floor を追加
    $sqlval['comment1'] = $arrList['comment1'];

560行目くらい

// 入力エラーチェック
    function lfErrorCheck($array) {
    $objErr = new SC_CheckError($array);
    $objErr->doFunc(array("商品名", "name", STEXT_LEN), array("EXIST_CHECK", "SPTAB_CHECK", "MAX_LENGTH_CHECK"));
    $objErr->doFunc(array("一覧-メインコメント", "main_list_comment", MTEXT_LEN), array("EXIST_CHECK", "SPTAB_CHECK", "MAX_LENGTH_CHECK"));
    $objErr->doFunc(array("詳細-メインコメント", "main_comment", LLTEXT_LEN), array("EXIST_CHECK", "SPTAB_CHECK", "MAX_LENGTH_CHECK"));
    $objErr->doFunc(array("詳細-メインコメント", "main_comment", $this->arrAllowedTag), array("HTML_TAG_CHECK"));
    $objErr->doFunc(array("ポイント付与率", "point_rate", PERCENTAGE_LEN), array("EXIST_CHECK", "NUM_CHECK", "SPTAB_CHECK", "MAX_LENGTH_CHECK"));
    $objErr->doFunc(array("商品送料", "deliv_fee", PRICE_LEN), array("NUM_CHECK", "SPTAB_CHECK", "MAX_LENGTH_CHECK"));
    // delive_free_floor をチェックするように追加
    $objErr->doFunc(array("送料無料", "deliv_free_floor", AMOUNT_LEN), array("EXIST_CHECK", "SPTAB_CHECK", "NUM_CHECK", "MAX_LENGTH_CHECK"));
    $objErr->doFunc(array("備考欄(SHOP専用)", "note", LLTEXT_LEN), array("SPTAB_CHECK", "MAX_LENGTH_CHECK"));
/data/class/db/dbfactory/SC_DB_DBFactory_MYSQL.php

管理ページの「商品管理」→「商品登録」でデータベースからデータを取得する関係のところ
382行目くらい
T1.delive_free_floor を追加しています。

"vw_products_nonclass" => '
    (SELECT
        T1.product_id,
        T1.name,
        T1.deliv_fee,
	T1.deliv_free_floor,
        T1.sale_limit,
        T1.sale_unlimited,
        T1.category_id,
        T1.rank,
        T1.status,
/data/class/helper/SC_Helper_DB.php

「現在のカゴの中」などで合計金額や送料を計算するときに関係するところ
245行目くらい

/**
 * 商品規格情報を取得する.
 *
 * @param array $arrID 規格ID
 * @return array 規格情報の配列
 */
function sfGetProductsClass($arrID) {
    list($product_id, $classcategory_id1, $classcategory_id2) = $arrID;

    if($classcategory_id1 == "") {
        $classcategory_id1 = '0';
    }
    if($classcategory_id2 == "") {
        $classcategory_id2 = '0';
    }

    // 商品規格取得
    // deliv_free_floor を追加
    $objQuery = new SC_Query();
    $col = "product_id, deliv_fee, deliv_free_floor, name, product_code, main_list_image, main_image, price01, price02, point_rate, product_class_id, classcategory_id1, classcategory_id2, class_id1, class_id2, stock, stock_unlimited, sale_limit, sale_unlimited";
    $table = "vw_product_class AS prdcls";

1521行目くらい

    // 送料無料の購入数が設定されている場合
    if(DELIV_FREE_AMOUNT > 0) {
        if($total_quantity >= DELIV_FREE_AMOUNT) {
            $arrData['deliv_fee'] = 0;
        }
    }

    // 商品に送料無料の購入数が設定されている場合 ←これを追加します。
    foreach($objPage->arrProductsClass as $item) {
        if($item['deliv_free_floor'] > 0) {
            if($item['quantity'] >= $item['deliv_free_floor']) {
                $arrData['deliv_fee'] = 0;
            }
        }
     }
		
     // 送料無料条件が設定されている場合
     if($arrInfo['free_rule'] > 0) {
         // 小計が無料条件を超えている場合
         if($arrData['subtotal'] >= $arrInfo['free_rule']) {
             $arrData['deliv_fee'] = 0;
         }
      }

変更したテンプレートファイル

  • /data/Smarty/templates/default/admin/products/product.tpl
  • /data/Smarty/templates/default/admin/products/confirm.tpl
/data/Smarty/templates/default/admin/products/product.tpl

管理ページの「商品管理」→「商品登録」で入力するときに表示されるページ
210行目くらい

<tr class="fs12n">
    <td bgcolor="#f2f1ec" width="160">購入制限<span class="red"> *</span></td>
    <td bgcolor="#ffffff" width="557">
    <span class="red12"><!--{$arrErr.sale_limit}--></span>
    <input type="text" name="sale_limit" value="<!--{$arrForm.sale_limit|escape}-->" size="6" class="box6" maxlength="<!--{$smarty.const.AMOUNT_LEN}-->" style="<!--{if $arrErr.sale_limit != ""}-->background-color: <!--{$smarty.const.ERR_COLOR}--><!--{/if}-->"/><input type="checkbox" name="sale_unlimited" value="1" <!--{if $arrForm.sale_unlimited == "1"}-->checked<!--{/if}--> onclick="fnCheckSaleLimit('<!--{$smarty.const.DISABLED_RGB}-->');"/>無制限</td>
    </td>
</tr>
<!-- ↓下記の項目を追加します。↓ -->
<tr class="fs12n">
    <td bgcolor="#f2f1ec" width="160">送料無料<span class="red"> *</span></td>
    <td bgcolor="#ffffff" width="557">
    <span class="red12"><!--{$arrErr.deliv_free_floor}--></span>
    <input type="text" name="deliv_free_floor" value="<!--{$arrForm.deliv_free_floor|escape}-->" size="6" class="box6" maxlength="<!--{$smarty.const.AMOUNT_LEN}-->" style="<!--{if $arrErr.deliv_free_floor != ""}-->background-color: <!--{$smarty.const.ERR_COLOR}--><!--{/if}-->"/>個以上は送料無料(0個の場合は送料無料なし)<span class="red10"> (半角数字で入力)</span>
     </td>
</tr>
/data/Smarty/templates/default/admin/products/confirm.tpl

管理ページの「商品管理」→「商品登録」で入力内容の確認をするときに表示されるページ
140行目くらい

<tr>
    <td bgcolor="#f2f1ec" width="160" class="fs12n">購入制限</td>
    <td bgcolor="#ffffff" width="557" class="fs12n">
    <!--{if $arrForm.sale_unlimited == 1}-->
    無制限
    <!--{else}-->
    <!--{$arrForm.sale_limit|escape}--><!--{/if}-->
    </td>
</tr>
<!-- ↓下記の項目を追加します。↓ -->
<tr>
    <td bgcolor="#f2f1ec" width="160" class="fs12n">送料無料</td>
    <td bgcolor="#ffffff" width="557" class="fs12n">
    <!--{if 0 < $arrForm.deliv_free_floor}-->
    <!--{$arrForm.deliv_free_floor|escape}-->
    個以上は送料無料
    <!--{else}-->
    なし
    <!--{/if}-->
    </td>
</tr>


以上、おわり。
お疲れ様でした。

EC-CUBE でメルマガの送信元名を会社名からショップ名に変更してみた。

EC-CUBEにはメルマガを配信する機能があります。



そこから、メルマガを配信すると送信元の名前が
「基本情報管理」の「SHOPマスタ」で設定した「会社名」のデータが使用されるみたいです。


他の商品を受注したときに送信されるサンクスメールなどは「ショップ名」が使われているのに
何故にメルマガだけ違うんだろう?


今回のEC-CUBEで構築したサイトでは、「会社名」と「ショップ名」は同一ではありません。
そのため、このままではサンクスメールとメルマガの送信元名が違う名前という
受け取る人にとっては、きっと迷惑な状態です。


ということで今回は、
メルマガの送信元名を「会社名」から「ショップ名」に変更したときのメモを書いときます。


といっても変更点は1行なので簡単です(笑)

方法

編集するファイル
  • data/class/pages/admin/mail/LC_Page_Admin_Mail_Sendmail.php
変更前

130行目くらい

$this->objMail->setItem(
	$list_data[$i][$j]["email"]
	,$subjectBody
	,$mailBody
	,$objSite->data["email03"]	// 送信元メールアドレス
	,$objSite->data["company_name"]	// 送信元名
	,$objSite->data["email03"]	// reply_to
	,$objSite->data["email04"]	// return_path
	,$objSite->data["email04"]	// errors_to
);
変更後
$this->objMail->setItem(
	$list_data[$i][$j]["email"]
	,$subjectBody
	,$mailBody
	,$objSite->data["email03"]	// 送信元メールアドレス
	,$objSite->data["shop_name"]	// 送信元名 company_name -> shop_name に変更
	,$objSite->data["email03"]	// reply_to
	,$objSite->data["email04"]	// return_path
	,$objSite->data["email04"]	// errors_to
);

HP ProLiant ML110 G5 をいじるために必要な工具。

HP ProLiant ML110 G5に使われているネジは、
ほとんどが星形の穴になっているタイプです。

普通のプラスドライバーが使えるのは、ケースファンのファンガードくらいかも。


ということで星形のネジ用の「トルクスドライバー」が必要になってきます。

今回は、近くのコーナンで購入しました。
トルクスドライバーのサイズは「T-15」です。
価格は、500円くらい。

ちなみにamazonでも売ってるよ -> Amazon.co.jp: トルクスドライバー B-5400TX-T15H: パソコン・周辺機器


コーナンの売り場には、ドライバータイプ以外に何本かセットになったレンチタイプのものも
ありましたが、ボク的にはドライバータイプがおすすめです。


レンチセットは複数のサイズが揃っていて便利ですが、
HP ML110のパソコンだけに限定した場合は、T-15のサイズだけで大丈夫です。
ドライバータイプは持ち手があるため握りやすいし、レンチに比べると長時間作業するときに楽だと思います。


ここで一応ドライバーの大切さを書いてみたのですが、ボクも最初は持ってませんでした。
そのため、HDDを増設するときにマイナスドライバーを使って、
ケース前面にあるネジを取り外そうと試みたのですが、ねじ山を潰しそうになり、かなり苦戦しました。
そのときのことを考えると、専用のドライバー買っておけば、と少し悲しくなります。

まあ、これからは大丈夫ということで、いい勉強になったなぁ、と思っておこう。

C#のChartを使って積み上げ縦棒グラフを表示してみる。

C#のChartを使って積み上げ縦棒グラフを表示する方法をメモ。

フォームの構成

フォームに配置するコントロール
  • コモンコントロール:Buttom → button1
  • データ:Chart → chart1

コード

private void button1_Click(object sender, EventArgs e)
{
    string[] legends = new string[] { "グラフ1", "グラフ2" }; //凡例

    chart1.Series.Clear();  //グラフ初期化

    foreach (var item in legends)
    {
        chart1.Series.Add(item);    //グラフ追加
        //グラフの種類を指定(Columnは積み上げ縦棒グラフ)
        chart1.Series[item].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.StackedColumn;
        chart1.Series[item].LegendText = item;  //凡例に表示するテキストを指定
    }  

    string[] xValues = new string[] { "A", "B", "C", "D", "E" };    //X軸のデータ
    int[,] yValues = new int[,] {{ 10, 20, 30, 40, 50 }, {20, 40, 60, 80, 100}};    //Y軸のデータ

    for (int i = 0; i < xValues.Length; i++)
    {
        for (int j = 0; j < yValues.GetLength(0); j++)
        {
            //グラフに追加するデータクラスを生成
            System.Windows.Forms.DataVisualization.Charting.DataPoint dp = new System.Windows.Forms.DataVisualization.Charting.DataPoint();
            dp.SetValueXY(xValues[i], yValues[j,i]);  //XとYの値を設定
            dp.IsValueShownAsLabel = true;  //グラフに値を表示するように指定
            chart1.Series[legends[j]].Points.Add(dp);   //グラフにデータ追加
        }
    }
}

実行結果

HP ProLiant ML110 G5 のケースファンを交換してみた。

Sofmapで1万円以下で購入できるようになったHPのProLiant ML110 G5 ですが、
安かったので購入してみました。
ちなみに今はもう売り切れちゃったみたいです。



型番:HP ProLiant ML110 G5
CPU:Celeron 440 2GHz
チップセットIntel 3200
光学ドライブ:DVD-ROMドライブ
HDD:160GB(SATA
メモリ:1GB(PC2-6400 アンバッファ ECC DDR2 SDRAM



現在は、Debian + Xen をインストールして遊んでるところ。


使ってみた第一印象はファンがかなりの騒音だということです。
ボクが使ってるパソコンたちは静音をそれなりに重視して作っているため、
HPのパソコンの音が結構気になります。


ということで、今回は静音化のためにケースファンを交換してみました。
だけど、結果だけ先に書いておくと、期待していた静音化はできませんでした(泣)
そこそこ静音化できたみたい。

ケースファンの選定

90mmファンであるケースファンの選定基準は、

  • 90mmファンであること
  • 静音を重視したもの
  • ファンの掃除が簡単

以上、3つの基準をもとに選んでみました。

で、選んだのがコレ。


ENERMAX UCTB9 (92×92×25mm/1400RPM)
型番:UCTB9
サイズ:92×92×25mm
回転数:1400RPM
風量:27.18CFM
最小ノイズ:13dBA


このファンの特徴は、サイドからの吸気ができることと、ファンの羽が取り外せることです。
ファンの羽が取り外せるので羽に付いた埃が取りやすい。
あと、価格も1,000円以下なのでお手頃な感じ。それと、ちょっとカッコイイ。

ケースファンの取り外し

このHPのパソコンのケースファンはネジではなく、防振ゴムブッシュで取り付けられています。
これにより、ファンの振動がケースに伝わらないのが良いところです。
でも、取り外しにはなかなか苦労しましたよw。

取り外し方としては、
ファンを内側から引っ張りつつ、ケースの外側からゴムの部分をマイナスドライバーで穴にねじ込むように押す。
です。

コツをつかむとそれなりに簡単に外せるようになります。

ケースファンの取り付け

もともと付いていたファンのコネクタは5ピンです。
マザーボードも5ピンです。
そして、今回買ったファンは普通の3ピンです。
そのため、3ピンコネクタの左側のガイド(突起)をニッパーで切断しました。
これでマザーボードコネクタが接続できるようになりました。


次は防振ゴムブッシュの取り付けです。
まずファンに取り付けますが、方法は思いっきり引っ張ってみるのみです。
また、同様にケースに取り付けるときも頑張って引っ張ります。

動作テスト

ファンの取り付け、取り外しに約30分ほどかかりました。
少し防振ゴムブッシュが嫌いになりそうでした。


とにかく、ファンの取り付けが完了したのでパソコンの電源をONして動作を確かめます。
ファンは正常に回転、OSも正常に立ち上がりました。
が、しかし、何だかあまり騒音レベルが変わってない気がする。。。


うん、騒音の原因はCPUファンだったのです、たぶん。
でっかいヒートシンクに隠れていてファンの存在に気づいてなかったよ。Σ( ̄Д ̄;)がーんっ!



ということで、そのうちCPUファンをどうにかして、静音化したいと思います。
頑張れ、ボク。

2010.10.07追記

今までは、うるさいパソコンだったので別の部屋に隔離していましたが、
今日、他のパソコンと同じ部屋に移動して、稼働させたところ、
前ほど、音が気にならないことに気づきました。


そのため、ケースファンを静音なファンに交換することは、そこそこ効果があるようです。
ただ、まだファンの音が若干気になるので、やっぱりCPUファンはそのうち交換したいです。

C#のChartを使って棒グラフを表示してみる。

VisualStudio 2010になるとC#でフォームアプリを作るときにグラフ表示が簡単にできるようになりました。
それは標準でコントロールに「Chart」というものができたからです。

慣れると便利なChartですが、最初は使い方が分からずGoogle先生に頼らないとやってられないです。
という個人的感想より、簡単チャート作成チュートリアル的なものを書いてみました。

フォームの構成


フォームに配置するコントロール
  • コモンコントロール:Buttom → button1
  • データ:Chart → chart1

コード

private void button1_Click(object sender, EventArgs e)
{
    string legend = "グラフ1";

    chart1.Series.Clear();  //グラフ初期化

    chart1.Series.Add(legend);  //グラフ追加
    //グラフの種類を指定(Columnは棒グラフ)
    chart1.Series[legend].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Column;
    chart1.Series[legend].LegendText = legend;  //凡例に表示するテキストを指定

    string[] xValues = new string[] { "A", "B", "C", "D", "E" };
    int[] yValues = new int[] { 10, 20, 30, 40, 50 };

    for (int i = 0; i < xValues.Length; i++)
    {
        //グラフに追加するデータクラスを生成
        System.Windows.Forms.DataVisualization.Charting.DataPoint dp = new System.Windows.Forms.DataVisualization.Charting.DataPoint();
        dp.SetValueXY(xValues[i], yValues[i]);  //XとYの値を設定
        dp.IsValueShownAsLabel = true;  //グラフに値を表示するように指定
        chart1.Series[legend].Points.Add(dp);   //グラフにデータ追加
    }
}

実行結果

まとめ

今回はChartを使った簡単な棒グラフを作ってみました。
気が向いたらバリエーションを増やしていきたいと思います。