Google Baseを使ったサンプル(2)

元記事はこちらです。

■Application.cfm

<cfprocessingdirective pageEncoding = "UTF-8">
<cfsetting enableCFoutputOnly="no">

<cfapplication name="#hash( getCurrentTemplatePath() )#"
    sessionmanagement="yes"
    sessiontimeout=#CreateTimeSpan(1, 0, 0, 0)# >

<cfset request.url = thisURL()>
<cfparam name="session.GToken"      default="">
<cfparam name="session.item_type"   default="">

<cfset request.proxyServer  = "">
<cfset request.proxyPort    = "80">
<cfset request.g_key = "xxx">

<cfset request.item=structNew()>
<cfset request.item.recipe  = "レシピ">
<cfset request.item.book    = "書籍">
<cfset request.item.meishi  = "名刺">
<!---==========================================
    thisURL
        実行されたURL。ただしファイル名は削除。
        例)http://hoge.com/
===========================================--->
<cffunction name="thisURL" access="public" returnType="string" output="no">
    <cfset var local = structNew()>

    <cfset local.server_name = cgi.server_name>
    <cfif cgi.server_port neq 80>
        <cfset local.server_name = local.server_name & ":" & cgi.server_port>
    </cfif>

    <cfset local.url = "#lcase(ListFirst(cgi.server_protocol,"/"))#://#local.server_name##cgi.script_name#">
    <cfset local.url = ListDeleteAt(local.url, ListLen(local.url, "/"), "/") & "/">

    <cfreturn local.url>
</cffunction>

■index.cfm

<cfprocessingdirective pageEncoding = "UTF-8">
<cfparam name="url.p"           default="">
<cfparam name="url.token"       default="">
<cfparam name="url.page"        default="1">
<cfparam name="form.item_type"  default="#session.item_type#">

<cfset iObj = "">
<cfif (form.item_type neq "")>
    <cfset iObj = createObject("component", "i_#item_type#").init()>
    <cfset session.item_type = form.item_type>
</cfif>

<!--- session.GToken --->
<cfif (session.GToken eq "")>
    <cfif (url.token neq "")>
        <cfset session.GToken = cst_authSubSessionToken(url.token)>
    </cfif>
</cfif>

<!--- 処理 --->
<cfset content = cst_dspMain()>
<cfswitch expression = "#url.p#">
    <!--- logout --->
    <cfcase value="logout">
        <cfset session.GToken = "">
    </cfcase>

    <!--- 一覧 --->
    <cfcase value="list">
        <cfset data = iObj.getData(url.page,3)>
        <cfset content = content & iObj.dspList(data)>
    </cfcase>

    <!--- add --->
    <cfcase value="add">
        <cfset content = content & iObj.dspAddFm()>
    </cfcase>

    <!--- addEnd --->
    <cfcase value="addEnd">
        <cfset form.id = "http://www.google.com/base/feeds/items/">
        <cfset data = iObj.setXmlForm()>
        <cfset content = content & cst_actionData(form.id, data, "post")>
    </cfcase>

    <!--- upd --->
    <cfcase value="upd">
        <cfset data = iObj.setXmlForm()>
        <cfset content = content & cst_actionData(form.id, data, "put")>
    </cfcase>

    <!--- del --->
    <cfcase value="del">
        <cfset content = content & cst_actionData(form.id, "", "delete")>
    </cfcase>

    <!--- 指定処理以外 --->
    <cfdefaultcase>
    </cfdefaultcase>
</cfswitch>
<cfif (session.GToken eq "")>
    <!--- 初期画面表示 --->
    <cfset content = "Please <a href='https://www.google.com/accounts/AuthSubRequest?next=#request.url#index.cfm&scope=http%3A%2F%2Fwww.google.com%2Fbase%2Ffeeds%2F&session=1&secure=0'>click here</A> to authorize.">
</cfif>
<cfset cst_dspLayout(content)>
<!---===============================
cst_authSubSessionToken
================================--->
<cffunction name="cst_authSubSessionToken" access="public" returnType="string" output="no">
    <cfargument name="token" type="string" required="yes">

    <cfhttp method="get" url="http://www.google.com/accounts/AuthSubSessionToken"
            proxyServer ="#request.proxyServer#"
            proxyPort   ="#request.proxyPort#"
    >
        <cfhttpparam type="header" name="Content-Type" value="application/atom+xml"> 
        <cfhttpparam type="header" name="Authorization" value="AuthSub token=#arguments.token#">
        <cfhttpparam name="X-Google-Key" type="Header" value="key=#request.g_key#">
    </cfhttp>

    <cfreturn ListLast(cfhttp.filecontent, "=")>
