アメブロのCSS構成

body#mainIndex
┣ ul#amebaBar
┣ div#frame
┃ ┗ div#subFrame
┃   ┣ div#overHeader
┃   ┃ ┣ div#userNaviAream  .clearFix
┃   ┃ ┗ div#header
┃   ┃   ┣ h1
┃   ┃   ┗ h2
┃   ┗ div#wrap
┃     ┗ div#firstContentsArea
┃       ┗ div#subFirstContentsArea
┃         ┣ div#sub_a
┃         ┃  ┣ div#freespace  . mainMenu
┃         ┃  ┣ div#profile  .mainMenu
┃         ┃  ┃ ┣ h4.menu_title
┃         ┃  ┃ ┗ div.menu_frame
┃         ┃  ┃   ┣ div#new_profile
┃         ┃  ┃   ┃ ┗ div#person
┃         ┃  ┃   ┗ ul#amemberProfArea
┃         ┃  ┣ div#theme_list  .mainMenu
┃         ┃  ┃ ┣ h4.menu_title
┃         ┃  ┃ ┗ div#menu_frame
┃         ┃  ┣ div#recent_entries  .mainMenu
┃         ┃  ┃ ┣ h4.menu_title
┃         ┃  ┃ ┗ div#menu_frame
┃         ┃  ┣ div#archives  .mainMenu
┃         ┃  ┃ ┣ h4.menu_title
┃         ┃  ┃ ┗ div#menu_frame
┃         ┃  ┣ div#reader  .mainMenu
┃         ┃  ┃ ┣ h4.menu_title
┃         ┃  ┃ ┗ div#menu_frame
┃         ┃  ┃   ┗ div#readerList
┃         ┃  ┣ div#ranking  .mainMenu
┃         ┃  ┃ ┣ h4.menu_title
┃         ┃  ┃ ┗ div#menu_frame
┃         ┃  ┃   ┣ div#rank_all
┃         ┃  ┃   ┗ div#rank_genre
┃         ┃  ┣ div#search  .mainMenu
┃         ┃  ┃ ┣ h4.menu_title
┃         ┃  ┃ ┗ div#menu_frame
┃         ┃  ┣ div#bookmark  .mainMenu
┃         ┃  ┃ ┣ h4.menu_title
┃         ┃  ┃ ┗ div#menu_frame
┃         ┃  ┣ div#calendar  .mainMenu
┃         ┃  ┃ ┣ h4.menu_title
┃         ┃  ┃ ┗ div#menu_frame
┃         ┃  ┣ div#recent_comment  .mainMenu
┃         ┃  ┃ ┣ h4.menu_title
┃         ┃  ┃ ┗ div#menu_frame
┃         ┃  ┣ div#favorite  .mainMenu
┃         ┃  ┃ ┗ h4.menu_title
┃         ┃  ┗ div#menu_frame
┃         ┣ div#main
┃         ┃ ┗ div#sub_main
┃         ┃   ┣ div#readerMainLink
┃         ┃   ┃ ◆◆◆ループ◆◆◆
┃         ┃   ┗ div#entry new
┃         ┃     ┣ div#entry_head
┃         ┃     ┃┗ span.date
┃         ┃     ┣ h3.title
┃         ┃     ┣ span.theme
┃         ┃     ┣ div#contents
┃         ┃     ┃ ┗ div#subContents
┃         ┃     ┃   ┣ div#advertising2
┃         ┃     ┃   ┗ div#themeBox
┃         ┃     ┃     ┗ h5
┃         ┃     ┗ div#foot
┃         ┃     ◆◆◆// ループ◆◆◆
┃         ┗ div#sub_b
┃           ┣ div#defaultAd  .mainMenu .defaultAd2
┃           ┃ ┣ h4.menu_title
┃           ┃ ┗ div#attentionBox  .menu_frame
┃           ┣ div#ameblo  .mainMenu
┃           ┃ ┗ div#menu_frame
┃           ┃   ┗ div#sideTextAd
┃           ┗ div#rss  .mainMenu
┃             ┗ div#menu_frame
┗ div#footerArea

季節で表示を変ええる

date関数で月日を4桁数字として取得する。
季節の月日と比較するだけ。

春  3月1日– 5月31日
夏  6月1日– 8月31日
秋  9月1日–11月31日
冬 12月1日–2月29日

<?php
    // 今日の月日を取得
    $date = date(md);
    // 春
    if( ($date >= 0310) && ($date <= 0531) ){
        $tab_active = 'Spring';
    // 夏
    }elseif( ($date >= 0601) && ($date <= 0831) ){
        $tab_active = 'Summer';
    // 秋
    }elseif( ($date >= 0901) && ($date <= 1131) ){
        $tab_active = 'Autumn';
    // 冬
    }elseif( ($date >= 1201) || ($date <= 0229) ){
        $tab_active = 'Winter';
    }
?>

会員登録のカスタマイズ

会員ランク[dtb_customer.status]の初期値を任意に操作する。

/data/class/pages/entry/LC_Page_Entry.php
L: 621

$arrRegist["status"] = "2";				// 本会員

この辺を変更する。

// 条件により会員ランクを分ける
if(条件1){
    $sqlval['status'] = '3';
}elseif(条件2){
   $sqlval['status'] = '4';
}

※ 「status = 1」は仮登録会員用として予約済み!

受注管理ページの変数

Smarty変数(配列)をphpに渡す。

/data/Smarty/templates/default/admin/order/index.tpl

global $objPage;
$hoge = ($objPage->arrResults);
var_dump($hoge);
これで配列が見える

global $objPage;
$hoge = ($objPage->arrResults);
$hoge_customer_id = $hoge[$aa][customer_id];

ループなので、カウントをとって「$aa」に代入
これで欲しい変数が見える!

AUTO_INCREMENTの値をリセットする方法

EC-CUBEなどで、カテゴリIDや商品IDを指定したいということもあるようです。
AUTO_INCREMENT(自動採番)を採用しているのは、指定する必要性が考えられないからです。
番号を指定したいというご要望も多いですね。
理由は聞かないことにしています。
辻褄の合う理由など存在しないのですから、聞いて腹だ立つのなら、聞かずに対応してしまいましょう。

操作は至って簡単!

ALTER TABLE <テーブル名> AUTO_INCREMENT = 1;

関連テーブルのIDの変更もお忘れなく…

PHPのショートタグとXML宣言

XHTMLにPHPを書く場合、行頭のXML宣言がPHPタグとみなされ、エラーが出てしまう。これはサーバー側のphp.iniファイルに記述してある、short_open_tagがOnになっているから起こる問題。
<?」でPHPが開始されるから発生する。
<?php」でなければ開始できないようにすればよい。
回避するためには

&lt;?php echo '&lt;? xml version="1.0" ?&gt;'; ?&gt; 

と、phpのPrint命令でxml宣言を書き出すか、
.htaccessファイルに以下の一行を追加すれば解決。

php_flag short_open_tag off

EC-CUBEでカスタマイズになるのかどうか判らない

EC-CUBEでカスタマイズになるのかどうか判らない
というお問い合わせが多いです。

EC-CUBEの機能一覧
http://www.ec-cube.net/product/function.php

EC-CUBEのデモサイト
http://www.ec-cube.net/product/demo.php#pc

その他の注意点

