PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / 2.21.13
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder v2.21.13
3.3.1 V-3.3.0 3.2.2 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 V3.0.3 V3.0.2 -3.0.1 V_3.0.0 1.1.1 1.1.8 1.2 1.3 1.4 1.4.18 1.5.2 1.9 2.0 2.10.0 2.10.1 All 138 releases
bit-form / includes / Core / Integration / GoogleSheet / GoogleSheetHandler.php

GoogleSheetHandler.php in Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder 2.21.13, at includes/Core/Integration/GoogleSheet/GoogleSheetHandler.php

458 lines 14.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * ZohoSheet Integration
5 *
6 */
7
8 namespace BitCode\BitForm\Core\Integration\GoogleSheet;
9
10 if (!defined('ABSPATH')) {
11 exit;
12 }
13
14 use BitCode\BitForm\Core\Integration\IntegrationHandler;
15 use BitCode\BitForm\Core\Util\HttpHelper;
16 use BitCode\BitForm\Core\Util\IpTool;
17 use BitCode\BitForm\GlobalHelper;
18 use WP_Error;
19
20 /**
21 * Provide functionality for ZohoCrm integration
22 */
23 class GoogleSheetHandler
24 {
25 private $_formID;
26 private $_integrationID;
27
28 public function __construct($integrationID, $fromID)
29 {
30 $this->_formID = $fromID;
31 $this->_integrationID = $integrationID;
32 }
33
34 /**
35 * Helps to register ajax function's with wp
36 *
37 * @return null
38 */
39 public static function registerAjax()
40 {
41 add_action('wp_ajax_bitforms_gsheet_generate_token', [__CLASS__, 'generateTokens']);
42 add_action('wp_ajax_bitforms_gsheet_refresh_spreadsheets', [__CLASS__, 'refreshSpreadsheetsAjaxHelper']);
43 add_action('wp_ajax_bitforms_gsheet_refresh_worksheets', [__CLASS__, 'refreshWorksheetsAjaxHelper']);
44 add_action('wp_ajax_bitforms_gsheet_refresh_worksheet_headers', [__CLASS__, 'refreshWorksheetHeadersAjaxHelper']);
45 }
46
47 /**
48 * Process ajax request for generate_token
49 *
50 * @return string json api response and status
51 */
52 public static function generateTokens()
53 {
54 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['_ajax_nonce'])), 'bitforms_save')) {
55 $authorizationHeader = null;
56
57 GlobalHelper::requirePostMethod();
58
59 try {
60 $requestsParams = GlobalHelper::formatRequestData();
61 } catch (\InvalidArgumentException $e) {
62 wp_send_json_error($e->getMessage(), 400);
63 }
64
65 if (
66 empty($requestsParams->clientId)
67 || empty($requestsParams->clientSecret)
68 || empty($requestsParams->redirectURI)
69 || empty($requestsParams->code)
70 ) {
71 wp_send_json_error(
72 __(
73 'Requested parameter is empty',
74 'bit-form'
75 ),
76 400
77 );
78 }
79
80 $apiEndpoint = 'https://oauth2.googleapis.com/token';
81 $authorizationHeader['Content-Type'] = 'application/x-www-form-urlencoded';
82 $requestParams = [
83 'grant_type' => 'authorization_code',
84 'client_id' => $requestsParams->clientId,
85 'client_secret' => $requestsParams->clientSecret,
86 'redirect_uri' => \urldecode($requestsParams->redirectURI),
87 'code' => urldecode($requestsParams->code)
88 ];
89 $apiResponse = HttpHelper::post($apiEndpoint, $requestParams, $authorizationHeader);
90
91 if (is_wp_error($apiResponse) || !empty($apiResponse->error)) {
92 wp_send_json_error(
93 empty($apiResponse->error) ? 'Unknown' : $apiResponse->error,
94 400
95 );
96 }
97 $apiResponse->generates_on = \time();
98 wp_send_json_success($apiResponse, 200);
99 } else {
100 wp_send_json_error(
101 __(
102 'Token expired',
103 'bit-form'
104 ),
105 401
106 );
107 }
108 }
109
110 /**
111 * Process ajax request for refresh crm modules
112 *
113 * @return string json crm module data
114 */
115 public static function refreshSpreadsheetsAjaxHelper()
116 {
117 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['_ajax_nonce'])), 'bitforms_save')) {
118 $authorizationHeader = null;
119
120
121 GlobalHelper::requirePostMethod();
122 try {
123 $queryParams = GlobalHelper::formatRequestData();
124 } catch (\InvalidArgumentException $e) {
125 wp_send_json_error($e->getMessage(), 400);
126 }
127
128 if (
129 empty($queryParams->tokenDetails)
130 || empty($queryParams->clientId)
131 || empty($queryParams->clientSecret)
132 ) {
133 wp_send_json_error(
134 __(
135 'Requested parameter is empty',
136 'bit-form'
137 ),
138 400
139 );
140 }
141 $response = [];
142 if ((intval($queryParams->tokenDetails->generates_on) + (55 * 60)) < time()) {
143 $response['tokenDetails'] = self::_refreshAccessToken($queryParams);
144 }
145
146 $workSheets = "https://www.googleapis.com/drive/v3/files?q=mimeType%20%3D%20'application%2Fvnd.google-apps.spreadsheet'";
147
148 $authorizationHeader['Authorization'] = "Bearer {$queryParams->tokenDetails->access_token}";
149 $workSheetResponse = HttpHelper::get($workSheets, null, $authorizationHeader);
150
151 $allSpreadsheet = [];
152 if (!is_wp_error($workSheetResponse) && empty($workSheetResponse->response->error)) {
153 $spreadsheets = $workSheetResponse->files;
154
155 foreach ($spreadsheets as $spreadsheet) {
156 $allSpreadsheet[$spreadsheet->name] = (object) [
157 'spreadsheetId' => $spreadsheet->id,
158 'spreadsheetName' => $spreadsheet->name
159 ];
160 }
161 uksort($allSpreadsheet, 'strnatcasecmp');
162 $response['spreadsheets'] = $allSpreadsheet;
163 } else {
164 wp_send_json_error(
165 $workSheetResponse->response->error->message,
166 400
167 );
168 }
169 if (!empty($response['tokenDetails']) && !empty($queryParams->id)) {
170 self::_saveRefreshedToken($queryParams->formID, $queryParams->id, $response['tokenDetails'], $response['$spreadsheets']);
171 }
172 wp_send_json_success($response, 200);
173 } else {
174 wp_send_json_error(
175 __(
176 'Token expired',
177 'bit-form'
178 ),
179 401
180 );
181 }
182 }
183
184 /**
185 * Process ajax request for refesh crm layouts
186 *
187 * @return JSON data
188 */
189 public static function refreshWorksheetsAjaxHelper()
190 {
191 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['_ajax_nonce'])), 'bitforms_save')) {
192 $authorizationHeader = null;
193
194
195 GlobalHelper::requirePostMethod();
196
197 try {
198 $queryParams = GlobalHelper::formatRequestData();
199 } catch (\InvalidArgumentException $e) {
200 wp_send_json_error($e->getMessage(), 400);
201 }
202
203 if (
204 empty($queryParams->clientId)
205 || empty($queryParams->clientSecret)
206 || empty($queryParams->spreadsheetId)
207 ) {
208 wp_send_json_error(
209 __(
210 'Requested parameter is empty',
211 'bit-form'
212 ),
213 400
214 );
215 }
216 $response = [];
217 if ((intval($queryParams->tokenDetails->generates_on) + (55 * 60)) < time()) {
218 $response['tokenDetails'] = self::_refreshAccessToken($queryParams);
219 }
220
221 $worksheetsMetaApiEndpoint = "https://sheets.googleapis.com/v4/spreadsheets/$queryParams->spreadsheetId?&fields=sheets.properties";
222
223 $authorizationHeader['Authorization'] = "Bearer {$queryParams->tokenDetails->access_token}";
224 $worksheetsMetaResponse = HttpHelper::get($worksheetsMetaApiEndpoint, null, $authorizationHeader);
225
226 if (!is_wp_error($worksheetsMetaResponse)) {
227 $worksheets = $worksheetsMetaResponse->sheets;
228 $response['worksheets'] = $worksheets;
229 } else {
230 wp_send_json_error(
231 'error' === $worksheetsMetaResponse->status ? $worksheetsMetaResponse->message : 'Unknown',
232 400
233 );
234 }
235 if (!empty($response['tokenDetails']) && $response['tokenDetails'] && !empty($queryParams->id)) {
236 $response['queryWorkbook'] = $queryParams->workbook;
237 self::_saveRefreshedToken($queryParams->formID, $queryParams->id, $response['tokenDetails'], $response);
238 }
239 wp_send_json_success($response, 200);
240 } else {
241 wp_send_json_error(
242 __(
243 'Token expired',
244 'bit-form'
245 ),
246 401
247 );
248 }
249 }
250
251 /**
252 * Process ajax request for refesh crm layouts
253 *
254 * @return JSON data
255 */
256 public static function refreshWorksheetHeadersAjaxHelper()
257 {
258 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['_ajax_nonce'])), 'bitforms_save')) {
259 $authorizationHeader = null;
260
261
262 GlobalHelper::requirePostMethod();
263 try {
264 $queryParams = GlobalHelper::formatRequestData();
265 } catch (\InvalidArgumentException $e) {
266 wp_send_json_error($e->getMessage(), 400);
267 }
268
269 if (
270 empty($queryParams->worksheetName)
271 || empty($queryParams->tokenDetails)
272 || empty($queryParams->clientId)
273 || empty($queryParams->clientSecret)
274 || empty($queryParams->header)
275 || empty($queryParams->headerRow)
276 ) {
277 wp_send_json_error(
278 __(
279 'Requested parameter is empty',
280 'bit-form'
281 ),
282 400
283 );
284 }
285 $response = [];
286 if ((intval($queryParams->tokenDetails->generates_on) + (55 * 60)) < time()) {
287 $response['tokenDetails'] = self::_refreshAccessToken($queryParams);
288 }
289 $headerRow = $queryParams->headerRow;
290 if ('ROWS' === $queryParams->header) {
291 $rangeNumber = preg_replace('/[^0-9]/', '', $headerRow);
292 $range = "{$headerRow}:ZZ{$rangeNumber}";
293 } else {
294 $columnLetter = preg_replace('/\d/', '', $headerRow);
295 $range = "{$headerRow}:{$columnLetter}1005";
296 }
297
298 $worksheetHeadersMetaApiEndpoint = "https://sheets.googleapis.com/v4/spreadsheets/{$queryParams->spreadsheetId}/values/{$queryParams->worksheetName}!{$range}?majorDimension={$queryParams->header}";
299
300 $authorizationHeader['Authorization'] = "Bearer {$queryParams->tokenDetails->access_token}";
301 $worksheetHeadersMetaResponse = HttpHelper::get($worksheetHeadersMetaApiEndpoint, null, $authorizationHeader);
302
303 if (!is_wp_error($worksheetHeadersMetaResponse)) {
304 $allHeaders = $worksheetHeadersMetaResponse->values[0];
305
306 if (null === $allHeaders) {
307 $response['worksheet_headers'] = [];
308 } else {
309 $response['worksheet_headers'] = $allHeaders;
310 }
311 } else {
312 wp_send_json_error(
313 'error' === $worksheetHeadersMetaResponse->status ? $worksheetHeadersMetaResponse->message : 'Unknown',
314 400
315 );
316 }
317 if (!empty($response['tokenDetails']) && $response['tokenDetails'] && !empty($queryParams->id)) {
318 $response['queryModule'] = $queryParams->module;
319 self::_saveRefreshedToken($queryParams->formID, $queryParams->id, $response['tokenDetails'], $response);
320 }
321 wp_send_json_success($response, 200);
322 } else {
323 wp_send_json_error(
324 __(
325 'Token expired',
326 'bit-form'
327 ),
328 401
329 );
330 }
331 }
332
333 /**
334 * Helps to refresh zoho crm access_token
335 *
336 * @param object $apiData Contains required data for refresh access token
337 * @return string|boolean $tokenDetails API token details
338 */
339 protected static function _refreshAccessToken($apiData)
340 {
341 if (
342 empty($apiData->clientId)
343 || empty($apiData->clientSecret)
344 || empty($apiData->tokenDetails)
345 ) {
346 return false;
347 }
348 $tokenDetails = $apiData->tokenDetails;
349
350 $apiEndpoint = 'https://oauth2.googleapis.com/token';
351 $requestParams = [
352 'grant_type' => 'refresh_token',
353 'client_id' => $apiData->clientId,
354 'client_secret' => $apiData->clientSecret,
355 'refresh_token' => $tokenDetails->refresh_token,
356 ];
357
358 $apiResponse = HttpHelper::post($apiEndpoint, $requestParams);
359 if (is_wp_error($apiResponse) || !empty($apiResponse->error)) {
360 return false;
361 }
362 $tokenDetails->generates_on = \time();
363 $tokenDetails->access_token = $apiResponse->access_token;
364 return $tokenDetails;
365 }
366
367 /**
368 * Save updated access_token to avoid unnecessary token generation
369 *
370 * @param integer $fromID ID of Integration related form
371 * @param integer $integrationID ID of Google Sheet Integration
372 * @param object $tokenDetails refreshed token info
373 *
374 * @return null
375 */
376 protected static function _saveRefreshedToken($formID, $integrationID, $tokenDetails, $others = null)
377 {
378 if (empty($formID) || empty($integrationID)) {
379 return;
380 }
381
382 $integrationHandler = new IntegrationHandler($formID, IpTool::getUserDetail());
383 $gsheetDetails = $integrationHandler->getAIntegration($integrationID);
384
385 if (is_wp_error($gsheetDetails)) {
386 return;
387 }
388 $newDetails = json_decode($gsheetDetails[0]->integration_details);
389
390 $newDetails->tokenDetails = $tokenDetails;
391 if (!empty($others['spreadsheets'])) {
392 $newDetails->default->workbooks = $others['spreadsheets'];
393 }
394 if (!empty($others['worksheets'])) {
395 $newDetails->default->worksheets = $others['worksheets'];
396 }
397 if (!empty($others['worksheet_headers'])) {
398 $newDetails->default->worksheets->headers->{$others['worksheet']} = $others['worksheet_headers'];
399 }
400
401 $integrationHandler->updateIntegration($integrationID, $gsheetDetails[0]->integration_name, 'Google Sheet', wp_json_encode($newDetails), 'form');
402 }
403
404 public function execute(IntegrationHandler $integrationHandler, $integrationData, $fieldValues, $entryID, $logID)
405 {
406 $integrationDetails = is_string($integrationData->integration_details) ? json_decode($integrationData->integration_details) : $integrationData->integration_details;
407
408 $tokenDetails = $integrationDetails->tokenDetails;
409 $spreadsheetId = $integrationDetails->spreadsheetId;
410 $worksheetName = $integrationDetails->worksheetName;
411 $headerRow = $integrationDetails->headerRow;
412 $header = $integrationDetails->header;
413 $fieldMap = $integrationDetails->field_map;
414 $actions = $integrationDetails->actions;
415 $defaultDataConf = $integrationDetails->default;
416 if (
417 empty($tokenDetails)
418 || empty($spreadsheetId)
419 || empty($worksheetName)
420 || empty($fieldMap)
421 ) {
422 return new WP_Error('REQ_FIELD_EMPTY', __('module, fields are required for Google sheet api', 'bit-form'));
423 }
424
425 $requiredParams = null;
426 if ((intval($tokenDetails->generates_on) + (55 * 60)) < time()) {
427 $requiredParams['clientId'] = $integrationDetails->clientId;
428 $requiredParams['clientSecret'] = $integrationDetails->clientSecret;
429 $requiredParams['tokenDetails'] = $tokenDetails;
430 $newTokenDetails = self::_refreshAccessToken((object)$requiredParams);
431 if ($newTokenDetails) {
432 self::_saveRefreshedToken($this->_formID, $this->_integrationID, $newTokenDetails);
433 $tokenDetails = $newTokenDetails;
434 }
435 }
436
437 $recordApiHelper = new RecordApiHelper($tokenDetails, $this->_integrationID, $logID, $entryID);
438 $fieldValues = IntegrationHandler::replaceFileWithUrl($fieldValues, $this->_formID, $entryID);
439
440 $gsheetApiResponse = $recordApiHelper->executeRecordApi(
441 $spreadsheetId,
442 $worksheetName,
443 $headerRow,
444 $header,
445 $actions,
446 $defaultDataConf,
447 $fieldValues,
448 $fieldMap,
449 $this->_formID
450 );
451
452 if (is_wp_error($gsheetApiResponse)) {
453 return $gsheetApiResponse;
454 }
455 return $gsheetApiResponse;
456 }
457 }
458