<?php
/**
 * zipcode_batch
 *
 * 郵便番号インポート処理
 *
 * @package   risoluto
 * @author    Risoluto Developers
 * @license   http://opensource.org/licenses/bsd-license.php new BSD license
 * @copyright (C) 2008-2009 Risoluto Developers / All Rights Reserved.
 */

  //------------------------------------------------------//
  // 定数定義
  //------------------------------------------------------//
  define( 'RISOLUTODIR',       dirname( dirname( dirname ( __FILE__ ) ) ) );
  define( 'RISOLUTO_SYSROOT',  RISOLUTODIR . '/risoluto/'                 );
  define( 'RISOLUTO_BATCH',    RISOLUTODIR . '/risoluto/batch/'           );
  define( 'RISOLUTO_CACHE',    RISOLUTODIR . '/risoluto/cache/'           );
  define( 'RISOLUTO_CONF',     RISOLUTODIR . '/risoluto/conf/'            );
  define( 'RISOLUTO_EXTLIB',   RISOLUTODIR . '/risoluto/extlib/'          );
  define( 'RISOLUTO_FUNC',     RISOLUTODIR . '/risoluto/func/'            );
  define( 'RISOLUTO_LOGS',     RISOLUTODIR . '/risoluto/logs/'            );
  define( 'RISOLUTO_SESS',     RISOLUTODIR . '/risoluto/sess/'            );
  define( 'RISOLUTO_UPLOAD',   RISOLUTODIR . '/risoluto/upload/'          );
  define( 'RISOLUTO_USERLAND', RISOLUTODIR . '/risoluto/userland/'        );

  define( 'DB_USER',            '' );
  define( 'DB_PASS',            '' );
  define( 'DB_SERV',            '' );
  define( 'DB_DBNM',            '' );

  define( 'POSI_ZIPCODE',       2   );
  define( 'POSI_PREFNAME',      6   );
  define( 'POSI_CITYNAME',      7   );
  define( 'POSI_CITYNAME_KANA', 4   );
  define( 'POSI_AREANAME',      8   );
  define( 'POSI_AREANAME_KANA', 5   );
  define( 'COLSEP',             "," );

  //------------------------------------------------------//
  // インクルードパスの変更
  //------------------------------------------------------//
  //------------------------------------------------------//
  set_include_path(                 RISOLUTO_EXTLIB . 'PEAR' 
                 . PATH_SEPARATOR . RISOLUTO_EXTLIB . 'Smarty/libs'
                 . PATH_SEPARATOR . get_include_path() );

  //------------------------------------------------------//
  // クラスファイルの読み込み
  //------------------------------------------------------//
  /**
   * コンフィグ操作クラス
   */
  require_once( RISOLUTO_FUNC . 'risoluto_conf.php' );

  /**
   * ログ出力クラス
   */
  require_once( RISOLUTO_FUNC . 'risoluto_log.php' );

  /**
   * セッションクラス
   */
  require_once( RISOLUTO_FUNC . 'risoluto_session.php' );

  /**
   * ユーティリティファンクションクラス
   */
  require_once( RISOLUTO_FUNC . 'risoluto_util.php' );

  class ZipcodeImport
  {
    //------------------------------------------------------//
    // クラス変数定義
    //------------------------------------------------------//
    /**
     * クラスインスタンスを保持する変数
     * @access private
     * @var    object
     */
    private static $obj_instance;
    /**
     * コンフィグクラスインスタンスを保持する変数
     * @access private
     * @var    object
     */
    private $obj_conf;
    /**
     * ログクラスインスタンスを保持する変数
     * @access private
     * @var    object
     */
    private $obj_logs;
    /**
     * セッションクラスインスタンスを保持する変数
     * @access private
     * @var    object
     */
    private $obj_sess;
    /**
     * ユーティリティクラスインスタンスを保持する変数
     * @access private
     * @var    object
     */
    private $obj_util;
    /**
     * データベース操作クラスインスタンスを保持する変数
     * @access private
     * @var    object
     */
    private $obj_db;

    //------------------------------------------------------//
    // クラスメソッド定義
    //------------------------------------------------------//
    /**
     * コンストラクタメソッド
     *
     * コントローラのコンストラクタメソッド
     *
     * @param     void なし
     * @return    void なし
     */
    private function __construct()
    {
    } // end of function:__construct()

    /**
     * クローンメソッド
     *
     * コントローラのクローンメソッド
     *
     * @param     void なし
     * @return    void なし
     */
    public function __clone()
    {
    } // end of function:__clone()

    /**
     * シングルトンメソッド
     *
     * コントローラのインスタンスをシングルトンパターンで生成する
     *
     * @param     void なし
     * @return    object インスタンス
     */
    public static function singleton()
    {
        if ( ! isset( self::$obj_instance ) )
        {
            $tmp_myself = __CLASS__;
            self::$obj_instance = new $tmp_myself;
        } // end of if

        return self::$obj_instance;
    }

    /**
     * run()
     *
     * コントローラメインロジック
     *
     * @param     void なし
     * @return    void なし
     */
    public function run()
    {

      //------------------------------------------------------//
      // 必要なオブジェクトを生成する
      //------------------------------------------------------//
      // コンフィグ
      $this->obj_conf  = new RisolutoConf();
      $this->obj_conf->parse( RISOLUTO_CONF . 'risoluto.ini' );
      // ログ
      $this->obj_logs  = RisolutoLog::singleton();
      // セッション
      $this->obj_sess  = RisolutoSession::singleton();
      // ユーティリティ
      $this->obj_util  = RisolutoUtils::singleton();

      // 現在日時の情報を取得する（加工後CSVファイル用）
      $tmp_currenttime = date( "Y-m-d H:i:s" );



      //------------------------------------------------------//
      // 読み込みファイルをオープンする
      //------------------------------------------------------//
      $tmp_inputcsv = RISOLUTO_BATCH . '/ken_all.csv';
      $tmp_inputhdl = @fopen( $tmp_inputcsv, "rb" );
      if ( ! $tmp_inputhdl )
      {
        // オープン失敗の場合は、ログを出力して終了する
        $this->obj_logs->logging( 'error', "[PHP:zipcode_batch.php]Cannot open for read: $tmp_inputcsv" );
        exit;
      } // end of if



      //------------------------------------------------------//
      // 書き込みファイルをオープンする
      //------------------------------------------------------//
      $tmp_outputcsv = RISOLUTO_BATCH . 'cooked_ken_all.csv';
      $tmp_outputhdl = @fopen( $tmp_outputcsv, "wb" );
      if ( ! $tmp_outputhdl )
      {
        // オープン失敗の場合は、ログを出力して終了する
        $this->obj_logs->logging( 'error', "[PHP:zipcode_batch.php]Cannot open for write: $tmp_inputcsv" );
        exit;
      } // end of if



      //------------------------------------------------------//
      // DBに格納するために、CSVファイルを加工する
      //------------------------------------------------------//
      $tmp_readdat = fgets( $tmp_inputhdl , 600 );
      while( ! feof( $tmp_inputhdl ) )
      {
        //----------ファイルから読み込んだデータの変換を行う
        // 文字コードをSJISからUTF-8に変換する
        $tmp_readdat = mb_convert_encoding( $tmp_readdat, "UTF-8", "SJIS-WIN" );
        // 半角カナを全角カナに変換する
        $tmp_readdat = mb_convert_kana( $tmp_readdat, "KV", "UTF-8" );
        // ダブルクォーテーションを消す
        $tmp_readdat = str_replace( '"' , "" , $tmp_readdat);

        //----------データ作成のためファイルから読み込んだデータを分割する
        $tmp_readdat_split = explode( "," , $tmp_readdat );

        //----------町域名情報を加工する
        // データに'()'が含まれている場合は削除する
        if( strstr( $tmp_readdat_split[ POSI_AREANAME ], "（" ) )
        {
          $tmp_readdat_split[ POSI_AREANAME      ] = substr( $tmp_readdat_split[ POSI_AREANAME      ], 0, strpos( $tmp_readdat_split[ POSI_AREANAME      ], "（" ) );
          $tmp_readdat_split[ POSI_AREANAME_KANA ] = substr( $tmp_readdat_split[ POSI_AREANAME_KANA ], 0, strpos( $tmp_readdat_split[ POSI_AREANAME_KANA ], "("  ) );
        } // end of if
        // 「以下に掲載がない場合」の場合は、町域名情報をなしにする
        if( $tmp_readdat_split[ POSI_AREANAME ] == "以下に掲載がない場合" )
        {
          $tmp_readdat_split[ POSI_AREANAME      ] = "";
          $tmp_readdat_split[ POSI_AREANAME_KANA ] = "";
        } // end of if

        //----------ファイルに書き込むデータを作成する
        $tmp_outcsv  =          $tmp_currenttime;                                        // 作成日時
        $tmp_outcsv .= COLSEP . "zipcode_batch";                                         // 作成PGM
        $tmp_outcsv .= COLSEP . $tmp_currenttime;                                        // 更新日時
        $tmp_outcsv .= COLSEP . "zipcode_batch";                                         // 作成PGM
        $tmp_outcsv .= COLSEP . substr( $tmp_readdat_split[ POSI_ZIPCODE ], 0, 3 );      // 郵便番号1
        $tmp_outcsv .= COLSEP . substr( $tmp_readdat_split[ POSI_ZIPCODE ], 3, 4 );      // 郵便番号2
        $tmp_outcsv .= COLSEP . $this->getPrefCd( $tmp_readdat_split[ POSI_PREFNAME ] ); // 都道府県コード
        $tmp_outcsv .= COLSEP . $tmp_readdat_split[ POSI_PREFNAME      ];                // 都道府県名
        $tmp_outcsv .= COLSEP . $tmp_readdat_split[ POSI_CITYNAME      ];                // 市区町村名
        $tmp_outcsv .= COLSEP . $tmp_readdat_split[ POSI_CITYNAME_KANA ];                // 市区町村名カナ
        $tmp_outcsv .= COLSEP . $tmp_readdat_split[ POSI_AREANAME      ];                // 町域名
        $tmp_outcsv .= COLSEP . $tmp_readdat_split[ POSI_AREANAME_KANA ];                // 町域名カナ
        $tmp_outcsv .= COLSEP . "1";                                                     // 有効・無効フラグ
        $tmp_outcsv .= "\n";                                                             // 改行コード（EOL）

        // ファイルに出力する
        fwrite( $tmp_outputhdl, $tmp_outcsv );

        // ファイルから次の1行を読み込む
        $tmp_readdat = fgets( $tmp_inputhdl , 600 );

      } // end of while



      //------------------------------------------------------//
      // ファイルをクローズする
      //------------------------------------------------------//
      fclose( $tmp_inputhdl  );
      fclose( $tmp_outputhdl );



      //------------------------------------------------------//
      // データベースに加工後のCSVファイルのデータを入れ込む
      //------------------------------------------------------//
      // データベースに接続する
      $dbcon = mysql_connect( DB_SERV, DB_USER, DB_PASS );
      if( ! $dbcon )
      {
        // 接続に失敗した場合はログを出力して処理を終了する
        $this->obj_logs->logging( 'error', "[PHP:zipcode_batch.php]Cannot connect to database" );
        exit;
      }
      else
      {
        // 対象となるDBを選択する
        if ( ! mysql_select_db( DB_DBNM, $dbcon ) )
        {
          // 失敗した場合はログを出力して処理を終了する
          $this->obj_logs->logging( 'error', "[PHP:zipcode_batch.php]Cannot select database" );
          mysql_close( $dbcon );
          exit;
        } // end of if
  
        // オートコミットをOffにし、トランザクションを開始する
        if ( ! mysql_query( 'set autocommit=0', $dbcon ) )
        {
          // 失敗した場合はログを出力して処理を終了する
          $this->obj_logs->logging( 'error', "[PHP:zipcode_batch.php]Cannot set option: autocommit" );
          mysql_close( $dbcon );
          exit;
        } // end of if
  
        if ( ! mysql_query( 'begin', $dbcon ) )
        {
          // 失敗した場合はログを出力して処理を終了する
          $this->obj_logs->logging( 'error', "[PHP:zipcode_batch.php]Cannot start transaction" );
          mysql_close( $dbcon );
          exit;
        } // end of if
  
        // 現時点でテーブル中に格納されたデータをすべて消す
        if ( ! mysql_query( 'TRUNCATE TABLE risoluto_m_zipcode', $dbcon ) )
        {
          // 失敗した場合はログを出力して処理を終了する
          $this->obj_logs->logging( 'error', "[PHP:zipcode_batch.php]Cannot truncate" );
          mysql_query( 'rollback', $dbcon );
          mysql_close( $dbcon );
          exit;
        }
  
        // LOAD DATA INFILEを実行する
        if ( ! mysql_query( "LOAD DATA INFILE '$tmp_outputcsv' IGNORE INTO TABLE risoluto_m_zipcode FIELDS TERMINATED BY ','", $dbcon ) )
        {
          // 失敗した場合はログを出力して処理を終了する
          $this->obj_logs->logging( 'error', "[PHP:zipcode_batch.php]Cannot load data infile" );
          mysql_query( 'rollback', $dbcon );
          mysql_close( $dbcon );
          exit;
        }
  
        // COMMITし、接続を切断する
        mysql_query( 'commit', $dbcon );
        mysql_close( $dbcon           );
      } // end of else

    } // end of function:run()



    /**
     * 都道府県コード変換ファンクション
     *
     * 郵便番号データをＤＢへ取り込む際に
     * 都道府県(和名)を特定のコードに変換する
     *
     * @param    $prefnm 都道府県名(和名)
     * @return   都道府県コード
     */
    private function getPrefCd( $prefnm )
    {
      // 変換テーブル
      $cnvDat = array(
                       "北海道"   => "01000"
                     , "青森県"   => "02000"
                     , "岩手県"   => "03000"
                     , "宮城県"   => "04000"
                     , "秋田県"   => "05000"
                     , "山形県"   => "06000"
                     , "福島県"   => "07000"
                     , "茨城県"   => "08000"
                     , "栃木県"   => "09000"
                     , "群馬県"   => "10000"
                     , "埼玉県"   => "11000"
                     , "千葉県"   => "12000"
                     , "東京都"   => "13000"
                     , "神奈川県" => "14000"
                     , "新潟県"   => "15000"
                     , "富山県"   => "16000"
                     , "石川県"   => "17000"
                     , "福井県"   => "18000"
                     , "山梨県"   => "19000"
                     , "長野県"   => "20000"
                     , "岐阜県"   => "21000"
                     , "静岡県"   => "22000"
                     , "愛知県"   => "23000"
                     , "三重県"   => "24000"
                     , "滋賀県"   => "25000"
                     , "京都府"   => "26000"
                     , "大阪府"   => "27000"
                     , "兵庫県"   => "28000"
                     , "奈良県"   => "29000"
                     , "和歌山県" => "30000"
                     , "鳥取県"   => "31000"
                     , "島根県"   => "32000"
                     , "岡山県"   => "33000"
                     , "広島県"   => "34000"
                     , "山口県"   => "35000"
                     , "徳島県"   => "36000"
                     , "香川県"   => "37000"
                     , "愛媛県"   => "38000"
                     , "高知県"   => "39000"
                     , "福岡県"   => "40000"
                     , "佐賀県"   => "41000"
                     , "長崎県"   => "42000"
                     , "熊本県"   => "43000"
                     , "大分県"   => "44000"
                     , "宮崎県"   => "45000"
                     , "鹿児島県" => "46000"
                     , "沖縄県"   => "47000"
                     );

      return $cnvDat[ str_replace( '"', "", $prefnm ) ];

    } // end of function:getPrefCd

  } // end of class:ZipcodeImport

  //------------------------------------------------------//
  // 実行
  //------------------------------------------------------//
  $tmp_this = ZipcodeImport::singleton();
  $tmp_this->run();

?>