1)TOPページ
弄りがいがあるページです。ブロック単位でのカスタマイズ希望が多いです。

2)検索機能
しょぼいです。基本設計からおかしいので「検索機能・一覧表示機能」を作り変えなければまともな検索は期待できません。

3)会員登録
項目を変える場合、モジュールファイルやデータベースの変更が必須です。

4)商品一覧
カスタマイズの可能性は極めて少ないです。

5)商品詳細
・画像
・商品名
・商品コード
・価格
・説明文
・カテゴリ
・メーカー
・在庫
で構成されます。
項目を増やす場合は、モジュールファイルやデータベースの変更が必須です。

6)買い物カゴ
カートから決済までのページは弄らないほうが無難です。
最も多いのは
「次へ」ボタンの表記を変えるなどです。他のページと流用が多いので、そのページだけに合うように変更することは避けたほうが無難です。

7)Myページ
変更のご依頼は、極めて少ないです。

カスタマイズを見分けるには?

1)機能を熟知していない
デザインやディレクション担当の方が機能を熟知していないため、カスタマイズかどうか判らないことが多いようです。
「機能一覧」を読んでもなかなか理解できないでしょう。
「デモサイト」を実際に使ってみてください。

2)カスタマイズを見分けるコツ
デザインや打ち合わせのときに「この機能はあるのかな?」と想像してください。
それで判らなければ、あなたにはEC-CUBEを扱うことは不可能です。
それでも、EC-CUBEを必要とするならば、お手伝いいたします。

3)基本機能がわかりません
という質問も多いです。言葉で説明しても、実際に使ってみるのとは感じ方が違います。
使って練習するのがもっとも早道です。
それが面倒な場合はカスタマイズがあっても無くても一律「込み込み料金」で承ります。
割高のようですが、本当は割安です。

4)安くて安心なご依頼方法
「カスタマイズがないから安く製作して欲しい」というご要望が多いです。
本当にカスタマイズがなかった事例は無に等しいです。
何らかのカスタマイズが含まれるならば「込み込み料金」がお勧めです。

カスタマイズと言うのは、細かなものでも一項目あたり数万円です。
2~3つのカスタマイズが含まれれば、カスタマイズ料金だけで10万円を超えます。
「込み込み料金」の場合、30万円相応までのカスタマイズ込みで一律15万円です。
(決済周りの複雑な改変を除く)
カスタマイズがない場合「損をする」とお考えならば、カスタマイズ無しのデザインをしたつもりで、カスタマイズ費用をお支払いください。たぶん15万円は越えてしまうと思います。

WordPressでカテゴリを指定して記事を表示する。

// 元

&lt;?php if (have_posts()) : while (have_posts()) : the_post(); ?&gt;

// カテゴリを指定して表示する

&lt;?php if (have_posts()) :  query_posts('&posts_per_page=20&cat=47');  ?&gt;
&lt;?php while (have_posts()) : the_post(); ?&gt;
posts_per_page=20、表示する記事数
cat=47、カテゴリIDなのだが、パーマリンクを変更するとこれが効かない。
category_nama=***、これでできた。

// 複数カテゴリを指定して表示する

&lt;?php query_posts(array('category__in' =&gt; array(25,24,23,10))); ?&gt;
&lt;?php if (have_posts()) : while (have_posts()) : the_post(); ?&gt;

会員のランク分け

ログイン処理
ログイン処理の変更
data/class/SC_Customer.php
// 本登録された会員のみ
// $sql = “SELECT * FROM dtb_customer WHERE (email = ?” . $sql_mobile . “) AND del_flg = 0 AND status = 2”;
$sql = “SELECT * FROM dtb_customer WHERE (email = ?” . $sql_mobile . “) AND del_flg = 0 AND ( status = 2 OR status = 3 )”;

「status = 2」以外も許可する

ログインIDをメールアドレスでなくても可能にする

会員情報管理
会員情報編集画面(青を追記)
ファイルdata\Smarty\templates\default\admin\customer\edit.tpl
<!–<input type=”radio” name=”status”value=1 id=”no_mem” <!–{if $list_data.status == 1}–> checked=”checked” <!–{/if}–> <!–{if $list_data.status == 2}–>disabled<!–{/if}–>><label for=”no_mem”>仮会員</label>–>
<input type=”radio” name=”status”value=2 id=”mem”<!–{if $list_data.status == 2}–> checked=”checked” <!–{/if}–>><label for=”mem”>一般会員</label>
<input type=”radio” name=”status”value=3 id=”mem”<!–{if $list_data.status == 3}–> checked=”checked” <!–{/if}–>><label for=”mem”>HIS会員</label>

確認ページ
I:\home\skyblue\data\Smarty\templates\default\admin\customer\edit_confirm.tpl

SQL文
I:\home\skyblue\data\class\pages\admin\customer\LC_Page_Admin_Customer_Edit.php
80行目くらい
入力チェック 同270行くらい

暗号化(AUTH_MAGIC)
I:\home\skyblue\data\mtb_constants_init.php

ログインチェック(ここで$_SESSION[customer]が殻で無ければログインとする)
I:\home\skyblue\data\class\pages\frontparts\bloc\LC_Page_FrontParts_Bloc_Login.php

会員ランクはCUBEにはじめから実装されている。
仮会員と本会員を識別するためのものだが、そのフラグを利用するのがもっともスマートな方法です。
$_SESSION[customer][status] で取り出すことができます。

ログイン処理(ECCUBEのログイン状態を作る)

バージョンによてファイル名が違う

data/class/pages/frontparts/LC_Page_FrontParts_LoginCheck.php

data/class/pages/frontparts/LC_Page_FrontParts_Bloc_Login.php

今回は「$_SESSION[member_id] 」があればログイン状態にする、というサンプルです。
Wordpressなど他のシステムにログインしていて
EC-CUBEにログイン状態を引き継ぐときなどに活用します。

// ログイン判定
if ($objCustomer->isLoginSuccess()) {
	$this->tpl_login = true;
	$this->tpl_user_point = $objCustomer->getValue('point');
	$this->tpl_name1 = $objCustomer->getValue('name01');
	$this->tpl_name2 = $objCustomer->getValue('name02');
//  ↓ ここから追記
}elseif($_SESSION[member_id] != '') {
	$this->tpl_login = true;
	$this->tpl_user_point = $objCustomer->getValue('point');
	$this->tpl_name1 = $objCustomer->getValue('name01');
	$this->tpl_name2 = $objCustomer->getValue('name02');
//  ↑ ここまで追記
} else {
	// クッキー判定
	$this->tpl_login_email = $objCookie->getCookie('login_email');
	if ($this->tpl_login_email != '') {
	$this->tpl_login_memory = '1';
	}
	// POSTされてきたIDがある場合は優先する。
	if (isset($_POST['login_email']) && $_POST['login_email'] != '') {
	$this->tpl_login_email = $_POST['login_email'];
	}
}

EC-CUBE文字化け(その2)

eccube-2.4.2 では、SC_DbConn.php に下記が追記された。

MySQL文字化け対策(MySQLで文字化けする場合は以下のコメントアウトをはずして動作確認してみてください。)
if (DB_TYPE == 'mysql') {
   $objDbConn->query('SET NAMES utf8');
}