</cffunction>
<!---===============================
cst_dspMain
================================--->
<cffunction name="cst_dspMain" access="public" returnType="string" output="no">
    <cfset var local = structNew()>

    <cfsavecontent variable = "local.ret">
    <cfoutput>
    <form name="srch" method="post">
    <select name="item_type">
    <option value=""></option>
    <cfloop item="local.itm" collection="#request.item#">
    <option value="#local.itm#" <cfif (form.item_type eq local.itm)>selected</cfif>>#request.item[local.itm]#</option>
    </cfloop>
    </select>
    <input type="button" value="一覧" onClick="js_list()">
    <input type="button" value="登録" onClick="js_add()">
    <input type="button" value="LOGOUT" onClick="js_logout()">
    </form>
    <script language="JavaScript">
    <!--
    function js_chkSrch(){
        with(document.srch){
            if(item_type.value ==""){
                alert("select item_type");
                return false;
            }
            return true;
        }
    }
    function js_list(){
        if(!js_chkSrch()) return;
        with(document.srch){
            action = "index.cfm?p=list";
            submit();
        }
    }
    function js_add(){
        if(!js_chkSrch()) return;
        with(document.srch){
            action = "index.cfm?p=add";
            submit();
        }
    }
    function js_logout(){
        with(document.srch){
            action = "index.cfm?p=logout";
            submit();
        }
    }
    //-->
    </script>
    </cfoutput>
    </cfsavecontent>

    <cfreturn local.ret>
</cffunction>
<!---===============================
cst_actionData
================================--->
<cffunction name="cst_actionData" access="public" returnType="string" output="no">
    <cfargument name="id"       type="string" required="yes">
    <cfargument name="data"     type="string" required="yes">
    <cfargument name="action"   type="string" required="yes">

    <cfhttp url="#arguments.id#" method="#arguments.action#" redirect="no"
        proxyServer ="#request.proxyServer#"
        proxyPort   ="#request.proxyPort#"
        >
        <cfhttpparam type="header" name="Content-Type" value="application/atom+xml"> 
        <cfhttpparam type="header" name="Authorization" value="AuthSub token=#session.GToken#">
        <cfhttpparam name="X-Google-Key" type="Header" value="key=#request.g_key#">
        <cfhttpparam type="Body" value="#arguments.data#">
    </cfhttp>

    <cfif (left(cfhttp.Responseheader.status_code,2) neq "20")>
        <cfreturn HTMLEditFormat(cfhttp.filecontent)>
    </cfif>

    <cfreturn "">
</cffunction>
<!---===============================
cst_dspLayout
================================--->
<cffunction name="cst_dspLayout" access="public" returnType="void" output="yes">
    <cfargument name="content" type="string" required="yes">

    <cfcontent type="text/html; charset=utf-8">
    <cfoutput>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta http-equiv="content-style-type" content="text/css; charset=utf-8" />
        <title>test</title>
    </head>
    <body>
    #arguments.content#
    </body>
    </html>
    </cfoutput>
</cffunction>

■item.cfc

<cfcomponent>
    <cfset variables.listFld = ""><!--- id,title,item_type以外(継承したcfcでセット) --->
