PluginProbe
Outfunnel: Web Visitor Tracking & CRM Integration / trunk
Outfunnel: Web Visitor Tracking & CRM Integration vtrunk
trunk 1.0.0 1.1.0 1.1.1 1.2.0 1.2.3 1.3.0 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 2.0.0 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 All 38 releases
outfunnel / outfunnel.php

outfunnel.php in Outfunnel: Web Visitor Tracking & CRM Integration trunk, at outfunnel.php

505 lines 17.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Outfunnel: Web Visitor Tracking & CRM Integration
4 Version: 2.9.6
5 Author: Outfunnel
6 Author URI: https://outfunnel.com/
7 Description: Easily sync leads from various Wordpress forms to Pipedrive, Copper, HubSpot and other CRMs. Includes web visitor tracking.
8 Text Domain: outfunnel
9 Domain Path: /languages
10 */
11
12 namespace Outfunnel;
13
14 use Outfunnel\Forms\ContactForm7;
15 use Outfunnel\Forms\Elementor;
16 use Outfunnel\Forms\GravityPlugin;
17 use Outfunnel\Forms\Form;
18 use Outfunnel\Forms\Logger;
19
20 include 'autoloader.php';
21
22 if (!defined('ABSPATH')) {
23 exit;
24 }
25
26 if (!class_exists('OUTFUNNEL')) {
27
28 class OUTFUNNEL {
29
30 public $plugin_version = '2.9.6';
31
32 /**
33 * @var Form
34 */
35 private $elementor;
36
37 /**
38 * @var Form
39 */
40 private $contact_form_7;
41
42 /**
43 * @var Form
44 */
45 private $gravity;
46
47 public function __construct() {
48 Autoloader::init();
49
50 if (!defined('OUTFUNNEL_VERSION')) {
51 define('OUTFUNNEL_VERSION', $this->plugin_version);
52 }
53
54 if (!defined('WORDPRESS_VERSION')) {
55 define('WORDPRESS_VERSION', $this->get_current_wp_version());
56 }
57
58 if (!defined('OF_APP_URL')) {
59 define('OF_APP_URL', 'https://app.outfunnel.com');
60 }
61
62 if (!defined('OF_API_URL')) {
63 define('OF_API_URL', 'https://api.outfunnel.com');
64 }
65
66 if (!defined('OF_CDN_URL')) {
67 define('OF_CDN_URL', 'https://cdn.outfunnel.com');
68 }
69
70 if (!defined('OF_WEBHOOK_URL')) {
71 define('OF_WEBHOOK_URL', 'https://push.outfunnel.com');
72 }
73
74 if (!defined('OF_TEXT_DOMAIN')) {
75 define('OF_TEXT_DOMAIN', 'outfunnel');
76 }
77
78 if (!defined('OF_SUPPORTED_FORM_SOURCES')) {
79 define('OF_SUPPORTED_FORM_SOURCES', ['elementor', 'contact-form-7', 'gravity']);
80 }
81
82 $this->plugin_includes();
83 }
84
85
86 /**
87 * @return String|null
88 */
89 private function get_current_wp_version() {
90 return get_bloginfo( 'version' );
91 }
92
93 private function get_logging_data($of_account_email, $of_api_key) {
94 $response = wp_remote_get(OF_API_URL . '/v1/wordpress/config', [
95 'headers' => [
96 'Content-Type' => 'application/json',
97 'x-account-email' => $of_account_email,
98 'x-api-key' => $of_api_key
99 ],
100 ]);
101
102 if (!in_array($response['response']['code'], [200, 201], true)) {
103 $type = 'error';
104 $message = __('Something went wrong', OF_TEXT_DOMAIN);
105 $body = json_decode($response['body']);
106
107 if (count($body->errors)) {
108 $message = $body->errors[0]->message;
109 }
110
111 add_settings_error(
112 'outfunnel_settings',
113 esc_attr('settings_updated'),
114 $message,
115 $type
116 );
117
118 return null;
119 }
120
121 $response_payload = json_decode($response['body'], true)['data'];
122
123 return [
124 'logging_url' => $response_payload['loggingUrl'],
125 'logging_api_key' => $response_payload['apiKey'],
126 'expires_at' => $response_payload['expiresAt']
127 ];
128 }
129
130 public function plugin_includes() {
131 if (is_admin()) {
132 add_filter('plugin_action_links', [$this, 'plugin_action_links'], 10, 2);
133 }
134 add_action('rest_api_init', [$this, 'rest_api_init']);
135 add_action('plugins_loaded', [$this, 'plugins_loaded_handler']);
136 add_action('admin_init', [$this, 'settings_api_init']);
137 add_action('admin_menu', [$this, 'add_options_menu']);
138 add_action('wp_head', [$this, 'add_tracking_code']);
139
140 add_action('activated_plugin', [$this, 'activation_redirect']);
141 }
142
143 public function activation_redirect($plugin) {
144 // $plugin should be "outfunnel/outfunnel.php"
145 if ($plugin == plugin_basename(__FILE__)) {
146 exit(wp_redirect(admin_url('options-general.php?page=outfunnel-settings')));
147 }
148 }
149
150 public function plugins_loaded_handler() {
151 load_plugin_textdomain('outfunnel', false, dirname(plugin_basename(__FILE__)) . '/languages/');
152
153 $this->elementor = Elementor::instance();
154 $this->contact_form_7 = ContactForm7::instance();
155 $this->gravity = GravityPlugin::instance();
156 }
157
158 public function plugin_url() {
159 if ($this->plugin_url) {
160 return $this->plugin_url;
161 }
162
163 return $this->plugin_url = plugins_url(basename(plugin_dir_path(__FILE__)), basename(__FILE__));
164 }
165
166 public function plugin_action_links($links, $file) {
167 if ($file == plugin_basename(dirname(__FILE__) . '/outfunnel.php')) {
168 $links[] = '<a href="options-general.php?page=outfunnel-settings">' . __('Settings', 'outfunnel') . '</a>';
169 }
170
171 return $links;
172 }
173
174 private function get_active_form_sources() {
175 return array_filter(OF_SUPPORTED_FORM_SOURCES, function($source) {
176 return $this->get_form_source($source) && $this->get_form_source($source)->is_form_plugin_active();
177 });
178 }
179
180 private function get_form_source($form_source) {
181 $source = str_replace('-', '_', $form_source);
182
183 if ($this->$source) {
184 return $this->$source;
185 }
186
187 return null;
188 }
189
190 public function get_all_forms($request) {
191 $form_source = $this->get_form_source($request['form_source']);
192
193 if ($form_source === null) {
194 return [
195 'errors' => [[
196 error => 'required_form_plugin_not_active',
197 message => 'Required form plugin not active',
198 context => 'form_source',
199 ]],
200 ];
201 }
202
203 return $form_source->get_all_forms();
204 }
205
206 public function rest_api_init() {
207 register_rest_route(
208 'outfunnel/v2',
209 '/form-sources/(?P<form_source>[a-zA-Z0-9_-]+)/forms',
210 [
211 'methods' => 'GET',
212 'callback' => [$this, 'get_all_forms'],
213 'permission_callback' => [$this, 'check_outfunnel_api_key'],
214 'args' => [
215 'form_source' => [
216 'required' => true,
217 'validate_callback' => function($param, $request, $key) {
218 return in_array($param, OF_SUPPORTED_FORM_SOURCES);
219 },
220 ]
221 ]
222 ]
223 );
224 }
225
226 public function add_options_menu() {
227 if (is_admin()) {
228 add_options_page(__('Outfunnel', 'outfunnel'), __('Outfunnel', 'outfunnel'), 'manage_options', 'outfunnel-settings', [$this, 'options_page']);
229 }
230 }
231
232 public function settings_api_init() {
233 register_setting('outfunnelpage', 'outfunnel_settings', [
234 'sanitize_callback' => [$this, 'outfunnel_settings_save_callback']
235 ]);
236
237 add_settings_section(
238 'outfunnel_tracking_section',
239 __('Web tracking configuration', 'outfunnel'),
240 [$this, 'outfunnel_tracking_settings_section_callback'],
241 'outfunnelpage'
242 );
243
244 add_settings_field(
245 'of_id',
246 __('Tracking ID', 'outfunnel'),
247 [$this, 'of_id_field'],
248 'outfunnelpage',
249 'outfunnel_tracking_section'
250 );
251
252 add_settings_section(
253 'outfunnel_forms_section',
254 __('Web forms integration', 'outfunnel'),
255 [$this, 'outfunnel_forms_settings_section_callback'],
256 'outfunnelpage'
257 );
258
259 add_settings_field(
260 'of_account_email',
261 __('Account email', 'outfunnel'),
262 [$this, 'of_account_email_field'],
263 'outfunnelpage',
264 'outfunnel_forms_section'
265 );
266
267 add_settings_field(
268 'of_api_key',
269 __('API key', 'outfunnel'),
270 [$this, 'of_api_key_field'],
271 'outfunnelpage',
272 'outfunnel_forms_section'
273 );
274
275 add_settings_section(
276 'outfunnel_log_section',
277 __('Logging', 'outfunnel'),
278 [$this, 'outfunnel_log_settings_section_callback'],
279 'outfunnelpage'
280 );
281
282 add_settings_field(
283 'of_enable_logging',
284 'Enable Logging',
285 [$this, 'of_enable_logging'],
286 'outfunnelpage',
287 'outfunnel_log_section'
288 );
289
290 }
291
292 public function options_page() {
293 ?>
294 <div class="wrap">
295 <h2>Outfunnel Web Tracking - v<?=OUTFUNNEL_VERSION?></h2>
296
297 <form action='options.php' method='post'>
298 <?php
299 settings_fields('outfunnelpage');
300 do_settings_sections('outfunnelpage');
301 submit_button();
302 ?>
303 </form>
304 </div>
305 <?php
306 }
307
308 public function outfunnel_settings_save_callback($data) {
309 if (empty($data['of_api_key'])) {
310 return $data;
311 }
312
313 $form_sources = $this->get_active_form_sources();
314
315 if (!count($form_sources)) {
316 $faq_url = 'https://support.outfunnel.com/en/articles/5234038-wordpress-forms-crm-integration';
317 add_settings_error(
318 'outfunnel_settings',
319 esc_attr('settings_updated'),
320 sprintf(
321 wp_kses(
322 __('Did not find any active form plugins. Please install and activate a <a target="_blank" href="%s">supported form plugin</a>', OF_TEXT_DOMAIN),
323 ['a' => ['href' => [], 'target' => []]]
324 ), esc_url($faq_url)
325 ),
326 'error'
327 );
328
329 return $data;
330 }
331
332 $site_url = get_site_url();
333
334 foreach($form_sources as $source) {
335 $response = wp_remote_post(OF_API_URL . '/v1/integrations', [
336 'headers' => [
337 'Content-Type' => 'application/json',
338 'x-account-email' => $data['of_account_email'],
339 'x-api-key' => $data['of_api_key']
340 ],
341 'body' => wp_json_encode([
342 'integration' => $source,
343 'siteUrl' => $site_url,
344 'formPluginVersion' => $this->get_form_source($source)->get_plugin_version(),
345 'formPluginName' => $this->get_form_source($source)->get_plugin_name(),
346 'wpVersion' => WORDPRESS_VERSION,
347 'ofPluginVersion' => OUTFUNNEL_VERSION
348 ]),
349 ]);
350
351 if (is_wp_error($response)) {
352 $type = 'error';
353 $message = $response->get_error_message();
354
355 add_settings_error(
356 'outfunnel_settings',
357 esc_attr('settings_updated'),
358 $message,
359 $type
360 );
361
362 return $data;
363 }
364
365 if (!in_array($response['response']['code'], [200, 201], true)) {
366 $type = 'error';
367 $message = __('Something went wrong', OF_TEXT_DOMAIN);
368 $body = json_decode($response['body']);
369
370 if (count($body->errors)) {
371 $message = $body->errors[0]->message;
372 }
373
374 add_settings_error(
375 'outfunnel_settings',
376 esc_attr('settings_updated'),
377 $message,
378 $type
379 );
380
381 return $data;
382 }
383 }
384
385 if (!empty($data['of_enable_logging'])) {
386 $logging_data = $this::get_logging_data($data['of_account_email'], $data['of_api_key']);
387
388 $data['logging_url'] = $logging_data['logging_url'];
389 $data['logging_api_key'] = $logging_data['logging_api_key'];
390 $data['logging_api_key_expiration'] = $logging_data['expires_at'];
391 }
392
393 return $data;
394 }
395
396 public function outfunnel_tracking_settings_section_callback() {
397 $config = get_option('outfunnel_settings');
398 $of_id = $config['of_id'];
399 $url = OF_APP_URL . '/web-tracking';
400 echo sprintf(wp_kses(__('Outfunnel\'s <a target="_blank" href="%s">Web tracking</a> shows you which leads are visiting your website, where they come from, and which pages they\'ve been on. Add the tracking ID of your Outfunnel account to enable.', 'outfunnel'), ['a' => ['href' => [], 'target' => []]]), esc_url($url));
401 }
402
403 public function of_id_field() {
404 $outfunnel_settings = get_option('outfunnel_settings');
405 $of_id = $outfunnel_settings['of_id'];
406 ?>
407 <input type='text' name='outfunnel_settings[of_id]' value='<?=esc_attr($of_id);?>' placeholder='ie. 5b5c331c27d95c39e42a09d3' class="regular-text code">
408 <p class="description"><?=__('Enter your Outfunnel Tracking ID for this website', OF_TEXT_DOMAIN);?></p>
409 <?php
410 }
411
412 public function outfunnel_forms_settings_section_callback() {
413 $config = get_option('outfunnel_settings');
414 $of_id = $config['of_id'];
415 $url = OF_APP_URL . '/connections';
416 echo sprintf(wp_kses(__('Outfunnel\'s <a target="_blank" href="%s">App connector</a> records Wordpress form submissions in your CRM. Add the account email and API key of your Outfunnel account to enable.', OF_TEXT_DOMAIN), ['a' => ['href' => [], 'target' => []]]), esc_url($url));
417 }
418
419 public function outfunnel_log_settings_section_callback() {
420 echo wp_kses('Enable sending logs to Outfunnel', []);
421 }
422
423 public function of_account_email_field() {
424 $outfunnel_settings = get_option('outfunnel_settings');
425 $of_account_email = $outfunnel_settings['of_account_email'];
426 ?>
427 <input type='text' name='outfunnel_settings[of_account_email]' value='<?=esc_attr($of_account_email);?>' placeholder='ie. example@example.com' class="regular-text code">
428 <p class="description"><?=__('Enter your Outfunnel account email', OF_TEXT_DOMAIN);?></p>
429 <?php
430 }
431
432 public function of_enable_logging() {
433 $outfunnel_settings = get_option('outfunnel_settings');
434 $of_enable_logging = isset($outfunnel_settings['of_enable_logging']) && $outfunnel_settings['of_enable_logging'] === "on";
435
436 echo '<input type="checkbox" name="outfunnel_settings[of_enable_logging]"' . checked( 1, $of_enable_logging, false ) . '/>';
437 }
438
439 public function of_api_key_field() {
440 $outfunnel_settings = get_option('outfunnel_settings');
441 $of_api_key = $outfunnel_settings['of_api_key'];
442 ?>
443 <input type='text' name='outfunnel_settings[of_api_key]' value='<?=esc_attr($of_api_key);?>' placeholder='ie. 5c419ca4a2f010de1762a8a44f3012ee8b829084553b1be83eaa94d498e7f07d' class="regular-text code">
444 <p class="description"><?=__('Enter your Outfunnel API key', OF_TEXT_DOMAIN);?></p>
445 <?php
446 }
447
448 public function check_outfunnel_api_key($request) {
449 $outfunnel_settings = get_option('outfunnel_settings');
450
451 if (!$outfunnel_settings) {
452 return false;
453 }
454
455 $api_key = $request->get_header('x-api-key');
456 $account_email = $request->get_header('x-account-email');
457
458 if (!$api_key || !$account_email) {
459 return false;
460 }
461
462 $of_api_key = $outfunnel_settings['of_api_key'];
463 $of_account_email = $outfunnel_settings['of_account_email'];
464
465 if (!$of_api_key || !$of_account_email) {
466 return false;
467 }
468
469 $is_request_authorized = $api_key == $of_api_key
470 && $of_account_email == $account_email;
471
472 return $is_request_authorized;
473 }
474
475 public function add_tracking_code() {
476
477 $outfunnel_settings = get_option('outfunnel_settings');
478 $of_id = $outfunnel_settings['of_id'];
479
480 if (!empty($of_id)) {
481 ?>
482
483 <!-- Generated with Outfunnel Web Tracking plugin v<?=$this->plugin_version?> -->
484 <script>
485 window.OFID = "<?=htmlspecialchars($of_id)?>";
486 window.OF_WP_VERSION = "<?=$this->plugin_version?>";
487 (function(){
488 var script = document.createElement('script');
489 var url = '<?=esc_attr(OF_CDN_URL)?>/c.js?v='+ new Date().toISOString().substring(0,10);
490 script.setAttribute('src', url);
491 document.getElementsByTagName('head')[0].appendChild(script);
492 })();
493 </script>
494 <!-- / Outfunnel Web Tracking plugin -->
495
496 <?php
497
498 // empty line after <?php needed for indentation
499 }
500 }
501 }
502
503 $GLOBALS['outfunnel'] = new OUTFUNNEL();
504 }
505