表示の文字化け対策にはなるだろう。
しかし、根本的な対策ではなさそうだ。

DBを直接除いたりしない人には関係無いかもしれないが、カスタマイズにはデータベースの操作が必須です。

CUBEの初期状態でインストールし、UTF-8にして上書きインストールしなければならない。

※ /data/cache を空にしないと反映されないので注意!

EC-CUBEで送料無料

EC-CUBEで送料無料の商品が含まれれば合計送料が無料になる。
「送料込み・送料別」をラジオボタンで選択式にする。

まず、どんな感じで実装するか?
DBは変更しない。dtb_products の deliv_fee を利用する。
このフィールドは将来拡張予定と書かれているが、拡張されても使いにくいのではないかと思うような書き方(ソースにコメントあり)なので、使い勝手の良いものを作ることにした。

1、管理登録・商品編集画面
File[data/Smarty/templates/default/admin/products/product.tpl]
eccube_custom_20091204a

2、確認画面
File[data/Smarty/templates/default/admin/products/confirm.tpl]
File[LC_Page_Admin_Products_Product.php]
eccube_custom_20091204b

3、送料の計算に例外処理を施す
File[data/class/helper/SC_Helper_DB.php]

決済後のメールやオーダー管理にもきちんと反映した。

ソースファイルはこちら ⇒ Dounload

EC-CUBEセキュリティパッチ

本不具合に対する対応方法
——————————————————————-
■不具合が存在するEC-CUBEのバージョン
——————————————————————-
EC-CUBE 正式版  2.4.0 RC1 以降 (2009年3月31日公開)
EC-CUBE コミュニティ版 r18068 以降 (2009年6月10日版以降)

——————————————————————-
■修正方法について
——————————————————————-
/data/class/pages/admin/customer/LC_Page_Admin_Customer_SearchCustomer.php#process
の最初に以下のログイン確認コードを挿入します。

