Zen Cart integration

From ClickTale Wiki
Jump to: navigation, search

This Integration module is for sites built with Zen cart and using content which changes for each user independently (Shopping cart pages are often such pages).
The module will allow you to store the exact version of the page that the user had seen and allow the ClickTale bot to fetch that version of the page so it is available for viewing during playback and for aggregated reports (Heatmaps, Form Analytics reports).


The module is PHP5-based, it is provided with full sources, that allows better integration of a PHP site with ClickTale, enabling accurate caching of the HTML that is sent to the visitor in the recorded pageviews.

If you are unable to install a binary module on your site, or if you have an older version of PHP (prior to Version 5), please use the FetchFromWithCookies method instead.


Installation Guide

  1. The module itself can be found here.
  2. Extract the archive to a directory named "ClickTale" on your website. You do not need to create a directory named "ClickTalePHPIntegrationModule_X.X" in it. Simply place the files in ".../ClickTale/".
  3. Generate the ClickTale tracking code you wish to use in your pages.
  4. Copy and paste the above code into the appropriate parts in the ClickTale/ClickTaleScripts.xml file.
  5. Add the cache fetching redirection code, according to your tracking code type:     (How can I find which code type my project is using?)

  6. If you have code type Atlas, click 'Expand' below to see the instructions for placing your code. Click 'Collapse' to close the section.    (How can I find which code type my project is using?)

     
    Add the line:
    var ClickTaleFetchFrom="%FetchFromUrl%";

    Just before the line

       if(typeof ClickTale=='function') ClickTale([your project parameters]);

    Please note: You do not need to change "%FetchFromUrl%" to a specific URL. It will be replaced automatically during the rendering process, with a value dependent on the page being recorded.
    Your xml file should now look like this (Please do not copy and paste this part):

    <?xml version="1.0" encoding="utf-8" ?>
     
    <scripts>
    <script name="Top" DoNotReplaceCondition = "&lt;!-- ClickTale Top part --&gt;">
    <![CDATA[
       <!-- ClickTale Top part -->
       <script type="text/javascript">
       var WRInitTime=(new Date()).getTime();
       </script>
       <!-- ClickTale end of Top part -->]]>
    </script>
    <script name="Bottom" DoNotReplaceCondition = "&lt;!-- ClickTale Bottom part --&gt;">
    <![CDATA[
       <!-- ClickTale Bottom part -->
    <div id="ClickTaleDiv" style="display: none;"></div>
    <script type='text/javascript'>
    document.write(unescape("%3Cscript%20src='"+
     (document.location.protocol=='https:'?
      'https://clicktalecdn.sslcs.cdngc.net/www/':
      'http://cdn.clicktale.net/')+
     "WRe0.js'%20type='text/javascript'%3E%3C/script%3E"));
       </script>
       <script type="text/javascript">
       var ClickTaleSSL=1;
       var ClickTaleFetchFrom="%FetchFromUrl%";
       if(typeof ClickTale=='function') ClickTale([your project parameters]);
       </script>
       <!-- ClickTale end of Bottom part -->
    ]]>
    </script>
    </scripts>



    If you have code type Balkan, click 'Expand' below to see the instructions for placing your code. Click 'Collapse' to close the section.

     
    Add the line:
    var ClickTaleFetchFrom="%FetchFromUrl%";

    Just before the line

    document.write(unescape("%3Cscript%20src='"+

    Please note: You do not need to change "%FetchFromUrl%" to a specific URL. It will be replaced automatically during the rendering process, with a value dependent on the page being recorded.
    Your xml file should now look like this (Please do not copy and paste this part):

    <?xml version="1.0" encoding="utf-8" ?>
     
    <scripts>
    <script name="Top" DoNotReplaceCondition = "&lt;!-- ClickTale Top part --&gt;">
    <![CDATA[
       <!-- ClickTale Top part -->
       <script type="text/javascript">
       var WRInitTime=(new Date()).getTime();
       </script>
       <!-- ClickTale end of Top part -->]]>
    </script>
    <script name="Bottom" DoNotReplaceCondition = "&lt;!-- ClickTale Bottom part --&gt;">
    <![CDATA[
    <!-- ClickTale Bottom part -->
    <script type='text/javascript'>
    // The ClickTale Balkan Tracking Code may be programmatically customized using hooks:
    //
    // function ClickTalePreRecordingHook() { /*place your customized code here*/ }
    //
    // For details about ClickTale hooks, please consult the Wiki page http://wiki.clicktale.com/Article/Customizing_code_version_2
     
    var ClickTaleFetchFrom="%FetchFromUrl%";
    document.write(unescape("%3Cscript%20src='"+
    (document.location.protocol=='https:'?
    "https://clicktalecdn.sslcs.cdngc.net/wwwXX/ptc/xxxxxx-xxxx-xxxx-xxx-xxxxxx.js":
    "http://cdn.clicktale.net/wwwXX/ptc/xxxxxx-xxxx-xxxx-xxx-xxxxxx.js")+"'%20type='text/javascript'%3E%3C/script%3E"));
    </script>
    <!-- ClickTale end of Bottom part -->
    ]]>
    </script>
    </scripts>



    PLEASE NOTE: This is how the code looks like in a text editor. In a browser, "&lt;" will be converted to "<" and "&gt;" will become ">"

    PLEASE ALSO NOTE: This code sample relates to both HTTP and HTTPS page tracking. Your account may or may not have the option to record HTTPS pages. Please check and consult with your account manager, if you need assistance.


    Add to header and footer

  7. Include the top and bottom PHP snippets inside the files "/includes/application_top.php" and "/includes/application_bottom.php" respectively.

  8. See examples below.


    The "/includes/application_top.php" file should look like the following example:

    <?php
    require_once("[physical_path_to_clicktale_dir_here]\ClickTale\ClickTaleTop.php");
    ?>


    The /includes/application_bottom.php should look like the following example:

    <?php
    require_once("[physical_path_to_clicktale_dir_here]\ClickTale\ClickTaleBottom.php");
    ?>


    Make sure to replace [physical_path_to_clicktale_dir_here] with the relevant folder.


  9. Create two directories named "Cache" and "Logs" under the 'ClickTale' directory. Make sure they have writing permissions, for instance:
    • If you are using Apache with mod_php then the Cache and Log directories should be writable by Apache.
    • If the PHP is executed by some other means (CGI, for instance), it is possible that it is executed under a different user than that of the web server. In that case, it might be simpler to set the permissions for those directories to 777.
    • For windows machines, the directories should be writable by the webserver.
  10. Tip: see Selective Recording to disable or enable yourself from being recorded. Apply this to everyone who is working in the organization, otherwise they may use a part of your account's recording quota. You may enable the option to be recorded for testing purposes.

Troubleshooting

After the files are copied you can navigate to http://yoursite/ClickTale/Install/index.php to view some helpful information regarding caching and other configuration settings. You may delete the Install folder in case you don't need the troubleshooting/debugging assistance it provides. Deleting it prevents some of your configuration setting from being publicly available.

Configuration

Configuring the caching provider

The Integration Module caches the content of the pages so it can later provide the content to the ClickTale servers for processing. This caching requires some persistent storage,thus, different caching providers are supported. The default caching provider is the file system ("cache" folder). ClickTale recommends using the MySQLMemory provider. Doing so requires a valid connection to a MySQL database.

Another option is using the APC module. More details about APC can be found here.

After installing APC or MySQL, you can enable its provider by editing config.php file, and changing:

$config['CacheProvider'] = "FileSystem";

to

$config['CacheProvider'] = "MySQLMemory";

or

$config['CacheProvider'] = "APC";

Note: The file-system provider will need write permissions to the "ClickTale/Cache" folder.

Caching Provider Settings

FileSystem
  • $config['DeleteAfterPull'] = (true / false)
    • If true, the cached page is deleted after clicktale fetches it from your site
  • $config['CacheLocation'] = (path to directory)
    • Where the cache files should be saved. This directory should be writable (you can use the Install/index.php to check write permissions)
  • $config['MaxFolderSize'] = (integer)
    • The size of the cache dir in MegaBytes. If the cache gets larger than that, stale caches are removed
MySQLMemory
  • $config['DeleteAfterPull'] = (true / false)
    • See FileSystem
  • $config['CacheLocation'] = (mysql url)
    • URL in this format: http://<db username>:<db password>@<host of mysql>:<port of mysql>/<database to use>.<table name>

     * Table name is created automatically by ClickTale and doesn’t need to be specified.

  • $config['MaxCachedSeconds'] = (integer)
    • Will only keep pages in cache for up to MaxCachedSeconds seconds. This will make sure that your cache storage will only take a small amount of memory.
APC
  • $config['DeleteAfterPull'] = (true / false)
    • See FileSystem
  • $config['MaxCachedSeconds'] = (integer)
    • See MySQLMemory

Use With "Expires" Header and Enable Reuse of Cached Pages

Some websites use "cache-control" and "expires" headers to cache pages on the client. This improves performance but may be problematic when used with our module. Pages are removed from the module's cache right after they are being accessed (for security and performance reasons). So, if a visitor browses a page more than once without refreshing the content from the server (usually a result of using the back button), ClickTaleCache.php will be called several times with the same token. This will cause a cache miss for any request beyond the first one. To overcome this problem, it is possible to use the DeleteAfterPull="false" parameter in the configuration. This will disable the removal of cached pages when ClickTaleCache.php is called. Cached data will be removed after MaxFolderSize/MaxCachedSeconds ="???" new pages are cached, so you might want to extend this parameter as well to allow sufficient traffic between the first pageview and the next (duplicate pageview). Additionally, you can change your HTTP cache control to "no-cache" which will might be more correct for your application logic in the first place. Currently, this feature is not available when caching to databases.

Using with a (reverse) proxy server

If you are using a (reverse) proxy server, that server could change the request in such a way that it appears to originate from the proxy and not from the ClickTale servers. This will prevent the module from authenticating the request based on the IP address. There are two ways to work around this issue:

  • Change the allowed addresses (“AllowedAddresses”) value in the configuration section of PHP module in your config.php file and set it to the IP of the proxy. You will then need to configure your proxy to block access to the ClickTaleCache.php file and only grant access to IPs "75.125.82.64/26 50.97.162.64/26" (note, this stands for 75.125.82.64 - 75.125.82.127 and 50.97.162.64 - 50.97.162.127 using CIDR notation)- The latter recommendation is to ensure that no requests other than that of the ClickTale Bot can access the cache location.

or

  • If your proxy includes the original IP address in the HTTP headers, you could add a module setting in your config.php file to instruct the module to use that header. If your proxy uses a header field called "X-Forwarded-For" (this is common), then add   $config['IPAddressHeaderFieldName'] = "X-Forwarded-For";   to your config.php file to utilize this field.

Please note that failing to implement the above security measures causes a potential security breach to your website. Please ensure that you have taken the necessary steps. Contact ClickTale support if you have any questions.

Load Balancing Scenario

The module uses local storage for storing the temporary cached of pages' content. That content is later fetched by the ClickTale bot and saved on the ClickTale servers. When using a multi server environment and a load balancer to distribute the requests across the servers there is a chance that a visitor will be forwarded to a different server than the one to which the ClickTale Bot is forwarded. As a result the bot will hit a server that doesn't contain the requested information and the request for fetching the cached page (not the page presented to the visitor) will fail with a 404 error.

There are two manners to overcome this issue:

  • A way to force the request form the ClickTale to reach a specific server in the farm.
  • A centralized cache location.

Using a Centralized Cached Location

This may be achieved by configuring either MySQLMemory or APC as your caching provider

Forcing a Specific Server

Using direct host for fetching

If you have a dedicated host for each server in the farm, and you are able to access resources of the web site by going to a direct URL, then you can set ClickTale to fetch from a specific server.
To do so you would customize the ‘CacheFetchingUrl’ variable (found in /ClickTale/config.php) of each server to specify a direct URL to that server.


For example if your site is http://www.site.com/ and your servers are http://s1.site.com/, http://s2.site.com/, you would change the value of this variable on each server to have ‘CacheFetchingUrl’ refer to the specific server directly. Like so:

For the first server:

$config['CacheFetchingUrl'] = "http://s1.site.com/ClickTaleCache.php?t=%CacheToken%";

For the second server:

$config['CacheFetchingUrl'] = "http://s2.site.com/ClickTaleCache.php?t=%CacheToken%";

and so on.

Using cookies for accessing a specific server

Some load balancers use an HTTP cookie to assign a specific visitor to a specific server permanently. This is often called "Sticky Sessions".
If you know that such a cookie exists in your environment, you should be able to have the Bot reach the original server by recording the cookie value. This is done using the ClickTaleFetchFromWithCookies API.
To do so, change the ClickTaleFetchFrom line to:

ClickTaleFetchFromWithCookies.setFromCookie("[!COOKIENAME!]");
ClickTaleFetchFrom=ClickTaleFetchFromWithCookies.constructFetchFromUrl("http://%RootPath%/ClickTaleCache.php?t=%CacheToken%");

Where [!COOKIENAME!] is the name of the cookie that maintains the visitor's affinity to a specific server.

The added code should be placed according to your code type, as outlined in this Code Placement article.



Troubleshooting and debugging

The module's log files are located in: "ClickTale/Logs/Log_{0}.txt", where {0} is the log file's date.

There are 3 settings which need to be modified in order to produce a detailed log of the Module's activity. All settings may be found in the config.php file:

1. $config['AllowDebug'] = true; Provides the basic log.

2. $config['LogCaching'] = true; Provides a log with entries regarding the caching process.

3. $config['LogFetching'] = true; Provides a log with entries regarding the fetching process.

License

The module is subject to a permissive license for ClickTale users. Please see license.txt in the archive for more information.

Q&A

Q: Are cached pages protected from being accessed by third party elements?
A: Yes, several layers of protection are in place. Only certain IPs are allowed to request the cached pages (IPs of ClickTale servers) and only processes which already have access to the page have the unique token required to request the cached content.
Q: Is it possible to inject the script in other places rather than after/before body tags?
A: Yes. By default the top script is injected after <body> and the bottom before </body>, but this can be changed by adding an 'InsertAfter' attribute to the script[name="Top"] element or by adding a InsertBefore attribute to the script[name="Bottom"] element, both are regular expressions.
Q: Some of my pages already have the ClickTale script, I do not want the script to appear twice.
A: You should either remove the script from those pages and let the module handle the insertion or you should use the DoNotReplaceCondition. See step 2 for an example. The default script in Step 2 is already configured to prevent double inclusion.
Q: After installing the module, I tried to watch a recording but I got the following notice instead: "Request from an unauthorized IP." . What should I do?
A: This could be a misconfiguration, a change in our IP addresses or a hacking attempt. Please contact us so we can investigate this further.
Q: I have installed the module but I don't see the tracking code in the source of the page. What is wrong?
A: The module will only inject the code for visitors who are classified as "to-record" (have the WRUID cookie with non-zero value) or for those who are not classified (no WRUID cookie). Visitors who are classified as "not-to-record" will not get the code.

Reference

ASP.NET integration module - Good read as some configuration schema is shared.