PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / V3.0.2
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder vV3.0.2
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 2.10.2 All 137 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 V3.0.2, at includes/Core/Integration/GoogleSheet/GoogleSheetHandler.php

454 lines 14.5 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 GlobalHelper::requirePostMethod();
121 try {
122 $queryParams = GlobalHelper::formatRequestData();
123 } catch (\InvalidArgumentException $e) {
124 wp_send_json_error($e->getMessage(), 400);
125 }
126
127 if (
128 empty($queryParams->tokenDetails)
129 || empty($queryParams->clientId)
130 || empty($queryParams->clientSecret)
131 ) {
132 wp_send_json_error(
133 __(
134 'Requested parameter is empty',
135 'bit-form'
136 ),
137 400
138 );
139 }
140 $response = [];
141 if ((intval($queryParams->tokenDetails->generates_on) + (55 * 60)) < time()) {
142 $response['tokenDetails'] = self::_refreshAccessToken($queryParams);
143 }
144
145 $workSheets = "https://www.googleapis.com/drive/v3/files?q=mimeType%20%3D%20'application%2Fvnd.google-apps.spreadsheet'";
146
147 $authorizationHeader['Authorization'] = "Bearer {$queryParams->tokenDetails->access_token}";
148 $workSheetResponse = HttpHelper::get($workSheets, null, $authorizationHeader);
149
150 $allSpreadsheet = [];
151 if (!is_wp_error($workSheetResponse) && empty($workSheetResponse->response->error)) {
152 $spreadsheets = $workSheetResponse->files;
153
154 foreach ($spreadsheets as $spreadsheet) {
155 $allSpreadsheet[$spreadsheet->name] = (object) [
156 'spreadsheetId' => $spreadsheet->id,
157 'spreadsheetName' => $spreadsheet->name
158 ];
159 }
160 uksort($allSpreadsheet, 'strnatcasecmp');
161 $response['spreadsheets'] = $allSpreadsheet;
162 } else {
163 wp_send_json_error(
164 $workSheetResponse->response->error->message,
165 400
166 );
167 }
168 if (!empty($response['tokenDetails']) && !empty($queryParams->id)) {
169 self::_saveRefreshedToken($queryParams->formID, $queryParams->id, $response['tokenDetails'], $response['$spreadsheets']);
170 }
171 wp_send_json_success($response, 200);
172 } else {
173 wp_send_json_error(
174 __(
175 'Token expired',
176 'bit-form'
177 ),
178 401
179 );
180 }
181 }
182
183 /**
184 * Process ajax request for refesh crm layouts
185 *
186 * @return JSON data
187 */
188 public static function refreshWorksheetsAjaxHelper()
189 {
190 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['_ajax_nonce'])), 'bitforms_save')) {
191 $authorizationHeader = null;
192
193 GlobalHelper::requirePostMethod();
194
195 try {
196 $queryParams = GlobalHelper::formatRequestData();
197 } catch (\InvalidArgumentException $e) {
198 wp_send_json_error($e->getMessage(), 400);
199 }
200
201 if (
202 empty($queryParams->clientId)
203 || empty($queryParams->clientSecret)
204 || empty($queryParams->spreadsheetId)
205 ) {
206 wp_send_json_error(
207 __(
208 'Requested parameter is empty',
209 'bit-form'
210 ),
211 400
212 );
213 }
214 $response = [];
215 if ((intval($queryParams->tokenDetails->generates_on) + (55 * 60)) < time()) {
216 $response['tokenDetails'] = self::_refreshAccessToken($queryParams);
217 }
218
219 $worksheetsMetaApiEndpoint = "https://sheets.googleapis.com/v4/spreadsheets/$queryParams->spreadsheetId?&fields=sheets.properties";
220
221 $authorizationHeader['Authorization'] = "Bearer {$queryParams->tokenDetails->access_token}";
222 $worksheetsMetaResponse = HttpHelper::get($worksheetsMetaApiEndpoint, null, $authorizationHeader);
223
224 if (!is_wp_error($worksheetsMetaResponse)) {
225 $worksheets = $worksheetsMetaResponse->sheets;
226 $response['worksheets'] = $worksheets;
227 } else {
228 wp_send_json_error(
229 'error' === $worksheetsMetaResponse->status ? $worksheetsMetaResponse->message : 'Unknown',
230 400
231 );
232 }
233 if (!empty($response['tokenDetails']) && $response['tokenDetails'] && !empty($queryParams->id)) {
234 $response['queryWorkbook'] = $queryParams->workbook;
235 self::_saveRefreshedToken($queryParams->formID, $queryParams->id, $response['tokenDetails'], $response);
236 }
237 wp_send_json_success($response, 200);
238 } else {
239 wp_send_json_error(
240 __(
241 'Token expired',
242 'bit-form'
243 ),
244 401
245 );
246 }
247 }
248
249 /**
250 * Process ajax request for refesh crm layouts
251 *
252 * @return JSON data
253 */
254 public static function refreshWorksheetHeadersAjaxHelper()
255 {
256 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['_ajax_nonce'])), 'bitforms_save')) {
257 $authorizationHeader = null;
258
259 GlobalHelper::requirePostMethod();
260 try {
261 $queryParams = GlobalHelper::formatRequestData();
262 } catch (\InvalidArgumentException $e) {
263 wp_send_json_error($e->getMessage(), 400);
264 }
265
266 if (
267 empty($queryParams->worksheetName)
268 || empty($queryParams->tokenDetails)
269 || empty($queryParams->clientId)
270 || empty($queryParams->clientSecret)
271 || empty($queryParams->header)
272 || empty($queryParams->headerRow)
273 ) {
274 wp_send_json_error(
275 __(
276 'Requested parameter is empty',
277 'bit-form'
278 ),
279 400
280 );
281 }
282 $response = [];
283 if ((intval($queryParams->tokenDetails->generates_on) + (55 * 60)) < time()) {
284 $response['tokenDetails'] = self::_refreshAccessToken($queryParams);
285 }
286 $headerRow = $queryParams->headerRow;
287 if ('ROWS' === $queryParams->header) {
288 $rangeNumber = preg_replace('/[^0-9]/', '', $headerRow);
289 $range = "{$headerRow}:ZZ{$rangeNumber}";
290 } else {
291 $columnLetter = preg_replace('/\d/', '', $headerRow);
292 $range = "{$headerRow}:{$columnLetter}1005";
293 }
294
295 $worksheetHeadersMetaApiEndpoint = "https://sheets.googleapis.com/v4/spreadsheets/{$queryParams->spreadsheetId}/values/{$queryParams->worksheetName}!{$range}?majorDimension={$queryParams->header}";
296
297 $authorizationHeader['Authorization'] = "Bearer {$queryParams->tokenDetails->access_token}";
298 $worksheetHeadersMetaResponse = HttpHelper::get($worksheetHeadersMetaApiEndpoint, null, $authorizationHeader);
299
300 if (!is_wp_error($worksheetHeadersMetaResponse)) {
301 $allHeaders = $worksheetHeadersMetaResponse->values[0];
302
303 if (null === $allHeaders) {
304 $response['worksheet_headers'] = [];
305 } else {
306 $response['worksheet_headers'] = $allHeaders;
307 }
308 } else {
309 wp_send_json_error(
310 'error' === $worksheetHeadersMetaResponse->status ? $worksheetHeadersMetaResponse->message : 'Unknown',
311 400
312 );
313 }
314 if (!empty($response['tokenDetails']) && $response['tokenDetails'] && !empty($queryParams->id)) {
315 $response['queryModule'] = $queryParams->module;
316 self::_saveRefreshedToken($queryParams->formID, $queryParams->id, $response['tokenDetails'], $response);
317 }
318 wp_send_json_success($response, 200);
319 } else {
320 wp_send_json_error(
321 __(
322 'Token expired',
323 'bit-form'
324 ),
325 401
326 );
327 }
328 }
329
330 /**
331 * Helps to refresh zoho crm access_token
332 *
333 * @param object $apiData Contains required data for refresh access token
334 * @return string|boolean $tokenDetails API token details
335 */
336 protected static function _refreshAccessToken($apiData)
337 {
338 if (
339 empty($apiData->clientId)
340 || empty($apiData->clientSecret)
341 || empty($apiData->tokenDetails)
342 ) {
343 return false;
344 }
345 $tokenDetails = $apiData->tokenDetails;
346
347 $apiEndpoint = 'https://oauth2.googleapis.com/token';
348 $requestParams = [
349 'grant_type' => 'refresh_token',
350 'client_id' => $apiData->clientId,
351 'client_secret' => $apiData->clientSecret,
352 'refresh_token' => $tokenDetails->refresh_token,
353 ];
354
355 $apiResponse = HttpHelper::post($apiEndpoint, $requestParams);
356 if (is_wp_error($apiResponse) || !empty($apiResponse->error)) {
357 return false;
358 }
359 $tokenDetails->generates_on = \time();
360 $tokenDetails->access_token = $apiResponse->access_token;
361 return $tokenDetails;
362 }
363
364 /**
365 * Save updated access_token to avoid unnecessary token generation
366 *
367 * @param integer $fromID ID of Integration related form
368 * @param integer $integrationID ID of Google Sheet Integration
369 * @param object $tokenDetails refreshed token info
370 *
371 * @return null
372 */
373 protected static function _saveRefreshedToken($formID, $integrationID, $tokenDetails, $others = null)
374 {
375 if (empty($formID) || empty($integrationID)) {
376 return;
377 }
378
379 $integrationHandler = new IntegrationHandler($formID, IpTool::getUserDetail());
380 $gsheetDetails = $integrationHandler->getAIntegration($integrationID);
381
382 if (is_wp_error($gsheetDetails)) {
383 return;
384 }
385 $newDetails = json_decode($gsheetDetails[0]->integration_details);
386
387 $newDetails->tokenDetails = $tokenDetails;
388 if (!empty($others['spreadsheets'])) {
389 $newDetails->default->workbooks = $others['spreadsheets'];
390 }
391 if (!empty($others['worksheets'])) {
392 $newDetails->default->worksheets = $others['worksheets'];
393 }
394 if (!empty($others['worksheet_headers'])) {
395 $newDetails->default->worksheets->headers->{$others['worksheet']} = $others['worksheet_headers'];
396 }
397
398 $integrationHandler->updateIntegration($integrationID, $gsheetDetails[0]->integration_name, 'Google Sheet', wp_json_encode($newDetails), 'form');
399 }
400
401 public function execute(IntegrationHandler $integrationHandler, $integrationData, $fieldValues, $entryID, $logID)
402 {
403 $integrationDetails = is_string($integrationData->integration_details) ? json_decode($integrationData->integration_details) : $integrationData->integration_details;
404
405 $tokenDetails = $integrationDetails->tokenDetails;
406 $spreadsheetId = $integrationDetails->spreadsheetId;
407 $worksheetName = $integrationDetails->worksheetName;
408 $headerRow = $integrationDetails->headerRow;
409 $header = $integrationDetails->header;
410 $fieldMap = $integrationDetails->field_map;
411 $actions = $integrationDetails->actions;
412 $defaultDataConf = $integrationDetails->default;
413 if (
414 empty($tokenDetails)
415 || empty($spreadsheetId)
416 || empty($worksheetName)
417 || empty($fieldMap)
418 ) {
419 return new WP_Error('REQ_FIELD_EMPTY', __('module, fields are required for Google sheet api', 'bit-form'));
420 }
421
422 $requiredParams = null;
423 if ((intval($tokenDetails->generates_on) + (55 * 60)) < time()) {
424 $requiredParams['clientId'] = $integrationDetails->clientId;
425 $requiredParams['clientSecret'] = $integrationDetails->clientSecret;
426 $requiredParams['tokenDetails'] = $tokenDetails;
427 $newTokenDetails = self::_refreshAccessToken((object)$requiredParams);
428 if ($newTokenDetails) {
429 self::_saveRefreshedToken($this->_formID, $this->_integrationID, $newTokenDetails);
430 $tokenDetails = $newTokenDetails;
431 }
432 }
433
434 $recordApiHelper = new RecordApiHelper($tokenDetails, $this->_integrationID, $logID, $entryID);
435
436 $gsheetApiResponse = $recordApiHelper->executeRecordApi(
437 $spreadsheetId,
438 $worksheetName,
439 $headerRow,
440 $header,
441 $actions,
442 $defaultDataConf,
443 $fieldValues,
444 $fieldMap,
445 $this->_formID
446 );
447
448 if (is_wp_error($gsheetApiResponse)) {
449 return $gsheetApiResponse;
450 }
451 return $gsheetApiResponse;
452 }
453 }
454