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
V3.3.2 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 All 139 releases
bit-form / includes / Core / Integration / ZohoCRM / RecordApiHelper.php

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

294 lines 12.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * ZohoCrm Record Api
5 *
6 */
7
8 namespace BitCode\BitForm\Core\Integration\ZohoCRM;
9
10 use BitCode\BitForm\Core\Util\ApiResponse as UtilApiResponse;
11 use BitCode\BitForm\Core\Util\DateTimeHelper;
12 use BitCode\BitForm\Core\Util\HttpHelper;
13 use BitCode\BitForm\Core\Integration\ZohoCRM\FilesApiHelper;
14 use BitCode\BitForm\Core\Integration\ZohoCRM\TagApiHelper;
15 use BitCode\BitForm\Core\Util\Log;
16 use WP_Error;
17
18 /**
19 * Provide functionality for Record insert,upsert
20 */
21 class RecordApiHelper {
22 protected $_defaultHeader;
23 protected $_apiDomain;
24 protected $_tokenDetails;
25 protected $_logResponse;
26
27 public function __construct($tokenDetails) {
28 $this->_defaultHeader['Authorization'] = "Zoho-oauthtoken {$tokenDetails->access_token}";
29 $this->_apiDomain = \urldecode($tokenDetails->api_domain);
30 $this->_tokenDetails = $tokenDetails;
31 $this->_logResponse = new UtilApiResponse();
32 }
33
34 public function serachRecord($module, $searchCriteria) {
35 $searchRecordEndpoint = "{$this->_apiDomain}/crm/v2/{$module}/search";
36 return HttpHelper::get($searchRecordEndpoint, ['criteria' => "({$searchCriteria})"], $this->_defaultHeader);
37 }
38
39 public function upsertRecord($module, $data) {
40 $insertRecordEndpoint = "{$this->_apiDomain}/crm/v2/{$module}/upsert";
41 $data = \is_string($data) ? $data : \json_encode($data);
42 return HttpHelper::post($insertRecordEndpoint, $data, $this->_defaultHeader);
43 }
44
45 public function insertRecord($module, $data) {
46 $insertRecordEndpoint = "{$this->_apiDomain}/crm/v2/{$module}";
47 $data = \is_string($data) ? $data : \json_encode($data);
48 return HttpHelper::post($insertRecordEndpoint, $data, $this->_defaultHeader);
49 }
50
51 public function executeRecordApi($formID, $entryID, $integId, $logID, $defaultConf, $module, $layout, $fieldValues, $fieldMap, $actions, $required, $fileMap = [], $isRelated = false) {
52 $fieldData = [];
53 $filesApiHelper = new FilesApiHelper($this->_tokenDetails, $formID, $entryID, $integId, $logID);
54 foreach ($fieldMap as $fieldKey => $fieldPair) {
55 if (!empty($fieldPair->zohoFormField)) {
56 if (empty($defaultConf->layouts->{$module}->{$layout}->fields->{$fieldPair->zohoFormField})) {
57 continue;
58 }
59 if ('custom' === $fieldPair->formField && isset($fieldPair->customValue)) {
60 $fieldData[$fieldPair->zohoFormField] = $this->formatFieldValue($fieldPair->customValue, $defaultConf->layouts->{$module}->{$layout}->fields->{$fieldPair->zohoFormField});
61 } else {
62 $fieldData[$fieldPair->zohoFormField] = $this->formatFieldValue($fieldValues[$fieldPair->formField], $defaultConf->layouts->{$module}->{$layout}->fields->{$fieldPair->zohoFormField});
63 }
64 if (empty($fieldData[$fieldPair->zohoFormField]) && \in_array($fieldPair->zohoFormField, $required)) {
65 $error = new WP_Error('REQ_FIELD_EMPTY', wp_sprintf(__('%s is required for zoho crm, %s module', 'bit-form'), $fieldPair->zohoFormField, $module));
66 $this->_logResponse->apiResponse($logID, $integId, ['type' => 'record', 'type_name' => 'field'], 'validation', $error);
67 return $error;
68 }
69
70 if (!empty($fieldData[$fieldPair->zohoFormField])) {
71 $requiredLength = $defaultConf->layouts->{$module}->{$layout}->fields->{$fieldPair->zohoFormField}->length;
72 $currentLength = is_array($fieldData[$fieldPair->zohoFormField]) || is_object($fieldData[$fieldPair->zohoFormField]) ?
73 @count($fieldData[$fieldPair->zohoFormField])
74 : strlen($fieldData[$fieldPair->zohoFormField]);
75 if ($currentLength > $requiredLength) {
76 $error = new WP_Error('REQ_FIELD_LENGTH_EXCEEDED', wp_sprintf(__('zoho crm field %s\'s maximum length is %s, Given %s', 'bit-form'), $fieldPair->zohoFormField, $module));
77 $this->_logResponse->apiResponse($logID, $integId, ['type' => 'record', 'type_name' => 'field'], 'validation', $error);
78 return $error;
79 }
80 }
81 }
82 }
83
84 if (count($fileMap)) {
85 foreach ($fileMap as $fileKey => $filePair) {
86 if (!empty($filePair->zohoFormField)) {
87 if ('fileupload' === $defaultConf->layouts->{$module}->{$layout}->fileUploadFields->{$filePair->zohoFormField}->data_type && !empty($fieldValues[$filePair->formField])) {
88 $files = $fieldValues[$filePair->formField];
89 $fileLength = $defaultConf->layouts->{$module}->{$layout}->fileUploadFields->{$filePair->zohoFormField}->length;
90 if (\is_array($files) && count($files) !== $fileLength) {
91 $files = array_slice($fieldValues[$filePair->formField], 0, $fileLength);
92 }
93 $uploadsIDs = $filesApiHelper->uploadFiles($files);
94 if ($uploadsIDs) {
95 $fieldData[$filePair->zohoFormField] = $uploadsIDs;
96 }
97 }
98 }
99 }
100 }
101 if (!empty($defaultConf->layouts->{$module}->{$layout}->id)) {
102 $fieldData['Layout']['id'] = $defaultConf->layouts->{$module}->{$layout}->id;
103 }
104 if (!empty($actions->gclid) && isset($fieldValues['GCLID'])) {
105 $fieldData['$gclid'] = $fieldValues['GCLID'];
106 }
107 if (!empty($actions->rec_owner)) {
108 $fieldData['Owner']['id'] = $actions->rec_owner;
109 }
110 $requestParams['data'][] = (object) $fieldData;
111 $requestParams['trigger'] = [];
112 if (!empty($actions->workflow)) {
113 $requestParams['trigger'][] = 'workflow';
114 }
115 if (!empty($actions->approval)) {
116 $requestParams['trigger'][] = 'approval';
117 }
118 if (!empty($actions->blueprint)) {
119 $requestParams['trigger'][] = 'blueprint';
120 }
121 if (!empty($actions->assignment_rules)) {
122 $requestParams['lar_id'] = $actions->assignment_rules;
123 }
124 $recordApiResponse = '';
125 if (!empty($actions->upsert) && !empty($actions->upsert->crmField)) {
126 $requestParams['duplicate_check_fields'] = [];
127 if (!empty($actions->upsert)) {
128 $duplicateCheckFields = [];
129 $searchCriteria = '';
130 foreach ($actions->upsert->crmField as $fieldInfo) {
131 if (!empty($fieldInfo->name) && $fieldData[$fieldInfo->name]) {
132 $duplicateCheckFields[] = $fieldInfo->name;
133 if (empty($searchCriteria)) {
134 $searchCriteria .= "({$fieldInfo->name}:equals:{$fieldData[$fieldInfo->name]})";
135 } else {
136 $searchCriteria .= "and({$fieldInfo->name}:equals:{$fieldData[$fieldInfo->name]})";
137 }
138 }
139 }
140 if (isset($actions->upsert->overwrite) && !$actions->upsert->overwrite && !empty($searchCriteria)) {
141 $searchRecordApiResponse = $this->serachRecord($module, $searchCriteria);
142 if (!empty($searchRecordApiResponse) && !empty($searchRecordApiResponse->data)) {
143 $previousData = $searchRecordApiResponse->data[0];
144 foreach ($fieldData as $apiName => $currentValue) {
145 if (!empty($previousData->{$apiName})) {
146 $fieldData[$apiName] = $previousData->{$apiName};
147 }
148 }
149 $requestParams['data'][] = (object) $fieldData;
150 }
151 }
152 $requestParams['duplicate_check_fields'] = $duplicateCheckFields;
153 }
154 $recordApiResponse = $this->upsertRecord($module, (object) $requestParams);
155 } elseif ($isRelated) {
156 $recordApiResponse = $this->insertRecord($module, (object) $requestParams);
157 } else {
158 $recordApiResponse = $this->upsertRecord($module, (object) $requestParams);
159 }
160 if (isset($recordApiResponse->status) && 'error' === $recordApiResponse->status) {
161 $this->_logResponse->apiResponse($logID, $integId, ['type' => 'record', 'type_name' => $module], 'error', $recordApiResponse);
162 } else {
163 $this->_logResponse->apiResponse($logID, $integId, ['type' => 'record', 'type_name' => $module], 'success', $recordApiResponse);
164 }
165 if (
166 !empty($recordApiResponse->data)
167 && !empty($recordApiResponse->data[0]->code)
168 && 'SUCCESS' === $recordApiResponse->data[0]->code
169 && !empty($recordApiResponse->data[0]->details->id)
170 ) {
171 if (!empty($actions->tag_rec)) {
172 $tags = '';
173 $tag_rec = \explode(',', $actions->tag_rec);
174 foreach ($tag_rec as $tag) {
175 if (is_string($tag) && '${' === substr($tag, 0, 2) && '}' === $tag[strlen($tag) - 1]) {
176 $tags .= (!empty($tags) ? ',' : '') . $fieldValues[substr($tag, 2, strlen($tag) - 3)];
177 } else {
178 $tags .= (!empty($tags) ? ',' : '') . $tag;
179 }
180 }
181 $tagApiHelper = new TagApiHelper($this->_tokenDetails, $module);
182 $addTagResponse = $tagApiHelper->addTagsSingleRecord($recordApiResponse->data[0]->details->id, $tags);
183 if (isset($addTagResponse->status) && 'error' === $addTagResponse->status) {
184 $this->_logResponse->apiResponse($logID, $integId, ['type' => 'tag', 'type_name' => $module], 'error', $addTagResponse);
185 } else {
186 $this->_logResponse->apiResponse($logID, $integId, ['type' => 'tag', 'type_name' => $module], 'success', $addTagResponse);
187 }
188 }
189 if (!empty($actions->attachment)) {
190 $validAttachments = [];
191 $fileFound = 0;
192 $responseType = 'success';
193 $attachmentApiResponses = [];
194 $attachment = explode(',', $actions->attachment);
195 foreach ($attachment as $fileField) {
196 if (isset($fieldValues[$fileField]) && !empty($fieldValues[$fileField])) {
197 $fileFound = 1;
198 if (is_array($fieldValues[$fileField])) {
199 foreach ($fieldValues[$fileField] as $singleFile) {
200 $attachmentApiResponse = $filesApiHelper->uploadFiles($singleFile, true, $module, $recordApiResponse->data[0]->details->id);
201 if (isset($attachmentApiResponse->status) && 'error' === $attachmentApiResponse->status) {
202 $responseType = 'error';
203 }
204 }
205 } else {
206 $attachmentApiResponse = $filesApiHelper->uploadFiles($fieldValues[$fileField], true, $module, $recordApiResponse->data[0]->details->id);
207 if (isset($attachmentApiResponse->status) && 'error' === $attachmentApiResponse->status) {
208 $responseType = 'error';
209 }
210 }
211 }
212 }
213 if ($fileFound) {
214 $this->_logResponse->apiResponse($logID, $integId, ['type' => 'attachment', 'type_name' => $module], $responseType, $attachmentApiResponses);
215 }
216 }
217 }
218 return $recordApiResponse;
219 }
220
221 public function formatFieldValue($value, $formatSpecs) {
222 if (empty($value)) {
223 return '';
224 }
225
226 switch ($formatSpecs->json_type) {
227 case 'jsonarray':
228 $apiFormat = 'array';
229 break;
230 case 'jsonobject':
231 $apiFormat = 'object';
232 break;
233
234 default:
235 $apiFormat = $formatSpecs->json_type;
236 break;
237 }
238
239 $formatedValue = '';
240 $fieldFormat = gettype($value);
241 if ($fieldFormat === $apiFormat && 'datetime' !== $formatSpecs->data_type) {
242 $formatedValue = $value;
243 } else {
244 if ('array' === $apiFormat || 'object' === $apiFormat) {
245 if ('string' === $fieldFormat) {
246 if (-1 === strpos($value, ',')) {
247 $formatedValue = json_decode($value);
248 } else {
249 $formatedValue = explode(',', $value);
250 }
251 $formatedValue = is_null($formatedValue) && !is_null($value) ? [$value] : $formatedValue;
252 } else {
253 $formatedValue = $value;
254 }
255
256 if ('object' === $apiFormat) {
257 $formatedValue = (object) $formatedValue;
258 }
259 } elseif ('string' === $apiFormat && 'datetime' !== $formatSpecs->data_type) {
260 $formatedValue = !is_string($value) ? json_encode($value) : $value;
261 } elseif ('datetime' === $formatSpecs->data_type) {
262 $dateTimeHelper = new DateTimeHelper();
263 $formatedValue = $dateTimeHelper->getFormated($value, 'Y-m-d\TH:i', wp_timezone(), 'Y-m-d\TH:i:sP', null);
264 } else {
265 $stringyfiedValue = !is_string($value) ? json_encode($value) : $value;
266
267 switch ($apiFormat) {
268 case 'double':
269 $formatedValue = (float) $stringyfiedValue;
270 break;
271
272 case 'boolean':
273 $formatedValue = (bool) $stringyfiedValue;
274 break;
275
276 case 'integer':
277 $formatedValue = (int) $stringyfiedValue;
278 break;
279
280 default:
281 $formatedValue = $stringyfiedValue;
282 break;
283 }
284 }
285 }
286 $formatedValueLenght = 'array' === $apiFormat || 'object' === $apiFormat ? (is_countable($formatedValue) ? \count($formatedValue) : @count($formatedValue)) : \strlen($formatedValue);
287 if ($formatedValueLenght > $formatSpecs->length) {
288 $formatedValue = 'array' === $apiFormat || 'object' === $apiFormat ? array_slice($formatedValue, 0, $formatSpecs->length) : substr($formatedValue, 0, $formatSpecs->length);
289 }
290
291 return $formatedValue;
292 }
293 }
294