PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / 2.9.1
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder v2.9.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 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 2.9.1, at includes/Core/Integration/GoogleSheet/GoogleSheetHandler.php

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