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

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