Ignore:
Timestamp:
2011/02/23 17:21:50 (13 years ago)
Author:
adachi
Message:

#1031 商品CSVアップロードリファクタリング

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/version-2_5-dev/data/class/pages/admin/products/LC_Page_Admin_Products_UploadCSV.php

    r20345 r20346  
    5858    var $arrFormKeyList; 
    5959 
     60    var $arrRowErr; 
     61 
     62    var $arrRowResult; 
     63     
    6064    /** 
    6165     * Page を初期化する. 
     
    100104    function action() { 
    101105        $this->objDb = new SC_Helper_DB_Ex(); 
    102         $objView = new SC_SiteView_Ex(); 
    103106 
    104107        // ファイル管理クラス 
     
    107110        $this->arrInfo = $this->objDb->sfGetBasisData(); 
    108111        // CSV管理ヘルパー 
    109         $this->objCSV = new SC_Helper_CSV(); 
     112        $this->objCSV = new SC_Helper_CSV_Ex(); 
    110113        // CSV構造読み込み 
    111114        $arrCSVFrame = $this->objCSV->sfGetCsvOutput($this->csv_id); 
     
    114117        if( !$this->objCSV->sfIsImportCSVFrame($arrCSVFrame) ) { 
    115118            // 無効なフォーマットなので初期状態に強制変更 
    116             $arrCSVFram = $this->objCSV->sfGetCsvOutput($this->csv_id, '', array(), $order ='no'); 
     119            $arrCSVFrame = $this->objCSV->sfGetCsvOutput($this->csv_id, '', array(), 'no'); 
    117120            $this->tpl_is_format_default = true; 
    118121        } 
     
    126129        // パラメータ情報の初期化 
    127130        $this->lfInitParam($arrCSVFrame); 
    128         // 現在のフォーマットにおける列数を取得 
    129         $col_count = $this->objFormParam->getCount(); 
     131 
    130132        $this->objFormParam->setHtmlDispNameArray(); 
    131133        $this->arrTitle = $this->objFormParam->getHtmlDispNameArray(); 
     
    133135        switch($this->getMode()) { 
    134136        case 'csv_upload': 
    135             // 登録先テーブル カラム情報の初期化 
    136             $this->lfInitTableInfo(); 
    137             // 登録フォーム カラム情報 
    138             $this->arrFormKeyList = $this->objFormParam->getKeyList(); 
    139  
    140             $err = false; 
    141             // CSVファイルアップロード エラーチェック 
    142             $arrErr['csv_file'] = $this->objUpFile->makeTempFile('csv_file'); 
    143  
    144             if($arrErr['csv_file'] == "") { 
    145                 $arrErr = $this->objUpFile->checkEXISTS(); 
    146             } 
    147  
    148             $objView->assignobj($this); 
    149             $objView->display('admin_popup_header.tpl'); 
    150  
    151             // 実行時間を制限しない 
    152             set_time_limit(0); 
    153  
    154             // 出力をバッファリングしない(==日本語自動変換もしない) 
    155             ob_end_flush(); 
    156  
    157             // IEのために256バイト空文字出力 
    158             echo str_pad('',256); 
    159  
    160             if(empty($arrErr['csv_file'])) { 
    161                 // 一時ファイル名の取得 
    162                 $filepath = $this->objUpFile->getTempFilePath('csv_file'); 
    163                 // エンコード 
    164                 $enc_filepath = SC_Utils_Ex::sfEncodeFile($filepath, 
    165                                                           CHAR_CODE, CSV_TEMP_REALDIR); 
    166                 $fp = fopen($enc_filepath, "r"); 
    167  
    168                 // 無効なファイルポインタが渡された場合はエラー表示 
    169                 if ($fp === false) { 
    170                     SC_Utils_Ex::sfDispError(""); 
    171                 } 
    172  
    173                 // レコード行数を得る 
    174                 $record_count = $this->objCSV->sfGetCSVRecordCount($fp); 
    175                 // ファイルが無効な場合はエラー 
    176                 if($record_count === FALSE) { 
    177                     SC_Utils_Ex::sfDispError(""); 
    178                 } 
    179  
    180                 $line = 0;      // 現在行数 
    181                 $regist = 0;    // 登録数 
    182  
    183                 $objQuery =& SC_Query::getSingletonInstance(); 
    184                 $objQuery->begin(); 
    185  
    186                 echo "■ CSV登録進捗状況 <br/><br/>\n"; 
    187  
    188                 while(!feof($fp) && !$err) { 
    189                     $arrCSV = fgetcsv($fp, CSV_LINE_MAX); 
    190                     // 行カウント 
    191                     $line++; 
    192                     if($line <= 1) { 
    193                         continue; 
    194                     } 
    195                     // 現在行の項目数カウント 
    196                     $line_col_count = count($arrCSV); 
    197                     // 項目数が1以下の場合は無視する 
    198                     if($line_col_count <= 1) { 
    199                         continue; 
    200                     } 
    201  
    202                     // 項目数チェック 
    203                     if($line_col_count != $col_count) { 
    204                         echo "※ 項目数が" . $line_col_count . "個検出されました。項目数は" . $col_count . "個になります。</br>\n"; 
    205                         $err = true; 
    206                     } else { 
    207                         // シーケンス配列を格納する。 
    208                         $this->objFormParam->setParam($arrCSV, true); 
    209                         $arrRet = $this->objFormParam->getHashArray(); 
    210                         $this->objFormParam->setParam($arrRet); 
    211                         // 入力値の変換 
    212                         $this->objFormParam->convParam(); 
    213                         // <br>なしでエラー取得する。 
    214                         $arrCSVErr = $this->lfCheckError(); 
    215                     } 
    216  
    217                     // 入力エラーチェック 
    218                     if(count($arrCSVErr) > 0) { 
    219                         echo "<font color=\"red\">■ $line / $record_count 行目でエラーが発生しました。</font></br>\n"; 
    220                         foreach($arrCSVErr as $val) { 
    221                             $this->printError($val); 
    222                         } 
    223                         $err = true; 
    224                     } 
    225  
    226                     if(!$err) { 
    227                         $this->lfRegistProduct($objQuery, $line); 
    228                         $regist++; 
    229                     } 
    230                     $arrParam = $this->objFormParam->getHashArray(); 
    231  
    232                     if(!$err) echo $line. "行目 (商品ID:".$arrParam['product_id']." / 商品名:".$arrParam['name'].")\n<br />"; 
    233                     flush(); 
    234                 } 
    235                 fclose($fp); 
    236  
    237                 if(!$err) { 
    238                     $objQuery->commit(); 
    239                     echo "■" . $regist . "件のレコードを登録しました。"; 
    240                     // 商品件数カウント関数の実行 
    241                     $this->objDb->sfCountCategory($objQuery); 
    242                     $this->objDb->sfCountMaker($objQuery); 
    243                 } else { 
    244                     $objQuery->rollback(); 
    245                 } 
    246             } else { 
    247                 foreach($arrErr as $val) { 
    248                     $this->printError($val); 
    249                 } 
    250             } 
    251             echo "<br/><a href=\"javascript:window.close()\">→閉じる</a>"; 
    252             flush(); 
    253  
    254             $this->setTemplate('admin_popup_footer.tpl'); 
    255  
    256             return; 
     137            $this->doUploadCsv(); 
    257138            break; 
    258139        default: 
     
    262143 
    263144    /** 
     145     * 登録/編集結果のメッセージをプロパティへ追加する 
     146     * 
     147     * @param integer $line_count 行数 
     148     * @param stirng $message メッセージ 
     149     * @return void 
     150     */ 
     151    function addRowResult($line_count, $message) { 
     152        $this->arrRowResult[] = $line_count . "行目:" . $message; 
     153    } 
     154 
     155    /** 
     156     * 登録/編集結果のエラーメッセージをプロパティへ追加する 
     157     * 
     158     * @param integer $line_count 行数 
     159     * @param stirng $message メッセージ 
     160     * @return void 
     161     */ 
     162    function addRowErr($line_count, $message) { 
     163        $this->arrRowErr[] = $line_count . "行目:" . $message; 
     164    } 
     165 
     166    /** 
     167     * CSVアップロードを実行します. 
     168     *  
     169     * @return void 
     170     */ 
     171    function doUploadCsv() { 
     172        // ファイルアップロードのチェック 
     173        $this->objUpFile->makeTempFile('csv_file'); 
     174        $arrErr = $this->objUpFile->checkExists(); 
     175        if (count($arrErr) > 0) { 
     176            $this->arrErr = $arrErr; 
     177            return; 
     178        } 
     179        // 一時ファイル名の取得 
     180        $filepath = $this->objUpFile->getTempFilePath('csv_file'); 
     181        // CSVファイルの文字コード変換 
     182        $enc_filepath = SC_Utils_Ex::sfEncodeFile($filepath, CHAR_CODE, CSV_TEMP_REALDIR); 
     183        // CSVファイルのオープン 
     184        $fp = fopen($enc_filepath, "r"); 
     185        // 失敗した場合はエラー表示 
     186        if (!$fp) { 
     187             SC_Utils_Ex::sfDispError(""); 
     188        } 
     189         
     190        // 登録先テーブル カラム情報の初期化 
     191        $this->lfInitTableInfo(); 
     192         
     193        // 登録フォーム カラム情報 
     194        $this->arrFormKeyList = $this->objFormParam->getKeyList(); 
     195 
     196        $err = false; 
     197 
     198        // レコード行数を得る 
     199        $record_count = $this->objCSV->sfGetCSVRecordCount($fp); 
     200        // ファイルが無効な場合はエラー 
     201        if($record_count === FALSE) { 
     202            SC_Utils_Ex::sfDispError(""); 
     203        } 
     204 
     205        // 登録対象の列数 
     206        $col_max_count = $this->objFormParam->getCount(); 
     207        // 行数 
     208        $line_count = 0; 
     209 
     210        $objQuery =& SC_Query::getSingletonInstance(); 
     211        $objQuery->begin(); 
     212 
     213        $errFlag = false; 
     214 
     215        while (!feof($fp) && !$err) { 
     216            $arrCSV = fgetcsv($fp, CSV_LINE_MAX); 
     217            // 行カウント 
     218            $line_count++; 
     219            // ヘッダ行はスキップ 
     220            if ($line_count == 1) { 
     221                continue; 
     222            } 
     223            // 空行はスキップ 
     224            if (empty($arrCSV)) { 
     225                continue; 
     226            } 
     227            // 列数が異なる場合はエラー 
     228            if ($col_max_count != count($arrCSV)) { 
     229                $errFlag = true; 
     230                break; 
     231            } 
     232            // シーケンス配列を格納する。 
     233            $this->objFormParam->setParam($arrCSV, true); 
     234            $arrRet = $this->objFormParam->getHashArray(); 
     235            $this->objFormParam->setParam($arrRet); 
     236            // 入力値の変換 
     237            $this->objFormParam->convParam(); 
     238            // <br>なしでエラー取得する。 
     239            $arrCSVErr = $this->lfCheckError(); 
     240 
     241            // 入力エラーチェック 
     242            if (count($arrCSVErr) > 0) { 
     243                foreach ($arrCSVErr as $err) { 
     244                    $this->addRowErr($line_count, $err); 
     245                } 
     246                $errFlag = true; 
     247                break; 
     248            } 
     249 
     250            $this->lfRegistProduct($objQuery, $line_count); 
     251            $arrParam = $this->objFormParam->getHashArray(); 
     252 
     253            $this->addRowResult($line_count, "商品ID:".$arrParam['product_id'] . " / 商品名:" . $arrParam['name']); 
     254        } 
     255 
     256        // 実行結果画面を表示 
     257        $this->tpl_mainpage = 'products/upload_csv_complete.tpl'; 
     258 
     259        fclose($fp); 
     260 
     261        if ($errFlag) { 
     262            $objQuery->rollback(); 
     263            return; 
     264        } 
     265 
     266        $objQuery->commit(); 
     267 
     268        // 商品件数カウント関数の実行 
     269        $this->objDb->sfCountCategory($objQuery); 
     270        $this->objDb->sfCountMaker($objQuery); 
     271        return; 
     272    } 
     273     
     274    /** 
    264275     * デストラクタ. 
    265276     * 
     
    276287     */ 
    277288    function lfInitFile() { 
    278         $this->objUpFile->addFile("CSVファイル", 'csv_file', array('csv'), 
    279                                   CSV_SIZE, true, 0, 0, false); 
     289        $this->objUpFile->addFile("CSVファイル", 'csv_file', array('csv'), CSV_SIZE, true, 0, 0, false); 
    280290    } 
    281291 
     
    710720        $time = date("Y-m-d H:i:s"); 
    711721        // 秒以下を生成 
    712         if($line != '') { 
     722        if($line_no != '') { 
    713723            $microtime = sprintf("%06d", $line_no); 
    714724            $time .= ".$microtime"; 
     
    815825        return true; 
    816826    } 
    817  
    818     /** 
    819      * 引数の文字列をエラー出力する. 
    820      * 
    821      * 引数 $val の内容は, htmlspecialchars() によってサニタイズされる 
    822      * 
    823      * @param string $val 出力する文字列 
    824      * @return void 
    825      */ 
    826     function printError($val) { 
    827          echo "<font color=\"red\">" 
    828              . htmlspecialchars($val, ENT_QUOTES) 
    829              . "</font><br />\n"; 
    830     } 
    831827} 
    832 ?> 
Note: See TracChangeset for help on using the changeset viewer.