Drupal Commerce AdWords-module

Uit De Vliegende Brigade
Versie door Jeroen Strompf (overleg | bijdragen) op 18 feb 2017 om 23:43
(wijz) ← Oudere versie | Huidige versie (wijz) | Nieuwere versie → (wijz)
Naar navigatie springen Naar zoeken springen

In 2013/2014 werd module uc_adwords geïmplementeerd: Dynamische conversion-tracking voor Übercart 2/Drupal 6. Dit was geen 'complete' module en bevatte zelfs geen grafische interface, maar hij deed precies waar-ie voor bedoeld was. De module is vrijgegeven onder de GPL V2.

Eind 2016 was er geen ontkomen meer aan: De module moest omgezet worden naar Drupal 7/Drupal Commerce 1.x. Met als nieuwe naam: commerce_adwords. Omzetten van de code was echter minder triviaal. Hierbij het reisverslag. In één van de appendices vind je de resulterende code.

uc_adwords: Hoe het werkt

De module declareert twee functies die dankzij de juiste hooks rondom de dankjewel-pagina hun ding doen. Je hoeft dus geen code in te voegen in blocks of pagina's. In de code kun parameter PRODUCTS_ONLY gebruiken om te bepalen dat het orderbedrag in- of exclusief vervoerskosten overgenomen moet worden. Iets meer in detail:

  • uc_adwords_order() detecteert nieuwe orders, en slaat de order-id op in een custom sessie-variablee
  • uc_adwords_footer() detecteert de dankjewel-pagina. Haalt de sessie-variabele op, roept de tag-functie aan, en output de tag naar de footer
  • add_adwords_js() Genereer en retourneer AdWords-tag.

Welk bedrag precies?

Orderbedrag minus vrachtkosten minus BTW:

20151009-01.png
20151009-02.png

Drupal 7: Overzicht bestaande modules

Ik geloof niet dat er een module bestaat die dit dynamisch doet:

Debugging

Event registration

Gebruik drush fn-hook om een overzicht te krijgen van geregistreerde hooks. Bv.:

drush fn-hook commerce_checkout_complete

Enter the number of the hook implementation you wish to view.
 [0]  :  Cancel           
 [1]  :  commerce_adwords 
 [2]  :  commerce_cart

1

// file: /var/www/kbo215.dvb/sites/all/modules/commerce_adwords/commerce_adwords.module, lines 7-10
function commerce_adwords_commerce_checkout_complete($order)
{
	print phpinfo();
}

Event-code uitvoeren

Het resultaat van de code hiernaast

Hier komt de truuk: print phpinfo(); werkt niet! Blijkbaar zijn er events waarbij je niet op deze manier uitvoer naar het scherm kunt forceren! Een voorbeeld van wat wel werkt:

// commerce_checkout_complete
/////////////////////////////////////////////
//
function commerce_adwords_commerce_checkout_complete($order)
{
	dpm($order);
	// print "<br><br><br> commerce_checkout_complete";
	// print phpinfo();
}

Nieuwe order onderscheppen

Het gaat om dit event
hook_commerce_order_presave vuurt op het moment dat je iets toevoegt aan de winkelwagen
Order review-pagina: hook_commerce_order_presave en hook_entity_insert
Checkout complete-pagina: hook_commerce_checkout_complete, hook_commerce_order_presave, hook_init en hook_commerce_order_status_info. Deze eerste is het meest relevant

Dit zijn zoal de hooks die in aanmerking leken te komen om een nieuwe order te onderscheppen. Dit ruime lijstje ontstond, omdat ik niet effectief debugde (zie hierboven):

  • hook_commerce_checkout_complete - Lijkt niet te werken. Zie hieronder
  • hook_entity_insert [3]
  • hook_entity_update
  • hook_commerce_order_presave()
  • hook_commerce_order_status_update[4]
  • hook_commerce_order_state_info [5] - Waarschijnlijk niet
  • hook_commerce_order_status_info [6] - Actief op elke pagina. Bruikbaar?