<!---/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/
public
/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=--->
    <!---===============================
    init
    ================================--->
    <cffunction name="init" access="public" returnType="item" output="no">
        <cfreturn this>
    </cffunction>
    <!---===============================
    getData
    ================================--->
    <cffunction name="getData" access="public" returnType="struct" output="no">
        <cfargument name="page"     type="string" required="yes">
        <cfargument name="maxRow"   type="string" default="15">

        <cfset var local    = structNew()>
        <cfset var ret      = structNew()>

        <cfset local.start = 1 + (arguments.page - 1) * arguments.maxRow>

        <!--- Initial query string setup --->
        <cfset local.queryString="http://www.google.com/base/feeds/items?start-index=#local.start#&max-results=#arguments.maxRow#&bq=[itemtype:#urlencodedformat('#request.item[form.item_type]#')#]">

        <cfhttp method="Get" url="#local.queryString#"
            proxyServer ="#request.proxyServer#"
            proxyPort   ="#request.proxyPort#"
        >
            <cfhttpparam type="header" name="Authorization" value="AuthSub token=#session.GToken#">
            <cfhttpparam name="X-Google-Key" type="Header" value="key=#request.g_key#">
        </cfhttp>

        <cfset local.data = xmlparse(cfhttp.filecontent)>

        <cfset ret.totalResults = local.data.feed["openSearch:totalResults"].XmlText>
        <cfset ret.maxPage      = Ceiling(ret.totalResults / arguments.maxRow)>
        <cfif (ret.totalResults neq 0)>
            <cfset local.listFld = "id,title,#variables.listFld#">  <!--- id,titleを追加 --->
            <cfset ret.qry = QueryNew(local.listFld)>

            <cfloop index="local.idx" from="1" to="#arrayLen(local.data.feed.entry)#">
                <cfset local.currentData = local.data.feed.entry[local.idx]>

                <cfset QueryAddRow(ret.qry)>
                <cfloop index="local.idx" list="#local.listFld#">
                    <cfif isDefined("local.currentData.#local.idx#")>
                        <cfset local.tmp = "">
                        <!--- 同じ項目が複数ある場合は、カンマ区切り --->
                        <cfloop index="local.idx2" from="1" to="#arrayLen(local.currentData[local.idx])#">
                            <cfset local.cdata = local.currentData[local.idx][local.idx2]>
                            <cfset local.tmp = ListAppend(local.tmp,local.cdata.XmlText)>
                        </cfloop>
                        <cfset QuerySetCell(ret.qry, "#local.idx#", local.tmp)>
                    </cfif>
                </cfloop>
            </cfloop>
        </cfif>

        <cfreturn ret>
    </cffunction>
    <!---===============================
    setXmlForm
        id,title,item_typeと
        その他text項目だけの分
    ================================--->
    <cffunction name="setXmlForm" access="public" returnType="string" output="no">
        <cfset var local = structNew()>
        <cfset var ret = "">

        <!---xml --->
        <cfxml variable="ret">
        <cfoutput>
        <?xml version='1.0'?>
        <entry  xmlns='http://www.w3.org/2005/Atom'
                xmlns:g='http://base.google.com/ns/1.0'>
        <title type="text">#form.title#</title>
        <g:item_type type="text">#request.item[form.item_type]#</g:item_type>
        <cfloop index="local.idx" list="#variables.listFld#">
            <g:#local.idx# type="text">#form[local.idx]#</g:#local.idx#>
        </cfloop>
        </entry>
        </cfoutput>
        </cfxml>

        <cfreturn toString(ret)>
    </cffunction>
    <!---===============================
    dspList
    ================================--->
    <cffunction name="dspList" access="public" returnType="string" output="no">
        <cfargument name="data" type="struct" required="yes">

        <cfset var local    = structNew()>
        <cfset var qry      = "">
        <cfset var ret      = "">

        <cfset local.listFld = "title,#variables.listFld#"> <!--- titleを追加 --->

        <cfsavecontent variable = "ret">
        <cfoutput>
        <cfif (arguments.data.totalResults eq 0)>
        no data
        <cfelse>
            <cfset qry = arguments.data.qry>

            <table>
                <tr>
                    <cfloop index="local.idx" list="#local.listFld#">
                        <td>#local.idx#</td>
                    </cfloop>
                </tr>

                <cfloop query="qry">
                    <form name="frm_#qry.currentRow#" method="post">
                    <input type="hidden" name="id" value="#qry.id#">
                    <input type="hidden" name="item_type" value="#form.item_type#">

                    <tr>
                        <cfloop index="local.idx" list="#local.listFld#">
                            <cfset local.tmp = "">
                            <cfif isDefined("qry.#local.idx#")>
                                <cfset local.tmp = qry[local.idx]>
                            </cfif>
                            <td><input type="text" name="#local.idx#" value="#local.tmp#"></td>
                        </cfloop>
                        <td><input type="button" value="upd" onClick="js_upd(#qry.currentRow#)"></td>
                        <td><input type="button" value="del" onClick="js_del(#qry.currentRow#)"></td>
                    </tr>
                    </form>
                </cfloop>
            </table>
            <cfif (url.page gt 1)>
                <cfset local.page = url.page - 1>
                <a href="index.cfm?p=list&page=#local.page#">prev</a>&nbsp;
            </cfif>
            <cfif (url.page lt arguments.data.maxPage)>
                <cfset local.page = url.page + 1>
                <a href="index.cfm?p=list&page=#local.page#">next</a>
            </cfif>
        </cfif>

        <script language="JavaScript">
        <!--
        function js_upd(pID){
            with(eval("document.frm_"+pID)){
                action = "index.cfm?p=upd";
                submit();
            }
        }
        function js_del(pID){
            with(eval("document.frm_"+pID)){
                action = "index.cfm?p=del";
                submit();
            }
        }
        //-->
        </script>

        </cfoutput>
        </cfsavecontent>

        <cfreturn ret>
    </cffunction>
    <!---===============================
    dspAddFm
    ================================--->
    <cffunction name="dspAddFm" access="public" returnType="string" output="no">
        <cfset var local = structNew()>
        <cfset var ret = "">

        <cfset local.listFld = "title,#variables.listFld#"> <!--- titleを追加 --->

        <cfsavecontent variable = "ret">
        <cfoutput>
        <form name="frm" action="index.cfm?p=addEnd" method="post">
        <input type="hidden" name="item_type" value="#form.item_type#">
        <table>
            <cfloop index="local.idx" list="#local.listFld#">
                <tr>
                    <td>#local.idx#</td>
                    <td><input type="text" name="#local.idx#"></td>
                </tr>
            </cfloop>
        </table>
        <input type="button" value="add" onClick="js_addEnd()">
        </form>

        <script language="JavaScript">
        <!--
        function js_addEnd(){
            with(document.frm){
                <cfloop index="local.idx" list="#local.listFld#">
                    if(#local.idx#.value==""){
                        alert("please input #local.idx#");
                        return;
                    }
                </cfloop>
                submit();
            }
        }
        //-->
        </script>
        </cfoutput>
        </cfsavecontent>

        <cfreturn ret>
    </cffunction>
