PluginProbe
Connector for Gravity Forms and Google Sheets / 1.2.4
Connector for Gravity Forms and Google Sheets v1.2.4
1.3.0 trunk 1.0.2 1.0.3 1.0.4 1.0.7 1.1.1 1.2.0 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9
wp-gravity-forms-spreadsheets / wp-gravity-forms-spreadsheets.php

wp-gravity-forms-spreadsheets.php in Connector for Gravity Forms and Google Sheets 1.2.4, at wp-gravity-forms-spreadsheets.php

1,845 lines 63.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: Connector for Gravity Forms and Google Sheets
4 * Description: Integrates Gravity Forms with Google Sheets allowing form submissions to be automatically sent to your Google Sheets.
5 * Version: 1.2.4
6 * Requires at least: 3.8
7 * Author URI: https://www.crmperks.com
8 * Plugin URI: https://www.crmperks.com/plugins/gravity-forms-plugins/gravity-forms-google-sheets-plugin/
9 * Author: CRM Perks.
10 * Text Domain: gravity-forms-googlesheets-crm
11 * Domain Path: /languages/
12 */
13 // Exit if accessed directly
14 if( !defined( 'ABSPATH' ) ) exit;
15
16
17 if( !class_exists( 'vxg_googlesheets' ) ):
18
19 class vxg_googlesheets {
20
21
22 public $url = 'https://www.crmperks.com';
23
24 public $crm_name = 'googlesheets';
25 public $id = 'vxg_googlesheets';
26 public $domain = 'vxg-gsheets';
27 public $version = "1.2.4";
28 public $update_id = '30021';
29 public $min_gravityforms_version = '1.3.9';
30 public $type = 'vxg_googlesheets_pro';
31 public $fields = null;
32 public $data = null;
33
34 private $filter_condition;
35 private $plugin_dir= '';
36 private $temp= '';
37 private $crm_arr= false;
38 private $entry;
39 private $form;
40 public $notice_js= false;
41 public static $title='Gravity Forms Google Sheets Plugin';
42 public static $path = '';
43 public static $slug = '';
44 public static $debug_html = '';
45 public static $save_key='';
46 public static $lic_msg = '';
47 public static $db_version='';
48 public static $vx_plugins;
49 public static $note;
50 public static $feeds_res;
51 public static $gf_status='';
52 public static $plugin='';
53 public static $gf_status_msg='';
54 public static $is_pr=true;
55 public static $api_timeout;
56
57 public function instance(){
58 self::$path=$this->get_base_path();
59 add_action( 'plugins_loaded', array( $this, 'setup_main' ) );
60 register_deactivation_hook(__FILE__,array($this,'deactivate'));
61 register_activation_hook(__FILE__,(array($this,'activate')));
62
63
64 }
65
66 /**
67 * Plugin starting point. Will load appropriate files
68 *
69 */
70 public function init(){
71
72 self::$gf_status= $this->gravity_forms_status();
73 if(self::$gf_status !== 1){
74 add_action( 'admin_notices', array( $this, 'install_gf_notice' ) );
75 $slug=$this->get_slug();
76 add_action( 'after_plugin_row_'.$slug, array( $this, 'install_gf_notice_plugin_row' ) );
77 return;
78 }
79
80 $pro_file=self::$path . 'wp/crmperks-notices.php';
81 if(file_exists($pro_file)){
82 include_once($pro_file);
83 self::$is_pr=false;
84 }else{
85 $this->plugin_api(true);
86 self::$is_pr=true;
87 $pro_file=self::$path . 'pro/add-ons.php';
88 if(file_exists($pro_file)){
89 include_once($pro_file);
90 } }
91
92 require_once(self::$path . "includes/crmperks-gf.php");
93 require_once(self::$path . "includes/plugin-pages.php");
94
95 }
96
97
98 /**
99 * install plugin
100 *
101 */
102 public function setup_main(){
103
104
105
106 // include_once(self::$path. "includes/edit-form.php");
107 //handling post submission. gform_after_submission runs after gform_replace_merge_tags
108 add_action('gform_entry_created', array($this, 'gf_entry_created_before'), 99, 2);
109 //added via GF API
110 add_action("gform_post_add_entry", array($this, 'gf_entry_created_before'), 40, 2);
111 //trash , restore entry
112 add_action('gform_update_status', array($this, 'entry_status'),10,3);
113 //update entry
114 add_action('gform_after_update_entry', array($this, 'update_entry'),10,2);
115 //updated via GF API
116 add_action('gform_post_update_entry', array($this, 'update_entry_api'),10,2);
117
118
119
120 if(self::$is_pr){
121 // add_action("gform_post_payment_status", array($this, 'gf_entry_paid'), 10, 2); //$feed,$entry
122 add_action("gform_post_payment_completed", array($this, 'gf_entry_paid_normal'), 10, 2); //$entry,$pay_info
123
124 add_action('gform_after_submission', array($this, 'gf_entry_created_after'), 99, 2);
125 add_action("gform_post_add_subscription_payment", array($this, 'gf_entry_paid_subscription'), 10, 2); //$entry,$pay_info
126 }
127
128 add_filter("gform_confirmation", array($this, 'confirmation_error'));
129
130 if(is_admin()){
131 add_action('init', array($this,'init'));
132 //loading translations
133 load_plugin_textdomain('gravity-forms-googlesheets-crm', FALSE, $this->plugin_dir_name(). '/languages/' );
134
135 self::$db_version=get_option($this->type."_version");
136 if(self::$db_version != $this->version && current_user_can( 'manage_options' )){
137 $data=$this->get_data_object();
138 $data->update_table();
139 update_option($this->type."_version", $this->version);
140 //add post permissions
141 require_once(self::$path . "includes/install.php");
142 $install=new vxg_install_googlesheets();
143 $install->create_roles();
144 $log_str="Installing ".self::$title." version=".$this->version;
145 $this->log_msg($log_str);
146 }
147
148 }
149 }
150
151 public function plugin_api($start_instance=false){
152 if(empty(self::$path)){ self::$path=$this->get_base_path(); }
153 $file=self::$path . "pro/plugin-api.php";
154 if(!class_exists('vxcf_plugin_api') && file_exists($file)){
155 require_once($file);
156 }
157 if(class_exists('vxcf_plugin_api')){
158 $slug=$this->get_slug();
159 $settings_link=$this->link_to_settings();
160 $is_plugin_page=$this->is_crm_page();
161 self::$plugin=new vxcf_plugin_api($this->id,$this->version,$this->type,$this->domain,$this->update_id,self::$title,$slug,self::$path,$settings_link,$is_plugin_page);
162 if($start_instance){
163 self::$plugin->instance();
164 }
165 } }
166 public function install_gf_notice(){
167 $message=self::$gf_status_msg;
168 if(!empty($message)){
169 $this->display_msg('admin',$message,'gravity');
170 $this->notice_js=true;
171
172 }
173 }
174 /**
175 * Install Gravity Forms Notice (plugin row)
176 *
177 */
178 public function install_gf_notice_plugin_row(){
179 $message=self::$gf_status_msg;
180 if(!empty($message)){
181 $this->display_msg('',$message,'gravity');
182 }
183 }
184 /**
185 * display admin notice
186 *
187 * @param mixed $type
188 * @param mixed $message
189 * @param mixed $id
190 */
191 public function display_msg($type,$message,$id=""){
192 //exp
193 global $wp_version;
194 $ver=floatval($wp_version);
195 if($type == "admin"){
196 if($ver<4.2){
197 ?>
198 <div class="error vx_notice notice" data-id="<?php echo esc_html($id) ?>"><p style="display: table"><span style="display: table-cell; width: 98%"><span class="dashicons dashicons-megaphone"></span> <b><?php esc_html_e('Gravity Forms Google Sheets Plugin','gravity-forms-googlesheets-crm') ?>. </b><?php echo wp_kses_post($message);?> </span>
199 <span style="display: table-cell; padding-left: 10px; vertical-align: middle;"><a href="#" class="notice-dismiss" title="<?php esc_html_e('Dismiss Notice','gravity-forms-googlesheets-crm') ?>">dismiss</a></span> </p></div>
200 <?php
201 }else{
202 ?>
203 <div class="error vx_notice notice is-dismissible" data-id="<?php echo esc_html($id) ?>"><p><span class="dashicons dashicons-megaphone"></span> <b><?php esc_html_e('Gravity Forms Google Sheets Plugin','gravity-forms-googlesheets-crm') ?>. </b> <?php echo wp_kses_post($message);?> </p>
204 </div>
205 <?php
206 }
207 }else{
208 ?>
209 <tr class="plugin-update-tr"><td colspan="5" class="plugin-update">
210 <style type="text/css"> .vx_msg a{color: #fff; text-decoration: underline;} .vx_msg a:hover{color: #eee} </style>
211 <div style="background-color: rgba(224, 224, 224, 0.5); padding: 9px; margin: 0px 10px 10px 28px "><div style="background-color: #d54d21; padding: 5px 10px; color: #fff" class="vx_msg"> <span class="dashicons dashicons-info"></span> <?php echo wp_kses_post($message) ?>
212 </div></div></td></tr>
213 <?php
214 }
215 }
216 /**
217 * admin_screen_message function.
218 *
219 * @param mixed $message
220 * @param mixed $level
221 */
222 public function screen_msg( $message, $level = 'updated') {
223 echo '<div class="'. esc_attr( $level ) .' notice is-dismissible"><p>';
224 echo wp_kses_post($message);
225 echo '</p></div>';
226 }
227
228
229
230 /**
231 * Gravity forms status
232 *
233 */
234 public function gravity_forms_status() {
235
236 $installed = 0;
237 if(!class_exists('RGForms')) {
238 if(file_exists(WP_PLUGIN_DIR.'/gravityforms/gravityforms.php')) {
239 $installed=2;
240 }
241 }else{
242 $installed=1;
243 if(!$this->is_gravityforms_supported()){
244 $installed=3;
245 }
246 }
247 if($installed !=1){
248 if($installed === 0){ // not found
249 $message = sprintf(__("%sGravity Forms%s is required. %sPurchase it today!%s", 'gravity-forms-googlesheets-crm'), "<a href='http://www.gravityforms.com/'>", "</a>", "<a href='http://www.gravityforms.com/'>", "</a>");
250 }else if($installed === 2){ // not active
251 $message = sprintf(__('Gravity Forms is installed but not active. %sActivate Gravity Forms%s to use the Gravity Forms Google Sheets Plugin','gravity-forms-googlesheets-crm'), '<strong><a href="'.wp_nonce_url(admin_url('plugins.php?action=activate&plugin=gravityforms/gravityforms.php'), 'activate-plugin_gravityforms/gravityforms.php').'">', '</a></strong>');
252 } else if($installed === 3){ // not supported
253 $message = sprintf(__("A higher version of %sGravity Forms%s is required. %sPurchase it today!%s", 'gravity-forms-googlesheets-crm'), "<a href='http://www.gravityforms.com/'>", "</a>", "<a href='http://www.gravityforms.com/'>", "</a>");
254 }
255 self::$gf_status_msg=$message;
256 }
257 return $installed;
258 }
259 /**
260 * display error to admin only in form front
261 *
262 * @param mixed $confirmation
263 * @param mixed $form
264 * @param mixed $lead
265 * @param mixed $ajax
266 */
267 public function confirmation_error($confirmation, $form = '', $lead = '', $ajax ='' ) {
268 if(current_user_can('administrator') && !empty($_REQUEST['VXGGoogle SheetsError'])) { ///
269 $confirmation .= sprintf(__('%sThe entry was not added to Google Sheets because: %s. %sYou are only being shown this because you are an administrator. Other users will not see this message.%s', 'gravity-forms-googlesheets-crm'), '<div class="error" style="text-align:center; color:#790000; font-size:14px; line-height:1.5em; margin-bottom:16px;background-color:#FFDFDF; margin-bottom:6px!important; padding:6px 6px 4px 6px!important; border:1px dotted #C89797">','<strong>'.esc_html($_REQUEST['VXGGoogle SheetsError']). '</strong>', '<br /><em>', '</em></div>');
270 }
271 return $confirmation;
272 }
273
274 /**
275 * Returns true if the current page is an Feed pages. Returns false if not
276 *
277 * @param mixed $page
278 */
279 public function is_crm_page($page=""){
280 if(empty($page)) {
281 $page = $this->post("page");
282 }
283 if(isset($_GET['subview'])){
284 $page = $this->post("subview");
285 }
286 return $page == $this->id;
287 }
288 /**
289 * Called when entry is manually updated in the Single Entry view of Gravity Forms.
290 *
291 * @param mixed $form
292 * @param mixed $entry_id
293 */
294 public function manual_export( $form, $entry_id = NULL ) {
295
296 global $plugin_page;
297
298 // Is this the Gravity Forms entries page?
299 if(false === ($this->is_gravity_page('gf_entries') && rgget("view") == 'entry' && (rgget('lid') || !rgblank(rgget('pos'))))) {
300 return;
301 }
302 $entry=array();
303 // Both admin_init and gforms_after_update_entry will have this set
304 if( empty( $_POST['gforms_save_entry'] ) || empty( $_POST['action'] ) ) { return; }
305
306 // Different checks since admin_init runs in both cases but we need to wait for entry update
307 $current_hook = current_filter();
308
309 if( $current_hook == 'admin_init' && empty( $_POST[$this->id.'_send'] ) ) { return; }
310 if( $current_hook == 'gform_after_update_entry' && empty( $_POST[$this->id.'_update'] ) ) { return; }
311
312 // Verify authenticity of request
313 check_admin_referer('gforms_save_entry', 'gforms_save_entry');
314
315 // For admin_init hook, get the entry ID from the URL
316 if(empty($entry_id)) {
317 $entry_id = rgget('lid');
318 $form_id = rgget('id');
319
320 // fetch alternative entry id: look for gf list details when using pagination
321 if(empty($entry_id)) {
322 $entry_id=$this->get_entry_id($form_id);
323 }
324 $form = RGFormsModel::get_form_meta($form_id);
325 }
326 $entry=$this->get_gf_entry($entry_id);
327 if(!current_user_can($this->id."_send_to_crm")){
328 return;
329 }
330 // Export the entry
331 $push=$this->push($entry, $form,"",true);
332 if(!empty($push['msg'])){
333 $this->screen_msg($push['msg'],$push['class']);
334 }
335 // Don't send twice.
336 unset($_POST[$this->id.'_update']);
337 unset($_POST[$this->id.'_send']);
338 }
339 /**
340 * get entry id
341 *
342 * @param mixed $form_id
343 */
344 public function get_entry_id($form_id){
345 $entry_id='';
346 $position = rgget('pos');
347 $paging = array('offset' => $position, 'page_size' => 1);
348
349 $entries = GFAPI::get_entries($form_id, array(), null, $paging);
350
351 if(!empty($entries)) {
352 // pluck first entry to use id from, should always only be one
353 $entry = array_shift($entries);
354 $entry_id = $entry['id'];
355 }
356
357 return $entry_id;
358 }
359
360
361 /**
362 * settings link
363 *
364 * @param mixed $escaped
365 */
366 public function link_to_settings( $escaped = true ) {
367
368 $url = admin_url('admin.php?page=gf_settings&subview='.$this->id);
369
370 return $url;
371 }
372
373 /**
374 * Get CRM info
375 *
376 */
377 public function get_info($id){
378 $data=$this->get_data_object();
379 $info=$data->get_account($id);
380 $info_arr=$data=array(); $meta=array();
381 if(is_array($info)){
382 if(!empty($info['data'])){
383
384 $info['data']=trim($info['data']);
385 if(strpos($info['data'],'{') !== 0){
386 $info['data']=$this->de_crypt($info['data']);
387 }
388 $info_arr=json_decode($info['data'],true);
389
390 if(!is_array($info_arr)){
391 $info_arr=array();
392 }
393 }
394
395 //$info_arr['time']=$info['time'];
396 $info_arr['id']=$info['id'];
397 $info['data']=$info_arr;
398 if(!empty($info['meta'])){
399 $meta=json_decode($info['meta'],true);
400 }
401 $info['meta']=is_array($meta) ? $meta : array();
402
403 if(!empty($info['time'])){
404 $info['time']=strtotime($info['time']);
405 }
406 }
407
408 return $info;
409 }
410 /**
411 * update account
412 *
413 * @param mixed $data
414 * @param mixed $id
415 */
416 public function update_info($data,$id) {
417
418 if(empty($id)){
419 return;
420 }
421
422 $time = current_time( 'mysql' ,1);
423
424 $sql=array('updated'=>$time);
425 if(is_array($data)){
426
427
428 if(isset($data['meta'])){
429 $sql['meta']= json_encode($data['meta']);
430 }
431 if( isset($data['data']) && is_array($data['data'])){
432 $_data=$this->get_data_object();
433 $acount=$_data->get_account($id);
434 if(empty($acount['time'])){
435 $sql['time']= $time;
436 }
437 $sql['status']='2';
438 if(isset($data['data']['class'])){
439 $sql['status']= $data['data']['class'] == 'updated' ? '1' : '2';
440 }
441 if(isset($data['data']['meta'])){
442 unset($data['data']['meta']);
443 }
444 if(isset($data['data']['status'])){
445 unset($data['data']['status']);
446 }
447 if(isset($data['data']['name'])){
448 $sql['name']=$data['data']['name'];
449 // unset($data['data']['name']);
450 }else if(isset($_GET['id'])){
451 $sql['name']="Account #".$this->post('id');
452 }
453
454 $enc_str=json_encode($data['data']);
455 // $enc_str=$this->en_crypt($enc_str);
456 $sql['data']=$enc_str;
457 }
458 }
459
460
461 $data=$this->get_data_object();
462 $result = $data->update_account($sql,$id);
463
464 return $result;
465 }
466
467 /**
468 * gravity forms field values, modify check boxes etc
469 *
470 * @param mixed $entry
471 * @param mixed $form
472 * @param mixed $gf_field_id
473 * @param mixed $crm_field_id
474 * @param mixed $custom
475 */
476 public function verify_field_val($entry,$form,$gf_field_id,$crm_field_id="",$custom=""){
477
478 $value=false;
479 /* if(empty($field)){
480 return $value;
481 }*/
482
483 if(isset($entry[$gf_field_id])){
484 $value=maybe_unserialize($entry[$gf_field_id]);
485 if(in_array($gf_field_id,array('date_created','payment_date'))){
486 $date_format=trim(get_option( 'date_format' ).' '.get_option( 'time_format' ));
487 if(empty($date_format)){
488 $date_format='Y/m/d H:i:s';
489 }
490 $value=GFCommon::format_date( $value, false, $date_format , false );
491
492 }
493 if(is_numeric($gf_field_id)){
494 $field = RGFormsModel::get_field($form, $gf_field_id);
495 if(isset($field->type) && in_array($field->type,array('option','product')) ){
496 $found=strpos($value,'|');
497 if($found){
498 if(!empty($custom)){ //it is empty with process_tags function
499 $value=substr($value,$found+1);
500 }else{
501 $value=substr($value,0,$found);
502 }
503 }
504 }
505 if( (isset($field->storageType) && $field->storageType == 'json') || $field->type == 'fileupload' ){
506 $value=$field->get_value_entry_detail($value,'',false,'text');//convert direct url to gravity download hash
507 /* $value_temp=json_decode($value,1); if(!empty($value_temp)){ $value=$value_temp; }
508 if(is_array($value)){
509 $value=implode("\n",$value);
510 }*/
511 }
512 if( in_array($field->type, array('survey','quiz')) && !empty($field->choices)){
513 $val_temp=explode(':',$value);
514 if(count($val_temp) > 1){ $value=$val_temp[1]; }
515 foreach($field->choices as $v){
516 if($v['value'] == $value){
517 $value=!empty($v['score']) ? $v['score'] : $v['text'];
518 break;
519 }
520 }
521 }
522 if($field->type == 'consent'){
523 $value= !empty($value) ? 'Yes' : 'No';
524 }
525
526 if($field->type == 'date' && !empty($value) ){
527 $formats=array('mdy'=>'m/d/Y','dmy'=>'d/m/Y','dmy_dash'=>'d-m-Y','dmy_dot'=>'d.m.Y','ymd_slash'=>'Y/m/d','ymd_dash'=>'Y-m-d','ymd_dot'=>'Y.m.d');
528 if( !empty($field->dateFormat) && isset($formats[$field->dateFormat])){
529 $value=date($formats[$field->dateFormat],strtotime($value));
530 }
531 }else if($field->type == "post_image"){
532 $value=rtrim($value,'|:|');
533 }else if($field->type == 'list' && is_array($value)){
534 $v_temp=array();
535 foreach($value as $v){
536 if(is_array($v)){
537 $v=trim(implode(', ',array_values($v)));
538 }
539 $v_temp[]=$v;
540 }
541 $value=trim(implode(" - \n",$v_temp));
542 }else if($field->type == 'number'){
543 $value=$field->get_value_entry_detail($value);
544 }
545 }
546 $val=true;
547 }else{ //check if full address
548 if($gf_field_id=='entry_url'){
549 $value=add_query_arg(array('page'=>'gf_entries','view'=>'entry','lid'=>$entry['id'],'id'=>$entry['form_id']), admin_url('admin.php'));
550 $val=true;
551 }else if($gf_field_id=="form_title"){
552 $value=$form['title'];
553 $val=true;
554 }else{
555 $field = RGFormsModel::get_field($form, $gf_field_id);
556
557 if(!empty($field)){
558 if($field->type == "address"){
559 $address_type="";
560 if($crm_field_id!=""){
561 $address_type=isset($custom[$crm_field_id]['type']) && $custom[$crm_field_id]['type'] == "address" ? "json" : "";
562 }
563 $value=$this->get_address($entry,$gf_field_id,$address_type);
564 $val=true;
565 }else if(is_numeric($gf_field_id)){
566 // This is for checkboxes
567 $elements = array();
568 foreach($entry as $key => $val_e) {
569 if(is_numeric($key) && floor($key) == floor($gf_field_id) && !empty($val_e)) {
570 $elements[] = htmlspecialchars($val_e);
571 }}
572 if(count($elements)>0){
573 $value=$elements; $val=true;
574 } }
575 }else if(isset($_REQUEST[$gf_field_id])){
576 $value=$this->post($gf_field_id);
577 }
578 }
579 }
580 if($value && is_array($value)){
581 // $value=implode(", ",$value);
582 }
583
584 return $value;
585 }
586 /**
587 * filter enteries
588 *
589 * @param mixed $feed
590 * @param mixed $entry
591 * @param mixed $form
592 */
593 public function check_filter($feed,$entry,$form){
594 $filters=$this->post('filters',$feed);
595 $final=$this->filter_condition=null;
596 if(is_array($filters)){
597 $time=current_time('timestamp');
598 foreach($filters as $filter_s){
599 $check=null; $and=null; $and_c=array();
600 if(is_array($filter_s)){
601 foreach($filter_s as $filter){
602 $field=$filter['field'];
603 $fval=$filter['value'];
604 $val=$this->verify_field_val($entry,$form,$field);
605 if(is_array($val)){ $val=implode(' ',$val); }
606
607 switch($filter['op']){
608 case"is": $check=$fval == $val; break;
609 case"is_not": $check=$fval != $val; break;
610 case"contains": $check=preg_match('/'.$fval.'/i', $val) > 0; break;
611 case"not_contains": $check=preg_match('/'.$fval.'/i', $val) === 0; break;
612 case"is_in": $check=strpos($fval,$val) !==false; break;
613 case"not_in": $check=strpos($fval,$val) ===false; break;
614 case"starts": $check=strpos($val,$fval) === 0; break;
615 case"not_starts": $check=strpos($val,$fval) !== 0; break;
616 case"ends": $check=(strrpos($val,$fval)+strlen($fval)) == strlen($val); break;
617 case"not_ends": $check=(strrpos($val,$fval)+strlen($fval)) != strlen($val); break;
618 case"less": $check=(float)$val<(float)$fval; break;
619 case"greater": $check=(float)$val>(float)$fval; break;
620 case"less_date": $check=strtotime($val,$time) < strtotime($fval,$time); break;
621 case"greater_date": $check=strtotime($val,$time) > strtotime($fval,$time); break;
622 case"equal_date": $check=strtotime($val,$time) == strtotime($fval,$time); break;
623 case"empty": $check=$val == ""; break;
624 case"not_empty": $check=$val != ""; break;
625 }
626 $and_c[]=array("check"=>$check,"field_val"=>$fval,"input"=>$val,"field"=>$field,"op"=>$filter['op']);
627 if($check !== null){
628 if($and !== null){
629 $and=$and && $check;
630 }else{
631 $and=$check;
632 }
633 }
634 } //end and loop filter
635 }
636 if($and !== null){
637 if($final !== null){
638 $final=$final || $and;
639 }else{
640 $final=$and;
641 }
642 }
643 $this->filter_condition[]=$and_c;
644 } // end or loop
645 }
646 // var_dump($final); die();
647 return $final === null ? true : $final;
648 }
649
650 /**
651 * get address components
652 *
653 * @param mixed $entry
654 * @param mixed $field_id
655 * @param mixed $type
656 */
657 private function get_address($entry, $field_id,$type=""){
658 $street_value = str_replace(" ", " ", trim($entry[$field_id . ".1"]));
659 $street2_value = str_replace(" ", " ", trim($entry[$field_id . ".2"]));
660 $city_value = str_replace(" ", " ", trim($entry[$field_id . ".3"]));
661 $state_value = str_replace(" ", " ", trim($entry[$field_id . ".4"]));
662 $zip_value = trim($entry[$field_id . ".5"]);
663 if(method_exists('GF_Field_Address','get_country_code')){
664 $field_c=new GF_Field_Address();
665 $country_value=$field_c->get_country_code(trim($entry[$field_id . ".6"]));
666 }else{
667 $country_value = GFCommon::get_country_code(trim($entry[$field_id . ".6"]));
668 }
669 $country =trim($entry[$field_id . ".6"]);
670 $address = $street_value;
671 $address .= !empty($address) && !empty($street2_value) ? " $street2_value" : $street2_value;
672 if($type =="json"){
673 $arr=array("street"=>$address,"city"=>$city_value,"state"=>$state_value,"zip"=>$zip_value,"country"=>$country);
674 return json_encode($arr);
675 }
676 $address .= !empty($address) && (!empty($city_value) || !empty($state_value)) ? " $city_value" : $city_value;
677 $address .= !empty($address) && !empty($city_value) && !empty($state_value) ? " $state_value" : $state_value;
678 $address .= !empty($address) && !empty($zip_value) ? " $zip_value" : $zip_value;
679 $address .= !empty($address) && !empty($country_value) ? " $country_value" : $country_value;
680
681 return $address;
682 }
683 /**
684 * if gravity forms page
685 *
686 * @param mixed $page
687 */
688 public function is_gravity_page($page = array()){
689 if(!class_exists('RGForms')) { return false; }
690 $current_page = trim(strtolower(RGForms::get("page")));
691 if(empty($page)) {
692 $gf_pages = array("gf_edit_forms","gf_new_form","gf_entries","gf_settings","gf_export","gf_help");
693 } else {
694 $gf_pages = is_array($page) ? $page : array($page);
695 }
696
697 return in_array($current_page, $gf_pages);
698 }
699 /**
700 * Add checkbox to entry info - option to send entry to crm
701 *
702 * @param mixed $form_id
703 * @param mixed $lead
704 */
705 public function entry_info_send_checkbox( $form_id, $lead ) {
706
707 // If this entry's form isn't connected to crm, don't show the checkbox
708 if(!$this->show_send_to_crm_button() ) { return; }
709
710 // If this is not the Edit screen, get outta here.
711 if(empty($_POST["screen_mode"]) || $_POST["screen_mode"] === 'view') { return; }
712
713 if(!current_user_can($this->id."_send_to_crm")){return; }
714
715 if( apply_filters( $this->id.'_show_manual_export_button', true ) ) {
716 printf('<input type="checkbox" name="'.$this->id.'_update" id="'.$this->id.'_update" value="1" /><label for="'.$this->id.'_update" title="%s">%s</label><br /><br />', esc_html__('Create or update this entry in Google Sheets. The fields will be mapped according to the form feed settings.', 'gravity-forms-googlesheets-crm'), esc_html__('Send to Google Sheets', 'gravity-forms-googlesheets-crm'));
717 } else {
718 echo '<input type="hidden" name="'.$this->id.'_update" id="'.$this->id.'_update" value="1" />';
719 }
720 }
721 /**
722 * Add button to entry info - option to send entry to crm
723 *
724 * @param mixed $button
725 */
726 public function entry_info_send_button( $button = '' ) {
727 // If this entry's form isn't connected to crm, don't show the button
728 if(!$this->show_send_to_crm_button()) { return $button; }
729 if(!current_user_can($this->id."_send_to_crm")){return; }
730 // Is this the view or the edit screen?
731 $mode = empty($_POST["screen_mode"]) ? "view" : $this->post("screen_mode");
732 if($mode === 'view') {
733 $margin="";
734 if(defined("vx_btn")){
735 $margin="margin-top: 5px;";
736 }else{define('vx_btn','true');}
737 $button.= '<input type="submit" class="button button-large button-secondary alignright" name="'.$this->id.'_send" style="margin-left:5px; '.$margin.'" title="'.__('Create or update this entry in Google Sheets. The fields will be mapped according to the form feed settings.','gravity-forms-googlesheets-crm').'" value="'.__('Send to Google Sheets', 'gravity-forms-googlesheets-crm').'" onclick="jQuery(\'#action\').val(\'send_to_crm\')" />';
738 //logs button
739
740 $entry_id=$this->post('lid');
741 $form_id = rgget('id');
742 if(empty($entry_id)){
743 $entry_id=$this->get_entry_id($form_id);
744 }
745 $log_url=admin_url( 'admin.php?page=gf_edit_forms&view=settings&subview='.$this->id.'&tab=log&id='.$form_id.'&entry_id='.$entry_id);
746 $button.= '<a class="button button-large button-secondary alignright" style="margin-left:5px; margin-top:5px; " title="'.__('Go to Google Sheets Logs','gravity-forms-googlesheets-crm').'" href="'.$log_url.'">'.__('Google Sheets Logs','gravity-forms-googlesheets-crm').'</a>';
747
748 }
749 return $button;
750 }
751 /**
752 * Whether to show the Entry "Send to CRM" button or not
753 *
754 * If the entry's form has been mapped to CRM feed, show the Send to CRM button. Otherwise, don't.
755 *
756 * @return boolean True: Show the button; False: don't show the button.
757 */
758 public function show_send_to_crm_button() {
759
760 $form_id = rgget('id');
761
762 return $this->has_feed($form_id);
763 }
764 /**
765 * Does the current form have a feed assigned to it?
766 * @param INT $form_id Form ID
767 * @return boolean
768 */
769 function has_feed($form_id) {
770 $data=$this->get_data_object();
771 $feeds = $data->get_feed_by_form( $form_id , true);
772
773 return !empty($feeds);
774 }
775
776 /**
777 * Add note to GF Entry
778 * @param int $id Entry ID
779 * @param string $note Note text
780 */
781 private function add_note($id, $note) {
782
783 RGFormsModel::add_note($id, 0, esc_html__('Gravity Forms Google Sheets Plugin','gravity-forms-googlesheets-crm'), $note);
784 }
785
786 /**
787 * if gravity forms installed and supported
788 *
789 */
790 private function is_gravityforms_supported(){
791 if(class_exists("GFCommon")){
792 $is_correct_version = version_compare(GFCommon::$version, $this->min_gravityforms_version, ">=");
793 return $is_correct_version;
794 }
795 else{
796 return false;
797 }
798 }
799 /**
800 * uninstall plugin
801 *
802 */
803 public function uninstall(){
804 //droping all tables
805 require_once(self::$path . "includes/install.php");
806 $install=new vxg_install_googlesheets();
807 do_action('uninstall_vx_plugin_'.$install->id);
808 $install->remove_data();
809 }
810 /**
811 * email validation
812 *
813 * @param mixed $email
814 */
815 public function is_valid_email($email){
816 if(function_exists('filter_var')){
817 if(filter_var($email, FILTER_VALIDATE_EMAIL)){
818 return true;
819 }
820 }else{
821 if(strpos($email,"@")>1){
822 return true;
823 }
824 }
825 return false;
826 }
827 /**
828 * deactivate
829 *
830 * @param mixed $action
831 */
832 public function deactivate($action="deactivate"){
833 do_action('plugin_status_'.$this->type,$action);
834 }
835 /**
836 * activate plugin
837 *
838 */
839 public function activate(){
840 $this->plugin_api(true);
841 do_action('plugin_status_'.$this->type,'activate');
842 }
843 /**
844 * Send CURL Request
845 *
846 * @param mixed $body
847 * @param mixed $path
848 * @param mixed $method
849 */
850 public function request($path="",$method='POST',$body="",$head=array()) {
851
852 $args = array(
853 'body' => $body,
854 'headers'=> $head,
855 'method' => strtoupper($method), // GET, POST, PUT, DELETE, etc.
856 'sslverify' => false,
857 'timeout' => 20,
858 );
859
860 $response = wp_remote_request($path, $args);
861
862 if(is_wp_error($response)) {
863 $this->error_msg= $response->get_error_message();
864 return false;
865 } else if(isset($response['response']['code']) && $response['response']['code'] != 200 && $response['response']['code'] != 404) {
866 $this->error_msg = strip_tags($response['body']);
867 return false;
868 } else if(!$response) {
869 return false;
870 }
871 $result=wp_remote_retrieve_body($response);
872 return $result;
873 }
874
875 /**
876 * Adds feed tooltips to the list of tooltips
877 *
878 * @param mixed $tooltips
879 */
880 public function tooltips($tooltips){
881 $crm_tooltips = array(
882 'vx_feed_name' => '<h6>' . esc_html__('Feed Name', 'gravity-forms-googlesheets-crm') . '</h6>' . esc_html__('Enter feed name of your choice.', 'gravity-forms-googlesheets-crm'),
883 'vx_sel_object' => '<h6>' .__('Google Sheets Object', 'gravity-forms-googlesheets-crm') . '</h6>' . esc_html__('Select the Object to Create when a Form is Submitted.', 'gravity-forms-googlesheets-crm'),
884 'vx_sel_account' => '<h6>' .__('Google Sheets Account', 'gravity-forms-googlesheets-crm') . '</h6>' . esc_html__('Select the Google Sheets account you would like to export entries to.', 'gravity-forms-googlesheets-crm'),
885 'vx_sel_form' => '<h6>' . esc_html__('Gravity Form', 'gravity-forms-googlesheets-crm') . '</h6>' . esc_html__('Select the Gravity Form you would like to integrate with Google Sheets. Contacts generated by this form will be automatically added to your Google Sheets account.', 'gravity-forms-googlesheets-crm'),
886
887 'vx_map_fields' => '<h6>' . esc_html__('Map Standard Fields', 'gravity-forms-googlesheets-crm') . '</h6>' . esc_html__('Associate your Google Sheets fields to the appropriate Gravity Form fields.', 'gravity-forms-googlesheets-crm'),
888
889 'vx_optin_condition' => '<h6>' . esc_html__('Opt-In Condition', 'gravity-forms-googlesheets-crm') . '</h6>' . esc_html__('When the opt-in condition is enabled, form submissions will only be exported to Google Sheets when the condition is met. When disabled all form submissions will be exported.', 'gravity-forms-googlesheets-crm'),
890
891 'vx_manual_export' => '<h6>' . esc_html__('Manual Export', 'gravity-forms-googlesheets-crm') . '</h6>' . esc_html__('If you do not want all entries sent to Google Sheets, but only specific, approved entries, check this box. To manually send an entry to Google Sheets, go to Entries, choose the entry you would like to send to Google Sheets, and then click the "Send to Google Sheets" button.', 'gravity-forms-googlesheets-crm'),
892
893 'vx_entry_notes' => '<h6>' . esc_html__('Entry Notes', 'gravity-forms-googlesheets-crm') . '</h6>' . esc_html__('Enable this option if you want to synchronize Gravity Forms entry notes to Google Sheets Object notes. For example , when you add a note to a Gravity Forms entry, it will be added to the Google Sheets Object selected in the feed.', 'gravity-forms-googlesheets-crm'),
894
895 'vx_primary_key' => '<h6>' . esc_html__('Primary Key', 'gravity-forms-googlesheets-crm') . '</h6>' . esc_html__('Which field should be used to update existing objects?', 'gravity-forms-googlesheets-crm'),
896
897
898 'vx_web' => '<h6>' . esc_html__('Web to Lead', 'gravity-forms-googlesheets-crm') . '</h6>' . sprintf(__('Web-to-Lead is available for all Google Sheets Editions. If you are not sure if your Google Sheets Edition supports the API, you should use Web-to-Lead. Editions that do not support the Google Sheets API: %s 1: Personal Edition %s 2: Group Edition %s 3: Professional Edition %s Note: You can purchase API access for a Professional Edition', 'gravity-forms-googlesheets-crm'),'<br/>','<br/>','<br/>','<br/>'),
899
900 'vx_api' => '<h6>' . esc_html__('Google Sheets API', 'gravity-forms-googlesheets-crm') . '</h6>' .sprintf(__('The API features are more powerful than Web-to-Lead. You can create different object types, as well as other advanced features. If you have any of the following Google Sheets Editions, you can use the included API Add-on: %s 1: Enterprise Edition %s 2: Unlimited Edition %s 3: Developer Edition %s 4: Professional Edition - Requires API Upgrade', 'gravity-forms-googlesheets-crm'),'<br/>','<br/>','<br/>','<br/>','<br/>'),
901
902
903 'vx_custom_app'=>'<h6>' . esc_html__('Custom App', 'gravity-forms-googlesheets-crm') . '</h6>' .__('This option is for advanced users who want to override default Google Sheets App.','gravity-forms-googlesheets-crm'),
904
905
906 'vx_camps'=>'<h6>' . esc_html__('Google Sheets Campaigns', 'gravity-forms-googlesheets-crm') . '</h6>' .__('Get Campaigns and Status list from googlesheets.','gravity-forms-googlesheets-crm'),
907
908 'vx_sel_price_book'=>__('Which Pricebook should be searched for product','gravity-forms-googlesheets-crm'),
909
910 'vx_sel_camp'=>'<h6>' . esc_html__('Select Campaign', 'gravity-forms-googlesheets-crm') . '</h6>' .__('Which Campaign should be assigned to this object.','gravity-forms-googlesheets-crm'),
911
912 'vx_sel_status'=>'<h6>' . esc_html__('Campaign Status', 'gravity-forms-googlesheets-crm') . '</h6>' .__('What should be Member Status.','gravity-forms-googlesheets-crm'),
913
914 'vx_pro_desc'=>'<h6>' . esc_html__('Price Book', 'gravity-forms-googlesheets-crm') . '</h6>' .__('A new product will be created in selected Pricebook. You can add a description for new products created by this plugin.','gravity-forms-googlesheets-crm'),
915
916 'vx_assign_account'=>'<h6>' . esc_html__('Google Sheets Account', 'gravity-forms-googlesheets-crm') . '</h6>' .__('Enable this option if you want to assign an account this object.','gravity-forms-googlesheets-crm'),
917
918 'vx_sel_account'=>'<h6>' . esc_html__('Select Account', 'gravity-forms-googlesheets-crm') . '</h6>' .__('Object created by this feed will be assigned to the selected Account.','gravity-forms-googlesheets-crm'),
919
920 'vx_assign_contract'=>'<h6>' . esc_html__('Assign Contract', 'gravity-forms-googlesheets-crm') . '</h6>' .__('Enable this option , if you want to assign a Contract to this object','gravity-forms-googlesheets-crm'),
921
922 'vx_sel_contract'=>'<h6>' . esc_html__('Select Contact', 'gravity-forms-googlesheets-crm') . '</h6>' .__('Select Contract feed. Contract created by this feed will be assigned to this object','gravity-forms-googlesheets-crm'),
923
924 'vx_camp_check'=>'<h6>' . esc_html__('Add to Campaign', 'gravity-forms-googlesheets-crm') . '</h6>' .__('If enabled, Lead/Contact will be added to selected Campaign','gravity-forms-googlesheets-crm'),
925 'vx_owner_check'=>'<h6>' . esc_html__('Assign Owner', 'gravity-forms-googlesheets-crm') . '</h6>' .__('Enable this option if you want to assign another object owner.','gravity-forms-googlesheets-crm'),
926
927 'vx_owners'=>'<h6>' . esc_html__('Google Sheets Users', 'gravity-forms-googlesheets-crm') . '</h6>' .__('Get Users list from Google Sheets','gravity-forms-googlesheets-crm'),
928
929 'vx_order_notes'=>'<h6>' . esc_html__('Entry Notes', 'gravity-forms-googlesheets-crm') . '</h6>' .__('Enable this option if you want to synchronize Entry notes to Google Sheets Object notes. For example, when you add a note to a Entry, it will be added to the Google Sheets Object selected in the feed.','gravity-forms-googlesheets-crm'),
930
931 'vx_sel_owner'=>'<h6>' . esc_html__('Select Owner', 'gravity-forms-googlesheets-crm') . '</h6>' .__('Select a user as a owner of this object','gravity-forms-googlesheets-crm'),
932
933 'vx_entry_note'=>'<h6>' . esc_html__('Entry Note', 'gravity-forms-googlesheets-crm') . '</h6>' .__('Check this option if you want to send more data as CRM entry note.', 'gravity-forms-googlesheets-crm'),
934 'vx_note_fields'=>'<h6>' . esc_html__('Note Fields', 'gravity-forms-googlesheets-crm') . '</h6>' .__('Select fields which you want to send as a note', 'gravity-forms-googlesheets-crm'),
935 'vx_disable_note'=>'<h6>' . esc_html__('Note Fields', 'gravity-forms-googlesheets-crm') . '</h6>' .__('Enable this option if you want to add note only for new CRM entry', 'gravity-forms-googlesheets-crm')
936
937 );
938 return array_merge($tooltips,$crm_tooltips);
939 }
940
941 /**
942 * Formates User Informations and submitted form to string
943 * This string is sent to email and googlesheets
944 * @param array $info User informations
945 * @param bool $is_html If HTML needed or not
946 * @return string formated string
947 */
948 public function format_user_info($info,$is_html=false){
949 $str=""; $file="";
950 if($is_html){
951 if(file_exists(self::$path."templates/email.php")){
952 ob_start();
953 include_once(self::$path."templates/email.php");
954 $file= ob_get_contents(); // data is now in here
955 ob_end_clean();
956 }
957 if(trim($file) == "")
958 $is_html=false;
959 }
960 if(isset($info['info']) && is_array($info['info'])){
961 if($is_html){
962 if(isset($info['info_title'])){
963 $str.='<tr><td style="font-family: Helvetica, Arial, sans-serif;background-color: #C35050; height: 36px; color: #fff; font-size: 24px; padding: 0px 10px">'.$info['info_title'].'</td></tr>'."\n";
964 }
965 if(is_array($info['info']) && count($info['info'])>0){
966 $str.='<tr><td style="padding: 10px;"><table border="0" cellpadding="0" cellspacing="0" width="100%;"><tbody>';
967 foreach($info['info'] as $f_k=>$f_val){
968 $str.='<tr><td style="padding-top: 10px;color: #303030;font-family: Helvetica;font-size: 13px;line-height: 150%;text-align: right; font-weight: bold; width: 28%; padding-right: 10px;">'.$f_k.'</td><td style="padding-top: 10px;color: #303030;font-family: Helvetica;font-size: 13px;line-height: 150%;text-align: left; word-break:break-all;">'.$f_val.'</td></tr>'."\n";
969 }
970 $str.="</table></td></tr>";
971 }
972 }else{
973 if(isset($info['title']))
974 $str.="\n".$info['title']."\n";
975 foreach($info['info'] as $f_k=>$f_val){
976 $str.=$f_k." : ".$f_val."\n";
977 }
978 }
979 }
980 if($is_html){
981 $str=str_replace(array("{title}","{msg}","{sf_contents}"),array($info['title'],$info['msg'],$str),$file);
982 }
983 return $str;
984 }
985
986
987 /**
988 * if plugin user is valid
989 *
990 * @param mixed $update
991 */
992
993 public function is_valid_user($update){
994 return is_array($update) && isset($update['user']['user']) && $update['user']['user']!=""&& isset($update['user']['expires']);
995 }
996 /**
997 * Get variable from array
998 *
999 * @param mixed $key
1000 * @param mixed $arr
1001 */
1002 public function post($key, $arr="") {
1003 if(is_array($arr)){
1004 return isset($arr[$key]) ? $arr[$key] : "";
1005 }
1006 //clean when getting extrenals
1007 return isset($_REQUEST[$key]) ? $this->clean($_REQUEST[$key],$key) : "";
1008 }
1009 public function clean($var,$key=''){
1010 if ( is_array( $var ) ) {
1011 $a=array();
1012 foreach($var as $k=>$v){
1013 $a[$k]=$this->clean($v,$k);
1014 }
1015 return $a;
1016 }else {
1017 $var=wp_unslash($var);
1018 if(in_array($key,array('note_val','value'))){
1019 $var=sanitize_textarea_field($var);
1020 }else{
1021 $var=sanitize_text_field($var);
1022 }
1023 return $var;
1024 }
1025 }
1026
1027 /**
1028 * Get WP Encryption key
1029 * @return string Encryption key
1030 */
1031 public static function get_key(){
1032 $k='Wezj%+l-x.4fNzx%hJ]FORKT5Ay1w,iczS=DZrp~H+ve2@1YnS;;g?_VTTWX~-|t';
1033 if(defined('AUTH_KEY')){
1034 $k=AUTH_KEY;
1035 }
1036 return substr($k,0,30);
1037 }
1038 /**
1039 * check if other version of this plugin exists
1040 *
1041 */
1042 public function other_plugin_version(){
1043
1044 $status=0;
1045 if(class_exists('vxg_googlesheets_wp')){
1046 $status=1;
1047 }else if( file_exists(WP_PLUGIN_DIR.'/gravity-forms-googlesheets-crm/gravity-forms-googlesheets-crm.php')) {
1048 $status=2;
1049 }
1050 return $status;
1051 }
1052 /**
1053 * Get time Offset
1054 *
1055 */
1056 public function time_offset(){
1057 $offset = (int) get_option('gmt_offset');
1058 return $offset*3600;
1059 }
1060 /**
1061 * Decrypts Values
1062 * @param array $info Google Sheets encrypted API info
1063 * @return array API settings
1064 */
1065 public static function de_crypt($info){
1066 $info=trim($info);
1067 if($info == "")
1068 return '';
1069 $str=base64_decode($info);
1070 $key=self::get_key();
1071 $decrypted_string='';
1072 if(function_exists("openssl_encrypt") && strpos($str,':')!==false ) {
1073 $method='AES-256-CBC';
1074 $arr = explode(':', $str);
1075 if(isset($arr[1]) && $arr[1]!=""){
1076 $decrypted_string=openssl_decrypt($arr[0],$method,$key,false, base64_decode($arr[1]));
1077 }
1078 }else{
1079 $decrypted_string=$str;
1080 }
1081 return $decrypted_string;
1082 }
1083 /**
1084 * Encrypts Values
1085 * @param string $str
1086 * @return string Encrypted Value
1087 */
1088 public static function en_crypt($str){
1089 $str=trim($str);
1090 if($str == "")
1091 return '';
1092 $key=self::get_key();
1093 if(function_exists("openssl_encrypt")) {
1094 $method='AES-256-CBC';
1095 $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($method));
1096 $enc_str=openssl_encrypt($str,$method, $key,false,$iv);
1097 $enc_str.=":".base64_encode($iv);
1098 }else{
1099 $enc_str=$str;
1100 }
1101 $enc_str=base64_encode($enc_str);
1102 return $enc_str;
1103 }
1104
1105 /**
1106 * Get variable from array
1107 *
1108 * @param mixed $key
1109 * @param mixed $key2
1110 * @param mixed $arr
1111 */
1112 public function post2($key,$key2, $arr="") {
1113 if(is_array($arr) && isset($arr[$key]) && is_array($arr[$key])){
1114 return isset($arr[$key][$key2]) ? $arr[$key][$key2] : "";
1115 }
1116 return isset($_REQUEST[$key][$key2]) && is_array($_REQUEST[$key]) ? $this->clean($_REQUEST[$key][$key2]) : "";
1117 }
1118 /**
1119 * Get variable from array
1120 *
1121 * @param mixed $key
1122 * @param mixed $key2
1123 * @param mixed $arr
1124 */
1125 public function post3($key,$key2,$key3, $arr="") {
1126 if(is_array($arr)){
1127 return isset($arr[$key][$key2][$key3]) ? $arr[$key][$key2][$key3] : "";
1128 }
1129 return isset($_REQUEST[$key][$key2][$key3]) ? $this->clean($_REQUEST[$key][$key2][$key3]) : "";
1130 }
1131 /**
1132 * get base url
1133 *
1134 */
1135 public function get_base_url(){
1136 return plugin_dir_url(__FILE__);
1137 }
1138 /**
1139 * get plugin direcotry name
1140 *
1141 */
1142 public function plugin_dir_name(){
1143 if(!empty($this->plugin_dir)){
1144 return $this->plugin_dir;
1145 }
1146 if(empty(self::$path)){
1147 self::$path=$this->get_base_path();
1148 }
1149 $this->plugin_dir=basename(self::$path);
1150 return $this->plugin_dir;
1151 }
1152 /**
1153 * get plugin slug
1154 *
1155 */
1156 public function get_slug(){
1157 return plugin_basename(__FILE__);
1158 }
1159 public function do_actions(){
1160 if(!is_object(self::$plugin) ){ $this->plugin_api(); }
1161 if(is_object(self::$plugin) && method_exists(self::$plugin,'valid_addons')){
1162 return self::$plugin->valid_addons();
1163 }
1164
1165 return false;
1166 }
1167 /**
1168 * Returns the physical path of the plugin's root folder
1169 *
1170 */
1171 public function get_base_path(){
1172 return plugin_dir_path(__FILE__);
1173 }
1174 /**
1175 * Writes an error message to the Gravity Forms log.
1176 *
1177 */
1178 public function log_msg($message,$type=""){
1179 if (class_exists("GFLogging")) {
1180 GFLogging::include_logger();
1181 $slug=$this->plugin_dir_name();
1182 $log_type=KLogger::DEBUG;
1183 if($type == "error"){
1184 $log_type=KLogger::ERROR;
1185 }
1186 GFLogging::log_message($slug, $message,$log_type);
1187 }
1188 }
1189 /**
1190 * get api object
1191 *
1192 * @param mixed $settings
1193 * @return vxg_api_zoho
1194 */
1195 public function get_api($crm=""){
1196 $api = false;
1197 if(!class_exists("vxg_googlesheets_api"))
1198 require_once($this->get_base_path()."api/api.php");
1199
1200 $api= new vxg_googlesheets_api($crm);
1201
1202 return $api;
1203 }
1204 /**
1205 * get gravity forms entry
1206 *
1207 */
1208 public function get_gf_entry($entry_id){
1209 $entry=array();
1210 // Fetch entry (use new GF API from version 1.8)
1211 if( class_exists( 'GFAPI' ) && !empty( $entry_id ) ) {
1212 $entry = GFAPI::get_entry( $entry_id );
1213 } elseif( class_exists( 'RGFormsModel' ) && !empty( $entry_id ) ) {
1214 $entry = RGFormsModel::get_lead( $entry_id );
1215 }
1216 return $entry;
1217 }
1218 /**
1219 * get data object
1220 *
1221 */
1222 public function get_data_object(){
1223 require_once(self::$path . "includes/data.php");
1224 if(!is_object($this->data))
1225 $this->data=new vxg_googlesheets_data();
1226 return $this->data;
1227 }
1228 public function gf_entry_created_before($entry, $form){
1229 $this->gf_entry_created($entry, $form);
1230 }
1231 public function gf_entry_created_after($entry, $form){
1232 $this->gf_entry_created($entry, $form,'after_submit');
1233 }
1234 /**
1235 * gravity forms entry created
1236 *
1237 * @param mixed $entry
1238 * @param mixed $form
1239 */
1240 public function gf_entry_created( $entry, $form, $event='submit'){
1241
1242 if(is_array($entry) && isset($entry['status']) && $entry['status'] == 'active' && empty($entry['partial_entry_percent'])){
1243
1244 $entry_id=$this->post('id',$entry);
1245 if($this->do_actions()){
1246 do_action('vx_addons_save_entry',$entry_id,$entry,'gf',$form);
1247 }
1248 $this->push($entry,$form,$event,false);
1249 }
1250 }
1251
1252 public function gf_entry_paid_normal($entry,$pay_info){
1253 $this->gf_entry_paid($entry,$pay_info);
1254 }
1255 public function gf_entry_paid_subscription($entry,$pay_info){
1256 $this->gf_entry_paid($entry,$pay_info,'subscription_paid');
1257 }
1258 public function gf_entry_paid($entry,$pay_info,$event='paid'){
1259 // if($entry['payment_status'] == 'Paid'){
1260 $entry_id=$this->post('id',$entry);
1261 $form=array('id'=>$entry['form_id'],'title'=>'form id '.$entry['form_id']);
1262 if(!empty($feed['meta']['feedName'])){
1263 $form['title']=$feed['meta']['feedName'];
1264 }
1265 if($this->do_actions()){
1266 do_action('vx_addons_save_entry',$entry_id,$entry,'gf',$form);
1267 }
1268 $this->push($entry,$form,'paid',false);
1269 // }
1270 }
1271 /**
1272 * Send entry to crm on update
1273 *
1274 * @param mixed $form
1275 * @param mixed $lead_id
1276 */
1277 public function update_entry($form,$lead_id){
1278
1279 $meta=get_option($this->type.'_settings',array());
1280
1281 if(!empty($meta['update']) || isset($_POST[$this->id.'_update'])){
1282 $entry=$this->get_gf_entry($lead_id);
1283
1284 $push=$this->push($entry,$form,'update');
1285 if(!empty($push['msg'])){
1286 $this->screen_msg($push['msg'],$push['class']);
1287 }
1288 }
1289
1290 }
1291 public function update_entry_api($entry){
1292 $meta=get_option($this->type.'_settings',array());
1293 if(!empty($meta['update']) || isset($_POST[$this->id.'_update'])){
1294 if(!empty($entry['form_id'])){
1295 $form = GFAPI::get_form( $entry['form_id'] );
1296 $push=$this->push($entry,$form,'update');
1297 if(!empty($push['msg'])){
1298 $this->screen_msg($push['msg'],$push['class']);
1299 }
1300 }
1301 }
1302 }
1303 public function entry_status($id,$status,$old){
1304 $meta=get_option($this->type.'_settings',array());
1305 $option = '';
1306 if($status == 'active'){
1307 $option= 'restore';
1308 }else if($status == 'trash'){
1309 $option='delete';
1310 }
1311
1312 if( !empty($option) && !empty($meta[$option])){
1313 // $option= $option == 'restore' ? '' : $option;
1314 $entry=$this->get_gf_entry($id);
1315 $form=array();
1316 if(!empty($entry['form_id'])){
1317 $form = RGFormsModel::get_form_meta($entry['form_id']);
1318 }
1319 $this->push($entry,$form,$option);
1320 }
1321
1322 }
1323 /**
1324 * push form data to crm
1325 *
1326 * @param mixed $entry
1327 * @param mixed $form
1328 * @param mixed $is_admin
1329 */
1330 public function push($entry, $form,$event="",$is_admin=false,$log=""){
1331
1332
1333 $data_db=$this->get_data_object();
1334 $log_id=''; $feeds_meta=array();
1335 if(!empty($log)){
1336 if(isset($log['id'])){
1337 $log_id=$log['id'];
1338 }
1339 $log_feed=$data_db->get_feed($log['feed_id']);
1340 if(!empty($log_feed)){
1341 $feeds_meta=array($log_feed);
1342 }
1343 }else{
1344 //get feeds of a form
1345 $feeds=$data_db->get_feed_by_form($entry['form_id'],true);
1346
1347 if(is_array($feeds) && count($feeds)>0){
1348 $k=1000; $e=2000; $i=1;
1349 foreach($feeds as $feed){
1350 $data=isset($feed['data']) ? json_decode($feed['data'],true) : array();
1351 $meta=isset($feed['meta']) ? json_decode($feed['meta'],true) : array();
1352 $feed['meta']=$meta;
1353 $feed['data']=$data;
1354 $object=$this->post('object',$feed);
1355 if(!empty($data['contract_check']) || !empty($data['account_check'])|| !empty($data['contact_check'])){
1356 if($object == 'Order'){
1357 $feeds_meta[$e++]=$feed;
1358 }else{
1359 $feeds_meta[$k++]=$feed;
1360 }
1361 }else{
1362 $feeds_meta[$i++]=$feed;
1363 }
1364 }
1365 ksort($feeds_meta);
1366 //
1367 }
1368 }
1369 $form_id=0;
1370 if(isset($form['id'])){
1371 $form_id=$form['id'];
1372 }
1373
1374 $entry_id=$this->post('id',$entry);
1375 if(isset($entry['__vx_id'])){
1376 $entry_id=$entry['__vx_id'];
1377 }else{
1378 $entry=apply_filters('vx_crm_post_fields',$entry,$entry_id,'gf',$form);
1379 }
1380 //var_dump($entry); die();
1381 $n=0;
1382 $screen_msg_class="updated"; $notice="";
1383 if(is_array($feeds_meta) && count($feeds_meta)>0){
1384 while($feed=current($feeds_meta)){
1385 next($feeds_meta);
1386 $n++;
1387 $temp=array();
1388 $force_send=false;
1389 $post_comment=true;
1390 $screen_msg="";
1391 $parent_id=0;
1392 if(isset($entry['__vx_parent_id'])){
1393 $parent_id=$entry['__vx_parent_id'];
1394 }
1395 $object=$this->post('object',$feed);
1396 $data=$feed['data'];
1397 $meta=$feed['meta'];
1398 $account=$this->post('account',$feed);
1399
1400 $info=$this->get_info($account);
1401 $info_data=array();
1402 if(isset($info['data'])){
1403 $info_data=$info['data'];
1404 }
1405 $api_type=$this->post('api',$info_data);
1406
1407 if(!empty($object) && in_array($event,array('restore','update','delete','add_note','delete_note'))){
1408
1409 $search_object=$object;
1410 if(in_array($event,array('add_note','delete_note')) && !empty($log)){
1411
1412 if($event == 'add_note'){
1413 $note=json_decode($log['data'],true);
1414 if(!empty($note['Title']['value'])){
1415 self::$note=array('id'=>$log['parent_id']);
1416 self::$note['title']=$note['Title']['value'];
1417 self::$note['body']=$note['Body']['value'];
1418 }
1419 }
1420 }
1421 if($event == 'delete_note' && !empty(self::$note)){
1422 $parent_id=self::$note['id'];
1423 }
1424
1425 if(in_array($event,array('delete_note','add_note'))){
1426 //check feed
1427 $order_notes=$this->post('entry_notes',$data); //if notes sync not enabled in feed return
1428
1429 if( empty($order_notes)){
1430 continue;
1431 }
1432
1433 //change main object to Note
1434 $feed['related_object']=$object;
1435 $object=$feed['object']=!empty($meta['note_list']) ? 'ContentNote' : 'Note';
1436 }
1437 if($event == 'delete_note'){
1438 //when deleting note search note object
1439 $search_object='Note';
1440 }
1441 $_data=$this->get_data_object();
1442 $feed_log=$_data->get_feed_log($feed['id'],$entry_id,$search_object,$parent_id);
1443
1444 if($event == 'restore' && $feed_log['status'] != 5) { // only allow successfully deleted records
1445 continue;
1446 }
1447 if( in_array($event,array('update','delete') ) && !in_array($feed_log['status'],array(1,2) ) ){ // only allow successfully sent records
1448 continue;
1449 }
1450
1451 if(empty($feed_log['crm_id']) || empty($feed_log['object']) || $feed_log['object'] != $search_object){
1452
1453 continue;
1454 }
1455 //if($event !='restore'){
1456 $feed['crm_id']=$feed_log['crm_id'];
1457 // unset($feed['primary_key']);
1458 //}
1459 $feed['event']=$event;
1460 // add note and save related extra info
1461 if( $event == 'add_note' && !empty(self::$note)){
1462 $temp=array('Title'=>array('value'=>self::$note['title']),'Body'=>array('value'=>self::$note['body']),'ParentId'=>array('value'=> $feed['crm_id']));
1463
1464 $parent_id=self::$note['id'];
1465 $object_link=$feed_log['crm_id'];
1466 $feed['note_object_link']='<a href="'.$feed_log['link'].'" target="_blank">'.$feed_log['crm_id'].'</a>';
1467 }
1468 // delete not and save extra info
1469 if( $event == 'delete_note'){
1470
1471 $feed_log_arr= json_decode($feed_log['extra'],true);
1472 if(isset($feed_log_arr['note_object_link'])){
1473 $feed['note_object_link']=$feed_log_arr['note_object_link'];
1474 }
1475 $temp=array('ParentId'=>array('value'=> $feed['crm_id']));
1476 }
1477 //delete object
1478 if( $event == 'delete'){
1479 $temp=array('Id'=>array('value'=> $feed['crm_id']));
1480 }
1481 //
1482 if(!in_array($event , array('update','restore') )){
1483 //do not apply filters when adding note , deleting note , entry etc
1484 $force_send=true;
1485 }
1486 if($event == 'restore'){ // send as new entry
1487 // unset($feed['crm_id']);
1488 }
1489 //do not post comment in al other cases
1490 $post_comment=false;
1491
1492 }
1493 // var_dump(self::$note,$object,$feed['note_object'],$feed['object'],$feed['crm_id'],$feed['event'],$temp,$force_send);
1494 //continue;
1495 $feed_event=$this->post('manual_export',$data);
1496 if(!$is_admin){
1497 if($event == 'submit' && $feed_event != ''){ //if manual export is yes
1498 continue;
1499 }
1500 if($event == 'after_submit' && $feed_event != '4'){
1501 continue;
1502 }
1503 if($event == 'subscription_paid' && $feed_event != '3'){
1504 continue;
1505 }
1506 if($event == 'paid' && $feed_event != '2'){ // only process paid event, if set in feed
1507 continue;
1508 }
1509 }
1510 if(!$force_send && isset($data['map']) && is_array($data['map']) && count($data['map'])>0){
1511
1512
1513 $custom= isset($meta['fields']['fields']) && is_array($meta['fields']['fields']) ? $meta['fields']['fields'] : array();
1514 $skip_feed=false;
1515 foreach($data['map'] as $k=>$v){
1516
1517 $value=false;
1518 if(!empty($v)){ //if value not empty
1519 $field_type=$this->post('type',$v);
1520 if( !empty($field_type) ){ //custom value
1521 $value=trim($this->post('value',$v));
1522 $value=$this->process_tags($entry,$form,$value);
1523
1524
1525 }else{ //general field
1526 $field=$this->post('field',$v);
1527 if($field !=""){
1528 if(strpos($field,'_vx_feed-') !== false){
1529 $temp_feed_id=substr($field,9);
1530 if(isset(self::$feeds_res[$temp_feed_id])){
1531 $value= !empty(self::$feeds_res[$temp_feed_id]['id']) ? self::$feeds_res[$temp_feed_id]['id'] : '';
1532 }else if($n < count($feeds_meta) ){ // it is not last element
1533 $feeds_meta[]=$feed; $skip_feed=true;
1534 break;
1535 }
1536 }else{
1537 $value=$this->verify_field_val($entry,$form,$field,$k,$custom);
1538 $gf_field= RGFormsModel::get_field($form, $field);
1539 if(!empty($gf_field) && in_array($gf_field->type,array('checkbox')) && !empty($gf_field->choices) && count($gf_field->choices)< 2 ){
1540 if(!empty($value)){ $value='Yes'; }else{ $value='No'; } //single checkbox or acceptance field , googlesheets web2lead accepts only 1 for checkbox field
1541 }
1542 }
1543 }
1544
1545 }
1546
1547 if($value!== false){
1548 if(isset($custom[$k]['name'])){
1549 $temp[$k]=array('value'=>$value,'label'=>$custom[$k]['label']);
1550 }else if(isset($custom[$k]['name_c'])){
1551 $temp[$custom[$k]['name_c']]=array('value'=>$value,'label'=>$custom[$k]['name_c']);
1552 }
1553 }
1554 }
1555 }
1556 //var_dump($temp,$entry,$form); die();
1557 if($skip_feed){ continue; }
1558
1559 if($object == 'Order'){
1560 $temp['Status']=array('value'=>'Draft','label'=>'Draft');
1561 }
1562 //change owner id
1563 if(isset($data['owner']) && !empty($data['user'])){
1564 $temp['OwnerId']=array('value'=>apply_filters('vx_assigned_user_id',$data['user'],$this->id,$feed['id'],$entry,$form),'label'=>'Owner ID');
1565 }
1566
1567 //add account or contract
1568
1569 if(!empty($data['contract_check']) && !empty($data['object_contract'])){
1570 $contract_feed=$data['object_contract'];
1571 if( isset(self::$feeds_res[$contract_feed]) ){
1572
1573 $contract_res=self::$feeds_res[$contract_feed];
1574 /////
1575 if(!empty($contract_res['id'])){
1576 $temp['ContractId']=array('value'=> $contract_res['id'],'label'=>'Contract ID');
1577 }else{ //if empty continue
1578 continue;
1579 }
1580 }
1581 }
1582 if(!empty($data['account_check']) && !empty($data['object_account'])){
1583 $account_feed=$data['object_account'];
1584 if( isset(self::$feeds_res[$account_feed]) ){
1585
1586 $account_res=self::$feeds_res[$account_feed];
1587 /////
1588 if(!empty($account_res['id'])){
1589 $temp['AccountId']=array('value'=> $account_res['id'],'label'=>'Account ID');
1590 }else{ //if empty continue
1591 continue;
1592 }
1593 }
1594
1595 }
1596 if(!empty($data['contact_check']) && !empty($data['contact_feed'])){
1597 $contact_feed=$data['contact_feed'];
1598 if( isset(self::$feeds_res[$contact_feed]) ){
1599
1600 $contact_res=self::$feeds_res[$contact_feed];
1601 /////
1602 if(!empty($contact_res['id'])){
1603 $temp['contact_id']=$contact_res['id'];
1604 }else{ //if empty continue
1605 // continue;
1606 }
1607 }
1608 }
1609 //add note
1610 if(!empty($data['note_check']) ){
1611 $entry_note=''; $entry_note_title='';
1612 if(!empty($data['note_fields']) && is_array($data['note_fields'])){
1613 $data['note_val']='{'.implode("}\n{",$data['note_fields'])."}\n";
1614 }
1615 if(!empty($data['note_val'])){
1616 $entry_note=$this->process_tags($entry,$form,$data['note_val']);
1617 if(empty($entry_note_title)){
1618 $entry_note_title=substr($entry_note,0,20);
1619 }
1620 if(!empty($entry_note)){
1621 $feed['__vx_entry_note']=array('Title'=>$entry_note_title,'Body'=>$entry_note);
1622 }
1623 }
1624 }
1625 }
1626 $no_filter=true;
1627
1628 if(isset($_REQUEST['bulk_action']) && $_REQUEST['bulk_action'] =="send_to_crm_bulk_force" && !empty($log_id)){
1629 $force_send=true;
1630 }
1631 if(!$force_send && $this->post('optin_enabled',$data) == "1"){ //apply filters if not sending by force and optin is enabled
1632 $no_filter=$this->check_filter($data,$entry,$form);
1633 $res=array("status"=>"4","extra"=>array("filter"=>$this->filter_condition),"data"=>$temp);
1634 }
1635
1636 //echo json_encode($temp).'---------'.json_encode($entry); die();
1637
1638
1639 if($no_filter){ //get $res if no filter , other wise use filtered $res
1640 $api=$this->get_api($info);
1641 $feed_arr=$feed;
1642 if(is_array($meta) && is_array($data)){
1643 $feed_arr=array_merge($meta,$data,$feed);
1644 }
1645 $res=$api->push_object($feed['object'],$temp,$feed_arr);
1646 if($object == 'Contact' && !empty($res['id'])){
1647 $entry['sf_contact_id']=$res['id'];
1648 }
1649 }
1650
1651 $feed_id=$this->post('id',$feed);
1652 self::$feeds_res[$feed_id]=$res;
1653 $status=$res['status']; $error="";
1654 $id=$this->post('id',$res);
1655 $added=false;
1656 if($api_type != 'web' && !empty($id)){
1657 $added=true;
1658 }else if($api_type == 'web' && !empty($status)){
1659 $added=true;
1660 }
1661 if( $added){
1662 $id=$res['id'];
1663 $action=$this->post('action',$res);
1664 if($action == "Added"){
1665 if(empty($res['link'])){
1666 $msg=sprintf(__('Successfully Added to Google Sheets (%s) with ID # %s .', 'gravity-forms-googlesheets-crm'),$feed['object'],$res['id']);
1667 }else{
1668 $msg=sprintf(__('Successfully Added to Google Sheets (%s) with ID # %s . View entry at %s', 'gravity-forms-googlesheets-crm'),$feed['object'],$res['id'],$res['link']);
1669 }
1670 $screen_msg=__( 'Entry added in Google Sheets', 'gravity-forms-googlesheets-crm');
1671 }else{
1672 if(empty($res['link'])){
1673 $msg=sprintf(__('Successfully Updated to Google Sheets (%s) with ID # %s . View entry at %s', 'gravity-forms-googlesheets-crm'),$feed['object'],$res['id'],$res['link']);
1674 }else{
1675 $msg=sprintf(__('Successfully Updated to Google Sheets (%s) with ID # %s .', 'gravity-forms-googlesheets-crm'),$feed['object'],$res['id']);
1676 }
1677 $screen_msg=__( 'Entry updated in Google Sheets', 'gravity-forms-googlesheets-crm');
1678 }
1679
1680
1681 }else if($this->post('status',$res) == 4){
1682 $screen_msg=$msg=__( 'Entry filtered', 'gravity-forms-googlesheets-crm');
1683 }else{
1684 $status=0; $screen_msg_class="error";
1685 $screen_msg=__('Errors when adding to Google Sheets. Entry not sent! Check the Entry Notes below for more details.' , 'gravity-forms-googlesheets-crm' );
1686 if($log_id!=""){
1687 //message for bulk actions in logs
1688 $screen_msg=__('Errors when adding to Google Sheets. Entry not sent' , 'gravity-forms-googlesheets-crm' );
1689 }
1690 $msg=sprintf(__('Error while creating %s', 'gravity-forms-googlesheets-crm'),$feed['object']);
1691 if($this->post('error',$res)!=""){
1692 $error= is_array($res['error']) ? json_encode($res['error']) : $res['error'];
1693 $msg.=" ($error)";
1694
1695 $_REQUEST['VXGGoogle SheetsError']=$msg; //front end form error for admin only
1696 }
1697 if(!$is_admin){
1698 $info_data['msg']=$msg;
1699 $this->send_error_email($info_data,$entry,$form);
1700 }
1701 }
1702 //insert log
1703 $arr=array("object"=>$feed["object"],"form_id"=>$form_id,"status"=>$status,"entry_id"=>$entry_id,"crm_id"=>$id,"meta"=>$error,"time"=>date('Y-m-d H:i:s'),"data"=>$temp,"response"=>$this->post('response',$res),"extra"=>$this->post('extra',$res),"feed_id"=>$this->post('id',$feed),"link"=>$this->post('link',$res),'parent_id'=>$parent_id,'event'=>$event);
1704
1705
1706 $settings=get_option($this->type.'_settings',array());
1707 if($this->post('disable_log',$settings) !="yes"){
1708 $insert_id=$data_db->insert_log($arr,$log_id);
1709 }
1710 if(!empty($insert_id)){ //
1711 $log_url=admin_url( 'admin.php?page=gf_edit_forms&view=settings&subview='.$this->id.'&tab=log&log_id='.$insert_id.'&id='.$form_id);
1712 $log_link=' <a href="'.$log_url.'" class="vx_log_link" data-id="'.$insert_id.'">'.__('View Detail','gravity-forms-googlesheets-crm')."</a>";
1713 $screen_msg.=$log_link;
1714 }
1715 if($post_comment){
1716 //insert entry comment
1717
1718 // $this->add_note($entry["id"], $msg);
1719 }
1720
1721 if($notice!=""){
1722 $notice.='<br/>';
1723 }
1724 $notice.='<b>'.$object.': </b>'.$screen_msg;
1725
1726 }
1727 }
1728
1729 return array("msg"=>$notice,"class"=>$screen_msg_class);
1730 }
1731 public function process_tags($entry,$form,$value,$crm_field_id='',$custom=''){
1732 //starts with { and ends } , any char in brackets except {
1733 preg_match_all('/\{[^\{]+\}/',$value,$matches);
1734 if(!empty($matches[0])){
1735 $vals=array();
1736 foreach($matches[0] as $m){
1737 $m=trim($m,'{}');
1738 $val_cust=$this->verify_field_val($entry,$form,$m,$crm_field_id,$custom);
1739 if(is_array($val_cust)){ $val_cust=trim(implode(' ',$val_cust)); }
1740 $vals['{'.$m.'}']=$val_cust;
1741 }
1742
1743 $value=str_replace(array_keys($vals),array_values($vals),$value);
1744 }
1745 return $value;
1746 }
1747 /**
1748 * Send error email
1749 *
1750 * @param mixed $info
1751 * @param mixed $entry
1752 * @param mixed $form
1753 */
1754 public function send_error_email($info,$entry,$form){
1755 if( trim($this->post('error_email',$info))!=""){
1756 $subject="Error While Posting to Google Sheets";
1757 $entry_link=add_query_arg(array('page' => 'gf_entries','view'=>'entry', 'id' => $entry['form_id'],'lid'=>$entry['id']), admin_url('admin.php'));
1758 $page_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
1759
1760 $detail=array(
1761 "Time"=>date('d/M/y H:i:s',current_time('timestamp')),
1762 "Page URL"=>'<a href="'.$page_url.'" style="word-break:break-all;">'.$page_url.'</a>',
1763 "Entry ID"=>'<a href="'.$entry_link.'" target="_blank" style="word-break:break-all;">'.$entry_link.'</a>'
1764 );
1765 if(isset($form['title'])){
1766 $detail["Form Name"]=$form['title'];
1767 $detail["Form Id"]=$form['id'];
1768 }
1769 $email_info=array("msg"=>$info['msg'],"title"=>__('Google Sheets','gravity-forms-googlesheets-crm')." Error","info_title"=>"More Detail","info"=>$detail);
1770 $email_body=$this->format_user_info($email_info,true);
1771
1772 $error_emails=explode(",",$info['error_email']);
1773 $headers = array('Content-Type: text/html; charset=UTF-8');
1774 foreach($error_emails as $email)
1775 wp_mail(trim($email),$subject, $email_body,$headers);
1776 }
1777 }
1778 /**
1779 * Get Objects from local options or from googlesheets
1780 *
1781 * @param mixed $check_option
1782 * @return array
1783 */
1784 public function get_objects($info="",$refresh=false){
1785
1786 $data=$this->post('data',$info);
1787 $api_type=$this->post('api',$data);
1788
1789 if(empty($info)){
1790 $option=get_option($this->id.'_meta',array());
1791
1792 return !empty($option['objects']) ? $option['objects'] : '';
1793 }
1794 $objects=array();
1795 $meta=$this->post('meta',$info);
1796
1797 if(! isset($meta['objects'])){
1798 $refresh=true;
1799 }else{
1800 $objects=$meta['objects'];
1801 }
1802 //get objects from googlesheets
1803 if($refresh){
1804 $api=$this->get_api($info);
1805 $objects=$api->get_crm_objects();
1806
1807 if(is_array($objects)){
1808 $option=get_option($this->id.'_meta',array());
1809
1810 $option_objects=$objects;
1811 if(!empty($option['objects']) && is_array($option['objects'])){
1812 $option_objects=array_merge($option['objects'],$option_objects);
1813 }
1814
1815 $option['objects']=$option_objects;
1816 update_option($this->id.'_meta',$option); //save objects for logs search option
1817 $meta["objects"]=$objects;
1818 $this->update_info(array("meta"=>$meta),$info['id']);
1819 }
1820 }
1821 return $objects;
1822 }
1823
1824 /**
1825 * check if user conected to crm
1826 *
1827 * @param mixed $settings
1828 */
1829 public function api_is_valid($info="") {
1830 if(!empty($info['data']['api']) && $info['data']['api'] == 'web'){
1831 return true;
1832 }
1833
1834 if(isset($info['data']) && is_array($info['data']) && isset($info['data']['access_token']) && !empty($info['data']['access_token'])){
1835 return true;
1836 }else{
1837 return false;}
1838 }
1839 }
1840
1841 endif;
1842 $vxg_googlesheets=new vxg_googlesheets();
1843 $vxg_googlesheets->instance();
1844 $vx_gf['vxg_googlesheets']='vxg_googlesheets';
1845