commerce_order_checkout_complete is het juiste event. Dat zie je ook terug in de eerste regels van deze code-export van het checkout_completetion_email_send-event:

{ "commerce_checkout_order_email" : 
   {
      "LABEL" : "Send an order notification e-mail",
      "PLUGIN" : "reaction rule",
      "WEIGHT" : "4",
      "OWNER" : "rules",
      "TAGS" : [ "Commerce Checkout" ],
      "REQUIRES" : [ "rules", "commerce_checkout" ],
      "ON" : { "commerce_checkout_complete" : [] },
...

Zie de appendix voor alle hooks bij elkaar.

order_id of order_number?

Drupal Commerce kent een order_id en een order_number. Geen idee wat het verschil is. Ik houd het erop, dat ik deze eerste nodig heb.

Order_number opslaan

Hebbes: order_number is inderdaad '27763

Tjakka:

/////////////////////////////////////////////
// Niewe order onderscheppen
/////////////////////////////////////////////
//
function commerce_adwords_commerce_checkout_complete($order)
{
	$_SESSION['adwords_commerce_order_number'] = $order->order_number;
	dpm($order);
	dpm($order->order_number);
	dpm($_SESSION['adwords_commerce_order_number']);
}

In de schermafdruk hiernaast zie je dat de onderste twee dpm-commando's functioneren, want het order_number is inderdaad 27763.

Orderbedrag uitlezen

Übercart heeft de functie uc_order_get_total($order, TRUE); om ordergegevens boven water te toveren als je het $order-object opgeeft. Hoe doe je dat in Drupal Commerce?

Uit het order-object peuteren

Yep: Ik kan het uit het order-object peuteren, maar da's nogal lastig + instabiel. Dat kan vast beter.

API-calls?

Voorbeelden van mogelijk relevante functies:

https://drupalcommerce.org/discussions/397/get-order-total:

$order = commerce_order_load($order_id);
$wrapper = entity_metadata_wrapper('commerce_order', $order);
$total = $wrapper->commerce_order_total->amount->value();
$currency_code = $wrapper->commerce_order_total->currency_code->value();

Output tag to page

Nu nog die tag op de betreffende pagina serveren. Dat heeft een paar onderdelen, die vaak met elkaar verweven zijn:

  • Hook om een pagina aan te passen
  • Selectiemechanisme om de dankjewel-pagina te selecteren
  • Plaatsingsmechanisme om de tag te plaatsen
  • Executie: Dit betreft een JavaScript-tag, en dat ding moet uitgevoerd worden, en niet bv. afgebeeld worden alsof het gewoon tekst is.

hook_footer (Drupal 6)

In uc_adwords werd hook_footer gebruikt om het script te incorporeren op een pagina. [7]:

Insert closing HTML.

This hook enables modules to insert HTML just before the \</body\> closing tag of web pages. 
This is useful for adding JavaScript code to the footer and for outputting debug information. 
It is not possible to add JavaScript to the header at this point, and developers wishing to 
do so should use hook_init() instead.

Aanroep is verbluffend eenvoudig, bv.:

mijnmodule_footer
{
   ...
   return $mijncode;
}

In Drupal 7 bestaat hook_footer niet meer [8].

hook_init (nee!)

Leuk geprobeerd, maar helaas.

<?php

/////////////////////////////////////////////
// hook - commerce_checkout_complete($order)
/////////////////////////////////////////////
//
// Werkt niet. Zie http://wiki.devliegendebrigade.nl/Drupal_Commerce_AdWords-module
//
// function commerce_adwords_commerce_checkout_complete($order)
// {
//	print phpinfo();
// }	

/////////////////////////////////////////////
// hook_init()
/////////////////////////////////////////////
//
// Dit is de basis
// 
// * hook_init() is run on every page load except for cached pages, 
//   so depending on your use case that might be an option.
// * (http://drupal.stackexchange.com/questions/33789/how-to-run-check-on-each-page-load)
//
// function commerce_adwords_init()
// {
// 	print "commerce_adwords_init";
// }	

/////////////////////////////////////////////
// commerce_adwords_init()
/////////////////////////////////////////////
//
function commerce_adwords_init()
{
	if (arg(0)=='checkout' && arg(2)=='complete')
	{
		print phpinfo();
	}
}

drupal_add_js (nee!)

  • Met drupal_add_js kun je JavaScript-code toevoegen aan een pagina
  • Het is de vraag of dit is wat we zoeken: Eigenlijk willen we gewoon HTML invoegen (waar toevallig JavaScript in zit). Bij gebruik van drupal_add_js, zou de AdWords Conversion-tag in twee aparte functies gesplitst worden. Dat lijkt me niet de bedoeling.

Syntaxis

Het werkt met vijf parameters. Documentatie vermeld alleen de eerste twee parameters:

  1. Code: De eerste parameter is een bestandsnaam, een array met instellingen, of direct JavaScript-code → Ik kies deze laatste
  2. Bron: Keuze uit 'module' (standaard) 'setting', 'theme' or 'online' → Deze laatste gebruiken

Voorbeeld

drupal_add_js('jQuery(document).ready(function () { alert("Hello!"); });', 'inline');

Met aangepaste formattering:

drupal_add_js
(
   '
      jQuery(document).ready
      (
         function () 
         { 
            alert("Hello!"); 
         }
       );
   '

   , 

   'inline'
);

hook_page_build (ja!)

In Drupal 7 is hook_page_build() de opvolger van hook_footer. Dit event vindt plaats bij elke pagina-aanroep.

Syntaxis

hook_page_build(&$page)

  • Hierbij is &$page een array van weer te geven elementen, dat tezamen de pagina vorm
  • Het input-argument is een render array.

Voorbeeld

Zo simpel kan het al, dus zonder de page-variabele:

// ----------------------------------------------------------------------------
// Test - hook_page_build
// ----------------------------------------------------------------------------
//
function commerce_adwords_page_build()
{
	dpm("hook_page_build");
}
Output van hook_page_build-test

hook_page_alter (nee!)

hook_page_alter() is het broertje van hook_page_build(), en is bedoeld om content die van een andere module komt, aan te passen of te verwijderen [9]. Dat is waarschijnlijk niet wat ik zoek.

$page_bottom, $page_top (nee!)

$page_bottom, $page_top, hook_page_build(), hook_page_alter() - https://www.drupal.org/node/224333#hook_footer

Render arrays (ja!)

In Drupal 7 zijn render arrays iets nieuws: Als je met blokken html-code moet schuiven, moet je dat doen in de vorm van zo'n render arrary. Dat zijn (mogelijk geneste) arrays met data en aanwijzingen tav. de weergave daarvan. Het bestaat uit paren van property-labels en de bijbehorende waardes.

Voorbeelden

Zie ook de voorbeelden verderop in de artikel!

$page = array(
  '#show_messages' => TRUE,
  '#theme' => 'page',
  '#type' => 'page',
  'content' => array(
    'system_main' => array(...),
    'another_block' => array(...),
    '#sorted' => TRUE,
  ),
  'sidebar_first' => array(
    ...
  ),
  'footer' => array(
    ...
  ),
  ...
);
function mymodule_page_alter(&$page) 
{

  // Move search form into the footer.
  //
  $page['footer']['search_form'] = $page['sidebar_first']['search_form'];
  unset($page['sidebar_first']['search_form']);
  
  // Remove the "powered by Drupal" block
  //
  unset($page['footer']['system_powered-by']);
}

hook_page_build + render array (warm!)

Dit werkt:

// ----------------------------------------------------------------------------
// Test - hook_page_build + render array
// ----------------------------------------------------------------------------
//
function commerce_adwords_page_build(&$page)
{
   $page['footer']['testblock']=array(
      '#type' => 'markup',
      '#markup' => '<p>Hello, world!</p>'
   );
}
Tjakka!

Dit werkt ook:

$page['page_bottom']['ga_adwords'] = array(
   '#weight' => 25,
   '#markup' => '
      <!-- Start Google Code for commerce_adwords Conversion Page -->
      <script type="text/javascript">
      /* <![CDATA[ */
      var google_conversion_id = ...
      ...
      ',
);

hook_page_build + render array + executie (heet!)

En weer een stap verder: HTML-code die via hook_page_build wordt ingevoerd, wordt daadwerkelijk geëxecuteerd:

function commerce_adwords_page_build(&$page)
{
   $tag="Hello, <h1>World!</h1>";

   // Place tag
   // -----------------------------------------------------------------------
   //
   $page['footer']['adwords_conversion_tag']=array(
      '#type' => 'markup',
      '#markup' => $tag
   );
}
Het woord 'World' is daadwerkelijk in H1 weergegeven. De code wordt dus geëvalueerd

Appendix: Broncode uc_adwords

uc_adwords.info

name = uc_adwords
description = Implements dynamic conversion tracking for adwords in ubercart
version = 6.x-0.1
core = 6.x
package = Custom
files[] = uc_adwords.module

uc_adwords.install

Er is geen installatie-procedure:

<?php

uc_adwords.module - 2014

<?php

define('PRODUCTS_ONLY', FALSE); // If set to TRUE google_conversion_value will be products only (without shipping costs)

function uc_adwords_footer () {
  // Check to see if we are at the order completion page.
  if (arg(0) == 'cart' && arg(1) == 'checkout' && arg(2) == 'complete') {
    // If we can load the order...
    if ($order = uc_order_load($_SESSION['uc_adwords_order_id'])) {
      $output = add_adwords_js($order);
    }
    // Clean out the session variable.
    unset($_SESSION['uc_adwords_order_id']);
  }
  return $output;
}

/**
 * Implementation of hook_order().
 */
function uc_adwords_order($op, &$arg1, $arg2) {
  switch ($op) {
    case 'new':
      // Store the order ID for later use.
      $_SESSION['uc_adwords_order_id'] = $arg1->order_id;
      break;
  }
}

function add_adwords_js ($order) {
	//global $_google_adwords_footer_script;

	$script = '';

	// google adwords parameters
        //
	$google_conversion_id = 9xxxxxxx5;
	$google_conversion_language = "en";
	$google_conversion_format = "2";
	$google_conversion_color = "ffffff";
	$google_conversion_label = "FxxxxxxxxxxxxxxxxxM";
	$google_remarketing_only = false;

	// conversion value
	// ================
	//
	// Value PRODUCTS_ONLY (boolean)
	//
	// true : Only value of products incorporated, ex. transportation cost
	// false: Complete order amount incorporated
	//
	$PRODUCTS_ONLY = True;

	if (PRODUCTS_ONLY)
		$google_conversion_value = uc_order_get_total($order, TRUE);
	else {
		$google_conversion_value = $order->order_total;
	}
	$google_conversion_value = uc_currency_format($google_conversion_value, FALSE, TRUE, '.');

	// google adwords script
  $script = '';    
  $script .= "\n" . '<!-- Google Code for Order Complete scherm Conversion Page -->' . "\n";
  $script .= '<script type="text/javascript">' . "\n";
  //$script .= '<!--' . "\n";
  $script .= ' /* <![CDATA[ */' . "\n";
  $script .= '    var google_conversion_id = '. $google_conversion_id .';' . "\n";
  $script .= '    var google_conversion_language = "'. $google_conversion_language .'";' . "\n";
  $script .= '    var google_conversion_format = "'. $google_conversion_format .'";' . "\n";
  $script .= '    var google_conversion_color = "'. $google_conversion_color .'";' . "\n";
  $script .= '    var google_conversion_label = "'. $google_conversion_label .'";' . "\n";
  $script .= '    var google_conversion_value = "'. $google_conversion_value .'";' . "\n";
  $script .= '    var google_remarketing_only = "'. $google_remarketing_only .'";' . "\n";
  $script .= ' /* ]]> */ ' . "\n";
  $script .= '</script>' . "\n";
  $script .= '<script type="text/javascript" src="//www.googleadservices.com/pagead/conversion.js">' . "\n";
  $script .= '</script>' . "\n";
  $script .= '<noscript>' . "\n";
  $script .= '<div style="display:inline;">' . "\n";
  $script .= '<img height="1" width="1" border="0" src="https://www.googleadservices.com/pagead/conversion/' . $google_conversion_id . '?value='. $google_conversion_value .'&label='. $google_conversion_label .'&guid=ON&script=0" alt=""/>' . "\n";
  $script .= '</div>' . "\n";
  $script .= '</noscript>' . "\n";

	return $script;  
}

uc_adwords.module - 2015

Wijzigingen:

  • Google Tag Assistant suggereerde dat geldbedragen numerieke waardes dienen te zijn, en geen strings
  • Voorzien van commentaar
<?php

define('PRODUCTS_ONLY', FALSE); // If set to TRUE google_conversion_value will be products only (without shipping costs)

/////////////////////////////////////////////////////////////////////////
// uc_adwords_footer() 
/////////////////////////////////////////////////////////////////////////
//
// Output the AdWords Conversion-tag at the checkout completion page
//
// * The hook is 'footer'
// * Additionally, check that we're on the checkout completion page
// * Additionally, check that we can load the current order
// * Call function add_adwords_js($order)
//
function uc_adwords_footer () 
{
   if (arg(0) == 'cart' && arg(1) == 'checkout' && arg(2) == 'complete') 
   {
      // If we can load the order...
      if ($order = uc_order_load($_SESSION['uc_adwords_order_id'])) 
      {
         $output = add_adwords_js($order);
       }
       // Clean out the session variable.
       unset($_SESSION['uc_adwords_order_id']);
   }
   return $output;
}

/////////////////////////////////
// uc_adwords_order()
/////////////////////////////////
//
// Intercept any new order and store order-ID in a custom session variable
//
// * Hook = "order": http://www.ubercart.nl/docs/api/hook_order
// * $op:   De action that is being performed
// * $arg1: Order-object
// * $arg2: Eventueel additioneel argument bij $arg1

function uc_adwords_order($op, &$arg1, $arg2) 
{
   switch ($op) 
   {
      case 'new':

         // Store the order ID in a session variable for later use
         //
         $_SESSION['uc_adwords_order_id'] = $arg1->order_id;
         break;
   }
}

/////////////////////////////////
// add_adwords_js()
/////////////////////////////////
//
// Generate tag
//
function add_adwords_js ($order) 
{
   //global $_google_adwords_footer_script;

   $script = '';

   // google adwords parameters
   //
   $google_conversion_id = 9xxxxxxx5;
   $google_conversion_language = "en";
   $google_conversion_format = "2";
   $google_conversion_color = "ffffff";
   $google_conversion_label = "FxxxxxxxxxxxxxxxxxM";
   $google_remarketing_only = false;

   // conversion value
   // ================
   //
   // Value PRODUCTS_ONLY (boolean)
   //
   // true : Only value of products incorporated, ex. transportation cost
   // false: Complete order amount incorporated
   //
   $PRODUCTS_ONLY = True;

   if (PRODUCTS_ONLY)
      $google_conversion_value = uc_order_get_total($order, TRUE);
   else 
   {
      $google_conversion_value = $order->order_total;
   }

   $google_conversion_value = uc_currency_format($google_conversion_value, FALSE, TRUE, '.');

   // Assemble Adwords tag
   // ====================
   //
   $script = '';    
   $script .= "\n" . '<!-- Google Code for Order Complete scherm Conversion Page -->' . "\n";
   $script .= '<script type="text/javascript">' . "\n";
   //$script .= '<!--' . "\n";
   $script .= ' /* <![CDATA[ */' . "\n";
   $script .= '    var google_conversion_id = '. $google_conversion_id .';' . "\n";
   $script .= '    var google_conversion_language = "'. $google_conversion_language .'";' . "\n";
   $script .= '    var google_conversion_format = "'. $google_conversion_format .'";' . "\n";
   $script .= '    var google_conversion_color = "'. $google_conversion_color .'";' . "\n";
   $script .= '    var google_conversion_label = "'. $google_conversion_label .'";' . "\n";
   $script .= '    var google_conversion_value = '. $google_conversion_value .';' . "\n";
   $script .= '    var google_remarketing_only = "'. $google_remarketing_only .'";' . "\n";
   $script .= ' /* ]]> */ ' . "\n";
   $script .= '</script>' . "\n";
   $script .= '<script type="text/javascript" src="//www.googleadservices.com/pagead/conversion.js">' . "\n";
   $script .= '</script>' . "\n";
   $script .= '<noscript>' . "\n";
   $script .= '<div style="display:inline;">' . "\n";
   $script .= '<img height="1" width="1" border="0" src="https://www.googleadservices.com/pagead/conversion/' . $google_conversion_id . '?value='. $google_conversion_value .'&label='. $google_conversion_label .'&guid=ON&script=0" alt=""/>' . "\n";
   $script .= '</div>' . "\n";
   $script .= '</noscript>' . "\n";

   return $script;  
}

Appendix: Nieuwe order onderscheppen (Drupal 7)

Let op: dpm($order) werkt. Print-opdrachten werken vaak niet!

<?php

/////////////////////////////////////////////
// Niewe order onderscheppen
/////////////////////////////////////////////

// entity_insert
/////////////////////////////////////////////
//
function commerce_adwords_entity_insert($entity, $type)
{
	// dpm($order);
	// print "<br><br><br> entity_insert";
	// print phpinfo();
}

// entity_presave
/////////////////////////////////////////////
//
function commerce_adwords_entity_presave()
{
	// dpm();
	print "<br><br><br> entity_presave";
	// print phpinfo();
}

// entity_update
/////////////////////////////////////////////
//
function commerce_adwords_entity_update($entity, $type)
{
	// dpm();
	print "<br><br><br> entity_update";
	// print phpinfo();
}

// commerce_checkout_complete
/////////////////////////////////////////////
//
function commerce_adwords_commerce_checkout_complete($order)
{
	dpm($order);
	// print "<br><br><br> commerce_checkout_complete";
	// print phpinfo();
}

// Overige events
/////////////////////////////////////////////
//
function commerce_adwords_commerce_order_presave($order)
{
	dpm($order);
	// print "<br><br><br> commerce_order_presave";
	// print phpinfo();
}

function commerce_adwords_order_state_info()
{
	dpm($order);
	// print "<br><br><br> commerce_adwords_commerce_order_presave";
	// print phpinfo();
}

function commerce_adwords_commerce_order_status_update()
{
	dpm($order);
	// print "<br><br><br> commerce_order_status_update";
	// print phpinfo();
}

function commerce_adwords_commerce_order_status_info()
{
	// dpm($order);
	print "<br><br><br> commerce_order_status_info";
	// print phpinfo();
}

function commerce_adwords_init()
{
	if (arg(0)=='checkout' && arg(2)=='complete')
	{
		print "<br><br><br> commerce_adwords_init - checkout-completed-page<br>";
	}
}	

Appendix: Broncode Drupal Commerce AdWords (versie 1)

Deze versie is op 18 feb. 2017 in gebruik genomen. Details:

  • Twee functies ipv. drie: Geen aparte functie meer voor het samenstellen van de tag
  • Er wordt geverifiëerd dat de dankjewel-pagina niet meerdere keren worden aangeroepen.
<?php
// ----------------------------------------------------------------------------
// Store ID of newly created order in a session variable
// ----------------------------------------------------------------------------
//
function commerce_adwords_commerce_checkout_complete($order)
{
  $_SESSION['adwords_commerce_order_number'] = $order->order_number;
}

// ---------------------------------------------------------------------------------
// Output tag to completed-page
// ---------------------------------------------------------------------------------
//
function commerce_adwords_page_build(&$page) {
  if (substr(current_path(),0,8)=="checkout" and substr(current_path(),-8)=="complete") {
    // If user refreshes page we don't want to track conversion again so redirect to homepage
    if (!isset($_SESSION['adwords_commerce_order_number'])) {
      drupal_goto('<front>');
    }
    else {
      $order = commerce_order_load($_SESSION['adwords_commerce_order_number']);
      $wrapper = entity_metadata_wrapper('commerce_order', $order);
      $order_total = $wrapper->commerce_order_total->amount->value();
      $google_conversion_value = intval(($order_total / 1.21 - 326)) / 100;

      $page['page_bottom']['ga_adwords'] = array(
        '#weight' => 25,
        '#markup' => '
                      <!-- Start Google Code for commerce_adwords Conversion Page -->
                      <script type="text/javascript">
                      /* <![CDATA[ */
                      var google_conversion_id = 1xxxxx;
                      var google_conversion_language = "en";
                      var google_conversion_format = "3";
                      var google_conversion_color = "ffffff";
                      var google_conversion_label = "zqxxxxxxmwQ6ube6wM";
                      var google_conversion_value = ' . $google_conversion_value . ';
                      var google_conversion_currency = "EUR";
                      var google_remarketing_only = false;
                      /* ]]> */
                      </script>
                      <script type="text/javascript" src="//www.googleadservices.com/pagead/conversion.js">
                      </script>
                      <noscript>
                      <div style="display:inline;">
                      <img height="1" width="1" style="border-style:none;" alt="" src="//www.googleadservices.com/pagead/conversion/xxxxxxx90/?value=' . $google_conversion_value . '&currency_code=EUR&label=zxxxxxxxxxxxe6wM&guid=ON&script=0"/>
                      </div>
                      </noscript>
                      <!-- End Google Code for commerce_adwords Conversion Page -->
                    ',
      );

      // Clear session variable always
      unset($_SESSION['adwords_commerce_order_number']);
    }
  }
}

Appendix: Broncode Drupal Commerce AdWords (versie 2)

  • Deze versie was nog niet af, op het moment dat de bovenstaande versie in gebruik werd genomen
  • Google Tag Assistant gaf inconsistente foutmeldingen, terwijl de code écht 100% correct is overgenomen. Ik heb de indruk dat Google Tag Assistant niet al te betrouwbaar is.
<?php

// ----------------------------------------------------------------------------
// Test - hook_page_build + render array
// ----------------------------------------------------------------------------
//
// function commerce_adwords_page_build(&$page)
// {
// 	dpm("hook_page_build");

// 	$page['footer']['testblock']=array(
// 		'#type' => 'markup',
// 		'#markup' => '<p>Hello, world!</p>'
// 	);

// 	// Moet ik nog wat doen met $page?

// }


// ----------------------------------------------------------------------------
// Store ID of newly created order in a session variable
// ----------------------------------------------------------------------------
//
// function commerce_adwords_commerce_checkout_complete($order)
// {
// 	$_SESSION['adwords_commerce_order_number'] = $order->order_number;
// 	// dpm($order);
// 	// dpm($order->order_number);
// 	// dpm($_SESSION['adwords_commerce_order_number']);
// }

// ---------------------------------------------------------------------------------
// Output tag to completed-page
// ---------------------------------------------------------------------------------
//
function commerce_adwords_page_build(&$page)
{

	// Get order-ID
	// ----------------------------------------------------------------------
	//
	// * Gebruik '27766' als-ie leeg is
	//
	// if is_null($_SESSION['adwords_commerce_order_number'])
	// {

	$order='27766';

	//}
	// else
	// {		
	// 	$order = commerce_order_load($_SESSION['adwords_commerce_order_number']);
	// }

	// Fetch tag
	// --------------------------------------------------------------------------
	//
	$tag=create_tag($order);

	// $tag="Hello, <h1>World!</h1>";
	dpm($tag);

	// Place tag
	// -----------------------------------------------------------------------
	//
	$page['footer']['adwords_conversion_tag']=array(
		'#type' => 'markup',
		'#markup' => $tag
	);

}
		
// ----------------------------------------------------------------------------
// Helper function: Create tag ($order)
// ----------------------------------------------------------------------------
//
// Input: Order-object for the given order_number
//
function create_tag ($order) 
{

	// Reset script
	// ------------------------------
	//
	$script = '';

	// Set AdWords parameters
	// ---------------------------------
	//
	$google_conversion_id = 1xxxxxxxx0;
  	$google_conversion_language = "en";
  	$google_conversion_format = "3";
  	$google_conversion_color = "ffffff";
  	$google_conversion_label = "zxxxxxxxxxxxxxxxxxM";
  	$google_conversion_value = 17.00;	// Default
	$google_conversion_currency = "EUR";
	$google_remarketing_only = "false";


	// Set conversion value
	// ----------------------------------
	//
	$wrapper = entity_metadata_wrapper('commerce_order', $order);
	$order_total = $wrapper->commerce_order_total->amount->value();
	$google_conversion_value = intval(($order_total/1.21-326))/100;

	// dpm($order_total);	// Correct
	// dpm($google_conversion_value); // Correct, behalve afrondfout

   // Assemble Adwords tag
   // ------------------------------
   //
   $script = '';    
   $script .= '<!-- Google Code for commerce_adwords Conversion Page -->' . "\n";
   $script .= '<script type="text/javascript">' . "\n";
   $script .= '/* <![CDATA[ */' . "\n";
   $script .= 'var google_conversion_id = '. $google_conversion_id .';' . "\n";
   $script .= 'var google_conversion_language = "'. $google_conversion_language .'";'. "\n";
   $script .= 'var google_conversion_format = "'  . $google_conversion_format   .'";'. "\n";
   $script .= 'var google_conversion_color = "'   . $google_conversion_color    .'";'. "\n";
   $script .= 'var google_conversion_label = "'   . $google_conversion_label    .'";'. "\n";
   $script .= 'var google_conversion_value = '    . $google_conversion_value    .';' . "\n";
   $script .= 'var google_conversion_currency = "'. $google_conversion_currency .'";'. "\n";
   $script .= 'var google_remarketing_only = '    . $google_remarketing_only    .';' . "\n";
   $script .= '/* ]]> */' . "\n";
   $script .= '</script>' . "\n";

   $script .= '<script type="text/javascript" src="//www.googleadservices.com/pagead/conversion.js">' . "\n";
   $script .= '</script>' . "\n";

   $script .= '<noscript>' . "\n";
   $script .= '<div style="display:inline;">' . "\n";
   $script .= '<img height="1" width="1" style="border-style:none;" alt="" src="//www.googleadservices.com/pagead/conversion/';
   $script .= $google_conversion_id . '/?value='. $google_conversion_value .'&currency_code='.$google_conversion_currency;
   $script .= '&label='.$google_conversion_label.'&guid=ON&script=0"/>'."\n";
   $script .= '</div>' . "\n";
   $script .= '</noscript>' . "\n";

	// Return script
	// ------------------
	//
 	return $script;  
}

Zie ook

Bronnen

hook_commerce_checkout_complete

Order uitlezen

Order uitlezen » hook_entity_insert & hook_entity_update

Order uitlezen '

drupal_add_js

HTML invoegen op een pagina

hook_page_build()

Render arrays