■56行目付近
——————————————————————-
変更前
——————————————————————-
function process()
{
$objView = new SC_AdminView();
——————————————————————-

——————————————————————-
変更後
——————————————————————-
function process()
{
// 認証可否の判定
$objSess = new SC_Session();
SC_Utils_Ex::sfIsSuccess($objSess);

$objView = new SC_AdminView();
——————————————————————-

EC-CUBEのエンコード対策

サーバ移転や、試験環境などの構築で、文字化けが発生することがしばしばある。
データベース接続まわりを除いてみると、大切な記述が欠けている。

オープンソースなので、完璧を求めてはいけない。
ファイル名: /data/class/SC_DbConn.php
65行付近

$this-&gt;conn = $objDbConn;
<span style="color: #3366ff;">$this-&gt;conn-&gt;query(”SET NAMES utf8″);</span>
$this-&gt;error_mail_to = DB_ERROR_MAIL_TO;
$this-&gt;error_mail_title = DB_ERROR_MAIL_SUBJECT;
$this-&gt;err_disp = $err_disp;
$this-&gt;dbFactory = SC_DB_DBFactory_Ex::getInstance();

「$this->conn->query(”SET NAMES utf8″);」を追記すれば解決する。

※ この作業を行うタイミングが重要です。
インストールのどのタイミングで行うか、DB接続直後です。
最近のバージョンはやり方が違う。
一度インストールし、上記エンコード指定をした後、再度インストールする。
このときデータベースが存在するので削除するかと聞いてくるので、削除する。
これでよいのだが、既にデータを登録しているときは消えてしまうので注意が必要だ。
注意
エンコード関連を変更した後は、キャッシュファイルのクリアを忘れるべからず。
(/data/chash)

解説
php.ini のエンコード関係は、あまり指定しないのがサーバー屋の流儀である。
その場合、データベースの読み書きは、サーバーのデフォルト・エンコードで行われる。
サーバーのエンコードは、
最近は、UTF-8が多くなってきたが、以前はEUCが主流だった。
DBのエンコードとPHPファイルのエンコードが同じであっても、文字化けが発生する場合は、サーバーのデフォルトエンコードを疑うのが基本である。

エンコードをきちんと理解しないで安易にまねすると、復旧不可能に陥ります。

ご自身の責任で行ってください。

ビジュアルエディタを使用しない

WordPress の投稿・編集で「ビジュアルリッチエディタ」を使いたくなることもある。
「ビジュアルリッチエディタ」の有効・無効の設定は「設定」にはない。
「ユーザー」にある。
なぜ?と思うかもしれないが、サイトの管理者と運用者、投稿者、などにより管理画面の簡易性を求めるためである。wp_20100102

Photoshop:レイヤーを別のPSDの同じ座標にコピーする

たまに質問されるので書いておく。
コピーしたいレイヤーを選択し、Shiftキーを押しながら、コピー先のPSDにD&D。
※ただし、コピー元、コピー先のPSDのサイズが同じであること。同じじゃない場合は中心に配置。

昔のバージョンは、Shiftキーを押さなくても座標が維持されていたと思うけど・・。
CS2ぐらいから変わったんじゃないかと思う。しらんけど。

WordPress のデータベースに接続

<?php
// Config読込み
include $_SERVER[DOCUMENT_ROOT]."/wp-config.php";// MySQLに接続 ------------------
$db = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD);
//mysql_query("SET NAMES utf8″);
// DB指定(確認用)
if(!mysql_select_db(DB_NAME, $db)){
// echo '<div style="color:red;">メインデータベースに接続できません。</div>';
}elseif(mysql_select_db(DB_NAME, $db)){
echo '<div style="color:green;">DB指定OK!('.DB_NAME.')</div>';
}
// < EOF > MySQLに接続 ------------------

// $sql="SELECT * FROM `dtb_product_categories` WHERE `product_id` = '$_GET[product_id]'";
// $rs = mysql_query($sql,$db);
// $item = mysql_fetch_assoc($rs);
// var_dump($item);
?>

VirtualHost(開発端末の設定)

httpd.conf
お決まりのバーチャル設定を書く

&lt;VirtualHost *:80&gt;
ServerAdmin has@mint410.com
DocumentRoot "I:/home/test"
ServerAlias test.localhost
ServerName localhost
&lt;/VirtualHost&gt;


Windowsの場合以下も必要

http://localhostの場合DNSを読みにいかないので、C:/WINDOWS/system32/drivers/etc/hostに追記する。

127.0.0.1       localhost[ここに追記]
127.0.0.1       localhost test1.localhost test2.localhost test3.localhost

MTへのDB接続


// MT設定読み込み
$line = '';
$line = file("../app/mt/mt-config.cgi");
$i = 0;
while($line[$i]!=""){
	// マッチしたら変数化
	if (preg_match("/Database/",$line[$i])) {
		$DB_NAME = explode(' ', $line[$i]);
		$DB_NAME = trim($DB_NAME[1]);
	}
	if (preg_match("/DBUser/",$line[$i])) {
		$DB_USER = explode(' ', $line[$i]);
		$DB_USER = trim($DB_USER[1]);
	}
	if (preg_match("/DBPassword/",$line[$i])) {
		$DB_PASSWORD = explode(' ', $line[$i]);
		$DB_PASSWORD = trim($DB_PASSWORD[1]);
	}
	if (preg_match("/DBHost/",$line[$i])) {
		$DB_SERVER = explode(' ', $line[$i]);
		$DB_SERVER = trim($DB_SERVER[1]);
	}
	$i ++;
}
 //------------------------------------------------------
// MT_DBに接続開始
	$db = mysql_connect($DB_SERVER,$DB_USER,$DB_PASSWORD);
	mysql_query("SET NAMES utf8");
	// DB指定(確認用)
	if(!mysql_select_db($DB_NAME, $db)){
		 echo "&lt;div style=\"color:red;\"&gt;\nメインデータベースに接続できません。&lt;/div&gt;\n";
	}elseif(mysql_select_db($DB_NAME, $db)){
		 // echo "&lt;div style=\"color:green;\"&gt;\nDB指定OK!(".$DB_NAME.")&lt;/div&gt;\n\n\n";
	}
 // EOF/MT_DBに接続開始
//------------------------------------------------------

MTサイトマップ

  &lt;urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" style="color:red; width:1000px;display:block;"&gt;
  &lt;url&gt;
  &lt;loc&gt;&lt;$MTBlogURL encode_xml="1"$&gt;&lt;/loc&gt;
  &lt;lastmod&gt;&lt;$MTDate format="%Y-%m-%dT%H:%M:%S"$&gt;&lt;$MTBlogTimezone$&gt;&lt;/lastmod&gt;

  &lt;changefreq&gt;daily&lt;/changefreq&gt;
  &lt;/url&gt;
  
  &lt;MTIfArchiveTypeEnabled archive_type="Individual"&gt; 
  &lt;MTEntries lastn="9999"&gt;
  &lt;url&gt;

  &lt;loc&gt;&lt;$MTEntryPermalink encode_xml="1"$&gt;&lt;/loc&gt;
  &lt;lastmod&gt;&lt;$MTEntryModifiedDate format="%Y-%m-%dT%H:%M:%S"$&gt;&lt;$MTBlogTimezone$&gt;&lt;/lastmod&gt;
  &lt;priority&gt;1.0&lt;/priority&gt;

  &lt;/url&gt;
  &lt;/MTEntries&gt;
  &lt;/MTIfArchiveTypeEnabled&gt;
  
  &lt;MTIfArchiveTypeEnabled archive_type="Monthly"&gt; 
  &lt;MTArchiveList archive_type="Monthly"&gt;
  &lt;url&gt;

  &lt;loc&gt;&lt;$MTArchiveLink encode_xml="1"$&gt;&lt;/loc&gt;
  &lt;MTEntries lastn="1" sort_by="modified_on"&gt;
  &lt;lastmod&gt;&lt;$MTEntryModifiedDate format="%Y-%m-%dT%H:%M:%S"$&gt;&lt;$MTBlogTimezone$&gt;&lt;/lastmod&gt;

  &lt;/MTEntries&gt;
  &lt;/url&gt;
  &lt;/MTArchiveList&gt;
  &lt;/MTIfArchiveTypeEnabled&gt;
  
  &lt;MTIfArchiveTypeEnabled archive_type="Weekly"&gt; 
  &lt;MTArchiveList archive_type="Weekly"&gt;

  &lt;url&gt;
  &lt;loc&gt;&lt;$MTArchiveLink encode_xml="1"$&gt;&lt;/loc&gt;
  &lt;MTEntries lastn="1" sort_by="modified_on"&gt;

  &lt;lastmod&gt;&lt;$MTEntryModifiedDate format="%Y-%m-%dT%H:%M:%S"$&gt;&lt;$MTBlogTimezone$&gt;&lt;/lastmod&gt;
  &lt;/MTEntries&gt;
  &lt;/url&gt;
  &lt;/MTArchiveList&gt;

  &lt;/MTIfArchiveTypeEnabled&gt;
  
  &lt;MTIfArchiveTypeEnabled archive_type="Daily"&gt; 
  &lt;MTArchiveList archive_type="Daily"&gt;
  &lt;url&gt;
  &lt;loc&gt;&lt;$MTArchiveLink encode_xml="1"$&gt;&lt;/loc&gt;

  &lt;MTEntries lastn="1" sort_by="modified_on"&gt;
  &lt;lastmod&gt;&lt;$MTEntryModifiedDate format="%Y-%m-%dT%H:%M:%S"$&gt;&lt;$MTBlogTimezone$&gt;&lt;/lastmod&gt;
  &lt;/MTEntries&gt;

  &lt;/url&gt;
  &lt;/MTArchiveList&gt;
  &lt;/MTIfArchiveTypeEnabled&gt;
  
  &lt;MTIfArchiveTypeEnabled archive_type="Author"&gt; 
  &lt;MTArchiveList archive_type="Author"&gt;
  &lt;url&gt;

  &lt;loc&gt;&lt;$MTArchiveLink encode_xml="1"$&gt;&lt;/loc&gt;
  &lt;MTEntries lastn="1" sort_by="modified_on"&gt;
  &lt;lastmod&gt;&lt;$MTEntryModifiedDate format="%Y-%m-%dT%H:%M:%S"$&gt;&lt;$MTBlogTimezone$&gt;&lt;/lastmod&gt;

  &lt;/MTEntries&gt;
  &lt;/url&gt;
  &lt;/MTArchiveList&gt;
  &lt;/MTIfArchiveTypeEnabled&gt;
  
  &lt;MTIfArchiveTypeEnabled archive_type="Author-Daily"&gt; 
  &lt;MTArchiveList archive_type="Author-Daily"&gt;

  &lt;url&gt;
  &lt;loc&gt;&lt;$MTArchiveLink encode_xml="1"$&gt;&lt;/loc&gt;
  &lt;MTEntries lastn="1" sort_by="modified_on"&gt;

  &lt;lastmod&gt;&lt;$MTEntryModifiedDate format="%Y-%m-%dT%H:%M:%S"$&gt;&lt;$MTBlogTimezone$&gt;&lt;/lastmod&gt;
  &lt;/MTEntries&gt;
  &lt;/url&gt;
  &lt;/MTArchiveList&gt;

  &lt;/MTIfArchiveTypeEnabled&gt;
  
  &lt;MTIfArchiveTypeEnabled archive_type="Author-Weekly"&gt; 
  &lt;MTArchiveList archive_type="Author-Weekly"&gt;
  &lt;url&gt;
  &lt;loc&gt;&lt;$MTArchiveLink encode_xml="1"$&gt;&lt;/loc&gt;

  &lt;MTEntries lastn="1" sort_by="modified_on"&gt;
  &lt;lastmod&gt;&lt;$MTEntryModifiedDate format="%Y-%m-%dT%H:%M:%S"$&gt;&lt;$MTBlogTimezone$&gt;&lt;/lastmod&gt;
  &lt;/MTEntries&gt;

  &lt;/url&gt;
  &lt;/MTArchiveList&gt;
  &lt;/MTIfArchiveTypeEnabled&gt;
  
  &lt;MTIfArchiveTypeEnabled archive_type="Author-Monthly"&gt; 
  &lt;MTArchiveList archive_type="Author-Monthly"&gt;
  &lt;
url&gt;

  &lt;loc&gt;&lt;$MTArchiveLink encode_xml="1"$&gt;&lt;/loc&gt;
  &lt;
MTEntries lastn="1" sort_by="modified_on"&gt;
  &lt;lastmod&gt;&lt;$MTEntryModifiedDate format="%Y-%m-%dT%H:%M:%S"$&gt;&lt;$MTBlogTimezone$&gt;&lt;/lastmod&gt;

  &lt;/MTEntries&gt;
  &lt;/url&gt;
  &lt;/MTArchiveList&gt;
  &lt;/MTIfArchiveTypeEnabled&gt;
  
  &lt;MTIfArchiveTypeEnabled archive_type="Author-Yearly"&gt; 
  &lt;MTArchiveList archive_type="Author-Yearly"&gt;

  &lt;url&gt;
  &lt;loc&gt;&lt;$MTArchiveLink encode_xml="1"$&gt;&lt;/loc&gt;
  &lt;MTEntries lastn="1" sort_by="modified_on"&gt;

  &lt;lastmod&gt;&lt;$MTEntryModifiedDate format="%Y-%m-%dT%H:%M:%S"$&gt;&lt;$MTBlogTimezone$&gt;&lt;/lastmod&gt;
  &lt;/MTEntries&gt;
  &lt;/url&gt;
  &lt;/MTArchiveList&gt;

  &lt;/MTIfArchiveTypeEnabled&gt;
  
  &lt;MTIfArchiveTypeEnabled archive_type="Category"&gt; 
  &lt;MTArchiveList archive_type="Category"&gt;
  &lt;url&gt;
  &lt;loc&gt;&lt;$MTArchiveLink encode_xml="1"$&gt;&lt;/loc&gt;

  &lt;MTEntries lastn="1" sort_by="modified_on"&gt;
  &lt;lastmod&gt;&lt;$MTEntryModifiedDate format="%Y-%m-%dT%H:%M:%S"$&gt;&lt;$MTBlogTimezone$&gt;&lt;/lastmod&gt;
  &lt;/MTEntries&gt;

  &lt;/url&gt;
  &lt;/MTArchiveList&gt;
  &lt;/MTIfArchiveTypeEnabled&gt;
  
  &lt;MTIfArchiveTypeEnabled archive_type="Category-Daily"&gt; 
  &lt;MTArchiveList archive_type="Category-Daily"&gt;
  &lt;url&gt;

  &lt;loc&gt;&lt;$MTArchiveLink encode_xml="1"$&gt;&lt;/loc&gt;
  &lt;MTEntries lastn="1" sort_by="modified_on"&gt;
  &lt;lastmod&gt;&lt;$MTEntryModifiedDate format="%Y-%m-%dT%H:%M:%S"$&gt;&lt;$MTBlogTimezone$&gt;&lt;/lastmod&gt;

  &lt;/MTEntries&gt;
  &lt;/url&gt;
  &lt;/MTArchiveList&gt;
  &lt;/MTIfArchiveTypeEnabled&gt;
  
  &lt;MTIfArchiveTypeEnabled archive_type="Category-Weekly"&gt; 
  &lt;MTArchiveList archive_type="Category-Weekly"&gt;

  &lt;url&gt;
  &lt;loc&gt;&lt;$MTArchiveLink encode_xml="1"$&gt;&lt;/loc&gt;
  &lt;MTEntries lastn="1" sort_by="modified_on"&gt;

  &lt;lastmod&gt;&lt;$MTEntryModifiedDate format="%Y-%m-%dT%H:%M:%S"$&gt;&lt;$MTBlogTimezone$&gt;&lt;/lastmod&gt;
  &lt;/MTEntries&gt;
  &lt;/url&gt;
  &lt;/MTArchiveList&gt;

  &lt;/MTIfArchiveTypeEnabled&gt;
  
  &lt;MTIfArchiveTypeEnabled archive_type="Category-Monthly"&gt; 
  &lt;MTArchiveList archive_type="Category-Monthly"&gt;
  &lt;url&gt;
  &lt;loc&gt;&lt;$MTArchiveLink encode_xml="1"$&gt;&lt;/loc&gt;

  &lt;MTEntries lastn="1" sort_by="modified_on"&gt;
  &lt;lastmod&gt;&lt;$MTEntryModifiedDate format="%Y-%m-%dT%H:%M:%S"$&gt;&lt;$MTBlogTimezone$&gt;&lt;/lastmod&gt;
  &lt;/MTEntries&gt;

  &lt;/url&gt;
  &lt;/MTArchiveList&gt;
  &lt;/MTIfArchiveTypeEnabled&gt;
  
  &lt;MTIfArchiveTypeEnabled archive_type="Category-Yearly"&gt; 
  &lt;MTArchiveList archive_type="Category-Yearly"&gt;
  &lt;url&gt;

  &lt;loc&gt;&lt;$MTArchiveLink encode_xml="1"$&gt;&lt;/loc&gt;
  &lt;MTEntries lastn="1" sort_by="modified_on"&gt;
  &lt;lastmod&gt;&lt;$MTEntryModifiedDate format="%Y-%m-%dT%H:%M:%S"$&gt;&lt;$MTBlogTimezone$&gt;&lt;/lastmod&gt;

  &lt;/MTEntries&gt;
  &lt;/url&gt;
  &lt;/MTArchiveList&gt;
  &lt;/MTIfArchiveTypeEnabled&gt;
  
  &lt;MTIfArchiveTypeEnabled archive_type="Page"&gt; 
  &lt;MTArchiveList archive_type="Page"&gt;

  &lt;url&gt;
  &lt;loc&gt;&lt;$MTArchiveLink encode_xml="1"$&gt;&lt;/loc&gt;
  &lt;MTEntries lastn="1" sort_by="modified_on"&gt;

  &lt;lastmod&gt;&lt;$MTEntryModifiedDate format="%Y-%m-%dT%H:%M:%S"$&gt;&lt;$MTBlogTimezone$&gt;&lt;/lastmod&gt;
  &lt;/MTEntries&gt;
  &lt;/url&gt;
  &lt;/MTArchiveList&gt;

  &lt;/MTIfArchiveTypeEnabled&gt;
  
&lt;/urlset&gt;

きれいなフォント

サイトタイトルなど、大きな文字、しかも日本語でもギザギザしないでなめらか。
きれいなフォントの例

<del datetime="2010-03-15T03:04:32+00:00">font: bold 2.5em "Arial", Sans-Serif; margin: 0; letter-spacing: -1px; </del>

↑ 半角英数ものがきれい、2バイト文字はだめ。

font: bold 1.5em "ヒラギノ明朝 Pro W6","Hiragino Mincho Pro","HGS明朝E","MS P明朝",serif; margin: 0; letter-spacing: -1px;

EC-CUBEのデザイン管理で、勝手にエスケープされる

EC-CUBEを地価鯖(チカッパサーバー)で運用していると、

管理画面から編集したときに「”」が勝手にエスケープされてしまう。

「”」→「¥”」

対応策

magic_quotes_gpc が ON ならば OFF にする。

対応策というより「常識」です。

チカッパでは、”,htaccess” に “php_flag magic_quotes_gpc 0” と書いても効きません。
コントロールパネル → php.ini設定
で設定します。

カテゴリLevrl1 ならリンクしない、それ以外はリンクする

<!-- カテゴリLevrl1 ならリンクしない、それ以外はリンクする -->
<!--{php}-->$hoge = ($this->get_template_vars('level')); if($hoge == 1){<!--{/php}-->
    <!--{$arrTree&#91;cnt&#93;.category_name|escape}-->
<!--{php}-->}else{<!--{/php}-->
    <a href="<!--{$smarty.const.URL_DIR}-->products/list.php?category_id=<!--{$arrTree&#91;cnt&#93;.category_id}-->"<!--{if in_array($arrTree&#91;cnt&#93;.category_id, $tpl_category_id) }--> class="onlink"<!--{/if}-->>
        <!--{$arrTree&#91;cnt&#93;.category_name|escape}-->
    </a>
<!--{php}-->}<!--{/php}-->

新規投稿・編集のテキストエリアのサイズ調整

私の場合、該当ファイル本体をいじっているが、こんなところで調整できるらしい?
Wordpressの記事を書くボックスが狭いのはなぜだろう?
疑問だが、どうせ別なエディタで編集してペーストだから、頬って置いたが、こんな機能があったことは知らなかった。
こういうのって、素人さんのほうがしているのかもしれない。
少々恥ずかしい発見でした。

wpman_20091220

サイトマップ生成プラグイン

WordPressでサイトマップ自動生成プラグイン

Dagon Designのがよさそうなので Download

プラグインを有効にしたら、サイトマップ用に固定ページをつくって一行書くだけ!

&lt;!-- ddsitmapgen --&gt;

※ハイフンとddsitmapgenの間にスペースがないと動作しないようだ。
ddsitmapgen
 
 

もう少々高度なことをしたい場合、

テーマディレクトリに”sitmap.php”を作る。
内容は下記のように記述する。

&lt;?php
/*
Template Name: SITEMAP
*/
?&gt;

&lt;?php get_header();?&gt;

&lt;div id="sitemap"&gt; 
    &lt;?php echo ddsg_create_sitemap(); ?&gt;
&lt;/div&gt;

&lt;?php get_footer(); ?&gt;

固定ページをつくる。

タイトル"サイトマップ"
パーマリンク"https://mint123.tokyo/technology/sitmap"

本文は空でよい。
ページのテンプレートに ‘SITEMAP” を選択する。
ddsitmapge2

あとは、テンプレートでお好きなようにどうぞ!!

・・・カスタマイズしないとイマイチなプラグインかもしれないことに気付いてしまった。

オープンソースなのだから、汎用性を言うことを考えれば、この程度の(作りこんでいない)ベースになるものがいいのかもしれない。

記事IDから親カテゴリ情報抽出

wordpress のDB構成というのはとても洗練された無駄の無いものです。
その反面、記事IDからカテゴリを抽出しようとすると、3重の逆ループをかけなければなりません。
3重逆ループってどこかで聞いたような…ルービックキューブの公式を見出すことと同じです。
覚えるとか慣れるということではなく、出すことと同じ難易度ということになります。
これができると一人前の数学者かもしれません。

&lt;?php

    // MySQLに接続 ------------------

    $sql="SELECT * FROM `tech_posts` WHERE `post_status` = 'publish' ORDER BY `ID` DESC";
    $hack .= '&lt;br&gt;'.$sql.'&lt;br&gt;';
    $rs = mysql_query($sql,$db);
    $i = 0;
    while($item = mysql_fetch_assoc($rs)){
        $hack .= '■'.$item[ID].'■';
        if($i &lt;= 9){
            
            // カテゴリID抽出
            $sql2="SELECT * FROM `tech_term_relationships` WHERE `object_id` = '$item[ID]'"; // post_id がマッチしたら
            $rs2 = mysql_query($sql2,$db);
            
            $item2 = mysql_fetch_assoc($rs2);
            if( ($item2[term_taxonomy_id] &gt;= "2") && ($item2[term_taxonomy_id] &lt;= "8") ){
                
                $sql3="SELECT * FROM `tech_term_relationships` WHERE `object_id` = '$item[ID]'";
                $rs3 = mysql_query($sql3,$db);
                $item3 = mysql_fetch_assoc($rs3);
                
                // カテゴリID整形
                    $idid1 = '00'.$item3[term_taxonomy_id].'-';

ソースコード全文はこちら

新規に作成したページのエラー

下記のようなエラーを吐いて何も表示されない。

Warning: Unknown: SAFE MODE Restriction in effect. The script whose gid is 1000 is not allowed to access /virtual/ドメイン名/public_html/xxxx/user_data/guide.php owned by uid 1000 in Unknown on line 0

Warning: Unknown: SAFE MODE Restriction in effect. The script whose uid is 1000 is not allowed to access /virtual/ドメイン名/public_html/xxxx/user_data/guide.php owned by uid 1000 in Unknown on line 0

Warning: Unknown: failed to open stream: Success in Unknown on line 0

Fatal error: Unknown: Failed opening required '/virtual/ドメイン名/public_html/xxxx/user_data/guide.php' (include_path='.:/usr/local/lib/php') in Unknown on line 0

user_dataのパーミッションは777
user_data内のphpファイルの権利者がapacheになっています。
これを、他のファイルと同じように変更すると回避できる。

「サイトを開く」のリンクを新しいタブで開くようにする。

wp_man20091204a

[File] wp-admin/admin-header.php
[Line] 104

&lt;a href="&lt;?php echo trailingslashit( get_bloginfo('url') ); ?&gt;" target="_blank" title="&lt;?php _e('Visit site') ?&gt;"&gt;&lt;/

なんだこんなこと?と馬鹿にしないでください。
2クリックか?1クリックか?
作業は倍か半分かというとても大きな違いです。
コレラが積み重なると大きなボトルネックなになります。

気がつくたびに、小さなことでもクリアしていかないと、最速の開発はできません。

子カテゴリーを表示する

tpl_subtitleに親カテゴリー+子カテゴリーを表示する

[修正ファイル EC-CUBE2系]

data/class/pages/products/LC_Page_Products_List.php

[修正前]

$arrFirstCat = $objDb->sfGetFirstCat($arrCategory_id[0]);
$tpl_subtitle = $arrFirstCat['name'];

[修正後]

$tpl_subtitle = $objDb->sfGetCatCombName($arrCategory_id[0]);

とすることで、親カテゴリー+子カテゴリーも表示する事が出来ます。

EC-CUBEのデータベースの文字化け

管理画面では化けないが、データベースをのぞくと化けてしまう。
これがEC-CUBEの仕様のようです。

そこで回避策ですが…
サーバー環境により異なりますので、一例としてご覧ください。

  1. 普通にインストール
  2. データベースのテーブルを全て削除
  3. お決まりの「UTF-8化おまじない」を行う
  4. 再度eccubeインストール

たったこれだけで、EC-CUBEが快適に利用できます。

データベースでも化けていないので、
メンテナンスも、サーバー移転も心配がありません。

オープンソースとは、完全でないからオープンソースです。
完璧にするのは利用者自身に委ねられています。

皆さんも挑戦してね!

Excel のセル内改行をなくす

WebプログラマのサイトでExcelが必要か?

Excel でお預かりしたデータの一括コンバートなどのメモです。

「検索する文字列」ボックスでCtrl+Jを入力する。

置換ボタンを押す。

これではNG!

「検索する文字列」ボックスでCtrl+Jを入力する。
(見た目は何も変化しない)

全て検索

検索結果が表示される

全て置換ボタンを押す。

これでOK!

商品をカートに入れる処理

商品を買い物カゴに入れる処理

// 新カートID
$new_no = カート内の番号;// product_id
$_SESSION[cart][$new_no][id][0] = (string)$product_id;

// 規格1
$_SESSION[cart][$new_no][id][1] = (string)$stsize;

// 規格2、指定がない場合は「0」
$_SESSION[cart][$new_no][id][2] = (string)0;

// 数
$_SESSION[cart][$new_no][quantity] = 1;

// カート番号
$_SESSION[cart][$new_no][cart_no] = カート内の番号;

// 価格
$_SESSION[cart][$new_no][price] = $price02;

// ポイントレート
$_SESSION[cart][$new_no][point_rate] = $point_rate;


このようにしてセッションに登録すれば、カートに入ったことになる。
しかし、注視すべき点が一つある。
(string)のようにするのが重要!
配列の型が適切でないと、決済の最後の処理で、「申し訳ございませんが、ご購入の直前で売り切れた商品があります。この手続きは無効となりました」としかられてしまう。

もとファイルを変更するなら
/data/class/SC_CartSession.php

WordPress の バックアップ

WordPress Database Backup というプラグインがある。

ダウンロードサイトは、http://www.ilfilosofo.com/blog/wp-db-backup

これは、とても素晴らしい!

他のプラグインは、あっても困らないが、無くても困らないものばかり。

これは、一度使ったら、手放せない。

30分もあれば作れる簡単なプラグインだが、配布してくれるのがうれしい。

いや、違う、まともなプラグインを作る輩が存在することが嬉しい!

サーバー内にバックアップしたところで、サーバがとまればそれまで、

主導でダウンロードしようものなら、そのうちに飽きてしまう。

しかし、設定しだいでは、毎日、バックアップしメールで送ってくれるしカラクリのようだ。

望むならば、1時間毎にも設定できる。

まあ、普通は1週間が妥当かもしれない。

自分の場合は、1日一回にした。

2日分もデータが飛んだら、大きな損失になる。

1時間に一回は多いような気がするので、

昼間、仕事をしている時間帯、つまりデータが次々と更新される時間帯に限り、

2時間に一回、バックアップをメールで送信にカスタマイズしようとも考えている。

…目視確認、DBに再インポートできるか確認、というのも、わずらわしいので、

受信して、DB検証をしてくれる、サーバーでも作ろうか。。。?

「最新の投稿」のMAXを変える

wp-includes/default-widgets.php
542行目付近

if ( !$number = (int) $instance['number'] )
$number = 10;
else if ( $number &lt; 1 )
$number = 1;
else if ( $number &gt; <strong>15</strong> )
$number = <strong>15</strong>;

同ファイル内に15という数値が沢山あるので、一括置換してしまおう!
バージョンによっては、1っ箇所の場合もある、その辺は、自分でソースコードをきちんと読んでから変更してください。
※ ソースコードを理解しないまま、見たり聞いたりした情報だけで作業を行うことは、とても危険です。

joomla!その2

インストールでphpの設定が違うと怒る

.htaccrss で設定すれば良いのは分かるが、

こう少し、サーバー側の設定に依存しない書き方をしなければ、オープンソースとしては、生き残れないだろう。

joomla!はユーザ登録できない仕様です。

Joomla! 1.0.15JP Stable での不具合

管理画面からのユーザー登録はOK

フロント画面からのユーザー登録は登録ボタンを押しても何も変化がない。

エラーにもならない。

ページも変わらない。

登録そのものが行われない。

こんなオープンソースなぜ配布しているのか?

/components/com_registration/registration.html.php の64行目を修正する。

このようにかかれていますが、明らかな構文違いです。

} else if (r.exec(form.username.value) || form.username.value.length &lt; 3) || mb.exec(form.username.value)) {

カッコだけにしてみると

} else if ( () || <span style="color: #ff0000;">)</span> || ()) {

明らかに閉じカッコが多い

下記のように修正すれば動きます。

} else if (r.exec(form.username.value) || form.username.value.length &lt; 3 || mb.exec(form.username.value)) {

Joomla!って結構面白そうだし、見た目はとてもよくできている。

しかし、このような致命的なバグを放置したりするから、人気が出ないのかもしれない。

少々直して動いたが、それ以上使う気にはなれない。

少なくなった在庫をメールで知らせてくれる機能

/html/shopping/complete.php (/data/class/pages/shopping/LC_Page_Shopping_Complete.php)

// 在庫を減らす処理
function lfReduceStock($objQuery, $arrID, $quantity) {
    $where = "product_id = ? AND classcategory_id1 = ? AND classcategory_id2 = ?";
    $arrRet = $objQuery->select("stock, stock_unlimited", "dtb_products_class", $where, $arrID);
    
    // 売り切れエラー
    if(($arrRet[0]['stock_unlimited'] != '1' && $arrRet[0]['stock'] < $quantity) || $quantity == 0) {
        $objQuery->rollback();
        sfDispSiteError(SOLD_OUT, "", true);
    // 無制限の場合、在庫はNULL
    } elseif($arrRet[0]['stock_unlimited'] == '1') {
        $sqlval['stock'] = null;
        $objQuery->update("dtb_products_class", $sqlval, $where, $arrID);
    // 在庫を減らす
    } else {
        $sqlval['stock'] = ($arrRet[0]['stock'] - $quantity);
        if($sqlval['stock'] == "") {
            $sqlval['stock'] = '0';
        }        
        $objQuery->update("dtb_products_class", $sqlval, $where, $arrID);
    }
    
<div style="color:tomato;">
// 在庫数が0の場合はNULL
    if( ($sqlval['stock'] <= 5) && ($arrRet&#91;0&#93;&#91;'stock_unlimited'&#93; != '1') ){
        // メール送信先
        $stock_mail = "zaiko@domain.com";
        // 件名
        $stock_sub = "商品在庫が少なくなりました。";
        // メッセージ
        $stock_msg = "商品ID:".$arrID&#91;0&#93;."(".$arrID&#91;1&#93;.",".$arrID&#91;2&#93;.")"."の商品が少なくなりました。";
        // メールを送信します。
        mb_send_mail($stock_mail, $stock_sub, $stock_msg);
    }
</div>
}

複数ファイルを圧縮してダウンロード

phpMyAdmin のライブラリを使用して、複数ファイルを圧縮できるようにします。
「zip.lib.php」を使用します。

&lt;?php

header( "Content-Type: application/octet-stream" );
header( "Content-disposition: attachment; filename=comp.zip" );

require_once('zip.lib.php');

// クラス作成
$zipfile = new zipfile();

// ファイルリストを読み込む
$line = file('tmp/lists.data');
$file_name = explode(',', $line[0]);

$i = 0;
while($file_name[$i] != ""){
    
    // ダウンロード元ファイルのPath
    $filename = $file_name[$i];
    
    // 保存時のファイル名
    ${'fName'.$i} = $filename;
    
    // ファイルをバイナリで読んで、変数にセット
    $handle = fopen($filename, "rb");
    $contents = fread($handle, filesize($filename));
    fclose($handle);

    // 追加
    $zipfile-&gt;addFile($contents, ${'fName'.$i});
    
    $i ++;
}

// zip をバイナリで変数にセット
$zip_buffer = $zipfile-&gt;file();

print $zip_buffer;

?&gt;

phpでPDFを生成

FPDF 1.52 リファレンス マニュアル
http://www.ryuzee.com/manual/fpdf152ja/

FPDF日本語版 fpdf_ja

&lt;?php
require('mbfpdf.php');// 用紙サイズは、「縦・横」の配列で指定する
$size = array(182, 257);$pdf=new MBFPDF('P', 'mm', $size);
// $pdf = new MBFPDF('P', 'mm'. 'A4');

$pdf-&gt;AddMBFont(GOTHIC, 'EUC-JP');
$pdf-&gt;Open();
$pdf-&gt;AddPage();
$pdf-&gt;SetFont(GOTHIC, '', 8);
// $pdf-&gt;Cell(80, 16, "罫線付き背景色付き(中央寄せ)", 1, 1, "L", 0);
// $pdf-&gt;Cell(80, 16, "罫線付き背景色付き(中央寄せ)", 1, 1, "L", 0);
$pdf-&gt;Cell(80, 6, "伝票番号:000000", 0, 0, "L", 0);
$pdf-&gt;Cell(80, 6, "発行日 YYYY年 MM月 DD日", 0, 1, "R", 0);

$pdf-&gt;SetFont(GOTHIC, '', 13);
$pdf-&gt;Cell(160, 16, "納品書兼販売証明書", 1, 1, "C", 0);

// space
$pdf-&gt;Cell(80, 20, " ", 0, 1, "L", 0);

$pdf-&gt;SetFont(GOTHIC, '', 10);
$pdf-&gt;Cell(80, 8, "エンドユーザー様 ", 0, 0, "L", 0);
$pdf-&gt;Cell(80, 8, "会員様会社名 店舗名", 0, 1, "L", 0);

$pdf-&gt;SetFont(GOTHIC, '', 8);
$pdf-&gt;Cell(80, 6, "〒000-0000 ", 0, 0, "L", 0);
$pdf-&gt;Cell(80, 6, "〒111-1111", 0, 1, "L", 0);

$pdf-&gt;Cell(80, 6, "○○県△△市☆町7-77", 0, 0, "L", 0);
$pdf-&gt;Cell(80, 6, "茨城県つくば市千現1-14", 0, 1, "L", 0);

$pdf-&gt;Cell(80, 6, "○○ビル2F", 0, 0, "L", 0);
$pdf-&gt;Cell(80, 6, "△△マンション707", 0, 1, "L", 0);

$pdf-&gt;Cell(80, 6, "TEL:000-0000-0000", 0, 0, "L", 0);
$pdf-&gt;Cell(80, 6, "TEL:111-1111-1111", 0, 1, "L", 0);

// space
$pdf-&gt;Cell(80, 20, " ", 0, 1, "L", 0);

$pdf-&gt;Cell(160, 10, "この度はお買い上げ頂まして誠にありがとうございます。", 0, 1, "L", 0);

$pdf-&gt;Cell(160, 10, "ご注文番号:1234567", 0, 1, "L", 0);

$pdf-&gt;SetFillColor(200, 200, 200); //背景色
$pdf-&gt;Cell(40, 6, "品番", 1, 0, "C", 1);
$pdf-&gt;Cell(100, 6, "商品名", 1, 0, "C", 1);
$pdf-&gt;Cell(20, 6, "数量", 1, 1, "C", 1);

$pdf-&gt;Cell(40, 6, "N000111", 1, 0, "C", 0);
$pdf-&gt;Cell(100, 6, "商品名商品名商品名", 1, 0, "C", 0);
$pdf-&gt;Cell(20, 6, "1", 1, 1, "C", 0);

$pdf-&gt;Cell(160, 40, "修理等のご依頼の際には、この販売証明書が必要となりますので大切に保管してください。", 0, 1, "L", 0);

$pdf-&gt;Output();

?&gt;

このようなファイルを作ればOKだが、このファイルのエンコードはEUCにしないと文字化けになる。
shisで化けないのが正解のような気がするが、そのうちに究明しよう!

EC-CUBEのログインチェック(裏技)

カスタマイズによる追加管理画面を別窓で開く場合、SESSIONを引っ張ってきてログインチェックをするのが正しい方法だが、
これでもいいじゃないか?
『「/admin/」からのリンクアクセスのみ許可する』方法でも、セキュリティ的には、変わらない。
しかもソースコードは短くなるので、重宝しています。

 //------------------------------------------------------
// LOGIN_CHECK
    if (preg_match("/admin/", $_SERVER[HTTP_REFERER])){
        
    }else{
        echo "&lt;html&gt;&lt;head&gt;&lt;/head&gt;&lt;meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /&gt;&lt;body&gt;&lt;div style=\"color:red;\"&gt;\n不正なアクセスです。&lt;/div&gt;&lt;/body&gt;&lt;/html&gt;\n";
        exit();
    }
 // EOF &gt;&gt; LOGIN_CHECK
//------------------------------------------------------

フィールド名とフォーム名の自動化

フィールド名を勝手に抽出し、
POSTがあれば、POSTを優先
無ければDBを優先
これを勝手に行うソースコード

この記事に出会ったあなたはラッキーです。

// テーブル抽出(1レコードのみ)
$sql = "SELECT * FROM `TABLE_NAME` LIMIT 1";
$statement = $pdo->query($sql);
$item = $statement->fetch(PDO::FETCH_ASSOC);

// Key を配列化
$key_arr = array();
foreach($item as $key => $val){
    // echo $key."=>".$val."&lt;br&gt;"; // 試験表示
    array_push($key_arr, $key);
}

// POST があれば変数に代入、無ければテーブルから変数に代入
$i="0";
while($key_arr[$i]!=""){
    $value=$key_arr[$i];
    
    // POST があれば変数に代入
    if(($_POST[$value]!="") && ($_POST[$value]!="NULL")){
        $$value=$_POST[$value];
    
    // 無ければテーブルから変数に代入
    }else{
        $$value=$item[$value];
    }
    
    $i ++;
}

変数の表示

「POST, GET, SESSION, SERVER」などの変数を表示する。

echo '&lt;pre&gt;&lt;h3&gt;_GET&lt;/h3&gt;';
var_dump($_GET);
echo '&lt;h3&gt;_POST&lt;/h3&gt;';
var_dump($_POST);
echo '&lt;h3&gt;_SESSION&lt;/h3&gt;';
var_dump($_SESSION);
echo '&lt;h3&gt;_SERVER&lt;/h3&gt;';
var_dump($_SERVER);

 
 

書いたり、消したりがめんどうなので、こんな感じです。
EC-CUBEの場合

&lt;!--{php}--&gt;
if($_GET[hack] != ""){
    $_SESSION[hack] = 1;
}
if($_SESSION[hack] == 1){
    echo '&lt;pre style="text-align:left;"&gt;&lt;h3&gt;_GET&lt;/h3&gt;';
    var_dump($_GET);
    echo '&lt;h3&gt;_POST&lt;/h3&gt;';
    var_dump($_POST);
    echo '&lt;h3&gt;_SESSION&lt;/h3&gt;';
    var_dump($_SESSION);
    echo '&lt;h3&gt;_SERVER&lt;/h3&gt;';
    var_dump($_SERVER);
    echo '&lt;/pre&gt;';
}
&lt;!--{/php}--&gt;