diff --git a/js/piwik.js b/js/piwik.js index bed97aa65f8..3422a71afc4 100644 --- a/js/piwik.js +++ b/js/piwik.js @@ -3970,9 +3970,10 @@ if (typeof window.Piwik !== 'object') { lastEcommerceOrderTs, now = new Date(), items = [], - sku; + sku, + isEcommerceOrder = String(orderId).length; - if (String(orderId).length) { + if (isEcommerceOrder) { request += '&ec_id=' + encodeWrapper(orderId); // Record date of order in the visitor cookie lastEcommerceOrderTs = Math.round(now.getTime() / 1000); @@ -4028,6 +4029,10 @@ if (typeof window.Piwik !== 'object') { } request = getRequest(request, configCustomData, 'ecommerce', lastEcommerceOrderTs); sendRequest(request, configTrackerPause); + + if (isEcommerceOrder) { + ecommerceItems = {}; + } } function logEcommerceOrder(orderId, grandTotal, subTotal, tax, shipping, discount) { @@ -6320,6 +6325,7 @@ if (typeof window.Piwik !== 'object') { * Adds an item (product) that is in the current Cart or in the Ecommerce order. * This function is called for every item (product) in the Cart or the Order. * The only required parameter is sku. + * The items are deleted from this JavaScript object when the Ecommerce order is tracked via the method trackEcommerceOrder. * * @param string sku (required) Item's SKU Code. This is the unique identifier for the product. * @param string name (optional) Item's name @@ -6338,6 +6344,7 @@ if (typeof window.Piwik !== 'object') { * If the Ecommerce order contains items (products), you must call first the addEcommerceItem() for each item in the order. * All revenues (grandTotal, subTotal, tax, shipping, discount) will be individually summed and reported in Piwik reports. * Parameters orderId and grandTotal are required. For others, you can set to false if you don't need to specify them. + * After calling this method, items added to the cart will be deleted. * * @param string|int orderId (required) Unique Order ID. * This will be used to count this order only once in the event the order page is reloaded several times. @@ -6356,6 +6363,7 @@ if (typeof window.Piwik !== 'object') { * Tracks a Cart Update (add item, remove item, update item). * On every Cart update, you must call addEcommerceItem() for each item (product) in the cart, including the items that haven't been updated since the last cart update. * Then you can call this function with the Cart grandTotal (typically the sum of all items' prices) + * Calling this method does not remove from this JavaScript object the items that were added to the cart via addEcommerceItem * * @param float grandTotal (required) Items (products) amount in the Cart */ diff --git a/piwik.js b/piwik.js index 4e2285c843c..3bf3250eac9 100644 --- a/piwik.js +++ b/piwik.js @@ -44,7 +44,7 @@ if(bh.length){cB[1]=bh}return cB}if(bh.length){cA=bh}else{if("0"===bx()){cA=""}e }function aj(){var cz=aT;aT=false;var cx=["id","ses","cvar","ref"];var cy,cA;for(cy=0;cycW){cN.visitCount++;cN.lastVisitTs=cN.currentVisitTs}if(!a1||!cF.length){for(cT in bS){if(Object.prototype.hasOwnProperty.call(bS,cT)){cF=M(cX,bS[cT]); if(cF.length){break}}}for(cT in ba){if(Object.prototype.hasOwnProperty.call(ba,cT)){cx=M(cX,ba[cT]);if(cx.length){break}}}}c0=c(aV);cI=cS.length?c(cS):"";if(c0.length&&!ay(c0)&&(!a1||!cI.length||ay(cI))){cS=aV}if(cS.length||cF.length){cE=cH;cR=[cF,cx,cE,bu(cS.slice(0,cB))];ct(cO,JSON2.stringify(cR),cm,aX,cg)}}cz+="&idsite="+by+"&rec=1&r="+String(Math.random()).slice(2,8)+"&h="+cy.getHours()+"&m="+cy.getMinutes()+"&s="+cy.getSeconds()+"&url="+n(bu(cX))+(aV.length?"&urlref="+n(bu(aV)):"")+((a4&&a4.length)?"&uid="+n(a4):"")+"&_id="+cN.uuid+"&_idts="+cN.createTs+"&_idvc="+cN.visitCount+"&_idn="+cN.newVisitor+(cF.length?"&_rcn="+n(cF):"")+(cx.length?"&_rck="+n(cx):"")+"&_refts="+cE+"&_viewts="+cN.lastVisitTs+(String(cN.lastEcommerceOrderTs).length?"&_ects="+cN.lastEcommerceOrderTs:"")+(String(cS).length?"&_ref="+n(bu(cS.slice(0,cB))):"")+(cK?"&cs="+n(cK):"")+"&send_image=0";for(cT in co){if(Object.prototype.hasOwnProperty.call(co,cT)){cz+="&"+cT+"="+co[cT]}}var cZ=[];if(cU){for(cT in cU){if(Object.prototype.hasOwnProperty.call(cU,cT)&&/^dimension\d+$/.test(cT)){var cD=cT.replace("dimension",""); cZ.push(parseInt(cD,10));cZ.push(String(cD));cz+="&"+cT+"="+cU[cT];delete cU[cT]}}}if(cU&&t(cU)){cU=null}for(cT in aU){if(Object.prototype.hasOwnProperty.call(aU,cT)){var cJ=(-1===cZ.indexOf(cT));if(cJ){cz+="&dimension"+cT+"="+aU[cT]}}}if(cU){cz+="&data="+n(JSON2.stringify(cU))}else{if(Y){cz+="&data="+n(JSON2.stringify(Y))}}function cG(c1,c2){var c3=JSON2.stringify(c1);if(c3.length>2){return"&"+c2+"="+n(c3)}return""}var cY=cw(bo);var cP=cw(bN);cz+=cG(cY,"cvar");cz+=cG(cP,"e_cvar");if(at){cz+=cG(at,"_cvar");for(cT in cQ){if(Object.prototype.hasOwnProperty.call(cQ,cT)){if(at[cT][0]===""||at[cT][1]===""){delete at[cT]}}}if(bj){ct(cL,JSON2.stringify(at),bQ,aX,cg)}}if(aE){if(bO){cz+=">_ms="+bO}else{if(g&&g.timing&&g.timing.requestStart&&g.timing.responseEnd){cz+=">_ms="+(g.timing.responseEnd-g.timing.requestStart)}}}cN.lastEcommerceOrderTs=A(cA)&&String(cA).length?cA:cN.lastEcommerceOrderTs;ao(cN);bF();cz+=R(cV);if(ci.length){cz+="&"+ci}if(s(bD)){cz=bD(cz)}return cz}bk=function aI(){var cx=new Date(); -if(ch+aH<=cx.getTime()){var cy=bT("ping=1",null,"ping");a9(cy,bc);return true}return false};function aY(cA,cz,cE,cB,cx,cH){var cC="idgoal=0",cD,cy=new Date(),cF=[],cG;if(String(cA).length){cC+="&ec_id="+n(cA);cD=Math.round(cy.getTime()/1000)}cC+="&revenue="+cz;if(String(cE).length){cC+="&ec_st="+cE}if(String(cB).length){cC+="&ec_tx="+cB}if(String(cx).length){cC+="&ec_sh="+cx}if(String(cH).length){cC+="&ec_dt="+cH}if(cj){for(cG in cj){if(Object.prototype.hasOwnProperty.call(cj,cG)){if(!A(cj[cG][1])){cj[cG][1]=""}if(!A(cj[cG][2])){cj[cG][2]=""}if(!A(cj[cG][3])||String(cj[cG][3]).length===0){cj[cG][3]=0}if(!A(cj[cG][4])||String(cj[cG][4]).length===0){cj[cG][4]=1}cF.push(cj[cG])}}cC+="&ec_items="+n(JSON2.stringify(cF))}cC=bT(cC,Y,"ecommerce",cD);a9(cC,bc)}function br(cx,cB,cA,cz,cy,cC){if(String(cx).length&&A(cB)){aY(cx,cB,cA,cz,cy,cC)}}function aZ(cx){if(A(cx)){aY("",cx,"","","","")}}function bs(cy,cA,cz){var cx=bT("action_name="+n(X(cy||aR)),cA,"log");a9(cx,bc,cz)}function aC(cz,cy){var cA,cx="(^| )(piwik[_-]"+cy; +if(ch+aH<=cx.getTime()){var cy=bT("ping=1",null,"ping");a9(cy,bc);return true}return false};function aY(cA,cz,cF,cB,cx,cI){var cD="idgoal=0",cE,cy=new Date(),cG=[],cH,cC=String(cA).length;if(cC){cD+="&ec_id="+n(cA);cE=Math.round(cy.getTime()/1000)}cD+="&revenue="+cz;if(String(cF).length){cD+="&ec_st="+cF}if(String(cB).length){cD+="&ec_tx="+cB}if(String(cx).length){cD+="&ec_sh="+cx}if(String(cI).length){cD+="&ec_dt="+cI}if(cj){for(cH in cj){if(Object.prototype.hasOwnProperty.call(cj,cH)){if(!A(cj[cH][1])){cj[cH][1]=""}if(!A(cj[cH][2])){cj[cH][2]=""}if(!A(cj[cH][3])||String(cj[cH][3]).length===0){cj[cH][3]=0}if(!A(cj[cH][4])||String(cj[cH][4]).length===0){cj[cH][4]=1}cG.push(cj[cH])}}cD+="&ec_items="+n(JSON2.stringify(cG))}cD=bT(cD,Y,"ecommerce",cE);a9(cD,bc);if(cC){cj={}}}function br(cx,cB,cA,cz,cy,cC){if(String(cx).length&&A(cB)){aY(cx,cB,cA,cz,cy,cC)}}function aZ(cx){if(A(cx)){aY("",cx,"","","","")}}function bs(cy,cA,cz){var cx=bT("action_name="+n(X(cy||aR)),cA,"log");a9(cx,bc,cz)}function aC(cz,cy){var cA,cx="(^| )(piwik[_-]"+cy; if(cz){for(cA=0;cA([0-9]+)\<\/span\>/.exec(results))[1], "36", "count tracking events" ); // firing callback ok( trackLinkCallbackFired, "trackLink() callback fired" ); @@ -3428,6 +3432,9 @@ function getLastInteractionType() { return lastInteractionType; } // Cart update ok( /idgoal=0&revenue=555.55&ec_items=%5B%5B%22SKU%20PRODUCT%22%2C%22random%22%2C%22random%20PRODUCT%20CATEGORY%22%2C11.1111%2C2%5D%2C%5B%22SKU%20ONLY%20SKU%22%2C%22%22%2C%22%22%2C0%2C1%5D%2C%5B%22SKU%20ONLY%20NAME%22%2C%22PRODUCT%20NAME%202%22%2C%22%22%2C0%2C1%5D%2C%5B%22SKU%20NO%20PRICE%20NO%20QUANTITY%22%2C%22PRODUCT%20NAME%203%22%2C%22CATEGORY%22%2C0%2C1%5D%2C%5B%22SKU%20ONLY%22%2C%22%22%2C%22%22%2C0%2C1%5D%5D/.test( results ), "logEcommerceCartUpdate() with items" ); + // Ecommerce order recorded twice, but each order empties the cart/list of items, so this order is empty of items + ok( /idgoal=0&ec_id=ORDER%20WITHOUT%20ANY%20ITEM&revenue=777&ec_st=444&ec_tx=222&ec_sh=111&ec_dt=1&ec_items=%5B%5D/.test( results ), "logEcommerceOrder() called twice, second time has no item" ); + // parameters inserted by plugin hooks ok( /testlog/.test( results ), "plugin hook log" ); ok( /testlink/.test( results ), "plugin hook link" );