PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / 3.1.1
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder v3.1.1
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 / ZohoSheet / ZohoSheetHandler.php

ZohoSheetHandler.php in Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder 3.1.1, at includes/Core/Integration/ZohoSheet/ZohoSheetHandler.php

477 lines 15.4 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\ZohoSheet;
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 ZohoSheetHandler
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_zsheet_generate_token', [__CLASS__, 'generateTokens']);
42 add_action('wp_ajax_bitforms_zsheet_refresh_workbooks', [__CLASS__, 'refreshWorkbooksAjaxHelper']);
43 add_action('wp_ajax_bitforms_zsheet_refresh_worksheets', [__CLASS__, 'refreshWorksheetsAjaxHelper']);
44 add_action('wp_ajax_bitforms_zsheet_refresh_worksheet_headers', [__CLASS__, 'refreshWorksheetHeadersAjaxHelper']);
45 }
46
47 /**
48 * Process ajax request for generate_token
49 *
50 * @return JSON zoho crm 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 GlobalHelper::requirePostMethod();
56
57 try {
58 $requestsParams = GlobalHelper::formatRequestData();
59 } catch (\InvalidArgumentException $e) {
60 wp_send_json_error($e->getMessage(), 400);
61 }
62
63 if (
64 empty($requestsParams->{'accounts-server'})
65 || empty($requestsParams->dataCenter)
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 = \urldecode($requestsParams->{'accounts-server'}) . '/oauth/v2/token';
81 $requestParams = [
82 'grant_type' => 'authorization_code',
83 'client_id' => $requestsParams->clientId,
84 'client_secret' => $requestsParams->clientSecret,
85 'redirect_uri' => \urldecode($requestsParams->redirectURI),
86 'code' => $requestsParams->code
87 ];
88 $apiResponse = HttpHelper::post($apiEndpoint, $requestParams);
89
90 if (is_wp_error($apiResponse) || !empty($apiResponse->error)) {
91 wp_send_json_error(
92 empty($apiResponse->error) ? 'Unknown' : $apiResponse->error,
93 400
94 );
95 }
96 $apiResponse->generates_on = \time();
97 wp_send_json_success($apiResponse, 200);
98 } else {
99 wp_send_json_error(
100 __(
101 'Token expired',
102 'bit-form'
103 ),
104 401
105 );
106 }
107 }
108
109 /**
110 * Process ajax request for refresh crm modules
111 *
112 * @return JSON crm module data
113 */
114 public static function refreshWorkbooksAjaxHelper()
115 {
116 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['_ajax_nonce'])), 'bitforms_save')) {
117 $authorizationHeader = null;
118
119 GlobalHelper::requirePostMethod();
120
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->dataCenter)
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'] = ZohoSheetHandler::_refreshAccessToken($queryParams);
144 }
145
146 $workbooksMetaApiEndpoint = "https://sheet.zoho.{$queryParams->dataCenter}/api/v2/workbooks?method=workbook.list";
147
148 $authorizationHeader['Authorization'] = "Zoho-oauthtoken {$queryParams->tokenDetails->access_token}";
149 $workbooksMetaResponse = HttpHelper::get($workbooksMetaApiEndpoint, null, $authorizationHeader);
150
151 $allWorkbooks = [];
152 if (!is_wp_error($workbooksMetaResponse) && empty($workbooksMetaResponse->response->error)) {
153 $workbooks = $workbooksMetaResponse->workbooks;
154 foreach ($workbooks as $workbook) {
155 $allWorkbooks[$workbook->workbook_name] = (object) [
156 'workbookId' => $workbook->resource_id,
157 'workbookName' => $workbook->workbook_name
158 ];
159 }
160 uksort($allWorkbooks, 'strnatcasecmp');
161 $response['workbooks'] = $allWorkbooks;
162 } else {
163 wp_send_json_error(
164 $workbooksMetaResponse->response->error->message,
165 400
166 );
167 }
168 if (!empty($response['tokenDetails']) && !empty($queryParams->id)) {
169 ZohoSheetHandler::_saveRefreshedToken($queryParams->formID, $queryParams->id, $response['tokenDetails'], $response['workbooks']);
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 crm layout 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 if (
201 empty($queryParams->workbook)
202 || empty($queryParams->tokenDetails)
203 || empty($queryParams->dataCenter)
204 || empty($queryParams->clientId)
205 || empty($queryParams->clientSecret)
206 ) {
207 wp_send_json_error(
208 __(
209 'Requested parameter is empty',
210 'bit-form'
211 ),
212 400
213 );
214 }
215 $response = [];
216 if ((intval($queryParams->tokenDetails->generates_on) + (55 * 60)) < time()) {
217 $response['tokenDetails'] = ZohoSheetHandler::_refreshAccessToken($queryParams);
218 }
219
220 $worksheetsMetaApiEndpoint = "https://sheet.zoho.{$queryParams->dataCenter}/api/v2/{$queryParams->workbook}?method=worksheet.list";
221
222 $authorizationHeader['Authorization'] = "Zoho-oauthtoken {$queryParams->tokenDetails->access_token}";
223 $worksheetsMetaResponse = HttpHelper::get($worksheetsMetaApiEndpoint, null, $authorizationHeader);
224
225 if (!is_wp_error($worksheetsMetaResponse)) {
226 $allWorksheets = [];
227 $worksheets = $worksheetsMetaResponse->worksheet_names;
228 foreach ($worksheets as $worksheet) {
229 $allWorksheets[] = $worksheet->worksheet_name;
230 }
231 usort($allWorksheets, 'strnatcasecmp');
232 $response['worksheets'] = $allWorksheets;
233 } else {
234 wp_send_json_error(
235 'error' === $fieldsMetaResponse->status ? $fieldsMetaResponse->message : 'Unknown',
236 400
237 );
238 }
239 if (!empty($response['tokenDetails']) && $response['tokenDetails'] && !empty($queryParams->id)) {
240 $response['queryWorkbook'] = $queryParams->workbook;
241 ZohoSheetHandler::_saveRefreshedToken($queryParams->formID, $queryParams->id, $response['tokenDetails'], $response);
242 }
243 wp_send_json_success($response, 200);
244 } else {
245 wp_send_json_error(
246 __(
247 'Token expired',
248 'bit-form'
249 ),
250 401
251 );
252 }
253 }
254
255 /**
256 * Process ajax request for refesh crm layouts
257 *
258 * @return JSON crm layout data
259 */
260 public static function refreshWorksheetHeadersAjaxHelper()
261 {
262 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['_ajax_nonce'])), 'bitforms_save')) {
263 $authorizationHeader = null;
264
265 GlobalHelper::requirePostMethod();
266
267 try {
268 $queryParams = GlobalHelper::formatRequestData();
269 } catch (\InvalidArgumentException $e) {
270 wp_send_json_error($e->getMessage(), 400);
271 }
272
273 if (
274 empty($queryParams->workbook)
275 || empty($queryParams->worksheet)
276 || empty($queryParams->tokenDetails)
277 || empty($queryParams->dataCenter)
278 || empty($queryParams->clientId)
279 || empty($queryParams->clientSecret)
280 || empty($queryParams->clientSecret)
281 ) {
282 wp_send_json_error(
283 __(
284 'Requested parameter is empty',
285 'bit-form'
286 ),
287 400
288 );
289 }
290 $response = [];
291 if ((intval($queryParams->tokenDetails->generates_on) + (55 * 60)) < time()) {
292 $response['tokenDetails'] = ZohoSheetHandler::_refreshAccessToken($queryParams);
293 }
294
295 if ((int) $queryParams->headerRow < 1) {
296 $queryParams->headerRow = 1;
297 }
298
299 $baseUrl = "https://sheet.zoho.{$queryParams->dataCenter}/api/v2/{$queryParams->workbook}";
300
301 $params = http_build_query([
302 'method' => 'range.content.get',
303 'worksheet_name' => $queryParams->worksheet,
304 'start_row' => $queryParams->headerRow,
305 'end_row' => $queryParams->headerRow,
306 'start_column' => 1,
307 'end_column' => 100
308 ]);
309
310 $worksheetHeadersMetaApiEndpoint = "{$baseUrl}?{$params}";
311
312 $authorizationHeader['Authorization'] = "Zoho-oauthtoken {$queryParams->tokenDetails->access_token}";
313 $worksheetHeadersMetaResponse = HttpHelper::get($worksheetHeadersMetaApiEndpoint, null, $authorizationHeader);
314
315 if (!is_wp_error($worksheetHeadersMetaResponse)) {
316 $rowDetails = $worksheetHeadersMetaResponse->range_details[0]->row_details ?? [];
317 $allHeaders = is_array($rowDetails)
318 ? array_map(
319 function ($rowDetail) {
320 return isset($rowDetail->content) ? (string) $rowDetail->content : null;
321 },
322 $rowDetails
323 )
324 : [];
325
326 usort($allHeaders, 'strnatcasecmp');
327 $response['worksheet_headers'] = $allHeaders;
328 } else {
329 wp_send_json_error(
330 'error' === $fieldsMetaResponse->status ? $fieldsMetaResponse->message : 'Unknown',
331 400
332 );
333 }
334 if (!empty($response['tokenDetails']) && $response['tokenDetails'] && !empty($queryParams->id)) {
335 $response['queryModule'] = $queryParams->module;
336 ZohoSheetHandler::_saveRefreshedToken($queryParams->formID, $queryParams->id, $response['tokenDetails'], $response);
337 }
338 wp_send_json_success($response, 200);
339 } else {
340 wp_send_json_error(
341 __(
342 'Token expired',
343 'bit-form'
344 ),
345 401
346 );
347 }
348 }
349
350 /**
351 * Helps to refresh zoho crm access_token
352 *
353 * @param object $apiData Contains required data for refresh access token
354 * @return string | boolean $tokenDetails API token details
355 */
356 protected static function _refreshAccessToken($apiData)
357 {
358 if (
359 empty($apiData->dataCenter)
360 || empty($apiData->clientId)
361 || empty($apiData->clientSecret)
362 || empty($apiData->tokenDetails)
363 ) {
364 return false;
365 }
366 $tokenDetails = $apiData->tokenDetails;
367
368 $dataCenter = $apiData->dataCenter;
369 $apiEndpoint = "https://accounts.zoho.{$dataCenter}/oauth/v2/token";
370 $requestParams = [
371 'grant_type' => 'refresh_token',
372 'client_id' => $apiData->clientId,
373 'client_secret' => $apiData->clientSecret,
374 'refresh_token' => $tokenDetails->refresh_token,
375 ];
376
377 $apiResponse = HttpHelper::post($apiEndpoint, $requestParams);
378 if (is_wp_error($apiResponse) || !empty($apiResponse->error)) {
379 return false;
380 }
381 $tokenDetails->generates_on = \time();
382 $tokenDetails->access_token = $apiResponse->access_token;
383 return $tokenDetails;
384 }
385
386 /**
387 * Save updated access_token to avoid unnecessary token generation
388 *
389 * @param integer $fromID ID of Integration related form
390 * @param integer $integrationID ID of Zoho crm Integration
391 * @param object $tokenDetails refreshed token info
392 *
393 * @return null
394 */
395 protected static function _saveRefreshedToken($formID, $integrationID, $tokenDetails, $others = null)
396 {
397 if (empty($formID) || empty($integrationID)) {
398 return;
399 }
400
401 $integrationHandler = new IntegrationHandler($formID, IpTool::getUserDetail());
402 $zsheetDetails = $integrationHandler->getAIntegration($integrationID);
403
404 if (is_wp_error($zsheetDetails)) {
405 return;
406 }
407 $newDetails = json_decode($zsheetDetails[0]->integration_details);
408
409 $newDetails->tokenDetails = $tokenDetails;
410 if (!empty($others['workbooks'])) {
411 $newDetails->default->workbooks = $others['workbooks'];
412 }
413 if (!empty($others['worksheets'])) {
414 $newDetails->default->worksheets = $others['worksheets'];
415 }
416 if (!empty($others['worksheet_headers'])) {
417 $newDetails->default->worksheets->headers->{$others['worksheet']} = $others['worksheet_headers'];
418 }
419
420 $integrationHandler->updateIntegration($integrationID, $zsheetDetails[0]->integration_name, 'Zoho Sheet', wp_json_encode($newDetails), 'form');
421 }
422
423 public function execute(IntegrationHandler $integrationHandler, $integrationData, $fieldValues, $entryID, $logID)
424 {
425 $integrationDetails = is_string($integrationData->integration_details) ? json_decode($integrationData->integration_details) : $integrationData->integration_details;
426
427 $tokenDetails = $integrationDetails->tokenDetails;
428 $workbook = $integrationDetails->workbook;
429 $worksheet = $integrationDetails->worksheet;
430 $headerRow = $integrationDetails->headerRow;
431 $dataCenter = $integrationDetails->dataCenter;
432 $fieldMap = $integrationDetails->field_map;
433 $actions = $integrationDetails->actions;
434 $defaultDataConf = $integrationDetails->default;
435 if (
436 empty($tokenDetails)
437 || empty($workbook)
438 || empty($worksheet)
439 || empty($fieldMap)
440 ) {
441 return new WP_Error('REQ_FIELD_EMPTY', __('module, fields are required for zoho sheet api', 'bit-form'));
442 }
443
444 $requiredParams = null;
445 if ((intval($tokenDetails->generates_on) + (55 * 60)) < time()) {
446 $requiredParams['clientId'] = $integrationDetails->clientId;
447 $requiredParams['clientSecret'] = $integrationDetails->clientSecret;
448 $requiredParams['dataCenter'] = $integrationDetails->dataCenter;
449 $requiredParams['tokenDetails'] = $tokenDetails;
450 $newTokenDetails = ZohoSheetHandler::_refreshAccessToken((object)$requiredParams);
451 if ($newTokenDetails) {
452 ZohoSheetHandler::_saveRefreshedToken($this->_formID, $this->_integrationID, $newTokenDetails);
453 $tokenDetails = $newTokenDetails;
454 }
455 }
456
457 // $actions = $integrationDetails->actions;
458 $recordApiHelper = new RecordApiHelper($tokenDetails, $this->_integrationID, $logID, $this->_formID, $entryID);
459
460 $zsheetApiResponse = $recordApiHelper->executeRecordApi(
461 $workbook,
462 $worksheet,
463 $headerRow,
464 $dataCenter,
465 $actions,
466 $defaultDataConf,
467 $fieldValues,
468 $fieldMap
469 );
470
471 if (is_wp_error($zsheetApiResponse)) {
472 return $zsheetApiResponse;
473 }
474 return $zsheetApiResponse;
475 }
476 }
477