PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/x2engine/webTracker.php

https://gitlab.com/e0/X2CRM
PHP | 279 lines | 208 code | 14 blank | 57 comment | 4 complexity | 798d98e03dcd3c25bb6c1bfe922eab9c MD5 | raw file
  1. <?php
  2. /***********************************************************************************
  3. * X2CRM is a customer relationship management program developed by
  4. * X2Engine, Inc. Copyright (C) 2011-2016 X2Engine Inc.
  5. *
  6. * This program is free software; you can redistribute it and/or modify it under
  7. * the terms of the GNU Affero General Public License version 3 as published by the
  8. * Free Software Foundation with the addition of the following permission added
  9. * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
  10. * IN WHICH THE COPYRIGHT IS OWNED BY X2ENGINE, X2ENGINE DISCLAIMS THE WARRANTY
  11. * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
  12. *
  13. * This program is distributed in the hope that it will be useful, but WITHOUT
  14. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  15. * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public License along with
  19. * this program; if not, see http://www.gnu.org/licenses or write to the Free
  20. * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  21. * 02110-1301 USA.
  22. *
  23. * You can contact X2Engine, Inc. P.O. Box 66752, Scotts Valley,
  24. * California 95067, USA. on our website at www.x2crm.com, or at our
  25. * email address: contact@x2engine.com.
  26. *
  27. * The interactive user interfaces in modified source and object code versions
  28. * of this program must display Appropriate Legal Notices, as required under
  29. * Section 5 of the GNU Affero General Public License version 3.
  30. *
  31. * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
  32. * these Appropriate Legal Notices must retain the display of the "Powered by
  33. * X2Engine" logo. If the display of the logo is not reasonably feasible for
  34. * technical reasons, the Appropriate Legal Notices must display the words
  35. * "Powered by X2Engine".
  36. **********************************************************************************/
  37. /*
  38. Iframe-less version of the webtracker
  39. The legacy version of webtracker is in webListener.php.
  40. This script generates a key as soon as someone visits the page. The key as well as the referring
  41. url get sent to the server where, if the visitor is a contact, they'll be tracked.
  42. */
  43. // prevent browser errors caused by strict MIME type checking
  44. header('Content-type: application/javascript');
  45. ?>
  46. var x2WebTracker = {};
  47. <?php
  48. /**
  49. * Send key and url to server by creating a new script node which points to the desired action.
  50. * If x2GETKey is set, send that to the server as well.
  51. *
  52. * @param url string The url of the server on which the CRM is running
  53. * @param string x2GETKey The key (tracking link or campaign click) sent in the GET parameters.
  54. */
  55. ?>
  56. /**
  57. * Constructs the weblistener url
  58. * @return string
  59. */
  60. x2WebTracker.getSendKeyUrl = function () {
  61. return '<?php
  62. $protocol = !empty ($_SERVER['HTTPS']) ? 'https' : 'http';
  63. $baseUrl = $protocol . '://' . $_SERVER['HTTP_HOST'];
  64. $path = preg_replace ("/\/webTracker\.php/", '', $_SERVER['REQUEST_URI']);
  65. if ($path) $baseUrl .= $path;
  66. echo $baseUrl;
  67. ?>/<?php echo (defined ('FUNCTIONAL_TEST') && constant ('FUNCTIONAL_TEST') ?
  68. 'index-test.php' : 'index.php');
  69. ?>/api/webListener';
  70. };
  71. /**
  72. * Structures the parameters which will get sent to the weblistener action, either as a query
  73. * string or as a dictionary
  74. * @param object args
  75. * @param string method ('GET'|'POST')
  76. * @return object|string
  77. */
  78. x2WebTracker.getSendKeyParams = function (args, method) {
  79. var x2GETKey = args['x2KeyGetParam'];
  80. var url = args['url'];
  81. var attributes;
  82. var fingerprint = args['fingerprint']
  83. if (typeof fingerprint !== 'undefined') {
  84. // Ensure fingerprint data has valid keys: these will not be set
  85. // at this point if the client has DNT set
  86. if (typeof fingerprint['attributes'] !== 'undefined')
  87. attributes = fingerprint['attributes'];
  88. if (typeof fingerprint['fingerprint'] !== 'undefined')
  89. fingerprint = fingerprint['fingerprint'];
  90. }
  91. var params = {
  92. url: (method === 'GET') ? encodeURIComponent (url) : url,
  93. fingerprint: fingerprint,
  94. /*attributes: (method === 'GET') ? encodeURIComponent (fingerprint['attributes']) :
  95. fingerprint['attributes'],*/
  96. };
  97. if (x2GETKey !== null)
  98. params['get_key'] = (method === 'GET') ? encodeURIComponent (x2GETKey) : x2GETKey
  99. for (var fingerprintAttr in attributes) {
  100. params[fingerprintAttr] = (method === 'GET' ?
  101. encodeURIComponent (attributes[fingerprintAttr]) :
  102. attributes[fingerprintAttr]);
  103. }
  104. if (method === 'GET') {
  105. var queryString = '';
  106. var i = 0;
  107. for (var paramName in params) {
  108. if (i++ === 0) {
  109. queryString += '?';
  110. } else {
  111. queryString += '&';
  112. }
  113. queryString += paramName + '=' + params[paramName];
  114. }
  115. return queryString;
  116. } else {
  117. return params;
  118. }
  119. };
  120. /**
  121. * Sends the tracking information to the server using a script tag
  122. */
  123. x2WebTracker.sendKeyNoCORS = function (args) {
  124. var sendKeyScript = document.createElement ('script');
  125. sendKeyScript.setAttribute (
  126. 'src', x2WebTracker.getSendKeyUrl () + x2WebTracker.getSendKeyParams (args, 'GET'),
  127. true);
  128. document.getElementsByTagName("head")[0].appendChild(sendKeyScript);
  129. };
  130. /**
  131. * Sends tracking information to the server using an AJAX request if CORS is supported by browser.
  132. * Falls back on sendKey ().
  133. */
  134. x2WebTracker.sendKey = function (args) {
  135. x2WebTracker.sendKeyNoCORS (args);
  136. };
  137. <?php
  138. /**
  139. * Generate and return a 32 character key
  140. */
  141. ?>
  142. x2WebTracker.generateKey = function () {
  143. var chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  144. var key = '';
  145. for(var i = 0; i < 32; ++i) {
  146. key += chars.charAt (parseInt (Math.floor (Math.random () * chars.length)));
  147. }
  148. //console.log ('key = ' + key);
  149. return key;
  150. };
  151. <?php
  152. /**
  153. * Set the key cookie with an expiration date 1 year in the future
  154. */
  155. ?>
  156. x2WebTracker.setKeyCookie = function (key) {
  157. // Remove a subdomain if present
  158. if (document.domain.split('.').length > 2)
  159. var domain = document.domain.replace (/^[^.]*/, '');
  160. else
  161. var domain = document.domain;
  162. document.cookie = "x2_key=" + key +
  163. ";expires=" + (new Date (+new Date () + 31556940000)).toGMTString () +
  164. ";path=/;domain=" + domain;
  165. };
  166. <?php
  167. /**
  168. * Detects a hidden key cookie input fields and populates it with the cookie key. The purpose of
  169. * this function is to enable tracking for users who have custom web lead forms that submit via
  170. * the web lead form API.
  171. */
  172. ?>
  173. x2WebTracker.setKeyCookieHiddenField = function (key) {
  174. document.onreadystatechange = function () {
  175. if (document.readyState === 'complete') {
  176. var hiddenFields = document.getElementsByName ('x2_key');
  177. if (hiddenFields.length > 0) {
  178. var hiddenField = hiddenFields[0];
  179. hiddenField.setAttribute ('value', key);
  180. }
  181. }
  182. }
  183. };
  184. (x2WebTracker.main = function () {
  185. var url = window.location.href;
  186. <?php ?>
  187. var fingerprint;
  188. <?php if (!isset ($_SERVER['HTTP_DNT']) || $_SERVER['HTTP_DNT'] != 1) {
  189. require(__DIR__.'/js/fontdetect.js');
  190. require(__DIR__.'/js/X2Identity.js'); ?>
  191. fingerprint = x2Identity.fingerprint();
  192. <?php } ?>
  193. <?php ?>
  194. <?php
  195. /*
  196. Tracking campaign clicks and tracking links take precedence. If its GET key is set, generate
  197. a new key for tracking and send the GET key to the server for lookup.
  198. */
  199. ?>
  200. var getParamRegex = /(?:^[?]|[?].*[?&])x2_key=([^&]+)/;
  201. if (window.location.search && window.location.search.match (getParamRegex)) {
  202. var x2KeyGetParam = window.location.search.replace (getParamRegex, '$1');
  203. if (x2KeyGetParam.match (/[a-zA-Z0-9]/)) {
  204. var x2KeyCookie = x2WebTracker.generateKey ();
  205. x2WebTracker.setKeyCookie (x2KeyCookie);
  206. x2WebTracker.sendKey ({
  207. url: url,
  208. x2KeyGetParam: x2KeyGetParam <?php ?>,
  209. fingerprint: fingerprint<?php ?>
  210. });
  211. x2WebTracker.setKeyCookieHiddenField (x2KeyGetParam);
  212. return;
  213. }
  214. }
  215. <?php // generate cookie key if there isn't one ?>
  216. var cookieRegex = /(?:^|.*;)\s*x2_key\s*=\s*([^;]*)(?:.*$|$)/;
  217. if (!document.cookie.match (cookieRegex)) {
  218. //console.log ('no cookie');
  219. var x2KeyCookie = x2WebTracker.generateKey ();
  220. x2WebTracker.setKeyCookie (x2KeyCookie);
  221. x2WebTracker.setKeyCookieHiddenField (x2KeyCookie);
  222. <?php ?>
  223. x2WebTracker.sendKey ({
  224. url: url,
  225. x2KeyGetParam: null,
  226. fingerprint: fingerprint
  227. });
  228. <?php ?>
  229. return;
  230. }
  231. <?php // there's a cookie key, request content ?>
  232. var x2KeyCookie = document.cookie.replace (cookieRegex, '$1');
  233. //console.log ('x2KeyCookie = ');
  234. //console.log ('1' + x2KeyCookie + '1');
  235. if (x2KeyCookie.match (/[a-zA-Z0-9]/)) {
  236. x2WebTracker.sendKey ({
  237. url: url,
  238. x2KeyGetParam: null <?php ?>,
  239. fingerprint: fingerprint<?php ?>
  240. });
  241. x2WebTracker.setKeyCookieHiddenField (x2KeyCookie);
  242. }
  243. }) ();