<!---/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/
private
/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=--->
</cfcomponent>

■i_book.cfc

<cfcomponent extends="item">
    <cfset variables.listFld = "asin,author,price"><!--- id,title,item_type以外 --->
</cfcomponent>

■i_meishi.cfc

<cfcomponent extends="item">
    <cfset variables.listFld = "sei,sei_yomi,mei,mei_yomi,company,tel,fax"><!--- id,title,item_type以外 --->
</cfcomponent>

■i_recipe.cfc

<cfcomponent extends="item">
    <cfprocessingdirective pageEncoding = "UTF-8">  <!--- ソース内に画面など書く場合、component内ではここで指定(cfcomponentの上ではエラーとなる) --->
    <cfset variables.listFld = "content,cuisine,cooking_time,main_ingredient"><!--- id,title,item_type以外 --->
<!---/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/
public
/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=--->
    <!---===============================
    setXmlForm
    ================================--->
    <cffunction name="setXmlForm" access="public" returnType="string" output="no">
        <cfset var local = structNew()>
        <cfset var ret = "">

        <!---xml --->
        <cfxml variable="ret">
        <cfoutput>
        <?xml version='1.0'?>
        <entry  xmlns='http://www.w3.org/2005/Atom'
                xmlns:g='http://base.google.com/ns/1.0'>
        <title type="text">#form.title#</title>
        <g:item_type type="text">#request.item[form.item_type]#</g:item_type>
        <content type="xhtml">#form.content#</content>
        <g:cuisine type="text">#form.cuisine#</g:cuisine>
        <g:cooking_time type="intUnit">#form.cooking_time#</g:cooking_time>

        <!--- 複数あり --->
        <cfloop index="local.idx" list="#form.main_ingredient#">
            <g:main_ingredient type="text">#local.idx#</g:main_ingredient>
        </cfloop>
        </entry>
        </cfoutput>
        </cfxml>

        <cfreturn toString(ret)>
    </cffunction>

    <!---===============================
    dspAddFm
    ================================--->
    <cffunction name="dspAddFm" access="public" returnType="string" output="no">
        <cfset var local = structNew()>
        <cfset var ret = "">

        <cfset local.listFld = "title,#variables.listFld#"> <!--- titleを追加 --->

        <cfsavecontent variable = "ret">
        <cfoutput>
        <form name="frm" action="index.cfm?p=addEnd" method="post">
        <input type="hidden" name="item_type" value="#form.item_type#">
        <table>
            <tr>
                <td>title</td>
                <td><input type="text" name="title"></td>
                <td>タイトル</td>
            </tr>
            <tr>
                <td>content</td>
                <td valign="top"><textarea cols="30" rows="5" name="content"></textarea></td>
                <td>コンテンツ(htmlタグを使う)</td>
            </tr>
            <tr>
                <td>cuisine</td>
                <td><input type="text" name="cuisine"></td>
            </tr>
            <tr>
                <td>cooking_time</td>
                <td><input type="text" name="cooking_time"></td>
                <td>料理時間(半角数字)</td>
            </tr>
            <tr>
                <td>main_ingredient</td>
                <td><input type="text" name="main_ingredient"></td>
                <td>メインとなる材料(複数の場合半角カンマ区切り)</td>
            </tr>
        </table>
        <input type="button" value="add" onClick="js_addEnd()">
        </form>

        <script language="JavaScript">
        <!--
        function js_addEnd(){
            with(document.frm){
                <cfloop index="local.idx" list="#local.listFld#">
                    if(#local.idx#.value==""){
                        alert("please input #local.idx#");
                        return;
                    }
                </cfloop>
                submit();
            }
        }
        //-->
        </script>
        </cfoutput>
        </cfsavecontent>

        <cfreturn ret>
    </cffunction>
</cfcomponent>