Version Description
- Updating docblocks for APIGen
- [Restored] Impression tracking was failing in select theme environments.
Download this release
Release Info
Developer | adbox |
Plugin | WordPress Landing Pages |
Version | 2.5.8 |
Comparing to | |
See all releases |
Code changes from version 2.5.7 to 2.5.8
- assets/tests/bin/phantomloader +0 -7
- assets/tests/bin/wpcept +0 -7
- assets/tests/build/php.conf +0 -4
- assets/tests/build/php.load +0 -1
- assets/tests/build/travis-ci-apache +0 -23
- assets/tests/codeception/_bootstrap.php +0 -14
- assets/tests/codeception/_data/dump.sql +0 -1
- assets/tests/codeception/_support/AcceptanceHelper.php +0 -10
- assets/tests/codeception/_support/FunctionalHelper.php +0 -10
- assets/tests/codeception/_support/UnitHelper.php +0 -10
- assets/tests/codeception/acceptance/AcceptanceTester.php +0 -1918
- assets/tests/codeception/acceptance/LoginCept.php +0 -48
- assets/tests/codeception/acceptance/StatisticsCept.php +0 -55
- assets/tests/codeception/acceptance/WelcomeCept.php +0 -7
- assets/tests/codeception/acceptance/_bootstrap.php +0 -2
- assets/tests/codeception/functional/FunctionalTester.php +0 -360
- assets/tests/codeception/functional/_bootstrap.php +0 -2
- assets/tests/codeception/unit/UnitTester.php +0 -300
- assets/tests/codeception/unit/_bootstrap.php +0 -2
- assets/tests/phpunit/bootstrap.php +0 -15
- assets/tests/phpunit/test.activations.php +0 -49
- assets/tests/travis-ci/test.statistics.php +0 -68
- classes/class.acf-integration.php +527 -527
- classes/class.activation.php +5 -2
- classes/class.activation.upgrade-routines.php +244 -251
- classes/class.admin-menus.php +3 -3
- classes/class.admin-notices.php +6 -0
- classes/class.click-tracking.php +0 -210
- classes/class.install.php +6 -0
- classes/class.landing-pages.php +7 -5
- classes/class.load-templates.php +5 -0
- classes/class.metaboxes.php +6 -1
- classes/class.post-type.landing-page.php +513 -509
- classes/class.postmeta.php +4 -1
- classes/class.row-actions.php +6 -0
- classes/class.settings.php +6 -0
- classes/class.sidebars.php +5 -1
- classes/class.statistics.php +178 -182
- classes/class.store.php +20 -170
- classes/class.template-management.php +5 -0
- classes/class.variations.php +600 -602
- classes/class.welcome.php +2 -6
- classes/class.widgets.php +8 -0
- classes/class.wp-list-table.templates.php +7 -0
- landing-pages.php +6 -3
- modules/module.redirect-ab-testing.php +7 -1
- modules/module.utils.php +9 -0
- readme.txt +5 -1
- shared/assets/js/admin/marketing-button.js +243 -243
- shared/assets/js/frontend/analytics-src/analytics.events.js +609 -609
- shared/assets/js/frontend/analytics-src/analytics.forms.js +1207 -1207
- shared/assets/js/frontend/analytics-src/analytics.hooks.js +404 -404
- shared/assets/js/frontend/analytics-src/analytics.init.js +130 -130
- shared/assets/js/frontend/analytics-src/analytics.page.js +394 -393
- shared/assets/js/frontend/analytics-src/analytics.start.js +17 -17
- shared/assets/js/frontend/analytics-src/analytics.utils.js +858 -858
- shared/assets/js/frontend/analytics/inboundAnalytics.js +3847 -3846
- shared/assets/js/frontend/analytics/inboundAnalytics.min.js +2 -2
- shared/assets/js/global/debug.js +0 -37
- shared/assets/js/global/inbound-dequeue-scripts.js +0 -49
- shared/classes/class.acf-bootstrap.php +93 -87
- shared/classes/class.ajax.php +153 -164
- shared/classes/class.confirm-double-optin.php +200 -194
- shared/classes/class.database-routines.php +312 -312
assets/tests/bin/phantomloader
DELETED
@@ -1,7 +0,0 @@
|
|
1 |
-
#!/usr/bin/env sh
|
2 |
-
SRC_DIR="`pwd`"
|
3 |
-
cd "`dirname "$0"`"
|
4 |
-
cd "../../vendor/jonnyw/php-phantomjs/bin"
|
5 |
-
BIN_TARGET="`pwd`/phantomloader"
|
6 |
-
cd "$SRC_DIR"
|
7 |
-
"$BIN_TARGET" "$@"
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
assets/tests/bin/wpcept
DELETED
@@ -1,7 +0,0 @@
|
|
1 |
-
#!/usr/bin/env sh
|
2 |
-
SRC_DIR="`pwd`"
|
3 |
-
cd "`dirname "$0"`"
|
4 |
-
cd "../../vendor/lucatume/wp-browser"
|
5 |
-
BIN_TARGET="`pwd`/wpcept"
|
6 |
-
cd "$SRC_DIR"
|
7 |
-
"$BIN_TARGET" "$@"
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
assets/tests/build/php.conf
DELETED
@@ -1,4 +0,0 @@
|
|
1 |
-
<IfModule mod_php5.c>
|
2 |
-
AddType application/x-httpd-php .php .phtml .php5
|
3 |
-
AddType application/x-httpd-php-source .phps
|
4 |
-
</IfModule>
|
Â
|
|
Â
|
|
Â
|
|
Â
|
assets/tests/build/php.load
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
LoadModule php5_module /usr/lib/apache2/modules/libphp5.so
|
Â
|
assets/tests/build/travis-ci-apache
DELETED
@@ -1,23 +0,0 @@
|
|
1 |
-
<VirtualHost *:80>
|
2 |
-
ServerAdmin tests@inboundnow.com
|
3 |
-
DocumentRoot /var/www/inboundtesting.dev/
|
4 |
-
ServerName inboundtesting.dev
|
5 |
-
ErrorLog ${APACHE_LOG_DIR}/error.log
|
6 |
-
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
7 |
-
|
8 |
-
# Wire up Apache to use Travis CI's php-fpm.
|
9 |
-
<IfModule mod_fastcgi.c>
|
10 |
-
AddHandler php5-fcgi .php
|
11 |
-
Action php5-fcgi /php5-fcgi
|
12 |
-
Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
|
13 |
-
FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization
|
14 |
-
</IfModule>
|
15 |
-
|
16 |
-
<Directory "/var/www/inboundtesting.dev/">
|
17 |
-
Options FollowSymLinks MultiViews ExecCGI
|
18 |
-
AllowOverride All
|
19 |
-
Order deny,allow
|
20 |
-
Allow from all
|
21 |
-
</Directory>
|
22 |
-
</VirtualHost>
|
23 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
assets/tests/codeception/_bootstrap.php
DELETED
@@ -1,14 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
-
/* load wp */
|
5 |
-
require '../../../wp-load.php';
|
6 |
-
require '../../../wp-admin/includes/plugin.php';
|
7 |
-
|
8 |
-
/* load coception addons */
|
9 |
-
require LANDINGPAGES_PATH . 'vendor/lucatume/wp-browser/src/Codeception/Module/WPBrowserMethods.php';
|
10 |
-
require LANDINGPAGES_PATH . 'vendor/lucatume/wp-browser/src/Codeception/Module/WPBrowser.php';
|
11 |
-
|
12 |
-
/* Set current users */
|
13 |
-
wp_set_current_user( 1 );
|
14 |
-
global $wpdb;
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
assets/tests/codeception/_data/dump.sql
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
/* Replace this file with actual dump of your database */
|
Â
|
assets/tests/codeception/_support/AcceptanceHelper.php
DELETED
@@ -1,10 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Codeception\Module;
|
3 |
-
|
4 |
-
// here you can define custom actions
|
5 |
-
// all public methods declared in helper class will be available in $I
|
6 |
-
|
7 |
-
class AcceptanceHelper extends \Codeception\Module
|
8 |
-
{
|
9 |
-
|
10 |
-
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
assets/tests/codeception/_support/FunctionalHelper.php
DELETED
@@ -1,10 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Codeception\Module;
|
3 |
-
|
4 |
-
// here you can define custom actions
|
5 |
-
// all public methods declared in helper class will be available in $I
|
6 |
-
|
7 |
-
class FunctionalHelper extends \Codeception\Module
|
8 |
-
{
|
9 |
-
|
10 |
-
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
assets/tests/codeception/_support/UnitHelper.php
DELETED
@@ -1,10 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
namespace Codeception\Module;
|
3 |
-
|
4 |
-
// here you can define custom actions
|
5 |
-
// all public methods declared in helper class will be available in $I
|
6 |
-
|
7 |
-
class UnitHelper extends \Codeception\Module
|
8 |
-
{
|
9 |
-
|
10 |
-
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
assets/tests/codeception/acceptance/AcceptanceTester.php
DELETED
@@ -1,1918 +0,0 @@
|
|
1 |
-
<?php //[STAMP] 2d5aa64986f8f94bc0f812d88aa9dee6
|
2 |
-
|
3 |
-
// This class was automatically generated by build task
|
4 |
-
// You should not change it manually as it will be overwritten on next build
|
5 |
-
// @codingStandardsIgnoreFile
|
6 |
-
|
7 |
-
|
8 |
-
use Codeception\Module\PhpBrowser;
|
9 |
-
use Codeception\Module\AcceptanceHelper;
|
10 |
-
|
11 |
-
/**
|
12 |
-
* Inherited Methods
|
13 |
-
* @method void wantToTest($text)
|
14 |
-
* @method void wantTo($text)
|
15 |
-
* @method void execute($callable)
|
16 |
-
* @method void expectTo($prediction)
|
17 |
-
* @method void expect($prediction)
|
18 |
-
* @method void amGoingTo($argumentation)
|
19 |
-
* @method void am($role)
|
20 |
-
* @method void lookForwardTo($achieveValue)
|
21 |
-
* @method void comment($description)
|
22 |
-
* @method void haveFriend($name, $actorClass = null)
|
23 |
-
*
|
24 |
-
* @SuppressWarnings(PHPMD)
|
25 |
-
*/
|
26 |
-
class AcceptanceTester extends \Codeception\Actor
|
27 |
-
{
|
28 |
-
|
29 |
-
/**
|
30 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
31 |
-
*
|
32 |
-
* Sets the HTTP header to the passed value - which is used on
|
33 |
-
* subsequent HTTP requests through PhpBrowser.
|
34 |
-
*
|
35 |
-
* Example:
|
36 |
-
* ```php
|
37 |
-
* <?php
|
38 |
-
* $I->setHeader('X-Requested-With', 'Codeception');
|
39 |
-
* $I->amOnPage('test-headers.php');
|
40 |
-
* ?>
|
41 |
-
* ```
|
42 |
-
*
|
43 |
-
* @param string $name the name of the request header
|
44 |
-
* @param string $value the value to set it to for subsequent
|
45 |
-
* requests
|
46 |
-
* @see \Codeception\Module\PhpBrowser::setHeader()
|
47 |
-
*/
|
48 |
-
public function setHeader($name, $value) {
|
49 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('setHeader', func_get_args()));
|
50 |
-
}
|
51 |
-
|
52 |
-
|
53 |
-
/**
|
54 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
55 |
-
*
|
56 |
-
* Deletes the header with the passed name. Subsequent requests
|
57 |
-
* will not have the deleted header in its request.
|
58 |
-
*
|
59 |
-
* Example:
|
60 |
-
* ```php
|
61 |
-
* <?php
|
62 |
-
* $I->setHeader('X-Requested-With', 'Codeception');
|
63 |
-
* $I->amOnPage('test-headers.php');
|
64 |
-
* // ...
|
65 |
-
* $I->deleteHeader('X-Requested-With');
|
66 |
-
* $I->amOnPage('some-other-page.php');
|
67 |
-
* ?>
|
68 |
-
* ```
|
69 |
-
*
|
70 |
-
* @param string $name the name of the header to delete.
|
71 |
-
* @see \Codeception\Module\PhpBrowser::deleteHeader()
|
72 |
-
*/
|
73 |
-
public function deleteHeader($name) {
|
74 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('deleteHeader', func_get_args()));
|
75 |
-
}
|
76 |
-
|
77 |
-
|
78 |
-
/**
|
79 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
80 |
-
*
|
81 |
-
* Authenticates user for HTTP_AUTH
|
82 |
-
*
|
83 |
-
* @param $username
|
84 |
-
* @param $password
|
85 |
-
* @see \Codeception\Module\PhpBrowser::amHttpAuthenticated()
|
86 |
-
*/
|
87 |
-
public function amHttpAuthenticated($username, $password) {
|
88 |
-
return $this->scenario->runStep(new \Codeception\Step\Condition('amHttpAuthenticated', func_get_args()));
|
89 |
-
}
|
90 |
-
|
91 |
-
|
92 |
-
/**
|
93 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
94 |
-
*
|
95 |
-
* Opens the page for the given relative URI.
|
96 |
-
*
|
97 |
-
* ``` php
|
98 |
-
* <?php
|
99 |
-
* // opens front page
|
100 |
-
* $I->amOnPage('/');
|
101 |
-
* // opens /register page
|
102 |
-
* $I->amOnPage('/register');
|
103 |
-
* ?>
|
104 |
-
* ```
|
105 |
-
*
|
106 |
-
* @param $page
|
107 |
-
* @see \Codeception\Module\PhpBrowser::amOnPage()
|
108 |
-
*/
|
109 |
-
public function amOnPage($page) {
|
110 |
-
return $this->scenario->runStep(new \Codeception\Step\Condition('amOnPage', func_get_args()));
|
111 |
-
}
|
112 |
-
|
113 |
-
|
114 |
-
/**
|
115 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
116 |
-
*
|
117 |
-
* Open web page at the given absolute URL and sets its hostname as the base host.
|
118 |
-
*
|
119 |
-
* ``` php
|
120 |
-
* <?php
|
121 |
-
* $I->amOnUrl('http://codeception.com');
|
122 |
-
* $I->amOnPage('/quickstart'); // moves to http://codeception.com/quickstart
|
123 |
-
* ?>
|
124 |
-
* ```
|
125 |
-
* @see \Codeception\Module\PhpBrowser::amOnUrl()
|
126 |
-
*/
|
127 |
-
public function amOnUrl($url) {
|
128 |
-
return $this->scenario->runStep(new \Codeception\Step\Condition('amOnUrl', func_get_args()));
|
129 |
-
}
|
130 |
-
|
131 |
-
|
132 |
-
/**
|
133 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
134 |
-
*
|
135 |
-
* Changes the subdomain for the 'url' configuration parameter.
|
136 |
-
* Does not open a page; use `amOnPage` for that.
|
137 |
-
*
|
138 |
-
* ``` php
|
139 |
-
* <?php
|
140 |
-
* // If config is: 'http://mysite.com'
|
141 |
-
* // or config is: 'http://www.mysite.com'
|
142 |
-
* // or config is: 'http://company.mysite.com'
|
143 |
-
*
|
144 |
-
* $I->amOnSubdomain('user');
|
145 |
-
* $I->amOnPage('/');
|
146 |
-
* // moves to http://user.mysite.com/
|
147 |
-
* ?>
|
148 |
-
* ```
|
149 |
-
*
|
150 |
-
* @param $subdomain
|
151 |
-
*
|
152 |
-
* @return mixed
|
153 |
-
* @see \Codeception\Module\PhpBrowser::amOnSubdomain()
|
154 |
-
*/
|
155 |
-
public function amOnSubdomain($subdomain) {
|
156 |
-
return $this->scenario->runStep(new \Codeception\Step\Condition('amOnSubdomain', func_get_args()));
|
157 |
-
}
|
158 |
-
|
159 |
-
|
160 |
-
/**
|
161 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
162 |
-
*
|
163 |
-
* Low-level API method.
|
164 |
-
* If Codeception commands are not enough, use [Guzzle HTTP Client](http://guzzlephp.org/) methods directly
|
165 |
-
*
|
166 |
-
* Example:
|
167 |
-
*
|
168 |
-
* ``` php
|
169 |
-
* <?php
|
170 |
-
* $I->executeInGuzzle(function (\GuzzleHttp\Client $client) {
|
171 |
-
* $client->get('/get', ['query' => ['foo' => 'bar']]);
|
172 |
-
* });
|
173 |
-
* ?>
|
174 |
-
* ```
|
175 |
-
*
|
176 |
-
* It is not recommended to use this command on a regular basis.
|
177 |
-
* If Codeception lacks important Guzzle Client methods, implement them and submit patches.
|
178 |
-
*
|
179 |
-
* @param callable $function
|
180 |
-
* @see \Codeception\Module\PhpBrowser::executeInGuzzle()
|
181 |
-
*/
|
182 |
-
public function executeInGuzzle($function) {
|
183 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('executeInGuzzle', func_get_args()));
|
184 |
-
}
|
185 |
-
|
186 |
-
|
187 |
-
/**
|
188 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
189 |
-
*
|
190 |
-
* Perform a click on a link or a button, given by a locator.
|
191 |
-
* If a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.
|
192 |
-
* For buttons, the "value" attribute, "name" attribute, and inner text are searched.
|
193 |
-
* For links, the link text is searched.
|
194 |
-
* For images, the "alt" attribute and inner text of any parent links are searched.
|
195 |
-
*
|
196 |
-
* The second parameter is a context (CSS or XPath locator) to narrow the search.
|
197 |
-
*
|
198 |
-
* Note that if the locator matches a button of type `submit`, the form will be submitted.
|
199 |
-
*
|
200 |
-
* ``` php
|
201 |
-
* <?php
|
202 |
-
* // simple link
|
203 |
-
* $I->click('Logout');
|
204 |
-
* // button of form
|
205 |
-
* $I->click('Submit');
|
206 |
-
* // CSS button
|
207 |
-
* $I->click('#form input[type=submit]');
|
208 |
-
* // XPath
|
209 |
-
* $I->click('//form/*[@type=submit]');
|
210 |
-
* // link in context
|
211 |
-
* $I->click('Logout', '#nav');
|
212 |
-
* // using strict locator
|
213 |
-
* $I->click(['link' => 'Login']);
|
214 |
-
* ?>
|
215 |
-
* ```
|
216 |
-
*
|
217 |
-
* @param $link
|
218 |
-
* @param $context
|
219 |
-
* @see \Codeception\Lib\InnerBrowser::click()
|
220 |
-
*/
|
221 |
-
public function click($link, $context = null) {
|
222 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('click', func_get_args()));
|
223 |
-
}
|
224 |
-
|
225 |
-
|
226 |
-
/**
|
227 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
228 |
-
*
|
229 |
-
* Checks that the current page contains the given string.
|
230 |
-
* Specify a locator as the second parameter to match a specific region.
|
231 |
-
*
|
232 |
-
* ``` php
|
233 |
-
* <?php
|
234 |
-
* $I->see('Logout'); // I can suppose user is logged in
|
235 |
-
* $I->see('Sign Up','h1'); // I can suppose it's a signup page
|
236 |
-
* $I->see('Sign Up','//body/h1'); // with XPath
|
237 |
-
* ?>
|
238 |
-
* ```
|
239 |
-
*
|
240 |
-
* @param $text
|
241 |
-
* @param null $selector
|
242 |
-
* Conditional Assertion: Test won't be stopped on fail
|
243 |
-
* @see \Codeception\Lib\InnerBrowser::see()
|
244 |
-
*/
|
245 |
-
public function canSee($text, $selector = null) {
|
246 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('see', func_get_args()));
|
247 |
-
}
|
248 |
-
/**
|
249 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
250 |
-
*
|
251 |
-
* Checks that the current page contains the given string.
|
252 |
-
* Specify a locator as the second parameter to match a specific region.
|
253 |
-
*
|
254 |
-
* ``` php
|
255 |
-
* <?php
|
256 |
-
* $I->see('Logout'); // I can suppose user is logged in
|
257 |
-
* $I->see('Sign Up','h1'); // I can suppose it's a signup page
|
258 |
-
* $I->see('Sign Up','//body/h1'); // with XPath
|
259 |
-
* ?>
|
260 |
-
* ```
|
261 |
-
*
|
262 |
-
* @param $text
|
263 |
-
* @param null $selector
|
264 |
-
* @see \Codeception\Lib\InnerBrowser::see()
|
265 |
-
*/
|
266 |
-
public function see($text, $selector = null) {
|
267 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('see', func_get_args()));
|
268 |
-
}
|
269 |
-
|
270 |
-
|
271 |
-
/**
|
272 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
273 |
-
*
|
274 |
-
* Checks that the current page doesn't contain the text specified.
|
275 |
-
* Give a locator as the second parameter to match a specific region.
|
276 |
-
*
|
277 |
-
* ```php
|
278 |
-
* <?php
|
279 |
-
* $I->dontSee('Login'); // I can suppose user is already logged in
|
280 |
-
* $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page
|
281 |
-
* $I->dontSee('Sign Up','//body/h1'); // with XPath
|
282 |
-
* ?>
|
283 |
-
* ```
|
284 |
-
*
|
285 |
-
* @param $text
|
286 |
-
* @param null $selector
|
287 |
-
* Conditional Assertion: Test won't be stopped on fail
|
288 |
-
* @see \Codeception\Lib\InnerBrowser::dontSee()
|
289 |
-
*/
|
290 |
-
public function cantSee($text, $selector = null) {
|
291 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSee', func_get_args()));
|
292 |
-
}
|
293 |
-
/**
|
294 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
295 |
-
*
|
296 |
-
* Checks that the current page doesn't contain the text specified.
|
297 |
-
* Give a locator as the second parameter to match a specific region.
|
298 |
-
*
|
299 |
-
* ```php
|
300 |
-
* <?php
|
301 |
-
* $I->dontSee('Login'); // I can suppose user is already logged in
|
302 |
-
* $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page
|
303 |
-
* $I->dontSee('Sign Up','//body/h1'); // with XPath
|
304 |
-
* ?>
|
305 |
-
* ```
|
306 |
-
*
|
307 |
-
* @param $text
|
308 |
-
* @param null $selector
|
309 |
-
* @see \Codeception\Lib\InnerBrowser::dontSee()
|
310 |
-
*/
|
311 |
-
public function dontSee($text, $selector = null) {
|
312 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSee', func_get_args()));
|
313 |
-
}
|
314 |
-
|
315 |
-
|
316 |
-
/**
|
317 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
318 |
-
*
|
319 |
-
* Checks that there's a link with the specified text.
|
320 |
-
* Give a full URL as the second parameter to match links with that exact URL.
|
321 |
-
*
|
322 |
-
* ``` php
|
323 |
-
* <?php
|
324 |
-
* $I->seeLink('Logout'); // matches <a href="#">Logout</a>
|
325 |
-
* $I->seeLink('Logout','/logout'); // matches <a href="/logout">Logout</a>
|
326 |
-
* ?>
|
327 |
-
* ```
|
328 |
-
*
|
329 |
-
* @param $text
|
330 |
-
* @param null $url
|
331 |
-
* Conditional Assertion: Test won't be stopped on fail
|
332 |
-
* @see \Codeception\Lib\InnerBrowser::seeLink()
|
333 |
-
*/
|
334 |
-
public function canSeeLink($text, $url = null) {
|
335 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeLink', func_get_args()));
|
336 |
-
}
|
337 |
-
/**
|
338 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
339 |
-
*
|
340 |
-
* Checks that there's a link with the specified text.
|
341 |
-
* Give a full URL as the second parameter to match links with that exact URL.
|
342 |
-
*
|
343 |
-
* ``` php
|
344 |
-
* <?php
|
345 |
-
* $I->seeLink('Logout'); // matches <a href="#">Logout</a>
|
346 |
-
* $I->seeLink('Logout','/logout'); // matches <a href="/logout">Logout</a>
|
347 |
-
* ?>
|
348 |
-
* ```
|
349 |
-
*
|
350 |
-
* @param $text
|
351 |
-
* @param null $url
|
352 |
-
* @see \Codeception\Lib\InnerBrowser::seeLink()
|
353 |
-
*/
|
354 |
-
public function seeLink($text, $url = null) {
|
355 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('seeLink', func_get_args()));
|
356 |
-
}
|
357 |
-
|
358 |
-
|
359 |
-
/**
|
360 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
361 |
-
*
|
362 |
-
* Checks that the page doesn't contain a link with the given string.
|
363 |
-
* If the second parameter is given, only links with a matching "href" attribute will be checked.
|
364 |
-
*
|
365 |
-
* ``` php
|
366 |
-
* <?php
|
367 |
-
* $I->dontSeeLink('Logout'); // I suppose user is not logged in
|
368 |
-
* $I->dontSeeLink('Checkout now', '/store/cart.php');
|
369 |
-
* ?>
|
370 |
-
* ```
|
371 |
-
*
|
372 |
-
* @param $text
|
373 |
-
* @param null $url
|
374 |
-
* Conditional Assertion: Test won't be stopped on fail
|
375 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeLink()
|
376 |
-
*/
|
377 |
-
public function cantSeeLink($text, $url = null) {
|
378 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeLink', func_get_args()));
|
379 |
-
}
|
380 |
-
/**
|
381 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
382 |
-
*
|
383 |
-
* Checks that the page doesn't contain a link with the given string.
|
384 |
-
* If the second parameter is given, only links with a matching "href" attribute will be checked.
|
385 |
-
*
|
386 |
-
* ``` php
|
387 |
-
* <?php
|
388 |
-
* $I->dontSeeLink('Logout'); // I suppose user is not logged in
|
389 |
-
* $I->dontSeeLink('Checkout now', '/store/cart.php');
|
390 |
-
* ?>
|
391 |
-
* ```
|
392 |
-
*
|
393 |
-
* @param $text
|
394 |
-
* @param null $url
|
395 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeLink()
|
396 |
-
*/
|
397 |
-
public function dontSeeLink($text, $url = null) {
|
398 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeLink', func_get_args()));
|
399 |
-
}
|
400 |
-
|
401 |
-
|
402 |
-
/**
|
403 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
404 |
-
*
|
405 |
-
* Checks that current URI contains the given string.
|
406 |
-
*
|
407 |
-
* ``` php
|
408 |
-
* <?php
|
409 |
-
* // to match: /home/dashboard
|
410 |
-
* $I->seeInCurrentUrl('home');
|
411 |
-
* // to match: /users/1
|
412 |
-
* $I->seeInCurrentUrl('/users/');
|
413 |
-
* ?>
|
414 |
-
* ```
|
415 |
-
*
|
416 |
-
* @param $uri
|
417 |
-
* Conditional Assertion: Test won't be stopped on fail
|
418 |
-
* @see \Codeception\Lib\InnerBrowser::seeInCurrentUrl()
|
419 |
-
*/
|
420 |
-
public function canSeeInCurrentUrl($uri) {
|
421 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeInCurrentUrl', func_get_args()));
|
422 |
-
}
|
423 |
-
/**
|
424 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
425 |
-
*
|
426 |
-
* Checks that current URI contains the given string.
|
427 |
-
*
|
428 |
-
* ``` php
|
429 |
-
* <?php
|
430 |
-
* // to match: /home/dashboard
|
431 |
-
* $I->seeInCurrentUrl('home');
|
432 |
-
* // to match: /users/1
|
433 |
-
* $I->seeInCurrentUrl('/users/');
|
434 |
-
* ?>
|
435 |
-
* ```
|
436 |
-
*
|
437 |
-
* @param $uri
|
438 |
-
* @see \Codeception\Lib\InnerBrowser::seeInCurrentUrl()
|
439 |
-
*/
|
440 |
-
public function seeInCurrentUrl($uri) {
|
441 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('seeInCurrentUrl', func_get_args()));
|
442 |
-
}
|
443 |
-
|
444 |
-
|
445 |
-
/**
|
446 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
447 |
-
*
|
448 |
-
* Checks that the current URI doesn't contain the given string.
|
449 |
-
*
|
450 |
-
* ``` php
|
451 |
-
* <?php
|
452 |
-
* $I->dontSeeInCurrentUrl('/users/');
|
453 |
-
* ?>
|
454 |
-
* ```
|
455 |
-
*
|
456 |
-
* @param $uri
|
457 |
-
* Conditional Assertion: Test won't be stopped on fail
|
458 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeInCurrentUrl()
|
459 |
-
*/
|
460 |
-
public function cantSeeInCurrentUrl($uri) {
|
461 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInCurrentUrl', func_get_args()));
|
462 |
-
}
|
463 |
-
/**
|
464 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
465 |
-
*
|
466 |
-
* Checks that the current URI doesn't contain the given string.
|
467 |
-
*
|
468 |
-
* ``` php
|
469 |
-
* <?php
|
470 |
-
* $I->dontSeeInCurrentUrl('/users/');
|
471 |
-
* ?>
|
472 |
-
* ```
|
473 |
-
*
|
474 |
-
* @param $uri
|
475 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeInCurrentUrl()
|
476 |
-
*/
|
477 |
-
public function dontSeeInCurrentUrl($uri) {
|
478 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeInCurrentUrl', func_get_args()));
|
479 |
-
}
|
480 |
-
|
481 |
-
|
482 |
-
/**
|
483 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
484 |
-
*
|
485 |
-
* Checks that the current URL is equal to the given string.
|
486 |
-
* Unlike `seeInCurrentUrl`, this only matches the full URL.
|
487 |
-
*
|
488 |
-
* ``` php
|
489 |
-
* <?php
|
490 |
-
* // to match root url
|
491 |
-
* $I->seeCurrentUrlEquals('/');
|
492 |
-
* ?>
|
493 |
-
* ```
|
494 |
-
*
|
495 |
-
* @param $uri
|
496 |
-
* Conditional Assertion: Test won't be stopped on fail
|
497 |
-
* @see \Codeception\Lib\InnerBrowser::seeCurrentUrlEquals()
|
498 |
-
*/
|
499 |
-
public function canSeeCurrentUrlEquals($uri) {
|
500 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeCurrentUrlEquals', func_get_args()));
|
501 |
-
}
|
502 |
-
/**
|
503 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
504 |
-
*
|
505 |
-
* Checks that the current URL is equal to the given string.
|
506 |
-
* Unlike `seeInCurrentUrl`, this only matches the full URL.
|
507 |
-
*
|
508 |
-
* ``` php
|
509 |
-
* <?php
|
510 |
-
* // to match root url
|
511 |
-
* $I->seeCurrentUrlEquals('/');
|
512 |
-
* ?>
|
513 |
-
* ```
|
514 |
-
*
|
515 |
-
* @param $uri
|
516 |
-
* @see \Codeception\Lib\InnerBrowser::seeCurrentUrlEquals()
|
517 |
-
*/
|
518 |
-
public function seeCurrentUrlEquals($uri) {
|
519 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('seeCurrentUrlEquals', func_get_args()));
|
520 |
-
}
|
521 |
-
|
522 |
-
|
523 |
-
/**
|
524 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
525 |
-
*
|
526 |
-
* Checks that the current URL doesn't equal the given string.
|
527 |
-
* Unlike `dontSeeInCurrentUrl`, this only matches the full URL.
|
528 |
-
*
|
529 |
-
* ``` php
|
530 |
-
* <?php
|
531 |
-
* // current url is not root
|
532 |
-
* $I->dontSeeCurrentUrlEquals('/');
|
533 |
-
* ?>
|
534 |
-
* ```
|
535 |
-
*
|
536 |
-
* @param $uri
|
537 |
-
* Conditional Assertion: Test won't be stopped on fail
|
538 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlEquals()
|
539 |
-
*/
|
540 |
-
public function cantSeeCurrentUrlEquals($uri) {
|
541 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCurrentUrlEquals', func_get_args()));
|
542 |
-
}
|
543 |
-
/**
|
544 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
545 |
-
*
|
546 |
-
* Checks that the current URL doesn't equal the given string.
|
547 |
-
* Unlike `dontSeeInCurrentUrl`, this only matches the full URL.
|
548 |
-
*
|
549 |
-
* ``` php
|
550 |
-
* <?php
|
551 |
-
* // current url is not root
|
552 |
-
* $I->dontSeeCurrentUrlEquals('/');
|
553 |
-
* ?>
|
554 |
-
* ```
|
555 |
-
*
|
556 |
-
* @param $uri
|
557 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlEquals()
|
558 |
-
*/
|
559 |
-
public function dontSeeCurrentUrlEquals($uri) {
|
560 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeCurrentUrlEquals', func_get_args()));
|
561 |
-
}
|
562 |
-
|
563 |
-
|
564 |
-
/**
|
565 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
566 |
-
*
|
567 |
-
* Checks that the current URL matches the given regular expression.
|
568 |
-
*
|
569 |
-
* ``` php
|
570 |
-
* <?php
|
571 |
-
* // to match root url
|
572 |
-
* $I->seeCurrentUrlMatches('~$/users/(\d+)~');
|
573 |
-
* ?>
|
574 |
-
* ```
|
575 |
-
*
|
576 |
-
* @param $uri
|
577 |
-
* Conditional Assertion: Test won't be stopped on fail
|
578 |
-
* @see \Codeception\Lib\InnerBrowser::seeCurrentUrlMatches()
|
579 |
-
*/
|
580 |
-
public function canSeeCurrentUrlMatches($uri) {
|
581 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeCurrentUrlMatches', func_get_args()));
|
582 |
-
}
|
583 |
-
/**
|
584 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
585 |
-
*
|
586 |
-
* Checks that the current URL matches the given regular expression.
|
587 |
-
*
|
588 |
-
* ``` php
|
589 |
-
* <?php
|
590 |
-
* // to match root url
|
591 |
-
* $I->seeCurrentUrlMatches('~$/users/(\d+)~');
|
592 |
-
* ?>
|
593 |
-
* ```
|
594 |
-
*
|
595 |
-
* @param $uri
|
596 |
-
* @see \Codeception\Lib\InnerBrowser::seeCurrentUrlMatches()
|
597 |
-
*/
|
598 |
-
public function seeCurrentUrlMatches($uri) {
|
599 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('seeCurrentUrlMatches', func_get_args()));
|
600 |
-
}
|
601 |
-
|
602 |
-
|
603 |
-
/**
|
604 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
605 |
-
*
|
606 |
-
* Checks that current url doesn't match the given regular expression.
|
607 |
-
*
|
608 |
-
* ``` php
|
609 |
-
* <?php
|
610 |
-
* // to match root url
|
611 |
-
* $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~');
|
612 |
-
* ?>
|
613 |
-
* ```
|
614 |
-
*
|
615 |
-
* @param $uri
|
616 |
-
* Conditional Assertion: Test won't be stopped on fail
|
617 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlMatches()
|
618 |
-
*/
|
619 |
-
public function cantSeeCurrentUrlMatches($uri) {
|
620 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCurrentUrlMatches', func_get_args()));
|
621 |
-
}
|
622 |
-
/**
|
623 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
624 |
-
*
|
625 |
-
* Checks that current url doesn't match the given regular expression.
|
626 |
-
*
|
627 |
-
* ``` php
|
628 |
-
* <?php
|
629 |
-
* // to match root url
|
630 |
-
* $I->dontSeeCurrentUrlMatches('~$/users/(\d+)~');
|
631 |
-
* ?>
|
632 |
-
* ```
|
633 |
-
*
|
634 |
-
* @param $uri
|
635 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeCurrentUrlMatches()
|
636 |
-
*/
|
637 |
-
public function dontSeeCurrentUrlMatches($uri) {
|
638 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeCurrentUrlMatches', func_get_args()));
|
639 |
-
}
|
640 |
-
|
641 |
-
|
642 |
-
/**
|
643 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
644 |
-
*
|
645 |
-
* Executes the given regular expression against the current URI and returns the first match.
|
646 |
-
* If no parameters are provided, the full URI is returned.
|
647 |
-
*
|
648 |
-
* ``` php
|
649 |
-
* <?php
|
650 |
-
* $user_id = $I->grabFromCurrentUrl('~$/user/(\d+)/~');
|
651 |
-
* $uri = $I->grabFromCurrentUrl();
|
652 |
-
* ?>
|
653 |
-
* ```
|
654 |
-
*
|
655 |
-
* @param null $uri
|
656 |
-
*
|
657 |
-
* @internal param $url
|
658 |
-
* @return mixed
|
659 |
-
* @see \Codeception\Lib\InnerBrowser::grabFromCurrentUrl()
|
660 |
-
*/
|
661 |
-
public function grabFromCurrentUrl($uri = null) {
|
662 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('grabFromCurrentUrl', func_get_args()));
|
663 |
-
}
|
664 |
-
|
665 |
-
|
666 |
-
/**
|
667 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
668 |
-
*
|
669 |
-
* Checks that the specified checkbox is checked.
|
670 |
-
*
|
671 |
-
* ``` php
|
672 |
-
* <?php
|
673 |
-
* $I->seeCheckboxIsChecked('#agree'); // I suppose user agreed to terms
|
674 |
-
* $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user agreed to terms, If there is only one checkbox in form.
|
675 |
-
* $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]');
|
676 |
-
* ?>
|
677 |
-
* ```
|
678 |
-
*
|
679 |
-
* @param $checkbox
|
680 |
-
* Conditional Assertion: Test won't be stopped on fail
|
681 |
-
* @see \Codeception\Lib\InnerBrowser::seeCheckboxIsChecked()
|
682 |
-
*/
|
683 |
-
public function canSeeCheckboxIsChecked($checkbox) {
|
684 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeCheckboxIsChecked', func_get_args()));
|
685 |
-
}
|
686 |
-
/**
|
687 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
688 |
-
*
|
689 |
-
* Checks that the specified checkbox is checked.
|
690 |
-
*
|
691 |
-
* ``` php
|
692 |
-
* <?php
|
693 |
-
* $I->seeCheckboxIsChecked('#agree'); // I suppose user agreed to terms
|
694 |
-
* $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user agreed to terms, If there is only one checkbox in form.
|
695 |
-
* $I->seeCheckboxIsChecked('//form/input[@type=checkbox and @name=agree]');
|
696 |
-
* ?>
|
697 |
-
* ```
|
698 |
-
*
|
699 |
-
* @param $checkbox
|
700 |
-
* @see \Codeception\Lib\InnerBrowser::seeCheckboxIsChecked()
|
701 |
-
*/
|
702 |
-
public function seeCheckboxIsChecked($checkbox) {
|
703 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('seeCheckboxIsChecked', func_get_args()));
|
704 |
-
}
|
705 |
-
|
706 |
-
|
707 |
-
/**
|
708 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
709 |
-
*
|
710 |
-
* Check that the specified checkbox is unchecked.
|
711 |
-
*
|
712 |
-
* ``` php
|
713 |
-
* <?php
|
714 |
-
* $I->dontSeeCheckboxIsChecked('#agree'); // I suppose user didn't agree to terms
|
715 |
-
* $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user didn't check the first checkbox in form.
|
716 |
-
* ?>
|
717 |
-
* ```
|
718 |
-
*
|
719 |
-
* @param $checkbox
|
720 |
-
* Conditional Assertion: Test won't be stopped on fail
|
721 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeCheckboxIsChecked()
|
722 |
-
*/
|
723 |
-
public function cantSeeCheckboxIsChecked($checkbox) {
|
724 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCheckboxIsChecked', func_get_args()));
|
725 |
-
}
|
726 |
-
/**
|
727 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
728 |
-
*
|
729 |
-
* Check that the specified checkbox is unchecked.
|
730 |
-
*
|
731 |
-
* ``` php
|
732 |
-
* <?php
|
733 |
-
* $I->dontSeeCheckboxIsChecked('#agree'); // I suppose user didn't agree to terms
|
734 |
-
* $I->seeCheckboxIsChecked('#signup_form input[type=checkbox]'); // I suppose user didn't check the first checkbox in form.
|
735 |
-
* ?>
|
736 |
-
* ```
|
737 |
-
*
|
738 |
-
* @param $checkbox
|
739 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeCheckboxIsChecked()
|
740 |
-
*/
|
741 |
-
public function dontSeeCheckboxIsChecked($checkbox) {
|
742 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeCheckboxIsChecked', func_get_args()));
|
743 |
-
}
|
744 |
-
|
745 |
-
|
746 |
-
/**
|
747 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
748 |
-
*
|
749 |
-
* Checks that the given input field or textarea contains the given value.
|
750 |
-
* For fuzzy locators, fields are matched by label text, the "name" attribute, CSS, and XPath.
|
751 |
-
*
|
752 |
-
* ``` php
|
753 |
-
* <?php
|
754 |
-
* $I->seeInField('Body','Type your comment here');
|
755 |
-
* $I->seeInField('form textarea[name=body]','Type your comment here');
|
756 |
-
* $I->seeInField('form input[type=hidden]','hidden_value');
|
757 |
-
* $I->seeInField('#searchform input','Search');
|
758 |
-
* $I->seeInField('//form/*[@name=search]','Search');
|
759 |
-
* $I->seeInField(['name' => 'search'], 'Search');
|
760 |
-
* ?>
|
761 |
-
* ```
|
762 |
-
*
|
763 |
-
* @param $field
|
764 |
-
* @param $value
|
765 |
-
* Conditional Assertion: Test won't be stopped on fail
|
766 |
-
* @see \Codeception\Lib\InnerBrowser::seeInField()
|
767 |
-
*/
|
768 |
-
public function canSeeInField($field, $value) {
|
769 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeInField', func_get_args()));
|
770 |
-
}
|
771 |
-
/**
|
772 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
773 |
-
*
|
774 |
-
* Checks that the given input field or textarea contains the given value.
|
775 |
-
* For fuzzy locators, fields are matched by label text, the "name" attribute, CSS, and XPath.
|
776 |
-
*
|
777 |
-
* ``` php
|
778 |
-
* <?php
|
779 |
-
* $I->seeInField('Body','Type your comment here');
|
780 |
-
* $I->seeInField('form textarea[name=body]','Type your comment here');
|
781 |
-
* $I->seeInField('form input[type=hidden]','hidden_value');
|
782 |
-
* $I->seeInField('#searchform input','Search');
|
783 |
-
* $I->seeInField('//form/*[@name=search]','Search');
|
784 |
-
* $I->seeInField(['name' => 'search'], 'Search');
|
785 |
-
* ?>
|
786 |
-
* ```
|
787 |
-
*
|
788 |
-
* @param $field
|
789 |
-
* @param $value
|
790 |
-
* @see \Codeception\Lib\InnerBrowser::seeInField()
|
791 |
-
*/
|
792 |
-
public function seeInField($field, $value) {
|
793 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('seeInField', func_get_args()));
|
794 |
-
}
|
795 |
-
|
796 |
-
|
797 |
-
/**
|
798 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
799 |
-
*
|
800 |
-
* Checks that an input field or textarea doesn't contain the given value.
|
801 |
-
* For fuzzy locators, the field is matched by label text, CSS and XPath.
|
802 |
-
*
|
803 |
-
* ``` php
|
804 |
-
* <?php
|
805 |
-
* $I->dontSeeInField('Body','Type your comment here');
|
806 |
-
* $I->dontSeeInField('form textarea[name=body]','Type your comment here');
|
807 |
-
* $I->dontSeeInField('form input[type=hidden]','hidden_value');
|
808 |
-
* $I->dontSeeInField('#searchform input','Search');
|
809 |
-
* $I->dontSeeInField('//form/*[@name=search]','Search');
|
810 |
-
* $I->dontSeeInField(['name' => 'search'], 'Search');
|
811 |
-
* ?>
|
812 |
-
* ```
|
813 |
-
*
|
814 |
-
* @param $field
|
815 |
-
* @param $value
|
816 |
-
* Conditional Assertion: Test won't be stopped on fail
|
817 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeInField()
|
818 |
-
*/
|
819 |
-
public function cantSeeInField($field, $value) {
|
820 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInField', func_get_args()));
|
821 |
-
}
|
822 |
-
/**
|
823 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
824 |
-
*
|
825 |
-
* Checks that an input field or textarea doesn't contain the given value.
|
826 |
-
* For fuzzy locators, the field is matched by label text, CSS and XPath.
|
827 |
-
*
|
828 |
-
* ``` php
|
829 |
-
* <?php
|
830 |
-
* $I->dontSeeInField('Body','Type your comment here');
|
831 |
-
* $I->dontSeeInField('form textarea[name=body]','Type your comment here');
|
832 |
-
* $I->dontSeeInField('form input[type=hidden]','hidden_value');
|
833 |
-
* $I->dontSeeInField('#searchform input','Search');
|
834 |
-
* $I->dontSeeInField('//form/*[@name=search]','Search');
|
835 |
-
* $I->dontSeeInField(['name' => 'search'], 'Search');
|
836 |
-
* ?>
|
837 |
-
* ```
|
838 |
-
*
|
839 |
-
* @param $field
|
840 |
-
* @param $value
|
841 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeInField()
|
842 |
-
*/
|
843 |
-
public function dontSeeInField($field, $value) {
|
844 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeInField', func_get_args()));
|
845 |
-
}
|
846 |
-
|
847 |
-
|
848 |
-
/**
|
849 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
850 |
-
*
|
851 |
-
* Checks if the array of form parameters (name => value) are set on the form matched with the
|
852 |
-
* passed selector.
|
853 |
-
*
|
854 |
-
* ``` php
|
855 |
-
* <?php
|
856 |
-
* $I->seeInFormFields('form[name=myform]', [
|
857 |
-
* 'input1' => 'value',
|
858 |
-
* 'input2' => 'other value',
|
859 |
-
* ]);
|
860 |
-
* ?>
|
861 |
-
* ```
|
862 |
-
*
|
863 |
-
* For multi-select elements, or to check values of multiple elements with the same name, an
|
864 |
-
* array may be passed:
|
865 |
-
*
|
866 |
-
* ``` php
|
867 |
-
* <?php
|
868 |
-
* $I->seeInFormFields('.form-class', [
|
869 |
-
* 'multiselect' => [
|
870 |
-
* 'value1',
|
871 |
-
* 'value2',
|
872 |
-
* ],
|
873 |
-
* 'checkbox[]' => [
|
874 |
-
* 'a checked value',
|
875 |
-
* 'another checked value',
|
876 |
-
* ],
|
877 |
-
* ]);
|
878 |
-
* ?>
|
879 |
-
* ```
|
880 |
-
*
|
881 |
-
* Additionally, checkbox values can be checked with a boolean.
|
882 |
-
*
|
883 |
-
* ``` php
|
884 |
-
* <?php
|
885 |
-
* $I->seeInFormFields('#form-id', [
|
886 |
-
* 'checkbox1' => true, // passes if checked
|
887 |
-
* 'checkbox2' => false, // passes if unchecked
|
888 |
-
* ]);
|
889 |
-
* ?>
|
890 |
-
* ```
|
891 |
-
*
|
892 |
-
* Pair this with submitForm for quick testing magic.
|
893 |
-
*
|
894 |
-
* ``` php
|
895 |
-
* <?php
|
896 |
-
* $form = [
|
897 |
-
* 'field1' => 'value',
|
898 |
-
* 'field2' => 'another value',
|
899 |
-
* 'checkbox1' => true,
|
900 |
-
* // ...
|
901 |
-
* ];
|
902 |
-
* $I->submitForm('//form[@id=my-form]', $form, 'submitButton');
|
903 |
-
* // $I->amOnPage('/path/to/form-page') may be needed
|
904 |
-
* $I->seeInFormFields('//form[@id=my-form]', $form);
|
905 |
-
* ?>
|
906 |
-
* ```
|
907 |
-
*
|
908 |
-
* @param $formSelector
|
909 |
-
* @param $params
|
910 |
-
* Conditional Assertion: Test won't be stopped on fail
|
911 |
-
* @see \Codeception\Lib\InnerBrowser::seeInFormFields()
|
912 |
-
*/
|
913 |
-
public function canSeeInFormFields($formSelector, $params) {
|
914 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeInFormFields', func_get_args()));
|
915 |
-
}
|
916 |
-
/**
|
917 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
918 |
-
*
|
919 |
-
* Checks if the array of form parameters (name => value) are set on the form matched with the
|
920 |
-
* passed selector.
|
921 |
-
*
|
922 |
-
* ``` php
|
923 |
-
* <?php
|
924 |
-
* $I->seeInFormFields('form[name=myform]', [
|
925 |
-
* 'input1' => 'value',
|
926 |
-
* 'input2' => 'other value',
|
927 |
-
* ]);
|
928 |
-
* ?>
|
929 |
-
* ```
|
930 |
-
*
|
931 |
-
* For multi-select elements, or to check values of multiple elements with the same name, an
|
932 |
-
* array may be passed:
|
933 |
-
*
|
934 |
-
* ``` php
|
935 |
-
* <?php
|
936 |
-
* $I->seeInFormFields('.form-class', [
|
937 |
-
* 'multiselect' => [
|
938 |
-
* 'value1',
|
939 |
-
* 'value2',
|
940 |
-
* ],
|
941 |
-
* 'checkbox[]' => [
|
942 |
-
* 'a checked value',
|
943 |
-
* 'another checked value',
|
944 |
-
* ],
|
945 |
-
* ]);
|
946 |
-
* ?>
|
947 |
-
* ```
|
948 |
-
*
|
949 |
-
* Additionally, checkbox values can be checked with a boolean.
|
950 |
-
*
|
951 |
-
* ``` php
|
952 |
-
* <?php
|
953 |
-
* $I->seeInFormFields('#form-id', [
|
954 |
-
* 'checkbox1' => true, // passes if checked
|
955 |
-
* 'checkbox2' => false, // passes if unchecked
|
956 |
-
* ]);
|
957 |
-
* ?>
|
958 |
-
* ```
|
959 |
-
*
|
960 |
-
* Pair this with submitForm for quick testing magic.
|
961 |
-
*
|
962 |
-
* ``` php
|
963 |
-
* <?php
|
964 |
-
* $form = [
|
965 |
-
* 'field1' => 'value',
|
966 |
-
* 'field2' => 'another value',
|
967 |
-
* 'checkbox1' => true,
|
968 |
-
* // ...
|
969 |
-
* ];
|
970 |
-
* $I->submitForm('//form[@id=my-form]', $form, 'submitButton');
|
971 |
-
* // $I->amOnPage('/path/to/form-page') may be needed
|
972 |
-
* $I->seeInFormFields('//form[@id=my-form]', $form);
|
973 |
-
* ?>
|
974 |
-
* ```
|
975 |
-
*
|
976 |
-
* @param $formSelector
|
977 |
-
* @param $params
|
978 |
-
* @see \Codeception\Lib\InnerBrowser::seeInFormFields()
|
979 |
-
*/
|
980 |
-
public function seeInFormFields($formSelector, $params) {
|
981 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('seeInFormFields', func_get_args()));
|
982 |
-
}
|
983 |
-
|
984 |
-
|
985 |
-
/**
|
986 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
987 |
-
*
|
988 |
-
* Checks if the array of form parameters (name => value) are not set on the form matched with
|
989 |
-
* the passed selector.
|
990 |
-
*
|
991 |
-
* ``` php
|
992 |
-
* <?php
|
993 |
-
* $I->dontSeeInFormFields('form[name=myform]', [
|
994 |
-
* 'input1' => 'non-existent value',
|
995 |
-
* 'input2' => 'other non-existent value',
|
996 |
-
* ]);
|
997 |
-
* ?>
|
998 |
-
* ```
|
999 |
-
*
|
1000 |
-
* To check that an element hasn't been assigned any one of many values, an array can be passed
|
1001 |
-
* as the value:
|
1002 |
-
*
|
1003 |
-
* ``` php
|
1004 |
-
* <?php
|
1005 |
-
* $I->dontSeeInFormFields('.form-class', [
|
1006 |
-
* 'fieldName' => [
|
1007 |
-
* 'This value shouldn\'t be set',
|
1008 |
-
* 'And this value shouldn\'t be set',
|
1009 |
-
* ],
|
1010 |
-
* ]);
|
1011 |
-
* ?>
|
1012 |
-
* ```
|
1013 |
-
*
|
1014 |
-
* Additionally, checkbox values can be checked with a boolean.
|
1015 |
-
*
|
1016 |
-
* ``` php
|
1017 |
-
* <?php
|
1018 |
-
* $I->dontSeeInFormFields('#form-id', [
|
1019 |
-
* 'checkbox1' => true, // fails if checked
|
1020 |
-
* 'checkbox2' => false, // fails if unchecked
|
1021 |
-
* ]);
|
1022 |
-
* ?>
|
1023 |
-
* ```
|
1024 |
-
*
|
1025 |
-
* @param $formSelector
|
1026 |
-
* @param $params
|
1027 |
-
* Conditional Assertion: Test won't be stopped on fail
|
1028 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeInFormFields()
|
1029 |
-
*/
|
1030 |
-
public function cantSeeInFormFields($formSelector, $params) {
|
1031 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInFormFields', func_get_args()));
|
1032 |
-
}
|
1033 |
-
/**
|
1034 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1035 |
-
*
|
1036 |
-
* Checks if the array of form parameters (name => value) are not set on the form matched with
|
1037 |
-
* the passed selector.
|
1038 |
-
*
|
1039 |
-
* ``` php
|
1040 |
-
* <?php
|
1041 |
-
* $I->dontSeeInFormFields('form[name=myform]', [
|
1042 |
-
* 'input1' => 'non-existent value',
|
1043 |
-
* 'input2' => 'other non-existent value',
|
1044 |
-
* ]);
|
1045 |
-
* ?>
|
1046 |
-
* ```
|
1047 |
-
*
|
1048 |
-
* To check that an element hasn't been assigned any one of many values, an array can be passed
|
1049 |
-
* as the value:
|
1050 |
-
*
|
1051 |
-
* ``` php
|
1052 |
-
* <?php
|
1053 |
-
* $I->dontSeeInFormFields('.form-class', [
|
1054 |
-
* 'fieldName' => [
|
1055 |
-
* 'This value shouldn\'t be set',
|
1056 |
-
* 'And this value shouldn\'t be set',
|
1057 |
-
* ],
|
1058 |
-
* ]);
|
1059 |
-
* ?>
|
1060 |
-
* ```
|
1061 |
-
*
|
1062 |
-
* Additionally, checkbox values can be checked with a boolean.
|
1063 |
-
*
|
1064 |
-
* ``` php
|
1065 |
-
* <?php
|
1066 |
-
* $I->dontSeeInFormFields('#form-id', [
|
1067 |
-
* 'checkbox1' => true, // fails if checked
|
1068 |
-
* 'checkbox2' => false, // fails if unchecked
|
1069 |
-
* ]);
|
1070 |
-
* ?>
|
1071 |
-
* ```
|
1072 |
-
*
|
1073 |
-
* @param $formSelector
|
1074 |
-
* @param $params
|
1075 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeInFormFields()
|
1076 |
-
*/
|
1077 |
-
public function dontSeeInFormFields($formSelector, $params) {
|
1078 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeInFormFields', func_get_args()));
|
1079 |
-
}
|
1080 |
-
|
1081 |
-
|
1082 |
-
/**
|
1083 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1084 |
-
*
|
1085 |
-
* Submits the given form on the page, optionally with the given form values.
|
1086 |
-
* Give the form fields values as an array.
|
1087 |
-
*
|
1088 |
-
* Skipped fields will be filled by their values from the page.
|
1089 |
-
* You don't need to click the 'Submit' button afterwards.
|
1090 |
-
* This command itself triggers the request to form's action.
|
1091 |
-
*
|
1092 |
-
* You can optionally specify what button's value to include
|
1093 |
-
* in the request with the last parameter as an alternative to
|
1094 |
-
* explicitly setting its value in the second parameter, as
|
1095 |
-
* button values are not otherwise included in the request.
|
1096 |
-
*
|
1097 |
-
* Examples:
|
1098 |
-
*
|
1099 |
-
* ``` php
|
1100 |
-
* <?php
|
1101 |
-
* $I->submitForm('#login', array('login' => 'davert', 'password' => '123456'));
|
1102 |
-
* // or
|
1103 |
-
* $I->submitForm('#login', array('login' => 'davert', 'password' => '123456'), 'submitButtonName');
|
1104 |
-
*
|
1105 |
-
* ```
|
1106 |
-
*
|
1107 |
-
* For example, given this sample "Sign Up" form:
|
1108 |
-
*
|
1109 |
-
* ``` html
|
1110 |
-
* <form action="/sign_up">
|
1111 |
-
* Login: <input type="text" name="user[login]" /><br/>
|
1112 |
-
* Password: <input type="password" name="user[password]" /><br/>
|
1113 |
-
* Do you agree to out terms? <input type="checkbox" name="user[agree]" /><br/>
|
1114 |
-
* Select pricing plan <select name="plan"><option value="1">Free</option><option value="2" selected="selected">Paid</option></select>
|
1115 |
-
* <input type="submit" name="submitButton" value="Submit" />
|
1116 |
-
* </form>
|
1117 |
-
* ```
|
1118 |
-
*
|
1119 |
-
* You could write the following to submit it:
|
1120 |
-
*
|
1121 |
-
* ``` php
|
1122 |
-
* <?php
|
1123 |
-
* $I->submitForm('#userForm', array('user' => array('login' => 'Davert', 'password' => '123456', 'agree' => true)), 'submitButton');
|
1124 |
-
*
|
1125 |
-
* ```
|
1126 |
-
* Note that "2" will be the submitted value for the "plan" field, as it is the selected option.
|
1127 |
-
*
|
1128 |
-
* You can also emulate a JavaScript submission by not specifying any buttons in the third parameter to submitForm.
|
1129 |
-
*
|
1130 |
-
* ```php
|
1131 |
-
* <?php
|
1132 |
-
* $I->submitForm('#userForm', array('user' => array('login' => 'Davert', 'password' => '123456', 'agree' => true)));
|
1133 |
-
*
|
1134 |
-
* ```
|
1135 |
-
*
|
1136 |
-
* Pair this with seeInFormFields for quick testing magic.
|
1137 |
-
*
|
1138 |
-
* ``` php
|
1139 |
-
* <?php
|
1140 |
-
* $form = [
|
1141 |
-
* 'field1' => 'value',
|
1142 |
-
* 'field2' => 'another value',
|
1143 |
-
* 'checkbox1' => true,
|
1144 |
-
* // ...
|
1145 |
-
* ];
|
1146 |
-
* $I->submitForm('//form[@id=my-form]', $form, 'submitButton');
|
1147 |
-
* // $I->amOnPage('/path/to/form-page') may be needed
|
1148 |
-
* $I->seeInFormFields('//form[@id=my-form]', $form);
|
1149 |
-
* ?>
|
1150 |
-
* ```
|
1151 |
-
*
|
1152 |
-
* Parameter values can be set to arrays for multiple input fields
|
1153 |
-
* of the same name, or multi-select combo boxes. For checkboxes,
|
1154 |
-
* either the string value can be used, or boolean values which will
|
1155 |
-
* be replaced by the checkbox's value in the DOM.
|
1156 |
-
*
|
1157 |
-
* ``` php
|
1158 |
-
* <?php
|
1159 |
-
* $I->submitForm('#my-form', [
|
1160 |
-
* 'field1' => 'value',
|
1161 |
-
* 'checkbox' => [
|
1162 |
-
* 'value of first checkbox',
|
1163 |
-
* 'value of second checkbox,
|
1164 |
-
* ],
|
1165 |
-
* 'otherCheckboxes' => [
|
1166 |
-
* true,
|
1167 |
-
* false,
|
1168 |
-
* false
|
1169 |
-
* ],
|
1170 |
-
* 'multiselect' => [
|
1171 |
-
* 'first option value',
|
1172 |
-
* 'second option value'
|
1173 |
-
* ]
|
1174 |
-
* ]);
|
1175 |
-
* ?>
|
1176 |
-
* ```
|
1177 |
-
*
|
1178 |
-
* Mixing string and boolean values for a checkbox's value is not
|
1179 |
-
* supported and may produce unexpected results.
|
1180 |
-
*
|
1181 |
-
* @param $selector
|
1182 |
-
* @param $params
|
1183 |
-
* @param $button
|
1184 |
-
* @see \Codeception\Lib\InnerBrowser::submitForm()
|
1185 |
-
*/
|
1186 |
-
public function submitForm($selector, $params, $button = null) {
|
1187 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('submitForm', func_get_args()));
|
1188 |
-
}
|
1189 |
-
|
1190 |
-
|
1191 |
-
/**
|
1192 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1193 |
-
*
|
1194 |
-
* Fills a text field or textarea with the given string.
|
1195 |
-
*
|
1196 |
-
* ``` php
|
1197 |
-
* <?php
|
1198 |
-
* $I->fillField("//input[@type='text']", "Hello World!");
|
1199 |
-
* $I->fillField(['name' => 'email'], 'jon@mail.com');
|
1200 |
-
* ?>
|
1201 |
-
* ```
|
1202 |
-
*
|
1203 |
-
* @param $field
|
1204 |
-
* @param $value
|
1205 |
-
* @see \Codeception\Lib\InnerBrowser::fillField()
|
1206 |
-
*/
|
1207 |
-
public function fillField($field, $value) {
|
1208 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('fillField', func_get_args()));
|
1209 |
-
}
|
1210 |
-
|
1211 |
-
|
1212 |
-
/**
|
1213 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1214 |
-
*
|
1215 |
-
* Selects an option in a select tag or in radio button group.
|
1216 |
-
*
|
1217 |
-
* ``` php
|
1218 |
-
* <?php
|
1219 |
-
* $I->selectOption('form select[name=account]', 'Premium');
|
1220 |
-
* $I->selectOption('form input[name=payment]', 'Monthly');
|
1221 |
-
* $I->selectOption('//form/select[@name=account]', 'Monthly');
|
1222 |
-
* ?>
|
1223 |
-
* ```
|
1224 |
-
*
|
1225 |
-
* Provide an array for the second argument to select multiple options:
|
1226 |
-
*
|
1227 |
-
* ``` php
|
1228 |
-
* <?php
|
1229 |
-
* $I->selectOption('Which OS do you use?', array('Windows','Linux'));
|
1230 |
-
* ?>
|
1231 |
-
* ```
|
1232 |
-
*
|
1233 |
-
* @param $select
|
1234 |
-
* @param $option
|
1235 |
-
* @see \Codeception\Lib\InnerBrowser::selectOption()
|
1236 |
-
*/
|
1237 |
-
public function selectOption($select, $option) {
|
1238 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('selectOption', func_get_args()));
|
1239 |
-
}
|
1240 |
-
|
1241 |
-
|
1242 |
-
/**
|
1243 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1244 |
-
*
|
1245 |
-
* Ticks a checkbox. For radio buttons, use the `selectOption` method instead.
|
1246 |
-
*
|
1247 |
-
* ``` php
|
1248 |
-
* <?php
|
1249 |
-
* $I->checkOption('#agree');
|
1250 |
-
* ?>
|
1251 |
-
* ```
|
1252 |
-
*
|
1253 |
-
* @param $option
|
1254 |
-
* @see \Codeception\Lib\InnerBrowser::checkOption()
|
1255 |
-
*/
|
1256 |
-
public function checkOption($option) {
|
1257 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('checkOption', func_get_args()));
|
1258 |
-
}
|
1259 |
-
|
1260 |
-
|
1261 |
-
/**
|
1262 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1263 |
-
*
|
1264 |
-
* Unticks a checkbox.
|
1265 |
-
*
|
1266 |
-
* ``` php
|
1267 |
-
* <?php
|
1268 |
-
* $I->uncheckOption('#notify');
|
1269 |
-
* ?>
|
1270 |
-
* ```
|
1271 |
-
*
|
1272 |
-
* @param $option
|
1273 |
-
* @see \Codeception\Lib\InnerBrowser::uncheckOption()
|
1274 |
-
*/
|
1275 |
-
public function uncheckOption($option) {
|
1276 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('uncheckOption', func_get_args()));
|
1277 |
-
}
|
1278 |
-
|
1279 |
-
|
1280 |
-
/**
|
1281 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1282 |
-
*
|
1283 |
-
* Attaches a file relative to the Codeception data directory to the given file upload field.
|
1284 |
-
*
|
1285 |
-
* ``` php
|
1286 |
-
* <?php
|
1287 |
-
* // file is stored in 'tests/_data/prices.xls'
|
1288 |
-
* $I->attachFile('input[@type="file"]', 'prices.xls');
|
1289 |
-
* ?>
|
1290 |
-
* ```
|
1291 |
-
*
|
1292 |
-
* @param $field
|
1293 |
-
* @param $filename
|
1294 |
-
* @see \Codeception\Lib\InnerBrowser::attachFile()
|
1295 |
-
*/
|
1296 |
-
public function attachFile($field, $filename) {
|
1297 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('attachFile', func_get_args()));
|
1298 |
-
}
|
1299 |
-
|
1300 |
-
|
1301 |
-
/**
|
1302 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1303 |
-
*
|
1304 |
-
* If your page triggers an ajax request, you can perform it manually.
|
1305 |
-
* This action sends a GET ajax request with specified params.
|
1306 |
-
*
|
1307 |
-
* See ->sendAjaxPostRequest for examples.
|
1308 |
-
*
|
1309 |
-
* @param $uri
|
1310 |
-
* @param $params
|
1311 |
-
* @see \Codeception\Lib\InnerBrowser::sendAjaxGetRequest()
|
1312 |
-
*/
|
1313 |
-
public function sendAjaxGetRequest($uri, $params = null) {
|
1314 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('sendAjaxGetRequest', func_get_args()));
|
1315 |
-
}
|
1316 |
-
|
1317 |
-
|
1318 |
-
/**
|
1319 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1320 |
-
*
|
1321 |
-
* If your page triggers an ajax request, you can perform it manually.
|
1322 |
-
* This action sends a POST ajax request with specified params.
|
1323 |
-
* Additional params can be passed as array.
|
1324 |
-
*
|
1325 |
-
* Example:
|
1326 |
-
*
|
1327 |
-
* Imagine that by clicking checkbox you trigger ajax request which updates user settings.
|
1328 |
-
* We emulate that click by running this ajax request manually.
|
1329 |
-
*
|
1330 |
-
* ``` php
|
1331 |
-
* <?php
|
1332 |
-
* $I->sendAjaxPostRequest('/updateSettings', array('notifications' => true)); // POST
|
1333 |
-
* $I->sendAjaxGetRequest('/updateSettings', array('notifications' => true)); // GET
|
1334 |
-
*
|
1335 |
-
* ```
|
1336 |
-
*
|
1337 |
-
* @param $uri
|
1338 |
-
* @param $params
|
1339 |
-
* @see \Codeception\Lib\InnerBrowser::sendAjaxPostRequest()
|
1340 |
-
*/
|
1341 |
-
public function sendAjaxPostRequest($uri, $params = null) {
|
1342 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('sendAjaxPostRequest', func_get_args()));
|
1343 |
-
}
|
1344 |
-
|
1345 |
-
|
1346 |
-
/**
|
1347 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1348 |
-
*
|
1349 |
-
* If your page triggers an ajax request, you can perform it manually.
|
1350 |
-
* This action sends an ajax request with specified method and params.
|
1351 |
-
*
|
1352 |
-
* Example:
|
1353 |
-
*
|
1354 |
-
* You need to perform an ajax request specifying the HTTP method.
|
1355 |
-
*
|
1356 |
-
* ``` php
|
1357 |
-
* <?php
|
1358 |
-
* $I->sendAjaxRequest('PUT', '/posts/7', array('title' => 'new title'));
|
1359 |
-
*
|
1360 |
-
* ```
|
1361 |
-
*
|
1362 |
-
* @param $method
|
1363 |
-
* @param $uri
|
1364 |
-
* @param $params
|
1365 |
-
* @see \Codeception\Lib\InnerBrowser::sendAjaxRequest()
|
1366 |
-
*/
|
1367 |
-
public function sendAjaxRequest($method, $uri, $params = null) {
|
1368 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('sendAjaxRequest', func_get_args()));
|
1369 |
-
}
|
1370 |
-
|
1371 |
-
|
1372 |
-
/**
|
1373 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1374 |
-
*
|
1375 |
-
* Finds and returns the text contents of the given element.
|
1376 |
-
* If a fuzzy locator is used, the element is found using CSS, XPath, and by matching the full page source by regular expression.
|
1377 |
-
*
|
1378 |
-
* ``` php
|
1379 |
-
* <?php
|
1380 |
-
* $heading = $I->grabTextFrom('h1');
|
1381 |
-
* $heading = $I->grabTextFrom('descendant-or-self::h1');
|
1382 |
-
* $value = $I->grabTextFrom('~<input value=(.*?)]~sgi'); // match with a regex
|
1383 |
-
* ?>
|
1384 |
-
* ```
|
1385 |
-
*
|
1386 |
-
* @param $cssOrXPathOrRegex
|
1387 |
-
*
|
1388 |
-
* @return mixed
|
1389 |
-
* @see \Codeception\Lib\InnerBrowser::grabTextFrom()
|
1390 |
-
*/
|
1391 |
-
public function grabTextFrom($cssOrXPathOrRegex) {
|
1392 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('grabTextFrom', func_get_args()));
|
1393 |
-
}
|
1394 |
-
|
1395 |
-
|
1396 |
-
/**
|
1397 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1398 |
-
*
|
1399 |
-
* Grabs the value of the given attribute value from the given element.
|
1400 |
-
* Fails if element is not found.
|
1401 |
-
*
|
1402 |
-
* ``` php
|
1403 |
-
* <?php
|
1404 |
-
* $I->grabAttributeFrom('#tooltip', 'title');
|
1405 |
-
* ?>
|
1406 |
-
* ```
|
1407 |
-
*
|
1408 |
-
*
|
1409 |
-
* @param $cssOrXpath
|
1410 |
-
* @param $attribute
|
1411 |
-
* @internal param $element
|
1412 |
-
* @return mixed
|
1413 |
-
* @see \Codeception\Lib\InnerBrowser::grabAttributeFrom()
|
1414 |
-
*/
|
1415 |
-
public function grabAttributeFrom($cssOrXpath, $attribute) {
|
1416 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('grabAttributeFrom', func_get_args()));
|
1417 |
-
}
|
1418 |
-
|
1419 |
-
|
1420 |
-
/**
|
1421 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1422 |
-
*
|
1423 |
-
* @param $field
|
1424 |
-
*
|
1425 |
-
* @return array|mixed|null|string
|
1426 |
-
* @see \Codeception\Lib\InnerBrowser::grabValueFrom()
|
1427 |
-
*/
|
1428 |
-
public function grabValueFrom($field) {
|
1429 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('grabValueFrom', func_get_args()));
|
1430 |
-
}
|
1431 |
-
|
1432 |
-
|
1433 |
-
/**
|
1434 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1435 |
-
*
|
1436 |
-
* Sets a cookie with the given name and value.
|
1437 |
-
* You can set additional cookie params like `domain`, `path`, `expire`, `secure` in array passed as last argument.
|
1438 |
-
*
|
1439 |
-
* ``` php
|
1440 |
-
* <?php
|
1441 |
-
* $I->setCookie('PHPSESSID', 'el4ukv0kqbvoirg7nkp4dncpk3');
|
1442 |
-
* ?>
|
1443 |
-
* ```
|
1444 |
-
*
|
1445 |
-
* @param $name
|
1446 |
-
* @param $val
|
1447 |
-
* @param array $params
|
1448 |
-
* @internal param $cookie
|
1449 |
-
* @internal param $value
|
1450 |
-
*
|
1451 |
-
* @return mixed
|
1452 |
-
* @see \Codeception\Lib\InnerBrowser::setCookie()
|
1453 |
-
*/
|
1454 |
-
public function setCookie($name, $val, $params = null) {
|
1455 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('setCookie', func_get_args()));
|
1456 |
-
}
|
1457 |
-
|
1458 |
-
|
1459 |
-
/**
|
1460 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1461 |
-
*
|
1462 |
-
* Grabs a cookie value.
|
1463 |
-
* You can set additional cookie params like `domain`, `path` in array passed as last argument.
|
1464 |
-
*
|
1465 |
-
* @param $cookie
|
1466 |
-
*
|
1467 |
-
* @param array $params
|
1468 |
-
* @return mixed
|
1469 |
-
* @see \Codeception\Lib\InnerBrowser::grabCookie()
|
1470 |
-
*/
|
1471 |
-
public function grabCookie($name, $params = null) {
|
1472 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('grabCookie', func_get_args()));
|
1473 |
-
}
|
1474 |
-
|
1475 |
-
|
1476 |
-
/**
|
1477 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1478 |
-
*
|
1479 |
-
* Checks that a cookie with the given name is set.
|
1480 |
-
* You can set additional cookie params like `domain`, `path` as array passed in last argument.
|
1481 |
-
*
|
1482 |
-
* ``` php
|
1483 |
-
* <?php
|
1484 |
-
* $I->seeCookie('PHPSESSID');
|
1485 |
-
* ?>
|
1486 |
-
* ```
|
1487 |
-
*
|
1488 |
-
* @param $cookie
|
1489 |
-
* @param array $params
|
1490 |
-
* @return mixed
|
1491 |
-
* Conditional Assertion: Test won't be stopped on fail
|
1492 |
-
* @see \Codeception\Lib\InnerBrowser::seeCookie()
|
1493 |
-
*/
|
1494 |
-
public function canSeeCookie($name, $params = null) {
|
1495 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeCookie', func_get_args()));
|
1496 |
-
}
|
1497 |
-
/**
|
1498 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1499 |
-
*
|
1500 |
-
* Checks that a cookie with the given name is set.
|
1501 |
-
* You can set additional cookie params like `domain`, `path` as array passed in last argument.
|
1502 |
-
*
|
1503 |
-
* ``` php
|
1504 |
-
* <?php
|
1505 |
-
* $I->seeCookie('PHPSESSID');
|
1506 |
-
* ?>
|
1507 |
-
* ```
|
1508 |
-
*
|
1509 |
-
* @param $cookie
|
1510 |
-
* @param array $params
|
1511 |
-
* @return mixed
|
1512 |
-
* @see \Codeception\Lib\InnerBrowser::seeCookie()
|
1513 |
-
*/
|
1514 |
-
public function seeCookie($name, $params = null) {
|
1515 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('seeCookie', func_get_args()));
|
1516 |
-
}
|
1517 |
-
|
1518 |
-
|
1519 |
-
/**
|
1520 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1521 |
-
*
|
1522 |
-
* Checks that there isn't a cookie with the given name.
|
1523 |
-
* You can set additional cookie params like `domain`, `path` as array passed in last argument.
|
1524 |
-
*
|
1525 |
-
* @param $cookie
|
1526 |
-
*
|
1527 |
-
* @param array $params
|
1528 |
-
* @return mixed
|
1529 |
-
* Conditional Assertion: Test won't be stopped on fail
|
1530 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeCookie()
|
1531 |
-
*/
|
1532 |
-
public function cantSeeCookie($name, $params = null) {
|
1533 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeCookie', func_get_args()));
|
1534 |
-
}
|
1535 |
-
/**
|
1536 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1537 |
-
*
|
1538 |
-
* Checks that there isn't a cookie with the given name.
|
1539 |
-
* You can set additional cookie params like `domain`, `path` as array passed in last argument.
|
1540 |
-
*
|
1541 |
-
* @param $cookie
|
1542 |
-
*
|
1543 |
-
* @param array $params
|
1544 |
-
* @return mixed
|
1545 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeCookie()
|
1546 |
-
*/
|
1547 |
-
public function dontSeeCookie($name, $params = null) {
|
1548 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeCookie', func_get_args()));
|
1549 |
-
}
|
1550 |
-
|
1551 |
-
|
1552 |
-
/**
|
1553 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1554 |
-
*
|
1555 |
-
* Unsets cookie with the given name.
|
1556 |
-
* You can set additional cookie params like `domain`, `path` in array passed as last argument.
|
1557 |
-
*
|
1558 |
-
* @param $cookie
|
1559 |
-
*
|
1560 |
-
* @param array $params
|
1561 |
-
* @return mixed
|
1562 |
-
* @see \Codeception\Lib\InnerBrowser::resetCookie()
|
1563 |
-
*/
|
1564 |
-
public function resetCookie($name, $params = null) {
|
1565 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('resetCookie', func_get_args()));
|
1566 |
-
}
|
1567 |
-
|
1568 |
-
|
1569 |
-
/**
|
1570 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1571 |
-
*
|
1572 |
-
* Checks that the given element exists on the page and is visible.
|
1573 |
-
* You can also specify expected attributes of this element.
|
1574 |
-
*
|
1575 |
-
* ``` php
|
1576 |
-
* <?php
|
1577 |
-
* $I->seeElement('.error');
|
1578 |
-
* $I->seeElement('//form/input[1]');
|
1579 |
-
* $I->seeElement('input', ['name' => 'login']);
|
1580 |
-
* $I->seeElement('input', ['value' => '123456']);
|
1581 |
-
*
|
1582 |
-
* // strict locator in first arg, attributes in second
|
1583 |
-
* $I->seeElement(['css' => 'form input'], ['name' => 'login']);
|
1584 |
-
* ?>
|
1585 |
-
* ```
|
1586 |
-
*
|
1587 |
-
* @param $selector
|
1588 |
-
* @param array $attributes
|
1589 |
-
* @return
|
1590 |
-
* Conditional Assertion: Test won't be stopped on fail
|
1591 |
-
* @see \Codeception\Lib\InnerBrowser::seeElement()
|
1592 |
-
*/
|
1593 |
-
public function canSeeElement($selector, $attributes = null) {
|
1594 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeElement', func_get_args()));
|
1595 |
-
}
|
1596 |
-
/**
|
1597 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1598 |
-
*
|
1599 |
-
* Checks that the given element exists on the page and is visible.
|
1600 |
-
* You can also specify expected attributes of this element.
|
1601 |
-
*
|
1602 |
-
* ``` php
|
1603 |
-
* <?php
|
1604 |
-
* $I->seeElement('.error');
|
1605 |
-
* $I->seeElement('//form/input[1]');
|
1606 |
-
* $I->seeElement('input', ['name' => 'login']);
|
1607 |
-
* $I->seeElement('input', ['value' => '123456']);
|
1608 |
-
*
|
1609 |
-
* // strict locator in first arg, attributes in second
|
1610 |
-
* $I->seeElement(['css' => 'form input'], ['name' => 'login']);
|
1611 |
-
* ?>
|
1612 |
-
* ```
|
1613 |
-
*
|
1614 |
-
* @param $selector
|
1615 |
-
* @param array $attributes
|
1616 |
-
* @return
|
1617 |
-
* @see \Codeception\Lib\InnerBrowser::seeElement()
|
1618 |
-
*/
|
1619 |
-
public function seeElement($selector, $attributes = null) {
|
1620 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('seeElement', func_get_args()));
|
1621 |
-
}
|
1622 |
-
|
1623 |
-
|
1624 |
-
/**
|
1625 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1626 |
-
*
|
1627 |
-
* Checks that the given element is invisible or not present on the page.
|
1628 |
-
* You can also specify expected attributes of this element.
|
1629 |
-
*
|
1630 |
-
* ``` php
|
1631 |
-
* <?php
|
1632 |
-
* $I->dontSeeElement('.error');
|
1633 |
-
* $I->dontSeeElement('//form/input[1]');
|
1634 |
-
* $I->dontSeeElement('input', ['name' => 'login']);
|
1635 |
-
* $I->dontSeeElement('input', ['value' => '123456']);
|
1636 |
-
* ?>
|
1637 |
-
* ```
|
1638 |
-
*
|
1639 |
-
* @param $selector
|
1640 |
-
* @param array $attributes
|
1641 |
-
* Conditional Assertion: Test won't be stopped on fail
|
1642 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeElement()
|
1643 |
-
*/
|
1644 |
-
public function cantSeeElement($selector, $attributes = null) {
|
1645 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeElement', func_get_args()));
|
1646 |
-
}
|
1647 |
-
/**
|
1648 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1649 |
-
*
|
1650 |
-
* Checks that the given element is invisible or not present on the page.
|
1651 |
-
* You can also specify expected attributes of this element.
|
1652 |
-
*
|
1653 |
-
* ``` php
|
1654 |
-
* <?php
|
1655 |
-
* $I->dontSeeElement('.error');
|
1656 |
-
* $I->dontSeeElement('//form/input[1]');
|
1657 |
-
* $I->dontSeeElement('input', ['name' => 'login']);
|
1658 |
-
* $I->dontSeeElement('input', ['value' => '123456']);
|
1659 |
-
* ?>
|
1660 |
-
* ```
|
1661 |
-
*
|
1662 |
-
* @param $selector
|
1663 |
-
* @param array $attributes
|
1664 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeElement()
|
1665 |
-
*/
|
1666 |
-
public function dontSeeElement($selector, $attributes = null) {
|
1667 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeElement', func_get_args()));
|
1668 |
-
}
|
1669 |
-
|
1670 |
-
|
1671 |
-
/**
|
1672 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1673 |
-
*
|
1674 |
-
* Checks that there are a certain number of elements matched by the given locator on the page.
|
1675 |
-
*
|
1676 |
-
* ``` php
|
1677 |
-
* <?php
|
1678 |
-
* $I->seeNumberOfElements('tr', 10);
|
1679 |
-
* $I->seeNumberOfElements('tr', [0,10]); //between 0 and 10 elements
|
1680 |
-
* ?>
|
1681 |
-
* ```
|
1682 |
-
* @param $selector
|
1683 |
-
* @param mixed $expected:
|
1684 |
-
* - string: strict number
|
1685 |
-
* - array: range of numbers [0,10]
|
1686 |
-
* Conditional Assertion: Test won't be stopped on fail
|
1687 |
-
* @see \Codeception\Lib\InnerBrowser::seeNumberOfElements()
|
1688 |
-
*/
|
1689 |
-
public function canSeeNumberOfElements($selector, $expected) {
|
1690 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeNumberOfElements', func_get_args()));
|
1691 |
-
}
|
1692 |
-
/**
|
1693 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1694 |
-
*
|
1695 |
-
* Checks that there are a certain number of elements matched by the given locator on the page.
|
1696 |
-
*
|
1697 |
-
* ``` php
|
1698 |
-
* <?php
|
1699 |
-
* $I->seeNumberOfElements('tr', 10);
|
1700 |
-
* $I->seeNumberOfElements('tr', [0,10]); //between 0 and 10 elements
|
1701 |
-
* ?>
|
1702 |
-
* ```
|
1703 |
-
* @param $selector
|
1704 |
-
* @param mixed $expected:
|
1705 |
-
* - string: strict number
|
1706 |
-
* - array: range of numbers [0,10]
|
1707 |
-
* @see \Codeception\Lib\InnerBrowser::seeNumberOfElements()
|
1708 |
-
*/
|
1709 |
-
public function seeNumberOfElements($selector, $expected) {
|
1710 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('seeNumberOfElements', func_get_args()));
|
1711 |
-
}
|
1712 |
-
|
1713 |
-
|
1714 |
-
/**
|
1715 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1716 |
-
*
|
1717 |
-
* Checks that the given option is selected.
|
1718 |
-
*
|
1719 |
-
* ``` php
|
1720 |
-
* <?php
|
1721 |
-
* $I->seeOptionIsSelected('#form input[name=payment]', 'Visa');
|
1722 |
-
* ?>
|
1723 |
-
* ```
|
1724 |
-
*
|
1725 |
-
* @param $selector
|
1726 |
-
* @param $optionText
|
1727 |
-
*
|
1728 |
-
* @return mixed
|
1729 |
-
* Conditional Assertion: Test won't be stopped on fail
|
1730 |
-
* @see \Codeception\Lib\InnerBrowser::seeOptionIsSelected()
|
1731 |
-
*/
|
1732 |
-
public function canSeeOptionIsSelected($select, $optionText) {
|
1733 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeOptionIsSelected', func_get_args()));
|
1734 |
-
}
|
1735 |
-
/**
|
1736 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1737 |
-
*
|
1738 |
-
* Checks that the given option is selected.
|
1739 |
-
*
|
1740 |
-
* ``` php
|
1741 |
-
* <?php
|
1742 |
-
* $I->seeOptionIsSelected('#form input[name=payment]', 'Visa');
|
1743 |
-
* ?>
|
1744 |
-
* ```
|
1745 |
-
*
|
1746 |
-
* @param $selector
|
1747 |
-
* @param $optionText
|
1748 |
-
*
|
1749 |
-
* @return mixed
|
1750 |
-
* @see \Codeception\Lib\InnerBrowser::seeOptionIsSelected()
|
1751 |
-
*/
|
1752 |
-
public function seeOptionIsSelected($select, $optionText) {
|
1753 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('seeOptionIsSelected', func_get_args()));
|
1754 |
-
}
|
1755 |
-
|
1756 |
-
|
1757 |
-
/**
|
1758 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1759 |
-
*
|
1760 |
-
* Checks that the given option is not selected.
|
1761 |
-
*
|
1762 |
-
* ``` php
|
1763 |
-
* <?php
|
1764 |
-
* $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa');
|
1765 |
-
* ?>
|
1766 |
-
* ```
|
1767 |
-
*
|
1768 |
-
* @param $selector
|
1769 |
-
* @param $optionText
|
1770 |
-
*
|
1771 |
-
* @return mixed
|
1772 |
-
* Conditional Assertion: Test won't be stopped on fail
|
1773 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeOptionIsSelected()
|
1774 |
-
*/
|
1775 |
-
public function cantSeeOptionIsSelected($select, $optionText) {
|
1776 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeOptionIsSelected', func_get_args()));
|
1777 |
-
}
|
1778 |
-
/**
|
1779 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1780 |
-
*
|
1781 |
-
* Checks that the given option is not selected.
|
1782 |
-
*
|
1783 |
-
* ``` php
|
1784 |
-
* <?php
|
1785 |
-
* $I->dontSeeOptionIsSelected('#form input[name=payment]', 'Visa');
|
1786 |
-
* ?>
|
1787 |
-
* ```
|
1788 |
-
*
|
1789 |
-
* @param $selector
|
1790 |
-
* @param $optionText
|
1791 |
-
*
|
1792 |
-
* @return mixed
|
1793 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeOptionIsSelected()
|
1794 |
-
*/
|
1795 |
-
public function dontSeeOptionIsSelected($select, $optionText) {
|
1796 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeOptionIsSelected', func_get_args()));
|
1797 |
-
}
|
1798 |
-
|
1799 |
-
|
1800 |
-
/**
|
1801 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1802 |
-
*
|
1803 |
-
* Asserts that current page has 404 response status code.
|
1804 |
-
* Conditional Assertion: Test won't be stopped on fail
|
1805 |
-
* @see \Codeception\Lib\InnerBrowser::seePageNotFound()
|
1806 |
-
*/
|
1807 |
-
public function canSeePageNotFound() {
|
1808 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seePageNotFound', func_get_args()));
|
1809 |
-
}
|
1810 |
-
/**
|
1811 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1812 |
-
*
|
1813 |
-
* Asserts that current page has 404 response status code.
|
1814 |
-
* @see \Codeception\Lib\InnerBrowser::seePageNotFound()
|
1815 |
-
*/
|
1816 |
-
public function seePageNotFound() {
|
1817 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('seePageNotFound', func_get_args()));
|
1818 |
-
}
|
1819 |
-
|
1820 |
-
|
1821 |
-
/**
|
1822 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1823 |
-
*
|
1824 |
-
* Checks that response code is equal to value provided.
|
1825 |
-
*
|
1826 |
-
* @param $code
|
1827 |
-
*
|
1828 |
-
* @return mixed
|
1829 |
-
* Conditional Assertion: Test won't be stopped on fail
|
1830 |
-
* @see \Codeception\Lib\InnerBrowser::seeResponseCodeIs()
|
1831 |
-
*/
|
1832 |
-
public function canSeeResponseCodeIs($code) {
|
1833 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeResponseCodeIs', func_get_args()));
|
1834 |
-
}
|
1835 |
-
/**
|
1836 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1837 |
-
*
|
1838 |
-
* Checks that response code is equal to value provided.
|
1839 |
-
*
|
1840 |
-
* @param $code
|
1841 |
-
*
|
1842 |
-
* @return mixed
|
1843 |
-
* @see \Codeception\Lib\InnerBrowser::seeResponseCodeIs()
|
1844 |
-
*/
|
1845 |
-
public function seeResponseCodeIs($code) {
|
1846 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('seeResponseCodeIs', func_get_args()));
|
1847 |
-
}
|
1848 |
-
|
1849 |
-
|
1850 |
-
/**
|
1851 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1852 |
-
*
|
1853 |
-
* Checks that the page title contains the given string.
|
1854 |
-
*
|
1855 |
-
* ``` php
|
1856 |
-
* <?php
|
1857 |
-
* $I->seeInTitle('Blog - Post #1');
|
1858 |
-
* ?>
|
1859 |
-
* ```
|
1860 |
-
*
|
1861 |
-
* @param $title
|
1862 |
-
*
|
1863 |
-
* @return mixed
|
1864 |
-
* Conditional Assertion: Test won't be stopped on fail
|
1865 |
-
* @see \Codeception\Lib\InnerBrowser::seeInTitle()
|
1866 |
-
*/
|
1867 |
-
public function canSeeInTitle($title) {
|
1868 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeInTitle', func_get_args()));
|
1869 |
-
}
|
1870 |
-
/**
|
1871 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1872 |
-
*
|
1873 |
-
* Checks that the page title contains the given string.
|
1874 |
-
*
|
1875 |
-
* ``` php
|
1876 |
-
* <?php
|
1877 |
-
* $I->seeInTitle('Blog - Post #1');
|
1878 |
-
* ?>
|
1879 |
-
* ```
|
1880 |
-
*
|
1881 |
-
* @param $title
|
1882 |
-
*
|
1883 |
-
* @return mixed
|
1884 |
-
* @see \Codeception\Lib\InnerBrowser::seeInTitle()
|
1885 |
-
*/
|
1886 |
-
public function seeInTitle($title) {
|
1887 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('seeInTitle', func_get_args()));
|
1888 |
-
}
|
1889 |
-
|
1890 |
-
|
1891 |
-
/**
|
1892 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1893 |
-
*
|
1894 |
-
* Checks that the page title does not contain the given string.
|
1895 |
-
*
|
1896 |
-
* @param $title
|
1897 |
-
*
|
1898 |
-
* @return mixed
|
1899 |
-
* Conditional Assertion: Test won't be stopped on fail
|
1900 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeInTitle()
|
1901 |
-
*/
|
1902 |
-
public function cantSeeInTitle($title) {
|
1903 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInTitle', func_get_args()));
|
1904 |
-
}
|
1905 |
-
/**
|
1906 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
1907 |
-
*
|
1908 |
-
* Checks that the page title does not contain the given string.
|
1909 |
-
*
|
1910 |
-
* @param $title
|
1911 |
-
*
|
1912 |
-
* @return mixed
|
1913 |
-
* @see \Codeception\Lib\InnerBrowser::dontSeeInTitle()
|
1914 |
-
*/
|
1915 |
-
public function dontSeeInTitle($title) {
|
1916 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeInTitle', func_get_args()));
|
1917 |
-
}
|
1918 |
-
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
assets/tests/codeception/acceptance/LoginCept.php
DELETED
@@ -1,48 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* - login
|
4 |
-
* - navigate to plugins
|
5 |
-
* - verify landing pages is installed
|
6 |
-
* - deactivate landing pages
|
7 |
-
* - activate landing pages
|
8 |
-
* - confirm welcome page shows
|
9 |
-
*
|
10 |
-
*/
|
11 |
-
|
12 |
-
|
13 |
-
$I = new AcceptanceTester($scenario);
|
14 |
-
|
15 |
-
|
16 |
-
$I->wantTo('login to wp-admin');
|
17 |
-
$I->amOnPage( site_url().'/wp-login.php' );
|
18 |
-
$I->fillField('Username or Email', 'admin');
|
19 |
-
$I->fillField('Password','admin');
|
20 |
-
$I->click('Log In');
|
21 |
-
$I->see('Dashboard');
|
22 |
-
|
23 |
-
|
24 |
-
$I->wantTo('Navigate to plugins');
|
25 |
-
$I->click( [ 'link' => 'Installed Plugins']);
|
26 |
-
$I->see('Plugins');
|
27 |
-
$I->see('Landing Pages');
|
28 |
-
$I->see('Calls to Action');
|
29 |
-
$I->see('Leads');
|
30 |
-
|
31 |
-
$I->wantTo('Verify landing pages is installed');
|
32 |
-
|
33 |
-
$I->click( '.active a');
|
34 |
-
$I->see('Landing Pages');
|
35 |
-
$I->seePluginActivated('landing-pages');
|
36 |
-
$I->seePluginActivated('calls-to-action');
|
37 |
-
$I->seePluginActivated('leads');
|
38 |
-
|
39 |
-
$I->wantTo('Deactivate Landing Pages');
|
40 |
-
$I->deactivatePlugin( 'landing-pages');
|
41 |
-
$I->seePluginDeactivated('landing-pages');
|
42 |
-
|
43 |
-
$I->wantTo('Reactivate Landing Pages');
|
44 |
-
$I->activatePlugin( 'landing-pages');
|
45 |
-
|
46 |
-
$I->wantTo('Confirm welcome page');
|
47 |
-
$I->see('Welcome to WordPress Landing Pages ');
|
48 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
assets/tests/codeception/acceptance/StatisticsCept.php
DELETED
@@ -1,55 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* This test is desnged to test the impressions/conversions systems of landing pages.
|
4 |
-
* Systems tested:
|
5 |
-
* [x] Login to WordPress
|
6 |
-
* [x] Navigate to Landing Pages
|
7 |
-
* [x] Open example landing page
|
8 |
-
* [x] Check if impression/conversion UI display on landing page edit screen
|
9 |
-
* [ ] Reset impressions/conversions and refresh page
|
10 |
-
* [ ] Make sure stats read 0
|
11 |
-
* [ ] Open landing page and make sure it does not 404
|
12 |
-
* [ ] Refresh landing page and make sure variation 2 loads
|
13 |
-
* [ ] Submit test conversion on variation 2
|
14 |
-
* [ ] Navigate back to edit page and make sure stats read correctly
|
15 |
-
*/
|
16 |
-
|
17 |
-
$I = new AcceptanceTester($scenario);
|
18 |
-
|
19 |
-
$I->wantTo('login to wp-admin');
|
20 |
-
$I->amOnPage( site_url().'/wp-login.php' );
|
21 |
-
$I->fillField('Username', 'admin');
|
22 |
-
$I->fillField('Password','admin');
|
23 |
-
$I->click('Log In');
|
24 |
-
$I->see('Dashboard');
|
25 |
-
|
26 |
-
$I->wantTo('Navigate to landing pages list');
|
27 |
-
$I->click('Landing Pages');
|
28 |
-
$I->amOnPage( admin_url( 'edit.php?post_type=landing-page') );
|
29 |
-
$I->see( 'Landing Pages');
|
30 |
-
|
31 |
-
$I->wantTo('Open example landing page');
|
32 |
-
$I->click( [ 'link' => 'A/B Testing Landing Page Example']);
|
33 |
-
$I->wantTo('check if impressions are correct for variation a');
|
34 |
-
$imp = $I->grabTextFrom('#lp-variation-A .stat-span-impressions');
|
35 |
-
$I->assertContains( '30' , $imp );
|
36 |
-
|
37 |
-
$I->wantTo('check check impressions for variation b');
|
38 |
-
$imp = $I->grabTextFrom('#lp-variation-B .stat-span-impressions');
|
39 |
-
$I->assertContains( '35' , $imp , '' );
|
40 |
-
|
41 |
-
$I->wantTo('check conversions for variation a');
|
42 |
-
$con = $I->grabTextFrom('#lp-variation-A .stat-span-conversions');
|
43 |
-
$I->assertContains( '10' , $con , '' );
|
44 |
-
|
45 |
-
$I->wantTo('check conversions for variation b');
|
46 |
-
$con = $I->grabTextFrom('#lp-variation-B .stat-span-conversions');
|
47 |
-
$I->assertContains( '15' , $con );
|
48 |
-
|
49 |
-
$I->wantTo('check the conversion rate of variation a');
|
50 |
-
$per = $I->grabTextFrom('#lp-variation-A .stat-span-conversion_rate');
|
51 |
-
$I->assertContains( '33' , $per );
|
52 |
-
|
53 |
-
$I->wantTo('check the conversion rate of variation b');
|
54 |
-
$per = $I->grabTextFrom('#lp-variation-B .stat-span-conversion_rate');
|
55 |
-
$I->assertContains( '42.86' , $per );
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
assets/tests/codeception/acceptance/WelcomeCept.php
DELETED
@@ -1,7 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
$I = new AcceptanceTester($scenario);
|
4 |
-
$I->wantTo('Make sure the default WordPress homepage loads.');
|
5 |
-
$I->amOnPage( site_url() );
|
6 |
-
$I->see('Hello world!');
|
7 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
assets/tests/codeception/acceptance/_bootstrap.php
DELETED
@@ -1,2 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
// Here you can initialize variables that will be available to your tests
|
Â
|
|
Â
|
assets/tests/codeception/functional/FunctionalTester.php
DELETED
@@ -1,360 +0,0 @@
|
|
1 |
-
<?php //[STAMP] fa259e6277a310881c0cdeb89563ce4c
|
2 |
-
|
3 |
-
// This class was automatically generated by build task
|
4 |
-
// You should not change it manually as it will be overwritten on next build
|
5 |
-
// @codingStandardsIgnoreFile
|
6 |
-
|
7 |
-
|
8 |
-
use Codeception\Module\Filesystem;
|
9 |
-
use Codeception\Module\FunctionalHelper;
|
10 |
-
|
11 |
-
/**
|
12 |
-
* Inherited Methods
|
13 |
-
* @method void wantToTest($text)
|
14 |
-
* @method void wantTo($text)
|
15 |
-
* @method void execute($callable)
|
16 |
-
* @method void expectTo($prediction)
|
17 |
-
* @method void expect($prediction)
|
18 |
-
* @method void amGoingTo($argumentation)
|
19 |
-
* @method void am($role)
|
20 |
-
* @method void lookForwardTo($achieveValue)
|
21 |
-
* @method void comment($description)
|
22 |
-
* @method void haveFriend($name, $actorClass = null)
|
23 |
-
*
|
24 |
-
* @SuppressWarnings(PHPMD)
|
25 |
-
*/
|
26 |
-
class FunctionalTester extends \Codeception\Actor
|
27 |
-
{
|
28 |
-
|
29 |
-
/**
|
30 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
31 |
-
*
|
32 |
-
* Enters a directory In local filesystem.
|
33 |
-
* Project root directory is used by default
|
34 |
-
*
|
35 |
-
* @param $path
|
36 |
-
* @see \Codeception\Module\Filesystem::amInPath()
|
37 |
-
*/
|
38 |
-
public function amInPath($path) {
|
39 |
-
return $this->scenario->runStep(new \Codeception\Step\Condition('amInPath', func_get_args()));
|
40 |
-
}
|
41 |
-
|
42 |
-
|
43 |
-
/**
|
44 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
45 |
-
*
|
46 |
-
* Opens a file and stores it's content.
|
47 |
-
*
|
48 |
-
* Usage:
|
49 |
-
*
|
50 |
-
* ``` php
|
51 |
-
* <?php
|
52 |
-
* $I->openFile('composer.json');
|
53 |
-
* $I->seeInThisFile('codeception/codeception');
|
54 |
-
* ?>
|
55 |
-
* ```
|
56 |
-
*
|
57 |
-
* @param $filename
|
58 |
-
* @see \Codeception\Module\Filesystem::openFile()
|
59 |
-
*/
|
60 |
-
public function openFile($filename) {
|
61 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('openFile', func_get_args()));
|
62 |
-
}
|
63 |
-
|
64 |
-
|
65 |
-
/**
|
66 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
67 |
-
*
|
68 |
-
* Deletes a file
|
69 |
-
*
|
70 |
-
* ``` php
|
71 |
-
* <?php
|
72 |
-
* $I->deleteFile('composer.lock');
|
73 |
-
* ?>
|
74 |
-
* ```
|
75 |
-
*
|
76 |
-
* @param $filename
|
77 |
-
* @see \Codeception\Module\Filesystem::deleteFile()
|
78 |
-
*/
|
79 |
-
public function deleteFile($filename) {
|
80 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('deleteFile', func_get_args()));
|
81 |
-
}
|
82 |
-
|
83 |
-
|
84 |
-
/**
|
85 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
86 |
-
*
|
87 |
-
* Deletes directory with all subdirectories
|
88 |
-
*
|
89 |
-
* ``` php
|
90 |
-
* <?php
|
91 |
-
* $I->deleteDir('vendor');
|
92 |
-
* ?>
|
93 |
-
* ```
|
94 |
-
*
|
95 |
-
* @param $dirname
|
96 |
-
* @see \Codeception\Module\Filesystem::deleteDir()
|
97 |
-
*/
|
98 |
-
public function deleteDir($dirname) {
|
99 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('deleteDir', func_get_args()));
|
100 |
-
}
|
101 |
-
|
102 |
-
|
103 |
-
/**
|
104 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
105 |
-
*
|
106 |
-
* Copies directory with all contents
|
107 |
-
*
|
108 |
-
* ``` php
|
109 |
-
* <?php
|
110 |
-
* $I->copyDir('vendor','old_vendor');
|
111 |
-
* ?>
|
112 |
-
* ```
|
113 |
-
*
|
114 |
-
* @param $src
|
115 |
-
* @param $dst
|
116 |
-
* @see \Codeception\Module\Filesystem::copyDir()
|
117 |
-
*/
|
118 |
-
public function copyDir($src, $dst) {
|
119 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('copyDir', func_get_args()));
|
120 |
-
}
|
121 |
-
|
122 |
-
|
123 |
-
/**
|
124 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
125 |
-
*
|
126 |
-
* Checks If opened file has `text` in it.
|
127 |
-
*
|
128 |
-
* Usage:
|
129 |
-
*
|
130 |
-
* ``` php
|
131 |
-
* <?php
|
132 |
-
* $I->openFile('composer.json');
|
133 |
-
* $I->seeInThisFile('codeception/codeception');
|
134 |
-
* ?>
|
135 |
-
* ```
|
136 |
-
*
|
137 |
-
* @param $text
|
138 |
-
* Conditional Assertion: Test won't be stopped on fail
|
139 |
-
* @see \Codeception\Module\Filesystem::seeInThisFile()
|
140 |
-
*/
|
141 |
-
public function canSeeInThisFile($text) {
|
142 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeInThisFile', func_get_args()));
|
143 |
-
}
|
144 |
-
/**
|
145 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
146 |
-
*
|
147 |
-
* Checks If opened file has `text` in it.
|
148 |
-
*
|
149 |
-
* Usage:
|
150 |
-
*
|
151 |
-
* ``` php
|
152 |
-
* <?php
|
153 |
-
* $I->openFile('composer.json');
|
154 |
-
* $I->seeInThisFile('codeception/codeception');
|
155 |
-
* ?>
|
156 |
-
* ```
|
157 |
-
*
|
158 |
-
* @param $text
|
159 |
-
* @see \Codeception\Module\Filesystem::seeInThisFile()
|
160 |
-
*/
|
161 |
-
public function seeInThisFile($text) {
|
162 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('seeInThisFile', func_get_args()));
|
163 |
-
}
|
164 |
-
|
165 |
-
|
166 |
-
/**
|
167 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
168 |
-
*
|
169 |
-
* Checks the strict matching of file contents.
|
170 |
-
* Unlike `seeInThisFile` will fail if file has something more than expected lines.
|
171 |
-
* Better to use with HEREDOC strings.
|
172 |
-
* Matching is done after removing "\r" chars from file content.
|
173 |
-
*
|
174 |
-
* ``` php
|
175 |
-
* <?php
|
176 |
-
* $I->openFile('process.pid');
|
177 |
-
* $I->seeFileContentsEqual('3192');
|
178 |
-
* ?>
|
179 |
-
* ```
|
180 |
-
*
|
181 |
-
* @param $text
|
182 |
-
* Conditional Assertion: Test won't be stopped on fail
|
183 |
-
* @see \Codeception\Module\Filesystem::seeFileContentsEqual()
|
184 |
-
*/
|
185 |
-
public function canSeeFileContentsEqual($text) {
|
186 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeFileContentsEqual', func_get_args()));
|
187 |
-
}
|
188 |
-
/**
|
189 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
190 |
-
*
|
191 |
-
* Checks the strict matching of file contents.
|
192 |
-
* Unlike `seeInThisFile` will fail if file has something more than expected lines.
|
193 |
-
* Better to use with HEREDOC strings.
|
194 |
-
* Matching is done after removing "\r" chars from file content.
|
195 |
-
*
|
196 |
-
* ``` php
|
197 |
-
* <?php
|
198 |
-
* $I->openFile('process.pid');
|
199 |
-
* $I->seeFileContentsEqual('3192');
|
200 |
-
* ?>
|
201 |
-
* ```
|
202 |
-
*
|
203 |
-
* @param $text
|
204 |
-
* @see \Codeception\Module\Filesystem::seeFileContentsEqual()
|
205 |
-
*/
|
206 |
-
public function seeFileContentsEqual($text) {
|
207 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('seeFileContentsEqual', func_get_args()));
|
208 |
-
}
|
209 |
-
|
210 |
-
|
211 |
-
/**
|
212 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
213 |
-
*
|
214 |
-
* Checks If opened file doesn't contain `text` in it
|
215 |
-
*
|
216 |
-
* ``` php
|
217 |
-
* <?php
|
218 |
-
* $I->openFile('composer.json');
|
219 |
-
* $I->dontSeeInThisFile('codeception/codeception');
|
220 |
-
* ?>
|
221 |
-
* ```
|
222 |
-
*
|
223 |
-
* @param $text
|
224 |
-
* Conditional Assertion: Test won't be stopped on fail
|
225 |
-
* @see \Codeception\Module\Filesystem::dontSeeInThisFile()
|
226 |
-
*/
|
227 |
-
public function cantSeeInThisFile($text) {
|
228 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInThisFile', func_get_args()));
|
229 |
-
}
|
230 |
-
/**
|
231 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
232 |
-
*
|
233 |
-
* Checks If opened file doesn't contain `text` in it
|
234 |
-
*
|
235 |
-
* ``` php
|
236 |
-
* <?php
|
237 |
-
* $I->openFile('composer.json');
|
238 |
-
* $I->dontSeeInThisFile('codeception/codeception');
|
239 |
-
* ?>
|
240 |
-
* ```
|
241 |
-
*
|
242 |
-
* @param $text
|
243 |
-
* @see \Codeception\Module\Filesystem::dontSeeInThisFile()
|
244 |
-
*/
|
245 |
-
public function dontSeeInThisFile($text) {
|
246 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeInThisFile', func_get_args()));
|
247 |
-
}
|
248 |
-
|
249 |
-
|
250 |
-
/**
|
251 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
252 |
-
*
|
253 |
-
* Deletes a file
|
254 |
-
* @see \Codeception\Module\Filesystem::deleteThisFile()
|
255 |
-
*/
|
256 |
-
public function deleteThisFile() {
|
257 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('deleteThisFile', func_get_args()));
|
258 |
-
}
|
259 |
-
|
260 |
-
|
261 |
-
/**
|
262 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
263 |
-
*
|
264 |
-
* Checks if file exists in path.
|
265 |
-
* Opens a file when it's exists
|
266 |
-
*
|
267 |
-
* ``` php
|
268 |
-
* <?php
|
269 |
-
* $I->seeFileFound('UserModel.php','app/models');
|
270 |
-
* ?>
|
271 |
-
* ```
|
272 |
-
*
|
273 |
-
* @param $filename
|
274 |
-
* @param string $path
|
275 |
-
* Conditional Assertion: Test won't be stopped on fail
|
276 |
-
* @see \Codeception\Module\Filesystem::seeFileFound()
|
277 |
-
*/
|
278 |
-
public function canSeeFileFound($filename, $path = null) {
|
279 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('seeFileFound', func_get_args()));
|
280 |
-
}
|
281 |
-
/**
|
282 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
283 |
-
*
|
284 |
-
* Checks if file exists in path.
|
285 |
-
* Opens a file when it's exists
|
286 |
-
*
|
287 |
-
* ``` php
|
288 |
-
* <?php
|
289 |
-
* $I->seeFileFound('UserModel.php','app/models');
|
290 |
-
* ?>
|
291 |
-
* ```
|
292 |
-
*
|
293 |
-
* @param $filename
|
294 |
-
* @param string $path
|
295 |
-
* @see \Codeception\Module\Filesystem::seeFileFound()
|
296 |
-
*/
|
297 |
-
public function seeFileFound($filename, $path = null) {
|
298 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('seeFileFound', func_get_args()));
|
299 |
-
}
|
300 |
-
|
301 |
-
|
302 |
-
/**
|
303 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
304 |
-
*
|
305 |
-
* Checks if file does not exists in path
|
306 |
-
*
|
307 |
-
* @param $filename
|
308 |
-
* @param string $path
|
309 |
-
* Conditional Assertion: Test won't be stopped on fail
|
310 |
-
* @see \Codeception\Module\Filesystem::dontSeeFileFound()
|
311 |
-
*/
|
312 |
-
public function cantSeeFileFound($filename, $path = null) {
|
313 |
-
return $this->scenario->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeFileFound', func_get_args()));
|
314 |
-
}
|
315 |
-
/**
|
316 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
317 |
-
*
|
318 |
-
* Checks if file does not exists in path
|
319 |
-
*
|
320 |
-
* @param $filename
|
321 |
-
* @param string $path
|
322 |
-
* @see \Codeception\Module\Filesystem::dontSeeFileFound()
|
323 |
-
*/
|
324 |
-
public function dontSeeFileFound($filename, $path = null) {
|
325 |
-
return $this->scenario->runStep(new \Codeception\Step\Assertion('dontSeeFileFound', func_get_args()));
|
326 |
-
}
|
327 |
-
|
328 |
-
|
329 |
-
/**
|
330 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
331 |
-
*
|
332 |
-
* Erases directory contents
|
333 |
-
*
|
334 |
-
* ``` php
|
335 |
-
* <?php
|
336 |
-
* $I->cleanDir('logs');
|
337 |
-
* ?>
|
338 |
-
* ```
|
339 |
-
*
|
340 |
-
* @param $dirname
|
341 |
-
* @see \Codeception\Module\Filesystem::cleanDir()
|
342 |
-
*/
|
343 |
-
public function cleanDir($dirname) {
|
344 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('cleanDir', func_get_args()));
|
345 |
-
}
|
346 |
-
|
347 |
-
|
348 |
-
/**
|
349 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
350 |
-
*
|
351 |
-
* Saves contents to file
|
352 |
-
*
|
353 |
-
* @param $filename
|
354 |
-
* @param $contents
|
355 |
-
* @see \Codeception\Module\Filesystem::writeToFile()
|
356 |
-
*/
|
357 |
-
public function writeToFile($filename, $contents) {
|
358 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('writeToFile', func_get_args()));
|
359 |
-
}
|
360 |
-
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
assets/tests/codeception/functional/_bootstrap.php
DELETED
@@ -1,2 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
// Here you can initialize variables that will be available to your tests
|
Â
|
|
Â
|
assets/tests/codeception/unit/UnitTester.php
DELETED
@@ -1,300 +0,0 @@
|
|
1 |
-
<?php //[STAMP] c8568e8eab4a240544c36ae031f88bd8
|
2 |
-
|
3 |
-
// This class was automatically generated by build task
|
4 |
-
// You should not change it manually as it will be overwritten on next build
|
5 |
-
// @codingStandardsIgnoreFile
|
6 |
-
|
7 |
-
|
8 |
-
use Codeception\Module\Asserts;
|
9 |
-
use Codeception\Module\UnitHelper;
|
10 |
-
|
11 |
-
/**
|
12 |
-
* Inherited Methods
|
13 |
-
* @method void wantToTest($text)
|
14 |
-
* @method void wantTo($text)
|
15 |
-
* @method void execute($callable)
|
16 |
-
* @method void expectTo($prediction)
|
17 |
-
* @method void expect($prediction)
|
18 |
-
* @method void amGoingTo($argumentation)
|
19 |
-
* @method void am($role)
|
20 |
-
* @method void lookForwardTo($achieveValue)
|
21 |
-
* @method void comment($description)
|
22 |
-
* @method void haveFriend($name, $actorClass = null)
|
23 |
-
*
|
24 |
-
* @SuppressWarnings(PHPMD)
|
25 |
-
*/
|
26 |
-
class UnitTester extends \Codeception\Actor
|
27 |
-
{
|
28 |
-
|
29 |
-
/**
|
30 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
31 |
-
*
|
32 |
-
* Checks that two variables are equal.
|
33 |
-
*
|
34 |
-
* @param $expected
|
35 |
-
* @param $actual
|
36 |
-
* @param string $message
|
37 |
-
*
|
38 |
-
* @return mixed
|
39 |
-
* @see \Codeception\Module\Asserts::assertEquals()
|
40 |
-
*/
|
41 |
-
public function assertEquals($expected, $actual, $message = null) {
|
42 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('assertEquals', func_get_args()));
|
43 |
-
}
|
44 |
-
|
45 |
-
|
46 |
-
/**
|
47 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
48 |
-
*
|
49 |
-
* Checks that two variables are not equal
|
50 |
-
*
|
51 |
-
* @param $expected
|
52 |
-
* @param $actual
|
53 |
-
* @param string $message
|
54 |
-
* @see \Codeception\Module\Asserts::assertNotEquals()
|
55 |
-
*/
|
56 |
-
public function assertNotEquals($expected, $actual, $message = null) {
|
57 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('assertNotEquals', func_get_args()));
|
58 |
-
}
|
59 |
-
|
60 |
-
|
61 |
-
/**
|
62 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
63 |
-
*
|
64 |
-
* Checks that two variables are same
|
65 |
-
*
|
66 |
-
* @param $expected
|
67 |
-
* @param $actual
|
68 |
-
* @param string $message
|
69 |
-
*
|
70 |
-
* @return mixed
|
71 |
-
* @see \Codeception\Module\Asserts::assertSame()
|
72 |
-
*/
|
73 |
-
public function assertSame($expected, $actual, $message = null) {
|
74 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('assertSame', func_get_args()));
|
75 |
-
}
|
76 |
-
|
77 |
-
|
78 |
-
/**
|
79 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
80 |
-
*
|
81 |
-
* Checks that two variables are not same
|
82 |
-
*
|
83 |
-
* @param $expected
|
84 |
-
* @param $actual
|
85 |
-
* @param string $message
|
86 |
-
* @see \Codeception\Module\Asserts::assertNotSame()
|
87 |
-
*/
|
88 |
-
public function assertNotSame($expected, $actual, $message = null) {
|
89 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('assertNotSame', func_get_args()));
|
90 |
-
}
|
91 |
-
|
92 |
-
|
93 |
-
/**
|
94 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
95 |
-
*
|
96 |
-
* Checks that expected is greater than actual
|
97 |
-
*
|
98 |
-
* @param $expected
|
99 |
-
* @param $actual
|
100 |
-
* @param string $message
|
101 |
-
* @see \Codeception\Module\Asserts::assertGreaterThan()
|
102 |
-
*/
|
103 |
-
public function assertGreaterThan($expected, $actual, $message = null) {
|
104 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThan', func_get_args()));
|
105 |
-
}
|
106 |
-
|
107 |
-
|
108 |
-
/**
|
109 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
110 |
-
*
|
111 |
-
* @deprecated
|
112 |
-
* @see \Codeception\Module\Asserts::assertGreaterThen()
|
113 |
-
*/
|
114 |
-
public function assertGreaterThen($expected, $actual, $message = null) {
|
115 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThen', func_get_args()));
|
116 |
-
}
|
117 |
-
|
118 |
-
|
119 |
-
/**
|
120 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
121 |
-
*
|
122 |
-
* Checks that expected is greater or equal than actual
|
123 |
-
*
|
124 |
-
* @param $expected
|
125 |
-
* @param $actual
|
126 |
-
* @param string $message
|
127 |
-
* @see \Codeception\Module\Asserts::assertGreaterThanOrEqual()
|
128 |
-
*/
|
129 |
-
public function assertGreaterThanOrEqual($expected, $actual, $message = null) {
|
130 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThanOrEqual', func_get_args()));
|
131 |
-
}
|
132 |
-
|
133 |
-
|
134 |
-
/**
|
135 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
136 |
-
*
|
137 |
-
* @deprecated
|
138 |
-
* @see \Codeception\Module\Asserts::assertGreaterThenOrEqual()
|
139 |
-
*/
|
140 |
-
public function assertGreaterThenOrEqual($expected, $actual, $message = null) {
|
141 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('assertGreaterThenOrEqual', func_get_args()));
|
142 |
-
}
|
143 |
-
|
144 |
-
|
145 |
-
/**
|
146 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
147 |
-
*
|
148 |
-
* Checks that expected is less than actual
|
149 |
-
*
|
150 |
-
* @param $expected
|
151 |
-
* @param $actual
|
152 |
-
* @param string $message
|
153 |
-
* @see \Codeception\Module\Asserts::assertLessThan()
|
154 |
-
*/
|
155 |
-
public function assertLessThan($expected, $actual, $message = null) {
|
156 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('assertLessThan', func_get_args()));
|
157 |
-
}
|
158 |
-
|
159 |
-
|
160 |
-
/**
|
161 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
162 |
-
*
|
163 |
-
* Checks that expected is less or equal than actual
|
164 |
-
*
|
165 |
-
* @param $expected
|
166 |
-
* @param $actual
|
167 |
-
* @param string $message
|
168 |
-
* @see \Codeception\Module\Asserts::assertLessThanOrEqual()
|
169 |
-
*/
|
170 |
-
public function assertLessThanOrEqual($expected, $actual, $message = null) {
|
171 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('assertLessThanOrEqual', func_get_args()));
|
172 |
-
}
|
173 |
-
|
174 |
-
|
175 |
-
/**
|
176 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
177 |
-
*
|
178 |
-
* Checks that haystack contains needle
|
179 |
-
*
|
180 |
-
* @param $needle
|
181 |
-
* @param $haystack
|
182 |
-
* @param string $message
|
183 |
-
* @see \Codeception\Module\Asserts::assertContains()
|
184 |
-
*/
|
185 |
-
public function assertContains($needle, $haystack, $message = null) {
|
186 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('assertContains', func_get_args()));
|
187 |
-
}
|
188 |
-
|
189 |
-
|
190 |
-
/**
|
191 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
192 |
-
*
|
193 |
-
* Checks that haystack doesn't contain needle.
|
194 |
-
*
|
195 |
-
* @param $needle
|
196 |
-
* @param $haystack
|
197 |
-
* @param string $message
|
198 |
-
* @see \Codeception\Module\Asserts::assertNotContains()
|
199 |
-
*/
|
200 |
-
public function assertNotContains($needle, $haystack, $message = null) {
|
201 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('assertNotContains', func_get_args()));
|
202 |
-
}
|
203 |
-
|
204 |
-
|
205 |
-
/**
|
206 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
207 |
-
*
|
208 |
-
* Checks that variable is empty.
|
209 |
-
*
|
210 |
-
* @param $actual
|
211 |
-
* @param string $message
|
212 |
-
* @see \Codeception\Module\Asserts::assertEmpty()
|
213 |
-
*/
|
214 |
-
public function assertEmpty($actual, $message = null) {
|
215 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('assertEmpty', func_get_args()));
|
216 |
-
}
|
217 |
-
|
218 |
-
|
219 |
-
/**
|
220 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
221 |
-
*
|
222 |
-
* Checks that variable is not empty.
|
223 |
-
*
|
224 |
-
* @param $actual
|
225 |
-
* @param string $message
|
226 |
-
* @see \Codeception\Module\Asserts::assertNotEmpty()
|
227 |
-
*/
|
228 |
-
public function assertNotEmpty($actual, $message = null) {
|
229 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('assertNotEmpty', func_get_args()));
|
230 |
-
}
|
231 |
-
|
232 |
-
|
233 |
-
/**
|
234 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
235 |
-
*
|
236 |
-
* Checks that variable is NULL
|
237 |
-
*
|
238 |
-
* @param $actual
|
239 |
-
* @param string $message
|
240 |
-
* @see \Codeception\Module\Asserts::assertNull()
|
241 |
-
*/
|
242 |
-
public function assertNull($actual, $message = null) {
|
243 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('assertNull', func_get_args()));
|
244 |
-
}
|
245 |
-
|
246 |
-
|
247 |
-
/**
|
248 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
249 |
-
*
|
250 |
-
* Checks that variable is not NULL
|
251 |
-
*
|
252 |
-
* @param $actual
|
253 |
-
* @param string $message
|
254 |
-
* @see \Codeception\Module\Asserts::assertNotNull()
|
255 |
-
*/
|
256 |
-
public function assertNotNull($actual, $message = null) {
|
257 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('assertNotNull', func_get_args()));
|
258 |
-
}
|
259 |
-
|
260 |
-
|
261 |
-
/**
|
262 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
263 |
-
*
|
264 |
-
* Checks that condition is positive.
|
265 |
-
*
|
266 |
-
* @param $condition
|
267 |
-
* @param string $message
|
268 |
-
* @see \Codeception\Module\Asserts::assertTrue()
|
269 |
-
*/
|
270 |
-
public function assertTrue($condition, $message = null) {
|
271 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('assertTrue', func_get_args()));
|
272 |
-
}
|
273 |
-
|
274 |
-
|
275 |
-
/**
|
276 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
277 |
-
*
|
278 |
-
* Checks that condition is negative.
|
279 |
-
*
|
280 |
-
* @param $condition
|
281 |
-
* @param string $message
|
282 |
-
* @see \Codeception\Module\Asserts::assertFalse()
|
283 |
-
*/
|
284 |
-
public function assertFalse($condition, $message = null) {
|
285 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('assertFalse', func_get_args()));
|
286 |
-
}
|
287 |
-
|
288 |
-
|
289 |
-
/**
|
290 |
-
* [!] Method is generated. Documentation taken from corresponding module.
|
291 |
-
*
|
292 |
-
* Fails the test with message.
|
293 |
-
*
|
294 |
-
* @param $message
|
295 |
-
* @see \Codeception\Module\Asserts::fail()
|
296 |
-
*/
|
297 |
-
public function fail($message) {
|
298 |
-
return $this->scenario->runStep(new \Codeception\Step\Action('fail', func_get_args()));
|
299 |
-
}
|
300 |
-
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
assets/tests/codeception/unit/_bootstrap.php
DELETED
@@ -1,2 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
// Here you can initialize variables that will be available to your tests
|
Â
|
|
Â
|
assets/tests/phpunit/bootstrap.php
DELETED
@@ -1,15 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Bootstrap the plugin unit testing environment.
|
4 |
-
*
|
5 |
-
* @package wordpress-plugin-tests
|
6 |
-
*/
|
7 |
-
|
8 |
-
/* load wp environemnt */
|
9 |
-
require '../../../wp-load.php';
|
10 |
-
|
11 |
-
/* load plugins */
|
12 |
-
require '../../../wp-admin/includes/plugin.php';
|
13 |
-
|
14 |
-
|
15 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
assets/tests/phpunit/test.activations.php
DELETED
@@ -1,49 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Tests to test that that testing framework is testing tests. Meta, huh?
|
5 |
-
*
|
6 |
-
* @package wordpress-plugins-tests
|
7 |
-
*/
|
8 |
-
class Tests_Activation extends PHPUnit_Framework_TestCase {
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Run a simple test to ensure that the tests are running
|
12 |
-
*/
|
13 |
-
function test_tests() {
|
14 |
-
$this->assertTrue( true );
|
15 |
-
}
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Ensure landing pages is active
|
19 |
-
*
|
20 |
-
function test_lading_pages_activated() {
|
21 |
-
$this->assertTrue( is_plugin_active( 'landing-pages/landing-pages.php' ) );
|
22 |
-
}
|
23 |
-
|
24 |
-
/**
|
25 |
-
* Ensure that the Leads has been installed and activated.
|
26 |
-
*
|
27 |
-
function test_leads_activated() {
|
28 |
-
$this->assertTrue( is_plugin_active( 'leads/leads.php' ) );
|
29 |
-
}
|
30 |
-
|
31 |
-
/**
|
32 |
-
* Ensure that the Calls to Action has been installed and activated.
|
33 |
-
*
|
34 |
-
function test_cta_activated() {
|
35 |
-
$this->assertTrue( is_plugin_active( 'cta/calls-to-action.php' ) );
|
36 |
-
}
|
37 |
-
|
38 |
-
/**
|
39 |
-
* Run upgrade routines and check option to see if complete
|
40 |
-
*
|
41 |
-
function test_run_upgrade_routines() {
|
42 |
-
include_once LANDINGPAGES_PATH . 'classes/class.activation.php';
|
43 |
-
include_once LANDINGPAGES_PATH . 'classes/class.activation.upgrade-routines.php';
|
44 |
-
Landing_Pages_Activation::run_updates();
|
45 |
-
$this->assertTrue( true );
|
46 |
-
}*/
|
47 |
-
|
48 |
-
}
|
49 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
assets/tests/travis-ci/test.statistics.php
DELETED
@@ -1,68 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Tests to test that that testing framework is testing tests. Meta, huh?
|
5 |
-
*
|
6 |
-
* @package wordpress-plugins-tests
|
7 |
-
*/
|
8 |
-
class Tests_Statistics extends WP_UnitTestCase {
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Test to see if get_post works.
|
12 |
-
*
|
13 |
-
* Compares a post ID ($org_post_id) with post ID
|
14 |
-
* taken out of get_post ($new_post_id).
|
15 |
-
* If they don't match, get_post() doesn't work, and it will
|
16 |
-
* return an error.
|
17 |
-
*/
|
18 |
-
function test_get_post() {
|
19 |
-
//Create new post using method provided by WP
|
20 |
-
$org_post_id = $this->factory->post->create();
|
21 |
-
|
22 |
-
//get post object using the new post's ID
|
23 |
-
$post_obj = get_post( $org_post_id );
|
24 |
-
|
25 |
-
//Get the post ID as given to us by get_post
|
26 |
-
$new_post_id = $post_obj->ID;
|
27 |
-
|
28 |
-
//Use pre-defined method to test if the two ID's match
|
29 |
-
$this->assertEquals( $org_post_id, $new_post_id );
|
30 |
-
|
31 |
-
}
|
32 |
-
|
33 |
-
/**
|
34 |
-
* creates a dummy landing page for testing
|
35 |
-
*/
|
36 |
-
function test_create_demo_lander() {
|
37 |
-
/* load the class used to create the dummy landing page */
|
38 |
-
include_once LANDINGPAGES_PATH . 'modules/module.install.php';
|
39 |
-
$lp_id = inbound_create_default_post_type();
|
40 |
-
$this->assertEquals( $lp_id , 4 );
|
41 |
-
echo 1;
|
42 |
-
}
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
/**
|
47 |
-
* Check if landing-page post type exists
|
48 |
-
*/
|
49 |
-
function test_check_if_landing_page_post_type_exist() {
|
50 |
-
$this->assertTrue( post_type_exists( 'landing-page' ) );
|
51 |
-
}
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
/**
|
56 |
-
* Set landing page stats to zero for testing
|
57 |
-
*/
|
58 |
-
function test_reset_landing_page_stats() {
|
59 |
-
echo 2;
|
60 |
-
print_r( get_option( 'lp_settings_general' ) );
|
61 |
-
$landing_page = get_post( 4 );
|
62 |
-
var_dump($landing_page);
|
63 |
-
|
64 |
-
}
|
65 |
-
|
66 |
-
}
|
67 |
-
|
68 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
classes/class.acf-integration.php
CHANGED
@@ -1,705 +1,705 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
3 |
-
|
Â
|
|
Â
|
|
Â
|
|
4 |
Â
|
5 |
-
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Name under which the transient for the current tab will be saved.
|
9 |
-
* @var string
|
10 |
-
*/
|
11 |
-
static $_transient_name = 'acf_current_tab';
|
12 |
-
/**
|
13 |
-
* Number of minutes the transient will be saved.
|
14 |
-
* @var int
|
15 |
-
*/
|
16 |
-
static $_transient_minutes = 5;
|
17 |
-
|
18 |
Â
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
25 |
Â
|
26 |
Â
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
Â
|
|
Â
|
|
31 |
Â
|
32 |
-
/* Load ACF Fields On ACF powered Email Template */
|
33 |
-
add_filter( 'acf/location/rule_match/template_id' , array( __CLASS__ , 'load_acf_on_template' ) , 10 , 3 );
|
34 |
Â
|
35 |
-
|
36 |
-
|
Â
|
|
Â
|
|
37 |
Â
|
38 |
-
|
39 |
-
|
40 |
Â
|
41 |
-
|
Â
|
|
42 |
Â
|
43 |
-
|
44 |
-
|
45 |
-
add_filter( '_wp_post_revision_field_inbound_settings', array( __CLASS__ , 'add_revision_field_values' ) , 10 , 3 );
|
46 |
Â
|
47 |
-
|
48 |
-
add_filter( 'acf/load_value' , array( __CLASS__ , 'load_value' ) , 11 , 3 );
|
49 |
Â
|
50 |
-
|
51 |
-
|
Â
|
|
52 |
Â
|
53 |
-
|
54 |
-
|
55 |
Â
|
56 |
-
|
57 |
-
|
58 |
Â
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
add_action( 'acf/input/admin_footer', array( __CLASS__ , 'handle_tab' ) );
|
63 |
-
add_action( 'wp_ajax_acf_save_current_tab', array( __CLASS__ , 'ajax_acf_save_current_tab' ) );
|
64 |
-
|
65 |
-
}
|
66 |
Â
|
67 |
-
|
68 |
-
|
69 |
-
* @return mixed
|
70 |
-
*/
|
71 |
-
public static function define_location_rule_types( $choices ) {
|
72 |
Â
|
73 |
-
|
74 |
-
|
75 |
-
}
|
76 |
Â
|
77 |
-
|
78 |
-
|
79 |
Â
|
80 |
-
|
81 |
-
$template_ids = Landing_Pages_Load_Extensions::get_uploaded_template_ids();
|
82 |
Â
|
83 |
-
|
84 |
-
|
85 |
-
|
Â
|
|
Â
|
|
86 |
Â
|
87 |
-
|
88 |
-
|
Â
|
|
89 |
Â
|
90 |
-
|
91 |
-
|
92 |
Â
|
93 |
-
|
94 |
-
|
95 |
Â
|
96 |
-
|
Â
|
|
97 |
Â
}
|
98 |
Â
|
99 |
-
|
100 |
-
|
101 |
-
*/
|
102 |
-
public static function reposition_acf_fields() {
|
103 |
-
global $post;
|
104 |
Â
|
105 |
-
|
106 |
-
|
107 |
-
}
|
108 |
Â
|
109 |
-
|
110 |
-
<script type='text/javascript'>
|
111 |
-
jQuery('.acf_postbox').each(function(){
|
112 |
-
jQuery('#template-display-options').append(jQuery(this));
|
113 |
-
});
|
114 |
-
</script>
|
115 |
-
<?php
|
116 |
Â
}
|
117 |
Â
|
Â
|
|
Â
|
|
118 |
Â
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
Â
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
Â
|
130 |
-
|
131 |
-
|
132 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
133 |
Â
|
134 |
-
/* save acf settings - uses our future data array - eventually we will migrate all post meta into this data object */
|
135 |
-
$fields = (isset($_POST['fields'])) ? $_POST['fields'] : null;
|
136 |
-
$fields = (isset($_POST['acf'])) ? $_POST['acf'] : $fields;
|
137 |
Â
|
138 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
139 |
Â
|
140 |
-
$settings = Landing_Pages_Meta::get_settings( $landing_page_id );
|
141 |
-
$variation_id = (isset($_REQUEST['lp-variation-id'])) ? intval($_REQUEST['lp-variation-id']) : '0';
|
142 |
Â
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
Â
|
147 |
-
|
148 |
-
|
149 |
-
}
|
150 |
Â
}
|
151 |
Â
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
* @param $revision_id
|
156 |
-
*/
|
157 |
-
public static function restore_acf_values( $post_id , $revision_id ) {
|
158 |
Â
|
159 |
-
|
160 |
-
if($post->post_type!='landing-page' ) {
|
161 |
-
return;
|
162 |
-
}
|
163 |
Â
|
164 |
-
$
|
Â
|
|
165 |
Â
|
166 |
-
|
Â
|
|
Â
|
|
167 |
Â
|
Â
|
|
Â
|
|
168 |
Â
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
169 |
Â
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
* @return mixed
|
174 |
-
*/
|
175 |
-
public static function add_revision_fields( $fields ) {
|
176 |
-
global $post;
|
177 |
-
$fields['inbound_settings'] = __('Landing Page Settings' , 'inbound-pro');
|
178 |
-
return $fields;
|
179 |
Â
}
|
180 |
Â
|
181 |
-
|
182 |
Â
|
183 |
-
|
184 |
-
return $value;
|
185 |
-
}
|
186 |
Â
|
187 |
-
|
188 |
Â
|
189 |
-
|
190 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
191 |
Â
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
* @param $post_id
|
196 |
-
* @param $field
|
197 |
-
* @return mixed
|
198 |
-
*/
|
199 |
-
public static function format_value( $value, $post_id, $field ) {
|
200 |
Â
return $value;
|
201 |
Â
}
|
202 |
Â
|
203 |
-
|
204 |
-
* Finds the correct value given the variation
|
205 |
-
*
|
206 |
-
* @param MIXED $value contains the non-variation value
|
207 |
-
* @param INT $post_id ID of landing page being loaded
|
208 |
-
* @param ARRAY $field wide array of data belonging to custom field (not leveraged in this method)
|
209 |
-
*
|
210 |
-
* @returns MIXED $new_value value mapped to variation.
|
211 |
-
*/
|
212 |
-
public static function load_value( $value, $post_id, $field ) {
|
213 |
-
global $post;
|
214 |
Â
|
215 |
-
|
216 |
-
|
217 |
-
}
|
218 |
Â
|
219 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
220 |
Â
|
221 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
222 |
Â
|
223 |
-
|
Â
|
|
Â
|
|
224 |
Â
|
225 |
-
|
226 |
Â
|
227 |
-
|
228 |
-
return self::load_legacy_value( $value, $post_id, $field );
|
229 |
-
}
|
230 |
Â
|
Â
|
|
231 |
Â
|
232 |
-
|
233 |
-
$new_value = self::search_field_array( $variations[ $vid ][ 'acf' ] , $field );
|
234 |
Â
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
} else if($new_value) {
|
239 |
-
if ($new_value =='_empty') {
|
240 |
-
$new_value = '';
|
241 |
-
}
|
242 |
-
$value = $new_value;
|
243 |
-
}
|
244 |
Â
|
245 |
-
/* acf lite isn't processing return values correctly - ignore repeater subfields */
|
246 |
-
if ( !is_admin() && defined('ACF_FREE') ) {
|
247 |
-
$value = self::acf_free_value_formatting( $value , $field );
|
248 |
Â
|
249 |
-
|
Â
|
|
250 |
Â
|
251 |
-
|
252 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
253 |
Â
}
|
Â
|
|
Â
|
|
254 |
Â
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
}
|
259 |
Â
|
260 |
Â
}
|
261 |
Â
|
262 |
-
|
Â
|
|
Â
|
|
263 |
Â
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
*
|
268 |
-
* @param MIXED $value contains the non-variation value
|
269 |
-
* @param INT $post_id ID of landing page being loaded
|
270 |
-
* @param ARRAY $field wide array of data belonging to custom field (not leveraged in this method)
|
271 |
-
*
|
272 |
-
* @returns MIXED $new_value value mapped to variation.
|
273 |
-
*/
|
274 |
-
public static function load_legacy_value( $value, $post_id, $field ) {
|
275 |
-
global $post;
|
276 |
-
|
277 |
-
/* get registered field object data */
|
278 |
-
$field = self::acf_get_registered_field( $field );
|
279 |
-
|
280 |
-
/* if a brand new post ignore return default value */
|
281 |
-
if ( $post->post_status != 'publish' ) {
|
282 |
-
return ( isset($field['default_value']) ) ? do_shortcode($field['default_value']) : '' ;
|
283 |
Â
}
|
284 |
Â
|
285 |
-
|
286 |
Â
|
287 |
-
|
288 |
-
$value = get_post_meta( $post_id , $field['name'] . '-' . $vid , true );
|
289 |
-
} else {
|
290 |
-
$value = get_post_meta( $post_id , $field['name'] , true );
|
291 |
-
}
|
292 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
293 |
Â
|
294 |
-
|
295 |
-
|
296 |
-
}
|
297 |
Â
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
}
|
303 |
Â
|
304 |
-
|
305 |
-
if (!strstr( $value , '#' ) && $value ) {
|
306 |
-
$value = '#'.$value;
|
307 |
-
}
|
308 |
-
}
|
309 |
Â
|
310 |
-
|
311 |
-
|
312 |
-
|
Â
|
|
Â
|
|
313 |
Â
|
314 |
-
return $value;
|
315 |
Â
|
Â
|
|
Â
|
|
316 |
Â
}
|
317 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
318 |
Â
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
*
|
325 |
-
* @return $feild value
|
326 |
-
*/
|
327 |
-
public static function search_field_array( $array , $field ) {
|
328 |
Â
|
329 |
-
|
Â
|
|
Â
|
|
330 |
Â
|
331 |
-
|
332 |
Â
|
Â
|
|
333 |
Â
|
334 |
-
if ($key === $needle && !is_array($value) ) {
|
335 |
-
$value = ($value) ? $value : '_empty' ;
|
336 |
-
return $value;
|
337 |
-
}
|
338 |
Â
|
339 |
-
|
340 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
341 |
Â
|
342 |
-
|
343 |
-
if ( $key === $needle ) {
|
344 |
Â
|
345 |
-
|
346 |
-
if ($repeater_array) {
|
347 |
-
return $repeater_array;
|
348 |
-
} else {
|
349 |
-
return $value;
|
350 |
-
}
|
351 |
Â
|
352 |
-
}
|
353 |
Â
|
354 |
-
|
355 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
356 |
Â
|
357 |
-
|
358 |
-
if ($
|
359 |
-
return $
|
Â
|
|
Â
|
|
360 |
Â
}
|
361 |
Â
|
Â
|
|
362 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
363 |
Â
}
|
364 |
Â
|
Â
|
|
365 |
Â
}
|
366 |
Â
|
367 |
-
return false;
|
368 |
Â
}
|
369 |
Â
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
Â
|
|
Â
|
|
Â
|
|
376 |
Â
|
377 |
-
|
378 |
Â
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
}
|
383 |
Â
}
|
384 |
-
|
385 |
-
return $fields;
|
386 |
Â
}
|
387 |
Â
|
Â
|
|
Â
|
|
Â
|
|
388 |
Â
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
Â
|
396 |
-
|
397 |
-
|
398 |
Â
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
Â
|
404 |
-
|
405 |
-
|
406 |
Â
|
407 |
Â
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
Â
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
Â
|
418 |
Â
|
419 |
Â
|
420 |
-
|
421 |
Â
|
422 |
-
|
423 |
Â
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
Â
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
Â
|
438 |
-
|
439 |
Â
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
}
|
445 |
Â
}
|
Â
|
|
446 |
Â
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
Â
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
Â
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
Â
|
473 |
-
|
474 |
Â
|
475 |
-
|
476 |
-
|
477 |
Â
|
478 |
-
|
479 |
Â
|
480 |
-
|
481 |
Â
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
}
|
486 |
Â
}
|
Â
|
|
487 |
Â
|
488 |
-
|
489 |
Â
|
490 |
-
|
491 |
-
|
492 |
Â
|
493 |
-
|
494 |
-
|
495 |
Â
|
496 |
-
|
497 |
Â
|
498 |
-
|
499 |
Â
|
500 |
-
|
501 |
Â
|
502 |
-
|
503 |
-
|
504 |
-
}
|
505 |
Â
}
|
506 |
-
|
507 |
-
return false;
|
508 |
Â
}
|
509 |
Â
|
510 |
-
|
511 |
-
|
512 |
Â
|
513 |
-
|
514 |
-
|
515 |
-
}
|
516 |
Â
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
Â
|
|
Â
|
|
Â
|
|
522 |
Â
}
|
523 |
Â
}
|
524 |
Â
}
|
Â
|
|
525 |
Â
|
526 |
Â
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
Â
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
Â
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
Â
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
Â
|
|
Â
|
|
Â
|
|
545 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
546 |
Â
return $value;
|
547 |
Â
}
|
Â
|
|
548 |
Â
|
549 |
-
/**
|
550 |
-
* checks template data type
|
551 |
-
* @param $value
|
552 |
-
* @param $field
|
553 |
-
* @return mixed
|
554 |
-
*/
|
555 |
-
public static function acf_check_if_acf4( $value , $field ) {
|
556 |
-
global $key, $lp_data;
|
557 |
Â
|
558 |
-
|
559 |
-
|
560 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
561 |
Â
|
562 |
-
|
563 |
-
|
Â
|
|
564 |
Â
} else {
|
565 |
-
|
Â
|
|
Â
|
|
Â
|
|
566 |
Â
}
|
567 |
-
}
|
568 |
-
|
569 |
-
|
570 |
-
/**
|
571 |
-
* This is a complicated array search method for working with ACF repeater fields.
|
572 |
-
* @param $array
|
573 |
-
* @param $field
|
574 |
-
* @param bool|false $get_parent if get_parent is set to true to will return the parent field group key of the repeater fields
|
575 |
-
* @param mixed $last_key placeholder for storing the last key...
|
576 |
-
* @return bool|int|string
|
577 |
-
*/
|
578 |
-
public static function key_search($array, $field , $get_parent = false , $last_key = false) {
|
579 |
-
$value = false;
|
580 |
Â
|
581 |
-
|
582 |
-
if (
|
583 |
-
$value
|
584 |
Â
} else {
|
585 |
-
|
586 |
-
$last_key = ( !is_numeric($key)) ? $key : $last_key;
|
587 |
-
$value = self::key_search($item, $field , $get_parent , $last_key );
|
588 |
-
}
|
589 |
Â
}
|
590 |
Â
|
591 |
-
if ($value) {
|
592 |
-
if (!$get_parent) {
|
593 |
-
return $value;
|
594 |
-
} else {
|
595 |
-
return $last_key;
|
596 |
-
}
|
597 |
-
|
598 |
-
}
|
599 |
Â
}
|
600 |
-
|
601 |
-
return false;
|
602 |
Â
}
|
603 |
-
|
604 |
-
/**
|
605 |
-
* Select tab that was selected in last edit session of the post.
|
606 |
-
*
|
607 |
-
* - If the time the same post that was last edited lies within the time the
|
608 |
-
* transient exists, the last selected tab will be selected via JavaScript.
|
609 |
-
* - If a new post is opened for editing, the current tab will be overwritten.
|
610 |
-
*/
|
611 |
-
public static function handle_tab() {
|
612 |
-
// Run only when post_id is present
|
613 |
-
if ( ! isset( $_GET['post'] ) || ! is_numeric( $_GET['post'] ) ) {
|
614 |
-
return;
|
615 |
-
}
|
616 |
-
$post_id = sanitize_key( $_GET['post'] );
|
617 |
-
// Check for existing transient
|
618 |
-
$current_tab = get_transient( self::$_transient_name );
|
619 |
-
// Use value only once, delete transient right away
|
620 |
-
delete_transient( self::$_transient_name );
|
621 |
-
// The first tab is selected by default
|
622 |
-
$tab_index = 0;
|
623 |
-
// Get tab index for current post
|
624 |
-
if ( $current_tab['post_id'] === $post_id ) {
|
625 |
-
$tab_index = $current_tab['tab_index'];
|
626 |
-
}
|
627 |
-
?>
|
628 |
-
<script type="text/javascript">
|
629 |
-
(function($) {
|
630 |
-
/**
|
631 |
-
* Global to save the current index of selected tab
|
632 |
-
* @type int
|
633 |
-
*/
|
634 |
-
window.acf_current_tab_index = null;
|
635 |
-
acf.add_action('ready', function( $el ){
|
636 |
-
var tabIndex = <?php echo $tab_index; ?>
|
637 |
-
// Get tab element by index
|
638 |
-
var $li = $('.acf-tab-group').find('li:eq(<?php echo $tab_index; ?>)');
|
639 |
-
// Select tab only when it’s not the first tab, which is selected by default
|
640 |
-
if (0 !== tabIndex) {
|
641 |
-
$li.find('a').click();
|
642 |
-
}
|
643 |
-
window.acf_current_tab_index = tabIndex;
|
644 |
-
});
|
645 |
-
acf.add_action('refresh', function($tabGroup) {
|
646 |
-
var $currentTab;
|
647 |
-
var currentTabIndex = window.acf_current_tab_index;
|
648 |
-
var newTabIndex;
|
649 |
-
// Bail out if we have no jQuery object
|
650 |
-
if (false === $tabGroup instanceof jQuery) {
|
651 |
-
return;
|
652 |
-
}
|
653 |
-
$currentTab = $tabGroup.find('li.active');
|
654 |
-
// Bail out if no active tab was found
|
655 |
-
if ($currentTab.length === 0) {
|
656 |
-
return;
|
657 |
-
}
|
658 |
-
// Get index of active tab
|
659 |
-
newTabIndex = $currentTab.index();
|
660 |
-
// Bail out if index is initial or previously selected tab is the same
|
661 |
-
if (null === currentTabIndex || newTabIndex === currentTabIndex) {
|
662 |
-
return;
|
663 |
-
}
|
664 |
-
window.acf_current_tab_index = newTabIndex;
|
665 |
-
// Send tabIndex to backend to save transient
|
666 |
-
$.ajax(ajaxurl, {
|
667 |
-
method: 'post',
|
668 |
-
data: {
|
669 |
-
action: 'acf_save_current_tab',
|
670 |
-
tab_index: newTabIndex,
|
671 |
-
post_id: <?php echo $post_id; ?>
|
672 |
-
}
|
673 |
-
});
|
674 |
-
});
|
675 |
-
})(jQuery);
|
676 |
-
</script>
|
677 |
-
<?php
|
678 |
-
}
|
679 |
-
public static function ajax_acf_save_current_tab() {
|
680 |
-
if ( ! isset( $_POST['tab_index'] ) || ! is_numeric( $_POST['tab_index'] ) ) {
|
681 |
-
return;
|
682 |
-
}
|
683 |
-
$tab_index = sanitize_text_field($_POST['tab_index']);
|
684 |
-
$post_id = $_POST['post_id'];
|
685 |
-
$transient_value = array(
|
686 |
-
'tab_index' => $tab_index,
|
687 |
-
'post_id' => $post_id,
|
688 |
-
);
|
689 |
-
$result = set_transient( self::$_transient_name, $transient_value, self::$_transient_minutes * 60 );
|
690 |
-
if ( $result ) {
|
691 |
-
wp_send_json_success();
|
692 |
-
}
|
693 |
-
wp_die();
|
694 |
-
}
|
695 |
Â
|
Â
|
|
696 |
Â
}
|
697 |
Â
|
698 |
Â
/**
|
699 |
-
*
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
700 |
Â
*/
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
701 |
Â
|
702 |
-
|
703 |
Â
|
Â
|
|
Â
|
|
Â
|
|
704 |
Â
|
705 |
-
|
1 |
Â
<?php
|
2 |
Â
|
3 |
+
/**
|
4 |
+
* Class ifor integrating landingpage CPT with ACF4 & ACF5
|
5 |
+
* @package ACF
|
6 |
+
*/
|
7 |
Â
|
8 |
+
class Landing_Pages_ACF {
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
9 |
Â
|
10 |
+
/**
|
11 |
+
* Name under which the transient for the current tab will be saved.
|
12 |
+
* @var string
|
13 |
+
*/
|
14 |
+
static $_transient_name = 'acf_current_tab';
|
15 |
+
/**
|
16 |
+
* Number of minutes the transient will be saved.
|
17 |
+
* @var int
|
18 |
+
*/
|
19 |
+
static $_transient_minutes = 5;
|
20 |
Â
|
21 |
Â
|
22 |
+
/**
|
23 |
+
* Initialize Landing_Pages_ACF Class
|
24 |
+
*/
|
25 |
+
public function __construct() {
|
26 |
+
self::load_hooks();
|
27 |
+
}
|
28 |
Â
|
Â
|
|
Â
|
|
29 |
Â
|
30 |
+
/**
|
31 |
+
* Load Hooks & Filters
|
32 |
+
*/
|
33 |
+
public static function load_hooks() {
|
34 |
Â
|
35 |
+
/* Load ACF Fields On ACF powered Email Template */
|
36 |
+
add_filter( 'acf/location/rule_match/template_id' , array( __CLASS__ , 'load_acf_on_template' ) , 10 , 3 );
|
37 |
Â
|
38 |
+
/* make sure fields are placed in the correct location */
|
39 |
+
add_action( 'save_post', array( __CLASS__ , 'save_acf_fields' ) );
|
40 |
Â
|
41 |
+
/* make sure fields are placed in the correct location */
|
42 |
+
add_action( 'wp_restore_post_revision', array( __CLASS__ , 'restore_acf_values' ) , 10 , 2 );
|
Â
|
|
43 |
Â
|
44 |
+
/* Adds revision fields to the revisions screen */
|
Â
|
|
45 |
Â
|
46 |
+
/* Adds revision fields value for Inbound Settings to the revisions screen */
|
47 |
+
add_filter( '_wp_post_revision_fields', array( __CLASS__ , 'add_revision_fields' ) );
|
48 |
+
add_filter( '_wp_post_revision_field_inbound_settings', array( __CLASS__ , 'add_revision_field_values' ) , 10 , 3 );
|
49 |
Â
|
50 |
+
/* Intercept load custom field value request and hijack it */
|
51 |
+
add_filter( 'acf/load_value' , array( __CLASS__ , 'load_value' ) , 11 , 3 );
|
52 |
Â
|
53 |
+
/* extra field formatting
|
54 |
+
add_filter( 'acf/format_value' , array( __CLASS__ , 'format_value' ) , 11 , 3 ); */
|
55 |
Â
|
56 |
+
/* make sure fields are placed in the correct location */
|
57 |
+
add_action( 'admin_print_footer_scripts', array( __CLASS__ , 'reposition_acf_fields' ) );
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
58 |
Â
|
59 |
+
/* add new location rule to ACF Field UI */
|
60 |
+
add_filter('acf/location/rule_types', array( __CLASS__ , 'define_location_rule_types' ) );
|
Â
|
|
Â
|
|
Â
|
|
61 |
Â
|
62 |
+
/* add new location rule values to ACF Field UI */
|
63 |
+
add_filter('acf/location/rule_values/template_id', array( __CLASS__ , 'define_location_rule_values' ) );
|
Â
|
|
64 |
Â
|
65 |
+
add_action( 'acf/input/admin_footer', array( __CLASS__ , 'handle_tab' ) );
|
66 |
+
add_action( 'wp_ajax_acf_save_current_tab', array( __CLASS__ , 'ajax_acf_save_current_tab' ) );
|
67 |
Â
|
68 |
+
}
|
Â
|
|
69 |
Â
|
70 |
+
/**
|
71 |
+
* @param $choices
|
72 |
+
* @return mixed
|
73 |
+
*/
|
74 |
+
public static function define_location_rule_types( $choices ) {
|
75 |
Â
|
76 |
+
if (!isset($choices['Basic']['template_id'])) {
|
77 |
+
$choices['Basic']['template_id'] = __('Template ID', 'landing-page');
|
78 |
+
}
|
79 |
Â
|
80 |
+
return $choices;
|
81 |
+
}
|
82 |
Â
|
83 |
+
public static function define_location_rule_values( $choices ) {
|
84 |
+
$template_ids = Landing_Pages_Load_Extensions::get_uploaded_template_ids();
|
85 |
Â
|
86 |
+
if (!isset($choices['default'])) {
|
87 |
+
$choices[ 'default' ] = 'default';
|
88 |
Â
}
|
89 |
Â
|
90 |
+
if( $template_ids ) {
|
91 |
+
foreach( $template_ids as $template_id ) {
|
Â
|
|
Â
|
|
Â
|
|
92 |
Â
|
93 |
+
/* template ID by template name here */
|
94 |
+
$choices[ $template_id ] = $template_id;
|
Â
|
|
95 |
Â
|
96 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
97 |
Â
}
|
98 |
Â
|
99 |
+
return $choices;
|
100 |
+
}
|
101 |
Â
|
102 |
+
/**
|
103 |
+
* Adds javascript to make sure ACF fields load inside template container
|
104 |
+
*/
|
105 |
+
public static function reposition_acf_fields() {
|
106 |
+
global $post;
|
Â
|
|
107 |
Â
|
108 |
+
if ( !defined('ACF_FREE') || ( !isset($post) || $post->post_type != 'landing-page' ) ) {
|
109 |
+
return;
|
110 |
+
}
|
111 |
Â
|
112 |
+
?>
|
113 |
+
<script type='text/javascript'>
|
114 |
+
jQuery('.acf_postbox').each(function(){
|
115 |
+
jQuery('#template-display-options').append(jQuery(this));
|
116 |
+
});
|
117 |
+
</script>
|
118 |
+
<?php
|
119 |
+
}
|
120 |
Â
|
Â
|
|
Â
|
|
Â
|
|
121 |
Â
|
122 |
+
/**
|
123 |
+
* Compiles ACF Meta Data into a singular json pair for variation support
|
124 |
+
* @param $landing_page_id
|
125 |
+
*/
|
126 |
+
public static function save_acf_fields( $landing_page_id ) {
|
127 |
Â
|
Â
|
|
Â
|
|
128 |
Â
|
129 |
+
if ( !isset($_POST['post_type']) || $_POST['post_type'] != 'landing-page' ) {
|
130 |
+
return;
|
131 |
+
}
|
132 |
Â
|
133 |
+
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
|
134 |
+
return;
|
Â
|
|
135 |
Â
}
|
136 |
Â
|
137 |
+
/* save acf settings - uses our future data array - eventually we will migrate all post meta into this data object */
|
138 |
+
$fields = (isset($_POST['fields'])) ? $_POST['fields'] : null;
|
139 |
+
$fields = (isset($_POST['acf'])) ? $_POST['acf'] : $fields;
|
Â
|
|
Â
|
|
Â
|
|
140 |
Â
|
141 |
+
if ( $fields ) {
|
Â
|
|
Â
|
|
Â
|
|
142 |
Â
|
143 |
+
$settings = Landing_Pages_Meta::get_settings( $landing_page_id );
|
144 |
+
$variation_id = (isset($_REQUEST['lp-variation-id'])) ? intval($_REQUEST['lp-variation-id']) : '0';
|
145 |
Â
|
146 |
+
if (!isset($settings['variations'])) {
|
147 |
+
$settings['variations'] = array();
|
148 |
+
}
|
149 |
Â
|
150 |
+
$settings['variations'][$variation_id]['acf'] = $fields;
|
151 |
+
Landing_Pages_Meta::update_settings( $landing_page_id , $settings );
|
152 |
Â
}
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Restore landing page ACF values from revision
|
157 |
+
* @param $post_id
|
158 |
+
* @param $revision_id
|
159 |
+
*/
|
160 |
+
public static function restore_acf_values( $post_id , $revision_id ) {
|
161 |
Â
|
162 |
+
$post = get_post($post_id);
|
163 |
+
if($post->post_type!='landing-page' ) {
|
164 |
+
return;
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
165 |
Â
}
|
166 |
Â
|
167 |
+
$revision_settings = Landing_Pages_Meta::get_settings( $revision_id );
|
168 |
Â
|
169 |
+
Landing_Pages_Meta::update_settings( $post_id , $revision_settings );
|
Â
|
|
Â
|
|
170 |
Â
|
171 |
+
}
|
172 |
Â
|
173 |
+
/**
|
174 |
+
* Adds revision fields to revisions screen
|
175 |
+
* @param $fields
|
176 |
+
* @return mixed
|
177 |
+
*/
|
178 |
+
public static function add_revision_fields( $fields ) {
|
179 |
+
global $post;
|
180 |
+
$fields['inbound_settings'] = __('Landing Page Settings' , 'inbound-pro');
|
181 |
+
return $fields;
|
182 |
+
}
|
183 |
Â
|
184 |
+
public static function add_revision_field_values( $value , $field , $revision) {
|
185 |
+
|
186 |
+
if (!isset($revision->ID)) {
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
187 |
Â
return $value;
|
188 |
Â
}
|
189 |
Â
|
190 |
+
$settings = Landing_Pages_Meta::get_settings( $revision->ID );
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
191 |
Â
|
192 |
+
return json_encode($settings);
|
193 |
+
}
|
Â
|
|
194 |
Â
|
195 |
+
/**
|
196 |
+
* Although unused at the moment, this method can be used for filtering the return value with ACF5 fields
|
197 |
+
* @param $value
|
198 |
+
* @param $post_id
|
199 |
+
* @param $field
|
200 |
+
* @return mixed
|
201 |
+
*/
|
202 |
+
public static function format_value( $value, $post_id, $field ) {
|
203 |
+
return $value;
|
204 |
+
}
|
205 |
Â
|
206 |
+
/**
|
207 |
+
* Finds the correct value given the variation
|
208 |
+
*
|
209 |
+
* @param MIXED $value contains the non-variation value
|
210 |
+
* @param INT $post_id ID of landing page being loaded
|
211 |
+
* @param ARRAY $field wide array of data belonging to custom field (not leveraged in this method)
|
212 |
+
*
|
213 |
+
* @returns MIXED $new_value value mapped to variation.
|
214 |
+
*/
|
215 |
+
public static function load_value( $value, $post_id, $field ) {
|
216 |
+
global $post;
|
217 |
Â
|
218 |
+
if ( !isset($post) || $post->post_type != 'landing-page' ) {
|
219 |
+
return $value;
|
220 |
+
}
|
221 |
Â
|
222 |
+
$vid = Landing_Pages_Variations::get_new_variation_reference_id( $post->ID );
|
223 |
Â
|
224 |
+
$settings = Landing_Pages_Meta::get_settings( $post->ID );
|
Â
|
|
Â
|
|
225 |
Â
|
226 |
+
$variations = ( isset($settings['variations']) ) ? $settings['variations'] : null;
|
227 |
Â
|
228 |
+
/* If there is no ACF data for this template attempt to pull values from the legacy postmeta values */
|
Â
|
|
229 |
Â
|
230 |
+
if ( !isset( $variations[ $vid ][ 'acf' ] ) || !$variations[ $vid ][ 'acf' ]) {
|
231 |
+
return self::load_legacy_value( $value, $post_id, $field );
|
232 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
233 |
Â
|
Â
|
|
Â
|
|
Â
|
|
234 |
Â
|
235 |
+
if ( isset( $variations[ $vid ][ 'acf' ] ) ) {
|
236 |
+
$new_value = self::search_field_array( $variations[ $vid ][ 'acf' ] , $field );
|
237 |
Â
|
238 |
+
/* sometimes value is an array count when new_value believes it should be an array in this case get new count */
|
239 |
+
if (!is_array($value) && is_array($new_value)) {
|
240 |
+
$value = count($new_value);
|
241 |
+
} else if($new_value) {
|
242 |
+
if ($new_value =='_empty') {
|
243 |
+
$new_value = '';
|
244 |
Â
}
|
245 |
+
$value = $new_value;
|
246 |
+
}
|
247 |
Â
|
248 |
+
/* acf lite isn't processing return values correctly - ignore repeater subfields */
|
249 |
+
if ( !is_admin() && defined('ACF_FREE') ) {
|
250 |
+
$value = self::acf_free_value_formatting( $value , $field );
|
Â
|
|
251 |
Â
|
252 |
Â
}
|
253 |
Â
|
254 |
+
if ( !is_admin() && is_string($value) && !defined('INBOUND_DEBUG_GF_AJAX') ) {
|
255 |
+
$value = do_shortcode($value);
|
256 |
+
}
|
257 |
Â
|
258 |
+
/* handle non acf5 template return formatting */
|
259 |
+
if (defined('ACF_PRO')) {
|
260 |
+
$value = self::acf_check_if_acf4( $value , $field );
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
261 |
Â
}
|
262 |
Â
|
263 |
+
}
|
264 |
Â
|
265 |
+
return $value;
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
266 |
Â
|
267 |
+
}
|
268 |
+
/**
|
269 |
+
* Finds the correct value given the variation - uses legacy meta system
|
270 |
+
*
|
271 |
+
* @param MIXED $value contains the non-variation value
|
272 |
+
* @param INT $post_id ID of landing page being loaded
|
273 |
+
* @param ARRAY $field wide array of data belonging to custom field (not leveraged in this method)
|
274 |
+
*
|
275 |
+
* @returns MIXED $new_value value mapped to variation.
|
276 |
+
*/
|
277 |
+
public static function load_legacy_value( $value, $post_id, $field ) {
|
278 |
+
global $post;
|
279 |
Â
|
280 |
+
/* get registered field object data */
|
281 |
+
$field = self::acf_get_registered_field( $field );
|
Â
|
|
282 |
Â
|
283 |
+
/* if a brand new post ignore return default value */
|
284 |
+
if ( $post->post_status != 'publish' ) {
|
285 |
+
return ( isset($field['default_value']) ) ? do_shortcode($field['default_value']) : '' ;
|
286 |
+
}
|
Â
|
|
287 |
Â
|
288 |
+
$vid = Landing_Pages_Variations::get_new_variation_reference_id( $post->ID );
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
289 |
Â
|
290 |
+
if ( $vid ) {
|
291 |
+
$value = get_post_meta( $post_id , $field['name'] . '-' . $vid , true );
|
292 |
+
} else {
|
293 |
+
$value = get_post_meta( $post_id , $field['name'] , true );
|
294 |
+
}
|
295 |
Â
|
Â
|
|
296 |
Â
|
297 |
+
if ($field['type']=='image' && is_admin() ) {
|
298 |
+
$value = self::get_image_id_from_url( $value );
|
299 |
Â
}
|
300 |
Â
|
301 |
+
if ($field['type']=='date_picker') {
|
302 |
+
$value = str_replace('-' , '', $value);
|
303 |
+
$value = explode(' ' , $value);
|
304 |
+
$value = $value[0];
|
305 |
+
}
|
306 |
Â
|
307 |
+
if ($field['type']=='color_picker') {
|
308 |
+
if (!strstr( $value , '#' ) && $value ) {
|
309 |
+
$value = '#'.$value;
|
310 |
+
}
|
311 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
312 |
Â
|
313 |
+
if (!is_array($value) && !is_admin() ) {
|
314 |
+
$value = do_shortcode($value);
|
315 |
+
}
|
316 |
Â
|
317 |
+
return $value;
|
318 |
Â
|
319 |
+
}
|
320 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
321 |
Â
|
322 |
+
/**
|
323 |
+
* Searches ACF variation array and returns the correct field value given the field key
|
324 |
+
*
|
325 |
+
* @param ARRAY $array of custom field keys and values stored for variation
|
326 |
+
* @param STRING $needle acf form field key
|
327 |
+
*
|
328 |
+
* @return $feild value
|
329 |
+
*/
|
330 |
+
public static function search_field_array( $array , $field ) {
|
331 |
Â
|
332 |
+
$needle = $field['key'];
|
Â
|
|
333 |
Â
|
334 |
+
foreach ($array as $key => $value ){
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
335 |
Â
|
Â
|
|
336 |
Â
|
337 |
+
if ($key === $needle && !is_array($value) ) {
|
338 |
+
$value = ($value) ? $value : '_empty' ;
|
339 |
+
return $value;
|
340 |
+
}
|
341 |
+
|
342 |
+
/* Arrays could be repeaters or any custom field with sets of multiple values */
|
343 |
+
if ( is_array($value) ) {
|
344 |
+
|
345 |
+
/* Check if this array contains a repeater field layouts. If it does then return layouts, else this array is a non-repeater value set so return it */
|
346 |
+
if ( $key === $needle ) {
|
347 |
Â
|
348 |
+
$repeater_array = self::get_repeater_layouts( $value );
|
349 |
+
if ($repeater_array) {
|
350 |
+
return $repeater_array;
|
351 |
+
} else {
|
352 |
+
return $value;
|
353 |
Â
}
|
354 |
Â
|
355 |
+
}
|
356 |
Â
|
357 |
+
/* Check if array is repeater fields and determine correct value given a parsed field name with field key */
|
358 |
+
$repeater_value = self::get_repeater_values( $value , $field , $needle );
|
359 |
+
|
360 |
+
/* If target key is not in these repeater fields, or this array is not determined to be a repeater field then move on. */
|
361 |
+
if ($repeater_value) {
|
362 |
+
return $repeater_value;
|
363 |
Â
}
|
364 |
Â
|
365 |
+
|
366 |
Â
}
|
367 |
Â
|
Â
|
|
368 |
Â
}
|
369 |
Â
|
370 |
+
return false;
|
371 |
+
}
|
372 |
+
|
373 |
+
/**
|
374 |
+
* Searches an array assumed to be a repeater field dataset and returns an array of repeater field layout definitions
|
375 |
+
*
|
376 |
+
* @retuns ARRAY $fields this array will either be empty of contain repeater field layout definitions.
|
377 |
+
*/
|
378 |
+
public static function get_repeater_layouts( $array ) {
|
379 |
Â
|
380 |
+
$fields = array();
|
381 |
Â
|
382 |
+
foreach ($array as $key => $value) {
|
383 |
+
if ( isset( $value['acf_fc_layout'] ) ) {
|
384 |
+
$fields[] = $value['acf_fc_layout'];
|
Â
|
|
385 |
Â
}
|
Â
|
|
Â
|
|
386 |
Â
}
|
387 |
Â
|
388 |
+
return $fields;
|
389 |
+
}
|
390 |
+
|
391 |
Â
|
392 |
+
/**
|
393 |
+
* Searches an array assumed to be a repeater field dataset and returns an array of repeater field layout definitions
|
394 |
+
*
|
395 |
+
* @retuns ARRAY $fields this array will either be empty of contain repeater field layout definitions.
|
396 |
+
*/
|
397 |
+
public static function get_repeater_values( $array , $field , $needle ) {
|
398 |
Â
|
399 |
+
/* Discover correct repeater pointer by parsing field name */
|
400 |
+
preg_match('/(_\d_)/', $field['name'], $matches, 0);
|
401 |
Â
|
402 |
+
/* if not a repeater subfield then bail */
|
403 |
+
if (!$matches) {
|
404 |
+
return false;
|
405 |
+
}
|
406 |
Â
|
407 |
+
$pointer = str_replace('_' , '' , $matches[0]);
|
408 |
+
$repeater_key = self::key_search($array, $field , true ); /* returns parent flexible content field key using sub field key */
|
409 |
Â
|
410 |
Â
|
411 |
+
/* */
|
412 |
+
if ( $repeater_key && $repeater_key !== '0' && isset($array[$repeater_key][$pointer][$field['key']])){
|
413 |
+
return $array[$repeater_key][$pointer][$field['key']];
|
414 |
+
}
|
415 |
Â
|
416 |
+
/* repeater field comes after the pointer???? */
|
417 |
+
if (isset($array[$pointer][$needle])){
|
418 |
+
return $array[$pointer][$needle];
|
419 |
+
}
|
420 |
Â
|
421 |
Â
|
422 |
Â
|
423 |
+
return '';
|
424 |
Â
|
425 |
+
}
|
426 |
Â
|
427 |
+
/**
|
428 |
+
* Check if current post is a landing page using an ACF powered template
|
429 |
+
*
|
430 |
+
* @filter acf/location/rule_match/template_id
|
431 |
+
*
|
432 |
+
* @returns BOOL declaring if current page is a landing page with an ACF template loaded or not
|
433 |
+
*/
|
434 |
+
public static function load_acf_on_template( $allow , $rule, $args ) {
|
435 |
+
global $post;
|
436 |
Â
|
437 |
+
if ( !isset($post) || $post->post_type != 'landing-page' ) {
|
438 |
+
return $allow;
|
439 |
+
}
|
440 |
Â
|
441 |
+
$template = Landing_Pages_Variations::get_current_template( $args['post_id'] );
|
442 |
Â
|
443 |
+
if ($template == $rule['value']) {
|
444 |
+
return true;
|
445 |
+
} else {
|
446 |
+
return false;
|
Â
|
|
447 |
Â
}
|
448 |
+
}
|
449 |
Â
|
450 |
+
/**
|
451 |
+
*
|
452 |
+
* @param $image_url
|
453 |
+
* @return mixed
|
454 |
+
*/
|
455 |
+
public static function get_image_id_from_url($url) {
|
456 |
+
$dir = wp_upload_dir();
|
457 |
Â
|
458 |
+
// baseurl never has a trailing slash
|
459 |
+
if ( false === strpos( $url, $dir['baseurl'] . '/' ) ) {
|
460 |
+
// URL points to a place outside of upload directory
|
461 |
+
return false;
|
462 |
+
}
|
463 |
Â
|
464 |
+
$file = basename( $url );
|
465 |
+
$query = array(
|
466 |
+
'post_type' => 'attachment',
|
467 |
+
'fields' => 'ids',
|
468 |
+
'meta_query' => array(
|
469 |
+
array(
|
470 |
+
'value' => $file,
|
471 |
+
'compare' => 'LIKE',
|
472 |
+
),
|
473 |
+
)
|
474 |
+
);
|
475 |
Â
|
476 |
+
$query['meta_query'][0]['key'] = '_wp_attached_file';
|
477 |
Â
|
478 |
+
// query attachments
|
479 |
+
$ids = get_posts( $query );
|
480 |
Â
|
481 |
+
if ( ! empty( $ids ) ) {
|
482 |
Â
|
483 |
+
foreach ( $ids as $id ) {
|
484 |
Â
|
485 |
+
// first entry of returned array is the URL
|
486 |
+
if ( $url === array_shift( wp_get_attachment_image_src( $id, 'full' ) ) )
|
487 |
+
return $id;
|
Â
|
|
488 |
Â
}
|
489 |
+
}
|
490 |
Â
|
491 |
+
$query['meta_query'][0]['key'] = '_wp_attachment_metadata';
|
492 |
Â
|
493 |
+
// query attachments again
|
494 |
+
$ids = get_posts( $query );
|
495 |
Â
|
496 |
+
if ( empty( $ids) )
|
497 |
+
return false;
|
498 |
Â
|
499 |
+
foreach ( $ids as $id ) {
|
500 |
Â
|
501 |
+
$meta = wp_get_attachment_metadata( $id );
|
502 |
Â
|
503 |
+
foreach ( $meta['sizes'] as $size => $values ) {
|
504 |
Â
|
505 |
+
if ( $values['file'] === $file && $url === array_shift( wp_get_attachment_image_src( $id, $size ) ) )
|
506 |
+
return $id;
|
Â
|
|
507 |
Â
}
|
Â
|
|
Â
|
|
508 |
Â
}
|
509 |
Â
|
510 |
+
return false;
|
511 |
+
}
|
512 |
Â
|
513 |
+
public static function acf_get_registered_field( $field ) {
|
514 |
+
global $acf_register_field_group;
|
Â
|
|
515 |
Â
|
516 |
+
if (!$acf_register_field_group) {
|
517 |
+
return $field;
|
518 |
+
}
|
519 |
+
|
520 |
+
foreach ($acf_register_field_group as $key => $group) {
|
521 |
+
foreach ( $group['fields'] as $this_field ) {
|
522 |
+
if ( $this_field['name'] == $field['name'] ){
|
523 |
+
return $this_field;
|
524 |
Â
}
|
525 |
Â
}
|
526 |
Â
}
|
527 |
+
}
|
528 |
Â
|
529 |
Â
|
530 |
+
/**
|
531 |
+
* Correct return value formatting when Pro is NOT installed
|
532 |
+
*/
|
533 |
+
public static function acf_free_value_formatting( $value , $field ) {
|
534 |
Â
|
535 |
+
if ($field['type'] == 'image' && $field['return_format'] == 'url' && !strstr($value , 'http' ) ) {
|
536 |
+
$image_array = wp_get_attachment_image_src( $value , 'full' );
|
537 |
+
return $image_array[0];
|
538 |
+
}
|
539 |
Â
|
540 |
+
if ($field['type'] == 'file' && $field['return_format'] == 'url' && !strstr($value , 'http' ) ) {
|
541 |
+
return wp_get_attachment_url( $value );
|
542 |
+
}
|
543 |
Â
|
544 |
+
if ($field['type'] == 'wysiwyg') {
|
545 |
+
$vaue = wpautop($value);
|
546 |
+
$vaue = do_shortcode($value);
|
547 |
+
}
|
548 |
+
|
549 |
+
return $value;
|
550 |
+
}
|
551 |
Â
|
552 |
+
/**
|
553 |
+
* checks template data type
|
554 |
+
* @param $value
|
555 |
+
* @param $field
|
556 |
+
* @return mixed
|
557 |
+
*/
|
558 |
+
public static function acf_check_if_acf4( $value , $field ) {
|
559 |
+
global $key, $lp_data;
|
560 |
+
|
561 |
+
if (!isset($lp_data[$key])) {
|
562 |
+
return $value;
|
563 |
+
}
|
564 |
+
|
565 |
+
if ( $lp_data[$key]['info']['data_type'] == 'acf4' ) {
|
566 |
+
return self::acf_free_value_formatting($value , $field);
|
567 |
+
} else {
|
568 |
Â
return $value;
|
569 |
Â
}
|
570 |
+
}
|
571 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
572 |
Â
|
573 |
+
/**
|
574 |
+
* This is a complicated array search method for working with ACF repeater fields.
|
575 |
+
* @param $array
|
576 |
+
* @param $field
|
577 |
+
* @param bool|false $get_parent if get_parent is set to true to will return the parent field group key of the repeater fields
|
578 |
+
* @param mixed $last_key placeholder for storing the last key...
|
579 |
+
* @return bool|int|string
|
580 |
+
*/
|
581 |
+
public static function key_search($array, $field , $get_parent = false , $last_key = false) {
|
582 |
+
$value = false;
|
583 |
Â
|
584 |
+
foreach ($array as $key => $item) {
|
585 |
+
if ($key === $field['key'] ) {
|
586 |
+
$value = $item;
|
587 |
Â
} else {
|
588 |
+
if (is_array($item)) {
|
589 |
+
$last_key = ( !is_numeric($key)) ? $key : $last_key;
|
590 |
+
$value = self::key_search($item, $field , $get_parent , $last_key );
|
591 |
+
}
|
592 |
Â
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
593 |
Â
|
594 |
+
if ($value) {
|
595 |
+
if (!$get_parent) {
|
596 |
+
return $value;
|
597 |
Â
} else {
|
598 |
+
return $last_key;
|
Â
|
|
Â
|
|
Â
|
|
599 |
Â
}
|
600 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
601 |
Â
}
|
Â
|
|
Â
|
|
602 |
Â
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
603 |
Â
|
604 |
+
return false;
|
605 |
Â
}
|
606 |
Â
|
607 |
Â
/**
|
608 |
+
* Select tab that was selected in last edit session of the post.
|
609 |
+
*
|
610 |
+
* - If the time the same post that was last edited lies within the time the
|
611 |
+
* transient exists, the last selected tab will be selected via JavaScript.
|
612 |
+
* - If a new post is opened for editing, the current tab will be overwritten.
|
613 |
Â
*/
|
614 |
+
public static function handle_tab() {
|
615 |
+
// Run only when post_id is present
|
616 |
+
if ( ! isset( $_GET['post'] ) || ! is_numeric( $_GET['post'] ) ) {
|
617 |
+
return;
|
618 |
+
}
|
619 |
+
$post_id = sanitize_key( $_GET['post'] );
|
620 |
+
// Check for existing transient
|
621 |
+
$current_tab = get_transient( self::$_transient_name );
|
622 |
+
// Use value only once, delete transient right away
|
623 |
+
delete_transient( self::$_transient_name );
|
624 |
+
// The first tab is selected by default
|
625 |
+
$tab_index = 0;
|
626 |
+
// Get tab index for current post
|
627 |
+
if ( $current_tab['post_id'] === $post_id ) {
|
628 |
+
$tab_index = $current_tab['tab_index'];
|
629 |
+
}
|
630 |
+
?>
|
631 |
+
<script type="text/javascript">
|
632 |
+
(function($) {
|
633 |
+
/**
|
634 |
+
* Global to save the current index of selected tab
|
635 |
+
* @type int
|
636 |
+
*/
|
637 |
+
window.acf_current_tab_index = null;
|
638 |
+
acf.add_action('ready', function( $el ){
|
639 |
+
var tabIndex = <?php echo $tab_index; ?>
|
640 |
+
// Get tab element by index
|
641 |
+
var $li = $('.acf-tab-group').find('li:eq(<?php echo $tab_index; ?>)');
|
642 |
+
// Select tab only when it’s not the first tab, which is selected by default
|
643 |
+
if (0 !== tabIndex) {
|
644 |
+
$li.find('a').click();
|
645 |
+
}
|
646 |
+
window.acf_current_tab_index = tabIndex;
|
647 |
+
});
|
648 |
+
acf.add_action('refresh', function($tabGroup) {
|
649 |
+
var $currentTab;
|
650 |
+
var currentTabIndex = window.acf_current_tab_index;
|
651 |
+
var newTabIndex;
|
652 |
+
// Bail out if we have no jQuery object
|
653 |
+
if (false === $tabGroup instanceof jQuery) {
|
654 |
+
return;
|
655 |
+
}
|
656 |
+
$currentTab = $tabGroup.find('li.active');
|
657 |
+
// Bail out if no active tab was found
|
658 |
+
if ($currentTab.length === 0) {
|
659 |
+
return;
|
660 |
+
}
|
661 |
+
// Get index of active tab
|
662 |
+
newTabIndex = $currentTab.index();
|
663 |
+
// Bail out if index is initial or previously selected tab is the same
|
664 |
+
if (null === currentTabIndex || newTabIndex === currentTabIndex) {
|
665 |
+
return;
|
666 |
+
}
|
667 |
+
window.acf_current_tab_index = newTabIndex;
|
668 |
+
// Send tabIndex to backend to save transient
|
669 |
+
$.ajax(ajaxurl, {
|
670 |
+
method: 'post',
|
671 |
+
data: {
|
672 |
+
action: 'acf_save_current_tab',
|
673 |
+
tab_index: newTabIndex,
|
674 |
+
post_id: <?php echo $post_id; ?>
|
675 |
+
}
|
676 |
+
});
|
677 |
+
});
|
678 |
+
})(jQuery);
|
679 |
+
</script>
|
680 |
+
<?php
|
681 |
+
}
|
682 |
+
public static function ajax_acf_save_current_tab() {
|
683 |
+
if ( ! isset( $_POST['tab_index'] ) || ! is_numeric( $_POST['tab_index'] ) ) {
|
684 |
+
return;
|
685 |
+
}
|
686 |
+
$tab_index = sanitize_text_field($_POST['tab_index']);
|
687 |
+
$post_id = $_POST['post_id'];
|
688 |
+
$transient_value = array(
|
689 |
+
'tab_index' => $tab_index,
|
690 |
+
'post_id' => $post_id,
|
691 |
+
);
|
692 |
+
$result = set_transient( self::$_transient_name, $transient_value, self::$_transient_minutes * 60 );
|
693 |
+
if ( $result ) {
|
694 |
+
wp_send_json_success();
|
695 |
+
}
|
696 |
+
wp_die();
|
697 |
+
}
|
698 |
Â
|
699 |
+
}
|
700 |
Â
|
701 |
+
/**
|
702 |
+
* Initialize ACF Integrations
|
703 |
+
*/
|
704 |
Â
|
705 |
+
new Landing_Pages_ACF();
|
classes/class.activation.php
CHANGED
@@ -1,6 +1,10 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
3 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
4 |
Â
|
5 |
Â
class Landing_Pages_Activation {
|
6 |
Â
|
@@ -290,4 +294,3 @@ register_deactivation_hook( LANDINGPAGES_FILE , array( 'Landing_Pages_Activation
|
|
290 |
Â
|
291 |
Â
new Landing_Pages_Activation;
|
292 |
Â
|
293 |
-
}
|
1 |
Â
<?php
|
2 |
Â
|
3 |
+
/**
|
4 |
+
* Class for managing landing page activation routines
|
5 |
+
* @package LandingPages
|
6 |
+
* @subpackage Activation
|
7 |
+
*/
|
8 |
Â
|
9 |
Â
class Landing_Pages_Activation {
|
10 |
Â
|
294 |
Â
|
295 |
Â
new Landing_Pages_Activation;
|
296 |
Â
|
Â
|
classes/class.activation.upgrade-routines.php
CHANGED
@@ -1,301 +1,294 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
3 |
-
|
4 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
5 |
Â
|
6 |
-
if ( !class_exists('Landing_Pages_Activation_Update_Routines') ) {
|
7 |
Â
|
8 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
9 |
Â
|
Â
|
|
Â
|
|
10 |
Â
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
* @migration: convert meta key lp-conversion-area to template-name-conversion-area-content-{vid}
|
15 |
-
*/
|
16 |
-
public static function migrate_legacy_conversion_area_contents() {
|
17 |
Â
|
18 |
-
|
19 |
-
|
Â
|
|
Â
|
|
Â
|
|
20 |
Â
|
21 |
-
|
22 |
-
return;
|
23 |
-
}
|
24 |
Â
|
25 |
-
|
26 |
-
|
27 |
-
'post_type' => 'landing-page',
|
28 |
-
'posts_per_page' => -1
|
29 |
-
));
|
30 |
Â
|
31 |
-
|
Â
|
|
Â
|
|
32 |
Â
|
33 |
-
|
34 |
-
( get_post_meta($post->ID,'lp-ab-variations', true) ) ? $variations = get_post_meta($post->ID,'lp-ab-variations', true) : $variations = array( '0' => '0' );
|
35 |
Â
|
36 |
-
|
37 |
-
$variations = explode(',',$variations);
|
38 |
-
}
|
39 |
Â
|
40 |
-
|
41 |
Â
|
42 |
-
|
Â
|
|
Â
|
|
43 |
Â
|
44 |
-
|
Â
|
|
45 |
Â
|
46 |
-
|
47 |
-
|
48 |
-
|
Â
|
|
Â
|
|
49 |
Â
|
50 |
-
|
51 |
-
( $vid ) ? $conversion_area_content = get_post_meta( $post->ID , 'conversion-area-content' . $suffix , true ) : $conversion_area_content = get_post_meta( $post->ID , 'lp-conversion-area' , true );
|
52 |
Â
|
53 |
-
|
54 |
-
|
55 |
-
if (!$check) {
|
56 |
-
update_post_meta( $post->ID , $selected_template .'-conversion-area-content' . $suffix , $conversion_area_content );
|
57 |
-
}
|
58 |
Â
|
59 |
-
}
|
60 |
Â
|
61 |
-
|
62 |
-
|
Â
|
|
Â
|
|
63 |
Â
|
Â
|
|
Â
|
|
64 |
Â
|
65 |
-
|
66 |
-
|
67 |
-
* @migration-type: Meta pair migragtion
|
68 |
-
* @migration: mirgrates post_content and content-{vid} values to template-name-main-content-{vid}
|
69 |
Â
|
70 |
-
|
71 |
-
|
Â
|
|
72 |
Â
|
73 |
-
|
74 |
-
|
Â
|
|
Â
|
|
Â
|
|
75 |
Â
|
76 |
-
|
77 |
-
return;
|
78 |
-
}
|
79 |
Â
|
80 |
-
|
81 |
-
|
82 |
-
'post_type' => 'landing-page',
|
83 |
-
'posts_per_page' => -1
|
84 |
-
));
|
85 |
Â
|
86 |
-
|
Â
|
|
Â
|
|
87 |
Â
|
88 |
-
|
89 |
-
( get_post_meta($post->ID,'lp-ab-variations', true) ) ? $variations = get_post_meta($post->ID,'lp-ab-variations', true) : $variations = array( '0' => '0' );
|
90 |
Â
|
91 |
-
|
92 |
-
$variations = explode(',',$variations);
|
93 |
-
}
|
94 |
Â
|
95 |
-
|
Â
|
|
Â
|
|
Â
|
|
96 |
Â
|
97 |
-
|
Â
|
|
98 |
Â
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
Â
|
|
103 |
Â
|
104 |
-
|
105 |
-
( $vid ) ? $content = get_post_meta( $post->ID , 'content' . $suffix , true ) : $content = $post->post_content;
|
106 |
Â
|
107 |
-
|
108 |
-
|
109 |
-
if (!$check) {
|
110 |
-
update_post_meta( $post->ID , $selected_template .'-main-content' . $suffix , $content );
|
111 |
-
}
|
112 |
Â
|
113 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
114 |
Â
|
115 |
-
|
116 |
-
|
117 |
Â
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
* @migration: Moves legacy templates to uploads folder
|
122 |
-
*
|
123 |
-
*/
|
124 |
-
public static function updater_move_legacy_templates() {
|
125 |
Â
|
126 |
-
|
127 |
-
|
Â
|
|
128 |
Â
|
129 |
-
|
130 |
-
|
131 |
-
|
Â
|
|
Â
|
|
Â
|
|
132 |
Â
|
133 |
-
|
134 |
-
|
135 |
-
|
Â
|
|
136 |
Â
|
137 |
-
|
138 |
-
|
139 |
-
{
|
140 |
-
foreach ($template_paths as $name)
|
141 |
-
{
|
142 |
-
if (in_array( $name, $templates_to_move ))
|
143 |
-
{
|
144 |
-
$old_path = LANDINGPAGES_PATH."templates/$name/";
|
145 |
-
$new_path = LANDINGPAGES_UPLOADS_PATH."$name/";
|
146 |
-
|
147 |
-
/*
|
148 |
-
echo "oldpath: $old_path<br>";
|
149 |
-
echo "newpath: $new_path<br>";
|
150 |
-
*/
|
151 |
-
|
152 |
-
@mkdir($new_path , 0775);
|
153 |
-
chmod($old_path , 0775);
|
154 |
-
|
155 |
-
self::move_files( $old_path , $new_path );
|
156 |
-
|
157 |
-
rmdir($old_path);
|
158 |
-
}
|
159 |
-
}
|
160 |
-
}
|
161 |
-
}
|
162 |
-
|
163 |
-
/* Private Method - Moves files from one folder the older. This is not an updater process */
|
164 |
-
private static function move_files( $old_path , $new_path ) {
|
165 |
-
|
166 |
-
$files = scandir($old_path);
|
167 |
-
|
168 |
-
if (!$files) {
|
169 |
-
return;
|
170 |
-
}
|
171 |
-
|
172 |
-
foreach ($files as $file) {
|
173 |
-
if (in_array($file, array(".",".."))) {
|
174 |
-
continue;
|
175 |
-
}
|
176 |
-
|
177 |
-
if ($file==".DS_Store") {
|
178 |
-
unlink($old_path.$file);
|
179 |
-
continue;
|
180 |
-
}
|
181 |
-
|
182 |
-
if (is_dir($old_path.$file)) {
|
183 |
-
@mkdir($new_path.$file.'/' , 0775);
|
184 |
-
chmod($old_path.$file.'/' , 0775);
|
185 |
-
lp_move_template_files( $old_path.$file.'/' , $new_path.$file.'/' );
|
186 |
-
rmdir($old_path.$file);
|
187 |
-
continue;
|
188 |
-
}
|
189 |
-
|
190 |
-
/*
|
191 |
-
echo "oldfile:".$old_path.$file."<br>";
|
192 |
-
echo "newfile:".$new_path.$file."<br>";
|
193 |
-
*/
|
194 |
-
|
195 |
-
if (copy($old_path.$file, $new_path.$file)) {
|
196 |
-
unlink($old_path.$file);
|
197 |
-
}
|
198 |
-
}
|
199 |
-
|
200 |
-
$delete = (isset($delete)) ? $delete : false;
|
201 |
-
|
202 |
-
if (!$delete) {
|
203 |
-
return;
|
204 |
-
}
|
205 |
-
}
|
206 |
-
|
207 |
-
|
208 |
-
/*
|
209 |
-
* @introduced: 1.7.5
|
210 |
-
* @migration-type: Meta key rename
|
211 |
-
* @migration: renames all instances of inbound_conversion_data to _inbound_conversion_data
|
212 |
-
|
213 |
-
*/
|
214 |
-
public static function meta_key_change_conversion_object() {
|
215 |
-
global $wpdb;
|
216 |
-
|
217 |
-
/* ignore if not applicable */
|
218 |
-
$previous_installed_version = get_transient('lp_current_version');
|
219 |
-
|
220 |
-
if ( version_compare($previous_installed_version , "1.7.5") === 1 ) {
|
221 |
-
return;
|
222 |
-
}
|
223 |
-
|
224 |
-
$wpdb->query("UPDATE $wpdb->postmeta SET `meta_key` = REPLACE (`meta_key` , 'inbound_conversion_data', '_inbound_conversion_data')");
|
225 |
-
}
|
226 |
-
|
227 |
-
/*
|
228 |
-
* @introduced: 1.8.9
|
229 |
-
* @migration-type: Meta pair migragtion
|
230 |
-
* @migration: Make a meta pair copy of wp_content into 'content' meta key for variation 0 to use (refactor session)
|
231 |
-
* @moredetails: Before 1.8.9 we did not source post_content from a meta pair when variation 0 was served. In a step to refactor and normalize we now pull post_content from the meta pair with key 'content'. For now (subject to further improvements in the future), variation id 0 pulls from 'content' meta key while varation 1+ pulls from 'content-{varation_id}' meta key. *
|
232 |
-
*/
|
233 |
-
public static function prepare_content_meta_key_for_variation_0() {
|
234 |
-
|
235 |
-
/* ignore if not applicable */
|
236 |
-
$previous_installed_version = get_transient('lp_current_version');
|
237 |
-
|
238 |
-
if ( version_compare($previous_installed_version , "1.8.9") === 1 ) {
|
239 |
-
return;
|
240 |
-
}
|
241 |
-
|
242 |
-
/* for all landing pages load variations */
|
243 |
-
$landing_pages = get_posts( array (
|
244 |
-
'post_type' => 'landing-page',
|
245 |
-
'posts_per_page' => -1
|
246 |
-
));
|
247 |
-
|
248 |
-
/* loop through landing pages and copy post content into meta object */
|
249 |
-
foreach ($landing_pages as $post) {
|
250 |
-
$content = $post->post_content;
|
251 |
-
update_post_meta( $post->ID , 'content' , $content);
|
252 |
-
}
|
253 |
-
}
|
254 |
Â
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
291 |
Â
|
292 |
Â
}
|
293 |
Â
|
294 |
Â
|
295 |
Â
/* Declare Helper Functions here */
|
296 |
-
function lp_move_template_files(
|
297 |
-
{
|
298 |
-
|
299 |
Â
|
300 |
Â
|
301 |
Â
}
|
1 |
Â
<?php
|
2 |
Â
|
3 |
+
/**
|
4 |
+
* Class for defining and executing database routines. Updater methods fired are stored in transient to prevent repeat processing
|
5 |
+
* @package LandingPages
|
6 |
+
* @subpackage Activation
|
7 |
+
*/
|
8 |
+
class Landing_Pages_Activation_Update_Routines {
|
9 |
Â
|
Â
|
|
10 |
Â
|
11 |
+
/*
|
12 |
+
* @introduced: 1.5.7
|
13 |
+
* @migration-type: Meta pair migragtion
|
14 |
+
* @migration: convert meta key lp-conversion-area to template-name-conversion-area-content-{vid}
|
15 |
+
*/
|
16 |
+
public static function migrate_legacy_conversion_area_contents() {
|
17 |
Â
|
18 |
+
/* ignore if not applicable */
|
19 |
+
$previous_installed_version = get_transient('lp_current_version');
|
20 |
Â
|
21 |
+
if (version_compare($previous_installed_version, "1.5.7") === 1) {
|
22 |
+
return;
|
23 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
24 |
Â
|
25 |
+
/* for all landing pages load variations */
|
26 |
+
$landing_pages = get_posts(array(
|
27 |
+
'post_type' => 'landing-page',
|
28 |
+
'posts_per_page' => -1
|
29 |
+
));
|
30 |
Â
|
31 |
+
foreach ($landing_pages as $post) {
|
Â
|
|
Â
|
|
32 |
Â
|
33 |
+
/* for all variations loop through and migrate_data */
|
34 |
+
(get_post_meta($post->ID, 'lp-ab-variations', true)) ? $variations = get_post_meta($post->ID, 'lp-ab-variations', true) : $variations = array('0' => '0');
|
Â
|
|
Â
|
|
Â
|
|
35 |
Â
|
36 |
+
if (!is_array($variations) && strlen($variations) > 1) {
|
37 |
+
$variations = explode(',', $variations);
|
38 |
+
}
|
39 |
Â
|
40 |
+
foreach ($variations as $key => $vid) {
|
Â
|
|
41 |
Â
|
42 |
+
($vid) ? $suffix = '-' . $vid : $suffix = '';
|
Â
|
|
Â
|
|
43 |
Â
|
44 |
+
$selected_template = get_post_meta($post->ID, 'lp-selected-template' . $suffix, true);
|
45 |
Â
|
46 |
+
if (!$selected_template) {
|
47 |
+
continue;
|
48 |
+
}
|
49 |
Â
|
50 |
+
/* discover legacy main content */
|
51 |
+
($vid) ? $conversion_area_content = get_post_meta($post->ID, 'conversion-area-content' . $suffix, true) : $conversion_area_content = get_post_meta($post->ID, 'lp-conversion-area', true);
|
52 |
Â
|
53 |
+
/* Now if the new key is not already poplated, copy the content to the new key */
|
54 |
+
$check = get_post_meta($post->ID, $selected_template . '-conversion-area-content' . $suffix, true);
|
55 |
+
if (!$check) {
|
56 |
+
update_post_meta($post->ID, $selected_template . '-conversion-area-content' . $suffix, $conversion_area_content);
|
57 |
+
}
|
58 |
Â
|
59 |
+
}
|
Â
|
|
60 |
Â
|
61 |
+
}
|
62 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
63 |
Â
|
Â
|
|
64 |
Â
|
65 |
+
/*
|
66 |
+
* @introduced: 1.5.7
|
67 |
+
* @migration-type: Meta pair migragtion
|
68 |
+
* @migration: mirgrates post_content and content-{vid} values to template-name-main-content-{vid}
|
69 |
Â
|
70 |
+
*/
|
71 |
+
public static function migrate_legacy_main_content() {
|
72 |
Â
|
73 |
+
/* ignore if not applicable */
|
74 |
+
$previous_installed_version = get_transient('lp_current_version');
|
Â
|
|
Â
|
|
75 |
Â
|
76 |
+
if (version_compare($previous_installed_version, "1.5.8") === 1) {
|
77 |
+
return;
|
78 |
+
}
|
79 |
Â
|
80 |
+
/* for all landing pages load variations */
|
81 |
+
$landing_pages = get_posts(array(
|
82 |
+
'post_type' => 'landing-page',
|
83 |
+
'posts_per_page' => -1
|
84 |
+
));
|
85 |
Â
|
86 |
+
foreach ($landing_pages as $post) {
|
Â
|
|
Â
|
|
87 |
Â
|
88 |
+
/* for all variations loop through and migrate_data */
|
89 |
+
(get_post_meta($post->ID, 'lp-ab-variations', true)) ? $variations = get_post_meta($post->ID, 'lp-ab-variations', true) : $variations = array('0' => '0');
|
Â
|
|
Â
|
|
Â
|
|
90 |
Â
|
91 |
+
if (!is_array($variations) && strlen($variations) > 1) {
|
92 |
+
$variations = explode(',', $variations);
|
93 |
+
}
|
94 |
Â
|
95 |
+
foreach ($variations as $key => $vid) {
|
Â
|
|
96 |
Â
|
97 |
+
($vid) ? $suffix = '-' . $vid : $suffix = '';
|
Â
|
|
Â
|
|
98 |
Â
|
99 |
+
$selected_template = get_post_meta($post->ID, 'lp-selected-template' . $suffix, true);
|
100 |
+
if (!$selected_template) {
|
101 |
+
continue;
|
102 |
+
}
|
103 |
Â
|
104 |
+
/* discover legacy main content */
|
105 |
+
($vid) ? $content = get_post_meta($post->ID, 'content' . $suffix, true) : $content = $post->post_content;
|
106 |
Â
|
107 |
+
/* Now if the new key is not already poplated, copy the content to the new key */
|
108 |
+
$check = get_post_meta($post->ID, $selected_template . '-main-content' . $suffix, true);
|
109 |
+
if (!$check) {
|
110 |
+
update_post_meta($post->ID, $selected_template . '-main-content' . $suffix, $content);
|
111 |
+
}
|
112 |
Â
|
113 |
+
}
|
Â
|
|
114 |
Â
|
115 |
+
}
|
116 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
117 |
Â
|
118 |
+
/*
|
119 |
+
* @introduced: 1.5.8
|
120 |
+
* @migration-type: template migragtion
|
121 |
+
* @migration: Moves legacy templates to uploads folder
|
122 |
+
*
|
123 |
+
*/
|
124 |
+
public static function updater_move_legacy_templates() {
|
125 |
Â
|
126 |
+
/* ignore if not applicable */
|
127 |
+
$previous_installed_version = get_transient('lp_current_version');
|
128 |
Â
|
129 |
+
if (version_compare($previous_installed_version, "1.5.8") === 1) {
|
130 |
+
return;
|
131 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
132 |
Â
|
133 |
+
/* move copy of legacy core templates to the uploads folder and delete from core templates directory */
|
134 |
+
$templates_to_move = array('rsvp-envelope', 'super-slick');
|
135 |
+
chmod(LANDINGPAGES_UPLOADS_PATH, 0755);
|
136 |
Â
|
137 |
+
$template_paths = Landing_Pages_Load_Extensions::get_core_template_ids();
|
138 |
+
if (count($template_paths) > 0) {
|
139 |
+
foreach ($template_paths as $name) {
|
140 |
+
if (in_array($name, $templates_to_move)) {
|
141 |
+
$old_path = LANDINGPAGES_PATH . "templates/$name/";
|
142 |
+
$new_path = LANDINGPAGES_UPLOADS_PATH . "$name/";
|
143 |
Â
|
144 |
+
/*
|
145 |
+
echo "oldpath: $old_path<br>";
|
146 |
+
echo "newpath: $new_path<br>";
|
147 |
+
*/
|
148 |
Â
|
149 |
+
@mkdir($new_path, 0775);
|
150 |
+
chmod($old_path, 0775);
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
151 |
Â
|
152 |
+
self::move_files($old_path, $new_path);
|
153 |
+
|
154 |
+
rmdir($old_path);
|
155 |
+
}
|
156 |
+
}
|
157 |
+
}
|
158 |
+
}
|
159 |
+
|
160 |
+
/* Private Method - Moves files from one folder the older. This is not an updater process */
|
161 |
+
private static function move_files($old_path, $new_path) {
|
162 |
+
|
163 |
+
$files = scandir($old_path);
|
164 |
+
|
165 |
+
if (!$files) {
|
166 |
+
return;
|
167 |
+
}
|
168 |
+
|
169 |
+
foreach ($files as $file) {
|
170 |
+
if (in_array($file, array(".", ".."))) {
|
171 |
+
continue;
|
172 |
+
}
|
173 |
+
|
174 |
+
if ($file == ".DS_Store") {
|
175 |
+
unlink($old_path . $file);
|
176 |
+
continue;
|
177 |
+
}
|
178 |
+
|
179 |
+
if (is_dir($old_path . $file)) {
|
180 |
+
@mkdir($new_path . $file . '/', 0775);
|
181 |
+
chmod($old_path . $file . '/', 0775);
|
182 |
+
lp_move_template_files($old_path . $file . '/', $new_path . $file . '/');
|
183 |
+
rmdir($old_path . $file);
|
184 |
+
continue;
|
185 |
+
}
|
186 |
+
|
187 |
+
/*
|
188 |
+
echo "oldfile:".$old_path.$file."<br>";
|
189 |
+
echo "newfile:".$new_path.$file."<br>";
|
190 |
+
*/
|
191 |
+
|
192 |
+
if (copy($old_path . $file, $new_path . $file)) {
|
193 |
+
unlink($old_path . $file);
|
194 |
+
}
|
195 |
+
}
|
196 |
+
|
197 |
+
$delete = (isset($delete)) ? $delete : false;
|
198 |
+
|
199 |
+
if (!$delete) {
|
200 |
+
return;
|
201 |
+
}
|
202 |
+
}
|
203 |
+
|
204 |
+
|
205 |
+
/*
|
206 |
+
* @introduced: 1.7.5
|
207 |
+
* @migration-type: Meta key rename
|
208 |
+
* @migration: renames all instances of inbound_conversion_data to _inbound_conversion_data
|
209 |
+
|
210 |
+
*/
|
211 |
+
public static function meta_key_change_conversion_object() {
|
212 |
+
global $wpdb;
|
213 |
+
|
214 |
+
/* ignore if not applicable */
|
215 |
+
$previous_installed_version = get_transient('lp_current_version');
|
216 |
+
|
217 |
+
if (version_compare($previous_installed_version, "1.7.5") === 1) {
|
218 |
+
return;
|
219 |
+
}
|
220 |
+
|
221 |
+
$wpdb->query("UPDATE $wpdb->postmeta SET `meta_key` = REPLACE (`meta_key` , 'inbound_conversion_data', '_inbound_conversion_data')");
|
222 |
+
}
|
223 |
+
|
224 |
+
/*
|
225 |
+
* @introduced: 1.8.9
|
226 |
+
* @migration-type: Meta pair migragtion
|
227 |
+
* @migration: Make a meta pair copy of wp_content into 'content' meta key for variation 0 to use (refactor session)
|
228 |
+
* @moredetails: Before 1.8.9 we did not source post_content from a meta pair when variation 0 was served. In a step to refactor and normalize we now pull post_content from the meta pair with key 'content'. For now (subject to further improvements in the future), variation id 0 pulls from 'content' meta key while varation 1+ pulls from 'content-{varation_id}' meta key. *
|
229 |
+
*/
|
230 |
+
public static function prepare_content_meta_key_for_variation_0() {
|
231 |
+
|
232 |
+
/* ignore if not applicable */
|
233 |
+
$previous_installed_version = get_transient('lp_current_version');
|
234 |
+
|
235 |
+
if (version_compare($previous_installed_version, "1.8.9") === 1) {
|
236 |
+
return;
|
237 |
+
}
|
238 |
+
|
239 |
+
/* for all landing pages load variations */
|
240 |
+
$landing_pages = get_posts(array(
|
241 |
+
'post_type' => 'landing-page',
|
242 |
+
'posts_per_page' => -1
|
243 |
+
));
|
244 |
+
|
245 |
+
/* loop through landing pages and copy post content into meta object */
|
246 |
+
foreach ($landing_pages as $post) {
|
247 |
+
$content = $post->post_content;
|
248 |
+
update_post_meta($post->ID, 'content', $content);
|
249 |
+
}
|
250 |
+
}
|
251 |
+
|
252 |
+
/*
|
253 |
+
* @introduced: 2.0.4
|
254 |
+
* @migration-type: Meta pair migragtion
|
255 |
+
* @migration: mirgrates lp_ab_variation_status to lp_ab_variation_status-0
|
256 |
+
* @migration: mirgrates lp-variation-notes to lp-variation-notes-0
|
257 |
+
|
258 |
+
*/
|
259 |
+
public static function migrate_variation_status_metapair() {
|
260 |
+
|
261 |
+
/* ignore if not applicable */
|
262 |
+
$previous_installed_version = get_transient('lp_current_version');
|
263 |
+
|
264 |
+
if (version_compare($previous_installed_version, "2.0.4") === 1) {
|
265 |
+
return;
|
266 |
+
}
|
267 |
+
|
268 |
+
/* for all landing pages load variations */
|
269 |
+
$landing_pages = get_posts(array(
|
270 |
+
'post_type' => 'landing-page',
|
271 |
+
'posts_per_page' => -1
|
272 |
+
));
|
273 |
+
|
274 |
+
foreach ($landing_pages as $post) {
|
275 |
+
|
276 |
+
/* mirgrates lp_ab_variation_status to lp_ab_variation_status-0 */
|
277 |
+
$status = get_post_meta($post->ID, 'lp_ab_variation_status', true);
|
278 |
+
update_post_meta($post->ID, 'lp_ab_variation_status-0', $status);
|
279 |
+
|
280 |
+
/* mirgrates lp_ab_variation_status to lp_ab_variation_status-0 */
|
281 |
+
$status = get_post_meta($post->ID, 'lp-variation-notes', true);
|
282 |
+
update_post_meta($post->ID, 'lp-variation-notes-0', $status);
|
283 |
+
|
284 |
+
}
|
285 |
+
}
|
286 |
Â
|
287 |
Â
}
|
288 |
Â
|
289 |
Â
|
290 |
Â
/* Declare Helper Functions here */
|
291 |
+
function lp_move_template_files($old_path, $new_path) {
|
Â
|
|
Â
|
|
292 |
Â
|
293 |
Â
|
294 |
Â
}
|
classes/class.admin-menus.php
CHANGED
@@ -1,9 +1,9 @@
|
|
1 |
Â
<?php
|
2 |
-
|
3 |
Â
/**
|
4 |
-
* Class
|
Â
|
|
Â
|
|
5 |
Â
*/
|
6 |
-
|
7 |
Â
class Landing_Pages_Admin_Menus {
|
8 |
Â
|
9 |
Â
/**
|
1 |
Â
<?php
|
Â
|
|
2 |
Â
/**
|
3 |
+
* Class for adding Landing Pages menu items to left wp-admin menu
|
4 |
+
* @package LandingPages
|
5 |
+
* @subpackage Menus
|
6 |
Â
*/
|
Â
|
|
7 |
Â
class Landing_Pages_Admin_Menus {
|
8 |
Â
|
9 |
Â
/**
|
classes/class.admin-notices.php
CHANGED
@@ -1,5 +1,11 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
3 |
Â
class Landing_Pages_Admin_Notices {
|
4 |
Â
|
5 |
Â
public function __construct() {
|
1 |
Â
<?php
|
2 |
Â
|
3 |
+
/**
|
4 |
+
* Class for defining and displaying admin notices to users. Only displays notices in areas related to Landing Pages plugin.
|
5 |
+
* @package LandingPages
|
6 |
+
* @subpackage Notices
|
7 |
+
*/
|
8 |
+
|
9 |
Â
class Landing_Pages_Admin_Notices {
|
10 |
Â
|
11 |
Â
public function __construct() {
|
classes/class.click-tracking.php
DELETED
@@ -1,210 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class Landing_Pages_Click_Tracking {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* Initiate class
|
7 |
-
*/
|
8 |
-
public function __construct() {
|
9 |
-
self::add_hooks();
|
10 |
-
}
|
11 |
-
|
12 |
-
public static function add_hooks() {
|
13 |
-
|
14 |
-
add_action('wp_footer', array( __CLASS__ , 'build_trackable_links') );
|
15 |
-
add_action('init', array( __CLASS__ , 'intecept_tracked_link' ), 11);
|
16 |
-
}
|
17 |
-
|
18 |
-
/**
|
19 |
-
* Generate a trackable link. In the case of landing pages we are still using the legacy model
|
20 |
-
*/
|
21 |
-
public static function build_trackable_links() {
|
22 |
-
global $post;
|
23 |
-
|
24 |
-
if (!isset($post) || $post->post_type != 'landing-page') {
|
25 |
-
return;
|
26 |
-
}
|
27 |
-
|
28 |
-
$variation = (isset($_GET['lp-variation-id'])) ? $_GET['lp-variation-id'] : 0;
|
29 |
-
$variation = preg_replace('/[^-a-zA-Z0-9_]/', '', $variation);
|
30 |
-
|
31 |
-
?>
|
32 |
-
<script type="text/javascript">
|
33 |
-
if ( typeof jQuery != 'undefined' ) {
|
34 |
-
jQuery(document).ready(function($) {
|
35 |
-
|
36 |
-
var lead_cpt_id = _inbound.Utils.readCookie("wp_lead_id");
|
37 |
-
var lead_email = _inbound.Utils.readCookie("wp_lead_email");
|
38 |
-
var lead_unique_key = _inbound.Utils.readCookie("wp_lead_uid");
|
39 |
-
|
40 |
-
if (typeof (lead_cpt_id) != "undefined" && lead_cpt_id !== null) {
|
41 |
-
string = "&wpl_id=" + lead_cpt_id + "&l_type=wplid";
|
42 |
-
} else if (typeof (lead_email) != "undefined" && lead_email !== null && lead_email !== "") {
|
43 |
-
string = "&wpl_id=" + lead_email + "&l_type=wplemail";
|
44 |
-
} else if (typeof (lead_unique_key) != "undefined" && lead_unique_key !== null && lead_unique_key !== "") {
|
45 |
-
string = "&wpl_id=" + lead_unique_key + "&l_type=wpluid";
|
46 |
-
} else {
|
47 |
-
string = "";
|
48 |
-
}
|
49 |
-
|
50 |
-
var external = RegExp('^((f|ht)tps?:)?//(?!' + location.host + ')');
|
51 |
-
jQuery('.wpl-track-me-link a').not("#wpadminbar a").each(function () {
|
52 |
-
|
53 |
-
jQuery(this).attr("data-event-id", '<?php echo $post->ID; ?>').attr("data-cta-varation", '<?php echo $variation;?>');
|
54 |
-
|
55 |
-
var orignalurl = jQuery(this).attr("href");
|
56 |
-
|
57 |
-
var link_is = external.test(orignalurl);
|
58 |
-
|
59 |
-
if (link_is === true) {
|
60 |
-
base_url = window.location.origin;
|
61 |
-
} else {
|
62 |
-
base_url = orignalurl;
|
63 |
-
}
|
64 |
-
|
65 |
-
var variation_id = "&vid=" + jQuery(this).attr("data-cta-varation");
|
66 |
-
var this_id = jQuery(this).attr("data-event-id");
|
67 |
-
var newurl = base_url + "?lp_redirect_" + this_id + "=" + encodeURIComponent( orignalurl ) + variation_id + string;
|
68 |
-
jQuery(this).attr("href", newurl);
|
69 |
-
});
|
70 |
-
});
|
71 |
-
}
|
72 |
-
</script>
|
73 |
-
<?php
|
74 |
-
|
75 |
-
}
|
76 |
-
|
77 |
-
/**
|
78 |
-
* Intecept tracked link, process it, and redirect visitor
|
79 |
-
*/
|
80 |
-
public static function intecept_tracked_link() {
|
81 |
-
global $wpdb;
|
82 |
-
if ($qs = $_SERVER['REQUEST_URI']) {
|
83 |
-
parse_str($qs, $output);
|
84 |
-
(isset($output['l_type'])) ? $type = $output['l_type'] : $type = "";
|
85 |
-
(isset($output['wpl_id'])) ? $lead_id = $output['wpl_id'] : $lead_id = "";
|
86 |
-
(isset($output['vid'])) ? $variation_id = $output['vid'] : $variation_id = null;
|
87 |
-
$pos = strpos($qs, 'lp_redirect');
|
88 |
-
if (!(false === $pos)) {
|
89 |
-
$link = substr($qs, $pos);
|
90 |
-
$link = str_replace('lp_redirect=', '', $link); /* clean url */
|
91 |
-
|
92 |
-
/* Extract the ID and get the link */
|
93 |
-
$pattern = '/lp_redirect_(\d+?)\=/';
|
94 |
-
preg_match($pattern, $link, $matches);
|
95 |
-
$link = preg_replace($pattern, '', $link);
|
96 |
-
$landing_page_id = $matches[1]; /* Event ID */
|
97 |
-
$lead_ID = false;
|
98 |
-
$append = true;
|
99 |
-
/* If lead post id exists */
|
100 |
-
if ($type === 'wplid') {
|
101 |
-
$lead_ID = $lead_id;
|
102 |
-
}
|
103 |
-
/* If lead email exists */
|
104 |
-
elseif ($type === 'wplemail') {
|
105 |
-
$query = $wpdb->prepare(
|
106 |
-
'SELECT ID FROM ' . $wpdb->posts . '
|
107 |
-
WHERE post_title = %s
|
108 |
-
AND post_type = \'wp-lead\'',
|
109 |
-
$lead_id
|
110 |
-
);
|
111 |
-
$wpdb->query( $query );
|
112 |
-
if ( $wpdb->num_rows ) {
|
113 |
-
$lead_ID = $wpdb->get_var( $query );
|
114 |
-
}
|
115 |
-
}
|
116 |
-
/* If lead wp_uid exists */
|
117 |
-
elseif ($type === 'wpluid') {
|
118 |
-
$query = $wpdb->prepare(
|
119 |
-
'SELECT post_id FROM ' . $wpdb->prefix . 'postmeta
|
120 |
-
WHERE meta_value = %s',
|
121 |
-
$lead_id
|
122 |
-
);
|
123 |
-
$wpdb->query( $query );
|
124 |
-
if ( $wpdb->num_rows ) {
|
125 |
-
$lead_ID = $wpdb->get_var( $query );
|
126 |
-
} else {
|
127 |
-
$lead_ID = $lead_id;
|
128 |
-
$append = false;
|
129 |
-
}
|
130 |
-
}
|
131 |
-
|
132 |
-
/* Save click! */
|
133 |
-
self::store_click( $landing_page_id, $variation_id); /* Store CTA data to CTA CPT */
|
134 |
-
|
135 |
-
if( $lead_ID && $append != false ) {
|
136 |
-
/* Add landing page click to lead profile */
|
137 |
-
self::log_lead_click($landing_page_id, $lead_ID, $variation_id);
|
138 |
-
}
|
139 |
-
$link = preg_replace('/(?<=wpl_id)(.*)(?=&)/s', '', $link); /* clean url */
|
140 |
-
$link = preg_replace('/&wpl_id&l_type=(\D*)/', '', $link); /* clean url2 */
|
141 |
-
$link = preg_replace('/&vid=(\d*)/', '', $link); /* clean url3 */
|
142 |
-
$link = urldecode( $link );
|
143 |
-
/* Redirect */
|
144 |
-
header("HTTP/1.1 302 Temporary Redirect");
|
145 |
-
header("Location:" . $link);
|
146 |
-
/* I'm outta here! */
|
147 |
-
exit(1);
|
148 |
-
}
|
149 |
-
}
|
150 |
-
}
|
151 |
-
|
152 |
-
/**
|
153 |
-
* Stores click data
|
154 |
-
*/
|
155 |
-
public static function store_click($landing_page_id, $variation_id){
|
156 |
-
$conversions = Landing_Pages_Variations::get_conversions( $landing_page_id , $variation_id );
|
157 |
-
$conversions++;
|
158 |
-
Landing_Pages_Variations::set_conversions_count( $landing_page_id , $variation_id , $conversions );
|
159 |
-
}
|
160 |
-
|
161 |
-
/**
|
162 |
-
* Log Landing Page click data into Lead Profile. Needs refactoring
|
163 |
-
*/
|
164 |
-
public static function log_lead_click($landing_page_id, $lead_ID, $variation_id) {
|
165 |
-
|
166 |
-
/* Current wordpress time from settings */
|
167 |
-
$time = current_time( 'timestamp', 0 );
|
168 |
-
$wordpress_date_time = date("Y-m-d G:i:s T", $time);
|
169 |
-
|
170 |
-
if ( !$lead_ID ) {
|
171 |
-
return;
|
172 |
-
}
|
173 |
-
|
174 |
-
$conversion_data = get_post_meta( $lead_ID, 'wpleads_conversion_data', TRUE );
|
175 |
-
$individual_event_count = get_post_meta( $lead_ID, 'wpleads_landing_page_'.$landing_page_id, TRUE );
|
176 |
-
$individual_event_count = ($individual_event_count != "") ? $individual_event_count : 0;
|
177 |
-
$individual_event_count++;
|
178 |
-
/* todo replace times */
|
179 |
-
$meta = get_post_meta( $lead_ID, 'times', TRUE );
|
180 |
-
$meta++;
|
181 |
-
$conversions_count = get_post_meta($lead_ID,'wpl-lead-conversion-count', true);
|
182 |
-
$conversions_count++;
|
183 |
-
if ($conversion_data) {
|
184 |
-
|
185 |
-
$conversion_data = json_decode($conversion_data,true);
|
186 |
-
$conversion_data[$meta]['id'] = $landing_page_id;
|
187 |
-
$conversion_data[$meta]['variation'] = $variation_id;
|
188 |
-
$conversion_data[$meta]['datetime'] = $wordpress_date_time;
|
189 |
-
$conversion_data = json_encode($conversion_data);
|
190 |
-
update_post_meta( $lead_ID, 'wpleads_conversion_data', $conversion_data );
|
191 |
-
update_post_meta( $lead_ID, 'wpleads_landing_page_'.$landing_page_id, $individual_event_count );
|
192 |
-
} else {
|
193 |
-
$conversion_data[1]['id'] = $landing_page_id;
|
194 |
-
$conversion_data[1]['variation'] = $variation_id;
|
195 |
-
$conversion_data[1]['datetime'] = $wordpress_date_time;
|
196 |
-
$conversion_data[1]['first_time'] = 1;
|
197 |
-
/* Add in exact link url clicked */
|
198 |
-
$conversion_data = json_encode($conversion_data);
|
199 |
-
update_post_meta( $lead_ID, 'wpleads_conversion_data', $conversion_data );
|
200 |
-
update_post_meta( $lead_ID, 'wpleads_landing_page_'.$landing_page_id, $individual_event_count );
|
201 |
-
/* update_post_meta( $lead_ID, 'lt_event_tracked_'.$landing_page_id, $individual_event_count ); */
|
202 |
-
}
|
203 |
-
update_post_meta( $lead_ID, 'times', $meta );
|
204 |
-
update_post_meta( $lead_ID, 'wpl-lead-conversion-count', $meta );
|
205 |
-
/* Need to call conversion paths too */
|
206 |
-
}
|
207 |
-
|
208 |
-
}
|
209 |
-
|
210 |
-
new Landing_Pages_Click_Tracking;
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
classes/class.install.php
CHANGED
@@ -1,5 +1,11 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
3 |
Â
class Landing_Pages_Install {
|
4 |
Â
|
5 |
Â
/**
|
1 |
Â
<?php
|
2 |
Â
|
3 |
+
/**
|
4 |
+
* Class for creating example landing page on first install and prompting Leads and CTA GPL plugin downloads when Landing Pages GPL installed.
|
5 |
+
* @package LandingPages
|
6 |
+
* @subpackage Activation
|
7 |
+
*/
|
8 |
+
|
9 |
Â
class Landing_Pages_Install {
|
10 |
Â
|
11 |
Â
/**
|
classes/class.landing-pages.php
CHANGED
@@ -1,8 +1,9 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
3 |
Â
/**
|
4 |
-
* Class
|
5 |
-
*
|
Â
|
|
6 |
Â
*/
|
7 |
Â
|
8 |
Â
class Landing_Pages_Template_Switcher {
|
@@ -82,8 +83,9 @@ class Landing_Pages_Template_Switcher {
|
|
82 |
Â
|
83 |
Â
$content = Landing_Pages_Variations::get_post_content( $post->ID );
|
84 |
Â
$content = do_shortcode( $content );
|
85 |
-
|
86 |
-
|
Â
|
|
87 |
Â
return $content;
|
88 |
Â
}
|
89 |
Â
|
@@ -570,7 +572,7 @@ function lp_rebuild_attributes($content = null, $wrapper_class = null) {
|
|
570 |
Â
foreach ($matches[0] as $key => $value) {
|
571 |
Â
if ($key == 0) {
|
572 |
Â
$new_value = $value;
|
573 |
-
$new_value = preg_replace('/ class=(["\'])(.*?)(["\'])/', 'class="$2
|
574 |
Â
|
575 |
Â
|
576 |
Â
$content = str_replace($value, $new_value, $content);
|
1 |
Â
<?php
|
2 |
Â
|
3 |
Â
/**
|
4 |
+
* Class for loading landing page templates when landing page is called on the frontend.
|
5 |
+
* @package LandingPages
|
6 |
+
* @subpackage Templates
|
7 |
Â
*/
|
8 |
Â
|
9 |
Â
class Landing_Pages_Template_Switcher {
|
83 |
Â
|
84 |
Â
$content = Landing_Pages_Variations::get_post_content( $post->ID );
|
85 |
Â
$content = do_shortcode( $content );
|
86 |
+
if (!defined('LANDING_PAGES_WPAUTOP') || LANDING_PAGES_WPAUTOP === TRUE) {
|
87 |
+
$content = wpautop($content);
|
88 |
+
}
|
89 |
Â
return $content;
|
90 |
Â
}
|
91 |
Â
|
572 |
Â
foreach ($matches[0] as $key => $value) {
|
573 |
Â
if ($key == 0) {
|
574 |
Â
$new_value = $value;
|
575 |
+
$new_value = preg_replace('/ class=(["\'])(.*?)(["\'])/', 'class="$2 inbound-track-link"', $new_value);
|
576 |
Â
|
577 |
Â
|
578 |
Â
$content = str_replace($value, $new_value, $content);
|
classes/class.load-templates.php
CHANGED
@@ -1,4 +1,9 @@
|
|
1 |
Â
<?php
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
2 |
Â
|
3 |
Â
class Landing_Pages_Load_Extensions {
|
4 |
Â
|
1 |
Â
<?php
|
2 |
+
/**
|
3 |
+
* Class for loading extensions and templates. Mostly templates. No extensions use this class anymore.
|
4 |
+
* @package LandingPages
|
5 |
+
* @subpackage Templates
|
6 |
+
*/
|
7 |
Â
|
8 |
Â
class Landing_Pages_Load_Extensions {
|
9 |
Â
|
classes/class.metaboxes.php
CHANGED
@@ -1,5 +1,10 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
3 |
Â
|
4 |
Â
class Landing_Pages_Metaboxes {
|
5 |
Â
|
@@ -692,7 +697,7 @@ href='?post=<?php echo $post->ID; ?>&action=edit&action-variation-id=<?php echo
|
|
692 |
Â
|
693 |
Â
/*Clear The Room! */
|
694 |
Â
echo "<div style='clear:both; display:block;'></div>";
|
695 |
-
echo "<div style='width:100%;text-align:right;margin-top:11px;'><div class='lp_tooltip' title=\"". __('To help track conversions Landing Pages Plugin will automatically add a tracking class to forms. If you would like to track a link add this class to it' , 'landing-pages') ." class='
|
696 |
Â
|
697 |
Â
}
|
698 |
Â
|
1 |
Â
<?php
|
2 |
Â
|
3 |
+
/**
|
4 |
+
* Class for rendering and storing data related to the landing-page CPT edit screen
|
5 |
+
* @package LandingPages
|
6 |
+
* @subpackage Management
|
7 |
+
*/
|
8 |
Â
|
9 |
Â
class Landing_Pages_Metaboxes {
|
10 |
Â
|
697 |
Â
|
698 |
Â
/*Clear The Room! */
|
699 |
Â
echo "<div style='clear:both; display:block;'></div>";
|
700 |
+
echo "<div style='width:100%;text-align:right;margin-top:11px;'><div class='lp_tooltip' title=\"". __('To help track conversions Landing Pages Plugin will automatically add a tracking class to forms. If you would like to track a link add this class to it' , 'landing-pages') ." class='inbound-track-link'\" ></div></div>";
|
701 |
Â
|
702 |
Â
}
|
703 |
Â
|
classes/class.post-type.landing-page.php
CHANGED
@@ -1,641 +1,645 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
3 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
4 |
Â
|
5 |
-
class Landing_Pages_Post_Type {
|
6 |
Â
|
7 |
-
|
8 |
-
self::load_hooks();
|
9 |
-
}
|
10 |
-
|
11 |
-
/**
|
12 |
-
* setup hooks and filters
|
13 |
-
*/
|
14 |
-
private function load_hooks() {
|
15 |
-
add_action('init', array( __CLASS__ , 'register_post_type' ) );
|
16 |
-
add_action( 'admin_init' , array( __CLASS__ , 'register_role_capabilities' ) ,999);
|
17 |
-
add_action('init', array( __CLASS__ , 'register_taxonomies' ) );
|
18 |
-
add_action('init', array( __CLASS__ , 'add_rewrite_rules') );
|
19 |
-
add_filter('mod_rewrite_rules', array( __CLASS__ , 'filter_rewrite_rules' ) , 1);
|
20 |
-
|
21 |
-
/* adds & managed collumns */
|
22 |
-
add_filter("manage_edit-landing-page_columns", array( __CLASS__ , 'register_columns' ) );
|
23 |
-
add_action("manage_posts_custom_column", array( __CLASS__ , "display_columns" ) );
|
24 |
-
add_filter('landing-page_orderby', 'lp_column_orderby', 10, 2);
|
25 |
-
|
26 |
-
/* disable SEO Filter */
|
27 |
-
if ((isset($_GET['post_type']) && ($_GET['post_type'] == 'landing-page'))) {
|
28 |
-
add_filter('wpseo_use_page_analysis', '__return_false');
|
29 |
-
}
|
30 |
Â
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
/* make columns sortable */
|
36 |
-
add_filter('manage_edit-landing-page_sortable_columns', array( __CLASS__ , 'define_sortable_columns' ));
|
37 |
Â
|
38 |
-
|
39 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
40 |
Â
|
41 |
-
|
42 |
-
|
Â
|
|
43 |
Â
|
Â
|
|
Â
|
|
44 |
Â
|
45 |
-
|
46 |
-
|
47 |
-
|| isset($_GET['iframe_window'])
|
48 |
-
|| isset($_GET['inbound-preview']) ) {
|
49 |
-
add_action('wp_enqueue_scripts', array(__CLASS__, 'stop_stat_tracking') , 20);
|
50 |
-
}
|
51 |
Â
|
52 |
-
|
53 |
-
|
54 |
-
/*add_action('wp_head', array( __CLASS__ , 'load_preview_iframe' ) );*/
|
55 |
-
add_action('admin_enqueue_scripts', array(__CLASS__, 'enqueue_scripts_iframe') );
|
56 |
-
}
|
57 |
Â
|
58 |
-
/* Miscelanous wp_head - Should probably be refactored into enqueue - h */
|
59 |
-
add_action('wp_head', array(__CLASS__, 'wp_head' ));
|
60 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
61 |
Â
}
|
62 |
Â
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
Â
|
|
67 |
Â
|
68 |
-
|
69 |
-
|
70 |
Â
|
71 |
-
|
72 |
Â
|
73 |
-
|
74 |
-
|
75 |
-
|
Â
|
|
76 |
Â
|
77 |
-
|
78 |
-
|
79 |
-
'singular_name' => __('Landing Page', 'inbound-pro' ),
|
80 |
-
'add_new' => __('Add New', 'inbound-pro' ),
|
81 |
-
'add_new_item' => __('Add New Landing Page' , 'inbound-pro' ),
|
82 |
-
'edit_item' => __('Edit Landing Page' , 'inbound-pro' ),
|
83 |
-
'new_item' => __('New Landing Page' , 'inbound-pro' ),
|
84 |
-
'view_item' => __('View Landing Page' , 'inbound-pro' ),
|
85 |
-
'search_items' => __('Search Landing Page' , 'inbound-pro' ),
|
86 |
-
'not_found' => __('Nothing found' , 'inbound-pro' ),
|
87 |
-
'not_found_in_trash' => __('Nothing found in Trash' , 'inbound-pro' ),
|
88 |
-
'parent_item_colon' => ''
|
89 |
-
);
|
90 |
Â
|
91 |
-
|
92 |
-
'labels' => $labels,
|
93 |
-
'public' => true,
|
94 |
-
'publicly_queryable' => true,
|
95 |
-
'show_ui' => true,
|
96 |
-
'query_var' => true,
|
97 |
-
'menu_icon' => '',
|
98 |
-
'rewrite' => array("slug" => "$slug",'with_front' => false),
|
99 |
-
'capability_type' => array('landing_page','landing_pages'),
|
100 |
-
'map_meta_cap' => true,
|
101 |
-
'hierarchical' => false,
|
102 |
-
'menu_position' => 32,
|
103 |
-
'supports' => $capabilities
|
104 |
-
);
|
105 |
Â
|
106 |
-
|
Â
|
|
107 |
Â
}
|
108 |
Â
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
115 |
Â
|
116 |
-
|
117 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
118 |
Â
|
119 |
-
|
120 |
-
|
121 |
-
continue;
|
122 |
-
}
|
123 |
Â
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
$role->add_cap( 'edit_landing_page' );
|
128 |
-
$role->add_cap( 'edit_landing_pages' );
|
129 |
-
$role->add_cap( 'edit_others_landing_pages' );
|
130 |
-
$role->add_cap( 'edit_published_landing_pages' );
|
131 |
-
$role->add_cap( 'publish_landing_pages' );
|
132 |
-
$role->add_cap( 'delete_landing_pages' );
|
133 |
-
$role->add_cap( 'delete_others_landing_pages' );
|
134 |
-
$role->add_cap( 'delete_private_landing_pages' );
|
135 |
-
$role->add_cap( 'delete_published_landing_pages' );
|
136 |
Â
}
|
137 |
-
}
|
138 |
Â
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
$
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
"rewrite" => true
|
152 |
-
);
|
153 |
-
|
154 |
-
register_taxonomy( 'landing_page_category', array('landing-page'), $args);
|
155 |
Â
}
|
Â
|
|
156 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
157 |
Â
|
158 |
Â
|
159 |
-
/**
|
160 |
-
* Register columns
|
161 |
-
*
|
162 |
-
* @param $columns
|
163 |
-
* @return array
|
164 |
-
*/
|
165 |
-
public static function register_columns($columns) {
|
166 |
-
$columns = array(
|
167 |
-
"cb" => "<input type=\"checkbox\" />",
|
168 |
-
"thumbnail-lander" => __("Preview", 'inbound-pro'),
|
169 |
-
"title" => __("Landing Page Title", 'inbound-pro'),
|
170 |
-
"stats" => __("Variation Testing Stats", 'inbound-pro'),
|
171 |
-
"impressions" => __("Total<br>Visits", 'inbound-pro'),
|
172 |
-
"actions" => __("Total<br>Conversions", 'inbound-pro'),
|
173 |
-
"cr" => __("Total<br>Conversion Rate", 'inbound-pro')
|
174 |
-
);
|
175 |
-
return $columns;
|
176 |
-
}
|
177 |
-
|
178 |
-
/**
|
179 |
-
* Enqueue admin scripts
|
180 |
-
*/
|
181 |
-
public static function enqueue_admin_scripts( $hook ) {
|
182 |
-
global $post;
|
183 |
-
$screen = get_current_screen();
|
184 |
-
|
185 |
-
if (!isset($post) ||$post->post_type != 'landing-page') {
|
186 |
-
return;
|
187 |
-
}
|
188 |
Â
|
189 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
190 |
Â
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
Â
|
|
196 |
Â
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
Â
|
201 |
-
|
202 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
203 |
Â
|
Â
|
|
Â
|
|
Â
|
|
204 |
Â
|
205 |
-
/* load css when landing page iframe preview is being loaded from within wp-admin */
|
206 |
-
if (isset($_GET['iframe_window'])) {
|
207 |
-
wp_enqueue_style('lp_ab_testing_customizer_css', LANDINGPAGES_URLPATH . 'assets/css/frontend/customizer-preview.css', array() , null);
|
208 |
-
}
|
209 |
Â
}
|
210 |
Â
|
211 |
-
/**
|
212 |
-
* Enqueue frontend scripts
|
213 |
-
*/
|
214 |
-
public static function enqueue_frontend_scripts() {
|
215 |
-
global $post;
|
216 |
-
if ( !isset($post) && $post->post_type=='landing-page') {
|
217 |
-
return;
|
218 |
-
}
|
219 |
Â
|
220 |
-
wp_enqueue_style('inbound-wordpress-base', LANDINGPAGES_URLPATH . 'assets/css/frontend/global-landing-page-style.css', array() , null);
|
221 |
-
wp_enqueue_style('inbound-shortcodes', INBOUND_FORMS.'css/frontend-render.css', array() , null);
|
222 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
223 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
224 |
Â
}
|
225 |
Â
|
226 |
-
|
227 |
-
|
228 |
-
* @param $columns
|
229 |
-
* @return array
|
230 |
-
*/
|
231 |
-
public static function display_columns($column) {
|
232 |
-
global $post;
|
233 |
Â
|
234 |
-
if ($post->post_type != 'landing-page') return;
|
235 |
Â
|
236 |
-
|
237 |
-
case 'ID':
|
238 |
-
echo $post->ID;
|
239 |
-
BREAK;
|
240 |
-
case 'thumbnail-lander':
|
241 |
Â
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
Â
|
|
Â
|
|
Â
|
|
246 |
Â
|
247 |
-
|
248 |
Â
|
249 |
-
|
250 |
-
|
251 |
-
|
Â
|
|
Â
|
|
252 |
Â
|
253 |
-
|
Â
|
|
Â
|
|
Â
|
|
254 |
Â
|
255 |
-
|
256 |
-
|
257 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
258 |
Â
|
259 |
Â
} else {
|
260 |
-
$thumbnail = '
|
261 |
Â
}
|
262 |
Â
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
self::show_stats();
|
267 |
-
BREAK;
|
268 |
-
case "impressions" :
|
269 |
-
echo self::show_aggregated_stats("impressions");
|
270 |
-
BREAK;
|
271 |
-
case "actions":
|
272 |
-
echo self::show_aggregated_stats("actions");
|
273 |
-
BREAK;
|
274 |
-
case "cr":
|
275 |
-
echo self::show_aggregated_stats("cr") . "%";
|
276 |
-
BREAK;
|
277 |
-
case "template":
|
278 |
-
$template_used = Landing_Pages_Variations::get_current_template( $post->ID );
|
279 |
-
echo $template_used;
|
280 |
-
BREAK;
|
281 |
-
}
|
282 |
-
}
|
283 |
-
|
284 |
Â
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
289 |
Â
|
290 |
-
return array(
|
291 |
-
'title' => 'title',
|
292 |
-
'impressions' => 'impressions',
|
293 |
-
'actions' => 'actions',
|
294 |
-
'cr' => 'cr'
|
295 |
-
);
|
296 |
Â
|
297 |
-
|
Â
|
|
Â
|
|
Â
|
|
298 |
Â
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
Â
|
|
Â
|
|
303 |
Â
|
304 |
-
|
305 |
-
$actions['clear'] = '<a href="#clear-stats" id="wp_cta_clear_'.$post->ID.'" class="clear_stats" title="'
|
306 |
-
. __( 'Clear impression and conversion records', 'cta' )
|
307 |
-
. '" >' . __( 'Clear All Stats' , 'cta') . '</a>';
|
308 |
Â
|
309 |
-
|
310 |
-
|
311 |
-
|
Â
|
|
312 |
Â
|
313 |
-
|
Â
|
|
Â
|
|
Â
|
|
314 |
Â
|
Â
|
|
Â
|
|
315 |
Â
}
|
316 |
Â
|
Â
|
|
317 |
Â
|
318 |
-
|
319 |
-
* Needs further refactoring & documentation
|
320 |
-
* @param $type_of_stat
|
321 |
-
* @return float|int
|
322 |
-
*/
|
323 |
-
public static function show_aggregated_stats($type_of_stat) {
|
324 |
-
global $post;
|
325 |
Â
|
326 |
-
$variations = get_post_meta($post->ID, 'lp-ab-variations', true);
|
327 |
-
$variations = explode(",", $variations);
|
328 |
Â
|
329 |
-
|
330 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
331 |
Â
|
332 |
-
|
333 |
-
|
334 |
-
$each_conversion = get_post_meta($post->ID, 'lp-ab-variation-conversions-' . $vid, true);
|
335 |
-
(($each_conversion === "")) ? $final_conversion = 0 : $final_conversion = $each_conversion;
|
336 |
-
$impressions += get_post_meta($post->ID, 'lp-ab-variation-impressions-' . $vid, true);
|
337 |
-
$conversions += get_post_meta($post->ID, 'lp-ab-variation-conversions-' . $vid, true);
|
338 |
-
}
|
339 |
Â
|
340 |
-
|
341 |
-
|
342 |
-
}
|
343 |
-
if ($type_of_stat === "impressions") {
|
344 |
-
return $impressions;
|
345 |
-
}
|
346 |
-
if ($type_of_stat === "cr") {
|
347 |
-
if ($impressions != 0) {
|
348 |
-
$conversion_rate = $conversions / $impressions;
|
349 |
-
} else {
|
350 |
-
$conversion_rate = 0;
|
351 |
-
}
|
352 |
-
$conversion_rate = round($conversion_rate, 2) * 100;
|
353 |
-
return $conversion_rate;
|
354 |
-
}
|
355 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
356 |
Â
}
|
357 |
Â
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
Â
|
|
366 |
Â
} else {
|
367 |
-
$
|
368 |
-
$this_path = explode('wp-content', $this_path);
|
369 |
-
$this_path = "wp-content" . $this_path[1] . "core/landing-pages/";
|
370 |
Â
}
|
Â
|
|
Â
|
|
Â
|
|
371 |
Â
|
372 |
-
|
373 |
-
$this_path = str_replace("\\" , "/" , $this_path);
|
374 |
-
|
375 |
-
$slug = Landing_Pages_Settings::get_setting( 'lp-main-landing-page-permalink-prefix', 'go' );
|
376 |
-
|
377 |
-
$ab_testing = Landing_Pages_Settings::get_setting('lp-main-landing-page-disable-turn-off-ab', "0");
|
378 |
-
if ($ab_testing === "0") {
|
379 |
-
add_rewrite_rule("$slug/([^/]*)/([0-9]+)/", "$slug/$1?lp-variation-id=$2", 'top');
|
380 |
-
add_rewrite_rule("$slug/([^/]*)?", $this_path . "modules/module.redirect-ab-testing.php?permalink_name=$1 ", 'top');
|
381 |
-
add_rewrite_rule("landing-page=([^/]*)?", $this_path . 'modules/module.redirect-ab-testing.php?permalink_name=$1', 'top');
|
382 |
-
}
|
383 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
384 |
Â
}
|
385 |
Â
|
386 |
-
|
387 |
-
|
388 |
-
* @param $rules
|
389 |
-
* @return string
|
390 |
-
*/
|
391 |
-
public static function filter_rewrite_rules( $rules ) {
|
392 |
-
if (stristr($rules, 'RewriteCond %{QUERY_STRING} !lp-variation-id')) {
|
393 |
-
return $rules;
|
394 |
-
}
|
395 |
Â
|
396 |
-
|
397 |
Â
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
Â
|
|
Â
|
|
402 |
Â
|
403 |
-
|
404 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
405 |
Â
|
406 |
-
|
407 |
Â
|
408 |
-
|
409 |
-
|
Â
|
|
Â
|
|
410 |
Â
|
411 |
-
|
412 |
-
$new_val = "RewriteCond %{QUERY_STRING} !lp-variation-id";
|
413 |
-
$rules_array[$i] = $new_val;
|
414 |
-
$i++;
|
415 |
-
$rules_array[$i] = $val;
|
416 |
-
$i++;
|
417 |
-
} else {
|
418 |
-
$rules_array[$i] = $val;
|
419 |
-
$i++;
|
420 |
-
}
|
421 |
-
}
|
422 |
Â
|
423 |
-
$rules = implode("\r\n", $rules_array);
|
424 |
Â
|
Â
|
|
425 |
Â
|
426 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
427 |
Â
}
|
428 |
Â
|
Â
|
|
429 |
Â
|
430 |
-
/**
|
431 |
-
* Show stats container on Landing Page lists page
|
432 |
-
*/
|
433 |
-
public static function show_stats() {
|
434 |
Â
|
435 |
-
|
436 |
-
|
437 |
-
$variations = Landing_Pages_Variations::get_variations($post->ID);
|
438 |
Â
|
439 |
-
echo "<span class='show-stats button'> " . __('Show Variation Stats', 'inbound-pro') . "</span>";
|
440 |
-
echo "<ul class='lp-varation-stat-ul'>";
|
441 |
-
$cr_array = array();
|
442 |
-
$i = 0;
|
443 |
Â
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
Â
|
449 |
-
|
450 |
-
|
Â
|
|
451 |
Â
|
452 |
-
|
453 |
-
|
Â
|
|
Â
|
|
454 |
Â
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
}
|
460 |
-
$conversion_rate = round($conversion_rate, 2) * 100;
|
461 |
Â
|
462 |
-
|
Â
|
|
463 |
Â
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
if ($winning_cr != 0) {
|
472 |
-
echo "<span class='variation-winner-is'>" . $post->ID . "-" . $winning_cr . "</span>";
|
473 |
Â
}
|
474 |
-
|
475 |
-
|
Â
|
|
476 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
477 |
Â
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
478 |
Â
|
479 |
Â
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
Â
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
Â
|
490 |
Â
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
}
|
510 |
Â
}
|
Â
|
|
511 |
Â
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
}
|
522 |
Â
}
|
Â
|
|
523 |
Â
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
}
|
531 |
-
return $post_states;
|
532 |
Â
}
|
Â
|
|
Â
|
|
533 |
Â
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
Â
|
539 |
-
|
540 |
-
|
541 |
Â
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
Â
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
Â
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
Â
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
Â
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
Â
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
});
|
583 |
Â
});
|
584 |
-
|
585 |
-
|
586 |
-
|
Â
|
|
587 |
Â
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
595 |
Â
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
596 |
Â
|
597 |
-
|
598 |
-
|
599 |
-
*/
|
600 |
-
public static function wp_head() {
|
601 |
-
global $post;
|
602 |
Â
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
}
|
612 |
-
:root:root:root {
|
613 |
-
margin-top: 0px !important;
|
614 |
-
min-height: 714px !important;
|
615 |
Â
}
|
616 |
-
</
|
617 |
-
<?php
|
618 |
-
|
619 |
-
if (isset($_GET['lp-variation-id']) && !isset($_GET['inbound-customizer']) && !isset($_GET['iframe_window']) && !isset($_GET['live-preview-area'])) {
|
620 |
-
?>
|
621 |
-
|
622 |
-
<?php
|
623 |
-
if(!defined('Inbound_Now_Disable_URL_CLEAN')) {
|
624 |
-
?>
|
625 |
-
<script type="text/javascript">
|
626 |
-
/* Then strip params if pushstate exists */
|
627 |
-
if (typeof window.history.pushState == 'function') {
|
628 |
-
var cleanparams=window.location.href.split("?");
|
629 |
-
var clean_url=cleanparams[0];history.replaceState({},"landing page",clean_url);
|
630 |
-
}
|
631 |
-
</script>
|
632 |
-
<?php
|
633 |
-
}
|
634 |
Â
}
|
635 |
-
|
636 |
Â
}
|
Â
|
|
637 |
Â
}
|
Â
|
|
638 |
Â
|
639 |
-
|
640 |
-
|
641 |
-
}
|
1 |
Â
<?php
|
2 |
Â
|
3 |
+
/**
|
4 |
+
* Class for registering the landing page CPT and expanding the CPT's listing page with additional data
|
5 |
+
* @package LandingPages
|
6 |
+
* @subpackage Management
|
7 |
+
*/
|
8 |
Â
|
Â
|
|
9 |
Â
|
10 |
+
class Landing_Pages_Post_Type {
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
11 |
Â
|
12 |
+
function __construct() {
|
13 |
+
self::load_hooks();
|
14 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
15 |
Â
|
16 |
+
/**
|
17 |
+
* setup hooks and filters
|
18 |
+
*/
|
19 |
+
private function load_hooks() {
|
20 |
+
add_action('init', array( __CLASS__ , 'register_post_type' ) );
|
21 |
+
add_action( 'admin_init' , array( __CLASS__ , 'register_role_capabilities' ) ,999);
|
22 |
+
add_action('init', array( __CLASS__ , 'register_taxonomies' ) );
|
23 |
+
add_action('init', array( __CLASS__ , 'add_rewrite_rules') );
|
24 |
+
add_filter('mod_rewrite_rules', array( __CLASS__ , 'filter_rewrite_rules' ) , 1);
|
25 |
+
|
26 |
+
/* adds & managed collumns */
|
27 |
+
add_filter("manage_edit-landing-page_columns", array( __CLASS__ , 'register_columns' ) );
|
28 |
+
add_action("manage_posts_custom_column", array( __CLASS__ , "display_columns" ) );
|
29 |
+
add_filter('landing-page_orderby', 'lp_column_orderby', 10, 2);
|
30 |
+
|
31 |
+
/* disable SEO Filter */
|
32 |
+
if ((isset($_GET['post_type']) && ($_GET['post_type'] == 'landing-page'))) {
|
33 |
+
add_filter('wpseo_use_page_analysis', '__return_false');
|
34 |
+
}
|
35 |
Â
|
36 |
+
/* adds category to landing page sorting filter */
|
37 |
+
add_action('restrict_manage_posts', array( __CLASS__, 'sort_by_category' ) );
|
38 |
+
add_filter('parse_query', array( __CLASS__ , 'sort_by_category_prepare_query' ));
|
39 |
Â
|
40 |
+
/* make columns sortable */
|
41 |
+
add_filter('manage_edit-landing-page_sortable_columns', array( __CLASS__ , 'define_sortable_columns' ));
|
42 |
Â
|
43 |
+
/* add styling handlers to custom post states */
|
44 |
+
add_filter('display_post_states', array( __CLASS__ , 'filter_custom_post_states' ) );
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
45 |
Â
|
46 |
+
/* enqueue scripts for landing page listings */
|
47 |
+
add_action( 'admin_enqueue_scripts' , array(__CLASS__, 'enqueue_admin_scripts' ) );
|
Â
|
|
Â
|
|
Â
|
|
48 |
Â
|
Â
|
|
Â
|
|
49 |
Â
|
50 |
+
/* enqueue scripts for landing page listings */
|
51 |
+
if (isset($_GET['dont_save'])
|
52 |
+
|| isset($_GET['iframe_window'])
|
53 |
+
|| isset($_GET['inbound-preview']) ) {
|
54 |
+
add_action('wp_enqueue_scripts', array(__CLASS__, 'stop_stat_tracking') , 20);
|
55 |
Â
}
|
56 |
Â
|
57 |
+
/* load iframed preview page when preview is clicked from AB stats box */
|
58 |
+
if (isset($_GET['iframe_window'])) {
|
59 |
+
/*add_action('wp_head', array( __CLASS__ , 'load_preview_iframe' ) );*/
|
60 |
+
add_action('admin_enqueue_scripts', array(__CLASS__, 'enqueue_scripts_iframe') );
|
61 |
+
}
|
62 |
Â
|
63 |
+
/* Miscelanous wp_head - Should probably be refactored into enqueue - h */
|
64 |
+
add_action('wp_head', array(__CLASS__, 'wp_head' ));
|
65 |
Â
|
66 |
+
}
|
67 |
Â
|
68 |
+
/**
|
69 |
+
* register post type
|
70 |
+
*/
|
71 |
+
public static function register_post_type() {
|
72 |
Â
|
73 |
+
$slug = Landing_Pages_Settings::get_setting( 'lp-main-landing-page-permalink-prefix', 'go' );
|
74 |
+
$featured_images = Landing_Pages_Settings::get_setting( 'lp-main-landing-page-enable-featured-image', false );
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
75 |
Â
|
76 |
+
$capabilities = array('title','custom-fields','editor', 'revisions');
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
77 |
Â
|
78 |
+
if ($featured_images) {
|
79 |
+
array_push($capabilities , 'thumbnail');
|
80 |
Â
}
|
81 |
Â
|
82 |
+
$labels = array(
|
83 |
+
'name' => __('Landing Pages', 'inbound-pro' ),
|
84 |
+
'singular_name' => __('Landing Page', 'inbound-pro' ),
|
85 |
+
'add_new' => __('Add New', 'inbound-pro' ),
|
86 |
+
'add_new_item' => __('Add New Landing Page' , 'inbound-pro' ),
|
87 |
+
'edit_item' => __('Edit Landing Page' , 'inbound-pro' ),
|
88 |
+
'new_item' => __('New Landing Page' , 'inbound-pro' ),
|
89 |
+
'view_item' => __('View Landing Page' , 'inbound-pro' ),
|
90 |
+
'search_items' => __('Search Landing Page' , 'inbound-pro' ),
|
91 |
+
'not_found' => __('Nothing found' , 'inbound-pro' ),
|
92 |
+
'not_found_in_trash' => __('Nothing found in Trash' , 'inbound-pro' ),
|
93 |
+
'parent_item_colon' => ''
|
94 |
+
);
|
95 |
+
|
96 |
+
$args = array(
|
97 |
+
'labels' => $labels,
|
98 |
+
'public' => true,
|
99 |
+
'publicly_queryable' => true,
|
100 |
+
'show_ui' => true,
|
101 |
+
'query_var' => true,
|
102 |
+
'menu_icon' => '',
|
103 |
+
'rewrite' => array("slug" => "$slug",'with_front' => false),
|
104 |
+
'capability_type' => array('landing_page','landing_pages'),
|
105 |
+
'map_meta_cap' => true,
|
106 |
+
'hierarchical' => false,
|
107 |
+
'menu_position' => 32,
|
108 |
+
'supports' => $capabilities
|
109 |
+
);
|
110 |
+
|
111 |
+
register_post_type( 'landing-page' , $args );
|
112 |
+
}
|
113 |
Â
|
114 |
+
/**
|
115 |
+
* Register Role Capabilities
|
116 |
+
*/
|
117 |
+
public static function register_role_capabilities() {
|
118 |
+
// Add the roles you'd like to administer the custom post types
|
119 |
+
$roles = array('inbound_marketer','administrator');
|
120 |
Â
|
121 |
+
// Loop through each role and assign capabilities
|
122 |
+
foreach($roles as $the_role) {
|
Â
|
|
Â
|
|
123 |
Â
|
124 |
+
$role = get_role($the_role);
|
125 |
+
if (!$role) {
|
126 |
+
continue;
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
127 |
Â
}
|
Â
|
|
128 |
Â
|
129 |
+
$role->add_cap( 'read' );
|
130 |
+
$role->add_cap( 'read_landing_page');
|
131 |
+
$role->add_cap( 'read_private_landing_pages' );
|
132 |
+
$role->add_cap( 'edit_landing_page' );
|
133 |
+
$role->add_cap( 'edit_landing_pages' );
|
134 |
+
$role->add_cap( 'edit_others_landing_pages' );
|
135 |
+
$role->add_cap( 'edit_published_landing_pages' );
|
136 |
+
$role->add_cap( 'publish_landing_pages' );
|
137 |
+
$role->add_cap( 'delete_landing_pages' );
|
138 |
+
$role->add_cap( 'delete_others_landing_pages' );
|
139 |
+
$role->add_cap( 'delete_private_landing_pages' );
|
140 |
+
$role->add_cap( 'delete_published_landing_pages' );
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
141 |
Â
}
|
142 |
+
}
|
143 |
Â
|
144 |
+
/**
|
145 |
+
* Register landing page taxonomies
|
146 |
+
*/
|
147 |
+
public static function register_taxonomies() {
|
148 |
+
|
149 |
+
$args = array(
|
150 |
+
'hierarchical' => true,
|
151 |
+
'label' => __("Categories", 'inbound-pro'),
|
152 |
+
'singular_label' => __("Landing Page Category",
|
153 |
+
'landing-pages'),
|
154 |
+
'show_ui' => true,
|
155 |
+
'query_var' => true,
|
156 |
+
"rewrite" => true
|
157 |
+
);
|
158 |
+
|
159 |
+
register_taxonomy( 'landing_page_category', array('landing-page'), $args);
|
160 |
+
}
|
161 |
Â
|
162 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
163 |
Â
|
164 |
+
/**
|
165 |
+
* Register columns
|
166 |
+
*
|
167 |
+
* @param $columns
|
168 |
+
* @return array
|
169 |
+
*/
|
170 |
+
public static function register_columns($columns) {
|
171 |
+
$columns = array(
|
172 |
+
"cb" => "<input type=\"checkbox\" />",
|
173 |
+
"thumbnail-lander" => __("Preview", 'inbound-pro'),
|
174 |
+
"title" => __("Landing Page Title", 'inbound-pro'),
|
175 |
+
"stats" => __("Variation Testing Stats", 'inbound-pro'),
|
176 |
+
"impressions" => __("Total<br>Visits", 'inbound-pro'),
|
177 |
+
"actions" => __("Total<br>Conversions", 'inbound-pro'),
|
178 |
+
"cr" => __("Total<br>Conversion Rate", 'inbound-pro')
|
179 |
+
);
|
180 |
+
return $columns;
|
181 |
+
}
|
182 |
Â
|
183 |
+
/**
|
184 |
+
* Enqueue admin scripts
|
185 |
+
*/
|
186 |
+
public static function enqueue_admin_scripts( $hook ) {
|
187 |
+
global $post;
|
188 |
+
$screen = get_current_screen();
|
189 |
Â
|
190 |
+
if (!isset($post) ||$post->post_type != 'landing-page') {
|
191 |
+
return;
|
192 |
+
}
|
193 |
Â
|
194 |
+
wp_enqueue_style('lp-content-stats', LANDINGPAGES_URLPATH . 'assets/css/admin/content-stats.css', array() , null);
|
195 |
Â
|
196 |
+
/* listing page only */
|
197 |
+
if ($screen->id == 'edit-landing-page' ) {
|
198 |
+
/* load stat clear handlers */
|
199 |
+
wp_enqueue_script( 'lp-admin-clear-stats-ajax-request', LANDINGPAGES_URLPATH . 'assets/js/ajax.clearstats.js', array( 'jquery' ) , null );
|
200 |
+
wp_localize_script( 'lp-admin-clear-stats-ajax-request', 'ajaxadmin', array( 'ajaxurl' => admin_url('admin-ajax.php'), 'lp_clear_nonce' => wp_create_nonce('lp-clear-nonce') ) );
|
201 |
Â
|
202 |
+
wp_enqueue_script('landing-page-list', LANDINGPAGES_URLPATH . 'assets/js/admin/admin.landing-page-list.js', array() , null);
|
203 |
+
wp_enqueue_style('landing-page-list-css', LANDINGPAGES_URLPATH.'assets/css/admin/landing-page-list.css', array() , null);
|
204 |
+
wp_enqueue_script('jqueryui');
|
205 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
206 |
Â
}
|
207 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
208 |
Â
|
Â
|
|
Â
|
|
209 |
Â
|
210 |
+
/* load css when landing page iframe preview is being loaded from within wp-admin */
|
211 |
+
if (isset($_GET['iframe_window'])) {
|
212 |
+
wp_enqueue_style('lp_ab_testing_customizer_css', LANDINGPAGES_URLPATH . 'assets/css/frontend/customizer-preview.css', array() , null);
|
213 |
+
}
|
214 |
+
}
|
215 |
Â
|
216 |
+
/**
|
217 |
+
* Enqueue frontend scripts
|
218 |
+
*/
|
219 |
+
public static function enqueue_frontend_scripts() {
|
220 |
+
global $post;
|
221 |
+
if ( !isset($post) && $post->post_type=='landing-page') {
|
222 |
+
return;
|
223 |
Â
}
|
224 |
Â
|
225 |
+
wp_enqueue_style('inbound-wordpress-base', LANDINGPAGES_URLPATH . 'assets/css/frontend/global-landing-page-style.css', array() , null);
|
226 |
+
wp_enqueue_style('inbound-shortcodes', INBOUND_FORMS.'css/frontend-render.css', array() , null);
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
227 |
Â
|
Â
|
|
228 |
Â
|
229 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
230 |
Â
|
231 |
+
/**
|
232 |
+
* Display column data
|
233 |
+
* @param $columns
|
234 |
+
* @return array
|
235 |
+
*/
|
236 |
+
public static function display_columns($column) {
|
237 |
+
global $post;
|
238 |
Â
|
239 |
+
if ($post->post_type != 'landing-page') return;
|
240 |
Â
|
241 |
+
switch ($column) {
|
242 |
+
case 'ID':
|
243 |
+
echo $post->ID;
|
244 |
+
BREAK;
|
245 |
+
case 'thumbnail-lander':
|
246 |
Â
|
247 |
+
$template = get_post_meta($post->ID, 'lp-selected-template', true);
|
248 |
+
$permalink = get_permalink($post->ID);
|
249 |
+
$datetime = the_modified_date('YmjH', null, null, false);
|
250 |
+
$permalink = $permalink = $permalink . '?dt=' . $datetime;
|
251 |
Â
|
252 |
+
if (in_array($_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1'))) {
|
253 |
+
|
254 |
+
if(file_exists(LANDINGPAGES_UPLOADS_PATH . $template . '/thumbnail.png')) {
|
255 |
+
$thumbnail = LANDINGPAGES_UPLOADS_URLPATH . $template . '/thumbnail.png';
|
256 |
+
} else if(file_exists(LANDINGPAGES_UPLOADS_PATH . $template . '/thumbnail.jpg')) {
|
257 |
+
|
258 |
+
$thumbnail = LANDINGPAGES_UPLOADS_URLPATH . $template . '/thumbnail.jpg';
|
259 |
Â
|
260 |
Â
} else {
|
261 |
+
$thumbnail = LANDINGPAGES_URLPATH . 'templates/' . $template . '/thumbnail.png';
|
262 |
Â
}
|
263 |
Â
|
264 |
+
} else {
|
265 |
+
$thumbnail = 'http://s.wordpress.com/mshots/v1/' . urlencode(esc_url($permalink)) . '?w=140';
|
266 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
267 |
Â
|
268 |
+
echo "<a title='" . __('Click to Preview this variation', 'inbound-pro') . "' class='thickbox' href='" . $permalink . "?lp-variation-id=0&iframe_window=on&post_id=" . $post->ID . "&TB_iframe=true&width=640&height=703' target='_blank'><img src='" . $thumbnail . "' style='width:155px;height:110px;' title='Click to Preview'></a>";
|
269 |
+
BREAK;
|
270 |
+
case "stats":
|
271 |
+
self::show_stats();
|
272 |
+
BREAK;
|
273 |
+
case "impressions" :
|
274 |
+
echo self::show_aggregated_stats("impressions");
|
275 |
+
BREAK;
|
276 |
+
case "actions":
|
277 |
+
echo self::show_aggregated_stats("actions");
|
278 |
+
BREAK;
|
279 |
+
case "cr":
|
280 |
+
echo self::show_aggregated_stats("cr") . "%";
|
281 |
+
BREAK;
|
282 |
+
case "template":
|
283 |
+
$template_used = Landing_Pages_Variations::get_current_template( $post->ID );
|
284 |
+
echo $template_used;
|
285 |
+
BREAK;
|
286 |
+
}
|
287 |
+
}
|
288 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
289 |
Â
|
290 |
+
/**
|
291 |
+
* Define Sortable Columns
|
292 |
+
*/
|
293 |
+
public static function define_sortable_columns($columns) {
|
294 |
Â
|
295 |
+
return array(
|
296 |
+
'title' => 'title',
|
297 |
+
'impressions' => 'impressions',
|
298 |
+
'actions' => 'actions',
|
299 |
+
'cr' => 'cr'
|
300 |
+
);
|
301 |
Â
|
302 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
303 |
Â
|
304 |
+
/**
|
305 |
+
* Define Row Actions
|
306 |
+
*/
|
307 |
+
public static function filter_row_actions( $actions , $post ) {
|
308 |
Â
|
309 |
+
if ($post->post_type=='wp-call-to-action') {
|
310 |
+
$actions['clear'] = '<a href="#clear-stats" id="wp_cta_clear_'.$post->ID.'" class="clear_stats" title="'
|
311 |
+
. __( 'Clear impression and conversion records', 'cta' )
|
312 |
+
. '" >' . __( 'Clear All Stats' , 'cta') . '</a>';
|
313 |
Â
|
314 |
+
/* show shortcode */
|
315 |
+
$actions['clear'] .= '<br><span style="color:#000;">' . __( 'Shortcode:' , 'cta' ) .'</span> <input type="text" style="width: 60%; text-align: center;" class="regular-text code short-shortcode-input" readonly="readonly" id="shortcode" name="shortcode" value="[cta id=\''.$post->ID.'\']">';
|
316 |
Â
}
|
317 |
Â
|
318 |
+
return $actions;
|
319 |
Â
|
320 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
321 |
Â
|
Â
|
|
Â
|
|
322 |
Â
|
323 |
+
/**
|
324 |
+
* Needs further refactoring & documentation
|
325 |
+
* @param $type_of_stat
|
326 |
+
* @return float|int
|
327 |
+
*/
|
328 |
+
public static function show_aggregated_stats($type_of_stat) {
|
329 |
+
global $post;
|
330 |
Â
|
331 |
+
$variations = get_post_meta($post->ID, 'lp-ab-variations', true);
|
332 |
+
$variations = explode(",", $variations);
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
333 |
Â
|
334 |
+
$impressions = 0;
|
335 |
+
$conversions = 0;
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
336 |
Â
|
337 |
+
foreach ($variations as $vid) {
|
338 |
+
$each_impression = get_post_meta($post->ID, 'lp-ab-variation-impressions-' . $vid, true);
|
339 |
+
$each_conversion = get_post_meta($post->ID, 'lp-ab-variation-conversions-' . $vid, true);
|
340 |
+
(($each_conversion === "")) ? $final_conversion = 0 : $final_conversion = $each_conversion;
|
341 |
+
$impressions += get_post_meta($post->ID, 'lp-ab-variation-impressions-' . $vid, true);
|
342 |
+
$conversions += get_post_meta($post->ID, 'lp-ab-variation-conversions-' . $vid, true);
|
343 |
Â
}
|
344 |
Â
|
345 |
+
if ($type_of_stat === "actions") {
|
346 |
+
return $conversions;
|
347 |
+
}
|
348 |
+
if ($type_of_stat === "impressions") {
|
349 |
+
return $impressions;
|
350 |
+
}
|
351 |
+
if ($type_of_stat === "cr") {
|
352 |
+
if ($impressions != 0) {
|
353 |
+
$conversion_rate = $conversions / $impressions;
|
354 |
Â
} else {
|
355 |
+
$conversion_rate = 0;
|
Â
|
|
Â
|
|
356 |
Â
}
|
357 |
+
$conversion_rate = round($conversion_rate, 2) * 100;
|
358 |
+
return $conversion_rate;
|
359 |
+
}
|
360 |
Â
|
361 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
362 |
Â
|
363 |
+
/**
|
364 |
+
* Adds rewrite rules
|
365 |
+
*/
|
366 |
+
public static function add_rewrite_rules() {
|
367 |
+
if ( !class_exists('Inbound_Pro_Plugin')){
|
368 |
+
$this_path = LANDINGPAGES_PATH;
|
369 |
+
$this_path = explode('wp-content', $this_path);
|
370 |
+
$this_path = "wp-content" . $this_path[1];
|
371 |
+
} else {
|
372 |
+
$this_path = INBOUND_PRO_PATH;
|
373 |
+
$this_path = explode('wp-content', $this_path);
|
374 |
+
$this_path = "wp-content" . $this_path[1] . "core/landing-pages/";
|
375 |
Â
}
|
376 |
Â
|
377 |
+
/* handles local environment */
|
378 |
+
$this_path = str_replace("\\" , "/" , $this_path);
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
379 |
Â
|
380 |
+
$slug = Landing_Pages_Settings::get_setting( 'lp-main-landing-page-permalink-prefix', 'go' );
|
381 |
Â
|
382 |
+
$ab_testing = Landing_Pages_Settings::get_setting('lp-main-landing-page-disable-turn-off-ab', "0");
|
383 |
+
if ($ab_testing === "0") {
|
384 |
+
add_rewrite_rule("$slug/([^/]*)/([0-9]+)/", "$slug/$1?lp-variation-id=$2", 'top');
|
385 |
+
add_rewrite_rule("$slug/([^/]*)?", $this_path . "modules/module.redirect-ab-testing.php?permalink_name=$1 ", 'top');
|
386 |
+
add_rewrite_rule("landing-page=([^/]*)?", $this_path . 'modules/module.redirect-ab-testing.php?permalink_name=$1', 'top');
|
387 |
+
}
|
388 |
Â
|
389 |
+
}
|
390 |
Â
|
391 |
+
/**
|
392 |
+
* Adds conditions to rewrite rules
|
393 |
+
* @param $rules
|
394 |
+
* @return string
|
395 |
+
*/
|
396 |
+
public static function filter_rewrite_rules( $rules ) {
|
397 |
+
if (stristr($rules, 'RewriteCond %{QUERY_STRING} !lp-variation-id')) {
|
398 |
+
return $rules;
|
399 |
+
}
|
400 |
Â
|
401 |
+
$rules_array = preg_split('/$\R?^/m', $rules);
|
402 |
Â
|
403 |
+
if (count($rules_array) < 3) {
|
404 |
+
$rules_array = explode("\n", $rules);
|
405 |
+
$rules_array = array_filter($rules_array);
|
406 |
+
}
|
407 |
Â
|
408 |
+
/* print_r($rules_array);exit; */
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
409 |
Â
|
Â
|
|
410 |
Â
|
411 |
+
$slug = Landing_Pages_Settings::get_setting( 'lp-main-landing-page-permalink-prefix', 'go' );
|
412 |
Â
|
413 |
+
$i = 0;
|
414 |
+
foreach ($rules_array as $key => $val) {
|
415 |
+
|
416 |
+
if (stristr($val, "RewriteRule ^{$slug}/([^/]*)? ") || stristr($val, "RewriteRule ^{$slug}/([^/]*)/([0-9]+)/ ")) {
|
417 |
+
$new_val = "RewriteCond %{QUERY_STRING} !lp-variation-id";
|
418 |
+
$rules_array[$i] = $new_val;
|
419 |
+
$i++;
|
420 |
+
$rules_array[$i] = $val;
|
421 |
+
$i++;
|
422 |
+
} else {
|
423 |
+
$rules_array[$i] = $val;
|
424 |
+
$i++;
|
425 |
+
}
|
426 |
Â
}
|
427 |
Â
|
428 |
+
$rules = implode("\r\n", $rules_array);
|
429 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
430 |
Â
|
431 |
+
return $rules;
|
432 |
+
}
|
Â
|
|
433 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
434 |
Â
|
435 |
+
/**
|
436 |
+
* Show stats container on Landing Page lists page
|
437 |
+
*/
|
438 |
+
public static function show_stats() {
|
439 |
Â
|
440 |
+
global $post;
|
441 |
+
$permalink = get_permalink($post->ID);
|
442 |
+
$variations = Landing_Pages_Variations::get_variations($post->ID);
|
443 |
Â
|
444 |
+
echo "<span class='show-stats button'> " . __('Show Variation Stats', 'inbound-pro') . "</span>";
|
445 |
+
echo "<ul class='lp-varation-stat-ul'>";
|
446 |
+
$cr_array = array();
|
447 |
+
$i = 0;
|
448 |
Â
|
449 |
+
foreach ($variations as $key => $vid) {
|
450 |
+
$letter = Landing_Pages_Variations::vid_to_letter($post->ID, $key); /* convert to letter */
|
451 |
+
$impressions = Landing_Pages_Variations::get_impressions($post->ID, $vid);
|
452 |
+
$conversions = Landing_Pages_Variations::get_conversions($post->ID, $vid);
|
Â
|
|
Â
|
|
453 |
Â
|
454 |
+
/* get variation status */
|
455 |
+
$status = Landing_Pages_Variations::get_variation_status( $post->ID, $vid ); /* Current status */
|
456 |
Â
|
457 |
+
/* Get variation notes */
|
458 |
+
$each_notes = Landing_Pages_Variations::get_variation_notes( $post->ID, $vid );
|
459 |
+
|
460 |
+
if ($impressions) {
|
461 |
+
$conversion_rate = $conversions / $impressions;
|
462 |
+
} else {
|
463 |
+
$conversion_rate = 0;
|
Â
|
|
Â
|
|
464 |
Â
}
|
465 |
+
$conversion_rate = round($conversion_rate, 2) * 100;
|
466 |
+
|
467 |
+
$cr_array[] = $conversion_rate;
|
468 |
Â
|
469 |
+
$data_letter = "data-letter=\"" . $letter . "\"";
|
470 |
+
$edit_link = admin_url('post.php?post=' . $post->ID . '&lp-variation-id=' . $vid . '&action=edit');
|
471 |
+
echo "<li rel='" . $status . "' data-postid='" . $post->ID . "' data-letter='" . $letter . "' data-lp='' class='lp-stat-row-" . $vid . " " . $post->ID . '-' . $conversion_rate . " status-" . $status . "'><a class='lp-letter' title='click to edit this variation' href='" . $edit_link . "'>" . $letter . "</a><span class='lp-numbers'><span class='lp-visitors'><span class='visit-text'>" . __( 'Impressions' , 'inbound-pro' ) . "</span><span class='lp-impress-num'>" . $impressions . "</span></span> <span class='lp-conversions'> <span class='lp-conversion-txt'>" . __( 'Conversions' , 'inbound-pro' ) . "</span> <span class='lp-con-num'>" . $conversions . "</span> </span> </span><a ". $data_letter . " class='cr-number cr-empty-" . $conversion_rate . "' href='" . $edit_link . "'>" . $conversion_rate . "%</a></li>";
|
472 |
+
$i++;
|
473 |
Â
}
|
474 |
+
echo "</ul>";
|
475 |
+
$winning_cr = max($cr_array); /* best conversion rate */
|
476 |
+
if ($winning_cr != 0) {
|
477 |
+
echo "<span class='variation-winner-is'>" . $post->ID . "-" . $winning_cr . "</span>";
|
478 |
+
}
|
479 |
+
/*echo "Total Visits: " . $impressions; */
|
480 |
+
/*echo "Total Conversions: " . $conversions; */
|
481 |
+
|
482 |
+
}
|
483 |
Â
|
484 |
Â
|
485 |
+
/**
|
486 |
+
* Show dropdown of landing page categories
|
487 |
+
*/
|
488 |
+
public static function sort_by_category() {
|
489 |
+
global $typenow;
|
490 |
Â
|
491 |
+
if ($typenow != "landing-page") {
|
492 |
+
return;
|
493 |
+
}
|
494 |
Â
|
495 |
Â
|
496 |
+
$filters = get_object_taxonomies($typenow);
|
497 |
+
|
498 |
+
foreach ($filters as $tax_slug) {
|
499 |
+
|
500 |
+
$tax_obj = get_taxonomy($tax_slug);
|
501 |
+
(isset($_GET[$tax_slug])) ? $current = $_GET[$tax_slug] : $current = 0;
|
502 |
+
wp_dropdown_categories(
|
503 |
+
array(
|
504 |
+
'show_option_all' => __('Show All ' . $tax_obj->label),
|
505 |
+
'taxonomy' => $tax_slug,
|
506 |
+
'name' => $tax_obj->name,
|
507 |
+
'orderby' => 'name',
|
508 |
+
'selected' => $current,
|
509 |
+
'hierarchical' => $tax_obj->hierarchical,
|
510 |
+
'show_count' => false,
|
511 |
+
'hide_empty' => true
|
512 |
+
)
|
513 |
+
);
|
Â
|
|
514 |
Â
}
|
515 |
+
}
|
516 |
Â
|
517 |
+
/**
|
518 |
+
* Convert the category id to the taxonomy id during a query
|
519 |
+
*/
|
520 |
+
public static function sort_by_category_prepare_query() {
|
521 |
+
global $pagenow;
|
522 |
+
$qv = &$query->query_vars;
|
523 |
+
if ($pagenow == 'edit.php' && isset($qv['landing_page_category']) && is_numeric($qv['landing_page_category'])) {
|
524 |
+
$term = get_term_by('id', $qv['landing_page_category'], 'landing_page_category');
|
525 |
+
$qv['landing_page_category'] = $term->slug;
|
Â
|
|
526 |
Â
}
|
527 |
+
}
|
528 |
Â
|
529 |
+
/**
|
530 |
+
* Add styling handlers to custom post states
|
531 |
+
*/
|
532 |
+
public static function filter_custom_post_states($post_states) {
|
533 |
+
foreach ($post_states as &$state) {
|
534 |
+
$state = '<span class="' . strtolower($state) . ' states">' . str_replace(' ', '-', $state) . '</span>';
|
Â
|
|
Â
|
|
535 |
Â
}
|
536 |
+
return $post_states;
|
537 |
+
}
|
538 |
Â
|
539 |
+
/**
|
540 |
+
* Loads preview iframe. Currently disabled. Plans to update @DavidWells
|
541 |
+
*/
|
542 |
+
public static function load_preview_iframe() {
|
543 |
Â
|
544 |
+
$variation_id = Landing_Pages_Variations::get_current_variation_id();
|
545 |
+
$landing_page_id = $_GET['post_id'];
|
546 |
Â
|
547 |
+
$variations = Landing_Pages_Variations::get_variations( $landing_page_id );
|
548 |
+
?>
|
549 |
+
<link rel="stylesheet" href="<?php echo LANDINGPAGES_URLPATH . 'assets/css/customizer-ab-testing.css';?>"/>
|
550 |
+
<style type="text/css">
|
551 |
Â
|
552 |
+
#variation-list {
|
553 |
+
position: absolute;
|
554 |
+
top: 0px;
|
555 |
+
left: 0px;
|
556 |
+
padding-left: 5px;
|
557 |
+
}
|
558 |
Â
|
559 |
+
#variation-list h3 {
|
560 |
+
text-decoration: none;
|
561 |
+
border-bottom: none;
|
562 |
+
}
|
563 |
Â
|
564 |
+
#variation-list div {
|
565 |
+
display: inline-block;
|
566 |
+
}
|
567 |
Â
|
568 |
+
#current_variation_id, #current-post-id {
|
569 |
+
display: none !important;
|
570 |
+
}
|
571 |
Â
|
572 |
+
</style>
|
573 |
+
<script type="text/javascript">
|
574 |
+
jQuery(document).ready(function ($) {
|
575 |
+
var current_page = jQuery("#current_variation_id").text();
|
576 |
+
/* reload the iframe preview page (for option toggles) */
|
577 |
+
jQuery('.variation-lp').on('click', function (event) {
|
578 |
+
variation_is = jQuery(this).attr("id");
|
579 |
+
var original_url = jQuery(parent.document).find("#TB_iframeContent").attr("src");
|
580 |
+
var current_id = jQuery("#current-post-id").text();
|
581 |
+
someURL = original_url;
|
582 |
+
|
583 |
+
splitURL = someURL.split('?');
|
584 |
+
someURL = splitURL[0];
|
585 |
+
new_url = someURL + "?lp-variation-id=" + variation_is + "&iframe_window=on&post_id=" + current_id;
|
586 |
+
jQuery(parent.document).find("#TB_iframeContent").attr("src", new_url);
|
Â
|
|
587 |
Â
});
|
588 |
+
});
|
589 |
+
</script>
|
590 |
+
<?php
|
591 |
+
}
|
592 |
Â
|
593 |
+
/**
|
594 |
+
* Load JS to disable stats from working for preview windows
|
595 |
+
*/
|
596 |
+
public static function stop_stat_tracking() {
|
597 |
+
show_admin_bar(false);
|
598 |
+
wp_enqueue_script('stop-inbound-stats-js', LANDINGPAGES_URLPATH . 'assets/js/stop_page_stats.js' , array('inbound-analytics') , null );
|
599 |
+
wp_enqueue_style('inbound-preview-window-css', LANDINGPAGES_URLPATH . 'assets/css/iframe-preview.css' , array() , null);
|
600 |
+
}
|
601 |
+
|
602 |
+
/**
|
603 |
+
* Load misc wp_head
|
604 |
+
*/
|
605 |
+
public static function wp_head() {
|
606 |
+
global $post;
|
607 |
+
|
608 |
+
if (isset($post) && $post->post_type !=='landing-page') {
|
609 |
+
return;
|
610 |
Â
}
|
611 |
+
/* if is tiny iframe preview window force these styles */
|
612 |
+
if (isset($_GET['dont_save'])) { ?>
|
613 |
+
<style type="text/css">
|
614 |
+
:root:root:root #wpadminbar {
|
615 |
+
display:none !important;
|
616 |
+
}
|
617 |
+
:root:root:root {
|
618 |
+
margin-top: 0px !important;
|
619 |
+
min-height: 714px !important;
|
620 |
+
}
|
621 |
+
</style>
|
622 |
+
<?php }
|
623 |
Â
|
624 |
+
if (isset($_GET['lp-variation-id']) && !isset($_GET['inbound-customizer']) && !isset($_GET['iframe_window']) && !isset($_GET['live-preview-area'])) {
|
625 |
+
?>
|
Â
|
|
Â
|
|
Â
|
|
626 |
Â
|
627 |
+
<?php
|
628 |
+
if(!defined('Inbound_Now_Disable_URL_CLEAN')) {
|
629 |
+
?>
|
630 |
+
<script type="text/javascript">
|
631 |
+
/* Then strip params if pushstate exists */
|
632 |
+
if (typeof window.history.pushState == 'function') {
|
633 |
+
var cleanparams=window.location.href.split("?");
|
634 |
+
var clean_url=cleanparams[0];history.replaceState({},"landing page",clean_url);
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
635 |
Â
}
|
636 |
+
</script>
|
637 |
+
<?php
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
638 |
Â
}
|
Â
|
|
639 |
Â
}
|
640 |
+
|
641 |
Â
}
|
642 |
+
}
|
643 |
Â
|
644 |
+
/* Load Post Type Pre Init */
|
645 |
+
new Landing_Pages_Post_Type();
|
Â
|
classes/class.postmeta.php
CHANGED
@@ -1,8 +1,11 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
3 |
Â
/**
|
4 |
-
* Class
|
Â
|
|
Â
|
|
5 |
Â
*/
|
Â
|
|
6 |
Â
class Landing_Pages_Meta {
|
7 |
Â
|
8 |
Â
/**
|
1 |
Â
<?php
|
2 |
Â
|
3 |
Â
/**
|
4 |
+
* Class provides a data interface for interacting with landing page meta data. Used by Landing_Pages_ACF class
|
5 |
+
* @package LandingPages
|
6 |
+
* @subpackage DataInterfaces
|
7 |
Â
*/
|
8 |
+
|
9 |
Â
class Landing_Pages_Meta {
|
10 |
Â
|
11 |
Â
/**
|
classes/class.row-actions.php
CHANGED
@@ -1,5 +1,11 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
3 |
Â
class Landing_Pages_Row_Actions {
|
4 |
Â
|
5 |
Â
/**
|
1 |
Â
<?php
|
2 |
Â
|
3 |
+
/**
|
4 |
+
* Class adds row actions to landing-page CPT listing page. Should be moved into class.post-type.landing-pages.php
|
5 |
+
* @package LandingPages
|
6 |
+
* @subpackage Management
|
7 |
+
*/
|
8 |
+
|
9 |
Â
class Landing_Pages_Row_Actions {
|
10 |
Â
|
11 |
Â
/**
|
classes/class.settings.php
CHANGED
@@ -1,5 +1,11 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
3 |
Â
class Landing_Pages_Settings {
|
4 |
Â
|
5 |
Â
/**
|
1 |
Â
<?php
|
2 |
Â
|
3 |
+
/**
|
4 |
+
* Class provides a data interface for retrieving and storing landing page settings into the GPL legacy setting system or the Inbound Pro settings system.
|
5 |
+
* @package LandingPages
|
6 |
+
* @subpackage DataInterfaces
|
7 |
+
*/
|
8 |
+
|
9 |
Â
class Landing_Pages_Settings {
|
10 |
Â
|
11 |
Â
/**
|
classes/class.sidebars.php
CHANGED
@@ -1,6 +1,10 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
3 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
4 |
Â
|
5 |
Â
class Landing_Pages_Sidebars {
|
6 |
Â
|
1 |
Â
<?php
|
2 |
Â
|
3 |
+
/**
|
4 |
+
* Class sets up landing page sidebar for holding conversion areas when 'default' template is selected.
|
5 |
+
* @package LandingPages
|
6 |
+
* @subpackage Sidebars
|
7 |
+
*/
|
8 |
Â
|
9 |
Â
class Landing_Pages_Sidebars {
|
10 |
Â
|
classes/class.statistics.php
CHANGED
@@ -1,218 +1,214 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
3 |
Â
/**
|
4 |
-
*
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
}
|
49 |
-
if (strstr( $_SERVER['HTTP_REFERER'] , 'edit.php' )) {
|
50 |
-
return;
|
51 |
-
}
|
52 |
-
|
53 |
-
/* If Landing Page Post Type */
|
54 |
-
if ( $post_type == 'landing-page' ) {
|
55 |
-
$impressions = Landing_Pages_Variations::get_impressions( $post_id, $variation_id );
|
56 |
-
$impressions++;
|
57 |
-
Landing_Pages_Variations::set_impressions_count( $post_id, $variation_id, $impressions );
|
58 |
-
}
|
59 |
-
/* If Non Landing Page Post Type */
|
60 |
-
else {
|
61 |
-
$impressions = Landing_Pages_Stats::get_impressions_count( $post_id );
|
62 |
-
$impressions++;
|
63 |
-
Landing_Pages_Stats::set_impressions_count( $post_id, $impressions );
|
64 |
-
}
|
65 |
Â
}
|
66 |
Â
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
}
|
81 |
-
|
82 |
-
/* this filter is used by Inbound Pro to check if visitor's ip is on a not track list */
|
83 |
-
$do_not_track = apply_filters('inbound_analytics_stop_track' , false );
|
84 |
-
|
85 |
-
if ( $do_not_track ) {
|
86 |
-
return $data;
|
87 |
-
}
|
88 |
-
|
89 |
-
|
90 |
-
/* increment conversions for landing pages */
|
91 |
-
if( isset($data['post_type']) && $data['post_type'] === 'landing-page' ) {
|
92 |
-
$conversions = Landing_Pages_Variations::get_conversions( $data['page_id'] , $data['variation'] );
|
93 |
-
$conversions++;
|
94 |
-
Landing_Pages_Variations::set_conversions_count( $data['page_id'] , $data['variation'] , $conversions );
|
95 |
-
}
|
96 |
-
/* increment conversions for non landing pages */
|
97 |
-
else {
|
98 |
-
$conversions = Landing_Pages_Stats::get_conversions_count( $data['page_id'] );
|
99 |
-
$conversions++;
|
100 |
-
Landing_Pages_Stats::set_conversions_count( $data['page_id'] , $conversions );
|
101 |
-
}
|
102 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
103 |
Â
return $data;
|
104 |
Â
}
|
105 |
Â
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
Â
|
111 |
-
|
112 |
-
|
113 |
-
$cols['inbound_conversion_rate'] = __( 'Conversion Rate' , 'inbound-email' );
|
114 |
Â
|
115 |
-
|
Â
|
|
116 |
Â
}
|
117 |
Â
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
break;
|
131 |
-
case "inbound_conversion_rate":
|
132 |
-
echo self::get_conversion_rate( $post->ID);
|
133 |
-
break;
|
134 |
-
}
|
135 |
Â
}
|
136 |
Â
|
Â
|
|
Â
|
|
137 |
Â
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
*
|
143 |
-
* @return INT impression count
|
144 |
-
*/
|
145 |
-
public static function get_impressions_count( $post_id ) {
|
146 |
Â
|
147 |
-
|
Â
|
|
Â
|
|
148 |
Â
|
149 |
-
|
150 |
-
|
151 |
-
}
|
152 |
Â
|
153 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
154 |
Â
}
|
155 |
-
|
156 |
-
/**
|
157 |
-
* Returns conversion count for non landing page. See Landing_Pages_Variations class for retrieving landing page statistics
|
158 |
-
*
|
159 |
-
* @param INT $post_id id
|
160 |
-
*
|
161 |
-
* @return INT impression count
|
162 |
-
*/
|
163 |
-
public static function get_conversions_count( $post_id ) {
|
164 |
Â
|
165 |
Â
|
166 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
167 |
Â
|
168 |
-
|
169 |
-
$conversions = 0;
|
170 |
-
}
|
171 |
Â
|
172 |
-
|
Â
|
|
173 |
Â
}
|
174 |
Â
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
Â
|
|
Â
|
|
Â
|
|
183 |
Â
|
184 |
-
$impressions = Landing_Pages_Stats::get_impressions_count( $post_id );
|
185 |
-
$conversions = Landing_Pages_Stats::get_conversions_count( $post_id );
|
186 |
-
|
187 |
-
if ($impressions > 0) {
|
188 |
-
$conversion_rate = $conversions / $impressions;
|
189 |
-
$conversion_rate_number = $conversion_rate * 100;
|
190 |
-
$conversion_rate_number = round($conversion_rate_number, 2);
|
191 |
-
$conversion_rate = $conversion_rate_number;
|
192 |
-
} else {
|
193 |
-
$conversion_rate = 0;
|
194 |
-
}
|
195 |
-
|
196 |
-
return $conversion_rate;
|
197 |
-
}
|
198 |
Â
|
Â
|
|
199 |
Â
|
200 |
-
|
201 |
-
|
202 |
-
*/
|
203 |
-
public static function set_impressions_count( $post_id , $count ) {
|
204 |
-
update_post_meta( $post_id, '_inbound_impressions_count', $count );
|
205 |
Â
}
|
206 |
Â
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
212 |
Â
}
|
213 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
214 |
Â
}
|
215 |
Â
|
Â
|
|
Â
|
|
216 |
Â
|
217 |
-
|
218 |
-
}
|
1 |
Â
<?php
|
2 |
Â
|
3 |
Â
/**
|
4 |
+
* Class addsa impressions/conversions counter box to all post types that are not a landing page. This feature is disabled for Inbound Pro users.
|
5 |
+
* @package LandingPages
|
6 |
+
* @subpackage Tracking
|
7 |
+
*/
|
8 |
+
|
9 |
+
class Landing_Pages_Stats {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Initiate class
|
13 |
+
*/
|
14 |
+
public function __construct() {
|
15 |
+
self::load_hooks();
|
16 |
+
}
|
17 |
+
|
18 |
+
/**
|
19 |
+
* load hooks and filters
|
20 |
+
*/
|
21 |
+
public static function load_hooks() {
|
22 |
+
|
23 |
+
/* records page impression */
|
24 |
+
add_action( 'lp_record_impression' , array( __CLASS__ , 'record_impression' ) , 10, 3);
|
25 |
+
|
26 |
+
/* record landing page conversion */
|
27 |
+
add_filter( 'inboundnow_store_lead_pre_filter_data' , array( __CLASS__ , 'record_conversion' ) ,10,1);
|
28 |
+
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Records landing page & non landing page impression
|
33 |
+
* @param $post_id
|
34 |
+
* @param string $post_type
|
35 |
+
* @param int $variation_id
|
36 |
+
*/
|
37 |
+
public static function record_impression($post_id, $post_type , $variation_id = 0) {
|
38 |
+
|
39 |
+
/* ignore mshots and previews from admin area */
|
40 |
+
if (strstr( $_SERVER['HTTP_REFERER'] , 'edit.php?post_type=landing-page' )) {
|
41 |
+
return;
|
42 |
+
}
|
43 |
+
if (strstr( $_SERVER['HTTP_REFERER'] , 'post.php' )) {
|
44 |
+
return;
|
45 |
+
}
|
46 |
+
if (strstr( $_SERVER['HTTP_REFERER'] , 'edit.php' )) {
|
47 |
+
return;
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
48 |
Â
}
|
49 |
Â
|
50 |
+
/* If Landing Page Post Type */
|
51 |
+
if ( $post_type == 'landing-page' ) {
|
52 |
+
$impressions = Landing_Pages_Variations::get_impressions( $post_id, $variation_id );
|
53 |
+
$impressions++;
|
54 |
+
Landing_Pages_Variations::set_impressions_count( $post_id, $variation_id, $impressions );
|
55 |
+
}
|
56 |
+
/* If Non Landing Page Post Type */
|
57 |
+
else {
|
58 |
+
$impressions = Landing_Pages_Stats::get_impressions_count( $post_id );
|
59 |
+
$impressions++;
|
60 |
+
Landing_Pages_Stats::set_impressions_count( $post_id, $impressions );
|
61 |
+
}
|
62 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
63 |
Â
|
64 |
+
/**
|
65 |
+
* Listens for new lead creation events and if the lead converted on a landing page then capture the conversion
|
66 |
+
* @param $data
|
67 |
+
*/
|
68 |
+
public static function record_conversion($data) {
|
69 |
+
|
70 |
+
if (!isset( $data['page_id'] ) ) {
|
71 |
Â
return $data;
|
72 |
Â
}
|
73 |
Â
|
74 |
+
$post = get_post( $data['page_id'] );
|
75 |
+
if ($post) {
|
76 |
+
$data['post_type'] = $post->post_type;
|
77 |
+
}
|
78 |
Â
|
79 |
+
/* this filter is used by Inbound Pro to check if visitor's ip is on a not track list */
|
80 |
+
$do_not_track = apply_filters('inbound_analytics_stop_track' , false );
|
Â
|
|
81 |
Â
|
82 |
+
if ( $do_not_track ) {
|
83 |
+
return $data;
|
84 |
Â
}
|
85 |
Â
|
86 |
+
|
87 |
+
/* increment conversions for landing pages */
|
88 |
+
if( isset($data['post_type']) && $data['post_type'] === 'landing-page' ) {
|
89 |
+
$conversions = Landing_Pages_Variations::get_conversions( $data['page_id'] , $data['variation'] );
|
90 |
+
$conversions++;
|
91 |
+
Landing_Pages_Variations::set_conversions_count( $data['page_id'] , $data['variation'] , $conversions );
|
92 |
+
}
|
93 |
+
/* increment conversions for non landing pages */
|
94 |
+
else {
|
95 |
+
$conversions = Landing_Pages_Stats::get_conversions_count( $data['page_id'] );
|
96 |
+
$conversions++;
|
97 |
+
Landing_Pages_Stats::set_conversions_count( $data['page_id'] , $conversions );
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
98 |
Â
}
|
99 |
Â
|
100 |
+
return $data;
|
101 |
+
}
|
102 |
Â
|
103 |
+
/**
|
104 |
+
* Register Columns
|
105 |
+
*/
|
106 |
+
public static function register_columns( $cols ) {
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
107 |
Â
|
108 |
+
$cols['inbound_impressions'] = __( 'Impressions' , 'inbound-email' );
|
109 |
+
$cols['inbound_conversions'] = __( 'Conversions' , 'inbound-email' );
|
110 |
+
$cols['inbound_conversion_rate'] = __( 'Conversion Rate' , 'inbound-email' );
|
111 |
Â
|
112 |
+
return $cols;
|
113 |
+
}
|
Â
|
|
114 |
Â
|
115 |
+
/**
|
116 |
+
* Prepare Column Data
|
117 |
+
*/
|
118 |
+
public static function prepare_column_data( $column , $post_id ) {
|
119 |
+
global $post;
|
120 |
+
|
121 |
+
switch ($column) {
|
122 |
+
case "inbound_impressions":
|
123 |
+
echo self::get_impressions_count( $post->ID );
|
124 |
+
break;
|
125 |
+
case "inbound_conversions":
|
126 |
+
echo self::get_conversions_count( $post->ID );
|
127 |
+
break;
|
128 |
+
case "inbound_conversion_rate":
|
129 |
+
echo self::get_conversion_rate( $post->ID);
|
130 |
+
break;
|
131 |
Â
}
|
132 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
133 |
Â
|
134 |
Â
|
135 |
+
/**
|
136 |
+
* Returns impression count for non landing pages. See Landing_Pages_Variations class for retrieving landing page statistics
|
137 |
+
*
|
138 |
+
* @param INT $post_id id of call to action
|
139 |
+
*
|
140 |
+
* @return INT impression count
|
141 |
+
*/
|
142 |
+
public static function get_impressions_count( $post_id ) {
|
143 |
Â
|
144 |
+
$impressions = get_post_meta( $post_id , '_inbound_impressions_count' , true);
|
Â
|
|
Â
|
|
145 |
Â
|
146 |
+
if (!is_numeric($impressions)) {
|
147 |
+
$impressions = 0;
|
148 |
Â
}
|
149 |
Â
|
150 |
+
return $impressions;
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Returns conversion count for non landing page. See Landing_Pages_Variations class for retrieving landing page statistics
|
155 |
+
*
|
156 |
+
* @param INT $post_id id
|
157 |
+
*
|
158 |
+
* @return INT impression count
|
159 |
+
*/
|
160 |
+
public static function get_conversions_count( $post_id ) {
|
161 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
162 |
Â
|
163 |
+
$conversions = get_post_meta( $post_id , '_inbound_conversions_count' , true);
|
164 |
Â
|
165 |
+
if (!is_numeric($conversions)) {
|
166 |
+
$conversions = 0;
|
Â
|
|
Â
|
|
Â
|
|
167 |
Â
}
|
168 |
Â
|
169 |
+
return $conversions;
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Returns conversion count for non landing page. See Landing_Pages_Variations class for retrieving landing page statistics
|
174 |
+
*
|
175 |
+
* @param INT $post_id id
|
176 |
+
*
|
177 |
+
* @return INT
|
178 |
+
*/
|
179 |
+
public static function get_conversion_rate( $post_id ) {
|
180 |
+
|
181 |
+
$impressions = Landing_Pages_Stats::get_impressions_count( $post_id );
|
182 |
+
$conversions = Landing_Pages_Stats::get_conversions_count( $post_id );
|
183 |
+
|
184 |
+
if ($impressions > 0) {
|
185 |
+
$conversion_rate = $conversions / $impressions;
|
186 |
+
$conversion_rate_number = $conversion_rate * 100;
|
187 |
+
$conversion_rate_number = round($conversion_rate_number, 2);
|
188 |
+
$conversion_rate = $conversion_rate_number;
|
189 |
+
} else {
|
190 |
+
$conversion_rate = 0;
|
191 |
Â
}
|
192 |
Â
|
193 |
+
return $conversion_rate;
|
194 |
+
}
|
195 |
+
|
196 |
+
|
197 |
+
/**
|
198 |
+
* Set impression count
|
199 |
+
*/
|
200 |
+
public static function set_impressions_count( $post_id , $count ) {
|
201 |
+
update_post_meta( $post_id, '_inbound_impressions_count', $count );
|
202 |
+
}
|
203 |
+
|
204 |
+
/**
|
205 |
+
* Set conversion count
|
206 |
+
*/
|
207 |
+
public static function set_conversions_count( $post_id , $count ) {
|
208 |
+
update_post_meta( $post_id, '_inbound_conversions_count', $count );
|
209 |
Â
}
|
210 |
Â
|
211 |
+
}
|
212 |
+
|
213 |
Â
|
214 |
+
new Landing_Pages_Stats;
|
Â
|
classes/class.store.php
CHANGED
@@ -1,183 +1,33 @@
|
|
1 |
Â
<?php
|
Â
|
|
2 |
Â
/**
|
3 |
-
* Inbound
|
Â
|
|
Â
|
|
4 |
Â
*/
|
5 |
-
|
6 |
-
|
7 |
-
class Inbound_Now_Store {
|
8 |
-
|
9 |
-
static function init() {
|
10 |
-
if ( !class_exists('Inbound_Pro_Plugin') ) {
|
11 |
-
self::load_hooks();
|
12 |
-
}
|
13 |
-
}
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Loads hooks and filters
|
17 |
-
*/
|
18 |
-
public static function load_hooks() {
|
19 |
-
add_action( 'wp_ajax_show_store_ajax' , array( __CLASS__ , 'show_store_ajax' ) );
|
20 |
-
add_action( 'admin_enqueue_scripts' , array( __CLASS__ , 'enqueue_scripts' ) );
|
21 |
-
add_action( 'admin_print_footer_scripts' , array( __CLASS__ , 'print_scripts' ) );
|
22 |
-
}
|
23 |
-
|
24 |
-
/**
|
25 |
-
* enqueues scripts and styles
|
26 |
-
*/
|
27 |
-
public static function enqueue_scripts() {
|
28 |
-
global $plugin_page;
|
29 |
-
|
30 |
-
wp_enqueue_script('jquery');
|
31 |
-
|
32 |
-
}
|
33 |
-
|
34 |
-
public static function print_scripts() {
|
35 |
-
?>
|
36 |
-
<script type="text/javascript">
|
37 |
-
jQuery(document).ready(function($) {
|
38 |
-
jQuery('#menu-posts-landing-page a[href*="lp_store"]').each(function() {
|
39 |
-
jQuery(this).attr('target','_blank');
|
40 |
-
jQuery(this).attr('href','http://www.inboundnow.com/upgrade');
|
41 |
-
});
|
42 |
-
});
|
43 |
-
</script>
|
44 |
-
<?php
|
45 |
-
}
|
46 |
-
|
47 |
-
public static function show_store_ajax() {
|
48 |
-
if(empty($_POST) || !isset($_POST)) {
|
49 |
-
return;
|
50 |
-
} else {
|
51 |
-
/* show store forever */
|
52 |
-
$user_id = get_current_user_id();
|
53 |
-
add_user_meta($user_id, 'inbound_show_store', true);
|
54 |
-
die();
|
55 |
-
}
|
56 |
-
|
57 |
-
}
|
58 |
-
|
59 |
-
/**
|
60 |
-
*
|
61 |
-
*/
|
62 |
-
public static function store_display(){
|
63 |
-
global $current_user;
|
64 |
-
|
65 |
-
$user_id = $current_user->ID;
|
66 |
-
|
67 |
-
self::dom_output();
|
68 |
-
|
69 |
-
if ( !get_user_meta($user_id, 'inbound_show_store') ) {
|
70 |
-
self::inbound_store_notice();
|
71 |
-
} else {
|
72 |
-
/* normal display here */
|
73 |
-
self::store_redirect();
|
74 |
-
}
|
75 |
-
|
76 |
-
}
|
77 |
-
|
78 |
-
/* loads when user_meta opt in is NOT found */
|
79 |
-
public static function inbound_store_notice(){
|
80 |
Â
|
81 |
-
|
82 |
-
|
83 |
-
|
Â
|
|
84 |
Â
|
85 |
-
|
86 |
-
|
87 |
-
<br>
|
88 |
-
<a href="#" id="accept-agreement" class="button button-primary">I accept this agreement, show me the goods!</a>
|
89 |
-
</div>
|
90 |
Â
|
91 |
-
|
92 |
-
<script>
|
93 |
-
jQuery(document).ready(function($) {
|
94 |
-
|
95 |
-
jQuery("#accept-agreement").on('click', function (e) {
|
96 |
-
e.preventDefault();
|
97 |
-
|
98 |
-
$('#agreement').slideToggle();
|
99 |
-
|
100 |
-
showInboundStore();
|
101 |
-
|
102 |
-
jQuery.ajax({
|
103 |
-
type: 'POST',
|
104 |
-
url: ajaxadmin.ajaxurl,
|
105 |
-
data: {
|
106 |
-
action: 'show_store_ajax'
|
107 |
-
},
|
108 |
-
success: function(user_id){
|
109 |
-
console.log('user meta updated');
|
110 |
-
},
|
111 |
-
error: function(MLHttpRequest, textStatus, errorThrown){
|
112 |
-
|
113 |
-
}
|
114 |
-
|
115 |
-
});
|
116 |
-
|
117 |
-
});
|
118 |
-
});
|
119 |
-
</script>
|
120 |
-
|
121 |
-
<?php }
|
122 |
Â
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
Â
|
129 |
-
|
130 |
Â
|
131 |
-
|
132 |
Â
<?php
|
133 |
-
}
|
134 |
-
|
135 |
-
/* Always loads on store pages */
|
136 |
-
public static function dom_output(){
|
137 |
-
|
138 |
-
if (isset($_GET['inbound-store']) && $_GET['inbound-store'] === 'templates') {
|
139 |
-
$url = 'http://www.inboundnow.com/products/landing-pages/templates/';
|
140 |
-
} else if (isset($_GET['inbound-store']) && $_GET['inbound-store'] === 'addons') {
|
141 |
-
$url = 'http://www.inboundnow.com/products/landing-pages/extensions/';
|
142 |
-
} else {
|
143 |
-
$url = LANDINGPAGES_STORE_URL;
|
144 |
-
}
|
145 |
-
?>
|
146 |
-
<style type="text/css">
|
147 |
-
#setting-error-tgmpa, .updated, #wpfooter { display: none !important; }
|
148 |
-
#wpwrap { background: #fff !important; }
|
149 |
-
div#inbound-store-container { margin-top: 0px !important; }
|
150 |
-
div#inbound-store-container iframe { width:100%; }
|
151 |
-
#wpbody-content { padding-bottom: 0px !important; }
|
152 |
-
</style>
|
153 |
-
<script type='text/javascript'>
|
154 |
-
function showInboundStore(){
|
155 |
-
new easyXDM.Socket({
|
156 |
-
remote: "<?php echo $url;?>",
|
157 |
-
container: document.getElementById("inbound-store-container"),
|
158 |
-
onMessage: function(message, origin){
|
159 |
-
var height = Number(message) + 1000;
|
160 |
-
this.container.getElementsByTagName("iframe")[0].scrolling="no";
|
161 |
-
this.container.getElementsByTagName("iframe")[0].style.height = height + "px";
|
162 |
-
|
163 |
-
},
|
164 |
-
onReady: function() {
|
165 |
-
socket.postMessage("Yay, it works!");
|
166 |
-
/*alert('run'); */
|
167 |
-
}
|
168 |
-
});
|
169 |
-
|
170 |
-
setTimeout(function() {
|
171 |
-
jQuery("#inbound-store-container iframe").css('height', window.outerHeight + "px");
|
172 |
-
}, 2000);
|
173 |
-
}
|
174 |
-
</script>
|
175 |
-
|
176 |
-
<div id="inbound-store-container"></div>
|
177 |
-
<?php }
|
178 |
-
|
179 |
Â
}
|
Â
|
|
180 |
Â
|
181 |
-
Inbound_Now_Store::init();
|
182 |
Â
|
183 |
-
}
|
1 |
Â
<?php
|
2 |
+
|
3 |
Â
/**
|
4 |
+
* Class adds prompts to upgrade to Inbound Pro when user is using GPL Landing Pages. Also will be foundation for template installation engine once we phase out all free templates from core.
|
5 |
+
* @package LandingPages
|
6 |
+
* @subpackage NeedsAttention
|
7 |
Â
*/
|
8 |
+
class Inbound_Now_Store {
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
9 |
Â
|
10 |
+
/**
|
11 |
+
*
|
12 |
+
*/
|
13 |
+
public static function store_display() {
|
14 |
Â
|
15 |
+
/* normal display here */
|
16 |
+
self::store_redirect();
|
Â
|
|
Â
|
|
Â
|
|
17 |
Â
|
18 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
19 |
Â
|
20 |
+
/**
|
21 |
+
*
|
22 |
+
*/
|
23 |
+
public static function store_redirect() { ?>
|
24 |
+
<script>
|
25 |
Â
|
26 |
+
window.location = "https://www.inboundnow.com/market";
|
27 |
Â
|
28 |
+
</script>
|
29 |
Â
<?php
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
30 |
Â
}
|
31 |
+
}
|
32 |
Â
|
Â
|
|
33 |
Â
|
Â
|
classes/class.template-management.php
CHANGED
@@ -1,5 +1,10 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
3 |
Â
|
4 |
Â
class Landing_Pages_Template_Management {
|
5 |
Â
|
1 |
Â
<?php
|
2 |
Â
|
3 |
+
/**
|
4 |
+
* Class for managing and installing landing page templates manually. This feature is redundant for Inbound Pro subscribers using 1-click-installations.
|
5 |
+
* @package LandingPages
|
6 |
+
* @subpackage Templates
|
7 |
+
*/
|
8 |
Â
|
9 |
Â
class Landing_Pages_Template_Management {
|
10 |
Â
|
classes/class.variations.php
CHANGED
@@ -1,813 +1,811 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
3 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
4 |
Â
|
5 |
-
|
6 |
Â
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
Â
|
11 |
-
|
12 |
Â
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
Â
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
Â
|
21 |
Â
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
Â
|
31 |
-
|
32 |
Â
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
Â
|
38 |
Â
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
Â
|
44 |
-
|
45 |
-
|
46 |
Â
|
47 |
Â
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
Â
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
Â
SELECT `meta_key`, `meta_value`
|
61 |
Â
FROM $wpdb->postmeta
|
62 |
Â
WHERE `post_id` = " . $landing_page_id . "
|
63 |
Â
");
|
64 |
Â
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
Â
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
}
|
74 |
Â
}
|
75 |
-
|
76 |
-
|
77 |
Â
}
|
78 |
Â
|
79 |
-
/**
|
80 |
-
* Pauses variation for a call to action
|
81 |
-
*
|
82 |
-
* @param INT $landing_page_id id of call to action
|
83 |
-
* @param INT $variation_id id of variation to delete
|
84 |
-
*
|
85 |
-
*/
|
86 |
-
public static function pause_variation($landing_page_id, $variation_id) {
|
87 |
-
update_post_meta( $landing_page_id , 'lp_ab_variation_status-' . $variation_id, '0');
|
88 |
-
}
|
89 |
Â
|
90 |
-
|
91 |
-
* Activations variation for a call to action
|
92 |
-
*
|
93 |
-
* @param INT $landing_page_id id of call to action
|
94 |
-
* @param INT $variation_id id of variation to play
|
95 |
-
*
|
96 |
-
*/
|
97 |
-
public static function play_variation($landing_page_id, $variation_id) {
|
98 |
-
update_post_meta( $landing_page_id , 'lp_ab_variation_status-' . $variation_id, 1 );
|
99 |
-
}
|
100 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
101 |
Â
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
Â
|
|
Â
|
|
110 |
Â
|
111 |
-
if ( is_array($variations) ) {
|
112 |
-
$variations = implode(',', $variations);
|
113 |
-
}
|
114 |
Â
|
115 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
116 |
Â
|
Â
|
|
Â
|
|
117 |
Â
}
|
118 |
Â
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
* @param INT $landing_page_id id of call to action
|
123 |
-
* @param INT $variation_id id of variation belonging to call to action
|
124 |
-
*
|
125 |
-
*/
|
126 |
-
public static function record_impression($landing_page_id, $variation_id) {
|
127 |
Â
|
128 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
129 |
Â
|
130 |
-
|
131 |
-
$impressions = 1;
|
132 |
-
} else {
|
133 |
-
$impressions++;
|
134 |
-
}
|
135 |
Â
|
136 |
-
|
Â
|
|
Â
|
|
Â
|
|
137 |
Â
}
|
138 |
Â
|
Â
|
|
Â
|
|
139 |
Â
|
140 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
141 |
Â
|
Â
|
|
142 |
Â
|
143 |
-
|
144 |
-
* Prepare a variation id for a new variation
|
145 |
-
*
|
146 |
-
* @param INT $landing_page_id id of landing page
|
147 |
-
*
|
148 |
-
* @returns INT $vid variation id
|
149 |
-
*/
|
150 |
-
public static function prepare_new_variation_id( $landing_page_id ) {
|
151 |
Â
|
152 |
-
|
153 |
Â
|
154 |
-
|
Â
|
|
155 |
Â
|
156 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
157 |
Â
|
158 |
-
|
Â
|
|
159 |
Â
}
|
160 |
Â
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
*/
|
168 |
-
public static function prepare_input_id( $id , $variation_id = null , $legacy = true) {
|
169 |
Â
|
170 |
-
|
171 |
-
|
172 |
-
|
Â
|
|
Â
|
|
Â
|
|
173 |
Â
|
174 |
-
|
175 |
-
|
176 |
-
} else {
|
177 |
-
return $id;
|
178 |
-
}
|
179 |
Â
}
|
180 |
Â
|
181 |
-
|
182 |
-
* Convert permalink to the correct variation preview link
|
183 |
-
* @param $link
|
184 |
-
* @return mixed
|
185 |
-
*/
|
186 |
-
public static function prepare_filter_link( $link ) {
|
187 |
Â
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
Â
|
192 |
-
|
Â
|
|
Â
|
|
193 |
Â
|
194 |
-
if (!isset($screen) || $screen->parent_file != 'edit.php?post_type=landing-page' || strstr($link ,'%') ){
|
195 |
-
return $link;
|
196 |
-
}
|
197 |
Â
|
198 |
-
|
199 |
-
return $link;
|
200 |
-
}
|
201 |
Â
|
Â
|
|
202 |
Â
|
203 |
-
|
Â
|
|
204 |
Â
|
205 |
-
$link = add_query_arg(array('lp-variation-id'=>$vid) , $link);
|
206 |
Â
|
207 |
-
|
208 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
209 |
Â
|
Â
|
|
210 |
Â
|
211 |
-
|
212 |
-
* Sets the variation status to a custom status
|
213 |
-
*
|
214 |
-
* @param INT $landing_page_id id of call to action
|
215 |
-
* @param INT $variation_id id of variation to delete
|
216 |
-
* @param STRING $status custom status
|
217 |
-
*
|
218 |
-
*/
|
219 |
-
public static function set_variation_status($landing_page_id, $variation_id, $status = '1') {
|
220 |
Â
|
221 |
-
update_post_meta( $landing_page_id , 'lp_ab_variation_status-' . $variation_id, $status );
|
222 |
Â
|
223 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
224 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
225 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
226 |
Â
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
Â
|
|
Â
|
|
233 |
Â
|
234 |
-
|
235 |
Â
|
236 |
-
|
237 |
-
|
238 |
-
*
|
239 |
-
* @param INT $landing_page_id id of call to action
|
240 |
-
* @param INT $variation_id id of variation belonging to call to action
|
241 |
-
* @param INT $count
|
242 |
-
*
|
243 |
-
*/
|
244 |
-
public static function set_impressions_count($landing_page_id, $variation_id = 0 , $count) {
|
245 |
-
update_post_meta($landing_page_id, 'lp-ab-variation-impressions-' . $variation_id, $count);
|
246 |
Â
}
|
247 |
Â
|
248 |
-
|
249 |
-
|
250 |
-
*
|
251 |
-
* @param INT $landing_page_id id of landing page
|
252 |
-
* @param INT $variation_id id of variation
|
253 |
-
* @param INT $count
|
254 |
-
*/
|
255 |
-
public static function set_conversions_count( $landing_page_id , $variation_id , $count) {
|
256 |
-
update_post_meta($landing_page_id, 'lp-ab-variation-conversions-' . $variation_id , $count);
|
257 |
Â
}
|
258 |
Â
|
259 |
-
|
260 |
-
|
261 |
-
*
|
262 |
-
* @param INT $landing_page_id id of landing page
|
263 |
-
*
|
264 |
-
* @returns ARRAY of variation data
|
265 |
-
*/
|
266 |
-
public static function get_variations($landing_page_id) {
|
267 |
-
|
268 |
-
$variations = get_post_meta($landing_page_id, 'lp-ab-variations', true);
|
269 |
Â
|
270 |
-
if (!is_array($variations) && $variations ) {
|
271 |
-
$variations = explode( ',' , $variations);
|
272 |
-
}
|
273 |
Â
|
274 |
-
|
275 |
-
|
276 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
277 |
Â
|
278 |
-
|
Â
|
|
279 |
Â
}
|
280 |
Â
|
Â
|
|
281 |
Â
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
*
|
288 |
-
* @returns STRING status
|
289 |
-
*/
|
290 |
-
public static function get_variation_status($landing_page_id, $variation_id = null) {
|
291 |
Â
|
292 |
-
|
293 |
-
$variation_id = Landing_Pages_Variations::get_current_variation_id();
|
294 |
-
}
|
295 |
Â
|
296 |
-
$variation_status = get_post_meta( $landing_page_id , 'lp_ab_variation_status-' . $variation_id, true);
|
297 |
Â
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
Â
|
|
303 |
Â
|
304 |
-
}
|
305 |
Â
|
Â
|
|
306 |
Â
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
Â
|
|
Â
|
|
314 |
Â
|
Â
|
|
Â
|
|
315 |
Â
}
|
316 |
Â
|
317 |
-
|
318 |
-
* Returns the permalink of a variation given landing_page_id and vid
|
319 |
-
*
|
320 |
-
* @param INT $landing_page_id id of call to action
|
321 |
-
* @param INT $variation_id variation id of call to action
|
322 |
-
*
|
323 |
-
* @returns STRING permalink
|
324 |
-
*/
|
325 |
-
public static function get_variation_permalink($landing_page_id, $variation_id = null) {
|
326 |
Â
|
327 |
-
|
328 |
-
|
329 |
-
}
|
330 |
Â
|
331 |
-
$permalink = get_permalink($landing_page_id);
|
332 |
Â
|
333 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
334 |
Â
}
|
335 |
Â
|
Â
|
|
336 |
Â
|
337 |
-
|
338 |
-
|
339 |
-
*
|
340 |
-
* @param INT $landing_page_id id of call to action
|
341 |
-
* @param INT $variation_id variation id of call to action variation, will attempt to autodetect if left as null
|
342 |
-
*
|
343 |
-
* @return STRING $notes variation notes.
|
344 |
-
*/
|
345 |
-
public static function get_variation_notes($landing_page_id, $variation_id = null) {
|
346 |
-
if ($variation_id === null) {
|
347 |
-
$variation_id = Landing_Pages_Variations::get_current_variation_id();
|
348 |
-
}
|
349 |
Â
|
350 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
351 |
Â
|
352 |
-
|
Â
|
|
353 |
Â
}
|
354 |
Â
|
355 |
-
|
356 |
-
* Gets the call to action variation custom css
|
357 |
-
*
|
358 |
-
* @param INT $landing_page_id id of call to action
|
359 |
-
* @param INT $variation_id variation id of call to action variation, will attempt to autodetect if left as null
|
360 |
-
*
|
361 |
-
* @return STRING $custom_css.
|
362 |
-
*/
|
363 |
-
public static function get_custom_css($landing_page_id, $variation_id = null) {
|
364 |
Â
|
365 |
-
|
366 |
-
$variation_id = Landing_Pages_Variations::get_current_variation_id();
|
367 |
-
}
|
368 |
Â
|
369 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
370 |
Â
|
Â
|
|
Â
|
|
371 |
Â
}
|
372 |
Â
|
373 |
-
|
374 |
-
|
375 |
-
*
|
376 |
-
* @param INT $landing_page_id id of call to action
|
377 |
-
* @param INT $variation_id variation id of call to action variation, will attempt to autodetect if left as null
|
378 |
-
*
|
379 |
-
* @return STRING $custom_js.
|
380 |
-
*/
|
381 |
-
public static function get_custom_js($landing_page_id, $variation_id = null) {
|
382 |
Â
|
383 |
-
|
384 |
-
|
385 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
386 |
Â
|
387 |
-
|
Â
|
|
388 |
Â
}
|
389 |
Â
|
390 |
-
/*
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
*/
|
395 |
-
public static function get_current_variation_id() {
|
396 |
-
global $post, $current_variation_id;
|
397 |
-
|
398 |
-
if (isset($_SESSION['lp_ab_test_open_variation']) && isset($_GET['ab-action']) && is_admin()) {
|
399 |
-
return $_SESSION['lp_ab_test_open_variation'];
|
400 |
-
}
|
401 |
-
|
402 |
-
/* check to see if this has already been set during the instance */
|
403 |
-
if (is_numeric($current_variation_id)) {
|
404 |
-
return $current_variation_id;
|
405 |
-
}
|
406 |
Â
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
Â
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
Â
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
Â
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
Â
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
}
|
433 |
-
|
434 |
-
$variations = self::get_variations($post_id);
|
435 |
-
$id = array_values($variations);
|
436 |
-
$current_variation_id = array_shift($id);
|
437 |
Â
}
|
438 |
Â
|
439 |
-
$
|
440 |
-
|
441 |
-
|
442 |
Â
}
|
443 |
Â
|
444 |
-
|
445 |
-
* Looks up the variation id we should use for prepopulating settings on cloned variations and new variations
|
446 |
-
*
|
447 |
-
* @returns INT of variation id
|
448 |
-
*/
|
449 |
-
public static function get_new_variation_reference_id( $landing_page_id , $variation_id = null ) {
|
450 |
-
global $post;
|
451 |
Â
|
452 |
-
|
453 |
-
|
454 |
-
$variation_id = Landing_Pages_Variations::get_current_variation_id();
|
455 |
-
}
|
456 |
Â
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
Â
|
|
Â
|
|
462 |
Â
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
Â
|
468 |
-
|
Â
|
|
Â
|
|
Â
|
|
469 |
Â
}
|
470 |
Â
|
471 |
-
/*
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
*/
|
476 |
-
public static function get_next_available_variation_id($landing_page_id) {
|
477 |
Â
|
478 |
-
|
479 |
-
|
480 |
Â
|
481 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
482 |
Â
|
483 |
-
|
Â
|
|
484 |
Â
|
485 |
-
|
486 |
-
}
|
487 |
Â
|
488 |
-
|
489 |
-
* Gets string id of template given email id
|
490 |
-
*
|
491 |
-
* @param INT $landing_page_id of call to action
|
492 |
-
* @param INT $variation_id of variation id
|
493 |
-
*
|
494 |
-
* @returns STRING id of selected template
|
495 |
-
*/
|
496 |
-
public static function get_current_template($landing_page_id, $variation_id = null) {
|
497 |
Â
|
498 |
-
|
499 |
-
|
500 |
-
}
|
501 |
Â
|
502 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
503 |
Â
|
Â
|
|
Â
|
|
504 |
Â
}
|
505 |
Â
|
506 |
-
|
507 |
-
* Get Screenshot URL for Call to Action preview. If local environment show template thumbnail.
|
508 |
-
*
|
509 |
-
* @param INT $landing_page_id id if of call to action
|
510 |
-
* @param INT $variation_id id of variation belonging to call to action
|
511 |
-
*
|
512 |
-
* @return STRING url of preview
|
513 |
-
*/
|
514 |
-
public static function get_screenshot_url($landing_page_id, $variation_id = null) {
|
515 |
Â
|
516 |
-
|
517 |
-
|
518 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
519 |
Â
|
520 |
-
|
Â
|
|
Â
|
|
521 |
Â
|
522 |
-
|
523 |
Â
|
524 |
-
|
525 |
-
$screenshot = INBOUND_EMAIL_UPLOADS_URLPATH . 'templates/' . $template . '/thumbnail.png';
|
526 |
-
} else {
|
527 |
-
$screenshot = INBOUND_EMAIL_URLPATH . 'templates/' . $template . '/thumbnail.png';
|
528 |
-
}
|
529 |
Â
|
Â
|
|
Â
|
|
530 |
Â
} else {
|
531 |
-
$screenshot = '
|
532 |
Â
}
|
533 |
Â
|
534 |
-
|
Â
|
|
535 |
Â
}
|
536 |
Â
|
Â
|
|
Â
|
|
537 |
Â
|
538 |
-
/**
|
539 |
-
* Returns impression for given cta and variation id
|
540 |
-
*
|
541 |
-
* @param INT $landing_page_id id of call to action
|
542 |
-
* @param INT $variation_id id of variation belonging to call to action
|
543 |
-
*
|
544 |
-
* @return INT impression count
|
545 |
-
*/
|
546 |
-
public static function get_impressions( $landing_page_id, $variation_id ) {
|
547 |
Â
|
548 |
-
|
549 |
-
|
550 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
551 |
Â
|
552 |
-
|
553 |
-
$
|
554 |
-
|
555 |
-
return $impressions;
|
556 |
Â
}
|
557 |
Â
|
558 |
-
|
559 |
-
|
560 |
-
*
|
561 |
-
* @param INT $landing_page_id id of call to action
|
562 |
-
* @param INT $variation_id id of variation belonging to call to action
|
563 |
-
*
|
564 |
-
* @return INT conversion count
|
565 |
-
*/
|
566 |
-
public static function get_conversions( $landing_page_id , $variation_id ) {
|
567 |
Â
|
568 |
-
|
569 |
-
|
570 |
-
}
|
571 |
Â
|
572 |
-
|
573 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
574 |
Â
|
575 |
-
|
Â
|
|
576 |
Â
}
|
577 |
Â
|
578 |
-
|
579 |
-
|
580 |
-
*
|
581 |
-
* @param INT $landing_page_id id of call to action
|
582 |
-
* @param INT $variation_id id of variation belonging to call to action
|
583 |
-
*
|
584 |
-
* @return INT conversion rate
|
585 |
-
*/
|
586 |
-
public static function get_conversion_rate($landing_page_id, $variation_id) {
|
587 |
Â
|
588 |
-
|
589 |
-
|
590 |
Â
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
599 |
Â
|
600 |
-
|
601 |
-
|
Â
|
|
Â
|
|
Â
|
|
602 |
Â
|
603 |
-
|
604 |
-
|
605 |
-
* @param null $variation_id
|
606 |
-
*/
|
607 |
-
public static function get_conversion_area( $landing_page_id, $variation_id = null) {
|
608 |
Â
|
609 |
-
|
610 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
611 |
Â
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
$
|
619 |
-
return Landing_Pages_Variations::get_setting_value( $template . '-conversion-area-placement' , $landing_page_id, $variation_id );
|
620 |
Â
}
|
621 |
Â
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
}
|
630 |
Â
|
631 |
-
|
Â
|
|
632 |
Â
}
|
633 |
Â
|
634 |
-
|
635 |
-
|
636 |
-
*/
|
637 |
-
public static function get_main_headline( $landing_page_id , $variation_id = null ) {
|
638 |
Â
|
639 |
-
|
640 |
-
|
641 |
-
|
Â
|
|
642 |
Â
|
643 |
-
|
Â
|
|
Â
|
|
Â
|
|
644 |
Â
}
|
Â
|
|
645 |
Â
|
646 |
-
/**
|
647 |
-
* Gets thumbnail for selected template
|
648 |
-
*/
|
649 |
-
public static function get_template_thumbnail( $template ) {
|
650 |
-
|
651 |
-
if (file_exists(LANDINGPAGES_UPLOADS_PATH . $template . '/thumbnail.png')) {
|
652 |
-
return LANDINGPAGES_UPLOADS_URLPATH . $template . '/thumbnail.png';
|
653 |
-
} else {
|
654 |
-
return LANDINGPAGES_URLPATH . 'templates/' . $template . '/thumbnail.png';
|
655 |
-
}
|
656 |
-
}
|
657 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
658 |
Â
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
* @param $variation_id
|
664 |
-
* @param string $default
|
665 |
-
* @return string
|
666 |
-
*/
|
667 |
-
public static function get_setting_value( $key , $landing_page_id , $variation_id = null, $default = '' ) {
|
668 |
Â
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
Â
|
|
673 |
Â
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
}
|
679 |
Â
|
680 |
-
|
681 |
-
if (
|
682 |
-
$
|
Â
|
|
Â
|
|
683 |
Â
}
|
Â
|
|
684 |
Â
|
685 |
-
if ( $
|
686 |
-
|
687 |
-
return get_post_meta( $landing_page_id , $key .'-' . $variation_id, true);
|
688 |
-
} else {
|
689 |
-
return $default;
|
690 |
-
}
|
691 |
Â
} else {
|
692 |
-
|
693 |
-
if (metadata_exists('post', $landing_page_id , $key )) {
|
694 |
-
return get_post_meta( $landing_page_id , $key, true);
|
695 |
-
} else {
|
696 |
-
return $default;
|
697 |
-
}
|
698 |
Â
}
|
699 |
-
|
700 |
Â
}
|
701 |
Â
|
Â
|
|
702 |
Â
|
703 |
-
/**
|
704 |
-
* Increments conversion count for given landing page id and variation id
|
705 |
-
*
|
706 |
-
* @param INT $landing_page_id id of landing page
|
707 |
-
* @param INT $variation_id id of variation belonging to call to action
|
708 |
-
*
|
709 |
-
*/
|
710 |
-
public static function record_conversion($landing_page_id, $variation_id) {
|
711 |
Â
|
712 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
713 |
Â
|
714 |
-
|
715 |
-
$conversions = 1;
|
716 |
-
} else {
|
717 |
-
$conversions++;
|
718 |
-
}
|
719 |
Â
|
720 |
-
|
Â
|
|
Â
|
|
Â
|
|
721 |
Â
}
|
722 |
Â
|
723 |
-
|
724 |
-
|
725 |
-
*
|
726 |
-
* @param link STRING URL that param will be appended onto
|
727 |
-
*
|
728 |
-
*
|
729 |
-
* @return STRING modified URL.
|
730 |
-
*/
|
731 |
-
public static function append_variation_id_to_url($link) {
|
732 |
-
global $post;
|
733 |
Â
|
734 |
-
|
735 |
-
|
736 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
737 |
Â
|
738 |
-
|
739 |
Â
|
740 |
Â
|
741 |
-
|
742 |
Â
|
743 |
-
|
744 |
-
|
745 |
Â
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
Â
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
}
|
762 |
-
$i++;
|
763 |
Â
}
|
Â
|
|
Â
|
|
764 |
Â
|
765 |
-
|
766 |
Â
|
767 |
-
|
768 |
-
|
769 |
-
}
|
770 |
Â
}
|
Â
|
|
771 |
Â
|
772 |
Â
|
773 |
-
|
774 |
-
|
775 |
-
|
776 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
$landing_page_id = intval($_POST['page_id']);
|
781 |
Â
|
782 |
-
|
783 |
Â
|
784 |
-
|
785 |
-
update_post_meta( $landing_page_id , 'lp-ab-variation-impressions-' . $vid, 0 , false);
|
786 |
-
update_post_meta( $landing_page_id , 'lp-ab-variation-conversions-' . $vid, 0 , false);
|
787 |
-
}
|
788 |
Â
|
789 |
-
|
Â
|
|
Â
|
|
790 |
Â
}
|
791 |
Â
|
Â
|
|
Â
|
|
792 |
Â
|
793 |
-
/**
|
794 |
-
* Adds Ajax for Clear Stats button
|
795 |
-
* clear stats for single variations
|
796 |
-
*/
|
797 |
-
public static function ajax_clear_stats_single() {
|
798 |
-
global $wpdb;
|
799 |
Â
|
800 |
-
|
801 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
802 |
Â
|
803 |
-
|
804 |
-
|
805 |
Â
|
806 |
-
|
807 |
-
|
808 |
Â
|
Â
|
|
809 |
Â
}
|
810 |
Â
|
811 |
-
|
812 |
Â
|
813 |
-
|
1 |
Â
<?php
|
2 |
Â
|
3 |
+
/**
|
4 |
+
* Class covers methods handling landing page edit screen
|
5 |
+
* @package LandingPages
|
6 |
+
* @subpackage Templates
|
7 |
+
*/
|
8 |
Â
|
9 |
+
class Landing_Pages_Variations {
|
10 |
Â
|
11 |
+
public function __construct() {
|
12 |
+
self::load_hooks();
|
13 |
+
}
|
14 |
Â
|
15 |
+
public static function load_hooks() {
|
16 |
Â
|
17 |
+
/* load ajax listeners */
|
18 |
+
add_action('wp_ajax_lp_clear_stats_action', array(__CLASS__, 'ajax_clear_stats'));
|
19 |
+
add_action('wp_ajax_lp_clear_stats_single', array(__CLASS__, 'ajax_clear_stats_single'));
|
20 |
Â
|
21 |
+
/* alter preview link */
|
22 |
+
add_filter('post_type_link', array(__CLASS__, 'prepare_filter_link'), 10, 1);
|
23 |
+
}
|
24 |
Â
|
25 |
Â
|
26 |
+
/**
|
27 |
+
* Deletes variation for a call to action
|
28 |
+
*
|
29 |
+
* @param INT $landing_page_id id of call to action
|
30 |
+
* @param INT $variation_id id of variation to delete
|
31 |
+
*
|
32 |
+
*/
|
33 |
+
public static function delete_variation($landing_page_id, $variation_id) {
|
34 |
Â
|
35 |
+
$variations = Landing_Pages_Variations::get_variations($landing_page_id);
|
36 |
Â
|
37 |
+
/* unset variation */
|
38 |
+
if (($key = array_search($variation_id, $variations)) !== false) {
|
39 |
+
unset($variations[$key]);
|
40 |
+
}
|
41 |
Â
|
42 |
Â
|
43 |
+
/* set next variation to be open */
|
44 |
+
$current_variation_id = current($variations);
|
45 |
+
$_SESSION['lp_ab_test_open_variation'] = $current_variation_id;
|
46 |
+
$_GET['lp-variation-id'] = $current_variation_id;
|
47 |
Â
|
48 |
+
/* update variations */
|
49 |
+
Landing_Pages_Variations::update_variations($landing_page_id, $variations);
|
50 |
Â
|
51 |
Â
|
52 |
+
if ($variation_id > 0) {
|
53 |
+
$suffix = '-' . $variation_id;
|
54 |
+
$len = strlen($suffix);
|
55 |
+
} else {
|
56 |
+
$suffix = '';
|
57 |
+
$len = strlen($suffix);
|
58 |
+
}
|
59 |
Â
|
60 |
+
/*delete each meta value associated with variation */
|
61 |
+
global $wpdb;
|
62 |
+
$data = array();
|
63 |
+
$wpdb->query("
|
64 |
Â
SELECT `meta_key`, `meta_value`
|
65 |
Â
FROM $wpdb->postmeta
|
66 |
Â
WHERE `post_id` = " . $landing_page_id . "
|
67 |
Â
");
|
68 |
Â
|
69 |
+
foreach ($wpdb->last_result as $k => $v) {
|
70 |
+
$data[$v->meta_key] = $v->meta_value;
|
71 |
+
};
|
72 |
Â
|
73 |
+
/*echo $len;exit; */
|
74 |
+
foreach ($data as $key => $value) {
|
75 |
+
if (substr($key, -$len) == $suffix) {
|
76 |
+
delete_post_meta($landing_page_id, $key, $value);
|
Â
|
|
77 |
Â
}
|
Â
|
|
Â
|
|
78 |
Â
}
|
79 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
80 |
Â
|
81 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
82 |
Â
|
83 |
+
/**
|
84 |
+
* Pauses variation for a call to action
|
85 |
+
*
|
86 |
+
* @param INT $landing_page_id id of call to action
|
87 |
+
* @param INT $variation_id id of variation to delete
|
88 |
+
*
|
89 |
+
*/
|
90 |
+
public static function pause_variation($landing_page_id, $variation_id) {
|
91 |
+
update_post_meta($landing_page_id, 'lp_ab_variation_status-' . $variation_id, '0');
|
92 |
+
}
|
93 |
Â
|
94 |
+
/**
|
95 |
+
* Activations variation for a call to action
|
96 |
+
*
|
97 |
+
* @param INT $landing_page_id id of call to action
|
98 |
+
* @param INT $variation_id id of variation to play
|
99 |
+
*
|
100 |
+
*/
|
101 |
+
public static function play_variation($landing_page_id, $variation_id) {
|
102 |
+
update_post_meta($landing_page_id, 'lp_ab_variation_status-' . $variation_id, 1);
|
103 |
+
}
|
104 |
Â
|
Â
|
|
Â
|
|
Â
|
|
105 |
Â
|
106 |
+
/**
|
107 |
+
* Updates 'inbound-email-variations' meta key with json object
|
108 |
+
*
|
109 |
+
* @param INT $landing_page_id id of call to action
|
110 |
+
* @param variations ARRAY of variation data
|
111 |
+
*
|
112 |
+
*/
|
113 |
+
public static function update_variations($landing_page_id, $variations) {
|
114 |
Â
|
115 |
+
if (is_array($variations)) {
|
116 |
+
$variations = implode(',', $variations);
|
117 |
Â
}
|
118 |
Â
|
119 |
+
update_post_meta($landing_page_id, 'lp-ab-variations', $variations);
|
120 |
+
|
121 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
122 |
Â
|
123 |
+
/**
|
124 |
+
* Increments impression count for given cta and variation id
|
125 |
+
*
|
126 |
+
* @param INT $landing_page_id id of call to action
|
127 |
+
* @param INT $variation_id id of variation belonging to call to action
|
128 |
+
*
|
129 |
+
*/
|
130 |
+
public static function record_impression($landing_page_id, $variation_id) {
|
131 |
Â
|
132 |
+
$impressions = get_post_meta($landing_page_id, 'lp-ab-variation-impressions--' . $variation_id, true);
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
133 |
Â
|
134 |
+
if (!is_numeric($impressions)) {
|
135 |
+
$impressions = 1;
|
136 |
+
} else {
|
137 |
+
$impressions++;
|
138 |
Â
}
|
139 |
Â
|
140 |
+
update_post_meta($landing_page_id, 'lp-ab-variation-impressions--' . $variation_id, $impressions);
|
141 |
+
}
|
142 |
Â
|
143 |
Â
|
144 |
+
/**
|
145 |
+
* Prepare a variation id for a new variation
|
146 |
+
*
|
147 |
+
* @param INT $landing_page_id id of landing page
|
148 |
+
*
|
149 |
+
* @returns INT $vid variation id
|
150 |
+
*/
|
151 |
+
public static function prepare_new_variation_id($landing_page_id) {
|
152 |
Â
|
153 |
+
$variations = self::get_variations($landing_page_id);
|
154 |
Â
|
155 |
+
sort($variations, SORT_NUMERIC);
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
156 |
Â
|
157 |
+
$vid = end($variations);
|
158 |
Â
|
159 |
+
return $vid + 1;
|
160 |
+
}
|
161 |
Â
|
162 |
+
/* Adds variation id onto base meta key
|
163 |
+
*
|
164 |
+
* @param id STRING of meta key to store data into for given setting
|
165 |
+
* @param INT $variation_id id of variation belonging to call to action, will attempt to autodetect if left as null
|
166 |
+
*
|
167 |
+
* @returns STRING of meta key appended with variation id
|
168 |
+
*/
|
169 |
+
public static function prepare_input_id($id, $variation_id = null, $legacy = true) {
|
170 |
Â
|
171 |
+
if ($variation_id === null) {
|
172 |
+
$variation_id = Landing_Pages_Variations::get_current_variation_id();
|
173 |
Â
}
|
174 |
Â
|
175 |
+
if ($variation_id > 0 || !$legacy) {
|
176 |
+
return $id . '-' . $variation_id;
|
177 |
+
} else {
|
178 |
+
return $id;
|
179 |
+
}
|
180 |
+
}
|
Â
|
|
Â
|
|
181 |
Â
|
182 |
+
/**
|
183 |
+
* Convert permalink to the correct variation preview link
|
184 |
+
* @param $link
|
185 |
+
* @return mixed
|
186 |
+
*/
|
187 |
+
public static function prepare_filter_link($link) {
|
188 |
Â
|
189 |
+
if (!is_admin() || !function_exists('get_current_screen')) {
|
190 |
+
return $link;
|
Â
|
|
Â
|
|
Â
|
|
191 |
Â
}
|
192 |
Â
|
193 |
+
$screen = get_current_screen();
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
194 |
Â
|
195 |
+
if (!isset($screen) || $screen->parent_file != 'edit.php?post_type=landing-page' || strstr($link, '%')) {
|
196 |
+
return $link;
|
197 |
+
}
|
198 |
Â
|
199 |
+
if (strstr($link, 'lp-variation-id')) {
|
200 |
+
return $link;
|
201 |
+
}
|
202 |
Â
|
Â
|
|
Â
|
|
Â
|
|
203 |
Â
|
204 |
+
$vid = self::get_current_variation_id();
|
Â
|
|
Â
|
|
205 |
Â
|
206 |
+
$link = add_query_arg(array('lp-variation-id' => $vid), $link);
|
207 |
Â
|
208 |
+
return $link;
|
209 |
+
}
|
210 |
Â
|
Â
|
|
211 |
Â
|
212 |
+
/**
|
213 |
+
* Sets the variation status to a custom status
|
214 |
+
*
|
215 |
+
* @param INT $landing_page_id id of call to action
|
216 |
+
* @param INT $variation_id id of variation to delete
|
217 |
+
* @param STRING $status custom status
|
218 |
+
*
|
219 |
+
*/
|
220 |
+
public static function set_variation_status($landing_page_id, $variation_id, $status = '1') {
|
221 |
Â
|
222 |
+
update_post_meta($landing_page_id, 'lp_ab_variation_status-' . $variation_id, $status);
|
223 |
Â
|
224 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
225 |
Â
|
Â
|
|
226 |
Â
|
227 |
+
/**
|
228 |
+
* Updates variation marker (used for single sends)
|
229 |
+
* @param INT $landing_page_id
|
230 |
+
* @param INT $variation_marker
|
231 |
+
*/
|
232 |
+
public static function set_variation_marker($landing_page_id, $variation_marker) {
|
233 |
+
|
234 |
+
}
|
235 |
Â
|
236 |
+
/**
|
237 |
+
* Manually sets conversion count for given cta id and variation id
|
238 |
+
*
|
239 |
+
* @param INT $landing_page_id id of call to action
|
240 |
+
* @param INT $variation_id id of variation belonging to call to action
|
241 |
+
* @param INT $count
|
242 |
+
*
|
243 |
+
*/
|
244 |
+
public static function set_impressions_count($landing_page_id, $variation_id = 0, $count) {
|
245 |
+
update_post_meta($landing_page_id, 'lp-ab-variation-impressions-' . $variation_id, $count);
|
246 |
+
}
|
247 |
Â
|
248 |
+
/**
|
249 |
+
* Manually sets conversion count for given cta id and variation id
|
250 |
+
*
|
251 |
+
* @param INT $landing_page_id id of landing page
|
252 |
+
* @param INT $variation_id id of variation
|
253 |
+
* @param INT $count
|
254 |
+
*/
|
255 |
+
public static function set_conversions_count($landing_page_id, $variation_id, $count) {
|
256 |
+
update_post_meta($landing_page_id, 'lp-ab-variation-conversions-' . $variation_id, $count);
|
257 |
+
}
|
258 |
Â
|
259 |
+
/**
|
260 |
+
* Returns array of variation data given a landing page id
|
261 |
+
*
|
262 |
+
* @param INT $landing_page_id id of landing page
|
263 |
+
*
|
264 |
+
* @returns ARRAY of variation data
|
265 |
+
*/
|
266 |
+
public static function get_variations($landing_page_id) {
|
267 |
Â
|
268 |
+
$variations = get_post_meta($landing_page_id, 'lp-ab-variations', true);
|
269 |
Â
|
270 |
+
if (!is_array($variations) && $variations) {
|
271 |
+
$variations = explode(',', $variations);
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
272 |
Â
}
|
273 |
Â
|
274 |
+
if (!is_array($variations) || !$variations) {
|
275 |
+
$variations = array(0 => "0");
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
276 |
Â
}
|
277 |
Â
|
278 |
+
return $variations;
|
279 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
280 |
Â
|
Â
|
|
Â
|
|
Â
|
|
281 |
Â
|
282 |
+
/**
|
283 |
+
* Returns the status of a variation given landing_page_id and vid
|
284 |
+
*
|
285 |
+
* @param INT $landing_page_id id of call to action
|
286 |
+
* @param INT $variation_id variation id of call to action
|
287 |
+
*
|
288 |
+
* @returns STRING status
|
289 |
+
*/
|
290 |
+
public static function get_variation_status($landing_page_id, $variation_id = null) {
|
291 |
Â
|
292 |
+
if ($variation_id === null) {
|
293 |
+
$variation_id = Landing_Pages_Variations::get_current_variation_id();
|
294 |
Â
}
|
295 |
Â
|
296 |
+
$variation_status = get_post_meta($landing_page_id, 'lp_ab_variation_status-' . $variation_id, true);
|
297 |
Â
|
298 |
+
if (!is_numeric($variation_status)) {
|
299 |
+
return 1;
|
300 |
+
} else {
|
301 |
+
return $variation_status;
|
302 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
303 |
Â
|
304 |
+
}
|
Â
|
|
Â
|
|
305 |
Â
|
Â
|
|
306 |
Â
|
307 |
+
/**
|
308 |
+
* Get next variation ID available
|
309 |
+
* @param INT $landing_page_id
|
310 |
+
* @return INT $next_variant_marker
|
311 |
+
*/
|
312 |
+
public static function get_next_variant_marker($landing_page_id) {
|
313 |
Â
|
Â
|
|
314 |
Â
|
315 |
+
}
|
316 |
Â
|
317 |
+
/**
|
318 |
+
* Returns the permalink of a variation given landing_page_id and vid
|
319 |
+
*
|
320 |
+
* @param INT $landing_page_id id of call to action
|
321 |
+
* @param INT $variation_id variation id of call to action
|
322 |
+
*
|
323 |
+
* @returns STRING permalink
|
324 |
+
*/
|
325 |
+
public static function get_variation_permalink($landing_page_id, $variation_id = null) {
|
326 |
Â
|
327 |
+
if ($variation_id === null) {
|
328 |
+
$variation_id = Landing_Pages_Variations::get_current_variation_id();
|
329 |
Â
}
|
330 |
Â
|
331 |
+
$permalink = get_permalink($landing_page_id);
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
332 |
Â
|
333 |
+
return add_query_arg(array('lp-variation-id' => $variation_id), $permalink);
|
334 |
+
}
|
Â
|
|
335 |
Â
|
Â
|
|
336 |
Â
|
337 |
+
/**
|
338 |
+
* Gets the call to action variation notes
|
339 |
+
*
|
340 |
+
* @param INT $landing_page_id id of call to action
|
341 |
+
* @param INT $variation_id variation id of call to action variation, will attempt to autodetect if left as null
|
342 |
+
*
|
343 |
+
* @return STRING $notes variation notes.
|
344 |
+
*/
|
345 |
+
public static function get_variation_notes($landing_page_id, $variation_id = null) {
|
346 |
+
if ($variation_id === null) {
|
347 |
+
$variation_id = Landing_Pages_Variations::get_current_variation_id();
|
348 |
Â
}
|
349 |
Â
|
350 |
+
$variation_notes = get_post_meta($landing_page_id, 'lp-variation-notes-' . $variation_id, true);
|
351 |
Â
|
352 |
+
return $variation_notes;
|
353 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
354 |
Â
|
355 |
+
/**
|
356 |
+
* Gets the call to action variation custom css
|
357 |
+
*
|
358 |
+
* @param INT $landing_page_id id of call to action
|
359 |
+
* @param INT $variation_id variation id of call to action variation, will attempt to autodetect if left as null
|
360 |
+
*
|
361 |
+
* @return STRING $custom_css.
|
362 |
+
*/
|
363 |
+
public static function get_custom_css($landing_page_id, $variation_id = null) {
|
364 |
Â
|
365 |
+
if ($variation_id === null) {
|
366 |
+
$variation_id = Landing_Pages_Variations::get_current_variation_id();
|
367 |
Â
}
|
368 |
Â
|
369 |
+
return Landing_Pages_Variations::get_setting_value('lp-custom-css', $landing_page_id, $variation_id, '');
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
370 |
Â
|
371 |
+
}
|
Â
|
|
Â
|
|
372 |
Â
|
373 |
+
/**
|
374 |
+
* Gets the call to action variation custom js
|
375 |
+
*
|
376 |
+
* @param INT $landing_page_id id of call to action
|
377 |
+
* @param INT $variation_id variation id of call to action variation, will attempt to autodetect if left as null
|
378 |
+
*
|
379 |
+
* @return STRING $custom_js.
|
380 |
+
*/
|
381 |
+
public static function get_custom_js($landing_page_id, $variation_id = null) {
|
382 |
Â
|
383 |
+
if ($variation_id === null) {
|
384 |
+
$variation_id = Landing_Pages_Variations::get_current_variation_id();
|
385 |
Â
}
|
386 |
Â
|
387 |
+
return Landing_Pages_Variations::get_setting_value('lp-custom-js', $landing_page_id, $variation_id, '');
|
388 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
389 |
Â
|
390 |
+
/*
|
391 |
+
* Gets the current variation id
|
392 |
+
*
|
393 |
+
* @returns INT of variation id
|
394 |
+
*/
|
395 |
+
public static function get_current_variation_id() {
|
396 |
+
global $post, $current_variation_id;
|
397 |
Â
|
398 |
+
if (isset($_SESSION['lp_ab_test_open_variation']) && isset($_GET['ab-action']) && is_admin()) {
|
399 |
+
return $_SESSION['lp_ab_test_open_variation'];
|
400 |
Â
}
|
401 |
Â
|
402 |
+
/* check to see if this has already been set during the instance */
|
403 |
+
if (is_numeric($current_variation_id)) {
|
404 |
+
return $current_variation_id;
|
405 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
406 |
Â
|
407 |
+
if (isset($_REQUEST['lp-variation-id'])) {
|
408 |
+
$_SESSION['lp_ab_test_open_variation'] = intval($_REQUEST['lp-variation-id']);
|
409 |
+
$current_variation_id = intval($_REQUEST['lp-variation-id']);
|
410 |
+
}
|
411 |
Â
|
412 |
+
if (isset($_GET['message']) && $_GET['message'] == 1 && isset($_SESSION['lp_ab_test_open_variation'])) {
|
413 |
+
$current_variation_id = $_SESSION['lp_ab_test_open_variation'];
|
414 |
+
}
|
415 |
Â
|
416 |
+
if (isset($_GET['ab-action']) && $_GET['ab-action'] == 'delete-variation') {
|
417 |
+
$current_variation_id = 0;
|
418 |
+
$_SESSION['lp_ab_test_open_variation'] = 0;
|
419 |
+
}
|
420 |
Â
|
421 |
+
if (isset($_GET['new_meta_key'])) {
|
422 |
+
$current_variation_id = $_GET['new_meta_key'];
|
423 |
+
}
|
424 |
Â
|
425 |
+
if (!isset($current_variation_id)) {
|
426 |
+
if (!isset($post) && isset($_GET['post'])) {
|
427 |
+
$post_id = $_GET['post'];
|
428 |
+
} else if (isset($post)) {
|
429 |
+
$post_id = $post->ID;
|
430 |
+
} else {
|
431 |
+
$post_id = 0;
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
432 |
Â
}
|
433 |
Â
|
434 |
+
$variations = self::get_variations($post_id);
|
435 |
+
$id = array_values($variations);
|
436 |
+
$current_variation_id = array_shift($id);
|
437 |
Â
}
|
438 |
Â
|
439 |
+
$GLOBALS['current_variation_id'] = $current_variation_id;
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
440 |
Â
|
441 |
+
return $current_variation_id;
|
442 |
+
}
|
Â
|
|
Â
|
|
443 |
Â
|
444 |
+
/*
|
445 |
+
* Looks up the variation id we should use for prepopulating settings on cloned variations and new variations
|
446 |
+
*
|
447 |
+
* @returns INT of variation id
|
448 |
+
*/
|
449 |
+
public static function get_new_variation_reference_id($landing_page_id, $variation_id = null) {
|
450 |
+
global $post;
|
451 |
Â
|
452 |
+
/* if no variation set look for variation */
|
453 |
+
if (!isset($variation_id)) {
|
454 |
+
$variation_id = Landing_Pages_Variations::get_current_variation_id();
|
455 |
+
}
|
456 |
Â
|
457 |
+
/* listen for new variation */
|
458 |
+
if (isset($_REQUEST['new-variation']) && !isset($_REQUEST['clone'])) {
|
459 |
+
$variations = Landing_Pages_Variations::get_variations($landing_page_id);
|
460 |
+
$variation_id = key($variations);
|
461 |
Â
}
|
462 |
Â
|
463 |
+
/* listen for clone variation */
|
464 |
+
if (isset($_REQUEST['new-variation']) && isset($_REQUEST['clone'])) {
|
465 |
+
$variation_id = intval($_REQUEST['clone']);
|
466 |
+
}
|
Â
|
|
Â
|
|
467 |
Â
|
468 |
+
return $variation_id;
|
469 |
+
}
|
470 |
Â
|
471 |
+
/*
|
472 |
+
* Gets the next available variation id
|
473 |
+
*
|
474 |
+
* @returns INT of variation id
|
475 |
+
*/
|
476 |
+
public static function get_next_available_variation_id($landing_page_id) {
|
477 |
Â
|
478 |
+
$variations = Landing_Pages_Variations::get_variations($landing_page_id);
|
479 |
+
$array_variations = $variations;
|
480 |
Â
|
481 |
+
end($array_variations);
|
Â
|
|
482 |
Â
|
483 |
+
$last_variation_id = key($array_variations);
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
484 |
Â
|
485 |
+
return $last_variation_id + 1;
|
486 |
+
}
|
Â
|
|
487 |
Â
|
488 |
+
/*
|
489 |
+
* Gets string id of template given email id
|
490 |
+
*
|
491 |
+
* @param INT $landing_page_id of call to action
|
492 |
+
* @param INT $variation_id of variation id
|
493 |
+
*
|
494 |
+
* @returns STRING id of selected template
|
495 |
+
*/
|
496 |
+
public static function get_current_template($landing_page_id, $variation_id = null) {
|
497 |
Â
|
498 |
+
if (!is_numeric($variation_id)) {
|
499 |
+
$variation_id = Landing_Pages_Variations::get_current_variation_id();
|
500 |
Â
}
|
501 |
Â
|
502 |
+
return Landing_Pages_Variations::get_setting_value('lp-selected-template', $landing_page_id, $variation_id, 'default');
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
503 |
Â
|
504 |
+
}
|
505 |
+
|
506 |
+
/**
|
507 |
+
* Get Screenshot URL for Call to Action preview. If local environment show template thumbnail.
|
508 |
+
*
|
509 |
+
* @param INT $landing_page_id id if of call to action
|
510 |
+
* @param INT $variation_id id of variation belonging to call to action
|
511 |
+
*
|
512 |
+
* @return STRING url of preview
|
513 |
+
*/
|
514 |
+
public static function get_screenshot_url($landing_page_id, $variation_id = null) {
|
515 |
Â
|
516 |
+
if ($variation_id === null) {
|
517 |
+
$variation_id = Landing_Pages_Variations::get_current_variation_id();
|
518 |
+
}
|
519 |
Â
|
520 |
+
$template = Landing_Pages_Variations::get_current_template($landing_page_id, $variation_id);
|
521 |
Â
|
522 |
+
if (in_array($_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1'))) {
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
523 |
Â
|
524 |
+
if (file_exists(INBOUND_EMAIL_UPLOADS_URLPATH . 'templates/' . $template . '/thumbnail.png')) {
|
525 |
+
$screenshot = INBOUND_EMAIL_UPLOADS_URLPATH . 'templates/' . $template . '/thumbnail.png';
|
526 |
Â
} else {
|
527 |
+
$screenshot = INBOUND_EMAIL_URLPATH . 'templates/' . $template . '/thumbnail.png';
|
528 |
Â
}
|
529 |
Â
|
530 |
+
} else {
|
531 |
+
$screenshot = 'http://s.wordpress.com/mshots/v1/' . urlencode(esc_url($permalink)) . '?w=140';
|
532 |
Â
}
|
533 |
Â
|
534 |
+
return $screenshot;
|
535 |
+
}
|
536 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
537 |
Â
|
538 |
+
/**
|
539 |
+
* Returns impression for given cta and variation id
|
540 |
+
*
|
541 |
+
* @param INT $landing_page_id id of call to action
|
542 |
+
* @param INT $variation_id id of variation belonging to call to action
|
543 |
+
*
|
544 |
+
* @return INT impression count
|
545 |
+
*/
|
546 |
+
public static function get_impressions($landing_page_id, $variation_id) {
|
547 |
Â
|
548 |
+
if (!is_numeric($variation_id)) {
|
549 |
+
$variation_id = Landing_Pages_Variations::get_current_variation_id();
|
Â
|
|
Â
|
|
550 |
Â
}
|
551 |
Â
|
552 |
+
$impressions = get_post_meta($landing_page_id, 'lp-ab-variation-impressions-' . $variation_id, true);
|
553 |
+
$impressions = (is_numeric($impressions)) ? $impressions : 0;
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
554 |
Â
|
555 |
+
return $impressions;
|
556 |
+
}
|
Â
|
|
557 |
Â
|
558 |
+
/**
|
559 |
+
* Returns impression for given cta and variation id
|
560 |
+
*
|
561 |
+
* @param INT $landing_page_id id of call to action
|
562 |
+
* @param INT $variation_id id of variation belonging to call to action
|
563 |
+
*
|
564 |
+
* @return INT conversion count
|
565 |
+
*/
|
566 |
+
public static function get_conversions($landing_page_id, $variation_id) {
|
567 |
Â
|
568 |
+
if (!is_numeric($variation_id)) {
|
569 |
+
$variation_id = Landing_Pages_Variations::get_current_variation_id();
|
570 |
Â
}
|
571 |
Â
|
572 |
+
$conversions = get_post_meta($landing_page_id, 'lp-ab-variation-conversions-' . $variation_id, true);
|
573 |
+
$conversions = (is_numeric($conversions)) ? $conversions : 0;
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
574 |
Â
|
575 |
+
return $conversions;
|
576 |
+
}
|
577 |
Â
|
578 |
+
/**
|
579 |
+
* Returns conversion rate for given cta and variation id
|
580 |
+
*
|
581 |
+
* @param INT $landing_page_id id of call to action
|
582 |
+
* @param INT $variation_id id of variation belonging to call to action
|
583 |
+
*
|
584 |
+
* @return INT conversion rate
|
585 |
+
*/
|
586 |
+
public static function get_conversion_rate($landing_page_id, $variation_id) {
|
587 |
+
|
588 |
+
$impressions = Landing_Pages_Variations::get_impressions($landing_page_id, $variation_id);
|
589 |
+
$conversions = Landing_Pages_Variations::get_conversions($landing_page_id, $variation_id);
|
590 |
+
|
591 |
+
if ($impressions > 0) {
|
592 |
+
$conversion_rate = $conversions / $impressions;
|
593 |
+
$conversion_rate_number = $conversion_rate * 100;
|
594 |
+
$conversion_rate_number = round($conversion_rate_number, 2);
|
595 |
+
$conversion_rate = $conversion_rate_number;
|
596 |
+
} else {
|
597 |
+
$conversion_rate = 0;
|
598 |
+
}
|
599 |
+
|
600 |
+
return $conversion_rate;
|
601 |
+
}
|
602 |
Â
|
603 |
+
/**
|
604 |
+
* @param $landing_page_id
|
605 |
+
* @param null $variation_id
|
606 |
+
*/
|
607 |
+
public static function get_conversion_area($landing_page_id, $variation_id = null) {
|
608 |
Â
|
609 |
+
return Landing_Pages_Variations::get_setting_value('lp-conversion-area', $landing_page_id, $variation_id);
|
610 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
611 |
Â
|
612 |
+
/**
|
613 |
+
* Returns conversion area placement
|
614 |
+
* @param $landing_page_id
|
615 |
+
* @param null $variation_id
|
616 |
+
*/
|
617 |
+
public static function get_conversion_area_placement($landing_page_id, $variation_id = null) {
|
618 |
+
$template = Landing_Pages_Variations::get_current_template($landing_page_id);
|
619 |
+
return Landing_Pages_Variations::get_setting_value($template . '-conversion-area-placement', $landing_page_id, $variation_id);
|
620 |
+
}
|
621 |
Â
|
622 |
+
/**
|
623 |
+
* @param $landing_page_id
|
624 |
+
* @param null $variation_id
|
625 |
+
*/
|
626 |
+
public static function get_post_content($landing_page_id, $variation_id = null) {
|
627 |
+
if (!is_numeric($variation_id)) {
|
628 |
+
$variation_id = Landing_Pages_Variations::get_current_variation_id();
|
Â
|
|
629 |
Â
}
|
630 |
Â
|
631 |
+
return Landing_Pages_Variations::get_setting_value('content', $landing_page_id, $variation_id);
|
632 |
+
}
|
633 |
+
|
634 |
+
/**
|
635 |
+
* Get main headline
|
636 |
+
*/
|
637 |
+
public static function get_main_headline($landing_page_id, $variation_id = null) {
|
Â
|
|
638 |
Â
|
639 |
+
if (!is_numeric($variation_id)) {
|
640 |
+
$variation_id = Landing_Pages_Variations::get_current_variation_id();
|
641 |
Â
}
|
642 |
Â
|
643 |
+
return Landing_Pages_Variations::get_setting_value('lp-main-headline', $landing_page_id, $variation_id, '');
|
644 |
+
}
|
Â
|
|
Â
|
|
645 |
Â
|
646 |
+
/**
|
647 |
+
* Gets thumbnail for selected template
|
648 |
+
*/
|
649 |
+
public static function get_template_thumbnail($template) {
|
650 |
Â
|
651 |
+
if (file_exists(LANDINGPAGES_UPLOADS_PATH . $template . '/thumbnail.png')) {
|
652 |
+
return LANDINGPAGES_UPLOADS_URLPATH . $template . '/thumbnail.png';
|
653 |
+
} else {
|
654 |
+
return LANDINGPAGES_URLPATH . 'templates/' . $template . '/thumbnail.png';
|
655 |
Â
}
|
656 |
+
}
|
657 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
658 |
Â
|
659 |
+
/**
|
660 |
+
* Gets stored setting value
|
661 |
+
* @param $key
|
662 |
+
* @param $landing_page_id
|
663 |
+
* @param $variation_id
|
664 |
+
* @param string $default
|
665 |
+
* @return string
|
666 |
+
*/
|
667 |
+
public static function get_setting_value($key, $landing_page_id, $variation_id = null, $default = '') {
|
668 |
Â
|
669 |
+
/* if no variation set look for variation */
|
670 |
+
if (!isset($variation_id)) {
|
671 |
+
$variation_id = Landing_Pages_Variations::get_current_variation_id();
|
672 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
673 |
Â
|
674 |
+
/* listen for new variation */
|
675 |
+
if (isset($_REQUEST['new-variation']) && !isset($_REQUEST['clone'])) {
|
676 |
+
$variations = Landing_Pages_Variations::get_variations($landing_page_id);
|
677 |
+
$variation_id = key($variations);
|
678 |
+
}
|
679 |
Â
|
680 |
+
/* listen for clone variation */
|
681 |
+
if (isset($_REQUEST['new-variation']) && isset($_REQUEST['clone'])) {
|
682 |
+
$variation_id = intval($_REQUEST['clone']);
|
683 |
+
}
|
Â
|
|
684 |
Â
|
685 |
+
if ($variation_id > 0) {
|
686 |
+
if (metadata_exists('post', $landing_page_id, $key . '-' . $variation_id)) {
|
687 |
+
return get_post_meta($landing_page_id, $key . '-' . $variation_id, true);
|
688 |
+
} else {
|
689 |
+
return $default;
|
690 |
Â
}
|
691 |
+
} else {
|
692 |
Â
|
693 |
+
if (metadata_exists('post', $landing_page_id, $key)) {
|
694 |
+
return get_post_meta($landing_page_id, $key, true);
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
695 |
Â
} else {
|
696 |
+
return $default;
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
697 |
Â
}
|
Â
|
|
698 |
Â
}
|
699 |
Â
|
700 |
+
}
|
701 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
702 |
Â
|
703 |
+
/**
|
704 |
+
* Increments conversion count for given landing page id and variation id
|
705 |
+
*
|
706 |
+
* @param INT $landing_page_id id of landing page
|
707 |
+
* @param INT $variation_id id of variation belonging to call to action
|
708 |
+
*
|
709 |
+
*/
|
710 |
+
public static function record_conversion($landing_page_id, $variation_id) {
|
711 |
Â
|
712 |
+
$conversions = self::get_conversions($landing_page_id, $variation_id);
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
713 |
Â
|
714 |
+
if (!is_numeric($conversions)) {
|
715 |
+
$conversions = 1;
|
716 |
+
} else {
|
717 |
+
$conversions++;
|
718 |
Â
}
|
719 |
Â
|
720 |
+
self::set_conversions_count($landing_page_id, $variation_id, $conversions);
|
721 |
+
}
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
722 |
Â
|
723 |
+
/**
|
724 |
+
* Appends current variation id onto a URL
|
725 |
+
*
|
726 |
+
* @param link STRING URL that param will be appended onto
|
727 |
+
*
|
728 |
+
*
|
729 |
+
* @return STRING modified URL.
|
730 |
+
*/
|
731 |
+
public static function append_variation_id_to_url($link) {
|
732 |
+
global $post;
|
733 |
+
|
734 |
+
if (!isset($post) || $post->post_type != 'landing-pages') {
|
735 |
+
return $link;
|
736 |
+
}
|
737 |
Â
|
738 |
+
$current_variation_id = Landing_Pages_Variations::get_current_variation_id();
|
739 |
Â
|
740 |
Â
|
741 |
+
$link = add_query_arg(array('inbvid' => $current_variation_id), $link);
|
742 |
Â
|
743 |
+
return $link;
|
744 |
+
}
|
745 |
Â
|
746 |
+
/**
|
747 |
+
* Discovers which alphabetic letter should be associated with a given cta's variation id.
|
748 |
+
*
|
749 |
+
* @param INT $landing_page_id id of call to action
|
750 |
+
* @param INT $variation_id id of variation belonging to call to action
|
751 |
+
*
|
752 |
+
* @return STRING alphebit letter.
|
753 |
+
*/
|
754 |
+
public static function vid_to_letter($landing_page_id, $variation_id) {
|
755 |
+
$variations = Landing_Pages_Variations::get_variations($landing_page_id);
|
756 |
Â
|
757 |
+
$i = 0;
|
758 |
+
foreach ($variations as $key => $variation) {
|
759 |
+
if ($variation_id == $key) {
|
760 |
+
break;
|
Â
|
|
Â
|
|
761 |
Â
}
|
762 |
+
$i++;
|
763 |
+
}
|
764 |
Â
|
765 |
+
$alphabet = array(__('A', 'landing-pages'), __('B', 'landing-pages'), __('C', 'landing-pages'), __('D', 'landing-pages'), __('E', 'landing-pages'), __('F', 'landing-pages'), __('G', 'landing-pages'), __('H', 'landing-pages'), __('I', 'landing-pages'), __('J', 'landing-pages'), __('K', 'landing-pages'), __('L', 'landing-pages'), __('M', 'landing-pages'), __('N', 'landing-pages'), __('O', 'landing-pages'), __('P', 'landing-pages'), __('Q', 'landing-pages'), __('R', 'landing-pages'), __('S', 'landing-pages'), __('T', 'landing-pages'), __('U', 'landing-pages'), __('V', 'landing-pages'), __('W', 'landing-pages'), __('X', 'landing-pages'), __('Y', 'landing-pages'), __('Z', 'landing-pages'));
|
766 |
Â
|
767 |
+
if (isset($alphabet[$i])) {
|
768 |
+
return $alphabet[$i];
|
Â
|
|
769 |
Â
}
|
770 |
+
}
|
771 |
Â
|
772 |
Â
|
773 |
+
/**
|
774 |
+
* Adds Ajax for Clear Stats button
|
775 |
+
* clear stats for all variations
|
776 |
+
*/
|
777 |
+
public static function ajax_clear_stats() {
|
778 |
+
global $wpdb;
|
Â
|
|
Â
|
|
779 |
Â
|
780 |
+
$landing_page_id = intval($_POST['page_id']);
|
781 |
Â
|
782 |
+
$variations = self::get_variations($landing_page_id);
|
Â
|
|
Â
|
|
Â
|
|
783 |
Â
|
784 |
+
foreach ($variations as $vid) {
|
785 |
+
update_post_meta($landing_page_id, 'lp-ab-variation-impressions-' . $vid, 0, false);
|
786 |
+
update_post_meta($landing_page_id, 'lp-ab-variation-conversions-' . $vid, 0, false);
|
787 |
Â
}
|
788 |
Â
|
789 |
+
header('HTTP/1.1 200 OK');
|
790 |
+
}
|
791 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
792 |
Â
|
793 |
+
/**
|
794 |
+
* Adds Ajax for Clear Stats button
|
795 |
+
* clear stats for single variations
|
796 |
+
*/
|
797 |
+
public static function ajax_clear_stats_single() {
|
798 |
+
global $wpdb;
|
799 |
Â
|
800 |
+
$landing_page_id = intval($_POST['page_id']);
|
801 |
+
$vid = intval($_POST['variation']);
|
802 |
Â
|
803 |
+
self::set_impressions_count($landing_page_id, $vid, 0);
|
804 |
+
self::set_conversions_count($landing_page_id, $vid, 0);
|
805 |
Â
|
806 |
+
header('HTTP/1.1 200 OK');
|
807 |
Â
}
|
808 |
Â
|
809 |
+
}
|
810 |
Â
|
811 |
+
new Landing_Pages_Variations();
|
classes/class.welcome.php
CHANGED
@@ -2,12 +2,8 @@
|
|
2 |
Â
/**
|
3 |
Â
* Weclome Page Class
|
4 |
Â
*
|
5 |
-
* @package
|
6 |
-
* @subpackage
|
7 |
-
* @copyright Copyright (c) 2013, Pippin Williamson
|
8 |
-
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
9 |
-
* @since 1.4
|
10 |
-
* Forked from pippin's WordPress Landing Pages! https://easydigitaldownloads.com/
|
11 |
Â
*/
|
12 |
Â
|
13 |
Â
/* Exit if accessed directly */
|
2 |
Â
/**
|
3 |
Â
* Weclome Page Class
|
4 |
Â
*
|
5 |
+
* @package LandingPages
|
6 |
+
* @subpackage WelcomeScreen
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
7 |
Â
*/
|
8 |
Â
|
9 |
Â
/* Exit if accessed directly */
|
classes/class.widgets.php
CHANGED
@@ -1,5 +1,13 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
3 |
Â
add_action('widgets_init', 'lp_load_widgets');
|
4 |
Â
|
5 |
Â
function lp_load_widgets() {
|
1 |
Â
<?php
|
2 |
Â
|
3 |
+
/**
|
4 |
+
* Class adds the 'conversion area widget' designed to compliment landing pages set to use the default template.
|
5 |
+
*
|
6 |
+
* @package LandingPages
|
7 |
+
* @subpackage Widgets
|
8 |
+
*/
|
9 |
+
|
10 |
+
|
11 |
Â
add_action('widgets_init', 'lp_load_widgets');
|
12 |
Â
|
13 |
Â
function lp_load_widgets() {
|
classes/class.wp-list-table.templates.php
CHANGED
@@ -1,5 +1,12 @@
|
|
1 |
Â
<?php
|
2 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
3 |
Â
if (!class_exists('WP_List_Table')) {
|
4 |
Â
require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
|
5 |
Â
}
|
1 |
Â
<?php
|
2 |
Â
|
3 |
+
/**
|
4 |
+
* Class displays activated landing page templates
|
5 |
+
*
|
6 |
+
* @package LandingPages
|
7 |
+
* @subpackage Templates
|
8 |
+
*/
|
9 |
+
|
10 |
Â
if (!class_exists('WP_List_Table')) {
|
11 |
Â
require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
|
12 |
Â
}
|
landing-pages.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Â
Plugin Name: Landing Pages
|
4 |
Â
Plugin URI: http://www.inboundnow.com/landing-pages/
|
5 |
Â
Description: Landing page template framework with variant testing and lead capturing through cooperation with Inbound Now's Leads plugin. This is the stand alone version served through WordPress.org.
|
6 |
-
Version: 2.5.
|
7 |
Â
Author: Inbound Now
|
8 |
Â
Author URI: http://www.inboundnow.com/
|
9 |
Â
|
@@ -11,6 +11,10 @@ Author URI: http://www.inboundnow.com/
|
|
11 |
Â
|
12 |
Â
if (!class_exists('Inbound_Landing_Pages_Plugin')) {
|
13 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
14 |
Â
final class Inbound_Landing_Pages_Plugin {
|
15 |
Â
|
16 |
Â
/**
|
@@ -37,7 +41,7 @@ if (!class_exists('Inbound_Landing_Pages_Plugin')) {
|
|
37 |
Â
*/
|
38 |
Â
private static function load_constants() {
|
39 |
Â
|
40 |
-
define('LANDINGPAGES_CURRENT_VERSION', '2.5.
|
41 |
Â
define('LANDINGPAGES_URLPATH', plugins_url( '/' , __FILE__ ) );
|
42 |
Â
define('LANDINGPAGES_PATH', WP_PLUGIN_DIR.'/'.plugin_basename( dirname(__FILE__) ).'/' );
|
43 |
Â
define('LANDINGPAGES_PLUGIN_SLUG', 'landing-pages' );
|
@@ -93,7 +97,6 @@ if (!class_exists('Inbound_Landing_Pages_Plugin')) {
|
|
93 |
Â
include_once( LANDINGPAGES_PATH . 'classes/class.acf-integration.php');
|
94 |
Â
include_once( LANDINGPAGES_PATH . 'classes/class.postmeta.php');
|
95 |
Â
include_once( LANDINGPAGES_PATH . 'classes/class.statistics.php');
|
96 |
-
include_once( LANDINGPAGES_PATH . 'classes/class.click-tracking.php');
|
97 |
Â
include_once( LANDINGPAGES_PATH . 'classes/class.post-type.landing-page.php');
|
98 |
Â
include_once( LANDINGPAGES_PATH . 'modules/module.utils.php');
|
99 |
Â
include_once( LANDINGPAGES_PATH . 'classes/class.sidebars.php');
|
3 |
Â
Plugin Name: Landing Pages
|
4 |
Â
Plugin URI: http://www.inboundnow.com/landing-pages/
|
5 |
Â
Description: Landing page template framework with variant testing and lead capturing through cooperation with Inbound Now's Leads plugin. This is the stand alone version served through WordPress.org.
|
6 |
+
Version: 2.5.8
|
7 |
Â
Author: Inbound Now
|
8 |
Â
Author URI: http://www.inboundnow.com/
|
9 |
Â
|
11 |
Â
|
12 |
Â
if (!class_exists('Inbound_Landing_Pages_Plugin')) {
|
13 |
Â
|
14 |
+
/**
|
15 |
+
* Class Inbound_Landing_Pages_Plugin loads Landing Pages plugin
|
16 |
+
* @package Leads
|
17 |
+
*/
|
18 |
Â
final class Inbound_Landing_Pages_Plugin {
|
19 |
Â
|
20 |
Â
/**
|
41 |
Â
*/
|
42 |
Â
private static function load_constants() {
|
43 |
Â
|
44 |
+
define('LANDINGPAGES_CURRENT_VERSION', '2.5.8' );
|
45 |
Â
define('LANDINGPAGES_URLPATH', plugins_url( '/' , __FILE__ ) );
|
46 |
Â
define('LANDINGPAGES_PATH', WP_PLUGIN_DIR.'/'.plugin_basename( dirname(__FILE__) ).'/' );
|
47 |
Â
define('LANDINGPAGES_PLUGIN_SLUG', 'landing-pages' );
|
97 |
Â
include_once( LANDINGPAGES_PATH . 'classes/class.acf-integration.php');
|
98 |
Â
include_once( LANDINGPAGES_PATH . 'classes/class.postmeta.php');
|
99 |
Â
include_once( LANDINGPAGES_PATH . 'classes/class.statistics.php');
|
Â
|
|
100 |
Â
include_once( LANDINGPAGES_PATH . 'classes/class.post-type.landing-page.php');
|
101 |
Â
include_once( LANDINGPAGES_PATH . 'modules/module.utils.php');
|
102 |
Â
include_once( LANDINGPAGES_PATH . 'classes/class.sidebars.php');
|
modules/module.redirect-ab-testing.php
CHANGED
@@ -15,6 +15,12 @@ if (file_exists('./../../../../wp-load.php')) {
|
|
15 |
Â
include_once('./../../../../../../../wp-load.php');
|
16 |
Â
}
|
17 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
18 |
Â
class LP_Variation_Rotation {
|
19 |
Â
|
20 |
Â
static $permalink_name;
|
@@ -205,4 +211,4 @@ class LP_Variation_Rotation {
|
|
205 |
Â
}
|
206 |
Â
}
|
207 |
Â
|
208 |
-
|
15 |
Â
include_once('./../../../../../../../wp-load.php');
|
16 |
Â
}
|
17 |
Â
|
18 |
+
/**
|
19 |
+
* Class LP_Variation_Rotation provides an external WP instance set of classes for controlling landing page rotation memory
|
20 |
+
* @package Landing Pages
|
21 |
+
* @subpackage Variations
|
22 |
+
*/
|
23 |
+
|
24 |
Â
class LP_Variation_Rotation {
|
25 |
Â
|
26 |
Â
static $permalink_name;
|
211 |
Â
}
|
212 |
Â
}
|
213 |
Â
|
214 |
+
new LP_Variation_Rotation;
|
modules/module.utils.php
CHANGED
@@ -37,6 +37,15 @@ if (!function_exists('inbound_qtrans_disable')) {
|
|
37 |
Â
* Add namespaces for legacy classes to try and prevent fatals
|
38 |
Â
*/
|
39 |
Â
if (!class_exists('LP_EXTENSION_UPDATER') ){
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
40 |
Â
class LP_EXTENSION_UPDATER { };
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
41 |
Â
class LP_EXTENSION_LICENSENING { };
|
42 |
Â
}
|
37 |
Â
* Add namespaces for legacy classes to try and prevent fatals
|
38 |
Â
*/
|
39 |
Â
if (!class_exists('LP_EXTENSION_UPDATER') ){
|
40 |
+
/**
|
41 |
+
* Class LP_EXTENSION_UPDATER depreciated class name
|
42 |
+
* @package xDepreciated
|
43 |
+
*/
|
44 |
Â
class LP_EXTENSION_UPDATER { };
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Class LP_EXTENSION_LICENSENING depreciated class name
|
48 |
+
* @package xDepreciated
|
49 |
+
*/
|
50 |
Â
class LP_EXTENSION_LICENSENING { };
|
51 |
Â
}
|
readme.txt
CHANGED
@@ -7,7 +7,7 @@ License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
|
7 |
Â
Tags: landing pages, inbound marketing, conversion pages, split testing, a b test, a b testing, a/b test, a/b testing, coming soon page, email list, landing page, list building, maintenance page, squeeze page, inbound now, landing-pages, splash pages, cpa, click tracking, goal tracking, analytics, free landing page templates
|
8 |
Â
Requires at least: 3.8
|
9 |
Â
Tested up to: 4.8
|
10 |
-
Stable Tag: 2.5.
|
11 |
Â
|
12 |
Â
|
13 |
Â
Create landing pages for your WordPress site. Monitor and improve conversion rates, run A/B split tests, customize your own templates and more.
|
@@ -85,6 +85,10 @@ We also offer a guide for using <a href="https://github.com/inboundnow/landing-p
|
|
85 |
Â
|
86 |
Â
== Changelog ==
|
87 |
Â
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
88 |
Â
= 2.5.7 =
|
89 |
Â
* Compatible with WordPress 4.8
|
90 |
Â
* Updating shared files
|
7 |
Â
Tags: landing pages, inbound marketing, conversion pages, split testing, a b test, a b testing, a/b test, a/b testing, coming soon page, email list, landing page, list building, maintenance page, squeeze page, inbound now, landing-pages, splash pages, cpa, click tracking, goal tracking, analytics, free landing page templates
|
8 |
Â
Requires at least: 3.8
|
9 |
Â
Tested up to: 4.8
|
10 |
+
Stable Tag: 2.5.8
|
11 |
Â
|
12 |
Â
|
13 |
Â
Create landing pages for your WordPress site. Monitor and improve conversion rates, run A/B split tests, customize your own templates and more.
|
85 |
Â
|
86 |
Â
== Changelog ==
|
87 |
Â
|
88 |
+
= 2.5.8 =
|
89 |
+
* Updating docblocks for APIGen
|
90 |
+
* [Restored] Impression tracking was failing in select theme environments.
|
91 |
+
|
92 |
Â
= 2.5.7 =
|
93 |
Â
* Compatible with WordPress 4.8
|
94 |
Â
* Updating shared files
|
shared/assets/js/admin/marketing-button.js
CHANGED
@@ -1,243 +1,243 @@
|
|
1 |
-
/**
|
2 |
-
* Marketing Button JS
|
3 |
-
*/
|
4 |
-
var MarketingButton = (function () {
|
5 |
-
|
6 |
-
var _privateMethod = function () {};
|
7 |
-
|
8 |
-
var inbound_buttons_loaded = false;
|
9 |
-
var Public = {
|
10 |
-
init: function () {
|
11 |
-
// add listeners to iframes
|
12 |
-
this.waitForEditorLoad();
|
13 |
-
this.attachHandlers();
|
14 |
-
},
|
15 |
-
attachHandlers: function(){
|
16 |
-
this.closePopupHandler();
|
17 |
-
this.triggerPopupHandler();
|
18 |
-
this.insertShortcodeHandler();
|
19 |
-
this.launchShortcodeWindow();
|
20 |
-
this.backButtonHandler();
|
21 |
-
},
|
22 |
-
triggerPopupHandler: function() {
|
23 |
-
var that = this;
|
24 |
-
jQuery("body").on('click', '.open-marketing-button-popup', function (e) {
|
25 |
-
e.preventDefault();
|
26 |
-
var id = jQuery(this).attr('data-editor');
|
27 |
-
jQuery('#iframe-target').attr('current-editor', id);
|
28 |
-
|
29 |
-
if(document.getElementById(id) && document.getElementById(id).parentNode.parentNode.parentNode.style.display !== "none") {
|
30 |
-
console.log('iframe display');
|
31 |
-
} else {
|
32 |
-
id = id.replace("_ifr", "");
|
33 |
-
jQuery('#iframe-target').attr('current-editor', id);
|
34 |
-
console.log('textarea display');
|
35 |
-
}
|
36 |
-
|
37 |
-
console.log('editor id', id);
|
38 |
-
/*var pos = that.getCursorPosition(iframeTarget);*/
|
39 |
-
|
40 |
-
/* Run popup here */
|
41 |
-
jQuery.magnificPopup.open({
|
42 |
-
items: {
|
43 |
-
src: '#inbound-marketing-popup', // can be a HTML string, jQuery object, or CSS selector
|
44 |
-
type: 'inline',
|
45 |
-
callbacks: {
|
46 |
-
open: function() {
|
47 |
-
jQuery('.inbound-short-list').show();
|
48 |
-
},
|
49 |
-
close: function() {
|
50 |
-
jQuery("#iframe-target").html('');
|
51 |
-
}
|
52 |
-
}
|
53 |
-
}
|
54 |
-
});
|
55 |
-
|
56 |
-
});
|
57 |
-
// on marketing button click, grab ID to insert to
|
58 |
-
},
|
59 |
-
waitForEditorLoad: function() {
|
60 |
-
var that = this;
|
61 |
-
jQuery(".acf_postbox .field_type-wysiwyg iframe")
|
62 |
-
.waitUntilExists(function(){
|
63 |
-
console.log('wait');
|
64 |
-
if(!inbound_buttons_loaded) {
|
65 |
-
// do stuff with editor
|
66 |
-
|
67 |
-
that.addButtonsToACFNormal();
|
68 |
-
|
69 |
-
inbound_buttons_loaded = true;
|
70 |
-
}
|
71 |
-
});
|
72 |
-
},
|
73 |
-
launchShortcodeWindow: function(){
|
74 |
-
jQuery(".launch-marketing-shortcode").on('click', function (e) {
|
75 |
-
var $this = jQuery(this);
|
76 |
-
var type = $this.attr('data-launch-sc');
|
77 |
-
var url = inbound_load.image_dir + 'popup.php?popup=' + type + '&width=' + 900 + "&path=" + encodeURIComponent(inbound_load.image_dir);
|
78 |
-
//$('shortcode-frame').attr('href', url);
|
79 |
-
// hide list
|
80 |
-
jQuery('.inbound-short-list').hide();
|
81 |
-
var iframe = "<iframe src="+url+">";
|
82 |
-
//$('#iframe-target').html('');
|
83 |
-
//$('#iframe-target').html(iframe);
|
84 |
-
jQuery.ajax({
|
85 |
-
url: url,
|
86 |
-
success:function(data){
|
87 |
-
jQuery('#iframe-target').html(data);
|
88 |
-
}
|
89 |
-
});
|
90 |
-
});
|
91 |
-
},
|
92 |
-
/* Add buttons to normal ACF */
|
93 |
-
addButtonsToACFNormal: function(){
|
94 |
-
console.log('add buttons');
|
95 |
-
jQuery('.acf_postbox .field_type-wysiwyg').each(function(){
|
96 |
-
var $this = jQuery(this);
|
97 |
-
var label = $this.find('label');
|
98 |
-
var iframeID = $this.find('iframe').attr('id');
|
99 |
-
//console.log('iframe', iframeID);
|
100 |
-
var marButton = '<a data-editor="'+iframeID+'" href="#inbound-marketing-popup" class="button inbound-marketing-button open-marketing-button-popup" title="Marketing"><span class="wp-media-buttons-icon" id="inboundnow-media-button"></span>Marketing</a>';
|
101 |
-
jQuery(marButton).appendTo(label);
|
102 |
-
});
|
103 |
-
|
104 |
-
},
|
105 |
-
|
106 |
-
insertShortcodeHandler: function() {
|
107 |
-
var that = this;
|
108 |
-
jQuery("body").on('click', '#marketing-insert-shortcode', function () {
|
109 |
-
console.log('Insert the shortcode dudddee');
|
110 |
-
// insert into content
|
111 |
-
var shortcode = jQuery('#_inbound_shortcodes_newoutput').html();
|
112 |
-
var id = jQuery('#iframe-target').attr('current-editor');
|
113 |
-
|
114 |
-
if(id.indexOf("_ifr") > -1) {
|
115 |
-
var iframeTarget = document.getElementById(id).contentWindow.document.body;
|
116 |
-
var type = "iframe";
|
117 |
-
} else {
|
118 |
-
var iframeTarget = jQuery("#" + id);
|
119 |
-
var type = "textarea";
|
120 |
-
}
|
121 |
-
|
122 |
-
setTimeout(function() {
|
123 |
-
|
124 |
-
if(type === "iframe") {
|
125 |
-
that.insertContent(shortcode, iframeTarget);
|
126 |
-
} else {
|
127 |
-
that.insertTextAreaContent(shortcode, iframeTarget);
|
128 |
-
}
|
129 |
-
|
130 |
-
jQuery.magnificPopup.close();
|
131 |
-
|
132 |
-
}, 300);
|
133 |
-
});
|
134 |
-
},
|
135 |
-
closePopupHandler: function() {
|
136 |
-
var that = this;
|
137 |
-
jQuery("body").on('click', '#cancel_marketing_button', function () {
|
138 |
-
jQuery.magnificPopup.close();
|
139 |
-
jQuery("#iframe-target").html('');
|
140 |
-
jQuery('.inbound-short-list').show();
|
141 |
-
});
|
142 |
-
},
|
143 |
-
insertTextAreaContent: function(text, selector) {
|
144 |
-
var cursorPos = selector.prop('selectionStart');
|
145 |
-
var v = selector.val();
|
146 |
-
var textBefore = v.substring(0, cursorPos );
|
147 |
-
var textAfter = v.substring( cursorPos, v.length );
|
148 |
-
selector.val( textBefore + text + textAfter );
|
149 |
-
},
|
150 |
-
insertContent: function(text, iframe) {
|
151 |
-
var sel, range, html;
|
152 |
-
var doc = iframe.ownerDocument || iframe.document;
|
153 |
-
var win = doc.defaultView || doc.parentWindow;
|
154 |
-
sel = win.getSelection();
|
155 |
-
if (sel && sel.rangeCount > 0) {
|
156 |
-
console.log('Content inserted!');
|
157 |
-
range = sel.getRangeAt(0);
|
158 |
-
range.deleteContents();
|
159 |
-
var textNode = document.createTextNode(text);
|
160 |
-
range.insertNode(textNode);
|
161 |
-
range.setStartAfter(textNode);
|
162 |
-
sel.removeAllRanges();
|
163 |
-
sel.addRange(range);
|
164 |
-
} else {
|
165 |
-
console.log('havent clicked in box yet');
|
166 |
-
/* focus for the user to insert the content */
|
167 |
-
iframe.focus();
|
168 |
-
console.log('run this again');
|
169 |
-
this.insertContent(text, iframe);
|
170 |
-
}
|
171 |
-
},
|
172 |
-
backButtonHandler: function() {
|
173 |
-
jQuery("body").on('click', '.marketing-back-button', function () {
|
174 |
-
// toggle display
|
175 |
-
jQuery("#iframe-target").html('');
|
176 |
-
jQuery('.select2-drop').remove();
|
177 |
-
jQuery('.inbound-short-list').show();
|
178 |
-
});
|
179 |
-
},
|
180 |
-
getCursorPosition: function (iframe) {
|
181 |
-
var caretOffset = 0,
|
182 |
-
doc = iframe.ownerDocument || iframe.document,
|
183 |
-
win = doc.defaultView || doc.parentWindow,
|
184 |
-
sel;
|
185 |
-
|
186 |
-
if (typeof win.getSelection != "undefined") {
|
187 |
-
sel = win.getSelection();
|
188 |
-
if (sel.rangeCount > 0) {
|
189 |
-
var range = win.getSelection().getRangeAt(0);
|
190 |
-
var preCaretRange = range.cloneRange();
|
191 |
-
preCaretRange.selectNodeContents(iframe);
|
192 |
-
preCaretRange.setEnd(range.endContainer, range.endOffset);
|
193 |
-
caretOffset = preCaretRange.toString().length;
|
194 |
-
}
|
195 |
-
} else if ( (sel = doc.selection) && sel.type != "Control") {
|
196 |
-
var textRange = sel.createRange();
|
197 |
-
var preCaretTextRange = doc.body.createTextRange();
|
198 |
-
preCaretTextRange.moveToElementText(iframe);
|
199 |
-
preCaretTextRange.setEndPoint("EndToEnd", textRange);
|
200 |
-
caretOffset = preCaretTextRange.text.length;
|
201 |
-
}
|
202 |
-
|
203 |
-
return caretOffset;
|
204 |
-
}
|
205 |
-
};
|
206 |
-
|
207 |
-
return Public;
|
208 |
-
|
209 |
-
})();
|
210 |
-
|
211 |
-
jQuery(document).ready(function($) {
|
212 |
-
MarketingButton.init();
|
213 |
-
|
214 |
-
});
|
215 |
-
|
216 |
-
(function ($) {
|
217 |
-
|
218 |
-
/**
|
219 |
-
* @function
|
220 |
-
* @property {object} jQuery plugin which runs handler function once specified element is inserted into the DOM
|
221 |
-
* @param {function} handler A function to execute at the time when the element is inserted
|
222 |
-
* @param {bool} shouldRunHandlerOnce Optional: if true, handler is unbound after its first invocation
|
223 |
-
* @example $(selector).waitUntilExists(function);
|
224 |
-
*/
|
225 |
-
|
226 |
-
$.fn.waitUntilExists = function (handler, shouldRunHandlerOnce, isChild) {
|
227 |
-
var found = 'found';
|
228 |
-
var $this = $(this.selector);
|
229 |
-
var $elements = $this.not(function () { return $(this).data(found); }).each(handler).data(found, true);
|
230 |
-
|
231 |
-
if (!isChild) {
|
232 |
-
(window.wait_until_exists = window.wait_until_exists || {})[this.selector] = window.setInterval(function () {
|
233 |
-
$this.waitUntilExists(handler, shouldRunHandlerOnce, true);
|
234 |
-
}, 500)
|
235 |
-
;
|
236 |
-
} else if (shouldRunHandlerOnce && $elements.length) {
|
237 |
-
window.clearInterval(window.wait_until_exists[this.selector]);
|
238 |
-
}
|
239 |
-
|
240 |
-
return $this;
|
241 |
-
}
|
242 |
-
|
243 |
-
}(jQuery));
|
1 |
+
/**
|
2 |
+
* Marketing Button JS
|
3 |
+
*/
|
4 |
+
var MarketingButton = (function () {
|
5 |
+
|
6 |
+
var _privateMethod = function () {};
|
7 |
+
|
8 |
+
var inbound_buttons_loaded = false;
|
9 |
+
var Public = {
|
10 |
+
init: function () {
|
11 |
+
// add listeners to iframes
|
12 |
+
this.waitForEditorLoad();
|
13 |
+
this.attachHandlers();
|
14 |
+
},
|
15 |
+
attachHandlers: function(){
|
16 |
+
this.closePopupHandler();
|
17 |
+
this.triggerPopupHandler();
|
18 |
+
this.insertShortcodeHandler();
|
19 |
+
this.launchShortcodeWindow();
|
20 |
+
this.backButtonHandler();
|
21 |
+
},
|
22 |
+
triggerPopupHandler: function() {
|
23 |
+
var that = this;
|
24 |
+
jQuery("body").on('click', '.open-marketing-button-popup', function (e) {
|
25 |
+
e.preventDefault();
|
26 |
+
var id = jQuery(this).attr('data-editor');
|
27 |
+
jQuery('#iframe-target').attr('current-editor', id);
|
28 |
+
|
29 |
+
if(document.getElementById(id) && document.getElementById(id).parentNode.parentNode.parentNode.style.display !== "none") {
|
30 |
+
console.log('iframe display');
|
31 |
+
} else {
|
32 |
+
id = id.replace("_ifr", "");
|
33 |
+
jQuery('#iframe-target').attr('current-editor', id);
|
34 |
+
console.log('textarea display');
|
35 |
+
}
|
36 |
+
|
37 |
+
console.log('editor id', id);
|
38 |
+
/*var pos = that.getCursorPosition(iframeTarget);*/
|
39 |
+
|
40 |
+
/* Run popup here */
|
41 |
+
jQuery.magnificPopup.open({
|
42 |
+
items: {
|
43 |
+
src: '#inbound-marketing-popup', // can be a HTML string, jQuery object, or CSS selector
|
44 |
+
type: 'inline',
|
45 |
+
callbacks: {
|
46 |
+
open: function() {
|
47 |
+
jQuery('.inbound-short-list').show();
|
48 |
+
},
|
49 |
+
close: function() {
|
50 |
+
jQuery("#iframe-target").html('');
|
51 |
+
}
|
52 |
+
}
|
53 |
+
}
|
54 |
+
});
|
55 |
+
|
56 |
+
});
|
57 |
+
// on marketing button click, grab ID to insert to
|
58 |
+
},
|
59 |
+
waitForEditorLoad: function() {
|
60 |
+
var that = this;
|
61 |
+
jQuery(".acf_postbox .field_type-wysiwyg iframe")
|
62 |
+
.waitUntilExists(function(){
|
63 |
+
console.log('wait');
|
64 |
+
if(!inbound_buttons_loaded) {
|
65 |
+
// do stuff with editor
|
66 |
+
|
67 |
+
that.addButtonsToACFNormal();
|
68 |
+
|
69 |
+
inbound_buttons_loaded = true;
|
70 |
+
}
|
71 |
+
});
|
72 |
+
},
|
73 |
+
launchShortcodeWindow: function(){
|
74 |
+
jQuery(".launch-marketing-shortcode").on('click', function (e) {
|
75 |
+
var $this = jQuery(this);
|
76 |
+
var type = $this.attr('data-launch-sc');
|
77 |
+
var url = inbound_load.image_dir + 'popup.php?popup=' + type + '&width=' + 900 + "&path=" + encodeURIComponent(inbound_load.image_dir);
|
78 |
+
//$('shortcode-frame').attr('href', url);
|
79 |
+
// hide list
|
80 |
+
jQuery('.inbound-short-list').hide();
|
81 |
+
var iframe = "<iframe src="+url+">";
|
82 |
+
//$('#iframe-target').html('');
|
83 |
+
//$('#iframe-target').html(iframe);
|
84 |
+
jQuery.ajax({
|
85 |
+
url: url,
|
86 |
+
success:function(data){
|
87 |
+
jQuery('#iframe-target').html(data);
|
88 |
+
}
|
89 |
+
});
|
90 |
+
});
|
91 |
+
},
|
92 |
+
/* Add buttons to normal ACF */
|
93 |
+
addButtonsToACFNormal: function(){
|
94 |
+
console.log('add buttons');
|
95 |
+
jQuery('.acf_postbox .field_type-wysiwyg').each(function(){
|
96 |
+
var $this = jQuery(this);
|
97 |
+
var label = $this.find('label');
|
98 |
+
var iframeID = $this.find('iframe').attr('id');
|
99 |
+
//console.log('iframe', iframeID);
|
100 |
+
var marButton = '<a data-editor="'+iframeID+'" href="#inbound-marketing-popup" class="button inbound-marketing-button open-marketing-button-popup" title="Marketing"><span class="wp-media-buttons-icon" id="inboundnow-media-button"></span>Marketing</a>';
|
101 |
+
jQuery(marButton).appendTo(label);
|
102 |
+
});
|
103 |
+
|
104 |
+
},
|
105 |
+
|
106 |
+
insertShortcodeHandler: function() {
|
107 |
+
var that = this;
|
108 |
+
jQuery("body").on('click', '#marketing-insert-shortcode', function () {
|
109 |
+
console.log('Insert the shortcode dudddee');
|
110 |
+
// insert into content
|
111 |
+
var shortcode = jQuery('#_inbound_shortcodes_newoutput').html();
|
112 |
+
var id = jQuery('#iframe-target').attr('current-editor');
|
113 |
+
|
114 |
+
if(id.indexOf("_ifr") > -1) {
|
115 |
+
var iframeTarget = document.getElementById(id).contentWindow.document.body;
|
116 |
+
var type = "iframe";
|
117 |
+
} else {
|
118 |
+
var iframeTarget = jQuery("#" + id);
|
119 |
+
var type = "textarea";
|
120 |
+
}
|
121 |
+
|
122 |
+
setTimeout(function() {
|
123 |
+
|
124 |
+
if(type === "iframe") {
|
125 |
+
that.insertContent(shortcode, iframeTarget);
|
126 |
+
} else {
|
127 |
+
that.insertTextAreaContent(shortcode, iframeTarget);
|
128 |
+
}
|
129 |
+
|
130 |
+
jQuery.magnificPopup.close();
|
131 |
+
|
132 |
+
}, 300);
|
133 |
+
});
|
134 |
+
},
|
135 |
+
closePopupHandler: function() {
|
136 |
+
var that = this;
|
137 |
+
jQuery("body").on('click', '#cancel_marketing_button', function () {
|
138 |
+
jQuery.magnificPopup.close();
|
139 |
+
jQuery("#iframe-target").html('');
|
140 |
+
jQuery('.inbound-short-list').show();
|
141 |
+
});
|
142 |
+
},
|
143 |
+
insertTextAreaContent: function(text, selector) {
|
144 |
+
var cursorPos = selector.prop('selectionStart');
|
145 |
+
var v = selector.val();
|
146 |
+
var textBefore = v.substring(0, cursorPos );
|
147 |
+
var textAfter = v.substring( cursorPos, v.length );
|
148 |
+
selector.val( textBefore + text + textAfter );
|
149 |
+
},
|
150 |
+
insertContent: function(text, iframe) {
|
151 |
+
var sel, range, html;
|
152 |
+
var doc = iframe.ownerDocument || iframe.document;
|
153 |
+
var win = doc.defaultView || doc.parentWindow;
|
154 |
+
sel = win.getSelection();
|
155 |
+
if (sel && sel.rangeCount > 0) {
|
156 |
+
console.log('Content inserted!');
|
157 |
+
range = sel.getRangeAt(0);
|
158 |
+
range.deleteContents();
|
159 |
+
var textNode = document.createTextNode(text);
|
160 |
+
range.insertNode(textNode);
|
161 |
+
range.setStartAfter(textNode);
|
162 |
+
sel.removeAllRanges();
|
163 |
+
sel.addRange(range);
|
164 |
+
} else {
|
165 |
+
console.log('havent clicked in box yet');
|
166 |
+
/* focus for the user to insert the content */
|
167 |
+
iframe.focus();
|
168 |
+
console.log('run this again');
|
169 |
+
this.insertContent(text, iframe);
|
170 |
+
}
|
171 |
+
},
|
172 |
+
backButtonHandler: function() {
|
173 |
+
jQuery("body").on('click', '.marketing-back-button', function () {
|
174 |
+
// toggle display
|
175 |
+
jQuery("#iframe-target").html('');
|
176 |
+
jQuery('.select2-drop').remove();
|
177 |
+
jQuery('.inbound-short-list').show();
|
178 |
+
});
|
179 |
+
},
|
180 |
+
getCursorPosition: function (iframe) {
|
181 |
+
var caretOffset = 0,
|
182 |
+
doc = iframe.ownerDocument || iframe.document,
|
183 |
+
win = doc.defaultView || doc.parentWindow,
|
184 |
+
sel;
|
185 |
+
|
186 |
+
if (typeof win.getSelection != "undefined") {
|
187 |
+
sel = win.getSelection();
|
188 |
+
if (sel.rangeCount > 0) {
|
189 |
+
var range = win.getSelection().getRangeAt(0);
|
190 |
+
var preCaretRange = range.cloneRange();
|
191 |
+
preCaretRange.selectNodeContents(iframe);
|
192 |
+
preCaretRange.setEnd(range.endContainer, range.endOffset);
|
193 |
+
caretOffset = preCaretRange.toString().length;
|
194 |
+
}
|
195 |
+
} else if ( (sel = doc.selection) && sel.type != "Control") {
|
196 |
+
var textRange = sel.createRange();
|
197 |
+
var preCaretTextRange = doc.body.createTextRange();
|
198 |
+
preCaretTextRange.moveToElementText(iframe);
|
199 |
+
preCaretTextRange.setEndPoint("EndToEnd", textRange);
|
200 |
+
caretOffset = preCaretTextRange.text.length;
|
201 |
+
}
|
202 |
+
|
203 |
+
return caretOffset;
|
204 |
+
}
|
205 |
+
};
|
206 |
+
|
207 |
+
return Public;
|
208 |
+
|
209 |
+
})();
|
210 |
+
|
211 |
+
jQuery(document).ready(function($) {
|
212 |
+
MarketingButton.init();
|
213 |
+
|
214 |
+
});
|
215 |
+
|
216 |
+
(function ($) {
|
217 |
+
|
218 |
+
/**
|
219 |
+
* @function
|
220 |
+
* @property {object} jQuery plugin which runs handler function once specified element is inserted into the DOM
|
221 |
+
* @param {function} handler A function to execute at the time when the element is inserted
|
222 |
+
* @param {bool} shouldRunHandlerOnce Optional: if true, handler is unbound after its first invocation
|
223 |
+
* @example $(selector).waitUntilExists(function);
|
224 |
+
*/
|
225 |
+
|
226 |
+
$.fn.waitUntilExists = function (handler, shouldRunHandlerOnce, isChild) {
|
227 |
+
var found = 'found';
|
228 |
+
var $this = $(this.selector);
|
229 |
+
var $elements = $this.not(function () { return $(this).data(found); }).each(handler).data(found, true);
|
230 |
+
|
231 |
+
if (!isChild) {
|
232 |
+
(window.wait_until_exists = window.wait_until_exists || {})[this.selector] = window.setInterval(function () {
|
233 |
+
$this.waitUntilExists(handler, shouldRunHandlerOnce, true);
|
234 |
+
}, 500)
|
235 |
+
;
|
236 |
+
} else if (shouldRunHandlerOnce && $elements.length) {
|
237 |
+
window.clearInterval(window.wait_until_exists[this.selector]);
|
238 |
+
}
|
239 |
+
|
240 |
+
return $this;
|
241 |
+
}
|
242 |
+
|
243 |
+
}(jQuery));
|
shared/assets/js/frontend/analytics-src/analytics.events.js
CHANGED
@@ -1,609 +1,609 @@
|
|
1 |
-
/**
|
2 |
-
* # Analytics Events
|
3 |
-
*
|
4 |
-
* Events are triggered throughout the visitors journey through the site. See more on [Inbound Now][in]
|
5 |
-
*
|
6 |
-
* @
|
7 |
-
* @
|
8 |
-
* @version 0.0.2
|
9 |
-
*
|
10 |
-
* [in]: http://www.inboundnow.com/
|
11 |
-
*/
|
12 |
-
|
13 |
-
// Add object to _inbound
|
14 |
-
var _inboundEvents = (function(_inbound) {
|
15 |
-
|
16 |
-
|
17 |
-
_inbound.trigger = function(trigger, data) {
|
18 |
-
_inbound.Events[trigger](data);
|
19 |
-
|
20 |
-
};
|
21 |
-
|
22 |
-
/*!
|
23 |
-
*
|
24 |
-
* Private Function that Fires & Emits Events
|
25 |
-
*
|
26 |
-
* There are three options for firing events and they trigger in this order:
|
27 |
-
*
|
28 |
-
* 1. Vanilla JS dispatch event
|
29 |
-
* 2. `_inbound.add_action('namespace', callback, priority)`
|
30 |
-
* 3. jQuery Trigger `jQuery.trigger('namespace', callback);`
|
31 |
-
*
|
32 |
-
* The Event `data` can be filtered before events are triggered
|
33 |
-
* with filters. Example: filter_ + "namespace"
|
34 |
-
*
|
35 |
-
* ```js
|
36 |
-
* // Filter Form Data before submissionsz
|
37 |
-
* _inbound.add_filter( 'filter_form_before_submission', event_filter_data_example, 10);
|
38 |
-
*
|
39 |
-
* function event_filter_data_example(data) {
|
40 |
-
* var data = data || {};
|
41 |
-
* // Do something with data
|
42 |
-
* return data;
|
43 |
-
* }
|
44 |
-
* ```
|
45 |
-
*
|
46 |
-
* @param {string} eventName Name of the event
|
47 |
-
* @param {object} data Data passed to external functions/triggers
|
48 |
-
* @param {object} options Options for configuring events
|
49 |
-
* @return {null} Nothing returned
|
50 |
-
*/
|
51 |
-
function fireEvent(eventName, data, options) {
|
52 |
-
var data = data || {};
|
53 |
-
options = options || {};
|
54 |
-
|
55 |
-
/*! defaults for JS dispatch event */
|
56 |
-
options.bubbles = options.bubbles || true,
|
57 |
-
options.cancelable = options.cancelable || true;
|
58 |
-
|
59 |
-
/*! Customize Data via filter_ + "namespace" */
|
60 |
-
data = _inbound.apply_filters('filter_' + eventName, data);
|
61 |
-
|
62 |
-
var is_IE_11 = !(window.ActiveXObject) && "ActiveXObject" in window;
|
63 |
-
|
64 |
-
if( typeof CustomEvent === 'function') {
|
65 |
-
|
66 |
-
var TriggerEvent = new CustomEvent(eventName, {
|
67 |
-
detail: data,
|
68 |
-
bubbles: options.bubbles,
|
69 |
-
cancelable: options.cancelable
|
70 |
-
});
|
71 |
-
|
72 |
-
} else {
|
73 |
-
var TriggerEvent = document.createEvent("Event");
|
74 |
-
TriggerEvent.initEvent(eventName, true, true);
|
75 |
-
}
|
76 |
-
|
77 |
-
/*! 1. Trigger Pure Javascript Event See: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events for example on creating events */
|
78 |
-
window.dispatchEvent(TriggerEvent);
|
79 |
-
/*! 2. Trigger _inbound action */
|
80 |
-
_inbound.do_action(eventName, data);
|
81 |
-
/*! 3. jQuery trigger */
|
82 |
-
triggerJQueryEvent(eventName, data);
|
83 |
-
|
84 |
-
// console.log('Action:' + eventName + " ran on ->", data);
|
85 |
-
|
86 |
-
}
|
87 |
-
|
88 |
-
function triggerJQueryEvent(eventName, data) {
|
89 |
-
if (window.jQuery) {
|
90 |
-
var data = data || {};
|
91 |
-
/*! try catch here */
|
92 |
-
jQuery(document).trigger(eventName, data);
|
93 |
-
}
|
94 |
-
};
|
95 |
-
|
96 |
-
var universalGA,
|
97 |
-
classicGA,
|
98 |
-
googleTagManager;
|
99 |
-
|
100 |
-
_inbound.Events = {
|
101 |
-
|
102 |
-
/**
|
103 |
-
* # Event Usage
|
104 |
-
*
|
105 |
-
* Events are triggered throughout the visitors path through the site.
|
106 |
-
* You can hook into these custom actions and filters much like WordPress Core
|
107 |
-
*
|
108 |
-
* See below for examples
|
109 |
-
*/
|
110 |
-
|
111 |
-
/**
|
112 |
-
* Adding Custom Actions
|
113 |
-
* ------------------
|
114 |
-
* You can hook into custom events throughout analytics. See the full list of available [events below](#all-events)
|
115 |
-
*
|
116 |
-
* `
|
117 |
-
* _inbound.add_action( 'action_name', callback, priority );
|
118 |
-
* `
|
119 |
-
*
|
120 |
-
* ```js
|
121 |
-
* // example:
|
122 |
-
*
|
123 |
-
* // Add custom function to `page_visit` event
|
124 |
-
* _inbound.add_action( 'page_visit', callback, 10 );
|
125 |
-
*
|
126 |
-
* // add custom callback to trigger when `page_visit` fires
|
127 |
-
* function callback(pageData){
|
128 |
-
* var pageData = pageData || {};
|
129 |
-
* // run callback on 'page_visit' trigger
|
130 |
-
* alert(pageData.title);
|
131 |
-
* }
|
132 |
-
* ```
|
133 |
-
*
|
134 |
-
* @param {string} action_name Name of the event trigger
|
135 |
-
* @param {function} callback function to trigger when event happens
|
136 |
-
* @param {int} priority Order to trigger the event in
|
137 |
-
*
|
138 |
-
*/
|
139 |
-
|
140 |
-
/**
|
141 |
-
* Removing Custom Actions
|
142 |
-
* ------------------
|
143 |
-
* You can hook into custom events throughout analytics. See the full list of available [events below](#all-events)
|
144 |
-
*
|
145 |
-
* `
|
146 |
-
* _inbound.remove_action( 'action_name');
|
147 |
-
* `
|
148 |
-
*
|
149 |
-
* ```js
|
150 |
-
* // example:
|
151 |
-
*
|
152 |
-
* _inbound.remove_action( 'page_visit');
|
153 |
-
* // all 'page_visit' actions have been deregistered
|
154 |
-
* ```
|
155 |
-
*
|
156 |
-
* @param {string} action_name Name of the event trigger
|
157 |
-
*
|
158 |
-
*/
|
159 |
-
|
160 |
-
/**
|
161 |
-
* # Event List
|
162 |
-
*
|
163 |
-
* Events are triggered throughout the visitors journey through the site
|
164 |
-
*/
|
165 |
-
|
166 |
-
/**
|
167 |
-
* Triggers when analyics has finished loading
|
168 |
-
*/
|
169 |
-
analytics_ready: function() {
|
170 |
-
var ops = {
|
171 |
-
'opt1': true
|
172 |
-
};
|
173 |
-
var data = {
|
174 |
-
'data': 'xyxy'
|
175 |
-
};
|
176 |
-
fireEvent('analytics_ready', data, ops);
|
177 |
-
},
|
178 |
-
/**
|
179 |
-
* Triggers when the browser url params are parsed. You can perform custom actions
|
180 |
-
* if specific url params exist.
|
181 |
-
*
|
182 |
-
* ```js
|
183 |
-
* // Usage:
|
184 |
-
*
|
185 |
-
* // Add function to 'url_parameters' event
|
186 |
-
* _inbound.add_action( 'url_parameters', url_parameters_func_example, 10);
|
187 |
-
*
|
188 |
-
* function url_parameters_func_example(urlParams) {
|
189 |
-
* var urlParams = urlParams || {};
|
190 |
-
* for( var param in urlParams ) {
|
191 |
-
* var key = param;
|
192 |
-
* var value = urlParams[param];
|
193 |
-
* }
|
194 |
-
* // All URL Params
|
195 |
-
* alert(JSON.stringify(urlParams));
|
196 |
-
*
|
197 |
-
* // Check if URL parameter `utm_source` exists and matches value
|
198 |
-
* if(urlParams.utm_source === "twitter") {
|
199 |
-
* alert('This person is from twitter!');
|
200 |
-
* }
|
201 |
-
* }
|
202 |
-
* ```
|
203 |
-
*/
|
204 |
-
url_parameters: function(data) {
|
205 |
-
fireEvent('url_parameters', data);
|
206 |
-
},
|
207 |
-
/**
|
208 |
-
* Triggers when session starts
|
209 |
-
*
|
210 |
-
* ```js
|
211 |
-
* // Usage:
|
212 |
-
*
|
213 |
-
* // Add function to 'session_start' event
|
214 |
-
* _inbound.add_action( 'session_start', session_start_func_example, 10);
|
215 |
-
*
|
216 |
-
* function session_start_func_example(data) {
|
217 |
-
* var data = data || {};
|
218 |
-
* // session start. Do something for new visitor
|
219 |
-
* }
|
220 |
-
* ```
|
221 |
-
*/
|
222 |
-
session_start: function() {
|
223 |
-
console.log('');
|
224 |
-
fireEvent('session_start');
|
225 |
-
},
|
226 |
-
/**
|
227 |
-
* Triggers when visitor session goes idle for more than 30 minutes.
|
228 |
-
*
|
229 |
-
* ```js
|
230 |
-
* // Usage:
|
231 |
-
*
|
232 |
-
* // Add function to 'session_end' event
|
233 |
-
* _inbound.add_action( 'session_end', session_end_func_example, 10);
|
234 |
-
*
|
235 |
-
* function session_end_func_example(data) {
|
236 |
-
* var data = data || {};
|
237 |
-
* // Do something when session ends
|
238 |
-
* alert("Hey! It's been 30 minutes... where did you go?");
|
239 |
-
* }
|
240 |
-
* ```
|
241 |
-
*/
|
242 |
-
session_end: function(clockTime) {
|
243 |
-
fireEvent('session_end', clockTime);
|
244 |
-
console.log('Session End');
|
245 |
-
},
|
246 |
-
/**
|
247 |
-
* Triggers if active session is detected
|
248 |
-
*
|
249 |
-
* ```js
|
250 |
-
* // Usage:
|
251 |
-
*
|
252 |
-
* // Add function to 'session_active' event
|
253 |
-
* _inbound.add_action( 'session_active', session_active_func_example, 10);
|
254 |
-
*
|
255 |
-
* function session_active_func_example(data) {
|
256 |
-
* var data = data || {};
|
257 |
-
* // session active
|
258 |
-
* }
|
259 |
-
* ```
|
260 |
-
*/
|
261 |
-
session_active: function() {
|
262 |
-
fireEvent('session_active');
|
263 |
-
},
|
264 |
-
/**
|
265 |
-
* Triggers when visitor session goes idle. Idling occurs after 60 seconds of
|
266 |
-
* inactivity or when the visitor switches browser tabs
|
267 |
-
*
|
268 |
-
* ```js
|
269 |
-
* // Usage:
|
270 |
-
*
|
271 |
-
* // Add function to 'session_idle' event
|
272 |
-
* _inbound.add_action( 'session_idle', session_idle_func_example, 10);
|
273 |
-
*
|
274 |
-
* function session_idle_func_example(data) {
|
275 |
-
* var data = data || {};
|
276 |
-
* // Do something when session idles
|
277 |
-
* alert('Here is a special offer for you!');
|
278 |
-
* }
|
279 |
-
* ```
|
280 |
-
*/
|
281 |
-
session_idle: function(clockTime) {
|
282 |
-
fireEvent('session_idle', clockTime);
|
283 |
-
},
|
284 |
-
/**
|
285 |
-
* Triggers when session is already active and gets resumed
|
286 |
-
*
|
287 |
-
* ```js
|
288 |
-
* // Usage:
|
289 |
-
*
|
290 |
-
* // Add function to 'session_resume' event
|
291 |
-
* _inbound.add_action( 'session_resume', session_resume_func_example, 10);
|
292 |
-
*
|
293 |
-
* function session_resume_func_example(data) {
|
294 |
-
* var data = data || {};
|
295 |
-
* // Session exists and is being resumed
|
296 |
-
* }
|
297 |
-
* ```
|
298 |
-
*/
|
299 |
-
session_resume: function() {
|
300 |
-
fireEvent('session_resume');
|
301 |
-
},
|
302 |
-
/**
|
303 |
-
* Session emitter. Runs every 10 seconds. This is a useful function for
|
304 |
-
* pinging third party services
|
305 |
-
*
|
306 |
-
* ```js
|
307 |
-
* // Usage:
|
308 |
-
*
|
309 |
-
* // Add session_heartbeat_func_example function to 'session_heartbeat' event
|
310 |
-
* _inbound.add_action( 'session_heartbeat', session_heartbeat_func_example, 10);
|
311 |
-
*
|
312 |
-
* function session_heartbeat_func_example(data) {
|
313 |
-
* var data = data || {};
|
314 |
-
* // Do something with every 10 seconds
|
315 |
-
* }
|
316 |
-
* ```
|
317 |
-
*/
|
318 |
-
session_heartbeat: function(clockTime) {
|
319 |
-
var data = {
|
320 |
-
'clock': clockTime,
|
321 |
-
'leadData': InboundLeadData
|
322 |
-
};
|
323 |
-
fireEvent('session_heartbeat', data);
|
324 |
-
},
|
325 |
-
/**
|
326 |
-
* Triggers Every Page View
|
327 |
-
*
|
328 |
-
* ```js
|
329 |
-
* // Usage:
|
330 |
-
*
|
331 |
-
* // Add function to 'page_visit' event
|
332 |
-
* _inbound.add_action( 'page_visit', page_visit_func_example, 10);
|
333 |
-
*
|
334 |
-
* function session_idle_func_example(pageData) {
|
335 |
-
* var pageData = pageData || {};
|
336 |
-
* if( pageData.view_count > 8 ){
|
337 |
-
* alert('Wow you have been to this page more than 8 times.');
|
338 |
-
* }
|
339 |
-
* }
|
340 |
-
* ```
|
341 |
-
*/
|
342 |
-
page_visit: function(pageData) {
|
343 |
-
fireEvent('page_view', pageData);
|
344 |
-
},
|
345 |
-
/**
|
346 |
-
* Triggers If the visitor has never seen the page before
|
347 |
-
*
|
348 |
-
* ```js
|
349 |
-
* // Usage:
|
350 |
-
*
|
351 |
-
* // Add function to 'page_first_visit' event
|
352 |
-
* _inbound.add_action( 'page_first_visit', page_first_visit_func_example, 10);
|
353 |
-
*
|
354 |
-
* function page_first_visit_func_example(pageData) {
|
355 |
-
* var pageData = pageData || {};
|
356 |
-
* alert('Welcome to this page! Its the first time you have seen it')
|
357 |
-
* }
|
358 |
-
* ```
|
359 |
-
*/
|
360 |
-
page_first_visit: function(pageData) {
|
361 |
-
fireEvent('page_first_visit');
|
362 |
-
_inbound.deBugger('pages', 'First Ever Page View of this Page');
|
363 |
-
},
|
364 |
-
/**
|
365 |
-
* Triggers If the visitor has seen the page before
|
366 |
-
*
|
367 |
-
* ```js
|
368 |
-
* // Usage:
|
369 |
-
*
|
370 |
-
* // Add function to 'page_revisit' event
|
371 |
-
* _inbound.add_action( 'page_revisit', page_revisit_func_example, 10);
|
372 |
-
*
|
373 |
-
* function page_revisit_func_example(pageData) {
|
374 |
-
* var pageData = pageData || {};
|
375 |
-
* alert('Welcome back to this page!');
|
376 |
-
* // Show visitor special content/offer
|
377 |
-
* }
|
378 |
-
* ```
|
379 |
-
*/
|
380 |
-
page_revisit: function(pageData) {
|
381 |
-
|
382 |
-
fireEvent('page_revisit', pageData);
|
383 |
-
|
384 |
-
var logger = function() {
|
385 |
-
console.log('pageData', pageData);
|
386 |
-
console.log('Page Revisit viewed ' + pageData + " times");
|
387 |
-
}
|
388 |
-
_inbound.deBugger('pages', status, logger);
|
389 |
-
},
|
390 |
-
|
391 |
-
/**
|
392 |
-
* `tab_hidden` is triggered when the visitor switches browser tabs
|
393 |
-
*
|
394 |
-
* ```js
|
395 |
-
* // Usage:
|
396 |
-
*
|
397 |
-
* // Adding the callback
|
398 |
-
* function tab_hidden_function( data ) {
|
399 |
-
* alert('The Tab is Hidden');
|
400 |
-
* };
|
401 |
-
*
|
402 |
-
* // Hook the function up the the `tab_hidden` event
|
403 |
-
* _inbound.add_action( 'tab_hidden', tab_hidden_function, 10 );
|
404 |
-
* ```
|
405 |
-
*/
|
406 |
-
tab_hidden: function(data) {
|
407 |
-
_inbound.deBugger('pages', 'Tab Hidden');
|
408 |
-
fireEvent('tab_hidden');
|
409 |
-
},
|
410 |
-
/**
|
411 |
-
* `tab_visible` is triggered when the visitor switches back to the sites tab
|
412 |
-
*
|
413 |
-
* ```js
|
414 |
-
* // Usage:
|
415 |
-
*
|
416 |
-
* // Adding the callback
|
417 |
-
* function tab_visible_function( data ) {
|
418 |
-
* alert('Welcome back to this tab!');
|
419 |
-
* // trigger popup or offer special discount etc.
|
420 |
-
* };
|
421 |
-
*
|
422 |
-
* // Hook the function up the the `tab_visible` event
|
423 |
-
* _inbound.add_action( 'tab_visible', tab_visible_function, 10 );
|
424 |
-
* ```
|
425 |
-
*/
|
426 |
-
tab_visible: function(data) {
|
427 |
-
_inbound.deBugger('pages', 'Tab Visible');
|
428 |
-
fireEvent('tab_visible');
|
429 |
-
},
|
430 |
-
/**
|
431 |
-
* `tab_mouseout` is triggered when the visitor mouses out of the browser window.
|
432 |
-
* This is especially useful for exit popups
|
433 |
-
*
|
434 |
-
* ```js
|
435 |
-
* // Usage:
|
436 |
-
*
|
437 |
-
* // Adding the callback
|
438 |
-
* function tab_mouseout_function( data ) {
|
439 |
-
* alert("Wait don't Go");
|
440 |
-
* // trigger popup or offer special discount etc.
|
441 |
-
* };
|
442 |
-
*
|
443 |
-
* // Hook the function up the the `tab_mouseout` event
|
444 |
-
* _inbound.add_action( 'tab_mouseout', tab_mouseout_function, 10 );
|
445 |
-
* ```
|
446 |
-
*/
|
447 |
-
tab_mouseout: function(data) {
|
448 |
-
_inbound.deBugger('pages', 'Tab Mouseout');
|
449 |
-
fireEvent('tab_mouseout');
|
450 |
-
},
|
451 |
-
/**
|
452 |
-
* `form_input_change` is triggered when tracked form inputs change
|
453 |
-
* You can use this to add additional validation or set conditional triggers
|
454 |
-
*
|
455 |
-
* ```js
|
456 |
-
* // Usage:
|
457 |
-
*
|
458 |
-
* ```
|
459 |
-
*/
|
460 |
-
form_input_change: function(inputData) {
|
461 |
-
var logger = function() {
|
462 |
-
console.log(inputData);
|
463 |
-
//console.log('Page Revisit viewed ' + pageData + " times");
|
464 |
-
}
|
465 |
-
_inbound.deBugger('forms', 'inputData change. Data=', logger);
|
466 |
-
fireEvent('form_input_change', inputData);
|
467 |
-
},
|
468 |
-
/**
|
469 |
-
* `form_before_submission` is triggered before the form is submitted to the server.
|
470 |
-
* You can filter the data here or send it to third party services
|
471 |
-
*
|
472 |
-
* ```js
|
473 |
-
* // Usage:
|
474 |
-
*
|
475 |
-
* // Adding the callback
|
476 |
-
* function form_before_submission_function( data ) {
|
477 |
-
* var data = data || {};
|
478 |
-
* // filter form data
|
479 |
-
* };
|
480 |
-
*
|
481 |
-
* // Hook the function up the the `form_before_submission` event
|
482 |
-
* _inbound.add_action( 'form_before_submission', form_before_submission_function, 10 );
|
483 |
-
* ```
|
484 |
-
*/
|
485 |
-
form_before_submission: function(formData) {
|
486 |
-
fireEvent('form_before_submission', formData);
|
487 |
-
},
|
488 |
-
/**
|
489 |
-
* `form_after_submission` is triggered after the form is submitted to the server.
|
490 |
-
* You can filter the data here or send it to third party services
|
491 |
-
*
|
492 |
-
* ```js
|
493 |
-
* // Usage:
|
494 |
-
*
|
495 |
-
* // Adding the callback
|
496 |
-
* function form_after_submission_function( data ) {
|
497 |
-
* var data = data || {};
|
498 |
-
* // filter form data
|
499 |
-
* };
|
500 |
-
*
|
501 |
-
* // Hook the function up the the `form_after_submission` event
|
502 |
-
* _inbound.add_action( 'form_after_submission', form_after_submission_function, 10 );
|
503 |
-
* ```
|
504 |
-
*/
|
505 |
-
form_after_submission: function(formData) {
|
506 |
-
|
507 |
-
fireEvent('form_after_submission', formData);
|
508 |
-
|
509 |
-
},
|
510 |
-
/**
|
511 |
-
* `search_before_caching` is triggered before the search is stored in the user's browser.
|
512 |
-
* If a lead ID is set, the search data will be saved to the server when the next page loads.
|
513 |
-
* You can filter the data here or send it to third party services
|
514 |
-
*
|
515 |
-
* ```js
|
516 |
-
* // Usage:
|
517 |
-
*
|
518 |
-
* // Adding the callback
|
519 |
-
* function search_before_caching_function( data ) {
|
520 |
-
* var data = data || {};
|
521 |
-
* // filter search data
|
522 |
-
* };
|
523 |
-
*
|
524 |
-
* // Hook the function up the the `search_before_caching` event
|
525 |
-
* _inbound.add_action( 'search_before_caching', search_before_caching_function, 10 );
|
526 |
-
* ```
|
527 |
-
*/
|
528 |
-
search_before_caching: function(searchData) {
|
529 |
-
fireEvent('search_before_caching', searchData);
|
530 |
-
},
|
531 |
-
/*! Scrol depth https://github.com/robflaherty/jquery-scrolldepth/blob/master/jquery.scrolldepth.js */
|
532 |
-
|
533 |
-
analyticsError: function(MLHttpRequest, textStatus, errorThrown) {
|
534 |
-
var error = new CustomEvent("inbound_analytics_error", {
|
535 |
-
detail: {
|
536 |
-
MLHttpRequest: MLHttpRequest,
|
537 |
-
textStatus: textStatus,
|
538 |
-
errorThrown: errorThrown
|
539 |
-
}
|
540 |
-
});
|
541 |
-
window.dispatchEvent(error);
|
542 |
-
console.log('Page Save Error');
|
543 |
-
}
|
544 |
-
|
545 |
-
};
|
546 |
-
|
547 |
-
return _inbound;
|
548 |
-
|
549 |
-
})(_inbound || {});
|
550 |
-
|
551 |
-
|
552 |
-
function inboundFormNoRedirect(){
|
553 |
-
/*button == the button that was clicked, form == the form that button belongs to, formRedirectUrl == the link that the form redirects to, if set*/
|
554 |
-
|
555 |
-
/*Get the button...*/
|
556 |
-
/*If not an iframe*/
|
557 |
-
if(window.frames.frameElement == null){
|
558 |
-
var button = document.querySelectorAll('button.inbound-button-submit[disabled]')[0];
|
559 |
-
}
|
560 |
-
/*If it is an iframe*/
|
561 |
-
else if(window.frames.frameElement.tagName.toLowerCase() == "iframe"){
|
562 |
-
var button = window.frames.frameElement.contentWindow.document.querySelectorAll('button.inbound-button-submit')[0];
|
563 |
-
}
|
564 |
-
|
565 |
-
if ( typeof button == 'undefined' ) {
|
566 |
-
return;
|
567 |
-
}
|
568 |
-
|
569 |
-
var form = button.form,
|
570 |
-
formRedirectUrl = form.querySelectorAll('input[value][type="hidden"][name="inbound_furl"]:not([value=""])');
|
571 |
-
|
572 |
-
/*If the redirect link is not set, or there is a single space in it, the form isn't supposed to redirect. So set the action for void*/
|
573 |
-
if(formRedirectUrl.length == 0 || formRedirectUrl[0]['value'] == 'IA=='){
|
574 |
-
form.action = 'javascript:void(0)';
|
575 |
-
}
|
576 |
-
}
|
577 |
-
|
578 |
-
_inbound.add_action( 'form_before_submission', inboundFormNoRedirect, 10 );
|
579 |
-
|
580 |
-
function inboundFormNoRedirectContent(){
|
581 |
-
|
582 |
-
/*If not an iframe*/
|
583 |
-
if(window.frames.frameElement == null){
|
584 |
-
var button = document.querySelectorAll('button.inbound-button-submit[disabled]')[0];
|
585 |
-
}
|
586 |
-
/*If it is an iframe*/
|
587 |
-
else if(window.frames.frameElement.tagName.toLowerCase() == "iframe"){
|
588 |
-
var button = window.frames.frameElement.contentWindow.document.querySelectorAll('button.inbound-button-submit')[0];
|
589 |
-
}
|
590 |
-
|
591 |
-
|
592 |
-
if ( typeof button == 'undefined' ) {
|
593 |
-
return;
|
594 |
-
}
|
595 |
-
|
596 |
-
var form = button.form,
|
597 |
-
formRedirectUrl = form.querySelectorAll('input[value][type="hidden"][name="inbound_furl"]:not([value=""])'),
|
598 |
-
btnBackground = jQuery(button).css('background'),
|
599 |
-
btnFontColor = jQuery(button).css('color'),
|
600 |
-
btnHeight = jQuery(button).css('height'),
|
601 |
-
spinner = button.getElementsByClassName('inbound-form-spinner');
|
602 |
-
|
603 |
-
if(formRedirectUrl.length == 0 || formRedirectUrl[0]['value'] == 'IA=='){
|
604 |
-
jQuery(spinner).remove();
|
605 |
-
jQuery(button).prepend('<div id="redir-check"><i class="fa fa-check-square" aria-hidden="true" style="background='+ btnBackground +'; color='+ btnFontColor +'; font-size:calc('+ btnHeight +' * .42);"></i></div>');
|
606 |
-
}
|
607 |
-
}
|
608 |
-
|
609 |
-
_inbound.add_action( 'form_after_submission', inboundFormNoRedirectContent, 10 );
|
1 |
+
/**
|
2 |
+
* # Analytics Events
|
3 |
+
*
|
4 |
+
* Events are triggered throughout the visitors journey through the site. See more on [Inbound Now][in]
|
5 |
+
*
|
6 |
+
* @contributor David Wells <david@inboundnow.com>
|
7 |
+
* @contributor Hudson Atwell <hudson@inboundnow.com>
|
8 |
+
* @version 0.0.2
|
9 |
+
*
|
10 |
+
* [in]: http://www.inboundnow.com/
|
11 |
+
*/
|
12 |
+
|
13 |
+
// Add object to _inbound
|
14 |
+
var _inboundEvents = (function(_inbound) {
|
15 |
+
|
16 |
+
|
17 |
+
_inbound.trigger = function(trigger, data) {
|
18 |
+
_inbound.Events[trigger](data);
|
19 |
+
|
20 |
+
};
|
21 |
+
|
22 |
+
/*!
|
23 |
+
*
|
24 |
+
* Private Function that Fires & Emits Events
|
25 |
+
*
|
26 |
+
* There are three options for firing events and they trigger in this order:
|
27 |
+
*
|
28 |
+
* 1. Vanilla JS dispatch event
|
29 |
+
* 2. `_inbound.add_action('namespace', callback, priority)`
|
30 |
+
* 3. jQuery Trigger `jQuery.trigger('namespace', callback);`
|
31 |
+
*
|
32 |
+
* The Event `data` can be filtered before events are triggered
|
33 |
+
* with filters. Example: filter_ + "namespace"
|
34 |
+
*
|
35 |
+
* ```js
|
36 |
+
* // Filter Form Data before submissionsz
|
37 |
+
* _inbound.add_filter( 'filter_form_before_submission', event_filter_data_example, 10);
|
38 |
+
*
|
39 |
+
* function event_filter_data_example(data) {
|
40 |
+
* var data = data || {};
|
41 |
+
* // Do something with data
|
42 |
+
* return data;
|
43 |
+
* }
|
44 |
+
* ```
|
45 |
+
*
|
46 |
+
* @param {string} eventName Name of the event
|
47 |
+
* @param {object} data Data passed to external functions/triggers
|
48 |
+
* @param {object} options Options for configuring events
|
49 |
+
* @return {null} Nothing returned
|
50 |
+
*/
|
51 |
+
function fireEvent(eventName, data, options) {
|
52 |
+
var data = data || {};
|
53 |
+
options = options || {};
|
54 |
+
|
55 |
+
/*! defaults for JS dispatch event */
|
56 |
+
options.bubbles = options.bubbles || true,
|
57 |
+
options.cancelable = options.cancelable || true;
|
58 |
+
|
59 |
+
/*! Customize Data via filter_ + "namespace" */
|
60 |
+
data = _inbound.apply_filters('filter_' + eventName, data);
|
61 |
+
|
62 |
+
var is_IE_11 = !(window.ActiveXObject) && "ActiveXObject" in window;
|
63 |
+
|
64 |
+
if( typeof CustomEvent === 'function') {
|
65 |
+
|
66 |
+
var TriggerEvent = new CustomEvent(eventName, {
|
67 |
+
detail: data,
|
68 |
+
bubbles: options.bubbles,
|
69 |
+
cancelable: options.cancelable
|
70 |
+
});
|
71 |
+
|
72 |
+
} else {
|
73 |
+
var TriggerEvent = document.createEvent("Event");
|
74 |
+
TriggerEvent.initEvent(eventName, true, true);
|
75 |
+
}
|
76 |
+
|
77 |
+
/*! 1. Trigger Pure Javascript Event See: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events for example on creating events */
|
78 |
+
window.dispatchEvent(TriggerEvent);
|
79 |
+
/*! 2. Trigger _inbound action */
|
80 |
+
_inbound.do_action(eventName, data);
|
81 |
+
/*! 3. jQuery trigger */
|
82 |
+
triggerJQueryEvent(eventName, data);
|
83 |
+
|
84 |
+
// console.log('Action:' + eventName + " ran on ->", data);
|
85 |
+
|
86 |
+
}
|
87 |
+
|
88 |
+
function triggerJQueryEvent(eventName, data) {
|
89 |
+
if (window.jQuery) {
|
90 |
+
var data = data || {};
|
91 |
+
/*! try catch here */
|
92 |
+
jQuery(document).trigger(eventName, data);
|
93 |
+
}
|
94 |
+
};
|
95 |
+
|
96 |
+
var universalGA,
|
97 |
+
classicGA,
|
98 |
+
googleTagManager;
|
99 |
+
|
100 |
+
_inbound.Events = {
|
101 |
+
|
102 |
+
/**
|
103 |
+
* # Event Usage
|
104 |
+
*
|
105 |
+
* Events are triggered throughout the visitors path through the site.
|
106 |
+
* You can hook into these custom actions and filters much like WordPress Core
|
107 |
+
*
|
108 |
+
* See below for examples
|
109 |
+
*/
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Adding Custom Actions
|
113 |
+
* ------------------
|
114 |
+
* You can hook into custom events throughout analytics. See the full list of available [events below](#all-events)
|
115 |
+
*
|
116 |
+
* `
|
117 |
+
* _inbound.add_action( 'action_name', callback, priority );
|
118 |
+
* `
|
119 |
+
*
|
120 |
+
* ```js
|
121 |
+
* // example:
|
122 |
+
*
|
123 |
+
* // Add custom function to `page_visit` event
|
124 |
+
* _inbound.add_action( 'page_visit', callback, 10 );
|
125 |
+
*
|
126 |
+
* // add custom callback to trigger when `page_visit` fires
|
127 |
+
* function callback(pageData){
|
128 |
+
* var pageData = pageData || {};
|
129 |
+
* // run callback on 'page_visit' trigger
|
130 |
+
* alert(pageData.title);
|
131 |
+
* }
|
132 |
+
* ```
|
133 |
+
*
|
134 |
+
* @param {string} action_name Name of the event trigger
|
135 |
+
* @param {function} callback function to trigger when event happens
|
136 |
+
* @param {int} priority Order to trigger the event in
|
137 |
+
*
|
138 |
+
*/
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Removing Custom Actions
|
142 |
+
* ------------------
|
143 |
+
* You can hook into custom events throughout analytics. See the full list of available [events below](#all-events)
|
144 |
+
*
|
145 |
+
* `
|
146 |
+
* _inbound.remove_action( 'action_name');
|
147 |
+
* `
|
148 |
+
*
|
149 |
+
* ```js
|
150 |
+
* // example:
|
151 |
+
*
|
152 |
+
* _inbound.remove_action( 'page_visit');
|
153 |
+
* // all 'page_visit' actions have been deregistered
|
154 |
+
* ```
|
155 |
+
*
|
156 |
+
* @param {string} action_name Name of the event trigger
|
157 |
+
*
|
158 |
+
*/
|
159 |
+
|
160 |
+
/**
|
161 |
+
* # Event List
|
162 |
+
*
|
163 |
+
* Events are triggered throughout the visitors journey through the site
|
164 |
+
*/
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Triggers when analyics has finished loading
|
168 |
+
*/
|
169 |
+
analytics_ready: function() {
|
170 |
+
var ops = {
|
171 |
+
'opt1': true
|
172 |
+
};
|
173 |
+
var data = {
|
174 |
+
'data': 'xyxy'
|
175 |
+
};
|
176 |
+
fireEvent('analytics_ready', data, ops);
|
177 |
+
},
|
178 |
+
/**
|
179 |
+
* Triggers when the browser url params are parsed. You can perform custom actions
|
180 |
+
* if specific url params exist.
|
181 |
+
*
|
182 |
+
* ```js
|
183 |
+
* // Usage:
|
184 |
+
*
|
185 |
+
* // Add function to 'url_parameters' event
|
186 |
+
* _inbound.add_action( 'url_parameters', url_parameters_func_example, 10);
|
187 |
+
*
|
188 |
+
* function url_parameters_func_example(urlParams) {
|
189 |
+
* var urlParams = urlParams || {};
|
190 |
+
* for( var param in urlParams ) {
|
191 |
+
* var key = param;
|
192 |
+
* var value = urlParams[param];
|
193 |
+
* }
|
194 |
+
* // All URL Params
|
195 |
+
* alert(JSON.stringify(urlParams));
|
196 |
+
*
|
197 |
+
* // Check if URL parameter `utm_source` exists and matches value
|
198 |
+
* if(urlParams.utm_source === "twitter") {
|
199 |
+
* alert('This person is from twitter!');
|
200 |
+
* }
|
201 |
+
* }
|
202 |
+
* ```
|
203 |
+
*/
|
204 |
+
url_parameters: function(data) {
|
205 |
+
fireEvent('url_parameters', data);
|
206 |
+
},
|
207 |
+
/**
|
208 |
+
* Triggers when session starts
|
209 |
+
*
|
210 |
+
* ```js
|
211 |
+
* // Usage:
|
212 |
+
*
|
213 |
+
* // Add function to 'session_start' event
|
214 |
+
* _inbound.add_action( 'session_start', session_start_func_example, 10);
|
215 |
+
*
|
216 |
+
* function session_start_func_example(data) {
|
217 |
+
* var data = data || {};
|
218 |
+
* // session start. Do something for new visitor
|
219 |
+
* }
|
220 |
+
* ```
|
221 |
+
*/
|
222 |
+
session_start: function() {
|
223 |
+
console.log('');
|
224 |
+
fireEvent('session_start');
|
225 |
+
},
|
226 |
+
/**
|
227 |
+
* Triggers when visitor session goes idle for more than 30 minutes.
|
228 |
+
*
|
229 |
+
* ```js
|
230 |
+
* // Usage:
|
231 |
+
*
|
232 |
+
* // Add function to 'session_end' event
|
233 |
+
* _inbound.add_action( 'session_end', session_end_func_example, 10);
|
234 |
+
*
|
235 |
+
* function session_end_func_example(data) {
|
236 |
+
* var data = data || {};
|
237 |
+
* // Do something when session ends
|
238 |
+
* alert("Hey! It's been 30 minutes... where did you go?");
|
239 |
+
* }
|
240 |
+
* ```
|
241 |
+
*/
|
242 |
+
session_end: function(clockTime) {
|
243 |
+
fireEvent('session_end', clockTime);
|
244 |
+
console.log('Session End');
|
245 |
+
},
|
246 |
+
/**
|
247 |
+
* Triggers if active session is detected
|
248 |
+
*
|
249 |
+
* ```js
|
250 |
+
* // Usage:
|
251 |
+
*
|
252 |
+
* // Add function to 'session_active' event
|
253 |
+
* _inbound.add_action( 'session_active', session_active_func_example, 10);
|
254 |
+
*
|
255 |
+
* function session_active_func_example(data) {
|
256 |
+
* var data = data || {};
|
257 |
+
* // session active
|
258 |
+
* }
|
259 |
+
* ```
|
260 |
+
*/
|
261 |
+
session_active: function() {
|
262 |
+
fireEvent('session_active');
|
263 |
+
},
|
264 |
+
/**
|
265 |
+
* Triggers when visitor session goes idle. Idling occurs after 60 seconds of
|
266 |
+
* inactivity or when the visitor switches browser tabs
|
267 |
+
*
|
268 |
+
* ```js
|
269 |
+
* // Usage:
|
270 |
+
*
|
271 |
+
* // Add function to 'session_idle' event
|
272 |
+
* _inbound.add_action( 'session_idle', session_idle_func_example, 10);
|
273 |
+
*
|
274 |
+
* function session_idle_func_example(data) {
|
275 |
+
* var data = data || {};
|
276 |
+
* // Do something when session idles
|
277 |
+
* alert('Here is a special offer for you!');
|
278 |
+
* }
|
279 |
+
* ```
|
280 |
+
*/
|
281 |
+
session_idle: function(clockTime) {
|
282 |
+
fireEvent('session_idle', clockTime);
|
283 |
+
},
|
284 |
+
/**
|
285 |
+
* Triggers when session is already active and gets resumed
|
286 |
+
*
|
287 |
+
* ```js
|
288 |
+
* // Usage:
|
289 |
+
*
|
290 |
+
* // Add function to 'session_resume' event
|
291 |
+
* _inbound.add_action( 'session_resume', session_resume_func_example, 10);
|
292 |
+
*
|
293 |
+
* function session_resume_func_example(data) {
|
294 |
+
* var data = data || {};
|
295 |
+
* // Session exists and is being resumed
|
296 |
+
* }
|
297 |
+
* ```
|
298 |
+
*/
|
299 |
+
session_resume: function() {
|
300 |
+
fireEvent('session_resume');
|
301 |
+
},
|
302 |
+
/**
|
303 |
+
* Session emitter. Runs every 10 seconds. This is a useful function for
|
304 |
+
* pinging third party services
|
305 |
+
*
|
306 |
+
* ```js
|
307 |
+
* // Usage:
|
308 |
+
*
|
309 |
+
* // Add session_heartbeat_func_example function to 'session_heartbeat' event
|
310 |
+
* _inbound.add_action( 'session_heartbeat', session_heartbeat_func_example, 10);
|
311 |
+
*
|
312 |
+
* function session_heartbeat_func_example(data) {
|
313 |
+
* var data = data || {};
|
314 |
+
* // Do something with every 10 seconds
|
315 |
+
* }
|
316 |
+
* ```
|
317 |
+
*/
|
318 |
+
session_heartbeat: function(clockTime) {
|
319 |
+
var data = {
|
320 |
+
'clock': clockTime,
|
321 |
+
'leadData': InboundLeadData
|
322 |
+
};
|
323 |
+
fireEvent('session_heartbeat', data);
|
324 |
+
},
|
325 |
+
/**
|
326 |
+
* Triggers Every Page View
|
327 |
+
*
|
328 |
+
* ```js
|
329 |
+
* // Usage:
|
330 |
+
*
|
331 |
+
* // Add function to 'page_visit' event
|
332 |
+
* _inbound.add_action( 'page_visit', page_visit_func_example, 10);
|
333 |
+
*
|
334 |
+
* function session_idle_func_example(pageData) {
|
335 |
+
* var pageData = pageData || {};
|
336 |
+
* if( pageData.view_count > 8 ){
|
337 |
+
* alert('Wow you have been to this page more than 8 times.');
|
338 |
+
* }
|
339 |
+
* }
|
340 |
+
* ```
|
341 |
+
*/
|
342 |
+
page_visit: function(pageData) {
|
343 |
+
fireEvent('page_view', pageData);
|
344 |
+
},
|
345 |
+
/**
|
346 |
+
* Triggers If the visitor has never seen the page before
|
347 |
+
*
|
348 |
+
* ```js
|
349 |
+
* // Usage:
|
350 |
+
*
|
351 |
+
* // Add function to 'page_first_visit' event
|
352 |
+
* _inbound.add_action( 'page_first_visit', page_first_visit_func_example, 10);
|
353 |
+
*
|
354 |
+
* function page_first_visit_func_example(pageData) {
|
355 |
+
* var pageData = pageData || {};
|
356 |
+
* alert('Welcome to this page! Its the first time you have seen it')
|
357 |
+
* }
|
358 |
+
* ```
|
359 |
+
*/
|
360 |
+
page_first_visit: function(pageData) {
|
361 |
+
fireEvent('page_first_visit');
|
362 |
+
_inbound.deBugger('pages', 'First Ever Page View of this Page');
|
363 |
+
},
|
364 |
+
/**
|
365 |
+
* Triggers If the visitor has seen the page before
|
366 |
+
*
|
367 |
+
* ```js
|
368 |
+
* // Usage:
|
369 |
+
*
|
370 |
+
* // Add function to 'page_revisit' event
|
371 |
+
* _inbound.add_action( 'page_revisit', page_revisit_func_example, 10);
|
372 |
+
*
|
373 |
+
* function page_revisit_func_example(pageData) {
|
374 |
+
* var pageData = pageData || {};
|
375 |
+
* alert('Welcome back to this page!');
|
376 |
+
* // Show visitor special content/offer
|
377 |
+
* }
|
378 |
+
* ```
|
379 |
+
*/
|
380 |
+
page_revisit: function(pageData) {
|
381 |
+
|
382 |
+
fireEvent('page_revisit', pageData);
|
383 |
+
|
384 |
+
var logger = function() {
|
385 |
+
console.log('pageData', pageData);
|
386 |
+
console.log('Page Revisit viewed ' + pageData + " times");
|
387 |
+
}
|
388 |
+
_inbound.deBugger('pages', status, logger);
|
389 |
+
},
|
390 |
+
|
391 |
+
/**
|
392 |
+
* `tab_hidden` is triggered when the visitor switches browser tabs
|
393 |
+
*
|
394 |
+
* ```js
|
395 |
+
* // Usage:
|
396 |
+
*
|
397 |
+
* // Adding the callback
|
398 |
+
* function tab_hidden_function( data ) {
|
399 |
+
* alert('The Tab is Hidden');
|
400 |
+
* };
|
401 |
+
*
|
402 |
+
* // Hook the function up the the `tab_hidden` event
|
403 |
+
* _inbound.add_action( 'tab_hidden', tab_hidden_function, 10 );
|
404 |
+
* ```
|
405 |
+
*/
|
406 |
+
tab_hidden: function(data) {
|
407 |
+
_inbound.deBugger('pages', 'Tab Hidden');
|
408 |
+
fireEvent('tab_hidden');
|
409 |
+
},
|
410 |
+
/**
|
411 |
+
* `tab_visible` is triggered when the visitor switches back to the sites tab
|
412 |
+
*
|
413 |
+
* ```js
|
414 |
+
* // Usage:
|
415 |
+
*
|
416 |
+
* // Adding the callback
|
417 |
+
* function tab_visible_function( data ) {
|
418 |
+
* alert('Welcome back to this tab!');
|
419 |
+
* // trigger popup or offer special discount etc.
|
420 |
+
* };
|
421 |
+
*
|
422 |
+
* // Hook the function up the the `tab_visible` event
|
423 |
+
* _inbound.add_action( 'tab_visible', tab_visible_function, 10 );
|
424 |
+
* ```
|
425 |
+
*/
|
426 |
+
tab_visible: function(data) {
|
427 |
+
_inbound.deBugger('pages', 'Tab Visible');
|
428 |
+
fireEvent('tab_visible');
|
429 |
+
},
|
430 |
+
/**
|
431 |
+
* `tab_mouseout` is triggered when the visitor mouses out of the browser window.
|
432 |
+
* This is especially useful for exit popups
|
433 |
+
*
|
434 |
+
* ```js
|
435 |
+
* // Usage:
|
436 |
+
*
|
437 |
+
* // Adding the callback
|
438 |
+
* function tab_mouseout_function( data ) {
|
439 |
+
* alert("Wait don't Go");
|
440 |
+
* // trigger popup or offer special discount etc.
|
441 |
+
* };
|
442 |
+
*
|
443 |
+
* // Hook the function up the the `tab_mouseout` event
|
444 |
+
* _inbound.add_action( 'tab_mouseout', tab_mouseout_function, 10 );
|
445 |
+
* ```
|
446 |
+
*/
|
447 |
+
tab_mouseout: function(data) {
|
448 |
+
_inbound.deBugger('pages', 'Tab Mouseout');
|
449 |
+
fireEvent('tab_mouseout');
|
450 |
+
},
|
451 |
+
/**
|
452 |
+
* `form_input_change` is triggered when tracked form inputs change
|
453 |
+
* You can use this to add additional validation or set conditional triggers
|
454 |
+
*
|
455 |
+
* ```js
|
456 |
+
* // Usage:
|
457 |
+
*
|
458 |
+
* ```
|
459 |
+
*/
|
460 |
+
form_input_change: function(inputData) {
|
461 |
+
var logger = function() {
|
462 |
+
console.log(inputData);
|
463 |
+
//console.log('Page Revisit viewed ' + pageData + " times");
|
464 |
+
}
|
465 |
+
_inbound.deBugger('forms', 'inputData change. Data=', logger);
|
466 |
+
fireEvent('form_input_change', inputData);
|
467 |
+
},
|
468 |
+
/**
|
469 |
+
* `form_before_submission` is triggered before the form is submitted to the server.
|
470 |
+
* You can filter the data here or send it to third party services
|
471 |
+
*
|
472 |
+
* ```js
|
473 |
+
* // Usage:
|
474 |
+
*
|
475 |
+
* // Adding the callback
|
476 |
+
* function form_before_submission_function( data ) {
|
477 |
+
* var data = data || {};
|
478 |
+
* // filter form data
|
479 |
+
* };
|
480 |
+
*
|
481 |
+
* // Hook the function up the the `form_before_submission` event
|
482 |
+
* _inbound.add_action( 'form_before_submission', form_before_submission_function, 10 );
|
483 |
+
* ```
|
484 |
+
*/
|
485 |
+
form_before_submission: function(formData) {
|
486 |
+
fireEvent('form_before_submission', formData);
|
487 |
+
},
|
488 |
+
/**
|
489 |
+
* `form_after_submission` is triggered after the form is submitted to the server.
|
490 |
+
* You can filter the data here or send it to third party services
|
491 |
+
*
|
492 |
+
* ```js
|
493 |
+
* // Usage:
|
494 |
+
*
|
495 |
+
* // Adding the callback
|
496 |
+
* function form_after_submission_function( data ) {
|
497 |
+
* var data = data || {};
|
498 |
+
* // filter form data
|
499 |
+
* };
|
500 |
+
*
|
501 |
+
* // Hook the function up the the `form_after_submission` event
|
502 |
+
* _inbound.add_action( 'form_after_submission', form_after_submission_function, 10 );
|
503 |
+
* ```
|
504 |
+
*/
|
505 |
+
form_after_submission: function(formData) {
|
506 |
+
|
507 |
+
fireEvent('form_after_submission', formData);
|
508 |
+
|
509 |
+
},
|
510 |
+
/**
|
511 |
+
* `search_before_caching` is triggered before the search is stored in the user's browser.
|
512 |
+
* If a lead ID is set, the search data will be saved to the server when the next page loads.
|
513 |
+
* You can filter the data here or send it to third party services
|
514 |
+
*
|
515 |
+
* ```js
|
516 |
+
* // Usage:
|
517 |
+
*
|
518 |
+
* // Adding the callback
|
519 |
+
* function search_before_caching_function( data ) {
|
520 |
+
* var data = data || {};
|
521 |
+
* // filter search data
|
522 |
+
* };
|
523 |
+
*
|
524 |
+
* // Hook the function up the the `search_before_caching` event
|
525 |
+
* _inbound.add_action( 'search_before_caching', search_before_caching_function, 10 );
|
526 |
+
* ```
|
527 |
+
*/
|
528 |
+
search_before_caching: function(searchData) {
|
529 |
+
fireEvent('search_before_caching', searchData);
|
530 |
+
},
|
531 |
+
/*! Scrol depth https://github.com/robflaherty/jquery-scrolldepth/blob/master/jquery.scrolldepth.js */
|
532 |
+
|
533 |
+
analyticsError: function(MLHttpRequest, textStatus, errorThrown) {
|
534 |
+
var error = new CustomEvent("inbound_analytics_error", {
|
535 |
+
detail: {
|
536 |
+
MLHttpRequest: MLHttpRequest,
|
537 |
+
textStatus: textStatus,
|
538 |
+
errorThrown: errorThrown
|
539 |
+
}
|
540 |
+
});
|
541 |
+
window.dispatchEvent(error);
|
542 |
+
console.log('Page Save Error');
|
543 |
+
}
|
544 |
+
|
545 |
+
};
|
546 |
+
|
547 |
+
return _inbound;
|
548 |
+
|
549 |
+
})(_inbound || {});
|
550 |
+
|
551 |
+
|
552 |
+
function inboundFormNoRedirect(){
|
553 |
+
/*button == the button that was clicked, form == the form that button belongs to, formRedirectUrl == the link that the form redirects to, if set*/
|
554 |
+
|
555 |
+
/*Get the button...*/
|
556 |
+
/*If not an iframe*/
|
557 |
+
if(window.frames.frameElement == null){
|
558 |
+
var button = document.querySelectorAll('button.inbound-button-submit[disabled]')[0];
|
559 |
+
}
|
560 |
+
/*If it is an iframe*/
|
561 |
+
else if(window.frames.frameElement.tagName.toLowerCase() == "iframe"){
|
562 |
+
var button = window.frames.frameElement.contentWindow.document.querySelectorAll('button.inbound-button-submit')[0];
|
563 |
+
}
|
564 |
+
|
565 |
+
if ( typeof button == 'undefined' ) {
|
566 |
+
return;
|
567 |
+
}
|
568 |
+
|
569 |
+
var form = button.form,
|
570 |
+
formRedirectUrl = form.querySelectorAll('input[value][type="hidden"][name="inbound_furl"]:not([value=""])');
|
571 |
+
|
572 |
+
/*If the redirect link is not set, or there is a single space in it, the form isn't supposed to redirect. So set the action for void*/
|
573 |
+
if(formRedirectUrl.length == 0 || formRedirectUrl[0]['value'] == 'IA=='){
|
574 |
+
form.action = 'javascript:void(0)';
|
575 |
+
}
|
576 |
+
}
|
577 |
+
|
578 |
+
_inbound.add_action( 'form_before_submission', inboundFormNoRedirect, 10 );
|
579 |
+
|
580 |
+
function inboundFormNoRedirectContent(){
|
581 |
+
|
582 |
+
/*If not an iframe*/
|
583 |
+
if(window.frames.frameElement == null){
|
584 |
+
var button = document.querySelectorAll('button.inbound-button-submit[disabled]')[0];
|
585 |
+
}
|
586 |
+
/*If it is an iframe*/
|
587 |
+
else if(window.frames.frameElement.tagName.toLowerCase() == "iframe"){
|
588 |
+
var button = window.frames.frameElement.contentWindow.document.querySelectorAll('button.inbound-button-submit')[0];
|
589 |
+
}
|
590 |
+
|
591 |
+
|
592 |
+
if ( typeof button == 'undefined' ) {
|
593 |
+
return;
|
594 |
+
}
|
595 |
+
|
596 |
+
var form = button.form,
|
597 |
+
formRedirectUrl = form.querySelectorAll('input[value][type="hidden"][name="inbound_furl"]:not([value=""])'),
|
598 |
+
btnBackground = jQuery(button).css('background'),
|
599 |
+
btnFontColor = jQuery(button).css('color'),
|
600 |
+
btnHeight = jQuery(button).css('height'),
|
601 |
+
spinner = button.getElementsByClassName('inbound-form-spinner');
|
602 |
+
|
603 |
+
if(formRedirectUrl.length == 0 || formRedirectUrl[0]['value'] == 'IA=='){
|
604 |
+
jQuery(spinner).remove();
|
605 |
+
jQuery(button).prepend('<div id="redir-check"><i class="fa fa-check-square" aria-hidden="true" style="background='+ btnBackground +'; color='+ btnFontColor +'; font-size:calc('+ btnHeight +' * .42);"></i></div>');
|
606 |
+
}
|
607 |
+
}
|
608 |
+
|
609 |
+
_inbound.add_action( 'form_after_submission', inboundFormNoRedirectContent, 10 );
|
shared/assets/js/frontend/analytics-src/analytics.forms.js
CHANGED
@@ -1,1207 +1,1207 @@
|
|
1 |
-
/**
|
2 |
-
* # Inbound Forms
|
3 |
-
*
|
4 |
-
* This file contains all of the form functions of the main _inbound object.
|
5 |
-
* Filters and actions are described below
|
6 |
-
*
|
7 |
-
* @
|
8 |
-
* @
|
9 |
-
* @version 0.0.2
|
10 |
-
*/
|
11 |
-
/* Finish Exclusions for CC */
|
12 |
-
|
13 |
-
/* Launches form class */
|
14 |
-
var InboundForms = (function(_inbound) {
|
15 |
-
|
16 |
-
var debugMode = false,
|
17 |
-
utils = _inbound.Utils,
|
18 |
-
no_match = [],
|
19 |
-
rawParams = [],
|
20 |
-
mappedParams = [],
|
21 |
-
callTracker = {},
|
22 |
-
settings = _inbound.Settings;
|
23 |
-
|
24 |
-
var FieldMapArray = [
|
25 |
-
"first name",
|
26 |
-
"last name",
|
27 |
-
"name",
|
28 |
-
"email",
|
29 |
-
"e-mail",
|
30 |
-
"phone",
|
31 |
-
"website",
|
32 |
-
"job title",
|
33 |
-
"your favorite food",
|
34 |
-
"company",
|
35 |
-
"tele",
|
36 |
-
"address",
|
37 |
-
"comment"
|
38 |
-
/* Adding values here maps them */
|
39 |
-
];
|
40 |
-
|
41 |
-
_inbound.Forms = {
|
42 |
-
|
43 |
-
// Init Form functions
|
44 |
-
init: function() {
|
45 |
-
_inbound.Forms.runFieldMappingFilters();
|
46 |
-
_inbound.Forms.formTrackInit();
|
47 |
-
_inbound.Forms.searchTrackInit();
|
48 |
-
},
|
49 |
-
/**
|
50 |
-
* This triggers the forms.field_map filter on the mapping array.
|
51 |
-
* This will allow you to add or remore Items from the mapping lookup
|
52 |
-
*
|
53 |
-
* ### Example inbound.form_map_before filter
|
54 |
-
*
|
55 |
-
* This is an example of how form mapping can be filtered and
|
56 |
-
* additional fields can be mapped via javascript
|
57 |
-
*
|
58 |
-
* ```js
|
59 |
-
* // Adding the filter function
|
60 |
-
* function Inbound_Add_Filter_Example( FieldMapArray ) {
|
61 |
-
* var map = FieldMapArray || [];
|
62 |
-
* map.push('new lookup value');
|
63 |
-
*
|
64 |
-
* return map;
|
65 |
-
* };
|
66 |
-
*
|
67 |
-
* // Adding the filter on dom ready
|
68 |
-
* _inbound.hooks.addFilter( 'inbound.form_map_before', Inbound_Add_Filter_Example, 10 );
|
69 |
-
* ```
|
70 |
-
*
|
71 |
-
* @return {[type]} [description]
|
72 |
-
*/
|
73 |
-
runFieldMappingFilters: function() {
|
74 |
-
FieldMapArray = _inbound.hooks.applyFilters('forms.field_map', FieldMapArray);
|
75 |
-
//alert(FieldMapArray);
|
76 |
-
},
|
77 |
-
debug: function(msg, callback) {
|
78 |
-
//if app not in debug mode, exit immediately
|
79 |
-
if (!debugMode || !console) {
|
80 |
-
return;
|
81 |
-
}
|
82 |
-
|
83 |
-
var msg = msg || false;
|
84 |
-
//console.log the message
|
85 |
-
if (msg && (typeof msg === 'string')) {
|
86 |
-
console.log(msg);
|
87 |
-
}
|
88 |
-
|
89 |
-
//execute the callback if one was passed-in
|
90 |
-
if (callback && (callback instanceof Function)) {
|
91 |
-
callback();
|
92 |
-
}
|
93 |
-
},
|
94 |
-
formTrackInit: function() {
|
95 |
-
|
96 |
-
for (var i = 0; i < window.document.forms.length; i++) {
|
97 |
-
var trackForm = false;
|
98 |
-
var form = window.document.forms[i];
|
99 |
-
/* process forms only once */
|
100 |
-
if (!form.dataset.formProcessed) {
|
101 |
-
form.dataset.formProcessed = true;
|
102 |
-
trackForm = this.checkTrackStatus(form);
|
103 |
-
if (trackForm) {
|
104 |
-
this.attachFormSubmitEvent(form); /* attach form listener */
|
105 |
-
this.initFormMapping(form);
|
106 |
-
}
|
107 |
-
}
|
108 |
-
}
|
109 |
-
},
|
110 |
-
searchTrackInit: function(){
|
111 |
-
|
112 |
-
/* exit if searches aren't supposed to be tracked, or this function has already been called */
|
113 |
-
if(inbound_settings.search_tracking == 'off' || callTracker['searchTrackInit']){
|
114 |
-
return;
|
115 |
-
}
|
116 |
-
|
117 |
-
for (var i = 0; i < window.document.forms.length; i++) {
|
118 |
-
var trackForm = false;
|
119 |
-
var form = window.document.forms[i];
|
120 |
-
/* process forms only once */
|
121 |
-
if (!form.dataset.searchChecked) {
|
122 |
-
form.dataset.searchChecked = true;
|
123 |
-
trackForm = this.checkSearchTrackStatus(form);
|
124 |
-
if (trackForm) {
|
125 |
-
this.attachSearchFormSubmitEvent(form); /* attach form listener */
|
126 |
-
}
|
127 |
-
}
|
128 |
-
}
|
129 |
-
|
130 |
-
/* store the search data on init */
|
131 |
-
utils.storeSearchData();
|
132 |
-
|
133 |
-
/* log that this function has been called */
|
134 |
-
callTracker['searchTrackInit'] = true;
|
135 |
-
},
|
136 |
-
checkTrackStatus: function(form) {
|
137 |
-
var ClassIs = form.getAttribute('class');
|
138 |
-
if (ClassIs !== "" && ClassIs !== null) {
|
139 |
-
if (ClassIs.toLowerCase().indexOf("wpl-track-me") > -1) {
|
140 |
-
return true;
|
141 |
-
} else if (ClassIs.toLowerCase().indexOf("inbound-track") > -1) {
|
142 |
-
return true;
|
143 |
-
} else {
|
144 |
-
cb = function() { console.log(form); };
|
145 |
-
_inbound.deBugger('forms', "This form not tracked. Please assign on in settings...", cb);
|
146 |
-
return false;
|
147 |
-
}
|
148 |
-
}
|
149 |
-
},
|
150 |
-
checkSearchTrackStatus: function(form) {
|
151 |
-
var ClassIs = form.getAttribute('class'),
|
152 |
-
IdIs = form.getAttribute('id');
|
153 |
-
if (ClassIs !== "" && ClassIs !== null) {
|
154 |
-
if (ClassIs.toLowerCase().indexOf("search") > -1) {
|
155 |
-
return true;
|
156 |
-
}
|
157 |
-
}
|
158 |
-
if (IdIs !== "" && IdIs !== null) {
|
159 |
-
if (IdIs.toLowerCase().indexOf("search") > -1) {
|
160 |
-
return true;
|
161 |
-
}
|
162 |
-
}else{
|
163 |
-
cb = function() { console.log(form); };
|
164 |
-
_inbound.deBugger('searches', "This search form is not tracked. Please assign on in settings...", cb);
|
165 |
-
return false;
|
166 |
-
}
|
167 |
-
},
|
168 |
-
/* Loop through include/exclude items for tracking */
|
169 |
-
loopClassSelectors: function(selectors, action) {
|
170 |
-
for (var i = selectors.length - 1; i >= 0; i--) {
|
171 |
-
|
172 |
-
var selector = utils.trim(selectors[i])
|
173 |
-
if (selector.indexOf("#") === -1 && selector.indexOf(".") === -1) {
|
174 |
-
// assign ID as default
|
175 |
-
selector = "#" + selector;
|
176 |
-
}
|
177 |
-
//if(selectors[i] match . or # )
|
178 |
-
selector = document.querySelector(selector);
|
179 |
-
//console.log("SELECTOR", selector);
|
180 |
-
if (selector) {
|
181 |
-
if (action === 'add') {
|
182 |
-
_inbound.Utils.addClass('wpl-track-me', selector);
|
183 |
-
_inbound.Utils.addClass('inbound-track', selector);
|
184 |
-
} else {
|
185 |
-
_inbound.Utils.removeClass('wpl-track-me', selector);
|
186 |
-
_inbound.Utils.removeClass('inbound-track', selector);
|
187 |
-
}
|
188 |
-
}
|
189 |
-
}
|
190 |
-
},
|
191 |
-
/* Map field fields on load */
|
192 |
-
initFormMapping: function(form) {
|
193 |
-
var hiddenInputs = [];
|
194 |
-
|
195 |
-
for (var i = 0; i < form.elements.length; i++) {
|
196 |
-
formInput = form.elements[i];
|
197 |
-
|
198 |
-
if (formInput.type === 'hidden') {
|
199 |
-
hiddenInputs.push(formInput);
|
200 |
-
continue;
|
201 |
-
}
|
202 |
-
|
203 |
-
//this.ignoreFields(formInput);
|
204 |
-
/* Map form fields */
|
205 |
-
this.mapField(formInput);
|
206 |
-
/* Remember visible inputs */
|
207 |
-
this.rememberInputValues(formInput);
|
208 |
-
/* Fill visible inputs */
|
209 |
-
if (settings.formAutoPopulation && !_inbound.Utils.hasClass( "nopopulate", form ) ) {
|
210 |
-
this.fillInputValues(formInput);
|
211 |
-
}
|
212 |
-
|
213 |
-
}
|
214 |
-
|
215 |
-
/* loop hidden inputs */
|
216 |
-
for (var n = hiddenInputs.length - 1; n >= 0; n--) {
|
217 |
-
formInput = hiddenInputs[n];
|
218 |
-
this.mapField(formInput);
|
219 |
-
}
|
220 |
-
|
221 |
-
//console.log('mapping on load completed');
|
222 |
-
},
|
223 |
-
/* Maps data attributes to fields on page load */
|
224 |
-
mapField: function(input) {
|
225 |
-
|
226 |
-
var input_id = input.id || false;
|
227 |
-
var input_name = input.name || false;
|
228 |
-
var label = this.getInputLabel(input);
|
229 |
-
|
230 |
-
if(label){
|
231 |
-
//console.log(label[0].innerText);
|
232 |
-
var ignoreField = this.ignoreFieldByLabel(label[0].innerText);
|
233 |
-
if(ignoreField){
|
234 |
-
input.dataset.ignoreFormField = true;
|
235 |
-
return false;
|
236 |
-
}
|
237 |
-
}
|
238 |
-
|
239 |
-
/* Loop through all match possiblities */
|
240 |
-
for (i = 0; i < FieldMapArray.length; i++) {
|
241 |
-
//for (var i = FieldMapArray.length - 1; i >= 0; i--) {
|
242 |
-
var found = false;
|
243 |
-
var match = FieldMapArray[i];
|
244 |
-
var lookingFor = utils.trim(match);
|
245 |
-
var nice_name = lookingFor.replace(/ /g, '_');
|
246 |
-
|
247 |
-
|
248 |
-
//console.log("NICE NAME", nice_name);
|
249 |
-
//console.log('looking for match on ' + lookingFor);
|
250 |
-
//_inbound.deBugger('forms', 'looking for match on ' + lookingFor + " nice_name= " + nice_name);
|
251 |
-
|
252 |
-
// Check if input has an attached lable using for= tag
|
253 |
-
//var $laxbel = $("label[for='" + $element.attr('id') + "']").text();
|
254 |
-
//var labxel = 'label[for="' + input_id + '"]';
|
255 |
-
|
256 |
-
/* look for name attribute match */
|
257 |
-
if (input_name && input_name.toLowerCase().indexOf(lookingFor) > -1) {
|
258 |
-
found = true;
|
259 |
-
_inbound.deBugger('forms', 'Found matching name attribute for -> ' + lookingFor);
|
260 |
-
|
261 |
-
/* look for id match */
|
262 |
-
} else if (input_id && input_id.toLowerCase().indexOf(lookingFor) > -1) {
|
263 |
-
|
264 |
-
found = true;
|
265 |
-
_inbound.deBugger('forms', 'Found matching ID attribute for ->' + lookingFor);
|
266 |
-
|
267 |
-
/* Check siblings for label */
|
268 |
-
} else if (label) {
|
269 |
-
//var label = (label.length > 1 ? label[0] : label);
|
270 |
-
//console.log('label', label);
|
271 |
-
if (label[0].innerText.toLowerCase().indexOf(lookingFor) > -1) {
|
272 |
-
|
273 |
-
found = true;
|
274 |
-
_inbound.deBugger('forms', 'Found matching sibling label for -> ' + lookingFor);
|
275 |
-
|
276 |
-
}
|
277 |
-
|
278 |
-
} else {
|
279 |
-
/* no match found */
|
280 |
-
//_inbound.deBugger('forms', 'NO Match on ' + lookingFor + " in " + input_name);
|
281 |
-
no_match.push(lookingFor);
|
282 |
-
|
283 |
-
}
|
284 |
-
|
285 |
-
/* Map the field */
|
286 |
-
if (found) {
|
287 |
-
this.addDataAttr(input, nice_name);
|
288 |
-
this.removeArrayItem(FieldMapArray, lookingFor);
|
289 |
-
i--; //decrement count
|
290 |
-
}
|
291 |
-
|
292 |
-
}
|
293 |
-
|
294 |
-
return inbound_data;
|
295 |
-
|
296 |
-
},
|
297 |
-
/* prevent default submission temporarily */
|
298 |
-
formListener: function(event) {
|
299 |
-
//console.log(event);
|
300 |
-
event.preventDefault();
|
301 |
-
_inbound.Forms.saveFormData(event.target);
|
302 |
-
document.body.style.cursor = "wait";
|
303 |
-
},
|
304 |
-
/* prevent default submission temporarily */
|
305 |
-
searchFormListener: function(event) {
|
306 |
-
//console.log(event);
|
307 |
-
event.preventDefault();
|
308 |
-
_inbound.Forms.saveSearchData(event.target);
|
309 |
-
//document.body.style.cursor = "wait";
|
310 |
-
},
|
311 |
-
/* attach form listeners */
|
312 |
-
attachFormSubmitEvent: function(form) {
|
313 |
-
utils.addListener(form, 'submit', this.formListener);
|
314 |
-
var email_input = document.querySelector('.inbound-email');
|
315 |
-
/* utils.addListener(email_input, 'blur', this.mailCheck); */
|
316 |
-
},
|
317 |
-
/* attach search form listener */
|
318 |
-
attachSearchFormSubmitEvent: function(form) {
|
319 |
-
utils.addListener(form, 'submit', this.searchFormListener);
|
320 |
-
},
|
321 |
-
/* Ignore CC data */
|
322 |
-
ignoreFieldByLabel: function(label) {
|
323 |
-
var ignore_field = false;
|
324 |
-
|
325 |
-
if(!label){ return false; }
|
326 |
-
|
327 |
-
// Ignore any fields with labels that indicate a credit card field
|
328 |
-
if (label.toLowerCase().indexOf('credit card') != -1 || label.toLowerCase().indexOf('card number') != -1) {
|
329 |
-
ignore_field = true;
|
330 |
-
}
|
331 |
-
|
332 |
-
if (label.toLowerCase().indexOf('expiration') != -1 || label.toLowerCase().indexOf('expiry') != -1) {
|
333 |
-
ignore_field = true;
|
334 |
-
}
|
335 |
-
|
336 |
-
if (label.toLowerCase() == 'month' || label.toLowerCase() == 'mm' || label.toLowerCase() == 'yy' || label.toLowerCase() == 'yyyy' || label.toLowerCase() == 'year') {
|
337 |
-
ignore_field = true;
|
338 |
-
}
|
339 |
-
|
340 |
-
if (label.toLowerCase().indexOf('cvv') != -1 || label.toLowerCase().indexOf('cvc') != -1 || label.toLowerCase().indexOf('secure code') != -1 || label.toLowerCase().indexOf('security code') != -1) {
|
341 |
-
ignore_field = true;
|
342 |
-
}
|
343 |
-
|
344 |
-
if(ignore_field){
|
345 |
-
_inbound.deBugger('forms', 'ignore ' + label);
|
346 |
-
}
|
347 |
-
|
348 |
-
return ignore_field;
|
349 |
-
|
350 |
-
},
|
351 |
-
/* not implemented yet */
|
352 |
-
ignoreFieldByValue: function(value){
|
353 |
-
var ignore_field = false;
|
354 |
-
|
355 |
-
if(!value){ return false; }
|
356 |
-
|
357 |
-
if (value.toLowerCase() == 'visa' || value.toLowerCase() == 'mastercard' || value.toLowerCase() == 'american express' || value.toLowerCase() == 'amex' || value.toLowerCase() == 'discover') {
|
358 |
-
ignore_field = true;
|
359 |
-
}
|
360 |
-
|
361 |
-
// Check if value has integers, strip out spaces, then ignore anything with a credit card length (>16) or an expiration/cvv length (<5)
|
362 |
-
var int_regex = new RegExp("/^[0-9]+$/");
|
363 |
-
if (int_regex.test(value)) {
|
364 |
-
var value_no_spaces = value.replace(' ', '');
|
365 |
-
|
366 |
-
if (this.isInt(value_no_spaces) && value_no_spaces.length >= 16) {
|
367 |
-
ignore_field = true;
|
368 |
-
}
|
369 |
-
|
370 |
-
}
|
371 |
-
|
372 |
-
return ignore_field;
|
373 |
-
|
374 |
-
},
|
375 |
-
isInt: function(n) {
|
376 |
-
return typeof n == "number" && isFinite(n) && n % 1 === 0;
|
377 |
-
},
|
378 |
-
releaseFormSubmit: function(form) {
|
379 |
-
//console.log('remove form listener event');
|
380 |
-
document.body.style.cursor = "default";
|
381 |
-
utils.removeClass('wpl-track-me', form);
|
382 |
-
utils.removeListener(form, 'submit', this.formListener);
|
383 |
-
var formClass = form.getAttribute('class');
|
384 |
-
if (formClass !== "" && formClass !== null) {
|
385 |
-
/* If contact form 7 do this */
|
386 |
-
if (formClass.toLowerCase().indexOf("wpcf7-form") != -1) {
|
387 |
-
//alert('release')
|
388 |
-
setTimeout(function() {
|
389 |
-
document.body.style.cursor = "default";
|
390 |
-
}, 300);
|
391 |
-
return true;
|
392 |
-
}
|
393 |
-
}
|
394 |
-
|
395 |
-
form.submit();
|
396 |
-
/* fallback if submit name="submit" */
|
397 |
-
setTimeout(function() {
|
398 |
-
for (var i = 0; i < form.elements.length; i++) {
|
399 |
-
formInput = form.elements[i];
|
400 |
-
type = formInput.type || false;
|
401 |
-
if (type === "submit" && formInput.name === "submit") {
|
402 |
-
form.elements[i].click();
|
403 |
-
}
|
404 |
-
}
|
405 |
-
}, 2000);
|
406 |
-
|
407 |
-
},
|
408 |
-
saveFormData: function(form) {
|
409 |
-
var inputsObject = inputsObject || {};
|
410 |
-
for (var i = 0; i < form.elements.length; i++) {
|
411 |
-
|
412 |
-
// console.log(inputsObject);
|
413 |
-
|
414 |
-
formInput = form.elements[i];
|
415 |
-
multiple = false;
|
416 |
-
|
417 |
-
if (formInput.name) {
|
418 |
-
|
419 |
-
if (formInput.dataset.ignoreFormField) {
|
420 |
-
_inbound.deBugger('forms', 'ignore ' + formInput.name);
|
421 |
-
continue;
|
422 |
-
}
|
423 |
-
|
424 |
-
inputName = formInput.name.replace(/\[([^\[]*)\]/g, "%5B%5D$1");
|
425 |
-
//inputName = inputName.replace(/-/g, "_");
|
426 |
-
if (!inputsObject[inputName]) {
|
427 |
-
inputsObject[inputName] = {};
|
428 |
-
}
|
429 |
-
if (formInput.type) {
|
430 |
-
inputsObject[inputName]['type'] = formInput.type;
|
431 |
-
}
|
432 |
-
if (!inputsObject[inputName]['name']) {
|
433 |
-
inputsObject[inputName]['name'] = formInput.name;
|
434 |
-
}
|
435 |
-
if (formInput.dataset.mapFormField) {
|
436 |
-
inputsObject[inputName]['map'] = formInput.dataset.mapFormField;
|
437 |
-
}
|
438 |
-
|
439 |
-
|
440 |
-
switch (formInput.nodeName) {
|
441 |
-
|
442 |
-
case 'INPUT':
|
443 |
-
value = this.getInputValue(formInput);
|
444 |
-
|
445 |
-
|
446 |
-
if (value === false) {
|
447 |
-
continue;
|
448 |
-
}
|
449 |
-
break;
|
450 |
-
|
451 |
-
case 'TEXTAREA':
|
452 |
-
value = formInput.value;
|
453 |
-
break;
|
454 |
-
|
455 |
-
case 'SELECT':
|
456 |
-
if (formInput.multiple) {
|
457 |
-
values = [];
|
458 |
-
multiple = true;
|
459 |
-
|
460 |
-
for (var j = 0; j < formInput.length; j++) {
|
461 |
-
if (formInput[j].selected) {
|
462 |
-
values.push(encodeURIComponent(formInput[j].value));
|
463 |
-
}
|
464 |
-
}
|
465 |
-
|
466 |
-
} else {
|
467 |
-
value = (formInput.value);
|
468 |
-
}
|
469 |
-
|
470 |
-
break;
|
471 |
-
}
|
472 |
-
|
473 |
-
_inbound.deBugger('forms', 'Input Value = ' + value);
|
474 |
-
|
475 |
-
|
476 |
-
if (value) {
|
477 |
-
/* inputsObject[inputName].push(multiple ? values.join(',') : encodeURIComponent(value)); */
|
478 |
-
if (!inputsObject[inputName]['value']) {
|
479 |
-
inputsObject[inputName]['value'] = [];
|
480 |
-
}
|
481 |
-
inputsObject[inputName]['value'].push(multiple ? values.join(',') : encodeURIComponent(value));
|
482 |
-
var value = multiple ? values.join(',') : encodeURIComponent(value);
|
483 |
-
|
484 |
-
}
|
485 |
-
|
486 |
-
}
|
487 |
-
}
|
488 |
-
_inbound.deBugger('forms', inputsObject);
|
489 |
-
|
490 |
-
//console.log('These are the raw values', inputsObject);
|
491 |
-
//_inbound.totalStorage('the_key', inputsObject);
|
492 |
-
//var inputsObject = sortInputs(inputsObject);
|
493 |
-
|
494 |
-
var matchCommon = /name|first name|last name|email|e-mail|phone|website|job title|company|tele|address|comment/;
|
495 |
-
|
496 |
-
for (var input in inputsObject) {
|
497 |
-
//console.log(input);
|
498 |
-
|
499 |
-
var inputValue = inputsObject[input]['value'];
|
500 |
-
var inputMappedField = inputsObject[input]['map'];
|
501 |
-
//if (matchCommon.test(input) !== false) {
|
502 |
-
//console.log(input + " Matches Regex run mapping test");
|
503 |
-
//var map = inputsObject[input];
|
504 |
-
//console.log("MAPP", map);
|
505 |
-
//mappedParams.push( input + '=' + inputsObject[input]['value'].join(',') );
|
506 |
-
//}
|
507 |
-
|
508 |
-
/* Add custom hook here to look for additional values */
|
509 |
-
if (typeof(inputValue) != "undefined" && inputValue != null && inputValue != "") {
|
510 |
-
rawParams.push(input + '=' + inputsObject[input]['value'].join(','));
|
511 |
-
}
|
512 |
-
|
513 |
-
if (typeof(inputMappedField) != "undefined" && inputMappedField != null && inputsObject[input]['value']) {
|
514 |
-
//console.log('Data ATTR', formInput.dataset.mapFormField);
|
515 |
-
mappedParams.push(inputMappedField + "=" + inputsObject[input]['value'].join(','));
|
516 |
-
if (input === 'email') {
|
517 |
-
var email = inputsObject[input]['value'].join(',');
|
518 |
-
//alert(email);
|
519 |
-
|
520 |
-
}
|
521 |
-
}
|
522 |
-
}
|
523 |
-
|
524 |
-
var raw_params = rawParams.join('&');
|
525 |
-
_inbound.deBugger('forms', "Stringified Raw Form PARAMS: " + raw_params);
|
526 |
-
|
527 |
-
var mapped_params = mappedParams.join('&');
|
528 |
-
_inbound.deBugger('forms', "Stringified Mapped PARAMS" + mapped_params);
|
529 |
-
|
530 |
-
/* Check Use form Email or Cookie */
|
531 |
-
var email = utils.getParameterVal('email', mapped_params) || utils.readCookie('wp_lead_email');
|
532 |
-
|
533 |
-
/* Legacy Email map */
|
534 |
-
if (!email) {
|
535 |
-
email = utils.getParameterVal('wpleads_email_address', mapped_params);
|
536 |
-
}
|
537 |
-
|
538 |
-
var fullName = utils.getParameterVal('name', mapped_params);
|
539 |
-
var fName = utils.getParameterVal('first_name', mapped_params);
|
540 |
-
var lName = utils.getParameterVal('last_name', mapped_params);
|
541 |
-
|
542 |
-
// Fallbacks for empty values
|
543 |
-
if (!lName && fName) {
|
544 |
-
var parts = decodeURI(fName).split(" ");
|
545 |
-
if (parts.length > 0) {
|
546 |
-
fName = parts[0];
|
547 |
-
lName = parts[1];
|
548 |
-
}
|
549 |
-
}
|
550 |
-
|
551 |
-
if (fullName && !lName && !fName) {
|
552 |
-
var parts = decodeURI(fullName).split(" ");
|
553 |
-
if (parts.length > 0) {
|
554 |
-
fName = parts[0];
|
555 |
-
lName = parts[1];
|
556 |
-
}
|
557 |
-
}
|
558 |
-
|
559 |
-
fullName = (fName && lName) ? fName + " " + lName : fullName;
|
560 |
-
|
561 |
-
if(!fName) { fName = ""; }
|
562 |
-
if(!lName) { lName = ""; }
|
563 |
-
|
564 |
-
_inbound.deBugger('forms', "fName = " + fName);
|
565 |
-
_inbound.deBugger('forms', "lName = " + lName);
|
566 |
-
_inbound.deBugger('forms', "fullName = " + fullName);
|
567 |
-
|
568 |
-
//return false;
|
569 |
-
var page_views = _inbound.totalStorage('page_views') || {};
|
570 |
-
var urlParams = _inbound.totalStorage('inbound_url_params') || {};
|
571 |
-
|
572 |
-
/* check if redirect url is empty */
|
573 |
-
var formRedirectUrl = form.querySelectorAll('input[value][type="hidden"][name="inbound_furl"]:not([value=""])');
|
574 |
-
var inbound_form_is_ajax = false;
|
575 |
-
if(formRedirectUrl.length == 0 || formRedirectUrl[0]['value'] == 'IA=='){
|
576 |
-
var inbound_form_is_ajax = true;
|
577 |
-
}
|
578 |
-
|
579 |
-
/* get form id */
|
580 |
-
var inbound_form_id = form.querySelectorAll('input[value][type="hidden"][name="inbound_form_id"]');
|
581 |
-
if(inbound_form_id.length > 0 ){
|
582 |
-
inbound_form_id = inbound_form_id[0]['value'];
|
583 |
-
} else {
|
584 |
-
inbound_form_id = 0;
|
585 |
-
}
|
586 |
-
|
587 |
-
var inboundDATA = {
|
588 |
-
'email': email
|
589 |
-
};
|
590 |
-
|
591 |
-
/* Get Variation ID */
|
592 |
-
if (typeof(landing_path_info) != "undefined") {
|
593 |
-
var variation = landing_path_info.variation;
|
594 |
-
} else if (typeof(cta_path_info) != "undefined") {
|
595 |
-
var variation = cta_path_info.variation;
|
596 |
-
} else {
|
597 |
-
var variation = inbound_settings.variation_id;
|
598 |
-
}
|
599 |
-
var post_type = inbound_settings.post_type || 'page';
|
600 |
-
var page_id = inbound_settings.post_id || 0;
|
601 |
-
// data['wp_lead_uid'] = jQuery.cookie("wp_lead_uid") || null;
|
602 |
-
// data['search_data'] = JSON.stringify(jQuery.totalStorage('inbound_search')) || {};
|
603 |
-
search_data = {};
|
604 |
-
/* Filter here for raw */
|
605 |
-
formData = {
|
606 |
-
'action': 'inbound_lead_store',
|
607 |
-
'email': email,
|
608 |
-
"full_name": fullName,
|
609 |
-
"first_name": fName,
|
610 |
-
"last_name": lName,
|
611 |
-
'raw_params': raw_params,
|
612 |
-
'mapped_params': mapped_params,
|
613 |
-
'url_params': JSON.stringify(urlParams),
|
614 |
-
'search_data': 'test',
|
615 |
-
'page_views': JSON.stringify(page_views),
|
616 |
-
'post_type': post_type,
|
617 |
-
'page_id': page_id,
|
618 |
-
'variation': variation,
|
619 |
-
'source': utils.readCookie("inbound_referral_site"),
|
620 |
-
'inbound_submitted': inbound_form_is_ajax,
|
621 |
-
'inbound_form_id': inbound_form_id,
|
622 |
-
'inbound_nonce': inbound_settings.ajax_nonce,
|
623 |
-
'event': form
|
624 |
-
};
|
625 |
-
|
626 |
-
callback = function(leadID) {
|
627 |
-
/* Action Example */
|
628 |
-
|
629 |
-
_inbound.deBugger('forms', 'Lead Created with ID: ' + leadID);
|
630 |
-
leadID = parseInt(leadID, 10);
|
631 |
-
formData.leadID = leadID;
|
632 |
-
/* Set Lead cookie ID */
|
633 |
-
if (leadID) {
|
634 |
-
utils.createCookie("wp_lead_id", leadID);
|
635 |
-
_inbound.totalStorage.deleteItem('page_views'); // remove pageviews
|
636 |
-
_inbound.totalStorage.deleteItem('tracking_events'); // remove events
|
637 |
-
}
|
638 |
-
|
639 |
-
_inbound.trigger('form_after_submission', formData);
|
640 |
-
|
641 |
-
/* Resume normal form functionality */
|
642 |
-
_inbound.Forms.releaseFormSubmit(form);
|
643 |
-
|
644 |
-
}
|
645 |
-
|
646 |
-
_inbound.trigger('form_before_submission', formData);
|
647 |
-
|
648 |
-
utils.ajaxPost(inbound_settings.admin_url, formData, callback);
|
649 |
-
},
|
650 |
-
saveSearchData: function(form) {
|
651 |
-
var inputsObject = inputsObject || {};
|
652 |
-
for (var i = 0; i < form.elements.length; i++) {
|
653 |
-
|
654 |
-
//console.log(inputsObject);
|
655 |
-
|
656 |
-
formInput = form.elements[i];
|
657 |
-
multiple = false;
|
658 |
-
|
659 |
-
if (formInput.name) {
|
660 |
-
|
661 |
-
if (formInput.dataset.ignoreFormField) {
|
662 |
-
_inbound.deBugger('searches', 'ignore ' + formInput.name);
|
663 |
-
continue;
|
664 |
-
}
|
665 |
-
|
666 |
-
inputName = formInput.name.replace(/\[([^\[]*)\]/g, "%5B%5D$1");
|
667 |
-
//inputName = inputName.replace(/-/g, "_");
|
668 |
-
if (!inputsObject[inputName]) {
|
669 |
-
inputsObject[inputName] = {};
|
670 |
-
}
|
671 |
-
if (formInput.type) {
|
672 |
-
inputsObject[inputName]['type'] = formInput.type;
|
673 |
-
|
674 |
-
}
|
675 |
-
if (!inputsObject[inputName]['name']) {
|
676 |
-
inputsObject[inputName]['name'] = formInput.name;
|
677 |
-
}
|
678 |
-
if (formInput.dataset.mapFormField) {
|
679 |
-
inputsObject[inputName]['map'] = formInput.dataset.mapFormField;
|
680 |
-
}
|
681 |
-
|
682 |
-
|
683 |
-
switch (formInput.nodeName) {
|
684 |
-
|
685 |
-
case 'INPUT':
|
686 |
-
value = this.getInputValue(formInput);
|
687 |
-
|
688 |
-
|
689 |
-
if (value === false) {
|
690 |
-
continue;
|
691 |
-
}
|
692 |
-
break;
|
693 |
-
|
694 |
-
case 'TEXTAREA':
|
695 |
-
value = formInput.value;
|
696 |
-
break;
|
697 |
-
|
698 |
-
case 'SELECT':
|
699 |
-
if (formInput.multiple) {
|
700 |
-
values = [];
|
701 |
-
multiple = true;
|
702 |
-
|
703 |
-
for (var j = 0; j < formInput.length; j++) {
|
704 |
-
if (formInput[j].selected) {
|
705 |
-
values.push(encodeURIComponent(formInput[j].value));
|
706 |
-
}
|
707 |
-
}
|
708 |
-
|
709 |
-
} else {
|
710 |
-
value = (formInput.value);
|
711 |
-
}
|
712 |
-
|
713 |
-
break;
|
714 |
-
}
|
715 |
-
|
716 |
-
_inbound.deBugger('searches', 'Input Value = ' + value);
|
717 |
-
|
718 |
-
|
719 |
-
if (value) {
|
720 |
-
/* inputsObject[inputName].push(multiple ? values.join(',') : encodeURIComponent(value)); */
|
721 |
-
if (!inputsObject[inputName]['value']) {
|
722 |
-
inputsObject[inputName]['value'] = [];
|
723 |
-
}
|
724 |
-
inputsObject[inputName]['value'].push(multiple ? values.join(',') : encodeURIComponent(value));
|
725 |
-
var value = multiple ? values.join(',') : encodeURIComponent(value);
|
726 |
-
|
727 |
-
}
|
728 |
-
|
729 |
-
}
|
730 |
-
}
|
731 |
-
|
732 |
-
_inbound.deBugger('searches', inputsObject);
|
733 |
-
|
734 |
-
/* create an array of search fields //(not fully implemented) at the moment, it only maps the text in the "search" input types*/
|
735 |
-
var searchQuery = [];
|
736 |
-
for (var input in inputsObject) {
|
737 |
-
var inputValue = inputsObject[input]['value'];
|
738 |
-
var inputType = inputsObject[input]['type'];
|
739 |
-
|
740 |
-
/* Add custom hook here to look for additional values */
|
741 |
-
if (typeof(inputValue) != "undefined" && inputValue != null && inputValue != "") {
|
742 |
-
// This is for mapping all fields of a search form. The resulting string is processed
|
743 |
-
// in inbound-pro\classes\admin\report-templates\report.lead-searches-and-comments.php
|
744 |
-
// In the function print_action_popup()
|
745 |
-
// searchQuery.push(input + '|value|' + inputsObject[input]['value'].join(','));
|
746 |
-
|
747 |
-
// get the search input value
|
748 |
-
if(inputType == 'search'){
|
749 |
-
searchQuery.push('search_text' + '|value|' + inputsObject[input]['value']);
|
750 |
-
}
|
751 |
-
}
|
752 |
-
}
|
753 |
-
/* exit if there isn't a search query */
|
754 |
-
if(!searchQuery[0]){
|
755 |
-
return;
|
756 |
-
}
|
757 |
-
|
758 |
-
var searchString = searchQuery.join('|field|');
|
759 |
-
_inbound.deBugger('searches', "Stringified Search Form PARAMS: " + searchString);
|
760 |
-
|
761 |
-
/* Get Variation ID */
|
762 |
-
if (typeof(landing_path_info) != "undefined") {
|
763 |
-
var variation = landing_path_info.variation;
|
764 |
-
} else if (typeof(cta_path_info) != "undefined") {
|
765 |
-
var variation = cta_path_info.variation;
|
766 |
-
} else {
|
767 |
-
var variation = inbound_settings.variation_id;
|
768 |
-
}
|
769 |
-
var post_type = inbound_settings.post_type || 'page';
|
770 |
-
var page_id = inbound_settings.post_id || 0;
|
771 |
-
|
772 |
-
var user_UID = utils.readCookie("wp_lead_uid");
|
773 |
-
|
774 |
-
/* get the user's email address if possible */
|
775 |
-
if(inbound_settings.wp_lead_data.lead_email){
|
776 |
-
email = inbound_settings.wp_lead_data.lead_email;
|
777 |
-
}else if(utils.readCookie('inbound_wpleads_email_address')){
|
778 |
-
email = utils.readCookie('inbound_wpleads_email_address');
|
779 |
-
}else{
|
780 |
-
email = '';
|
781 |
-
}
|
782 |
-
|
783 |
-
/* Filter here for raw */
|
784 |
-
searchData = {
|
785 |
-
'email': email,
|
786 |
-
'search_data': searchString,
|
787 |
-
'user_UID': user_UID,
|
788 |
-
'post_type': post_type,
|
789 |
-
'page_id': page_id,
|
790 |
-
'variation': variation,
|
791 |
-
'source': utils.readCookie("inbound_referral_site"),
|
792 |
-
'ip_address': inbound_settings.ip_address,
|
793 |
-
'timestamp': Math.floor((new Date).getTime()/1000),
|
794 |
-
};
|
795 |
-
|
796 |
-
/* filter data before caching it in the user's browser */
|
797 |
-
_inbound.trigger('search_before_caching', searchData);
|
798 |
-
|
799 |
-
/* cache search data */
|
800 |
-
if(inbound_settings.wp_lead_data.lead_id){
|
801 |
-
searchData['lead_id'] = inbound_settings.wp_lead_data.lead_id;
|
802 |
-
utils.cacheSearchData(searchData, form)
|
803 |
-
}else{
|
804 |
-
utils.cacheSearchData(searchData, form);
|
805 |
-
}
|
806 |
-
|
807 |
-
|
808 |
-
},
|
809 |
-
rememberInputValues: function(input) {
|
810 |
-
var name = (input.name) ? "inbound_" + input.name : '';
|
811 |
-
var type = (input.type) ? input.type : 'text';
|
812 |
-
if (type === 'submit' || type === 'hidden' || type === 'file' || type === "password" || input.dataset.ignoreFormField) {
|
813 |
-
return false;
|
814 |
-
}
|
815 |
-
|
816 |
-
utils.addListener(input, 'change', function(e) {
|
817 |
-
if (e.target.name) {
|
818 |
-
/* Check for input type */
|
819 |
-
if (type !== "checkbox") {
|
820 |
-
var value = e.target.value;
|
821 |
-
} else {
|
822 |
-
var values = [];
|
823 |
-
var checkboxes = document.querySelectorAll('input[name="' + e.target.name + '"]');
|
824 |
-
for (var i = 0; i < checkboxes.length; i++) {
|
825 |
-
var checked = checkboxes[i].checked;
|
826 |
-
if (checked) {
|
827 |
-
values.push(checkboxes[i].value);
|
828 |
-
}
|
829 |
-
value = values.join(',');
|
830 |
-
};
|
831 |
-
}
|
832 |
-
//console.log(e.target.nodeName);
|
833 |
-
//console.log('change ' + e.target.name + " " + encodeURIComponent(value));
|
834 |
-
|
835 |
-
inputData = {
|
836 |
-
name: e.target.name,
|
837 |
-
node: e.target.nodeName.toLowerCase(),
|
838 |
-
type: type,
|
839 |
-
value: value,
|
840 |
-
mapping: e.target.dataset.mapFormField
|
841 |
-
};
|
842 |
-
|
843 |
-
_inbound.trigger('form_input_change', inputData);
|
844 |
-
/* Set Field Input Cookies */
|
845 |
-
utils.createCookie("inbound_" + e.target.name, encodeURIComponent(value));
|
846 |
-
// _inbound.totalStorage('the_key', FormStore);
|
847 |
-
/* Push to 'unsubmitted form object' */
|
848 |
-
}
|
849 |
-
|
850 |
-
});
|
851 |
-
},
|
852 |
-
fillInputValues: function(input) {
|
853 |
-
var name = (input.name) ? "inbound_" + input.name : '';
|
854 |
-
var type = (input.type) ? input.type : 'text';
|
855 |
-
if (type === 'submit' || type === 'hidden' || type === 'file' || type === "password") {
|
856 |
-
return false;
|
857 |
-
}
|
858 |
-
if (utils.readCookie(name) && name != 'comment') {
|
859 |
-
|
860 |
-
value = decodeURIComponent(utils.readCookie(name));
|
861 |
-
if (type === 'checkbox' || type === 'radio') {
|
862 |
-
var checkbox_vals = value.split(',');
|
863 |
-
for (var i = 0; i < checkbox_vals.length; i++) {
|
864 |
-
if (input.value.indexOf(checkbox_vals[i]) > -1) {
|
865 |
-
input.checked = true;
|
866 |
-
}
|
867 |
-
}
|
868 |
-
} else {
|
869 |
-
if (value !== "undefined") {
|
870 |
-
input.value = value;
|
871 |
-
}
|
872 |
-
}
|
873 |
-
}
|
874 |
-
},
|
875 |
-
getInputLabel: function(input){
|
876 |
-
var label;
|
877 |
-
if(label = this.siblingsIsLabel(input)){
|
878 |
-
return label;
|
879 |
-
} else if (label = this.CheckParentForLabel(input)) {
|
880 |
-
return label;
|
881 |
-
} else {
|
882 |
-
//console.log("no label nf", input);
|
883 |
-
return false;
|
884 |
-
}
|
885 |
-
},
|
886 |
-
/* Get correct input values */
|
887 |
-
getInputValue: function(input) {
|
888 |
-
var value = false;
|
889 |
-
|
890 |
-
switch (input.type) {
|
891 |
-
case 'radio':
|
892 |
-
case 'checkbox':
|
893 |
-
if (input.checked) {
|
894 |
-
value = input.value;
|
895 |
-
//console.log("CHECKBOX VAL", value)
|
896 |
-
}
|
897 |
-
break;
|
898 |
-
|
899 |
-
case 'text':
|
900 |
-
case 'hidden':
|
901 |
-
default:
|
902 |
-
value = input.value;
|
903 |
-
break;
|
904 |
-
|
905 |
-
}
|
906 |
-
|
907 |
-
return value;
|
908 |
-
},
|
909 |
-
/* Add data-map-form-field attr to input */
|
910 |
-
addDataAttr: function(formInput, match) {
|
911 |
-
|
912 |
-
var getAllInputs = document.getElementsByName(formInput.name);
|
913 |
-
for (var i = getAllInputs.length - 1; i >= 0; i--) {
|
914 |
-
if (!formInput.dataset.mapFormField) {
|
915 |
-
getAllInputs[i].dataset.mapFormField = match;
|
916 |
-
}
|
917 |
-
};
|
918 |
-
},
|
919 |
-
/* Optimize FieldMapArray array for fewer lookups */
|
920 |
-
removeArrayItem: function(array, item) {
|
921 |
-
if (array.indexOf) {
|
922 |
-
index = array.indexOf(item);
|
923 |
-
} else {
|
924 |
-
for (index = array.length - 1; index >= 0; --index) {
|
925 |
-
if (array[index] === item) {
|
926 |
-
break;
|
927 |
-
}
|
928 |
-
}
|
929 |
-
}
|
930 |
-
if (index >= 0) {
|
931 |
-
array.splice(index, 1);
|
932 |
-
}
|
933 |
-
//_inbound.deBugger('forms', 'removed ' + item + " from array");
|
934 |
-
//console.log('removed ' + item + " from array");
|
935 |
-
return;
|
936 |
-
},
|
937 |
-
/* Look for siblings that are form labels */
|
938 |
-
siblingsIsLabel: function(input) {
|
939 |
-
var siblings = this.getSiblings(input);
|
940 |
-
var labels = [];
|
941 |
-
for (var i = siblings.length - 1; i >= 0; i--) {
|
942 |
-
if (siblings[i].nodeName.toLowerCase() === 'label') {
|
943 |
-
labels.push(siblings[i]);
|
944 |
-
}
|
945 |
-
};
|
946 |
-
/* if only 1 label */
|
947 |
-
if (labels.length > 0 && labels.length < 2) {
|
948 |
-
return labels;
|
949 |
-
}
|
950 |
-
|
951 |
-
return false;
|
952 |
-
},
|
953 |
-
getChildren: function(n, skipMe) {
|
954 |
-
var r = [];
|
955 |
-
var elem = null;
|
956 |
-
for (; n; n = n.nextSibling)
|
957 |
-
if (n.nodeType == 1 && n != skipMe)
|
958 |
-
r.push(n);
|
959 |
-
return r;
|
960 |
-
},
|
961 |
-
getSiblings: function(n) {
|
962 |
-
return this.getChildren(n.parentNode.firstChild, n);
|
963 |
-
},
|
964 |
-
/* Check parent elements inside form for labels */
|
965 |
-
CheckParentForLabel: function(element) {
|
966 |
-
if (element.nodeName === 'FORM') {
|
967 |
-
return null;
|
968 |
-
}
|
969 |
-
do {
|
970 |
-
var labels = element.getElementsByTagName("label");
|
971 |
-
if (labels.length > 0 && labels.length < 2) {
|
972 |
-
return element.getElementsByTagName("label");
|
973 |
-
}
|
974 |
-
|
975 |
-
} while (element = element.parentNode);
|
976 |
-
|
977 |
-
return null;
|
978 |
-
},
|
979 |
-
/* Validate Common Email addresses */
|
980 |
-
mailCheck: function() {
|
981 |
-
var email_input = document.querySelector('.inbound-email');
|
982 |
-
if (email_input) {
|
983 |
-
//
|
984 |
-
utils.addListener(email_input, 'blur', this.mailCheck);
|
985 |
-
|
986 |
-
Mailcheck.run({
|
987 |
-
email: document.querySelector('.inbound-email').value,
|
988 |
-
suggested: function(suggestion) {
|
989 |
-
// callback code
|
990 |
-
|
991 |
-
var suggest = document.querySelector('.email_suggestion');
|
992 |
-
if (suggest) {
|
993 |
-
utils.removeElement(suggest);
|
994 |
-
}
|
995 |
-
var el = document.createElement("span");
|
996 |
-
el.innerHTML = "<span class=\"email_suggestion\">Did youu mean <b><i id='email_correction' style='cursor: pointer;' title=\"click to update\">" + suggestion.full + "</b></i>?</span>";
|
997 |
-
email_input.parentNode.insertBefore(el, email_input.nextSibling);
|
998 |
-
var update = document.getElementById('email_correction');
|
999 |
-
utils.addListener(update, 'click', function() {
|
1000 |
-
email_input.value = update.innerHTML;
|
1001 |
-
update.parentNode.parentNode.innerHTML = "Fixed!";
|
1002 |
-
});
|
1003 |
-
},
|
1004 |
-
empty: function() {
|
1005 |
-
//$(".email_suggestion").html("No Suggestions :(");
|
1006 |
-
}
|
1007 |
-
});
|
1008 |
-
}
|
1009 |
-
}
|
1010 |
-
|
1011 |
-
};
|
1012 |
-
/* Mailcheck */
|
1013 |
-
if (typeof Mailcheck === "undefined") {
|
1014 |
-
var Mailcheck = {
|
1015 |
-
domainThreshold: 1,
|
1016 |
-
topLevelThreshold: 3,
|
1017 |
-
|
1018 |
-
defaultDomains: ["yahoo.com", "google.com", "hotmail.com", "gmail.com", "me.com", "aol.com", "mac.com",
|
1019 |
-
"live.com", "comcast.net", "googlemail.com", "msn.com", "hotmail.co.uk", "yahoo.co.uk",
|
1020 |
-
"facebook.com", "verizon.net", "sbcglobal.net", "att.net", "gmx.com", "mail.com", "outlook.com", "icloud.com"
|
1021 |
-
],
|
1022 |
-
|
1023 |
-
defaultTopLevelDomains: ["co.jp", "co.uk", "com", "net", "org", "info", "edu", "gov", "mil", "ca", "de"],
|
1024 |
-
|
1025 |
-
run: function(opts) {
|
1026 |
-
opts.domains = opts.domains || Mailcheck.defaultDomains;
|
1027 |
-
opts.topLevelDomains = opts.topLevelDomains || Mailcheck.defaultTopLevelDomains;
|
1028 |
-
opts.distanceFunction = opts.distanceFunction || Mailcheck.sift3Distance;
|
1029 |
-
|
1030 |
-
var defaultCallback = function(result) {
|
1031 |
-
return result;
|
1032 |
-
};
|
1033 |
-
var suggestedCallback = opts.suggested || defaultCallback;
|
1034 |
-
var emptyCallback = opts.empty || defaultCallback;
|
1035 |
-
|
1036 |
-
var result = Mailcheck.suggest(Mailcheck.encodeEmail(opts.email), opts.domains, opts.topLevelDomains, opts.distanceFunction);
|
1037 |
-
|
1038 |
-
return result ? suggestedCallback(result) : emptyCallback();
|
1039 |
-
},
|
1040 |
-
|
1041 |
-
suggest: function(email, domains, topLevelDomains, distanceFunction) {
|
1042 |
-
email = email.toLowerCase();
|
1043 |
-
|
1044 |
-
var emailParts = this.splitEmail(email);
|
1045 |
-
|
1046 |
-
var closestDomain = this.findClosestDomain(emailParts.domain, domains, distanceFunction, this.domainThreshold);
|
1047 |
-
|
1048 |
-
if (closestDomain) {
|
1049 |
-
if (closestDomain != emailParts.domain) {
|
1050 |
-
// The email address closely matches one of the supplied domains; return a suggestion
|
1051 |
-
return {
|
1052 |
-
address: emailParts.address,
|
1053 |
-
domain: closestDomain,
|
1054 |
-
full: emailParts.address + "@" + closestDomain
|
1055 |
-
};
|
1056 |
-
}
|
1057 |
-
} else {
|
1058 |
-
// The email address does not closely match one of the supplied domains
|
1059 |
-
var closestTopLevelDomain = this.findClosestDomain(emailParts.topLevelDomain, topLevelDomains, distanceFunction, this.topLevelThreshold);
|
1060 |
-
if (emailParts.domain && closestTopLevelDomain && closestTopLevelDomain != emailParts.topLevelDomain) {
|
1061 |
-
// The email address may have a mispelled top-level domain; return a suggestion
|
1062 |
-
var domain = emailParts.domain;
|
1063 |
-
closestDomain = domain.substring(0, domain.lastIndexOf(emailParts.topLevelDomain)) + closestTopLevelDomain;
|
1064 |
-
return {
|
1065 |
-
address: emailParts.address,
|
1066 |
-
domain: closestDomain,
|
1067 |
-
full: emailParts.address + "@" + closestDomain
|
1068 |
-
};
|
1069 |
-
}
|
1070 |
-
}
|
1071 |
-
/* The email address exactly matches one of the supplied domains, does not closely
|
1072 |
-
* match any domain and does not appear to simply have a mispelled top-level domain,
|
1073 |
-
* or is an invalid email address; do not return a suggestion.
|
1074 |
-
*/
|
1075 |
-
return false;
|
1076 |
-
},
|
1077 |
-
|
1078 |
-
findClosestDomain: function(domain, domains, distanceFunction, threshold) {
|
1079 |
-
threshold = threshold || this.topLevelThreshold;
|
1080 |
-
var dist;
|
1081 |
-
var minDist = 99;
|
1082 |
-
var closestDomain = null;
|
1083 |
-
|
1084 |
-
if (!domain || !domains) {
|
1085 |
-
return false;
|
1086 |
-
}
|
1087 |
-
if (!distanceFunction) {
|
1088 |
-
distanceFunction = this.sift3Distance;
|
1089 |
-
}
|
1090 |
-
|
1091 |
-
for (var i = 0; i < domains.length; i++) {
|
1092 |
-
if (domain === domains[i]) {
|
1093 |
-
return domain;
|
1094 |
-
}
|
1095 |
-
dist = distanceFunction(domain, domains[i]);
|
1096 |
-
if (dist < minDist) {
|
1097 |
-
minDist = dist;
|
1098 |
-
closestDomain = domains[i];
|
1099 |
-
}
|
1100 |
-
}
|
1101 |
-
|
1102 |
-
if (minDist <= threshold && closestDomain !== null) {
|
1103 |
-
return closestDomain;
|
1104 |
-
} else {
|
1105 |
-
return false;
|
1106 |
-
}
|
1107 |
-
},
|
1108 |
-
|
1109 |
-
sift3Distance: function(s1, s2) {
|
1110 |
-
// sift3: http://siderite.blogspot.com/2007/04/super-fast-and-accurate-string-distance.html
|
1111 |
-
if (s1 === null || s1.length === 0) {
|
1112 |
-
if (s2 === null || s2.length === 0) {
|
1113 |
-
return 0;
|
1114 |
-
} else {
|
1115 |
-
return s2.length;
|
1116 |
-
}
|
1117 |
-
}
|
1118 |
-
|
1119 |
-
if (s2 === null || s2.length === 0) {
|
1120 |
-
return s1.length;
|
1121 |
-
}
|
1122 |
-
|
1123 |
-
var c = 0;
|
1124 |
-
var offset1 = 0;
|
1125 |
-
var offset2 = 0;
|
1126 |
-
var lcs = 0;
|
1127 |
-
var maxOffset = 5;
|
1128 |
-
|
1129 |
-
while ((c + offset1 < s1.length) && (c + offset2 < s2.length)) {
|
1130 |
-
if (s1.charAt(c + offset1) == s2.charAt(c + offset2)) {
|
1131 |
-
lcs++;
|
1132 |
-
} else {
|
1133 |
-
offset1 = 0;
|
1134 |
-
offset2 = 0;
|
1135 |
-
for (var i = 0; i < maxOffset; i++) {
|
1136 |
-
if ((c + i < s1.length) && (s1.charAt(c + i) == s2.charAt(c))) {
|
1137 |
-
offset1 = i;
|
1138 |
-
break;
|
1139 |
-
}
|
1140 |
-
if ((c + i < s2.length) && (s1.charAt(c) == s2.charAt(c + i))) {
|
1141 |
-
offset2 = i;
|
1142 |
-
break;
|
1143 |
-
}
|
1144 |
-
}
|
1145 |
-
}
|
1146 |
-
c++;
|
1147 |
-
}
|
1148 |
-
return (s1.length + s2.length) / 2 - lcs;
|
1149 |
-
},
|
1150 |
-
|
1151 |
-
splitEmail: function(email) {
|
1152 |
-
var parts = email.trim().split("@");
|
1153 |
-
|
1154 |
-
if (parts.length < 2) {
|
1155 |
-
return false;
|
1156 |
-
}
|
1157 |
-
|
1158 |
-
for (var i = 0; i < parts.length; i++) {
|
1159 |
-
if (parts[i] === "") {
|
1160 |
-
return false;
|
1161 |
-
}
|
1162 |
-
}
|
1163 |
-
|
1164 |
-
var domain = parts.pop();
|
1165 |
-
var domainParts = domain.split(".");
|
1166 |
-
var tld = "";
|
1167 |
-
|
1168 |
-
if (domainParts.length === 0) {
|
1169 |
-
// The address does not have a top-level domain
|
1170 |
-
return false;
|
1171 |
-
} else if (domainParts.length == 1) {
|
1172 |
-
// The address has only a top-level domain (valid under RFC)
|
1173 |
-
tld = domainParts[0];
|
1174 |
-
} else {
|
1175 |
-
// The address has a domain and a top-level domain
|
1176 |
-
for (var i = 1; i < domainParts.length; i++) {
|
1177 |
-
tld += domainParts[i] + ".";
|
1178 |
-
}
|
1179 |
-
if (domainParts.length >= 2) {
|
1180 |
-
tld = tld.substring(0, tld.length - 1);
|
1181 |
-
}
|
1182 |
-
}
|
1183 |
-
|
1184 |
-
return {
|
1185 |
-
topLevelDomain: tld,
|
1186 |
-
domain: domain,
|
1187 |
-
address: parts.join("@")
|
1188 |
-
};
|
1189 |
-
},
|
1190 |
-
|
1191 |
-
// Encode the email address to prevent XSS but leave in valid
|
1192 |
-
// characters, following this official spec:
|
1193 |
-
// http://en.wikipedia.org/wiki/Email_address#Syntax
|
1194 |
-
encodeEmail: function(email) {
|
1195 |
-
var result = encodeURI(email);
|
1196 |
-
result = result.replace("%20", " ").replace("%25", "%").replace("%5E", "^")
|
1197 |
-
.replace("%60", "`").replace("%7B", "{").replace("%7C", "|")
|
1198 |
-
.replace("%7D", "}");
|
1199 |
-
return result;
|
1200 |
-
}
|
1201 |
-
};
|
1202 |
-
} // End Mailcheck
|
1203 |
-
|
1204 |
-
|
1205 |
-
return _inbound;
|
1206 |
-
|
1207 |
-
})(_inbound || {});
|
1 |
+
/**
|
2 |
+
* # Inbound Forms
|
3 |
+
*
|
4 |
+
* This file contains all of the form functions of the main _inbound object.
|
5 |
+
* Filters and actions are described below
|
6 |
+
*
|
7 |
+
* @contributor David Wells <david@inboundnow.com>
|
8 |
+
* @contributor Hudson Atwell <hudson@inboundnow.com>
|
9 |
+
* @version 0.0.2
|
10 |
+
*/
|
11 |
+
/* Finish Exclusions for CC */
|
12 |
+
|
13 |
+
/* Launches form class */
|
14 |
+
var InboundForms = (function(_inbound) {
|
15 |
+
|
16 |
+
var debugMode = false,
|
17 |
+
utils = _inbound.Utils,
|
18 |
+
no_match = [],
|
19 |
+
rawParams = [],
|
20 |
+
mappedParams = [],
|
21 |
+
callTracker = {},
|
22 |
+
settings = _inbound.Settings;
|
23 |
+
|
24 |
+
var FieldMapArray = [
|
25 |
+
"first name",
|
26 |
+
"last name",
|
27 |
+
"name",
|
28 |
+
"email",
|
29 |
+
"e-mail",
|
30 |
+
"phone",
|
31 |
+
"website",
|
32 |
+
"job title",
|
33 |
+
"your favorite food",
|
34 |
+
"company",
|
35 |
+
"tele",
|
36 |
+
"address",
|
37 |
+
"comment"
|
38 |
+
/* Adding values here maps them */
|
39 |
+
];
|
40 |
+
|
41 |
+
_inbound.Forms = {
|
42 |
+
|
43 |
+
// Init Form functions
|
44 |
+
init: function() {
|
45 |
+
_inbound.Forms.runFieldMappingFilters();
|
46 |
+
_inbound.Forms.formTrackInit();
|
47 |
+
_inbound.Forms.searchTrackInit();
|
48 |
+
},
|
49 |
+
/**
|
50 |
+
* This triggers the forms.field_map filter on the mapping array.
|
51 |
+
* This will allow you to add or remore Items from the mapping lookup
|
52 |
+
*
|
53 |
+
* ### Example inbound.form_map_before filter
|
54 |
+
*
|
55 |
+
* This is an example of how form mapping can be filtered and
|
56 |
+
* additional fields can be mapped via javascript
|
57 |
+
*
|
58 |
+
* ```js
|
59 |
+
* // Adding the filter function
|
60 |
+
* function Inbound_Add_Filter_Example( FieldMapArray ) {
|
61 |
+
* var map = FieldMapArray || [];
|
62 |
+
* map.push('new lookup value');
|
63 |
+
*
|
64 |
+
* return map;
|
65 |
+
* };
|
66 |
+
*
|
67 |
+
* // Adding the filter on dom ready
|
68 |
+
* _inbound.hooks.addFilter( 'inbound.form_map_before', Inbound_Add_Filter_Example, 10 );
|
69 |
+
* ```
|
70 |
+
*
|
71 |
+
* @return {[type]} [description]
|
72 |
+
*/
|
73 |
+
runFieldMappingFilters: function() {
|
74 |
+
FieldMapArray = _inbound.hooks.applyFilters('forms.field_map', FieldMapArray);
|
75 |
+
//alert(FieldMapArray);
|
76 |
+
},
|
77 |
+
debug: function(msg, callback) {
|
78 |
+
//if app not in debug mode, exit immediately
|
79 |
+
if (!debugMode || !console) {
|
80 |
+
return;
|
81 |
+
}
|
82 |
+
|
83 |
+
var msg = msg || false;
|
84 |
+
//console.log the message
|
85 |
+
if (msg && (typeof msg === 'string')) {
|
86 |
+
console.log(msg);
|
87 |
+
}
|
88 |
+
|
89 |
+
//execute the callback if one was passed-in
|
90 |
+
if (callback && (callback instanceof Function)) {
|
91 |
+
callback();
|
92 |
+
}
|
93 |
+
},
|
94 |
+
formTrackInit: function() {
|
95 |
+
|
96 |
+
for (var i = 0; i < window.document.forms.length; i++) {
|
97 |
+
var trackForm = false;
|
98 |
+
var form = window.document.forms[i];
|
99 |
+
/* process forms only once */
|
100 |
+
if (!form.dataset.formProcessed) {
|
101 |
+
form.dataset.formProcessed = true;
|
102 |
+
trackForm = this.checkTrackStatus(form);
|
103 |
+
if (trackForm) {
|
104 |
+
this.attachFormSubmitEvent(form); /* attach form listener */
|
105 |
+
this.initFormMapping(form);
|
106 |
+
}
|
107 |
+
}
|
108 |
+
}
|
109 |
+
},
|
110 |
+
searchTrackInit: function(){
|
111 |
+
|
112 |
+
/* exit if searches aren't supposed to be tracked, or this function has already been called */
|
113 |
+
if(inbound_settings.search_tracking == 'off' || callTracker['searchTrackInit']){
|
114 |
+
return;
|
115 |
+
}
|
116 |
+
|
117 |
+
for (var i = 0; i < window.document.forms.length; i++) {
|
118 |
+
var trackForm = false;
|
119 |
+
var form = window.document.forms[i];
|
120 |
+
/* process forms only once */
|
121 |
+
if (!form.dataset.searchChecked) {
|
122 |
+
form.dataset.searchChecked = true;
|
123 |
+
trackForm = this.checkSearchTrackStatus(form);
|
124 |
+
if (trackForm) {
|
125 |
+
this.attachSearchFormSubmitEvent(form); /* attach form listener */
|
126 |
+
}
|
127 |
+
}
|
128 |
+
}
|
129 |
+
|
130 |
+
/* store the search data on init */
|
131 |
+
utils.storeSearchData();
|
132 |
+
|
133 |
+
/* log that this function has been called */
|
134 |
+
callTracker['searchTrackInit'] = true;
|
135 |
+
},
|
136 |
+
checkTrackStatus: function(form) {
|
137 |
+
var ClassIs = form.getAttribute('class');
|
138 |
+
if (ClassIs !== "" && ClassIs !== null) {
|
139 |
+
if (ClassIs.toLowerCase().indexOf("wpl-track-me") > -1) {
|
140 |
+
return true;
|
141 |
+
} else if (ClassIs.toLowerCase().indexOf("inbound-track") > -1) {
|
142 |
+
return true;
|
143 |
+
} else {
|
144 |
+
cb = function() { console.log(form); };
|
145 |
+
_inbound.deBugger('forms', "This form not tracked. Please assign on in settings...", cb);
|
146 |
+
return false;
|
147 |
+
}
|
148 |
+
}
|
149 |
+
},
|
150 |
+
checkSearchTrackStatus: function(form) {
|
151 |
+
var ClassIs = form.getAttribute('class'),
|
152 |
+
IdIs = form.getAttribute('id');
|
153 |
+
if (ClassIs !== "" && ClassIs !== null) {
|
154 |
+
if (ClassIs.toLowerCase().indexOf("search") > -1) {
|
155 |
+
return true;
|
156 |
+
}
|
157 |
+
}
|
158 |
+
if (IdIs !== "" && IdIs !== null) {
|
159 |
+
if (IdIs.toLowerCase().indexOf("search") > -1) {
|
160 |
+
return true;
|
161 |
+
}
|
162 |
+
}else{
|
163 |
+
cb = function() { console.log(form); };
|
164 |
+
_inbound.deBugger('searches', "This search form is not tracked. Please assign on in settings...", cb);
|
165 |
+
return false;
|
166 |
+
}
|
167 |
+
},
|
168 |
+
/* Loop through include/exclude items for tracking */
|
169 |
+
loopClassSelectors: function(selectors, action) {
|
170 |
+
for (var i = selectors.length - 1; i >= 0; i--) {
|
171 |
+
|
172 |
+
var selector = utils.trim(selectors[i])
|
173 |
+
if (selector.indexOf("#") === -1 && selector.indexOf(".") === -1) {
|
174 |
+
// assign ID as default
|
175 |
+
selector = "#" + selector;
|
176 |
+
}
|
177 |
+
//if(selectors[i] match . or # )
|
178 |
+
selector = document.querySelector(selector);
|
179 |
+
//console.log("SELECTOR", selector);
|
180 |
+
if (selector) {
|
181 |
+
if (action === 'add') {
|
182 |
+
_inbound.Utils.addClass('wpl-track-me', selector);
|
183 |
+
_inbound.Utils.addClass('inbound-track', selector);
|
184 |
+
} else {
|
185 |
+
_inbound.Utils.removeClass('wpl-track-me', selector);
|
186 |
+
_inbound.Utils.removeClass('inbound-track', selector);
|
187 |
+
}
|
188 |
+
}
|
189 |
+
}
|
190 |
+
},
|
191 |
+
/* Map field fields on load */
|
192 |
+
initFormMapping: function(form) {
|
193 |
+
var hiddenInputs = [];
|
194 |
+
|
195 |
+
for (var i = 0; i < form.elements.length; i++) {
|
196 |
+
formInput = form.elements[i];
|
197 |
+
|
198 |
+
if (formInput.type === 'hidden') {
|
199 |
+
hiddenInputs.push(formInput);
|
200 |
+
continue;
|
201 |
+
}
|
202 |
+
|
203 |
+
//this.ignoreFields(formInput);
|
204 |
+
/* Map form fields */
|
205 |
+
this.mapField(formInput);
|
206 |
+
/* Remember visible inputs */
|
207 |
+
this.rememberInputValues(formInput);
|
208 |
+
/* Fill visible inputs */
|
209 |
+
if (settings.formAutoPopulation && !_inbound.Utils.hasClass( "nopopulate", form ) ) {
|
210 |
+
this.fillInputValues(formInput);
|
211 |
+
}
|
212 |
+
|
213 |
+
}
|
214 |
+
|
215 |
+
/* loop hidden inputs */
|
216 |
+
for (var n = hiddenInputs.length - 1; n >= 0; n--) {
|
217 |
+
formInput = hiddenInputs[n];
|
218 |
+
this.mapField(formInput);
|
219 |
+
}
|
220 |
+
|
221 |
+
//console.log('mapping on load completed');
|
222 |
+
},
|
223 |
+
/* Maps data attributes to fields on page load */
|
224 |
+
mapField: function(input) {
|
225 |
+
|
226 |
+
var input_id = input.id || false;
|
227 |
+
var input_name = input.name || false;
|
228 |
+
var label = this.getInputLabel(input);
|
229 |
+
|
230 |
+
if(label){
|
231 |
+
//console.log(label[0].innerText);
|
232 |
+
var ignoreField = this.ignoreFieldByLabel(label[0].innerText);
|
233 |
+
if(ignoreField){
|
234 |
+
input.dataset.ignoreFormField = true;
|
235 |
+
return false;
|
236 |
+
}
|
237 |
+
}
|
238 |
+
|
239 |
+
/* Loop through all match possiblities */
|
240 |
+
for (i = 0; i < FieldMapArray.length; i++) {
|
241 |
+
//for (var i = FieldMapArray.length - 1; i >= 0; i--) {
|
242 |
+
var found = false;
|
243 |
+
var match = FieldMapArray[i];
|
244 |
+
var lookingFor = utils.trim(match);
|
245 |
+
var nice_name = lookingFor.replace(/ /g, '_');
|
246 |
+
|
247 |
+
|
248 |
+
//console.log("NICE NAME", nice_name);
|
249 |
+
//console.log('looking for match on ' + lookingFor);
|
250 |
+
//_inbound.deBugger('forms', 'looking for match on ' + lookingFor + " nice_name= " + nice_name);
|
251 |
+
|
252 |
+
// Check if input has an attached lable using for= tag
|
253 |
+
//var $laxbel = $("label[for='" + $element.attr('id') + "']").text();
|
254 |
+
//var labxel = 'label[for="' + input_id + '"]';
|
255 |
+
|
256 |
+
/* look for name attribute match */
|
257 |
+
if (input_name && input_name.toLowerCase().indexOf(lookingFor) > -1) {
|
258 |
+
found = true;
|
259 |
+
_inbound.deBugger('forms', 'Found matching name attribute for -> ' + lookingFor);
|
260 |
+
|
261 |
+
/* look for id match */
|
262 |
+
} else if (input_id && input_id.toLowerCase().indexOf(lookingFor) > -1) {
|
263 |
+
|
264 |
+
found = true;
|
265 |
+
_inbound.deBugger('forms', 'Found matching ID attribute for ->' + lookingFor);
|
266 |
+
|
267 |
+
/* Check siblings for label */
|
268 |
+
} else if (label) {
|
269 |
+
//var label = (label.length > 1 ? label[0] : label);
|
270 |
+
//console.log('label', label);
|
271 |
+
if (label[0].innerText.toLowerCase().indexOf(lookingFor) > -1) {
|
272 |
+
|
273 |
+
found = true;
|
274 |
+
_inbound.deBugger('forms', 'Found matching sibling label for -> ' + lookingFor);
|
275 |
+
|
276 |
+
}
|
277 |
+
|
278 |
+
} else {
|
279 |
+
/* no match found */
|
280 |
+
//_inbound.deBugger('forms', 'NO Match on ' + lookingFor + " in " + input_name);
|
281 |
+
no_match.push(lookingFor);
|
282 |
+
|
283 |
+
}
|
284 |
+
|
285 |
+
/* Map the field */
|
286 |
+
if (found) {
|
287 |
+
this.addDataAttr(input, nice_name);
|
288 |
+
this.removeArrayItem(FieldMapArray, lookingFor);
|
289 |
+
i--; //decrement count
|
290 |
+
}
|
291 |
+
|
292 |
+
}
|
293 |
+
|
294 |
+
return inbound_data;
|
295 |
+
|
296 |
+
},
|
297 |
+
/* prevent default submission temporarily */
|
298 |
+
formListener: function(event) {
|
299 |
+
//console.log(event);
|
300 |
+
event.preventDefault();
|
301 |
+
_inbound.Forms.saveFormData(event.target);
|
302 |
+
document.body.style.cursor = "wait";
|
303 |
+
},
|
304 |
+
/* prevent default submission temporarily */
|
305 |
+
searchFormListener: function(event) {
|
306 |
+
//console.log(event);
|
307 |
+
event.preventDefault();
|
308 |
+
_inbound.Forms.saveSearchData(event.target);
|
309 |
+
//document.body.style.cursor = "wait";
|
310 |
+
},
|
311 |
+
/* attach form listeners */
|
312 |
+
attachFormSubmitEvent: function(form) {
|
313 |
+
utils.addListener(form, 'submit', this.formListener);
|
314 |
+
var email_input = document.querySelector('.inbound-email');
|
315 |
+
/* utils.addListener(email_input, 'blur', this.mailCheck); */
|
316 |
+
},
|
317 |
+
/* attach search form listener */
|
318 |
+
attachSearchFormSubmitEvent: function(form) {
|
319 |
+
utils.addListener(form, 'submit', this.searchFormListener);
|
320 |
+
},
|
321 |
+
/* Ignore CC data */
|
322 |
+
ignoreFieldByLabel: function(label) {
|
323 |
+
var ignore_field = false;
|
324 |
+
|
325 |
+
if(!label){ return false; }
|
326 |
+
|
327 |
+
// Ignore any fields with labels that indicate a credit card field
|
328 |
+
if (label.toLowerCase().indexOf('credit card') != -1 || label.toLowerCase().indexOf('card number') != -1) {
|
329 |
+
ignore_field = true;
|
330 |
+
}
|
331 |
+
|
332 |
+
if (label.toLowerCase().indexOf('expiration') != -1 || label.toLowerCase().indexOf('expiry') != -1) {
|
333 |
+
ignore_field = true;
|
334 |
+
}
|
335 |
+
|
336 |
+
if (label.toLowerCase() == 'month' || label.toLowerCase() == 'mm' || label.toLowerCase() == 'yy' || label.toLowerCase() == 'yyyy' || label.toLowerCase() == 'year') {
|
337 |
+
ignore_field = true;
|
338 |
+
}
|
339 |
+
|
340 |
+
if (label.toLowerCase().indexOf('cvv') != -1 || label.toLowerCase().indexOf('cvc') != -1 || label.toLowerCase().indexOf('secure code') != -1 || label.toLowerCase().indexOf('security code') != -1) {
|
341 |
+
ignore_field = true;
|
342 |
+
}
|
343 |
+
|
344 |
+
if(ignore_field){
|
345 |
+
_inbound.deBugger('forms', 'ignore ' + label);
|
346 |
+
}
|
347 |
+
|
348 |
+
return ignore_field;
|
349 |
+
|
350 |
+
},
|
351 |
+
/* not implemented yet */
|
352 |
+
ignoreFieldByValue: function(value){
|
353 |
+
var ignore_field = false;
|
354 |
+
|
355 |
+
if(!value){ return false; }
|
356 |
+
|
357 |
+
if (value.toLowerCase() == 'visa' || value.toLowerCase() == 'mastercard' || value.toLowerCase() == 'american express' || value.toLowerCase() == 'amex' || value.toLowerCase() == 'discover') {
|
358 |
+
ignore_field = true;
|
359 |
+
}
|
360 |
+
|
361 |
+
// Check if value has integers, strip out spaces, then ignore anything with a credit card length (>16) or an expiration/cvv length (<5)
|
362 |
+
var int_regex = new RegExp("/^[0-9]+$/");
|
363 |
+
if (int_regex.test(value)) {
|
364 |
+
var value_no_spaces = value.replace(' ', '');
|
365 |
+
|
366 |
+
if (this.isInt(value_no_spaces) && value_no_spaces.length >= 16) {
|
367 |
+
ignore_field = true;
|
368 |
+
}
|
369 |
+
|
370 |
+
}
|
371 |
+
|
372 |
+
return ignore_field;
|
373 |
+
|
374 |
+
},
|
375 |
+
isInt: function(n) {
|
376 |
+
return typeof n == "number" && isFinite(n) && n % 1 === 0;
|
377 |
+
},
|
378 |
+
releaseFormSubmit: function(form) {
|
379 |
+
//console.log('remove form listener event');
|
380 |
+
document.body.style.cursor = "default";
|
381 |
+
utils.removeClass('wpl-track-me', form);
|
382 |
+
utils.removeListener(form, 'submit', this.formListener);
|
383 |
+
var formClass = form.getAttribute('class');
|
384 |
+
if (formClass !== "" && formClass !== null) {
|
385 |
+
/* If contact form 7 do this */
|
386 |
+
if (formClass.toLowerCase().indexOf("wpcf7-form") != -1) {
|
387 |
+
//alert('release')
|
388 |
+
setTimeout(function() {
|
389 |
+
document.body.style.cursor = "default";
|
390 |
+
}, 300);
|
391 |
+
return true;
|
392 |
+
}
|
393 |
+
}
|
394 |
+
|
395 |
+
form.submit();
|
396 |
+
/* fallback if submit name="submit" */
|
397 |
+
setTimeout(function() {
|
398 |
+
for (var i = 0; i < form.elements.length; i++) {
|
399 |
+
formInput = form.elements[i];
|
400 |
+
type = formInput.type || false;
|
401 |
+
if (type === "submit" && formInput.name === "submit") {
|
402 |
+
form.elements[i].click();
|
403 |
+
}
|
404 |
+
}
|
405 |
+
}, 2000);
|
406 |
+
|
407 |
+
},
|
408 |
+
saveFormData: function(form) {
|
409 |
+
var inputsObject = inputsObject || {};
|
410 |
+
for (var i = 0; i < form.elements.length; i++) {
|
411 |
+
|
412 |
+
// console.log(inputsObject);
|
413 |
+
|
414 |
+
formInput = form.elements[i];
|
415 |
+
multiple = false;
|
416 |
+
|
417 |
+
if (formInput.name) {
|
418 |
+
|
419 |
+
if (formInput.dataset.ignoreFormField) {
|
420 |
+
_inbound.deBugger('forms', 'ignore ' + formInput.name);
|
421 |
+
continue;
|
422 |
+
}
|
423 |
+
|
424 |
+
inputName = formInput.name.replace(/\[([^\[]*)\]/g, "%5B%5D$1");
|
425 |
+
//inputName = inputName.replace(/-/g, "_");
|
426 |
+
if (!inputsObject[inputName]) {
|
427 |
+
inputsObject[inputName] = {};
|
428 |
+
}
|
429 |
+
if (formInput.type) {
|
430 |
+
inputsObject[inputName]['type'] = formInput.type;
|
431 |
+
}
|
432 |
+
if (!inputsObject[inputName]['name']) {
|
433 |
+
inputsObject[inputName]['name'] = formInput.name;
|
434 |
+
}
|
435 |
+
if (formInput.dataset.mapFormField) {
|
436 |
+
inputsObject[inputName]['map'] = formInput.dataset.mapFormField;
|
437 |
+
}
|
438 |
+
|
439 |
+
|
440 |
+
switch (formInput.nodeName) {
|
441 |
+
|
442 |
+
case 'INPUT':
|
443 |
+
value = this.getInputValue(formInput);
|
444 |
+
|
445 |
+
|
446 |
+
if (value === false) {
|
447 |
+
continue;
|
448 |
+
}
|
449 |
+
break;
|
450 |
+
|
451 |
+
case 'TEXTAREA':
|
452 |
+
value = formInput.value;
|
453 |
+
break;
|
454 |
+
|
455 |
+
case 'SELECT':
|
456 |
+
if (formInput.multiple) {
|
457 |
+
values = [];
|
458 |
+
multiple = true;
|
459 |
+
|
460 |
+
for (var j = 0; j < formInput.length; j++) {
|
461 |
+
if (formInput[j].selected) {
|
462 |
+
values.push(encodeURIComponent(formInput[j].value));
|
463 |
+
}
|
464 |
+
}
|
465 |
+
|
466 |
+
} else {
|
467 |
+
value = (formInput.value);
|
468 |
+
}
|
469 |
+
|
470 |
+
break;
|
471 |
+
}
|
472 |
+
|
473 |
+
_inbound.deBugger('forms', 'Input Value = ' + value);
|
474 |
+
|
475 |
+
|
476 |
+
if (value) {
|
477 |
+
/* inputsObject[inputName].push(multiple ? values.join(',') : encodeURIComponent(value)); */
|
478 |
+
if (!inputsObject[inputName]['value']) {
|
479 |
+
inputsObject[inputName]['value'] = [];
|
480 |
+
}
|
481 |
+
inputsObject[inputName]['value'].push(multiple ? values.join(',') : encodeURIComponent(value));
|
482 |
+
var value = multiple ? values.join(',') : encodeURIComponent(value);
|
483 |
+
|
484 |
+
}
|
485 |
+
|
486 |
+
}
|
487 |
+
}
|
488 |
+
_inbound.deBugger('forms', inputsObject);
|
489 |
+
|
490 |
+
//console.log('These are the raw values', inputsObject);
|
491 |
+
//_inbound.totalStorage('the_key', inputsObject);
|
492 |
+
//var inputsObject = sortInputs(inputsObject);
|
493 |
+
|
494 |
+
var matchCommon = /name|first name|last name|email|e-mail|phone|website|job title|company|tele|address|comment/;
|
495 |
+
|
496 |
+
for (var input in inputsObject) {
|
497 |
+
//console.log(input);
|
498 |
+
|
499 |
+
var inputValue = inputsObject[input]['value'];
|
500 |
+
var inputMappedField = inputsObject[input]['map'];
|
501 |
+
//if (matchCommon.test(input) !== false) {
|
502 |
+
//console.log(input + " Matches Regex run mapping test");
|
503 |
+
//var map = inputsObject[input];
|
504 |
+
//console.log("MAPP", map);
|
505 |
+
//mappedParams.push( input + '=' + inputsObject[input]['value'].join(',') );
|
506 |
+
//}
|
507 |
+
|
508 |
+
/* Add custom hook here to look for additional values */
|
509 |
+
if (typeof(inputValue) != "undefined" && inputValue != null && inputValue != "") {
|
510 |
+
rawParams.push(input + '=' + inputsObject[input]['value'].join(','));
|
511 |
+
}
|
512 |
+
|
513 |
+
if (typeof(inputMappedField) != "undefined" && inputMappedField != null && inputsObject[input]['value']) {
|
514 |
+
//console.log('Data ATTR', formInput.dataset.mapFormField);
|
515 |
+
mappedParams.push(inputMappedField + "=" + inputsObject[input]['value'].join(','));
|
516 |
+
if (input === 'email') {
|
517 |
+
var email = inputsObject[input]['value'].join(',');
|
518 |
+
//alert(email);
|
519 |
+
|
520 |
+
}
|
521 |
+
}
|
522 |
+
}
|
523 |
+
|
524 |
+
var raw_params = rawParams.join('&');
|
525 |
+
_inbound.deBugger('forms', "Stringified Raw Form PARAMS: " + raw_params);
|
526 |
+
|
527 |
+
var mapped_params = mappedParams.join('&');
|
528 |
+
_inbound.deBugger('forms', "Stringified Mapped PARAMS" + mapped_params);
|
529 |
+
|
530 |
+
/* Check Use form Email or Cookie */
|
531 |
+
var email = utils.getParameterVal('email', mapped_params) || utils.readCookie('wp_lead_email');
|
532 |
+
|
533 |
+
/* Legacy Email map */
|
534 |
+
if (!email) {
|
535 |
+
email = utils.getParameterVal('wpleads_email_address', mapped_params);
|
536 |
+
}
|
537 |
+
|
538 |
+
var fullName = utils.getParameterVal('name', mapped_params);
|
539 |
+
var fName = utils.getParameterVal('first_name', mapped_params);
|
540 |
+
var lName = utils.getParameterVal('last_name', mapped_params);
|
541 |
+
|
542 |
+
// Fallbacks for empty values
|
543 |
+
if (!lName && fName) {
|
544 |
+
var parts = decodeURI(fName).split(" ");
|
545 |
+
if (parts.length > 0) {
|
546 |
+
fName = parts[0];
|
547 |
+
lName = parts[1];
|
548 |
+
}
|
549 |
+
}
|
550 |
+
|
551 |
+
if (fullName && !lName && !fName) {
|
552 |
+
var parts = decodeURI(fullName).split(" ");
|
553 |
+
if (parts.length > 0) {
|
554 |
+
fName = parts[0];
|
555 |
+
lName = parts[1];
|
556 |
+
}
|
557 |
+
}
|
558 |
+
|
559 |
+
fullName = (fName && lName) ? fName + " " + lName : fullName;
|
560 |
+
|
561 |
+
if(!fName) { fName = ""; }
|
562 |
+
if(!lName) { lName = ""; }
|
563 |
+
|
564 |
+
_inbound.deBugger('forms', "fName = " + fName);
|
565 |
+
_inbound.deBugger('forms', "lName = " + lName);
|
566 |
+
_inbound.deBugger('forms', "fullName = " + fullName);
|
567 |
+
|
568 |
+
//return false;
|
569 |
+
var page_views = _inbound.totalStorage('page_views') || {};
|
570 |
+
var urlParams = _inbound.totalStorage('inbound_url_params') || {};
|
571 |
+
|
572 |
+
/* check if redirect url is empty */
|
573 |
+
var formRedirectUrl = form.querySelectorAll('input[value][type="hidden"][name="inbound_furl"]:not([value=""])');
|
574 |
+
var inbound_form_is_ajax = false;
|
575 |
+
if(formRedirectUrl.length == 0 || formRedirectUrl[0]['value'] == 'IA=='){
|
576 |
+
var inbound_form_is_ajax = true;
|
577 |
+
}
|
578 |
+
|
579 |
+
/* get form id */
|
580 |
+
var inbound_form_id = form.querySelectorAll('input[value][type="hidden"][name="inbound_form_id"]');
|
581 |
+
if(inbound_form_id.length > 0 ){
|
582 |
+
inbound_form_id = inbound_form_id[0]['value'];
|
583 |
+
} else {
|
584 |
+
inbound_form_id = 0;
|
585 |
+
}
|
586 |
+
|
587 |
+
var inboundDATA = {
|
588 |
+
'email': email
|
589 |
+
};
|
590 |
+
|
591 |
+
/* Get Variation ID */
|
592 |
+
if (typeof(landing_path_info) != "undefined") {
|
593 |
+
var variation = landing_path_info.variation;
|
594 |
+
} else if (typeof(cta_path_info) != "undefined") {
|
595 |
+
var variation = cta_path_info.variation;
|
596 |
+
} else {
|
597 |
+
var variation = inbound_settings.variation_id;
|
598 |
+
}
|
599 |
+
var post_type = inbound_settings.post_type || 'page';
|
600 |
+
var page_id = inbound_settings.post_id || 0;
|
601 |
+
// data['wp_lead_uid'] = jQuery.cookie("wp_lead_uid") || null;
|
602 |
+
// data['search_data'] = JSON.stringify(jQuery.totalStorage('inbound_search')) || {};
|
603 |
+
search_data = {};
|
604 |
+
/* Filter here for raw */
|
605 |
+
formData = {
|
606 |
+
'action': 'inbound_lead_store',
|
607 |
+
'email': email,
|
608 |
+
"full_name": fullName,
|
609 |
+
"first_name": fName,
|
610 |
+
"last_name": lName,
|
611 |
+
'raw_params': raw_params,
|
612 |
+
'mapped_params': mapped_params,
|
613 |
+
'url_params': JSON.stringify(urlParams),
|
614 |
+
'search_data': 'test',
|
615 |
+
'page_views': JSON.stringify(page_views),
|
616 |
+
'post_type': post_type,
|
617 |
+
'page_id': page_id,
|
618 |
+
'variation': variation,
|
619 |
+
'source': utils.readCookie("inbound_referral_site"),
|
620 |
+
'inbound_submitted': inbound_form_is_ajax,
|
621 |
+
'inbound_form_id': inbound_form_id,
|
622 |
+
'inbound_nonce': inbound_settings.ajax_nonce,
|
623 |
+
'event': form
|
624 |
+
};
|
625 |
+
|
626 |
+
callback = function(leadID) {
|
627 |
+
/* Action Example */
|
628 |
+
|
629 |
+
_inbound.deBugger('forms', 'Lead Created with ID: ' + leadID);
|
630 |
+
leadID = parseInt(leadID, 10);
|
631 |
+
formData.leadID = leadID;
|
632 |
+
/* Set Lead cookie ID */
|
633 |
+
if (leadID) {
|
634 |
+
utils.createCookie("wp_lead_id", leadID);
|
635 |
+
_inbound.totalStorage.deleteItem('page_views'); // remove pageviews
|
636 |
+
_inbound.totalStorage.deleteItem('tracking_events'); // remove events
|
637 |
+
}
|
638 |
+
|
639 |
+
_inbound.trigger('form_after_submission', formData);
|
640 |
+
|
641 |
+
/* Resume normal form functionality */
|
642 |
+
_inbound.Forms.releaseFormSubmit(form);
|
643 |
+
|
644 |
+
}
|
645 |
+
|
646 |
+
_inbound.trigger('form_before_submission', formData);
|
647 |
+
|
648 |
+
utils.ajaxPost(inbound_settings.admin_url, formData, callback);
|
649 |
+
},
|
650 |
+
saveSearchData: function(form) {
|
651 |
+
var inputsObject = inputsObject || {};
|
652 |
+
for (var i = 0; i < form.elements.length; i++) {
|
653 |
+
|
654 |
+
//console.log(inputsObject);
|
655 |
+
|
656 |
+
formInput = form.elements[i];
|
657 |
+
multiple = false;
|
658 |
+
|
659 |
+
if (formInput.name) {
|
660 |
+
|
661 |
+
if (formInput.dataset.ignoreFormField) {
|
662 |
+
_inbound.deBugger('searches', 'ignore ' + formInput.name);
|
663 |
+
continue;
|
664 |
+
}
|
665 |
+
|
666 |
+
inputName = formInput.name.replace(/\[([^\[]*)\]/g, "%5B%5D$1");
|
667 |
+
//inputName = inputName.replace(/-/g, "_");
|
668 |
+
if (!inputsObject[inputName]) {
|
669 |
+
inputsObject[inputName] = {};
|
670 |
+
}
|
671 |
+
if (formInput.type) {
|
672 |
+
inputsObject[inputName]['type'] = formInput.type;
|
673 |
+
|
674 |
+
}
|
675 |
+
if (!inputsObject[inputName]['name']) {
|
676 |
+
inputsObject[inputName]['name'] = formInput.name;
|
677 |
+
}
|
678 |
+
if (formInput.dataset.mapFormField) {
|
679 |
+
inputsObject[inputName]['map'] = formInput.dataset.mapFormField;
|
680 |
+
}
|
681 |
+
|
682 |
+
|
683 |
+
switch (formInput.nodeName) {
|
684 |
+
|
685 |
+
case 'INPUT':
|
686 |
+
value = this.getInputValue(formInput);
|
687 |
+
|
688 |
+
|
689 |
+
if (value === false) {
|
690 |
+
continue;
|
691 |
+
}
|
692 |
+
break;
|
693 |
+
|
694 |
+
case 'TEXTAREA':
|
695 |
+
value = formInput.value;
|
696 |
+
break;
|
697 |
+
|
698 |
+
case 'SELECT':
|
699 |
+
if (formInput.multiple) {
|
700 |
+
values = [];
|
701 |
+
multiple = true;
|
702 |
+
|
703 |
+
for (var j = 0; j < formInput.length; j++) {
|
704 |
+
if (formInput[j].selected) {
|
705 |
+
values.push(encodeURIComponent(formInput[j].value));
|
706 |
+
}
|
707 |
+
}
|
708 |
+
|
709 |
+
} else {
|
710 |
+
value = (formInput.value);
|
711 |
+
}
|
712 |
+
|
713 |
+
break;
|
714 |
+
}
|
715 |
+
|
716 |
+
_inbound.deBugger('searches', 'Input Value = ' + value);
|
717 |
+
|
718 |
+
|
719 |
+
if (value) {
|
720 |
+
/* inputsObject[inputName].push(multiple ? values.join(',') : encodeURIComponent(value)); */
|
721 |
+
if (!inputsObject[inputName]['value']) {
|
722 |
+
inputsObject[inputName]['value'] = [];
|
723 |
+
}
|
724 |
+
inputsObject[inputName]['value'].push(multiple ? values.join(',') : encodeURIComponent(value));
|
725 |
+
var value = multiple ? values.join(',') : encodeURIComponent(value);
|
726 |
+
|
727 |
+
}
|
728 |
+
|
729 |
+
}
|
730 |
+
}
|
731 |
+
|
732 |
+
_inbound.deBugger('searches', inputsObject);
|
733 |
+
|
734 |
+
/* create an array of search fields //(not fully implemented) at the moment, it only maps the text in the "search" input types*/
|
735 |
+
var searchQuery = [];
|
736 |
+
for (var input in inputsObject) {
|
737 |
+
var inputValue = inputsObject[input]['value'];
|
738 |
+
var inputType = inputsObject[input]['type'];
|
739 |
+
|
740 |
+
/* Add custom hook here to look for additional values */
|
741 |
+
if (typeof(inputValue) != "undefined" && inputValue != null && inputValue != "") {
|
742 |
+
// This is for mapping all fields of a search form. The resulting string is processed
|
743 |
+
// in inbound-pro\classes\admin\report-templates\report.lead-searches-and-comments.php
|
744 |
+
// In the function print_action_popup()
|
745 |
+
// searchQuery.push(input + '|value|' + inputsObject[input]['value'].join(','));
|
746 |
+
|
747 |
+
// get the search input value
|
748 |
+
if(inputType == 'search'){
|
749 |
+
searchQuery.push('search_text' + '|value|' + inputsObject[input]['value']);
|
750 |
+
}
|
751 |
+
}
|
752 |
+
}
|
753 |
+
/* exit if there isn't a search query */
|
754 |
+
if(!searchQuery[0]){
|
755 |
+
return;
|
756 |
+
}
|
757 |
+
|
758 |
+
var searchString = searchQuery.join('|field|');
|
759 |
+
_inbound.deBugger('searches', "Stringified Search Form PARAMS: " + searchString);
|
760 |
+
|
761 |
+
/* Get Variation ID */
|
762 |
+
if (typeof(landing_path_info) != "undefined") {
|
763 |
+
var variation = landing_path_info.variation;
|
764 |
+
} else if (typeof(cta_path_info) != "undefined") {
|
765 |
+
var variation = cta_path_info.variation;
|
766 |
+
} else {
|
767 |
+
var variation = inbound_settings.variation_id;
|
768 |
+
}
|
769 |
+
var post_type = inbound_settings.post_type || 'page';
|
770 |
+
var page_id = inbound_settings.post_id || 0;
|
771 |
+
|
772 |
+
var user_UID = utils.readCookie("wp_lead_uid");
|
773 |
+
|
774 |
+
/* get the user's email address if possible */
|
775 |
+
if(inbound_settings.wp_lead_data.lead_email){
|
776 |
+
email = inbound_settings.wp_lead_data.lead_email;
|
777 |
+
}else if(utils.readCookie('inbound_wpleads_email_address')){
|
778 |
+
email = utils.readCookie('inbound_wpleads_email_address');
|
779 |
+
}else{
|
780 |
+
email = '';
|
781 |
+
}
|
782 |
+
|
783 |
+
/* Filter here for raw */
|
784 |
+
searchData = {
|
785 |
+
'email': email,
|
786 |
+
'search_data': searchString,
|
787 |
+
'user_UID': user_UID,
|
788 |
+
'post_type': post_type,
|
789 |
+
'page_id': page_id,
|
790 |
+
'variation': variation,
|
791 |
+
'source': utils.readCookie("inbound_referral_site"),
|
792 |
+
'ip_address': inbound_settings.ip_address,
|
793 |
+
'timestamp': Math.floor((new Date).getTime()/1000),
|
794 |
+
};
|
795 |
+
|
796 |
+
/* filter data before caching it in the user's browser */
|
797 |
+
_inbound.trigger('search_before_caching', searchData);
|
798 |
+
|
799 |
+
/* cache search data */
|
800 |
+
if(inbound_settings.wp_lead_data.lead_id){
|
801 |
+
searchData['lead_id'] = inbound_settings.wp_lead_data.lead_id;
|
802 |
+
utils.cacheSearchData(searchData, form)
|
803 |
+
}else{
|
804 |
+
utils.cacheSearchData(searchData, form);
|
805 |
+
}
|
806 |
+
|
807 |
+
|
808 |
+
},
|
809 |
+
rememberInputValues: function(input) {
|
810 |
+
var name = (input.name) ? "inbound_" + input.name : '';
|
811 |
+
var type = (input.type) ? input.type : 'text';
|
812 |
+
if (type === 'submit' || type === 'hidden' || type === 'file' || type === "password" || input.dataset.ignoreFormField) {
|
813 |
+
return false;
|
814 |
+
}
|
815 |
+
|
816 |
+
utils.addListener(input, 'change', function(e) {
|
817 |
+
if (e.target.name) {
|
818 |
+
/* Check for input type */
|
819 |
+
if (type !== "checkbox") {
|
820 |
+
var value = e.target.value;
|
821 |
+
} else {
|
822 |
+
var values = [];
|
823 |
+
var checkboxes = document.querySelectorAll('input[name="' + e.target.name + '"]');
|
824 |
+
for (var i = 0; i < checkboxes.length; i++) {
|
825 |
+
var checked = checkboxes[i].checked;
|
826 |
+
if (checked) {
|
827 |
+
values.push(checkboxes[i].value);
|
828 |
+
}
|
829 |
+
value = values.join(',');
|
830 |
+
};
|
831 |
+
}
|
832 |
+
//console.log(e.target.nodeName);
|
833 |
+
//console.log('change ' + e.target.name + " " + encodeURIComponent(value));
|
834 |
+
|
835 |
+
inputData = {
|
836 |
+
name: e.target.name,
|
837 |
+
node: e.target.nodeName.toLowerCase(),
|
838 |
+
type: type,
|
839 |
+
value: value,
|
840 |
+
mapping: e.target.dataset.mapFormField
|
841 |
+
};
|
842 |
+
|
843 |
+
_inbound.trigger('form_input_change', inputData);
|
844 |
+
/* Set Field Input Cookies */
|
845 |
+
utils.createCookie("inbound_" + e.target.name, encodeURIComponent(value));
|
846 |
+
// _inbound.totalStorage('the_key', FormStore);
|
847 |
+
/* Push to 'unsubmitted form object' */
|
848 |
+
}
|
849 |
+
|
850 |
+
});
|
851 |
+
},
|
852 |
+
fillInputValues: function(input) {
|
853 |
+
var name = (input.name) ? "inbound_" + input.name : '';
|
854 |
+
var type = (input.type) ? input.type : 'text';
|
855 |
+
if (type === 'submit' || type === 'hidden' || type === 'file' || type === "password") {
|
856 |
+
return false;
|
857 |
+
}
|
858 |
+
if (utils.readCookie(name) && name != 'comment') {
|
859 |
+
|
860 |
+
value = decodeURIComponent(utils.readCookie(name));
|
861 |
+
if (type === 'checkbox' || type === 'radio') {
|
862 |
+
var checkbox_vals = value.split(',');
|
863 |
+
for (var i = 0; i < checkbox_vals.length; i++) {
|
864 |
+
if (input.value.indexOf(checkbox_vals[i]) > -1) {
|
865 |
+
input.checked = true;
|
866 |
+
}
|
867 |
+
}
|
868 |
+
} else {
|
869 |
+
if (value !== "undefined") {
|
870 |
+
input.value = value;
|
871 |
+
}
|
872 |
+
}
|
873 |
+
}
|
874 |
+
},
|
875 |
+
getInputLabel: function(input){
|
876 |
+
var label;
|
877 |
+
if(label = this.siblingsIsLabel(input)){
|
878 |
+
return label;
|
879 |
+
} else if (label = this.CheckParentForLabel(input)) {
|
880 |
+
return label;
|
881 |
+
} else {
|
882 |
+
//console.log("no label nf", input);
|
883 |
+
return false;
|
884 |
+
}
|
885 |
+
},
|
886 |
+
/* Get correct input values */
|
887 |
+
getInputValue: function(input) {
|
888 |
+
var value = false;
|
889 |
+
|
890 |
+
switch (input.type) {
|
891 |
+
case 'radio':
|
892 |
+
case 'checkbox':
|
893 |
+
if (input.checked) {
|
894 |
+
value = input.value;
|
895 |
+
//console.log("CHECKBOX VAL", value)
|
896 |
+
}
|
897 |
+
break;
|
898 |
+
|
899 |
+
case 'text':
|
900 |
+
case 'hidden':
|
901 |
+
default:
|
902 |
+
value = input.value;
|
903 |
+
break;
|
904 |
+
|
905 |
+
}
|
906 |
+
|
907 |
+
return value;
|
908 |
+
},
|
909 |
+
/* Add data-map-form-field attr to input */
|
910 |
+
addDataAttr: function(formInput, match) {
|
911 |
+
|
912 |
+
var getAllInputs = document.getElementsByName(formInput.name);
|
913 |
+
for (var i = getAllInputs.length - 1; i >= 0; i--) {
|
914 |
+
if (!formInput.dataset.mapFormField) {
|
915 |
+
getAllInputs[i].dataset.mapFormField = match;
|
916 |
+
}
|
917 |
+
};
|
918 |
+
},
|
919 |
+
/* Optimize FieldMapArray array for fewer lookups */
|
920 |
+
removeArrayItem: function(array, item) {
|
921 |
+
if (array.indexOf) {
|
922 |
+
index = array.indexOf(item);
|
923 |
+
} else {
|
924 |
+
for (index = array.length - 1; index >= 0; --index) {
|
925 |
+
if (array[index] === item) {
|
926 |
+
break;
|
927 |
+
}
|
928 |
+
}
|
929 |
+
}
|
930 |
+
if (index >= 0) {
|
931 |
+
array.splice(index, 1);
|
932 |
+
}
|
933 |
+
//_inbound.deBugger('forms', 'removed ' + item + " from array");
|
934 |
+
//console.log('removed ' + item + " from array");
|
935 |
+
return;
|
936 |
+
},
|
937 |
+
/* Look for siblings that are form labels */
|
938 |
+
siblingsIsLabel: function(input) {
|
939 |
+
var siblings = this.getSiblings(input);
|
940 |
+
var labels = [];
|
941 |
+
for (var i = siblings.length - 1; i >= 0; i--) {
|
942 |
+
if (siblings[i].nodeName.toLowerCase() === 'label') {
|
943 |
+
labels.push(siblings[i]);
|
944 |
+
}
|
945 |
+
};
|
946 |
+
/* if only 1 label */
|
947 |
+
if (labels.length > 0 && labels.length < 2) {
|
948 |
+
return labels;
|
949 |
+
}
|
950 |
+
|
951 |
+
return false;
|
952 |
+
},
|
953 |
+
getChildren: function(n, skipMe) {
|
954 |
+
var r = [];
|
955 |
+
var elem = null;
|
956 |
+
for (; n; n = n.nextSibling)
|
957 |
+
if (n.nodeType == 1 && n != skipMe)
|
958 |
+
r.push(n);
|
959 |
+
return r;
|
960 |
+
},
|
961 |
+
getSiblings: function(n) {
|
962 |
+
return this.getChildren(n.parentNode.firstChild, n);
|
963 |
+
},
|
964 |
+
/* Check parent elements inside form for labels */
|
965 |
+
CheckParentForLabel: function(element) {
|
966 |
+
if (element.nodeName === 'FORM') {
|
967 |
+
return null;
|
968 |
+
}
|
969 |
+
do {
|
970 |
+
var labels = element.getElementsByTagName("label");
|
971 |
+
if (labels.length > 0 && labels.length < 2) {
|
972 |
+
return element.getElementsByTagName("label");
|
973 |
+
}
|
974 |
+
|
975 |
+
} while (element = element.parentNode);
|
976 |
+
|
977 |
+
return null;
|
978 |
+
},
|
979 |
+
/* Validate Common Email addresses */
|
980 |
+
mailCheck: function() {
|
981 |
+
var email_input = document.querySelector('.inbound-email');
|
982 |
+
if (email_input) {
|
983 |
+
//
|
984 |
+
utils.addListener(email_input, 'blur', this.mailCheck);
|
985 |
+
|
986 |
+
Mailcheck.run({
|
987 |
+
email: document.querySelector('.inbound-email').value,
|
988 |
+
suggested: function(suggestion) {
|
989 |
+
// callback code
|
990 |
+
|
991 |
+
var suggest = document.querySelector('.email_suggestion');
|
992 |
+
if (suggest) {
|
993 |
+
utils.removeElement(suggest);
|
994 |
+
}
|
995 |
+
var el = document.createElement("span");
|
996 |
+
el.innerHTML = "<span class=\"email_suggestion\">Did youu mean <b><i id='email_correction' style='cursor: pointer;' title=\"click to update\">" + suggestion.full + "</b></i>?</span>";
|
997 |
+
email_input.parentNode.insertBefore(el, email_input.nextSibling);
|
998 |
+
var update = document.getElementById('email_correction');
|
999 |
+
utils.addListener(update, 'click', function() {
|
1000 |
+
email_input.value = update.innerHTML;
|
1001 |
+
update.parentNode.parentNode.innerHTML = "Fixed!";
|
1002 |
+
});
|
1003 |
+
},
|
1004 |
+
empty: function() {
|
1005 |
+
//$(".email_suggestion").html("No Suggestions :(");
|
1006 |
+
}
|
1007 |
+
});
|
1008 |
+
}
|
1009 |
+
}
|
1010 |
+
|
1011 |
+
};
|
1012 |
+
/* Mailcheck */
|
1013 |
+
if (typeof Mailcheck === "undefined") {
|
1014 |
+
var Mailcheck = {
|
1015 |
+
domainThreshold: 1,
|
1016 |
+
topLevelThreshold: 3,
|
1017 |
+
|
1018 |
+
defaultDomains: ["yahoo.com", "google.com", "hotmail.com", "gmail.com", "me.com", "aol.com", "mac.com",
|
1019 |
+
"live.com", "comcast.net", "googlemail.com", "msn.com", "hotmail.co.uk", "yahoo.co.uk",
|
1020 |
+
"facebook.com", "verizon.net", "sbcglobal.net", "att.net", "gmx.com", "mail.com", "outlook.com", "icloud.com"
|
1021 |
+
],
|
1022 |
+
|
1023 |
+
defaultTopLevelDomains: ["co.jp", "co.uk", "com", "net", "org", "info", "edu", "gov", "mil", "ca", "de"],
|
1024 |
+
|
1025 |
+
run: function(opts) {
|
1026 |
+
opts.domains = opts.domains || Mailcheck.defaultDomains;
|
1027 |
+
opts.topLevelDomains = opts.topLevelDomains || Mailcheck.defaultTopLevelDomains;
|
1028 |
+
opts.distanceFunction = opts.distanceFunction || Mailcheck.sift3Distance;
|
1029 |
+
|
1030 |
+
var defaultCallback = function(result) {
|
1031 |
+
return result;
|
1032 |
+
};
|
1033 |
+
var suggestedCallback = opts.suggested || defaultCallback;
|
1034 |
+
var emptyCallback = opts.empty || defaultCallback;
|
1035 |
+
|
1036 |
+
var result = Mailcheck.suggest(Mailcheck.encodeEmail(opts.email), opts.domains, opts.topLevelDomains, opts.distanceFunction);
|
1037 |
+
|
1038 |
+
return result ? suggestedCallback(result) : emptyCallback();
|
1039 |
+
},
|
1040 |
+
|
1041 |
+
suggest: function(email, domains, topLevelDomains, distanceFunction) {
|
1042 |
+
email = email.toLowerCase();
|
1043 |
+
|
1044 |
+
var emailParts = this.splitEmail(email);
|
1045 |
+
|
1046 |
+
var closestDomain = this.findClosestDomain(emailParts.domain, domains, distanceFunction, this.domainThreshold);
|
1047 |
+
|
1048 |
+
if (closestDomain) {
|
1049 |
+
if (closestDomain != emailParts.domain) {
|
1050 |
+
// The email address closely matches one of the supplied domains; return a suggestion
|
1051 |
+
return {
|
1052 |
+
address: emailParts.address,
|
1053 |
+
domain: closestDomain,
|
1054 |
+
full: emailParts.address + "@" + closestDomain
|
1055 |
+
};
|
1056 |
+
}
|
1057 |
+
} else {
|
1058 |
+
// The email address does not closely match one of the supplied domains
|
1059 |
+
var closestTopLevelDomain = this.findClosestDomain(emailParts.topLevelDomain, topLevelDomains, distanceFunction, this.topLevelThreshold);
|
1060 |
+
if (emailParts.domain && closestTopLevelDomain && closestTopLevelDomain != emailParts.topLevelDomain) {
|
1061 |
+
// The email address may have a mispelled top-level domain; return a suggestion
|
1062 |
+
var domain = emailParts.domain;
|
1063 |
+
closestDomain = domain.substring(0, domain.lastIndexOf(emailParts.topLevelDomain)) + closestTopLevelDomain;
|
1064 |
+
return {
|
1065 |
+
address: emailParts.address,
|
1066 |
+
domain: closestDomain,
|
1067 |
+
full: emailParts.address + "@" + closestDomain
|
1068 |
+
};
|
1069 |
+
}
|
1070 |
+
}
|
1071 |
+
/* The email address exactly matches one of the supplied domains, does not closely
|
1072 |
+
* match any domain and does not appear to simply have a mispelled top-level domain,
|
1073 |
+
* or is an invalid email address; do not return a suggestion.
|
1074 |
+
*/
|
1075 |
+
return false;
|
1076 |
+
},
|
1077 |
+
|
1078 |
+
findClosestDomain: function(domain, domains, distanceFunction, threshold) {
|
1079 |
+
threshold = threshold || this.topLevelThreshold;
|
1080 |
+
var dist;
|
1081 |
+
var minDist = 99;
|
1082 |
+
var closestDomain = null;
|
1083 |
+
|
1084 |
+
if (!domain || !domains) {
|
1085 |
+
return false;
|
1086 |
+
}
|
1087 |
+
if (!distanceFunction) {
|
1088 |
+
distanceFunction = this.sift3Distance;
|
1089 |
+
}
|
1090 |
+
|
1091 |
+
for (var i = 0; i < domains.length; i++) {
|
1092 |
+
if (domain === domains[i]) {
|
1093 |
+
return domain;
|
1094 |
+
}
|
1095 |
+
dist = distanceFunction(domain, domains[i]);
|
1096 |
+
if (dist < minDist) {
|
1097 |
+
minDist = dist;
|
1098 |
+
closestDomain = domains[i];
|
1099 |
+
}
|
1100 |
+
}
|
1101 |
+
|
1102 |
+
if (minDist <= threshold && closestDomain !== null) {
|
1103 |
+
return closestDomain;
|
1104 |
+
} else {
|
1105 |
+
return false;
|
1106 |
+
}
|
1107 |
+
},
|
1108 |
+
|
1109 |
+
sift3Distance: function(s1, s2) {
|
1110 |
+
// sift3: http://siderite.blogspot.com/2007/04/super-fast-and-accurate-string-distance.html
|
1111 |
+
if (s1 === null || s1.length === 0) {
|
1112 |
+
if (s2 === null || s2.length === 0) {
|
1113 |
+
return 0;
|
1114 |
+
} else {
|
1115 |
+
return s2.length;
|
1116 |
+
}
|
1117 |
+
}
|
1118 |
+
|
1119 |
+
if (s2 === null || s2.length === 0) {
|
1120 |
+
return s1.length;
|
1121 |
+
}
|
1122 |
+
|
1123 |
+
var c = 0;
|
1124 |
+
var offset1 = 0;
|
1125 |
+
var offset2 = 0;
|
1126 |
+
var lcs = 0;
|
1127 |
+
var maxOffset = 5;
|
1128 |
+
|
1129 |
+
while ((c + offset1 < s1.length) && (c + offset2 < s2.length)) {
|
1130 |
+
if (s1.charAt(c + offset1) == s2.charAt(c + offset2)) {
|
1131 |
+
lcs++;
|
1132 |
+
} else {
|
1133 |
+
offset1 = 0;
|
1134 |
+
offset2 = 0;
|
1135 |
+
for (var i = 0; i < maxOffset; i++) {
|
1136 |
+
if ((c + i < s1.length) && (s1.charAt(c + i) == s2.charAt(c))) {
|
1137 |
+
offset1 = i;
|
1138 |
+
break;
|
1139 |
+
}
|
1140 |
+
if ((c + i < s2.length) && (s1.charAt(c) == s2.charAt(c + i))) {
|
1141 |
+
offset2 = i;
|
1142 |
+
break;
|
1143 |
+
}
|
1144 |
+
}
|
1145 |
+
}
|
1146 |
+
c++;
|
1147 |
+
}
|
1148 |
+
return (s1.length + s2.length) / 2 - lcs;
|
1149 |
+
},
|
1150 |
+
|
1151 |
+
splitEmail: function(email) {
|
1152 |
+
var parts = email.trim().split("@");
|
1153 |
+
|
1154 |
+
if (parts.length < 2) {
|
1155 |
+
return false;
|
1156 |
+
}
|
1157 |
+
|
1158 |
+
for (var i = 0; i < parts.length; i++) {
|
1159 |
+
if (parts[i] === "") {
|
1160 |
+
return false;
|
1161 |
+
}
|
1162 |
+
}
|
1163 |
+
|
1164 |
+
var domain = parts.pop();
|
1165 |
+
var domainParts = domain.split(".");
|
1166 |
+
var tld = "";
|
1167 |
+
|
1168 |
+
if (domainParts.length === 0) {
|
1169 |
+
// The address does not have a top-level domain
|
1170 |
+
return false;
|
1171 |
+
} else if (domainParts.length == 1) {
|
1172 |
+
// The address has only a top-level domain (valid under RFC)
|
1173 |
+
tld = domainParts[0];
|
1174 |
+
} else {
|
1175 |
+
// The address has a domain and a top-level domain
|
1176 |
+
for (var i = 1; i < domainParts.length; i++) {
|
1177 |
+
tld += domainParts[i] + ".";
|
1178 |
+
}
|
1179 |
+
if (domainParts.length >= 2) {
|
1180 |
+
tld = tld.substring(0, tld.length - 1);
|
1181 |
+
}
|
1182 |
+
}
|
1183 |
+
|
1184 |
+
return {
|
1185 |
+
topLevelDomain: tld,
|
1186 |
+
domain: domain,
|
1187 |
+
address: parts.join("@")
|
1188 |
+
};
|
1189 |
+
},
|
1190 |
+
|
1191 |
+
// Encode the email address to prevent XSS but leave in valid
|
1192 |
+
// characters, following this official spec:
|
1193 |
+
// http://en.wikipedia.org/wiki/Email_address#Syntax
|
1194 |
+
encodeEmail: function(email) {
|
1195 |
+
var result = encodeURI(email);
|
1196 |
+
result = result.replace("%20", " ").replace("%25", "%").replace("%5E", "^")
|
1197 |
+
.replace("%60", "`").replace("%7B", "{").replace("%7C", "|")
|
1198 |
+
.replace("%7D", "}");
|
1199 |
+
return result;
|
1200 |
+
}
|
1201 |
+
};
|
1202 |
+
} // End Mailcheck
|
1203 |
+
|
1204 |
+
|
1205 |
+
return _inbound;
|
1206 |
+
|
1207 |
+
})(_inbound || {});
|
shared/assets/js/frontend/analytics-src/analytics.hooks.js
CHANGED
@@ -1,405 +1,405 @@
|
|
1 |
-
/**
|
2 |
-
* # Hooks & Filters
|
3 |
-
*
|
4 |
-
* This file contains all of the form functions of the main _inbound object.
|
5 |
-
* Filters and actions are described below
|
6 |
-
*
|
7 |
-
* Forked from https://github.com/carldanley/WP-JS-Hooks/blob/master/src/event-manager.js
|
8 |
-
*
|
9 |
-
* @
|
10 |
-
* @
|
11 |
-
* @version 0.0.2
|
12 |
-
*/
|
13 |
-
|
14 |
-
var _inboundHooks = (function (_inbound) {
|
15 |
-
|
16 |
-
/**
|
17 |
-
* # EventManager
|
18 |
-
*
|
19 |
-
* Actions and filters List
|
20 |
-
* addAction( 'namespace.identifier', callback, priority )
|
21 |
-
* addFilter( 'namespace.identifier', callback, priority )
|
22 |
-
* removeAction( 'namespace.identifier' )
|
23 |
-
* removeFilter( 'namespace.identifier' )
|
24 |
-
* doAction( 'namespace.identifier', arg1, arg2, moreArgs, finalArg )
|
25 |
-
* applyFilters( 'namespace.identifier', content )
|
26 |
-
* @return {[type]} [description]
|
27 |
-
*/
|
28 |
-
|
29 |
-
/**
|
30 |
-
* Handles managing all events for whatever you plug it into. Priorities for hooks are based on lowest to highest in
|
31 |
-
* that, lowest priority hooks are fired first.
|
32 |
-
*/
|
33 |
-
var EventManager = function() {
|
34 |
-
/**
|
35 |
-
* Maintain a reference to the object scope so our public methods never get confusing.
|
36 |
-
*/
|
37 |
-
var MethodsAvailable = {
|
38 |
-
removeFilter : removeFilter,
|
39 |
-
applyFilters : applyFilters,
|
40 |
-
addFilter : addFilter,
|
41 |
-
removeAction : removeAction,
|
42 |
-
doAction : doAction,
|
43 |
-
addAction : addAction
|
44 |
-
};
|
45 |
-
|
46 |
-
/**
|
47 |
-
* Contains the hooks that get registered with this EventManager. The array for storage utilizes a "flat"
|
48 |
-
* object literal such that looking up the hook utilizes the native object literal hash.
|
49 |
-
*/
|
50 |
-
var STORAGE = {
|
51 |
-
actions : {},
|
52 |
-
filters : {}
|
53 |
-
};
|
54 |
-
|
55 |
-
/**
|
56 |
-
* Adds an action to the event manager.
|
57 |
-
*
|
58 |
-
* @param action Must contain namespace.identifier
|
59 |
-
* @param callback Must be a valid callback function before this action is added
|
60 |
-
* @param [priority=10] Used to control when the function is executed in relation to other callbacks bound to the same hook
|
61 |
-
* @param [context] Supply a value to be used for this
|
62 |
-
*/
|
63 |
-
function addAction( action, callback, priority, context ) {
|
64 |
-
if( typeof action === 'string' && typeof callback === 'function' ) {
|
65 |
-
priority = parseInt( ( priority || 10 ), 10 );
|
66 |
-
_addHook( 'actions', action, callback, priority, context );
|
67 |
-
}
|
68 |
-
|
69 |
-
return MethodsAvailable;
|
70 |
-
}
|
71 |
-
|
72 |
-
/**
|
73 |
-
* Performs an action if it exists. You can pass as many arguments as you want to this function; the only rule is
|
74 |
-
* that the first argument must always be the action.
|
75 |
-
*/
|
76 |
-
function doAction( /* action, arg1, arg2, ... */ ) {
|
77 |
-
var args = Array.prototype.slice.call( arguments );
|
78 |
-
var action = args.shift();
|
79 |
-
|
80 |
-
if( typeof action === 'string' ) {
|
81 |
-
_runHook( 'actions', action, args );
|
82 |
-
}
|
83 |
-
|
84 |
-
return MethodsAvailable;
|
85 |
-
}
|
86 |
-
|
87 |
-
/**
|
88 |
-
* Removes the specified action if it contains a namespace.identifier & exists.
|
89 |
-
*
|
90 |
-
* @param action The action to remove
|
91 |
-
* @param [callback] Callback function to remove
|
92 |
-
*/
|
93 |
-
function removeAction( action, callback ) {
|
94 |
-
if( typeof action === 'string' ) {
|
95 |
-
_removeHook( 'actions', action, callback );
|
96 |
-
}
|
97 |
-
|
98 |
-
return MethodsAvailable;
|
99 |
-
}
|
100 |
-
|
101 |
-
/**
|
102 |
-
* Adds a filter to the event manager.
|
103 |
-
*
|
104 |
-
* @param filter Must contain namespace.identifier
|
105 |
-
* @param callback Must be a valid callback function before this action is added
|
106 |
-
* @param [priority=10] Used to control when the function is executed in relation to other callbacks bound to the same hook
|
107 |
-
* @param [context] Supply a value to be used for this
|
108 |
-
*/
|
109 |
-
function addFilter( filter, callback, priority, context ) {
|
110 |
-
if( typeof filter === 'string' && typeof callback === 'function' ) {
|
111 |
-
//console.log('add filter', filter);
|
112 |
-
priority = parseInt( ( priority || 10 ), 10 );
|
113 |
-
_addHook( 'filters', filter, callback, priority );
|
114 |
-
}
|
115 |
-
|
116 |
-
return MethodsAvailable;
|
117 |
-
}
|
118 |
-
|
119 |
-
/**
|
120 |
-
* Performs a filter if it exists. You should only ever pass 1 argument to be filtered. The only rule is that
|
121 |
-
* the first argument must always be the filter.
|
122 |
-
*/
|
123 |
-
function applyFilters( /* filter, filtered arg, arg2, ... */ ) {
|
124 |
-
var args = Array.prototype.slice.call( arguments );
|
125 |
-
var filter = args.shift();
|
126 |
-
|
127 |
-
if( typeof filter === 'string' ) {
|
128 |
-
return _runHook( 'filters', filter, args );
|
129 |
-
}
|
130 |
-
|
131 |
-
return MethodsAvailable;
|
132 |
-
}
|
133 |
-
|
134 |
-
/**
|
135 |
-
* Removes the specified filter if it contains a namespace.identifier & exists.
|
136 |
-
*
|
137 |
-
* @param filter The action to remove
|
138 |
-
* @param [callback] Callback function to remove
|
139 |
-
*/
|
140 |
-
function removeFilter( filter, callback ) {
|
141 |
-
if( typeof filter === 'string') {
|
142 |
-
_removeHook( 'filters', filter, callback );
|
143 |
-
}
|
144 |
-
|
145 |
-
return MethodsAvailable;
|
146 |
-
}
|
147 |
-
|
148 |
-
/**
|
149 |
-
* Removes the specified hook by resetting the value of it.
|
150 |
-
*
|
151 |
-
* @param type Type of hook, either 'actions' or 'filters'
|
152 |
-
* @param hook The hook (namespace.identifier) to remove
|
153 |
-
* @private
|
154 |
-
*/
|
155 |
-
function _removeHook( type, hook, callback, context ) {
|
156 |
-
if ( !STORAGE[ type ][ hook ] ) {
|
157 |
-
return;
|
158 |
-
}
|
159 |
-
if ( !callback ) {
|
160 |
-
STORAGE[ type ][ hook ] = [];
|
161 |
-
} else {
|
162 |
-
var handlers = STORAGE[ type ][ hook ];
|
163 |
-
var i;
|
164 |
-
if ( !context ) {
|
165 |
-
for ( i = handlers.length; i--; ) {
|
166 |
-
if ( handlers[i].callback === callback ) {
|
167 |
-
handlers.splice( i, 1 );
|
168 |
-
}
|
169 |
-
}
|
170 |
-
}
|
171 |
-
else {
|
172 |
-
for ( i = handlers.length; i--; ) {
|
173 |
-
var handler = handlers[i];
|
174 |
-
if ( handler.callback === callback && handler.context === context) {
|
175 |
-
handlers.splice( i, 1 );
|
176 |
-
}
|
177 |
-
}
|
178 |
-
}
|
179 |
-
}
|
180 |
-
}
|
181 |
-
|
182 |
-
/**
|
183 |
-
* Adds the hook to the appropriate storage container
|
184 |
-
*
|
185 |
-
* @param type 'actions' or 'filters'
|
186 |
-
* @param hook The hook (namespace.identifier) to add to our event manager
|
187 |
-
* @param callback The function that will be called when the hook is executed.
|
188 |
-
* @param priority The priority of this hook. Must be an integer.
|
189 |
-
* @param [context] A value to be used for this
|
190 |
-
* @private
|
191 |
-
*/
|
192 |
-
function _addHook( type, hook, callback, priority, context ) {
|
193 |
-
var hookObject = {
|
194 |
-
callback : callback,
|
195 |
-
priority : priority,
|
196 |
-
context : context
|
197 |
-
};
|
198 |
-
|
199 |
-
// Utilize 'prop itself' : http://jsperf.com/hasownproperty-vs-in-vs-undefined/19
|
200 |
-
var hooks = STORAGE[ type ][ hook ];
|
201 |
-
if( hooks ) {
|
202 |
-
hooks.push( hookObject );
|
203 |
-
hooks = _hookInsertSort( hooks );
|
204 |
-
}
|
205 |
-
else {
|
206 |
-
hooks = [ hookObject ];
|
207 |
-
}
|
208 |
-
|
209 |
-
STORAGE[ type ][ hook ] = hooks;
|
210 |
-
}
|
211 |
-
|
212 |
-
/**
|
213 |
-
* Use an insert sort for keeping our hooks organized based on priority. This function is ridiculously faster
|
214 |
-
* than bubble sort, etc: http://jsperf.com/javascript-sort
|
215 |
-
*
|
216 |
-
* @param hooks The custom array containing all of the appropriate hooks to perform an insert sort on.
|
217 |
-
* @private
|
218 |
-
*/
|
219 |
-
function _hookInsertSort( hooks ) {
|
220 |
-
var tmpHook, j, prevHook;
|
221 |
-
for( var i = 1, len = hooks.length; i < len; i++ ) {
|
222 |
-
tmpHook = hooks[ i ];
|
223 |
-
j = i;
|
224 |
-
while( ( prevHook = hooks[ j - 1 ] ) && prevHook.priority > tmpHook.priority ) {
|
225 |
-
hooks[ j ] = hooks[ j - 1 ];
|
226 |
-
--j;
|
227 |
-
}
|
228 |
-
hooks[ j ] = tmpHook;
|
229 |
-
}
|
230 |
-
|
231 |
-
return hooks;
|
232 |
-
}
|
233 |
-
|
234 |
-
/**
|
235 |
-
* Runs the specified hook. If it is an action, the value is not modified but if it is a filter, it is.
|
236 |
-
*
|
237 |
-
* @param type 'actions' or 'filters'
|
238 |
-
* @param hook The hook ( namespace.identifier ) to be ran.
|
239 |
-
* @param args Arguments to pass to the action/filter. If it's a filter, args is actually a single parameter.
|
240 |
-
* @private
|
241 |
-
*/
|
242 |
-
function _runHook( type, hook, args ) {
|
243 |
-
var handlers = STORAGE[ type ][ hook ];
|
244 |
-
|
245 |
-
if ( !handlers ) {
|
246 |
-
return (type === 'filters') ? args[0] : false;
|
247 |
-
}
|
248 |
-
|
249 |
-
var i = 0, len = handlers.length;
|
250 |
-
if ( type === 'filters' ) {
|
251 |
-
for ( ; i < len; i++ ) {
|
252 |
-
args[ 0 ] = handlers[ i ].callback.apply( handlers[ i ].context, args );
|
253 |
-
}
|
254 |
-
} else {
|
255 |
-
for ( ; i < len; i++ ) {
|
256 |
-
handlers[ i ].callback.apply( handlers[ i ].context, args );
|
257 |
-
}
|
258 |
-
}
|
259 |
-
|
260 |
-
return ( type === 'filters' ) ? args[ 0 ] : true;
|
261 |
-
}
|
262 |
-
|
263 |
-
// return all of the publicly available methods
|
264 |
-
return MethodsAvailable;
|
265 |
-
|
266 |
-
};
|
267 |
-
|
268 |
-
_inbound.hooks = new EventManager();
|
269 |
-
|
270 |
-
|
271 |
-
/**
|
272 |
-
* Event Hooks and Filters public methods
|
273 |
-
*/
|
274 |
-
/*
|
275 |
-
* add_action
|
276 |
-
*
|
277 |
-
* This function uses _inbound.hooks to mimics WP add_action
|
278 |
-
*
|
279 |
-
* ```js
|
280 |
-
* function Inbound_Add_Action_Example(data) {
|
281 |
-
* // Do stuff here.
|
282 |
-
* };
|
283 |
-
* // Add action to the hook
|
284 |
-
* _inbound.add_action( 'name_of_action', Inbound_Add_Action_Example, 10 );
|
285 |
-
* ```
|
286 |
-
*/
|
287 |
-
_inbound.add_action = function() {
|
288 |
-
// allow multiple action parameters such as 'ready append'
|
289 |
-
var actions = arguments[0].split(' ');
|
290 |
-
|
291 |
-
for( k in actions ) {
|
292 |
-
|
293 |
-
// prefix action
|
294 |
-
arguments[0] = 'inbound.' + actions[ k ];
|
295 |
-
|
296 |
-
_inbound.hooks.addAction.apply(this, arguments);
|
297 |
-
}
|
298 |
-
|
299 |
-
return this;
|
300 |
-
|
301 |
-
};
|
302 |
-
/*
|
303 |
-
* remove_action
|
304 |
-
*
|
305 |
-
* This function uses _inbound.hooks to mimics WP remove_action
|
306 |
-
*
|
307 |
-
* ```js
|
308 |
-
* // Add remove action 'name_of_action'
|
309 |
-
* _inbound.remove_action( 'name_of_action');
|
310 |
-
* ```
|
311 |
-
*
|
312 |
-
*/
|
313 |
-
_inbound.remove_action = function() {
|
314 |
-
// prefix action
|
315 |
-
arguments[0] = 'inbound.' + arguments[0];
|
316 |
-
_inbound.hooks.removeAction.apply(this, arguments);
|
317 |
-
|
318 |
-
return this;
|
319 |
-
|
320 |
-
};
|
321 |
-
/*
|
322 |
-
* do_action
|
323 |
-
*
|
324 |
-
* This function uses _inbound.hooks to mimics WP do_action
|
325 |
-
* This is used if you want to allow for third party JS plugins to act on your functions
|
326 |
-
*
|
327 |
-
*/
|
328 |
-
_inbound.do_action = function() {
|
329 |
-
// prefix action
|
330 |
-
arguments[0] = 'inbound.' + arguments[0];
|
331 |
-
_inbound.hooks.doAction.apply(this, arguments);
|
332 |
-
|
333 |
-
return this;
|
334 |
-
|
335 |
-
};
|
336 |
-
/*
|
337 |
-
* add_filter
|
338 |
-
*
|
339 |
-
* This function uses _inbound.hooks to mimics WP add_filter
|
340 |
-
*
|
341 |
-
* ```js
|
342 |
-
* _inbound.add_filter( 'urlParamFilter', URL_Param_Filter, 10 );
|
343 |
-
* function URL_Param_Filter(urlParams) {
|
344 |
-
*
|
345 |
-
* var params = urlParams || {};
|
346 |
-
* // check for item in object
|
347 |
-
* if(params.utm_source !== "undefined"){
|
348 |
-
* //alert('url param "utm_source" is here');
|
349 |
-
* }
|
350 |
-
*
|
351 |
-
* // delete item from object
|
352 |
-
* delete params.utm_source;
|
353 |
-
*
|
354 |
-
* return params;
|
355 |
-
*
|
356 |
-
* }
|
357 |
-
* ```
|
358 |
-
*/
|
359 |
-
_inbound.add_filter = function() {
|
360 |
-
// prefix action
|
361 |
-
arguments[0] = 'inbound.' + arguments[0];
|
362 |
-
_inbound.hooks.addFilter.apply(this, arguments);
|
363 |
-
|
364 |
-
return this;
|
365 |
-
|
366 |
-
};
|
367 |
-
/*
|
368 |
-
* remove_filter
|
369 |
-
*
|
370 |
-
* This function uses _inbound.hooks to mimics WP remove_filter
|
371 |
-
*
|
372 |
-
* ```js
|
373 |
-
* // Add remove filter 'urlParamFilter'
|
374 |
-
* _inbound.remove_action( 'urlParamFilter');
|
375 |
-
* ```
|
376 |
-
*
|
377 |
-
*/
|
378 |
-
_inbound.remove_filter = function() {
|
379 |
-
// prefix action
|
380 |
-
arguments[0] = 'inbound.' + arguments[0];
|
381 |
-
|
382 |
-
_inbound.hooks.removeFilter.apply(this, arguments);
|
383 |
-
|
384 |
-
return this;
|
385 |
-
|
386 |
-
};
|
387 |
-
/*
|
388 |
-
* apply_filters
|
389 |
-
*
|
390 |
-
* This function uses _inbound.hooks to mimics WP apply_filters
|
391 |
-
*
|
392 |
-
*/
|
393 |
-
_inbound.apply_filters = function() {
|
394 |
-
//console.log('Filter:' + arguments[0] + " ran on ->", arguments[1]);
|
395 |
-
// prefix action
|
396 |
-
arguments[0] = 'inbound.' + arguments[0];
|
397 |
-
|
398 |
-
return _inbound.hooks.applyFilters.apply(this, arguments);
|
399 |
-
|
400 |
-
};
|
401 |
-
|
402 |
-
|
403 |
-
return _inbound;
|
404 |
-
|
405 |
Â
})(_inbound || {});
|
1 |
+
/**
|
2 |
+
* # Hooks & Filters
|
3 |
+
*
|
4 |
+
* This file contains all of the form functions of the main _inbound object.
|
5 |
+
* Filters and actions are described below
|
6 |
+
*
|
7 |
+
* Forked from https://github.com/carldanley/WP-JS-Hooks/blob/master/src/event-manager.js
|
8 |
+
*
|
9 |
+
* @contributor David Wells <david@inboundnow.com>
|
10 |
+
* @contributor Hudson Atwell <hudson@inboundnow.com>
|
11 |
+
* @version 0.0.2
|
12 |
+
*/
|
13 |
+
|
14 |
+
var _inboundHooks = (function (_inbound) {
|
15 |
+
|
16 |
+
/**
|
17 |
+
* # EventManager
|
18 |
+
*
|
19 |
+
* Actions and filters List
|
20 |
+
* addAction( 'namespace.identifier', callback, priority )
|
21 |
+
* addFilter( 'namespace.identifier', callback, priority )
|
22 |
+
* removeAction( 'namespace.identifier' )
|
23 |
+
* removeFilter( 'namespace.identifier' )
|
24 |
+
* doAction( 'namespace.identifier', arg1, arg2, moreArgs, finalArg )
|
25 |
+
* applyFilters( 'namespace.identifier', content )
|
26 |
+
* @return {[type]} [description]
|
27 |
+
*/
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Handles managing all events for whatever you plug it into. Priorities for hooks are based on lowest to highest in
|
31 |
+
* that, lowest priority hooks are fired first.
|
32 |
+
*/
|
33 |
+
var EventManager = function() {
|
34 |
+
/**
|
35 |
+
* Maintain a reference to the object scope so our public methods never get confusing.
|
36 |
+
*/
|
37 |
+
var MethodsAvailable = {
|
38 |
+
removeFilter : removeFilter,
|
39 |
+
applyFilters : applyFilters,
|
40 |
+
addFilter : addFilter,
|
41 |
+
removeAction : removeAction,
|
42 |
+
doAction : doAction,
|
43 |
+
addAction : addAction
|
44 |
+
};
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Contains the hooks that get registered with this EventManager. The array for storage utilizes a "flat"
|
48 |
+
* object literal such that looking up the hook utilizes the native object literal hash.
|
49 |
+
*/
|
50 |
+
var STORAGE = {
|
51 |
+
actions : {},
|
52 |
+
filters : {}
|
53 |
+
};
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Adds an action to the event manager.
|
57 |
+
*
|
58 |
+
* @param action Must contain namespace.identifier
|
59 |
+
* @param callback Must be a valid callback function before this action is added
|
60 |
+
* @param [priority=10] Used to control when the function is executed in relation to other callbacks bound to the same hook
|
61 |
+
* @param [context] Supply a value to be used for this
|
62 |
+
*/
|
63 |
+
function addAction( action, callback, priority, context ) {
|
64 |
+
if( typeof action === 'string' && typeof callback === 'function' ) {
|
65 |
+
priority = parseInt( ( priority || 10 ), 10 );
|
66 |
+
_addHook( 'actions', action, callback, priority, context );
|
67 |
+
}
|
68 |
+
|
69 |
+
return MethodsAvailable;
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Performs an action if it exists. You can pass as many arguments as you want to this function; the only rule is
|
74 |
+
* that the first argument must always be the action.
|
75 |
+
*/
|
76 |
+
function doAction( /* action, arg1, arg2, ... */ ) {
|
77 |
+
var args = Array.prototype.slice.call( arguments );
|
78 |
+
var action = args.shift();
|
79 |
+
|
80 |
+
if( typeof action === 'string' ) {
|
81 |
+
_runHook( 'actions', action, args );
|
82 |
+
}
|
83 |
+
|
84 |
+
return MethodsAvailable;
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Removes the specified action if it contains a namespace.identifier & exists.
|
89 |
+
*
|
90 |
+
* @param action The action to remove
|
91 |
+
* @param [callback] Callback function to remove
|
92 |
+
*/
|
93 |
+
function removeAction( action, callback ) {
|
94 |
+
if( typeof action === 'string' ) {
|
95 |
+
_removeHook( 'actions', action, callback );
|
96 |
+
}
|
97 |
+
|
98 |
+
return MethodsAvailable;
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Adds a filter to the event manager.
|
103 |
+
*
|
104 |
+
* @param filter Must contain namespace.identifier
|
105 |
+
* @param callback Must be a valid callback function before this action is added
|
106 |
+
* @param [priority=10] Used to control when the function is executed in relation to other callbacks bound to the same hook
|
107 |
+
* @param [context] Supply a value to be used for this
|
108 |
+
*/
|
109 |
+
function addFilter( filter, callback, priority, context ) {
|
110 |
+
if( typeof filter === 'string' && typeof callback === 'function' ) {
|
111 |
+
//console.log('add filter', filter);
|
112 |
+
priority = parseInt( ( priority || 10 ), 10 );
|
113 |
+
_addHook( 'filters', filter, callback, priority );
|
114 |
+
}
|
115 |
+
|
116 |
+
return MethodsAvailable;
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Performs a filter if it exists. You should only ever pass 1 argument to be filtered. The only rule is that
|
121 |
+
* the first argument must always be the filter.
|
122 |
+
*/
|
123 |
+
function applyFilters( /* filter, filtered arg, arg2, ... */ ) {
|
124 |
+
var args = Array.prototype.slice.call( arguments );
|
125 |
+
var filter = args.shift();
|
126 |
+
|
127 |
+
if( typeof filter === 'string' ) {
|
128 |
+
return _runHook( 'filters', filter, args );
|
129 |
+
}
|
130 |
+
|
131 |
+
return MethodsAvailable;
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Removes the specified filter if it contains a namespace.identifier & exists.
|
136 |
+
*
|
137 |
+
* @param filter The action to remove
|
138 |
+
* @param [callback] Callback function to remove
|
139 |
+
*/
|
140 |
+
function removeFilter( filter, callback ) {
|
141 |
+
if( typeof filter === 'string') {
|
142 |
+
_removeHook( 'filters', filter, callback );
|
143 |
+
}
|
144 |
+
|
145 |
+
return MethodsAvailable;
|
146 |
+
}
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Removes the specified hook by resetting the value of it.
|
150 |
+
*
|
151 |
+
* @param type Type of hook, either 'actions' or 'filters'
|
152 |
+
* @param hook The hook (namespace.identifier) to remove
|
153 |
+
* @private
|
154 |
+
*/
|
155 |
+
function _removeHook( type, hook, callback, context ) {
|
156 |
+
if ( !STORAGE[ type ][ hook ] ) {
|
157 |
+
return;
|
158 |
+
}
|
159 |
+
if ( !callback ) {
|
160 |
+
STORAGE[ type ][ hook ] = [];
|
161 |
+
} else {
|
162 |
+
var handlers = STORAGE[ type ][ hook ];
|
163 |
+
var i;
|
164 |
+
if ( !context ) {
|
165 |
+
for ( i = handlers.length; i--; ) {
|
166 |
+
if ( handlers[i].callback === callback ) {
|
167 |
+
handlers.splice( i, 1 );
|
168 |
+
}
|
169 |
+
}
|
170 |
+
}
|
171 |
+
else {
|
172 |
+
for ( i = handlers.length; i--; ) {
|
173 |
+
var handler = handlers[i];
|
174 |
+
if ( handler.callback === callback && handler.context === context) {
|
175 |
+
handlers.splice( i, 1 );
|
176 |
+
}
|
177 |
+
}
|
178 |
+
}
|
179 |
+
}
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Adds the hook to the appropriate storage container
|
184 |
+
*
|
185 |
+
* @param type 'actions' or 'filters'
|
186 |
+
* @param hook The hook (namespace.identifier) to add to our event manager
|
187 |
+
* @param callback The function that will be called when the hook is executed.
|
188 |
+
* @param priority The priority of this hook. Must be an integer.
|
189 |
+
* @param [context] A value to be used for this
|
190 |
+
* @private
|
191 |
+
*/
|
192 |
+
function _addHook( type, hook, callback, priority, context ) {
|
193 |
+
var hookObject = {
|
194 |
+
callback : callback,
|
195 |
+
priority : priority,
|
196 |
+
context : context
|
197 |
+
};
|
198 |
+
|
199 |
+
// Utilize 'prop itself' : http://jsperf.com/hasownproperty-vs-in-vs-undefined/19
|
200 |
+
var hooks = STORAGE[ type ][ hook ];
|
201 |
+
if( hooks ) {
|
202 |
+
hooks.push( hookObject );
|
203 |
+
hooks = _hookInsertSort( hooks );
|
204 |
+
}
|
205 |
+
else {
|
206 |
+
hooks = [ hookObject ];
|
207 |
+
}
|
208 |
+
|
209 |
+
STORAGE[ type ][ hook ] = hooks;
|
210 |
+
}
|
211 |
+
|
212 |
+
/**
|
213 |
+
* Use an insert sort for keeping our hooks organized based on priority. This function is ridiculously faster
|
214 |
+
* than bubble sort, etc: http://jsperf.com/javascript-sort
|
215 |
+
*
|
216 |
+
* @param hooks The custom array containing all of the appropriate hooks to perform an insert sort on.
|
217 |
+
* @private
|
218 |
+
*/
|
219 |
+
function _hookInsertSort( hooks ) {
|
220 |
+
var tmpHook, j, prevHook;
|
221 |
+
for( var i = 1, len = hooks.length; i < len; i++ ) {
|
222 |
+
tmpHook = hooks[ i ];
|
223 |
+
j = i;
|
224 |
+
while( ( prevHook = hooks[ j - 1 ] ) && prevHook.priority > tmpHook.priority ) {
|
225 |
+
hooks[ j ] = hooks[ j - 1 ];
|
226 |
+
--j;
|
227 |
+
}
|
228 |
+
hooks[ j ] = tmpHook;
|
229 |
+
}
|
230 |
+
|
231 |
+
return hooks;
|
232 |
+
}
|
233 |
+
|
234 |
+
/**
|
235 |
+
* Runs the specified hook. If it is an action, the value is not modified but if it is a filter, it is.
|
236 |
+
*
|
237 |
+
* @param type 'actions' or 'filters'
|
238 |
+
* @param hook The hook ( namespace.identifier ) to be ran.
|
239 |
+
* @param args Arguments to pass to the action/filter. If it's a filter, args is actually a single parameter.
|
240 |
+
* @private
|
241 |
+
*/
|
242 |
+
function _runHook( type, hook, args ) {
|
243 |
+
var handlers = STORAGE[ type ][ hook ];
|
244 |
+
|
245 |
+
if ( !handlers ) {
|
246 |
+
return (type === 'filters') ? args[0] : false;
|
247 |
+
}
|
248 |
+
|
249 |
+
var i = 0, len = handlers.length;
|
250 |
+
if ( type === 'filters' ) {
|
251 |
+
for ( ; i < len; i++ ) {
|
252 |
+
args[ 0 ] = handlers[ i ].callback.apply( handlers[ i ].context, args );
|
253 |
+
}
|
254 |
+
} else {
|
255 |
+
for ( ; i < len; i++ ) {
|
256 |
+
handlers[ i ].callback.apply( handlers[ i ].context, args );
|
257 |
+
}
|
258 |
+
}
|
259 |
+
|
260 |
+
return ( type === 'filters' ) ? args[ 0 ] : true;
|
261 |
+
}
|
262 |
+
|
263 |
+
// return all of the publicly available methods
|
264 |
+
return MethodsAvailable;
|
265 |
+
|
266 |
+
};
|
267 |
+
|
268 |
+
_inbound.hooks = new EventManager();
|
269 |
+
|
270 |
+
|
271 |
+
/**
|
272 |
+
* Event Hooks and Filters public methods
|
273 |
+
*/
|
274 |
+
/*
|
275 |
+
* add_action
|
276 |
+
*
|
277 |
+
* This function uses _inbound.hooks to mimics WP add_action
|
278 |
+
*
|
279 |
+
* ```js
|
280 |
+
* function Inbound_Add_Action_Example(data) {
|
281 |
+
* // Do stuff here.
|
282 |
+
* };
|
283 |
+
* // Add action to the hook
|
284 |
+
* _inbound.add_action( 'name_of_action', Inbound_Add_Action_Example, 10 );
|
285 |
+
* ```
|
286 |
+
*/
|
287 |
+
_inbound.add_action = function() {
|
288 |
+
// allow multiple action parameters such as 'ready append'
|
289 |
+
var actions = arguments[0].split(' ');
|
290 |
+
|
291 |
+
for( k in actions ) {
|
292 |
+
|
293 |
+
// prefix action
|
294 |
+
arguments[0] = 'inbound.' + actions[ k ];
|
295 |
+
|
296 |
+
_inbound.hooks.addAction.apply(this, arguments);
|
297 |
+
}
|
298 |
+
|
299 |
+
return this;
|
300 |
+
|
301 |
+
};
|
302 |
+
/*
|
303 |
+
* remove_action
|
304 |
+
*
|
305 |
+
* This function uses _inbound.hooks to mimics WP remove_action
|
306 |
+
*
|
307 |
+
* ```js
|
308 |
+
* // Add remove action 'name_of_action'
|
309 |
+
* _inbound.remove_action( 'name_of_action');
|
310 |
+
* ```
|
311 |
+
*
|
312 |
+
*/
|
313 |
+
_inbound.remove_action = function() {
|
314 |
+
// prefix action
|
315 |
+
arguments[0] = 'inbound.' + arguments[0];
|
316 |
+
_inbound.hooks.removeAction.apply(this, arguments);
|
317 |
+
|
318 |
+
return this;
|
319 |
+
|
320 |
+
};
|
321 |
+
/*
|
322 |
+
* do_action
|
323 |
+
*
|
324 |
+
* This function uses _inbound.hooks to mimics WP do_action
|
325 |
+
* This is used if you want to allow for third party JS plugins to act on your functions
|
326 |
+
*
|
327 |
+
*/
|
328 |
+
_inbound.do_action = function() {
|
329 |
+
// prefix action
|
330 |
+
arguments[0] = 'inbound.' + arguments[0];
|
331 |
+
_inbound.hooks.doAction.apply(this, arguments);
|
332 |
+
|
333 |
+
return this;
|
334 |
+
|
335 |
+
};
|
336 |
+
/*
|
337 |
+
* add_filter
|
338 |
+
*
|
339 |
+
* This function uses _inbound.hooks to mimics WP add_filter
|
340 |
+
*
|
341 |
+
* ```js
|
342 |
+
* _inbound.add_filter( 'urlParamFilter', URL_Param_Filter, 10 );
|
343 |
+
* function URL_Param_Filter(urlParams) {
|
344 |
+
*
|
345 |
+
* var params = urlParams || {};
|
346 |
+
* // check for item in object
|
347 |
+
* if(params.utm_source !== "undefined"){
|
348 |
+
* //alert('url param "utm_source" is here');
|
349 |
+
* }
|
350 |
+
*
|
351 |
+
* // delete item from object
|
352 |
+
* delete params.utm_source;
|
353 |
+
*
|
354 |
+
* return params;
|
355 |
+
*
|
356 |
+
* }
|
357 |
+
* ```
|
358 |
+
*/
|
359 |
+
_inbound.add_filter = function() {
|
360 |
+
// prefix action
|
361 |
+
arguments[0] = 'inbound.' + arguments[0];
|
362 |
+
_inbound.hooks.addFilter.apply(this, arguments);
|
363 |
+
|
364 |
+
return this;
|
365 |
+
|
366 |
+
};
|
367 |
+
/*
|
368 |
+
* remove_filter
|
369 |
+
*
|
370 |
+
* This function uses _inbound.hooks to mimics WP remove_filter
|
371 |
+
*
|
372 |
+
* ```js
|
373 |
+
* // Add remove filter 'urlParamFilter'
|
374 |
+
* _inbound.remove_action( 'urlParamFilter');
|
375 |
+
* ```
|
376 |
+
*
|
377 |
+
*/
|
378 |
+
_inbound.remove_filter = function() {
|
379 |
+
// prefix action
|
380 |
+
arguments[0] = 'inbound.' + arguments[0];
|
381 |
+
|
382 |
+
_inbound.hooks.removeFilter.apply(this, arguments);
|
383 |
+
|
384 |
+
return this;
|
385 |
+
|
386 |
+
};
|
387 |
+
/*
|
388 |
+
* apply_filters
|
389 |
+
*
|
390 |
+
* This function uses _inbound.hooks to mimics WP apply_filters
|
391 |
+
*
|
392 |
+
*/
|
393 |
+
_inbound.apply_filters = function() {
|
394 |
+
//console.log('Filter:' + arguments[0] + " ran on ->", arguments[1]);
|
395 |
+
// prefix action
|
396 |
+
arguments[0] = 'inbound.' + arguments[0];
|
397 |
+
|
398 |
+
return _inbound.hooks.applyFilters.apply(this, arguments);
|
399 |
+
|
400 |
+
};
|
401 |
+
|
402 |
+
|
403 |
+
return _inbound;
|
404 |
+
|
405 |
Â
})(_inbound || {});
|
shared/assets/js/frontend/analytics-src/analytics.init.js
CHANGED
@@ -1,131 +1,131 @@
|
|
1 |
-
/**
|
2 |
-
* # _inbound
|
3 |
-
*
|
4 |
-
* This main the _inbound class
|
5 |
-
*
|
6 |
-
* @
|
7 |
-
* @
|
8 |
-
* @version 0.0.2
|
9 |
-
*/
|
10 |
-
|
11 |
-
var inbound_data = inbound_data || {};
|
12 |
-
var _inboundOptions = _inboundOptions || {};
|
13 |
-
/* Ensure global _gaq Google Analytics queue has been initialized. */
|
14 |
-
var _gaq = _gaq || [];
|
15 |
-
|
16 |
-
var _inbound = (function(options) {
|
17 |
-
|
18 |
-
/* Constants */
|
19 |
-
var defaults = {
|
20 |
-
timeout: ( inbound_settings.is_admin ? 500 : 10000 ),
|
21 |
-
formAutoTracking: true,
|
22 |
-
formAutoPopulation: true
|
23 |
-
};
|
24 |
-
|
25 |
-
var Analytics = {
|
26 |
-
/* Initialize individual modules */
|
27 |
-
init: function() {
|
28 |
-
_inbound.Utils.init();
|
29 |
-
|
30 |
-
_inbound.Utils.domReady(window, function() {
|
31 |
-
/* On Load Analytics Events */
|
32 |
-
_inbound.DomLoaded();
|
33 |
-
|
34 |
-
});
|
35 |
-
},
|
36 |
-
DomLoaded: function() {
|
37 |
-
_inbound.PageTracking.init();
|
38 |
-
/* run form mapping */
|
39 |
-
_inbound.Forms.init();
|
40 |
-
/* set URL params */
|
41 |
-
_inbound.Utils.setUrlParams();
|
42 |
-
_inbound.LeadsAPI.init();
|
43 |
-
/* run form mapping for dynamically generated forms */
|
44 |
-
setTimeout(function() {
|
45 |
-
_inbound.Forms.init();
|
46 |
-
}, 2000);
|
47 |
-
|
48 |
-
_inbound.trigger('analytics_ready');
|
49 |
-
|
50 |
-
},
|
51 |
-
/**
|
52 |
-
* Merge script defaults with user options
|
53 |
-
* @private
|
54 |
-
* @param {Object} defaults Default settings
|
55 |
-
* @param {Object} options User options
|
56 |
-
* @returns {Object} Merged values of defaults and options
|
57 |
-
*/
|
58 |
-
extend: function(defaults, options) {
|
59 |
-
var extended = {};
|
60 |
-
var prop;
|
61 |
-
for (prop in defaults) {
|
62 |
-
if (Object.prototype.hasOwnProperty.call(defaults, prop)) {
|
63 |
-
extended[prop] = defaults[prop];
|
64 |
-
}
|
65 |
-
}
|
66 |
-
for (prop in options) {
|
67 |
-
if (Object.prototype.hasOwnProperty.call(options, prop)) {
|
68 |
-
extended[prop] = options[prop];
|
69 |
-
}
|
70 |
-
}
|
71 |
-
return extended;
|
72 |
-
},
|
73 |
-
/* Debugger Function toggled by var debugMode */
|
74 |
-
debug: function(msg, callback) {
|
75 |
-
/* legacy */
|
76 |
-
},
|
77 |
-
deBugger: function(context, msg, callback) {
|
78 |
-
|
79 |
-
if (!console) {
|
80 |
-
return;
|
81 |
-
}
|
82 |
-
//if app not in debug mode, exit immediately
|
83 |
-
// check for hash
|
84 |
-
var hash = (document.location.hash) ? document.location.hash : '',
|
85 |
-
debugHash = hash.indexOf("#debug") > -1,
|
86 |
-
msg = msg || false,
|
87 |
-
logCookie,
|
88 |
-
logAllMessages,
|
89 |
-
hashcontext;
|
90 |
-
|
91 |
-
if (hash && hash.match(/debug/)) {
|
92 |
-
hash = hash.split('-');
|
93 |
-
hashcontext = hash[1];
|
94 |
-
}
|
95 |
-
|
96 |
-
|
97 |
-
logAllMessages = (_inbound.Utils.readCookie("inbound_debug") === "true") ? true : false;
|
98 |
-
logCookie = (_inbound.Utils.readCookie("inbound_debug_" + context) === "true") ? true : false;
|
99 |
-
|
100 |
-
if (!logCookie && !debugHash && !logAllMessages) {
|
101 |
-
// no logger set. exit.
|
102 |
-
return;
|
103 |
-
};
|
104 |
-
|
105 |
-
//console.log the message
|
106 |
-
if (msg && (typeof msg === 'string')) {
|
107 |
-
|
108 |
-
if (logAllMessages || hashcontext === 'all') {
|
109 |
-
console.log('logAll "' + context + '" =>', msg)
|
110 |
-
} else if (logCookie) {
|
111 |
-
console.log('log "' + context + '" =>', msg)
|
112 |
-
} else if (context === hashcontext) {
|
113 |
-
console.log('#log "' + context + '" =>', msg)
|
114 |
-
}
|
115 |
-
|
116 |
-
};
|
117 |
-
|
118 |
-
//execute the callback if one was passed-in
|
119 |
-
if (callback && (callback instanceof Function)) {
|
120 |
-
callback();
|
121 |
-
};
|
122 |
-
}
|
123 |
-
};
|
124 |
-
|
125 |
-
var settings = Analytics.extend(defaults, options);
|
126 |
-
/* Set globals */
|
127 |
-
Analytics.Settings = settings || {};
|
128 |
-
|
129 |
-
return Analytics;
|
130 |
-
|
131 |
Â
})(_inboundOptions);
|
1 |
+
/**
|
2 |
+
* # _inbound
|
3 |
+
*
|
4 |
+
* This main the _inbound class
|
5 |
+
*
|
6 |
+
* @contributor David Wells <david@inboundnow.com>
|
7 |
+
* @contributor Hudson Atwell <hudson@inboundnow.com>
|
8 |
+
* @version 0.0.2
|
9 |
+
*/
|
10 |
+
|
11 |
+
var inbound_data = inbound_data || {};
|
12 |
+
var _inboundOptions = _inboundOptions || {};
|
13 |
+
/* Ensure global _gaq Google Analytics queue has been initialized. */
|
14 |
+
var _gaq = _gaq || [];
|
15 |
+
|
16 |
+
var _inbound = (function(options) {
|
17 |
+
|
18 |
+
/* Constants */
|
19 |
+
var defaults = {
|
20 |
+
timeout: ( inbound_settings.is_admin ? 500 : 10000 ),
|
21 |
+
formAutoTracking: true,
|
22 |
+
formAutoPopulation: true
|
23 |
+
};
|
24 |
+
|
25 |
+
var Analytics = {
|
26 |
+
/* Initialize individual modules */
|
27 |
+
init: function() {
|
28 |
+
_inbound.Utils.init();
|
29 |
+
|
30 |
+
_inbound.Utils.domReady(window, function() {
|
31 |
+
/* On Load Analytics Events */
|
32 |
+
_inbound.DomLoaded();
|
33 |
+
|
34 |
+
});
|
35 |
+
},
|
36 |
+
DomLoaded: function() {
|
37 |
+
_inbound.PageTracking.init();
|
38 |
+
/* run form mapping */
|
39 |
+
_inbound.Forms.init();
|
40 |
+
/* set URL params */
|
41 |
+
_inbound.Utils.setUrlParams();
|
42 |
+
_inbound.LeadsAPI.init();
|
43 |
+
/* run form mapping for dynamically generated forms */
|
44 |
+
setTimeout(function() {
|
45 |
+
_inbound.Forms.init();
|
46 |
+
}, 2000);
|
47 |
+
|
48 |
+
_inbound.trigger('analytics_ready');
|
49 |
+
|
50 |
+
},
|
51 |
+
/**
|
52 |
+
* Merge script defaults with user options
|
53 |
+
* @private
|
54 |
+
* @param {Object} defaults Default settings
|
55 |
+
* @param {Object} options User options
|
56 |
+
* @returns {Object} Merged values of defaults and options
|
57 |
+
*/
|
58 |
+
extend: function(defaults, options) {
|
59 |
+
var extended = {};
|
60 |
+
var prop;
|
61 |
+
for (prop in defaults) {
|
62 |
+
if (Object.prototype.hasOwnProperty.call(defaults, prop)) {
|
63 |
+
extended[prop] = defaults[prop];
|
64 |
+
}
|
65 |
+
}
|
66 |
+
for (prop in options) {
|
67 |
+
if (Object.prototype.hasOwnProperty.call(options, prop)) {
|
68 |
+
extended[prop] = options[prop];
|
69 |
+
}
|
70 |
+
}
|
71 |
+
return extended;
|
72 |
+
},
|
73 |
+
/* Debugger Function toggled by var debugMode */
|
74 |
+
debug: function(msg, callback) {
|
75 |
+
/* legacy */
|
76 |
+
},
|
77 |
+
deBugger: function(context, msg, callback) {
|
78 |
+
|
79 |
+
if (!console) {
|
80 |
+
return;
|
81 |
+
}
|
82 |
+
//if app not in debug mode, exit immediately
|
83 |
+
// check for hash
|
84 |
+
var hash = (document.location.hash) ? document.location.hash : '',
|
85 |
+
debugHash = hash.indexOf("#debug") > -1,
|
86 |
+
msg = msg || false,
|
87 |
+
logCookie,
|
88 |
+
logAllMessages,
|
89 |
+
hashcontext;
|
90 |
+
|
91 |
+
if (hash && hash.match(/debug/)) {
|
92 |
+
hash = hash.split('-');
|
93 |
+
hashcontext = hash[1];
|
94 |
+
}
|
95 |
+
|
96 |
+
|
97 |
+
logAllMessages = (_inbound.Utils.readCookie("inbound_debug") === "true") ? true : false;
|
98 |
+
logCookie = (_inbound.Utils.readCookie("inbound_debug_" + context) === "true") ? true : false;
|
99 |
+
|
100 |
+
if (!logCookie && !debugHash && !logAllMessages) {
|
101 |
+
// no logger set. exit.
|
102 |
+
return;
|
103 |
+
};
|
104 |
+
|
105 |
+
//console.log the message
|
106 |
+
if (msg && (typeof msg === 'string')) {
|
107 |
+
|
108 |
+
if (logAllMessages || hashcontext === 'all') {
|
109 |
+
console.log('logAll "' + context + '" =>', msg)
|
110 |
+
} else if (logCookie) {
|
111 |
+
console.log('log "' + context + '" =>', msg)
|
112 |
+
} else if (context === hashcontext) {
|
113 |
+
console.log('#log "' + context + '" =>', msg)
|
114 |
+
}
|
115 |
+
|
116 |
+
};
|
117 |
+
|
118 |
+
//execute the callback if one was passed-in
|
119 |
+
if (callback && (callback instanceof Function)) {
|
120 |
+
callback();
|
121 |
+
};
|
122 |
+
}
|
123 |
+
};
|
124 |
+
|
125 |
+
var settings = Analytics.extend(defaults, options);
|
126 |
+
/* Set globals */
|
127 |
+
Analytics.Settings = settings || {};
|
128 |
+
|
129 |
+
return Analytics;
|
130 |
+
|
131 |
Â
})(_inboundOptions);
|
shared/assets/js/frontend/analytics-src/analytics.page.js
CHANGED
@@ -1,394 +1,395 @@
|
|
1 |
-
/**
|
2 |
-
* # Page View Tracking
|
3 |
-
*
|
4 |
-
* Page view tracking
|
5 |
-
*
|
6 |
-
* @
|
7 |
-
* @
|
8 |
-
* @version 0.0.2
|
9 |
-
*/
|
10 |
-
/* Launches view tracking */
|
11 |
-
var _inboundPageTracking = (function(_inbound) {
|
12 |
-
|
13 |
-
var started = false,
|
14 |
-
stopped = false,
|
15 |
-
turnedOff = false,
|
16 |
-
clockTime = parseInt(_inbound.Utils.readCookie("lead_session"), 10) || 0,
|
17 |
-
inactiveClockTime = 0,
|
18 |
-
startTime = new Date(),
|
19 |
-
clockTimer = null,
|
20 |
-
inactiveClockTimer = null,
|
21 |
-
idleTimer = null,
|
22 |
-
reportInterval,
|
23 |
-
idleTimeout,
|
24 |
-
utils = _inbound.Utils,
|
25 |
-
timeNow = _inbound.Utils.GetDate(),
|
26 |
-
lsType = 'page_views',
|
27 |
-
Pages = _inbound.totalStorage(lsType) || {},
|
28 |
-
/*!
|
29 |
-
Todo: Use UTC offset
|
30 |
-
var x = new Date();
|
31 |
-
var currentTime = x.getTimezoneOffset() / 60;
|
32 |
-
console.log(currentTime) // gets UTC offset
|
33 |
-
*/
|
34 |
-
id = inbound_settings.post_id || window.location.pathname,
|
35 |
-
analyticsTimeout = _inbound.Settings.timeout || 10000;
|
36 |
-
|
37 |
-
_inbound.PageTracking = {
|
38 |
-
|
39 |
-
init: function(options) {
|
40 |
-
|
41 |
-
if(lsType !== 'page_views') {
|
42 |
-
return false; // in admin
|
43 |
-
}
|
44 |
-
|
45 |
-
this.CheckTimeOut();
|
46 |
-
// Set up options and defaults
|
47 |
-
options = options || {};
|
48 |
-
reportInterval = parseInt(options.reportInterval, 10) || 10;
|
49 |
-
idleTimeout = parseInt(options.idleTimeout, 10) || 3;
|
50 |
-
|
51 |
-
// Basic activity event listeners
|
52 |
-
utils.addListener(document, 'keydown', utils.throttle(_inbound.PageTracking.pingSession, 1000));
|
53 |
-
utils.addListener(document, 'click', utils.throttle(_inbound.PageTracking.pingSession, 1000));
|
54 |
-
utils.addListener(window, 'mousemove', utils.throttle(_inbound.PageTracking.pingSession, 1000));
|
55 |
-
//utils.addListener(window, 'scroll', utils.throttle(_inbound.PageTracking.pingSession, 1000));
|
56 |
-
|
57 |
-
// Page visibility listeners
|
58 |
-
_inbound.PageTracking.checkVisibility();
|
59 |
-
|
60 |
-
/* Start Session on page load */
|
61 |
-
this.startSession();
|
62 |
-
|
63 |
-
},
|
64 |
-
|
65 |
-
setIdle: function(reason) {
|
66 |
-
var reason = reason || "No Movement",
|
67 |
-
msg = 'Session IDLE. Activity Timeout due to ' + reason;
|
68 |
-
|
69 |
-
_inbound.deBugger('pages', msg);
|
70 |
-
|
71 |
-
clearTimeout(_inbound.PageTracking.idleTimer);
|
72 |
-
_inbound.PageTracking.stopClock();
|
73 |
-
_inbound.trigger('session_idle');
|
74 |
-
|
75 |
-
},
|
76 |
-
|
77 |
-
checkVisibility: function() {
|
78 |
-
var hidden, visibilityState, visibilityChange;
|
79 |
-
|
80 |
-
if (typeof document.hidden !== "undefined") {
|
81 |
-
hidden = "hidden", visibilityChange = "visibilitychange", visibilityState = "visibilityState";
|
82 |
-
} else if (typeof document.mozHidden !== "undefined") {
|
83 |
-
hidden = "mozHidden", visibilityChange = "mozvisibilitychange", visibilityState = "mozVisibilityState";
|
84 |
-
} else if (typeof document.msHidden !== "undefined") {
|
85 |
-
hidden = "msHidden", visibilityChange = "msvisibilitychange", visibilityState = "msVisibilityState";
|
86 |
-
} else if (typeof document.webkitHidden !== "undefined") {
|
87 |
-
hidden = "webkitHidden", visibilityChange = "webkitvisibilitychange", visibilityState = "webkitVisibilityState";
|
88 |
-
}
|
89 |
-
|
90 |
-
var document_hidden = document[hidden];
|
91 |
-
|
92 |
-
_inbound.Utils.addListener(document, visibilityChange, function(e) {
|
93 |
-
/*! Listen for visibility changes */
|
94 |
-
if (document_hidden != document[hidden]) {
|
95 |
-
if (document[hidden]) {
|
96 |
-
// Document hidden
|
97 |
-
_inbound.trigger('tab_hidden');
|
98 |
-
_inbound.PageTracking.setIdle('browser tab switch');
|
99 |
-
} else {
|
100 |
-
// Document shown
|
101 |
-
_inbound.trigger('tab_visible');
|
102 |
-
_inbound.PageTracking.pingSession();
|
103 |
-
}
|
104 |
-
|
105 |
-
document_hidden = document[hidden];
|
106 |
-
}
|
107 |
-
});
|
108 |
-
},
|
109 |
-
clock: function() {
|
110 |
-
clockTime += 1;
|
111 |
-
var niceTime = clockTime / 60;
|
112 |
-
var msg = 'Total time spent on Page in this Session: ' + niceTime.toFixed(2) + " min";
|
113 |
-
_inbound.deBugger('pages', msg);
|
114 |
-
if (clockTime > 0 && (clockTime % reportInterval === 0)) {
|
115 |
-
|
116 |
-
var d = new Date();
|
117 |
-
d.setTime(d.getTime() + 30 * 60 * 1000);
|
118 |
-
utils.createCookie("lead_session", clockTime, d); // Set cookie on page load
|
119 |
-
|
120 |
-
/*! every 10 seconds run this */
|
121 |
-
//console.log('Session Heartbeat every ' + reportInterval + ' secs');
|
122 |
-
_inbound.trigger('session_heartbeat', clockTime);
|
123 |
-
|
124 |
-
}
|
125 |
-
|
126 |
-
},
|
127 |
-
inactiveClock: function() {
|
128 |
-
inactiveClockTime += 1;
|
129 |
-
var TimeUntilTimeOut = (1800 - inactiveClockTime) / 60;
|
130 |
-
var msg = 'Time until Session Timeout: ' + TimeUntilTimeOut.toFixed(2) + " min";
|
131 |
-
_inbound.deBugger('pages', msg);
|
132 |
-
//console.log('Time until Session Timeout: ', TimeUntilTimeOut.toFixed(2) + " min");
|
133 |
-
/* Session timeout after 30min */
|
134 |
-
if (inactiveClockTime > 1800) {
|
135 |
-
|
136 |
-
// sendEvent(clockTime);
|
137 |
-
/*! End session after 30min timeout */
|
138 |
-
_inbound.trigger('session_end', InboundLeadData);
|
139 |
-
_inbound.Utils.eraseCookie("lead_session");
|
140 |
-
/* todo maybe? remove session Cookie */
|
141 |
-
inactiveClockTime = 0;
|
142 |
-
clearTimeout(inactiveClockTimer);
|
143 |
-
}
|
144 |
-
|
145 |
-
|
146 |
-
},
|
147 |
-
stopClock: function() {
|
148 |
-
stopped = true;
|
149 |
-
clearTimeout(clockTimer);
|
150 |
-
clearTimeout(inactiveClockTimer);
|
151 |
-
inactiveClockTimer = setInterval(_inbound.PageTracking.inactiveClock, 1000);
|
152 |
-
},
|
153 |
-
|
154 |
-
restartClock: function() {
|
155 |
-
stopped = false;
|
156 |
-
|
157 |
-
|
158 |
-
_inbound.trigger('session_resume');
|
159 |
-
_inbound.deBugger('pages', 'Activity resumed. Session Active');
|
160 |
-
/* todo add session_resume */
|
161 |
-
clearTimeout(clockTimer);
|
162 |
-
inactiveClockTime = 0;
|
163 |
-
clearTimeout(inactiveClockTimer);
|
164 |
-
clockTimer = setInterval(_inbound.PageTracking.clock, 1000);
|
165 |
-
},
|
166 |
-
|
167 |
-
turnOff: function() {
|
168 |
-
_inbound.PageTracking.setIdle();
|
169 |
-
turnedOff = true;
|
170 |
-
},
|
171 |
-
|
172 |
-
turnOn: function() {
|
173 |
-
turnedOff = false;
|
174 |
-
},
|
175 |
-
/* This start only runs once */
|
176 |
-
startSession: function() {
|
177 |
-
/* todo add session Cookie */
|
178 |
-
// Calculate seconds from start to first interaction
|
179 |
-
var currentTime = new Date();
|
180 |
-
var diff = currentTime - startTime;
|
181 |
-
|
182 |
-
|
183 |
-
started = true; // Set global
|
184 |
-
|
185 |
-
// Send User Timing Event
|
186 |
-
/* Todo session start here */
|
187 |
-
|
188 |
-
// Start clock
|
189 |
-
clockTimer = setInterval(_inbound.PageTracking.clock, 1000);
|
190 |
-
//utils.eraseCookie("lead_session");
|
191 |
-
var session = utils.readCookie("lead_session");
|
192 |
-
|
193 |
-
if (!session) {
|
194 |
-
_inbound.trigger('session_start'); // trigger 'inbound_analytics_session_start'
|
195 |
-
var d = new Date();
|
196 |
-
d.setTime(d.getTime() + 30 * 60 * 1000);
|
197 |
-
_inbound.Utils.createCookie("lead_session", 1, d); // Set cookie on page load
|
198 |
-
} else {
|
199 |
-
_inbound.trigger('session_active');
|
200 |
-
//console.log("count of secs " + session);
|
201 |
-
//_inbound.trigger('session_active'); // trigger 'inbound_analytics_session_active'
|
202 |
-
}
|
203 |
-
|
204 |
-
this.pingSession();
|
205 |
-
|
206 |
-
|
207 |
-
},
|
208 |
-
resetInactiveFunc: function() {
|
209 |
-
inactiveClockTime = 0;
|
210 |
-
clearTimeout(inactiveClockTimer);
|
211 |
-
},
|
212 |
-
/* Ping Session to keep active */
|
213 |
-
pingSession: function(e) {
|
214 |
-
|
215 |
-
|
216 |
-
if (turnedOff) {
|
217 |
-
return;
|
218 |
-
}
|
219 |
-
|
220 |
-
if (!started) {
|
221 |
-
_inbound.PageTracking.startSession();
|
222 |
-
}
|
223 |
-
|
224 |
-
if (stopped) {
|
225 |
-
_inbound.PageTracking.restartClock();
|
226 |
-
}
|
227 |
-
|
228 |
-
clearTimeout(idleTimer);
|
229 |
-
|
230 |
-
idleTimer = setTimeout(_inbound.PageTracking.setIdle, idleTimeout * 1000 + 100);
|
231 |
-
|
232 |
-
if (typeof(e) != "undefined") {
|
233 |
-
if (e.type === "mousemove") {
|
234 |
-
_inbound.PageTracking.mouseEvents(e);
|
235 |
-
}
|
236 |
-
}
|
237 |
-
|
238 |
-
},
|
239 |
-
mouseEvents: function(e) {
|
240 |
-
|
241 |
-
if (e.pageY <= 5) {
|
242 |
-
_inbound.trigger('tab_mouseout');
|
243 |
-
}
|
244 |
-
|
245 |
-
},
|
246 |
-
/**
|
247 |
-
* Returns the pages viewed by the site visitor
|
248 |
-
*
|
249 |
-
* ```js
|
250 |
-
* var pageViews = _inbound.PageTracking.getPageViews();
|
251 |
-
* // returns page view object
|
252 |
-
* ```
|
253 |
-
*
|
254 |
-
* @return {object} page view object with page ID as key and timestamp
|
255 |
-
*/
|
256 |
-
getPageViews: function() {
|
257 |
-
var local_store = _inbound.Utils.checkLocalStorage();
|
258 |
-
if (local_store) {
|
259 |
-
var page_views = localStorage.getItem(lsType),
|
260 |
-
local_object = JSON.parse(page_views);
|
261 |
-
if (typeof local_object == 'object' && local_object) {
|
262 |
-
//this.triggerPageView();
|
263 |
-
}
|
264 |
-
return local_object;
|
265 |
-
}
|
266 |
-
},
|
267 |
-
isRevisit: function(Pages) {
|
268 |
-
var revisitCheck = false;
|
269 |
-
var Pages = Pages || {};
|
270 |
-
var pageSeen = Pages[id];
|
271 |
-
if (typeof(pageSeen) != "undefined" && pageSeen !== null) {
|
272 |
-
revisitCheck = true;
|
273 |
-
}
|
274 |
-
return revisitCheck;
|
275 |
-
},
|
276 |
-
triggerPageView: function(pageRevisit) {
|
277 |
-
|
278 |
-
var pageData = {
|
279 |
-
title: document.title,
|
280 |
-
url: document.location.href,
|
281 |
-
path: document.location.pathname,
|
282 |
-
count: 1 // default
|
283 |
-
};
|
284 |
-
|
285 |
-
if (pageRevisit) {
|
286 |
-
/* Page Revisit Trigger */
|
287 |
-
Pages[id].push(timeNow);
|
288 |
-
pageData.count = Pages[id].length;
|
289 |
-
_inbound.trigger('page_revisit', pageData);
|
290 |
-
|
291 |
-
} else {
|
292 |
-
/* Page First Seen Trigger */
|
293 |
-
Pages[id] = [];
|
294 |
-
Pages[id].push(timeNow);
|
295 |
-
_inbound.trigger('page_first_visit', pageData);
|
296 |
-
}
|
297 |
-
|
298 |
-
_inbound.trigger('page_visit', pageData);
|
299 |
-
|
300 |
-
_inbound.totalStorage(lsType, Pages);
|
301 |
-
|
302 |
-
this.storePageView();
|
303 |
-
|
304 |
-
},
|
305 |
-
CheckTimeOut: function() {
|
306 |
-
|
307 |
-
var pageRevisit = this.isRevisit(Pages),
|
308 |
-
status,
|
309 |
-
timeout;
|
310 |
-
|
311 |
-
/* Default */
|
312 |
-
if (pageRevisit) {
|
313 |
-
|
314 |
-
var prev = Pages[id].length - 1,
|
315 |
-
lastView = Pages[id][prev],
|
316 |
-
timeDiff = Math.abs(new Date(lastView).getTime() - new Date(timeNow).getTime());
|
317 |
-
|
318 |
-
timeout = timeDiff > analyticsTimeout;
|
319 |
-
|
320 |
-
if (timeout) {
|
321 |
-
status = 'Timeout Happened. Page view fired';
|
322 |
-
this.triggerPageView(pageRevisit);
|
323 |
-
} else {
|
324 |
-
time_left = Math.abs((analyticsTimeout - timeDiff)) * 0.001;
|
325 |
-
status = analyticsTimeout / 1000 + ' sec timeout not done: ' + time_left + " seconds left";
|
326 |
-
}
|
327 |
-
|
328 |
-
} else {
|
329 |
-
/*! Page never seen before save view */
|
330 |
-
this.triggerPageView(pageRevisit);
|
331 |
-
}
|
332 |
-
|
333 |
-
_inbound.deBugger('pages', status);
|
334 |
-
},
|
335 |
-
storePageView: function() {
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
Â
|
|
394 |
Â
})(_inbound || {});
|
1 |
+
/**
|
2 |
+
* # Page View Tracking
|
3 |
+
*
|
4 |
+
* Page view tracking
|
5 |
+
*
|
6 |
+
* @contributor David Wells <david@inboundnow.com>
|
7 |
+
* @contributor Hudson Atwell <hudson@inboundnow.com>
|
8 |
+
* @version 0.0.2
|
9 |
+
*/
|
10 |
+
/* Launches view tracking */
|
11 |
+
var _inboundPageTracking = (function(_inbound) {
|
12 |
+
|
13 |
+
var started = false,
|
14 |
+
stopped = false,
|
15 |
+
turnedOff = false,
|
16 |
+
clockTime = parseInt(_inbound.Utils.readCookie("lead_session"), 10) || 0,
|
17 |
+
inactiveClockTime = 0,
|
18 |
+
startTime = new Date(),
|
19 |
+
clockTimer = null,
|
20 |
+
inactiveClockTimer = null,
|
21 |
+
idleTimer = null,
|
22 |
+
reportInterval,
|
23 |
+
idleTimeout,
|
24 |
+
utils = _inbound.Utils,
|
25 |
+
timeNow = _inbound.Utils.GetDate(),
|
26 |
+
lsType = 'page_views',
|
27 |
+
Pages = _inbound.totalStorage(lsType) || {},
|
28 |
+
/*!
|
29 |
+
Todo: Use UTC offset
|
30 |
+
var x = new Date();
|
31 |
+
var currentTime = x.getTimezoneOffset() / 60;
|
32 |
+
console.log(currentTime) // gets UTC offset
|
33 |
+
*/
|
34 |
+
id = inbound_settings.post_id || window.location.pathname,
|
35 |
+
analyticsTimeout = _inbound.Settings.timeout || 10000;
|
36 |
+
|
37 |
+
_inbound.PageTracking = {
|
38 |
+
|
39 |
+
init: function(options) {
|
40 |
+
|
41 |
+
if(lsType !== 'page_views') {
|
42 |
+
return false; // in admin
|
43 |
+
}
|
44 |
+
|
45 |
+
this.CheckTimeOut();
|
46 |
+
// Set up options and defaults
|
47 |
+
options = options || {};
|
48 |
+
reportInterval = parseInt(options.reportInterval, 10) || 10;
|
49 |
+
idleTimeout = parseInt(options.idleTimeout, 10) || 3;
|
50 |
+
|
51 |
+
// Basic activity event listeners
|
52 |
+
utils.addListener(document, 'keydown', utils.throttle(_inbound.PageTracking.pingSession, 1000));
|
53 |
+
utils.addListener(document, 'click', utils.throttle(_inbound.PageTracking.pingSession, 1000));
|
54 |
+
utils.addListener(window, 'mousemove', utils.throttle(_inbound.PageTracking.pingSession, 1000));
|
55 |
+
//utils.addListener(window, 'scroll', utils.throttle(_inbound.PageTracking.pingSession, 1000));
|
56 |
+
|
57 |
+
// Page visibility listeners
|
58 |
+
_inbound.PageTracking.checkVisibility();
|
59 |
+
|
60 |
+
/* Start Session on page load */
|
61 |
+
this.startSession();
|
62 |
+
|
63 |
+
},
|
64 |
+
|
65 |
+
setIdle: function(reason) {
|
66 |
+
var reason = reason || "No Movement",
|
67 |
+
msg = 'Session IDLE. Activity Timeout due to ' + reason;
|
68 |
+
|
69 |
+
_inbound.deBugger('pages', msg);
|
70 |
+
|
71 |
+
clearTimeout(_inbound.PageTracking.idleTimer);
|
72 |
+
_inbound.PageTracking.stopClock();
|
73 |
+
_inbound.trigger('session_idle');
|
74 |
+
|
75 |
+
},
|
76 |
+
|
77 |
+
checkVisibility: function() {
|
78 |
+
var hidden, visibilityState, visibilityChange;
|
79 |
+
|
80 |
+
if (typeof document.hidden !== "undefined") {
|
81 |
+
hidden = "hidden", visibilityChange = "visibilitychange", visibilityState = "visibilityState";
|
82 |
+
} else if (typeof document.mozHidden !== "undefined") {
|
83 |
+
hidden = "mozHidden", visibilityChange = "mozvisibilitychange", visibilityState = "mozVisibilityState";
|
84 |
+
} else if (typeof document.msHidden !== "undefined") {
|
85 |
+
hidden = "msHidden", visibilityChange = "msvisibilitychange", visibilityState = "msVisibilityState";
|
86 |
+
} else if (typeof document.webkitHidden !== "undefined") {
|
87 |
+
hidden = "webkitHidden", visibilityChange = "webkitvisibilitychange", visibilityState = "webkitVisibilityState";
|
88 |
+
}
|
89 |
+
|
90 |
+
var document_hidden = document[hidden];
|
91 |
+
|
92 |
+
_inbound.Utils.addListener(document, visibilityChange, function(e) {
|
93 |
+
/*! Listen for visibility changes */
|
94 |
+
if (document_hidden != document[hidden]) {
|
95 |
+
if (document[hidden]) {
|
96 |
+
// Document hidden
|
97 |
+
_inbound.trigger('tab_hidden');
|
98 |
+
_inbound.PageTracking.setIdle('browser tab switch');
|
99 |
+
} else {
|
100 |
+
// Document shown
|
101 |
+
_inbound.trigger('tab_visible');
|
102 |
+
_inbound.PageTracking.pingSession();
|
103 |
+
}
|
104 |
+
|
105 |
+
document_hidden = document[hidden];
|
106 |
+
}
|
107 |
+
});
|
108 |
+
},
|
109 |
+
clock: function() {
|
110 |
+
clockTime += 1;
|
111 |
+
var niceTime = clockTime / 60;
|
112 |
+
var msg = 'Total time spent on Page in this Session: ' + niceTime.toFixed(2) + " min";
|
113 |
+
_inbound.deBugger('pages', msg);
|
114 |
+
if (clockTime > 0 && (clockTime % reportInterval === 0)) {
|
115 |
+
|
116 |
+
var d = new Date();
|
117 |
+
d.setTime(d.getTime() + 30 * 60 * 1000);
|
118 |
+
utils.createCookie("lead_session", clockTime, d); // Set cookie on page load
|
119 |
+
|
120 |
+
/*! every 10 seconds run this */
|
121 |
+
//console.log('Session Heartbeat every ' + reportInterval + ' secs');
|
122 |
+
_inbound.trigger('session_heartbeat', clockTime);
|
123 |
+
|
124 |
+
}
|
125 |
+
|
126 |
+
},
|
127 |
+
inactiveClock: function() {
|
128 |
+
inactiveClockTime += 1;
|
129 |
+
var TimeUntilTimeOut = (1800 - inactiveClockTime) / 60;
|
130 |
+
var msg = 'Time until Session Timeout: ' + TimeUntilTimeOut.toFixed(2) + " min";
|
131 |
+
_inbound.deBugger('pages', msg);
|
132 |
+
//console.log('Time until Session Timeout: ', TimeUntilTimeOut.toFixed(2) + " min");
|
133 |
+
/* Session timeout after 30min */
|
134 |
+
if (inactiveClockTime > 1800) {
|
135 |
+
|
136 |
+
// sendEvent(clockTime);
|
137 |
+
/*! End session after 30min timeout */
|
138 |
+
_inbound.trigger('session_end', InboundLeadData);
|
139 |
+
_inbound.Utils.eraseCookie("lead_session");
|
140 |
+
/* todo maybe? remove session Cookie */
|
141 |
+
inactiveClockTime = 0;
|
142 |
+
clearTimeout(inactiveClockTimer);
|
143 |
+
}
|
144 |
+
|
145 |
+
|
146 |
+
},
|
147 |
+
stopClock: function() {
|
148 |
+
stopped = true;
|
149 |
+
clearTimeout(clockTimer);
|
150 |
+
clearTimeout(inactiveClockTimer);
|
151 |
+
inactiveClockTimer = setInterval(_inbound.PageTracking.inactiveClock, 1000);
|
152 |
+
},
|
153 |
+
|
154 |
+
restartClock: function() {
|
155 |
+
stopped = false;
|
156 |
+
|
157 |
+
|
158 |
+
_inbound.trigger('session_resume');
|
159 |
+
_inbound.deBugger('pages', 'Activity resumed. Session Active');
|
160 |
+
/* todo add session_resume */
|
161 |
+
clearTimeout(clockTimer);
|
162 |
+
inactiveClockTime = 0;
|
163 |
+
clearTimeout(inactiveClockTimer);
|
164 |
+
clockTimer = setInterval(_inbound.PageTracking.clock, 1000);
|
165 |
+
},
|
166 |
+
|
167 |
+
turnOff: function() {
|
168 |
+
_inbound.PageTracking.setIdle();
|
169 |
+
turnedOff = true;
|
170 |
+
},
|
171 |
+
|
172 |
+
turnOn: function() {
|
173 |
+
turnedOff = false;
|
174 |
+
},
|
175 |
+
/* This start only runs once */
|
176 |
+
startSession: function() {
|
177 |
+
/* todo add session Cookie */
|
178 |
+
// Calculate seconds from start to first interaction
|
179 |
+
var currentTime = new Date();
|
180 |
+
var diff = currentTime - startTime;
|
181 |
+
|
182 |
+
|
183 |
+
started = true; // Set global
|
184 |
+
|
185 |
+
// Send User Timing Event
|
186 |
+
/* Todo session start here */
|
187 |
+
|
188 |
+
// Start clock
|
189 |
+
clockTimer = setInterval(_inbound.PageTracking.clock, 1000);
|
190 |
+
//utils.eraseCookie("lead_session");
|
191 |
+
var session = utils.readCookie("lead_session");
|
192 |
+
|
193 |
+
if (!session) {
|
194 |
+
_inbound.trigger('session_start'); // trigger 'inbound_analytics_session_start'
|
195 |
+
var d = new Date();
|
196 |
+
d.setTime(d.getTime() + 30 * 60 * 1000);
|
197 |
+
_inbound.Utils.createCookie("lead_session", 1, d); // Set cookie on page load
|
198 |
+
} else {
|
199 |
+
_inbound.trigger('session_active');
|
200 |
+
//console.log("count of secs " + session);
|
201 |
+
//_inbound.trigger('session_active'); // trigger 'inbound_analytics_session_active'
|
202 |
+
}
|
203 |
+
|
204 |
+
this.pingSession();
|
205 |
+
|
206 |
+
|
207 |
+
},
|
208 |
+
resetInactiveFunc: function() {
|
209 |
+
inactiveClockTime = 0;
|
210 |
+
clearTimeout(inactiveClockTimer);
|
211 |
+
},
|
212 |
+
/* Ping Session to keep active */
|
213 |
+
pingSession: function(e) {
|
214 |
+
|
215 |
+
|
216 |
+
if (turnedOff) {
|
217 |
+
return;
|
218 |
+
}
|
219 |
+
|
220 |
+
if (!started) {
|
221 |
+
_inbound.PageTracking.startSession();
|
222 |
+
}
|
223 |
+
|
224 |
+
if (stopped) {
|
225 |
+
_inbound.PageTracking.restartClock();
|
226 |
+
}
|
227 |
+
|
228 |
+
clearTimeout(idleTimer);
|
229 |
+
|
230 |
+
idleTimer = setTimeout(_inbound.PageTracking.setIdle, idleTimeout * 1000 + 100);
|
231 |
+
|
232 |
+
if (typeof(e) != "undefined") {
|
233 |
+
if (e.type === "mousemove") {
|
234 |
+
_inbound.PageTracking.mouseEvents(e);
|
235 |
+
}
|
236 |
+
}
|
237 |
+
|
238 |
+
},
|
239 |
+
mouseEvents: function(e) {
|
240 |
+
|
241 |
+
if (e.pageY <= 5) {
|
242 |
+
_inbound.trigger('tab_mouseout');
|
243 |
+
}
|
244 |
+
|
245 |
+
},
|
246 |
+
/**
|
247 |
+
* Returns the pages viewed by the site visitor
|
248 |
+
*
|
249 |
+
* ```js
|
250 |
+
* var pageViews = _inbound.PageTracking.getPageViews();
|
251 |
+
* // returns page view object
|
252 |
+
* ```
|
253 |
+
*
|
254 |
+
* @return {object} page view object with page ID as key and timestamp
|
255 |
+
*/
|
256 |
+
getPageViews: function() {
|
257 |
+
var local_store = _inbound.Utils.checkLocalStorage();
|
258 |
+
if (local_store) {
|
259 |
+
var page_views = localStorage.getItem(lsType),
|
260 |
+
local_object = JSON.parse(page_views);
|
261 |
+
if (typeof local_object == 'object' && local_object) {
|
262 |
+
//this.triggerPageView();
|
263 |
+
}
|
264 |
+
return local_object;
|
265 |
+
}
|
266 |
+
},
|
267 |
+
isRevisit: function(Pages) {
|
268 |
+
var revisitCheck = false;
|
269 |
+
var Pages = Pages || {};
|
270 |
+
var pageSeen = Pages[id];
|
271 |
+
if (typeof(pageSeen) != "undefined" && pageSeen !== null) {
|
272 |
+
revisitCheck = true;
|
273 |
+
}
|
274 |
+
return revisitCheck;
|
275 |
+
},
|
276 |
+
triggerPageView: function(pageRevisit) {
|
277 |
+
|
278 |
+
var pageData = {
|
279 |
+
title: document.title,
|
280 |
+
url: document.location.href,
|
281 |
+
path: document.location.pathname,
|
282 |
+
count: 1 // default
|
283 |
+
};
|
284 |
+
|
285 |
+
if (pageRevisit) {
|
286 |
+
/* Page Revisit Trigger */
|
287 |
+
Pages[id].push(timeNow);
|
288 |
+
pageData.count = Pages[id].length;
|
289 |
+
_inbound.trigger('page_revisit', pageData);
|
290 |
+
|
291 |
+
} else {
|
292 |
+
/* Page First Seen Trigger */
|
293 |
+
Pages[id] = [];
|
294 |
+
Pages[id].push(timeNow);
|
295 |
+
_inbound.trigger('page_first_visit', pageData);
|
296 |
+
}
|
297 |
+
|
298 |
+
_inbound.trigger('page_visit', pageData);
|
299 |
+
|
300 |
+
_inbound.totalStorage(lsType, Pages);
|
301 |
+
|
302 |
+
this.storePageView();
|
303 |
+
|
304 |
+
},
|
305 |
+
CheckTimeOut: function() {
|
306 |
+
|
307 |
+
var pageRevisit = this.isRevisit(Pages),
|
308 |
+
status,
|
309 |
+
timeout;
|
310 |
+
|
311 |
+
/* Default */
|
312 |
+
if (pageRevisit) {
|
313 |
+
|
314 |
+
var prev = Pages[id].length - 1,
|
315 |
+
lastView = Pages[id][prev],
|
316 |
+
timeDiff = Math.abs(new Date(lastView).getTime() - new Date(timeNow).getTime());
|
317 |
+
|
318 |
+
timeout = timeDiff > analyticsTimeout;
|
319 |
+
|
320 |
+
if (timeout) {
|
321 |
+
status = 'Timeout Happened. Page view fired';
|
322 |
+
this.triggerPageView(pageRevisit);
|
323 |
+
} else {
|
324 |
+
time_left = Math.abs((analyticsTimeout - timeDiff)) * 0.001;
|
325 |
+
status = analyticsTimeout / 1000 + ' sec timeout not done: ' + time_left + " seconds left";
|
326 |
+
}
|
327 |
+
|
328 |
+
} else {
|
329 |
+
/*! Page never seen before save view */
|
330 |
+
this.triggerPageView(pageRevisit);
|
331 |
+
}
|
332 |
+
|
333 |
+
_inbound.deBugger('pages', status);
|
334 |
+
},
|
335 |
+
storePageView: function() {
|
336 |
+
var stored = false;
|
337 |
+
|
338 |
+
/* ignore if page tracking off and page is not a landing page */
|
339 |
+
if ( inbound_settings.page_tracking == 'off' && inbound_settings.post_type != 'landing-page' ) {
|
340 |
+
return;
|
341 |
+
}
|
342 |
+
|
343 |
+
/* Let's try and fire this last - also defines what constitutes a bounce - */
|
344 |
+
document.onreadystatechange = function(){
|
345 |
+
|
346 |
+
if(document.readyState !== 'loading' && stored === false){
|
347 |
+
setTimeout(function(){
|
348 |
+
var leadID = ( _inbound.Utils.readCookie('wp_lead_id') ) ? _inbound.Utils.readCookie('wp_lead_id') : '';
|
349 |
+
var lead_uid = ( _inbound.Utils.readCookie('wp_lead_uid') ) ? _inbound.Utils.readCookie('wp_lead_uid') : '';
|
350 |
+
var ctas_loaded = _inbound.totalStorage('wp_cta_loaded');
|
351 |
+
var ctas_impressions = _inbound.totalStorage('wp_cta_impressions');
|
352 |
+
stored = true;
|
353 |
+
|
354 |
+
/* now reset impressions */
|
355 |
+
_inbound.totalStorage('wp_cta_impressions' , {} );
|
356 |
+
|
357 |
+
var data = {
|
358 |
+
action: 'inbound_track_lead',
|
359 |
+
wp_lead_uid: lead_uid,
|
360 |
+
wp_lead_id: leadID,
|
361 |
+
page_id: inbound_settings.post_id,
|
362 |
+
variation_id: inbound_settings.variation_id,
|
363 |
+
post_type: inbound_settings.post_type,
|
364 |
+
current_url: window.location.href,
|
365 |
+
page_views: JSON.stringify(_inbound.PageTracking.getPageViews()),
|
366 |
+
cta_impressions : JSON.stringify(ctas_impressions),
|
367 |
+
cta_history : JSON.stringify(ctas_loaded),
|
368 |
+
json: '0'
|
369 |
+
};
|
370 |
+
|
371 |
+
var firePageCallback = function(leadID) {
|
372 |
+
//_inbound.Events.page_view_saved(leadID);
|
373 |
+
};
|
374 |
+
//_inbound.Utils.doAjax(data, firePageCallback);
|
375 |
+
|
376 |
+
_inbound.Utils.ajaxPost(inbound_settings.admin_url, data, firePageCallback);
|
377 |
+
|
378 |
+
} , 200 );
|
379 |
+
}
|
380 |
+
}
|
381 |
+
}
|
382 |
+
/*! GA functions
|
383 |
+
function log_event(category, action, label) {
|
384 |
+
_gaq.push(['_trackEvent', category, action, label]);
|
385 |
+
}
|
386 |
+
|
387 |
+
function log_click(category, link) {
|
388 |
+
log_event(category, 'Click', $(link).text());
|
389 |
+
}
|
390 |
+
*/
|
391 |
+
};
|
392 |
+
|
393 |
+
return _inbound;
|
394 |
+
|
395 |
Â
})(_inbound || {});
|
shared/assets/js/frontend/analytics-src/analytics.start.js
CHANGED
@@ -1,17 +1,17 @@
|
|
1 |
-
/**
|
2 |
-
* # Start
|
3 |
-
*
|
4 |
-
* Runs init functions
|
5 |
-
*
|
6 |
-
* @
|
7 |
-
* @
|
8 |
-
* @version 0.0.2
|
9 |
-
*/
|
10 |
-
|
11 |
-
|
12 |
-
/* Initialize _inbound */
|
13 |
-
_inbound.init();
|
14 |
-
|
15 |
-
/* Set Global Lead Data */
|
16 |
-
InboundLeadData = _inbound.totalStorage('inbound_lead_data') || null;
|
17 |
-
|
1 |
+
/**
|
2 |
+
* # Start
|
3 |
+
*
|
4 |
+
* Runs init functions
|
5 |
+
*
|
6 |
+
* @contributor David Wells <david@inboundnow.com>
|
7 |
+
* @contributor Hudson Atwell <hudson@inboundnow.com>
|
8 |
+
* @version 0.0.2
|
9 |
+
*/
|
10 |
+
|
11 |
+
|
12 |
+
/* Initialize _inbound */
|
13 |
+
_inbound.init();
|
14 |
+
|
15 |
+
/* Set Global Lead Data */
|
16 |
+
InboundLeadData = _inbound.totalStorage('inbound_lead_data') || null;
|
17 |
+
|
shared/assets/js/frontend/analytics-src/analytics.utils.js
CHANGED
@@ -1,858 +1,858 @@
|
|
1 |
-
/**
|
2 |
-
* # _inbound UTILS
|
3 |
-
*
|
4 |
-
* This file contains all of the utility functions used by analytics
|
5 |
-
*
|
6 |
-
* @
|
7 |
-
* @
|
8 |
-
* @version 0.0.2
|
9 |
-
*/
|
10 |
-
|
11 |
-
var _inboundUtils = (function(_inbound) {
|
12 |
-
|
13 |
-
var storageSupported,
|
14 |
-
corsEnabled = window.XMLHttpRequest && 'withCredentials' in new XMLHttpRequest(),
|
15 |
-
toString = Object.prototype.toString,
|
16 |
-
currentPage = ('https:' == location.protocol ? 'https://' : 'http://') + location.hostname + location.pathname.replace(/\/$/, "");
|
17 |
-
|
18 |
-
var settings = {
|
19 |
-
api_host: currentPage,
|
20 |
-
track_pageview: true,
|
21 |
-
track_links_timeout: 300,
|
22 |
-
cookie_name: '_sp',
|
23 |
-
cookie_expiration: 365,
|
24 |
-
cookie_domain: (host = location.hostname.match(/[a-z0-9][a-z0-9\-]+\.[a-z\.]{2,6}$/i)) ? host[0] : ''
|
25 |
-
};
|
26 |
-
|
27 |
-
_inbound.Utils = {
|
28 |
-
init: function() {
|
29 |
-
|
30 |
-
this.polyFills();
|
31 |
-
this.checkLocalStorage();
|
32 |
-
this.SetUID();
|
33 |
-
this.storeReferralData();
|
34 |
-
|
35 |
-
},
|
36 |
-
/*! http://stackoverflow.com/questions/951791/javascript-global-error-handling */
|
37 |
-
/* Polyfills for missing browser functionality */
|
38 |
-
polyFills: function() {
|
39 |
-
/* Console.log fix for old browsers */
|
40 |
-
if (!window.console) {
|
41 |
-
window.console = {};
|
42 |
-
}
|
43 |
-
var m = [
|
44 |
-
"log", "info", "warn", "error", "debug", "trace", "dir", "group",
|
45 |
-
"groupCollapsed", "groupEnd", "time", "timeEnd", "profile", "profileEnd",
|
46 |
-
"dirxml", "assert", "count", "markTimeline", "timeStamp", "clear"
|
47 |
-
];
|
48 |
-
// define undefined methods as noops to prevent errors
|
49 |
-
for (var i = 0; i < m.length; i++) {
|
50 |
-
if (!window.console[m[i]]) {
|
51 |
-
window.console[m[i]] = function() {};
|
52 |
-
}
|
53 |
-
}
|
54 |
-
/* Event trigger polyfill for IE9 and 10
|
55 |
-
(function() {
|
56 |
-
function CustomEvent(event, params) {
|
57 |
-
params = params || {
|
58 |
-
bubbles: false,
|
59 |
-
cancelable: false,
|
60 |
-
detail: undefined
|
61 |
-
};
|
62 |
-
var evt = document.createEvent('CustomEvent');
|
63 |
-
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
|
64 |
-
return evt;
|
65 |
-
}
|
66 |
-
|
67 |
-
CustomEvent.prototype = window.Event.prototype;
|
68 |
-
|
69 |
-
window.CustomEvent = CustomEvent;
|
70 |
-
})();*/
|
71 |
-
|
72 |
-
/*\
|
73 |
-
|*| Polyfill Date.toISOString
|
74 |
-
\*/
|
75 |
-
if (!Date.prototype.toISOString) {
|
76 |
-
(function() {
|
77 |
-
/**
|
78 |
-
* @param {number} text
|
79 |
-
* @returns {?}
|
80 |
-
*/
|
81 |
-
function pad(text) {
|
82 |
-
/** @type {string} */
|
83 |
-
var code = String(text);
|
84 |
-
return 1 === code.length && (code = '0' + code), code;
|
85 |
-
}
|
86 |
-
/**
|
87 |
-
* @returns {string}
|
88 |
-
*/
|
89 |
-
Date.prototype.toISOString = function() {
|
90 |
-
return this.getUTCFullYear() + '-' + pad(this.getUTCMonth() + 1) + '-' + pad(this.getUTCDate()) + 'T' + pad(this.getUTCHours()) + ':' + pad(this.getUTCMinutes()) + ':' + pad(this.getUTCSeconds()) + '.' + String((this.getUTCMilliseconds() / 1E3).toFixed(3)).slice(2, 5) + 'Z';
|
91 |
-
};
|
92 |
-
})();
|
93 |
-
}
|
94 |
-
|
95 |
-
/* custom event for ie8+ https://gist.github.com/WebReflection/6693661 */
|
96 |
-
try {
|
97 |
-
new CustomEvent('?');
|
98 |
-
} catch (o_O) {
|
99 |
-
/*!(C) Andrea Giammarchi -- WTFPL License*/
|
100 |
-
this.CustomEvent = function(
|
101 |
-
eventName,
|
102 |
-
defaultInitDict
|
103 |
-
) {
|
104 |
-
|
105 |
-
// the infamous substitute
|
106 |
-
function CustomEvent(type, eventInitDict) {
|
107 |
-
var event = document.createEvent(eventName);
|
108 |
-
if (type !== null) {
|
109 |
-
initCustomEvent.call(
|
110 |
-
event,
|
111 |
-
type, (eventInitDict || (
|
112 |
-
// if falsy we can just use defaults
|
113 |
-
eventInitDict = defaultInitDict
|
114 |
-
)).bubbles,
|
115 |
-
eventInitDict.cancelable,
|
116 |
-
eventInitDict.detail
|
117 |
-
);
|
118 |
-
} else {
|
119 |
-
// no need to put the expando property otherwise
|
120 |
-
// since an event cannot be initialized twice
|
121 |
-
// previous case is the most common one anyway
|
122 |
-
// but if we end up here ... there it goes
|
123 |
-
event.initCustomEvent = initCustomEvent;
|
124 |
-
}
|
125 |
-
return event;
|
126 |
-
}
|
127 |
-
|
128 |
-
// borrowed or attached at runtime
|
129 |
-
function initCustomEvent(
|
130 |
-
type, bubbles, cancelable, detail
|
131 |
-
) {
|
132 |
-
this['init' + eventName](type, bubbles, cancelable, detail);
|
133 |
-
'detail' in this || (this.detail = detail);
|
134 |
-
}
|
135 |
-
|
136 |
-
// that's it
|
137 |
-
return CustomEvent;
|
138 |
-
}(
|
139 |
-
// is this IE9 or IE10 ?
|
140 |
-
// where CustomEvent is there
|
141 |
-
// but not usable as construtor ?
|
142 |
-
this.CustomEvent ?
|
143 |
-
// use the CustomEvent interface in such case
|
144 |
-
'CustomEvent' : 'Event',
|
145 |
-
// otherwise the common compatible one
|
146 |
-
{
|
147 |
-
bubbles: false,
|
148 |
-
cancelable: false,
|
149 |
-
detail: null
|
150 |
-
}
|
151 |
-
);
|
152 |
-
}
|
153 |
-
/* querySelectorAll polyfill for ie7+ */
|
154 |
-
if (!document.querySelectorAll) {
|
155 |
-
document.querySelectorAll = function(selectors) {
|
156 |
-
var style = document.createElement('style'),
|
157 |
-
elements = [],
|
158 |
-
element;
|
159 |
-
document.documentElement.firstChild.appendChild(style);
|
160 |
-
document._qsa = [];
|
161 |
-
|
162 |
-
style.styleSheet.cssText = selectors + '{x-qsa:expression(document._qsa && document._qsa.push(this))}';
|
163 |
-
window.scrollBy(0, 0);
|
164 |
-
style.parentNode.removeChild(style);
|
165 |
-
|
166 |
-
while (document._qsa.length) {
|
167 |
-
element = document._qsa.shift();
|
168 |
-
element.style.removeAttribute('x-qsa');
|
169 |
-
elements.push(element);
|
170 |
-
}
|
171 |
-
document._qsa = null;
|
172 |
-
return elements;
|
173 |
-
};
|
174 |
-
}
|
175 |
-
|
176 |
-
if (!document.querySelector) {
|
177 |
-
document.querySelector = function(selectors) {
|
178 |
-
var elements = document.querySelectorAll(selectors);
|
179 |
-
return (elements.length) ? elements[0] : null;
|
180 |
-
};
|
181 |
-
}
|
182 |
-
/* Innertext shim for firefox https://github.com/duckinator/innerText-polyfill/blob/master/innertext.js */
|
183 |
-
if ((!('innerText' in document.createElement('a'))) && ('getSelection' in window)) {
|
184 |
-
HTMLElement.prototype.__defineGetter__("innerText", function() {
|
185 |
-
var selection = window.getSelection(),
|
186 |
-
ranges = [],
|
187 |
-
str;
|
188 |
-
|
189 |
-
// Save existing selections.
|
190 |
-
for (var i = 0; i < selection.rangeCount; i++) {
|
191 |
-
ranges[i] = selection.getRangeAt(i);
|
192 |
-
}
|
193 |
-
|
194 |
-
// Deselect everything.
|
195 |
-
selection.removeAllRanges();
|
196 |
-
|
197 |
-
// Select `el` and all child nodes.
|
198 |
-
// 'this' is the element .innerText got called on
|
199 |
-
selection.selectAllChildren(this);
|
200 |
-
|
201 |
-
// Get the string representation of the selected nodes.
|
202 |
-
str = selection.toString();
|
203 |
-
|
204 |
-
// Deselect everything. Again.
|
205 |
-
selection.removeAllRanges();
|
206 |
-
|
207 |
-
// Restore all formerly existing selections.
|
208 |
-
for (var i = 0; i < ranges.length; i++) {
|
209 |
-
selection.addRange(ranges[i]);
|
210 |
-
}
|
211 |
-
|
212 |
-
// Oh look, this is what we wanted.
|
213 |
-
// String representation of the element, close to as rendered.
|
214 |
-
return str;
|
215 |
-
})
|
216 |
-
}
|
217 |
-
},
|
218 |
-
/**
|
219 |
-
* Create cookie
|
220 |
-
*
|
221 |
-
* ```js
|
222 |
-
* // Creates cookie for 10 days
|
223 |
-
* _inbound.Utils.createCookie( 'cookie_name', 'value', 10 );
|
224 |
-
* ```
|
225 |
-
*
|
226 |
-
* @param {string} name Name of cookie
|
227 |
-
* @param {string} value Value of cookie
|
228 |
-
* @param {string} days Length of storage
|
229 |
-
*/
|
230 |
-
createCookie: function(name, value, days) {
|
231 |
-
var expires = "";
|
232 |
-
if (days) {
|
233 |
-
var date = new Date();
|
234 |
-
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
235 |
-
expires = "; expires=" + date.toGMTString();
|
236 |
-
}
|
237 |
-
document.cookie = name + "=" + value + expires + "; path=/";
|
238 |
-
},
|
239 |
-
/**
|
240 |
-
* Read cookie value
|
241 |
-
*
|
242 |
-
* ```js
|
243 |
-
* var cookie = _inbound.Utils.readCookie( 'cookie_name' );
|
244 |
-
* console.log(cookie); // cookie value
|
245 |
-
* ```
|
246 |
-
* @param {string} name name of cookie
|
247 |
-
* @return {string} value of cookie
|
248 |
-
*/
|
249 |
-
readCookie: function(name) {
|
250 |
-
var nameEQ = name + "=";
|
251 |
-
var ca = document.cookie.split(';');
|
252 |
-
for (var i = 0; i < ca.length; i++) {
|
253 |
-
var c = ca[i];
|
254 |
-
while (c.charAt(0) === ' ') {
|
255 |
-
c = c.substring(1, c.length);
|
256 |
-
}
|
257 |
-
if (c.indexOf(nameEQ) === 0) {
|
258 |
-
return c.substring(nameEQ.length, c.length);
|
259 |
-
}
|
260 |
-
}
|
261 |
-
return null;
|
262 |
-
},
|
263 |
-
/**
|
264 |
-
* Erase cookie
|
265 |
-
*
|
266 |
-
* ```js
|
267 |
-
* // usage:
|
268 |
-
* _inbound.Utils.eraseCookie( 'cookie_name' );
|
269 |
-
* // deletes 'cookie_name' value
|
270 |
-
* ```
|
271 |
-
* @param {string} name name of cookie
|
272 |
-
* @return {string} value of cookie
|
273 |
-
*/
|
274 |
-
eraseCookie: function(name) {
|
275 |
-
this.createCookie(name, "", -1);
|
276 |
-
},
|
277 |
-
/* Get All Cookies */
|
278 |
-
getAllCookies: function() {
|
279 |
-
var cookies = {};
|
280 |
-
if (document.cookie && document.cookie !== '') {
|
281 |
-
var split = document.cookie.split(';');
|
282 |
-
for (var i = 0; i < split.length; i++) {
|
283 |
-
var name_value = split[i].split("=");
|
284 |
-
name_value[0] = name_value[0].replace(/^ /, '');
|
285 |
-
cookies[decodeURIComponent(name_value[0])] = decodeURIComponent(name_value[1]);
|
286 |
-
}
|
287 |
-
}
|
288 |
-
_inbound.totalStorage('inbound_cookies', cookies); // store cookie data
|
289 |
-
return cookies;
|
290 |
-
},
|
291 |
-
/* Grab URL params and save */
|
292 |
-
setUrlParams: function() {
|
293 |
-
var urlParams = {};
|
294 |
-
|
295 |
-
(function() {
|
296 |
-
var e,
|
297 |
-
d = function(s) {
|
298 |
-
return decodeURIComponent(s).replace(/\+/g, " ");
|
299 |
-
},
|
300 |
-
q = window.location.search.substring(1),
|
301 |
-
r = /([^&=]+)=?([^&]*)/g;
|
302 |
-
|
303 |
-
while (e = r.exec(q)) {
|
304 |
-
if (e[1].indexOf("[") == "-1")
|
305 |
-
urlParams[d(e[1])] = d(e[2]);
|
306 |
-
else {
|
307 |
-
var b1 = e[1].indexOf("["),
|
308 |
-
aN = e[1].slice(b1 + 1, e[1].indexOf("]", b1)),
|
309 |
-
pN = d(e[1].slice(0, b1));
|
310 |
-
|
311 |
-
if (typeof urlParams[pN] != "object")
|
312 |
-
urlParams[d(pN)] = {},
|
313 |
-
urlParams[d(pN)].length = 0;
|
314 |
-
|
315 |
-
if (aN)
|
316 |
-
urlParams[d(pN)][d(aN)] = d(e[2]);
|
317 |
-
else
|
318 |
-
Array.prototype.push.call(urlParams[d(pN)], d(e[2]));
|
319 |
-
|
320 |
-
}
|
321 |
-
}
|
322 |
-
})();
|
323 |
-
|
324 |
-
/* Set Param Cookies */
|
325 |
-
for (var k in urlParams) {
|
326 |
-
/* account for wordpress media uploader bug */
|
327 |
-
if (k == 'action') {
|
328 |
-
continue;
|
329 |
-
}
|
330 |
-
|
331 |
-
if (typeof urlParams[k] == "object") {
|
332 |
-
for (var k2 in urlParams[k])
|
333 |
-
this.createCookie(k2, urlParams[k][k2], 30);
|
334 |
-
} else {
|
335 |
-
this.createCookie(k, urlParams[k], 30);
|
336 |
-
}
|
337 |
-
}
|
338 |
-
/* Set Param LocalStorage */
|
339 |
-
if (storageSupported) {
|
340 |
-
var pastParams = _inbound.totalStorage('inbound_url_params') || {};
|
341 |
-
var params = this.mergeObjs(pastParams, urlParams);
|
342 |
-
_inbound.totalStorage('inbound_url_params', params); // store cookie data
|
343 |
-
}
|
344 |
-
|
345 |
-
var options = {
|
346 |
-
'option1': 'yo',
|
347 |
-
'option2': 'woooo'
|
348 |
-
};
|
349 |
-
|
350 |
-
_inbound.trigger('url_parameters', urlParams, options);
|
351 |
-
|
352 |
-
},
|
353 |
-
getAllUrlParams: function() {
|
354 |
-
var get_params = {};
|
355 |
-
if (storageSupported) {
|
356 |
-
var get_params = _inbound.totalStorage('inbound_url_params');
|
357 |
-
}
|
358 |
-
return get_params;
|
359 |
-
},
|
360 |
-
/* Get url param */
|
361 |
-
getParameterVal: function(name, string) {
|
362 |
-
return (RegExp(name + '=' + '(.+?)(&|$)').exec(string) || [, false])[1];
|
363 |
-
},
|
364 |
-
// Check local storage
|
365 |
-
// provate browsing safari fix https://github.com/marcuswestin/store.js/issues/42#issuecomment-25274685
|
366 |
-
checkLocalStorage: function() {
|
367 |
-
if ('localStorage' in window) {
|
368 |
-
try {
|
369 |
-
ls = (typeof window.localStorage === 'undefined') ? undefined : window.localStorage;
|
370 |
-
if (typeof ls == 'undefined' || typeof window.JSON == 'undefined') {
|
371 |
-
storageSupported = false;
|
372 |
-
} else {
|
373 |
-
storageSupported = true;
|
374 |
-
}
|
375 |
-
|
376 |
-
} catch (err) {
|
377 |
-
storageSupported = false;
|
378 |
-
}
|
379 |
-
}
|
380 |
-
return storageSupported;
|
381 |
-
/* http://spin.atomicobject.com/2013/01/23/ios-private-browsing-localstorage/
|
382 |
-
var hasStorage;
|
383 |
-
hasStorage = function() {
|
384 |
-
var mod, result;
|
385 |
-
try {
|
386 |
-
mod = new Date;
|
387 |
-
localStorage.setItem(mod, mod.toString());
|
388 |
-
result = localStorage.getItem(mod) === mod.toString();
|
389 |
-
localStorage.removeItem(mod);
|
390 |
-
return result;
|
391 |
-
} catch (_error) {}
|
392 |
-
};
|
393 |
-
*/
|
394 |
-
},
|
395 |
-
// http://stackoverflow.com/questions/4391575/how-to-find-the-size-of-localstorage
|
396 |
-
showLocalStorageSize: function() {
|
397 |
-
function stringSizeBytes(str) {
|
398 |
-
return str.length * 2;
|
399 |
-
}
|
400 |
-
|
401 |
-
function toMB(bytes) {
|
402 |
-
return bytes / 1024 / 1024;
|
403 |
-
}
|
404 |
-
|
405 |
-
function toSize(key) {
|
406 |
-
return {
|
407 |
-
name: key,
|
408 |
-
size: stringSizeBytes(localStorage[key])
|
409 |
-
};
|
410 |
-
}
|
411 |
-
|
412 |
-
function toSizeMB(info) {
|
413 |
-
info.size = toMB(info.size).toFixed(2) + ' MB';
|
414 |
-
return info;
|
415 |
-
}
|
416 |
-
|
417 |
-
var sizes = Object.keys(localStorage).map(toSize).map(toSizeMB);
|
418 |
-
|
419 |
-
console.table(sizes);
|
420 |
-
},
|
421 |
-
/* Add days to datetime */
|
422 |
-
addDays: function(myDate, days) {
|
423 |
-
return new Date(myDate.getTime() + days * 24 * 60 * 60 * 1000);
|
424 |
-
},
|
425 |
-
GetDate: function() {
|
426 |
-
var timeNow = new Date(),
|
427 |
-
d = timeNow.getDate(),
|
428 |
-
dPre = (d < 10) ? "0" : "",
|
429 |
-
y = timeNow.getFullYear(),
|
430 |
-
h = timeNow.getHours(),
|
431 |
-
hPre = (h < 10) ? "0" : "",
|
432 |
-
min = timeNow.getMinutes(),
|
433 |
-
minPre = (min < 10) ? "0" : "",
|
434 |
-
sec = timeNow.getSeconds(),
|
435 |
-
secPre = (sec < 10) ? "0" : "",
|
436 |
-
m = timeNow.getMonth() + 1,
|
437 |
-
mPre = (m < 10) ? "0" : "";
|
438 |
-
|
439 |
-
var datetime = y + '/' + mPre + m + "/" + dPre + d + " " + hPre + h + ":" + minPre + min + ":" + secPre + sec;
|
440 |
-
/* format 2014/11/13 18:22:02 */
|
441 |
-
return datetime;
|
442 |
-
},
|
443 |
-
/* Set Expiration Date of Session Logging. LEGACY Not in Use */
|
444 |
-
SetSessionTimeout: function() {
|
445 |
-
var session = this.readCookie("lead_session_expire");
|
446 |
-
//console.log(session_check);
|
447 |
-
if (!session) {
|
448 |
-
//_inbound.trigger('session_start'); // trigger 'inbound_analytics_session_start'
|
449 |
-
} else {
|
450 |
-
//_inbound.trigger('session_resume'); // trigger 'inbound_analytics_session_active'
|
451 |
-
}
|
452 |
-
var d = new Date();
|
453 |
-
d.setTime(d.getTime() + 30 * 60 * 1000);
|
454 |
-
|
455 |
-
this.createCookie("lead_session_expire", true, d); // Set cookie on page load
|
456 |
-
|
457 |
-
},
|
458 |
-
storeReferralData: function() {
|
459 |
-
//console.log(expire_time);
|
460 |
-
var d = new Date(),
|
461 |
-
referrer = document.referrer || "Direct Traffic",
|
462 |
-
referrer_cookie = _inbound.Utils.readCookie("inbound_referral_site"),
|
463 |
-
original_src = _inbound.totalStorage('inbound_original_referral');
|
464 |
-
|
465 |
-
d.setTime(d.getTime() + 30 * 60 * 1000);
|
466 |
-
|
467 |
-
if (!referrer_cookie) {
|
468 |
-
this.createCookie("inbound_referral_site", referrer, d);
|
469 |
-
}
|
470 |
-
if (!original_src) {
|
471 |
-
_inbound.totalStorage('inbound_original_referral', original_src);
|
472 |
-
}
|
473 |
-
},
|
474 |
-
CreateUID: function(length) {
|
475 |
-
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'.split(''),
|
476 |
-
str = '';
|
477 |
-
if (!length) {
|
478 |
-
length = Math.floor(Math.random() * chars.length);
|
479 |
-
}
|
480 |
-
for (var i = 0; i < length; i++) {
|
481 |
-
str += chars[Math.floor(Math.random() * chars.length)];
|
482 |
-
}
|
483 |
-
return str;
|
484 |
-
},
|
485 |
-
generateGUID: function(a) {
|
486 |
-
return a ? (a ^ 16 * Math.random() >> a / 4).toString(16) : ([1E7] + -1E3 + -4E3 + -8E3 + -1E11).replace(/[018]/g, guid);
|
487 |
-
},
|
488 |
-
SetUID: function(leadUID) {
|
489 |
-
/* Set Lead UID */
|
490 |
-
if (!this.readCookie("wp_lead_uid")) {
|
491 |
-
var wp_lead_uid = leadUID || this.CreateUID(35);
|
492 |
-
this.createCookie("wp_lead_uid", wp_lead_uid);
|
493 |
-
}
|
494 |
-
},
|
495 |
-
/* Count number of session visits */
|
496 |
-
countProperties: function(obj) {
|
497 |
-
var count = 0;
|
498 |
-
for (var prop in obj) {
|
499 |
-
if (obj.hasOwnProperty(prop)) {
|
500 |
-
++count;
|
501 |
-
}
|
502 |
-
}
|
503 |
-
return count;
|
504 |
-
},
|
505 |
-
mergeObjs: function(obj1, obj2) {
|
506 |
-
var obj3 = {};
|
507 |
-
for (var attrname in obj1) {
|
508 |
-
obj3[attrname] = obj1[attrname];
|
509 |
-
}
|
510 |
-
for (var attrname in obj2) {
|
511 |
-
obj3[attrname] = obj2[attrname];
|
512 |
-
}
|
513 |
-
return obj3;
|
514 |
-
},
|
515 |
-
hasClass: function(className, el) {
|
516 |
-
var hasClass;
|
517 |
-
if ('classList' in document.documentElement) {
|
518 |
-
var hasClass = el.classList.contains(className);
|
519 |
-
} else {
|
520 |
-
var hasClass = new RegExp('(^|\\s)' + className + '(\\s|$)').test(el.className); /* IE Polyfill */
|
521 |
-
}
|
522 |
-
return hasClass;
|
523 |
-
},
|
524 |
-
addClass: function(className, el) {
|
525 |
-
if ('classList' in document.documentElement) {
|
526 |
-
el.classList.add(className);
|
527 |
-
} else {
|
528 |
-
if (!this.hasClass(el, className)) {
|
529 |
-
el.className += (el.className ? ' ' : '') + className;
|
530 |
-
}
|
531 |
-
}
|
532 |
-
},
|
533 |
-
removeClass: function(className, el) {
|
534 |
-
if ('classList' in document.documentElement) {
|
535 |
-
el.classList.remove(className);
|
536 |
-
} else {
|
537 |
-
if (this.hasClass(el, className)) {
|
538 |
-
el.className = el.className.replace(new RegExp('(^|\\s)*' + className + '(\\s|$)*', 'g'), '');
|
539 |
-
}
|
540 |
-
}
|
541 |
-
},
|
542 |
-
removeElement: function(el) {
|
543 |
-
el.parentNode.removeChild(el);
|
544 |
-
},
|
545 |
-
trim: function(s) {
|
546 |
-
s = s.replace(/(^\s*)|(\s*$)/gi, "");
|
547 |
-
s = s.replace(/[ ]{2,}/gi, " ");
|
548 |
-
s = s.replace(/\n /, "\n");
|
549 |
-
return s;
|
550 |
-
},
|
551 |
-
ajaxPolyFill: function() {
|
552 |
-
if (typeof XMLHttpRequest !== 'undefined') {
|
553 |
-
return new XMLHttpRequest();
|
554 |
-
}
|
555 |
-
var versions = [
|
556 |
-
"MSXML2.XmlHttp.5.0",
|
557 |
-
"MSXML2.XmlHttp.4.0",
|
558 |
-
"MSXML2.XmlHttp.3.0",
|
559 |
-
"MSXML2.XmlHttp.2.0",
|
560 |
-
"Microsoft.XmlHttp"
|
561 |
-
];
|
562 |
-
|
563 |
-
var xhr;
|
564 |
-
for (var i = 0; i < versions.length; i++) {
|
565 |
-
try {
|
566 |
-
xhr = new ActiveXObject(versions[i]);
|
567 |
-
break;
|
568 |
-
} catch (e) {}
|
569 |
-
}
|
570 |
-
return xhr;
|
571 |
-
},
|
572 |
-
ajaxSendData: function(url, callback, method, data, sync) {
|
573 |
-
var x = this.ajaxPolyFill();
|
574 |
-
/* timeout for safari idiocy */
|
575 |
-
setTimeout(function() {
|
576 |
-
x.open(method, url, true);
|
577 |
-
x.onreadystatechange = function() {
|
578 |
-
if (x.readyState == 4) {
|
579 |
-
callback(x.responseText)
|
580 |
-
}
|
581 |
-
};
|
582 |
-
if (method == 'POST') {
|
583 |
-
x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
584 |
-
}
|
585 |
-
x.send(data);
|
586 |
-
}, 100);
|
587 |
-
},
|
588 |
-
ajaxGet: function(url, data, callback, sync) {
|
589 |
-
var query = [];
|
590 |
-
for (var key in data) {
|
591 |
-
query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
|
592 |
-
}
|
593 |
-
this.ajaxSendData(url + '?' + query.join('&'), callback, 'GET', null, sync)
|
594 |
-
},
|
595 |
-
ajaxPost: function(url, data, callback, sync) {
|
596 |
-
var query = [];
|
597 |
-
for (var key in data) {
|
598 |
-
query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
|
599 |
-
}
|
600 |
-
this.ajaxSendData(url, callback, 'POST', query.join('&'), sync)
|
601 |
-
},
|
602 |
-
/**
|
603 |
-
* @param {string} event
|
604 |
-
* @param {(Object|null)} properties
|
605 |
-
* @param {(Function|null)} callback
|
606 |
-
*/
|
607 |
-
sendEvent: function(event, properties, callback) {
|
608 |
-
properties = properties || {};
|
609 |
-
async = true;
|
610 |
-
var cookieData = getCookie(); /* get cookie data */
|
611 |
-
if (cookieData) {
|
612 |
-
var key;
|
613 |
-
for (key in cookieData) {
|
614 |
-
properties[key] = cookieData[key];
|
615 |
-
}
|
616 |
-
}
|
617 |
-
if (!properties.id) {
|
618 |
-
properties.id = getId();
|
619 |
-
}
|
620 |
-
var props = {
|
621 |
-
e: event,
|
622 |
-
t: (new Date()).toISOString(),
|
623 |
-
kv: properties
|
624 |
-
};
|
625 |
-
var path = settings.api_host + '/track?data=' + encodeURIComponent(JSON.stringify(props));
|
626 |
-
if (corsEnabled) {
|
627 |
-
/* CORS */
|
628 |
-
var xhr = new XMLHttpRequest();
|
629 |
-
xhr.open('GET', path, async);
|
630 |
-
xhr.withCredentials = async;
|
631 |
-
xhr.send(null);
|
632 |
-
} else {
|
633 |
-
/* jsonP */
|
634 |
-
var el = document.createElement('script');
|
635 |
-
el.type = 'text/javascript';
|
636 |
-
el.async = async;
|
637 |
-
el.defer = async;
|
638 |
-
el.src = path;
|
639 |
-
var insertAt = document.getElementsByTagName('script')[0];
|
640 |
-
insertAt.parentNode.insertBefore(el, insertAt);
|
641 |
-
}
|
642 |
-
return action(callback), self;
|
643 |
-
},
|
644 |
-
domReady: function(win, fn) {
|
645 |
-
|
646 |
-
var done = false,
|
647 |
-
top = true,
|
648 |
-
|
649 |
-
doc = win.document,
|
650 |
-
root = doc.documentElement,
|
651 |
-
|
652 |
-
add = doc.addEventListener ? 'addEventListener' : 'attachEvent',
|
653 |
-
rem = doc.addEventListener ? 'removeEventListener' : 'detachEvent',
|
654 |
-
pre = doc.addEventListener ? '' : 'on',
|
655 |
-
|
656 |
-
init = function(e) {
|
657 |
-
if (e.type == 'readystatechange' && doc.readyState != 'complete') return;
|
658 |
-
(e.type == 'load' ? win : doc)[rem](pre + e.type, init, false);
|
659 |
-
if (!done && (done = true)) fn.call(win, e.type || e);
|
660 |
-
},
|
661 |
-
|
662 |
-
poll = function() {
|
663 |
-
try {
|
664 |
-
root.doScroll('left');
|
665 |
-
} catch (e) {
|
666 |
-
setTimeout(poll, 50);
|
667 |
-
return;
|
668 |
-
}
|
669 |
-
init('poll');
|
670 |
-
};
|
671 |
-
|
672 |
-
if (doc.readyState == 'complete') {
|
673 |
-
|
674 |
-
fn.call(win, 'lazy');
|
675 |
-
|
676 |
-
} else {
|
677 |
-
if (doc.createEventObject && root.doScroll) {
|
678 |
-
try {
|
679 |
-
top = !win.frameElement;
|
680 |
-
} catch (e) {}
|
681 |
-
if (top) poll();
|
682 |
-
}
|
683 |
-
doc[add](pre + 'DOMContentLoaded', init, false);
|
684 |
-
doc[add](pre + 'readystatechange', init, false);
|
685 |
-
win[add](pre + 'load', init, false);
|
686 |
-
}
|
687 |
-
|
688 |
-
},
|
689 |
-
/* Cross-browser event listening */
|
690 |
-
addListener: function(element, eventName, listener) {
|
691 |
-
if (!element) {
|
692 |
-
return;
|
693 |
-
}
|
694 |
-
//console.log(eventName);
|
695 |
-
//console.log(listener);
|
696 |
-
if (element.addEventListener) {
|
697 |
-
element.addEventListener(eventName, listener, false);
|
698 |
-
} else if (element.attachEvent) {
|
699 |
-
element.attachEvent("on" + eventName, listener);
|
700 |
-
} else {
|
701 |
-
element['on' + eventName] = listener;
|
702 |
-
}
|
703 |
-
},
|
704 |
-
removeListener: function(element, eventName, listener) {
|
705 |
-
|
706 |
-
if (element.removeEventListener) {
|
707 |
-
element.removeEventListener(eventName, listener, false);
|
708 |
-
} else if (element.detachEvent) {
|
709 |
-
element.detachEvent("on" + eventName, listener);
|
710 |
-
} else {
|
711 |
-
element["on" + eventName] = null;
|
712 |
-
}
|
713 |
-
},
|
714 |
-
/*
|
715 |
-
* Throttle function borrowed from:
|
716 |
-
* Underscore.js 1.5.2
|
717 |
-
* http://underscorejs.org
|
718 |
-
* (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
719 |
-
* Underscore may be freely distributed under the MIT license.
|
720 |
-
*/
|
721 |
-
throttle: function(func, wait) {
|
722 |
-
var context, args, result;
|
723 |
-
var timeout = null;
|
724 |
-
var previous = 0;
|
725 |
-
var later = function() {
|
726 |
-
previous = new Date;
|
727 |
-
timeout = null;
|
728 |
-
result = func.apply(context, args);
|
729 |
-
};
|
730 |
-
return function() {
|
731 |
-
var now = new Date;
|
732 |
-
if (!previous) previous = now;
|
733 |
-
var remaining = wait - (now - previous);
|
734 |
-
context = this;
|
735 |
-
args = arguments;
|
736 |
-
if (remaining <= 0) {
|
737 |
-
clearTimeout(timeout);
|
738 |
-
timeout = null;
|
739 |
-
previous = now;
|
740 |
-
result = func.apply(context, args);
|
741 |
-
} else if (!timeout) {
|
742 |
-
timeout = setTimeout(later, remaining);
|
743 |
-
}
|
744 |
-
return result;
|
745 |
-
};
|
746 |
-
},
|
747 |
-
/*
|
748 |
-
* Determine which version of GA is being used
|
749 |
-
* "ga", "_gaq", and "dataLayer" are the possible globals
|
750 |
-
*/
|
751 |
-
checkTypeofGA: function() {
|
752 |
-
if (typeof ga === "function") {
|
753 |
-
universalGA = true;
|
754 |
-
}
|
755 |
-
|
756 |
-
if (typeof _gaq !== "undefined" && typeof _gaq.push === "function") {
|
757 |
-
classicGA = true;
|
758 |
-
}
|
759 |
-
|
760 |
-
if (typeof dataLayer !== "undefined" && typeof dataLayer.push === "function") {
|
761 |
-
googleTagManager = true;
|
762 |
-
}
|
763 |
-
|
764 |
-
},
|
765 |
-
/**
|
766 |
-
* Caches user's search data in the browser until they can be saved to the database
|
767 |
-
*/
|
768 |
-
cacheSearchData: function(searchData, form) {
|
769 |
-
|
770 |
-
if(storageSupported){
|
771 |
-
//store the searches in the local storage
|
772 |
-
var stored = _inbound.totalStorage.getItem('inbound_search_storage');
|
773 |
-
if(stored){
|
774 |
-
//if there are stored searches, put the new one in the first index
|
775 |
-
stored.unshift(searchData);
|
776 |
-
_inbound.totalStorage.setItem('inbound_search_storage', stored);
|
777 |
-
}else{
|
778 |
-
//if there aren't any searches stored, save the current search
|
779 |
-
var store = [searchData];
|
780 |
-
_inbound.totalStorage.setItem('inbound_search_storage', store);
|
781 |
-
}
|
782 |
-
}else{
|
783 |
-
//if local storage is not possible, store the data in a cookie
|
784 |
-
var new_search = JSON.stringify(searchData),
|
785 |
-
stored_searches = this.readCookie('inbound_search_storage');
|
786 |
-
|
787 |
-
if(stored_searches){
|
788 |
-
//add the old searches to the new one
|
789 |
-
new_search += ('SPLIT-TOKEN' + stored_searches);
|
790 |
-
}
|
791 |
-
this.createCookie('inbound_search_storage', new_search, '180');
|
792 |
-
}
|
793 |
-
|
794 |
-
_inbound.Forms.releaseFormSubmit(form);
|
795 |
-
},
|
796 |
-
/**
|
797 |
-
* Stores search data to the database on page load.
|
798 |
-
* If successful, it erases the cached searches from the user's browser
|
799 |
-
*/
|
800 |
-
storeSearchData: function(){
|
801 |
-
|
802 |
-
/*if there isn't a lead id or the nonce isn't set, don't try to store the data*/
|
803 |
-
if(!inbound_settings.wp_lead_data.lead_id || !inbound_settings.wp_lead_data.lead_nonce){
|
804 |
-
return;
|
805 |
-
}
|
806 |
-
|
807 |
-
var dataToSend = [],
|
808 |
-
localStorageData = _inbound.totalStorage.getItem('inbound_search_storage'),
|
809 |
-
cookieStorageData = this.readCookie('inbound_search_storage');
|
810 |
-
|
811 |
-
/*if nothing is stored, exit*/
|
812 |
-
if(!localStorageData && !cookieStorageData){
|
813 |
-
return;
|
814 |
-
}
|
815 |
-
|
816 |
-
/*if set, add the cookie search data to the data to send*/
|
817 |
-
if(cookieStorageData){
|
818 |
-
cookieStorageData = cookieStorageData.split('SPLIT-TOKEN');
|
819 |
-
|
820 |
-
for(var i in cookieStorageData){
|
821 |
-
//console.log(cookieStorageData[i]);
|
822 |
-
dataToSend.push(JSON.parse(cookieStorageData[i]));
|
823 |
-
}
|
824 |
-
}
|
825 |
-
|
826 |
-
/*if set, add the locally stored data to the data to send*/
|
827 |
-
if(localStorageData){
|
828 |
-
dataToSend = dataToSend.concat(localStorageData);
|
829 |
-
}
|
830 |
-
|
831 |
-
dataToSend.sort(function(a, b){ return a.timestamp - b.timestamp; });
|
832 |
-
|
833 |
-
dataToSend = encodeURIComponent(JSON.stringify(dataToSend));
|
834 |
-
|
835 |
-
var package = {'action' : 'inbound_search_store', 'data' : dataToSend, 'nonce' : inbound_settings.wp_lead_data.lead_nonce, 'lead_id' : inbound_settings.wp_lead_data.lead_id };
|
836 |
-
|
837 |
-
callback = function(status){
|
838 |
-
if(status){ status = JSON.parse(status); }
|
839 |
-
|
840 |
-
if(status.success){
|
841 |
-
//log the success!
|
842 |
-
console.log(status.success);
|
843 |
-
//erase the stored data
|
844 |
-
_inbound.Utils.eraseCookie('inbound_search_storage');
|
845 |
-
_inbound.totalStorage.deleteItem('inbound_search_storage');
|
846 |
-
}
|
847 |
-
|
848 |
-
if(status.error){
|
849 |
-
console.log(status.error);
|
850 |
-
}
|
851 |
-
};
|
852 |
-
this.ajaxPost(inbound_settings.admin_url, package, callback);
|
853 |
-
}
|
854 |
-
};
|
855 |
-
|
856 |
-
return _inbound;
|
857 |
-
|
858 |
-
})(_inbound || {});
|
1 |
+
/**
|
2 |
+
* # _inbound UTILS
|
3 |
+
*
|
4 |
+
* This file contains all of the utility functions used by analytics
|
5 |
+
*
|
6 |
+
* @contributor David Wells <david@inboundnow.com>
|
7 |
+
* @contributor Hudson Atwell <hudson@inboundnow.com>
|
8 |
+
* @version 0.0.2
|
9 |
+
*/
|
10 |
+
|
11 |
+
var _inboundUtils = (function(_inbound) {
|
12 |
+
|
13 |
+
var storageSupported,
|
14 |
+
corsEnabled = window.XMLHttpRequest && 'withCredentials' in new XMLHttpRequest(),
|
15 |
+
toString = Object.prototype.toString,
|
16 |
+
currentPage = ('https:' == location.protocol ? 'https://' : 'http://') + location.hostname + location.pathname.replace(/\/$/, "");
|
17 |
+
|
18 |
+
var settings = {
|
19 |
+
api_host: currentPage,
|
20 |
+
track_pageview: true,
|
21 |
+
track_links_timeout: 300,
|
22 |
+
cookie_name: '_sp',
|
23 |
+
cookie_expiration: 365,
|
24 |
+
cookie_domain: (host = location.hostname.match(/[a-z0-9][a-z0-9\-]+\.[a-z\.]{2,6}$/i)) ? host[0] : ''
|
25 |
+
};
|
26 |
+
|
27 |
+
_inbound.Utils = {
|
28 |
+
init: function() {
|
29 |
+
|
30 |
+
this.polyFills();
|
31 |
+
this.checkLocalStorage();
|
32 |
+
this.SetUID();
|
33 |
+
this.storeReferralData();
|
34 |
+
|
35 |
+
},
|
36 |
+
/*! http://stackoverflow.com/questions/951791/javascript-global-error-handling */
|
37 |
+
/* Polyfills for missing browser functionality */
|
38 |
+
polyFills: function() {
|
39 |
+
/* Console.log fix for old browsers */
|
40 |
+
if (!window.console) {
|
41 |
+
window.console = {};
|
42 |
+
}
|
43 |
+
var m = [
|
44 |
+
"log", "info", "warn", "error", "debug", "trace", "dir", "group",
|
45 |
+
"groupCollapsed", "groupEnd", "time", "timeEnd", "profile", "profileEnd",
|
46 |
+
"dirxml", "assert", "count", "markTimeline", "timeStamp", "clear"
|
47 |
+
];
|
48 |
+
// define undefined methods as noops to prevent errors
|
49 |
+
for (var i = 0; i < m.length; i++) {
|
50 |
+
if (!window.console[m[i]]) {
|
51 |
+
window.console[m[i]] = function() {};
|
52 |
+
}
|
53 |
+
}
|
54 |
+
/* Event trigger polyfill for IE9 and 10
|
55 |
+
(function() {
|
56 |
+
function CustomEvent(event, params) {
|
57 |
+
params = params || {
|
58 |
+
bubbles: false,
|
59 |
+
cancelable: false,
|
60 |
+
detail: undefined
|
61 |
+
};
|
62 |
+
var evt = document.createEvent('CustomEvent');
|
63 |
+
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
|
64 |
+
return evt;
|
65 |
+
}
|
66 |
+
|
67 |
+
CustomEvent.prototype = window.Event.prototype;
|
68 |
+
|
69 |
+
window.CustomEvent = CustomEvent;
|
70 |
+
})();*/
|
71 |
+
|
72 |
+
/*\
|
73 |
+
|*| Polyfill Date.toISOString
|
74 |
+
\*/
|
75 |
+
if (!Date.prototype.toISOString) {
|
76 |
+
(function() {
|
77 |
+
/**
|
78 |
+
* @param {number} text
|
79 |
+
* @returns {?}
|
80 |
+
*/
|
81 |
+
function pad(text) {
|
82 |
+
/** @type {string} */
|
83 |
+
var code = String(text);
|
84 |
+
return 1 === code.length && (code = '0' + code), code;
|
85 |
+
}
|
86 |
+
/**
|
87 |
+
* @returns {string}
|
88 |
+
*/
|
89 |
+
Date.prototype.toISOString = function() {
|
90 |
+
return this.getUTCFullYear() + '-' + pad(this.getUTCMonth() + 1) + '-' + pad(this.getUTCDate()) + 'T' + pad(this.getUTCHours()) + ':' + pad(this.getUTCMinutes()) + ':' + pad(this.getUTCSeconds()) + '.' + String((this.getUTCMilliseconds() / 1E3).toFixed(3)).slice(2, 5) + 'Z';
|
91 |
+
};
|
92 |
+
})();
|
93 |
+
}
|
94 |
+
|
95 |
+
/* custom event for ie8+ https://gist.github.com/WebReflection/6693661 */
|
96 |
+
try {
|
97 |
+
new CustomEvent('?');
|
98 |
+
} catch (o_O) {
|
99 |
+
/*!(C) Andrea Giammarchi -- WTFPL License*/
|
100 |
+
this.CustomEvent = function(
|
101 |
+
eventName,
|
102 |
+
defaultInitDict
|
103 |
+
) {
|
104 |
+
|
105 |
+
// the infamous substitute
|
106 |
+
function CustomEvent(type, eventInitDict) {
|
107 |
+
var event = document.createEvent(eventName);
|
108 |
+
if (type !== null) {
|
109 |
+
initCustomEvent.call(
|
110 |
+
event,
|
111 |
+
type, (eventInitDict || (
|
112 |
+
// if falsy we can just use defaults
|
113 |
+
eventInitDict = defaultInitDict
|
114 |
+
)).bubbles,
|
115 |
+
eventInitDict.cancelable,
|
116 |
+
eventInitDict.detail
|
117 |
+
);
|
118 |
+
} else {
|
119 |
+
// no need to put the expando property otherwise
|
120 |
+
// since an event cannot be initialized twice
|
121 |
+
// previous case is the most common one anyway
|
122 |
+
// but if we end up here ... there it goes
|
123 |
+
event.initCustomEvent = initCustomEvent;
|
124 |
+
}
|
125 |
+
return event;
|
126 |
+
}
|
127 |
+
|
128 |
+
// borrowed or attached at runtime
|
129 |
+
function initCustomEvent(
|
130 |
+
type, bubbles, cancelable, detail
|
131 |
+
) {
|
132 |
+
this['init' + eventName](type, bubbles, cancelable, detail);
|
133 |
+
'detail' in this || (this.detail = detail);
|
134 |
+
}
|
135 |
+
|
136 |
+
// that's it
|
137 |
+
return CustomEvent;
|
138 |
+
}(
|
139 |
+
// is this IE9 or IE10 ?
|
140 |
+
// where CustomEvent is there
|
141 |
+
// but not usable as construtor ?
|
142 |
+
this.CustomEvent ?
|
143 |
+
// use the CustomEvent interface in such case
|
144 |
+
'CustomEvent' : 'Event',
|
145 |
+
// otherwise the common compatible one
|
146 |
+
{
|
147 |
+
bubbles: false,
|
148 |
+
cancelable: false,
|
149 |
+
detail: null
|
150 |
+
}
|
151 |
+
);
|
152 |
+
}
|
153 |
+
/* querySelectorAll polyfill for ie7+ */
|
154 |
+
if (!document.querySelectorAll) {
|
155 |
+
document.querySelectorAll = function(selectors) {
|
156 |
+
var style = document.createElement('style'),
|
157 |
+
elements = [],
|
158 |
+
element;
|
159 |
+
document.documentElement.firstChild.appendChild(style);
|
160 |
+
document._qsa = [];
|
161 |
+
|
162 |
+
style.styleSheet.cssText = selectors + '{x-qsa:expression(document._qsa && document._qsa.push(this))}';
|
163 |
+
window.scrollBy(0, 0);
|
164 |
+
style.parentNode.removeChild(style);
|
165 |
+
|
166 |
+
while (document._qsa.length) {
|
167 |
+
element = document._qsa.shift();
|
168 |
+
element.style.removeAttribute('x-qsa');
|
169 |
+
elements.push(element);
|
170 |
+
}
|
171 |
+
document._qsa = null;
|
172 |
+
return elements;
|
173 |
+
};
|
174 |
+
}
|
175 |
+
|
176 |
+
if (!document.querySelector) {
|
177 |
+
document.querySelector = function(selectors) {
|
178 |
+
var elements = document.querySelectorAll(selectors);
|
179 |
+
return (elements.length) ? elements[0] : null;
|
180 |
+
};
|
181 |
+
}
|
182 |
+
/* Innertext shim for firefox https://github.com/duckinator/innerText-polyfill/blob/master/innertext.js */
|
183 |
+
if ((!('innerText' in document.createElement('a'))) && ('getSelection' in window)) {
|
184 |
+
HTMLElement.prototype.__defineGetter__("innerText", function() {
|
185 |
+
var selection = window.getSelection(),
|
186 |
+
ranges = [],
|
187 |
+
str;
|
188 |
+
|
189 |
+
// Save existing selections.
|
190 |
+
for (var i = 0; i < selection.rangeCount; i++) {
|
191 |
+
ranges[i] = selection.getRangeAt(i);
|
192 |
+
}
|
193 |
+
|
194 |
+
// Deselect everything.
|
195 |
+
selection.removeAllRanges();
|
196 |
+
|
197 |
+
// Select `el` and all child nodes.
|
198 |
+
// 'this' is the element .innerText got called on
|
199 |
+
selection.selectAllChildren(this);
|
200 |
+
|
201 |
+
// Get the string representation of the selected nodes.
|
202 |
+
str = selection.toString();
|
203 |
+
|
204 |
+
// Deselect everything. Again.
|
205 |
+
selection.removeAllRanges();
|
206 |
+
|
207 |
+
// Restore all formerly existing selections.
|
208 |
+
for (var i = 0; i < ranges.length; i++) {
|
209 |
+
selection.addRange(ranges[i]);
|
210 |
+
}
|
211 |
+
|
212 |
+
// Oh look, this is what we wanted.
|
213 |
+
// String representation of the element, close to as rendered.
|
214 |
+
return str;
|
215 |
+
})
|
216 |
+
}
|
217 |
+
},
|
218 |
+
/**
|
219 |
+
* Create cookie
|
220 |
+
*
|
221 |
+
* ```js
|
222 |
+
* // Creates cookie for 10 days
|
223 |
+
* _inbound.Utils.createCookie( 'cookie_name', 'value', 10 );
|
224 |
+
* ```
|
225 |
+
*
|
226 |
+
* @param {string} name Name of cookie
|
227 |
+
* @param {string} value Value of cookie
|
228 |
+
* @param {string} days Length of storage
|
229 |
+
*/
|
230 |
+
createCookie: function(name, value, days) {
|
231 |
+
var expires = "";
|
232 |
+
if (days) {
|
233 |
+
var date = new Date();
|
234 |
+
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
235 |
+
expires = "; expires=" + date.toGMTString();
|
236 |
+
}
|
237 |
+
document.cookie = name + "=" + value + expires + "; path=/";
|
238 |
+
},
|
239 |
+
/**
|
240 |
+
* Read cookie value
|
241 |
+
*
|
242 |
+
* ```js
|
243 |
+
* var cookie = _inbound.Utils.readCookie( 'cookie_name' );
|
244 |
+
* console.log(cookie); // cookie value
|
245 |
+
* ```
|
246 |
+
* @param {string} name name of cookie
|
247 |
+
* @return {string} value of cookie
|
248 |
+
*/
|
249 |
+
readCookie: function(name) {
|
250 |
+
var nameEQ = name + "=";
|
251 |
+
var ca = document.cookie.split(';');
|
252 |
+
for (var i = 0; i < ca.length; i++) {
|
253 |
+
var c = ca[i];
|
254 |
+
while (c.charAt(0) === ' ') {
|
255 |
+
c = c.substring(1, c.length);
|
256 |
+
}
|
257 |
+
if (c.indexOf(nameEQ) === 0) {
|
258 |
+
return c.substring(nameEQ.length, c.length);
|
259 |
+
}
|
260 |
+
}
|
261 |
+
return null;
|
262 |
+
},
|
263 |
+
/**
|
264 |
+
* Erase cookie
|
265 |
+
*
|
266 |
+
* ```js
|
267 |
+
* // usage:
|
268 |
+
* _inbound.Utils.eraseCookie( 'cookie_name' );
|
269 |
+
* // deletes 'cookie_name' value
|
270 |
+
* ```
|
271 |
+
* @param {string} name name of cookie
|
272 |
+
* @return {string} value of cookie
|
273 |
+
*/
|
274 |
+
eraseCookie: function(name) {
|
275 |
+
this.createCookie(name, "", -1);
|
276 |
+
},
|
277 |
+
/* Get All Cookies */
|
278 |
+
getAllCookies: function() {
|
279 |
+
var cookies = {};
|
280 |
+
if (document.cookie && document.cookie !== '') {
|
281 |
+
var split = document.cookie.split(';');
|
282 |
+
for (var i = 0; i < split.length; i++) {
|
283 |
+
var name_value = split[i].split("=");
|
284 |
+
name_value[0] = name_value[0].replace(/^ /, '');
|
285 |
+
cookies[decodeURIComponent(name_value[0])] = decodeURIComponent(name_value[1]);
|
286 |
+
}
|
287 |
+
}
|
288 |
+
_inbound.totalStorage('inbound_cookies', cookies); // store cookie data
|
289 |
+
return cookies;
|
290 |
+
},
|
291 |
+
/* Grab URL params and save */
|
292 |
+
setUrlParams: function() {
|
293 |
+
var urlParams = {};
|
294 |
+
|
295 |
+
(function() {
|
296 |
+
var e,
|
297 |
+
d = function(s) {
|
298 |
+
return decodeURIComponent(s).replace(/\+/g, " ");
|
299 |
+
},
|
300 |
+
q = window.location.search.substring(1),
|
301 |
+
r = /([^&=]+)=?([^&]*)/g;
|
302 |
+
|
303 |
+
while (e = r.exec(q)) {
|
304 |
+
if (e[1].indexOf("[") == "-1")
|
305 |
+
urlParams[d(e[1])] = d(e[2]);
|
306 |
+
else {
|
307 |
+
var b1 = e[1].indexOf("["),
|
308 |
+
aN = e[1].slice(b1 + 1, e[1].indexOf("]", b1)),
|
309 |
+
pN = d(e[1].slice(0, b1));
|
310 |
+
|
311 |
+
if (typeof urlParams[pN] != "object")
|
312 |
+
urlParams[d(pN)] = {},
|
313 |
+
urlParams[d(pN)].length = 0;
|
314 |
+
|
315 |
+
if (aN)
|
316 |
+
urlParams[d(pN)][d(aN)] = d(e[2]);
|
317 |
+
else
|
318 |
+
Array.prototype.push.call(urlParams[d(pN)], d(e[2]));
|
319 |
+
|
320 |
+
}
|
321 |
+
}
|
322 |
+
})();
|
323 |
+
|
324 |
+
/* Set Param Cookies */
|
325 |
+
for (var k in urlParams) {
|
326 |
+
/* account for wordpress media uploader bug */
|
327 |
+
if (k == 'action') {
|
328 |
+
continue;
|
329 |
+
}
|
330 |
+
|
331 |
+
if (typeof urlParams[k] == "object") {
|
332 |
+
for (var k2 in urlParams[k])
|
333 |
+
this.createCookie(k2, urlParams[k][k2], 30);
|
334 |
+
} else {
|
335 |
+
this.createCookie(k, urlParams[k], 30);
|
336 |
+
}
|
337 |
+
}
|
338 |
+
/* Set Param LocalStorage */
|
339 |
+
if (storageSupported) {
|
340 |
+
var pastParams = _inbound.totalStorage('inbound_url_params') || {};
|
341 |
+
var params = this.mergeObjs(pastParams, urlParams);
|
342 |
+
_inbound.totalStorage('inbound_url_params', params); // store cookie data
|
343 |
+
}
|
344 |
+
|
345 |
+
var options = {
|
346 |
+
'option1': 'yo',
|
347 |
+
'option2': 'woooo'
|
348 |
+
};
|
349 |
+
|
350 |
+
_inbound.trigger('url_parameters', urlParams, options);
|
351 |
+
|
352 |
+
},
|
353 |
+
getAllUrlParams: function() {
|
354 |
+
var get_params = {};
|
355 |
+
if (storageSupported) {
|
356 |
+
var get_params = _inbound.totalStorage('inbound_url_params');
|
357 |
+
}
|
358 |
+
return get_params;
|
359 |
+
},
|
360 |
+
/* Get url param */
|
361 |
+
getParameterVal: function(name, string) {
|
362 |
+
return (RegExp(name + '=' + '(.+?)(&|$)').exec(string) || [, false])[1];
|
363 |
+
},
|
364 |
+
// Check local storage
|
365 |
+
// provate browsing safari fix https://github.com/marcuswestin/store.js/issues/42#issuecomment-25274685
|
366 |
+
checkLocalStorage: function() {
|
367 |
+
if ('localStorage' in window) {
|
368 |
+
try {
|
369 |
+
ls = (typeof window.localStorage === 'undefined') ? undefined : window.localStorage;
|
370 |
+
if (typeof ls == 'undefined' || typeof window.JSON == 'undefined') {
|
371 |
+
storageSupported = false;
|
372 |
+
} else {
|
373 |
+
storageSupported = true;
|
374 |
+
}
|
375 |
+
|
376 |
+
} catch (err) {
|
377 |
+
storageSupported = false;
|
378 |
+
}
|
379 |
+
}
|
380 |
+
return storageSupported;
|
381 |
+
/* http://spin.atomicobject.com/2013/01/23/ios-private-browsing-localstorage/
|
382 |
+
var hasStorage;
|
383 |
+
hasStorage = function() {
|
384 |
+
var mod, result;
|
385 |
+
try {
|
386 |
+
mod = new Date;
|
387 |
+
localStorage.setItem(mod, mod.toString());
|
388 |
+
result = localStorage.getItem(mod) === mod.toString();
|
389 |
+
localStorage.removeItem(mod);
|
390 |
+
return result;
|
391 |
+
} catch (_error) {}
|
392 |
+
};
|
393 |
+
*/
|
394 |
+
},
|
395 |
+
// http://stackoverflow.com/questions/4391575/how-to-find-the-size-of-localstorage
|
396 |
+
showLocalStorageSize: function() {
|
397 |
+
function stringSizeBytes(str) {
|
398 |
+
return str.length * 2;
|
399 |
+
}
|
400 |
+
|
401 |
+
function toMB(bytes) {
|
402 |
+
return bytes / 1024 / 1024;
|
403 |
+
}
|
404 |
+
|
405 |
+
function toSize(key) {
|
406 |
+
return {
|
407 |
+
name: key,
|
408 |
+
size: stringSizeBytes(localStorage[key])
|
409 |
+
};
|
410 |
+
}
|
411 |
+
|
412 |
+
function toSizeMB(info) {
|
413 |
+
info.size = toMB(info.size).toFixed(2) + ' MB';
|
414 |
+
return info;
|
415 |
+
}
|
416 |
+
|
417 |
+
var sizes = Object.keys(localStorage).map(toSize).map(toSizeMB);
|
418 |
+
|
419 |
+
console.table(sizes);
|
420 |
+
},
|
421 |
+
/* Add days to datetime */
|
422 |
+
addDays: function(myDate, days) {
|
423 |
+
return new Date(myDate.getTime() + days * 24 * 60 * 60 * 1000);
|
424 |
+
},
|
425 |
+
GetDate: function() {
|
426 |
+
var timeNow = new Date(),
|
427 |
+
d = timeNow.getDate(),
|
428 |
+
dPre = (d < 10) ? "0" : "",
|
429 |
+
y = timeNow.getFullYear(),
|
430 |
+
h = timeNow.getHours(),
|
431 |
+
hPre = (h < 10) ? "0" : "",
|
432 |
+
min = timeNow.getMinutes(),
|
433 |
+
minPre = (min < 10) ? "0" : "",
|
434 |
+
sec = timeNow.getSeconds(),
|
435 |
+
secPre = (sec < 10) ? "0" : "",
|
436 |
+
m = timeNow.getMonth() + 1,
|
437 |
+
mPre = (m < 10) ? "0" : "";
|
438 |
+
|
439 |
+
var datetime = y + '/' + mPre + m + "/" + dPre + d + " " + hPre + h + ":" + minPre + min + ":" + secPre + sec;
|
440 |
+
/* format 2014/11/13 18:22:02 */
|
441 |
+
return datetime;
|
442 |
+
},
|
443 |
+
/* Set Expiration Date of Session Logging. LEGACY Not in Use */
|
444 |
+
SetSessionTimeout: function() {
|
445 |
+
var session = this.readCookie("lead_session_expire");
|
446 |
+
//console.log(session_check);
|
447 |
+
if (!session) {
|
448 |
+
//_inbound.trigger('session_start'); // trigger 'inbound_analytics_session_start'
|
449 |
+
} else {
|
450 |
+
//_inbound.trigger('session_resume'); // trigger 'inbound_analytics_session_active'
|
451 |
+
}
|
452 |
+
var d = new Date();
|
453 |
+
d.setTime(d.getTime() + 30 * 60 * 1000);
|
454 |
+
|
455 |
+
this.createCookie("lead_session_expire", true, d); // Set cookie on page load
|
456 |
+
|
457 |
+
},
|
458 |
+
storeReferralData: function() {
|
459 |
+
//console.log(expire_time);
|
460 |
+
var d = new Date(),
|
461 |
+
referrer = document.referrer || "Direct Traffic",
|
462 |
+
referrer_cookie = _inbound.Utils.readCookie("inbound_referral_site"),
|
463 |
+
original_src = _inbound.totalStorage('inbound_original_referral');
|
464 |
+
|
465 |
+
d.setTime(d.getTime() + 30 * 60 * 1000);
|
466 |
+
|
467 |
+
if (!referrer_cookie) {
|
468 |
+
this.createCookie("inbound_referral_site", referrer, d);
|
469 |
+
}
|
470 |
+
if (!original_src) {
|
471 |
+
_inbound.totalStorage('inbound_original_referral', original_src);
|
472 |
+
}
|
473 |
+
},
|
474 |
+
CreateUID: function(length) {
|
475 |
+
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'.split(''),
|
476 |
+
str = '';
|
477 |
+
if (!length) {
|
478 |
+
length = Math.floor(Math.random() * chars.length);
|
479 |
+
}
|
480 |
+
for (var i = 0; i < length; i++) {
|
481 |
+
str += chars[Math.floor(Math.random() * chars.length)];
|
482 |
+
}
|
483 |
+
return str;
|
484 |
+
},
|
485 |
+
generateGUID: function(a) {
|
486 |
+
return a ? (a ^ 16 * Math.random() >> a / 4).toString(16) : ([1E7] + -1E3 + -4E3 + -8E3 + -1E11).replace(/[018]/g, guid);
|
487 |
+
},
|
488 |
+
SetUID: function(leadUID) {
|
489 |
+
/* Set Lead UID */
|
490 |
+
if (!this.readCookie("wp_lead_uid")) {
|
491 |
+
var wp_lead_uid = leadUID || this.CreateUID(35);
|
492 |
+
this.createCookie("wp_lead_uid", wp_lead_uid);
|
493 |
+
}
|
494 |
+
},
|
495 |
+
/* Count number of session visits */
|
496 |
+
countProperties: function(obj) {
|
497 |
+
var count = 0;
|
498 |
+
for (var prop in obj) {
|
499 |
+
if (obj.hasOwnProperty(prop)) {
|
500 |
+
++count;
|
501 |
+
}
|
502 |
+
}
|
503 |
+
return count;
|
504 |
+
},
|
505 |
+
mergeObjs: function(obj1, obj2) {
|
506 |
+
var obj3 = {};
|
507 |
+
for (var attrname in obj1) {
|
508 |
+
obj3[attrname] = obj1[attrname];
|
509 |
+
}
|
510 |
+
for (var attrname in obj2) {
|
511 |
+
obj3[attrname] = obj2[attrname];
|
512 |
+
}
|
513 |
+
return obj3;
|
514 |
+
},
|
515 |
+
hasClass: function(className, el) {
|
516 |
+
var hasClass;
|
517 |
+
if ('classList' in document.documentElement) {
|
518 |
+
var hasClass = el.classList.contains(className);
|
519 |
+
} else {
|
520 |
+
var hasClass = new RegExp('(^|\\s)' + className + '(\\s|$)').test(el.className); /* IE Polyfill */
|
521 |
+
}
|
522 |
+
return hasClass;
|
523 |
+
},
|
524 |
+
addClass: function(className, el) {
|
525 |
+
if ('classList' in document.documentElement) {
|
526 |
+
el.classList.add(className);
|
527 |
+
} else {
|
528 |
+
if (!this.hasClass(el, className)) {
|
529 |
+
el.className += (el.className ? ' ' : '') + className;
|
530 |
+
}
|
531 |
+
}
|
532 |
+
},
|
533 |
+
removeClass: function(className, el) {
|
534 |
+
if ('classList' in document.documentElement) {
|
535 |
+
el.classList.remove(className);
|
536 |
+
} else {
|
537 |
+
if (this.hasClass(el, className)) {
|
538 |
+
el.className = el.className.replace(new RegExp('(^|\\s)*' + className + '(\\s|$)*', 'g'), '');
|
539 |
+
}
|
540 |
+
}
|
541 |
+
},
|
542 |
+
removeElement: function(el) {
|
543 |
+
el.parentNode.removeChild(el);
|
544 |
+
},
|
545 |
+
trim: function(s) {
|
546 |
+
s = s.replace(/(^\s*)|(\s*$)/gi, "");
|
547 |
+
s = s.replace(/[ ]{2,}/gi, " ");
|
548 |
+
s = s.replace(/\n /, "\n");
|
549 |
+
return s;
|
550 |
+
},
|
551 |
+
ajaxPolyFill: function() {
|
552 |
+
if (typeof XMLHttpRequest !== 'undefined') {
|
553 |
+
return new XMLHttpRequest();
|
554 |
+
}
|
555 |
+
var versions = [
|
556 |
+
"MSXML2.XmlHttp.5.0",
|
557 |
+
"MSXML2.XmlHttp.4.0",
|
558 |
+
"MSXML2.XmlHttp.3.0",
|
559 |
+
"MSXML2.XmlHttp.2.0",
|
560 |
+
"Microsoft.XmlHttp"
|
561 |
+
];
|
562 |
+
|
563 |
+
var xhr;
|
564 |
+
for (var i = 0; i < versions.length; i++) {
|
565 |
+
try {
|
566 |
+
xhr = new ActiveXObject(versions[i]);
|
567 |
+
break;
|
568 |
+
} catch (e) {}
|
569 |
+
}
|
570 |
+
return xhr;
|
571 |
+
},
|
572 |
+
ajaxSendData: function(url, callback, method, data, sync) {
|
573 |
+
var x = this.ajaxPolyFill();
|
574 |
+
/* timeout for safari idiocy */
|
575 |
+
setTimeout(function() {
|
576 |
+
x.open(method, url, true);
|
577 |
+
x.onreadystatechange = function() {
|
578 |
+
if (x.readyState == 4) {
|
579 |
+
callback(x.responseText)
|
580 |
+
}
|
581 |
+
};
|
582 |
+
if (method == 'POST') {
|
583 |
+
x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
584 |
+
}
|
585 |
+
x.send(data);
|
586 |
+
}, 100);
|
587 |
+
},
|
588 |
+
ajaxGet: function(url, data, callback, sync) {
|
589 |
+
var query = [];
|
590 |
+
for (var key in data) {
|
591 |
+
query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
|
592 |
+
}
|
593 |
+
this.ajaxSendData(url + '?' + query.join('&'), callback, 'GET', null, sync)
|
594 |
+
},
|
595 |
+
ajaxPost: function(url, data, callback, sync) {
|
596 |
+
var query = [];
|
597 |
+
for (var key in data) {
|
598 |
+
query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
|
599 |
+
}
|
600 |
+
this.ajaxSendData(url, callback, 'POST', query.join('&'), sync)
|
601 |
+
},
|
602 |
+
/**
|
603 |
+
* @param {string} event
|
604 |
+
* @param {(Object|null)} properties
|
605 |
+
* @param {(Function|null)} callback
|
606 |
+
*/
|
607 |
+
sendEvent: function(event, properties, callback) {
|
608 |
+
properties = properties || {};
|
609 |
+
async = true;
|
610 |
+
var cookieData = getCookie(); /* get cookie data */
|
611 |
+
if (cookieData) {
|
612 |
+
var key;
|
613 |
+
for (key in cookieData) {
|
614 |
+
properties[key] = cookieData[key];
|
615 |
+
}
|
616 |
+
}
|
617 |
+
if (!properties.id) {
|
618 |
+
properties.id = getId();
|
619 |
+
}
|
620 |
+
var props = {
|
621 |
+
e: event,
|
622 |
+
t: (new Date()).toISOString(),
|
623 |
+
kv: properties
|
624 |
+
};
|
625 |
+
var path = settings.api_host + '/track?data=' + encodeURIComponent(JSON.stringify(props));
|
626 |
+
if (corsEnabled) {
|
627 |
+
/* CORS */
|
628 |
+
var xhr = new XMLHttpRequest();
|
629 |
+
xhr.open('GET', path, async);
|
630 |
+
xhr.withCredentials = async;
|
631 |
+
xhr.send(null);
|
632 |
+
} else {
|
633 |
+
/* jsonP */
|
634 |
+
var el = document.createElement('script');
|
635 |
+
el.type = 'text/javascript';
|
636 |
+
el.async = async;
|
637 |
+
el.defer = async;
|
638 |
+
el.src = path;
|
639 |
+
var insertAt = document.getElementsByTagName('script')[0];
|
640 |
+
insertAt.parentNode.insertBefore(el, insertAt);
|
641 |
+
}
|
642 |
+
return action(callback), self;
|
643 |
+
},
|
644 |
+
domReady: function(win, fn) {
|
645 |
+
|
646 |
+
var done = false,
|
647 |
+
top = true,
|
648 |
+
|
649 |
+
doc = win.document,
|
650 |
+
root = doc.documentElement,
|
651 |
+
|
652 |
+
add = doc.addEventListener ? 'addEventListener' : 'attachEvent',
|
653 |
+
rem = doc.addEventListener ? 'removeEventListener' : 'detachEvent',
|
654 |
+
pre = doc.addEventListener ? '' : 'on',
|
655 |
+
|
656 |
+
init = function(e) {
|
657 |
+
if (e.type == 'readystatechange' && doc.readyState != 'complete') return;
|
658 |
+
(e.type == 'load' ? win : doc)[rem](pre + e.type, init, false);
|
659 |
+
if (!done && (done = true)) fn.call(win, e.type || e);
|
660 |
+
},
|
661 |
+
|
662 |
+
poll = function() {
|
663 |
+
try {
|
664 |
+
root.doScroll('left');
|
665 |
+
} catch (e) {
|
666 |
+
setTimeout(poll, 50);
|
667 |
+
return;
|
668 |
+
}
|
669 |
+
init('poll');
|
670 |
+
};
|
671 |
+
|
672 |
+
if (doc.readyState == 'complete') {
|
673 |
+
|
674 |
+
fn.call(win, 'lazy');
|
675 |
+
|
676 |
+
} else {
|
677 |
+
if (doc.createEventObject && root.doScroll) {
|
678 |
+
try {
|
679 |
+
top = !win.frameElement;
|
680 |
+
} catch (e) {}
|
681 |
+
if (top) poll();
|
682 |
+
}
|
683 |
+
doc[add](pre + 'DOMContentLoaded', init, false);
|
684 |
+
doc[add](pre + 'readystatechange', init, false);
|
685 |
+
win[add](pre + 'load', init, false);
|
686 |
+
}
|
687 |
+
|
688 |
+
},
|
689 |
+
/* Cross-browser event listening */
|
690 |
+
addListener: function(element, eventName, listener) {
|
691 |
+
if (!element) {
|
692 |
+
return;
|
693 |
+
}
|
694 |
+
//console.log(eventName);
|
695 |
+
//console.log(listener);
|
696 |
+
if (element.addEventListener) {
|
697 |
+
element.addEventListener(eventName, listener, false);
|
698 |
+
} else if (element.attachEvent) {
|
699 |
+
element.attachEvent("on" + eventName, listener);
|
700 |
+
} else {
|
701 |
+
element['on' + eventName] = listener;
|
702 |
+
}
|
703 |
+
},
|
704 |
+
removeListener: function(element, eventName, listener) {
|
705 |
+
|
706 |
+
if (element.removeEventListener) {
|
707 |
+
element.removeEventListener(eventName, listener, false);
|
708 |
+
} else if (element.detachEvent) {
|
709 |
+
element.detachEvent("on" + eventName, listener);
|
710 |
+
} else {
|
711 |
+
element["on" + eventName] = null;
|
712 |
+
}
|
713 |
+
},
|
714 |
+
/*
|
715 |
+
* Throttle function borrowed from:
|
716 |
+
* Underscore.js 1.5.2
|
717 |
+
* http://underscorejs.org
|
718 |
+
* (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
719 |
+
* Underscore may be freely distributed under the MIT license.
|
720 |
+
*/
|
721 |
+
throttle: function(func, wait) {
|
722 |
+
var context, args, result;
|
723 |
+
var timeout = null;
|
724 |
+
var previous = 0;
|
725 |
+
var later = function() {
|
726 |
+
previous = new Date;
|
727 |
+
timeout = null;
|
728 |
+
result = func.apply(context, args);
|
729 |
+
};
|
730 |
+
return function() {
|
731 |
+
var now = new Date;
|
732 |
+
if (!previous) previous = now;
|
733 |
+
var remaining = wait - (now - previous);
|
734 |
+
context = this;
|
735 |
+
args = arguments;
|
736 |
+
if (remaining <= 0) {
|
737 |
+
clearTimeout(timeout);
|
738 |
+
timeout = null;
|
739 |
+
previous = now;
|
740 |
+
result = func.apply(context, args);
|
741 |
+
} else if (!timeout) {
|
742 |
+
timeout = setTimeout(later, remaining);
|
743 |
+
}
|
744 |
+
return result;
|
745 |
+
};
|
746 |
+
},
|
747 |
+
/*
|
748 |
+
* Determine which version of GA is being used
|
749 |
+
* "ga", "_gaq", and "dataLayer" are the possible globals
|
750 |
+
*/
|
751 |
+
checkTypeofGA: function() {
|
752 |
+
if (typeof ga === "function") {
|
753 |
+
universalGA = true;
|
754 |
+
}
|
755 |
+
|
756 |
+
if (typeof _gaq !== "undefined" && typeof _gaq.push === "function") {
|
757 |
+
classicGA = true;
|
758 |
+
}
|
759 |
+
|
760 |
+
if (typeof dataLayer !== "undefined" && typeof dataLayer.push === "function") {
|
761 |
+
googleTagManager = true;
|
762 |
+
}
|
763 |
+
|
764 |
+
},
|
765 |
+
/**
|
766 |
+
* Caches user's search data in the browser until they can be saved to the database
|
767 |
+
*/
|
768 |
+
cacheSearchData: function(searchData, form) {
|
769 |
+
|
770 |
+
if(storageSupported){
|
771 |
+
//store the searches in the local storage
|
772 |
+
var stored = _inbound.totalStorage.getItem('inbound_search_storage');
|
773 |
+
if(stored){
|
774 |
+
//if there are stored searches, put the new one in the first index
|
775 |
+
stored.unshift(searchData);
|
776 |
+
_inbound.totalStorage.setItem('inbound_search_storage', stored);
|
777 |
+
}else{
|
778 |
+
//if there aren't any searches stored, save the current search
|
779 |
+
var store = [searchData];
|
780 |
+
_inbound.totalStorage.setItem('inbound_search_storage', store);
|
781 |
+
}
|
782 |
+
}else{
|
783 |
+
//if local storage is not possible, store the data in a cookie
|
784 |
+
var new_search = JSON.stringify(searchData),
|
785 |
+
stored_searches = this.readCookie('inbound_search_storage');
|
786 |
+
|
787 |
+
if(stored_searches){
|
788 |
+
//add the old searches to the new one
|
789 |
+
new_search += ('SPLIT-TOKEN' + stored_searches);
|
790 |
+
}
|
791 |
+
this.createCookie('inbound_search_storage', new_search, '180');
|
792 |
+
}
|
793 |
+
|
794 |
+
_inbound.Forms.releaseFormSubmit(form);
|
795 |
+
},
|
796 |
+
/**
|
797 |
+
* Stores search data to the database on page load.
|
798 |
+
* If successful, it erases the cached searches from the user's browser
|
799 |
+
*/
|
800 |
+
storeSearchData: function(){
|
801 |
+
|
802 |
+
/*if there isn't a lead id or the nonce isn't set, don't try to store the data*/
|
803 |
+
if(!inbound_settings.wp_lead_data.lead_id || !inbound_settings.wp_lead_data.lead_nonce){
|
804 |
+
return;
|
805 |
+
}
|
806 |
+
|
807 |
+
var dataToSend = [],
|
808 |
+
localStorageData = _inbound.totalStorage.getItem('inbound_search_storage'),
|
809 |
+
cookieStorageData = this.readCookie('inbound_search_storage');
|
810 |
+
|
811 |
+
/*if nothing is stored, exit*/
|
812 |
+
if(!localStorageData && !cookieStorageData){
|
813 |
+
return;
|
814 |
+
}
|
815 |
+
|
816 |
+
/*if set, add the cookie search data to the data to send*/
|
817 |
+
if(cookieStorageData){
|
818 |
+
cookieStorageData = cookieStorageData.split('SPLIT-TOKEN');
|
819 |
+
|
820 |
+
for(var i in cookieStorageData){
|
821 |
+
//console.log(cookieStorageData[i]);
|
822 |
+
dataToSend.push(JSON.parse(cookieStorageData[i]));
|
823 |
+
}
|
824 |
+
}
|
825 |
+
|
826 |
+
/*if set, add the locally stored data to the data to send*/
|
827 |
+
if(localStorageData){
|
828 |
+
dataToSend = dataToSend.concat(localStorageData);
|
829 |
+
}
|
830 |
+
|
831 |
+
dataToSend.sort(function(a, b){ return a.timestamp - b.timestamp; });
|
832 |
+
|
833 |
+
dataToSend = encodeURIComponent(JSON.stringify(dataToSend));
|
834 |
+
|
835 |
+
var package = {'action' : 'inbound_search_store', 'data' : dataToSend, 'nonce' : inbound_settings.wp_lead_data.lead_nonce, 'lead_id' : inbound_settings.wp_lead_data.lead_id };
|
836 |
+
|
837 |
+
callback = function(status){
|
838 |
+
if(status){ status = JSON.parse(status); }
|
839 |
+
|
840 |
+
if(status.success){
|
841 |
+
//log the success!
|
842 |
+
console.log(status.success);
|
843 |
+
//erase the stored data
|
844 |
+
_inbound.Utils.eraseCookie('inbound_search_storage');
|
845 |
+
_inbound.totalStorage.deleteItem('inbound_search_storage');
|
846 |
+
}
|
847 |
+
|
848 |
+
if(status.error){
|
849 |
+
console.log(status.error);
|
850 |
+
}
|
851 |
+
};
|
852 |
+
this.ajaxPost(inbound_settings.admin_url, package, callback);
|
853 |
+
}
|
854 |
+
};
|
855 |
+
|
856 |
+
return _inbound;
|
857 |
+
|
858 |
+
})(_inbound || {});
|
shared/assets/js/frontend/analytics/inboundAnalytics.js
CHANGED
@@ -1,3846 +1,3847 @@
|
|
1 |
-
/*! Inbound Analyticsv1.0.0 | (c) 2017 Inbound Now | https://github.com/inboundnow/cta */
|
2 |
-
/**
|
3 |
-
* # _inbound
|
4 |
-
*
|
5 |
-
* This main the _inbound class
|
6 |
-
*
|
7 |
-
* @
|
8 |
-
* @
|
9 |
-
* @version 0.0.2
|
10 |
-
*/
|
11 |
-
|
12 |
-
var inbound_data = inbound_data || {};
|
13 |
-
var _inboundOptions = _inboundOptions || {};
|
14 |
-
/* Ensure global _gaq Google Analytics queue has been initialized. */
|
15 |
-
var _gaq = _gaq || [];
|
16 |
-
|
17 |
-
var _inbound = (function(options) {
|
18 |
-
|
19 |
-
/* Constants */
|
20 |
-
var defaults = {
|
21 |
-
timeout: ( inbound_settings.is_admin ? 500 : 10000 ),
|
22 |
-
formAutoTracking: true,
|
23 |
-
formAutoPopulation: true
|
24 |
-
};
|
25 |
-
|
26 |
-
var Analytics = {
|
27 |
-
/* Initialize individual modules */
|
28 |
-
init: function() {
|
29 |
-
_inbound.Utils.init();
|
30 |
-
|
31 |
-
_inbound.Utils.domReady(window, function() {
|
32 |
-
/* On Load Analytics Events */
|
33 |
-
_inbound.DomLoaded();
|
34 |
-
|
35 |
-
});
|
36 |
-
},
|
37 |
-
DomLoaded: function() {
|
38 |
-
_inbound.PageTracking.init();
|
39 |
-
/* run form mapping */
|
40 |
-
_inbound.Forms.init();
|
41 |
-
/* set URL params */
|
42 |
-
_inbound.Utils.setUrlParams();
|
43 |
-
_inbound.LeadsAPI.init();
|
44 |
-
/* run form mapping for dynamically generated forms */
|
45 |
-
setTimeout(function() {
|
46 |
-
_inbound.Forms.init();
|
47 |
-
}, 2000);
|
48 |
-
|
49 |
-
_inbound.trigger('analytics_ready');
|
50 |
-
|
51 |
-
},
|
52 |
-
/**
|
53 |
-
* Merge script defaults with user options
|
54 |
-
* @private
|
55 |
-
* @param {Object} defaults Default settings
|
56 |
-
* @param {Object} options User options
|
57 |
-
* @returns {Object} Merged values of defaults and options
|
58 |
-
*/
|
59 |
-
extend: function(defaults, options) {
|
60 |
-
var extended = {};
|
61 |
-
var prop;
|
62 |
-
for (prop in defaults) {
|
63 |
-
if (Object.prototype.hasOwnProperty.call(defaults, prop)) {
|
64 |
-
extended[prop] = defaults[prop];
|
65 |
-
}
|
66 |
-
}
|
67 |
-
for (prop in options) {
|
68 |
-
if (Object.prototype.hasOwnProperty.call(options, prop)) {
|
69 |
-
extended[prop] = options[prop];
|
70 |
-
}
|
71 |
-
}
|
72 |
-
return extended;
|
73 |
-
},
|
74 |
-
/* Debugger Function toggled by var debugMode */
|
75 |
-
debug: function(msg, callback) {
|
76 |
-
/* legacy */
|
77 |
-
},
|
78 |
-
deBugger: function(context, msg, callback) {
|
79 |
-
|
80 |
-
if (!console) {
|
81 |
-
return;
|
82 |
-
}
|
83 |
-
//if app not in debug mode, exit immediately
|
84 |
-
// check for hash
|
85 |
-
var hash = (document.location.hash) ? document.location.hash : '',
|
86 |
-
debugHash = hash.indexOf("#debug") > -1,
|
87 |
-
msg = msg || false,
|
88 |
-
logCookie,
|
89 |
-
logAllMessages,
|
90 |
-
hashcontext;
|
91 |
-
|
92 |
-
if (hash && hash.match(/debug/)) {
|
93 |
-
hash = hash.split('-');
|
94 |
-
hashcontext = hash[1];
|
95 |
-
}
|
96 |
-
|
97 |
-
|
98 |
-
logAllMessages = (_inbound.Utils.readCookie("inbound_debug") === "true") ? true : false;
|
99 |
-
logCookie = (_inbound.Utils.readCookie("inbound_debug_" + context) === "true") ? true : false;
|
100 |
-
|
101 |
-
if (!logCookie && !debugHash && !logAllMessages) {
|
102 |
-
// no logger set. exit.
|
103 |
-
return;
|
104 |
-
};
|
105 |
-
|
106 |
-
//console.log the message
|
107 |
-
if (msg && (typeof msg === 'string')) {
|
108 |
-
|
109 |
-
if (logAllMessages || hashcontext === 'all') {
|
110 |
-
console.log('logAll "' + context + '" =>', msg)
|
111 |
-
} else if (logCookie) {
|
112 |
-
console.log('log "' + context + '" =>', msg)
|
113 |
-
} else if (context === hashcontext) {
|
114 |
-
console.log('#log "' + context + '" =>', msg)
|
115 |
-
}
|
116 |
-
|
117 |
-
};
|
118 |
-
|
119 |
-
//execute the callback if one was passed-in
|
120 |
-
if (callback && (callback instanceof Function)) {
|
121 |
-
callback();
|
122 |
-
};
|
123 |
-
}
|
124 |
-
};
|
125 |
-
|
126 |
-
var settings = Analytics.extend(defaults, options);
|
127 |
-
/* Set globals */
|
128 |
-
Analytics.Settings = settings || {};
|
129 |
-
|
130 |
-
return Analytics;
|
131 |
-
|
132 |
-
})(_inboundOptions);
|
133 |
-
/**
|
134 |
-
* # Hooks & Filters
|
135 |
-
*
|
136 |
-
* This file contains all of the form functions of the main _inbound object.
|
137 |
-
* Filters and actions are described below
|
138 |
-
*
|
139 |
-
* Forked from https://github.com/carldanley/WP-JS-Hooks/blob/master/src/event-manager.js
|
140 |
-
*
|
141 |
-
* @
|
142 |
-
* @
|
143 |
-
* @version 0.0.2
|
144 |
-
*/
|
145 |
-
|
146 |
-
var _inboundHooks = (function (_inbound) {
|
147 |
-
|
148 |
-
/**
|
149 |
-
* # EventManager
|
150 |
-
*
|
151 |
-
* Actions and filters List
|
152 |
-
* addAction( 'namespace.identifier', callback, priority )
|
153 |
-
* addFilter( 'namespace.identifier', callback, priority )
|
154 |
-
* removeAction( 'namespace.identifier' )
|
155 |
-
* removeFilter( 'namespace.identifier' )
|
156 |
-
* doAction( 'namespace.identifier', arg1, arg2, moreArgs, finalArg )
|
157 |
-
* applyFilters( 'namespace.identifier', content )
|
158 |
-
* @return {[type]} [description]
|
159 |
-
*/
|
160 |
-
|
161 |
-
/**
|
162 |
-
* Handles managing all events for whatever you plug it into. Priorities for hooks are based on lowest to highest in
|
163 |
-
* that, lowest priority hooks are fired first.
|
164 |
-
*/
|
165 |
-
var EventManager = function() {
|
166 |
-
/**
|
167 |
-
* Maintain a reference to the object scope so our public methods never get confusing.
|
168 |
-
*/
|
169 |
-
var MethodsAvailable = {
|
170 |
-
removeFilter : removeFilter,
|
171 |
-
applyFilters : applyFilters,
|
172 |
-
addFilter : addFilter,
|
173 |
-
removeAction : removeAction,
|
174 |
-
doAction : doAction,
|
175 |
-
addAction : addAction
|
176 |
-
};
|
177 |
-
|
178 |
-
/**
|
179 |
-
* Contains the hooks that get registered with this EventManager. The array for storage utilizes a "flat"
|
180 |
-
* object literal such that looking up the hook utilizes the native object literal hash.
|
181 |
-
*/
|
182 |
-
var STORAGE = {
|
183 |
-
actions : {},
|
184 |
-
filters : {}
|
185 |
-
};
|
186 |
-
|
187 |
-
/**
|
188 |
-
* Adds an action to the event manager.
|
189 |
-
*
|
190 |
-
* @param action Must contain namespace.identifier
|
191 |
-
* @param callback Must be a valid callback function before this action is added
|
192 |
-
* @param [priority=10] Used to control when the function is executed in relation to other callbacks bound to the same hook
|
193 |
-
* @param [context] Supply a value to be used for this
|
194 |
-
*/
|
195 |
-
function addAction( action, callback, priority, context ) {
|
196 |
-
if( typeof action === 'string' && typeof callback === 'function' ) {
|
197 |
-
priority = parseInt( ( priority || 10 ), 10 );
|
198 |
-
_addHook( 'actions', action, callback, priority, context );
|
199 |
-
}
|
200 |
-
|
201 |
-
return MethodsAvailable;
|
202 |
-
}
|
203 |
-
|
204 |
-
/**
|
205 |
-
* Performs an action if it exists. You can pass as many arguments as you want to this function; the only rule is
|
206 |
-
* that the first argument must always be the action.
|
207 |
-
*/
|
208 |
-
function doAction( /* action, arg1, arg2, ... */ ) {
|
209 |
-
var args = Array.prototype.slice.call( arguments );
|
210 |
-
var action = args.shift();
|
211 |
-
|
212 |
-
if( typeof action === 'string' ) {
|
213 |
-
_runHook( 'actions', action, args );
|
214 |
-
}
|
215 |
-
|
216 |
-
return MethodsAvailable;
|
217 |
-
}
|
218 |
-
|
219 |
-
/**
|
220 |
-
* Removes the specified action if it contains a namespace.identifier & exists.
|
221 |
-
*
|
222 |
-
* @param action The action to remove
|
223 |
-
* @param [callback] Callback function to remove
|
224 |
-
*/
|
225 |
-
function removeAction( action, callback ) {
|
226 |
-
if( typeof action === 'string' ) {
|
227 |
-
_removeHook( 'actions', action, callback );
|
228 |
-
}
|
229 |
-
|
230 |
-
return MethodsAvailable;
|
231 |
-
}
|
232 |
-
|
233 |
-
/**
|
234 |
-
* Adds a filter to the event manager.
|
235 |
-
*
|
236 |
-
* @param filter Must contain namespace.identifier
|
237 |
-
* @param callback Must be a valid callback function before this action is added
|
238 |
-
* @param [priority=10] Used to control when the function is executed in relation to other callbacks bound to the same hook
|
239 |
-
* @param [context] Supply a value to be used for this
|
240 |
-
*/
|
241 |
-
function addFilter( filter, callback, priority, context ) {
|
242 |
-
if( typeof filter === 'string' && typeof callback === 'function' ) {
|
243 |
-
//console.log('add filter', filter);
|
244 |
-
priority = parseInt( ( priority || 10 ), 10 );
|
245 |
-
_addHook( 'filters', filter, callback, priority );
|
246 |
-
}
|
247 |
-
|
248 |
-
return MethodsAvailable;
|
249 |
-
}
|
250 |
-
|
251 |
-
/**
|
252 |
-
* Performs a filter if it exists. You should only ever pass 1 argument to be filtered. The only rule is that
|
253 |
-
* the first argument must always be the filter.
|
254 |
-
*/
|
255 |
-
function applyFilters( /* filter, filtered arg, arg2, ... */ ) {
|
256 |
-
var args = Array.prototype.slice.call( arguments );
|
257 |
-
var filter = args.shift();
|
258 |
-
|
259 |
-
if( typeof filter === 'string' ) {
|
260 |
-
return _runHook( 'filters', filter, args );
|
261 |
-
}
|
262 |
-
|
263 |
-
return MethodsAvailable;
|
264 |
-
}
|
265 |
-
|
266 |
-
/**
|
267 |
-
* Removes the specified filter if it contains a namespace.identifier & exists.
|
268 |
-
*
|
269 |
-
* @param filter The action to remove
|
270 |
-
* @param [callback] Callback function to remove
|
271 |
-
*/
|
272 |
-
function removeFilter( filter, callback ) {
|
273 |
-
if( typeof filter === 'string') {
|
274 |
-
_removeHook( 'filters', filter, callback );
|
275 |
-
}
|
276 |
-
|
277 |
-
return MethodsAvailable;
|
278 |
-
}
|
279 |
-
|
280 |
-
/**
|
281 |
-
* Removes the specified hook by resetting the value of it.
|
282 |
-
*
|
283 |
-
* @param type Type of hook, either 'actions' or 'filters'
|
284 |
-
* @param hook The hook (namespace.identifier) to remove
|
285 |
-
* @private
|
286 |
-
*/
|
287 |
-
function _removeHook( type, hook, callback, context ) {
|
288 |
-
if ( !STORAGE[ type ][ hook ] ) {
|
289 |
-
return;
|
290 |
-
}
|
291 |
-
if ( !callback ) {
|
292 |
-
STORAGE[ type ][ hook ] = [];
|
293 |
-
} else {
|
294 |
-
var handlers = STORAGE[ type ][ hook ];
|
295 |
-
var i;
|
296 |
-
if ( !context ) {
|
297 |
-
for ( i = handlers.length; i--; ) {
|
298 |
-
if ( handlers[i].callback === callback ) {
|
299 |
-
handlers.splice( i, 1 );
|
300 |
-
}
|
301 |
-
}
|
302 |
-
}
|
303 |
-
else {
|
304 |
-
for ( i = handlers.length; i--; ) {
|
305 |
-
var handler = handlers[i];
|
306 |
-
if ( handler.callback === callback && handler.context === context) {
|
307 |
-
handlers.splice( i, 1 );
|
308 |
-
}
|
309 |
-
}
|
310 |
-
}
|
311 |
-
}
|
312 |
-
}
|
313 |
-
|
314 |
-
/**
|
315 |
-
* Adds the hook to the appropriate storage container
|
316 |
-
*
|
317 |
-
* @param type 'actions' or 'filters'
|
318 |
-
* @param hook The hook (namespace.identifier) to add to our event manager
|
319 |
-
* @param callback The function that will be called when the hook is executed.
|
320 |
-
* @param priority The priority of this hook. Must be an integer.
|
321 |
-
* @param [context] A value to be used for this
|
322 |
-
* @private
|
323 |
-
*/
|
324 |
-
function _addHook( type, hook, callback, priority, context ) {
|
325 |
-
var hookObject = {
|
326 |
-
callback : callback,
|
327 |
-
priority : priority,
|
328 |
-
context : context
|
329 |
-
};
|
330 |
-
|
331 |
-
// Utilize 'prop itself' : http://jsperf.com/hasownproperty-vs-in-vs-undefined/19
|
332 |
-
var hooks = STORAGE[ type ][ hook ];
|
333 |
-
if( hooks ) {
|
334 |
-
hooks.push( hookObject );
|
335 |
-
hooks = _hookInsertSort( hooks );
|
336 |
-
}
|
337 |
-
else {
|
338 |
-
hooks = [ hookObject ];
|
339 |
-
}
|
340 |
-
|
341 |
-
STORAGE[ type ][ hook ] = hooks;
|
342 |
-
}
|
343 |
-
|
344 |
-
/**
|
345 |
-
* Use an insert sort for keeping our hooks organized based on priority. This function is ridiculously faster
|
346 |
-
* than bubble sort, etc: http://jsperf.com/javascript-sort
|
347 |
-
*
|
348 |
-
* @param hooks The custom array containing all of the appropriate hooks to perform an insert sort on.
|
349 |
-
* @private
|
350 |
-
*/
|
351 |
-
function _hookInsertSort( hooks ) {
|
352 |
-
var tmpHook, j, prevHook;
|
353 |
-
for( var i = 1, len = hooks.length; i < len; i++ ) {
|
354 |
-
tmpHook = hooks[ i ];
|
355 |
-
j = i;
|
356 |
-
while( ( prevHook = hooks[ j - 1 ] ) && prevHook.priority > tmpHook.priority ) {
|
357 |
-
hooks[ j ] = hooks[ j - 1 ];
|
358 |
-
--j;
|
359 |
-
}
|
360 |
-
hooks[ j ] = tmpHook;
|
361 |
-
}
|
362 |
-
|
363 |
-
return hooks;
|
364 |
-
}
|
365 |
-
|
366 |
-
/**
|
367 |
-
* Runs the specified hook. If it is an action, the value is not modified but if it is a filter, it is.
|
368 |
-
*
|
369 |
-
* @param type 'actions' or 'filters'
|
370 |
-
* @param hook The hook ( namespace.identifier ) to be ran.
|
371 |
-
* @param args Arguments to pass to the action/filter. If it's a filter, args is actually a single parameter.
|
372 |
-
* @private
|
373 |
-
*/
|
374 |
-
function _runHook( type, hook, args ) {
|
375 |
-
var handlers = STORAGE[ type ][ hook ];
|
376 |
-
|
377 |
-
if ( !handlers ) {
|
378 |
-
return (type === 'filters') ? args[0] : false;
|
379 |
-
}
|
380 |
-
|
381 |
-
var i = 0, len = handlers.length;
|
382 |
-
if ( type === 'filters' ) {
|
383 |
-
for ( ; i < len; i++ ) {
|
384 |
-
args[ 0 ] = handlers[ i ].callback.apply( handlers[ i ].context, args );
|
385 |
-
}
|
386 |
-
} else {
|
387 |
-
for ( ; i < len; i++ ) {
|
388 |
-
handlers[ i ].callback.apply( handlers[ i ].context, args );
|
389 |
-
}
|
390 |
-
}
|
391 |
-
|
392 |
-
return ( type === 'filters' ) ? args[ 0 ] : true;
|
393 |
-
}
|
394 |
-
|
395 |
-
// return all of the publicly available methods
|
396 |
-
return MethodsAvailable;
|
397 |
-
|
398 |
-
};
|
399 |
-
|
400 |
-
_inbound.hooks = new EventManager();
|
401 |
-
|
402 |
-
|
403 |
-
/**
|
404 |
-
* Event Hooks and Filters public methods
|
405 |
-
*/
|
406 |
-
/*
|
407 |
-
* add_action
|
408 |
-
*
|
409 |
-
* This function uses _inbound.hooks to mimics WP add_action
|
410 |
-
*
|
411 |
-
* ```js
|
412 |
-
* function Inbound_Add_Action_Example(data) {
|
413 |
-
* // Do stuff here.
|
414 |
-
* };
|
415 |
-
* // Add action to the hook
|
416 |
-
* _inbound.add_action( 'name_of_action', Inbound_Add_Action_Example, 10 );
|
417 |
-
* ```
|
418 |
-
*/
|
419 |
-
_inbound.add_action = function() {
|
420 |
-
// allow multiple action parameters such as 'ready append'
|
421 |
-
var actions = arguments[0].split(' ');
|
422 |
-
|
423 |
-
for( k in actions ) {
|
424 |
-
|
425 |
-
// prefix action
|
426 |
-
arguments[0] = 'inbound.' + actions[ k ];
|
427 |
-
|
428 |
-
_inbound.hooks.addAction.apply(this, arguments);
|
429 |
-
}
|
430 |
-
|
431 |
-
return this;
|
432 |
-
|
433 |
-
};
|
434 |
-
/*
|
435 |
-
* remove_action
|
436 |
-
*
|
437 |
-
* This function uses _inbound.hooks to mimics WP remove_action
|
438 |
-
*
|
439 |
-
* ```js
|
440 |
-
* // Add remove action 'name_of_action'
|
441 |
-
* _inbound.remove_action( 'name_of_action');
|
442 |
-
* ```
|
443 |
-
*
|
444 |
-
*/
|
445 |
-
_inbound.remove_action = function() {
|
446 |
-
// prefix action
|
447 |
-
arguments[0] = 'inbound.' + arguments[0];
|
448 |
-
_inbound.hooks.removeAction.apply(this, arguments);
|
449 |
-
|
450 |
-
return this;
|
451 |
-
|
452 |
-
};
|
453 |
-
/*
|
454 |
-
* do_action
|
455 |
-
*
|
456 |
-
* This function uses _inbound.hooks to mimics WP do_action
|
457 |
-
* This is used if you want to allow for third party JS plugins to act on your functions
|
458 |
-
*
|
459 |
-
*/
|
460 |
-
_inbound.do_action = function() {
|
461 |
-
// prefix action
|
462 |
-
arguments[0] = 'inbound.' + arguments[0];
|
463 |
-
_inbound.hooks.doAction.apply(this, arguments);
|
464 |
-
|
465 |
-
return this;
|
466 |
-
|
467 |
-
};
|
468 |
-
/*
|
469 |
-
* add_filter
|
470 |
-
*
|
471 |
-
* This function uses _inbound.hooks to mimics WP add_filter
|
472 |
-
*
|
473 |
-
* ```js
|
474 |
-
* _inbound.add_filter( 'urlParamFilter', URL_Param_Filter, 10 );
|
475 |
-
* function URL_Param_Filter(urlParams) {
|
476 |
-
*
|
477 |
-
* var params = urlParams || {};
|
478 |
-
* // check for item in object
|
479 |
-
* if(params.utm_source !== "undefined"){
|
480 |
-
* //alert('url param "utm_source" is here');
|
481 |
-
* }
|
482 |
-
*
|
483 |
-
* // delete item from object
|
484 |
-
* delete params.utm_source;
|
485 |
-
*
|
486 |
-
* return params;
|
487 |
-
*
|
488 |
-
* }
|
489 |
-
* ```
|
490 |
-
*/
|
491 |
-
_inbound.add_filter = function() {
|
492 |
-
// prefix action
|
493 |
-
arguments[0] = 'inbound.' + arguments[0];
|
494 |
-
_inbound.hooks.addFilter.apply(this, arguments);
|
495 |
-
|
496 |
-
return this;
|
497 |
-
|
498 |
-
};
|
499 |
-
/*
|
500 |
-
* remove_filter
|
501 |
-
*
|
502 |
-
* This function uses _inbound.hooks to mimics WP remove_filter
|
503 |
-
*
|
504 |
-
* ```js
|
505 |
-
* // Add remove filter 'urlParamFilter'
|
506 |
-
* _inbound.remove_action( 'urlParamFilter');
|
507 |
-
* ```
|
508 |
-
*
|
509 |
-
*/
|
510 |
-
_inbound.remove_filter = function() {
|
511 |
-
// prefix action
|
512 |
-
arguments[0] = 'inbound.' + arguments[0];
|
513 |
-
|
514 |
-
_inbound.hooks.removeFilter.apply(this, arguments);
|
515 |
-
|
516 |
-
return this;
|
517 |
-
|
518 |
-
};
|
519 |
-
/*
|
520 |
-
* apply_filters
|
521 |
-
*
|
522 |
-
* This function uses _inbound.hooks to mimics WP apply_filters
|
523 |
-
*
|
524 |
-
*/
|
525 |
-
_inbound.apply_filters = function() {
|
526 |
-
//console.log('Filter:' + arguments[0] + " ran on ->", arguments[1]);
|
527 |
-
// prefix action
|
528 |
-
arguments[0] = 'inbound.' + arguments[0];
|
529 |
-
|
530 |
-
return _inbound.hooks.applyFilters.apply(this, arguments);
|
531 |
-
|
532 |
-
};
|
533 |
-
|
534 |
-
|
535 |
-
return _inbound;
|
536 |
-
|
537 |
-
})(_inbound || {});
|
538 |
-
/**
|
539 |
-
* # _inbound UTILS
|
540 |
-
*
|
541 |
-
* This file contains all of the utility functions used by analytics
|
542 |
-
*
|
543 |
-
* @
|
544 |
-
* @
|
545 |
-
* @version 0.0.2
|
546 |
-
*/
|
547 |
-
|
548 |
-
var _inboundUtils = (function(_inbound) {
|
549 |
-
|
550 |
-
var storageSupported,
|
551 |
-
corsEnabled = window.XMLHttpRequest && 'withCredentials' in new XMLHttpRequest(),
|
552 |
-
toString = Object.prototype.toString,
|
553 |
-
currentPage = ('https:' == location.protocol ? 'https://' : 'http://') + location.hostname + location.pathname.replace(/\/$/, "");
|
554 |
-
|
555 |
-
var settings = {
|
556 |
-
api_host: currentPage,
|
557 |
-
track_pageview: true,
|
558 |
-
track_links_timeout: 300,
|
559 |
-
cookie_name: '_sp',
|
560 |
-
cookie_expiration: 365,
|
561 |
-
cookie_domain: (host = location.hostname.match(/[a-z0-9][a-z0-9\-]+\.[a-z\.]{2,6}$/i)) ? host[0] : ''
|
562 |
-
};
|
563 |
-
|
564 |
-
_inbound.Utils = {
|
565 |
-
init: function() {
|
566 |
-
|
567 |
-
this.polyFills();
|
568 |
-
this.checkLocalStorage();
|
569 |
-
this.SetUID();
|
570 |
-
this.storeReferralData();
|
571 |
-
|
572 |
-
},
|
573 |
-
/*! http://stackoverflow.com/questions/951791/javascript-global-error-handling */
|
574 |
-
/* Polyfills for missing browser functionality */
|
575 |
-
polyFills: function() {
|
576 |
-
/* Console.log fix for old browsers */
|
577 |
-
if (!window.console) {
|
578 |
-
window.console = {};
|
579 |
-
}
|
580 |
-
var m = [
|
581 |
-
"log", "info", "warn", "error", "debug", "trace", "dir", "group",
|
582 |
-
"groupCollapsed", "groupEnd", "time", "timeEnd", "profile", "profileEnd",
|
583 |
-
"dirxml", "assert", "count", "markTimeline", "timeStamp", "clear"
|
584 |
-
];
|
585 |
-
// define undefined methods as noops to prevent errors
|
586 |
-
for (var i = 0; i < m.length; i++) {
|
587 |
-
if (!window.console[m[i]]) {
|
588 |
-
window.console[m[i]] = function() {};
|
589 |
-
}
|
590 |
-
}
|
591 |
-
/* Event trigger polyfill for IE9 and 10
|
592 |
-
(function() {
|
593 |
-
function CustomEvent(event, params) {
|
594 |
-
params = params || {
|
595 |
-
bubbles: false,
|
596 |
-
cancelable: false,
|
597 |
-
detail: undefined
|
598 |
-
};
|
599 |
-
var evt = document.createEvent('CustomEvent');
|
600 |
-
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
|
601 |
-
return evt;
|
602 |
-
}
|
603 |
-
|
604 |
-
CustomEvent.prototype = window.Event.prototype;
|
605 |
-
|
606 |
-
window.CustomEvent = CustomEvent;
|
607 |
-
})();*/
|
608 |
-
|
609 |
-
/*\
|
610 |
-
|*| Polyfill Date.toISOString
|
611 |
-
\*/
|
612 |
-
if (!Date.prototype.toISOString) {
|
613 |
-
(function() {
|
614 |
-
/**
|
615 |
-
* @param {number} text
|
616 |
-
* @returns {?}
|
617 |
-
*/
|
618 |
-
function pad(text) {
|
619 |
-
/** @type {string} */
|
620 |
-
var code = String(text);
|
621 |
-
return 1 === code.length && (code = '0' + code), code;
|
622 |
-
}
|
623 |
-
/**
|
624 |
-
* @returns {string}
|
625 |
-
*/
|
626 |
-
Date.prototype.toISOString = function() {
|
627 |
-
return this.getUTCFullYear() + '-' + pad(this.getUTCMonth() + 1) + '-' + pad(this.getUTCDate()) + 'T' + pad(this.getUTCHours()) + ':' + pad(this.getUTCMinutes()) + ':' + pad(this.getUTCSeconds()) + '.' + String((this.getUTCMilliseconds() / 1E3).toFixed(3)).slice(2, 5) + 'Z';
|
628 |
-
};
|
629 |
-
})();
|
630 |
-
}
|
631 |
-
|
632 |
-
/* custom event for ie8+ https://gist.github.com/WebReflection/6693661 */
|
633 |
-
try {
|
634 |
-
new CustomEvent('?');
|
635 |
-
} catch (o_O) {
|
636 |
-
/*!(C) Andrea Giammarchi -- WTFPL License*/
|
637 |
-
this.CustomEvent = function(
|
638 |
-
eventName,
|
639 |
-
defaultInitDict
|
640 |
-
) {
|
641 |
-
|
642 |
-
// the infamous substitute
|
643 |
-
function CustomEvent(type, eventInitDict) {
|
644 |
-
var event = document.createEvent(eventName);
|
645 |
-
if (type !== null) {
|
646 |
-
initCustomEvent.call(
|
647 |
-
event,
|
648 |
-
type, (eventInitDict || (
|
649 |
-
// if falsy we can just use defaults
|
650 |
-
eventInitDict = defaultInitDict
|
651 |
-
)).bubbles,
|
652 |
-
eventInitDict.cancelable,
|
653 |
-
eventInitDict.detail
|
654 |
-
);
|
655 |
-
} else {
|
656 |
-
// no need to put the expando property otherwise
|
657 |
-
// since an event cannot be initialized twice
|
658 |
-
// previous case is the most common one anyway
|
659 |
-
// but if we end up here ... there it goes
|
660 |
-
event.initCustomEvent = initCustomEvent;
|
661 |
-
}
|
662 |
-
return event;
|
663 |
-
}
|
664 |
-
|
665 |
-
// borrowed or attached at runtime
|
666 |
-
function initCustomEvent(
|
667 |
-
type, bubbles, cancelable, detail
|
668 |
-
) {
|
669 |
-
this['init' + eventName](type, bubbles, cancelable, detail);
|
670 |
-
'detail' in this || (this.detail = detail);
|
671 |
-
}
|
672 |
-
|
673 |
-
// that's it
|
674 |
-
return CustomEvent;
|
675 |
-
}(
|
676 |
-
// is this IE9 or IE10 ?
|
677 |
-
// where CustomEvent is there
|
678 |
-
// but not usable as construtor ?
|
679 |
-
this.CustomEvent ?
|
680 |
-
// use the CustomEvent interface in such case
|
681 |
-
'CustomEvent' : 'Event',
|
682 |
-
// otherwise the common compatible one
|
683 |
-
{
|
684 |
-
bubbles: false,
|
685 |
-
cancelable: false,
|
686 |
-
detail: null
|
687 |
-
}
|
688 |
-
);
|
689 |
-
}
|
690 |
-
/* querySelectorAll polyfill for ie7+ */
|
691 |
-
if (!document.querySelectorAll) {
|
692 |
-
document.querySelectorAll = function(selectors) {
|
693 |
-
var style = document.createElement('style'),
|
694 |
-
elements = [],
|
695 |
-
element;
|
696 |
-
document.documentElement.firstChild.appendChild(style);
|
697 |
-
document._qsa = [];
|
698 |
-
|
699 |
-
style.styleSheet.cssText = selectors + '{x-qsa:expression(document._qsa && document._qsa.push(this))}';
|
700 |
-
window.scrollBy(0, 0);
|
701 |
-
style.parentNode.removeChild(style);
|
702 |
-
|
703 |
-
while (document._qsa.length) {
|
704 |
-
element = document._qsa.shift();
|
705 |
-
element.style.removeAttribute('x-qsa');
|
706 |
-
elements.push(element);
|
707 |
-
}
|
708 |
-
document._qsa = null;
|
709 |
-
return elements;
|
710 |
-
};
|
711 |
-
}
|
712 |
-
|
713 |
-
if (!document.querySelector) {
|
714 |
-
document.querySelector = function(selectors) {
|
715 |
-
var elements = document.querySelectorAll(selectors);
|
716 |
-
return (elements.length) ? elements[0] : null;
|
717 |
-
};
|
718 |
-
}
|
719 |
-
/* Innertext shim for firefox https://github.com/duckinator/innerText-polyfill/blob/master/innertext.js */
|
720 |
-
if ((!('innerText' in document.createElement('a'))) && ('getSelection' in window)) {
|
721 |
-
HTMLElement.prototype.__defineGetter__("innerText", function() {
|
722 |
-
var selection = window.getSelection(),
|
723 |
-
ranges = [],
|
724 |
-
str;
|
725 |
-
|
726 |
-
// Save existing selections.
|
727 |
-
for (var i = 0; i < selection.rangeCount; i++) {
|
728 |
-
ranges[i] = selection.getRangeAt(i);
|
729 |
-
}
|
730 |
-
|
731 |
-
// Deselect everything.
|
732 |
-
selection.removeAllRanges();
|
733 |
-
|
734 |
-
// Select `el` and all child nodes.
|
735 |
-
// 'this' is the element .innerText got called on
|
736 |
-
selection.selectAllChildren(this);
|
737 |
-
|
738 |
-
// Get the string representation of the selected nodes.
|
739 |
-
str = selection.toString();
|
740 |
-
|
741 |
-
// Deselect everything. Again.
|
742 |
-
selection.removeAllRanges();
|
743 |
-
|
744 |
-
// Restore all formerly existing selections.
|
745 |
-
for (var i = 0; i < ranges.length; i++) {
|
746 |
-
selection.addRange(ranges[i]);
|
747 |
-
}
|
748 |
-
|
749 |
-
// Oh look, this is what we wanted.
|
750 |
-
// String representation of the element, close to as rendered.
|
751 |
-
return str;
|
752 |
-
})
|
753 |
-
}
|
754 |
-
},
|
755 |
-
/**
|
756 |
-
* Create cookie
|
757 |
-
*
|
758 |
-
* ```js
|
759 |
-
* // Creates cookie for 10 days
|
760 |
-
* _inbound.Utils.createCookie( 'cookie_name', 'value', 10 );
|
761 |
-
* ```
|
762 |
-
*
|
763 |
-
* @param {string} name Name of cookie
|
764 |
-
* @param {string} value Value of cookie
|
765 |
-
* @param {string} days Length of storage
|
766 |
-
*/
|
767 |
-
createCookie: function(name, value, days) {
|
768 |
-
var expires = "";
|
769 |
-
if (days) {
|
770 |
-
var date = new Date();
|
771 |
-
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
772 |
-
expires = "; expires=" + date.toGMTString();
|
773 |
-
}
|
774 |
-
document.cookie = name + "=" + value + expires + "; path=/";
|
775 |
-
},
|
776 |
-
/**
|
777 |
-
* Read cookie value
|
778 |
-
*
|
779 |
-
* ```js
|
780 |
-
* var cookie = _inbound.Utils.readCookie( 'cookie_name' );
|
781 |
-
* console.log(cookie); // cookie value
|
782 |
-
* ```
|
783 |
-
* @param {string} name name of cookie
|
784 |
-
* @return {string} value of cookie
|
785 |
-
*/
|
786 |
-
readCookie: function(name) {
|
787 |
-
var nameEQ = name + "=";
|
788 |
-
var ca = document.cookie.split(';');
|
789 |
-
for (var i = 0; i < ca.length; i++) {
|
790 |
-
var c = ca[i];
|
791 |
-
while (c.charAt(0) === ' ') {
|
792 |
-
c = c.substring(1, c.length);
|
793 |
-
}
|
794 |
-
if (c.indexOf(nameEQ) === 0) {
|
795 |
-
return c.substring(nameEQ.length, c.length);
|
796 |
-
}
|
797 |
-
}
|
798 |
-
return null;
|
799 |
-
},
|
800 |
-
/**
|
801 |
-
* Erase cookie
|
802 |
-
*
|
803 |
-
* ```js
|
804 |
-
* // usage:
|
805 |
-
* _inbound.Utils.eraseCookie( 'cookie_name' );
|
806 |
-
* // deletes 'cookie_name' value
|
807 |
-
* ```
|
808 |
-
* @param {string} name name of cookie
|
809 |
-
* @return {string} value of cookie
|
810 |
-
*/
|
811 |
-
eraseCookie: function(name) {
|
812 |
-
this.createCookie(name, "", -1);
|
813 |
-
},
|
814 |
-
/* Get All Cookies */
|
815 |
-
getAllCookies: function() {
|
816 |
-
var cookies = {};
|
817 |
-
if (document.cookie && document.cookie !== '') {
|
818 |
-
var split = document.cookie.split(';');
|
819 |
-
for (var i = 0; i < split.length; i++) {
|
820 |
-
var name_value = split[i].split("=");
|
821 |
-
name_value[0] = name_value[0].replace(/^ /, '');
|
822 |
-
cookies[decodeURIComponent(name_value[0])] = decodeURIComponent(name_value[1]);
|
823 |
-
}
|
824 |
-
}
|
825 |
-
_inbound.totalStorage('inbound_cookies', cookies); // store cookie data
|
826 |
-
return cookies;
|
827 |
-
},
|
828 |
-
/* Grab URL params and save */
|
829 |
-
setUrlParams: function() {
|
830 |
-
var urlParams = {};
|
831 |
-
|
832 |
-
(function() {
|
833 |
-
var e,
|
834 |
-
d = function(s) {
|
835 |
-
return decodeURIComponent(s).replace(/\+/g, " ");
|
836 |
-
},
|
837 |
-
q = window.location.search.substring(1),
|
838 |
-
r = /([^&=]+)=?([^&]*)/g;
|
839 |
-
|
840 |
-
while (e = r.exec(q)) {
|
841 |
-
if (e[1].indexOf("[") == "-1")
|
842 |
-
urlParams[d(e[1])] = d(e[2]);
|
843 |
-
else {
|
844 |
-
var b1 = e[1].indexOf("["),
|
845 |
-
aN = e[1].slice(b1 + 1, e[1].indexOf("]", b1)),
|
846 |
-
pN = d(e[1].slice(0, b1));
|
847 |
-
|
848 |
-
if (typeof urlParams[pN] != "object")
|
849 |
-
urlParams[d(pN)] = {},
|
850 |
-
urlParams[d(pN)].length = 0;
|
851 |
-
|
852 |
-
if (aN)
|
853 |
-
urlParams[d(pN)][d(aN)] = d(e[2]);
|
854 |
-
else
|
855 |
-
Array.prototype.push.call(urlParams[d(pN)], d(e[2]));
|
856 |
-
|
857 |
-
}
|
858 |
-
}
|
859 |
-
})();
|
860 |
-
|
861 |
-
/* Set Param Cookies */
|
862 |
-
for (var k in urlParams) {
|
863 |
-
/* account for wordpress media uploader bug */
|
864 |
-
if (k == 'action') {
|
865 |
-
continue;
|
866 |
-
}
|
867 |
-
|
868 |
-
if (typeof urlParams[k] == "object") {
|
869 |
-
for (var k2 in urlParams[k])
|
870 |
-
this.createCookie(k2, urlParams[k][k2], 30);
|
871 |
-
} else {
|
872 |
-
this.createCookie(k, urlParams[k], 30);
|
873 |
-
}
|
874 |
-
}
|
875 |
-
/* Set Param LocalStorage */
|
876 |
-
if (storageSupported) {
|
877 |
-
var pastParams = _inbound.totalStorage('inbound_url_params') || {};
|
878 |
-
var params = this.mergeObjs(pastParams, urlParams);
|
879 |
-
_inbound.totalStorage('inbound_url_params', params); // store cookie data
|
880 |
-
}
|
881 |
-
|
882 |
-
var options = {
|
883 |
-
'option1': 'yo',
|
884 |
-
'option2': 'woooo'
|
885 |
-
};
|
886 |
-
|
887 |
-
_inbound.trigger('url_parameters', urlParams, options);
|
888 |
-
|
889 |
-
},
|
890 |
-
getAllUrlParams: function() {
|
891 |
-
var get_params = {};
|
892 |
-
if (storageSupported) {
|
893 |
-
var get_params = _inbound.totalStorage('inbound_url_params');
|
894 |
-
}
|
895 |
-
return get_params;
|
896 |
-
},
|
897 |
-
/* Get url param */
|
898 |
-
getParameterVal: function(name, string) {
|
899 |
-
return (RegExp(name + '=' + '(.+?)(&|$)').exec(string) || [, false])[1];
|
900 |
-
},
|
901 |
-
// Check local storage
|
902 |
-
// provate browsing safari fix https://github.com/marcuswestin/store.js/issues/42#issuecomment-25274685
|
903 |
-
checkLocalStorage: function() {
|
904 |
-
if ('localStorage' in window) {
|
905 |
-
try {
|
906 |
-
ls = (typeof window.localStorage === 'undefined') ? undefined : window.localStorage;
|
907 |
-
if (typeof ls == 'undefined' || typeof window.JSON == 'undefined') {
|
908 |
-
storageSupported = false;
|
909 |
-
} else {
|
910 |
-
storageSupported = true;
|
911 |
-
}
|
912 |
-
|
913 |
-
} catch (err) {
|
914 |
-
storageSupported = false;
|
915 |
-
}
|
916 |
-
}
|
917 |
-
return storageSupported;
|
918 |
-
/* http://spin.atomicobject.com/2013/01/23/ios-private-browsing-localstorage/
|
919 |
-
var hasStorage;
|
920 |
-
hasStorage = function() {
|
921 |
-
var mod, result;
|
922 |
-
try {
|
923 |
-
mod = new Date;
|
924 |
-
localStorage.setItem(mod, mod.toString());
|
925 |
-
result = localStorage.getItem(mod) === mod.toString();
|
926 |
-
localStorage.removeItem(mod);
|
927 |
-
return result;
|
928 |
-
} catch (_error) {}
|
929 |
-
};
|
930 |
-
*/
|
931 |
-
},
|
932 |
-
// http://stackoverflow.com/questions/4391575/how-to-find-the-size-of-localstorage
|
933 |
-
showLocalStorageSize: function() {
|
934 |
-
function stringSizeBytes(str) {
|
935 |
-
return str.length * 2;
|
936 |
-
}
|
937 |
-
|
938 |
-
function toMB(bytes) {
|
939 |
-
return bytes / 1024 / 1024;
|
940 |
-
}
|
941 |
-
|
942 |
-
function toSize(key) {
|
943 |
-
return {
|
944 |
-
name: key,
|
945 |
-
size: stringSizeBytes(localStorage[key])
|
946 |
-
};
|
947 |
-
}
|
948 |
-
|
949 |
-
function toSizeMB(info) {
|
950 |
-
info.size = toMB(info.size).toFixed(2) + ' MB';
|
951 |
-
return info;
|
952 |
-
}
|
953 |
-
|
954 |
-
var sizes = Object.keys(localStorage).map(toSize).map(toSizeMB);
|
955 |
-
|
956 |
-
console.table(sizes);
|
957 |
-
},
|
958 |
-
/* Add days to datetime */
|
959 |
-
addDays: function(myDate, days) {
|
960 |
-
return new Date(myDate.getTime() + days * 24 * 60 * 60 * 1000);
|
961 |
-
},
|
962 |
-
GetDate: function() {
|
963 |
-
var timeNow = new Date(),
|
964 |
-
d = timeNow.getDate(),
|
965 |
-
dPre = (d < 10) ? "0" : "",
|
966 |
-
y = timeNow.getFullYear(),
|
967 |
-
h = timeNow.getHours(),
|
968 |
-
hPre = (h < 10) ? "0" : "",
|
969 |
-
min = timeNow.getMinutes(),
|
970 |
-
minPre = (min < 10) ? "0" : "",
|
971 |
-
sec = timeNow.getSeconds(),
|
972 |
-
secPre = (sec < 10) ? "0" : "",
|
973 |
-
m = timeNow.getMonth() + 1,
|
974 |
-
mPre = (m < 10) ? "0" : "";
|
975 |
-
|
976 |
-
var datetime = y + '/' + mPre + m + "/" + dPre + d + " " + hPre + h + ":" + minPre + min + ":" + secPre + sec;
|
977 |
-
/* format 2014/11/13 18:22:02 */
|
978 |
-
return datetime;
|
979 |
-
},
|
980 |
-
/* Set Expiration Date of Session Logging. LEGACY Not in Use */
|
981 |
-
SetSessionTimeout: function() {
|
982 |
-
var session = this.readCookie("lead_session_expire");
|
983 |
-
//console.log(session_check);
|
984 |
-
if (!session) {
|
985 |
-
//_inbound.trigger('session_start'); // trigger 'inbound_analytics_session_start'
|
986 |
-
} else {
|
987 |
-
//_inbound.trigger('session_resume'); // trigger 'inbound_analytics_session_active'
|
988 |
-
}
|
989 |
-
var d = new Date();
|
990 |
-
d.setTime(d.getTime() + 30 * 60 * 1000);
|
991 |
-
|
992 |
-
this.createCookie("lead_session_expire", true, d); // Set cookie on page load
|
993 |
-
|
994 |
-
},
|
995 |
-
storeReferralData: function() {
|
996 |
-
//console.log(expire_time);
|
997 |
-
var d = new Date(),
|
998 |
-
referrer = document.referrer || "Direct Traffic",
|
999 |
-
referrer_cookie = _inbound.Utils.readCookie("inbound_referral_site"),
|
1000 |
-
original_src = _inbound.totalStorage('inbound_original_referral');
|
1001 |
-
|
1002 |
-
d.setTime(d.getTime() + 30 * 60 * 1000);
|
1003 |
-
|
1004 |
-
if (!referrer_cookie) {
|
1005 |
-
this.createCookie("inbound_referral_site", referrer, d);
|
1006 |
-
}
|
1007 |
-
if (!original_src) {
|
1008 |
-
_inbound.totalStorage('inbound_original_referral', original_src);
|
1009 |
-
}
|
1010 |
-
},
|
1011 |
-
CreateUID: function(length) {
|
1012 |
-
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'.split(''),
|
1013 |
-
str = '';
|
1014 |
-
if (!length) {
|
1015 |
-
length = Math.floor(Math.random() * chars.length);
|
1016 |
-
}
|
1017 |
-
for (var i = 0; i < length; i++) {
|
1018 |
-
str += chars[Math.floor(Math.random() * chars.length)];
|
1019 |
-
}
|
1020 |
-
return str;
|
1021 |
-
},
|
1022 |
-
generateGUID: function(a) {
|
1023 |
-
return a ? (a ^ 16 * Math.random() >> a / 4).toString(16) : ([1E7] + -1E3 + -4E3 + -8E3 + -1E11).replace(/[018]/g, guid);
|
1024 |
-
},
|
1025 |
-
SetUID: function(leadUID) {
|
1026 |
-
/* Set Lead UID */
|
1027 |
-
if (!this.readCookie("wp_lead_uid")) {
|
1028 |
-
var wp_lead_uid = leadUID || this.CreateUID(35);
|
1029 |
-
this.createCookie("wp_lead_uid", wp_lead_uid);
|
1030 |
-
}
|
1031 |
-
},
|
1032 |
-
/* Count number of session visits */
|
1033 |
-
countProperties: function(obj) {
|
1034 |
-
var count = 0;
|
1035 |
-
for (var prop in obj) {
|
1036 |
-
if (obj.hasOwnProperty(prop)) {
|
1037 |
-
++count;
|
1038 |
-
}
|
1039 |
-
}
|
1040 |
-
return count;
|
1041 |
-
},
|
1042 |
-
mergeObjs: function(obj1, obj2) {
|
1043 |
-
var obj3 = {};
|
1044 |
-
for (var attrname in obj1) {
|
1045 |
-
obj3[attrname] = obj1[attrname];
|
1046 |
-
}
|
1047 |
-
for (var attrname in obj2) {
|
1048 |
-
obj3[attrname] = obj2[attrname];
|
1049 |
-
}
|
1050 |
-
return obj3;
|
1051 |
-
},
|
1052 |
-
hasClass: function(className, el) {
|
1053 |
-
var hasClass;
|
1054 |
-
if ('classList' in document.documentElement) {
|
1055 |
-
var hasClass = el.classList.contains(className);
|
1056 |
-
} else {
|
1057 |
-
var hasClass = new RegExp('(^|\\s)' + className + '(\\s|$)').test(el.className); /* IE Polyfill */
|
1058 |
-
}
|
1059 |
-
return hasClass;
|
1060 |
-
},
|
1061 |
-
addClass: function(className, el) {
|
1062 |
-
if ('classList' in document.documentElement) {
|
1063 |
-
el.classList.add(className);
|
1064 |
-
} else {
|
1065 |
-
if (!this.hasClass(el, className)) {
|
1066 |
-
el.className += (el.className ? ' ' : '') + className;
|
1067 |
-
}
|
1068 |
-
}
|
1069 |
-
},
|
1070 |
-
removeClass: function(className, el) {
|
1071 |
-
if ('classList' in document.documentElement) {
|
1072 |
-
el.classList.remove(className);
|
1073 |
-
} else {
|
1074 |
-
if (this.hasClass(el, className)) {
|
1075 |
-
el.className = el.className.replace(new RegExp('(^|\\s)*' + className + '(\\s|$)*', 'g'), '');
|
1076 |
-
}
|
1077 |
-
}
|
1078 |
-
},
|
1079 |
-
removeElement: function(el) {
|
1080 |
-
el.parentNode.removeChild(el);
|
1081 |
-
},
|
1082 |
-
trim: function(s) {
|
1083 |
-
s = s.replace(/(^\s*)|(\s*$)/gi, "");
|
1084 |
-
s = s.replace(/[ ]{2,}/gi, " ");
|
1085 |
-
s = s.replace(/\n /, "\n");
|
1086 |
-
return s;
|
1087 |
-
},
|
1088 |
-
ajaxPolyFill: function() {
|
1089 |
-
if (typeof XMLHttpRequest !== 'undefined') {
|
1090 |
-
return new XMLHttpRequest();
|
1091 |
-
}
|
1092 |
-
var versions = [
|
1093 |
-
"MSXML2.XmlHttp.5.0",
|
1094 |
-
"MSXML2.XmlHttp.4.0",
|
1095 |
-
"MSXML2.XmlHttp.3.0",
|
1096 |
-
"MSXML2.XmlHttp.2.0",
|
1097 |
-
"Microsoft.XmlHttp"
|
1098 |
-
];
|
1099 |
-
|
1100 |
-
var xhr;
|
1101 |
-
for (var i = 0; i < versions.length; i++) {
|
1102 |
-
try {
|
1103 |
-
xhr = new ActiveXObject(versions[i]);
|
1104 |
-
break;
|
1105 |
-
} catch (e) {}
|
1106 |
-
}
|
1107 |
-
return xhr;
|
1108 |
-
},
|
1109 |
-
ajaxSendData: function(url, callback, method, data, sync) {
|
1110 |
-
var x = this.ajaxPolyFill();
|
1111 |
-
/* timeout for safari idiocy */
|
1112 |
-
setTimeout(function() {
|
1113 |
-
x.open(method, url, true);
|
1114 |
-
x.onreadystatechange = function() {
|
1115 |
-
if (x.readyState == 4) {
|
1116 |
-
callback(x.responseText)
|
1117 |
-
}
|
1118 |
-
};
|
1119 |
-
if (method == 'POST') {
|
1120 |
-
x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
1121 |
-
}
|
1122 |
-
x.send(data);
|
1123 |
-
}, 100);
|
1124 |
-
},
|
1125 |
-
ajaxGet: function(url, data, callback, sync) {
|
1126 |
-
var query = [];
|
1127 |
-
for (var key in data) {
|
1128 |
-
query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
|
1129 |
-
}
|
1130 |
-
this.ajaxSendData(url + '?' + query.join('&'), callback, 'GET', null, sync)
|
1131 |
-
},
|
1132 |
-
ajaxPost: function(url, data, callback, sync) {
|
1133 |
-
var query = [];
|
1134 |
-
for (var key in data) {
|
1135 |
-
query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
|
1136 |
-
}
|
1137 |
-
this.ajaxSendData(url, callback, 'POST', query.join('&'), sync)
|
1138 |
-
},
|
1139 |
-
/**
|
1140 |
-
* @param {string} event
|
1141 |
-
* @param {(Object|null)} properties
|
1142 |
-
* @param {(Function|null)} callback
|
1143 |
-
*/
|
1144 |
-
sendEvent: function(event, properties, callback) {
|
1145 |
-
properties = properties || {};
|
1146 |
-
async = true;
|
1147 |
-
var cookieData = getCookie(); /* get cookie data */
|
1148 |
-
if (cookieData) {
|
1149 |
-
var key;
|
1150 |
-
for (key in cookieData) {
|
1151 |
-
properties[key] = cookieData[key];
|
1152 |
-
}
|
1153 |
-
}
|
1154 |
-
if (!properties.id) {
|
1155 |
-
properties.id = getId();
|
1156 |
-
}
|
1157 |
-
var props = {
|
1158 |
-
e: event,
|
1159 |
-
t: (new Date()).toISOString(),
|
1160 |
-
kv: properties
|
1161 |
-
};
|
1162 |
-
var path = settings.api_host + '/track?data=' + encodeURIComponent(JSON.stringify(props));
|
1163 |
-
if (corsEnabled) {
|
1164 |
-
/* CORS */
|
1165 |
-
var xhr = new XMLHttpRequest();
|
1166 |
-
xhr.open('GET', path, async);
|
1167 |
-
xhr.withCredentials = async;
|
1168 |
-
xhr.send(null);
|
1169 |
-
} else {
|
1170 |
-
/* jsonP */
|
1171 |
-
var el = document.createElement('script');
|
1172 |
-
el.type = 'text/javascript';
|
1173 |
-
el.async = async;
|
1174 |
-
el.defer = async;
|
1175 |
-
el.src = path;
|
1176 |
-
var insertAt = document.getElementsByTagName('script')[0];
|
1177 |
-
insertAt.parentNode.insertBefore(el, insertAt);
|
1178 |
-
}
|
1179 |
-
return action(callback), self;
|
1180 |
-
},
|
1181 |
-
domReady: function(win, fn) {
|
1182 |
-
|
1183 |
-
var done = false,
|
1184 |
-
top = true,
|
1185 |
-
|
1186 |
-
doc = win.document,
|
1187 |
-
root = doc.documentElement,
|
1188 |
-
|
1189 |
-
add = doc.addEventListener ? 'addEventListener' : 'attachEvent',
|
1190 |
-
rem = doc.addEventListener ? 'removeEventListener' : 'detachEvent',
|
1191 |
-
pre = doc.addEventListener ? '' : 'on',
|
1192 |
-
|
1193 |
-
init = function(e) {
|
1194 |
-
if (e.type == 'readystatechange' && doc.readyState != 'complete') return;
|
1195 |
-
(e.type == 'load' ? win : doc)[rem](pre + e.type, init, false);
|
1196 |
-
if (!done && (done = true)) fn.call(win, e.type || e);
|
1197 |
-
},
|
1198 |
-
|
1199 |
-
poll = function() {
|
1200 |
-
try {
|
1201 |
-
root.doScroll('left');
|
1202 |
-
} catch (e) {
|
1203 |
-
setTimeout(poll, 50);
|
1204 |
-
return;
|
1205 |
-
}
|
1206 |
-
init('poll');
|
1207 |
-
};
|
1208 |
-
|
1209 |
-
if (doc.readyState == 'complete') {
|
1210 |
-
|
1211 |
-
fn.call(win, 'lazy');
|
1212 |
-
|
1213 |
-
} else {
|
1214 |
-
if (doc.createEventObject && root.doScroll) {
|
1215 |
-
try {
|
1216 |
-
top = !win.frameElement;
|
1217 |
-
} catch (e) {}
|
1218 |
-
if (top) poll();
|
1219 |
-
}
|
1220 |
-
doc[add](pre + 'DOMContentLoaded', init, false);
|
1221 |
-
doc[add](pre + 'readystatechange', init, false);
|
1222 |
-
win[add](pre + 'load', init, false);
|
1223 |
-
}
|
1224 |
-
|
1225 |
-
},
|
1226 |
-
/* Cross-browser event listening */
|
1227 |
-
addListener: function(element, eventName, listener) {
|
1228 |
-
if (!element) {
|
1229 |
-
return;
|
1230 |
-
}
|
1231 |
-
//console.log(eventName);
|
1232 |
-
//console.log(listener);
|
1233 |
-
if (element.addEventListener) {
|
1234 |
-
element.addEventListener(eventName, listener, false);
|
1235 |
-
} else if (element.attachEvent) {
|
1236 |
-
element.attachEvent("on" + eventName, listener);
|
1237 |
-
} else {
|
1238 |
-
element['on' + eventName] = listener;
|
1239 |
-
}
|
1240 |
-
},
|
1241 |
-
removeListener: function(element, eventName, listener) {
|
1242 |
-
|
1243 |
-
if (element.removeEventListener) {
|
1244 |
-
element.removeEventListener(eventName, listener, false);
|
1245 |
-
} else if (element.detachEvent) {
|
1246 |
-
element.detachEvent("on" + eventName, listener);
|
1247 |
-
} else {
|
1248 |
-
element["on" + eventName] = null;
|
1249 |
-
}
|
1250 |
-
},
|
1251 |
-
/*
|
1252 |
-
* Throttle function borrowed from:
|
1253 |
-
* Underscore.js 1.5.2
|
1254 |
-
* http://underscorejs.org
|
1255 |
-
* (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
1256 |
-
* Underscore may be freely distributed under the MIT license.
|
1257 |
-
*/
|
1258 |
-
throttle: function(func, wait) {
|
1259 |
-
var context, args, result;
|
1260 |
-
var timeout = null;
|
1261 |
-
var previous = 0;
|
1262 |
-
var later = function() {
|
1263 |
-
previous = new Date;
|
1264 |
-
timeout = null;
|
1265 |
-
result = func.apply(context, args);
|
1266 |
-
};
|
1267 |
-
return function() {
|
1268 |
-
var now = new Date;
|
1269 |
-
if (!previous) previous = now;
|
1270 |
-
var remaining = wait - (now - previous);
|
1271 |
-
context = this;
|
1272 |
-
args = arguments;
|
1273 |
-
if (remaining <= 0) {
|
1274 |
-
clearTimeout(timeout);
|
1275 |
-
timeout = null;
|
1276 |
-
previous = now;
|
1277 |
-
result = func.apply(context, args);
|
1278 |
-
} else if (!timeout) {
|
1279 |
-
timeout = setTimeout(later, remaining);
|
1280 |
-
}
|
1281 |
-
return result;
|
1282 |
-
};
|
1283 |
-
},
|
1284 |
-
/*
|
1285 |
-
* Determine which version of GA is being used
|
1286 |
-
* "ga", "_gaq", and "dataLayer" are the possible globals
|
1287 |
-
*/
|
1288 |
-
checkTypeofGA: function() {
|
1289 |
-
if (typeof ga === "function") {
|
1290 |
-
universalGA = true;
|
1291 |
-
}
|
1292 |
-
|
1293 |
-
if (typeof _gaq !== "undefined" && typeof _gaq.push === "function") {
|
1294 |
-
classicGA = true;
|
1295 |
-
}
|
1296 |
-
|
1297 |
-
if (typeof dataLayer !== "undefined" && typeof dataLayer.push === "function") {
|
1298 |
-
googleTagManager = true;
|
1299 |
-
}
|
1300 |
-
|
1301 |
-
},
|
1302 |
-
/**
|
1303 |
-
* Caches user's search data in the browser until they can be saved to the database
|
1304 |
-
*/
|
1305 |
-
cacheSearchData: function(searchData, form) {
|
1306 |
-
|
1307 |
-
if(storageSupported){
|
1308 |
-
//store the searches in the local storage
|
1309 |
-
var stored = _inbound.totalStorage.getItem('inbound_search_storage');
|
1310 |
-
if(stored){
|
1311 |
-
//if there are stored searches, put the new one in the first index
|
1312 |
-
stored.unshift(searchData);
|
1313 |
-
_inbound.totalStorage.setItem('inbound_search_storage', stored);
|
1314 |
-
}else{
|
1315 |
-
//if there aren't any searches stored, save the current search
|
1316 |
-
var store = [searchData];
|
1317 |
-
_inbound.totalStorage.setItem('inbound_search_storage', store);
|
1318 |
-
}
|
1319 |
-
}else{
|
1320 |
-
//if local storage is not possible, store the data in a cookie
|
1321 |
-
var new_search = JSON.stringify(searchData),
|
1322 |
-
stored_searches = this.readCookie('inbound_search_storage');
|
1323 |
-
|
1324 |
-
if(stored_searches){
|
1325 |
-
//add the old searches to the new one
|
1326 |
-
new_search += ('SPLIT-TOKEN' + stored_searches);
|
1327 |
-
}
|
1328 |
-
this.createCookie('inbound_search_storage', new_search, '180');
|
1329 |
-
}
|
1330 |
-
|
1331 |
-
_inbound.Forms.releaseFormSubmit(form);
|
1332 |
-
},
|
1333 |
-
/**
|
1334 |
-
* Stores search data to the database on page load.
|
1335 |
-
* If successful, it erases the cached searches from the user's browser
|
1336 |
-
*/
|
1337 |
-
storeSearchData: function(){
|
1338 |
-
|
1339 |
-
/*if there isn't a lead id or the nonce isn't set, don't try to store the data*/
|
1340 |
-
if(!inbound_settings.wp_lead_data.lead_id || !inbound_settings.wp_lead_data.lead_nonce){
|
1341 |
-
return;
|
1342 |
-
}
|
1343 |
-
|
1344 |
-
var dataToSend = [],
|
1345 |
-
localStorageData = _inbound.totalStorage.getItem('inbound_search_storage'),
|
1346 |
-
cookieStorageData = this.readCookie('inbound_search_storage');
|
1347 |
-
|
1348 |
-
/*if nothing is stored, exit*/
|
1349 |
-
if(!localStorageData && !cookieStorageData){
|
1350 |
-
return;
|
1351 |
-
}
|
1352 |
-
|
1353 |
-
/*if set, add the cookie search data to the data to send*/
|
1354 |
-
if(cookieStorageData){
|
1355 |
-
cookieStorageData = cookieStorageData.split('SPLIT-TOKEN');
|
1356 |
-
|
1357 |
-
for(var i in cookieStorageData){
|
1358 |
-
//console.log(cookieStorageData[i]);
|
1359 |
-
dataToSend.push(JSON.parse(cookieStorageData[i]));
|
1360 |
-
}
|
1361 |
-
}
|
1362 |
-
|
1363 |
-
/*if set, add the locally stored data to the data to send*/
|
1364 |
-
if(localStorageData){
|
1365 |
-
dataToSend = dataToSend.concat(localStorageData);
|
1366 |
-
}
|
1367 |
-
|
1368 |
-
dataToSend.sort(function(a, b){ return a.timestamp - b.timestamp; });
|
1369 |
-
|
1370 |
-
dataToSend = encodeURIComponent(JSON.stringify(dataToSend));
|
1371 |
-
|
1372 |
-
var package = {'action' : 'inbound_search_store', 'data' : dataToSend, 'nonce' : inbound_settings.wp_lead_data.lead_nonce, 'lead_id' : inbound_settings.wp_lead_data.lead_id };
|
1373 |
-
|
1374 |
-
callback = function(status){
|
1375 |
-
if(status){ status = JSON.parse(status); }
|
1376 |
-
|
1377 |
-
if(status.success){
|
1378 |
-
//log the success!
|
1379 |
-
console.log(status.success);
|
1380 |
-
//erase the stored data
|
1381 |
-
_inbound.Utils.eraseCookie('inbound_search_storage');
|
1382 |
-
_inbound.totalStorage.deleteItem('inbound_search_storage');
|
1383 |
-
}
|
1384 |
-
|
1385 |
-
if(status.error){
|
1386 |
-
console.log(status.error);
|
1387 |
-
}
|
1388 |
-
};
|
1389 |
-
this.ajaxPost(inbound_settings.admin_url, package, callback);
|
1390 |
-
}
|
1391 |
-
};
|
1392 |
-
|
1393 |
-
return _inbound;
|
1394 |
-
|
1395 |
-
})(_inbound || {});
|
1396 |
-
|
1397 |
-
/**
|
1398 |
-
* # Inbound Forms
|
1399 |
-
*
|
1400 |
-
* This file contains all of the form functions of the main _inbound object.
|
1401 |
-
* Filters and actions are described below
|
1402 |
-
*
|
1403 |
-
* @
|
1404 |
-
* @
|
1405 |
-
* @version 0.0.2
|
1406 |
-
*/
|
1407 |
-
/* Finish Exclusions for CC */
|
1408 |
-
|
1409 |
-
/* Launches form class */
|
1410 |
-
var InboundForms = (function(_inbound) {
|
1411 |
-
|
1412 |
-
var debugMode = false,
|
1413 |
-
utils = _inbound.Utils,
|
1414 |
-
no_match = [],
|
1415 |
-
rawParams = [],
|
1416 |
-
mappedParams = [],
|
1417 |
-
callTracker = {},
|
1418 |
-
settings = _inbound.Settings;
|
1419 |
-
|
1420 |
-
var FieldMapArray = [
|
1421 |
-
"first name",
|
1422 |
-
"last name",
|
1423 |
-
"name",
|
1424 |
-
"email",
|
1425 |
-
"e-mail",
|
1426 |
-
"phone",
|
1427 |
-
"website",
|
1428 |
-
"job title",
|
1429 |
-
"your favorite food",
|
1430 |
-
"company",
|
1431 |
-
"tele",
|
1432 |
-
"address",
|
1433 |
-
"comment"
|
1434 |
-
/* Adding values here maps them */
|
1435 |
-
];
|
1436 |
-
|
1437 |
-
_inbound.Forms = {
|
1438 |
-
|
1439 |
-
// Init Form functions
|
1440 |
-
init: function() {
|
1441 |
-
_inbound.Forms.runFieldMappingFilters();
|
1442 |
-
_inbound.Forms.formTrackInit();
|
1443 |
-
_inbound.Forms.searchTrackInit();
|
1444 |
-
},
|
1445 |
-
/**
|
1446 |
-
* This triggers the forms.field_map filter on the mapping array.
|
1447 |
-
* This will allow you to add or remore Items from the mapping lookup
|
1448 |
-
*
|
1449 |
-
* ### Example inbound.form_map_before filter
|
1450 |
-
*
|
1451 |
-
* This is an example of how form mapping can be filtered and
|
1452 |
-
* additional fields can be mapped via javascript
|
1453 |
-
*
|
1454 |
-
* ```js
|
1455 |
-
* // Adding the filter function
|
1456 |
-
* function Inbound_Add_Filter_Example( FieldMapArray ) {
|
1457 |
-
* var map = FieldMapArray || [];
|
1458 |
-
* map.push('new lookup value');
|
1459 |
-
*
|
1460 |
-
* return map;
|
1461 |
-
* };
|
1462 |
-
*
|
1463 |
-
* // Adding the filter on dom ready
|
1464 |
-
* _inbound.hooks.addFilter( 'inbound.form_map_before', Inbound_Add_Filter_Example, 10 );
|
1465 |
-
* ```
|
1466 |
-
*
|
1467 |
-
* @return {[type]} [description]
|
1468 |
-
*/
|
1469 |
-
runFieldMappingFilters: function() {
|
1470 |
-
FieldMapArray = _inbound.hooks.applyFilters('forms.field_map', FieldMapArray);
|
1471 |
-
//alert(FieldMapArray);
|
1472 |
-
},
|
1473 |
-
debug: function(msg, callback) {
|
1474 |
-
//if app not in debug mode, exit immediately
|
1475 |
-
if (!debugMode || !console) {
|
1476 |
-
return;
|
1477 |
-
}
|
1478 |
-
|
1479 |
-
var msg = msg || false;
|
1480 |
-
//console.log the message
|
1481 |
-
if (msg && (typeof msg === 'string')) {
|
1482 |
-
console.log(msg);
|
1483 |
-
}
|
1484 |
-
|
1485 |
-
//execute the callback if one was passed-in
|
1486 |
-
if (callback && (callback instanceof Function)) {
|
1487 |
-
callback();
|
1488 |
-
}
|
1489 |
-
},
|
1490 |
-
formTrackInit: function() {
|
1491 |
-
|
1492 |
-
for (var i = 0; i < window.document.forms.length; i++) {
|
1493 |
-
var trackForm = false;
|
1494 |
-
var form = window.document.forms[i];
|
1495 |
-
/* process forms only once */
|
1496 |
-
if (!form.dataset.formProcessed) {
|
1497 |
-
form.dataset.formProcessed = true;
|
1498 |
-
trackForm = this.checkTrackStatus(form);
|
1499 |
-
if (trackForm) {
|
1500 |
-
this.attachFormSubmitEvent(form); /* attach form listener */
|
1501 |
-
this.initFormMapping(form);
|
1502 |
-
}
|
1503 |
-
}
|
1504 |
-
}
|
1505 |
-
},
|
1506 |
-
searchTrackInit: function(){
|
1507 |
-
|
1508 |
-
/* exit if searches aren't supposed to be tracked, or this function has already been called */
|
1509 |
-
if(inbound_settings.search_tracking == 'off' || callTracker['searchTrackInit']){
|
1510 |
-
return;
|
1511 |
-
}
|
1512 |
-
|
1513 |
-
for (var i = 0; i < window.document.forms.length; i++) {
|
1514 |
-
var trackForm = false;
|
1515 |
-
var form = window.document.forms[i];
|
1516 |
-
/* process forms only once */
|
1517 |
-
if (!form.dataset.searchChecked) {
|
1518 |
-
form.dataset.searchChecked = true;
|
1519 |
-
trackForm = this.checkSearchTrackStatus(form);
|
1520 |
-
if (trackForm) {
|
1521 |
-
this.attachSearchFormSubmitEvent(form); /* attach form listener */
|
1522 |
-
}
|
1523 |
-
}
|
1524 |
-
}
|
1525 |
-
|
1526 |
-
/* store the search data on init */
|
1527 |
-
utils.storeSearchData();
|
1528 |
-
|
1529 |
-
/* log that this function has been called */
|
1530 |
-
callTracker['searchTrackInit'] = true;
|
1531 |
-
},
|
1532 |
-
checkTrackStatus: function(form) {
|
1533 |
-
var ClassIs = form.getAttribute('class');
|
1534 |
-
if (ClassIs !== "" && ClassIs !== null) {
|
1535 |
-
if (ClassIs.toLowerCase().indexOf("wpl-track-me") > -1) {
|
1536 |
-
return true;
|
1537 |
-
} else if (ClassIs.toLowerCase().indexOf("inbound-track") > -1) {
|
1538 |
-
return true;
|
1539 |
-
} else {
|
1540 |
-
cb = function() { console.log(form); };
|
1541 |
-
_inbound.deBugger('forms', "This form not tracked. Please assign on in settings...", cb);
|
1542 |
-
return false;
|
1543 |
-
}
|
1544 |
-
}
|
1545 |
-
},
|
1546 |
-
checkSearchTrackStatus: function(form) {
|
1547 |
-
var ClassIs = form.getAttribute('class'),
|
1548 |
-
IdIs = form.getAttribute('id');
|
1549 |
-
if (ClassIs !== "" && ClassIs !== null) {
|
1550 |
-
if (ClassIs.toLowerCase().indexOf("search") > -1) {
|
1551 |
-
return true;
|
1552 |
-
}
|
1553 |
-
}
|
1554 |
-
if (IdIs !== "" && IdIs !== null) {
|
1555 |
-
if (IdIs.toLowerCase().indexOf("search") > -1) {
|
1556 |
-
return true;
|
1557 |
-
}
|
1558 |
-
}else{
|
1559 |
-
cb = function() { console.log(form); };
|
1560 |
-
_inbound.deBugger('searches', "This search form is not tracked. Please assign on in settings...", cb);
|
1561 |
-
return false;
|
1562 |
-
}
|
1563 |
-
},
|
1564 |
-
/* Loop through include/exclude items for tracking */
|
1565 |
-
loopClassSelectors: function(selectors, action) {
|
1566 |
-
for (var i = selectors.length - 1; i >= 0; i--) {
|
1567 |
-
|
1568 |
-
var selector = utils.trim(selectors[i])
|
1569 |
-
if (selector.indexOf("#") === -1 && selector.indexOf(".") === -1) {
|
1570 |
-
// assign ID as default
|
1571 |
-
selector = "#" + selector;
|
1572 |
-
}
|
1573 |
-
//if(selectors[i] match . or # )
|
1574 |
-
selector = document.querySelector(selector);
|
1575 |
-
//console.log("SELECTOR", selector);
|
1576 |
-
if (selector) {
|
1577 |
-
if (action === 'add') {
|
1578 |
-
_inbound.Utils.addClass('wpl-track-me', selector);
|
1579 |
-
_inbound.Utils.addClass('inbound-track', selector);
|
1580 |
-
} else {
|
1581 |
-
_inbound.Utils.removeClass('wpl-track-me', selector);
|
1582 |
-
_inbound.Utils.removeClass('inbound-track', selector);
|
1583 |
-
}
|
1584 |
-
}
|
1585 |
-
}
|
1586 |
-
},
|
1587 |
-
/* Map field fields on load */
|
1588 |
-
initFormMapping: function(form) {
|
1589 |
-
var hiddenInputs = [];
|
1590 |
-
|
1591 |
-
for (var i = 0; i < form.elements.length; i++) {
|
1592 |
-
formInput = form.elements[i];
|
1593 |
-
|
1594 |
-
if (formInput.type === 'hidden') {
|
1595 |
-
hiddenInputs.push(formInput);
|
1596 |
-
continue;
|
1597 |
-
}
|
1598 |
-
|
1599 |
-
//this.ignoreFields(formInput);
|
1600 |
-
/* Map form fields */
|
1601 |
-
this.mapField(formInput);
|
1602 |
-
/* Remember visible inputs */
|
1603 |
-
this.rememberInputValues(formInput);
|
1604 |
-
/* Fill visible inputs */
|
1605 |
-
if (settings.formAutoPopulation && !_inbound.Utils.hasClass( "nopopulate", form ) ) {
|
1606 |
-
this.fillInputValues(formInput);
|
1607 |
-
}
|
1608 |
-
|
1609 |
-
}
|
1610 |
-
|
1611 |
-
/* loop hidden inputs */
|
1612 |
-
for (var n = hiddenInputs.length - 1; n >= 0; n--) {
|
1613 |
-
formInput = hiddenInputs[n];
|
1614 |
-
this.mapField(formInput);
|
1615 |
-
}
|
1616 |
-
|
1617 |
-
//console.log('mapping on load completed');
|
1618 |
-
},
|
1619 |
-
/* Maps data attributes to fields on page load */
|
1620 |
-
mapField: function(input) {
|
1621 |
-
|
1622 |
-
var input_id = input.id || false;
|
1623 |
-
var input_name = input.name || false;
|
1624 |
-
var label = this.getInputLabel(input);
|
1625 |
-
|
1626 |
-
if(label){
|
1627 |
-
//console.log(label[0].innerText);
|
1628 |
-
var ignoreField = this.ignoreFieldByLabel(label[0].innerText);
|
1629 |
-
if(ignoreField){
|
1630 |
-
input.dataset.ignoreFormField = true;
|
1631 |
-
return false;
|
1632 |
-
}
|
1633 |
-
}
|
1634 |
-
|
1635 |
-
/* Loop through all match possiblities */
|
1636 |
-
for (i = 0; i < FieldMapArray.length; i++) {
|
1637 |
-
//for (var i = FieldMapArray.length - 1; i >= 0; i--) {
|
1638 |
-
var found = false;
|
1639 |
-
var match = FieldMapArray[i];
|
1640 |
-
var lookingFor = utils.trim(match);
|
1641 |
-
var nice_name = lookingFor.replace(/ /g, '_');
|
1642 |
-
|
1643 |
-
|
1644 |
-
//console.log("NICE NAME", nice_name);
|
1645 |
-
//console.log('looking for match on ' + lookingFor);
|
1646 |
-
//_inbound.deBugger('forms', 'looking for match on ' + lookingFor + " nice_name= " + nice_name);
|
1647 |
-
|
1648 |
-
// Check if input has an attached lable using for= tag
|
1649 |
-
//var $laxbel = $("label[for='" + $element.attr('id') + "']").text();
|
1650 |
-
//var labxel = 'label[for="' + input_id + '"]';
|
1651 |
-
|
1652 |
-
/* look for name attribute match */
|
1653 |
-
if (input_name && input_name.toLowerCase().indexOf(lookingFor) > -1) {
|
1654 |
-
found = true;
|
1655 |
-
_inbound.deBugger('forms', 'Found matching name attribute for -> ' + lookingFor);
|
1656 |
-
|
1657 |
-
/* look for id match */
|
1658 |
-
} else if (input_id && input_id.toLowerCase().indexOf(lookingFor) > -1) {
|
1659 |
-
|
1660 |
-
found = true;
|
1661 |
-
_inbound.deBugger('forms', 'Found matching ID attribute for ->' + lookingFor);
|
1662 |
-
|
1663 |
-
/* Check siblings for label */
|
1664 |
-
} else if (label) {
|
1665 |
-
//var label = (label.length > 1 ? label[0] : label);
|
1666 |
-
//console.log('label', label);
|
1667 |
-
if (label[0].innerText.toLowerCase().indexOf(lookingFor) > -1) {
|
1668 |
-
|
1669 |
-
found = true;
|
1670 |
-
_inbound.deBugger('forms', 'Found matching sibling label for -> ' + lookingFor);
|
1671 |
-
|
1672 |
-
}
|
1673 |
-
|
1674 |
-
} else {
|
1675 |
-
/* no match found */
|
1676 |
-
//_inbound.deBugger('forms', 'NO Match on ' + lookingFor + " in " + input_name);
|
1677 |
-
no_match.push(lookingFor);
|
1678 |
-
|
1679 |
-
}
|
1680 |
-
|
1681 |
-
/* Map the field */
|
1682 |
-
if (found) {
|
1683 |
-
this.addDataAttr(input, nice_name);
|
1684 |
-
this.removeArrayItem(FieldMapArray, lookingFor);
|
1685 |
-
i--; //decrement count
|
1686 |
-
}
|
1687 |
-
|
1688 |
-
}
|
1689 |
-
|
1690 |
-
return inbound_data;
|
1691 |
-
|
1692 |
-
},
|
1693 |
-
/* prevent default submission temporarily */
|
1694 |
-
formListener: function(event) {
|
1695 |
-
//console.log(event);
|
1696 |
-
event.preventDefault();
|
1697 |
-
_inbound.Forms.saveFormData(event.target);
|
1698 |
-
document.body.style.cursor = "wait";
|
1699 |
-
},
|
1700 |
-
/* prevent default submission temporarily */
|
1701 |
-
searchFormListener: function(event) {
|
1702 |
-
//console.log(event);
|
1703 |
-
event.preventDefault();
|
1704 |
-
_inbound.Forms.saveSearchData(event.target);
|
1705 |
-
//document.body.style.cursor = "wait";
|
1706 |
-
},
|
1707 |
-
/* attach form listeners */
|
1708 |
-
attachFormSubmitEvent: function(form) {
|
1709 |
-
utils.addListener(form, 'submit', this.formListener);
|
1710 |
-
var email_input = document.querySelector('.inbound-email');
|
1711 |
-
/* utils.addListener(email_input, 'blur', this.mailCheck); */
|
1712 |
-
},
|
1713 |
-
/* attach search form listener */
|
1714 |
-
attachSearchFormSubmitEvent: function(form) {
|
1715 |
-
utils.addListener(form, 'submit', this.searchFormListener);
|
1716 |
-
},
|
1717 |
-
/* Ignore CC data */
|
1718 |
-
ignoreFieldByLabel: function(label) {
|
1719 |
-
var ignore_field = false;
|
1720 |
-
|
1721 |
-
if(!label){ return false; }
|
1722 |
-
|
1723 |
-
// Ignore any fields with labels that indicate a credit card field
|
1724 |
-
if (label.toLowerCase().indexOf('credit card') != -1 || label.toLowerCase().indexOf('card number') != -1) {
|
1725 |
-
ignore_field = true;
|
1726 |
-
}
|
1727 |
-
|
1728 |
-
if (label.toLowerCase().indexOf('expiration') != -1 || label.toLowerCase().indexOf('expiry') != -1) {
|
1729 |
-
ignore_field = true;
|
1730 |
-
}
|
1731 |
-
|
1732 |
-
if (label.toLowerCase() == 'month' || label.toLowerCase() == 'mm' || label.toLowerCase() == 'yy' || label.toLowerCase() == 'yyyy' || label.toLowerCase() == 'year') {
|
1733 |
-
ignore_field = true;
|
1734 |
-
}
|
1735 |
-
|
1736 |
-
if (label.toLowerCase().indexOf('cvv') != -1 || label.toLowerCase().indexOf('cvc') != -1 || label.toLowerCase().indexOf('secure code') != -1 || label.toLowerCase().indexOf('security code') != -1) {
|
1737 |
-
ignore_field = true;
|
1738 |
-
}
|
1739 |
-
|
1740 |
-
if(ignore_field){
|
1741 |
-
_inbound.deBugger('forms', 'ignore ' + label);
|
1742 |
-
}
|
1743 |
-
|
1744 |
-
return ignore_field;
|
1745 |
-
|
1746 |
-
},
|
1747 |
-
/* not implemented yet */
|
1748 |
-
ignoreFieldByValue: function(value){
|
1749 |
-
var ignore_field = false;
|
1750 |
-
|
1751 |
-
if(!value){ return false; }
|
1752 |
-
|
1753 |
-
if (value.toLowerCase() == 'visa' || value.toLowerCase() == 'mastercard' || value.toLowerCase() == 'american express' || value.toLowerCase() == 'amex' || value.toLowerCase() == 'discover') {
|
1754 |
-
ignore_field = true;
|
1755 |
-
}
|
1756 |
-
|
1757 |
-
// Check if value has integers, strip out spaces, then ignore anything with a credit card length (>16) or an expiration/cvv length (<5)
|
1758 |
-
var int_regex = new RegExp("/^[0-9]+$/");
|
1759 |
-
if (int_regex.test(value)) {
|
1760 |
-
var value_no_spaces = value.replace(' ', '');
|
1761 |
-
|
1762 |
-
if (this.isInt(value_no_spaces) && value_no_spaces.length >= 16) {
|
1763 |
-
ignore_field = true;
|
1764 |
-
}
|
1765 |
-
|
1766 |
-
}
|
1767 |
-
|
1768 |
-
return ignore_field;
|
1769 |
-
|
1770 |
-
},
|
1771 |
-
isInt: function(n) {
|
1772 |
-
return typeof n == "number" && isFinite(n) && n % 1 === 0;
|
1773 |
-
},
|
1774 |
-
releaseFormSubmit: function(form) {
|
1775 |
-
//console.log('remove form listener event');
|
1776 |
-
document.body.style.cursor = "default";
|
1777 |
-
utils.removeClass('wpl-track-me', form);
|
1778 |
-
utils.removeListener(form, 'submit', this.formListener);
|
1779 |
-
var formClass = form.getAttribute('class');
|
1780 |
-
if (formClass !== "" && formClass !== null) {
|
1781 |
-
/* If contact form 7 do this */
|
1782 |
-
if (formClass.toLowerCase().indexOf("wpcf7-form") != -1) {
|
1783 |
-
//alert('release')
|
1784 |
-
setTimeout(function() {
|
1785 |
-
document.body.style.cursor = "default";
|
1786 |
-
}, 300);
|
1787 |
-
return true;
|
1788 |
-
}
|
1789 |
-
}
|
1790 |
-
|
1791 |
-
form.submit();
|
1792 |
-
/* fallback if submit name="submit" */
|
1793 |
-
setTimeout(function() {
|
1794 |
-
for (var i = 0; i < form.elements.length; i++) {
|
1795 |
-
formInput = form.elements[i];
|
1796 |
-
type = formInput.type || false;
|
1797 |
-
if (type === "submit" && formInput.name === "submit") {
|
1798 |
-
form.elements[i].click();
|
1799 |
-
}
|
1800 |
-
}
|
1801 |
-
}, 2000);
|
1802 |
-
|
1803 |
-
},
|
1804 |
-
saveFormData: function(form) {
|
1805 |
-
var inputsObject = inputsObject || {};
|
1806 |
-
for (var i = 0; i < form.elements.length; i++) {
|
1807 |
-
|
1808 |
-
// console.log(inputsObject);
|
1809 |
-
|
1810 |
-
formInput = form.elements[i];
|
1811 |
-
multiple = false;
|
1812 |
-
|
1813 |
-
if (formInput.name) {
|
1814 |
-
|
1815 |
-
if (formInput.dataset.ignoreFormField) {
|
1816 |
-
_inbound.deBugger('forms', 'ignore ' + formInput.name);
|
1817 |
-
continue;
|
1818 |
-
}
|
1819 |
-
|
1820 |
-
inputName = formInput.name.replace(/\[([^\[]*)\]/g, "%5B%5D$1");
|
1821 |
-
//inputName = inputName.replace(/-/g, "_");
|
1822 |
-
if (!inputsObject[inputName]) {
|
1823 |
-
inputsObject[inputName] = {};
|
1824 |
-
}
|
1825 |
-
if (formInput.type) {
|
1826 |
-
inputsObject[inputName]['type'] = formInput.type;
|
1827 |
-
}
|
1828 |
-
if (!inputsObject[inputName]['name']) {
|
1829 |
-
inputsObject[inputName]['name'] = formInput.name;
|
1830 |
-
}
|
1831 |
-
if (formInput.dataset.mapFormField) {
|
1832 |
-
inputsObject[inputName]['map'] = formInput.dataset.mapFormField;
|
1833 |
-
}
|
1834 |
-
|
1835 |
-
|
1836 |
-
switch (formInput.nodeName) {
|
1837 |
-
|
1838 |
-
case 'INPUT':
|
1839 |
-
value = this.getInputValue(formInput);
|
1840 |
-
|
1841 |
-
|
1842 |
-
if (value === false) {
|
1843 |
-
continue;
|
1844 |
-
}
|
1845 |
-
break;
|
1846 |
-
|
1847 |
-
case 'TEXTAREA':
|
1848 |
-
value = formInput.value;
|
1849 |
-
break;
|
1850 |
-
|
1851 |
-
case 'SELECT':
|
1852 |
-
if (formInput.multiple) {
|
1853 |
-
values = [];
|
1854 |
-
multiple = true;
|
1855 |
-
|
1856 |
-
for (var j = 0; j < formInput.length; j++) {
|
1857 |
-
if (formInput[j].selected) {
|
1858 |
-
values.push(encodeURIComponent(formInput[j].value));
|
1859 |
-
}
|
1860 |
-
}
|
1861 |
-
|
1862 |
-
} else {
|
1863 |
-
value = (formInput.value);
|
1864 |
-
}
|
1865 |
-
|
1866 |
-
break;
|
1867 |
-
}
|
1868 |
-
|
1869 |
-
_inbound.deBugger('forms', 'Input Value = ' + value);
|
1870 |
-
|
1871 |
-
|
1872 |
-
if (value) {
|
1873 |
-
/* inputsObject[inputName].push(multiple ? values.join(',') : encodeURIComponent(value)); */
|
1874 |
-
if (!inputsObject[inputName]['value']) {
|
1875 |
-
inputsObject[inputName]['value'] = [];
|
1876 |
-
}
|
1877 |
-
inputsObject[inputName]['value'].push(multiple ? values.join(',') : encodeURIComponent(value));
|
1878 |
-
var value = multiple ? values.join(',') : encodeURIComponent(value);
|
1879 |
-
|
1880 |
-
}
|
1881 |
-
|
1882 |
-
}
|
1883 |
-
}
|
1884 |
-
_inbound.deBugger('forms', inputsObject);
|
1885 |
-
|
1886 |
-
//console.log('These are the raw values', inputsObject);
|
1887 |
-
//_inbound.totalStorage('the_key', inputsObject);
|
1888 |
-
//var inputsObject = sortInputs(inputsObject);
|
1889 |
-
|
1890 |
-
var matchCommon = /name|first name|last name|email|e-mail|phone|website|job title|company|tele|address|comment/;
|
1891 |
-
|
1892 |
-
for (var input in inputsObject) {
|
1893 |
-
//console.log(input);
|
1894 |
-
|
1895 |
-
var inputValue = inputsObject[input]['value'];
|
1896 |
-
var inputMappedField = inputsObject[input]['map'];
|
1897 |
-
//if (matchCommon.test(input) !== false) {
|
1898 |
-
//console.log(input + " Matches Regex run mapping test");
|
1899 |
-
//var map = inputsObject[input];
|
1900 |
-
//console.log("MAPP", map);
|
1901 |
-
//mappedParams.push( input + '=' + inputsObject[input]['value'].join(',') );
|
1902 |
-
//}
|
1903 |
-
|
1904 |
-
/* Add custom hook here to look for additional values */
|
1905 |
-
if (typeof(inputValue) != "undefined" && inputValue != null && inputValue != "") {
|
1906 |
-
rawParams.push(input + '=' + inputsObject[input]['value'].join(','));
|
1907 |
-
}
|
1908 |
-
|
1909 |
-
if (typeof(inputMappedField) != "undefined" && inputMappedField != null && inputsObject[input]['value']) {
|
1910 |
-
//console.log('Data ATTR', formInput.dataset.mapFormField);
|
1911 |
-
mappedParams.push(inputMappedField + "=" + inputsObject[input]['value'].join(','));
|
1912 |
-
if (input === 'email') {
|
1913 |
-
var email = inputsObject[input]['value'].join(',');
|
1914 |
-
//alert(email);
|
1915 |
-
|
1916 |
-
}
|
1917 |
-
}
|
1918 |
-
}
|
1919 |
-
|
1920 |
-
var raw_params = rawParams.join('&');
|
1921 |
-
_inbound.deBugger('forms', "Stringified Raw Form PARAMS: " + raw_params);
|
1922 |
-
|
1923 |
-
var mapped_params = mappedParams.join('&');
|
1924 |
-
_inbound.deBugger('forms', "Stringified Mapped PARAMS" + mapped_params);
|
1925 |
-
|
1926 |
-
/* Check Use form Email or Cookie */
|
1927 |
-
var email = utils.getParameterVal('email', mapped_params) || utils.readCookie('wp_lead_email');
|
1928 |
-
|
1929 |
-
/* Legacy Email map */
|
1930 |
-
if (!email) {
|
1931 |
-
email = utils.getParameterVal('wpleads_email_address', mapped_params);
|
1932 |
-
}
|
1933 |
-
|
1934 |
-
var fullName = utils.getParameterVal('name', mapped_params);
|
1935 |
-
var fName = utils.getParameterVal('first_name', mapped_params);
|
1936 |
-
var lName = utils.getParameterVal('last_name', mapped_params);
|
1937 |
-
|
1938 |
-
// Fallbacks for empty values
|
1939 |
-
if (!lName && fName) {
|
1940 |
-
var parts = decodeURI(fName).split(" ");
|
1941 |
-
if (parts.length > 0) {
|
1942 |
-
fName = parts[0];
|
1943 |
-
lName = parts[1];
|
1944 |
-
}
|
1945 |
-
}
|
1946 |
-
|
1947 |
-
if (fullName && !lName && !fName) {
|
1948 |
-
var parts = decodeURI(fullName).split(" ");
|
1949 |
-
if (parts.length > 0) {
|
1950 |
-
fName = parts[0];
|
1951 |
-
lName = parts[1];
|
1952 |
-
}
|
1953 |
-
}
|
1954 |
-
|
1955 |
-
fullName = (fName && lName) ? fName + " " + lName : fullName;
|
1956 |
-
|
1957 |
-
if(!fName) { fName = ""; }
|
1958 |
-
if(!lName) { lName = ""; }
|
1959 |
-
|
1960 |
-
_inbound.deBugger('forms', "fName = " + fName);
|
1961 |
-
_inbound.deBugger('forms', "lName = " + lName);
|
1962 |
-
_inbound.deBugger('forms', "fullName = " + fullName);
|
1963 |
-
|
1964 |
-
//return false;
|
1965 |
-
var page_views = _inbound.totalStorage('page_views') || {};
|
1966 |
-
var urlParams = _inbound.totalStorage('inbound_url_params') || {};
|
1967 |
-
|
1968 |
-
/* check if redirect url is empty */
|
1969 |
-
var formRedirectUrl = form.querySelectorAll('input[value][type="hidden"][name="inbound_furl"]:not([value=""])');
|
1970 |
-
var inbound_form_is_ajax = false;
|
1971 |
-
if(formRedirectUrl.length == 0 || formRedirectUrl[0]['value'] == 'IA=='){
|
1972 |
-
var inbound_form_is_ajax = true;
|
1973 |
-
}
|
1974 |
-
|
1975 |
-
/* get form id */
|
1976 |
-
var inbound_form_id = form.querySelectorAll('input[value][type="hidden"][name="inbound_form_id"]');
|
1977 |
-
if(inbound_form_id.length > 0 ){
|
1978 |
-
inbound_form_id = inbound_form_id[0]['value'];
|
1979 |
-
} else {
|
1980 |
-
inbound_form_id = 0;
|
1981 |
-
}
|
1982 |
-
|
1983 |
-
var inboundDATA = {
|
1984 |
-
'email': email
|
1985 |
-
};
|
1986 |
-
|
1987 |
-
/* Get Variation ID */
|
1988 |
-
if (typeof(landing_path_info) != "undefined") {
|
1989 |
-
var variation = landing_path_info.variation;
|
1990 |
-
} else if (typeof(cta_path_info) != "undefined") {
|
1991 |
-
var variation = cta_path_info.variation;
|
1992 |
-
} else {
|
1993 |
-
var variation = inbound_settings.variation_id;
|
1994 |
-
}
|
1995 |
-
var post_type = inbound_settings.post_type || 'page';
|
1996 |
-
var page_id = inbound_settings.post_id || 0;
|
1997 |
-
// data['wp_lead_uid'] = jQuery.cookie("wp_lead_uid") || null;
|
1998 |
-
// data['search_data'] = JSON.stringify(jQuery.totalStorage('inbound_search')) || {};
|
1999 |
-
search_data = {};
|
2000 |
-
/* Filter here for raw */
|
2001 |
-
formData = {
|
2002 |
-
'action': 'inbound_lead_store',
|
2003 |
-
'email': email,
|
2004 |
-
"full_name": fullName,
|
2005 |
-
"first_name": fName,
|
2006 |
-
"last_name": lName,
|
2007 |
-
'raw_params': raw_params,
|
2008 |
-
'mapped_params': mapped_params,
|
2009 |
-
'url_params': JSON.stringify(urlParams),
|
2010 |
-
'search_data': 'test',
|
2011 |
-
'page_views': JSON.stringify(page_views),
|
2012 |
-
'post_type': post_type,
|
2013 |
-
'page_id': page_id,
|
2014 |
-
'variation': variation,
|
2015 |
-
'source': utils.readCookie("inbound_referral_site"),
|
2016 |
-
'inbound_submitted': inbound_form_is_ajax,
|
2017 |
-
'inbound_form_id': inbound_form_id,
|
2018 |
-
'inbound_nonce': inbound_settings.ajax_nonce,
|
2019 |
-
'event': form
|
2020 |
-
};
|
2021 |
-
|
2022 |
-
callback = function(leadID) {
|
2023 |
-
/* Action Example */
|
2024 |
-
|
2025 |
-
_inbound.deBugger('forms', 'Lead Created with ID: ' + leadID);
|
2026 |
-
leadID = parseInt(leadID, 10);
|
2027 |
-
formData.leadID = leadID;
|
2028 |
-
/* Set Lead cookie ID */
|
2029 |
-
if (leadID) {
|
2030 |
-
utils.createCookie("wp_lead_id", leadID);
|
2031 |
-
_inbound.totalStorage.deleteItem('page_views'); // remove pageviews
|
2032 |
-
_inbound.totalStorage.deleteItem('tracking_events'); // remove events
|
2033 |
-
}
|
2034 |
-
|
2035 |
-
_inbound.trigger('form_after_submission', formData);
|
2036 |
-
|
2037 |
-
/* Resume normal form functionality */
|
2038 |
-
_inbound.Forms.releaseFormSubmit(form);
|
2039 |
-
|
2040 |
-
}
|
2041 |
-
|
2042 |
-
_inbound.trigger('form_before_submission', formData);
|
2043 |
-
|
2044 |
-
utils.ajaxPost(inbound_settings.admin_url, formData, callback);
|
2045 |
-
},
|
2046 |
-
saveSearchData: function(form) {
|
2047 |
-
var inputsObject = inputsObject || {};
|
2048 |
-
for (var i = 0; i < form.elements.length; i++) {
|
2049 |
-
|
2050 |
-
//console.log(inputsObject);
|
2051 |
-
|
2052 |
-
formInput = form.elements[i];
|
2053 |
-
multiple = false;
|
2054 |
-
|
2055 |
-
if (formInput.name) {
|
2056 |
-
|
2057 |
-
if (formInput.dataset.ignoreFormField) {
|
2058 |
-
_inbound.deBugger('searches', 'ignore ' + formInput.name);
|
2059 |
-
continue;
|
2060 |
-
}
|
2061 |
-
|
2062 |
-
inputName = formInput.name.replace(/\[([^\[]*)\]/g, "%5B%5D$1");
|
2063 |
-
//inputName = inputName.replace(/-/g, "_");
|
2064 |
-
if (!inputsObject[inputName]) {
|
2065 |
-
inputsObject[inputName] = {};
|
2066 |
-
}
|
2067 |
-
if (formInput.type) {
|
2068 |
-
inputsObject[inputName]['type'] = formInput.type;
|
2069 |
-
|
2070 |
-
}
|
2071 |
-
if (!inputsObject[inputName]['name']) {
|
2072 |
-
inputsObject[inputName]['name'] = formInput.name;
|
2073 |
-
}
|
2074 |
-
if (formInput.dataset.mapFormField) {
|
2075 |
-
inputsObject[inputName]['map'] = formInput.dataset.mapFormField;
|
2076 |
-
}
|
2077 |
-
|
2078 |
-
|
2079 |
-
switch (formInput.nodeName) {
|
2080 |
-
|
2081 |
-
case 'INPUT':
|
2082 |
-
value = this.getInputValue(formInput);
|
2083 |
-
|
2084 |
-
|
2085 |
-
if (value === false) {
|
2086 |
-
continue;
|
2087 |
-
}
|
2088 |
-
break;
|
2089 |
-
|
2090 |
-
case 'TEXTAREA':
|
2091 |
-
value = formInput.value;
|
2092 |
-
break;
|
2093 |
-
|
2094 |
-
case 'SELECT':
|
2095 |
-
if (formInput.multiple) {
|
2096 |
-
values = [];
|
2097 |
-
multiple = true;
|
2098 |
-
|
2099 |
-
for (var j = 0; j < formInput.length; j++) {
|
2100 |
-
if (formInput[j].selected) {
|
2101 |
-
values.push(encodeURIComponent(formInput[j].value));
|
2102 |
-
}
|
2103 |
-
}
|
2104 |
-
|
2105 |
-
} else {
|
2106 |
-
value = (formInput.value);
|
2107 |
-
}
|
2108 |
-
|
2109 |
-
break;
|
2110 |
-
}
|
2111 |
-
|
2112 |
-
_inbound.deBugger('searches', 'Input Value = ' + value);
|
2113 |
-
|
2114 |
-
|
2115 |
-
if (value) {
|
2116 |
-
/* inputsObject[inputName].push(multiple ? values.join(',') : encodeURIComponent(value)); */
|
2117 |
-
if (!inputsObject[inputName]['value']) {
|
2118 |
-
inputsObject[inputName]['value'] = [];
|
2119 |
-
}
|
2120 |
-
inputsObject[inputName]['value'].push(multiple ? values.join(',') : encodeURIComponent(value));
|
2121 |
-
var value = multiple ? values.join(',') : encodeURIComponent(value);
|
2122 |
-
|
2123 |
-
}
|
2124 |
-
|
2125 |
-
}
|
2126 |
-
}
|
2127 |
-
|
2128 |
-
_inbound.deBugger('searches', inputsObject);
|
2129 |
-
|
2130 |
-
/* create an array of search fields //(not fully implemented) at the moment, it only maps the text in the "search" input types*/
|
2131 |
-
var searchQuery = [];
|
2132 |
-
for (var input in inputsObject) {
|
2133 |
-
var inputValue = inputsObject[input]['value'];
|
2134 |
-
var inputType = inputsObject[input]['type'];
|
2135 |
-
|
2136 |
-
/* Add custom hook here to look for additional values */
|
2137 |
-
if (typeof(inputValue) != "undefined" && inputValue != null && inputValue != "") {
|
2138 |
-
// This is for mapping all fields of a search form. The resulting string is processed
|
2139 |
-
// in inbound-pro\classes\admin\report-templates\report.lead-searches-and-comments.php
|
2140 |
-
// In the function print_action_popup()
|
2141 |
-
// searchQuery.push(input + '|value|' + inputsObject[input]['value'].join(','));
|
2142 |
-
|
2143 |
-
// get the search input value
|
2144 |
-
if(inputType == 'search'){
|
2145 |
-
searchQuery.push('search_text' + '|value|' + inputsObject[input]['value']);
|
2146 |
-
}
|
2147 |
-
}
|
2148 |
-
}
|
2149 |
-
/* exit if there isn't a search query */
|
2150 |
-
if(!searchQuery[0]){
|
2151 |
-
return;
|
2152 |
-
}
|
2153 |
-
|
2154 |
-
var searchString = searchQuery.join('|field|');
|
2155 |
-
_inbound.deBugger('searches', "Stringified Search Form PARAMS: " + searchString);
|
2156 |
-
|
2157 |
-
/* Get Variation ID */
|
2158 |
-
if (typeof(landing_path_info) != "undefined") {
|
2159 |
-
var variation = landing_path_info.variation;
|
2160 |
-
} else if (typeof(cta_path_info) != "undefined") {
|
2161 |
-
var variation = cta_path_info.variation;
|
2162 |
-
} else {
|
2163 |
-
var variation = inbound_settings.variation_id;
|
2164 |
-
}
|
2165 |
-
var post_type = inbound_settings.post_type || 'page';
|
2166 |
-
var page_id = inbound_settings.post_id || 0;
|
2167 |
-
|
2168 |
-
var user_UID = utils.readCookie("wp_lead_uid");
|
2169 |
-
|
2170 |
-
/* get the user's email address if possible */
|
2171 |
-
if(inbound_settings.wp_lead_data.lead_email){
|
2172 |
-
email = inbound_settings.wp_lead_data.lead_email;
|
2173 |
-
}else if(utils.readCookie('inbound_wpleads_email_address')){
|
2174 |
-
email = utils.readCookie('inbound_wpleads_email_address');
|
2175 |
-
}else{
|
2176 |
-
email = '';
|
2177 |
-
}
|
2178 |
-
|
2179 |
-
/* Filter here for raw */
|
2180 |
-
searchData = {
|
2181 |
-
'email': email,
|
2182 |
-
'search_data': searchString,
|
2183 |
-
'user_UID': user_UID,
|
2184 |
-
'post_type': post_type,
|
2185 |
-
'page_id': page_id,
|
2186 |
-
'variation': variation,
|
2187 |
-
'source': utils.readCookie("inbound_referral_site"),
|
2188 |
-
'ip_address': inbound_settings.ip_address,
|
2189 |
-
'timestamp': Math.floor((new Date).getTime()/1000),
|
2190 |
-
};
|
2191 |
-
|
2192 |
-
/* filter data before caching it in the user's browser */
|
2193 |
-
_inbound.trigger('search_before_caching', searchData);
|
2194 |
-
|
2195 |
-
/* cache search data */
|
2196 |
-
if(inbound_settings.wp_lead_data.lead_id){
|
2197 |
-
searchData['lead_id'] = inbound_settings.wp_lead_data.lead_id;
|
2198 |
-
utils.cacheSearchData(searchData, form)
|
2199 |
-
}else{
|
2200 |
-
utils.cacheSearchData(searchData, form);
|
2201 |
-
}
|
2202 |
-
|
2203 |
-
|
2204 |
-
},
|
2205 |
-
rememberInputValues: function(input) {
|
2206 |
-
var name = (input.name) ? "inbound_" + input.name : '';
|
2207 |
-
var type = (input.type) ? input.type : 'text';
|
2208 |
-
if (type === 'submit' || type === 'hidden' || type === 'file' || type === "password" || input.dataset.ignoreFormField) {
|
2209 |
-
return false;
|
2210 |
-
}
|
2211 |
-
|
2212 |
-
utils.addListener(input, 'change', function(e) {
|
2213 |
-
if (e.target.name) {
|
2214 |
-
/* Check for input type */
|
2215 |
-
if (type !== "checkbox") {
|
2216 |
-
var value = e.target.value;
|
2217 |
-
} else {
|
2218 |
-
var values = [];
|
2219 |
-
var checkboxes = document.querySelectorAll('input[name="' + e.target.name + '"]');
|
2220 |
-
for (var i = 0; i < checkboxes.length; i++) {
|
2221 |
-
var checked = checkboxes[i].checked;
|
2222 |
-
if (checked) {
|
2223 |
-
values.push(checkboxes[i].value);
|
2224 |
-
}
|
2225 |
-
value = values.join(',');
|
2226 |
-
};
|
2227 |
-
}
|
2228 |
-
//console.log(e.target.nodeName);
|
2229 |
-
//console.log('change ' + e.target.name + " " + encodeURIComponent(value));
|
2230 |
-
|
2231 |
-
inputData = {
|
2232 |
-
name: e.target.name,
|
2233 |
-
node: e.target.nodeName.toLowerCase(),
|
2234 |
-
type: type,
|
2235 |
-
value: value,
|
2236 |
-
mapping: e.target.dataset.mapFormField
|
2237 |
-
};
|
2238 |
-
|
2239 |
-
_inbound.trigger('form_input_change', inputData);
|
2240 |
-
/* Set Field Input Cookies */
|
2241 |
-
utils.createCookie("inbound_" + e.target.name, encodeURIComponent(value));
|
2242 |
-
// _inbound.totalStorage('the_key', FormStore);
|
2243 |
-
/* Push to 'unsubmitted form object' */
|
2244 |
-
}
|
2245 |
-
|
2246 |
-
});
|
2247 |
-
},
|
2248 |
-
fillInputValues: function(input) {
|
2249 |
-
var name = (input.name) ? "inbound_" + input.name : '';
|
2250 |
-
var type = (input.type) ? input.type : 'text';
|
2251 |
-
if (type === 'submit' || type === 'hidden' || type === 'file' || type === "password") {
|
2252 |
-
return false;
|
2253 |
-
}
|
2254 |
-
if (utils.readCookie(name) && name != 'comment') {
|
2255 |
-
|
2256 |
-
value = decodeURIComponent(utils.readCookie(name));
|
2257 |
-
if (type === 'checkbox' || type === 'radio') {
|
2258 |
-
var checkbox_vals = value.split(',');
|
2259 |
-
for (var i = 0; i < checkbox_vals.length; i++) {
|
2260 |
-
if (input.value.indexOf(checkbox_vals[i]) > -1) {
|
2261 |
-
input.checked = true;
|
2262 |
-
}
|
2263 |
-
}
|
2264 |
-
} else {
|
2265 |
-
if (value !== "undefined") {
|
2266 |
-
input.value = value;
|
2267 |
-
}
|
2268 |
-
}
|
2269 |
-
}
|
2270 |
-
},
|
2271 |
-
getInputLabel: function(input){
|
2272 |
-
var label;
|
2273 |
-
if(label = this.siblingsIsLabel(input)){
|
2274 |
-
return label;
|
2275 |
-
} else if (label = this.CheckParentForLabel(input)) {
|
2276 |
-
return label;
|
2277 |
-
} else {
|
2278 |
-
//console.log("no label nf", input);
|
2279 |
-
return false;
|
2280 |
-
}
|
2281 |
-
},
|
2282 |
-
/* Get correct input values */
|
2283 |
-
getInputValue: function(input) {
|
2284 |
-
var value = false;
|
2285 |
-
|
2286 |
-
switch (input.type) {
|
2287 |
-
case 'radio':
|
2288 |
-
case 'checkbox':
|
2289 |
-
if (input.checked) {
|
2290 |
-
value = input.value;
|
2291 |
-
//console.log("CHECKBOX VAL", value)
|
2292 |
-
}
|
2293 |
-
break;
|
2294 |
-
|
2295 |
-
case 'text':
|
2296 |
-
case 'hidden':
|
2297 |
-
default:
|
2298 |
-
value = input.value;
|
2299 |
-
break;
|
2300 |
-
|
2301 |
-
}
|
2302 |
-
|
2303 |
-
return value;
|
2304 |
-
},
|
2305 |
-
/* Add data-map-form-field attr to input */
|
2306 |
-
addDataAttr: function(formInput, match) {
|
2307 |
-
|
2308 |
-
var getAllInputs = document.getElementsByName(formInput.name);
|
2309 |
-
for (var i = getAllInputs.length - 1; i >= 0; i--) {
|
2310 |
-
if (!formInput.dataset.mapFormField) {
|
2311 |
-
getAllInputs[i].dataset.mapFormField = match;
|
2312 |
-
}
|
2313 |
-
};
|
2314 |
-
},
|
2315 |
-
/* Optimize FieldMapArray array for fewer lookups */
|
2316 |
-
removeArrayItem: function(array, item) {
|
2317 |
-
if (array.indexOf) {
|
2318 |
-
index = array.indexOf(item);
|
2319 |
-
} else {
|
2320 |
-
for (index = array.length - 1; index >= 0; --index) {
|
2321 |
-
if (array[index] === item) {
|
2322 |
-
break;
|
2323 |
-
}
|
2324 |
-
}
|
2325 |
-
}
|
2326 |
-
if (index >= 0) {
|
2327 |
-
array.splice(index, 1);
|
2328 |
-
}
|
2329 |
-
//_inbound.deBugger('forms', 'removed ' + item + " from array");
|
2330 |
-
//console.log('removed ' + item + " from array");
|
2331 |
-
return;
|
2332 |
-
},
|
2333 |
-
/* Look for siblings that are form labels */
|
2334 |
-
siblingsIsLabel: function(input) {
|
2335 |
-
var siblings = this.getSiblings(input);
|
2336 |
-
var labels = [];
|
2337 |
-
for (var i = siblings.length - 1; i >= 0; i--) {
|
2338 |
-
if (siblings[i].nodeName.toLowerCase() === 'label') {
|
2339 |
-
labels.push(siblings[i]);
|
2340 |
-
}
|
2341 |
-
};
|
2342 |
-
/* if only 1 label */
|
2343 |
-
if (labels.length > 0 && labels.length < 2) {
|
2344 |
-
return labels;
|
2345 |
-
}
|
2346 |
-
|
2347 |
-
return false;
|
2348 |
-
},
|
2349 |
-
getChildren: function(n, skipMe) {
|
2350 |
-
var r = [];
|
2351 |
-
var elem = null;
|
2352 |
-
for (; n; n = n.nextSibling)
|
2353 |
-
if (n.nodeType == 1 && n != skipMe)
|
2354 |
-
r.push(n);
|
2355 |
-
return r;
|
2356 |
-
},
|
2357 |
-
getSiblings: function(n) {
|
2358 |
-
return this.getChildren(n.parentNode.firstChild, n);
|
2359 |
-
},
|
2360 |
-
/* Check parent elements inside form for labels */
|
2361 |
-
CheckParentForLabel: function(element) {
|
2362 |
-
if (element.nodeName === 'FORM') {
|
2363 |
-
return null;
|
2364 |
-
}
|
2365 |
-
do {
|
2366 |
-
var labels = element.getElementsByTagName("label");
|
2367 |
-
if (labels.length > 0 && labels.length < 2) {
|
2368 |
-
return element.getElementsByTagName("label");
|
2369 |
-
}
|
2370 |
-
|
2371 |
-
} while (element = element.parentNode);
|
2372 |
-
|
2373 |
-
return null;
|
2374 |
-
},
|
2375 |
-
/* Validate Common Email addresses */
|
2376 |
-
mailCheck: function() {
|
2377 |
-
var email_input = document.querySelector('.inbound-email');
|
2378 |
-
if (email_input) {
|
2379 |
-
//
|
2380 |
-
utils.addListener(email_input, 'blur', this.mailCheck);
|
2381 |
-
|
2382 |
-
Mailcheck.run({
|
2383 |
-
email: document.querySelector('.inbound-email').value,
|
2384 |
-
suggested: function(suggestion) {
|
2385 |
-
// callback code
|
2386 |
-
|
2387 |
-
var suggest = document.querySelector('.email_suggestion');
|
2388 |
-
if (suggest) {
|
2389 |
-
utils.removeElement(suggest);
|
2390 |
-
}
|
2391 |
-
var el = document.createElement("span");
|
2392 |
-
el.innerHTML = "<span class=\"email_suggestion\">Did youu mean <b><i id='email_correction' style='cursor: pointer;' title=\"click to update\">" + suggestion.full + "</b></i>?</span>";
|
2393 |
-
email_input.parentNode.insertBefore(el, email_input.nextSibling);
|
2394 |
-
var update = document.getElementById('email_correction');
|
2395 |
-
utils.addListener(update, 'click', function() {
|
2396 |
-
email_input.value = update.innerHTML;
|
2397 |
-
update.parentNode.parentNode.innerHTML = "Fixed!";
|
2398 |
-
});
|
2399 |
-
},
|
2400 |
-
empty: function() {
|
2401 |
-
//$(".email_suggestion").html("No Suggestions :(");
|
2402 |
-
}
|
2403 |
-
});
|
2404 |
-
}
|
2405 |
-
}
|
2406 |
-
|
2407 |
-
};
|
2408 |
-
/* Mailcheck */
|
2409 |
-
if (typeof Mailcheck === "undefined") {
|
2410 |
-
var Mailcheck = {
|
2411 |
-
domainThreshold: 1,
|
2412 |
-
topLevelThreshold: 3,
|
2413 |
-
|
2414 |
-
defaultDomains: ["yahoo.com", "google.com", "hotmail.com", "gmail.com", "me.com", "aol.com", "mac.com",
|
2415 |
-
"live.com", "comcast.net", "googlemail.com", "msn.com", "hotmail.co.uk", "yahoo.co.uk",
|
2416 |
-
"facebook.com", "verizon.net", "sbcglobal.net", "att.net", "gmx.com", "mail.com", "outlook.com", "icloud.com"
|
2417 |
-
],
|
2418 |
-
|
2419 |
-
defaultTopLevelDomains: ["co.jp", "co.uk", "com", "net", "org", "info", "edu", "gov", "mil", "ca", "de"],
|
2420 |
-
|
2421 |
-
run: function(opts) {
|
2422 |
-
opts.domains = opts.domains || Mailcheck.defaultDomains;
|
2423 |
-
opts.topLevelDomains = opts.topLevelDomains || Mailcheck.defaultTopLevelDomains;
|
2424 |
-
opts.distanceFunction = opts.distanceFunction || Mailcheck.sift3Distance;
|
2425 |
-
|
2426 |
-
var defaultCallback = function(result) {
|
2427 |
-
return result;
|
2428 |
-
};
|
2429 |
-
var suggestedCallback = opts.suggested || defaultCallback;
|
2430 |
-
var emptyCallback = opts.empty || defaultCallback;
|
2431 |
-
|
2432 |
-
var result = Mailcheck.suggest(Mailcheck.encodeEmail(opts.email), opts.domains, opts.topLevelDomains, opts.distanceFunction);
|
2433 |
-
|
2434 |
-
return result ? suggestedCallback(result) : emptyCallback();
|
2435 |
-
},
|
2436 |
-
|
2437 |
-
suggest: function(email, domains, topLevelDomains, distanceFunction) {
|
2438 |
-
email = email.toLowerCase();
|
2439 |
-
|
2440 |
-
var emailParts = this.splitEmail(email);
|
2441 |
-
|
2442 |
-
var closestDomain = this.findClosestDomain(emailParts.domain, domains, distanceFunction, this.domainThreshold);
|
2443 |
-
|
2444 |
-
if (closestDomain) {
|
2445 |
-
if (closestDomain != emailParts.domain) {
|
2446 |
-
// The email address closely matches one of the supplied domains; return a suggestion
|
2447 |
-
return {
|
2448 |
-
address: emailParts.address,
|
2449 |
-
domain: closestDomain,
|
2450 |
-
full: emailParts.address + "@" + closestDomain
|
2451 |
-
};
|
2452 |
-
}
|
2453 |
-
} else {
|
2454 |
-
// The email address does not closely match one of the supplied domains
|
2455 |
-
var closestTopLevelDomain = this.findClosestDomain(emailParts.topLevelDomain, topLevelDomains, distanceFunction, this.topLevelThreshold);
|
2456 |
-
if (emailParts.domain && closestTopLevelDomain && closestTopLevelDomain != emailParts.topLevelDomain) {
|
2457 |
-
// The email address may have a mispelled top-level domain; return a suggestion
|
2458 |
-
var domain = emailParts.domain;
|
2459 |
-
closestDomain = domain.substring(0, domain.lastIndexOf(emailParts.topLevelDomain)) + closestTopLevelDomain;
|
2460 |
-
return {
|
2461 |
-
address: emailParts.address,
|
2462 |
-
domain: closestDomain,
|
2463 |
-
full: emailParts.address + "@" + closestDomain
|
2464 |
-
};
|
2465 |
-
}
|
2466 |
-
}
|
2467 |
-
/* The email address exactly matches one of the supplied domains, does not closely
|
2468 |
-
* match any domain and does not appear to simply have a mispelled top-level domain,
|
2469 |
-
* or is an invalid email address; do not return a suggestion.
|
2470 |
-
*/
|
2471 |
-
return false;
|
2472 |
-
},
|
2473 |
-
|
2474 |
-
findClosestDomain: function(domain, domains, distanceFunction, threshold) {
|
2475 |
-
threshold = threshold || this.topLevelThreshold;
|
2476 |
-
var dist;
|
2477 |
-
var minDist = 99;
|
2478 |
-
var closestDomain = null;
|
2479 |
-
|
2480 |
-
if (!domain || !domains) {
|
2481 |
-
return false;
|
2482 |
-
}
|
2483 |
-
if (!distanceFunction) {
|
2484 |
-
distanceFunction = this.sift3Distance;
|
2485 |
-
}
|
2486 |
-
|
2487 |
-
for (var i = 0; i < domains.length; i++) {
|
2488 |
-
if (domain === domains[i]) {
|
2489 |
-
return domain;
|
2490 |
-
}
|
2491 |
-
dist = distanceFunction(domain, domains[i]);
|
2492 |
-
if (dist < minDist) {
|
2493 |
-
minDist = dist;
|
2494 |
-
closestDomain = domains[i];
|
2495 |
-
}
|
2496 |
-
}
|
2497 |
-
|
2498 |
-
if (minDist <= threshold && closestDomain !== null) {
|
2499 |
-
return closestDomain;
|
2500 |
-
} else {
|
2501 |
-
return false;
|
2502 |
-
}
|
2503 |
-
},
|
2504 |
-
|
2505 |
-
sift3Distance: function(s1, s2) {
|
2506 |
-
// sift3: http://siderite.blogspot.com/2007/04/super-fast-and-accurate-string-distance.html
|
2507 |
-
if (s1 === null || s1.length === 0) {
|
2508 |
-
if (s2 === null || s2.length === 0) {
|
2509 |
-
return 0;
|
2510 |
-
} else {
|
2511 |
-
return s2.length;
|
2512 |
-
}
|
2513 |
-
}
|
2514 |
-
|
2515 |
-
if (s2 === null || s2.length === 0) {
|
2516 |
-
return s1.length;
|
2517 |
-
}
|
2518 |
-
|
2519 |
-
var c = 0;
|
2520 |
-
var offset1 = 0;
|
2521 |
-
var offset2 = 0;
|
2522 |
-
var lcs = 0;
|
2523 |
-
var maxOffset = 5;
|
2524 |
-
|
2525 |
-
while ((c + offset1 < s1.length) && (c + offset2 < s2.length)) {
|
2526 |
-
if (s1.charAt(c + offset1) == s2.charAt(c + offset2)) {
|
2527 |
-
lcs++;
|
2528 |
-
} else {
|
2529 |
-
offset1 = 0;
|
2530 |
-
offset2 = 0;
|
2531 |
-
for (var i = 0; i < maxOffset; i++) {
|
2532 |
-
if ((c + i < s1.length) && (s1.charAt(c + i) == s2.charAt(c))) {
|
2533 |
-
offset1 = i;
|
2534 |
-
break;
|
2535 |
-
}
|
2536 |
-
if ((c + i < s2.length) && (s1.charAt(c) == s2.charAt(c + i))) {
|
2537 |
-
offset2 = i;
|
2538 |
-
break;
|
2539 |
-
}
|
2540 |
-
}
|
2541 |
-
}
|
2542 |
-
c++;
|
2543 |
-
}
|
2544 |
-
return (s1.length + s2.length) / 2 - lcs;
|
2545 |
-
},
|
2546 |
-
|
2547 |
-
splitEmail: function(email) {
|
2548 |
-
var parts = email.trim().split("@");
|
2549 |
-
|
2550 |
-
if (parts.length < 2) {
|
2551 |
-
return false;
|
2552 |
-
}
|
2553 |
-
|
2554 |
-
for (var i = 0; i < parts.length; i++) {
|
2555 |
-
if (parts[i] === "") {
|
2556 |
-
return false;
|
2557 |
-
}
|
2558 |
-
}
|
2559 |
-
|
2560 |
-
var domain = parts.pop();
|
2561 |
-
var domainParts = domain.split(".");
|
2562 |
-
var tld = "";
|
2563 |
-
|
2564 |
-
if (domainParts.length === 0) {
|
2565 |
-
// The address does not have a top-level domain
|
2566 |
-
return false;
|
2567 |
-
} else if (domainParts.length == 1) {
|
2568 |
-
// The address has only a top-level domain (valid under RFC)
|
2569 |
-
tld = domainParts[0];
|
2570 |
-
} else {
|
2571 |
-
// The address has a domain and a top-level domain
|
2572 |
-
for (var i = 1; i < domainParts.length; i++) {
|
2573 |
-
tld += domainParts[i] + ".";
|
2574 |
-
}
|
2575 |
-
if (domainParts.length >= 2) {
|
2576 |
-
tld = tld.substring(0, tld.length - 1);
|
2577 |
-
}
|
2578 |
-
}
|
2579 |
-
|
2580 |
-
return {
|
2581 |
-
topLevelDomain: tld,
|
2582 |
-
domain: domain,
|
2583 |
-
address: parts.join("@")
|
2584 |
-
};
|
2585 |
-
},
|
2586 |
-
|
2587 |
-
// Encode the email address to prevent XSS but leave in valid
|
2588 |
-
// characters, following this official spec:
|
2589 |
-
// http://en.wikipedia.org/wiki/Email_address#Syntax
|
2590 |
-
encodeEmail: function(email) {
|
2591 |
-
var result = encodeURI(email);
|
2592 |
-
result = result.replace("%20", " ").replace("%25", "%").replace("%5E", "^")
|
2593 |
-
.replace("%60", "`").replace("%7B", "{").replace("%7C", "|")
|
2594 |
-
.replace("%7D", "}");
|
2595 |
-
return result;
|
2596 |
-
}
|
2597 |
-
};
|
2598 |
-
} // End Mailcheck
|
2599 |
-
|
2600 |
-
|
2601 |
-
return _inbound;
|
2602 |
-
|
2603 |
-
})(_inbound || {});
|
2604 |
-
|
2605 |
-
/**
|
2606 |
-
* # Analytics Events
|
2607 |
-
*
|
2608 |
-
* Events are triggered throughout the visitors journey through the site. See more on [Inbound Now][in]
|
2609 |
-
*
|
2610 |
-
* @
|
2611 |
-
* @
|
2612 |
-
* @version 0.0.2
|
2613 |
-
*
|
2614 |
-
* [in]: http://www.inboundnow.com/
|
2615 |
-
*/
|
2616 |
-
|
2617 |
-
// Add object to _inbound
|
2618 |
-
var _inboundEvents = (function(_inbound) {
|
2619 |
-
|
2620 |
-
|
2621 |
-
_inbound.trigger = function(trigger, data) {
|
2622 |
-
_inbound.Events[trigger](data);
|
2623 |
-
|
2624 |
-
};
|
2625 |
-
|
2626 |
-
/*!
|
2627 |
-
*
|
2628 |
-
* Private Function that Fires & Emits Events
|
2629 |
-
*
|
2630 |
-
* There are three options for firing events and they trigger in this order:
|
2631 |
-
*
|
2632 |
-
* 1. Vanilla JS dispatch event
|
2633 |
-
* 2. `_inbound.add_action('namespace', callback, priority)`
|
2634 |
-
* 3. jQuery Trigger `jQuery.trigger('namespace', callback);`
|
2635 |
-
*
|
2636 |
-
* The Event `data` can be filtered before events are triggered
|
2637 |
-
* with filters. Example: filter_ + "namespace"
|
2638 |
-
*
|
2639 |
-
* ```js
|
2640 |
-
* // Filter Form Data before submissionsz
|
2641 |
-
* _inbound.add_filter( 'filter_form_before_submission', event_filter_data_example, 10);
|
2642 |
-
*
|
2643 |
-
* function event_filter_data_example(data) {
|
2644 |
-
* var data = data || {};
|
2645 |
-
* // Do something with data
|
2646 |
-
* return data;
|
2647 |
-
* }
|
2648 |
-
* ```
|
2649 |
-
*
|
2650 |
-
* @param {string} eventName Name of the event
|
2651 |
-
* @param {object} data Data passed to external functions/triggers
|
2652 |
-
* @param {object} options Options for configuring events
|
2653 |
-
* @return {null} Nothing returned
|
2654 |
-
*/
|
2655 |
-
function fireEvent(eventName, data, options) {
|
2656 |
-
var data = data || {};
|
2657 |
-
options = options || {};
|
2658 |
-
|
2659 |
-
/*! defaults for JS dispatch event */
|
2660 |
-
options.bubbles = options.bubbles || true,
|
2661 |
-
options.cancelable = options.cancelable || true;
|
2662 |
-
|
2663 |
-
/*! Customize Data via filter_ + "namespace" */
|
2664 |
-
data = _inbound.apply_filters('filter_' + eventName, data);
|
2665 |
-
|
2666 |
-
var is_IE_11 = !(window.ActiveXObject) && "ActiveXObject" in window;
|
2667 |
-
|
2668 |
-
if( typeof CustomEvent === 'function') {
|
2669 |
-
|
2670 |
-
var TriggerEvent = new CustomEvent(eventName, {
|
2671 |
-
detail: data,
|
2672 |
-
bubbles: options.bubbles,
|
2673 |
-
cancelable: options.cancelable
|
2674 |
-
});
|
2675 |
-
|
2676 |
-
} else {
|
2677 |
-
var TriggerEvent = document.createEvent("Event");
|
2678 |
-
TriggerEvent.initEvent(eventName, true, true);
|
2679 |
-
}
|
2680 |
-
|
2681 |
-
/*! 1. Trigger Pure Javascript Event See: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events for example on creating events */
|
2682 |
-
window.dispatchEvent(TriggerEvent);
|
2683 |
-
/*! 2. Trigger _inbound action */
|
2684 |
-
_inbound.do_action(eventName, data);
|
2685 |
-
/*! 3. jQuery trigger */
|
2686 |
-
triggerJQueryEvent(eventName, data);
|
2687 |
-
|
2688 |
-
// console.log('Action:' + eventName + " ran on ->", data);
|
2689 |
-
|
2690 |
-
}
|
2691 |
-
|
2692 |
-
function triggerJQueryEvent(eventName, data) {
|
2693 |
-
if (window.jQuery) {
|
2694 |
-
var data = data || {};
|
2695 |
-
/*! try catch here */
|
2696 |
-
jQuery(document).trigger(eventName, data);
|
2697 |
-
}
|
2698 |
-
};
|
2699 |
-
|
2700 |
-
var universalGA,
|
2701 |
-
classicGA,
|
2702 |
-
googleTagManager;
|
2703 |
-
|
2704 |
-
_inbound.Events = {
|
2705 |
-
|
2706 |
-
/**
|
2707 |
-
* # Event Usage
|
2708 |
-
*
|
2709 |
-
* Events are triggered throughout the visitors path through the site.
|
2710 |
-
* You can hook into these custom actions and filters much like WordPress Core
|
2711 |
-
*
|
2712 |
-
* See below for examples
|
2713 |
-
*/
|
2714 |
-
|
2715 |
-
/**
|
2716 |
-
* Adding Custom Actions
|
2717 |
-
* ------------------
|
2718 |
-
* You can hook into custom events throughout analytics. See the full list of available [events below](#all-events)
|
2719 |
-
*
|
2720 |
-
* `
|
2721 |
-
* _inbound.add_action( 'action_name', callback, priority );
|
2722 |
-
* `
|
2723 |
-
*
|
2724 |
-
* ```js
|
2725 |
-
* // example:
|
2726 |
-
*
|
2727 |
-
* // Add custom function to `page_visit` event
|
2728 |
-
* _inbound.add_action( 'page_visit', callback, 10 );
|
2729 |
-
*
|
2730 |
-
* // add custom callback to trigger when `page_visit` fires
|
2731 |
-
* function callback(pageData){
|
2732 |
-
* var pageData = pageData || {};
|
2733 |
-
* // run callback on 'page_visit' trigger
|
2734 |
-
* alert(pageData.title);
|
2735 |
-
* }
|
2736 |
-
* ```
|
2737 |
-
*
|
2738 |
-
* @param {string} action_name Name of the event trigger
|
2739 |
-
* @param {function} callback function to trigger when event happens
|
2740 |
-
* @param {int} priority Order to trigger the event in
|
2741 |
-
*
|
2742 |
-
*/
|
2743 |
-
|
2744 |
-
/**
|
2745 |
-
* Removing Custom Actions
|
2746 |
-
* ------------------
|
2747 |
-
* You can hook into custom events throughout analytics. See the full list of available [events below](#all-events)
|
2748 |
-
*
|
2749 |
-
* `
|
2750 |
-
* _inbound.remove_action( 'action_name');
|
2751 |
-
* `
|
2752 |
-
*
|
2753 |
-
* ```js
|
2754 |
-
* // example:
|
2755 |
-
*
|
2756 |
-
* _inbound.remove_action( 'page_visit');
|
2757 |
-
* // all 'page_visit' actions have been deregistered
|
2758 |
-
* ```
|
2759 |
-
*
|
2760 |
-
* @param {string} action_name Name of the event trigger
|
2761 |
-
*
|
2762 |
-
*/
|
2763 |
-
|
2764 |
-
/**
|
2765 |
-
* # Event List
|
2766 |
-
*
|
2767 |
-
* Events are triggered throughout the visitors journey through the site
|
2768 |
-
*/
|
2769 |
-
|
2770 |
-
/**
|
2771 |
-
* Triggers when analyics has finished loading
|
2772 |
-
*/
|
2773 |
-
analytics_ready: function() {
|
2774 |
-
var ops = {
|
2775 |
-
'opt1': true
|
2776 |
-
};
|
2777 |
-
var data = {
|
2778 |
-
'data': 'xyxy'
|
2779 |
-
};
|
2780 |
-
fireEvent('analytics_ready', data, ops);
|
2781 |
-
},
|
2782 |
-
/**
|
2783 |
-
* Triggers when the browser url params are parsed. You can perform custom actions
|
2784 |
-
* if specific url params exist.
|
2785 |
-
*
|
2786 |
-
* ```js
|
2787 |
-
* // Usage:
|
2788 |
-
*
|
2789 |
-
* // Add function to 'url_parameters' event
|
2790 |
-
* _inbound.add_action( 'url_parameters', url_parameters_func_example, 10);
|
2791 |
-
*
|
2792 |
-
* function url_parameters_func_example(urlParams) {
|
2793 |
-
* var urlParams = urlParams || {};
|
2794 |
-
* for( var param in urlParams ) {
|
2795 |
-
* var key = param;
|
2796 |
-
* var value = urlParams[param];
|
2797 |
-
* }
|
2798 |
-
* // All URL Params
|
2799 |
-
* alert(JSON.stringify(urlParams));
|
2800 |
-
*
|
2801 |
-
* // Check if URL parameter `utm_source` exists and matches value
|
2802 |
-
* if(urlParams.utm_source === "twitter") {
|
2803 |
-
* alert('This person is from twitter!');
|
2804 |
-
* }
|
2805 |
-
* }
|
2806 |
-
* ```
|
2807 |
-
*/
|
2808 |
-
url_parameters: function(data) {
|
2809 |
-
fireEvent('url_parameters', data);
|
2810 |
-
},
|
2811 |
-
/**
|
2812 |
-
* Triggers when session starts
|
2813 |
-
*
|
2814 |
-
* ```js
|
2815 |
-
* // Usage:
|
2816 |
-
*
|
2817 |
-
* // Add function to 'session_start' event
|
2818 |
-
* _inbound.add_action( 'session_start', session_start_func_example, 10);
|
2819 |
-
*
|
2820 |
-
* function session_start_func_example(data) {
|
2821 |
-
* var data = data || {};
|
2822 |
-
* // session start. Do something for new visitor
|
2823 |
-
* }
|
2824 |
-
* ```
|
2825 |
-
*/
|
2826 |
-
session_start: function() {
|
2827 |
-
console.log('');
|
2828 |
-
fireEvent('session_start');
|
2829 |
-
},
|
2830 |
-
/**
|
2831 |
-
* Triggers when visitor session goes idle for more than 30 minutes.
|
2832 |
-
*
|
2833 |
-
* ```js
|
2834 |
-
* // Usage:
|
2835 |
-
*
|
2836 |
-
* // Add function to 'session_end' event
|
2837 |
-
* _inbound.add_action( 'session_end', session_end_func_example, 10);
|
2838 |
-
*
|
2839 |
-
* function session_end_func_example(data) {
|
2840 |
-
* var data = data || {};
|
2841 |
-
* // Do something when session ends
|
2842 |
-
* alert("Hey! It's been 30 minutes... where did you go?");
|
2843 |
-
* }
|
2844 |
-
* ```
|
2845 |
-
*/
|
2846 |
-
session_end: function(clockTime) {
|
2847 |
-
fireEvent('session_end', clockTime);
|
2848 |
-
console.log('Session End');
|
2849 |
-
},
|
2850 |
-
/**
|
2851 |
-
* Triggers if active session is detected
|
2852 |
-
*
|
2853 |
-
* ```js
|
2854 |
-
* // Usage:
|
2855 |
-
*
|
2856 |
-
* // Add function to 'session_active' event
|
2857 |
-
* _inbound.add_action( 'session_active', session_active_func_example, 10);
|
2858 |
-
*
|
2859 |
-
* function session_active_func_example(data) {
|
2860 |
-
* var data = data || {};
|
2861 |
-
* // session active
|
2862 |
-
* }
|
2863 |
-
* ```
|
2864 |
-
*/
|
2865 |
-
session_active: function() {
|
2866 |
-
fireEvent('session_active');
|
2867 |
-
},
|
2868 |
-
/**
|
2869 |
-
* Triggers when visitor session goes idle. Idling occurs after 60 seconds of
|
2870 |
-
* inactivity or when the visitor switches browser tabs
|
2871 |
-
*
|
2872 |
-
* ```js
|
2873 |
-
* // Usage:
|
2874 |
-
*
|
2875 |
-
* // Add function to 'session_idle' event
|
2876 |
-
* _inbound.add_action( 'session_idle', session_idle_func_example, 10);
|
2877 |
-
*
|
2878 |
-
* function session_idle_func_example(data) {
|
2879 |
-
* var data = data || {};
|
2880 |
-
* // Do something when session idles
|
2881 |
-
* alert('Here is a special offer for you!');
|
2882 |
-
* }
|
2883 |
-
* ```
|
2884 |
-
*/
|
2885 |
-
session_idle: function(clockTime) {
|
2886 |
-
fireEvent('session_idle', clockTime);
|
2887 |
-
},
|
2888 |
-
/**
|
2889 |
-
* Triggers when session is already active and gets resumed
|
2890 |
-
*
|
2891 |
-
* ```js
|
2892 |
-
* // Usage:
|
2893 |
-
*
|
2894 |
-
* // Add function to 'session_resume' event
|
2895 |
-
* _inbound.add_action( 'session_resume', session_resume_func_example, 10);
|
2896 |
-
*
|
2897 |
-
* function session_resume_func_example(data) {
|
2898 |
-
* var data = data || {};
|
2899 |
-
* // Session exists and is being resumed
|
2900 |
-
* }
|
2901 |
-
* ```
|
2902 |
-
*/
|
2903 |
-
session_resume: function() {
|
2904 |
-
fireEvent('session_resume');
|
2905 |
-
},
|
2906 |
-
/**
|
2907 |
-
* Session emitter. Runs every 10 seconds. This is a useful function for
|
2908 |
-
* pinging third party services
|
2909 |
-
*
|
2910 |
-
* ```js
|
2911 |
-
* // Usage:
|
2912 |
-
*
|
2913 |
-
* // Add session_heartbeat_func_example function to 'session_heartbeat' event
|
2914 |
-
* _inbound.add_action( 'session_heartbeat', session_heartbeat_func_example, 10);
|
2915 |
-
*
|
2916 |
-
* function session_heartbeat_func_example(data) {
|
2917 |
-
* var data = data || {};
|
2918 |
-
* // Do something with every 10 seconds
|
2919 |
-
* }
|
2920 |
-
* ```
|
2921 |
-
*/
|
2922 |
-
session_heartbeat: function(clockTime) {
|
2923 |
-
var data = {
|
2924 |
-
'clock': clockTime,
|
2925 |
-
'leadData': InboundLeadData
|
2926 |
-
};
|
2927 |
-
fireEvent('session_heartbeat', data);
|
2928 |
-
},
|
2929 |
-
/**
|
2930 |
-
* Triggers Every Page View
|
2931 |
-
*
|
2932 |
-
* ```js
|
2933 |
-
* // Usage:
|
2934 |
-
*
|
2935 |
-
* // Add function to 'page_visit' event
|
2936 |
-
* _inbound.add_action( 'page_visit', page_visit_func_example, 10);
|
2937 |
-
*
|
2938 |
-
* function session_idle_func_example(pageData) {
|
2939 |
-
* var pageData = pageData || {};
|
2940 |
-
* if( pageData.view_count > 8 ){
|
2941 |
-
* alert('Wow you have been to this page more than 8 times.');
|
2942 |
-
* }
|
2943 |
-
* }
|
2944 |
-
* ```
|
2945 |
-
*/
|
2946 |
-
page_visit: function(pageData) {
|
2947 |
-
fireEvent('page_view', pageData);
|
2948 |
-
},
|
2949 |
-
/**
|
2950 |
-
* Triggers If the visitor has never seen the page before
|
2951 |
-
*
|
2952 |
-
* ```js
|
2953 |
-
* // Usage:
|
2954 |
-
*
|
2955 |
-
* // Add function to 'page_first_visit' event
|
2956 |
-
* _inbound.add_action( 'page_first_visit', page_first_visit_func_example, 10);
|
2957 |
-
*
|
2958 |
-
* function page_first_visit_func_example(pageData) {
|
2959 |
-
* var pageData = pageData || {};
|
2960 |
-
* alert('Welcome to this page! Its the first time you have seen it')
|
2961 |
-
* }
|
2962 |
-
* ```
|
2963 |
-
*/
|
2964 |
-
page_first_visit: function(pageData) {
|
2965 |
-
fireEvent('page_first_visit');
|
2966 |
-
_inbound.deBugger('pages', 'First Ever Page View of this Page');
|
2967 |
-
},
|
2968 |
-
/**
|
2969 |
-
* Triggers If the visitor has seen the page before
|
2970 |
-
*
|
2971 |
-
* ```js
|
2972 |
-
* // Usage:
|
2973 |
-
*
|
2974 |
-
* // Add function to 'page_revisit' event
|
2975 |
-
* _inbound.add_action( 'page_revisit', page_revisit_func_example, 10);
|
2976 |
-
*
|
2977 |
-
* function page_revisit_func_example(pageData) {
|
2978 |
-
* var pageData = pageData || {};
|
2979 |
-
* alert('Welcome back to this page!');
|
2980 |
-
* // Show visitor special content/offer
|
2981 |
-
* }
|
2982 |
-
* ```
|
2983 |
-
*/
|
2984 |
-
page_revisit: function(pageData) {
|
2985 |
-
|
2986 |
-
fireEvent('page_revisit', pageData);
|
2987 |
-
|
2988 |
-
var logger = function() {
|
2989 |
-
console.log('pageData', pageData);
|
2990 |
-
console.log('Page Revisit viewed ' + pageData + " times");
|
2991 |
-
}
|
2992 |
-
_inbound.deBugger('pages', status, logger);
|
2993 |
-
},
|
2994 |
-
|
2995 |
-
/**
|
2996 |
-
* `tab_hidden` is triggered when the visitor switches browser tabs
|
2997 |
-
*
|
2998 |
-
* ```js
|
2999 |
-
* // Usage:
|
3000 |
-
*
|
3001 |
-
* // Adding the callback
|
3002 |
-
* function tab_hidden_function( data ) {
|
3003 |
-
* alert('The Tab is Hidden');
|
3004 |
-
* };
|
3005 |
-
*
|
3006 |
-
* // Hook the function up the the `tab_hidden` event
|
3007 |
-
* _inbound.add_action( 'tab_hidden', tab_hidden_function, 10 );
|
3008 |
-
* ```
|
3009 |
-
*/
|
3010 |
-
tab_hidden: function(data) {
|
3011 |
-
_inbound.deBugger('pages', 'Tab Hidden');
|
3012 |
-
fireEvent('tab_hidden');
|
3013 |
-
},
|
3014 |
-
/**
|
3015 |
-
* `tab_visible` is triggered when the visitor switches back to the sites tab
|
3016 |
-
*
|
3017 |
-
* ```js
|
3018 |
-
* // Usage:
|
3019 |
-
*
|
3020 |
-
* // Adding the callback
|
3021 |
-
* function tab_visible_function( data ) {
|
3022 |
-
* alert('Welcome back to this tab!');
|
3023 |
-
* // trigger popup or offer special discount etc.
|
3024 |
-
* };
|
3025 |
-
*
|
3026 |
-
* // Hook the function up the the `tab_visible` event
|
3027 |
-
* _inbound.add_action( 'tab_visible', tab_visible_function, 10 );
|
3028 |
-
* ```
|
3029 |
-
*/
|
3030 |
-
tab_visible: function(data) {
|
3031 |
-
_inbound.deBugger('pages', 'Tab Visible');
|
3032 |
-
fireEvent('tab_visible');
|
3033 |
-
},
|
3034 |
-
/**
|
3035 |
-
* `tab_mouseout` is triggered when the visitor mouses out of the browser window.
|
3036 |
-
* This is especially useful for exit popups
|
3037 |
-
*
|
3038 |
-
* ```js
|
3039 |
-
* // Usage:
|
3040 |
-
*
|
3041 |
-
* // Adding the callback
|
3042 |
-
* function tab_mouseout_function( data ) {
|
3043 |
-
* alert("Wait don't Go");
|
3044 |
-
* // trigger popup or offer special discount etc.
|
3045 |
-
* };
|
3046 |
-
*
|
3047 |
-
* // Hook the function up the the `tab_mouseout` event
|
3048 |
-
* _inbound.add_action( 'tab_mouseout', tab_mouseout_function, 10 );
|
3049 |
-
* ```
|
3050 |
-
*/
|
3051 |
-
tab_mouseout: function(data) {
|
3052 |
-
_inbound.deBugger('pages', 'Tab Mouseout');
|
3053 |
-
fireEvent('tab_mouseout');
|
3054 |
-
},
|
3055 |
-
/**
|
3056 |
-
* `form_input_change` is triggered when tracked form inputs change
|
3057 |
-
* You can use this to add additional validation or set conditional triggers
|
3058 |
-
*
|
3059 |
-
* ```js
|
3060 |
-
* // Usage:
|
3061 |
-
*
|
3062 |
-
* ```
|
3063 |
-
*/
|
3064 |
-
form_input_change: function(inputData) {
|
3065 |
-
var logger = function() {
|
3066 |
-
console.log(inputData);
|
3067 |
-
//console.log('Page Revisit viewed ' + pageData + " times");
|
3068 |
-
}
|
3069 |
-
_inbound.deBugger('forms', 'inputData change. Data=', logger);
|
3070 |
-
fireEvent('form_input_change', inputData);
|
3071 |
-
},
|
3072 |
-
/**
|
3073 |
-
* `form_before_submission` is triggered before the form is submitted to the server.
|
3074 |
-
* You can filter the data here or send it to third party services
|
3075 |
-
*
|
3076 |
-
* ```js
|
3077 |
-
* // Usage:
|
3078 |
-
*
|
3079 |
-
* // Adding the callback
|
3080 |
-
* function form_before_submission_function( data ) {
|
3081 |
-
* var data = data || {};
|
3082 |
-
* // filter form data
|
3083 |
-
* };
|
3084 |
-
*
|
3085 |
-
* // Hook the function up the the `form_before_submission` event
|
3086 |
-
* _inbound.add_action( 'form_before_submission', form_before_submission_function, 10 );
|
3087 |
-
* ```
|
3088 |
-
*/
|
3089 |
-
form_before_submission: function(formData) {
|
3090 |
-
fireEvent('form_before_submission', formData);
|
3091 |
-
},
|
3092 |
-
/**
|
3093 |
-
* `form_after_submission` is triggered after the form is submitted to the server.
|
3094 |
-
* You can filter the data here or send it to third party services
|
3095 |
-
*
|
3096 |
-
* ```js
|
3097 |
-
* // Usage:
|
3098 |
-
*
|
3099 |
-
* // Adding the callback
|
3100 |
-
* function form_after_submission_function( data ) {
|
3101 |
-
* var data = data || {};
|
3102 |
-
* // filter form data
|
3103 |
-
* };
|
3104 |
-
*
|
3105 |
-
* // Hook the function up the the `form_after_submission` event
|
3106 |
-
* _inbound.add_action( 'form_after_submission', form_after_submission_function, 10 );
|
3107 |
-
* ```
|
3108 |
-
*/
|
3109 |
-
form_after_submission: function(formData) {
|
3110 |
-
|
3111 |
-
fireEvent('form_after_submission', formData);
|
3112 |
-
|
3113 |
-
},
|
3114 |
-
/**
|
3115 |
-
* `search_before_caching` is triggered before the search is stored in the user's browser.
|
3116 |
-
* If a lead ID is set, the search data will be saved to the server when the next page loads.
|
3117 |
-
* You can filter the data here or send it to third party services
|
3118 |
-
*
|
3119 |
-
* ```js
|
3120 |
-
* // Usage:
|
3121 |
-
*
|
3122 |
-
* // Adding the callback
|
3123 |
-
* function search_before_caching_function( data ) {
|
3124 |
-
* var data = data || {};
|
3125 |
-
* // filter search data
|
3126 |
-
* };
|
3127 |
-
*
|
3128 |
-
* // Hook the function up the the `search_before_caching` event
|
3129 |
-
* _inbound.add_action( 'search_before_caching', search_before_caching_function, 10 );
|
3130 |
-
* ```
|
3131 |
-
*/
|
3132 |
-
search_before_caching: function(searchData) {
|
3133 |
-
fireEvent('search_before_caching', searchData);
|
3134 |
-
},
|
3135 |
-
/*! Scrol depth https://github.com/robflaherty/jquery-scrolldepth/blob/master/jquery.scrolldepth.js */
|
3136 |
-
|
3137 |
-
analyticsError: function(MLHttpRequest, textStatus, errorThrown) {
|
3138 |
-
var error = new CustomEvent("inbound_analytics_error", {
|
3139 |
-
detail: {
|
3140 |
-
MLHttpRequest: MLHttpRequest,
|
3141 |
-
textStatus: textStatus,
|
3142 |
-
errorThrown: errorThrown
|
3143 |
-
}
|
3144 |
-
});
|
3145 |
-
window.dispatchEvent(error);
|
3146 |
-
console.log('Page Save Error');
|
3147 |
-
}
|
3148 |
-
|
3149 |
-
};
|
3150 |
-
|
3151 |
-
return _inbound;
|
3152 |
-
|
3153 |
-
})(_inbound || {});
|
3154 |
-
|
3155 |
-
|
3156 |
-
function inboundFormNoRedirect(){
|
3157 |
-
/*button == the button that was clicked, form == the form that button belongs to, formRedirectUrl == the link that the form redirects to, if set*/
|
3158 |
-
|
3159 |
-
/*Get the button...*/
|
3160 |
-
/*If not an iframe*/
|
3161 |
-
if(window.frames.frameElement == null){
|
3162 |
-
var button = document.querySelectorAll('button.inbound-button-submit[disabled]')[0];
|
3163 |
-
}
|
3164 |
-
/*If it is an iframe*/
|
3165 |
-
else if(window.frames.frameElement.tagName.toLowerCase() == "iframe"){
|
3166 |
-
var button = window.frames.frameElement.contentWindow.document.querySelectorAll('button.inbound-button-submit')[0];
|
3167 |
-
}
|
3168 |
-
|
3169 |
-
if ( typeof button == 'undefined' ) {
|
3170 |
-
return;
|
3171 |
-
}
|
3172 |
-
|
3173 |
-
var form = button.form,
|
3174 |
-
formRedirectUrl = form.querySelectorAll('input[value][type="hidden"][name="inbound_furl"]:not([value=""])');
|
3175 |
-
|
3176 |
-
/*If the redirect link is not set, or there is a single space in it, the form isn't supposed to redirect. So set the action for void*/
|
3177 |
-
if(formRedirectUrl.length == 0 || formRedirectUrl[0]['value'] == 'IA=='){
|
3178 |
-
form.action = 'javascript:void(0)';
|
3179 |
-
}
|
3180 |
-
}
|
3181 |
-
|
3182 |
-
_inbound.add_action( 'form_before_submission', inboundFormNoRedirect, 10 );
|
3183 |
-
|
3184 |
-
function inboundFormNoRedirectContent(){
|
3185 |
-
|
3186 |
-
/*If not an iframe*/
|
3187 |
-
if(window.frames.frameElement == null){
|
3188 |
-
var button = document.querySelectorAll('button.inbound-button-submit[disabled]')[0];
|
3189 |
-
}
|
3190 |
-
/*If it is an iframe*/
|
3191 |
-
else if(window.frames.frameElement.tagName.toLowerCase() == "iframe"){
|
3192 |
-
var button = window.frames.frameElement.contentWindow.document.querySelectorAll('button.inbound-button-submit')[0];
|
3193 |
-
}
|
3194 |
-
|
3195 |
-
|
3196 |
-
if ( typeof button == 'undefined' ) {
|
3197 |
-
return;
|
3198 |
-
}
|
3199 |
-
|
3200 |
-
var form = button.form,
|
3201 |
-
formRedirectUrl = form.querySelectorAll('input[value][type="hidden"][name="inbound_furl"]:not([value=""])'),
|
3202 |
-
btnBackground = jQuery(button).css('background'),
|
3203 |
-
btnFontColor = jQuery(button).css('color'),
|
3204 |
-
btnHeight = jQuery(button).css('height'),
|
3205 |
-
spinner = button.getElementsByClassName('inbound-form-spinner');
|
3206 |
-
|
3207 |
-
if(formRedirectUrl.length == 0 || formRedirectUrl[0]['value'] == 'IA=='){
|
3208 |
-
jQuery(spinner).remove();
|
3209 |
-
jQuery(button).prepend('<div id="redir-check"><i class="fa fa-check-square" aria-hidden="true" style="background='+ btnBackground +'; color='+ btnFontColor +'; font-size:calc('+ btnHeight +' * .42);"></i></div>');
|
3210 |
-
}
|
3211 |
-
}
|
3212 |
-
|
3213 |
-
_inbound.add_action( 'form_after_submission', inboundFormNoRedirectContent, 10 );
|
3214 |
-
|
3215 |
-
/* LocalStorage Component */
|
3216 |
-
var InboundTotalStorage = (function (_inbound){
|
3217 |
-
|
3218 |
-
var supported, ls, mod = '_inbound';
|
3219 |
-
if ('localStorage' in window){
|
3220 |
-
try {
|
3221 |
-
ls = (typeof window.localStorage === 'undefined') ? undefined : window.localStorage;
|
3222 |
-
if (typeof ls == 'undefined' || typeof window.JSON == 'undefined'){
|
3223 |
-
supported = false;
|
3224 |
-
} else {
|
3225 |
-
supported = true;
|
3226 |
-
}
|
3227 |
-
window.localStorage.setItem(mod, '1');
|
3228 |
-
window.localStorage.removeItem(mod);
|
3229 |
-
}
|
3230 |
-
catch (err){
|
3231 |
-
supported = false;
|
3232 |
-
}
|
3233 |
-
}
|
3234 |
-
|
3235 |
-
/* Make the methods public */
|
3236 |
-
_inbound.totalStorage = function(key, value, options){
|
3237 |
-
return _inbound.totalStorage.impl.init(key, value);
|
3238 |
-
};
|
3239 |
-
|
3240 |
-
_inbound.totalStorage.setItem = function(key, value){
|
3241 |
-
return _inbound.totalStorage.impl.setItem(key, value);
|
3242 |
-
};
|
3243 |
-
|
3244 |
-
_inbound.totalStorage.getItem = function(key){
|
3245 |
-
return _inbound.totalStorage.impl.getItem(key);
|
3246 |
-
};
|
3247 |
-
|
3248 |
-
_inbound.totalStorage.getAll = function(){
|
3249 |
-
return _inbound.totalStorage.impl.getAll();
|
3250 |
-
};
|
3251 |
-
|
3252 |
-
_inbound.totalStorage.deleteItem = function(key){
|
3253 |
-
return _inbound.totalStorage.impl.deleteItem(key);
|
3254 |
-
};
|
3255 |
-
|
3256 |
-
|
3257 |
-
_inbound.totalStorage.impl = {
|
3258 |
-
|
3259 |
-
init: function(key, value){
|
3260 |
-
if (typeof value != 'undefined') {
|
3261 |
-
return this.setItem(key, value);
|
3262 |
-
} else {
|
3263 |
-
return this.getItem(key);
|
3264 |
-
}
|
3265 |
-
},
|
3266 |
-
|
3267 |
-
setItem: function(key, value){
|
3268 |
-
if (!supported){
|
3269 |
-
try {
|
3270 |
-
_inbound.Utils.createCookie(key, value);
|
3271 |
-
return value;
|
3272 |
-
} catch(e){
|
3273 |
-
console.log('Local Storage not supported by this browser. Install the cookie plugin on your site to take advantage of the same functionality. You can get it at https://github.com/carhartl/jquery-cookie');
|
3274 |
-
}
|
3275 |
-
}
|
3276 |
-
var saver = JSON.stringify(value);
|
3277 |
-
ls.setItem(key, saver);
|
3278 |
-
return this.parseResult(saver);
|
3279 |
-
},
|
3280 |
-
getItem: function(key){
|
3281 |
-
if (!supported){
|
3282 |
-
try {
|
3283 |
-
return this.parseResult(_inbound.Utils.readCookie(key));
|
3284 |
-
} catch(e){
|
3285 |
-
return null;
|
3286 |
-
}
|
3287 |
-
}
|
3288 |
-
var item = ls.getItem(key);
|
3289 |
-
return this.parseResult(item);
|
3290 |
-
},
|
3291 |
-
deleteItem: function(key){
|
3292 |
-
if (!supported){
|
3293 |
-
try {
|
3294 |
-
_inbound.Utils.eraseCookie(key, null);
|
3295 |
-
return true;
|
3296 |
-
} catch(e){
|
3297 |
-
return false;
|
3298 |
-
}
|
3299 |
-
}
|
3300 |
-
ls.removeItem(key);
|
3301 |
-
return true;
|
3302 |
-
},
|
3303 |
-
getAll: function(){
|
3304 |
-
var items = [];
|
3305 |
-
if (!supported){
|
3306 |
-
try {
|
3307 |
-
var pairs = document.cookie.split(";");
|
3308 |
-
for (var i = 0; i<pairs.length; i++){
|
3309 |
-
var pair = pairs[i].split('=');
|
3310 |
-
var key = pair[0];
|
3311 |
-
items.push({key:key, value:this.parseResult(_inbound.Utils.readCookie(key))});
|
3312 |
-
}
|
3313 |
-
} catch(e){
|
3314 |
-
return null;
|
3315 |
-
}
|
3316 |
-
} else {
|
3317 |
-
for (var j in ls){
|
3318 |
-
if (j.length){
|
3319 |
-
items.push({key:j, value:this.parseResult(ls.getItem(j))});
|
3320 |
-
}
|
3321 |
-
}
|
3322 |
-
}
|
3323 |
-
return items;
|
3324 |
-
},
|
3325 |
-
parseResult: function(res){
|
3326 |
-
var ret;
|
3327 |
-
try {
|
3328 |
-
ret = JSON.parse(res);
|
3329 |
-
if (typeof ret == 'undefined'){
|
3330 |
-
ret = res;
|
3331 |
-
}
|
3332 |
-
if (ret == 'true'){
|
3333 |
-
ret = true;
|
3334 |
-
}
|
3335 |
-
if (ret == 'false'){
|
3336 |
-
ret = false;
|
3337 |
-
}
|
3338 |
-
if (parseFloat(ret) == ret && typeof ret != "object"){
|
3339 |
-
ret = parseFloat(ret);
|
3340 |
-
}
|
3341 |
-
} catch(e){
|
3342 |
-
ret = res;
|
3343 |
-
}
|
3344 |
-
return ret;
|
3345 |
-
}
|
3346 |
-
};
|
3347 |
-
})(_inbound || {});
|
3348 |
-
/**
|
3349 |
-
* Leads API functions
|
3350 |
-
* @param Object _inbound - Main JS object
|
3351 |
-
* @return Object - include event triggers
|
3352 |
-
*/
|
3353 |
-
var _inboundLeadsAPI = (function(_inbound) {
|
3354 |
-
var httpRequest;
|
3355 |
-
_inbound.LeadsAPI = {
|
3356 |
-
init: function() {
|
3357 |
-
|
3358 |
-
var utils = _inbound.Utils,
|
3359 |
-
wp_lead_uid = utils.readCookie("wp_lead_uid"),
|
3360 |
-
wp_lead_id = utils.readCookie("wp_lead_id"),
|
3361 |
-
expire_check = utils.readCookie("lead_session_expire"); // check for session
|
3362 |
-
|
3363 |
-
if (!expire_check) {
|
3364 |
-
_inbound.deBugger('leads', 'expired vistor. Run Processes');
|
3365 |
-
//var data_to_lookup = global-localized-vars;
|
3366 |
-
if (wp_lead_id) {
|
3367 |
-
/* Get InboundLeadData */
|
3368 |
-
_inbound.LeadsAPI.getAllLeadData();
|
3369 |
-
}
|
3370 |
-
}
|
3371 |
-
},
|
3372 |
-
setGlobalLeadData: function(data) {
|
3373 |
-
InboundLeadData = data;
|
3374 |
-
},
|
3375 |
-
getAllLeadData: function(expire_check) {
|
3376 |
-
var wp_lead_id = _inbound.Utils.readCookie("wp_lead_id"),
|
3377 |
-
leadData = _inbound.totalStorage('inbound_lead_data'),
|
3378 |
-
leadDataExpire = _inbound.Utils.readCookie("lead_data_expire");
|
3379 |
-
data = {
|
3380 |
-
action: 'inbound_get_all_lead_data',
|
3381 |
-
wp_lead_id: wp_lead_id
|
3382 |
-
},
|
3383 |
-
success = function(returnData) {
|
3384 |
-
var leadData = JSON.parse(returnData);
|
3385 |
-
_inbound.LeadsAPI.setGlobalLeadData(leadData);
|
3386 |
-
_inbound.totalStorage('inbound_lead_data', leadData); // store lead data
|
3387 |
-
|
3388 |
-
/* Set 3 day timeout for checking DB for new lead data for Lead_Global var */
|
3389 |
-
var d = new Date();
|
3390 |
-
d.setTime(d.getTime() + 30 * 60 * 1000);
|
3391 |
-
var expire = _inbound.Utils.addDays(d, 3);
|
3392 |
-
_inbound.Utils.createCookie("lead_data_expire", true, expire);
|
3393 |
-
|
3394 |
-
};
|
3395 |
-
|
3396 |
-
if (!leadData) {
|
3397 |
-
// Get New Lead Data from DB
|
3398 |
-
_inbound.Utils.ajaxPost(inbound_settings.admin_url, data, success);
|
3399 |
-
|
3400 |
-
} else {
|
3401 |
-
// set global lead var with localstorage data
|
3402 |
-
_inbound.LeadsAPI.setGlobalLeadData(leadData);
|
3403 |
-
_inbound.deBugger('lead', 'Set Global Lead Data from Localstorage');
|
3404 |
-
|
3405 |
-
if (!leadDataExpire) {
|
3406 |
-
_inbound.Utils.ajaxPost(inbound_settings.admin_url, data, success);
|
3407 |
-
//console.log('Set Global Lead Data from Localstorage');
|
3408 |
-
_inbound.deBugger('lead', 'localized data old. Pull new from DB');
|
3409 |
-
//console.log('localized data old. Pull new from DB');
|
3410 |
-
}
|
3411 |
-
}
|
3412 |
-
|
3413 |
-
},
|
3414 |
-
getLeadLists: function() {
|
3415 |
-
var wp_lead_id = _inbound.Utils.readCookie("wp_lead_id");
|
3416 |
-
var data = {
|
3417 |
-
action: 'wpl_check_lists',
|
3418 |
-
wp_lead_id: wp_lead_id
|
3419 |
-
};
|
3420 |
-
var success = function(user_id) {
|
3421 |
-
_inbound.Utils.createCookie("lead_session_list_check", true, {
|
3422 |
-
path: '/',
|
3423 |
-
expires: 1
|
3424 |
-
});
|
3425 |
-
_inbound.deBugger('lead', "Lists checked");
|
3426 |
-
//console.log("Lists checked");
|
3427 |
-
};
|
3428 |
-
//_inbound.Utils.doAjax(data, success);
|
3429 |
-
_inbound.Utils.ajaxPost(inbound_settings.admin_url, data, success);
|
3430 |
-
}
|
3431 |
-
};
|
3432 |
-
|
3433 |
-
return _inbound;
|
3434 |
-
|
3435 |
-
})(_inbound || {});
|
3436 |
-
/**
|
3437 |
-
* # Page View Tracking
|
3438 |
-
*
|
3439 |
-
* Page view tracking
|
3440 |
-
*
|
3441 |
-
* @
|
3442 |
-
* @
|
3443 |
-
* @version 0.0.2
|
3444 |
-
*/
|
3445 |
-
/* Launches view tracking */
|
3446 |
-
var _inboundPageTracking = (function(_inbound) {
|
3447 |
-
|
3448 |
-
var started = false,
|
3449 |
-
stopped = false,
|
3450 |
-
turnedOff = false,
|
3451 |
-
clockTime = parseInt(_inbound.Utils.readCookie("lead_session"), 10) || 0,
|
3452 |
-
inactiveClockTime = 0,
|
3453 |
-
startTime = new Date(),
|
3454 |
-
clockTimer = null,
|
3455 |
-
inactiveClockTimer = null,
|
3456 |
-
idleTimer = null,
|
3457 |
-
reportInterval,
|
3458 |
-
idleTimeout,
|
3459 |
-
utils = _inbound.Utils,
|
3460 |
-
timeNow = _inbound.Utils.GetDate(),
|
3461 |
-
lsType = 'page_views',
|
3462 |
-
Pages = _inbound.totalStorage(lsType) || {},
|
3463 |
-
/*!
|
3464 |
-
Todo: Use UTC offset
|
3465 |
-
var x = new Date();
|
3466 |
-
var currentTime = x.getTimezoneOffset() / 60;
|
3467 |
-
console.log(currentTime) // gets UTC offset
|
3468 |
-
*/
|
3469 |
-
id = inbound_settings.post_id || window.location.pathname,
|
3470 |
-
analyticsTimeout = _inbound.Settings.timeout || 10000;
|
3471 |
-
|
3472 |
-
_inbound.PageTracking = {
|
3473 |
-
|
3474 |
-
init: function(options) {
|
3475 |
-
|
3476 |
-
if(lsType !== 'page_views') {
|
3477 |
-
return false; // in admin
|
3478 |
-
}
|
3479 |
-
|
3480 |
-
this.CheckTimeOut();
|
3481 |
-
// Set up options and defaults
|
3482 |
-
options = options || {};
|
3483 |
-
reportInterval = parseInt(options.reportInterval, 10) || 10;
|
3484 |
-
idleTimeout = parseInt(options.idleTimeout, 10) || 3;
|
3485 |
-
|
3486 |
-
// Basic activity event listeners
|
3487 |
-
utils.addListener(document, 'keydown', utils.throttle(_inbound.PageTracking.pingSession, 1000));
|
3488 |
-
utils.addListener(document, 'click', utils.throttle(_inbound.PageTracking.pingSession, 1000));
|
3489 |
-
utils.addListener(window, 'mousemove', utils.throttle(_inbound.PageTracking.pingSession, 1000));
|
3490 |
-
//utils.addListener(window, 'scroll', utils.throttle(_inbound.PageTracking.pingSession, 1000));
|
3491 |
-
|
3492 |
-
// Page visibility listeners
|
3493 |
-
_inbound.PageTracking.checkVisibility();
|
3494 |
-
|
3495 |
-
/* Start Session on page load */
|
3496 |
-
this.startSession();
|
3497 |
-
|
3498 |
-
},
|
3499 |
-
|
3500 |
-
setIdle: function(reason) {
|
3501 |
-
var reason = reason || "No Movement",
|
3502 |
-
msg = 'Session IDLE. Activity Timeout due to ' + reason;
|
3503 |
-
|
3504 |
-
_inbound.deBugger('pages', msg);
|
3505 |
-
|
3506 |
-
clearTimeout(_inbound.PageTracking.idleTimer);
|
3507 |
-
_inbound.PageTracking.stopClock();
|
3508 |
-
_inbound.trigger('session_idle');
|
3509 |
-
|
3510 |
-
},
|
3511 |
-
|
3512 |
-
checkVisibility: function() {
|
3513 |
-
var hidden, visibilityState, visibilityChange;
|
3514 |
-
|
3515 |
-
if (typeof document.hidden !== "undefined") {
|
3516 |
-
hidden = "hidden", visibilityChange = "visibilitychange", visibilityState = "visibilityState";
|
3517 |
-
} else if (typeof document.mozHidden !== "undefined") {
|
3518 |
-
hidden = "mozHidden", visibilityChange = "mozvisibilitychange", visibilityState = "mozVisibilityState";
|
3519 |
-
} else if (typeof document.msHidden !== "undefined") {
|
3520 |
-
hidden = "msHidden", visibilityChange = "msvisibilitychange", visibilityState = "msVisibilityState";
|
3521 |
-
} else if (typeof document.webkitHidden !== "undefined") {
|
3522 |
-
hidden = "webkitHidden", visibilityChange = "webkitvisibilitychange", visibilityState = "webkitVisibilityState";
|
3523 |
-
}
|
3524 |
-
|
3525 |
-
var document_hidden = document[hidden];
|
3526 |
-
|
3527 |
-
_inbound.Utils.addListener(document, visibilityChange, function(e) {
|
3528 |
-
/*! Listen for visibility changes */
|
3529 |
-
if (document_hidden != document[hidden]) {
|
3530 |
-
if (document[hidden]) {
|
3531 |
-
// Document hidden
|
3532 |
-
_inbound.trigger('tab_hidden');
|
3533 |
-
_inbound.PageTracking.setIdle('browser tab switch');
|
3534 |
-
} else {
|
3535 |
-
// Document shown
|
3536 |
-
_inbound.trigger('tab_visible');
|
3537 |
-
_inbound.PageTracking.pingSession();
|
3538 |
-
}
|
3539 |
-
|
3540 |
-
document_hidden = document[hidden];
|
3541 |
-
}
|
3542 |
-
});
|
3543 |
-
},
|
3544 |
-
clock: function() {
|
3545 |
-
clockTime += 1;
|
3546 |
-
var niceTime = clockTime / 60;
|
3547 |
-
var msg = 'Total time spent on Page in this Session: ' + niceTime.toFixed(2) + " min";
|
3548 |
-
_inbound.deBugger('pages', msg);
|
3549 |
-
if (clockTime > 0 && (clockTime % reportInterval === 0)) {
|
3550 |
-
|
3551 |
-
var d = new Date();
|
3552 |
-
d.setTime(d.getTime() + 30 * 60 * 1000);
|
3553 |
-
utils.createCookie("lead_session", clockTime, d); // Set cookie on page load
|
3554 |
-
|
3555 |
-
/*! every 10 seconds run this */
|
3556 |
-
//console.log('Session Heartbeat every ' + reportInterval + ' secs');
|
3557 |
-
_inbound.trigger('session_heartbeat', clockTime);
|
3558 |
-
|
3559 |
-
}
|
3560 |
-
|
3561 |
-
},
|
3562 |
-
inactiveClock: function() {
|
3563 |
-
inactiveClockTime += 1;
|
3564 |
-
var TimeUntilTimeOut = (1800 - inactiveClockTime) / 60;
|
3565 |
-
var msg = 'Time until Session Timeout: ' + TimeUntilTimeOut.toFixed(2) + " min";
|
3566 |
-
_inbound.deBugger('pages', msg);
|
3567 |
-
//console.log('Time until Session Timeout: ', TimeUntilTimeOut.toFixed(2) + " min");
|
3568 |
-
/* Session timeout after 30min */
|
3569 |
-
if (inactiveClockTime > 1800) {
|
3570 |
-
|
3571 |
-
// sendEvent(clockTime);
|
3572 |
-
/*! End session after 30min timeout */
|
3573 |
-
_inbound.trigger('session_end', InboundLeadData);
|
3574 |
-
_inbound.Utils.eraseCookie("lead_session");
|
3575 |
-
/* todo maybe? remove session Cookie */
|
3576 |
-
inactiveClockTime = 0;
|
3577 |
-
clearTimeout(inactiveClockTimer);
|
3578 |
-
}
|
3579 |
-
|
3580 |
-
|
3581 |
-
},
|
3582 |
-
stopClock: function() {
|
3583 |
-
stopped = true;
|
3584 |
-
clearTimeout(clockTimer);
|
3585 |
-
clearTimeout(inactiveClockTimer);
|
3586 |
-
inactiveClockTimer = setInterval(_inbound.PageTracking.inactiveClock, 1000);
|
3587 |
-
},
|
3588 |
-
|
3589 |
-
restartClock: function() {
|
3590 |
-
stopped = false;
|
3591 |
-
|
3592 |
-
|
3593 |
-
_inbound.trigger('session_resume');
|
3594 |
-
_inbound.deBugger('pages', 'Activity resumed. Session Active');
|
3595 |
-
/* todo add session_resume */
|
3596 |
-
clearTimeout(clockTimer);
|
3597 |
-
inactiveClockTime = 0;
|
3598 |
-
clearTimeout(inactiveClockTimer);
|
3599 |
-
clockTimer = setInterval(_inbound.PageTracking.clock, 1000);
|
3600 |
-
},
|
3601 |
-
|
3602 |
-
turnOff: function() {
|
3603 |
-
_inbound.PageTracking.setIdle();
|
3604 |
-
turnedOff = true;
|
3605 |
-
},
|
3606 |
-
|
3607 |
-
turnOn: function() {
|
3608 |
-
turnedOff = false;
|
3609 |
-
},
|
3610 |
-
/* This start only runs once */
|
3611 |
-
startSession: function() {
|
3612 |
-
/* todo add session Cookie */
|
3613 |
-
// Calculate seconds from start to first interaction
|
3614 |
-
var currentTime = new Date();
|
3615 |
-
var diff = currentTime - startTime;
|
3616 |
-
|
3617 |
-
|
3618 |
-
started = true; // Set global
|
3619 |
-
|
3620 |
-
// Send User Timing Event
|
3621 |
-
/* Todo session start here */
|
3622 |
-
|
3623 |
-
// Start clock
|
3624 |
-
clockTimer = setInterval(_inbound.PageTracking.clock, 1000);
|
3625 |
-
//utils.eraseCookie("lead_session");
|
3626 |
-
var session = utils.readCookie("lead_session");
|
3627 |
-
|
3628 |
-
if (!session) {
|
3629 |
-
_inbound.trigger('session_start'); // trigger 'inbound_analytics_session_start'
|
3630 |
-
var d = new Date();
|
3631 |
-
d.setTime(d.getTime() + 30 * 60 * 1000);
|
3632 |
-
_inbound.Utils.createCookie("lead_session", 1, d); // Set cookie on page load
|
3633 |
-
} else {
|
3634 |
-
_inbound.trigger('session_active');
|
3635 |
-
//console.log("count of secs " + session);
|
3636 |
-
//_inbound.trigger('session_active'); // trigger 'inbound_analytics_session_active'
|
3637 |
-
}
|
3638 |
-
|
3639 |
-
this.pingSession();
|
3640 |
-
|
3641 |
-
|
3642 |
-
},
|
3643 |
-
resetInactiveFunc: function() {
|
3644 |
-
inactiveClockTime = 0;
|
3645 |
-
clearTimeout(inactiveClockTimer);
|
3646 |
-
},
|
3647 |
-
/* Ping Session to keep active */
|
3648 |
-
pingSession: function(e) {
|
3649 |
-
|
3650 |
-
|
3651 |
-
if (turnedOff) {
|
3652 |
-
return;
|
3653 |
-
}
|
3654 |
-
|
3655 |
-
if (!started) {
|
3656 |
-
_inbound.PageTracking.startSession();
|
3657 |
-
}
|
3658 |
-
|
3659 |
-
if (stopped) {
|
3660 |
-
_inbound.PageTracking.restartClock();
|
3661 |
-
}
|
3662 |
-
|
3663 |
-
clearTimeout(idleTimer);
|
3664 |
-
|
3665 |
-
idleTimer = setTimeout(_inbound.PageTracking.setIdle, idleTimeout * 1000 + 100);
|
3666 |
-
|
3667 |
-
if (typeof(e) != "undefined") {
|
3668 |
-
if (e.type === "mousemove") {
|
3669 |
-
_inbound.PageTracking.mouseEvents(e);
|
3670 |
-
}
|
3671 |
-
}
|
3672 |
-
|
3673 |
-
},
|
3674 |
-
mouseEvents: function(e) {
|
3675 |
-
|
3676 |
-
if (e.pageY <= 5) {
|
3677 |
-
_inbound.trigger('tab_mouseout');
|
3678 |
-
}
|
3679 |
-
|
3680 |
-
},
|
3681 |
-
/**
|
3682 |
-
* Returns the pages viewed by the site visitor
|
3683 |
-
*
|
3684 |
-
* ```js
|
3685 |
-
* var pageViews = _inbound.PageTracking.getPageViews();
|
3686 |
-
* // returns page view object
|
3687 |
-
* ```
|
3688 |
-
*
|
3689 |
-
* @return {object} page view object with page ID as key and timestamp
|
3690 |
-
*/
|
3691 |
-
getPageViews: function() {
|
3692 |
-
var local_store = _inbound.Utils.checkLocalStorage();
|
3693 |
-
if (local_store) {
|
3694 |
-
var page_views = localStorage.getItem(lsType),
|
3695 |
-
local_object = JSON.parse(page_views);
|
3696 |
-
if (typeof local_object == 'object' && local_object) {
|
3697 |
-
//this.triggerPageView();
|
3698 |
-
}
|
3699 |
-
return local_object;
|
3700 |
-
}
|
3701 |
-
},
|
3702 |
-
isRevisit: function(Pages) {
|
3703 |
-
var revisitCheck = false;
|
3704 |
-
var Pages = Pages || {};
|
3705 |
-
var pageSeen = Pages[id];
|
3706 |
-
if (typeof(pageSeen) != "undefined" && pageSeen !== null) {
|
3707 |
-
revisitCheck = true;
|
3708 |
-
}
|
3709 |
-
return revisitCheck;
|
3710 |
-
},
|
3711 |
-
triggerPageView: function(pageRevisit) {
|
3712 |
-
|
3713 |
-
var pageData = {
|
3714 |
-
title: document.title,
|
3715 |
-
url: document.location.href,
|
3716 |
-
path: document.location.pathname,
|
3717 |
-
count: 1 // default
|
3718 |
-
};
|
3719 |
-
|
3720 |
-
if (pageRevisit) {
|
3721 |
-
/* Page Revisit Trigger */
|
3722 |
-
Pages[id].push(timeNow);
|
3723 |
-
pageData.count = Pages[id].length;
|
3724 |
-
_inbound.trigger('page_revisit', pageData);
|
3725 |
-
|
3726 |
-
} else {
|
3727 |
-
/* Page First Seen Trigger */
|
3728 |
-
Pages[id] = [];
|
3729 |
-
Pages[id].push(timeNow);
|
3730 |
-
_inbound.trigger('page_first_visit', pageData);
|
3731 |
-
}
|
3732 |
-
|
3733 |
-
_inbound.trigger('page_visit', pageData);
|
3734 |
-
|
3735 |
-
_inbound.totalStorage(lsType, Pages);
|
3736 |
-
|
3737 |
-
this.storePageView();
|
3738 |
-
|
3739 |
-
},
|
3740 |
-
CheckTimeOut: function() {
|
3741 |
-
|
3742 |
-
var pageRevisit = this.isRevisit(Pages),
|
3743 |
-
status,
|
3744 |
-
timeout;
|
3745 |
-
|
3746 |
-
/* Default */
|
3747 |
-
if (pageRevisit) {
|
3748 |
-
|
3749 |
-
var prev = Pages[id].length - 1,
|
3750 |
-
lastView = Pages[id][prev],
|
3751 |
-
timeDiff = Math.abs(new Date(lastView).getTime() - new Date(timeNow).getTime());
|
3752 |
-
|
3753 |
-
timeout = timeDiff > analyticsTimeout;
|
3754 |
-
|
3755 |
-
if (timeout) {
|
3756 |
-
status = 'Timeout Happened. Page view fired';
|
3757 |
-
this.triggerPageView(pageRevisit);
|
3758 |
-
} else {
|
3759 |
-
time_left = Math.abs((analyticsTimeout - timeDiff)) * 0.001;
|
3760 |
-
status = analyticsTimeout / 1000 + ' sec timeout not done: ' + time_left + " seconds left";
|
3761 |
-
}
|
3762 |
-
|
3763 |
-
} else {
|
3764 |
-
/*! Page never seen before save view */
|
3765 |
-
this.triggerPageView(pageRevisit);
|
3766 |
-
}
|
3767 |
-
|
3768 |
-
_inbound.deBugger('pages', status);
|
3769 |
-
},
|
3770 |
-
storePageView: function() {
|
3771 |
-
|
3772 |
-
|
3773 |
-
|
3774 |
-
|
3775 |
-
|
3776 |
-
|
3777 |
-
|
3778 |
-
|
3779 |
-
|
3780 |
-
|
3781 |
-
|
3782 |
-
|
3783 |
-
|
3784 |
-
|
3785 |
-
|
3786 |
-
|
3787 |
-
|
3788 |
-
|
3789 |
-
|
3790 |
-
|
3791 |
-
|
3792 |
-
|
3793 |
-
|
3794 |
-
|
3795 |
-
|
3796 |
-
|
3797 |
-
|
3798 |
-
|
3799 |
-
|
3800 |
-
|
3801 |
-
|
3802 |
-
|
3803 |
-
|
3804 |
-
|
3805 |
-
|
3806 |
-
|
3807 |
-
|
3808 |
-
|
3809 |
-
|
3810 |
-
|
3811 |
-
|
3812 |
-
|
3813 |
-
|
3814 |
-
|
3815 |
-
|
3816 |
-
|
3817 |
-
|
3818 |
-
|
3819 |
-
|
3820 |
-
|
3821 |
-
|
3822 |
-
|
3823 |
-
|
3824 |
-
|
3825 |
-
|
3826 |
-
|
3827 |
-
|
3828 |
-
|
3829 |
-
|
3830 |
-
|
3831 |
-
|
3832 |
-
*
|
3833 |
-
*
|
3834 |
-
*
|
3835 |
-
*
|
3836 |
-
* @
|
3837 |
-
* @
|
3838 |
-
|
3839 |
-
|
3840 |
-
|
3841 |
-
|
3842 |
-
_inbound
|
3843 |
-
|
3844 |
-
|
3845 |
-
|
3846 |
-
|
Â
|
1 |
+
/*! Inbound Analyticsv1.0.0 | (c) 2017 Inbound Now | https://github.com/inboundnow/cta */
|
2 |
+
/**
|
3 |
+
* # _inbound
|
4 |
+
*
|
5 |
+
* This main the _inbound class
|
6 |
+
*
|
7 |
+
* @contributor David Wells <david@inboundnow.com>
|
8 |
+
* @contributor Hudson Atwell <hudson@inboundnow.com>
|
9 |
+
* @version 0.0.2
|
10 |
+
*/
|
11 |
+
|
12 |
+
var inbound_data = inbound_data || {};
|
13 |
+
var _inboundOptions = _inboundOptions || {};
|
14 |
+
/* Ensure global _gaq Google Analytics queue has been initialized. */
|
15 |
+
var _gaq = _gaq || [];
|
16 |
+
|
17 |
+
var _inbound = (function(options) {
|
18 |
+
|
19 |
+
/* Constants */
|
20 |
+
var defaults = {
|
21 |
+
timeout: ( inbound_settings.is_admin ? 500 : 10000 ),
|
22 |
+
formAutoTracking: true,
|
23 |
+
formAutoPopulation: true
|
24 |
+
};
|
25 |
+
|
26 |
+
var Analytics = {
|
27 |
+
/* Initialize individual modules */
|
28 |
+
init: function() {
|
29 |
+
_inbound.Utils.init();
|
30 |
+
|
31 |
+
_inbound.Utils.domReady(window, function() {
|
32 |
+
/* On Load Analytics Events */
|
33 |
+
_inbound.DomLoaded();
|
34 |
+
|
35 |
+
});
|
36 |
+
},
|
37 |
+
DomLoaded: function() {
|
38 |
+
_inbound.PageTracking.init();
|
39 |
+
/* run form mapping */
|
40 |
+
_inbound.Forms.init();
|
41 |
+
/* set URL params */
|
42 |
+
_inbound.Utils.setUrlParams();
|
43 |
+
_inbound.LeadsAPI.init();
|
44 |
+
/* run form mapping for dynamically generated forms */
|
45 |
+
setTimeout(function() {
|
46 |
+
_inbound.Forms.init();
|
47 |
+
}, 2000);
|
48 |
+
|
49 |
+
_inbound.trigger('analytics_ready');
|
50 |
+
|
51 |
+
},
|
52 |
+
/**
|
53 |
+
* Merge script defaults with user options
|
54 |
+
* @private
|
55 |
+
* @param {Object} defaults Default settings
|
56 |
+
* @param {Object} options User options
|
57 |
+
* @returns {Object} Merged values of defaults and options
|
58 |
+
*/
|
59 |
+
extend: function(defaults, options) {
|
60 |
+
var extended = {};
|
61 |
+
var prop;
|
62 |
+
for (prop in defaults) {
|
63 |
+
if (Object.prototype.hasOwnProperty.call(defaults, prop)) {
|
64 |
+
extended[prop] = defaults[prop];
|
65 |
+
}
|
66 |
+
}
|
67 |
+
for (prop in options) {
|
68 |
+
if (Object.prototype.hasOwnProperty.call(options, prop)) {
|
69 |
+
extended[prop] = options[prop];
|
70 |
+
}
|
71 |
+
}
|
72 |
+
return extended;
|
73 |
+
},
|
74 |
+
/* Debugger Function toggled by var debugMode */
|
75 |
+
debug: function(msg, callback) {
|
76 |
+
/* legacy */
|
77 |
+
},
|
78 |
+
deBugger: function(context, msg, callback) {
|
79 |
+
|
80 |
+
if (!console) {
|
81 |
+
return;
|
82 |
+
}
|
83 |
+
//if app not in debug mode, exit immediately
|
84 |
+
// check for hash
|
85 |
+
var hash = (document.location.hash) ? document.location.hash : '',
|
86 |
+
debugHash = hash.indexOf("#debug") > -1,
|
87 |
+
msg = msg || false,
|
88 |
+
logCookie,
|
89 |
+
logAllMessages,
|
90 |
+
hashcontext;
|
91 |
+
|
92 |
+
if (hash && hash.match(/debug/)) {
|
93 |
+
hash = hash.split('-');
|
94 |
+
hashcontext = hash[1];
|
95 |
+
}
|
96 |
+
|
97 |
+
|
98 |
+
logAllMessages = (_inbound.Utils.readCookie("inbound_debug") === "true") ? true : false;
|
99 |
+
logCookie = (_inbound.Utils.readCookie("inbound_debug_" + context) === "true") ? true : false;
|
100 |
+
|
101 |
+
if (!logCookie && !debugHash && !logAllMessages) {
|
102 |
+
// no logger set. exit.
|
103 |
+
return;
|
104 |
+
};
|
105 |
+
|
106 |
+
//console.log the message
|
107 |
+
if (msg && (typeof msg === 'string')) {
|
108 |
+
|
109 |
+
if (logAllMessages || hashcontext === 'all') {
|
110 |
+
console.log('logAll "' + context + '" =>', msg)
|
111 |
+
} else if (logCookie) {
|
112 |
+
console.log('log "' + context + '" =>', msg)
|
113 |
+
} else if (context === hashcontext) {
|
114 |
+
console.log('#log "' + context + '" =>', msg)
|
115 |
+
}
|
116 |
+
|
117 |
+
};
|
118 |
+
|
119 |
+
//execute the callback if one was passed-in
|
120 |
+
if (callback && (callback instanceof Function)) {
|
121 |
+
callback();
|
122 |
+
};
|
123 |
+
}
|
124 |
+
};
|
125 |
+
|
126 |
+
var settings = Analytics.extend(defaults, options);
|
127 |
+
/* Set globals */
|
128 |
+
Analytics.Settings = settings || {};
|
129 |
+
|
130 |
+
return Analytics;
|
131 |
+
|
132 |
+
})(_inboundOptions);
|
133 |
+
/**
|
134 |
+
* # Hooks & Filters
|
135 |
+
*
|
136 |
+
* This file contains all of the form functions of the main _inbound object.
|
137 |
+
* Filters and actions are described below
|
138 |
+
*
|
139 |
+
* Forked from https://github.com/carldanley/WP-JS-Hooks/blob/master/src/event-manager.js
|
140 |
+
*
|
141 |
+
* @contributor David Wells <david@inboundnow.com>
|
142 |
+
* @contributor Hudson Atwell <hudson@inboundnow.com>
|
143 |
+
* @version 0.0.2
|
144 |
+
*/
|
145 |
+
|
146 |
+
var _inboundHooks = (function (_inbound) {
|
147 |
+
|
148 |
+
/**
|
149 |
+
* # EventManager
|
150 |
+
*
|
151 |
+
* Actions and filters List
|
152 |
+
* addAction( 'namespace.identifier', callback, priority )
|
153 |
+
* addFilter( 'namespace.identifier', callback, priority )
|
154 |
+
* removeAction( 'namespace.identifier' )
|
155 |
+
* removeFilter( 'namespace.identifier' )
|
156 |
+
* doAction( 'namespace.identifier', arg1, arg2, moreArgs, finalArg )
|
157 |
+
* applyFilters( 'namespace.identifier', content )
|
158 |
+
* @return {[type]} [description]
|
159 |
+
*/
|
160 |
+
|
161 |
+
/**
|
162 |
+
* Handles managing all events for whatever you plug it into. Priorities for hooks are based on lowest to highest in
|
163 |
+
* that, lowest priority hooks are fired first.
|
164 |
+
*/
|
165 |
+
var EventManager = function() {
|
166 |
+
/**
|
167 |
+
* Maintain a reference to the object scope so our public methods never get confusing.
|
168 |
+
*/
|
169 |
+
var MethodsAvailable = {
|
170 |
+
removeFilter : removeFilter,
|
171 |
+
applyFilters : applyFilters,
|
172 |
+
addFilter : addFilter,
|
173 |
+
removeAction : removeAction,
|
174 |
+
doAction : doAction,
|
175 |
+
addAction : addAction
|
176 |
+
};
|
177 |
+
|
178 |
+
/**
|
179 |
+
* Contains the hooks that get registered with this EventManager. The array for storage utilizes a "flat"
|
180 |
+
* object literal such that looking up the hook utilizes the native object literal hash.
|
181 |
+
*/
|
182 |
+
var STORAGE = {
|
183 |
+
actions : {},
|
184 |
+
filters : {}
|
185 |
+
};
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Adds an action to the event manager.
|
189 |
+
*
|
190 |
+
* @param action Must contain namespace.identifier
|
191 |
+
* @param callback Must be a valid callback function before this action is added
|
192 |
+
* @param [priority=10] Used to control when the function is executed in relation to other callbacks bound to the same hook
|
193 |
+
* @param [context] Supply a value to be used for this
|
194 |
+
*/
|
195 |
+
function addAction( action, callback, priority, context ) {
|
196 |
+
if( typeof action === 'string' && typeof callback === 'function' ) {
|
197 |
+
priority = parseInt( ( priority || 10 ), 10 );
|
198 |
+
_addHook( 'actions', action, callback, priority, context );
|
199 |
+
}
|
200 |
+
|
201 |
+
return MethodsAvailable;
|
202 |
+
}
|
203 |
+
|
204 |
+
/**
|
205 |
+
* Performs an action if it exists. You can pass as many arguments as you want to this function; the only rule is
|
206 |
+
* that the first argument must always be the action.
|
207 |
+
*/
|
208 |
+
function doAction( /* action, arg1, arg2, ... */ ) {
|
209 |
+
var args = Array.prototype.slice.call( arguments );
|
210 |
+
var action = args.shift();
|
211 |
+
|
212 |
+
if( typeof action === 'string' ) {
|
213 |
+
_runHook( 'actions', action, args );
|
214 |
+
}
|
215 |
+
|
216 |
+
return MethodsAvailable;
|
217 |
+
}
|
218 |
+
|
219 |
+
/**
|
220 |
+
* Removes the specified action if it contains a namespace.identifier & exists.
|
221 |
+
*
|
222 |
+
* @param action The action to remove
|
223 |
+
* @param [callback] Callback function to remove
|
224 |
+
*/
|
225 |
+
function removeAction( action, callback ) {
|
226 |
+
if( typeof action === 'string' ) {
|
227 |
+
_removeHook( 'actions', action, callback );
|
228 |
+
}
|
229 |
+
|
230 |
+
return MethodsAvailable;
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Adds a filter to the event manager.
|
235 |
+
*
|
236 |
+
* @param filter Must contain namespace.identifier
|
237 |
+
* @param callback Must be a valid callback function before this action is added
|
238 |
+
* @param [priority=10] Used to control when the function is executed in relation to other callbacks bound to the same hook
|
239 |
+
* @param [context] Supply a value to be used for this
|
240 |
+
*/
|
241 |
+
function addFilter( filter, callback, priority, context ) {
|
242 |
+
if( typeof filter === 'string' && typeof callback === 'function' ) {
|
243 |
+
//console.log('add filter', filter);
|
244 |
+
priority = parseInt( ( priority || 10 ), 10 );
|
245 |
+
_addHook( 'filters', filter, callback, priority );
|
246 |
+
}
|
247 |
+
|
248 |
+
return MethodsAvailable;
|
249 |
+
}
|
250 |
+
|
251 |
+
/**
|
252 |
+
* Performs a filter if it exists. You should only ever pass 1 argument to be filtered. The only rule is that
|
253 |
+
* the first argument must always be the filter.
|
254 |
+
*/
|
255 |
+
function applyFilters( /* filter, filtered arg, arg2, ... */ ) {
|
256 |
+
var args = Array.prototype.slice.call( arguments );
|
257 |
+
var filter = args.shift();
|
258 |
+
|
259 |
+
if( typeof filter === 'string' ) {
|
260 |
+
return _runHook( 'filters', filter, args );
|
261 |
+
}
|
262 |
+
|
263 |
+
return MethodsAvailable;
|
264 |
+
}
|
265 |
+
|
266 |
+
/**
|
267 |
+
* Removes the specified filter if it contains a namespace.identifier & exists.
|
268 |
+
*
|
269 |
+
* @param filter The action to remove
|
270 |
+
* @param [callback] Callback function to remove
|
271 |
+
*/
|
272 |
+
function removeFilter( filter, callback ) {
|
273 |
+
if( typeof filter === 'string') {
|
274 |
+
_removeHook( 'filters', filter, callback );
|
275 |
+
}
|
276 |
+
|
277 |
+
return MethodsAvailable;
|
278 |
+
}
|
279 |
+
|
280 |
+
/**
|
281 |
+
* Removes the specified hook by resetting the value of it.
|
282 |
+
*
|
283 |
+
* @param type Type of hook, either 'actions' or 'filters'
|
284 |
+
* @param hook The hook (namespace.identifier) to remove
|
285 |
+
* @private
|
286 |
+
*/
|
287 |
+
function _removeHook( type, hook, callback, context ) {
|
288 |
+
if ( !STORAGE[ type ][ hook ] ) {
|
289 |
+
return;
|
290 |
+
}
|
291 |
+
if ( !callback ) {
|
292 |
+
STORAGE[ type ][ hook ] = [];
|
293 |
+
} else {
|
294 |
+
var handlers = STORAGE[ type ][ hook ];
|
295 |
+
var i;
|
296 |
+
if ( !context ) {
|
297 |
+
for ( i = handlers.length; i--; ) {
|
298 |
+
if ( handlers[i].callback === callback ) {
|
299 |
+
handlers.splice( i, 1 );
|
300 |
+
}
|
301 |
+
}
|
302 |
+
}
|
303 |
+
else {
|
304 |
+
for ( i = handlers.length; i--; ) {
|
305 |
+
var handler = handlers[i];
|
306 |
+
if ( handler.callback === callback && handler.context === context) {
|
307 |
+
handlers.splice( i, 1 );
|
308 |
+
}
|
309 |
+
}
|
310 |
+
}
|
311 |
+
}
|
312 |
+
}
|
313 |
+
|
314 |
+
/**
|
315 |
+
* Adds the hook to the appropriate storage container
|
316 |
+
*
|
317 |
+
* @param type 'actions' or 'filters'
|
318 |
+
* @param hook The hook (namespace.identifier) to add to our event manager
|
319 |
+
* @param callback The function that will be called when the hook is executed.
|
320 |
+
* @param priority The priority of this hook. Must be an integer.
|
321 |
+
* @param [context] A value to be used for this
|
322 |
+
* @private
|
323 |
+
*/
|
324 |
+
function _addHook( type, hook, callback, priority, context ) {
|
325 |
+
var hookObject = {
|
326 |
+
callback : callback,
|
327 |
+
priority : priority,
|
328 |
+
context : context
|
329 |
+
};
|
330 |
+
|
331 |
+
// Utilize 'prop itself' : http://jsperf.com/hasownproperty-vs-in-vs-undefined/19
|
332 |
+
var hooks = STORAGE[ type ][ hook ];
|
333 |
+
if( hooks ) {
|
334 |
+
hooks.push( hookObject );
|
335 |
+
hooks = _hookInsertSort( hooks );
|
336 |
+
}
|
337 |
+
else {
|
338 |
+
hooks = [ hookObject ];
|
339 |
+
}
|
340 |
+
|
341 |
+
STORAGE[ type ][ hook ] = hooks;
|
342 |
+
}
|
343 |
+
|
344 |
+
/**
|
345 |
+
* Use an insert sort for keeping our hooks organized based on priority. This function is ridiculously faster
|
346 |
+
* than bubble sort, etc: http://jsperf.com/javascript-sort
|
347 |
+
*
|
348 |
+
* @param hooks The custom array containing all of the appropriate hooks to perform an insert sort on.
|
349 |
+
* @private
|
350 |
+
*/
|
351 |
+
function _hookInsertSort( hooks ) {
|
352 |
+
var tmpHook, j, prevHook;
|
353 |
+
for( var i = 1, len = hooks.length; i < len; i++ ) {
|
354 |
+
tmpHook = hooks[ i ];
|
355 |
+
j = i;
|
356 |
+
while( ( prevHook = hooks[ j - 1 ] ) && prevHook.priority > tmpHook.priority ) {
|
357 |
+
hooks[ j ] = hooks[ j - 1 ];
|
358 |
+
--j;
|
359 |
+
}
|
360 |
+
hooks[ j ] = tmpHook;
|
361 |
+
}
|
362 |
+
|
363 |
+
return hooks;
|
364 |
+
}
|
365 |
+
|
366 |
+
/**
|
367 |
+
* Runs the specified hook. If it is an action, the value is not modified but if it is a filter, it is.
|
368 |
+
*
|
369 |
+
* @param type 'actions' or 'filters'
|
370 |
+
* @param hook The hook ( namespace.identifier ) to be ran.
|
371 |
+
* @param args Arguments to pass to the action/filter. If it's a filter, args is actually a single parameter.
|
372 |
+
* @private
|
373 |
+
*/
|
374 |
+
function _runHook( type, hook, args ) {
|
375 |
+
var handlers = STORAGE[ type ][ hook ];
|
376 |
+
|
377 |
+
if ( !handlers ) {
|
378 |
+
return (type === 'filters') ? args[0] : false;
|
379 |
+
}
|
380 |
+
|
381 |
+
var i = 0, len = handlers.length;
|
382 |
+
if ( type === 'filters' ) {
|
383 |
+
for ( ; i < len; i++ ) {
|
384 |
+
args[ 0 ] = handlers[ i ].callback.apply( handlers[ i ].context, args );
|
385 |
+
}
|
386 |
+
} else {
|
387 |
+
for ( ; i < len; i++ ) {
|
388 |
+
handlers[ i ].callback.apply( handlers[ i ].context, args );
|
389 |
+
}
|
390 |
+
}
|
391 |
+
|
392 |
+
return ( type === 'filters' ) ? args[ 0 ] : true;
|
393 |
+
}
|
394 |
+
|
395 |
+
// return all of the publicly available methods
|
396 |
+
return MethodsAvailable;
|
397 |
+
|
398 |
+
};
|
399 |
+
|
400 |
+
_inbound.hooks = new EventManager();
|
401 |
+
|
402 |
+
|
403 |
+
/**
|
404 |
+
* Event Hooks and Filters public methods
|
405 |
+
*/
|
406 |
+
/*
|
407 |
+
* add_action
|
408 |
+
*
|
409 |
+
* This function uses _inbound.hooks to mimics WP add_action
|
410 |
+
*
|
411 |
+
* ```js
|
412 |
+
* function Inbound_Add_Action_Example(data) {
|
413 |
+
* // Do stuff here.
|
414 |
+
* };
|
415 |
+
* // Add action to the hook
|
416 |
+
* _inbound.add_action( 'name_of_action', Inbound_Add_Action_Example, 10 );
|
417 |
+
* ```
|
418 |
+
*/
|
419 |
+
_inbound.add_action = function() {
|
420 |
+
// allow multiple action parameters such as 'ready append'
|
421 |
+
var actions = arguments[0].split(' ');
|
422 |
+
|
423 |
+
for( k in actions ) {
|
424 |
+
|
425 |
+
// prefix action
|
426 |
+
arguments[0] = 'inbound.' + actions[ k ];
|
427 |
+
|
428 |
+
_inbound.hooks.addAction.apply(this, arguments);
|
429 |
+
}
|
430 |
+
|
431 |
+
return this;
|
432 |
+
|
433 |
+
};
|
434 |
+
/*
|
435 |
+
* remove_action
|
436 |
+
*
|
437 |
+
* This function uses _inbound.hooks to mimics WP remove_action
|
438 |
+
*
|
439 |
+
* ```js
|
440 |
+
* // Add remove action 'name_of_action'
|
441 |
+
* _inbound.remove_action( 'name_of_action');
|
442 |
+
* ```
|
443 |
+
*
|
444 |
+
*/
|
445 |
+
_inbound.remove_action = function() {
|
446 |
+
// prefix action
|
447 |
+
arguments[0] = 'inbound.' + arguments[0];
|
448 |
+
_inbound.hooks.removeAction.apply(this, arguments);
|
449 |
+
|
450 |
+
return this;
|
451 |
+
|
452 |
+
};
|
453 |
+
/*
|
454 |
+
* do_action
|
455 |
+
*
|
456 |
+
* This function uses _inbound.hooks to mimics WP do_action
|
457 |
+
* This is used if you want to allow for third party JS plugins to act on your functions
|
458 |
+
*
|
459 |
+
*/
|
460 |
+
_inbound.do_action = function() {
|
461 |
+
// prefix action
|
462 |
+
arguments[0] = 'inbound.' + arguments[0];
|
463 |
+
_inbound.hooks.doAction.apply(this, arguments);
|
464 |
+
|
465 |
+
return this;
|
466 |
+
|
467 |
+
};
|
468 |
+
/*
|
469 |
+
* add_filter
|
470 |
+
*
|
471 |
+
* This function uses _inbound.hooks to mimics WP add_filter
|
472 |
+
*
|
473 |
+
* ```js
|
474 |
+
* _inbound.add_filter( 'urlParamFilter', URL_Param_Filter, 10 );
|
475 |
+
* function URL_Param_Filter(urlParams) {
|
476 |
+
*
|
477 |
+
* var params = urlParams || {};
|
478 |
+
* // check for item in object
|
479 |
+
* if(params.utm_source !== "undefined"){
|
480 |
+
* //alert('url param "utm_source" is here');
|
481 |
+
* }
|
482 |
+
*
|
483 |
+
* // delete item from object
|
484 |
+
* delete params.utm_source;
|
485 |
+
*
|
486 |
+
* return params;
|
487 |
+
*
|
488 |
+
* }
|
489 |
+
* ```
|
490 |
+
*/
|
491 |
+
_inbound.add_filter = function() {
|
492 |
+
// prefix action
|
493 |
+
arguments[0] = 'inbound.' + arguments[0];
|
494 |
+
_inbound.hooks.addFilter.apply(this, arguments);
|
495 |
+
|
496 |
+
return this;
|
497 |
+
|
498 |
+
};
|
499 |
+
/*
|
500 |
+
* remove_filter
|
501 |
+
*
|
502 |
+
* This function uses _inbound.hooks to mimics WP remove_filter
|
503 |
+
*
|
504 |
+
* ```js
|
505 |
+
* // Add remove filter 'urlParamFilter'
|
506 |
+
* _inbound.remove_action( 'urlParamFilter');
|
507 |
+
* ```
|
508 |
+
*
|
509 |
+
*/
|
510 |
+
_inbound.remove_filter = function() {
|
511 |
+
// prefix action
|
512 |
+
arguments[0] = 'inbound.' + arguments[0];
|
513 |
+
|
514 |
+
_inbound.hooks.removeFilter.apply(this, arguments);
|
515 |
+
|
516 |
+
return this;
|
517 |
+
|
518 |
+
};
|
519 |
+
/*
|
520 |
+
* apply_filters
|
521 |
+
*
|
522 |
+
* This function uses _inbound.hooks to mimics WP apply_filters
|
523 |
+
*
|
524 |
+
*/
|
525 |
+
_inbound.apply_filters = function() {
|
526 |
+
//console.log('Filter:' + arguments[0] + " ran on ->", arguments[1]);
|
527 |
+
// prefix action
|
528 |
+
arguments[0] = 'inbound.' + arguments[0];
|
529 |
+
|
530 |
+
return _inbound.hooks.applyFilters.apply(this, arguments);
|
531 |
+
|
532 |
+
};
|
533 |
+
|
534 |
+
|
535 |
+
return _inbound;
|
536 |
+
|
537 |
+
})(_inbound || {});
|
538 |
+
/**
|
539 |
+
* # _inbound UTILS
|
540 |
+
*
|
541 |
+
* This file contains all of the utility functions used by analytics
|
542 |
+
*
|
543 |
+
* @contributor David Wells <david@inboundnow.com>
|
544 |
+
* @contributor Hudson Atwell <hudson@inboundnow.com>
|
545 |
+
* @version 0.0.2
|
546 |
+
*/
|
547 |
+
|
548 |
+
var _inboundUtils = (function(_inbound) {
|
549 |
+
|
550 |
+
var storageSupported,
|
551 |
+
corsEnabled = window.XMLHttpRequest && 'withCredentials' in new XMLHttpRequest(),
|
552 |
+
toString = Object.prototype.toString,
|
553 |
+
currentPage = ('https:' == location.protocol ? 'https://' : 'http://') + location.hostname + location.pathname.replace(/\/$/, "");
|
554 |
+
|
555 |
+
var settings = {
|
556 |
+
api_host: currentPage,
|
557 |
+
track_pageview: true,
|
558 |
+
track_links_timeout: 300,
|
559 |
+
cookie_name: '_sp',
|
560 |
+
cookie_expiration: 365,
|
561 |
+
cookie_domain: (host = location.hostname.match(/[a-z0-9][a-z0-9\-]+\.[a-z\.]{2,6}$/i)) ? host[0] : ''
|
562 |
+
};
|
563 |
+
|
564 |
+
_inbound.Utils = {
|
565 |
+
init: function() {
|
566 |
+
|
567 |
+
this.polyFills();
|
568 |
+
this.checkLocalStorage();
|
569 |
+
this.SetUID();
|
570 |
+
this.storeReferralData();
|
571 |
+
|
572 |
+
},
|
573 |
+
/*! http://stackoverflow.com/questions/951791/javascript-global-error-handling */
|
574 |
+
/* Polyfills for missing browser functionality */
|
575 |
+
polyFills: function() {
|
576 |
+
/* Console.log fix for old browsers */
|
577 |
+
if (!window.console) {
|
578 |
+
window.console = {};
|
579 |
+
}
|
580 |
+
var m = [
|
581 |
+
"log", "info", "warn", "error", "debug", "trace", "dir", "group",
|
582 |
+
"groupCollapsed", "groupEnd", "time", "timeEnd", "profile", "profileEnd",
|
583 |
+
"dirxml", "assert", "count", "markTimeline", "timeStamp", "clear"
|
584 |
+
];
|
585 |
+
// define undefined methods as noops to prevent errors
|
586 |
+
for (var i = 0; i < m.length; i++) {
|
587 |
+
if (!window.console[m[i]]) {
|
588 |
+
window.console[m[i]] = function() {};
|
589 |
+
}
|
590 |
+
}
|
591 |
+
/* Event trigger polyfill for IE9 and 10
|
592 |
+
(function() {
|
593 |
+
function CustomEvent(event, params) {
|
594 |
+
params = params || {
|
595 |
+
bubbles: false,
|
596 |
+
cancelable: false,
|
597 |
+
detail: undefined
|
598 |
+
};
|
599 |
+
var evt = document.createEvent('CustomEvent');
|
600 |
+
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
|
601 |
+
return evt;
|
602 |
+
}
|
603 |
+
|
604 |
+
CustomEvent.prototype = window.Event.prototype;
|
605 |
+
|
606 |
+
window.CustomEvent = CustomEvent;
|
607 |
+
})();*/
|
608 |
+
|
609 |
+
/*\
|
610 |
+
|*| Polyfill Date.toISOString
|
611 |
+
\*/
|
612 |
+
if (!Date.prototype.toISOString) {
|
613 |
+
(function() {
|
614 |
+
/**
|
615 |
+
* @param {number} text
|
616 |
+
* @returns {?}
|
617 |
+
*/
|
618 |
+
function pad(text) {
|
619 |
+
/** @type {string} */
|
620 |
+
var code = String(text);
|
621 |
+
return 1 === code.length && (code = '0' + code), code;
|
622 |
+
}
|
623 |
+
/**
|
624 |
+
* @returns {string}
|
625 |
+
*/
|
626 |
+
Date.prototype.toISOString = function() {
|
627 |
+
return this.getUTCFullYear() + '-' + pad(this.getUTCMonth() + 1) + '-' + pad(this.getUTCDate()) + 'T' + pad(this.getUTCHours()) + ':' + pad(this.getUTCMinutes()) + ':' + pad(this.getUTCSeconds()) + '.' + String((this.getUTCMilliseconds() / 1E3).toFixed(3)).slice(2, 5) + 'Z';
|
628 |
+
};
|
629 |
+
})();
|
630 |
+
}
|
631 |
+
|
632 |
+
/* custom event for ie8+ https://gist.github.com/WebReflection/6693661 */
|
633 |
+
try {
|
634 |
+
new CustomEvent('?');
|
635 |
+
} catch (o_O) {
|
636 |
+
/*!(C) Andrea Giammarchi -- WTFPL License*/
|
637 |
+
this.CustomEvent = function(
|
638 |
+
eventName,
|
639 |
+
defaultInitDict
|
640 |
+
) {
|
641 |
+
|
642 |
+
// the infamous substitute
|
643 |
+
function CustomEvent(type, eventInitDict) {
|
644 |
+
var event = document.createEvent(eventName);
|
645 |
+
if (type !== null) {
|
646 |
+
initCustomEvent.call(
|
647 |
+
event,
|
648 |
+
type, (eventInitDict || (
|
649 |
+
// if falsy we can just use defaults
|
650 |
+
eventInitDict = defaultInitDict
|
651 |
+
)).bubbles,
|
652 |
+
eventInitDict.cancelable,
|
653 |
+
eventInitDict.detail
|
654 |
+
);
|
655 |
+
} else {
|
656 |
+
// no need to put the expando property otherwise
|
657 |
+
// since an event cannot be initialized twice
|
658 |
+
// previous case is the most common one anyway
|
659 |
+
// but if we end up here ... there it goes
|
660 |
+
event.initCustomEvent = initCustomEvent;
|
661 |
+
}
|
662 |
+
return event;
|
663 |
+
}
|
664 |
+
|
665 |
+
// borrowed or attached at runtime
|
666 |
+
function initCustomEvent(
|
667 |
+
type, bubbles, cancelable, detail
|
668 |
+
) {
|
669 |
+
this['init' + eventName](type, bubbles, cancelable, detail);
|
670 |
+
'detail' in this || (this.detail = detail);
|
671 |
+
}
|
672 |
+
|
673 |
+
// that's it
|
674 |
+
return CustomEvent;
|
675 |
+
}(
|
676 |
+
// is this IE9 or IE10 ?
|
677 |
+
// where CustomEvent is there
|
678 |
+
// but not usable as construtor ?
|
679 |
+
this.CustomEvent ?
|
680 |
+
// use the CustomEvent interface in such case
|
681 |
+
'CustomEvent' : 'Event',
|
682 |
+
// otherwise the common compatible one
|
683 |
+
{
|
684 |
+
bubbles: false,
|
685 |
+
cancelable: false,
|
686 |
+
detail: null
|
687 |
+
}
|
688 |
+
);
|
689 |
+
}
|
690 |
+
/* querySelectorAll polyfill for ie7+ */
|
691 |
+
if (!document.querySelectorAll) {
|
692 |
+
document.querySelectorAll = function(selectors) {
|
693 |
+
var style = document.createElement('style'),
|
694 |
+
elements = [],
|
695 |
+
element;
|
696 |
+
document.documentElement.firstChild.appendChild(style);
|
697 |
+
document._qsa = [];
|
698 |
+
|
699 |
+
style.styleSheet.cssText = selectors + '{x-qsa:expression(document._qsa && document._qsa.push(this))}';
|
700 |
+
window.scrollBy(0, 0);
|
701 |
+
style.parentNode.removeChild(style);
|
702 |
+
|
703 |
+
while (document._qsa.length) {
|
704 |
+
element = document._qsa.shift();
|
705 |
+
element.style.removeAttribute('x-qsa');
|
706 |
+
elements.push(element);
|
707 |
+
}
|
708 |
+
document._qsa = null;
|
709 |
+
return elements;
|
710 |
+
};
|
711 |
+
}
|
712 |
+
|
713 |
+
if (!document.querySelector) {
|
714 |
+
document.querySelector = function(selectors) {
|
715 |
+
var elements = document.querySelectorAll(selectors);
|
716 |
+
return (elements.length) ? elements[0] : null;
|
717 |
+
};
|
718 |
+
}
|
719 |
+
/* Innertext shim for firefox https://github.com/duckinator/innerText-polyfill/blob/master/innertext.js */
|
720 |
+
if ((!('innerText' in document.createElement('a'))) && ('getSelection' in window)) {
|
721 |
+
HTMLElement.prototype.__defineGetter__("innerText", function() {
|
722 |
+
var selection = window.getSelection(),
|
723 |
+
ranges = [],
|
724 |
+
str;
|
725 |
+
|
726 |
+
// Save existing selections.
|
727 |
+
for (var i = 0; i < selection.rangeCount; i++) {
|
728 |
+
ranges[i] = selection.getRangeAt(i);
|
729 |
+
}
|
730 |
+
|
731 |
+
// Deselect everything.
|
732 |
+
selection.removeAllRanges();
|
733 |
+
|
734 |
+
// Select `el` and all child nodes.
|
735 |
+
// 'this' is the element .innerText got called on
|
736 |
+
selection.selectAllChildren(this);
|
737 |
+
|
738 |
+
// Get the string representation of the selected nodes.
|
739 |
+
str = selection.toString();
|
740 |
+
|
741 |
+
// Deselect everything. Again.
|
742 |
+
selection.removeAllRanges();
|
743 |
+
|
744 |
+
// Restore all formerly existing selections.
|
745 |
+
for (var i = 0; i < ranges.length; i++) {
|
746 |
+
selection.addRange(ranges[i]);
|
747 |
+
}
|
748 |
+
|
749 |
+
// Oh look, this is what we wanted.
|
750 |
+
// String representation of the element, close to as rendered.
|
751 |
+
return str;
|
752 |
+
})
|
753 |
+
}
|
754 |
+
},
|
755 |
+
/**
|
756 |
+
* Create cookie
|
757 |
+
*
|
758 |
+
* ```js
|
759 |
+
* // Creates cookie for 10 days
|
760 |
+
* _inbound.Utils.createCookie( 'cookie_name', 'value', 10 );
|
761 |
+
* ```
|
762 |
+
*
|
763 |
+
* @param {string} name Name of cookie
|
764 |
+
* @param {string} value Value of cookie
|
765 |
+
* @param {string} days Length of storage
|
766 |
+
*/
|
767 |
+
createCookie: function(name, value, days) {
|
768 |
+
var expires = "";
|
769 |
+
if (days) {
|
770 |
+
var date = new Date();
|
771 |
+
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
772 |
+
expires = "; expires=" + date.toGMTString();
|
773 |
+
}
|
774 |
+
document.cookie = name + "=" + value + expires + "; path=/";
|
775 |
+
},
|
776 |
+
/**
|
777 |
+
* Read cookie value
|
778 |
+
*
|
779 |
+
* ```js
|
780 |
+
* var cookie = _inbound.Utils.readCookie( 'cookie_name' );
|
781 |
+
* console.log(cookie); // cookie value
|
782 |
+
* ```
|
783 |
+
* @param {string} name name of cookie
|
784 |
+
* @return {string} value of cookie
|
785 |
+
*/
|
786 |
+
readCookie: function(name) {
|
787 |
+
var nameEQ = name + "=";
|
788 |
+
var ca = document.cookie.split(';');
|
789 |
+
for (var i = 0; i < ca.length; i++) {
|
790 |
+
var c = ca[i];
|
791 |
+
while (c.charAt(0) === ' ') {
|
792 |
+
c = c.substring(1, c.length);
|
793 |
+
}
|
794 |
+
if (c.indexOf(nameEQ) === 0) {
|
795 |
+
return c.substring(nameEQ.length, c.length);
|
796 |
+
}
|
797 |
+
}
|
798 |
+
return null;
|
799 |
+
},
|
800 |
+
/**
|
801 |
+
* Erase cookie
|
802 |
+
*
|
803 |
+
* ```js
|
804 |
+
* // usage:
|
805 |
+
* _inbound.Utils.eraseCookie( 'cookie_name' );
|
806 |
+
* // deletes 'cookie_name' value
|
807 |
+
* ```
|
808 |
+
* @param {string} name name of cookie
|
809 |
+
* @return {string} value of cookie
|
810 |
+
*/
|
811 |
+
eraseCookie: function(name) {
|
812 |
+
this.createCookie(name, "", -1);
|
813 |
+
},
|
814 |
+
/* Get All Cookies */
|
815 |
+
getAllCookies: function() {
|
816 |
+
var cookies = {};
|
817 |
+
if (document.cookie && document.cookie !== '') {
|
818 |
+
var split = document.cookie.split(';');
|
819 |
+
for (var i = 0; i < split.length; i++) {
|
820 |
+
var name_value = split[i].split("=");
|
821 |
+
name_value[0] = name_value[0].replace(/^ /, '');
|
822 |
+
cookies[decodeURIComponent(name_value[0])] = decodeURIComponent(name_value[1]);
|
823 |
+
}
|
824 |
+
}
|
825 |
+
_inbound.totalStorage('inbound_cookies', cookies); // store cookie data
|
826 |
+
return cookies;
|
827 |
+
},
|
828 |
+
/* Grab URL params and save */
|
829 |
+
setUrlParams: function() {
|
830 |
+
var urlParams = {};
|
831 |
+
|
832 |
+
(function() {
|
833 |
+
var e,
|
834 |
+
d = function(s) {
|
835 |
+
return decodeURIComponent(s).replace(/\+/g, " ");
|
836 |
+
},
|
837 |
+
q = window.location.search.substring(1),
|
838 |
+
r = /([^&=]+)=?([^&]*)/g;
|
839 |
+
|
840 |
+
while (e = r.exec(q)) {
|
841 |
+
if (e[1].indexOf("[") == "-1")
|
842 |
+
urlParams[d(e[1])] = d(e[2]);
|
843 |
+
else {
|
844 |
+
var b1 = e[1].indexOf("["),
|
845 |
+
aN = e[1].slice(b1 + 1, e[1].indexOf("]", b1)),
|
846 |
+
pN = d(e[1].slice(0, b1));
|
847 |
+
|
848 |
+
if (typeof urlParams[pN] != "object")
|
849 |
+
urlParams[d(pN)] = {},
|
850 |
+
urlParams[d(pN)].length = 0;
|
851 |
+
|
852 |
+
if (aN)
|
853 |
+
urlParams[d(pN)][d(aN)] = d(e[2]);
|
854 |
+
else
|
855 |
+
Array.prototype.push.call(urlParams[d(pN)], d(e[2]));
|
856 |
+
|
857 |
+
}
|
858 |
+
}
|
859 |
+
})();
|
860 |
+
|
861 |
+
/* Set Param Cookies */
|
862 |
+
for (var k in urlParams) {
|
863 |
+
/* account for wordpress media uploader bug */
|
864 |
+
if (k == 'action') {
|
865 |
+
continue;
|
866 |
+
}
|
867 |
+
|
868 |
+
if (typeof urlParams[k] == "object") {
|
869 |
+
for (var k2 in urlParams[k])
|
870 |
+
this.createCookie(k2, urlParams[k][k2], 30);
|
871 |
+
} else {
|
872 |
+
this.createCookie(k, urlParams[k], 30);
|
873 |
+
}
|
874 |
+
}
|
875 |
+
/* Set Param LocalStorage */
|
876 |
+
if (storageSupported) {
|
877 |
+
var pastParams = _inbound.totalStorage('inbound_url_params') || {};
|
878 |
+
var params = this.mergeObjs(pastParams, urlParams);
|
879 |
+
_inbound.totalStorage('inbound_url_params', params); // store cookie data
|
880 |
+
}
|
881 |
+
|
882 |
+
var options = {
|
883 |
+
'option1': 'yo',
|
884 |
+
'option2': 'woooo'
|
885 |
+
};
|
886 |
+
|
887 |
+
_inbound.trigger('url_parameters', urlParams, options);
|
888 |
+
|
889 |
+
},
|
890 |
+
getAllUrlParams: function() {
|
891 |
+
var get_params = {};
|
892 |
+
if (storageSupported) {
|
893 |
+
var get_params = _inbound.totalStorage('inbound_url_params');
|
894 |
+
}
|
895 |
+
return get_params;
|
896 |
+
},
|
897 |
+
/* Get url param */
|
898 |
+
getParameterVal: function(name, string) {
|
899 |
+
return (RegExp(name + '=' + '(.+?)(&|$)').exec(string) || [, false])[1];
|
900 |
+
},
|
901 |
+
// Check local storage
|
902 |
+
// provate browsing safari fix https://github.com/marcuswestin/store.js/issues/42#issuecomment-25274685
|
903 |
+
checkLocalStorage: function() {
|
904 |
+
if ('localStorage' in window) {
|
905 |
+
try {
|
906 |
+
ls = (typeof window.localStorage === 'undefined') ? undefined : window.localStorage;
|
907 |
+
if (typeof ls == 'undefined' || typeof window.JSON == 'undefined') {
|
908 |
+
storageSupported = false;
|
909 |
+
} else {
|
910 |
+
storageSupported = true;
|
911 |
+
}
|
912 |
+
|
913 |
+
} catch (err) {
|
914 |
+
storageSupported = false;
|
915 |
+
}
|
916 |
+
}
|
917 |
+
return storageSupported;
|
918 |
+
/* http://spin.atomicobject.com/2013/01/23/ios-private-browsing-localstorage/
|
919 |
+
var hasStorage;
|
920 |
+
hasStorage = function() {
|
921 |
+
var mod, result;
|
922 |
+
try {
|
923 |
+
mod = new Date;
|
924 |
+
localStorage.setItem(mod, mod.toString());
|
925 |
+
result = localStorage.getItem(mod) === mod.toString();
|
926 |
+
localStorage.removeItem(mod);
|
927 |
+
return result;
|
928 |
+
} catch (_error) {}
|
929 |
+
};
|
930 |
+
*/
|
931 |
+
},
|
932 |
+
// http://stackoverflow.com/questions/4391575/how-to-find-the-size-of-localstorage
|
933 |
+
showLocalStorageSize: function() {
|
934 |
+
function stringSizeBytes(str) {
|
935 |
+
return str.length * 2;
|
936 |
+
}
|
937 |
+
|
938 |
+
function toMB(bytes) {
|
939 |
+
return bytes / 1024 / 1024;
|
940 |
+
}
|
941 |
+
|
942 |
+
function toSize(key) {
|
943 |
+
return {
|
944 |
+
name: key,
|
945 |
+
size: stringSizeBytes(localStorage[key])
|
946 |
+
};
|
947 |
+
}
|
948 |
+
|
949 |
+
function toSizeMB(info) {
|
950 |
+
info.size = toMB(info.size).toFixed(2) + ' MB';
|
951 |
+
return info;
|
952 |
+
}
|
953 |
+
|
954 |
+
var sizes = Object.keys(localStorage).map(toSize).map(toSizeMB);
|
955 |
+
|
956 |
+
console.table(sizes);
|
957 |
+
},
|
958 |
+
/* Add days to datetime */
|
959 |
+
addDays: function(myDate, days) {
|
960 |
+
return new Date(myDate.getTime() + days * 24 * 60 * 60 * 1000);
|
961 |
+
},
|
962 |
+
GetDate: function() {
|
963 |
+
var timeNow = new Date(),
|
964 |
+
d = timeNow.getDate(),
|
965 |
+
dPre = (d < 10) ? "0" : "",
|
966 |
+
y = timeNow.getFullYear(),
|
967 |
+
h = timeNow.getHours(),
|
968 |
+
hPre = (h < 10) ? "0" : "",
|
969 |
+
min = timeNow.getMinutes(),
|
970 |
+
minPre = (min < 10) ? "0" : "",
|
971 |
+
sec = timeNow.getSeconds(),
|
972 |
+
secPre = (sec < 10) ? "0" : "",
|
973 |
+
m = timeNow.getMonth() + 1,
|
974 |
+
mPre = (m < 10) ? "0" : "";
|
975 |
+
|
976 |
+
var datetime = y + '/' + mPre + m + "/" + dPre + d + " " + hPre + h + ":" + minPre + min + ":" + secPre + sec;
|
977 |
+
/* format 2014/11/13 18:22:02 */
|
978 |
+
return datetime;
|
979 |
+
},
|
980 |
+
/* Set Expiration Date of Session Logging. LEGACY Not in Use */
|
981 |
+
SetSessionTimeout: function() {
|
982 |
+
var session = this.readCookie("lead_session_expire");
|
983 |
+
//console.log(session_check);
|
984 |
+
if (!session) {
|
985 |
+
//_inbound.trigger('session_start'); // trigger 'inbound_analytics_session_start'
|
986 |
+
} else {
|
987 |
+
//_inbound.trigger('session_resume'); // trigger 'inbound_analytics_session_active'
|
988 |
+
}
|
989 |
+
var d = new Date();
|
990 |
+
d.setTime(d.getTime() + 30 * 60 * 1000);
|
991 |
+
|
992 |
+
this.createCookie("lead_session_expire", true, d); // Set cookie on page load
|
993 |
+
|
994 |
+
},
|
995 |
+
storeReferralData: function() {
|
996 |
+
//console.log(expire_time);
|
997 |
+
var d = new Date(),
|
998 |
+
referrer = document.referrer || "Direct Traffic",
|
999 |
+
referrer_cookie = _inbound.Utils.readCookie("inbound_referral_site"),
|
1000 |
+
original_src = _inbound.totalStorage('inbound_original_referral');
|
1001 |
+
|
1002 |
+
d.setTime(d.getTime() + 30 * 60 * 1000);
|
1003 |
+
|
1004 |
+
if (!referrer_cookie) {
|
1005 |
+
this.createCookie("inbound_referral_site", referrer, d);
|
1006 |
+
}
|
1007 |
+
if (!original_src) {
|
1008 |
+
_inbound.totalStorage('inbound_original_referral', original_src);
|
1009 |
+
}
|
1010 |
+
},
|
1011 |
+
CreateUID: function(length) {
|
1012 |
+
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'.split(''),
|
1013 |
+
str = '';
|
1014 |
+
if (!length) {
|
1015 |
+
length = Math.floor(Math.random() * chars.length);
|
1016 |
+
}
|
1017 |
+
for (var i = 0; i < length; i++) {
|
1018 |
+
str += chars[Math.floor(Math.random() * chars.length)];
|
1019 |
+
}
|
1020 |
+
return str;
|
1021 |
+
},
|
1022 |
+
generateGUID: function(a) {
|
1023 |
+
return a ? (a ^ 16 * Math.random() >> a / 4).toString(16) : ([1E7] + -1E3 + -4E3 + -8E3 + -1E11).replace(/[018]/g, guid);
|
1024 |
+
},
|
1025 |
+
SetUID: function(leadUID) {
|
1026 |
+
/* Set Lead UID */
|
1027 |
+
if (!this.readCookie("wp_lead_uid")) {
|
1028 |
+
var wp_lead_uid = leadUID || this.CreateUID(35);
|
1029 |
+
this.createCookie("wp_lead_uid", wp_lead_uid);
|
1030 |
+
}
|
1031 |
+
},
|
1032 |
+
/* Count number of session visits */
|
1033 |
+
countProperties: function(obj) {
|
1034 |
+
var count = 0;
|
1035 |
+
for (var prop in obj) {
|
1036 |
+
if (obj.hasOwnProperty(prop)) {
|
1037 |
+
++count;
|
1038 |
+
}
|
1039 |
+
}
|
1040 |
+
return count;
|
1041 |
+
},
|
1042 |
+
mergeObjs: function(obj1, obj2) {
|
1043 |
+
var obj3 = {};
|
1044 |
+
for (var attrname in obj1) {
|
1045 |
+
obj3[attrname] = obj1[attrname];
|
1046 |
+
}
|
1047 |
+
for (var attrname in obj2) {
|
1048 |
+
obj3[attrname] = obj2[attrname];
|
1049 |
+
}
|
1050 |
+
return obj3;
|
1051 |
+
},
|
1052 |
+
hasClass: function(className, el) {
|
1053 |
+
var hasClass;
|
1054 |
+
if ('classList' in document.documentElement) {
|
1055 |
+
var hasClass = el.classList.contains(className);
|
1056 |
+
} else {
|
1057 |
+
var hasClass = new RegExp('(^|\\s)' + className + '(\\s|$)').test(el.className); /* IE Polyfill */
|
1058 |
+
}
|
1059 |
+
return hasClass;
|
1060 |
+
},
|
1061 |
+
addClass: function(className, el) {
|
1062 |
+
if ('classList' in document.documentElement) {
|
1063 |
+
el.classList.add(className);
|
1064 |
+
} else {
|
1065 |
+
if (!this.hasClass(el, className)) {
|
1066 |
+
el.className += (el.className ? ' ' : '') + className;
|
1067 |
+
}
|
1068 |
+
}
|
1069 |
+
},
|
1070 |
+
removeClass: function(className, el) {
|
1071 |
+
if ('classList' in document.documentElement) {
|
1072 |
+
el.classList.remove(className);
|
1073 |
+
} else {
|
1074 |
+
if (this.hasClass(el, className)) {
|
1075 |
+
el.className = el.className.replace(new RegExp('(^|\\s)*' + className + '(\\s|$)*', 'g'), '');
|
1076 |
+
}
|
1077 |
+
}
|
1078 |
+
},
|
1079 |
+
removeElement: function(el) {
|
1080 |
+
el.parentNode.removeChild(el);
|
1081 |
+
},
|
1082 |
+
trim: function(s) {
|
1083 |
+
s = s.replace(/(^\s*)|(\s*$)/gi, "");
|
1084 |
+
s = s.replace(/[ ]{2,}/gi, " ");
|
1085 |
+
s = s.replace(/\n /, "\n");
|
1086 |
+
return s;
|
1087 |
+
},
|
1088 |
+
ajaxPolyFill: function() {
|
1089 |
+
if (typeof XMLHttpRequest !== 'undefined') {
|
1090 |
+
return new XMLHttpRequest();
|
1091 |
+
}
|
1092 |
+
var versions = [
|
1093 |
+
"MSXML2.XmlHttp.5.0",
|
1094 |
+
"MSXML2.XmlHttp.4.0",
|
1095 |
+
"MSXML2.XmlHttp.3.0",
|
1096 |
+
"MSXML2.XmlHttp.2.0",
|
1097 |
+
"Microsoft.XmlHttp"
|
1098 |
+
];
|
1099 |
+
|
1100 |
+
var xhr;
|
1101 |
+
for (var i = 0; i < versions.length; i++) {
|
1102 |
+
try {
|
1103 |
+
xhr = new ActiveXObject(versions[i]);
|
1104 |
+
break;
|
1105 |
+
} catch (e) {}
|
1106 |
+
}
|
1107 |
+
return xhr;
|
1108 |
+
},
|
1109 |
+
ajaxSendData: function(url, callback, method, data, sync) {
|
1110 |
+
var x = this.ajaxPolyFill();
|
1111 |
+
/* timeout for safari idiocy */
|
1112 |
+
setTimeout(function() {
|
1113 |
+
x.open(method, url, true);
|
1114 |
+
x.onreadystatechange = function() {
|
1115 |
+
if (x.readyState == 4) {
|
1116 |
+
callback(x.responseText)
|
1117 |
+
}
|
1118 |
+
};
|
1119 |
+
if (method == 'POST') {
|
1120 |
+
x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
1121 |
+
}
|
1122 |
+
x.send(data);
|
1123 |
+
}, 100);
|
1124 |
+
},
|
1125 |
+
ajaxGet: function(url, data, callback, sync) {
|
1126 |
+
var query = [];
|
1127 |
+
for (var key in data) {
|
1128 |
+
query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
|
1129 |
+
}
|
1130 |
+
this.ajaxSendData(url + '?' + query.join('&'), callback, 'GET', null, sync)
|
1131 |
+
},
|
1132 |
+
ajaxPost: function(url, data, callback, sync) {
|
1133 |
+
var query = [];
|
1134 |
+
for (var key in data) {
|
1135 |
+
query.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key]));
|
1136 |
+
}
|
1137 |
+
this.ajaxSendData(url, callback, 'POST', query.join('&'), sync)
|
1138 |
+
},
|
1139 |
+
/**
|
1140 |
+
* @param {string} event
|
1141 |
+
* @param {(Object|null)} properties
|
1142 |
+
* @param {(Function|null)} callback
|
1143 |
+
*/
|
1144 |
+
sendEvent: function(event, properties, callback) {
|
1145 |
+
properties = properties || {};
|
1146 |
+
async = true;
|
1147 |
+
var cookieData = getCookie(); /* get cookie data */
|
1148 |
+
if (cookieData) {
|
1149 |
+
var key;
|
1150 |
+
for (key in cookieData) {
|
1151 |
+
properties[key] = cookieData[key];
|
1152 |
+
}
|
1153 |
+
}
|
1154 |
+
if (!properties.id) {
|
1155 |
+
properties.id = getId();
|
1156 |
+
}
|
1157 |
+
var props = {
|
1158 |
+
e: event,
|
1159 |
+
t: (new Date()).toISOString(),
|
1160 |
+
kv: properties
|
1161 |
+
};
|
1162 |
+
var path = settings.api_host + '/track?data=' + encodeURIComponent(JSON.stringify(props));
|
1163 |
+
if (corsEnabled) {
|
1164 |
+
/* CORS */
|
1165 |
+
var xhr = new XMLHttpRequest();
|
1166 |
+
xhr.open('GET', path, async);
|
1167 |
+
xhr.withCredentials = async;
|
1168 |
+
xhr.send(null);
|
1169 |
+
} else {
|
1170 |
+
/* jsonP */
|
1171 |
+
var el = document.createElement('script');
|
1172 |
+
el.type = 'text/javascript';
|
1173 |
+
el.async = async;
|
1174 |
+
el.defer = async;
|
1175 |
+
el.src = path;
|
1176 |
+
var insertAt = document.getElementsByTagName('script')[0];
|
1177 |
+
insertAt.parentNode.insertBefore(el, insertAt);
|
1178 |
+
}
|
1179 |
+
return action(callback), self;
|
1180 |
+
},
|
1181 |
+
domReady: function(win, fn) {
|
1182 |
+
|
1183 |
+
var done = false,
|
1184 |
+
top = true,
|
1185 |
+
|
1186 |
+
doc = win.document,
|
1187 |
+
root = doc.documentElement,
|
1188 |
+
|
1189 |
+
add = doc.addEventListener ? 'addEventListener' : 'attachEvent',
|
1190 |
+
rem = doc.addEventListener ? 'removeEventListener' : 'detachEvent',
|
1191 |
+
pre = doc.addEventListener ? '' : 'on',
|
1192 |
+
|
1193 |
+
init = function(e) {
|
1194 |
+
if (e.type == 'readystatechange' && doc.readyState != 'complete') return;
|
1195 |
+
(e.type == 'load' ? win : doc)[rem](pre + e.type, init, false);
|
1196 |
+
if (!done && (done = true)) fn.call(win, e.type || e);
|
1197 |
+
},
|
1198 |
+
|
1199 |
+
poll = function() {
|
1200 |
+
try {
|
1201 |
+
root.doScroll('left');
|
1202 |
+
} catch (e) {
|
1203 |
+
setTimeout(poll, 50);
|
1204 |
+
return;
|
1205 |
+
}
|
1206 |
+
init('poll');
|
1207 |
+
};
|
1208 |
+
|
1209 |
+
if (doc.readyState == 'complete') {
|
1210 |
+
|
1211 |
+
fn.call(win, 'lazy');
|
1212 |
+
|
1213 |
+
} else {
|
1214 |
+
if (doc.createEventObject && root.doScroll) {
|
1215 |
+
try {
|
1216 |
+
top = !win.frameElement;
|
1217 |
+
} catch (e) {}
|
1218 |
+
if (top) poll();
|
1219 |
+
}
|
1220 |
+
doc[add](pre + 'DOMContentLoaded', init, false);
|
1221 |
+
doc[add](pre + 'readystatechange', init, false);
|
1222 |
+
win[add](pre + 'load', init, false);
|
1223 |
+
}
|
1224 |
+
|
1225 |
+
},
|
1226 |
+
/* Cross-browser event listening */
|
1227 |
+
addListener: function(element, eventName, listener) {
|
1228 |
+
if (!element) {
|
1229 |
+
return;
|
1230 |
+
}
|
1231 |
+
//console.log(eventName);
|
1232 |
+
//console.log(listener);
|
1233 |
+
if (element.addEventListener) {
|
1234 |
+
element.addEventListener(eventName, listener, false);
|
1235 |
+
} else if (element.attachEvent) {
|
1236 |
+
element.attachEvent("on" + eventName, listener);
|
1237 |
+
} else {
|
1238 |
+
element['on' + eventName] = listener;
|
1239 |
+
}
|
1240 |
+
},
|
1241 |
+
removeListener: function(element, eventName, listener) {
|
1242 |
+
|
1243 |
+
if (element.removeEventListener) {
|
1244 |
+
element.removeEventListener(eventName, listener, false);
|
1245 |
+
} else if (element.detachEvent) {
|
1246 |
+
element.detachEvent("on" + eventName, listener);
|
1247 |
+
} else {
|
1248 |
+
element["on" + eventName] = null;
|
1249 |
+
}
|
1250 |
+
},
|
1251 |
+
/*
|
1252 |
+
* Throttle function borrowed from:
|
1253 |
+
* Underscore.js 1.5.2
|
1254 |
+
* http://underscorejs.org
|
1255 |
+
* (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
1256 |
+
* Underscore may be freely distributed under the MIT license.
|
1257 |
+
*/
|
1258 |
+
throttle: function(func, wait) {
|
1259 |
+
var context, args, result;
|
1260 |
+
var timeout = null;
|
1261 |
+
var previous = 0;
|
1262 |
+
var later = function() {
|
1263 |
+
previous = new Date;
|
1264 |
+
timeout = null;
|
1265 |
+
result = func.apply(context, args);
|
1266 |
+
};
|
1267 |
+
return function() {
|
1268 |
+
var now = new Date;
|
1269 |
+
if (!previous) previous = now;
|
1270 |
+
var remaining = wait - (now - previous);
|
1271 |
+
context = this;
|
1272 |
+
args = arguments;
|
1273 |
+
if (remaining <= 0) {
|
1274 |
+
clearTimeout(timeout);
|
1275 |
+
timeout = null;
|
1276 |
+
previous = now;
|
1277 |
+
result = func.apply(context, args);
|
1278 |
+
} else if (!timeout) {
|
1279 |
+
timeout = setTimeout(later, remaining);
|
1280 |
+
}
|
1281 |
+
return result;
|
1282 |
+
};
|
1283 |
+
},
|
1284 |
+
/*
|
1285 |
+
* Determine which version of GA is being used
|
1286 |
+
* "ga", "_gaq", and "dataLayer" are the possible globals
|
1287 |
+
*/
|
1288 |
+
checkTypeofGA: function() {
|
1289 |
+
if (typeof ga === "function") {
|
1290 |
+
universalGA = true;
|
1291 |
+
}
|
1292 |
+
|
1293 |
+
if (typeof _gaq !== "undefined" && typeof _gaq.push === "function") {
|
1294 |
+
classicGA = true;
|
1295 |
+
}
|
1296 |
+
|
1297 |
+
if (typeof dataLayer !== "undefined" && typeof dataLayer.push === "function") {
|
1298 |
+
googleTagManager = true;
|
1299 |
+
}
|
1300 |
+
|
1301 |
+
},
|
1302 |
+
/**
|
1303 |
+
* Caches user's search data in the browser until they can be saved to the database
|
1304 |
+
*/
|
1305 |
+
cacheSearchData: function(searchData, form) {
|
1306 |
+
|
1307 |
+
if(storageSupported){
|
1308 |
+
//store the searches in the local storage
|
1309 |
+
var stored = _inbound.totalStorage.getItem('inbound_search_storage');
|
1310 |
+
if(stored){
|
1311 |
+
//if there are stored searches, put the new one in the first index
|
1312 |
+
stored.unshift(searchData);
|
1313 |
+
_inbound.totalStorage.setItem('inbound_search_storage', stored);
|
1314 |
+
}else{
|
1315 |
+
//if there aren't any searches stored, save the current search
|
1316 |
+
var store = [searchData];
|
1317 |
+
_inbound.totalStorage.setItem('inbound_search_storage', store);
|
1318 |
+
}
|
1319 |
+
}else{
|
1320 |
+
//if local storage is not possible, store the data in a cookie
|
1321 |
+
var new_search = JSON.stringify(searchData),
|
1322 |
+
stored_searches = this.readCookie('inbound_search_storage');
|
1323 |
+
|
1324 |
+
if(stored_searches){
|
1325 |
+
//add the old searches to the new one
|
1326 |
+
new_search += ('SPLIT-TOKEN' + stored_searches);
|
1327 |
+
}
|
1328 |
+
this.createCookie('inbound_search_storage', new_search, '180');
|
1329 |
+
}
|
1330 |
+
|
1331 |
+
_inbound.Forms.releaseFormSubmit(form);
|
1332 |
+
},
|
1333 |
+
/**
|
1334 |
+
* Stores search data to the database on page load.
|
1335 |
+
* If successful, it erases the cached searches from the user's browser
|
1336 |
+
*/
|
1337 |
+
storeSearchData: function(){
|
1338 |
+
|
1339 |
+
/*if there isn't a lead id or the nonce isn't set, don't try to store the data*/
|
1340 |
+
if(!inbound_settings.wp_lead_data.lead_id || !inbound_settings.wp_lead_data.lead_nonce){
|
1341 |
+
return;
|
1342 |
+
}
|
1343 |
+
|
1344 |
+
var dataToSend = [],
|
1345 |
+
localStorageData = _inbound.totalStorage.getItem('inbound_search_storage'),
|
1346 |
+
cookieStorageData = this.readCookie('inbound_search_storage');
|
1347 |
+
|
1348 |
+
/*if nothing is stored, exit*/
|
1349 |
+
if(!localStorageData && !cookieStorageData){
|
1350 |
+
return;
|
1351 |
+
}
|
1352 |
+
|
1353 |
+
/*if set, add the cookie search data to the data to send*/
|
1354 |
+
if(cookieStorageData){
|
1355 |
+
cookieStorageData = cookieStorageData.split('SPLIT-TOKEN');
|
1356 |
+
|
1357 |
+
for(var i in cookieStorageData){
|
1358 |
+
//console.log(cookieStorageData[i]);
|
1359 |
+
dataToSend.push(JSON.parse(cookieStorageData[i]));
|
1360 |
+
}
|
1361 |
+
}
|
1362 |
+
|
1363 |
+
/*if set, add the locally stored data to the data to send*/
|
1364 |
+
if(localStorageData){
|
1365 |
+
dataToSend = dataToSend.concat(localStorageData);
|
1366 |
+
}
|
1367 |
+
|
1368 |
+
dataToSend.sort(function(a, b){ return a.timestamp - b.timestamp; });
|
1369 |
+
|
1370 |
+
dataToSend = encodeURIComponent(JSON.stringify(dataToSend));
|
1371 |
+
|
1372 |
+
var package = {'action' : 'inbound_search_store', 'data' : dataToSend, 'nonce' : inbound_settings.wp_lead_data.lead_nonce, 'lead_id' : inbound_settings.wp_lead_data.lead_id };
|
1373 |
+
|
1374 |
+
callback = function(status){
|
1375 |
+
if(status){ status = JSON.parse(status); }
|
1376 |
+
|
1377 |
+
if(status.success){
|
1378 |
+
//log the success!
|
1379 |
+
console.log(status.success);
|
1380 |
+
//erase the stored data
|
1381 |
+
_inbound.Utils.eraseCookie('inbound_search_storage');
|
1382 |
+
_inbound.totalStorage.deleteItem('inbound_search_storage');
|
1383 |
+
}
|
1384 |
+
|
1385 |
+
if(status.error){
|
1386 |
+
console.log(status.error);
|
1387 |
+
}
|
1388 |
+
};
|
1389 |
+
this.ajaxPost(inbound_settings.admin_url, package, callback);
|
1390 |
+
}
|
1391 |
+
};
|
1392 |
+
|
1393 |
+
return _inbound;
|
1394 |
+
|
1395 |
+
})(_inbound || {});
|
1396 |
+
|
1397 |
+
/**
|
1398 |
+
* # Inbound Forms
|
1399 |
+
*
|
1400 |
+
* This file contains all of the form functions of the main _inbound object.
|
1401 |
+
* Filters and actions are described below
|
1402 |
+
*
|
1403 |
+
* @contributor David Wells <david@inboundnow.com>
|
1404 |
+
* @contributor Hudson Atwell <hudson@inboundnow.com>
|
1405 |
+
* @version 0.0.2
|
1406 |
+
*/
|
1407 |
+
/* Finish Exclusions for CC */
|
1408 |
+
|
1409 |
+
/* Launches form class */
|
1410 |
+
var InboundForms = (function(_inbound) {
|
1411 |
+
|
1412 |
+
var debugMode = false,
|
1413 |
+
utils = _inbound.Utils,
|
1414 |
+
no_match = [],
|
1415 |
+
rawParams = [],
|
1416 |
+
mappedParams = [],
|
1417 |
+
callTracker = {},
|
1418 |
+
settings = _inbound.Settings;
|
1419 |
+
|
1420 |
+
var FieldMapArray = [
|
1421 |
+
"first name",
|
1422 |
+
"last name",
|
1423 |
+
"name",
|
1424 |
+
"email",
|
1425 |
+
"e-mail",
|
1426 |
+
"phone",
|
1427 |
+
"website",
|
1428 |
+
"job title",
|
1429 |
+
"your favorite food",
|
1430 |
+
"company",
|
1431 |
+
"tele",
|
1432 |
+
"address",
|
1433 |
+
"comment"
|
1434 |
+
/* Adding values here maps them */
|
1435 |
+
];
|
1436 |
+
|
1437 |
+
_inbound.Forms = {
|
1438 |
+
|
1439 |
+
// Init Form functions
|
1440 |
+
init: function() {
|
1441 |
+
_inbound.Forms.runFieldMappingFilters();
|
1442 |
+
_inbound.Forms.formTrackInit();
|
1443 |
+
_inbound.Forms.searchTrackInit();
|
1444 |
+
},
|
1445 |
+
/**
|
1446 |
+
* This triggers the forms.field_map filter on the mapping array.
|
1447 |
+
* This will allow you to add or remore Items from the mapping lookup
|
1448 |
+
*
|
1449 |
+
* ### Example inbound.form_map_before filter
|
1450 |
+
*
|
1451 |
+
* This is an example of how form mapping can be filtered and
|
1452 |
+
* additional fields can be mapped via javascript
|
1453 |
+
*
|
1454 |
+
* ```js
|
1455 |
+
* // Adding the filter function
|
1456 |
+
* function Inbound_Add_Filter_Example( FieldMapArray ) {
|
1457 |
+
* var map = FieldMapArray || [];
|
1458 |
+
* map.push('new lookup value');
|
1459 |
+
*
|
1460 |
+
* return map;
|
1461 |
+
* };
|
1462 |
+
*
|
1463 |
+
* // Adding the filter on dom ready
|
1464 |
+
* _inbound.hooks.addFilter( 'inbound.form_map_before', Inbound_Add_Filter_Example, 10 );
|
1465 |
+
* ```
|
1466 |
+
*
|
1467 |
+
* @return {[type]} [description]
|
1468 |
+
*/
|
1469 |
+
runFieldMappingFilters: function() {
|
1470 |
+
FieldMapArray = _inbound.hooks.applyFilters('forms.field_map', FieldMapArray);
|
1471 |
+
//alert(FieldMapArray);
|
1472 |
+
},
|
1473 |
+
debug: function(msg, callback) {
|
1474 |
+
//if app not in debug mode, exit immediately
|
1475 |
+
if (!debugMode || !console) {
|
1476 |
+
return;
|
1477 |
+
}
|
1478 |
+
|
1479 |
+
var msg = msg || false;
|
1480 |
+
//console.log the message
|
1481 |
+
if (msg && (typeof msg === 'string')) {
|
1482 |
+
console.log(msg);
|
1483 |
+
}
|
1484 |
+
|
1485 |
+
//execute the callback if one was passed-in
|
1486 |
+
if (callback && (callback instanceof Function)) {
|
1487 |
+
callback();
|
1488 |
+
}
|
1489 |
+
},
|
1490 |
+
formTrackInit: function() {
|
1491 |
+
|
1492 |
+
for (var i = 0; i < window.document.forms.length; i++) {
|
1493 |
+
var trackForm = false;
|
1494 |
+
var form = window.document.forms[i];
|
1495 |
+
/* process forms only once */
|
1496 |
+
if (!form.dataset.formProcessed) {
|
1497 |
+
form.dataset.formProcessed = true;
|
1498 |
+
trackForm = this.checkTrackStatus(form);
|
1499 |
+
if (trackForm) {
|
1500 |
+
this.attachFormSubmitEvent(form); /* attach form listener */
|
1501 |
+
this.initFormMapping(form);
|
1502 |
+
}
|
1503 |
+
}
|
1504 |
+
}
|
1505 |
+
},
|
1506 |
+
searchTrackInit: function(){
|
1507 |
+
|
1508 |
+
/* exit if searches aren't supposed to be tracked, or this function has already been called */
|
1509 |
+
if(inbound_settings.search_tracking == 'off' || callTracker['searchTrackInit']){
|
1510 |
+
return;
|
1511 |
+
}
|
1512 |
+
|
1513 |
+
for (var i = 0; i < window.document.forms.length; i++) {
|
1514 |
+
var trackForm = false;
|
1515 |
+
var form = window.document.forms[i];
|
1516 |
+
/* process forms only once */
|
1517 |
+
if (!form.dataset.searchChecked) {
|
1518 |
+
form.dataset.searchChecked = true;
|
1519 |
+
trackForm = this.checkSearchTrackStatus(form);
|
1520 |
+
if (trackForm) {
|
1521 |
+
this.attachSearchFormSubmitEvent(form); /* attach form listener */
|
1522 |
+
}
|
1523 |
+
}
|
1524 |
+
}
|
1525 |
+
|
1526 |
+
/* store the search data on init */
|
1527 |
+
utils.storeSearchData();
|
1528 |
+
|
1529 |
+
/* log that this function has been called */
|
1530 |
+
callTracker['searchTrackInit'] = true;
|
1531 |
+
},
|
1532 |
+
checkTrackStatus: function(form) {
|
1533 |
+
var ClassIs = form.getAttribute('class');
|
1534 |
+
if (ClassIs !== "" && ClassIs !== null) {
|
1535 |
+
if (ClassIs.toLowerCase().indexOf("wpl-track-me") > -1) {
|
1536 |
+
return true;
|
1537 |
+
} else if (ClassIs.toLowerCase().indexOf("inbound-track") > -1) {
|
1538 |
+
return true;
|
1539 |
+
} else {
|
1540 |
+
cb = function() { console.log(form); };
|
1541 |
+
_inbound.deBugger('forms', "This form not tracked. Please assign on in settings...", cb);
|
1542 |
+
return false;
|
1543 |
+
}
|
1544 |
+
}
|
1545 |
+
},
|
1546 |
+
checkSearchTrackStatus: function(form) {
|
1547 |
+
var ClassIs = form.getAttribute('class'),
|
1548 |
+
IdIs = form.getAttribute('id');
|
1549 |
+
if (ClassIs !== "" && ClassIs !== null) {
|
1550 |
+
if (ClassIs.toLowerCase().indexOf("search") > -1) {
|
1551 |
+
return true;
|
1552 |
+
}
|
1553 |
+
}
|
1554 |
+
if (IdIs !== "" && IdIs !== null) {
|
1555 |
+
if (IdIs.toLowerCase().indexOf("search") > -1) {
|
1556 |
+
return true;
|
1557 |
+
}
|
1558 |
+
}else{
|
1559 |
+
cb = function() { console.log(form); };
|
1560 |
+
_inbound.deBugger('searches', "This search form is not tracked. Please assign on in settings...", cb);
|
1561 |
+
return false;
|
1562 |
+
}
|
1563 |
+
},
|
1564 |
+
/* Loop through include/exclude items for tracking */
|
1565 |
+
loopClassSelectors: function(selectors, action) {
|
1566 |
+
for (var i = selectors.length - 1; i >= 0; i--) {
|
1567 |
+
|
1568 |
+
var selector = utils.trim(selectors[i])
|
1569 |
+
if (selector.indexOf("#") === -1 && selector.indexOf(".") === -1) {
|
1570 |
+
// assign ID as default
|
1571 |
+
selector = "#" + selector;
|
1572 |
+
}
|
1573 |
+
//if(selectors[i] match . or # )
|
1574 |
+
selector = document.querySelector(selector);
|
1575 |
+
//console.log("SELECTOR", selector);
|
1576 |
+
if (selector) {
|
1577 |
+
if (action === 'add') {
|
1578 |
+
_inbound.Utils.addClass('wpl-track-me', selector);
|
1579 |
+
_inbound.Utils.addClass('inbound-track', selector);
|
1580 |
+
} else {
|
1581 |
+
_inbound.Utils.removeClass('wpl-track-me', selector);
|
1582 |
+
_inbound.Utils.removeClass('inbound-track', selector);
|
1583 |
+
}
|
1584 |
+
}
|
1585 |
+
}
|
1586 |
+
},
|
1587 |
+
/* Map field fields on load */
|
1588 |
+
initFormMapping: function(form) {
|
1589 |
+
var hiddenInputs = [];
|
1590 |
+
|
1591 |
+
for (var i = 0; i < form.elements.length; i++) {
|
1592 |
+
formInput = form.elements[i];
|
1593 |
+
|
1594 |
+
if (formInput.type === 'hidden') {
|
1595 |
+
hiddenInputs.push(formInput);
|
1596 |
+
continue;
|
1597 |
+
}
|
1598 |
+
|
1599 |
+
//this.ignoreFields(formInput);
|
1600 |
+
/* Map form fields */
|
1601 |
+
this.mapField(formInput);
|
1602 |
+
/* Remember visible inputs */
|
1603 |
+
this.rememberInputValues(formInput);
|
1604 |
+
/* Fill visible inputs */
|
1605 |
+
if (settings.formAutoPopulation && !_inbound.Utils.hasClass( "nopopulate", form ) ) {
|
1606 |
+
this.fillInputValues(formInput);
|
1607 |
+
}
|
1608 |
+
|
1609 |
+
}
|
1610 |
+
|
1611 |
+
/* loop hidden inputs */
|
1612 |
+
for (var n = hiddenInputs.length - 1; n >= 0; n--) {
|
1613 |
+
formInput = hiddenInputs[n];
|
1614 |
+
this.mapField(formInput);
|
1615 |
+
}
|
1616 |
+
|
1617 |
+
//console.log('mapping on load completed');
|
1618 |
+
},
|
1619 |
+
/* Maps data attributes to fields on page load */
|
1620 |
+
mapField: function(input) {
|
1621 |
+
|
1622 |
+
var input_id = input.id || false;
|
1623 |
+
var input_name = input.name || false;
|
1624 |
+
var label = this.getInputLabel(input);
|
1625 |
+
|
1626 |
+
if(label){
|
1627 |
+
//console.log(label[0].innerText);
|
1628 |
+
var ignoreField = this.ignoreFieldByLabel(label[0].innerText);
|
1629 |
+
if(ignoreField){
|
1630 |
+
input.dataset.ignoreFormField = true;
|
1631 |
+
return false;
|
1632 |
+
}
|
1633 |
+
}
|
1634 |
+
|
1635 |
+
/* Loop through all match possiblities */
|
1636 |
+
for (i = 0; i < FieldMapArray.length; i++) {
|
1637 |
+
//for (var i = FieldMapArray.length - 1; i >= 0; i--) {
|
1638 |
+
var found = false;
|
1639 |
+
var match = FieldMapArray[i];
|
1640 |
+
var lookingFor = utils.trim(match);
|
1641 |
+
var nice_name = lookingFor.replace(/ /g, '_');
|
1642 |
+
|
1643 |
+
|
1644 |
+
//console.log("NICE NAME", nice_name);
|
1645 |
+
//console.log('looking for match on ' + lookingFor);
|
1646 |
+
//_inbound.deBugger('forms', 'looking for match on ' + lookingFor + " nice_name= " + nice_name);
|
1647 |
+
|
1648 |
+
// Check if input has an attached lable using for= tag
|
1649 |
+
//var $laxbel = $("label[for='" + $element.attr('id') + "']").text();
|
1650 |
+
//var labxel = 'label[for="' + input_id + '"]';
|
1651 |
+
|
1652 |
+
/* look for name attribute match */
|
1653 |
+
if (input_name && input_name.toLowerCase().indexOf(lookingFor) > -1) {
|
1654 |
+
found = true;
|
1655 |
+
_inbound.deBugger('forms', 'Found matching name attribute for -> ' + lookingFor);
|
1656 |
+
|
1657 |
+
/* look for id match */
|
1658 |
+
} else if (input_id && input_id.toLowerCase().indexOf(lookingFor) > -1) {
|
1659 |
+
|
1660 |
+
found = true;
|
1661 |
+
_inbound.deBugger('forms', 'Found matching ID attribute for ->' + lookingFor);
|
1662 |
+
|
1663 |
+
/* Check siblings for label */
|
1664 |
+
} else if (label) {
|
1665 |
+
//var label = (label.length > 1 ? label[0] : label);
|
1666 |
+
//console.log('label', label);
|
1667 |
+
if (label[0].innerText.toLowerCase().indexOf(lookingFor) > -1) {
|
1668 |
+
|
1669 |
+
found = true;
|
1670 |
+
_inbound.deBugger('forms', 'Found matching sibling label for -> ' + lookingFor);
|
1671 |
+
|
1672 |
+
}
|
1673 |
+
|
1674 |
+
} else {
|
1675 |
+
/* no match found */
|
1676 |
+
//_inbound.deBugger('forms', 'NO Match on ' + lookingFor + " in " + input_name);
|
1677 |
+
no_match.push(lookingFor);
|
1678 |
+
|
1679 |
+
}
|
1680 |
+
|
1681 |
+
/* Map the field */
|
1682 |
+
if (found) {
|
1683 |
+
this.addDataAttr(input, nice_name);
|
1684 |
+
this.removeArrayItem(FieldMapArray, lookingFor);
|
1685 |
+
i--; //decrement count
|
1686 |
+
}
|
1687 |
+
|
1688 |
+
}
|
1689 |
+
|
1690 |
+
return inbound_data;
|
1691 |
+
|
1692 |
+
},
|
1693 |
+
/* prevent default submission temporarily */
|
1694 |
+
formListener: function(event) {
|
1695 |
+
//console.log(event);
|
1696 |
+
event.preventDefault();
|
1697 |
+
_inbound.Forms.saveFormData(event.target);
|
1698 |
+
document.body.style.cursor = "wait";
|
1699 |
+
},
|
1700 |
+
/* prevent default submission temporarily */
|
1701 |
+
searchFormListener: function(event) {
|
1702 |
+
//console.log(event);
|
1703 |
+
event.preventDefault();
|
1704 |
+
_inbound.Forms.saveSearchData(event.target);
|
1705 |
+
//document.body.style.cursor = "wait";
|
1706 |
+
},
|
1707 |
+
/* attach form listeners */
|
1708 |
+
attachFormSubmitEvent: function(form) {
|
1709 |
+
utils.addListener(form, 'submit', this.formListener);
|
1710 |
+
var email_input = document.querySelector('.inbound-email');
|
1711 |
+
/* utils.addListener(email_input, 'blur', this.mailCheck); */
|
1712 |
+
},
|
1713 |
+
/* attach search form listener */
|
1714 |
+
attachSearchFormSubmitEvent: function(form) {
|
1715 |
+
utils.addListener(form, 'submit', this.searchFormListener);
|
1716 |
+
},
|
1717 |
+
/* Ignore CC data */
|
1718 |
+
ignoreFieldByLabel: function(label) {
|
1719 |
+
var ignore_field = false;
|
1720 |
+
|
1721 |
+
if(!label){ return false; }
|
1722 |
+
|
1723 |
+
// Ignore any fields with labels that indicate a credit card field
|
1724 |
+
if (label.toLowerCase().indexOf('credit card') != -1 || label.toLowerCase().indexOf('card number') != -1) {
|
1725 |
+
ignore_field = true;
|
1726 |
+
}
|
1727 |
+
|
1728 |
+
if (label.toLowerCase().indexOf('expiration') != -1 || label.toLowerCase().indexOf('expiry') != -1) {
|
1729 |
+
ignore_field = true;
|
1730 |
+
}
|
1731 |
+
|
1732 |
+
if (label.toLowerCase() == 'month' || label.toLowerCase() == 'mm' || label.toLowerCase() == 'yy' || label.toLowerCase() == 'yyyy' || label.toLowerCase() == 'year') {
|
1733 |
+
ignore_field = true;
|
1734 |
+
}
|
1735 |
+
|
1736 |
+
if (label.toLowerCase().indexOf('cvv') != -1 || label.toLowerCase().indexOf('cvc') != -1 || label.toLowerCase().indexOf('secure code') != -1 || label.toLowerCase().indexOf('security code') != -1) {
|
1737 |
+
ignore_field = true;
|
1738 |
+
}
|
1739 |
+
|
1740 |
+
if(ignore_field){
|
1741 |
+
_inbound.deBugger('forms', 'ignore ' + label);
|
1742 |
+
}
|
1743 |
+
|
1744 |
+
return ignore_field;
|
1745 |
+
|
1746 |
+
},
|
1747 |
+
/* not implemented yet */
|
1748 |
+
ignoreFieldByValue: function(value){
|
1749 |
+
var ignore_field = false;
|
1750 |
+
|
1751 |
+
if(!value){ return false; }
|
1752 |
+
|
1753 |
+
if (value.toLowerCase() == 'visa' || value.toLowerCase() == 'mastercard' || value.toLowerCase() == 'american express' || value.toLowerCase() == 'amex' || value.toLowerCase() == 'discover') {
|
1754 |
+
ignore_field = true;
|
1755 |
+
}
|
1756 |
+
|
1757 |
+
// Check if value has integers, strip out spaces, then ignore anything with a credit card length (>16) or an expiration/cvv length (<5)
|
1758 |
+
var int_regex = new RegExp("/^[0-9]+$/");
|
1759 |
+
if (int_regex.test(value)) {
|
1760 |
+
var value_no_spaces = value.replace(' ', '');
|
1761 |
+
|
1762 |
+
if (this.isInt(value_no_spaces) && value_no_spaces.length >= 16) {
|
1763 |
+
ignore_field = true;
|
1764 |
+
}
|
1765 |
+
|
1766 |
+
}
|
1767 |
+
|
1768 |
+
return ignore_field;
|
1769 |
+
|
1770 |
+
},
|
1771 |
+
isInt: function(n) {
|
1772 |
+
return typeof n == "number" && isFinite(n) && n % 1 === 0;
|
1773 |
+
},
|
1774 |
+
releaseFormSubmit: function(form) {
|
1775 |
+
//console.log('remove form listener event');
|
1776 |
+
document.body.style.cursor = "default";
|
1777 |
+
utils.removeClass('wpl-track-me', form);
|
1778 |
+
utils.removeListener(form, 'submit', this.formListener);
|
1779 |
+
var formClass = form.getAttribute('class');
|
1780 |
+
if (formClass !== "" && formClass !== null) {
|
1781 |
+
/* If contact form 7 do this */
|
1782 |
+
if (formClass.toLowerCase().indexOf("wpcf7-form") != -1) {
|
1783 |
+
//alert('release')
|
1784 |
+
setTimeout(function() {
|
1785 |
+
document.body.style.cursor = "default";
|
1786 |
+
}, 300);
|
1787 |
+
return true;
|
1788 |
+
}
|
1789 |
+
}
|
1790 |
+
|
1791 |
+
form.submit();
|
1792 |
+
/* fallback if submit name="submit" */
|
1793 |
+
setTimeout(function() {
|
1794 |
+
for (var i = 0; i < form.elements.length; i++) {
|
1795 |
+
formInput = form.elements[i];
|
1796 |
+
type = formInput.type || false;
|
1797 |
+
if (type === "submit" && formInput.name === "submit") {
|
1798 |
+
form.elements[i].click();
|
1799 |
+
}
|
1800 |
+
}
|
1801 |
+
}, 2000);
|
1802 |
+
|
1803 |
+
},
|
1804 |
+
saveFormData: function(form) {
|
1805 |
+
var inputsObject = inputsObject || {};
|
1806 |
+
for (var i = 0; i < form.elements.length; i++) {
|
1807 |
+
|
1808 |
+
// console.log(inputsObject);
|
1809 |
+
|
1810 |
+
formInput = form.elements[i];
|
1811 |
+
multiple = false;
|
1812 |
+
|
1813 |
+
if (formInput.name) {
|
1814 |
+
|
1815 |
+
if (formInput.dataset.ignoreFormField) {
|
1816 |
+
_inbound.deBugger('forms', 'ignore ' + formInput.name);
|
1817 |
+
continue;
|
1818 |
+
}
|
1819 |
+
|
1820 |
+
inputName = formInput.name.replace(/\[([^\[]*)\]/g, "%5B%5D$1");
|
1821 |
+
//inputName = inputName.replace(/-/g, "_");
|
1822 |
+
if (!inputsObject[inputName]) {
|
1823 |
+
inputsObject[inputName] = {};
|
1824 |
+
}
|
1825 |
+
if (formInput.type) {
|
1826 |
+
inputsObject[inputName]['type'] = formInput.type;
|
1827 |
+
}
|
1828 |
+
if (!inputsObject[inputName]['name']) {
|
1829 |
+
inputsObject[inputName]['name'] = formInput.name;
|
1830 |
+
}
|
1831 |
+
if (formInput.dataset.mapFormField) {
|
1832 |
+
inputsObject[inputName]['map'] = formInput.dataset.mapFormField;
|
1833 |
+
}
|
1834 |
+
|
1835 |
+
|
1836 |
+
switch (formInput.nodeName) {
|
1837 |
+
|
1838 |
+
case 'INPUT':
|
1839 |
+
value = this.getInputValue(formInput);
|
1840 |
+
|
1841 |
+
|
1842 |
+
if (value === false) {
|
1843 |
+
continue;
|
1844 |
+
}
|
1845 |
+
break;
|
1846 |
+
|
1847 |
+
case 'TEXTAREA':
|
1848 |
+
value = formInput.value;
|
1849 |
+
break;
|
1850 |
+
|
1851 |
+
case 'SELECT':
|
1852 |
+
if (formInput.multiple) {
|
1853 |
+
values = [];
|
1854 |
+
multiple = true;
|
1855 |
+
|
1856 |
+
for (var j = 0; j < formInput.length; j++) {
|
1857 |
+
if (formInput[j].selected) {
|
1858 |
+
values.push(encodeURIComponent(formInput[j].value));
|
1859 |
+
}
|
1860 |
+
}
|
1861 |
+
|
1862 |
+
} else {
|
1863 |
+
value = (formInput.value);
|
1864 |
+
}
|
1865 |
+
|
1866 |
+
break;
|
1867 |
+
}
|
1868 |
+
|
1869 |
+
_inbound.deBugger('forms', 'Input Value = ' + value);
|
1870 |
+
|
1871 |
+
|
1872 |
+
if (value) {
|
1873 |
+
/* inputsObject[inputName].push(multiple ? values.join(',') : encodeURIComponent(value)); */
|
1874 |
+
if (!inputsObject[inputName]['value']) {
|
1875 |
+
inputsObject[inputName]['value'] = [];
|
1876 |
+
}
|
1877 |
+
inputsObject[inputName]['value'].push(multiple ? values.join(',') : encodeURIComponent(value));
|
1878 |
+
var value = multiple ? values.join(',') : encodeURIComponent(value);
|
1879 |
+
|
1880 |
+
}
|
1881 |
+
|
1882 |
+
}
|
1883 |
+
}
|
1884 |
+
_inbound.deBugger('forms', inputsObject);
|
1885 |
+
|
1886 |
+
//console.log('These are the raw values', inputsObject);
|
1887 |
+
//_inbound.totalStorage('the_key', inputsObject);
|
1888 |
+
//var inputsObject = sortInputs(inputsObject);
|
1889 |
+
|
1890 |
+
var matchCommon = /name|first name|last name|email|e-mail|phone|website|job title|company|tele|address|comment/;
|
1891 |
+
|
1892 |
+
for (var input in inputsObject) {
|
1893 |
+
//console.log(input);
|
1894 |
+
|
1895 |
+
var inputValue = inputsObject[input]['value'];
|
1896 |
+
var inputMappedField = inputsObject[input]['map'];
|
1897 |
+
//if (matchCommon.test(input) !== false) {
|
1898 |
+
//console.log(input + " Matches Regex run mapping test");
|
1899 |
+
//var map = inputsObject[input];
|
1900 |
+
//console.log("MAPP", map);
|
1901 |
+
//mappedParams.push( input + '=' + inputsObject[input]['value'].join(',') );
|
1902 |
+
//}
|
1903 |
+
|
1904 |
+
/* Add custom hook here to look for additional values */
|
1905 |
+
if (typeof(inputValue) != "undefined" && inputValue != null && inputValue != "") {
|
1906 |
+
rawParams.push(input + '=' + inputsObject[input]['value'].join(','));
|
1907 |
+
}
|
1908 |
+
|
1909 |
+
if (typeof(inputMappedField) != "undefined" && inputMappedField != null && inputsObject[input]['value']) {
|
1910 |
+
//console.log('Data ATTR', formInput.dataset.mapFormField);
|
1911 |
+
mappedParams.push(inputMappedField + "=" + inputsObject[input]['value'].join(','));
|
1912 |
+
if (input === 'email') {
|
1913 |
+
var email = inputsObject[input]['value'].join(',');
|
1914 |
+
//alert(email);
|
1915 |
+
|
1916 |
+
}
|
1917 |
+
}
|
1918 |
+
}
|
1919 |
+
|
1920 |
+
var raw_params = rawParams.join('&');
|
1921 |
+
_inbound.deBugger('forms', "Stringified Raw Form PARAMS: " + raw_params);
|
1922 |
+
|
1923 |
+
var mapped_params = mappedParams.join('&');
|
1924 |
+
_inbound.deBugger('forms', "Stringified Mapped PARAMS" + mapped_params);
|
1925 |
+
|
1926 |
+
/* Check Use form Email or Cookie */
|
1927 |
+
var email = utils.getParameterVal('email', mapped_params) || utils.readCookie('wp_lead_email');
|
1928 |
+
|
1929 |
+
/* Legacy Email map */
|
1930 |
+
if (!email) {
|
1931 |
+
email = utils.getParameterVal('wpleads_email_address', mapped_params);
|
1932 |
+
}
|
1933 |
+
|
1934 |
+
var fullName = utils.getParameterVal('name', mapped_params);
|
1935 |
+
var fName = utils.getParameterVal('first_name', mapped_params);
|
1936 |
+
var lName = utils.getParameterVal('last_name', mapped_params);
|
1937 |
+
|
1938 |
+
// Fallbacks for empty values
|
1939 |
+
if (!lName && fName) {
|
1940 |
+
var parts = decodeURI(fName).split(" ");
|
1941 |
+
if (parts.length > 0) {
|
1942 |
+
fName = parts[0];
|
1943 |
+
lName = parts[1];
|
1944 |
+
}
|
1945 |
+
}
|
1946 |
+
|
1947 |
+
if (fullName && !lName && !fName) {
|
1948 |
+
var parts = decodeURI(fullName).split(" ");
|
1949 |
+
if (parts.length > 0) {
|
1950 |
+
fName = parts[0];
|
1951 |
+
lName = parts[1];
|
1952 |
+
}
|
1953 |
+
}
|
1954 |
+
|
1955 |
+
fullName = (fName && lName) ? fName + " " + lName : fullName;
|
1956 |
+
|
1957 |
+
if(!fName) { fName = ""; }
|
1958 |
+
if(!lName) { lName = ""; }
|
1959 |
+
|
1960 |
+
_inbound.deBugger('forms', "fName = " + fName);
|
1961 |
+
_inbound.deBugger('forms', "lName = " + lName);
|
1962 |
+
_inbound.deBugger('forms', "fullName = " + fullName);
|
1963 |
+
|
1964 |
+
//return false;
|
1965 |
+
var page_views = _inbound.totalStorage('page_views') || {};
|
1966 |
+
var urlParams = _inbound.totalStorage('inbound_url_params') || {};
|
1967 |
+
|
1968 |
+
/* check if redirect url is empty */
|
1969 |
+
var formRedirectUrl = form.querySelectorAll('input[value][type="hidden"][name="inbound_furl"]:not([value=""])');
|
1970 |
+
var inbound_form_is_ajax = false;
|
1971 |
+
if(formRedirectUrl.length == 0 || formRedirectUrl[0]['value'] == 'IA=='){
|
1972 |
+
var inbound_form_is_ajax = true;
|
1973 |
+
}
|
1974 |
+
|
1975 |
+
/* get form id */
|
1976 |
+
var inbound_form_id = form.querySelectorAll('input[value][type="hidden"][name="inbound_form_id"]');
|
1977 |
+
if(inbound_form_id.length > 0 ){
|
1978 |
+
inbound_form_id = inbound_form_id[0]['value'];
|
1979 |
+
} else {
|
1980 |
+
inbound_form_id = 0;
|
1981 |
+
}
|
1982 |
+
|
1983 |
+
var inboundDATA = {
|
1984 |
+
'email': email
|
1985 |
+
};
|
1986 |
+
|
1987 |
+
/* Get Variation ID */
|
1988 |
+
if (typeof(landing_path_info) != "undefined") {
|
1989 |
+
var variation = landing_path_info.variation;
|
1990 |
+
} else if (typeof(cta_path_info) != "undefined") {
|
1991 |
+
var variation = cta_path_info.variation;
|
1992 |
+
} else {
|
1993 |
+
var variation = inbound_settings.variation_id;
|
1994 |
+
}
|
1995 |
+
var post_type = inbound_settings.post_type || 'page';
|
1996 |
+
var page_id = inbound_settings.post_id || 0;
|
1997 |
+
// data['wp_lead_uid'] = jQuery.cookie("wp_lead_uid") || null;
|
1998 |
+
// data['search_data'] = JSON.stringify(jQuery.totalStorage('inbound_search')) || {};
|
1999 |
+
search_data = {};
|
2000 |
+
/* Filter here for raw */
|
2001 |
+
formData = {
|
2002 |
+
'action': 'inbound_lead_store',
|
2003 |
+
'email': email,
|
2004 |
+
"full_name": fullName,
|
2005 |
+
"first_name": fName,
|
2006 |
+
"last_name": lName,
|
2007 |
+
'raw_params': raw_params,
|
2008 |
+
'mapped_params': mapped_params,
|
2009 |
+
'url_params': JSON.stringify(urlParams),
|
2010 |
+
'search_data': 'test',
|
2011 |
+
'page_views': JSON.stringify(page_views),
|
2012 |
+
'post_type': post_type,
|
2013 |
+
'page_id': page_id,
|
2014 |
+
'variation': variation,
|
2015 |
+
'source': utils.readCookie("inbound_referral_site"),
|
2016 |
+
'inbound_submitted': inbound_form_is_ajax,
|
2017 |
+
'inbound_form_id': inbound_form_id,
|
2018 |
+
'inbound_nonce': inbound_settings.ajax_nonce,
|
2019 |
+
'event': form
|
2020 |
+
};
|
2021 |
+
|
2022 |
+
callback = function(leadID) {
|
2023 |
+
/* Action Example */
|
2024 |
+
|
2025 |
+
_inbound.deBugger('forms', 'Lead Created with ID: ' + leadID);
|
2026 |
+
leadID = parseInt(leadID, 10);
|
2027 |
+
formData.leadID = leadID;
|
2028 |
+
/* Set Lead cookie ID */
|
2029 |
+
if (leadID) {
|
2030 |
+
utils.createCookie("wp_lead_id", leadID);
|
2031 |
+
_inbound.totalStorage.deleteItem('page_views'); // remove pageviews
|
2032 |
+
_inbound.totalStorage.deleteItem('tracking_events'); // remove events
|
2033 |
+
}
|
2034 |
+
|
2035 |
+
_inbound.trigger('form_after_submission', formData);
|
2036 |
+
|
2037 |
+
/* Resume normal form functionality */
|
2038 |
+
_inbound.Forms.releaseFormSubmit(form);
|
2039 |
+
|
2040 |
+
}
|
2041 |
+
|
2042 |
+
_inbound.trigger('form_before_submission', formData);
|
2043 |
+
|
2044 |
+
utils.ajaxPost(inbound_settings.admin_url, formData, callback);
|
2045 |
+
},
|
2046 |
+
saveSearchData: function(form) {
|
2047 |
+
var inputsObject = inputsObject || {};
|
2048 |
+
for (var i = 0; i < form.elements.length; i++) {
|
2049 |
+
|
2050 |
+
//console.log(inputsObject);
|
2051 |
+
|
2052 |
+
formInput = form.elements[i];
|
2053 |
+
multiple = false;
|
2054 |
+
|
2055 |
+
if (formInput.name) {
|
2056 |
+
|
2057 |
+
if (formInput.dataset.ignoreFormField) {
|
2058 |
+
_inbound.deBugger('searches', 'ignore ' + formInput.name);
|
2059 |
+
continue;
|
2060 |
+
}
|
2061 |
+
|
2062 |
+
inputName = formInput.name.replace(/\[([^\[]*)\]/g, "%5B%5D$1");
|
2063 |
+
//inputName = inputName.replace(/-/g, "_");
|
2064 |
+
if (!inputsObject[inputName]) {
|
2065 |
+
inputsObject[inputName] = {};
|
2066 |
+
}
|
2067 |
+
if (formInput.type) {
|
2068 |
+
inputsObject[inputName]['type'] = formInput.type;
|
2069 |
+
|
2070 |
+
}
|
2071 |
+
if (!inputsObject[inputName]['name']) {
|
2072 |
+
inputsObject[inputName]['name'] = formInput.name;
|
2073 |
+
}
|
2074 |
+
if (formInput.dataset.mapFormField) {
|
2075 |
+
inputsObject[inputName]['map'] = formInput.dataset.mapFormField;
|
2076 |
+
}
|
2077 |
+
|
2078 |
+
|
2079 |
+
switch (formInput.nodeName) {
|
2080 |
+
|
2081 |
+
case 'INPUT':
|
2082 |
+
value = this.getInputValue(formInput);
|
2083 |
+
|
2084 |
+
|
2085 |
+
if (value === false) {
|
2086 |
+
continue;
|
2087 |
+
}
|
2088 |
+
break;
|
2089 |
+
|
2090 |
+
case 'TEXTAREA':
|
2091 |
+
value = formInput.value;
|
2092 |
+
break;
|
2093 |
+
|
2094 |
+
case 'SELECT':
|
2095 |
+
if (formInput.multiple) {
|
2096 |
+
values = [];
|
2097 |
+
multiple = true;
|
2098 |
+
|
2099 |
+
for (var j = 0; j < formInput.length; j++) {
|
2100 |
+
if (formInput[j].selected) {
|
2101 |
+
values.push(encodeURIComponent(formInput[j].value));
|
2102 |
+
}
|
2103 |
+
}
|
2104 |
+
|
2105 |
+
} else {
|
2106 |
+
value = (formInput.value);
|
2107 |
+
}
|
2108 |
+
|
2109 |
+
break;
|
2110 |
+
}
|
2111 |
+
|
2112 |
+
_inbound.deBugger('searches', 'Input Value = ' + value);
|
2113 |
+
|
2114 |
+
|
2115 |
+
if (value) {
|
2116 |
+
/* inputsObject[inputName].push(multiple ? values.join(',') : encodeURIComponent(value)); */
|
2117 |
+
if (!inputsObject[inputName]['value']) {
|
2118 |
+
inputsObject[inputName]['value'] = [];
|
2119 |
+
}
|
2120 |
+
inputsObject[inputName]['value'].push(multiple ? values.join(',') : encodeURIComponent(value));
|
2121 |
+
var value = multiple ? values.join(',') : encodeURIComponent(value);
|
2122 |
+
|
2123 |
+
}
|
2124 |
+
|
2125 |
+
}
|
2126 |
+
}
|
2127 |
+
|
2128 |
+
_inbound.deBugger('searches', inputsObject);
|
2129 |
+
|
2130 |
+
/* create an array of search fields //(not fully implemented) at the moment, it only maps the text in the "search" input types*/
|
2131 |
+
var searchQuery = [];
|
2132 |
+
for (var input in inputsObject) {
|
2133 |
+
var inputValue = inputsObject[input]['value'];
|
2134 |
+
var inputType = inputsObject[input]['type'];
|
2135 |
+
|
2136 |
+
/* Add custom hook here to look for additional values */
|
2137 |
+
if (typeof(inputValue) != "undefined" && inputValue != null && inputValue != "") {
|
2138 |
+
// This is for mapping all fields of a search form. The resulting string is processed
|
2139 |
+
// in inbound-pro\classes\admin\report-templates\report.lead-searches-and-comments.php
|
2140 |
+
// In the function print_action_popup()
|
2141 |
+
// searchQuery.push(input + '|value|' + inputsObject[input]['value'].join(','));
|
2142 |
+
|
2143 |
+
// get the search input value
|
2144 |
+
if(inputType == 'search'){
|
2145 |
+
searchQuery.push('search_text' + '|value|' + inputsObject[input]['value']);
|
2146 |
+
}
|
2147 |
+
}
|
2148 |
+
}
|
2149 |
+
/* exit if there isn't a search query */
|
2150 |
+
if(!searchQuery[0]){
|
2151 |
+
return;
|
2152 |
+
}
|
2153 |
+
|
2154 |
+
var searchString = searchQuery.join('|field|');
|
2155 |
+
_inbound.deBugger('searches', "Stringified Search Form PARAMS: " + searchString);
|
2156 |
+
|
2157 |
+
/* Get Variation ID */
|
2158 |
+
if (typeof(landing_path_info) != "undefined") {
|
2159 |
+
var variation = landing_path_info.variation;
|
2160 |
+
} else if (typeof(cta_path_info) != "undefined") {
|
2161 |
+
var variation = cta_path_info.variation;
|
2162 |
+
} else {
|
2163 |
+
var variation = inbound_settings.variation_id;
|
2164 |
+
}
|
2165 |
+
var post_type = inbound_settings.post_type || 'page';
|
2166 |
+
var page_id = inbound_settings.post_id || 0;
|
2167 |
+
|
2168 |
+
var user_UID = utils.readCookie("wp_lead_uid");
|
2169 |
+
|
2170 |
+
/* get the user's email address if possible */
|
2171 |
+
if(inbound_settings.wp_lead_data.lead_email){
|
2172 |
+
email = inbound_settings.wp_lead_data.lead_email;
|
2173 |
+
}else if(utils.readCookie('inbound_wpleads_email_address')){
|
2174 |
+
email = utils.readCookie('inbound_wpleads_email_address');
|
2175 |
+
}else{
|
2176 |
+
email = '';
|
2177 |
+
}
|
2178 |
+
|
2179 |
+
/* Filter here for raw */
|
2180 |
+
searchData = {
|
2181 |
+
'email': email,
|
2182 |
+
'search_data': searchString,
|
2183 |
+
'user_UID': user_UID,
|
2184 |
+
'post_type': post_type,
|
2185 |
+
'page_id': page_id,
|
2186 |
+
'variation': variation,
|
2187 |
+
'source': utils.readCookie("inbound_referral_site"),
|
2188 |
+
'ip_address': inbound_settings.ip_address,
|
2189 |
+
'timestamp': Math.floor((new Date).getTime()/1000),
|
2190 |
+
};
|
2191 |
+
|
2192 |
+
/* filter data before caching it in the user's browser */
|
2193 |
+
_inbound.trigger('search_before_caching', searchData);
|
2194 |
+
|
2195 |
+
/* cache search data */
|
2196 |
+
if(inbound_settings.wp_lead_data.lead_id){
|
2197 |
+
searchData['lead_id'] = inbound_settings.wp_lead_data.lead_id;
|
2198 |
+
utils.cacheSearchData(searchData, form)
|
2199 |
+
}else{
|
2200 |
+
utils.cacheSearchData(searchData, form);
|
2201 |
+
}
|
2202 |
+
|
2203 |
+
|
2204 |
+
},
|
2205 |
+
rememberInputValues: function(input) {
|
2206 |
+
var name = (input.name) ? "inbound_" + input.name : '';
|
2207 |
+
var type = (input.type) ? input.type : 'text';
|
2208 |
+
if (type === 'submit' || type === 'hidden' || type === 'file' || type === "password" || input.dataset.ignoreFormField) {
|
2209 |
+
return false;
|
2210 |
+
}
|
2211 |
+
|
2212 |
+
utils.addListener(input, 'change', function(e) {
|
2213 |
+
if (e.target.name) {
|
2214 |
+
/* Check for input type */
|
2215 |
+
if (type !== "checkbox") {
|
2216 |
+
var value = e.target.value;
|
2217 |
+
} else {
|
2218 |
+
var values = [];
|
2219 |
+
var checkboxes = document.querySelectorAll('input[name="' + e.target.name + '"]');
|
2220 |
+
for (var i = 0; i < checkboxes.length; i++) {
|
2221 |
+
var checked = checkboxes[i].checked;
|
2222 |
+
if (checked) {
|
2223 |
+
values.push(checkboxes[i].value);
|
2224 |
+
}
|
2225 |
+
value = values.join(',');
|
2226 |
+
};
|
2227 |
+
}
|
2228 |
+
//console.log(e.target.nodeName);
|
2229 |
+
//console.log('change ' + e.target.name + " " + encodeURIComponent(value));
|
2230 |
+
|
2231 |
+
inputData = {
|
2232 |
+
name: e.target.name,
|
2233 |
+
node: e.target.nodeName.toLowerCase(),
|
2234 |
+
type: type,
|
2235 |
+
value: value,
|
2236 |
+
mapping: e.target.dataset.mapFormField
|
2237 |
+
};
|
2238 |
+
|
2239 |
+
_inbound.trigger('form_input_change', inputData);
|
2240 |
+
/* Set Field Input Cookies */
|
2241 |
+
utils.createCookie("inbound_" + e.target.name, encodeURIComponent(value));
|
2242 |
+
// _inbound.totalStorage('the_key', FormStore);
|
2243 |
+
/* Push to 'unsubmitted form object' */
|
2244 |
+
}
|
2245 |
+
|
2246 |
+
});
|
2247 |
+
},
|
2248 |
+
fillInputValues: function(input) {
|
2249 |
+
var name = (input.name) ? "inbound_" + input.name : '';
|
2250 |
+
var type = (input.type) ? input.type : 'text';
|
2251 |
+
if (type === 'submit' || type === 'hidden' || type === 'file' || type === "password") {
|
2252 |
+
return false;
|
2253 |
+
}
|
2254 |
+
if (utils.readCookie(name) && name != 'comment') {
|
2255 |
+
|
2256 |
+
value = decodeURIComponent(utils.readCookie(name));
|
2257 |
+
if (type === 'checkbox' || type === 'radio') {
|
2258 |
+
var checkbox_vals = value.split(',');
|
2259 |
+
for (var i = 0; i < checkbox_vals.length; i++) {
|
2260 |
+
if (input.value.indexOf(checkbox_vals[i]) > -1) {
|
2261 |
+
input.checked = true;
|
2262 |
+
}
|
2263 |
+
}
|
2264 |
+
} else {
|
2265 |
+
if (value !== "undefined") {
|
2266 |
+
input.value = value;
|
2267 |
+
}
|
2268 |
+
}
|
2269 |
+
}
|
2270 |
+
},
|
2271 |
+
getInputLabel: function(input){
|
2272 |
+
var label;
|
2273 |
+
if(label = this.siblingsIsLabel(input)){
|
2274 |
+
return label;
|
2275 |
+
} else if (label = this.CheckParentForLabel(input)) {
|
2276 |
+
return label;
|
2277 |
+
} else {
|
2278 |
+
//console.log("no label nf", input);
|
2279 |
+
return false;
|
2280 |
+
}
|
2281 |
+
},
|
2282 |
+
/* Get correct input values */
|
2283 |
+
getInputValue: function(input) {
|
2284 |
+
var value = false;
|
2285 |
+
|
2286 |
+
switch (input.type) {
|
2287 |
+
case 'radio':
|
2288 |
+
case 'checkbox':
|
2289 |
+
if (input.checked) {
|
2290 |
+
value = input.value;
|
2291 |
+
//console.log("CHECKBOX VAL", value)
|
2292 |
+
}
|
2293 |
+
break;
|
2294 |
+
|
2295 |
+
case 'text':
|
2296 |
+
case 'hidden':
|
2297 |
+
default:
|
2298 |
+
value = input.value;
|
2299 |
+
break;
|
2300 |
+
|
2301 |
+
}
|
2302 |
+
|
2303 |
+
return value;
|
2304 |
+
},
|
2305 |
+
/* Add data-map-form-field attr to input */
|
2306 |
+
addDataAttr: function(formInput, match) {
|
2307 |
+
|
2308 |
+
var getAllInputs = document.getElementsByName(formInput.name);
|
2309 |
+
for (var i = getAllInputs.length - 1; i >= 0; i--) {
|
2310 |
+
if (!formInput.dataset.mapFormField) {
|
2311 |
+
getAllInputs[i].dataset.mapFormField = match;
|
2312 |
+
}
|
2313 |
+
};
|
2314 |
+
},
|
2315 |
+
/* Optimize FieldMapArray array for fewer lookups */
|
2316 |
+
removeArrayItem: function(array, item) {
|
2317 |
+
if (array.indexOf) {
|
2318 |
+
index = array.indexOf(item);
|
2319 |
+
} else {
|
2320 |
+
for (index = array.length - 1; index >= 0; --index) {
|
2321 |
+
if (array[index] === item) {
|
2322 |
+
break;
|
2323 |
+
}
|
2324 |
+
}
|
2325 |
+
}
|
2326 |
+
if (index >= 0) {
|
2327 |
+
array.splice(index, 1);
|
2328 |
+
}
|
2329 |
+
//_inbound.deBugger('forms', 'removed ' + item + " from array");
|
2330 |
+
//console.log('removed ' + item + " from array");
|
2331 |
+
return;
|
2332 |
+
},
|
2333 |
+
/* Look for siblings that are form labels */
|
2334 |
+
siblingsIsLabel: function(input) {
|
2335 |
+
var siblings = this.getSiblings(input);
|
2336 |
+
var labels = [];
|
2337 |
+
for (var i = siblings.length - 1; i >= 0; i--) {
|
2338 |
+
if (siblings[i].nodeName.toLowerCase() === 'label') {
|
2339 |
+
labels.push(siblings[i]);
|
2340 |
+
}
|
2341 |
+
};
|
2342 |
+
/* if only 1 label */
|
2343 |
+
if (labels.length > 0 && labels.length < 2) {
|
2344 |
+
return labels;
|
2345 |
+
}
|
2346 |
+
|
2347 |
+
return false;
|
2348 |
+
},
|
2349 |
+
getChildren: function(n, skipMe) {
|
2350 |
+
var r = [];
|
2351 |
+
var elem = null;
|
2352 |
+
for (; n; n = n.nextSibling)
|
2353 |
+
if (n.nodeType == 1 && n != skipMe)
|
2354 |
+
r.push(n);
|
2355 |
+
return r;
|
2356 |
+
},
|
2357 |
+
getSiblings: function(n) {
|
2358 |
+
return this.getChildren(n.parentNode.firstChild, n);
|
2359 |
+
},
|
2360 |
+
/* Check parent elements inside form for labels */
|
2361 |
+
CheckParentForLabel: function(element) {
|
2362 |
+
if (element.nodeName === 'FORM') {
|
2363 |
+
return null;
|
2364 |
+
}
|
2365 |
+
do {
|
2366 |
+
var labels = element.getElementsByTagName("label");
|
2367 |
+
if (labels.length > 0 && labels.length < 2) {
|
2368 |
+
return element.getElementsByTagName("label");
|
2369 |
+
}
|
2370 |
+
|
2371 |
+
} while (element = element.parentNode);
|
2372 |
+
|
2373 |
+
return null;
|
2374 |
+
},
|
2375 |
+
/* Validate Common Email addresses */
|
2376 |
+
mailCheck: function() {
|
2377 |
+
var email_input = document.querySelector('.inbound-email');
|
2378 |
+
if (email_input) {
|
2379 |
+
//
|
2380 |
+
utils.addListener(email_input, 'blur', this.mailCheck);
|
2381 |
+
|
2382 |
+
Mailcheck.run({
|
2383 |
+
email: document.querySelector('.inbound-email').value,
|
2384 |
+
suggested: function(suggestion) {
|
2385 |
+
// callback code
|
2386 |
+
|
2387 |
+
var suggest = document.querySelector('.email_suggestion');
|
2388 |
+
if (suggest) {
|
2389 |
+
utils.removeElement(suggest);
|
2390 |
+
}
|
2391 |
+
var el = document.createElement("span");
|
2392 |
+
el.innerHTML = "<span class=\"email_suggestion\">Did youu mean <b><i id='email_correction' style='cursor: pointer;' title=\"click to update\">" + suggestion.full + "</b></i>?</span>";
|
2393 |
+
email_input.parentNode.insertBefore(el, email_input.nextSibling);
|
2394 |
+
var update = document.getElementById('email_correction');
|
2395 |
+
utils.addListener(update, 'click', function() {
|
2396 |
+
email_input.value = update.innerHTML;
|
2397 |
+
update.parentNode.parentNode.innerHTML = "Fixed!";
|
2398 |
+
});
|
2399 |
+
},
|
2400 |
+
empty: function() {
|
2401 |
+
//$(".email_suggestion").html("No Suggestions :(");
|
2402 |
+
}
|
2403 |
+
});
|
2404 |
+
}
|
2405 |
+
}
|
2406 |
+
|
2407 |
+
};
|
2408 |
+
/* Mailcheck */
|
2409 |
+
if (typeof Mailcheck === "undefined") {
|
2410 |
+
var Mailcheck = {
|
2411 |
+
domainThreshold: 1,
|
2412 |
+
topLevelThreshold: 3,
|
2413 |
+
|
2414 |
+
defaultDomains: ["yahoo.com", "google.com", "hotmail.com", "gmail.com", "me.com", "aol.com", "mac.com",
|
2415 |
+
"live.com", "comcast.net", "googlemail.com", "msn.com", "hotmail.co.uk", "yahoo.co.uk",
|
2416 |
+
"facebook.com", "verizon.net", "sbcglobal.net", "att.net", "gmx.com", "mail.com", "outlook.com", "icloud.com"
|
2417 |
+
],
|
2418 |
+
|
2419 |
+
defaultTopLevelDomains: ["co.jp", "co.uk", "com", "net", "org", "info", "edu", "gov", "mil", "ca", "de"],
|
2420 |
+
|
2421 |
+
run: function(opts) {
|
2422 |
+
opts.domains = opts.domains || Mailcheck.defaultDomains;
|
2423 |
+
opts.topLevelDomains = opts.topLevelDomains || Mailcheck.defaultTopLevelDomains;
|
2424 |
+
opts.distanceFunction = opts.distanceFunction || Mailcheck.sift3Distance;
|
2425 |
+
|
2426 |
+
var defaultCallback = function(result) {
|
2427 |
+
return result;
|
2428 |
+
};
|
2429 |
+
var suggestedCallback = opts.suggested || defaultCallback;
|
2430 |
+
var emptyCallback = opts.empty || defaultCallback;
|
2431 |
+
|
2432 |
+
var result = Mailcheck.suggest(Mailcheck.encodeEmail(opts.email), opts.domains, opts.topLevelDomains, opts.distanceFunction);
|
2433 |
+
|
2434 |
+
return result ? suggestedCallback(result) : emptyCallback();
|
2435 |
+
},
|
2436 |
+
|
2437 |
+
suggest: function(email, domains, topLevelDomains, distanceFunction) {
|
2438 |
+
email = email.toLowerCase();
|
2439 |
+
|
2440 |
+
var emailParts = this.splitEmail(email);
|
2441 |
+
|
2442 |
+
var closestDomain = this.findClosestDomain(emailParts.domain, domains, distanceFunction, this.domainThreshold);
|
2443 |
+
|
2444 |
+
if (closestDomain) {
|
2445 |
+
if (closestDomain != emailParts.domain) {
|
2446 |
+
// The email address closely matches one of the supplied domains; return a suggestion
|
2447 |
+
return {
|
2448 |
+
address: emailParts.address,
|
2449 |
+
domain: closestDomain,
|
2450 |
+
full: emailParts.address + "@" + closestDomain
|
2451 |
+
};
|
2452 |
+
}
|
2453 |
+
} else {
|
2454 |
+
// The email address does not closely match one of the supplied domains
|
2455 |
+
var closestTopLevelDomain = this.findClosestDomain(emailParts.topLevelDomain, topLevelDomains, distanceFunction, this.topLevelThreshold);
|
2456 |
+
if (emailParts.domain && closestTopLevelDomain && closestTopLevelDomain != emailParts.topLevelDomain) {
|
2457 |
+
// The email address may have a mispelled top-level domain; return a suggestion
|
2458 |
+
var domain = emailParts.domain;
|
2459 |
+
closestDomain = domain.substring(0, domain.lastIndexOf(emailParts.topLevelDomain)) + closestTopLevelDomain;
|
2460 |
+
return {
|
2461 |
+
address: emailParts.address,
|
2462 |
+
domain: closestDomain,
|
2463 |
+
full: emailParts.address + "@" + closestDomain
|
2464 |
+
};
|
2465 |
+
}
|
2466 |
+
}
|
2467 |
+
/* The email address exactly matches one of the supplied domains, does not closely
|
2468 |
+
* match any domain and does not appear to simply have a mispelled top-level domain,
|
2469 |
+
* or is an invalid email address; do not return a suggestion.
|
2470 |
+
*/
|
2471 |
+
return false;
|
2472 |
+
},
|
2473 |
+
|
2474 |
+
findClosestDomain: function(domain, domains, distanceFunction, threshold) {
|
2475 |
+
threshold = threshold || this.topLevelThreshold;
|
2476 |
+
var dist;
|
2477 |
+
var minDist = 99;
|
2478 |
+
var closestDomain = null;
|
2479 |
+
|
2480 |
+
if (!domain || !domains) {
|
2481 |
+
return false;
|
2482 |
+
}
|
2483 |
+
if (!distanceFunction) {
|
2484 |
+
distanceFunction = this.sift3Distance;
|
2485 |
+
}
|
2486 |
+
|
2487 |
+
for (var i = 0; i < domains.length; i++) {
|
2488 |
+
if (domain === domains[i]) {
|
2489 |
+
return domain;
|
2490 |
+
}
|
2491 |
+
dist = distanceFunction(domain, domains[i]);
|
2492 |
+
if (dist < minDist) {
|
2493 |
+
minDist = dist;
|
2494 |
+
closestDomain = domains[i];
|
2495 |
+
}
|
2496 |
+
}
|
2497 |
+
|
2498 |
+
if (minDist <= threshold && closestDomain !== null) {
|
2499 |
+
return closestDomain;
|
2500 |
+
} else {
|
2501 |
+
return false;
|
2502 |
+
}
|
2503 |
+
},
|
2504 |
+
|
2505 |
+
sift3Distance: function(s1, s2) {
|
2506 |
+
// sift3: http://siderite.blogspot.com/2007/04/super-fast-and-accurate-string-distance.html
|
2507 |
+
if (s1 === null || s1.length === 0) {
|
2508 |
+
if (s2 === null || s2.length === 0) {
|
2509 |
+
return 0;
|
2510 |
+
} else {
|
2511 |
+
return s2.length;
|
2512 |
+
}
|
2513 |
+
}
|
2514 |
+
|
2515 |
+
if (s2 === null || s2.length === 0) {
|
2516 |
+
return s1.length;
|
2517 |
+
}
|
2518 |
+
|
2519 |
+
var c = 0;
|
2520 |
+
var offset1 = 0;
|
2521 |
+
var offset2 = 0;
|
2522 |
+
var lcs = 0;
|
2523 |
+
var maxOffset = 5;
|
2524 |
+
|
2525 |
+
while ((c + offset1 < s1.length) && (c + offset2 < s2.length)) {
|
2526 |
+
if (s1.charAt(c + offset1) == s2.charAt(c + offset2)) {
|
2527 |
+
lcs++;
|
2528 |
+
} else {
|
2529 |
+
offset1 = 0;
|
2530 |
+
offset2 = 0;
|
2531 |
+
for (var i = 0; i < maxOffset; i++) {
|
2532 |
+
if ((c + i < s1.length) && (s1.charAt(c + i) == s2.charAt(c))) {
|
2533 |
+
offset1 = i;
|
2534 |
+
break;
|
2535 |
+
}
|
2536 |
+
if ((c + i < s2.length) && (s1.charAt(c) == s2.charAt(c + i))) {
|
2537 |
+
offset2 = i;
|
2538 |
+
break;
|
2539 |
+
}
|
2540 |
+
}
|
2541 |
+
}
|
2542 |
+
c++;
|
2543 |
+
}
|
2544 |
+
return (s1.length + s2.length) / 2 - lcs;
|
2545 |
+
},
|
2546 |
+
|
2547 |
+
splitEmail: function(email) {
|
2548 |
+
var parts = email.trim().split("@");
|
2549 |
+
|
2550 |
+
if (parts.length < 2) {
|
2551 |
+
return false;
|
2552 |
+
}
|
2553 |
+
|
2554 |
+
for (var i = 0; i < parts.length; i++) {
|
2555 |
+
if (parts[i] === "") {
|
2556 |
+
return false;
|
2557 |
+
}
|
2558 |
+
}
|
2559 |
+
|
2560 |
+
var domain = parts.pop();
|
2561 |
+
var domainParts = domain.split(".");
|
2562 |
+
var tld = "";
|
2563 |
+
|
2564 |
+
if (domainParts.length === 0) {
|
2565 |
+
// The address does not have a top-level domain
|
2566 |
+
return false;
|
2567 |
+
} else if (domainParts.length == 1) {
|
2568 |
+
// The address has only a top-level domain (valid under RFC)
|
2569 |
+
tld = domainParts[0];
|
2570 |
+
} else {
|
2571 |
+
// The address has a domain and a top-level domain
|
2572 |
+
for (var i = 1; i < domainParts.length; i++) {
|
2573 |
+
tld += domainParts[i] + ".";
|
2574 |
+
}
|
2575 |
+
if (domainParts.length >= 2) {
|
2576 |
+
tld = tld.substring(0, tld.length - 1);
|
2577 |
+
}
|
2578 |
+
}
|
2579 |
+
|
2580 |
+
return {
|
2581 |
+
topLevelDomain: tld,
|
2582 |
+
domain: domain,
|
2583 |
+
address: parts.join("@")
|
2584 |
+
};
|
2585 |
+
},
|
2586 |
+
|
2587 |
+
// Encode the email address to prevent XSS but leave in valid
|
2588 |
+
// characters, following this official spec:
|
2589 |
+
// http://en.wikipedia.org/wiki/Email_address#Syntax
|
2590 |
+
encodeEmail: function(email) {
|
2591 |
+
var result = encodeURI(email);
|
2592 |
+
result = result.replace("%20", " ").replace("%25", "%").replace("%5E", "^")
|
2593 |
+
.replace("%60", "`").replace("%7B", "{").replace("%7C", "|")
|
2594 |
+
.replace("%7D", "}");
|
2595 |
+
return result;
|
2596 |
+
}
|
2597 |
+
};
|
2598 |
+
} // End Mailcheck
|
2599 |
+
|
2600 |
+
|
2601 |
+
return _inbound;
|
2602 |
+
|
2603 |
+
})(_inbound || {});
|
2604 |
+
|
2605 |
+
/**
|
2606 |
+
* # Analytics Events
|
2607 |
+
*
|
2608 |
+
* Events are triggered throughout the visitors journey through the site. See more on [Inbound Now][in]
|
2609 |
+
*
|
2610 |
+
* @contributor David Wells <david@inboundnow.com>
|
2611 |
+
* @contributor Hudson Atwell <hudson@inboundnow.com>
|
2612 |
+
* @version 0.0.2
|
2613 |
+
*
|
2614 |
+
* [in]: http://www.inboundnow.com/
|
2615 |
+
*/
|
2616 |
+
|
2617 |
+
// Add object to _inbound
|
2618 |
+
var _inboundEvents = (function(_inbound) {
|
2619 |
+
|
2620 |
+
|
2621 |
+
_inbound.trigger = function(trigger, data) {
|
2622 |
+
_inbound.Events[trigger](data);
|
2623 |
+
|
2624 |
+
};
|
2625 |
+
|
2626 |
+
/*!
|
2627 |
+
*
|
2628 |
+
* Private Function that Fires & Emits Events
|
2629 |
+
*
|
2630 |
+
* There are three options for firing events and they trigger in this order:
|
2631 |
+
*
|
2632 |
+
* 1. Vanilla JS dispatch event
|
2633 |
+
* 2. `_inbound.add_action('namespace', callback, priority)`
|
2634 |
+
* 3. jQuery Trigger `jQuery.trigger('namespace', callback);`
|
2635 |
+
*
|
2636 |
+
* The Event `data` can be filtered before events are triggered
|
2637 |
+
* with filters. Example: filter_ + "namespace"
|
2638 |
+
*
|
2639 |
+
* ```js
|
2640 |
+
* // Filter Form Data before submissionsz
|
2641 |
+
* _inbound.add_filter( 'filter_form_before_submission', event_filter_data_example, 10);
|
2642 |
+
*
|
2643 |
+
* function event_filter_data_example(data) {
|
2644 |
+
* var data = data || {};
|
2645 |
+
* // Do something with data
|
2646 |
+
* return data;
|
2647 |
+
* }
|
2648 |
+
* ```
|
2649 |
+
*
|
2650 |
+
* @param {string} eventName Name of the event
|
2651 |
+
* @param {object} data Data passed to external functions/triggers
|
2652 |
+
* @param {object} options Options for configuring events
|
2653 |
+
* @return {null} Nothing returned
|
2654 |
+
*/
|
2655 |
+
function fireEvent(eventName, data, options) {
|
2656 |
+
var data = data || {};
|
2657 |
+
options = options || {};
|
2658 |
+
|
2659 |
+
/*! defaults for JS dispatch event */
|
2660 |
+
options.bubbles = options.bubbles || true,
|
2661 |
+
options.cancelable = options.cancelable || true;
|
2662 |
+
|
2663 |
+
/*! Customize Data via filter_ + "namespace" */
|
2664 |
+
data = _inbound.apply_filters('filter_' + eventName, data);
|
2665 |
+
|
2666 |
+
var is_IE_11 = !(window.ActiveXObject) && "ActiveXObject" in window;
|
2667 |
+
|
2668 |
+
if( typeof CustomEvent === 'function') {
|
2669 |
+
|
2670 |
+
var TriggerEvent = new CustomEvent(eventName, {
|
2671 |
+
detail: data,
|
2672 |
+
bubbles: options.bubbles,
|
2673 |
+
cancelable: options.cancelable
|
2674 |
+
});
|
2675 |
+
|
2676 |
+
} else {
|
2677 |
+
var TriggerEvent = document.createEvent("Event");
|
2678 |
+
TriggerEvent.initEvent(eventName, true, true);
|
2679 |
+
}
|
2680 |
+
|
2681 |
+
/*! 1. Trigger Pure Javascript Event See: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events for example on creating events */
|
2682 |
+
window.dispatchEvent(TriggerEvent);
|
2683 |
+
/*! 2. Trigger _inbound action */
|
2684 |
+
_inbound.do_action(eventName, data);
|
2685 |
+
/*! 3. jQuery trigger */
|
2686 |
+
triggerJQueryEvent(eventName, data);
|
2687 |
+
|
2688 |
+
// console.log('Action:' + eventName + " ran on ->", data);
|
2689 |
+
|
2690 |
+
}
|
2691 |
+
|
2692 |
+
function triggerJQueryEvent(eventName, data) {
|
2693 |
+
if (window.jQuery) {
|
2694 |
+
var data = data || {};
|
2695 |
+
/*! try catch here */
|
2696 |
+
jQuery(document).trigger(eventName, data);
|
2697 |
+
}
|
2698 |
+
};
|
2699 |
+
|
2700 |
+
var universalGA,
|
2701 |
+
classicGA,
|
2702 |
+
googleTagManager;
|
2703 |
+
|
2704 |
+
_inbound.Events = {
|
2705 |
+
|
2706 |
+
/**
|
2707 |
+
* # Event Usage
|
2708 |
+
*
|
2709 |
+
* Events are triggered throughout the visitors path through the site.
|
2710 |
+
* You can hook into these custom actions and filters much like WordPress Core
|
2711 |
+
*
|
2712 |
+
* See below for examples
|
2713 |
+
*/
|
2714 |
+
|
2715 |
+
/**
|
2716 |
+
* Adding Custom Actions
|
2717 |
+
* ------------------
|
2718 |
+
* You can hook into custom events throughout analytics. See the full list of available [events below](#all-events)
|
2719 |
+
*
|
2720 |
+
* `
|
2721 |
+
* _inbound.add_action( 'action_name', callback, priority );
|
2722 |
+
* `
|
2723 |
+
*
|
2724 |
+
* ```js
|
2725 |
+
* // example:
|
2726 |
+
*
|
2727 |
+
* // Add custom function to `page_visit` event
|
2728 |
+
* _inbound.add_action( 'page_visit', callback, 10 );
|
2729 |
+
*
|
2730 |
+
* // add custom callback to trigger when `page_visit` fires
|
2731 |
+
* function callback(pageData){
|
2732 |
+
* var pageData = pageData || {};
|
2733 |
+
* // run callback on 'page_visit' trigger
|
2734 |
+
* alert(pageData.title);
|
2735 |
+
* }
|
2736 |
+
* ```
|
2737 |
+
*
|
2738 |
+
* @param {string} action_name Name of the event trigger
|
2739 |
+
* @param {function} callback function to trigger when event happens
|
2740 |
+
* @param {int} priority Order to trigger the event in
|
2741 |
+
*
|
2742 |
+
*/
|
2743 |
+
|
2744 |
+
/**
|
2745 |
+
* Removing Custom Actions
|
2746 |
+
* ------------------
|
2747 |
+
* You can hook into custom events throughout analytics. See the full list of available [events below](#all-events)
|
2748 |
+
*
|
2749 |
+
* `
|
2750 |
+
* _inbound.remove_action( 'action_name');
|
2751 |
+
* `
|
2752 |
+
*
|
2753 |
+
* ```js
|
2754 |
+
* // example:
|
2755 |
+
*
|
2756 |
+
* _inbound.remove_action( 'page_visit');
|
2757 |
+
* // all 'page_visit' actions have been deregistered
|
2758 |
+
* ```
|
2759 |
+
*
|
2760 |
+
* @param {string} action_name Name of the event trigger
|
2761 |
+
*
|
2762 |
+
*/
|
2763 |
+
|
2764 |
+
/**
|
2765 |
+
* # Event List
|
2766 |
+
*
|
2767 |
+
* Events are triggered throughout the visitors journey through the site
|
2768 |
+
*/
|
2769 |
+
|
2770 |
+
/**
|
2771 |
+
* Triggers when analyics has finished loading
|
2772 |
+
*/
|
2773 |
+
analytics_ready: function() {
|
2774 |
+
var ops = {
|
2775 |
+
'opt1': true
|
2776 |
+
};
|
2777 |
+
var data = {
|
2778 |
+
'data': 'xyxy'
|
2779 |
+
};
|
2780 |
+
fireEvent('analytics_ready', data, ops);
|
2781 |
+
},
|
2782 |
+
/**
|
2783 |
+
* Triggers when the browser url params are parsed. You can perform custom actions
|
2784 |
+
* if specific url params exist.
|
2785 |
+
*
|
2786 |
+
* ```js
|
2787 |
+
* // Usage:
|
2788 |
+
*
|
2789 |
+
* // Add function to 'url_parameters' event
|
2790 |
+
* _inbound.add_action( 'url_parameters', url_parameters_func_example, 10);
|
2791 |
+
*
|
2792 |
+
* function url_parameters_func_example(urlParams) {
|
2793 |
+
* var urlParams = urlParams || {};
|
2794 |
+
* for( var param in urlParams ) {
|
2795 |
+
* var key = param;
|
2796 |
+
* var value = urlParams[param];
|
2797 |
+
* }
|
2798 |
+
* // All URL Params
|
2799 |
+
* alert(JSON.stringify(urlParams));
|
2800 |
+
*
|
2801 |
+
* // Check if URL parameter `utm_source` exists and matches value
|
2802 |
+
* if(urlParams.utm_source === "twitter") {
|
2803 |
+
* alert('This person is from twitter!');
|
2804 |
+
* }
|
2805 |
+
* }
|
2806 |
+
* ```
|
2807 |
+
*/
|
2808 |
+
url_parameters: function(data) {
|
2809 |
+
fireEvent('url_parameters', data);
|
2810 |
+
},
|
2811 |
+
/**
|
2812 |
+
* Triggers when session starts
|
2813 |
+
*
|
2814 |
+
* ```js
|
2815 |
+
* // Usage:
|
2816 |
+
*
|
2817 |
+
* // Add function to 'session_start' event
|
2818 |
+
* _inbound.add_action( 'session_start', session_start_func_example, 10);
|
2819 |
+
*
|
2820 |
+
* function session_start_func_example(data) {
|
2821 |
+
* var data = data || {};
|
2822 |
+
* // session start. Do something for new visitor
|
2823 |
+
* }
|
2824 |
+
* ```
|
2825 |
+
*/
|
2826 |
+
session_start: function() {
|
2827 |
+
console.log('');
|
2828 |
+
fireEvent('session_start');
|
2829 |
+
},
|
2830 |
+
/**
|
2831 |
+
* Triggers when visitor session goes idle for more than 30 minutes.
|
2832 |
+
*
|
2833 |
+
* ```js
|
2834 |
+
* // Usage:
|
2835 |
+
*
|
2836 |
+
* // Add function to 'session_end' event
|
2837 |
+
* _inbound.add_action( 'session_end', session_end_func_example, 10);
|
2838 |
+
*
|
2839 |
+
* function session_end_func_example(data) {
|
2840 |
+
* var data = data || {};
|
2841 |
+
* // Do something when session ends
|
2842 |
+
* alert("Hey! It's been 30 minutes... where did you go?");
|
2843 |
+
* }
|
2844 |
+
* ```
|
2845 |
+
*/
|
2846 |
+
session_end: function(clockTime) {
|
2847 |
+
fireEvent('session_end', clockTime);
|
2848 |
+
console.log('Session End');
|
2849 |
+
},
|
2850 |
+
/**
|
2851 |
+
* Triggers if active session is detected
|
2852 |
+
*
|
2853 |
+
* ```js
|
2854 |
+
* // Usage:
|
2855 |
+
*
|
2856 |
+
* // Add function to 'session_active' event
|
2857 |
+
* _inbound.add_action( 'session_active', session_active_func_example, 10);
|
2858 |
+
*
|
2859 |
+
* function session_active_func_example(data) {
|
2860 |
+
* var data = data || {};
|
2861 |
+
* // session active
|
2862 |
+
* }
|
2863 |
+
* ```
|
2864 |
+
*/
|
2865 |
+
session_active: function() {
|
2866 |
+
fireEvent('session_active');
|
2867 |
+
},
|
2868 |
+
/**
|
2869 |
+
* Triggers when visitor session goes idle. Idling occurs after 60 seconds of
|
2870 |
+
* inactivity or when the visitor switches browser tabs
|
2871 |
+
*
|
2872 |
+
* ```js
|
2873 |
+
* // Usage:
|
2874 |
+
*
|
2875 |
+
* // Add function to 'session_idle' event
|
2876 |
+
* _inbound.add_action( 'session_idle', session_idle_func_example, 10);
|
2877 |
+
*
|
2878 |
+
* function session_idle_func_example(data) {
|
2879 |
+
* var data = data || {};
|
2880 |
+
* // Do something when session idles
|
2881 |
+
* alert('Here is a special offer for you!');
|
2882 |
+
* }
|
2883 |
+
* ```
|
2884 |
+
*/
|
2885 |
+
session_idle: function(clockTime) {
|
2886 |
+
fireEvent('session_idle', clockTime);
|
2887 |
+
},
|
2888 |
+
/**
|
2889 |
+
* Triggers when session is already active and gets resumed
|
2890 |
+
*
|
2891 |
+
* ```js
|
2892 |
+
* // Usage:
|
2893 |
+
*
|
2894 |
+
* // Add function to 'session_resume' event
|
2895 |
+
* _inbound.add_action( 'session_resume', session_resume_func_example, 10);
|
2896 |
+
*
|
2897 |
+
* function session_resume_func_example(data) {
|
2898 |
+
* var data = data || {};
|
2899 |
+
* // Session exists and is being resumed
|
2900 |
+
* }
|
2901 |
+
* ```
|
2902 |
+
*/
|
2903 |
+
session_resume: function() {
|
2904 |
+
fireEvent('session_resume');
|
2905 |
+
},
|
2906 |
+
/**
|
2907 |
+
* Session emitter. Runs every 10 seconds. This is a useful function for
|
2908 |
+
* pinging third party services
|
2909 |
+
*
|
2910 |
+
* ```js
|
2911 |
+
* // Usage:
|
2912 |
+
*
|
2913 |
+
* // Add session_heartbeat_func_example function to 'session_heartbeat' event
|
2914 |
+
* _inbound.add_action( 'session_heartbeat', session_heartbeat_func_example, 10);
|
2915 |
+
*
|
2916 |
+
* function session_heartbeat_func_example(data) {
|
2917 |
+
* var data = data || {};
|
2918 |
+
* // Do something with every 10 seconds
|
2919 |
+
* }
|
2920 |
+
* ```
|
2921 |
+
*/
|
2922 |
+
session_heartbeat: function(clockTime) {
|
2923 |
+
var data = {
|
2924 |
+
'clock': clockTime,
|
2925 |
+
'leadData': InboundLeadData
|
2926 |
+
};
|
2927 |
+
fireEvent('session_heartbeat', data);
|
2928 |
+
},
|
2929 |
+
/**
|
2930 |
+
* Triggers Every Page View
|
2931 |
+
*
|
2932 |
+
* ```js
|
2933 |
+
* // Usage:
|
2934 |
+
*
|
2935 |
+
* // Add function to 'page_visit' event
|
2936 |
+
* _inbound.add_action( 'page_visit', page_visit_func_example, 10);
|
2937 |
+
*
|
2938 |
+
* function session_idle_func_example(pageData) {
|
2939 |
+
* var pageData = pageData || {};
|
2940 |
+
* if( pageData.view_count > 8 ){
|
2941 |
+
* alert('Wow you have been to this page more than 8 times.');
|
2942 |
+
* }
|
2943 |
+
* }
|
2944 |
+
* ```
|
2945 |
+
*/
|
2946 |
+
page_visit: function(pageData) {
|
2947 |
+
fireEvent('page_view', pageData);
|
2948 |
+
},
|
2949 |
+
/**
|
2950 |
+
* Triggers If the visitor has never seen the page before
|
2951 |
+
*
|
2952 |
+
* ```js
|
2953 |
+
* // Usage:
|
2954 |
+
*
|
2955 |
+
* // Add function to 'page_first_visit' event
|
2956 |
+
* _inbound.add_action( 'page_first_visit', page_first_visit_func_example, 10);
|
2957 |
+
*
|
2958 |
+
* function page_first_visit_func_example(pageData) {
|
2959 |
+
* var pageData = pageData || {};
|
2960 |
+
* alert('Welcome to this page! Its the first time you have seen it')
|
2961 |
+
* }
|
2962 |
+
* ```
|
2963 |
+
*/
|
2964 |
+
page_first_visit: function(pageData) {
|
2965 |
+
fireEvent('page_first_visit');
|
2966 |
+
_inbound.deBugger('pages', 'First Ever Page View of this Page');
|
2967 |
+
},
|
2968 |
+
/**
|
2969 |
+
* Triggers If the visitor has seen the page before
|
2970 |
+
*
|
2971 |
+
* ```js
|
2972 |
+
* // Usage:
|
2973 |
+
*
|
2974 |
+
* // Add function to 'page_revisit' event
|
2975 |
+
* _inbound.add_action( 'page_revisit', page_revisit_func_example, 10);
|
2976 |
+
*
|
2977 |
+
* function page_revisit_func_example(pageData) {
|
2978 |
+
* var pageData = pageData || {};
|
2979 |
+
* alert('Welcome back to this page!');
|
2980 |
+
* // Show visitor special content/offer
|
2981 |
+
* }
|
2982 |
+
* ```
|
2983 |
+
*/
|
2984 |
+
page_revisit: function(pageData) {
|
2985 |
+
|
2986 |
+
fireEvent('page_revisit', pageData);
|
2987 |
+
|
2988 |
+
var logger = function() {
|
2989 |
+
console.log('pageData', pageData);
|
2990 |
+
console.log('Page Revisit viewed ' + pageData + " times");
|
2991 |
+
}
|
2992 |
+
_inbound.deBugger('pages', status, logger);
|
2993 |
+
},
|
2994 |
+
|
2995 |
+
/**
|
2996 |
+
* `tab_hidden` is triggered when the visitor switches browser tabs
|
2997 |
+
*
|
2998 |
+
* ```js
|
2999 |
+
* // Usage:
|
3000 |
+
*
|
3001 |
+
* // Adding the callback
|
3002 |
+
* function tab_hidden_function( data ) {
|
3003 |
+
* alert('The Tab is Hidden');
|
3004 |
+
* };
|
3005 |
+
*
|
3006 |
+
* // Hook the function up the the `tab_hidden` event
|
3007 |
+
* _inbound.add_action( 'tab_hidden', tab_hidden_function, 10 );
|
3008 |
+
* ```
|
3009 |
+
*/
|
3010 |
+
tab_hidden: function(data) {
|
3011 |
+
_inbound.deBugger('pages', 'Tab Hidden');
|
3012 |
+
fireEvent('tab_hidden');
|
3013 |
+
},
|
3014 |
+
/**
|
3015 |
+
* `tab_visible` is triggered when the visitor switches back to the sites tab
|
3016 |
+
*
|
3017 |
+
* ```js
|
3018 |
+
* // Usage:
|
3019 |
+
*
|
3020 |
+
* // Adding the callback
|
3021 |
+
* function tab_visible_function( data ) {
|
3022 |
+
* alert('Welcome back to this tab!');
|
3023 |
+
* // trigger popup or offer special discount etc.
|
3024 |
+
* };
|
3025 |
+
*
|
3026 |
+
* // Hook the function up the the `tab_visible` event
|
3027 |
+
* _inbound.add_action( 'tab_visible', tab_visible_function, 10 );
|
3028 |
+
* ```
|
3029 |
+
*/
|
3030 |
+
tab_visible: function(data) {
|
3031 |
+
_inbound.deBugger('pages', 'Tab Visible');
|
3032 |
+
fireEvent('tab_visible');
|
3033 |
+
},
|
3034 |
+
/**
|
3035 |
+
* `tab_mouseout` is triggered when the visitor mouses out of the browser window.
|
3036 |
+
* This is especially useful for exit popups
|
3037 |
+
*
|
3038 |
+
* ```js
|
3039 |
+
* // Usage:
|
3040 |
+
*
|
3041 |
+
* // Adding the callback
|
3042 |
+
* function tab_mouseout_function( data ) {
|
3043 |
+
* alert("Wait don't Go");
|
3044 |
+
* // trigger popup or offer special discount etc.
|
3045 |
+
* };
|
3046 |
+
*
|
3047 |
+
* // Hook the function up the the `tab_mouseout` event
|
3048 |
+
* _inbound.add_action( 'tab_mouseout', tab_mouseout_function, 10 );
|
3049 |
+
* ```
|
3050 |
+
*/
|
3051 |
+
tab_mouseout: function(data) {
|
3052 |
+
_inbound.deBugger('pages', 'Tab Mouseout');
|
3053 |
+
fireEvent('tab_mouseout');
|
3054 |
+
},
|
3055 |
+
/**
|
3056 |
+
* `form_input_change` is triggered when tracked form inputs change
|
3057 |
+
* You can use this to add additional validation or set conditional triggers
|
3058 |
+
*
|
3059 |
+
* ```js
|
3060 |
+
* // Usage:
|
3061 |
+
*
|
3062 |
+
* ```
|
3063 |
+
*/
|
3064 |
+
form_input_change: function(inputData) {
|
3065 |
+
var logger = function() {
|
3066 |
+
console.log(inputData);
|
3067 |
+
//console.log('Page Revisit viewed ' + pageData + " times");
|
3068 |
+
}
|
3069 |
+
_inbound.deBugger('forms', 'inputData change. Data=', logger);
|
3070 |
+
fireEvent('form_input_change', inputData);
|
3071 |
+
},
|
3072 |
+
/**
|
3073 |
+
* `form_before_submission` is triggered before the form is submitted to the server.
|
3074 |
+
* You can filter the data here or send it to third party services
|
3075 |
+
*
|
3076 |
+
* ```js
|
3077 |
+
* // Usage:
|
3078 |
+
*
|
3079 |
+
* // Adding the callback
|
3080 |
+
* function form_before_submission_function( data ) {
|
3081 |
+
* var data = data || {};
|
3082 |
+
* // filter form data
|
3083 |
+
* };
|
3084 |
+
*
|
3085 |
+
* // Hook the function up the the `form_before_submission` event
|
3086 |
+
* _inbound.add_action( 'form_before_submission', form_before_submission_function, 10 );
|
3087 |
+
* ```
|
3088 |
+
*/
|
3089 |
+
form_before_submission: function(formData) {
|
3090 |
+
fireEvent('form_before_submission', formData);
|
3091 |
+
},
|
3092 |
+
/**
|
3093 |
+
* `form_after_submission` is triggered after the form is submitted to the server.
|
3094 |
+
* You can filter the data here or send it to third party services
|
3095 |
+
*
|
3096 |
+
* ```js
|
3097 |
+
* // Usage:
|
3098 |
+
*
|
3099 |
+
* // Adding the callback
|
3100 |
+
* function form_after_submission_function( data ) {
|
3101 |
+
* var data = data || {};
|
3102 |
+
* // filter form data
|
3103 |
+
* };
|
3104 |
+
*
|
3105 |
+
* // Hook the function up the the `form_after_submission` event
|
3106 |
+
* _inbound.add_action( 'form_after_submission', form_after_submission_function, 10 );
|
3107 |
+
* ```
|
3108 |
+
*/
|
3109 |
+
form_after_submission: function(formData) {
|
3110 |
+
|
3111 |
+
fireEvent('form_after_submission', formData);
|
3112 |
+
|
3113 |
+
},
|
3114 |
+
/**
|
3115 |
+
* `search_before_caching` is triggered before the search is stored in the user's browser.
|
3116 |
+
* If a lead ID is set, the search data will be saved to the server when the next page loads.
|
3117 |
+
* You can filter the data here or send it to third party services
|
3118 |
+
*
|
3119 |
+
* ```js
|
3120 |
+
* // Usage:
|
3121 |
+
*
|
3122 |
+
* // Adding the callback
|
3123 |
+
* function search_before_caching_function( data ) {
|
3124 |
+
* var data = data || {};
|
3125 |
+
* // filter search data
|
3126 |
+
* };
|
3127 |
+
*
|
3128 |
+
* // Hook the function up the the `search_before_caching` event
|
3129 |
+
* _inbound.add_action( 'search_before_caching', search_before_caching_function, 10 );
|
3130 |
+
* ```
|
3131 |
+
*/
|
3132 |
+
search_before_caching: function(searchData) {
|
3133 |
+
fireEvent('search_before_caching', searchData);
|
3134 |
+
},
|
3135 |
+
/*! Scrol depth https://github.com/robflaherty/jquery-scrolldepth/blob/master/jquery.scrolldepth.js */
|
3136 |
+
|
3137 |
+
analyticsError: function(MLHttpRequest, textStatus, errorThrown) {
|
3138 |
+
var error = new CustomEvent("inbound_analytics_error", {
|
3139 |
+
detail: {
|
3140 |
+
MLHttpRequest: MLHttpRequest,
|
3141 |
+
textStatus: textStatus,
|
3142 |
+
errorThrown: errorThrown
|
3143 |
+
}
|
3144 |
+
});
|
3145 |
+
window.dispatchEvent(error);
|
3146 |
+
console.log('Page Save Error');
|
3147 |
+
}
|
3148 |
+
|
3149 |
+
};
|
3150 |
+
|
3151 |
+
return _inbound;
|
3152 |
+
|
3153 |
+
})(_inbound || {});
|
3154 |
+
|
3155 |
+
|
3156 |
+
function inboundFormNoRedirect(){
|
3157 |
+
/*button == the button that was clicked, form == the form that button belongs to, formRedirectUrl == the link that the form redirects to, if set*/
|
3158 |
+
|
3159 |
+
/*Get the button...*/
|
3160 |
+
/*If not an iframe*/
|
3161 |
+
if(window.frames.frameElement == null){
|
3162 |
+
var button = document.querySelectorAll('button.inbound-button-submit[disabled]')[0];
|
3163 |
+
}
|
3164 |
+
/*If it is an iframe*/
|
3165 |
+
else if(window.frames.frameElement.tagName.toLowerCase() == "iframe"){
|
3166 |
+
var button = window.frames.frameElement.contentWindow.document.querySelectorAll('button.inbound-button-submit')[0];
|
3167 |
+
}
|
3168 |
+
|
3169 |
+
if ( typeof button == 'undefined' ) {
|
3170 |
+
return;
|
3171 |
+
}
|
3172 |
+
|
3173 |
+
var form = button.form,
|
3174 |
+
formRedirectUrl = form.querySelectorAll('input[value][type="hidden"][name="inbound_furl"]:not([value=""])');
|
3175 |
+
|
3176 |
+
/*If the redirect link is not set, or there is a single space in it, the form isn't supposed to redirect. So set the action for void*/
|
3177 |
+
if(formRedirectUrl.length == 0 || formRedirectUrl[0]['value'] == 'IA=='){
|
3178 |
+
form.action = 'javascript:void(0)';
|
3179 |
+
}
|
3180 |
+
}
|
3181 |
+
|
3182 |
+
_inbound.add_action( 'form_before_submission', inboundFormNoRedirect, 10 );
|
3183 |
+
|
3184 |
+
function inboundFormNoRedirectContent(){
|
3185 |
+
|
3186 |
+
/*If not an iframe*/
|
3187 |
+
if(window.frames.frameElement == null){
|
3188 |
+
var button = document.querySelectorAll('button.inbound-button-submit[disabled]')[0];
|
3189 |
+
}
|
3190 |
+
/*If it is an iframe*/
|
3191 |
+
else if(window.frames.frameElement.tagName.toLowerCase() == "iframe"){
|
3192 |
+
var button = window.frames.frameElement.contentWindow.document.querySelectorAll('button.inbound-button-submit')[0];
|
3193 |
+
}
|
3194 |
+
|
3195 |
+
|
3196 |
+
if ( typeof button == 'undefined' ) {
|
3197 |
+
return;
|
3198 |
+
}
|
3199 |
+
|
3200 |
+
var form = button.form,
|
3201 |
+
formRedirectUrl = form.querySelectorAll('input[value][type="hidden"][name="inbound_furl"]:not([value=""])'),
|
3202 |
+
btnBackground = jQuery(button).css('background'),
|
3203 |
+
btnFontColor = jQuery(button).css('color'),
|
3204 |
+
btnHeight = jQuery(button).css('height'),
|
3205 |
+
spinner = button.getElementsByClassName('inbound-form-spinner');
|
3206 |
+
|
3207 |
+
if(formRedirectUrl.length == 0 || formRedirectUrl[0]['value'] == 'IA=='){
|
3208 |
+
jQuery(spinner).remove();
|
3209 |
+
jQuery(button).prepend('<div id="redir-check"><i class="fa fa-check-square" aria-hidden="true" style="background='+ btnBackground +'; color='+ btnFontColor +'; font-size:calc('+ btnHeight +' * .42);"></i></div>');
|
3210 |
+
}
|
3211 |
+
}
|
3212 |
+
|
3213 |
+
_inbound.add_action( 'form_after_submission', inboundFormNoRedirectContent, 10 );
|
3214 |
+
|
3215 |
+
/* LocalStorage Component */
|
3216 |
+
var InboundTotalStorage = (function (_inbound){
|
3217 |
+
|
3218 |
+
var supported, ls, mod = '_inbound';
|
3219 |
+
if ('localStorage' in window){
|
3220 |
+
try {
|
3221 |
+
ls = (typeof window.localStorage === 'undefined') ? undefined : window.localStorage;
|
3222 |
+
if (typeof ls == 'undefined' || typeof window.JSON == 'undefined'){
|
3223 |
+
supported = false;
|
3224 |
+
} else {
|
3225 |
+
supported = true;
|
3226 |
+
}
|
3227 |
+
window.localStorage.setItem(mod, '1');
|
3228 |
+
window.localStorage.removeItem(mod);
|
3229 |
+
}
|
3230 |
+
catch (err){
|
3231 |
+
supported = false;
|
3232 |
+
}
|
3233 |
+
}
|
3234 |
+
|
3235 |
+
/* Make the methods public */
|
3236 |
+
_inbound.totalStorage = function(key, value, options){
|
3237 |
+
return _inbound.totalStorage.impl.init(key, value);
|
3238 |
+
};
|
3239 |
+
|
3240 |
+
_inbound.totalStorage.setItem = function(key, value){
|
3241 |
+
return _inbound.totalStorage.impl.setItem(key, value);
|
3242 |
+
};
|
3243 |
+
|
3244 |
+
_inbound.totalStorage.getItem = function(key){
|
3245 |
+
return _inbound.totalStorage.impl.getItem(key);
|
3246 |
+
};
|
3247 |
+
|
3248 |
+
_inbound.totalStorage.getAll = function(){
|
3249 |
+
return _inbound.totalStorage.impl.getAll();
|
3250 |
+
};
|
3251 |
+
|
3252 |
+
_inbound.totalStorage.deleteItem = function(key){
|
3253 |
+
return _inbound.totalStorage.impl.deleteItem(key);
|
3254 |
+
};
|
3255 |
+
|
3256 |
+
|
3257 |
+
_inbound.totalStorage.impl = {
|
3258 |
+
|
3259 |
+
init: function(key, value){
|
3260 |
+
if (typeof value != 'undefined') {
|
3261 |
+
return this.setItem(key, value);
|
3262 |
+
} else {
|
3263 |
+
return this.getItem(key);
|
3264 |
+
}
|
3265 |
+
},
|
3266 |
+
|
3267 |
+
setItem: function(key, value){
|
3268 |
+
if (!supported){
|
3269 |
+
try {
|
3270 |
+
_inbound.Utils.createCookie(key, value);
|
3271 |
+
return value;
|
3272 |
+
} catch(e){
|
3273 |
+
console.log('Local Storage not supported by this browser. Install the cookie plugin on your site to take advantage of the same functionality. You can get it at https://github.com/carhartl/jquery-cookie');
|
3274 |
+
}
|
3275 |
+
}
|
3276 |
+
var saver = JSON.stringify(value);
|
3277 |
+
ls.setItem(key, saver);
|
3278 |
+
return this.parseResult(saver);
|
3279 |
+
},
|
3280 |
+
getItem: function(key){
|
3281 |
+
if (!supported){
|
3282 |
+
try {
|
3283 |
+
return this.parseResult(_inbound.Utils.readCookie(key));
|
3284 |
+
} catch(e){
|
3285 |
+
return null;
|
3286 |
+
}
|
3287 |
+
}
|
3288 |
+
var item = ls.getItem(key);
|
3289 |
+
return this.parseResult(item);
|
3290 |
+
},
|
3291 |
+
deleteItem: function(key){
|
3292 |
+
if (!supported){
|
3293 |
+
try {
|
3294 |
+
_inbound.Utils.eraseCookie(key, null);
|
3295 |
+
return true;
|
3296 |
+
} catch(e){
|
3297 |
+
return false;
|
3298 |
+
}
|
3299 |
+
}
|
3300 |
+
ls.removeItem(key);
|
3301 |
+
return true;
|
3302 |
+
},
|
3303 |
+
getAll: function(){
|
3304 |
+
var items = [];
|
3305 |
+
if (!supported){
|
3306 |
+
try {
|
3307 |
+
var pairs = document.cookie.split(";");
|
3308 |
+
for (var i = 0; i<pairs.length; i++){
|
3309 |
+
var pair = pairs[i].split('=');
|
3310 |
+
var key = pair[0];
|
3311 |
+
items.push({key:key, value:this.parseResult(_inbound.Utils.readCookie(key))});
|
3312 |
+
}
|
3313 |
+
} catch(e){
|
3314 |
+
return null;
|
3315 |
+
}
|
3316 |
+
} else {
|
3317 |
+
for (var j in ls){
|
3318 |
+
if (j.length){
|
3319 |
+
items.push({key:j, value:this.parseResult(ls.getItem(j))});
|
3320 |
+
}
|
3321 |
+
}
|
3322 |
+
}
|
3323 |
+
return items;
|
3324 |
+
},
|
3325 |
+
parseResult: function(res){
|
3326 |
+
var ret;
|
3327 |
+
try {
|
3328 |
+
ret = JSON.parse(res);
|
3329 |
+
if (typeof ret == 'undefined'){
|
3330 |
+
ret = res;
|
3331 |
+
}
|
3332 |
+
if (ret == 'true'){
|
3333 |
+
ret = true;
|
3334 |
+
}
|
3335 |
+
if (ret == 'false'){
|
3336 |
+
ret = false;
|
3337 |
+
}
|
3338 |
+
if (parseFloat(ret) == ret && typeof ret != "object"){
|
3339 |
+
ret = parseFloat(ret);
|
3340 |
+
}
|
3341 |
+
} catch(e){
|
3342 |
+
ret = res;
|
3343 |
+
}
|
3344 |
+
return ret;
|
3345 |
+
}
|
3346 |
+
};
|
3347 |
+
})(_inbound || {});
|
3348 |
+
/**
|
3349 |
+
* Leads API functions
|
3350 |
+
* @param Object _inbound - Main JS object
|
3351 |
+
* @return Object - include event triggers
|
3352 |
+
*/
|
3353 |
+
var _inboundLeadsAPI = (function(_inbound) {
|
3354 |
+
var httpRequest;
|
3355 |
+
_inbound.LeadsAPI = {
|
3356 |
+
init: function() {
|
3357 |
+
|
3358 |
+
var utils = _inbound.Utils,
|
3359 |
+
wp_lead_uid = utils.readCookie("wp_lead_uid"),
|
3360 |
+
wp_lead_id = utils.readCookie("wp_lead_id"),
|
3361 |
+
expire_check = utils.readCookie("lead_session_expire"); // check for session
|
3362 |
+
|
3363 |
+
if (!expire_check) {
|
3364 |
+
_inbound.deBugger('leads', 'expired vistor. Run Processes');
|
3365 |
+
//var data_to_lookup = global-localized-vars;
|
3366 |
+
if (wp_lead_id) {
|
3367 |
+
/* Get InboundLeadData */
|
3368 |
+
_inbound.LeadsAPI.getAllLeadData();
|
3369 |
+
}
|
3370 |
+
}
|
3371 |
+
},
|
3372 |
+
setGlobalLeadData: function(data) {
|
3373 |
+
InboundLeadData = data;
|
3374 |
+
},
|
3375 |
+
getAllLeadData: function(expire_check) {
|
3376 |
+
var wp_lead_id = _inbound.Utils.readCookie("wp_lead_id"),
|
3377 |
+
leadData = _inbound.totalStorage('inbound_lead_data'),
|
3378 |
+
leadDataExpire = _inbound.Utils.readCookie("lead_data_expire");
|
3379 |
+
data = {
|
3380 |
+
action: 'inbound_get_all_lead_data',
|
3381 |
+
wp_lead_id: wp_lead_id
|
3382 |
+
},
|
3383 |
+
success = function(returnData) {
|
3384 |
+
var leadData = JSON.parse(returnData);
|
3385 |
+
_inbound.LeadsAPI.setGlobalLeadData(leadData);
|
3386 |
+
_inbound.totalStorage('inbound_lead_data', leadData); // store lead data
|
3387 |
+
|
3388 |
+
/* Set 3 day timeout for checking DB for new lead data for Lead_Global var */
|
3389 |
+
var d = new Date();
|
3390 |
+
d.setTime(d.getTime() + 30 * 60 * 1000);
|
3391 |
+
var expire = _inbound.Utils.addDays(d, 3);
|
3392 |
+
_inbound.Utils.createCookie("lead_data_expire", true, expire);
|
3393 |
+
|
3394 |
+
};
|
3395 |
+
|
3396 |
+
if (!leadData) {
|
3397 |
+
// Get New Lead Data from DB
|
3398 |
+
_inbound.Utils.ajaxPost(inbound_settings.admin_url, data, success);
|
3399 |
+
|
3400 |
+
} else {
|
3401 |
+
// set global lead var with localstorage data
|
3402 |
+
_inbound.LeadsAPI.setGlobalLeadData(leadData);
|
3403 |
+
_inbound.deBugger('lead', 'Set Global Lead Data from Localstorage');
|
3404 |
+
|
3405 |
+
if (!leadDataExpire) {
|
3406 |
+
_inbound.Utils.ajaxPost(inbound_settings.admin_url, data, success);
|
3407 |
+
//console.log('Set Global Lead Data from Localstorage');
|
3408 |
+
_inbound.deBugger('lead', 'localized data old. Pull new from DB');
|
3409 |
+
//console.log('localized data old. Pull new from DB');
|
3410 |
+
}
|
3411 |
+
}
|
3412 |
+
|
3413 |
+
},
|
3414 |
+
getLeadLists: function() {
|
3415 |
+
var wp_lead_id = _inbound.Utils.readCookie("wp_lead_id");
|
3416 |
+
var data = {
|
3417 |
+
action: 'wpl_check_lists',
|
3418 |
+
wp_lead_id: wp_lead_id
|
3419 |
+
};
|
3420 |
+
var success = function(user_id) {
|
3421 |
+
_inbound.Utils.createCookie("lead_session_list_check", true, {
|
3422 |
+
path: '/',
|
3423 |
+
expires: 1
|
3424 |
+
});
|
3425 |
+
_inbound.deBugger('lead', "Lists checked");
|
3426 |
+
//console.log("Lists checked");
|
3427 |
+
};
|
3428 |
+
//_inbound.Utils.doAjax(data, success);
|
3429 |
+
_inbound.Utils.ajaxPost(inbound_settings.admin_url, data, success);
|
3430 |
+
}
|
3431 |
+
};
|
3432 |
+
|
3433 |
+
return _inbound;
|
3434 |
+
|
3435 |
+
})(_inbound || {});
|
3436 |
+
/**
|
3437 |
+
* # Page View Tracking
|
3438 |
+
*
|
3439 |
+
* Page view tracking
|
3440 |
+
*
|
3441 |
+
* @contributor David Wells <david@inboundnow.com>
|
3442 |
+
* @contributor Hudson Atwell <hudson@inboundnow.com>
|
3443 |
+
* @version 0.0.2
|
3444 |
+
*/
|
3445 |
+
/* Launches view tracking */
|
3446 |
+
var _inboundPageTracking = (function(_inbound) {
|
3447 |
+
|
3448 |
+
var started = false,
|
3449 |
+
stopped = false,
|
3450 |
+
turnedOff = false,
|
3451 |
+
clockTime = parseInt(_inbound.Utils.readCookie("lead_session"), 10) || 0,
|
3452 |
+
inactiveClockTime = 0,
|
3453 |
+
startTime = new Date(),
|
3454 |
+
clockTimer = null,
|
3455 |
+
inactiveClockTimer = null,
|
3456 |
+
idleTimer = null,
|
3457 |
+
reportInterval,
|
3458 |
+
idleTimeout,
|
3459 |
+
utils = _inbound.Utils,
|
3460 |
+
timeNow = _inbound.Utils.GetDate(),
|
3461 |
+
lsType = 'page_views',
|
3462 |
+
Pages = _inbound.totalStorage(lsType) || {},
|
3463 |
+
/*!
|
3464 |
+
Todo: Use UTC offset
|
3465 |
+
var x = new Date();
|
3466 |
+
var currentTime = x.getTimezoneOffset() / 60;
|
3467 |
+
console.log(currentTime) // gets UTC offset
|
3468 |
+
*/
|
3469 |
+
id = inbound_settings.post_id || window.location.pathname,
|
3470 |
+
analyticsTimeout = _inbound.Settings.timeout || 10000;
|
3471 |
+
|
3472 |
+
_inbound.PageTracking = {
|
3473 |
+
|
3474 |
+
init: function(options) {
|
3475 |
+
|
3476 |
+
if(lsType !== 'page_views') {
|
3477 |
+
return false; // in admin
|
3478 |
+
}
|
3479 |
+
|
3480 |
+
this.CheckTimeOut();
|
3481 |
+
// Set up options and defaults
|
3482 |
+
options = options || {};
|
3483 |
+
reportInterval = parseInt(options.reportInterval, 10) || 10;
|
3484 |
+
idleTimeout = parseInt(options.idleTimeout, 10) || 3;
|
3485 |
+
|
3486 |
+
// Basic activity event listeners
|
3487 |
+
utils.addListener(document, 'keydown', utils.throttle(_inbound.PageTracking.pingSession, 1000));
|
3488 |
+
utils.addListener(document, 'click', utils.throttle(_inbound.PageTracking.pingSession, 1000));
|
3489 |
+
utils.addListener(window, 'mousemove', utils.throttle(_inbound.PageTracking.pingSession, 1000));
|
3490 |
+
//utils.addListener(window, 'scroll', utils.throttle(_inbound.PageTracking.pingSession, 1000));
|
3491 |
+
|
3492 |
+
// Page visibility listeners
|
3493 |
+
_inbound.PageTracking.checkVisibility();
|
3494 |
+
|
3495 |
+
/* Start Session on page load */
|
3496 |
+
this.startSession();
|
3497 |
+
|
3498 |
+
},
|
3499 |
+
|
3500 |
+
setIdle: function(reason) {
|
3501 |
+
var reason = reason || "No Movement",
|
3502 |
+
msg = 'Session IDLE. Activity Timeout due to ' + reason;
|
3503 |
+
|
3504 |
+
_inbound.deBugger('pages', msg);
|
3505 |
+
|
3506 |
+
clearTimeout(_inbound.PageTracking.idleTimer);
|
3507 |
+
_inbound.PageTracking.stopClock();
|
3508 |
+
_inbound.trigger('session_idle');
|
3509 |
+
|
3510 |
+
},
|
3511 |
+
|
3512 |
+
checkVisibility: function() {
|
3513 |
+
var hidden, visibilityState, visibilityChange;
|
3514 |
+
|
3515 |
+
if (typeof document.hidden !== "undefined") {
|
3516 |
+
hidden = "hidden", visibilityChange = "visibilitychange", visibilityState = "visibilityState";
|
3517 |
+
} else if (typeof document.mozHidden !== "undefined") {
|
3518 |
+
hidden = "mozHidden", visibilityChange = "mozvisibilitychange", visibilityState = "mozVisibilityState";
|
3519 |
+
} else if (typeof document.msHidden !== "undefined") {
|
3520 |
+
hidden = "msHidden", visibilityChange = "msvisibilitychange", visibilityState = "msVisibilityState";
|
3521 |
+
} else if (typeof document.webkitHidden !== "undefined") {
|
3522 |
+
hidden = "webkitHidden", visibilityChange = "webkitvisibilitychange", visibilityState = "webkitVisibilityState";
|
3523 |
+
}
|
3524 |
+
|
3525 |
+
var document_hidden = document[hidden];
|
3526 |
+
|
3527 |
+
_inbound.Utils.addListener(document, visibilityChange, function(e) {
|
3528 |
+
/*! Listen for visibility changes */
|
3529 |
+
if (document_hidden != document[hidden]) {
|
3530 |
+
if (document[hidden]) {
|
3531 |
+
// Document hidden
|
3532 |
+
_inbound.trigger('tab_hidden');
|
3533 |
+
_inbound.PageTracking.setIdle('browser tab switch');
|
3534 |
+
} else {
|
3535 |
+
// Document shown
|
3536 |
+
_inbound.trigger('tab_visible');
|
3537 |
+
_inbound.PageTracking.pingSession();
|
3538 |
+
}
|
3539 |
+
|
3540 |
+
document_hidden = document[hidden];
|
3541 |
+
}
|
3542 |
+
});
|
3543 |
+
},
|
3544 |
+
clock: function() {
|
3545 |
+
clockTime += 1;
|
3546 |
+
var niceTime = clockTime / 60;
|
3547 |
+
var msg = 'Total time spent on Page in this Session: ' + niceTime.toFixed(2) + " min";
|
3548 |
+
_inbound.deBugger('pages', msg);
|
3549 |
+
if (clockTime > 0 && (clockTime % reportInterval === 0)) {
|
3550 |
+
|
3551 |
+
var d = new Date();
|
3552 |
+
d.setTime(d.getTime() + 30 * 60 * 1000);
|
3553 |
+
utils.createCookie("lead_session", clockTime, d); // Set cookie on page load
|
3554 |
+
|
3555 |
+
/*! every 10 seconds run this */
|
3556 |
+
//console.log('Session Heartbeat every ' + reportInterval + ' secs');
|
3557 |
+
_inbound.trigger('session_heartbeat', clockTime);
|
3558 |
+
|
3559 |
+
}
|
3560 |
+
|
3561 |
+
},
|
3562 |
+
inactiveClock: function() {
|
3563 |
+
inactiveClockTime += 1;
|
3564 |
+
var TimeUntilTimeOut = (1800 - inactiveClockTime) / 60;
|
3565 |
+
var msg = 'Time until Session Timeout: ' + TimeUntilTimeOut.toFixed(2) + " min";
|
3566 |
+
_inbound.deBugger('pages', msg);
|
3567 |
+
//console.log('Time until Session Timeout: ', TimeUntilTimeOut.toFixed(2) + " min");
|
3568 |
+
/* Session timeout after 30min */
|
3569 |
+
if (inactiveClockTime > 1800) {
|
3570 |
+
|
3571 |
+
// sendEvent(clockTime);
|
3572 |
+
/*! End session after 30min timeout */
|
3573 |
+
_inbound.trigger('session_end', InboundLeadData);
|
3574 |
+
_inbound.Utils.eraseCookie("lead_session");
|
3575 |
+
/* todo maybe? remove session Cookie */
|
3576 |
+
inactiveClockTime = 0;
|
3577 |
+
clearTimeout(inactiveClockTimer);
|
3578 |
+
}
|
3579 |
+
|
3580 |
+
|
3581 |
+
},
|
3582 |
+
stopClock: function() {
|
3583 |
+
stopped = true;
|
3584 |
+
clearTimeout(clockTimer);
|
3585 |
+
clearTimeout(inactiveClockTimer);
|
3586 |
+
inactiveClockTimer = setInterval(_inbound.PageTracking.inactiveClock, 1000);
|
3587 |
+
},
|
3588 |
+
|
3589 |
+
restartClock: function() {
|
3590 |
+
stopped = false;
|
3591 |
+
|
3592 |
+
|
3593 |
+
_inbound.trigger('session_resume');
|
3594 |
+
_inbound.deBugger('pages', 'Activity resumed. Session Active');
|
3595 |
+
/* todo add session_resume */
|
3596 |
+
clearTimeout(clockTimer);
|
3597 |
+
inactiveClockTime = 0;
|
3598 |
+
clearTimeout(inactiveClockTimer);
|
3599 |
+
clockTimer = setInterval(_inbound.PageTracking.clock, 1000);
|
3600 |
+
},
|
3601 |
+
|
3602 |
+
turnOff: function() {
|
3603 |
+
_inbound.PageTracking.setIdle();
|
3604 |
+
turnedOff = true;
|
3605 |
+
},
|
3606 |
+
|
3607 |
+
turnOn: function() {
|
3608 |
+
turnedOff = false;
|
3609 |
+
},
|
3610 |
+
/* This start only runs once */
|
3611 |
+
startSession: function() {
|
3612 |
+
/* todo add session Cookie */
|
3613 |
+
// Calculate seconds from start to first interaction
|
3614 |
+
var currentTime = new Date();
|
3615 |
+
var diff = currentTime - startTime;
|
3616 |
+
|
3617 |
+
|
3618 |
+
started = true; // Set global
|
3619 |
+
|
3620 |
+
// Send User Timing Event
|
3621 |
+
/* Todo session start here */
|
3622 |
+
|
3623 |
+
// Start clock
|
3624 |
+
clockTimer = setInterval(_inbound.PageTracking.clock, 1000);
|
3625 |
+
//utils.eraseCookie("lead_session");
|
3626 |
+
var session = utils.readCookie("lead_session");
|
3627 |
+
|
3628 |
+
if (!session) {
|
3629 |
+
_inbound.trigger('session_start'); // trigger 'inbound_analytics_session_start'
|
3630 |
+
var d = new Date();
|
3631 |
+
d.setTime(d.getTime() + 30 * 60 * 1000);
|
3632 |
+
_inbound.Utils.createCookie("lead_session", 1, d); // Set cookie on page load
|
3633 |
+
} else {
|
3634 |
+
_inbound.trigger('session_active');
|
3635 |
+
//console.log("count of secs " + session);
|
3636 |
+
//_inbound.trigger('session_active'); // trigger 'inbound_analytics_session_active'
|
3637 |
+
}
|
3638 |
+
|
3639 |
+
this.pingSession();
|
3640 |
+
|
3641 |
+
|
3642 |
+
},
|
3643 |
+
resetInactiveFunc: function() {
|
3644 |
+
inactiveClockTime = 0;
|
3645 |
+
clearTimeout(inactiveClockTimer);
|
3646 |
+
},
|
3647 |
+
/* Ping Session to keep active */
|
3648 |
+
pingSession: function(e) {
|
3649 |
+
|
3650 |
+
|
3651 |
+
if (turnedOff) {
|
3652 |
+
return;
|
3653 |
+
}
|
3654 |
+
|
3655 |
+
if (!started) {
|
3656 |
+
_inbound.PageTracking.startSession();
|
3657 |
+
}
|
3658 |
+
|
3659 |
+
if (stopped) {
|
3660 |
+
_inbound.PageTracking.restartClock();
|
3661 |
+
}
|
3662 |
+
|
3663 |
+
clearTimeout(idleTimer);
|
3664 |
+
|
3665 |
+
idleTimer = setTimeout(_inbound.PageTracking.setIdle, idleTimeout * 1000 + 100);
|
3666 |
+
|
3667 |
+
if (typeof(e) != "undefined") {
|
3668 |
+
if (e.type === "mousemove") {
|
3669 |
+
_inbound.PageTracking.mouseEvents(e);
|
3670 |
+
}
|
3671 |
+
}
|
3672 |
+
|
3673 |
+
},
|
3674 |
+
mouseEvents: function(e) {
|
3675 |
+
|
3676 |
+
if (e.pageY <= 5) {
|
3677 |
+
_inbound.trigger('tab_mouseout');
|
3678 |
+
}
|
3679 |
+
|
3680 |
+
},
|
3681 |
+
/**
|
3682 |
+
* Returns the pages viewed by the site visitor
|
3683 |
+
*
|
3684 |
+
* ```js
|
3685 |
+
* var pageViews = _inbound.PageTracking.getPageViews();
|
3686 |
+
* // returns page view object
|
3687 |
+
* ```
|
3688 |
+
*
|
3689 |
+
* @return {object} page view object with page ID as key and timestamp
|
3690 |
+
*/
|
3691 |
+
getPageViews: function() {
|
3692 |
+
var local_store = _inbound.Utils.checkLocalStorage();
|
3693 |
+
if (local_store) {
|
3694 |
+
var page_views = localStorage.getItem(lsType),
|
3695 |
+
local_object = JSON.parse(page_views);
|
3696 |
+
if (typeof local_object == 'object' && local_object) {
|
3697 |
+
//this.triggerPageView();
|
3698 |
+
}
|
3699 |
+
return local_object;
|
3700 |
+
}
|
3701 |
+
},
|
3702 |
+
isRevisit: function(Pages) {
|
3703 |
+
var revisitCheck = false;
|
3704 |
+
var Pages = Pages || {};
|
3705 |
+
var pageSeen = Pages[id];
|
3706 |
+
if (typeof(pageSeen) != "undefined" && pageSeen !== null) {
|
3707 |
+
revisitCheck = true;
|
3708 |
+
}
|
3709 |
+
return revisitCheck;
|
3710 |
+
},
|
3711 |
+
triggerPageView: function(pageRevisit) {
|
3712 |
+
|
3713 |
+
var pageData = {
|
3714 |
+
title: document.title,
|
3715 |
+
url: document.location.href,
|
3716 |
+
path: document.location.pathname,
|
3717 |
+
count: 1 // default
|
3718 |
+
};
|
3719 |
+
|
3720 |
+
if (pageRevisit) {
|
3721 |
+
/* Page Revisit Trigger */
|
3722 |
+
Pages[id].push(timeNow);
|
3723 |
+
pageData.count = Pages[id].length;
|
3724 |
+
_inbound.trigger('page_revisit', pageData);
|
3725 |
+
|
3726 |
+
} else {
|
3727 |
+
/* Page First Seen Trigger */
|
3728 |
+
Pages[id] = [];
|
3729 |
+
Pages[id].push(timeNow);
|
3730 |
+
_inbound.trigger('page_first_visit', pageData);
|
3731 |
+
}
|
3732 |
+
|
3733 |
+
_inbound.trigger('page_visit', pageData);
|
3734 |
+
|
3735 |
+
_inbound.totalStorage(lsType, Pages);
|
3736 |
+
|
3737 |
+
this.storePageView();
|
3738 |
+
|
3739 |
+
},
|
3740 |
+
CheckTimeOut: function() {
|
3741 |
+
|
3742 |
+
var pageRevisit = this.isRevisit(Pages),
|
3743 |
+
status,
|
3744 |
+
timeout;
|
3745 |
+
|
3746 |
+
/* Default */
|
3747 |
+
if (pageRevisit) {
|
3748 |
+
|
3749 |
+
var prev = Pages[id].length - 1,
|
3750 |
+
lastView = Pages[id][prev],
|
3751 |
+
timeDiff = Math.abs(new Date(lastView).getTime() - new Date(timeNow).getTime());
|
3752 |
+
|
3753 |
+
timeout = timeDiff > analyticsTimeout;
|
3754 |
+
|
3755 |
+
if (timeout) {
|
3756 |
+
status = 'Timeout Happened. Page view fired';
|
3757 |
+
this.triggerPageView(pageRevisit);
|
3758 |
+
} else {
|
3759 |
+
time_left = Math.abs((analyticsTimeout - timeDiff)) * 0.001;
|
3760 |
+
status = analyticsTimeout / 1000 + ' sec timeout not done: ' + time_left + " seconds left";
|
3761 |
+
}
|
3762 |
+
|
3763 |
+
} else {
|
3764 |
+
/*! Page never seen before save view */
|
3765 |
+
this.triggerPageView(pageRevisit);
|
3766 |
+
}
|
3767 |
+
|
3768 |
+
_inbound.deBugger('pages', status);
|
3769 |
+
},
|
3770 |
+
storePageView: function() {
|
3771 |
+
var stored = false;
|
3772 |
+
|
3773 |
+
/* ignore if page tracking off and page is not a landing page */
|
3774 |
+
if ( inbound_settings.page_tracking == 'off' && inbound_settings.post_type != 'landing-page' ) {
|
3775 |
+
return;
|
3776 |
+
}
|
3777 |
+
|
3778 |
+
/* Let's try and fire this last - also defines what constitutes a bounce - */
|
3779 |
+
document.onreadystatechange = function(){
|
3780 |
+
|
3781 |
+
if(document.readyState !== 'loading' && stored === false){
|
3782 |
+
setTimeout(function(){
|
3783 |
+
var leadID = ( _inbound.Utils.readCookie('wp_lead_id') ) ? _inbound.Utils.readCookie('wp_lead_id') : '';
|
3784 |
+
var lead_uid = ( _inbound.Utils.readCookie('wp_lead_uid') ) ? _inbound.Utils.readCookie('wp_lead_uid') : '';
|
3785 |
+
var ctas_loaded = _inbound.totalStorage('wp_cta_loaded');
|
3786 |
+
var ctas_impressions = _inbound.totalStorage('wp_cta_impressions');
|
3787 |
+
stored = true;
|
3788 |
+
|
3789 |
+
/* now reset impressions */
|
3790 |
+
_inbound.totalStorage('wp_cta_impressions' , {} );
|
3791 |
+
|
3792 |
+
var data = {
|
3793 |
+
action: 'inbound_track_lead',
|
3794 |
+
wp_lead_uid: lead_uid,
|
3795 |
+
wp_lead_id: leadID,
|
3796 |
+
page_id: inbound_settings.post_id,
|
3797 |
+
variation_id: inbound_settings.variation_id,
|
3798 |
+
post_type: inbound_settings.post_type,
|
3799 |
+
current_url: window.location.href,
|
3800 |
+
page_views: JSON.stringify(_inbound.PageTracking.getPageViews()),
|
3801 |
+
cta_impressions : JSON.stringify(ctas_impressions),
|
3802 |
+
cta_history : JSON.stringify(ctas_loaded),
|
3803 |
+
json: '0'
|
3804 |
+
};
|
3805 |
+
|
3806 |
+
var firePageCallback = function(leadID) {
|
3807 |
+
//_inbound.Events.page_view_saved(leadID);
|
3808 |
+
};
|
3809 |
+
//_inbound.Utils.doAjax(data, firePageCallback);
|
3810 |
+
|
3811 |
+
_inbound.Utils.ajaxPost(inbound_settings.admin_url, data, firePageCallback);
|
3812 |
+
|
3813 |
+
} , 200 );
|
3814 |
+
}
|
3815 |
+
}
|
3816 |
+
}
|
3817 |
+
/*! GA functions
|
3818 |
+
function log_event(category, action, label) {
|
3819 |
+
_gaq.push(['_trackEvent', category, action, label]);
|
3820 |
+
}
|
3821 |
+
|
3822 |
+
function log_click(category, link) {
|
3823 |
+
log_event(category, 'Click', $(link).text());
|
3824 |
+
}
|
3825 |
+
*/
|
3826 |
+
};
|
3827 |
+
|
3828 |
+
return _inbound;
|
3829 |
+
|
3830 |
+
})(_inbound || {});
|
3831 |
+
/**
|
3832 |
+
* # Start
|
3833 |
+
*
|
3834 |
+
* Runs init functions
|
3835 |
+
*
|
3836 |
+
* @contributor David Wells <david@inboundnow.com>
|
3837 |
+
* @contributor Hudson Atwell <hudson@inboundnow.com>
|
3838 |
+
* @version 0.0.2
|
3839 |
+
*/
|
3840 |
+
|
3841 |
+
|
3842 |
+
/* Initialize _inbound */
|
3843 |
+
_inbound.init();
|
3844 |
+
|
3845 |
+
/* Set Global Lead Data */
|
3846 |
+
InboundLeadData = _inbound.totalStorage('inbound_lead_data') || null;
|
3847 |
+
|
shared/assets/js/frontend/analytics/inboundAnalytics.min.js
CHANGED
@@ -1,2 +1,2 @@
|
|
1 |
-
/*! Inbound Analyticsv1.0.0 | (c) 2017 Inbound Now | https://github.com/inboundnow/cta */
|
2 |
-
function inboundFormNoRedirect(){if(null==window.frames.frameElement)e=document.querySelectorAll("button.inbound-button-submit[disabled]")[0];else if("iframe"==window.frames.frameElement.tagName.toLowerCase())var e=window.frames.frameElement.contentWindow.document.querySelectorAll("button.inbound-button-submit")[0];if(void 0!==e){var t=e.form,n=t.querySelectorAll('input[value][type="hidden"][name="inbound_furl"]:not([value=""])');0!=n.length&&"IA=="!=n[0].value||(t.action="javascript:void(0)")}}function inboundFormNoRedirectContent(){if(null==window.frames.frameElement)e=document.querySelectorAll("button.inbound-button-submit[disabled]")[0];else if("iframe"==window.frames.frameElement.tagName.toLowerCase())var e=window.frames.frameElement.contentWindow.document.querySelectorAll("button.inbound-button-submit")[0];if(void 0!==e){var t=e.form.querySelectorAll('input[value][type="hidden"][name="inbound_furl"]:not([value=""])'),n=jQuery(e).css("background"),o=jQuery(e).css("color"),i=jQuery(e).css("height"),a=e.getElementsByClassName("inbound-form-spinner");0!=t.length&&"IA=="!=t[0].value||(jQuery(a).remove(),jQuery(e).prepend('<div id="redir-check"><i class="fa fa-check-square" aria-hidden="true" style="background='+n+"; color="+o+"; font-size:calc("+i+' * .42);"></i></div>'))}}var inbound_data=inbound_data||{},_inboundOptions=_inboundOptions||{},_gaq=_gaq||[],_inbound=function(e){var t={timeout:inbound_settings.is_admin?500:1e4,formAutoTracking:!0,formAutoPopulation:!0},n={init:function(){_inbound.Utils.init(),_inbound.Utils.domReady(window,function(){_inbound.DomLoaded()})},DomLoaded:function(){_inbound.PageTracking.init(),_inbound.Forms.init(),_inbound.Utils.setUrlParams(),_inbound.LeadsAPI.init(),setTimeout(function(){_inbound.Forms.init()},2e3),_inbound.trigger("analytics_ready")},extend:function(e,t){var n,o={};for(n in e)Object.prototype.hasOwnProperty.call(e,n)&&(o[n]=e[n]);for(n in t)Object.prototype.hasOwnProperty.call(t,n)&&(o[n]=t[n]);return o},debug:function(e,t){},deBugger:function(e,t,n){if(console){var o,i,a,r=document.location.hash?document.location.hash:"",s=r.indexOf("#debug")>-1,t=t||!1;r&&r.match(/debug/)&&(a=(r=r.split("-"))[1]),i="true"===_inbound.Utils.readCookie("inbound_debug"),((o="true"===_inbound.Utils.readCookie("inbound_debug_"+e))||s||i)&&(t&&"string"==typeof t&&(i||"all"===a?console.log('logAll "'+e+'" =>',t):o?console.log('log "'+e+'" =>',t):e===a&&console.log('#log "'+e+'" =>',t)),n&&n instanceof Function&&n())}}},o=n.extend(t,e);return n.Settings=o||{},n}(_inboundOptions),_inboundHooks=function(e){return e.hooks=new function(){function e(e,t,n,o){if(a[e][t])if(n){var i,r=a[e][t];if(o)for(i=r.length;i--;){var s=r[i];s.callback===n&&s.context===o&&r.splice(i,1)}else for(i=r.length;i--;)r[i].callback===n&&r.splice(i,1)}else a[e][t]=[]}function t(e,t,o,i,r){var s={callback:o,priority:i,context:r},l=a[e][t];l?(l.push(s),l=n(l)):l=[s],a[e][t]=l}function n(e){for(var t,n,o,i=1,a=e.length;i<a;i++){for(t=e[i],n=i;(o=e[n-1])&&o.priority>t.priority;)e[n]=e[n-1],--n;e[n]=t}return e}function o(e,t,n){var o=a[e][t];if(!o)return"filters"===e&&n[0];var i=0,r=o.length;if("filters"===e)for(;i<r;i++)n[0]=o[i].callback.apply(o[i].context,n);else for(;i<r;i++)o[i].callback.apply(o[i].context,n);return"filters"!==e||n[0]}var i={removeFilter:function(t,n){return"string"==typeof t&&e("filters",t,n),i},applyFilters:function(){var e=Array.prototype.slice.call(arguments),t=e.shift();return"string"==typeof t?o("filters",t,e):i},addFilter:function(e,n,o,a){return"string"==typeof e&&"function"==typeof n&&t("filters",e,n,o=parseInt(o||10,10)),i},removeAction:function(t,n){return"string"==typeof t&&e("actions",t,n),i},doAction:function(){var e=Array.prototype.slice.call(arguments),t=e.shift();return"string"==typeof t&&o("actions",t,e),i},addAction:function(e,n,o,a){return"string"==typeof e&&"function"==typeof n&&t("actions",e,n,o=parseInt(o||10,10),a),i}},a={actions:{},filters:{}};return i},e.add_action=function(){var t=arguments[0].split(" ");for(k in t)arguments[0]="inbound."+t[k],e.hooks.addAction.apply(this,arguments);return this},e.remove_action=function(){return arguments[0]="inbound."+arguments[0],e.hooks.removeAction.apply(this,arguments),this},e.do_action=function(){return arguments[0]="inbound."+arguments[0],e.hooks.doAction.apply(this,arguments),this},e.add_filter=function(){return arguments[0]="inbound."+arguments[0],e.hooks.addFilter.apply(this,arguments),this},e.remove_filter=function(){return arguments[0]="inbound."+arguments[0],e.hooks.removeFilter.apply(this,arguments),this},e.apply_filters=function(){return arguments[0]="inbound."+arguments[0],e.hooks.applyFilters.apply(this,arguments)},e}(_inbound||{}),_inboundUtils=function(e){var t,n=window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest,o=(Object.prototype.toString,{api_host:("https:"==location.protocol?"https://":"http://")+location.hostname+location.pathname.replace(/\/$/,""),track_pageview:!0,track_links_timeout:300,cookie_name:"_sp",cookie_expiration:365,cookie_domain:(host=location.hostname.match(/[a-z0-9][a-z0-9\-]+\.[a-z\.]{2,6}$/i))?host[0]:""});return e.Utils={init:function(){this.polyFills(),this.checkLocalStorage(),this.SetUID(),this.storeReferralData()},polyFills:function(){window.console||(window.console={});for(var e=["log","info","warn","error","debug","trace","dir","group","groupCollapsed","groupEnd","time","timeEnd","profile","profileEnd","dirxml","assert","count","markTimeline","timeStamp","clear"],t=0;t<e.length;t++)window.console[e[t]]||(window.console[e[t]]=function(){});Date.prototype.toISOString||function(){function e(e){var t=String(e);return 1===t.length&&(t="0"+t),t}Date.prototype.toISOString=function(){return this.getUTCFullYear()+"-"+e(this.getUTCMonth()+1)+"-"+e(this.getUTCDate())+"T"+e(this.getUTCHours())+":"+e(this.getUTCMinutes())+":"+e(this.getUTCSeconds())+"."+String((this.getUTCMilliseconds()/1e3).toFixed(3)).slice(2,5)+"Z"}}();try{new CustomEvent("?")}catch(e){this.CustomEvent=function(e,t){function n(t,n,o,i){this["init"+e](t,n,o,i),"detail"in this||(this.detail=i)}return function(o,i){var a=document.createEvent(e);return null!==o?n.call(a,o,(i||(i=t)).bubbles,i.cancelable,i.detail):a.initCustomEvent=n,a}}(this.CustomEvent?"CustomEvent":"Event",{bubbles:!1,cancelable:!1,detail:null})}document.querySelectorAll||(document.querySelectorAll=function(e){var t,n=document.createElement("style"),o=[];for(document.documentElement.firstChild.appendChild(n),document._qsa=[],n.styleSheet.cssText=e+"{x-qsa:expression(document._qsa && document._qsa.push(this))}",window.scrollBy(0,0),n.parentNode.removeChild(n);document._qsa.length;)(t=document._qsa.shift()).style.removeAttribute("x-qsa"),o.push(t);return document._qsa=null,o}),document.querySelector||(document.querySelector=function(e){var t=document.querySelectorAll(e);return t.length?t[0]:null}),!("innerText"in document.createElement("a"))&&"getSelection"in window&&HTMLElement.prototype.__defineGetter__("innerText",function(){for(var e,t=window.getSelection(),n=[],o=0;o<t.rangeCount;o++)n[o]=t.getRangeAt(o);t.removeAllRanges(),t.selectAllChildren(this),e=t.toString(),t.removeAllRanges();for(o=0;o<n.length;o++)t.addRange(n[o]);return e})},createCookie:function(e,t,n){var o="";if(n){var i=new Date;i.setTime(i.getTime()+24*n*60*60*1e3),o="; expires="+i.toGMTString()}document.cookie=e+"="+t+o+"; path=/"},readCookie:function(e){for(var t=e+"=",n=document.cookie.split(";"),o=0;o<n.length;o++){for(var i=n[o];" "===i.charAt(0);)i=i.substring(1,i.length);if(0===i.indexOf(t))return i.substring(t.length,i.length)}return null},eraseCookie:function(e){this.createCookie(e,"",-1)},getAllCookies:function(){var t={};if(document.cookie&&""!==document.cookie)for(var n=document.cookie.split(";"),o=0;o<n.length;o++){var i=n[o].split("=");i[0]=i[0].replace(/^ /,""),t[decodeURIComponent(i[0])]=decodeURIComponent(i[1])}return e.totalStorage("inbound_cookies",t),t},setUrlParams:function(){var n={};!function(){for(var e,t=function(e){return decodeURIComponent(e).replace(/\+/g," ")},o=window.location.search.substring(1),i=/([^&=]+)=?([^&]*)/g;e=i.exec(o);)if("-1"==e[1].indexOf("["))n[t(e[1])]=t(e[2]);else{var a=e[1].indexOf("["),r=e[1].slice(a+1,e[1].indexOf("]",a)),s=t(e[1].slice(0,a));"object"!=typeof n[s]&&(n[t(s)]={},n[t(s)].length=0),r?n[t(s)][t(r)]=t(e[2]):Array.prototype.push.call(n[t(s)],t(e[2]))}}();for(var o in n)if("action"!=o)if("object"==typeof n[o])for(var i in n[o])this.createCookie(i,n[o][i],30);else this.createCookie(o,n[o],30);if(t){var a=e.totalStorage("inbound_url_params")||{},r=this.mergeObjs(a,n);e.totalStorage("inbound_url_params",r)}var s={option1:"yo",option2:"woooo"};e.trigger("url_parameters",n,s)},getAllUrlParams:function(){n={};if(t)var n=e.totalStorage("inbound_url_params");return n},getParameterVal:function(e,t){return(RegExp(e+"=(.+?)(&|$)").exec(t)||[,!1])[1]},checkLocalStorage:function(){if("localStorage"in window)try{ls=void 0===window.localStorage?void 0:window.localStorage,t="undefined"!=typeof ls&&void 0!==window.JSON}catch(e){t=!1}return t},showLocalStorageSize:function(){function e(e){return 2*e.length}function t(e){return e/1024/1024}var n=Object.keys(localStorage).map(function(t){return{name:t,size:e(localStorage[t])}}).map(function(e){return e.size=t(e.size).toFixed(2)+" MB",e});console.table(n)},addDays:function(e,t){return new Date(e.getTime()+24*t*60*60*1e3)},GetDate:function(){var e=new Date,t=e.getDate(),n=t<10?"0":"",o=e.getFullYear(),i=e.getHours(),a=i<10?"0":"",r=e.getMinutes(),s=r<10?"0":"",l=e.getSeconds(),u=l<10?"0":"",d=e.getMonth()+1;return o+"/"+(d<10?"0":"")+d+"/"+n+t+" "+a+i+":"+s+r+":"+u+l},SetSessionTimeout:function(){this.readCookie("lead_session_expire");var e=new Date;e.setTime(e.getTime()+18e5),this.createCookie("lead_session_expire",!0,e)},storeReferralData:function(){var t=new Date,n=document.referrer||"Direct Traffic",o=e.Utils.readCookie("inbound_referral_site"),i=e.totalStorage("inbound_original_referral");t.setTime(t.getTime()+18e5),o||this.createCookie("inbound_referral_site",n,t),i||e.totalStorage("inbound_original_referral",i)},CreateUID:function(e){var t="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz".split(""),n="";e||(e=Math.floor(Math.random()*t.length));for(var o=0;o<e;o++)n+=t[Math.floor(Math.random()*t.length)];return n},generateGUID:function(e){return e?(e^16*Math.random()>>e/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,guid)},SetUID:function(e){if(!this.readCookie("wp_lead_uid")){var t=e||this.CreateUID(35);this.createCookie("wp_lead_uid",t)}},countProperties:function(e){var t=0;for(var n in e)e.hasOwnProperty(n)&&++t;return t},mergeObjs:function(e,t){var n={};for(var o in e)n[o]=e[o];for(var o in t)n[o]=t[o];return n},hasClass:function(e,t){if("classList"in document.documentElement)n=t.classList.contains(e);else var n=new RegExp("(^|\\s)"+e+"(\\s|$)").test(t.className);return n},addClass:function(e,t){"classList"in document.documentElement?t.classList.add(e):this.hasClass(t,e)||(t.className+=(t.className?" ":"")+e)},removeClass:function(e,t){"classList"in document.documentElement?t.classList.remove(e):this.hasClass(t,e)&&(t.className=t.className.replace(new RegExp("(^|\\s)*"+e+"(\\s|$)*","g"),""))},removeElement:function(e){e.parentNode.removeChild(e)},trim:function(e){return e=e.replace(/(^\s*)|(\s*$)/gi,""),e=e.replace(/[ ]{2,}/gi," "),e=e.replace(/\n /,"\n")},ajaxPolyFill:function(){if("undefined"!=typeof XMLHttpRequest)return new XMLHttpRequest;for(var e,t=["MSXML2.XmlHttp.5.0","MSXML2.XmlHttp.4.0","MSXML2.XmlHttp.3.0","MSXML2.XmlHttp.2.0","Microsoft.XmlHttp"],n=0;n<t.length;n++)try{e=new ActiveXObject(t[n]);break}catch(e){}return e},ajaxSendData:function(e,t,n,o,i){var a=this.ajaxPolyFill();setTimeout(function(){a.open(n,e,!0),a.onreadystatechange=function(){4==a.readyState&&t(a.responseText)},"POST"==n&&a.setRequestHeader("Content-type","application/x-www-form-urlencoded"),a.send(o)},100)},ajaxGet:function(e,t,n,o){var i=[];for(var a in t)i.push(encodeURIComponent(a)+"="+encodeURIComponent(t[a]));this.ajaxSendData(e+"?"+i.join("&"),n,"GET",null,o)},ajaxPost:function(e,t,n,o){var i=[];for(var a in t)i.push(encodeURIComponent(a)+"="+encodeURIComponent(t[a]));this.ajaxSendData(e,n,"POST",i.join("&"),o)},sendEvent:function(e,t,i){t=t||{},async=!0;var a=getCookie();if(a){var r;for(r in a)t[r]=a[r]}t.id||(t.id=getId());var s={e:e,t:(new Date).toISOString(),kv:t},l=o.api_host+"/track?data="+encodeURIComponent(JSON.stringify(s));if(n){var u=new XMLHttpRequest;u.open("GET",l,async),u.withCredentials=async,u.send(null)}else{var d=document.createElement("script");d.type="text/javascript",d.async=async,d.defer=async,d.src=l;var c=document.getElementsByTagName("script")[0];c.parentNode.insertBefore(d,c)}return action(i),self},domReady:function(e,t){var n=!1,o=!0,i=e.document,a=i.documentElement,r=i.addEventListener?"addEventListener":"attachEvent",s=i.addEventListener?"removeEventListener":"detachEvent",l=i.addEventListener?"":"on",u=function(o){"readystatechange"==o.type&&"complete"!=i.readyState||(("load"==o.type?e:i)[s](l+o.type,u,!1),!n&&(n=!0)&&t.call(e,o.type||o))},d=function(){try{a.doScroll("left")}catch(e){return void setTimeout(d,50)}u("poll")};if("complete"==i.readyState)t.call(e,"lazy");else{if(i.createEventObject&&a.doScroll){try{o=!e.frameElement}catch(e){}o&&d()}i[r](l+"DOMContentLoaded",u,!1),i[r](l+"readystatechange",u,!1),e[r](l+"load",u,!1)}},addListener:function(e,t,n){e&&(e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent?e.attachEvent("on"+t,n):e["on"+t]=n)},removeListener:function(e,t,n){e.removeEventListener?e.removeEventListener(t,n,!1):e.detachEvent?e.detachEvent("on"+t,n):e["on"+t]=null},throttle:function(e,t){var n,o,i,a=null,r=0,s=function(){r=new Date,a=null,i=e.apply(n,o)};return function(){var l=new Date;r||(r=l);var u=t-(l-r);return n=this,o=arguments,u<=0?(clearTimeout(a),a=null,r=l,i=e.apply(n,o)):a||(a=setTimeout(s,u)),i}},checkTypeofGA:function(){"function"==typeof ga&&(universalGA=!0),void 0!==_gaq&&"function"==typeof _gaq.push&&(classicGA=!0),"undefined"!=typeof dataLayer&&"function"==typeof dataLayer.push&&(googleTagManager=!0)},cacheSearchData:function(n,o){if(t){var i=e.totalStorage.getItem("inbound_search_storage");if(i)i.unshift(n),e.totalStorage.setItem("inbound_search_storage",i);else{var a=[n];e.totalStorage.setItem("inbound_search_storage",a)}}else{var r=JSON.stringify(n),s=this.readCookie("inbound_search_storage");s&&(r+="SPLIT-TOKEN"+s),this.createCookie("inbound_search_storage",r,"180")}e.Forms.releaseFormSubmit(o)},storeSearchData:function(){if(inbound_settings.wp_lead_data.lead_id&&inbound_settings.wp_lead_data.lead_nonce){var t=[],n=e.totalStorage.getItem("inbound_search_storage"),o=this.readCookie("inbound_search_storage");if(n||o){if(o){o=o.split("SPLIT-TOKEN");for(var i in o)t.push(JSON.parse(o[i]))}n&&(t=t.concat(n)),t.sort(function(e,t){return e.timestamp-t.timestamp});var a={action:"inbound_search_store",data:t=encodeURIComponent(JSON.stringify(t)),nonce:inbound_settings.wp_lead_data.lead_nonce,lead_id:inbound_settings.wp_lead_data.lead_id};callback=function(t){t&&(t=JSON.parse(t)),t.success&&(console.log(t.success),e.Utils.eraseCookie("inbound_search_storage"),e.totalStorage.deleteItem("inbound_search_storage")),t.error&&console.log(t.error)},this.ajaxPost(inbound_settings.admin_url,a,callback)}}}},e}(_inbound||{}),InboundForms=function(e){var t=e.Utils,n=[],o=[],a=[],r={},s=e.Settings,l=["first name","last name","name","email","e-mail","phone","website","job title","your favorite food","company","tele","address","comment"];if(e.Forms={init:function(){e.Forms.runFieldMappingFilters(),e.Forms.formTrackInit(),e.Forms.searchTrackInit()},runFieldMappingFilters:function(){l=e.hooks.applyFilters("forms.field_map",l)},debug:function(e,t){return},formTrackInit:function(){for(var e=0;e<window.document.forms.length;e++){var t=window.document.forms[e];t.dataset.formProcessed||(t.dataset.formProcessed=!0,this.checkTrackStatus(t)&&(this.attachFormSubmitEvent(t),this.initFormMapping(t)))}},searchTrackInit:function(){if("off"!=inbound_settings.search_tracking&&!r.searchTrackInit){for(var e=0;e<window.document.forms.length;e++){var n=window.document.forms[e];n.dataset.searchChecked||(n.dataset.searchChecked=!0,this.checkSearchTrackStatus(n)&&this.attachSearchFormSubmitEvent(n))}t.storeSearchData(),r.searchTrackInit=!0}},checkTrackStatus:function(t){var n=t.getAttribute("class");if(""!==n&&null!==n)return n.toLowerCase().indexOf("wpl-track-me")>-1||(n.toLowerCase().indexOf("inbound-track")>-1||(cb=function(){console.log(t)},e.deBugger("forms","This form not tracked. Please assign on in settings...",cb),!1))},checkSearchTrackStatus:function(t){var n=t.getAttribute("class"),o=t.getAttribute("id");return""!==n&&null!==n&&n.toLowerCase().indexOf("search")>-1||(""===o||null===o?(cb=function(){console.log(t)},e.deBugger("searches","This search form is not tracked. Please assign on in settings...",cb),!1):o.toLowerCase().indexOf("search")>-1||void 0)},loopClassSelectors:function(n,o){for(var i=n.length-1;i>=0;i--){var a=t.trim(n[i]);-1===a.indexOf("#")&&-1===a.indexOf(".")&&(a="#"+a),(a=document.querySelector(a))&&("add"===o?(e.Utils.addClass("wpl-track-me",a),e.Utils.addClass("inbound-track",a)):(e.Utils.removeClass("wpl-track-me",a),e.Utils.removeClass("inbound-track",a)))}},initFormMapping:function(t){for(var n=[],o=0;o<t.elements.length;o++)formInput=t.elements[o],"hidden"!==formInput.type?(this.mapField(formInput),this.rememberInputValues(formInput),s.formAutoPopulation&&!e.Utils.hasClass("nopopulate",t)&&this.fillInputValues(formInput)):n.push(formInput);for(var i=n.length-1;i>=0;i--)formInput=n[i],this.mapField(formInput)},mapField:function(o){var a=o.id||!1,r=o.name||!1,s=this.getInputLabel(o);if(s&&this.ignoreFieldByLabel(s[0].innerText))return o.dataset.ignoreFormField=!0,!1;for(i=0;i<l.length;i++){var u=!1,d=l[i],c=t.trim(d),m=c.replace(/ /g,"_");r&&r.toLowerCase().indexOf(c)>-1?(u=!0,e.deBugger("forms","Found matching name attribute for -> "+c)):a&&a.toLowerCase().indexOf(c)>-1?(u=!0,e.deBugger("forms","Found matching ID attribute for ->"+c)):s?s[0].innerText.toLowerCase().indexOf(c)>-1&&(u=!0,e.deBugger("forms","Found matching sibling label for -> "+c)):n.push(c),u&&(this.addDataAttr(o,m),this.removeArrayItem(l,c),i--)}return inbound_data},formListener:function(t){t.preventDefault(),e.Forms.saveFormData(t.target),document.body.style.cursor="wait"},searchFormListener:function(t){t.preventDefault(),e.Forms.saveSearchData(t.target)},attachFormSubmitEvent:function(e){t.addListener(e,"submit",this.formListener);document.querySelector(".inbound-email")},attachSearchFormSubmitEvent:function(e){t.addListener(e,"submit",this.searchFormListener)},ignoreFieldByLabel:function(t){var n=!1;return!!t&&(-1==t.toLowerCase().indexOf("credit card")&&-1==t.toLowerCase().indexOf("card number")||(n=!0),-1==t.toLowerCase().indexOf("expiration")&&-1==t.toLowerCase().indexOf("expiry")||(n=!0),"month"!=t.toLowerCase()&&"mm"!=t.toLowerCase()&&"yy"!=t.toLowerCase()&&"yyyy"!=t.toLowerCase()&&"year"!=t.toLowerCase()||(n=!0),-1==t.toLowerCase().indexOf("cvv")&&-1==t.toLowerCase().indexOf("cvc")&&-1==t.toLowerCase().indexOf("secure code")&&-1==t.toLowerCase().indexOf("security code")||(n=!0),n&&e.deBugger("forms","ignore "+t),n)},ignoreFieldByValue:function(e){var t=!1;if(!e)return!1;if("visa"!=e.toLowerCase()&&"mastercard"!=e.toLowerCase()&&"american express"!=e.toLowerCase()&&"amex"!=e.toLowerCase()&&"discover"!=e.toLowerCase()||(t=!0),new RegExp("/^[0-9]+$/").test(e)){var n=e.replace(" ","");this.isInt(n)&&n.length>=16&&(t=!0)}return t},isInt:function(e){return"number"==typeof e&&isFinite(e)&&e%1==0},releaseFormSubmit:function(e){document.body.style.cursor="default",t.removeClass("wpl-track-me",e),t.removeListener(e,"submit",this.formListener);var n=e.getAttribute("class");if(""!==n&&null!==n&&-1!=n.toLowerCase().indexOf("wpcf7-form"))return setTimeout(function(){document.body.style.cursor="default"},300),!0;e.submit(),setTimeout(function(){for(var t=0;t<e.elements.length;t++)formInput=e.elements[t],type=formInput.type||!1,"submit"===type&&"submit"===formInput.name&&e.elements[t].click()},2e3)},saveFormData:function(n){for(var i=i||{},r=0;r<n.elements.length;r++)if(formInput=n.elements[r],multiple=!1,formInput.name){if(formInput.dataset.ignoreFormField){e.deBugger("forms","ignore "+formInput.name);continue}switch(inputName=formInput.name.replace(/\[([^\[]*)\]/g,"%5B%5D$1"),i[inputName]||(i[inputName]={}),formInput.type&&(i[inputName].type=formInput.type),i[inputName].name||(i[inputName].name=formInput.name),formInput.dataset.mapFormField&&(i[inputName].map=formInput.dataset.mapFormField),formInput.nodeName){case"INPUT":if(!1===(l=this.getInputValue(formInput)))continue;break;case"TEXTAREA":l=formInput.value;break;case"SELECT":if(formInput.multiple){values=[],multiple=!0;for(var s=0;s<formInput.length;s++)formInput[s].selected&&values.push(encodeURIComponent(formInput[s].value))}else l=formInput.value}if(e.deBugger("forms","Input Value = "+l),l){i[inputName].value||(i[inputName].value=[]),i[inputName].value.push(multiple?values.join(","):encodeURIComponent(l));var l=multiple?values.join(","):encodeURIComponent(l)}}e.deBugger("forms",i);for(var u in i){var d=i[u].value,c=i[u].map;if(void 0!==d&&null!=d&&""!=d&&o.push(u+"="+i[u].value.join(",")),void 0!==c&&null!=c&&i[u].value&&(a.push(c+"="+i[u].value.join(",")),"email"===u))var m=i[u].value.join(",")}var f=o.join("&");e.deBugger("forms","Stringified Raw Form PARAMS: "+f);var g=a.join("&");e.deBugger("forms","Stringified Mapped PARAMS"+g),(m=t.getParameterVal("email",g)||t.readCookie("wp_lead_email"))||(m=t.getParameterVal("wpleads_email_address",g));var p=t.getParameterVal("name",g),h=t.getParameterVal("first_name",g),v=t.getParameterVal("last_name",g);if(!v&&h&&(_=decodeURI(h).split(" ")).length>0&&(h=_[0],v=_[1]),p&&!v&&!h){var _=decodeURI(p).split(" ");_.length>0&&(h=_[0],v=_[1])}p=h&&v?h+" "+v:p,h||(h=""),v||(v=""),e.deBugger("forms","fName = "+h),e.deBugger("forms","lName = "+v),e.deBugger("forms","fullName = "+p);var b=e.totalStorage("page_views")||{},y=e.totalStorage("inbound_url_params")||{},w=n.querySelectorAll('input[value][type="hidden"][name="inbound_furl"]:not([value=""])'),k=!1;if(0==w.length||"IA=="==w[0].value)k=!0;var S=n.querySelectorAll('input[value][type="hidden"][name="inbound_form_id"]');S=S.length>0?S[0].value:0;if("undefined"!=typeof landing_path_info)C=landing_path_info.variation;else if("undefined"!=typeof cta_path_info)C=cta_path_info.variation;else var C=inbound_settings.variation_id;var I=inbound_settings.post_type||"page",L=inbound_settings.post_id||0;search_data={},formData={action:"inbound_lead_store",email:m,full_name:p,first_name:h,last_name:v,raw_params:f,mapped_params:g,url_params:JSON.stringify(y),search_data:"test",page_views:JSON.stringify(b),post_type:I,page_id:L,variation:C,source:t.readCookie("inbound_referral_site"),inbound_submitted:k,inbound_form_id:S,inbound_nonce:inbound_settings.ajax_nonce,event:n},callback=function(o){e.deBugger("forms","Lead Created with ID: "+o),o=parseInt(o,10),formData.leadID=o,o&&(t.createCookie("wp_lead_id",o),e.totalStorage.deleteItem("page_views"),e.totalStorage.deleteItem("tracking_events")),e.trigger("form_after_submission",formData),e.Forms.releaseFormSubmit(n)},e.trigger("form_before_submission",formData),t.ajaxPost(inbound_settings.admin_url,formData,callback)},saveSearchData:function(n){for(var o=o||{},i=0;i<n.elements.length;i++)if(formInput=n.elements[i],multiple=!1,formInput.name){if(formInput.dataset.ignoreFormField){e.deBugger("searches","ignore "+formInput.name);continue}switch(inputName=formInput.name.replace(/\[([^\[]*)\]/g,"%5B%5D$1"),o[inputName]||(o[inputName]={}),formInput.type&&(o[inputName].type=formInput.type),o[inputName].name||(o[inputName].name=formInput.name),formInput.dataset.mapFormField&&(o[inputName].map=formInput.dataset.mapFormField),formInput.nodeName){case"INPUT":if(!1===(r=this.getInputValue(formInput)))continue;break;case"TEXTAREA":r=formInput.value;break;case"SELECT":if(formInput.multiple){values=[],multiple=!0;for(var a=0;a<formInput.length;a++)formInput[a].selected&&values.push(encodeURIComponent(formInput[a].value))}else r=formInput.value}if(e.deBugger("searches","Input Value = "+r),r){o[inputName].value||(o[inputName].value=[]),o[inputName].value.push(multiple?values.join(","):encodeURIComponent(r));var r=multiple?values.join(","):encodeURIComponent(r)}}e.deBugger("searches",o);var s=[];for(var l in o){var u=o[l].value,d=o[l].type;void 0!==u&&null!=u&&""!=u&&"search"==d&&s.push("search_text|value|"+o[l].value)}if(s[0]){var c=s.join("|field|");if(e.deBugger("searches","Stringified Search Form PARAMS: "+c),"undefined"!=typeof landing_path_info)m=landing_path_info.variation;else if("undefined"!=typeof cta_path_info)m=cta_path_info.variation;else var m=inbound_settings.variation_id;var f=inbound_settings.post_type||"page",g=inbound_settings.post_id||0,p=t.readCookie("wp_lead_uid");inbound_settings.wp_lead_data.lead_email?email=inbound_settings.wp_lead_data.lead_email:t.readCookie("inbound_wpleads_email_address")?email=t.readCookie("inbound_wpleads_email_address"):email="",searchData={email:email,search_data:c,user_UID:p,post_type:f,page_id:g,variation:m,source:t.readCookie("inbound_referral_site"),ip_address:inbound_settings.ip_address,timestamp:Math.floor((new Date).getTime()/1e3)},e.trigger("search_before_caching",searchData),inbound_settings.wp_lead_data.lead_id?(searchData.lead_id=inbound_settings.wp_lead_data.lead_id,t.cacheSearchData(searchData,n)):t.cacheSearchData(searchData,n)}},rememberInputValues:function(n){n.name&&n.name;var o=n.type?n.type:"text";if("submit"===o||"hidden"===o||"file"===o||"password"===o||n.dataset.ignoreFormField)return!1;t.addListener(n,"change",function(n){if(n.target.name){if("checkbox"!==o)var i=n.target.value;else for(var a=[],r=document.querySelectorAll('input[name="'+n.target.name+'"]'),s=0;s<r.length;s++)r[s].checked&&a.push(r[s].value),i=a.join(",");inputData={name:n.target.name,node:n.target.nodeName.toLowerCase(),type:o,value:i,mapping:n.target.dataset.mapFormField},e.trigger("form_input_change",inputData),t.createCookie("inbound_"+n.target.name,encodeURIComponent(i))}})},fillInputValues:function(e){var n=e.name?"inbound_"+e.name:"",o=e.type?e.type:"text";if("submit"===o||"hidden"===o||"file"===o||"password"===o)return!1;if(t.readCookie(n)&&"comment"!=n)if(value=decodeURIComponent(t.readCookie(n)),"checkbox"===o||"radio"===o)for(var i=value.split(","),a=0;a<i.length;a++)e.value.indexOf(i[a])>-1&&(e.checked=!0);else"undefined"!==value&&(e.value=value)},getInputLabel:function(e){var t;return(t=this.siblingsIsLabel(e))?t:!!(t=this.CheckParentForLabel(e))&&t},getInputValue:function(e){var t=!1;switch(e.type){case"radio":case"checkbox":e.checked&&(t=e.value);break;case"text":case"hidden":default:t=e.value}return t},addDataAttr:function(e,t){for(var n=document.getElementsByName(e.name),o=n.length-1;o>=0;o--)e.dataset.mapFormField||(n[o].dataset.mapFormField=t)},removeArrayItem:function(e,t){if(e.indexOf)index=e.indexOf(t);else for(index=e.length-1;index>=0&&e[index]!==t;--index);index>=0&&e.splice(index,1)},siblingsIsLabel:function(e){for(var t=this.getSiblings(e),n=[],o=t.length-1;o>=0;o--)"label"===t[o].nodeName.toLowerCase()&&n.push(t[o]);return n.length>0&&n.length<2&&n},getChildren:function(e,t){for(var n=[];e;e=e.nextSibling)1==e.nodeType&&e!=t&&n.push(e);return n},getSiblings:function(e){return this.getChildren(e.parentNode.firstChild,e)},CheckParentForLabel:function(e){if("FORM"===e.nodeName)return null;do{var t=e.getElementsByTagName("label");if(t.length>0&&t.length<2)return e.getElementsByTagName("label")}while(e=e.parentNode);return null},mailCheck:function(){var e=document.querySelector(".inbound-email");e&&(t.addListener(e,"blur",this.mailCheck),u.run({email:document.querySelector(".inbound-email").value,suggested:function(n){var o=document.querySelector(".email_suggestion");o&&t.removeElement(o);var i=document.createElement("span");i.innerHTML="<span class=\"email_suggestion\">Did youu mean <b><i id='email_correction' style='cursor: pointer;' title=\"click to update\">"+n.full+"</b></i>?</span>",e.parentNode.insertBefore(i,e.nextSibling);var a=document.getElementById("email_correction");t.addListener(a,"click",function(){e.value=a.innerHTML,a.parentNode.parentNode.innerHTML="Fixed!"})},empty:function(){}}))}},void 0===u)var u={domainThreshold:1,topLevelThreshold:3,defaultDomains:["yahoo.com","google.com","hotmail.com","gmail.com","me.com","aol.com","mac.com","live.com","comcast.net","googlemail.com","msn.com","hotmail.co.uk","yahoo.co.uk","facebook.com","verizon.net","sbcglobal.net","att.net","gmx.com","mail.com","outlook.com","icloud.com"],defaultTopLevelDomains:["co.jp","co.uk","com","net","org","info","edu","gov","mil","ca","de"],run:function(e){e.domains=e.domains||u.defaultDomains,e.topLevelDomains=e.topLevelDomains||u.defaultTopLevelDomains,e.distanceFunction=e.distanceFunction||u.sift3Distance;var t=function(e){return e},n=e.suggested||t,o=e.empty||t,i=u.suggest(u.encodeEmail(e.email),e.domains,e.topLevelDomains,e.distanceFunction);return i?n(i):o()},suggest:function(e,t,n,o){e=e.toLowerCase();var i=this.splitEmail(e),a=this.findClosestDomain(i.domain,t,o,this.domainThreshold);if(a){if(a!=i.domain)return{address:i.address,domain:a,full:i.address+"@"+a}}else{var r=this.findClosestDomain(i.topLevelDomain,n,o,this.topLevelThreshold);if(i.domain&&r&&r!=i.topLevelDomain){var s=i.domain;return a=s.substring(0,s.lastIndexOf(i.topLevelDomain))+r,{address:i.address,domain:a,full:i.address+"@"+a}}}return!1},findClosestDomain:function(e,t,n,o){o=o||this.topLevelThreshold;var i,a=99,r=null;if(!e||!t)return!1;n||(n=this.sift3Distance);for(var s=0;s<t.length;s++){if(e===t[s])return e;(i=n(e,t[s]))<a&&(a=i,r=t[s])}return a<=o&&null!==r&&r},sift3Distance:function(e,t){if(null===e||0===e.length)return null===t||0===t.length?0:t.length;if(null===t||0===t.length)return e.length;for(var n=0,o=0,i=0,a=0;n+o<e.length&&n+i<t.length;){if(e.charAt(n+o)==t.charAt(n+i))a++;else{o=0,i=0;for(var r=0;r<5;r++){if(n+r<e.length&&e.charAt(n+r)==t.charAt(n)){o=r;break}if(n+r<t.length&&e.charAt(n)==t.charAt(n+r)){i=r;break}}}n++}return(e.length+t.length)/2-a},splitEmail:function(e){var t=e.trim().split("@");if(t.length<2)return!1;for(a=0;a<t.length;a++)if(""===t[a])return!1;var n=t.pop(),o=n.split("."),i="";if(0===o.length)return!1;if(1==o.length)i=o[0];else{for(var a=1;a<o.length;a++)i+=o[a]+".";o.length>=2&&(i=i.substring(0,i.length-1))}return{topLevelDomain:i,domain:n,address:t.join("@")}},encodeEmail:function(e){var t=encodeURI(e);return t=t.replace("%20"," ").replace("%25","%").replace("%5E","^").replace("%60","`").replace("%7B","{").replace("%7C","|").replace("%7D","}")}};return e}(_inbound||{}),_inboundEvents=function(e){function t(t,o,i){var o=o||{};(i=i||{}).bubbles=i.bubbles||!0,i.cancelable=i.cancelable||!0,o=e.apply_filters("filter_"+t,o);!window.ActiveXObject&&window;if("function"==typeof CustomEvent)var a=new CustomEvent(t,{detail:o,bubbles:i.bubbles,cancelable:i.cancelable});else(a=document.createEvent("Event")).initEvent(t,!0,!0);window.dispatchEvent(a),e.do_action(t,o),n(t,o)}function n(e,t){if(window.jQuery){var t=t||{};jQuery(document).trigger(e,t)}}e.trigger=function(t,n){e.Events[t](n)};return e.Events={analytics_ready:function(){t("analytics_ready",{data:"xyxy"},{opt1:!0})},url_parameters:function(e){t("url_parameters",e)},session_start:function(){console.log(""),t("session_start")},session_end:function(e){t("session_end",e),console.log("Session End")},session_active:function(){t("session_active")},session_idle:function(e){t("session_idle",e)},session_resume:function(){t("session_resume")},session_heartbeat:function(e){t("session_heartbeat",{clock:e,leadData:InboundLeadData})},page_visit:function(e){t("page_view",e)},page_first_visit:function(n){t("page_first_visit"),e.deBugger("pages","First Ever Page View of this Page")},page_revisit:function(n){t("page_revisit",n);e.deBugger("pages",status,function(){console.log("pageData",n),console.log("Page Revisit viewed "+n+" times")})},tab_hidden:function(n){e.deBugger("pages","Tab Hidden"),t("tab_hidden")},tab_visible:function(n){e.deBugger("pages","Tab Visible"),t("tab_visible")},tab_mouseout:function(n){e.deBugger("pages","Tab Mouseout"),t("tab_mouseout")},form_input_change:function(n){e.deBugger("forms","inputData change. Data=",function(){console.log(n)}),t("form_input_change",n)},form_before_submission:function(e){t("form_before_submission",e)},form_after_submission:function(e){t("form_after_submission",e)},search_before_caching:function(e){t("search_before_caching",e)},analyticsError:function(e,t,n){var o=new CustomEvent("inbound_analytics_error",{detail:{MLHttpRequest:e,textStatus:t,errorThrown:n}});window.dispatchEvent(o),console.log("Page Save Error")}},e}(_inbound||{});_inbound.add_action("form_before_submission",inboundFormNoRedirect,10),_inbound.add_action("form_after_submission",inboundFormNoRedirectContent,10);var InboundTotalStorage=function(e){var t,n;if("localStorage"in window)try{n=void 0===window.localStorage?void 0:window.localStorage,t=void 0!==n&&void 0!==window.JSON,window.localStorage.setItem("_inbound","1"),window.localStorage.removeItem("_inbound")}catch(e){t=!1}e.totalStorage=function(t,n,o){return e.totalStorage.impl.init(t,n)},e.totalStorage.setItem=function(t,n){return e.totalStorage.impl.setItem(t,n)},e.totalStorage.getItem=function(t){return e.totalStorage.impl.getItem(t)},e.totalStorage.getAll=function(){return e.totalStorage.impl.getAll()},e.totalStorage.deleteItem=function(t){return e.totalStorage.impl.deleteItem(t)},e.totalStorage.impl={init:function(e,t){return void 0!==t?this.setItem(e,t):this.getItem(e)},setItem:function(o,i){if(!t)try{return e.Utils.createCookie(o,i),i}catch(e){console.log("Local Storage not supported by this browser. Install the cookie plugin on your site to take advantage of the same functionality. You can get it at https://github.com/carhartl/jquery-cookie")}var a=JSON.stringify(i);return n.setItem(o,a),this.parseResult(a)},getItem:function(o){if(!t)try{return this.parseResult(e.Utils.readCookie(o))}catch(e){return null}var i=n.getItem(o);return this.parseResult(i)},deleteItem:function(o){if(!t)try{return e.Utils.eraseCookie(o,null),!0}catch(e){return!1}return n.removeItem(o),!0},getAll:function(){var o=[];if(t)for(var i in n)i.length&&o.push({key:i,value:this.parseResult(n.getItem(i))});else try{for(var a=document.cookie.split(";"),r=0;r<a.length;r++){var s=a[r].split("=")[0];o.push({key:s,value:this.parseResult(e.Utils.readCookie(s))})}}catch(e){return null}return o},parseResult:function(e){var t;try{void 0===(t=JSON.parse(e))&&(t=e),"true"==t&&(t=!0),"false"==t&&(t=!1),parseFloat(t)==t&&"object"!=typeof t&&(t=parseFloat(t))}catch(n){t=e}return t}}}(_inbound||{}),_inboundLeadsAPI=function(e){return e.LeadsAPI={init:function(){var t=e.Utils,n=(t.readCookie("wp_lead_uid"),t.readCookie("wp_lead_id"));t.readCookie("lead_session_expire")||(e.deBugger("leads","expired vistor. Run Processes"),n&&e.LeadsAPI.getAllLeadData())},setGlobalLeadData:function(e){InboundLeadData=e},getAllLeadData:function(t){var n=e.Utils.readCookie("wp_lead_id"),o=e.totalStorage("inbound_lead_data"),i=e.Utils.readCookie("lead_data_expire");data={action:"inbound_get_all_lead_data",wp_lead_id:n},success=function(t){var n=JSON.parse(t);e.LeadsAPI.setGlobalLeadData(n),e.totalStorage("inbound_lead_data",n);var o=new Date;o.setTime(o.getTime()+18e5);var i=e.Utils.addDays(o,3);e.Utils.createCookie("lead_data_expire",!0,i)},o?(e.LeadsAPI.setGlobalLeadData(o),e.deBugger("lead","Set Global Lead Data from Localstorage"),i||(e.Utils.ajaxPost(inbound_settings.admin_url,data,success),e.deBugger("lead","localized data old. Pull new from DB"))):e.Utils.ajaxPost(inbound_settings.admin_url,data,success)},getLeadLists:function(){var t={action:"wpl_check_lists",wp_lead_id:e.Utils.readCookie("wp_lead_id")};e.Utils.ajaxPost(inbound_settings.admin_url,t,function(t){e.Utils.createCookie("lead_session_list_check",!0,{path:"/",expires:1}),e.deBugger("lead","Lists checked")})}},e}(_inbound||{}),_inboundPageTracking=function(e){var t,n,o=!1,i=!1,a=!1,r=parseInt(e.Utils.readCookie("lead_session"),10)||0,s=0,l=(new Date,null),u=null,d=null,c=e.Utils,m=e.Utils.GetDate(),f="page_views",g=e.totalStorage(f)||{},p=inbound_settings.post_id||window.location.pathname,h=e.Settings.timeout||1e4;return e.PageTracking={init:function(o){this.CheckTimeOut(),o=o||{},t=parseInt(o.reportInterval,10)||10,n=parseInt(o.idleTimeout,10)||3,c.addListener(document,"keydown",c.throttle(e.PageTracking.pingSession,1e3)),c.addListener(document,"click",c.throttle(e.PageTracking.pingSession,1e3)),c.addListener(window,"mousemove",c.throttle(e.PageTracking.pingSession,1e3)),e.PageTracking.checkVisibility(),this.startSession()},setIdle:function(t){var n="Session IDLE. Activity Timeout due to "+(t=t||"No Movement");e.deBugger("pages",n),clearTimeout(e.PageTracking.idleTimer),e.PageTracking.stopClock(),e.trigger("session_idle")},checkVisibility:function(){var t,n;void 0!==document.hidden?(t="hidden",n="visibilitychange"):void 0!==document.mozHidden?(t="mozHidden",n="mozvisibilitychange"):void 0!==document.msHidden?(t="msHidden",n="msvisibilitychange"):void 0!==document.webkitHidden&&(t="webkitHidden",n="webkitvisibilitychange");var o=document[t];e.Utils.addListener(document,n,function(n){o!=document[t]&&(document[t]?(e.trigger("tab_hidden"),e.PageTracking.setIdle("browser tab switch")):(e.trigger("tab_visible"),e.PageTracking.pingSession()),o=document[t])})},clock:function(){var n="Total time spent on Page in this Session: "+((r+=1)/60).toFixed(2)+" min";if(e.deBugger("pages",n),r>0&&r%t==0){var o=new Date;o.setTime(o.getTime()+18e5),c.createCookie("lead_session",r,o),e.trigger("session_heartbeat",r)}},inactiveClock:function(){var t="Time until Session Timeout: "+((1800-(s+=1))/60).toFixed(2)+" min";e.deBugger("pages",t),s>1800&&(e.trigger("session_end",InboundLeadData),e.Utils.eraseCookie("lead_session"),s=0,clearTimeout(u))},stopClock:function(){i=!0,clearTimeout(l),clearTimeout(u),u=setInterval(e.PageTracking.inactiveClock,1e3)},restartClock:function(){i=!1,e.trigger("session_resume"),e.deBugger("pages","Activity resumed. Session Active"),clearTimeout(l),s=0,clearTimeout(u),l=setInterval(e.PageTracking.clock,1e3)},turnOff:function(){e.PageTracking.setIdle(),a=!0},turnOn:function(){a=!1},startSession:function(){new Date;if(o=!0,l=setInterval(e.PageTracking.clock,1e3),c.readCookie("lead_session"))e.trigger("session_active");else{e.trigger("session_start");var t=new Date;t.setTime(t.getTime()+18e5),e.Utils.createCookie("lead_session",1,t)}this.pingSession()},resetInactiveFunc:function(){s=0,clearTimeout(u)},pingSession:function(t){a||(o||e.PageTracking.startSession(),i&&e.PageTracking.restartClock(),clearTimeout(d),d=setTimeout(e.PageTracking.setIdle,1e3*n+100),void 0!==t&&"mousemove"===t.type&&e.PageTracking.mouseEvents(t))},mouseEvents:function(t){t.pageY<=5&&e.trigger("tab_mouseout")},getPageViews:function(){if(e.Utils.checkLocalStorage()){var t=localStorage.getItem(f),n=JSON.parse(t);return n}},isRevisit:function(e){var t=!1,n=(e=e||{})[p];return void 0!==n&&null!==n&&(t=!0),t},triggerPageView:function(t){var n={title:document.title,url:document.location.href,path:document.location.pathname,count:1};t?(g[p].push(m),n.count=g[p].length,e.trigger("page_revisit",n)):(g[p]=[],g[p].push(m),e.trigger("page_first_visit",n)),e.trigger("page_visit",n),e.totalStorage(f,g),this.storePageView()},CheckTimeOut:function(){var t,n=this.isRevisit(g);if(n){var o=g[p].length-1,i=g[p][o],a=Math.abs(new Date(i).getTime()-new Date(m).getTime());a>h?(t="Timeout Happened. Page view fired",this.triggerPageView(n)):(time_left=.001*Math.abs(h-a),t=h/1e3+" sec timeout not done: "+time_left+" seconds left")}else this.triggerPageView(n);e.deBugger("pages",t)},storePageView:function(){"off"==inbound_settings.page_tracking&&"landing-page"!=inbound_settings.post_type||document.addEventListener("DOMContentLoaded",function(){setTimeout(function(){var t=e.Utils.readCookie("wp_lead_id")?e.Utils.readCookie("wp_lead_id"):"",n=e.Utils.readCookie("wp_lead_uid")?e.Utils.readCookie("wp_lead_uid"):"",o=e.totalStorage("wp_cta_loaded"),i=e.totalStorage("wp_cta_impressions");e.totalStorage("wp_cta_impressions",{});var a={action:"inbound_track_lead",wp_lead_uid:n,wp_lead_id:t,page_id:inbound_settings.post_id,variation_id:inbound_settings.variation_id,post_type:inbound_settings.post_type,current_url:window.location.href,page_views:JSON.stringify(e.PageTracking.getPageViews()),cta_impressions:JSON.stringify(i),cta_history:JSON.stringify(o),json:"0"};e.Utils.ajaxPost(inbound_settings.admin_url,a,function(e){})},200)})}},e}(_inbound||{});_inbound.init(),InboundLeadData=_inbound.totalStorage("inbound_lead_data")||null;
|
1 |
+
/*! Inbound Analyticsv1.0.0 | (c) 2017 Inbound Now | https://github.com/inboundnow/cta */
|
2 |
+
function inboundFormNoRedirect(){if(null==window.frames.frameElement)e=document.querySelectorAll("button.inbound-button-submit[disabled]")[0];else if("iframe"==window.frames.frameElement.tagName.toLowerCase())var e=window.frames.frameElement.contentWindow.document.querySelectorAll("button.inbound-button-submit")[0];if(void 0!==e){var t=e.form,n=t.querySelectorAll('input[value][type="hidden"][name="inbound_furl"]:not([value=""])');0!=n.length&&"IA=="!=n[0].value||(t.action="javascript:void(0)")}}function inboundFormNoRedirectContent(){if(null==window.frames.frameElement)e=document.querySelectorAll("button.inbound-button-submit[disabled]")[0];else if("iframe"==window.frames.frameElement.tagName.toLowerCase())var e=window.frames.frameElement.contentWindow.document.querySelectorAll("button.inbound-button-submit")[0];if(void 0!==e){var t=e.form.querySelectorAll('input[value][type="hidden"][name="inbound_furl"]:not([value=""])'),n=jQuery(e).css("background"),o=jQuery(e).css("color"),i=jQuery(e).css("height"),a=e.getElementsByClassName("inbound-form-spinner");0!=t.length&&"IA=="!=t[0].value||(jQuery(a).remove(),jQuery(e).prepend('<div id="redir-check"><i class="fa fa-check-square" aria-hidden="true" style="background='+n+"; color="+o+"; font-size:calc("+i+' * .42);"></i></div>'))}}var inbound_data=inbound_data||{},_inboundOptions=_inboundOptions||{},_gaq=_gaq||[],_inbound=function(e){var t={timeout:inbound_settings.is_admin?500:1e4,formAutoTracking:!0,formAutoPopulation:!0},n={init:function(){_inbound.Utils.init(),_inbound.Utils.domReady(window,function(){_inbound.DomLoaded()})},DomLoaded:function(){_inbound.PageTracking.init(),_inbound.Forms.init(),_inbound.Utils.setUrlParams(),_inbound.LeadsAPI.init(),setTimeout(function(){_inbound.Forms.init()},2e3),_inbound.trigger("analytics_ready")},extend:function(e,t){var n,o={};for(n in e)Object.prototype.hasOwnProperty.call(e,n)&&(o[n]=e[n]);for(n in t)Object.prototype.hasOwnProperty.call(t,n)&&(o[n]=t[n]);return o},debug:function(e,t){},deBugger:function(e,t,n){if(console){var o,i,a,r=document.location.hash?document.location.hash:"",s=r.indexOf("#debug")>-1,t=t||!1;r&&r.match(/debug/)&&(a=(r=r.split("-"))[1]),i="true"===_inbound.Utils.readCookie("inbound_debug"),((o="true"===_inbound.Utils.readCookie("inbound_debug_"+e))||s||i)&&(t&&"string"==typeof t&&(i||"all"===a?console.log('logAll "'+e+'" =>',t):o?console.log('log "'+e+'" =>',t):e===a&&console.log('#log "'+e+'" =>',t)),n&&n instanceof Function&&n())}}},o=n.extend(t,e);return n.Settings=o||{},n}(_inboundOptions),_inboundHooks=function(e){return e.hooks=new function(){function e(e,t,n,o){if(a[e][t])if(n){var i,r=a[e][t];if(o)for(i=r.length;i--;){var s=r[i];s.callback===n&&s.context===o&&r.splice(i,1)}else for(i=r.length;i--;)r[i].callback===n&&r.splice(i,1)}else a[e][t]=[]}function t(e,t,o,i,r){var s={callback:o,priority:i,context:r},l=a[e][t];l?(l.push(s),l=n(l)):l=[s],a[e][t]=l}function n(e){for(var t,n,o,i=1,a=e.length;i<a;i++){for(t=e[i],n=i;(o=e[n-1])&&o.priority>t.priority;)e[n]=e[n-1],--n;e[n]=t}return e}function o(e,t,n){var o=a[e][t];if(!o)return"filters"===e&&n[0];var i=0,r=o.length;if("filters"===e)for(;i<r;i++)n[0]=o[i].callback.apply(o[i].context,n);else for(;i<r;i++)o[i].callback.apply(o[i].context,n);return"filters"!==e||n[0]}var i={removeFilter:function(t,n){return"string"==typeof t&&e("filters",t,n),i},applyFilters:function(){var e=Array.prototype.slice.call(arguments),t=e.shift();return"string"==typeof t?o("filters",t,e):i},addFilter:function(e,n,o,a){return"string"==typeof e&&"function"==typeof n&&t("filters",e,n,o=parseInt(o||10,10)),i},removeAction:function(t,n){return"string"==typeof t&&e("actions",t,n),i},doAction:function(){var e=Array.prototype.slice.call(arguments),t=e.shift();return"string"==typeof t&&o("actions",t,e),i},addAction:function(e,n,o,a){return"string"==typeof e&&"function"==typeof n&&t("actions",e,n,o=parseInt(o||10,10),a),i}},a={actions:{},filters:{}};return i},e.add_action=function(){var t=arguments[0].split(" ");for(k in t)arguments[0]="inbound."+t[k],e.hooks.addAction.apply(this,arguments);return this},e.remove_action=function(){return arguments[0]="inbound."+arguments[0],e.hooks.removeAction.apply(this,arguments),this},e.do_action=function(){return arguments[0]="inbound."+arguments[0],e.hooks.doAction.apply(this,arguments),this},e.add_filter=function(){return arguments[0]="inbound."+arguments[0],e.hooks.addFilter.apply(this,arguments),this},e.remove_filter=function(){return arguments[0]="inbound."+arguments[0],e.hooks.removeFilter.apply(this,arguments),this},e.apply_filters=function(){return arguments[0]="inbound."+arguments[0],e.hooks.applyFilters.apply(this,arguments)},e}(_inbound||{}),_inboundUtils=function(e){var t,n=window.XMLHttpRequest&&"withCredentials"in new XMLHttpRequest,o=(Object.prototype.toString,{api_host:("https:"==location.protocol?"https://":"http://")+location.hostname+location.pathname.replace(/\/$/,""),track_pageview:!0,track_links_timeout:300,cookie_name:"_sp",cookie_expiration:365,cookie_domain:(host=location.hostname.match(/[a-z0-9][a-z0-9\-]+\.[a-z\.]{2,6}$/i))?host[0]:""});return e.Utils={init:function(){this.polyFills(),this.checkLocalStorage(),this.SetUID(),this.storeReferralData()},polyFills:function(){window.console||(window.console={});for(var e=["log","info","warn","error","debug","trace","dir","group","groupCollapsed","groupEnd","time","timeEnd","profile","profileEnd","dirxml","assert","count","markTimeline","timeStamp","clear"],t=0;t<e.length;t++)window.console[e[t]]||(window.console[e[t]]=function(){});Date.prototype.toISOString||function(){function e(e){var t=String(e);return 1===t.length&&(t="0"+t),t}Date.prototype.toISOString=function(){return this.getUTCFullYear()+"-"+e(this.getUTCMonth()+1)+"-"+e(this.getUTCDate())+"T"+e(this.getUTCHours())+":"+e(this.getUTCMinutes())+":"+e(this.getUTCSeconds())+"."+String((this.getUTCMilliseconds()/1e3).toFixed(3)).slice(2,5)+"Z"}}();try{new CustomEvent("?")}catch(e){this.CustomEvent=function(e,t){function n(t,n,o,i){this["init"+e](t,n,o,i),"detail"in this||(this.detail=i)}return function(o,i){var a=document.createEvent(e);return null!==o?n.call(a,o,(i||(i=t)).bubbles,i.cancelable,i.detail):a.initCustomEvent=n,a}}(this.CustomEvent?"CustomEvent":"Event",{bubbles:!1,cancelable:!1,detail:null})}document.querySelectorAll||(document.querySelectorAll=function(e){var t,n=document.createElement("style"),o=[];for(document.documentElement.firstChild.appendChild(n),document._qsa=[],n.styleSheet.cssText=e+"{x-qsa:expression(document._qsa && document._qsa.push(this))}",window.scrollBy(0,0),n.parentNode.removeChild(n);document._qsa.length;)(t=document._qsa.shift()).style.removeAttribute("x-qsa"),o.push(t);return document._qsa=null,o}),document.querySelector||(document.querySelector=function(e){var t=document.querySelectorAll(e);return t.length?t[0]:null}),!("innerText"in document.createElement("a"))&&"getSelection"in window&&HTMLElement.prototype.__defineGetter__("innerText",function(){for(var e,t=window.getSelection(),n=[],o=0;o<t.rangeCount;o++)n[o]=t.getRangeAt(o);t.removeAllRanges(),t.selectAllChildren(this),e=t.toString(),t.removeAllRanges();for(o=0;o<n.length;o++)t.addRange(n[o]);return e})},createCookie:function(e,t,n){var o="";if(n){var i=new Date;i.setTime(i.getTime()+24*n*60*60*1e3),o="; expires="+i.toGMTString()}document.cookie=e+"="+t+o+"; path=/"},readCookie:function(e){for(var t=e+"=",n=document.cookie.split(";"),o=0;o<n.length;o++){for(var i=n[o];" "===i.charAt(0);)i=i.substring(1,i.length);if(0===i.indexOf(t))return i.substring(t.length,i.length)}return null},eraseCookie:function(e){this.createCookie(e,"",-1)},getAllCookies:function(){var t={};if(document.cookie&&""!==document.cookie)for(var n=document.cookie.split(";"),o=0;o<n.length;o++){var i=n[o].split("=");i[0]=i[0].replace(/^ /,""),t[decodeURIComponent(i[0])]=decodeURIComponent(i[1])}return e.totalStorage("inbound_cookies",t),t},setUrlParams:function(){var n={};!function(){for(var e,t=function(e){return decodeURIComponent(e).replace(/\+/g," ")},o=window.location.search.substring(1),i=/([^&=]+)=?([^&]*)/g;e=i.exec(o);)if("-1"==e[1].indexOf("["))n[t(e[1])]=t(e[2]);else{var a=e[1].indexOf("["),r=e[1].slice(a+1,e[1].indexOf("]",a)),s=t(e[1].slice(0,a));"object"!=typeof n[s]&&(n[t(s)]={},n[t(s)].length=0),r?n[t(s)][t(r)]=t(e[2]):Array.prototype.push.call(n[t(s)],t(e[2]))}}();for(var o in n)if("action"!=o)if("object"==typeof n[o])for(var i in n[o])this.createCookie(i,n[o][i],30);else this.createCookie(o,n[o],30);if(t){var a=e.totalStorage("inbound_url_params")||{},r=this.mergeObjs(a,n);e.totalStorage("inbound_url_params",r)}var s={option1:"yo",option2:"woooo"};e.trigger("url_parameters",n,s)},getAllUrlParams:function(){n={};if(t)var n=e.totalStorage("inbound_url_params");return n},getParameterVal:function(e,t){return(RegExp(e+"=(.+?)(&|$)").exec(t)||[,!1])[1]},checkLocalStorage:function(){if("localStorage"in window)try{ls=void 0===window.localStorage?void 0:window.localStorage,t="undefined"!=typeof ls&&void 0!==window.JSON}catch(e){t=!1}return t},showLocalStorageSize:function(){function e(e){return 2*e.length}function t(e){return e/1024/1024}var n=Object.keys(localStorage).map(function(t){return{name:t,size:e(localStorage[t])}}).map(function(e){return e.size=t(e.size).toFixed(2)+" MB",e});console.table(n)},addDays:function(e,t){return new Date(e.getTime()+24*t*60*60*1e3)},GetDate:function(){var e=new Date,t=e.getDate(),n=t<10?"0":"",o=e.getFullYear(),i=e.getHours(),a=i<10?"0":"",r=e.getMinutes(),s=r<10?"0":"",l=e.getSeconds(),u=l<10?"0":"",d=e.getMonth()+1;return o+"/"+(d<10?"0":"")+d+"/"+n+t+" "+a+i+":"+s+r+":"+u+l},SetSessionTimeout:function(){this.readCookie("lead_session_expire");var e=new Date;e.setTime(e.getTime()+18e5),this.createCookie("lead_session_expire",!0,e)},storeReferralData:function(){var t=new Date,n=document.referrer||"Direct Traffic",o=e.Utils.readCookie("inbound_referral_site"),i=e.totalStorage("inbound_original_referral");t.setTime(t.getTime()+18e5),o||this.createCookie("inbound_referral_site",n,t),i||e.totalStorage("inbound_original_referral",i)},CreateUID:function(e){var t="0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz".split(""),n="";e||(e=Math.floor(Math.random()*t.length));for(var o=0;o<e;o++)n+=t[Math.floor(Math.random()*t.length)];return n},generateGUID:function(e){return e?(e^16*Math.random()>>e/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,guid)},SetUID:function(e){if(!this.readCookie("wp_lead_uid")){var t=e||this.CreateUID(35);this.createCookie("wp_lead_uid",t)}},countProperties:function(e){var t=0;for(var n in e)e.hasOwnProperty(n)&&++t;return t},mergeObjs:function(e,t){var n={};for(var o in e)n[o]=e[o];for(var o in t)n[o]=t[o];return n},hasClass:function(e,t){if("classList"in document.documentElement)n=t.classList.contains(e);else var n=new RegExp("(^|\\s)"+e+"(\\s|$)").test(t.className);return n},addClass:function(e,t){"classList"in document.documentElement?t.classList.add(e):this.hasClass(t,e)||(t.className+=(t.className?" ":"")+e)},removeClass:function(e,t){"classList"in document.documentElement?t.classList.remove(e):this.hasClass(t,e)&&(t.className=t.className.replace(new RegExp("(^|\\s)*"+e+"(\\s|$)*","g"),""))},removeElement:function(e){e.parentNode.removeChild(e)},trim:function(e){return e=e.replace(/(^\s*)|(\s*$)/gi,""),e=e.replace(/[ ]{2,}/gi," "),e=e.replace(/\n /,"\n")},ajaxPolyFill:function(){if("undefined"!=typeof XMLHttpRequest)return new XMLHttpRequest;for(var e,t=["MSXML2.XmlHttp.5.0","MSXML2.XmlHttp.4.0","MSXML2.XmlHttp.3.0","MSXML2.XmlHttp.2.0","Microsoft.XmlHttp"],n=0;n<t.length;n++)try{e=new ActiveXObject(t[n]);break}catch(e){}return e},ajaxSendData:function(e,t,n,o,i){var a=this.ajaxPolyFill();setTimeout(function(){a.open(n,e,!0),a.onreadystatechange=function(){4==a.readyState&&t(a.responseText)},"POST"==n&&a.setRequestHeader("Content-type","application/x-www-form-urlencoded"),a.send(o)},100)},ajaxGet:function(e,t,n,o){var i=[];for(var a in t)i.push(encodeURIComponent(a)+"="+encodeURIComponent(t[a]));this.ajaxSendData(e+"?"+i.join("&"),n,"GET",null,o)},ajaxPost:function(e,t,n,o){var i=[];for(var a in t)i.push(encodeURIComponent(a)+"="+encodeURIComponent(t[a]));this.ajaxSendData(e,n,"POST",i.join("&"),o)},sendEvent:function(e,t,i){t=t||{},async=!0;var a=getCookie();if(a){var r;for(r in a)t[r]=a[r]}t.id||(t.id=getId());var s={e:e,t:(new Date).toISOString(),kv:t},l=o.api_host+"/track?data="+encodeURIComponent(JSON.stringify(s));if(n){var u=new XMLHttpRequest;u.open("GET",l,async),u.withCredentials=async,u.send(null)}else{var d=document.createElement("script");d.type="text/javascript",d.async=async,d.defer=async,d.src=l;var c=document.getElementsByTagName("script")[0];c.parentNode.insertBefore(d,c)}return action(i),self},domReady:function(e,t){var n=!1,o=!0,i=e.document,a=i.documentElement,r=i.addEventListener?"addEventListener":"attachEvent",s=i.addEventListener?"removeEventListener":"detachEvent",l=i.addEventListener?"":"on",u=function(o){"readystatechange"==o.type&&"complete"!=i.readyState||(("load"==o.type?e:i)[s](l+o.type,u,!1),!n&&(n=!0)&&t.call(e,o.type||o))},d=function(){try{a.doScroll("left")}catch(e){return void setTimeout(d,50)}u("poll")};if("complete"==i.readyState)t.call(e,"lazy");else{if(i.createEventObject&&a.doScroll){try{o=!e.frameElement}catch(e){}o&&d()}i[r](l+"DOMContentLoaded",u,!1),i[r](l+"readystatechange",u,!1),e[r](l+"load",u,!1)}},addListener:function(e,t,n){e&&(e.addEventListener?e.addEventListener(t,n,!1):e.attachEvent?e.attachEvent("on"+t,n):e["on"+t]=n)},removeListener:function(e,t,n){e.removeEventListener?e.removeEventListener(t,n,!1):e.detachEvent?e.detachEvent("on"+t,n):e["on"+t]=null},throttle:function(e,t){var n,o,i,a=null,r=0,s=function(){r=new Date,a=null,i=e.apply(n,o)};return function(){var l=new Date;r||(r=l);var u=t-(l-r);return n=this,o=arguments,u<=0?(clearTimeout(a),a=null,r=l,i=e.apply(n,o)):a||(a=setTimeout(s,u)),i}},checkTypeofGA:function(){"function"==typeof ga&&(universalGA=!0),void 0!==_gaq&&"function"==typeof _gaq.push&&(classicGA=!0),"undefined"!=typeof dataLayer&&"function"==typeof dataLayer.push&&(googleTagManager=!0)},cacheSearchData:function(n,o){if(t){var i=e.totalStorage.getItem("inbound_search_storage");if(i)i.unshift(n),e.totalStorage.setItem("inbound_search_storage",i);else{var a=[n];e.totalStorage.setItem("inbound_search_storage",a)}}else{var r=JSON.stringify(n),s=this.readCookie("inbound_search_storage");s&&(r+="SPLIT-TOKEN"+s),this.createCookie("inbound_search_storage",r,"180")}e.Forms.releaseFormSubmit(o)},storeSearchData:function(){if(inbound_settings.wp_lead_data.lead_id&&inbound_settings.wp_lead_data.lead_nonce){var t=[],n=e.totalStorage.getItem("inbound_search_storage"),o=this.readCookie("inbound_search_storage");if(n||o){if(o){o=o.split("SPLIT-TOKEN");for(var i in o)t.push(JSON.parse(o[i]))}n&&(t=t.concat(n)),t.sort(function(e,t){return e.timestamp-t.timestamp});var a={action:"inbound_search_store",data:t=encodeURIComponent(JSON.stringify(t)),nonce:inbound_settings.wp_lead_data.lead_nonce,lead_id:inbound_settings.wp_lead_data.lead_id};callback=function(t){t&&(t=JSON.parse(t)),t.success&&(console.log(t.success),e.Utils.eraseCookie("inbound_search_storage"),e.totalStorage.deleteItem("inbound_search_storage")),t.error&&console.log(t.error)},this.ajaxPost(inbound_settings.admin_url,a,callback)}}}},e}(_inbound||{}),InboundForms=function(e){var t=e.Utils,n=[],o=[],a=[],r={},s=e.Settings,l=["first name","last name","name","email","e-mail","phone","website","job title","your favorite food","company","tele","address","comment"];if(e.Forms={init:function(){e.Forms.runFieldMappingFilters(),e.Forms.formTrackInit(),e.Forms.searchTrackInit()},runFieldMappingFilters:function(){l=e.hooks.applyFilters("forms.field_map",l)},debug:function(e,t){return},formTrackInit:function(){for(var e=0;e<window.document.forms.length;e++){var t=window.document.forms[e];t.dataset.formProcessed||(t.dataset.formProcessed=!0,this.checkTrackStatus(t)&&(this.attachFormSubmitEvent(t),this.initFormMapping(t)))}},searchTrackInit:function(){if("off"!=inbound_settings.search_tracking&&!r.searchTrackInit){for(var e=0;e<window.document.forms.length;e++){var n=window.document.forms[e];n.dataset.searchChecked||(n.dataset.searchChecked=!0,this.checkSearchTrackStatus(n)&&this.attachSearchFormSubmitEvent(n))}t.storeSearchData(),r.searchTrackInit=!0}},checkTrackStatus:function(t){var n=t.getAttribute("class");if(""!==n&&null!==n)return n.toLowerCase().indexOf("wpl-track-me")>-1||(n.toLowerCase().indexOf("inbound-track")>-1||(cb=function(){console.log(t)},e.deBugger("forms","This form not tracked. Please assign on in settings...",cb),!1))},checkSearchTrackStatus:function(t){var n=t.getAttribute("class"),o=t.getAttribute("id");return""!==n&&null!==n&&n.toLowerCase().indexOf("search")>-1||(""===o||null===o?(cb=function(){console.log(t)},e.deBugger("searches","This search form is not tracked. Please assign on in settings...",cb),!1):o.toLowerCase().indexOf("search")>-1||void 0)},loopClassSelectors:function(n,o){for(var i=n.length-1;i>=0;i--){var a=t.trim(n[i]);-1===a.indexOf("#")&&-1===a.indexOf(".")&&(a="#"+a),(a=document.querySelector(a))&&("add"===o?(e.Utils.addClass("wpl-track-me",a),e.Utils.addClass("inbound-track",a)):(e.Utils.removeClass("wpl-track-me",a),e.Utils.removeClass("inbound-track",a)))}},initFormMapping:function(t){for(var n=[],o=0;o<t.elements.length;o++)formInput=t.elements[o],"hidden"!==formInput.type?(this.mapField(formInput),this.rememberInputValues(formInput),s.formAutoPopulation&&!e.Utils.hasClass("nopopulate",t)&&this.fillInputValues(formInput)):n.push(formInput);for(var i=n.length-1;i>=0;i--)formInput=n[i],this.mapField(formInput)},mapField:function(o){var a=o.id||!1,r=o.name||!1,s=this.getInputLabel(o);if(s&&this.ignoreFieldByLabel(s[0].innerText))return o.dataset.ignoreFormField=!0,!1;for(i=0;i<l.length;i++){var u=!1,d=l[i],c=t.trim(d),m=c.replace(/ /g,"_");r&&r.toLowerCase().indexOf(c)>-1?(u=!0,e.deBugger("forms","Found matching name attribute for -> "+c)):a&&a.toLowerCase().indexOf(c)>-1?(u=!0,e.deBugger("forms","Found matching ID attribute for ->"+c)):s?s[0].innerText.toLowerCase().indexOf(c)>-1&&(u=!0,e.deBugger("forms","Found matching sibling label for -> "+c)):n.push(c),u&&(this.addDataAttr(o,m),this.removeArrayItem(l,c),i--)}return inbound_data},formListener:function(t){t.preventDefault(),e.Forms.saveFormData(t.target),document.body.style.cursor="wait"},searchFormListener:function(t){t.preventDefault(),e.Forms.saveSearchData(t.target)},attachFormSubmitEvent:function(e){t.addListener(e,"submit",this.formListener);document.querySelector(".inbound-email")},attachSearchFormSubmitEvent:function(e){t.addListener(e,"submit",this.searchFormListener)},ignoreFieldByLabel:function(t){var n=!1;return!!t&&(-1==t.toLowerCase().indexOf("credit card")&&-1==t.toLowerCase().indexOf("card number")||(n=!0),-1==t.toLowerCase().indexOf("expiration")&&-1==t.toLowerCase().indexOf("expiry")||(n=!0),"month"!=t.toLowerCase()&&"mm"!=t.toLowerCase()&&"yy"!=t.toLowerCase()&&"yyyy"!=t.toLowerCase()&&"year"!=t.toLowerCase()||(n=!0),-1==t.toLowerCase().indexOf("cvv")&&-1==t.toLowerCase().indexOf("cvc")&&-1==t.toLowerCase().indexOf("secure code")&&-1==t.toLowerCase().indexOf("security code")||(n=!0),n&&e.deBugger("forms","ignore "+t),n)},ignoreFieldByValue:function(e){var t=!1;if(!e)return!1;if("visa"!=e.toLowerCase()&&"mastercard"!=e.toLowerCase()&&"american express"!=e.toLowerCase()&&"amex"!=e.toLowerCase()&&"discover"!=e.toLowerCase()||(t=!0),new RegExp("/^[0-9]+$/").test(e)){var n=e.replace(" ","");this.isInt(n)&&n.length>=16&&(t=!0)}return t},isInt:function(e){return"number"==typeof e&&isFinite(e)&&e%1==0},releaseFormSubmit:function(e){document.body.style.cursor="default",t.removeClass("wpl-track-me",e),t.removeListener(e,"submit",this.formListener);var n=e.getAttribute("class");if(""!==n&&null!==n&&-1!=n.toLowerCase().indexOf("wpcf7-form"))return setTimeout(function(){document.body.style.cursor="default"},300),!0;e.submit(),setTimeout(function(){for(var t=0;t<e.elements.length;t++)formInput=e.elements[t],type=formInput.type||!1,"submit"===type&&"submit"===formInput.name&&e.elements[t].click()},2e3)},saveFormData:function(n){for(var i=i||{},r=0;r<n.elements.length;r++)if(formInput=n.elements[r],multiple=!1,formInput.name){if(formInput.dataset.ignoreFormField){e.deBugger("forms","ignore "+formInput.name);continue}switch(inputName=formInput.name.replace(/\[([^\[]*)\]/g,"%5B%5D$1"),i[inputName]||(i[inputName]={}),formInput.type&&(i[inputName].type=formInput.type),i[inputName].name||(i[inputName].name=formInput.name),formInput.dataset.mapFormField&&(i[inputName].map=formInput.dataset.mapFormField),formInput.nodeName){case"INPUT":if(!1===(l=this.getInputValue(formInput)))continue;break;case"TEXTAREA":l=formInput.value;break;case"SELECT":if(formInput.multiple){values=[],multiple=!0;for(var s=0;s<formInput.length;s++)formInput[s].selected&&values.push(encodeURIComponent(formInput[s].value))}else l=formInput.value}if(e.deBugger("forms","Input Value = "+l),l){i[inputName].value||(i[inputName].value=[]),i[inputName].value.push(multiple?values.join(","):encodeURIComponent(l));var l=multiple?values.join(","):encodeURIComponent(l)}}e.deBugger("forms",i);for(var u in i){var d=i[u].value,c=i[u].map;if(void 0!==d&&null!=d&&""!=d&&o.push(u+"="+i[u].value.join(",")),void 0!==c&&null!=c&&i[u].value&&(a.push(c+"="+i[u].value.join(",")),"email"===u))var m=i[u].value.join(",")}var f=o.join("&");e.deBugger("forms","Stringified Raw Form PARAMS: "+f);var g=a.join("&");e.deBugger("forms","Stringified Mapped PARAMS"+g),(m=t.getParameterVal("email",g)||t.readCookie("wp_lead_email"))||(m=t.getParameterVal("wpleads_email_address",g));var p=t.getParameterVal("name",g),h=t.getParameterVal("first_name",g),v=t.getParameterVal("last_name",g);if(!v&&h&&(_=decodeURI(h).split(" ")).length>0&&(h=_[0],v=_[1]),p&&!v&&!h){var _=decodeURI(p).split(" ");_.length>0&&(h=_[0],v=_[1])}p=h&&v?h+" "+v:p,h||(h=""),v||(v=""),e.deBugger("forms","fName = "+h),e.deBugger("forms","lName = "+v),e.deBugger("forms","fullName = "+p);var b=e.totalStorage("page_views")||{},y=e.totalStorage("inbound_url_params")||{},w=n.querySelectorAll('input[value][type="hidden"][name="inbound_furl"]:not([value=""])'),k=!1;if(0==w.length||"IA=="==w[0].value)k=!0;var S=n.querySelectorAll('input[value][type="hidden"][name="inbound_form_id"]');S=S.length>0?S[0].value:0;if("undefined"!=typeof landing_path_info)C=landing_path_info.variation;else if("undefined"!=typeof cta_path_info)C=cta_path_info.variation;else var C=inbound_settings.variation_id;var I=inbound_settings.post_type||"page",L=inbound_settings.post_id||0;search_data={},formData={action:"inbound_lead_store",email:m,full_name:p,first_name:h,last_name:v,raw_params:f,mapped_params:g,url_params:JSON.stringify(y),search_data:"test",page_views:JSON.stringify(b),post_type:I,page_id:L,variation:C,source:t.readCookie("inbound_referral_site"),inbound_submitted:k,inbound_form_id:S,inbound_nonce:inbound_settings.ajax_nonce,event:n},callback=function(o){e.deBugger("forms","Lead Created with ID: "+o),o=parseInt(o,10),formData.leadID=o,o&&(t.createCookie("wp_lead_id",o),e.totalStorage.deleteItem("page_views"),e.totalStorage.deleteItem("tracking_events")),e.trigger("form_after_submission",formData),e.Forms.releaseFormSubmit(n)},e.trigger("form_before_submission",formData),t.ajaxPost(inbound_settings.admin_url,formData,callback)},saveSearchData:function(n){for(var o=o||{},i=0;i<n.elements.length;i++)if(formInput=n.elements[i],multiple=!1,formInput.name){if(formInput.dataset.ignoreFormField){e.deBugger("searches","ignore "+formInput.name);continue}switch(inputName=formInput.name.replace(/\[([^\[]*)\]/g,"%5B%5D$1"),o[inputName]||(o[inputName]={}),formInput.type&&(o[inputName].type=formInput.type),o[inputName].name||(o[inputName].name=formInput.name),formInput.dataset.mapFormField&&(o[inputName].map=formInput.dataset.mapFormField),formInput.nodeName){case"INPUT":if(!1===(r=this.getInputValue(formInput)))continue;break;case"TEXTAREA":r=formInput.value;break;case"SELECT":if(formInput.multiple){values=[],multiple=!0;for(var a=0;a<formInput.length;a++)formInput[a].selected&&values.push(encodeURIComponent(formInput[a].value))}else r=formInput.value}if(e.deBugger("searches","Input Value = "+r),r){o[inputName].value||(o[inputName].value=[]),o[inputName].value.push(multiple?values.join(","):encodeURIComponent(r));var r=multiple?values.join(","):encodeURIComponent(r)}}e.deBugger("searches",o);var s=[];for(var l in o){var u=o[l].value,d=o[l].type;void 0!==u&&null!=u&&""!=u&&"search"==d&&s.push("search_text|value|"+o[l].value)}if(s[0]){var c=s.join("|field|");if(e.deBugger("searches","Stringified Search Form PARAMS: "+c),"undefined"!=typeof landing_path_info)m=landing_path_info.variation;else if("undefined"!=typeof cta_path_info)m=cta_path_info.variation;else var m=inbound_settings.variation_id;var f=inbound_settings.post_type||"page",g=inbound_settings.post_id||0,p=t.readCookie("wp_lead_uid");inbound_settings.wp_lead_data.lead_email?email=inbound_settings.wp_lead_data.lead_email:t.readCookie("inbound_wpleads_email_address")?email=t.readCookie("inbound_wpleads_email_address"):email="",searchData={email:email,search_data:c,user_UID:p,post_type:f,page_id:g,variation:m,source:t.readCookie("inbound_referral_site"),ip_address:inbound_settings.ip_address,timestamp:Math.floor((new Date).getTime()/1e3)},e.trigger("search_before_caching",searchData),inbound_settings.wp_lead_data.lead_id?(searchData.lead_id=inbound_settings.wp_lead_data.lead_id,t.cacheSearchData(searchData,n)):t.cacheSearchData(searchData,n)}},rememberInputValues:function(n){n.name&&n.name;var o=n.type?n.type:"text";if("submit"===o||"hidden"===o||"file"===o||"password"===o||n.dataset.ignoreFormField)return!1;t.addListener(n,"change",function(n){if(n.target.name){if("checkbox"!==o)var i=n.target.value;else for(var a=[],r=document.querySelectorAll('input[name="'+n.target.name+'"]'),s=0;s<r.length;s++)r[s].checked&&a.push(r[s].value),i=a.join(",");inputData={name:n.target.name,node:n.target.nodeName.toLowerCase(),type:o,value:i,mapping:n.target.dataset.mapFormField},e.trigger("form_input_change",inputData),t.createCookie("inbound_"+n.target.name,encodeURIComponent(i))}})},fillInputValues:function(e){var n=e.name?"inbound_"+e.name:"",o=e.type?e.type:"text";if("submit"===o||"hidden"===o||"file"===o||"password"===o)return!1;if(t.readCookie(n)&&"comment"!=n)if(value=decodeURIComponent(t.readCookie(n)),"checkbox"===o||"radio"===o)for(var i=value.split(","),a=0;a<i.length;a++)e.value.indexOf(i[a])>-1&&(e.checked=!0);else"undefined"!==value&&(e.value=value)},getInputLabel:function(e){var t;return(t=this.siblingsIsLabel(e))?t:!!(t=this.CheckParentForLabel(e))&&t},getInputValue:function(e){var t=!1;switch(e.type){case"radio":case"checkbox":e.checked&&(t=e.value);break;case"text":case"hidden":default:t=e.value}return t},addDataAttr:function(e,t){for(var n=document.getElementsByName(e.name),o=n.length-1;o>=0;o--)e.dataset.mapFormField||(n[o].dataset.mapFormField=t)},removeArrayItem:function(e,t){if(e.indexOf)index=e.indexOf(t);else for(index=e.length-1;index>=0&&e[index]!==t;--index);index>=0&&e.splice(index,1)},siblingsIsLabel:function(e){for(var t=this.getSiblings(e),n=[],o=t.length-1;o>=0;o--)"label"===t[o].nodeName.toLowerCase()&&n.push(t[o]);return n.length>0&&n.length<2&&n},getChildren:function(e,t){for(var n=[];e;e=e.nextSibling)1==e.nodeType&&e!=t&&n.push(e);return n},getSiblings:function(e){return this.getChildren(e.parentNode.firstChild,e)},CheckParentForLabel:function(e){if("FORM"===e.nodeName)return null;do{var t=e.getElementsByTagName("label");if(t.length>0&&t.length<2)return e.getElementsByTagName("label")}while(e=e.parentNode);return null},mailCheck:function(){var e=document.querySelector(".inbound-email");e&&(t.addListener(e,"blur",this.mailCheck),u.run({email:document.querySelector(".inbound-email").value,suggested:function(n){var o=document.querySelector(".email_suggestion");o&&t.removeElement(o);var i=document.createElement("span");i.innerHTML="<span class=\"email_suggestion\">Did youu mean <b><i id='email_correction' style='cursor: pointer;' title=\"click to update\">"+n.full+"</b></i>?</span>",e.parentNode.insertBefore(i,e.nextSibling);var a=document.getElementById("email_correction");t.addListener(a,"click",function(){e.value=a.innerHTML,a.parentNode.parentNode.innerHTML="Fixed!"})},empty:function(){}}))}},void 0===u)var u={domainThreshold:1,topLevelThreshold:3,defaultDomains:["yahoo.com","google.com","hotmail.com","gmail.com","me.com","aol.com","mac.com","live.com","comcast.net","googlemail.com","msn.com","hotmail.co.uk","yahoo.co.uk","facebook.com","verizon.net","sbcglobal.net","att.net","gmx.com","mail.com","outlook.com","icloud.com"],defaultTopLevelDomains:["co.jp","co.uk","com","net","org","info","edu","gov","mil","ca","de"],run:function(e){e.domains=e.domains||u.defaultDomains,e.topLevelDomains=e.topLevelDomains||u.defaultTopLevelDomains,e.distanceFunction=e.distanceFunction||u.sift3Distance;var t=function(e){return e},n=e.suggested||t,o=e.empty||t,i=u.suggest(u.encodeEmail(e.email),e.domains,e.topLevelDomains,e.distanceFunction);return i?n(i):o()},suggest:function(e,t,n,o){e=e.toLowerCase();var i=this.splitEmail(e),a=this.findClosestDomain(i.domain,t,o,this.domainThreshold);if(a){if(a!=i.domain)return{address:i.address,domain:a,full:i.address+"@"+a}}else{var r=this.findClosestDomain(i.topLevelDomain,n,o,this.topLevelThreshold);if(i.domain&&r&&r!=i.topLevelDomain){var s=i.domain;return a=s.substring(0,s.lastIndexOf(i.topLevelDomain))+r,{address:i.address,domain:a,full:i.address+"@"+a}}}return!1},findClosestDomain:function(e,t,n,o){o=o||this.topLevelThreshold;var i,a=99,r=null;if(!e||!t)return!1;n||(n=this.sift3Distance);for(var s=0;s<t.length;s++){if(e===t[s])return e;(i=n(e,t[s]))<a&&(a=i,r=t[s])}return a<=o&&null!==r&&r},sift3Distance:function(e,t){if(null===e||0===e.length)return null===t||0===t.length?0:t.length;if(null===t||0===t.length)return e.length;for(var n=0,o=0,i=0,a=0;n+o<e.length&&n+i<t.length;){if(e.charAt(n+o)==t.charAt(n+i))a++;else{o=0,i=0;for(var r=0;r<5;r++){if(n+r<e.length&&e.charAt(n+r)==t.charAt(n)){o=r;break}if(n+r<t.length&&e.charAt(n)==t.charAt(n+r)){i=r;break}}}n++}return(e.length+t.length)/2-a},splitEmail:function(e){var t=e.trim().split("@");if(t.length<2)return!1;for(a=0;a<t.length;a++)if(""===t[a])return!1;var n=t.pop(),o=n.split("."),i="";if(0===o.length)return!1;if(1==o.length)i=o[0];else{for(var a=1;a<o.length;a++)i+=o[a]+".";o.length>=2&&(i=i.substring(0,i.length-1))}return{topLevelDomain:i,domain:n,address:t.join("@")}},encodeEmail:function(e){var t=encodeURI(e);return t=t.replace("%20"," ").replace("%25","%").replace("%5E","^").replace("%60","`").replace("%7B","{").replace("%7C","|").replace("%7D","}")}};return e}(_inbound||{}),_inboundEvents=function(e){function t(t,o,i){var o=o||{};(i=i||{}).bubbles=i.bubbles||!0,i.cancelable=i.cancelable||!0,o=e.apply_filters("filter_"+t,o);!window.ActiveXObject&&window;if("function"==typeof CustomEvent)var a=new CustomEvent(t,{detail:o,bubbles:i.bubbles,cancelable:i.cancelable});else(a=document.createEvent("Event")).initEvent(t,!0,!0);window.dispatchEvent(a),e.do_action(t,o),n(t,o)}function n(e,t){if(window.jQuery){var t=t||{};jQuery(document).trigger(e,t)}}e.trigger=function(t,n){e.Events[t](n)};return e.Events={analytics_ready:function(){t("analytics_ready",{data:"xyxy"},{opt1:!0})},url_parameters:function(e){t("url_parameters",e)},session_start:function(){console.log(""),t("session_start")},session_end:function(e){t("session_end",e),console.log("Session End")},session_active:function(){t("session_active")},session_idle:function(e){t("session_idle",e)},session_resume:function(){t("session_resume")},session_heartbeat:function(e){t("session_heartbeat",{clock:e,leadData:InboundLeadData})},page_visit:function(e){t("page_view",e)},page_first_visit:function(n){t("page_first_visit"),e.deBugger("pages","First Ever Page View of this Page")},page_revisit:function(n){t("page_revisit",n);e.deBugger("pages",status,function(){console.log("pageData",n),console.log("Page Revisit viewed "+n+" times")})},tab_hidden:function(n){e.deBugger("pages","Tab Hidden"),t("tab_hidden")},tab_visible:function(n){e.deBugger("pages","Tab Visible"),t("tab_visible")},tab_mouseout:function(n){e.deBugger("pages","Tab Mouseout"),t("tab_mouseout")},form_input_change:function(n){e.deBugger("forms","inputData change. Data=",function(){console.log(n)}),t("form_input_change",n)},form_before_submission:function(e){t("form_before_submission",e)},form_after_submission:function(e){t("form_after_submission",e)},search_before_caching:function(e){t("search_before_caching",e)},analyticsError:function(e,t,n){var o=new CustomEvent("inbound_analytics_error",{detail:{MLHttpRequest:e,textStatus:t,errorThrown:n}});window.dispatchEvent(o),console.log("Page Save Error")}},e}(_inbound||{});_inbound.add_action("form_before_submission",inboundFormNoRedirect,10),_inbound.add_action("form_after_submission",inboundFormNoRedirectContent,10);var InboundTotalStorage=function(e){var t,n;if("localStorage"in window)try{n=void 0===window.localStorage?void 0:window.localStorage,t=void 0!==n&&void 0!==window.JSON,window.localStorage.setItem("_inbound","1"),window.localStorage.removeItem("_inbound")}catch(e){t=!1}e.totalStorage=function(t,n,o){return e.totalStorage.impl.init(t,n)},e.totalStorage.setItem=function(t,n){return e.totalStorage.impl.setItem(t,n)},e.totalStorage.getItem=function(t){return e.totalStorage.impl.getItem(t)},e.totalStorage.getAll=function(){return e.totalStorage.impl.getAll()},e.totalStorage.deleteItem=function(t){return e.totalStorage.impl.deleteItem(t)},e.totalStorage.impl={init:function(e,t){return void 0!==t?this.setItem(e,t):this.getItem(e)},setItem:function(o,i){if(!t)try{return e.Utils.createCookie(o,i),i}catch(e){console.log("Local Storage not supported by this browser. Install the cookie plugin on your site to take advantage of the same functionality. You can get it at https://github.com/carhartl/jquery-cookie")}var a=JSON.stringify(i);return n.setItem(o,a),this.parseResult(a)},getItem:function(o){if(!t)try{return this.parseResult(e.Utils.readCookie(o))}catch(e){return null}var i=n.getItem(o);return this.parseResult(i)},deleteItem:function(o){if(!t)try{return e.Utils.eraseCookie(o,null),!0}catch(e){return!1}return n.removeItem(o),!0},getAll:function(){var o=[];if(t)for(var i in n)i.length&&o.push({key:i,value:this.parseResult(n.getItem(i))});else try{for(var a=document.cookie.split(";"),r=0;r<a.length;r++){var s=a[r].split("=")[0];o.push({key:s,value:this.parseResult(e.Utils.readCookie(s))})}}catch(e){return null}return o},parseResult:function(e){var t;try{void 0===(t=JSON.parse(e))&&(t=e),"true"==t&&(t=!0),"false"==t&&(t=!1),parseFloat(t)==t&&"object"!=typeof t&&(t=parseFloat(t))}catch(n){t=e}return t}}}(_inbound||{}),_inboundLeadsAPI=function(e){return e.LeadsAPI={init:function(){var t=e.Utils,n=(t.readCookie("wp_lead_uid"),t.readCookie("wp_lead_id"));t.readCookie("lead_session_expire")||(e.deBugger("leads","expired vistor. Run Processes"),n&&e.LeadsAPI.getAllLeadData())},setGlobalLeadData:function(e){InboundLeadData=e},getAllLeadData:function(t){var n=e.Utils.readCookie("wp_lead_id"),o=e.totalStorage("inbound_lead_data"),i=e.Utils.readCookie("lead_data_expire");data={action:"inbound_get_all_lead_data",wp_lead_id:n},success=function(t){var n=JSON.parse(t);e.LeadsAPI.setGlobalLeadData(n),e.totalStorage("inbound_lead_data",n);var o=new Date;o.setTime(o.getTime()+18e5);var i=e.Utils.addDays(o,3);e.Utils.createCookie("lead_data_expire",!0,i)},o?(e.LeadsAPI.setGlobalLeadData(o),e.deBugger("lead","Set Global Lead Data from Localstorage"),i||(e.Utils.ajaxPost(inbound_settings.admin_url,data,success),e.deBugger("lead","localized data old. Pull new from DB"))):e.Utils.ajaxPost(inbound_settings.admin_url,data,success)},getLeadLists:function(){var t={action:"wpl_check_lists",wp_lead_id:e.Utils.readCookie("wp_lead_id")};e.Utils.ajaxPost(inbound_settings.admin_url,t,function(t){e.Utils.createCookie("lead_session_list_check",!0,{path:"/",expires:1}),e.deBugger("lead","Lists checked")})}},e}(_inbound||{}),_inboundPageTracking=function(e){var t,n,o=!1,i=!1,a=!1,r=parseInt(e.Utils.readCookie("lead_session"),10)||0,s=0,l=(new Date,null),u=null,d=null,c=e.Utils,m=e.Utils.GetDate(),f="page_views",g=e.totalStorage(f)||{},p=inbound_settings.post_id||window.location.pathname,h=e.Settings.timeout||1e4;return e.PageTracking={init:function(o){this.CheckTimeOut(),o=o||{},t=parseInt(o.reportInterval,10)||10,n=parseInt(o.idleTimeout,10)||3,c.addListener(document,"keydown",c.throttle(e.PageTracking.pingSession,1e3)),c.addListener(document,"click",c.throttle(e.PageTracking.pingSession,1e3)),c.addListener(window,"mousemove",c.throttle(e.PageTracking.pingSession,1e3)),e.PageTracking.checkVisibility(),this.startSession()},setIdle:function(t){var n="Session IDLE. Activity Timeout due to "+(t=t||"No Movement");e.deBugger("pages",n),clearTimeout(e.PageTracking.idleTimer),e.PageTracking.stopClock(),e.trigger("session_idle")},checkVisibility:function(){var t,n;void 0!==document.hidden?(t="hidden",n="visibilitychange"):void 0!==document.mozHidden?(t="mozHidden",n="mozvisibilitychange"):void 0!==document.msHidden?(t="msHidden",n="msvisibilitychange"):void 0!==document.webkitHidden&&(t="webkitHidden",n="webkitvisibilitychange");var o=document[t];e.Utils.addListener(document,n,function(n){o!=document[t]&&(document[t]?(e.trigger("tab_hidden"),e.PageTracking.setIdle("browser tab switch")):(e.trigger("tab_visible"),e.PageTracking.pingSession()),o=document[t])})},clock:function(){var n="Total time spent on Page in this Session: "+((r+=1)/60).toFixed(2)+" min";if(e.deBugger("pages",n),r>0&&r%t==0){var o=new Date;o.setTime(o.getTime()+18e5),c.createCookie("lead_session",r,o),e.trigger("session_heartbeat",r)}},inactiveClock:function(){var t="Time until Session Timeout: "+((1800-(s+=1))/60).toFixed(2)+" min";e.deBugger("pages",t),s>1800&&(e.trigger("session_end",InboundLeadData),e.Utils.eraseCookie("lead_session"),s=0,clearTimeout(u))},stopClock:function(){i=!0,clearTimeout(l),clearTimeout(u),u=setInterval(e.PageTracking.inactiveClock,1e3)},restartClock:function(){i=!1,e.trigger("session_resume"),e.deBugger("pages","Activity resumed. Session Active"),clearTimeout(l),s=0,clearTimeout(u),l=setInterval(e.PageTracking.clock,1e3)},turnOff:function(){e.PageTracking.setIdle(),a=!0},turnOn:function(){a=!1},startSession:function(){new Date;if(o=!0,l=setInterval(e.PageTracking.clock,1e3),c.readCookie("lead_session"))e.trigger("session_active");else{e.trigger("session_start");var t=new Date;t.setTime(t.getTime()+18e5),e.Utils.createCookie("lead_session",1,t)}this.pingSession()},resetInactiveFunc:function(){s=0,clearTimeout(u)},pingSession:function(t){a||(o||e.PageTracking.startSession(),i&&e.PageTracking.restartClock(),clearTimeout(d),d=setTimeout(e.PageTracking.setIdle,1e3*n+100),void 0!==t&&"mousemove"===t.type&&e.PageTracking.mouseEvents(t))},mouseEvents:function(t){t.pageY<=5&&e.trigger("tab_mouseout")},getPageViews:function(){if(e.Utils.checkLocalStorage()){var t=localStorage.getItem(f),n=JSON.parse(t);return n}},isRevisit:function(e){var t=!1,n=(e=e||{})[p];return void 0!==n&&null!==n&&(t=!0),t},triggerPageView:function(t){var n={title:document.title,url:document.location.href,path:document.location.pathname,count:1};t?(g[p].push(m),n.count=g[p].length,e.trigger("page_revisit",n)):(g[p]=[],g[p].push(m),e.trigger("page_first_visit",n)),e.trigger("page_visit",n),e.totalStorage(f,g),this.storePageView()},CheckTimeOut:function(){var t,n=this.isRevisit(g);if(n){var o=g[p].length-1,i=g[p][o],a=Math.abs(new Date(i).getTime()-new Date(m).getTime());a>h?(t="Timeout Happened. Page view fired",this.triggerPageView(n)):(time_left=.001*Math.abs(h-a),t=h/1e3+" sec timeout not done: "+time_left+" seconds left")}else this.triggerPageView(n);e.deBugger("pages",t)},storePageView:function(){var t=!1;"off"==inbound_settings.page_tracking&&"landing-page"!=inbound_settings.post_type||(document.onreadystatechange=function(){"loading"!==document.readyState&&!1===t&&setTimeout(function(){var n=e.Utils.readCookie("wp_lead_id")?e.Utils.readCookie("wp_lead_id"):"",o=e.Utils.readCookie("wp_lead_uid")?e.Utils.readCookie("wp_lead_uid"):"",i=e.totalStorage("wp_cta_loaded"),a=e.totalStorage("wp_cta_impressions");t=!0,e.totalStorage("wp_cta_impressions",{});var r={action:"inbound_track_lead",wp_lead_uid:o,wp_lead_id:n,page_id:inbound_settings.post_id,variation_id:inbound_settings.variation_id,post_type:inbound_settings.post_type,current_url:window.location.href,page_views:JSON.stringify(e.PageTracking.getPageViews()),cta_impressions:JSON.stringify(a),cta_history:JSON.stringify(i),json:"0"};e.Utils.ajaxPost(inbound_settings.admin_url,r,function(e){})},200)})}},e}(_inbound||{});_inbound.init(),InboundLeadData=_inbound.totalStorage("inbound_lead_data")||null;
|
shared/assets/js/global/debug.js
DELETED
@@ -1,37 +0,0 @@
|
|
1 |
-
var errors = [];
|
2 |
-
window.onerror = function(msg, url, linenumber) {
|
3 |
-
//alert('Error message: '+msg+' URL: '+url+' Line Number: '+linenumber);
|
4 |
-
errors.push(msg + ' from ' + url + ' on line ' +linenumber);
|
5 |
-
}
|
6 |
-
jQuery(document).ready(function($) {
|
7 |
-
var url = window.location.href;
|
8 |
-
var match = url.match(/\?inbound_js/);
|
9 |
-
var param = "?";
|
10 |
-
if(match) {
|
11 |
-
var param = "?";
|
12 |
-
}
|
13 |
-
var url = url.replace('?inbound_js', '');
|
14 |
-
var url = url.replace('&inbound_js', '') + param + "inbound-dequeue-scripts";
|
15 |
-
setTimeout(function() {
|
16 |
-
document.write("<strong>Below are the javascript errors on this page</strong> " + "<br>");
|
17 |
-
/*if (errors.length === 0 ) {
|
18 |
-
document.write("<strong style="color:green;">None Detected</strong> " + "<br>");
|
19 |
-
}*/
|
20 |
-
document.write("<div id='errors-here'>");
|
21 |
-
for (var i=0,len=errors.length; i<len; i++){
|
22 |
-
document.write(i + 1 + ". " + errors[i] + "<br>");
|
23 |
-
}
|
24 |
-
document.write("</div>");
|
25 |
-
document.write("<div style=\'margin-top:20px;\'><strong>You need to fix these errors for things to work. There are 3 options:</strong> " + "<br>");
|
26 |
-
document.write("<strong>1. <a href=\'" +url+ "\'>Click here and dequeue (turn off) the broken javascript files</a> from this page.</strong> " + "<br>");
|
27 |
-
document.write("<strong>2. Contact the original developer of the plugin/theme causing the error.</strong> " + "<br>");
|
28 |
-
document.write("<strong>3. Disable the plugin or theme causing the conflict.</strong> " + "<br></div>");
|
29 |
-
}, 500);
|
30 |
-
setTimeout(function() {
|
31 |
-
var theDiv = document.getElementById("errors-here");
|
32 |
-
if(theDiv.innerHTML.length == 0){
|
33 |
-
theDiv.innerHTML = "<strong style='color:green;''>No JS Errors Detected</strong> " + "<br><br>" + "Sometimes errors are not detectatble by this handy tool, to double check please <a href='http://www.youtube.com/watch?v=x19VOytW9DM'>follow these instructions</a>";
|
34 |
-
theDiv.style.display="inline";
|
35 |
-
}
|
36 |
-
}, 1000);
|
37 |
-
});
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
shared/assets/js/global/inbound-dequeue-scripts.js
DELETED
@@ -1,49 +0,0 @@
|
|
1 |
-
jQuery(document).ready(function($) {
|
2 |
-
jQuery("body").on('click', 'label', function () {
|
3 |
-
|
4 |
-
var status = jQuery(this).attr('class');
|
5 |
-
var status = status.replace('turn-', "");
|
6 |
-
if (status === 'off') {
|
7 |
-
jQuery(this).parent().find('.switch-button').addClass('status-off');
|
8 |
-
} else {
|
9 |
-
jQuery(this).parent().find('.switch-button').removeClass('status-off');
|
10 |
-
}
|
11 |
-
var the_script = jQuery(this).parent().attr('id');
|
12 |
-
var post_id = $('#inbound-dequeue-id').text();
|
13 |
-
var admin_screen = $('#inbound-fix-page').attr('data-admin-screen');
|
14 |
-
if (typeof (admin_screen) != "undefined" && admin_screen != null && admin_screen != "") {
|
15 |
-
var admin_screen = admin_screen;
|
16 |
-
var action = 'inbound_dequeue_admin_js'
|
17 |
-
} else {
|
18 |
-
var admin_screen = "";
|
19 |
-
var action = 'inbound_dequeue_js'
|
20 |
-
}
|
21 |
-
console.log(the_script);
|
22 |
-
console.log(status);
|
23 |
-
|
24 |
-
jQuery.ajax({
|
25 |
-
type: 'POST',
|
26 |
-
url: inbound_debug.admin_url,
|
27 |
-
context: this,
|
28 |
-
data: {
|
29 |
-
action: action,
|
30 |
-
post_id: post_id,
|
31 |
-
status: status,
|
32 |
-
the_script: the_script,
|
33 |
-
admin_screen: admin_screen
|
34 |
-
},
|
35 |
-
|
36 |
-
success: function (data) {
|
37 |
-
console.log("The script " + the_script + " has been turned " + status);
|
38 |
-
var self = this;
|
39 |
-
var str = data;
|
40 |
-
var obj = JSON.parse(str);
|
41 |
-
console.log(obj);
|
42 |
-
},
|
43 |
-
|
44 |
-
error: function (MLHttpRequest, textStatus, errorThrown) {
|
45 |
-
alert("Ajax not enabled");
|
46 |
-
}
|
47 |
-
});
|
48 |
-
});
|
49 |
-
});
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
shared/classes/class.acf-bootstrap.php
CHANGED
@@ -1,88 +1,94 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
/*
|
27 |
-
add_filter('acf/settings/
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
88 |
Â
new Inbound_Shared_ACF_BootStrap;
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class loads ACF4 if no other ACF version has been loaded prior
|
5 |
+
* @package ACF
|
6 |
+
*/
|
7 |
+
|
8 |
+
|
9 |
+
class Inbound_Shared_ACF_BootStrap {
|
10 |
+
|
11 |
+
public function __construct() {
|
12 |
+
self::load_acf();
|
13 |
+
self::load_acf_extended_fields();
|
14 |
+
}
|
15 |
+
|
16 |
+
public static function load_acf() {
|
17 |
+
|
18 |
+
/* load ACF if not already loaded */
|
19 |
+
if( !class_exists('acf') || defined('ACF_PRELOADED') ) {
|
20 |
+
|
21 |
+
define( 'ACF_LITE', true );
|
22 |
+
define( 'ACF_FREE', true );
|
23 |
+
|
24 |
+
include_once( INBOUNDNOW_SHARED_PATH . 'assets/plugins/advanced-custom-fields/acf.php');
|
25 |
+
|
26 |
+
/* customize ACF path */
|
27 |
+
add_filter('acf/settings/path', array( __CLASS__, 'define_acf_settings_path' ) );
|
28 |
+
|
29 |
+
/* customize ACF URL path */
|
30 |
+
add_filter('acf/settings/dir', array( __CLASS__, 'define_acf_settings_url' ) );
|
31 |
+
|
32 |
+
/* Hide ACF field group menu item */
|
33 |
+
add_filter('acf/settings/show_admin', '__return_false');
|
34 |
+
|
35 |
+
|
36 |
+
} else {
|
37 |
+
/* find out if ACF free or ACF Pro is installed & activated*/
|
38 |
+
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
39 |
+
if ( !function_exists('acf_add_local_field_group') ) {
|
40 |
+
define( 'ACF_FREE', true );
|
41 |
+
} else {
|
42 |
+
define( 'ACF_PRO', true );
|
43 |
+
add_filter('lp_init' , array(__CLASS__,'acf_register_global') , 20 , 1 ); /* registeres a global of registered field values for support between ACF5 & ACF6 */
|
44 |
+
}
|
45 |
+
}
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Load extended/custom field support
|
50 |
+
*/
|
51 |
+
public static function load_acf_extended_fields() {
|
52 |
+
if (!function_exists('register_fields_font_awesome')) {
|
53 |
+
include_once( INBOUNDNOW_SHARED_PATH . 'assets/plugins/advanced-custom-fields-font-awesome/acf-font-awesome.php');
|
54 |
+
include_once( INBOUNDNOW_SHARED_PATH . 'assets/plugins/acf-field-date-time-picker/acf-date-time-picker.php');
|
55 |
+
}
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* If ACF Pro is active then register a global for active fields - this provides legacy support to Landing Pages
|
60 |
+
*/
|
61 |
+
public static function acf_register_global( $field_group ) {
|
62 |
+
$GLOBALS['acf_register_field_group'][] = array(
|
63 |
+
'fields' => acf_local()->fields
|
64 |
+
);
|
65 |
+
}
|
66 |
+
/**
|
67 |
+
* define custom ACF path
|
68 |
+
* @param $path
|
69 |
+
* @return string
|
70 |
+
*/
|
71 |
+
public static function define_acf_settings_path( $path ) {
|
72 |
+
|
73 |
+
$path = INBOUNDNOW_SHARED_PATH . 'assets/plugins/advanced-custom-fields/';
|
74 |
+
|
75 |
+
return $path;
|
76 |
+
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* define custom settings URL
|
81 |
+
* @param $url
|
82 |
+
* @return string
|
83 |
+
*/
|
84 |
+
public static function define_acf_settings_url( $url ) {
|
85 |
+
|
86 |
+
$url = INBOUNDNOW_SHARED_PATH . 'assets/plugins/advanced-custom-fields/';
|
87 |
+
|
88 |
+
return $url;
|
89 |
+
}
|
90 |
+
|
91 |
+
}
|
92 |
+
|
93 |
+
|
94 |
Â
new Inbound_Shared_ACF_BootStrap;
|
shared/classes/class.ajax.php
CHANGED
@@ -1,165 +1,154 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
-
*
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
add_action('
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
$
|
53 |
-
|
54 |
-
$
|
55 |
-
$lead_data['
|
56 |
-
$lead_data['
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
$lead_data['
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
$
|
74 |
-
}
|
75 |
-
|
76 |
-
/*
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
$
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
}
|
155 |
-
|
156 |
-
$list_array = json_encode(array('ids' => $lead_list));;
|
157 |
-
setcookie('wp_lead_list', $list_array, time() + (20 * 365 * 24 * 60 * 60), '/');
|
158 |
-
}
|
159 |
-
}
|
160 |
-
|
161 |
-
}
|
162 |
-
|
163 |
-
/* Loads Inbound_Ajax pre init */
|
164 |
-
$Inbound_Ajax = new Inbound_Ajax();
|
165 |
Â
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Class provides ajax that tracks lead frontend movement
|
4 |
+
* @package Shared
|
5 |
+
* @subpackage Tracking
|
6 |
+
*/
|
7 |
+
if (!class_exists('Inbound_Ajax')) {
|
8 |
+
|
9 |
+
class Inbound_Ajax {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Initializes classs
|
13 |
+
*/
|
14 |
+
public function __construct() {
|
15 |
+
self::load_hooks();
|
16 |
+
}
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Loads hooks and filters
|
20 |
+
*/
|
21 |
+
public static function load_hooks() {
|
22 |
+
|
23 |
+
/* Increases the page view statistics of lead on page load */
|
24 |
+
add_action('wp_ajax_inbound_track_lead', array(__CLASS__, 'track_lead'));
|
25 |
+
add_action('wp_ajax_nopriv_inbound_track_lead', array(__CLASS__, 'track_lead'));
|
26 |
+
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Listen for page view event
|
31 |
+
*/
|
32 |
+
public static function track_lead() {
|
33 |
+
|
34 |
+
global $wpdb;
|
35 |
+
|
36 |
+
/* check for known bots and ignore */
|
37 |
+
if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/bot|crawl|slurp|spider/i', $_SERVER['HTTP_USER_AGENT'])) {
|
38 |
+
return;
|
39 |
+
}
|
40 |
+
|
41 |
+
$lead_data['lead_id'] = (isset($_POST['wp_lead_id'])) ? $_POST['wp_lead_id'] : '';
|
42 |
+
$lead_data['nature'] = (isset($_POST['nature'])) ? $_POST['nature'] : 'non-conversion'; /* what is nature? */
|
43 |
+
$lead_data['json'] = (isset($_POST['json'])) ? addslashes($_POST['json']) : 0;
|
44 |
+
$lead_data['wp_lead_uid'] = (isset($_POST['wp_lead_uid'])) ? $_POST['wp_lead_uid'] : 0;
|
45 |
+
$lead_data['page_id'] = (isset($_POST['page_id'])) ? $_POST['page_id'] : 0;
|
46 |
+
$lead_data['current_url'] = (isset($_POST['current_url'])) ? $_POST['current_url'] : 'notfound';
|
47 |
+
$lead_data['variation_id'] = (isset($_POST['variation_id'])) ? $_POST['variation_id'] : '0';
|
48 |
+
|
49 |
+
$timezone_format = 'Y-m-d G:i:s T';
|
50 |
+
$lead_data['datetime'] = date_i18n($timezone_format);
|
51 |
+
|
52 |
+
$page_views = stripslashes($_POST['page_views']);
|
53 |
+
|
54 |
+
$page_views = ($page_views) ? $page_views : '';
|
55 |
+
$lead_data['event_details']['funnel'] = json_decode($page_views,true);
|
56 |
+
$lead_data['funnel'] = $page_views;
|
57 |
+
|
58 |
+
/* update funnel cookie */
|
59 |
+
if (isset($_COOKIE['inbound_page_views']) && !$page_views) {
|
60 |
+
$_SESSION['inbound_page_views'] = stripslashes($_COOKIE['inbound_page_views']);
|
61 |
+
} else {
|
62 |
+
$_SESSION['inbound_page_views'] = $page_views;
|
63 |
+
}
|
64 |
+
|
65 |
+
/* update lead data and set lead lists into cookies */
|
66 |
+
if ($lead_data['lead_id']) {
|
67 |
+
self::update_page_view_obj($lead_data);
|
68 |
+
self::set_current_lists($lead_data['lead_id']);
|
69 |
+
}
|
70 |
+
|
71 |
+
/* create page_view event */
|
72 |
+
if ($lead_data['page_id']) {
|
73 |
+
Inbound_Events::store_page_view($lead_data);
|
74 |
+
}
|
75 |
+
|
76 |
+
/* record CTA impressions */
|
77 |
+
$cta_impressions = ( isset($_POST['cta_impressions']) ) ? json_decode(stripslashes($_POST['cta_impressions']),true) : array();
|
78 |
+
|
79 |
+
foreach ( $cta_impressions as $cta_id => $vid ) {
|
80 |
+
do_action('wp_cta_record_impression', (int) $cta_id, (int) $vid );
|
81 |
+
}
|
82 |
+
|
83 |
+
/* update content data */
|
84 |
+
do_action('lp_record_impression', $lead_data['page_id'], $_POST['post_type'], $_POST['variation_id']);
|
85 |
+
|
86 |
+
die();
|
87 |
+
}
|
88 |
+
|
89 |
+
public static function update_page_view_obj($lead_data) {
|
90 |
+
|
91 |
+
if (!$lead_data['page_id']) {
|
92 |
+
return;
|
93 |
+
}
|
94 |
+
|
95 |
+
$current_page_view_count = get_post_meta($lead_data['lead_id'], 'wpleads_page_view_count', true);
|
96 |
+
$increment_page_views = $current_page_view_count + 1;
|
97 |
+
|
98 |
+
update_post_meta($lead_data['lead_id'], 'wpleads_page_view_count', $increment_page_views); // update count
|
99 |
+
|
100 |
+
$time = current_time('timestamp', 0); // Current wordpress time from settings
|
101 |
+
$wordpress_date_time = date("Y-m-d G:i:s T", $time);
|
102 |
+
$page_view_data = get_post_meta($lead_data['lead_id'], 'page_views', TRUE);
|
103 |
+
|
104 |
+
|
105 |
+
// If page_view meta exists do this
|
106 |
+
if ($page_view_data) {
|
107 |
+
$current_count = 0; // default
|
108 |
+
$timeout = 30; // 30 Timeout analytics tracking for same page timestamps
|
109 |
+
$page_view_data = json_decode($page_view_data, true);
|
110 |
+
// increment view count on page
|
111 |
+
if (isset($page_view_data[$lead_data['page_id']])) {
|
112 |
+
$current_count = count($page_view_data[$lead_data['page_id']]);
|
113 |
+
$last_view = $page_view_data[$lead_data['page_id']][$current_count];
|
114 |
+
$timeout = abs(strtotime($last_view) - strtotime($wordpress_date_time));
|
115 |
+
}
|
116 |
+
// If page hasn't been viewed in past 30 seconds. Log it
|
117 |
+
if ($timeout >= 30) {
|
118 |
+
$page_view_data[$lead_data['page_id']][$current_count + 1] = $wordpress_date_time;
|
119 |
+
$page_view_data = json_encode($page_view_data);
|
120 |
+
update_post_meta($lead_data['lead_id'], 'page_views', $page_view_data);
|
121 |
+
}
|
122 |
+
} else {
|
123 |
+
// Create page_view meta if it doesn't exist
|
124 |
+
$page_view_data = array();
|
125 |
+
$page_view_data[$lead_data['page_id']][0] = $wordpress_date_time;
|
126 |
+
$page_view_data = json_encode($page_view_data);
|
127 |
+
update_post_meta($lead_data['lead_id'], 'page_views', $page_view_data);
|
128 |
+
}
|
129 |
+
/* Run hook that tells WordPress lead data has been updated */
|
130 |
+
do_action('wplead_page_view', $lead_data);
|
131 |
+
}
|
132 |
+
|
133 |
+
public static function set_current_lists($lead_id) {
|
134 |
+
$terms = get_the_terms( $lead_id , 'wplead_list_category' );
|
135 |
+
|
136 |
+
if ( $terms && ! is_wp_error( $terms ) ) {
|
137 |
+
$lead_list = array();
|
138 |
+
$count = 0;
|
139 |
+
|
140 |
+
foreach ( $terms as $term ) {
|
141 |
+
$lead_list[] = $term->term_id;
|
142 |
+
$count++;
|
143 |
+
}
|
144 |
+
|
145 |
+
$list_array = json_encode(array('ids' => $lead_list));;
|
146 |
+
setcookie('wp_lead_list', $list_array, time() + (20 * 365 * 24 * 60 * 60), '/');
|
147 |
+
}
|
148 |
+
}
|
149 |
+
|
150 |
+
}
|
151 |
+
|
152 |
+
/* Loads Inbound_Ajax pre init */
|
153 |
+
$Inbound_Ajax = new Inbound_Ajax();
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
154 |
Â
}
|
shared/classes/class.confirm-double-optin.php
CHANGED
@@ -1,194 +1,200 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
$
|
101 |
-
|
102 |
-
if(!
|
103 |
-
$
|
104 |
-
}
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
$
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
if
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
}
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
/*
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
|
Â
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class provides shortcodes, listeners, and processing methods for double optin confirmation
|
5 |
+
* @package Shared
|
6 |
+
* @subpackage DoubleOptin
|
7 |
+
*/
|
8 |
+
if(!class_exists('Inbound_Confirm_Double_Optin')){
|
9 |
+
|
10 |
+
class Inbound_Confirm_Double_Optin{
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Initialize class
|
14 |
+
*/
|
15 |
+
function __construct(){
|
16 |
+
self::add_hooks();
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Load Hooks and Filters
|
21 |
+
*/
|
22 |
+
public static function add_hooks(){
|
23 |
+
|
24 |
+
/* Shortcode for displaying list double opt in confirmation form */
|
25 |
+
add_action( 'init' , array( __CLASS__, 'process_confrimation' ), 20 );
|
26 |
+
|
27 |
+
/* Process shortcode to produce the confirmation link,
|
28 |
+
* the name is different from the one the user uses to prevent early rendering */
|
29 |
+
add_shortcode( 'list-double-optin-link', array( __CLASS__, 'render_confirm_link' ) );
|
30 |
+
|
31 |
+
}
|
32 |
+
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @param $atts
|
36 |
+
* @return string
|
37 |
+
*/
|
38 |
+
public static function process_confrimation(){
|
39 |
+
global $inbound_settings;
|
40 |
+
|
41 |
+
if (!isset($_REQUEST['inbound-action']) || $_REQUEST['inbound-action'] != 'confirm' ) {
|
42 |
+
return;
|
43 |
+
}
|
44 |
+
|
45 |
+
/* get all lead lists */
|
46 |
+
$lead_lists = Inbound_Leads::get_lead_lists_as_array();
|
47 |
+
|
48 |
+
/* decode token */
|
49 |
+
$params = Inbound_API::get_args_from_token( sanitize_text_field($_GET['token'] ));
|
50 |
+
|
51 |
+
if ( !isset( $params['lead_id'] ) ) {
|
52 |
+
return;
|
53 |
+
}
|
54 |
+
|
55 |
+
self::confirm_being_added_to_lists($params);
|
56 |
+
}
|
57 |
+
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Creates the double optin confirmation link
|
61 |
+
* The shorcode used by the user is: inbound-list-double-optin-link.
|
62 |
+
* But Inbound_List_Double_Optin::add_confirm_link_shortcode_params trims the name to: list-double-optin-link.
|
63 |
+
* Then it gets rendered.
|
64 |
+
* The reason for this is so the shorcode isn't rendered until the atts have been added to it.
|
65 |
+
*/
|
66 |
+
public static function render_confirm_link( $params ) {
|
67 |
+
|
68 |
+
$params = shortcode_atts( array(
|
69 |
+
'lead_id' => '',
|
70 |
+
'list_ids' => '-1',
|
71 |
+
'email_id' => '-1'
|
72 |
+
), $params, 'list-double-optin-link');
|
73 |
+
/* check to see if lead id is set as a REQUEST */
|
74 |
+
if ( isset($params['lead_id']) ) {
|
75 |
+
$params['lead_id'] = intval($params['lead_id']);
|
76 |
+
} else if ( isset($_REQUEST['lead_id']) ) {
|
77 |
+
$params['lead_id'] = intval($_REQUEST['lead_id']);
|
78 |
+
} else if ( isset($_COOKIE['wp_lead_id']) ) {
|
79 |
+
$params['lead_id'] = intval($_COOKIE['wp_lead_id']);
|
80 |
+
}
|
81 |
+
/* Add variation id to confirm link */
|
82 |
+
$params['variation_id'] = ( isset($_REQUEST['inbvid']) ) ? intval($_REQUEST['inbvid']) : intval(0);
|
83 |
+
|
84 |
+
/* generate confirm link */
|
85 |
+
$confirm_link = self::generate_confirm_link( $params );
|
86 |
+
return $confirm_link;
|
87 |
+
}
|
88 |
+
|
89 |
+
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Generates confirm url given lead id and lists
|
93 |
+
* @param ARRAY $params contains: lead_id (INT ), list_ids (MIXED), email_id (INT)
|
94 |
+
* @return STRING $confirm_url
|
95 |
+
*/
|
96 |
+
public static function generate_confirm_link( $params ) {
|
97 |
+
if (!isset($params['lead_id']) || !$params['lead_id']) {
|
98 |
+
return __( '#confirm-not-available-in-online-mode' , 'inbound-pro' );
|
99 |
+
}
|
100 |
+
if (isset($_GET['lead_lists']) && !is_array($_GET['lead_lists'])){
|
101 |
+
$params['list_ids'] = explode( ',' , $_GET['lead_lists']);
|
102 |
+
} else if (isset($params['list_ids']) && !is_array($params['list_ids'])) {
|
103 |
+
$params['list_ids'] = explode( ',' , $params['list_ids']);
|
104 |
+
}
|
105 |
+
$args = array_merge( $params , $_GET );
|
106 |
+
$token = Inbound_API::analytics_get_tracking_code( $args );
|
107 |
+
|
108 |
+
if(!defined('INBOUND_PRO_CURRENT_VERSION')){
|
109 |
+
$double_optin_page_id = get_option('list-double-optin-page-id', '');
|
110 |
+
}else{
|
111 |
+
$settings = Inbound_Options_API::get_option('inbound-pro', 'settings', array());
|
112 |
+
$double_optin_page_id = $settings['leads']['list-double-optin-page-id'];
|
113 |
+
}
|
114 |
+
|
115 |
+
if ( empty($double_optin_page_id) ) {
|
116 |
+
$post = get_page_by_title( __( 'Confirm Subscription' , 'inbound-pro' ) );
|
117 |
+
$double_optin_page_id = $post->ID;
|
118 |
+
}
|
119 |
+
|
120 |
+
$base_url = get_permalink( $double_optin_page_id );
|
121 |
+
|
122 |
+
return add_query_arg( array( 'token'=>$token , 'inbound-action' => 'confirm' ) , $base_url );
|
123 |
+
}
|
124 |
+
|
125 |
+
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Decodes confirm token into an array of parameters
|
129 |
+
* @param STRING $reader_id Encoded lead id.
|
130 |
+
* @return ARRAY $confirm array of confirmation data
|
131 |
+
*/
|
132 |
+
public static function decode_confirm_token( $token ) {
|
133 |
+
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
|
134 |
+
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
|
135 |
+
$decrypted_string =
|
136 |
+
trim(
|
137 |
+
mcrypt_decrypt(
|
138 |
+
MCRYPT_RIJNDAEL_256 , substr( SECURE_AUTH_KEY , 0 , 16 ) , base64_decode( str_replace(array('-', '_', '^'), array('+', '/', '='), $token ) ) , MCRYPT_MODE_ECB, $iv
|
139 |
+
)
|
140 |
+
);
|
141 |
+
return json_decode($decrypted_string , true);
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* Adds the lead to lists he selected when filling out the confirmation form.
|
146 |
+
* If all_lists was selected, all lists currently waiting for confirmation will be selected and the lead will be added to those.
|
147 |
+
*/
|
148 |
+
public static function confirm_being_added_to_lists($params, $all = false){
|
149 |
+
|
150 |
+
/*get the double optin waiting list id*/
|
151 |
+
if(!defined('INBOUND_PRO_CURRENT_VERSION')){
|
152 |
+
$double_optin_list_id = get_option('list-double-optin-list-id', '');
|
153 |
+
}else{
|
154 |
+
$settings = Inbound_Options_API::get_option('inbound-pro', 'settings', array());
|
155 |
+
$double_optin_list_id = $settings['leads']['list-double-optin-list-id'];
|
156 |
+
}
|
157 |
+
|
158 |
+
|
159 |
+
/*get the lists waiting to be opted into*/
|
160 |
+
$stored_double_optin_lists = get_post_meta($params['lead_id'], 'double_optin_lists', true);
|
161 |
+
|
162 |
+
/*if there aren't any lists, exit*/
|
163 |
+
if(empty($stored_double_optin_lists)){
|
164 |
+
return;
|
165 |
+
}
|
166 |
+
|
167 |
+
/*if opt into all lists has been selected, set list ids to all stored list ids*/
|
168 |
+
if($all){
|
169 |
+
$params['list_ids'] = $stored_double_optin_lists;
|
170 |
+
}
|
171 |
+
|
172 |
+
/**for each supplied list, add the lead to the list.
|
173 |
+
* And remove the list id from the array of lists needing to be opted into**/
|
174 |
+
foreach($params['list_ids'] as $list_id){
|
175 |
+
Inbound_Leads::add_lead_to_list($params['lead_id'], $list_id);
|
176 |
+
|
177 |
+
if(in_array($list_id, $stored_double_optin_lists)){
|
178 |
+
$index = array_search($list_id, $stored_double_optin_lists);
|
179 |
+
unset($stored_double_optin_lists[$index]);
|
180 |
+
}
|
181 |
+
}
|
182 |
+
|
183 |
+
/**if there are still lists awaiting double optin confirmation after the "waiting" meta listing has been updated**/
|
184 |
+
if(!empty($stored_double_optin_lists)){
|
185 |
+
/*update the "waiting" meta listing with the remaining lists*/
|
186 |
+
update_post_meta($params['lead_id'], 'double_optin_lists', array_values($stored_double_optin_lists));
|
187 |
+
}else{
|
188 |
+
/**if there are no lists awaiting double optin confirmation**/
|
189 |
+
/*remove the meta listing for double optin*/
|
190 |
+
delete_post_meta($params['lead_id'], 'double_optin_lists');
|
191 |
+
/*remove this lead from the double optin list*/
|
192 |
+
wp_remove_object_terms($params['lead_id'], $double_optin_list_id, 'wplead_list_category');
|
193 |
+
/*update the lead status*/
|
194 |
+
update_post_meta( $params['lead_id'], 'wp_lead_status', 'active');
|
195 |
+
}
|
196 |
+
}
|
197 |
+
}
|
198 |
+
new Inbound_Confirm_Double_Optin;
|
199 |
+
|
200 |
+
}
|
shared/classes/class.database-routines.php
CHANGED
@@ -1,312 +1,314 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
static $
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
*
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
'
|
43 |
-
'
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
'
|
51 |
-
'
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
'
|
59 |
-
'
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
'
|
67 |
-
'
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
'
|
75 |
-
'
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
'
|
84 |
-
'
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
'
|
92 |
-
'
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
&&
|
113 |
-
!
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
$wpdb->get_results(
|
169 |
-
}
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
$
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
$
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
$
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
$
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class for defining and loading shared database routines
|
5 |
+
* @package Shared
|
6 |
+
* @subpackage DatabaseRoutines
|
7 |
+
*/
|
8 |
+
if ( !class_exists('Inbound_Upgrade_Routines') ) {
|
9 |
+
|
10 |
+
class Inbound_Upgrade_Routines {
|
11 |
+
static $routines;
|
12 |
+
static $past_version;
|
13 |
+
static $current_version;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Run upgrade routines defined in this class
|
17 |
+
*/
|
18 |
+
public static function load() {
|
19 |
+
self::define_routines();
|
20 |
+
self::load_routines();
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Add fallback listener to make sure database upgrade routines are ran even if the activation protocol does not fire.
|
25 |
+
* This function compares the shared files version in the database to the INBOUNDNOW_SHARED_DBRV constant. If they aren't the same then it runs the routines.
|
26 |
+
*
|
27 |
+
*/
|
28 |
+
public static function add_update_check() {
|
29 |
+
self::set_versions( array('scope'=>'shared') );
|
30 |
+
if ( self::$past_version != self::$current_version ) {
|
31 |
+
self::load();
|
32 |
+
}
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Defines upgrade routines to run.
|
37 |
+
*/
|
38 |
+
public static function define_routines() {
|
39 |
+
|
40 |
+
/* alter page view table */
|
41 |
+
self::$routines['page-views-table-1'] = array(
|
42 |
+
'id' => 'page-views-table-1',
|
43 |
+
'scope' => 'shared',
|
44 |
+
'introduced' => '1.0.2',
|
45 |
+
'callback' => array( __CLASS__ , 'alter_page_views_table_1')
|
46 |
+
);
|
47 |
+
|
48 |
+
/* alter page view table */
|
49 |
+
self::$routines['events-table-1'] = array(
|
50 |
+
'id' => 'events-table-1',
|
51 |
+
'scope' => 'shared',
|
52 |
+
'introduced' => '1.0.2',
|
53 |
+
'callback' => array( __CLASS__ , 'alter_events_table_1')
|
54 |
+
);
|
55 |
+
|
56 |
+
/* alter events table */
|
57 |
+
self::$routines['events-table-2'] = array(
|
58 |
+
'id' => 'events-table-2',
|
59 |
+
'scope' => 'shared',
|
60 |
+
'introduced' => '1.0.5',
|
61 |
+
'callback' => array( __CLASS__ , 'alter_events_table_1_0_5')
|
62 |
+
);
|
63 |
+
|
64 |
+
/* alter events table */
|
65 |
+
self::$routines['events-table-3'] = array(
|
66 |
+
'id' => 'events-table-3',
|
67 |
+
'scope' => 'shared',
|
68 |
+
'introduced' => '1.0.8',
|
69 |
+
'callback' => array( __CLASS__ , 'alter_events_table_1_0_8')
|
70 |
+
);
|
71 |
+
|
72 |
+
/* alter automation queue table */
|
73 |
+
self::$routines['automation-queue-table-1'] = array(
|
74 |
+
'id' => 'automation-queue-table-1',
|
75 |
+
'scope' => 'shared',
|
76 |
+
'introduced' => '1.0.3',
|
77 |
+
'callback' => array( __CLASS__ , 'alter_automation_queue_table_1')
|
78 |
+
);
|
79 |
+
|
80 |
+
|
81 |
+
/* alter events table */
|
82 |
+
self::$routines['events-pageviews-107'] = array(
|
83 |
+
'id' => 'events-pageviews-107',
|
84 |
+
'scope' => 'shared',
|
85 |
+
'introduced' => '1.0.7',
|
86 |
+
'callback' => array( __CLASS__ , 'alter_events_pageviews_107')
|
87 |
+
);
|
88 |
+
|
89 |
+
/* alter events table */
|
90 |
+
self::$routines['inbound-settings-109'] = array(
|
91 |
+
'id' => 'inbound-settings-109',
|
92 |
+
'scope' => 'shared',
|
93 |
+
'introduced' => '1.0.9',
|
94 |
+
'callback' => array( __CLASS__ , 'alter_inbound_settings_109')
|
95 |
+
);
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
*
|
100 |
+
*/
|
101 |
+
public static function load_routines() {
|
102 |
+
|
103 |
+
self::$routines = apply_filters( 'inbound-pro/upgrade-routines' , self::$routines);
|
104 |
+
|
105 |
+
foreach (self::$routines as $routine) {
|
106 |
+
/* set versions int static vars */
|
107 |
+
self::set_versions($routine);
|
108 |
+
|
109 |
+
/* compare versions and see last installed version is beneath the introduced version */
|
110 |
+
if (
|
111 |
+
self::$past_version
|
112 |
+
&&
|
113 |
+
!version_compare( self::$past_version , $routine['introduced'] , '<')
|
114 |
+
&&
|
115 |
+
!isset($_GET['force_upgrade_routines'])
|
116 |
+
) {
|
117 |
+
continue;
|
118 |
+
}
|
119 |
+
|
120 |
+
/* run the routine */
|
121 |
+
call_user_func(array($routine['callback'][0] , $routine['callback'][1]) );
|
122 |
+
}
|
123 |
+
|
124 |
+
/* set shared version transient */
|
125 |
+
update_option('inbound_shared_version' , INBOUNDNOW_SHARED_DBRV , false);
|
126 |
+
}
|
127 |
+
|
128 |
+
|
129 |
+
/**
|
130 |
+
* @param $routine
|
131 |
+
*/
|
132 |
+
public static function set_versions( $routine ) {
|
133 |
+
switch($routine['scope']) {
|
134 |
+
case 'shared':
|
135 |
+
self::$past_version = get_option('inbound_shared_version');
|
136 |
+
self::$current_version = INBOUNDNOW_SHARED_DBRV;
|
137 |
+
break;
|
138 |
+
case 'leads':
|
139 |
+
self::$past_version = get_transient('leads_shared_version');
|
140 |
+
self::$current_version = WPL_CURRENT_VERSION;
|
141 |
+
break;
|
142 |
+
case 'landing-pages':
|
143 |
+
self::$past_version = get_transient('lp_current_version');
|
144 |
+
self::$current_version = LANDINGPAGES_CURRENT_VERSION;
|
145 |
+
break;
|
146 |
+
case 'cta':
|
147 |
+
self::$past_version = get_transient('cta_current_version');
|
148 |
+
self::$current_version = WP_CTA_CURRENT_VERSION;
|
149 |
+
break;
|
150 |
+
}
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Alter pageview table from INT to VARCHARR
|
155 |
+
* @param $routines
|
156 |
+
*/
|
157 |
+
public static function alter_page_views_table_1() {
|
158 |
+
global $wpdb;
|
159 |
+
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
160 |
+
|
161 |
+
$table_name = $wpdb->prefix . "inbound_page_views";
|
162 |
+
|
163 |
+
/* add ip field if does not exist */
|
164 |
+
|
165 |
+
$col_check = $wpdb->get_row("SELECT * FROM " . $table_name ." limit 1");
|
166 |
+
|
167 |
+
if(!isset($col_check->ip)) {
|
168 |
+
$wpdb->get_results("ALTER TABLE {$table_name} ADD `ip` VARCHAR(45) NOT NULL");
|
169 |
+
} else {
|
170 |
+
$wpdb->get_results( "ALTER TABLE {$table_name} MODIFY COLUMN `ip` VARCHAR(45)" );
|
171 |
+
}
|
172 |
+
|
173 |
+
}
|
174 |
+
|
175 |
+
/**
|
176 |
+
* @migration-type: alter inbound_events table
|
177 |
+
* @mirgration: adds columns list_id funnel, and source to events table
|
178 |
+
*/
|
179 |
+
public static function alter_events_table_1() {
|
180 |
+
|
181 |
+
global $wpdb;
|
182 |
+
|
183 |
+
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
184 |
+
$table_name = $wpdb->prefix . "inbound_events";
|
185 |
+
|
186 |
+
$col_check = $wpdb->get_row("SELECT * FROM " . $table_name ." limit 1");
|
187 |
+
|
188 |
+
if(!isset($col_check->funnel)) {
|
189 |
+
$wpdb->get_results("ALTER TABLE {$table_name} ADD `funnel` text NOT NULL");
|
190 |
+
}
|
191 |
+
|
192 |
+
if(!isset($col_check->source)) {
|
193 |
+
$wpdb->get_results("ALTER TABLE {$table_name} ADD `source` text NOT NULL");
|
194 |
+
}
|
195 |
+
|
196 |
+
if(!isset($col_check->list_id)) {
|
197 |
+
$wpdb->get_results("ALTER TABLE {$table_name} ADD `list_id` mediumint(20) NOT NULL");
|
198 |
+
}
|
199 |
+
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* @migration-type: alter inbound_events table
|
204 |
+
* @mirgration: adds columns list_id funnel, and source to events table
|
205 |
+
*/
|
206 |
+
public static function alter_events_table_1_0_5() {
|
207 |
+
|
208 |
+
global $wpdb;
|
209 |
+
|
210 |
+
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
211 |
+
$table_name = $wpdb->prefix . "inbound_events";
|
212 |
+
|
213 |
+
$col_check = $wpdb->get_row("SELECT * FROM " . $table_name ." limit 1");
|
214 |
+
|
215 |
+
if(!isset($col_check->rule_id)) {
|
216 |
+
$wpdb->get_results("ALTER TABLE {$table_name} ADD `rule_id` mediumint(20) NOT NULL");
|
217 |
+
}
|
218 |
+
|
219 |
+
if(!isset($col_check->job_id)) {
|
220 |
+
$wpdb->get_results("ALTER TABLE {$table_name} ADD `job_id` mediumint(20) NOT NULL");
|
221 |
+
}
|
222 |
+
}
|
223 |
+
|
224 |
+
|
225 |
+
/**
|
226 |
+
* @migration-type: alter inbound_events table
|
227 |
+
* @mirgration: adds columns list_id funnel, and source to events table
|
228 |
+
*/
|
229 |
+
public static function alter_events_table_1_0_8() {
|
230 |
+
|
231 |
+
global $wpdb;
|
232 |
+
|
233 |
+
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
234 |
+
$table_name = $wpdb->prefix . "inbound_events";
|
235 |
+
|
236 |
+
$col_check = $wpdb->get_row("SELECT * FROM " . $table_name ." limit 1");
|
237 |
+
|
238 |
+
if(!isset($col_check->comment_id)) {
|
239 |
+
$wpdb->get_results("ALTER TABLE {$table_name} ADD `comment_id` mediumint(20) NOT NULL");
|
240 |
+
}
|
241 |
+
}
|
242 |
+
|
243 |
+
/**
|
244 |
+
* @migration-type: alter inbound_events,inbound_pageviews table
|
245 |
+
* @mirgration: convert page_id to VARCHAR to accept complex ids related to taxonomy archives
|
246 |
+
*/
|
247 |
+
public static function alter_events_pageviews_107() {
|
248 |
+
|
249 |
+
global $wpdb;
|
250 |
+
|
251 |
+
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
252 |
+
|
253 |
+
/* events table */
|
254 |
+
$table_name = $wpdb->prefix . "inbound_events";
|
255 |
+
$wpdb->get_results( "ALTER TABLE {$table_name} MODIFY COLUMN `page_id` VARCHAR(20)" );
|
256 |
+
|
257 |
+
/* pageviews table */
|
258 |
+
$table_name = $wpdb->prefix . "inbound_page_views";
|
259 |
+
$wpdb->get_results( "ALTER TABLE {$table_name} MODIFY COLUMN `page_id` VARCHAR(20)" );
|
260 |
+
}
|
261 |
+
|
262 |
+
|
263 |
+
/**
|
264 |
+
* @migration-type: alter inbound_automation_queue table
|
265 |
+
* @mirgration: adds columns lead_id
|
266 |
+
*/
|
267 |
+
public static function alter_automation_queue_table_1() {
|
268 |
+
|
269 |
+
global $wpdb;
|
270 |
+
|
271 |
+
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
272 |
+
$table_name = $wpdb->prefix . "inbound_automation_queue";
|
273 |
+
|
274 |
+
$col_check = $wpdb->get_row("SELECT * FROM " . $table_name ." limit 1");
|
275 |
+
|
276 |
+
if(!isset($col_check->lead_id)) {
|
277 |
+
$wpdb->get_results("ALTER TABLE {$table_name} ADD `lead_id` mediumint(20) NOT NULL");
|
278 |
+
}
|
279 |
+
}
|
280 |
+
|
281 |
+
|
282 |
+
/**
|
283 |
+
* @migration-type: inbound pro settings array
|
284 |
+
* @mirgration: change the 'mailer' key to 'mailer' key in $inbound_settings
|
285 |
+
*/
|
286 |
+
public static function alter_inbound_settings_109() {
|
287 |
+
if (class_exists('Inbound_Options_API')) {
|
288 |
+
$inbound_settings = Inbound_Options_API::get_option('inbound-pro', 'settings', array());
|
289 |
+
$inbound_settings['mailer'] = (isset($inbound_settings['inbound-mailer'])) ? $inbound_settings['inbound-mailer'] : array();
|
290 |
+
unset($inbound_settings['inbound-mailer']);
|
291 |
+
Inbound_Options_API::update_option('inbound-pro', 'settings', $inbound_settings);
|
292 |
+
}
|
293 |
+
}
|
294 |
+
}
|
295 |
+
|
296 |
+
/* set fallback action in case routines do not run via activation */
|
297 |
+
add_action('admin_init' , array( 'Inbound_Upgrade_Routines' , 'add_update_check') );
|
298 |
+
|
299 |
+
|
300 |
+
/**
|
301 |
+
* Listen for Database Repair Call
|
302 |
+
*/
|
303 |
+
if (isset($_REQUEST['force_upgrade_routines']) && $_REQUEST['force_upgrade_routines'] ) {
|
304 |
+
Inbound_Events::create_page_views_table();
|
305 |
+
Inbound_Events::create_events_table();
|
306 |
+
if (class_exists('Inbound_Automation_Activation')) {
|
307 |
+
Inbound_Automation_Activation::create_automation_queue_table();
|
308 |
+
}
|
309 |
+
if (class_exists('Inbound_Mailer_Activation')) {
|
310 |
+
Inbound_Mailer_Activation::create_email_queue_table();
|
311 |
+
}
|
312 |
+
Inbound_Upgrade_Routines:
|