LC_Page_Admin_Products_Category_Ex.phpを編集する
/data/class_extends/page_extends/admin/products/LC_Page_Admin_Products_Category_Ex.phpを編集します。
最初は基底クラスを継承しているだけのほとんど空のファイルですから、基底クラスの「LC_Page_Admin_Products_Category」より以下のメソッドをコピーしてきてください。
※当たり前のことですが、同名のメソッドは上書きしてくださいね!
- process
- lfInsertCat
- lfUpdateCat
- lfInitParam
あと、アップロードファイルの初期化用メソッドの
- lfInitFile
のみ新しく追加します。
じゃあ、それぞれのメソッドをいじっていきましょう。
変更前・変更後を書いていくのが面倒なので変更後のソースのみ記載していきますね。
変更前・変更後のdiffをとりたい場合はDFなどを使ってチェックしてみてね 😉
function process()
function process() {
$conn = new SC_DBConn();
$objView = new SC_AdminView();
$objSess = new SC_Session();
$objDb = new SC_Helper_DB_Ex();
// 認証可否の判定
SC_Utils_Ex::sfIsSuccess($objSess);
/*
* ファイルアップロード機能追加 fixed 200811101107
* ファイル管理クラス読込
* ファイル情報の初期化
*/
$this->objUpFile = new SC_UploadFile(IMAGE_TEMP_DIR, IMAGE_SAVE_DIR);
$this->lfInitFile();
// Hiddenからのデータを引き継ぐ
$this->objUpFile->setHiddenFileList($_POST);
// パラメータ管理クラス
$this->objFormParam = new SC_FormParam();
// パラメータ情報の初期化
$this->lfInitParam();
// POST値の取得
$this->objFormParam->setParam($_POST);
$this->arrForm = $_POST;
// 通常時は親カテゴリを0に設定する。
$this->arrForm['parent_category_id'] =
isset($_POST['parent_category_id']) ? $_POST['parent_category_id'] : "";
if (!isset($_POST['mode'])) $_POST['mode'] = "";
switch($_POST['mode']) {
case 'edit':
$this->objFormParam->convParam();
$arrRet = $this->objFormParam->getHashArray();
$this->arrErr = $this->lfCheckError($arrRet);
if(count($this->arrErr) == 0) {
if($_POST['category_id'] == "") {
$objQuery = new SC_Query();
$count = $objQuery->count("dtb_category");
if($count < CATEGORY_MAX) {
$this->lfInsertCat($_POST['parent_category_id']);
// 一時ファイルを本番ディレクトリに移動する
$this->objUpFile->moveTempFile();
// 新規登録後データ削除
$this->arrForm['category_name'] = "";
$this->arrForm['category_comment'] = "";
} else {
print("カテゴリの登録最大数を超えました。");
}
} else {
$this->lfUpdateCat($_POST['category_id']);
// 一時ファイルを本番ディレクトリに移動する
$this->objUpFile->moveTempFile();
// 更新したデータを取得
unset($this->arrForm);
$objQuery = new SC_Query();
$where = "category_id = ?";
$col = "category_name, category_image, category_comment, info_flag, level";
$arrRet = $objQuery->select($col, "dtb_category", $where, array($_POST['category_id']));
// 入力項目にカテゴリ名を入力する。
$this->arrForm['category_id'] = $_POST['category_id'];
$this->arrForm['parent_category_id'] = $_POST['parent_category_id'];
$this->arrForm['category_name'] = $arrRet[0]['category_name'];
$this->arrForm['category_image'] = $arrRet[0]['category_image'];
$this->arrForm['category_comment'] = $arrRet[0]['category_comment'];
$this->arrForm['info_flag'] = $arrRet[0]['info_flag'];
$this->arrForm['level'] = $arrRet[0]['level'];
// DBデータから画像ファイル名の読込
if (isset($this->arrForm['category_image'])) {
$this->objUpFile->setDBFileList($this->arrForm);
}
}
} else {
$this->arrForm = array_merge($this->arrForm, $this->objFormParam->getHashArray());
$this->arrForm['category_id'] = $_POST['category_id'];
}
break;
/*
* fixed 200811101606
*/
case 'pre_edit':
// 編集項目のカテゴリ名をDBより取得する。
#$oquery = new SC_Query();
$objQuery = new SC_Query();
$where = "category_id = ?";
#$cat_name = $oquery->get("dtb_category", "category_name", $where, array($_POST['category_id']));
$col = "category_name, category_image, category_comment, info_flag, level";
$arrRet = $objQuery->select($col, "dtb_category", $where, array($_POST['category_id']));
// 入力項目にカテゴリ名を入力する。
#$this->arrForm['category_name'] = $cat_name;
$this->arrForm['category_name'] = $arrRet[0]['category_name'];
$this->arrForm['category_image'] = $arrRet[0]['category_image'];
$this->arrForm['category_comment'] = $arrRet[0]['category_comment'];
$this->arrForm['info_flag'] = $arrRet[0]['info_flag'];
$this->arrForm['level'] = $arrRet[0]['level'];
// DBデータから画像ファイル名の読込
if (isset($this->arrForm['category_image'])) {
$this->objUpFile->setDBFileList($this->arrForm);
}
$this->arrHidden = array_merge((array)$this->arrHidden, (array)$this->objUpFile->getHiddenFileList());
// POSTデータを引き継ぐ
$this->arrForm['category_id'] = $_POST['category_id'];
break;
// 画像のアップロード
case 'upload_image':
// ファイル存在チェック
$this->arrErr = array_merge((array)$this->arrErr, (array)$this->objUpFile->checkEXISTS($_POST['image_key']));
// 画像保存処理
$this->arrErr[$_POST['image_key']] = $this->objUpFile->makeTempFile($_POST['image_key']);
// Form用配列を渡す。 fixed 200811101426
// HIDDEN用に配列を渡す。
$this->arrHidden = array_merge((array)$this->arrHidden, (array)$this->objUpFile->getHiddenFileList());
break;
// 画像の削除
case 'delete_image':
$this->objUpFile->deleteFile($_POST['image_key']);
break;
case 'delete':
$objQuery = new SC_Query();
// 子カテゴリのチェック
$where = "parent_category_id = ? AND del_flg = 0";
$count = $objQuery->count("dtb_category", $where, array($_POST['category_id']));
if($count != 0) {
$this->arrErr['category_name'] = "※ 子カテゴリが存在するため削除できません。<br>";
}
// 登録商品のチェック
$table = "dtb_product_categories AS T1 LEFT JOIN dtb_products AS T2 ON T1.product_id = T2.product_id";
$where = "T1.category_id = ? AND T2.del_flg = 0";
$count = $objQuery->count($table, $where, array($_POST['category_id']));
if($count != 0) {
$this->arrErr['category_name'] = "※ カテゴリ内に商品が存在するため削除できません。<br>";
}
if(!isset($this->arrErr['category_name'])) {
// ランク付きレコードの削除(※処理負荷を考慮してレコードごと削除する。)
$objDb->sfDeleteRankRecord("dtb_category", "category_id", $_POST['category_id'], "", true);
}
break;
case 'up':
$objQuery = new SC_Query();
$objQuery->begin();
$up_id = $this->lfGetUpRankID($objQuery, "dtb_category", "parent_category_id", "category_id", $_POST['category_id']);
if($up_id != "") {
// 上のグループのrankから減算する数
$my_count = $this->lfCountChilds($objQuery, "dtb_category", "parent_category_id", "category_id", $_POST['category_id']);
// 自分のグループのrankに加算する数
$up_count = $this->lfCountChilds($objQuery, "dtb_category", "parent_category_id", "category_id", $up_id);
if($my_count > 0 && $up_count > 0) {
// 自分のグループに加算
$this->lfUpRankChilds($objQuery, "dtb_category", "parent_category_id", "category_id", $_POST['category_id'], $up_count);
// 上のグループから減算
$this->lfDownRankChilds($objQuery, "dtb_category", "parent_category_id", "category_id", $up_id, $my_count);
}
}
$objQuery->commit();
break;
case 'down':
$objQuery = new SC_Query();
$objQuery->begin();
$down_id = $this->lfGetDownRankID($objQuery, "dtb_category", "parent_category_id", "category_id", $_POST['category_id']);
if($down_id != "") {
// 下のグループのrankに加算する数
$my_count = $this->lfCountChilds($objQuery, "dtb_category", "parent_category_id", "category_id", $_POST['category_id']);
// 自分のグループのrankから減算する数
$down_count = $this->lfCountChilds($objQuery, "dtb_category", "parent_category_id", "category_id", $down_id);
if($my_count > 0 && $down_count > 0) {
// 自分のグループから減算
$this->lfUpRankChilds($objQuery, "dtb_category", "parent_category_id", "category_id", $down_id, $my_count);
// 下のグループに加算
$this->lfDownRankChilds($objQuery, "dtb_category", "parent_category_id", "category_id", $_POST['category_id'], $down_count);
}
}
$objQuery->commit();
break;
case 'tree':
unset($this->arrForm);
$this->arrForm['parent_category_id'] = $_POST['parent_category_id'];
break;
case 'csv':
require_once(CLASS_EX_PATH . "helper_extends/SC_Helper_CSV_Ex.php");
$objCSV = new SC_Helper_CSV_Ex();
// オプションの指定
$option = "ORDER BY rank DESC";
// CSV出力タイトル行の作成
$arrOutput = SC_Utils_Ex::sfSwapArray($objCSV->sfgetCsvOutput(5, " WHERE csv_id = 5 AND status = 1"));
if (count($arrOutput) <= 0) break;
$arrOutputCols = $arrOutput['col'];
$arrOutputTitle = $arrOutput['disp_name'];
$head = SC_Utils_Ex::sfGetCSVList($arrOutputTitle);
$where = "del_flg = 0";
$data = $objCSV->lfGetCategoryCSV($where, $option, $arrval, $arrOutputCols);
// CSVを送信する。
SC_Utils_Ex::sfCSVDownload($head.$data, 'category');
exit;
break;
default:
$this->arrForm['parent_category_id'] = 0;
break;
}
$this->arrList = $this->lfGetCat($this->arrForm['parent_category_id']);
$this->arrTree = $objDb->sfGetCatTree($this->arrForm['parent_category_id']);
// Form用配列を渡す。
$this->arrFile = $this->objUpFile->getFormFileList(IMAGE_TEMP_URL, IMAGE_SAVE_URL);
$objView->assignobj($this);
$objView->display(MAIN_FRAME);
}
function lfInitFile()
function lfInitFile() {
$this->objUpFile->addFile("カテゴリ画像", 'category_image', array('jpg', 'gif', 'png'),IMAGE_SIZE, false, 669, 0);
}
}
lfInsertCat($parent_category_id)
function lfInsertCat($parent_category_id) {
$objQuery = new SC_Query();
$objQuery->begin(); // トランザクションの開始
if($parent_category_id == 0) {
// ROOT階層で最大のランクを取得する。
$where = "parent_category_id = ?";
$rank = $objQuery->max("dtb_category", "rank", $where, array($parent_category_id)) + 1;
} else {
// 親のランクを自分のランクとする。
$where = "category_id = ?";
$rank = $objQuery->get("dtb_category", "rank", $where, array($parent_category_id));
// 追加レコードのランク以上のレコードを一つあげる。
$sqlup = "UPDATE dtb_category SET rank = (rank + 1) WHERE rank >= ?";
$objQuery->exec($sqlup, array($rank));
}
$where = "category_id = ?";
// 自分のレベルを取得する(親のレベル + 1)
$level = $objQuery->get("dtb_category", "level", $where, array($parent_category_id)) + 1;
// 入力データを渡す。
$sqlval = $this->objFormParam->getHashArray(); // フォームのパラメータセット
$sqlval['create_date'] = "Now()";
$sqlval['update_date'] = "Now()";
$sqlval['creator_id'] = $_SESSION['member_id'];
/**
* @add 親の設定を引き継ぐ時
* @since version - 2008/11/10
* info_flagが1ならば親カテゴリの情報で上書きする
*/
$arrRet = $this->objUpFile->getDBFileList();
$sqlval = array_merge($sqlval, $arrRet);
$sqlval['parent_category_id'] = $parent_category_id;
$sqlval['rank'] = $rank;
$sqlval['level'] = $level;
// INSERTの実行
$objQuery->insert("dtb_category", $sqlval);
$objQuery->commit(); // トランザクションの終了
}
function lfUpdateCat($category_id)
function lfUpdateCat($category_id) {
$objQuery = new SC_Query();
// 入力データを渡す。
$sqlval = $this->objFormParam->getHashArray();
$sqlval['update_date'] = "Now()";
$arrRet = $this->objUpFile->getDBFileList();
$sqlval = array_merge($sqlval, $arrRet);
$where = "category_id = ?";
$objQuery->update("dtb_category", $sqlval, $where, array($category_id));
}
lfInitParam()
function lfInitParam() {
$this->objFormParam->addParam("カテゴリ名", "category_name", STEXT_LEN, "KVa", array("EXIST_CHECK","SPTAB_CHECK","MAX_LENGTH_CHECK"));
$this->objFormParam->addParam("カテゴリコメント", "category_comment", STEXT_LEN, "a", array("SPTAB_CHECK","MAX_LENGTH_CHECK"));
}
はい、これでとりあえず「LC_Page_Admin_Products_Category_Ex」の編集はおしまい。
解説が無くて申し訳ないところですが他人の汚いソースで得るものもきっとあるでしょう*1 。
さっきも書いたかもしれませんが、恐らく(いや間違いなく)バグもあるでしょう。
また「この方がずっと効率がいいよ」ということもあるでしょう。
もしお気づきの方がいらっしゃいましたらご指摘いただけるとありがたいです 😉
最後に、本来あまりいじりたくなかった「SC_UploadFile」に手を加えます。
次のページへお進みください。
- 反面教師にしてください [↩]
コメント
トラックバックありがとうございます&反映が遅くなってしまって申し訳ないです(まさかトラックバックされているとは夢にも思わず、確認を怠っておりました)
こうやって感化されて広がっていくのって、オープンソースらしくていいなーと感じているところです。僕もまだまだ勉強の途中なので、一緒にEC-CUBEを盛り上げていきましょうね♪
ソースも見やすくていいサイトですね^^
おぉ!先生!
いつも大変お世話になっております。
お褒めいただき大変恐縮です。
思いやりが足りないせいか先生のように見る人に優しい記事は書けずにいるのですが、先生を見習って精進したいと思っております。
これからもご指導のほどよろしくお願いいたします。
私も微力ながらこのBLOGでEC-CUBEを盛り上げる一助となれば幸いです。
わざわざどうもありがとうございました!
こんにちは。とても参考にさせていただいております。
上記のカスタマイズの件ですが、そのままコピーした状態ではファイルのアップロードができないようです。(アップロードボタンしても反応しない)
非常に有用なカスタムだと思いますので、ぜひ実装したいです。
宜しくお願いします。
Side8810さん、こんにちは 🙂
コメントありがとうございます。
アップロードボタンが反応しないとのことですので、おそらくは
<input type="button" name="btn" onclick="selectAll(‘category_id’); fnModeSubmit(‘upload_image’, ‘image_key’, ‘<!–{$key}–>’)" value="アップロード">
ボタンをonclickしたときのfnModeSubmit();呼び出しに失敗しているんじゃないかと思うんですが、すぐには原因の特定が難しいです。
そのうちまとまった時間が取れたらこちらで検証してみたいと思いますので、今しばらくお時間ください。
ちなみに、僕がこの記事を書くのに参考にさせていただいた穂万先生の記事
http://www.eccube-school.jp/products/detail43.html
の方法でもuploadフォルダにアップした画像を表示することが可能です。
もしお急ぎでしたら先生の方法をご利用になることをお薦めします。
この記事の内容を実装するには少なくともPHPの知識がある程度ないと正直難しいと思います。まずは穂万先生に習って、ただコピペするのではなくソースを理解しながら実装して、それから僕の方法にチャレンジしてもらうと理解も進んでいいんじゃないかなと思います。
最後に余計な事とは思いつつ…
僕もつい1,2年前まではPHPの事は何もわからない素人でした。
なので、Webで見つけたコードをそのままコピペしてカスタマイズとかしてましたが、それだと何か想定外のことが起こると対応できないのですよね。
ですので時間がかかってもそこに書かれたコードが何を意味するのか理解する努力をしてみるといいと思います。そうこうするうち今まで読めなかったソースが読めるようになって、楽しくなってくる。そうすると今度は自分で作ってみたくなる。どんどん上達するにつれて、実践でも活用できるようになりSide8810さんのお仕事の役にも立つと。
一朝一夕というわけにはいきませんがぜひ頑張ってみてくださいね。
通りすがりのものです。
数日前に EC-CUBE を使い始めました。
アップロードできない件ですがアップロードボタンにはりついている
JavaScript の selectAll() 関数が未定義のようでした。
(これは product.tpl からコピペ)
あと、アップロード直後にファイル名を入れておく
hidden フィールドも足りないような気がします。
v2.3.3 で確認しました。
単にカテゴリーに画像を貼るだけなのに、こんなに面倒とは。。
このあたり想定できる機能なので標準でいれてほしいですよね。
もしくはもっと簡単に拡張できないと。
HTML タグで貼るのもなぁという気がします。
ymさん、はじめまして 🙂
拙い僕の記事をフォローをしていただきましてありがとうございます!
仰るとおり、このカスタマイズかなり苦労した覚えがありまして、見直すのは難儀だなぁと…なかなか手をつけられずにおりまして…(言い訳)
ご指摘いただき大変助かりました。
EC-CUBEは一筋縄ではいかないですね^^;
特に管理画面は使い勝手にやや難がある上にカスタマイズが大変ということもあって、不便さを解消するためにCakePHPベースで管理機能を作って、そっちでDB操作をするようになりました(笑)
商品の一括変更とか一覧からフラグを切り替えたりとか簡単なものばかりですけど重宝します 🙂
EC-CUBEがCakePHP(他のフレームワークでもいいけど)ベースで作られてたら、もっと盛り上がるし開発も進むような気がするんですけどねぇ…なんて無責任な独り言でした。
さっそく反映していただきましてありがとうございます。
hidden フィールドですがもう一つ必要かもしれません。
$arrHidden にセットされるものです。クラスのほうを
ちゃんと確認してませんので、これで本当に良いのかどうか
わかりませんが、category.tpl の先頭数行は次のようにしました。
(v2.3.3 で確認したので他のバージョンには合わないかもしれません)
———————-8<————————-
// target の子要素を選択状態にする
function selectAll(target) {
$(‘#’ + target).children().attr({selected: true});
}
<form name=”form1″ id=”form1″ method=”post” action=”” enctype=”multipart/form-data”>
<input type=”hidden” name=”parent_category_id” value=”“>
<input type=”hidden” name=”category_id” value=”“>
<input type=”hidden” name=”” value=”“>
———————-8<————————-
あと、v2.3.3 では管理画面のテンプレートだけは常に default のほうが
使われるみたいですね。。これを理解するのにずいぶん時間が掛かってしまいました ^^;)
ymさん、本当にありがとうございます!ミスばかりで大変恐縮です >_< 仰るとおり、foreach で $arrHiddenを回す記述を忘れてました^^; 早速記事に反映させていただきますね 😉 ご迷惑ばかりおかけしますが、これからもご指導のほどよろしくお願いいたします。