Index: /branches/version-2_11-dev/html/admin/customer/upload_csv.php
===================================================================
--- /branches/version-2_11-dev/html/admin/customer/upload_csv.php (revision 20866)
+++ /branches/version-2_11-dev/html/admin/customer/upload_csv.php (revision 20866)
@@ -0,0 +1,35 @@
+init();
+$objPage->process();
+?>
Index: /branches/version-2_11-dev/data/class_extends/page_extends/admin/customer/LC_Page_Admin_Customer_UploadCSV_Ex.php
===================================================================
--- /branches/version-2_11-dev/data/class_extends/page_extends/admin/customer/LC_Page_Admin_Customer_UploadCSV_Ex.php (revision 20866)
+++ /branches/version-2_11-dev/data/class_extends/page_extends/admin/customer/LC_Page_Admin_Customer_UploadCSV_Ex.php (revision 20866)
@@ -0,0 +1,68 @@
+
Index: /branches/version-2_11-dev/data/class/pages/admin/customer/LC_Page_Admin_Customer_UploadCSV.php
===================================================================
--- /branches/version-2_11-dev/data/class/pages/admin/customer/LC_Page_Admin_Customer_UploadCSV.php (revision 20866)
+++ /branches/version-2_11-dev/data/class/pages/admin/customer/LC_Page_Admin_Customer_UploadCSV.php (revision 20866)
@@ -0,0 +1,620 @@
+tpl_mainpage = 'customer/upload_csv.tpl';
+ $this->tpl_subnavi = 'customer/subnavi.tpl';
+ $this->tpl_mainno = 'customer';
+ $this->tpl_subno = 'upload_csv';
+ $this->tpl_subtitle = '顧客登録CSV';
+ $this->csv_id = '7';
+
+ //$masterData = new SC_DB_MasterData_Ex();
+ $this->arrInfo = SC_Helper_DB_Ex::sfGetBasisData();
+ $this->arrTagCheckItem = array();
+ }
+
+ /**
+ * Page のプロセス.
+ *
+ * @return void
+ */
+ function process() {
+ $this->action();
+ $this->sendResponse();
+ }
+
+ /**
+ * Page のアクション.
+ *
+ * @return void
+ */
+ function action() {
+ $this->objDb = new SC_Helper_DB_Ex();
+
+ // CSV管理ヘルパー
+ $objCSV = new SC_Helper_CSV_Ex();
+ // CSV構造読み込み
+ $arrCSVFrame = $objCSV->sfGetCsvOutput($this->csv_id);
+
+ // CSV構造がインポート可能かのチェック
+ if(!$objCSV->sfIsImportCSVFrame($arrCSVFrame) ) {
+ // 無効なフォーマットなので初期状態に強制変更
+ $arrCSVFrame = $objCSV->sfGetCsvOutput($this->csv_id, '', array(), 'no');
+ $this->tpl_is_format_default = true;
+ }
+ // CSV構造は更新可能なフォーマットかのフラグ取得
+ $this->tpl_is_update = $objCSV->sfIsUpdateCSVFrame($arrCSVFrame);
+
+ // CSVファイルアップロード情報の初期化
+ $objUpFile = new SC_UploadFile_Ex(IMAGE_TEMP_REALDIR, IMAGE_SAVE_REALDIR);
+ $this->lfInitFile($objUpFile);
+
+ // パラメータ情報の初期化
+ $objFormParam = new SC_FormParam_Ex();
+ $this->lfInitParam($objFormParam, $arrCSVFrame);
+
+ $objFormParam->setHtmlDispNameArray();
+ $this->arrTitle = $objFormParam->getHtmlDispNameArray();
+
+ switch($this->getMode()) {
+ case 'csv_upload':
+ $this->doUploadCsv($objFormParam, $objUpFile);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /**
+ * 登録/編集結果のメッセージをプロパティへ追加する
+ *
+ * @param integer $line_count 行数
+ * @param stirng $message メッセージ
+ * @return void
+ */
+ function addRowResult($line_count, $message) {
+ $this->arrRowResult[] = $line_count . "行目:" . $message;
+ }
+
+ /**
+ * 登録/編集結果のエラーメッセージをプロパティへ追加する
+ *
+ * @param integer $line_count 行数
+ * @param stirng $message メッセージ
+ * @return void
+ */
+ function addRowErr($line_count, $message) {
+ $this->arrRowErr[] = $line_count . "行目:" . $message;
+ }
+
+ /**
+ * CSVアップロードを実行します.
+ *
+ * @return void
+ */
+ function doUploadCsv(&$objFormParam, &$objUpFile) {
+ // ファイルアップロードのチェック
+ $objUpFile->makeTempFile('csv_file');
+ $arrErr = $objUpFile->checkExists();
+ if (count($arrErr) > 0) {
+ $this->arrErr = $arrErr;
+ return;
+ }
+ // 一時ファイル名の取得
+ $filepath = $objUpFile->getTempFilePath('csv_file');
+ // CSVファイルの文字コード変換
+ $enc_filepath = SC_Utils_Ex::sfEncodeFile($filepath, CHAR_CODE, CSV_TEMP_REALDIR);
+ // CSVファイルのオープン
+ $fp = fopen($enc_filepath, 'r');
+ // 失敗した場合はエラー表示
+ if (!$fp) {
+ SC_Utils_Ex::sfDispError("");
+ }
+
+ // 登録先テーブル カラム情報の初期化
+ $this->lfInitTableInfo();
+
+ // 登録フォーム カラム情報
+ $this->arrFormKeyList = $objFormParam->getKeyList();
+
+ // 登録対象の列数
+ $col_max_count = $objFormParam->getCount();
+ // 行数
+ $line_count = 0;
+
+ $objQuery =& SC_Query_Ex::getSingletonInstance();
+ $objQuery->begin();
+
+ $errFlag = false;
+ $all_line_checked = false;
+
+ while (!feof($fp)) {
+ $arrCSV = fgetcsv($fp, CSV_LINE_MAX);
+
+ // 全行入力チェック後に、ファイルポインターを先頭に戻す
+ if (feof($fp) && !$all_line_checked) {
+ rewind($fp);
+ $line_count = 0;
+ $all_line_checked = true;
+ continue;
+ }
+
+ // 行カウント
+ $line_count++;
+ // ヘッダ行はスキップ
+ if ($line_count == 1) {
+ continue;
+ }
+ // 空行はスキップ
+ if (empty($arrCSV)) {
+ continue;
+ }
+ // 列数が異なる場合はエラー
+ $col_count = count($arrCSV);
+ if ($col_max_count != $col_count) {
+ $this->addRowErr($line_count, "※ 項目数が" . $col_count . "個検出されました。項目数は" . $col_max_count . "個になります。");
+ $errFlag = true;
+ break;
+ }
+ // シーケンス配列を格納する。
+ $objFormParam->setParam($arrCSV, true);
+ $arrRet = $objFormParam->getHashArray();
+ $objFormParam->setParam($arrRet);
+ // 入力値の変換
+ $objFormParam->convParam();
+ //
なしでエラー取得する。
+ $arrCSVErr = $this->lfCheckError($objFormParam);
+
+ // 入力エラーチェック
+ if (count($arrCSVErr) > 0) {
+ foreach ($arrCSVErr as $err) {
+ $this->addRowErr($line_count, $err);
+ }
+ $errFlag = true;
+ break;
+ }
+
+ if ($all_line_checked) {
+ $this->lfRegistCustomer($objQuery, $line_count, $objFormParam);
+ $arrParam = $objFormParam->getHashArray();
+
+ $this->addRowResult($line_count, "顧客ID:".$arrParam['customer_id'] . " / 顧客名:" . $arrParam['name01'] . " ". $arrParam['name02']);
+ }
+ }
+
+ // 実行結果画面を表示
+ $this->tpl_mainpage = 'customer/upload_csv_complete.tpl';
+
+ fclose($fp);
+
+ if ($errFlag) {
+ $objQuery->rollback();
+ return;
+ }
+
+ $objQuery->commit();
+
+ // 商品件数カウント関数の実行
+ $this->objDb->sfCountCategory($objQuery);
+ $this->objDb->sfCountMaker($objQuery);
+ return;
+ }
+
+ /**
+ * デストラクタ.
+ *
+ * @return void
+ */
+ function destroy() {
+ parent::destroy();
+ }
+
+ /**
+ * ファイル情報の初期化を行う.
+ *
+ * @return void
+ */
+ function lfInitFile(&$objUpFile) {
+ $objUpFile->addFile("CSVファイル", 'csv_file', array('csv'), CSV_SIZE, true, 0, 0, false);
+ }
+
+ /**
+ * 入力情報の初期化を行う.
+ *
+ * @param array CSV構造設定配列
+ * @return void
+ */
+ function lfInitParam(&$objFormParam, &$arrCSVFrame) {
+ // 固有の初期値調整
+ $arrCSVFrame = $this->lfSetParamDefaultValue($arrCSVFrame);
+ // CSV項目毎の処理
+ foreach($arrCSVFrame as $item) {
+ if($item['status'] == CSV_COLUMN_STATUS_FLG_DISABLE) continue;
+ //サブクエリ構造の場合は AS名 を使用
+ if(preg_match_all('/\(.+\)[ ]*as[ ]*(.+)$/i', $item['col'], $match, PREG_SET_ORDER)) {
+ $col = $match[0][1];
+ }else{
+ $col = $item['col'];
+ }
+ // HTML_TAG_CHECKは別途実行なので除去し、別保存しておく
+ if(strpos(strtoupper($item['error_check_types']), 'HTML_TAG_CHECK') !== FALSE) {
+ $this->arrTagCheckItem[] = $item;
+ $error_check_types = str_replace('HTML_TAG_CHECK', '', $item['error_check_types']);
+ }else{
+ $error_check_types = $item['error_check_types'];
+ }
+ $arrErrorCheckTypes = explode(',', $error_check_types);
+ foreach($arrErrorCheckTypes as $key => $val) {
+ if(trim($val) == "") {
+ unset($arrErrorCheckTypes[$key]);
+ }else{
+ $arrErrorCheckTypes[$key] = trim($val);
+ }
+ }
+ // パラメーター登録
+ $objFormParam->addParam(
+ $item['disp_name']
+ , $col
+ , constant($item['size_const_type'])
+ , $item['mb_convert_kana_option']
+ , $arrErrorCheckTypes
+ , $item['default']
+ , ($item['rw_flg'] != CSV_COLUMN_RW_FLG_READ_ONLY) ? true : false
+ );
+ }
+ }
+
+ /**
+ * 入力チェックを行う.
+ *
+ * @return void
+ */
+ function lfCheckError(&$objFormParam) {
+ // 入力データを渡す。
+ $arrRet = $objFormParam->getHashArray();
+ $objErr = new SC_CheckError_Ex($arrRet);
+ $objErr->arrErr = $objFormParam->checkError(false);
+ // HTMLタグチェックの実行
+ foreach($this->arrTagCheckItem as $item) {
+ $objErr->doFunc(array( $item['disp_name'], $item['col'], $this->arrAllowedTag), array("HTML_TAG_CHECK"));
+ }
+ // このフォーム特有の複雑系のエラーチェックを行う
+ if(count($objErr->arrErr) == 0) {
+ $objErr->arrErr = $this->lfCheckErrorDetail($arrRet, $objErr->arrErr);
+ }
+ return $objErr->arrErr;
+ }
+
+ /**
+ * 保存先テーブル情報の初期化を行う.
+ *
+ * @return void
+ */
+ function lfInitTableInfo() {
+ $objQuery =& SC_Query_Ex::getSingletonInstance();
+ $this->arrCustomerColumn = $objQuery->listTableFields('dtb_customer');
+ }
+
+ /**
+ * 顧客登録を行う.
+ *
+ *
+ * @param SC_Query $objQuery SC_Queryインスタンス
+ * @param string|integer $line 処理中の行数
+ * @return void
+ */
+ function lfRegistCustomer($objQuery, $line = "", &$objFormParam) {
+ $objCustomer = new SC_Customer_Ex();
+ // 登録データ対象取得
+ $arrList = $objFormParam->getHashArray();
+ // 登録時間を生成(DBのnow()だとcommitした際、すべて同一の時間になってしまう)
+ $arrList['update_date'] = $this->lfGetDbFormatTimeWithLine($line);
+
+ // 顧客登録情報を生成する。
+ // 商品テーブルのカラムに存在しているもののうち、Form投入設定されていないデータは上書きしない。
+ $sqlval = SC_Utils_Ex::sfArrayIntersectKeys($arrList, $this->arrCustomerColumn);
+
+ // 必須入力では無い項目だが、空文字では問題のある特殊なカラム値の初期値設定
+ $sqlval = $this->lfSetCustomerDefaultData($sqlval);
+
+ if(is_numeric($sqlval['customer_id'])) {
+ // id指定登録の場合、secret_keyを作成
+ $where = "customer_id = ?";
+ $customer_count = $objQuery->count("dtb_customer", $where, array($sqlval['customer_id']));
+ if($customer_count > 0){
+ $objQuery->update("dtb_customer", $sqlval, $where, array($sqlval['customer_id']));
+ }else{
+ // secret_keyを作成
+ $sqlval["secret_key"] = SC_Helper_Customer_Ex::sfGetUniqSecretKey();
+ $sqlval['create_date'] = $arrList['update_date'];
+ // INSERTの実行
+ $objQuery->insert("dtb_customer", $sqlval);
+ // シーケンスの調整
+ $seq_count = $objQuery->currVal('dtb_customer_customer_id');
+ if($seq_count < $sqlval['customer_id']){
+ $objQuery->setVal('dtb_customer_customer_id', $sqlval['customer_id'] + 1);
+ }
+ }
+ }else{
+ // 新規登録
+ $sqlval['customer_id'] = $objQuery->nextVal('dtb_customer_customer_id');
+ $product_id = $sqlval['customer_id'];
+ $sqlval['create_date'] = $arrList['update_date'];
+ $objQuery->insert("dtb_customer", $sqlval);
+ }
+ }
+
+ /**
+ * 初期値の設定
+ *
+ * @param array $arrCSVFrame CSV構造配列
+ * @return array $arrCSVFrame CSV構造配列
+ */
+ function lfSetParamDefaultValue(&$arrCSVFrame) {
+ foreach($arrCSVFrame as $key => $val) {
+ switch($val['col']) {
+ case 'status':
+ $arrCSVFrame[$key]['default'] = '2';
+ break;
+ case 'del_flg':
+ $arrCSVFrame[$key]['default'] = '0';
+ break;
+ case 'version_flg':
+ $arrCSVFrame[$key]['default'] = '0';
+ break;
+ default:
+ break;
+ }
+ }
+ return $arrCSVFrame;
+ }
+
+ /**
+ * 商品データ登録前に特殊な値の持ち方をする部分のデータ部分の初期値補正を行う
+ *
+ * @param array $sqlval 商品登録情報配列
+ * @return $sqlval 登録情報配列
+ */
+ function lfSetCustomerDefaultData(&$sqlval) {
+ //新規登録時且つデータ移行でない場合のみ設定する項目
+ if( $sqlval['customer_id'] == "" && $sqlval['version_flg'] != "1") {
+ if($sqlval['status'] == "") {
+ // 基本本登録にしておく
+ $sqlval['status'] = "2";
+ }
+ }
+/*else{
+ //移行でない場合はversion_flgをunset
+ unset($sqlval['version_flg'];
+ }*/
+ //共通で空欄時に上書きする項目
+ if($sqlval['del_flg'] == ""){
+ $sqlval['del_flg'] = '0'; //有効
+ }
+ return $sqlval;
+ }
+
+ /**
+ * 商品規格データ登録前に特殊な値の持ち方をする部分のデータ部分の初期値補正を行う
+ *
+ * @param array $sqlval 商品登録情報配列
+ * @return $sqlval 登録情報配列
+ */
+ function lfSetProductClassDefaultData(&$sqlval) {
+ //新規登録時のみ設定する項目
+ if($sqlval['product_class_id'] == "") {
+ if($sqlval['point_rate'] == "") {
+ $sqlval['point_rate'] = $this->arrInfo['point_rate'];
+ }
+ if($sqlval['product_type_id'] == "") {
+ $sqlval['product_type_id'] = DEFAULT_PRODUCT_DOWN;
+ }
+ // TODO: 在庫数、無制限フラグの扱いについて仕様がぶれているので要調整
+ if($sqlval['stock'] == "" and $sqlval['stock_unlimited'] != UNLIMITED_FLG_UNLIMITED) {
+ //在庫数設定がされておらず、かつ無制限フラグが設定されていない場合、強制無制限
+ $sqlval['stock_unlimited'] = UNLIMITED_FLG_UNLIMITED;
+ }elseif($sqlval['stock'] != "" and $sqlval['stock_unlimited'] != UNLIMITED_FLG_UNLIMITED) {
+ //在庫数設定時は在庫無制限フラグをクリア
+ $sqlval['stock_unlimited'] = UNLIMITED_FLG_LIMITED;
+ }elseif($sqlval['stock'] != "" and $sqlval['stock_unlimited'] == UNLIMITED_FLG_UNLIMITED) {
+ //在庫無制限フラグ設定時は在庫数をクリア
+ $sqlval['stock'] = '';
+ }
+ }else{
+ //更新時のみ設定する項目
+ if(array_key_exists('stock_unlimited', $sqlval) and $sqlval['stock_unlimited'] == UNLIMITED_FLG_UNLIMITED) {
+ $sqlval['stock'] = '';
+ }
+ }
+ //共通で設定する項目
+ if($sqlval['del_flg'] == ""){
+ $sqlval['del_flg'] = '0'; //有効
+ }
+ if($sqlval['creator_id'] == "") {
+ $sqlval['creator_id'] = $_SESSION['member_id'];
+ }
+ return $sqlval;
+ }
+
+ /**
+ * このフォーム特有の複雑な入力チェックを行う.
+ *
+ * @param array 確認対象データ
+ * @param array エラー配列
+ * @return array エラー配列
+ */
+ function lfCheckErrorDetail($item, $arrErr) {
+ return $arrErr;
+ }
+
+ // TODO: ここから下のルーチンは汎用ルーチンとして移動が望ましい
+
+ /**
+ * 指定された行番号をmicrotimeに付与してDB保存用の時間を生成する。
+ * トランザクション内のnow()は全てcommit()時の時間に統一されてしまう為。
+ *
+ * @param string $line_no 行番号
+ * @return string $time DB保存用の時間文字列
+ */
+ function lfGetDbFormatTimeWithLine($line_no = '') {
+ $time = date("Y-m-d H:i:s");
+ // 秒以下を生成
+ if($line_no != '') {
+ $microtime = sprintf("%06d", $line_no);
+ $time .= ".$microtime";
+ }
+ return $time;
+ }
+
+ /**
+ * 指定されたキーと複数値の有効性の配列内確認
+ *
+ * @param string $arr チェック対象配列
+ * @param string $keyname フォームキー名
+ * @param array $item 入力データ配列
+ * @param string $delimiter 分割文字
+ * @return boolean true:有効なデータがある false:有効ではない
+ */
+ function lfIsArrayRecordMulti($arr, $keyname, $item, $delimiter = ',') {
+ if(array_search($keyname, $this->arrFormKeyList) === FALSE) {
+ return true;
+ }
+ if($item[$keyname] == "") {
+ return true;
+ }
+ $arrItems = explode($delimiter, $item[$keyname]);
+ //空項目のチェック 1つでも空指定があったら不正とする。
+ if(array_search("", $arrItems) !== FALSE) {
+ return false;
+ }
+ //キー項目への存在チェック
+ foreach($arrItems as $item) {
+ if(!array_key_exists($item, $arr)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * 指定されたキーと複数値の有効性のDB確認
+ *
+ * @param string $table テーブル名
+ * @param string $tblkey テーブルキー名
+ * @param string $keyname フォームキー名
+ * @param array $item 入力データ配列
+ * @param string $delimiter 分割文字
+ * @return boolean true:有効なデータがある false:有効ではない
+ */
+ function lfIsDbRecordMulti($table, $tblkey, $keyname, $item, $delimiter = ',') {
+ if(array_search($keyname, $this->arrFormKeyList) === FALSE) {
+ return true;
+ }
+ if($item[$keyname] == "") {
+ return true;
+ }
+ $arrItems = explode($delimiter, $item[$keyname]);
+ //空項目のチェック 1つでも空指定があったら不正とする。
+ if(array_search("", $arrItems) !== FALSE) {
+ return false;
+ }
+ $count = count($arrItems);
+ $where = $tblkey ." IN (" . implode(",", array_fill(0, $count, "?")) . ")";
+
+ $objQuery =& SC_Query_Ex::getSingletonInstance();
+ $db_count = $objQuery->count($table, $where, $arrItems);
+ if($count != $db_count) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * 指定されたキーと値の有効性のDB確認
+ *
+ * @param string $table テーブル名
+ * @param string $keyname キー名
+ * @param array $item 入力データ配列
+ * @return boolean true:有効なデータがある false:有効ではない
+ */
+ function lfIsDbRecord($table, $keyname, $item) {
+ if(array_search($keyname, $this->arrFormKeyList) !== FALSE //入力対象である
+ and $item[$keyname] != "" // 空ではない
+ and !$this->objDb->sfIsRecord($table, $keyname, (array)$item[$keyname]) //DBに存在するか
+ ) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * 指定されたキーと値の有効性の配列内確認
+ *
+ * @param string $arr チェック対象配列
+ * @param string $keyname キー名
+ * @param array $item 入力データ配列
+ * @return boolean true:有効なデータがある false:有効ではない
+ */
+ function lfIsArrayRecord($arr, $keyname, $item) {
+ if(array_search($keyname, $this->arrFormKeyList) !== FALSE //入力対象である
+ and $item[$keyname] != "" // 空ではない
+ and !array_key_exists($item[$keyname], $arr) //配列に存在するか
+ ) {
+ return false;
+ }
+ return true;
+ }
+}
Index: /branches/version-2_11-dev/data/Smarty/templates/admin/customer/upload_csv.tpl
===================================================================
--- /branches/version-2_11-dev/data/Smarty/templates/admin/customer/upload_csv.tpl (revision 20866)
+++ /branches/version-2_11-dev/data/Smarty/templates/admin/customer/upload_csv.tpl (revision 20866)
@@ -0,0 +1,68 @@
+
+