end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

jquery & php による jsonp オレオレ template

たまに実装すると、すっかり忘れていることを痛感するので、メモ。

以下では snippet src しか記載していませんが、詳細は察して下さい。

client側 ( jquery / javascript )

FormBase.prototype = {
    api_url: "/cgi-bin3/form.php",
    err_url: "/contact3/common/error.html",
    err_msg_elm: "#callback_error",
    
    // 入力→確認画面遷移に伴う入力確認
    submit_input_to_confirm: function(){
        $(this.err_msg_elm).empty();

        form_data = this.collect_form_datas();
        var this_obj = this;
        
        var request = $.ajax({
            type: 'POST',
            url: this.api_url,
            data: form_data,
            dataType: 'jsonp',
            jsonpCallback: 'callback_input_to_confirm'
        });

        request.done(function(data,text_status){
            return this_obj.callback_input_to_confirm(data);
        });

        request.fail(function(jqXHR, textStatus, errorThrown) {
            window.onbeforeunload = null; //「離れていいですか?」をOFF
            $(window).off('beforeunload');
            window.location.href = this_obj.err_url;
        });
    },
    
    callback_input_to_confirm:function(submit_result){
        // OK→ セッションNoを受領し、確認画面を表示
        if(submit_result["result"]=="OK"){
            this.session_id = submit_result["session_id"];
            return this.init_confirm_page();
        }
        this.session_id = '';

        // NG→ 画面遷移せず、エラー内容を表示
        if("errors" in submit_result ){
            for (var atri_key in submit_result["errors"] ) {
                for (var i=0; i<submit_result["errors"][atri_key].length; i++){
                    var err_msg = submit_result["errors"][atri_key][i];
                    
                    $(this.err_msg_elm).append('<li>'+ err_msg +'</li>');
                }
            }
            $('html').animate( {scrollTop: $('.flow').offset().top - 50} );
        }
    },
}

server側 ( php )

class HelmForm4Client extends HelmForm {
    const JSONP_RES_HEADER = 'Content-Type: text/javascript; charset=utf-8';
    
    function __construct() {
        $this->ini_set();
    }

    function main(){
        $func_name = __CLASS__." ".__FUNCTION__;

        $refferer  = $_SERVER['HTTP_REFERER'];
        $parsed_url = parse_url($refferer);

        $this->write_log("START $func_name from $refferer");

        $assign_form_def = $this->assign_form_def($parsed_url['host'],
                                                  $parsed_url['path']);

        // request元からのaccess可否判定
        if( ! $assign_form_def ){
            $this->write_log("ERROR not assigned foom: $refferer");
            
            http_response_code( 500 );
            header(self::JSONP_RES_HEADER);
            echo "({'result':'NG',sys_msg':'bad request'});";
            return;
        }
        
        $callback_method = $_GET["callback"];

        //入力画面→確認画面 遷移時
        if(strcmp($callback_method,"callback_input_to_confirm")==0){
            return $this->main_input_to_confirm($callback_method,
                                                $assign_form_def);
        }
        //確認画面→完了画面 遷移時
        if(strcmp($callback_method,"callback_confirm_to_complete")==0){
            $result_main = $this->main_confirm_to_complete($callback_method,
                                                           $assign_form_def);
            return $result_main;
        }
        
        http_response_code( 500 );
        $this->write_log("WARN unknown request ". $_SERVER['REQUEST_URI'] );
    }

    
    //入力画面→確認画面 遷移時
    function main_input_to_confirm($callback_method, $assign_form_def){
        $func_name = __CLASS__." ".__FUNCTION__;
        $refferer = $assign_form_def['path'];
    
        // session id設定とsession開始
        session_id(sha1(uniqid(microtime())));
        if( session_start() ){
            $session_id = session_id();
        }

        $this->write_log("START $func_name session:$session_id $refferer");
        
        
        // validation ruleのload
        $validation_def
            = $this->validation_def($assign_form_def['validation_rule']);
        
        // request parameterの取得とvalidation
        $params_defs = $validation_def["definition"];

        // 住所、氏名等のpost reqesut parameterを取得
        $req_params_tmp = $this->load_req_params($params_defs, $_POST);
        $req_params = $req_params_tmp[0];
        $errors     = $req_params_tmp[1];

        // カタログに関する post reqesut parameterを取得
        $catalog = new HelmForm4Catalog();
        $max_catalogs = $assign_form_def["max_catalogs"];
        $req_params_tmp = $catalog->load_req_params($_POST,$max_catalogs);
        $req_params = array_merge($req_params, $req_params_tmp[0]);
        $errors     = array_merge($errors,     $req_params_tmp[1]);

        $_SESSION['req_params'] = $req_params;

        //validationの結果、errorなしなら、session idをclientへ返します
        if( count($errors)==0 ){
            $req_result_json = $this->json_encode(["result"    =>"OK",
                                                   "session_id"=>$session_id]);
            echo $callback_method ."(".$req_result_json .");";
            $this->write_log("DONE $func_name session:$session_id");
            return true;
        }
    
        $this->write_log("WARN fail validation $func_name session:$session_id");

        $tmp_msg = "validation result:". print_r($errors,true);
        // $tmp_msg = str_replace ("\n"," ",$tmp_msg);
        $tmp_msg = preg_replace("/\s+/"," ",$tmp_msg);
        $this->write_log($tmp_msg);

        $req_result_json = $this->json_encode(["result"=>"NG","errors"=>$errors]);
        $callback_method_all = $callback_method ."(".$req_result_json .");";
        header(self::JSONP_RES_HEADER);
        echo $callback_method_all;
    
        // セッション情報破棄
        $_SESSION = [];
        session_destroy();
        return false;
    }

}