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
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 / ZohoProjects / ZohoProjectsHandler.php

ZohoProjectsHandler.php in Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder 2.0, at includes/Core/Integration/ZohoProjects/ZohoProjectsHandler.php

1,146 lines 38.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * ZohoProjects Integration
5 *
6 */
7
8 namespace BitCode\BitForm\Core\Integration\ZohoProjects;
9
10 use BitCode\BitForm\Core\Integration\IntegrationHandler;
11 use BitCode\BitForm\Core\Util\HttpHelper;
12 use BitCode\BitForm\Core\Util\IpTool;
13
14 /**
15 * Provide functionality for ZohoCrm integration
16 */
17 class ZohoProjectsHandler {
18 private $_formID;
19 private $_integrationID;
20
21 public function __construct($integrationID, $formID) {
22 $this->_formID = $formID;
23 $this->_integrationID = $integrationID;
24 }
25
26 /**
27 * Helps to register ajax function's with wp
28 *
29 * @return null
30 */
31 public static function registerAjax() {
32 add_action('wp_ajax_bitforms_zprojects_generate_token', [__CLASS__, 'generateTokens']);
33 add_action('wp_ajax_bitforms_zprojects_refresh_portals', [__CLASS__, 'refreshPortalsAjaxHelper']);
34 add_action('wp_ajax_bitforms_zprojects_refresh_projects', [__CLASS__, 'refreshProjectsAjaxHelper']);
35 add_action('wp_ajax_bitforms_zprojects_refresh_milestones', [__CLASS__, 'refreshMilestonesAjaxHelper']);
36 add_action('wp_ajax_bitforms_zprojects_refresh_tasklists', [__CLASS__, 'refreshTasklistsAjaxHelper']);
37 add_action('wp_ajax_bitforms_zprojects_refresh_tasks', [__CLASS__, 'refreshTasksAjaxHelper']);
38 add_action('wp_ajax_bitforms_zprojects_refresh_fields', [__CLASS__, 'refreshFieldsAjaxHelper']);
39 add_action('wp_ajax_bitforms_zprojects_refresh_users', [__CLASS__, 'refreshUsersAjaxHelper']);
40 add_action('wp_ajax_bitforms_zprojects_refresh_task_layouts', [__CLASS__, 'refreshTaskLaysAjaxHelper']);
41 add_action('wp_ajax_bitforms_zprojects_refresh_groups', [__CLASS__, 'refreshGroupsAjaxHelper']);
42 add_action('wp_ajax_bitforms_zprojects_refresh_tags', [__CLASS__, 'refreshTagsAjaxHelper']);
43 }
44
45 /**
46 * Process ajax request for generate_token
47 *
48 * @return JSON zoho crm api response and status
49 */
50 public static function generateTokens() {
51 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce($_REQUEST['_ajax_nonce'], 'bitforms_save')) {
52 $inputJSON = file_get_contents('php://input');
53 $requestsParams = json_decode($inputJSON);
54 if (
55 empty($requestsParams->{'accounts-server'})
56 || empty($requestsParams->dataCenter)
57 || empty($requestsParams->clientId)
58 || empty($requestsParams->clientSecret)
59 || empty($requestsParams->redirectURI)
60 || empty($requestsParams->code)
61 ) {
62 wp_send_json_error(
63 __(
64 'Requested parameter is empty',
65 'bit-form'
66 ),
67 400
68 );
69 }
70
71 $apiEndpoint = \urldecode($requestsParams->{'accounts-server'}) . '/oauth/v2/token';
72 $requestParams = [
73 'grant_type' => 'authorization_code',
74 'client_id' => $requestsParams->clientId,
75 'client_secret' => $requestsParams->clientSecret,
76 'redirect_uri' => \urldecode($requestsParams->redirectURI),
77 'code' => $requestsParams->code
78 ];
79 $apiResponse = HttpHelper::post($apiEndpoint, $requestParams);
80
81 if (is_wp_error($apiResponse) || !empty($apiResponse->error)) {
82 wp_send_json_error(
83 empty($apiResponse->error) ? 'Unknown' : $apiResponse->error,
84 400
85 );
86 }
87 $apiResponse->generates_on = \time();
88 wp_send_json_success($apiResponse, 200);
89 } else {
90 wp_send_json_error(
91 __(
92 'Token expired',
93 'bit-form'
94 ),
95 401
96 );
97 }
98 }
99
100 public static function refreshPortalsAjaxHelper() {
101 $authorizationHeader = null;
102 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce($_REQUEST['_ajax_nonce'], 'bitforms_save')) {
103 $inputJSON = file_get_contents('php://input');
104 $queryParams = json_decode($inputJSON);
105 if (
106 empty($queryParams->tokenDetails)
107 || empty($queryParams->dataCenter)
108 || empty($queryParams->clientId)
109 || empty($queryParams->clientSecret)
110 ) {
111 wp_send_json_error(
112 __(
113 'Requested parameter is empty',
114 'bit-form'
115 ),
116 400
117 );
118 }
119 $response = [];
120 if ((intval($queryParams->tokenDetails->generates_on) + (55 * 60)) < time()) {
121 $response['tokenDetails'] = ZohoProjectsHandler::_refreshAccessToken($queryParams);
122 }
123
124 $portalsMetaApiEndpoint = "https://projectsapi.zoho.{$queryParams->dataCenter}/restapi/portals/";
125
126 $authorizationHeader['Authorization'] = "Zoho-oauthtoken {$queryParams->tokenDetails->access_token}";
127 $portalsMetaResponse = HttpHelper::get($portalsMetaApiEndpoint, null, $authorizationHeader);
128
129 if (!is_wp_error($portalsMetaResponse)) {
130 $allPortals = [];
131 $portals = $portalsMetaResponse->portals;
132
133 if (count($portals) > 0) {
134 foreach ($portals as $portal) {
135 $allPortals[$portal->name] = (object) [
136 'portalId' => $portal->id,
137 'portalName' => $portal->name
138 ];
139 }
140 }
141 uksort($allPortals, 'strnatcasecmp');
142 $response['portals'] = $allPortals;
143 } else {
144 wp_send_json_error(
145 empty($portalsMetaResponse->data) ? 'Unknown' : $portalsMetaResponse->error,
146 400
147 );
148 }
149 if (!empty($response['tokenDetails']) && !empty($queryParams->id)) {
150 ZohoProjectsHandler::_saveRefreshedToken($queryParams->formID, $queryParams->id, $response['tokenDetails'], $response['lists']);
151 }
152 wp_send_json_success($response, 200);
153 } else {
154 wp_send_json_error(
155 __(
156 'Token expired',
157 'bit-form'
158 ),
159 401
160 );
161 }
162 }
163
164 public static function refreshProjectsAjaxHelper() {
165 $authorizationHeader = null;
166 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce($_REQUEST['_ajax_nonce'], 'bitforms_save')) {
167 $inputJSON = file_get_contents('php://input');
168 $queryParams = json_decode($inputJSON);
169 if (
170 empty($queryParams->tokenDetails)
171 || empty($queryParams->dataCenter)
172 || empty($queryParams->clientId)
173 || empty($queryParams->clientSecret)
174 || empty($queryParams->portalId)
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'] = ZohoProjectsHandler::_refreshAccessToken($queryParams);
187 }
188
189 $projectsMetaApiEndpoint = "https://projectsapi.zoho.{$queryParams->dataCenter}/restapi/portal/{$queryParams->portalId}/projects/?range=1000&status=active";
190
191 $authorizationHeader['Authorization'] = "Zoho-oauthtoken {$queryParams->tokenDetails->access_token}";
192 $projectsMetaResponse = HttpHelper::get($projectsMetaApiEndpoint, null, $authorizationHeader);
193
194 // wp_send_json_success($projectsMetaResponse, 200);
195
196 if (!is_wp_error($projectsMetaResponse)) {
197 $allProjects = [];
198 $projects = $projectsMetaResponse->projects;
199
200 if (count($projects) > 0) {
201 foreach ($projects as $project) {
202 $allProjects[$project->name] = (object) [
203 'projectId' => $project->id_string,
204 'projectName' => $project->name
205 ];
206 }
207 }
208 uksort($allProjects, 'strnatcasecmp');
209 $response['projects'] = $allProjects;
210 } else {
211 wp_send_json_error(
212 empty($projectsMetaResponse->data) ? 'Unknown' : $projectsMetaResponse->error,
213 400
214 );
215 }
216 if (!empty($response['tokenDetails']) && !empty($queryParams->id)) {
217 ZohoProjectsHandler::_saveRefreshedToken($queryParams->formID, $queryParams->id, $response['tokenDetails'], $response['lists']);
218 }
219 wp_send_json_success($response, 200);
220 } else {
221 wp_send_json_error(
222 __(
223 'Token expired',
224 'bit-form'
225 ),
226 401
227 );
228 }
229 }
230
231 public static function refreshMilestonesAjaxHelper() {
232 $authorizationHeader = null;
233 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce($_REQUEST['_ajax_nonce'], 'bitforms_save')) {
234 $inputJSON = file_get_contents('php://input');
235 $queryParams = json_decode($inputJSON);
236 if (
237 empty($queryParams->tokenDetails)
238 || empty($queryParams->dataCenter)
239 || empty($queryParams->clientId)
240 || empty($queryParams->clientSecret)
241 || empty($queryParams->portalId)
242 || empty($queryParams->projectId)
243 ) {
244 wp_send_json_error(
245 __(
246 'Requested parameter is empty',
247 'bit-form'
248 ),
249 400
250 );
251 }
252 $response = [];
253 if ((intval($queryParams->tokenDetails->generates_on) + (55 * 60)) < time()) {
254 $response['tokenDetails'] = ZohoProjectsHandler::_refreshAccessToken($queryParams);
255 }
256
257 $milestonesMetaApiEndpoint = "https://projectsapi.zoho.{$queryParams->dataCenter}/restapi/portal/{$queryParams->portalId}/projects/{$queryParams->projectId}/milestones/?range=1000";
258
259 $authorizationHeader['Authorization'] = "Zoho-oauthtoken {$queryParams->tokenDetails->access_token}";
260 $milestonesMetaResponse = HttpHelper::get($milestonesMetaApiEndpoint, null, $authorizationHeader);
261
262 if (!is_wp_error($milestonesMetaResponse)) {
263 $allMilestones = [];
264 $milestones = $milestonesMetaResponse->milestones;
265
266 if (count($milestones) > 0) {
267 foreach ($milestones as $milestone) {
268 $allMilestones[$milestone->name] = (object) [
269 'milestoneId' => $milestone->id_string,
270 'milestoneName' => $milestone->name
271 ];
272 }
273 }
274 uksort($allMilestones, 'strnatcasecmp');
275 $response['milestones'] = $allMilestones;
276 } else {
277 wp_send_json_error(
278 empty($milestonesMetaResponse->data) ? 'Unknown' : $milestonesMetaResponse->error,
279 400
280 );
281 }
282 if (!empty($response['tokenDetails']) && !empty($queryParams->id)) {
283 ZohoProjectsHandler::_saveRefreshedToken($queryParams->formID, $queryParams->id, $response['tokenDetails'], $response['lists']);
284 }
285 wp_send_json_success($response, 200);
286 } else {
287 wp_send_json_error(
288 __(
289 'Token expired',
290 'bit-form'
291 ),
292 401
293 );
294 }
295 }
296
297 public static function refreshTasklistsAjaxHelper() {
298 $authorizationHeader = null;
299 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce($_REQUEST['_ajax_nonce'], 'bitforms_save')) {
300 $inputJSON = file_get_contents('php://input');
301 $queryParams = json_decode($inputJSON);
302 if (
303 empty($queryParams->tokenDetails)
304 || empty($queryParams->dataCenter)
305 || empty($queryParams->clientId)
306 || empty($queryParams->clientSecret)
307 || empty($queryParams->portalId)
308 || empty($queryParams->projectId)
309 || empty($queryParams->tasklistFlag)
310 ) {
311 wp_send_json_error(
312 __(
313 'Requested parameter is empty',
314 'bit-form'
315 ),
316 400
317 );
318 }
319 $response = [];
320 if ((intval($queryParams->tokenDetails->generates_on) + (55 * 60)) < time()) {
321 $response['tokenDetails'] = ZohoProjectsHandler::_refreshAccessToken($queryParams);
322 }
323
324 $tasklistsMetaApiEndpoint = "https://projectsapi.zoho.{$queryParams->dataCenter}/restapi/portal/{$queryParams->portalId}/projects/{$queryParams->projectId}/tasklists/?range=1000&flag={$queryParams->tasklistFlag}";
325
326 if ($queryParams->milestoneId) {
327 $tasklistsMetaApiEndpoint .= "&milestone_id={$queryParams->milestoneId}";
328 }
329
330 $authorizationHeader['Authorization'] = "Zoho-oauthtoken {$queryParams->tokenDetails->access_token}";
331 $tasklistsMetaResponse = HttpHelper::get($tasklistsMetaApiEndpoint, null, $authorizationHeader);
332
333 if (!is_wp_error($tasklistsMetaResponse)) {
334 $allTasklists = [];
335 $tasklists = $tasklistsMetaResponse->tasklists;
336
337 if (count($tasklists) > 0) {
338 foreach ($tasklists as $tasklist) {
339 $allTasklists[$tasklist->name] = (object) [
340 'tasklistId' => $tasklist->id_string,
341 'tasklistName' => $tasklist->name
342 ];
343 }
344 }
345 uksort($allTasklists, 'strnatcasecmp');
346 $response['tasklists'] = $allTasklists;
347 } else {
348 wp_send_json_error(
349 empty($tasklistsMetaResponse->data) ? 'Unknown' : $tasklistsMetaResponse->error,
350 400
351 );
352 }
353 if (!empty($response['tokenDetails']) && !empty($queryParams->id)) {
354 ZohoProjectsHandler::_saveRefreshedToken($queryParams->formID, $queryParams->id, $response['tokenDetails'], $response['lists']);
355 }
356 wp_send_json_success($response, 200);
357 } else {
358 wp_send_json_error(
359 __(
360 'Token expired',
361 'bit-form'
362 ),
363 401
364 );
365 }
366 }
367
368 public static function refreshTasksAjaxHelper() {
369 $authorizationHeader = null;
370 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce($_REQUEST['_ajax_nonce'], 'bitforms_save')) {
371 $inputJSON = file_get_contents('php://input');
372 $queryParams = json_decode($inputJSON);
373 if (
374 empty($queryParams->tokenDetails)
375 || empty($queryParams->dataCenter)
376 || empty($queryParams->clientId)
377 || empty($queryParams->clientSecret)
378 || empty($queryParams->portalId)
379 || empty($queryParams->projectId)
380 ) {
381 wp_send_json_error(
382 __(
383 'Requested parameter is empty',
384 'bit-form'
385 ),
386 400
387 );
388 }
389 $response = [];
390 if ((intval($queryParams->tokenDetails->generates_on) + (55 * 60)) < time()) {
391 $response['tokenDetails'] = ZohoProjectsHandler::_refreshAccessToken($queryParams);
392 }
393
394 $tasksMetaApiEndpoint = "https://projectsapi.zoho.{$queryParams->dataCenter}/restapi/portal/{$queryParams->portalId}/projects/{$queryParams->projectId}/tasks/?range=1000";
395
396 if ($queryParams->milestoneId) {
397 $tasksMetaApiEndpoint .= "&milestone_id={$queryParams->milestoneId}";
398 }
399 if ($queryParams->tasklistId) {
400 $tasksMetaApiEndpoint .= "&tasklist_id={$queryParams->tasklistId}";
401 }
402
403 $authorizationHeader['Authorization'] = "Zoho-oauthtoken {$queryParams->tokenDetails->access_token}";
404 $tasksMetaResponse = HttpHelper::get($tasksMetaApiEndpoint, null, $authorizationHeader);
405
406 if (!is_wp_error($tasksMetaResponse)) {
407 $allTasks = [];
408 $tasks = $tasksMetaResponse->tasks;
409
410 if (count($tasks) > 0) {
411 foreach ($tasks as $task) {
412 $allTasks[$task->name] = (object) [
413 'taskId' => $task->id_string,
414 'taskName' => $task->name
415 ];
416 }
417 }
418 uksort($allTasks, 'strnatcasecmp');
419 $response['tasks'] = $allTasks;
420 } else {
421 wp_send_json_error(
422 empty($tasksMetaResponse->data) ? 'Unknown' : $tasksMetaResponse->error,
423 400
424 );
425 }
426 if (!empty($response['tokenDetails']) && !empty($queryParams->id)) {
427 ZohoProjectsHandler::_saveRefreshedToken($queryParams->formID, $queryParams->id, $response['tokenDetails'], $response['lists']);
428 }
429 wp_send_json_success($response, 200);
430 } else {
431 wp_send_json_error(
432 __(
433 'Token expired',
434 'bit-form'
435 ),
436 401
437 );
438 }
439 }
440
441 public static function refreshFieldsAjaxHelper() {
442 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce($_REQUEST['_ajax_nonce'], 'bitforms_save')) {
443 $inputJSON = file_get_contents('php://input');
444 $queryParams = json_decode($inputJSON);
445 if (
446 empty($queryParams->tokenDetails)
447 || empty($queryParams->dataCenter)
448 || empty($queryParams->clientId)
449 || empty($queryParams->clientSecret)
450 || empty($queryParams->portalId)
451 || empty($queryParams->event)
452 ) {
453 wp_send_json_error(
454 __(
455 'Requested parameter is empty',
456 'bit-form'
457 ),
458 400
459 );
460 }
461 $response = [];
462 if ((intval($queryParams->tokenDetails->generates_on) + (55 * 60)) < time()) {
463 $response['tokenDetails'] = ZohoProjectsHandler::_refreshAccessToken($queryParams);
464 }
465
466 if ('project' === $queryParams->event) {
467 $response = ZohoProjectsHandler::getProjectFields($queryParams->dataCenter, $queryParams->portalId, $queryParams->tokenDetails->access_token);
468 } elseif ('milestone' === $queryParams->event) {
469 $response = ZohoProjectsHandler::getMilestoneFields();
470 } elseif ('tasklist' === $queryParams->event) {
471 $response = ZohoProjectsHandler::getTasklistFields();
472 } elseif ('task' === $queryParams->event || 'subtask' === $queryParams->event) {
473 $response = ZohoProjectsHandler::getTaskFields($queryParams->dataCenter, $queryParams->portalId, $queryParams->tokenDetails->access_token, $queryParams->projectId);
474 } elseif ('issue' === $queryParams->event) {
475 $response = ZohoProjectsHandler::getIssueFields($queryParams->dataCenter, $queryParams->portalId, $queryParams->tokenDetails->access_token, $queryParams->projectId);
476 }
477
478 if (!empty($response['tokenDetails']) && $response['tokenDetails'] && !empty($queryParams->id)) {
479 $response['queryModule'] = $queryParams->module;
480 ZohoProjectsHandler::_saveRefreshedToken($queryParams->formID, $queryParams->id, $response['tokenDetails'], $response);
481 }
482 wp_send_json_success($response, 200);
483 } else {
484 wp_send_json_error(
485 __(
486 'Token expired',
487 'bit-form'
488 ),
489 401
490 );
491 }
492 }
493
494 protected static function getProjectFields($dataCenter, $portalId, $access_token) {
495 $allFields = [
496 'Project Title' => [
497 'apiName' => 'name',
498 'displayLabel' => 'Project Title',
499 'required' => true
500 ],
501 'Project Overview' => [
502 'apiName' => 'description',
503 'displayLabel' => 'Project Overview'
504 ],
505 'Start Date' => [
506 'apiName' => 'start_date',
507 'displayLabel' => 'Start Date'
508 ],
509 'End Date' => [
510 'apiName' => 'end_date',
511 'displayLabel' => 'End Date'
512 ],
513 'Strict Project' => [
514 'apiName' => 'strict_project',
515 'displayLabel' => 'Strict Project'
516 ],
517 'Project Budget' => [
518 'apiName' => 'budget_type',
519 'displayLabel' => 'Project Budget'
520 ],
521 'Budget Amount' => [
522 'apiName' => 'budget_value',
523 'displayLabel' => 'Budget Amount'
524 ],
525 'Billing Method' => [
526 'apiName' => 'billing_method',
527 'displayLabel' => 'Billing Method'
528 ],
529 'Currency' => [
530 'apiName' => 'currency',
531 'displayLabel' => 'Currency'
532 ],
533 'Threshold Limit' => [
534 'apiName' => 'threshold',
535 'displayLabel' => 'Threshold Limit'
536 ],
537 'Rate Per Hour' => [
538 'apiName' => 'project_rate',
539 'displayLabel' => 'Rate Per Hour'
540 ],
541 'Fixed Cost' => [
542 'apiName' => 'fixed_cost',
543 'displayLabel' => 'Fixed Cost'
544 ],
545 'Bill Status' => [
546 'apiName' => 'bill_status',
547 'displayLabel' => 'Bill Status'
548 ]
549 ];
550
551 $response['required'][] = 'name';
552
553 $customFieldsMetaApiEndpoint = "https://projectsapi.zoho.{$dataCenter}/restapi/portal/{$portalId}/projects/customfields/";
554 $authorizationHeader['Authorization'] = "Zoho-oauthtoken {$access_token}";
555 $customFieldsMetaResponse = HttpHelper::get($customFieldsMetaApiEndpoint, null, $authorizationHeader);
556
557 if (!is_wp_error($customFieldsMetaResponse)) {
558 $fields = $customFieldsMetaResponse->project_custom_fields;
559
560 if (count($fields) > 0) {
561 foreach ($fields as $field) {
562 $allFields[$field->field_name] = (object) [
563 'apiName' => $field->field_id,
564 'displayLabel' => $field->field_name
565 ];
566
567 if ($field->is_mandatory) {
568 $response['required'][] = $field->field_id;
569 }
570 }
571 }
572 }
573
574 $response['fields'] = $allFields;
575 uksort($response['fields'], 'strnatcasecmp');
576 usort($response['required'], 'strnatcasecmp');
577
578 return $response;
579 }
580
581 protected static function getMilestoneFields() {
582 $allFields = [
583 'Milestone Title' => [
584 'apiName' => 'name',
585 'displayLabel' => 'Milestone Title',
586 'required' => true
587 ],
588 'Start Date' => [
589 'apiName' => 'start_date',
590 'displayLabel' => 'Start Date',
591 'required' => true
592 ],
593 'End Date' => [
594 'apiName' => 'end_date',
595 'displayLabel' => 'End Date',
596 'required' => true
597 ]
598 ];
599
600 $response['required'] = ['name', 'start_date', 'end_date'];
601
602 $response['fields'] = $allFields;
603 uksort($response['fields'], 'strnatcasecmp');
604 usort($response['required'], 'strnatcasecmp');
605
606 return $response;
607 }
608
609 protected static function getTasklistFields() {
610 $allFields = [
611 'Tasklist Title' => [
612 'apiName' => 'name',
613 'displayLabel' => 'Tasklist Title',
614 'required' => true
615 ]
616 ];
617
618 $response['required'] = ['name'];
619
620 $response['fields'] = $allFields;
621 uksort($response['fields'], 'strnatcasecmp');
622 usort($response['required'], 'strnatcasecmp');
623
624 return $response;
625 }
626
627 protected static function getTaskFields($dataCenter, $portalId, $access_token, $projectId) {
628 $allFields = [
629 'Task Title' => [
630 'apiName' => 'name',
631 'displayLabel' => 'Task Title',
632 'required' => true
633 ],
634 'Task Description' => [
635 'apiName' => 'description',
636 'displayLabel' => 'Task Description'
637 ],
638 'Start Date' => [
639 'apiName' => 'start_date',
640 'displayLabel' => 'Start Date'
641 ],
642 'End Date' => [
643 'apiName' => 'end_date',
644 'displayLabel' => 'End Date'
645 ],
646 'Duration' => [
647 'apiName' => 'duration',
648 'displayLabel' => 'Duration'
649 ],
650 'Duration Type' => [
651 'apiName' => 'duration_type',
652 'displayLabel' => 'Duration Type'
653 ],
654 'Start Time' => [
655 'apiName' => 'start_time',
656 'displayLabel' => 'Start Time'
657 ],
658 'End Time' => [
659 'apiName' => 'end_time',
660 'displayLabel' => 'End Time'
661 ],
662 'Rate Per Hour' => [
663 'apiName' => 'rate_per_hour',
664 'displayLabel' => 'Rate Per Hour'
665 ],
666 'Priority' => [
667 'apiName' => 'priority',
668 'displayLabel' => 'Priority'
669 ]
670 ];
671
672 $response['required'][] = 'name';
673
674 // for associate with project
675 $authorizationHeader = null;
676 if ($projectId) {
677 $customFieldsMetaApiEndpoint = "https://projectsapi.zoho.{$dataCenter}/restapi/portal/{$portalId}/projects/{$projectId}/tasklayouts";
678 $authorizationHeader['Authorization'] = "Zoho-oauthtoken {$access_token}";
679 $customFieldsMetaResponse = HttpHelper::get($customFieldsMetaApiEndpoint, null, $authorizationHeader);
680
681 if (!is_wp_error($customFieldsMetaResponse)) {
682 $sections = $customFieldsMetaResponse->section_details;
683
684 if (count($sections) > 0) {
685 foreach ($sections as $section) {
686 $fields = $section->customfield_details;
687 foreach ($fields as $field) {
688 if (!$field->is_default) {
689 $allFields[$field->display_name] = (object) [
690 'apiName' => 'cf_' . $field->column_name,
691 'displayLabel' => $field->display_name
692 ];
693 if ($field->is_mandatory) {
694 $response['required'][] = 'cf_' . $field->column_name;
695 }
696 }
697 }
698 }
699 }
700 }
701 }
702
703 $response['fields'] = $allFields;
704 uksort($response['fields'], 'strnatcasecmp');
705 usort($response['required'], 'strnatcasecmp');
706
707 return $response;
708 }
709
710 protected static function getIssueFields($dataCenter, $portalId, $access_token, $projectId) {
711 $allFields = [
712 'Issue Title' => [
713 'apiName' => 'title',
714 'displayLabel' => 'Issue Title',
715 'required' => true
716 ],
717 'Description' => [
718 'apiName' => 'description',
719 'displayLabel' => 'Description'
720 ],
721 'Due Date' => [
722 'apiName' => 'due_date',
723 'displayLabel' => 'Due Date'
724 ],
725 'Rate Per Hour' => [
726 'apiName' => 'rate_per_hour',
727 'displayLabel' => 'Rate Per Hour'
728 ]
729 ];
730
731 $response['required'] = ['title'];
732
733 // for associate with project
734 $authorizationHeader = null;
735 if ($projectId) {
736 // Custom Fields
737 $customFieldsMetaApiEndpoint = "https://projectsapi.zoho.{$dataCenter}/restapi/portal/{$portalId}/projects/{$projectId}/bugs/customfields/";
738 $authorizationHeader['Authorization'] = "Zoho-oauthtoken {$access_token}";
739 $customFieldsMetaResponse = HttpHelper::get($customFieldsMetaApiEndpoint, null, $authorizationHeader);
740
741 if (!is_wp_error($customFieldsMetaResponse)) {
742 $fields = $customFieldsMetaResponse->customfields;
743
744 if (count($fields) > 0) {
745 foreach ($fields as $field) {
746 $allFields[$field->label_name] = (object) [
747 'apiName' => $field->column_name,
748 'displayLabel' => $field->label_name
749 ];
750
751 if ('true' === $field->is_mandatory) {
752 $response['required'][] = $field->column_name;
753 }
754 }
755 }
756 }
757
758 // Default Fields
759 $defaultFieldsMetaApiEndpoint = "https://projectsapi.zoho.{$dataCenter}/restapi/portal/{$portalId}/projects/{$projectId}/bugs/defaultfields/";
760 $authorizationHeader['Authorization'] = "Zoho-oauthtoken {$access_token}";
761 $defaultFieldsMetaResponse = HttpHelper::get($defaultFieldsMetaApiEndpoint, null, $authorizationHeader);
762
763 if (!is_wp_error($defaultFieldsMetaResponse)) {
764 $response['defaultfields'] = $defaultFieldsMetaResponse->defaultfields;
765 }
766 }
767
768 $response['fields'] = $allFields;
769 uksort($response['fields'], 'strnatcasecmp');
770 usort($response['required'], 'strnatcasecmp');
771
772 return $response;
773 }
774
775 public static function refreshUsersAjaxHelper() {
776 $authorizationHeader = null;
777 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce($_REQUEST['_ajax_nonce'], 'bitforms_save')) {
778 $inputJSON = file_get_contents('php://input');
779 $queryParams = json_decode($inputJSON);
780 if (
781 empty($queryParams->tokenDetails)
782 || empty($queryParams->dataCenter)
783 || empty($queryParams->clientId)
784 || empty($queryParams->clientSecret)
785 || empty($queryParams->portalId)
786 ) {
787 wp_send_json_error(
788 __(
789 'Requested parameter is empty',
790 'bit-form'
791 ),
792 400
793 );
794 }
795 $response = [];
796 if ((intval($queryParams->tokenDetails->generates_on) + (55 * 60)) < time()) {
797 $response['tokenDetails'] = ZohoProjectsHandler::_refreshAccessToken($queryParams);
798 }
799
800 $usersMetaApiEndpoint = '';
801
802 if ($queryParams->projectId) {
803 $usersMetaApiEndpoint = "https://projectsapi.zoho.{$queryParams->dataCenter}/restapi/portal/{$queryParams->portalId}/projects/{$queryParams->projectId}/users/";
804 } else {
805 $usersMetaApiEndpoint = "https://projectsapi.zoho.{$queryParams->dataCenter}/restapi/portal/{$queryParams->portalId}/users/";
806 }
807
808 $authorizationHeader['Authorization'] = "Zoho-oauthtoken {$queryParams->tokenDetails->access_token}";
809 $usersMetaResponse = HttpHelper::get($usersMetaApiEndpoint, null, $authorizationHeader);
810
811 // wp_send_json_success($usersMetaResponse, 200);
812
813 if (!is_wp_error($usersMetaResponse)) {
814 $users = $usersMetaResponse->users;
815
816 if (count($users) > 0) {
817 foreach ($users as $user) {
818 $response['users'][] = (object) [
819 'userId' => $user->id,
820 'userName' => $user->name,
821 'userEmail' => $user->email,
822 ];
823 }
824 }
825 } else {
826 wp_send_json_error(
827 empty($usersMetaResponse->data) ? 'Unknown' : $usersMetaResponse->error,
828 400
829 );
830 }
831 if (!empty($response['tokenDetails']) && !empty($queryParams->id)) {
832 ZohoProjectsHandler::_saveRefreshedToken($queryParams->formID, $queryParams->id, $response['tokenDetails'], $response['lists']);
833 }
834 wp_send_json_success($response, 200);
835 } else {
836 wp_send_json_error(
837 __(
838 'Token expired',
839 'bit-form'
840 ),
841 401
842 );
843 }
844 }
845
846 public static function refreshTaskLaysAjaxHelper() {
847 $authorizationHeader = null;
848 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce($_REQUEST['_ajax_nonce'], 'bitforms_save')) {
849 $inputJSON = file_get_contents('php://input');
850 $queryParams = json_decode($inputJSON);
851 if (
852 empty($queryParams->tokenDetails)
853 || empty($queryParams->dataCenter)
854 || empty($queryParams->clientId)
855 || empty($queryParams->clientSecret)
856 || empty($queryParams->portalId)
857 ) {
858 wp_send_json_error(
859 __(
860 'Requested parameter is empty',
861 'bit-form'
862 ),
863 400
864 );
865 }
866 $response = [];
867 if ((intval($queryParams->tokenDetails->generates_on) + (55 * 60)) < time()) {
868 $response['tokenDetails'] = ZohoProjectsHandler::_refreshAccessToken($queryParams);
869 }
870
871 $taskLaysMetaApiEndpoint = "https://projectsapi.zoho.{$queryParams->dataCenter}/restapi/portal/{$queryParams->portalId}/tasklayouts";
872
873 $authorizationHeader['Authorization'] = "Zoho-oauthtoken {$queryParams->tokenDetails->access_token}";
874 $taskLaysMetaResponse = HttpHelper::get($taskLaysMetaApiEndpoint, null, $authorizationHeader);
875
876 // wp_send_json_success($taskLaysMetaResponse, 200);
877
878 if (!is_wp_error($taskLaysMetaResponse)) {
879 $taskLays = $taskLaysMetaResponse->layouts;
880
881 if (count($taskLays) > 0) {
882 foreach ($taskLays as $taskLay) {
883 $response['taskLays'][] = (object) [
884 'taskLayId' => $taskLay->layout_id,
885 'taskLayName' => $taskLay->layout_name
886 ];
887 }
888 }
889 } else {
890 wp_send_json_error(
891 empty($taskLaysMetaResponse->data) ? 'Unknown' : $taskLaysMetaResponse->error,
892 400
893 );
894 }
895 if (!empty($response['tokenDetails']) && !empty($queryParams->id)) {
896 ZohoProjectsHandler::_saveRefreshedToken($queryParams->formID, $queryParams->id, $response['tokenDetails'], $response['lists']);
897 }
898 wp_send_json_success($response, 200);
899 } else {
900 wp_send_json_error(
901 __(
902 'Token expired',
903 'bit-form'
904 ),
905 401
906 );
907 }
908 }
909
910 public static function refreshGroupsAjaxHelper() {
911 $authorizationHeader = null;
912 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce($_REQUEST['_ajax_nonce'], 'bitforms_save')) {
913 $inputJSON = file_get_contents('php://input');
914 $queryParams = json_decode($inputJSON);
915 if (
916 empty($queryParams->tokenDetails)
917 || empty($queryParams->dataCenter)
918 || empty($queryParams->clientId)
919 || empty($queryParams->clientSecret)
920 || empty($queryParams->portalId)
921 ) {
922 wp_send_json_error(
923 __(
924 'Requested parameter is empty',
925 'bit-form'
926 ),
927 400
928 );
929 }
930 $response = [];
931 if ((intval($queryParams->tokenDetails->generates_on) + (55 * 60)) < time()) {
932 $response['tokenDetails'] = ZohoProjectsHandler::_refreshAccessToken($queryParams);
933 }
934
935 $groupsMetaApiEndpoint = "https://projectsapi.zoho.{$queryParams->dataCenter}/restapi/portal/{$queryParams->portalId}/projects/groups";
936
937 $authorizationHeader['Authorization'] = "Zoho-oauthtoken {$queryParams->tokenDetails->access_token}";
938 $groupsMetaResponse = HttpHelper::get($groupsMetaApiEndpoint, null, $authorizationHeader);
939
940 // wp_send_json_success($groupsMetaResponse, 200);
941
942 if (!is_wp_error($groupsMetaResponse)) {
943 $groups = $groupsMetaResponse->groups;
944
945 if (count($groups) > 0) {
946 foreach ($groups as $group) {
947 $response['groups'][] = (object) [
948 'groupId' => $group->id,
949 'groupName' => $group->name
950 ];
951 }
952 }
953 } else {
954 wp_send_json_error(
955 empty($groupsMetaResponse->data) ? 'Unknown' : $groupsMetaResponse->error,
956 400
957 );
958 }
959 if (!empty($response['tokenDetails']) && !empty($queryParams->id)) {
960 ZohoProjectsHandler::_saveRefreshedToken($queryParams->formID, $queryParams->id, $response['tokenDetails'], $response['lists']);
961 }
962 wp_send_json_success($response, 200);
963 } else {
964 wp_send_json_error(
965 __(
966 'Token expired',
967 'bit-form'
968 ),
969 401
970 );
971 }
972 }
973
974 public static function refreshTagsAjaxHelper() {
975 $authorizationHeader = null;
976 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce($_REQUEST['_ajax_nonce'], 'bitforms_save')) {
977 $inputJSON = file_get_contents('php://input');
978 $queryParams = json_decode($inputJSON);
979 if (
980 empty($queryParams->tokenDetails)
981 || empty($queryParams->dataCenter)
982 || empty($queryParams->clientId)
983 || empty($queryParams->clientSecret)
984 || empty($queryParams->portalId)
985 ) {
986 wp_send_json_error(
987 __(
988 'Requested parameter is empty',
989 'bit-form'
990 ),
991 400
992 );
993 }
994
995 $response = [];
996 if ((intval($queryParams->tokenDetails->generates_on) + (55 * 60)) < time()) {
997 $response['tokenDetails'] = ZohoProjectsHandler::_refreshAccessToken($queryParams);
998 }
999
1000 $tagsMetaApiEndpoint = "https://projectsapi.zoho.{$queryParams->dataCenter}/api/v3/portal/{$queryParams->portalId}/tags";
1001
1002 $authorizationHeader['Authorization'] = "Zoho-oauthtoken {$queryParams->tokenDetails->access_token}";
1003 $tagsMetaResponse = HttpHelper::get($tagsMetaApiEndpoint, null, $authorizationHeader);
1004
1005 // wp_send_json_success($tagsMetaResponse, 200);
1006
1007 if (!is_wp_error($tagsMetaResponse)) {
1008 $tags = $tagsMetaResponse->tags;
1009
1010 if (count($tags) > 0) {
1011 $allTags = [];
1012 foreach ($tags as $tag) {
1013 $allTags[$tag->name] = (object) [
1014 'tagId' => $tag->id,
1015 'tagName' => $tag->name
1016 ];
1017 }
1018 uksort($allTags, 'strnatcasecmp');
1019 $response['tags'] = $allTags;
1020 }
1021 } else {
1022 wp_send_json_error(
1023 empty($tagsMetaResponse->data) ? 'Unknown' : $tagsMetaResponse->error,
1024 400
1025 );
1026 }
1027 if (!empty($response['tokenDetails']) && !empty($queryParams->id)) {
1028 ZohoProjectsHandler::_saveRefreshedToken($queryParams->formID, $queryParams->id, $response['tokenDetails'], $response['lists']);
1029 }
1030 wp_send_json_success($response, 200);
1031 } else {
1032 wp_send_json_error(
1033 __(
1034 'Token expired',
1035 'bit-form'
1036 ),
1037 401
1038 );
1039 }
1040 }
1041
1042 protected static function _refreshAccessToken($apiData) {
1043 if (
1044 empty($apiData->dataCenter)
1045 || empty($apiData->clientId)
1046 || empty($apiData->clientSecret)
1047 || empty($apiData->tokenDetails)
1048 ) {
1049 return false;
1050 }
1051 $tokenDetails = $apiData->tokenDetails;
1052
1053 $dataCenter = $apiData->dataCenter;
1054 $apiEndpoint = "https://accounts.zoho.{$dataCenter}/oauth/v2/token";
1055 $requestParams = [
1056 'grant_type' => 'refresh_token',
1057 'client_id' => $apiData->clientId,
1058 'client_secret' => $apiData->clientSecret,
1059 'refresh_token' => $tokenDetails->refresh_token,
1060 ];
1061
1062 $apiResponse = HttpHelper::post($apiEndpoint, $requestParams);
1063 if (is_wp_error($apiResponse) || !empty($apiResponse->error)) {
1064 return false;
1065 }
1066 $tokenDetails->generates_on = \time();
1067 $tokenDetails->access_token = $apiResponse->access_token;
1068 return $tokenDetails;
1069 }
1070
1071 /**
1072 * Save updated access_token to avoid unnecessary token generation
1073 *
1074 * @param Integer $formID ID of Integration related form
1075 * @param Integer $integrationID ID of Zoho crm Integration
1076 * @param Obeject $tokenDetails refreshed token info
1077 *
1078 * @return null
1079 */
1080 protected static function _saveRefreshedToken($formID, $integrationID, $tokenDetails, $others = null) {
1081 if (empty($formID) || empty($integrationID)) {
1082 return;
1083 }
1084
1085 $integrationHandler = new IntegrationHandler($formID, IpTool::getUserDetail());
1086 $zprojectsDetails = $integrationHandler->getAIntegration($integrationID);
1087
1088 if (is_wp_error($zprojectsDetails)) {
1089 return;
1090 }
1091 $newDetails = json_decode($zprojectsDetails[0]->integration_details);
1092
1093 $newDetails->tokenDetails = $tokenDetails;
1094 if (!empty($others['portals'])) {
1095 $newDetails->default->portals = $others['portals'];
1096 }
1097
1098 $integrationHandler->updateIntegration($integrationID, $zprojectsDetails[0]->integration_name, 'Zoho Projects', \json_encode($newDetails), 'form');
1099 }
1100
1101 public function execute(IntegrationHandler $integrationHandler, $integrationData, $fieldValues, $entryID, $logID) {
1102 $integrationDetails = is_string($integrationData->integration_details) ? json_decode($integrationData->integration_details) : $integrationData->integration_details;
1103
1104 $tokenDetails = $integrationDetails->tokenDetails;
1105 $portalId = $integrationDetails->portalId;
1106 $dataCenter = $integrationDetails->dataCenter;
1107 $fieldMap = $integrationDetails->field_map;
1108 if (
1109 empty($tokenDetails)
1110 || empty($portalId)
1111 || empty($fieldMap)
1112 ) {
1113 return new WP_Error('REQ_FIELD_EMPTY', __('list are required for zoho projects api', 'bit-form'));
1114 }
1115
1116 $requiredParams = null;
1117 if ((intval($tokenDetails->generates_on) + (55 * 60)) < time()) {
1118 $requiredParams['clientId'] = $integrationDetails->clientId;
1119 $requiredParams['clientSecret'] = $integrationDetails->clientSecret;
1120 $requiredParams['dataCenter'] = $integrationDetails->dataCenter;
1121 $requiredParams['tokenDetails'] = $tokenDetails;
1122 $newTokenDetails = ZohoProjectsHandler::_refreshAccessToken((object)$requiredParams);
1123 if ($newTokenDetails) {
1124 ZohoProjectsHandler::_saveRefreshedToken($this->_formID, $this->_integrationID, $newTokenDetails);
1125 $tokenDetails = $newTokenDetails;
1126 }
1127 }
1128
1129 $recordApiHelper = new RecordApiHelper($tokenDetails, $this->_integrationID, $logID);
1130
1131 $zprojectsApiResponse = $recordApiHelper->executeRecordApi(
1132 $this->_formID,
1133 $entryID,
1134 $integrationDetails,
1135 $dataCenter,
1136 $fieldMap,
1137 $fieldValues
1138 );
1139
1140 if (is_wp_error($zprojectsApiResponse)) {
1141 return $zprojectsApiResponse;
1142 }
1143 return $zprojectsApiResponse;
1144 }
1145 }
1146