PluginProbe
Connector for Gravity Forms and Google Sheets / trunk
Connector for Gravity Forms and Google Sheets vtrunk
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 / api / api.php

api.php in Connector for Gravity Forms and Google Sheets trunk, at api/api.php

407 lines 15.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // Exit if accessed directly
3 if( !defined( 'ABSPATH' ) ) exit;
4
5 if(!class_exists('vxg_googlesheets_api')){
6
7 class vxg_googlesheets_api extends vxg_googlesheets{
8
9 public $info='' ; // info
10 public $error= "";
11 public $timeout=30;
12 public $api_version=0;
13 public $api_res='';
14 public $token_url='https://www.googleapis.com/oauth2/v3/token';
15 public $url='https://sheets.googleapis.com/';
16
17
18 function __construct($info){
19 if(isset($info['data'])){
20 $this->info= $info['data'];
21 }
22 if(!empty(self::$api_timeout)){
23 $this->timeout=self::$api_timeout;
24 }
25
26 }
27 /**
28 * Get New Access Token from googlesheets
29 * @param array $form_id Form Id
30 * @param array $info (optional) Google Sheets Credentials of a form
31 * @param array $posted_form (optional) Form submitted by the user,In case of API error this form will be sent to email
32 * @return array Google Sheets API Access Informations
33 */
34 public function get_token($info=""){
35 if(!is_array($info)){
36 $info=$this->info;
37 }
38 if(!isset($info['refresh_token']) || empty($info['refresh_token'])){
39 return $info;
40 }
41 $client=$this->client_info();
42 ////////it is oauth
43 $body=array("client_id"=>$client['client_id'],"client_secret"=>$client['client_secret'],"redirect_uri"=>$client['call_back'],"grant_type"=>"refresh_token","refresh_token"=>$info['refresh_token']);
44 $res=$this->post_google('token',$this->token_url,"post",$body);
45
46 $re=json_decode($res,true);
47 if(isset($re['access_token']) && $re['access_token'] !=""){
48 $info["access_token"]=$re['access_token'];
49 $exp=(int)$this->post('expires_in',$re);
50 $info['expires']=time()+$exp;
51 $info["class"]='updated';
52 $token=$info;
53 }else{
54 $info['error']=isset($re['error_description']) ? $re['error_description'] : '';
55 $info['access_token']="";
56 $info["class"]='error';
57 $token=array(array('errorCode'=>'406','message'=>$re['error_description']));
58
59 }
60 $info["valid_api"]=current_time('timestamp')+86400; //api validity check
61 $this->info=$info;
62 //update googlesheets info
63 //got new token , so update it in db
64 $this->update_info( array("data"=> $info),$info['id']);
65 return $info;
66 }
67 public function handle_code(){
68 $info=$this->info;
69 $id=$info['id'];
70
71 $client=$this->client_info();
72 $log_str=$res=""; $token=array();
73 if(isset($_REQUEST['code'])){
74 $code=$this->post('code');
75 if(!empty($code)){
76 $body=array("client_id"=>$client['client_id'],"client_secret"=>$client['client_secret'],"redirect_uri"=>$client['call_back'],"grant_type"=>"authorization_code","code"=>$code);
77 $res=$this->post_google("token","https://www.googleapis.com/oauth2/v3/token","post",$body);
78 //var_dump($res); die();
79 $log_str="Getting access token from code";
80 $token=json_decode($res,true);
81
82 }
83
84 }else if(!empty($info['refresh_token'])){
85 //revoke token on user request
86 $res=$this->post_google('token',"https://accounts.google.com/o/oauth2/revoke?token=".$info['refresh_token'],"get");
87 $log_str="Access token Revoked on Request";
88 }
89
90 if(isset($_REQUEST['error'])){
91 if(isset($_REQUEST['error_description'])){
92 $token['error_description']=$this->post('error_description');
93 }else{
94 $token['error_description']=$this->post('error');
95 }
96 }
97
98 $info['access_token']=$this->post('access_token',$token);
99 $info['client_id']=$client['client_id'];
100 $info['_id']=$this->post('id',$token);
101 $info['refresh_token']=$this->post('refresh_token',$token);
102
103 $exp=(int)$this->post('expires_in',$token);
104 $info['expires']=time()+$exp;
105 $info['error']=$this->post('error_description',$token);
106 if(!empty($code) && empty($info['refresh_token'])){
107 $info['error']='Go to <a href="https://myaccount.google.com/permissions" target="_blank">https://myaccount.google.com/permissions</a> and select "CRM Perks" or "your custom name" app then click "Remove" button';
108 }
109 $info['time']=current_time('timestamp');
110 $info["class"]='error';
111 if(!empty($info['access_token'])){
112 $info["class"]='updated';
113 }
114
115 $this->info=$info;
116 if(!empty($info['refresh_token'])){
117 $arr=$this->post_google_arr('https://www.googleapis.com/oauth2/v2/userinfo'); //?access_token=
118 if(!empty($arr['email'])){ $info['email']=$arr['email']; }
119 }
120 // $info=$this->validate_api($info);
121 $this->update_info( array('data'=> $info) , $id);
122 //var_dump($info,$arr); //die();
123 return $info;
124 }
125 /**
126 * Posts data to googlesheets, Get New access token on expiration message from googlesheets
127 * @param string $path googlesheets path
128 * @param string $method CURL method
129 * @param array $body (optional) if you want to post data
130 * @return array Google Sheets Response array
131 */
132 public function post_google_arr($path='',$method='get',$body=""){
133 $info=$this->info;
134 $get_token=false;
135 $dev_key='';
136 $head=array();
137 if(!empty($info['access_token'])){
138 $exp=(int)$info['expires'];
139 $dev_key=$info['access_token'];
140 if($exp < time()-1){
141 // $token=$this->get_token();
142 if(!empty($token['access_token'])){
143 $dev_key=$token['access_token'];
144 }
145 }
146 $google_res=$this->post_google($dev_key,$path,$method,$body,$head);
147 $google_response=json_decode($google_res,true);
148 if(isset($google_response['error']['code']) && $google_response['error']['code'] == 401){
149 $token=$this->get_token();
150 if(!empty($token['access_token'])){
151 $dev_key=$token['access_token'];
152 }
153 $google_res=$this->post_google($dev_key,$path,$method,$body,$head);
154 $google_response=json_decode($google_res,true);
155 }
156 if(empty($google_response)){ $google_response=$google_res; }
157 $this->api_res=$google_res;
158
159 return $google_response;
160 }
161
162 }
163 /**
164 * Posts data to googlesheets
165 * @param string $dev_key Slesforce Access Token
166 * @param string $path Google Sheets Path
167 * @param string $method CURL method
168 * @param string $body (optional) if you want to post data
169 * @return string Google Sheets Response JSON
170 */
171 public function post_google($dev_key,$path,$method,$body="",$head=''){
172
173 if($dev_key == 'token'){
174 $header=array('content-type'=>'application/x-www-form-urlencoded');
175 }else if(!empty($dev_key)){
176 $header=array("Authorization"=>' Bearer ' . $dev_key,'content-type'=>'application/json');
177 }
178 if(!empty($head) && is_array($head)){ $header=array_merge($header,$head); }
179 if(is_array($body)&& count($body)>0)
180 {
181 // $body=http_build_query($body);
182 }
183
184 $response = wp_remote_post( $path, array(
185 'method' => strtoupper($method),
186 'timeout' => $this->timeout, //
187 'headers' => $header,
188 'body' => $body
189 ));
190
191 if(is_wp_error($response)){
192 $body=json_encode(array('wp_error'=>$response->get_error_message()));
193 }else{
194 $body=wp_remote_retrieve_body($response);
195 }
196
197 // echo json_encode($header).'-----'.json_encode($response); die();
198 return $body;
199 }
200 /**
201 * Get Google Sheets Client Information
202 * @param array $info (optional) Google Sheets Client Information Saved in Database
203 * @return array Google Sheets Client Information
204 */
205 public function client_info(){
206 $info=$this->info;
207 $client_id=$this->post('app_id',$info);
208 $client_secret=$this->post('app_secret',$info);
209 $call_back=$this->post('app_url',$info);
210
211
212 return array("client_id"=>$client_id,"client_secret"=>$client_secret,"call_back"=>$call_back);
213 }
214 /**
215 * Get fields from googlesheets
216 * @param string $form_id Form Id
217 * @param array $form (optional) Form Settings
218 * @param array $request (optional) custom array or $_REQUEST
219 * @return array Google Sheets fields
220 */
221 public function get_crm_fields($object,$tab=''){
222
223 $google_res=$this->post_google_arr($this->url.'v4/spreadsheets/'.$object); // '?includeGridData=1&ranges=1:1'
224 //var_dump($google_res);
225 $sheets=$fields=array();
226 if(!empty($google_res['sheets'])){
227 foreach($google_res['sheets'] as $v){
228 $title=$v['properties']['title'];
229 $sheets[$v['properties']['sheetId']]=trim($title);
230 if(empty($tab)){ $tab=$title; }
231 }
232 if(!in_array($tab,$sheets)){
233 $tab=$sheets[0];
234 }
235 $res=$this->post_google_arr($this->url.'v4/spreadsheets/'.$object.'/values/'.urlencode("'".$tab."'!1:1"));
236 if(!empty($res['values'][0])){
237 foreach($res['values'][0] as $k=>$v){
238 if(empty($v)){ $v='Col #'.($k+1); }
239 $k='field-'.$k;
240 $fields[$k]=array('name'=>$k,'label'=>$v,'type'=>'Text');
241 }
242 return array('tabs'=>$sheets,'fields'=>$fields);
243 }else{
244 return esc_html__('Sheet header is empty , please add first row in sheet as column titles ','gravity-forms-googlesheets-crm');
245 }
246 }else{
247 $msg=__("No Fields Found",'gravity-forms-googlesheets-crm');
248 if(isset($google_res['error']['errors'][0]['message'])){
249 $msg=$google_res['error']['errors'][0]['message'];
250 }else if(isset($google_res['error']['message'])){
251 $msg=$google_res['error']['message'];
252 }else{
253 $msg=json_encode($google_res);
254 }
255 return $msg;
256 }
257
258 }
259
260 /**
261 * Get Objects from googlesheets
262 * @return array
263 */
264 public function get_crm_objects($files=array(),$token=''){
265 /*$q='mimeType contains \'spreadsheet\''; //mimeType='application/vnd.google-apps.spreadsheet'
266 if(!empty($this->info['email'])){
267 $q.=' and \''.$this->info['email'].'\' in writers';
268 }*/
269
270 // $q="mimeType contains 'spreadsheet'";
271 $q="mimeType='application/vnd.google-apps.spreadsheet'"; //does not show application/vnd.openxmlformats-officedocument.spreadsheetml.sheet because we get "operation not permitted" for these xlxx files when getting header
272 if(!empty($this->info['email'])){
273 // $q.=" and '".$this->info['email']."' in writers";
274 }
275 //$q='';
276 //$sql=array('q'=>$q,'fields'=>'nextPageToken,nextLink,incompleteSearch, items(id,title,mimeType)');
277 $sql=array('q'=>$q,'pageSize'=>1000,'includeItemsFromAllDrives'=>'true','supportsAllDrives'=>'true','orderBy'=>'name');
278 if(!empty($token)){
279 // $sql=array();
280 $sql['pageToken']=$token;
281 }
282 $google_res=$this->post_google_arr('https://www.googleapis.com/drive/v3/files','get',$sql);
283 //$google_res=$this->post_google_arr('https://www.googleapis.com/drive/v2/files','get',$sql);
284 //var_dump($google_res); //die();
285 //echo json_encode($google_res); die();
286 if(isset($google_res['files'])){
287 foreach($google_res['files'] as $object){
288 $files[$object['id']]=$object['name'];
289 }
290 if(count($files)<3000 && !empty($google_res['nextPageToken'])){
291 $files=$this->get_crm_objects($files,$google_res['nextPageToken']);
292 }
293 return $files;
294 }
295 $msg="No Sheet Found"; //json_encode($google_res)
296 if(isset($google_res['error']['errors'][0]['message'])){
297 $msg=$google_res['error']['errors'][0]['message'];
298 }
299 return $msg;
300 }
301 /**
302 * Posts object to googlesheets, Creates/Updates Object or add to object feed
303 * @param array $entry_id Needed to update googlesheets response
304 * @return array Google Sheets Response and Object URL
305 */
306 public function push_object($object,$temp_fields,$meta){
307
308
309 /* $tab='sheet two';
310 $arr=array(array(null, '02-sep-2020 20:20:30','eexxx9999xzz22','zzxxxxxqqqq999qqqqqqq-uuuuuuu'));
311 $post=array('values'=>$arr,"majorDimension"=>"ROWS");
312 $res=$this->post_google_arr($this->url.'v4/spreadsheets/'.$object.'/values/'.urlencode("'".$tab."'!1:1").':append?valueInputOption=USER_ENTERED','post',json_encode($post));
313 var_dump($res); die();*/
314
315
316 $fields_info=array(); $fields=array(); $extra=array();
317 $id=""; $error=""; $action=""; $link=""; $status="";
318 $event=$this->post('event',$meta);
319 $fields_info=isset($meta['fields']['fields']) && is_array($meta['fields']['fields']) ? $meta['fields']['fields'] : array();
320 foreach($fields_info as $k=>$v){
321
322 $value=isset($temp_fields[$k]['value']) ? $temp_fields[$k]['value'] : null; //null
323
324 if(is_array($value) && !empty($value)){
325 if(isset($value[0]) && is_array($value[0])){
326 foreach($value as $kk=>$vv){
327 if(is_array($vv)){ $vv=trim(implode(' - ',$vv)); }
328 $value[$kk]=$vv;
329 }
330 }
331 $value=trim(implode(', ',$value)); }
332
333 $fields[]=$value;
334 }
335
336 if(!empty($meta['tab'])){
337
338 //create new lead
339 $type= !empty($meta['data_type']) ? $meta['data_type'] : 'USER_ENTERED';
340 $row_type= !empty($meta['row_type']) ? $meta['row_type'] : 'OVERWRITE';
341 // first cell of header row should be not empty , other it will continue overwrting first row only
342 $id= isset($meta['crm_id']) ? $meta['crm_id'] : ''; $google_res=array();
343 if($id == ''){
344 $action="Added"; $status="1";
345 $path=$this->url.'v4/spreadsheets/'.$object.'/values/'.urlencode("'".$meta['tab']."'!A2:A").':append?valueInputOption='.$type.'&insertDataOption='.$row_type;
346 //insertDataOption=INSERT_ROWS
347 $post=array('values'=>array($fields),"majorDimension"=>"ROWS");
348 $google_res=$this->post_google_arr($path,"post",json_encode($post));
349 // var_dump($google_res); die();
350 }else if(!empty($id) && is_numeric($id)){
351
352 // $id_arr=explode(':',$id);
353 // $last_index=preg_replace('/[^0-9]/', '', $id_arr[count($id_arr)-1]);
354 // unset($id_arr[count($id_arr)-1]);
355 // $tab=implode($id_arr).':'.$last_index;
356 if(in_array($event,array('delete'))){
357 $sheet_id='';
358 if(!empty($meta['fields']['tabs'])){
359 $sheet_id=array_search($meta['tab'],$meta['fields']['tabs']);
360 }
361 if(!empty($sheet_id)){
362 $method="delete";
363 $action="Deleted";
364 $status="5";
365 // $post=array('requests'=>array(array('deleteDimension'=>array('range'=>array('sheetId'=>$sheet_id,'dimension'=>'ROWS','startIndex'=>intval($id)-1,'endIndex'=>intval($id)))))); $path=$this->url.'v4/spreadsheets/'.$object.':batchUpdate';
366 $path=$this->url.'v4/spreadsheets/'.$object.'/values/'.urlencode("'".$meta['tab']."'!A".$id.":ZZZ".$id).':clear';
367 $google_res=$this->post_google_arr($path,"post",'');
368 }
369 }
370 else{
371 //update object
372 $status="2"; $action="Updated";
373 $method='put'; $end='Z'; if(count($fields)> 26){ $end='ZZZ'; }
374 $path=$this->url.'v4/spreadsheets/'.$object.'/values/'.urlencode("'".$meta['tab']."'!A".$id.":".$end.$id).'?valueInputOption='.$type;
375 $post=array('values'=>array($fields),"majorDimension"=>"ROWS");
376 $google_res=$this->post_google_arr($path,"put",json_encode($post));
377 }
378 }
379 ////insertDataOption=INSERT_ROWS
380 //insertDataOption=INSERT_ROWS
381 // $post=array();
382 //var_dump($meta['tab'],$google_res,$fields,$path,$post); die();
383 if(is_array($google_res)){
384 if(isset($google_res['spreadsheetId'])){
385 if(!empty($google_res['updates']['updatedRange'])){
386 $id_range=$google_res['updates']['updatedRange'];
387 $id_arr=explode(':',$id_range);
388 $id=preg_replace('/[^0-9]/', '', $id_arr[count($id_arr)-1]);
389 }
390 $link='https://docs.google.com/spreadsheets/d/'.$google_res['spreadsheetId'];
391
392 }else if(isset($google_res['error']['message'])){
393 $error=$google_res['error']['message'];
394 }else{
395 $error=json_encode($google_res);
396 }
397 }else{
398 $error=$google_res;
399 }
400 }
401 return array("error"=>substr($error,0,240),"id"=>$id,"link"=>$link,"action"=>$action,"status"=>$status,"data"=>$fields,"response"=>$google_res,"extra"=>$extra);
402 }
403
404
405 }
406 }
407 ?>