PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / 3.2.2
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder v3.2.2
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 / BitCRM / BitCRMHandler.php

BitCRMHandler.php in Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder 3.2.2, at includes/Core/Integration/BitCRM/BitCRMHandler.php

292 lines 8.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Bit CRM Integration
5 *
6 */
7
8 namespace BitCode\BitForm\Core\Integration\BitCRM;
9
10 if (!defined('ABSPATH')) {
11 exit;
12 }
13
14 use BitCode\BitForm\Core\Integration\IntegrationHandler;
15 use BitCode\BitForm\Core\Util\ApiResponse as UtilApiResponse;
16 use WP_Error;
17
18 /**
19 * Provide functionality for Bit CRM integration
20 */
21 class BitCRMHandler
22 {
23 public const CRM_PLUGIN_BASENAME = 'bit-crm-sales-marketing-automation/bit-crm-sales-marketing-automation.php';
24
25 private $_formID;
26
27 private $_integrationID;
28
29 public function __construct($integrationID, $fromID)
30 {
31 $this->_formID = $fromID;
32 $this->_integrationID = $integrationID;
33 }
34
35 /**
36 * Helps to register ajax function's with wp
37 *
38 * @return void
39 */
40 public static function registerAjax()
41 {
42 add_action('wp_ajax_bitforms_bitcrm_authorize', [__CLASS__, 'bitcrmAuthorize']);
43 add_action('wp_ajax_bitforms_bitcrm_fields', [__CLASS__, 'bitcrmFields']);
44 add_action('wp_ajax_bitforms_bitcrm_tags', [__CLASS__, 'bitcrmTags']);
45 }
46
47 /**
48 * Check Bit CRM plugin is active and its lead service is loadable
49 */
50 public static function checkedExistsBitCRM()
51 {
52 if (!\function_exists('is_plugin_active')) {
53 require_once ABSPATH . 'wp-admin/includes/plugin.php';
54 }
55 return is_plugin_active(self::CRM_PLUGIN_BASENAME) && class_exists('\BitApps\Crm\Services\LeadService');
56 }
57
58 /**
59 * Capability gate for the BitCRM admin AJAX endpoints. Registration is already
60 * capability-gated in AjaxService, this is defense-in-depth matching AdminAjax.
61 *
62 * @return void
63 */
64 private static function verifyAdminPermission()
65 {
66 if (!current_user_can('manage_bitform') && !current_user_can('manage_options')) {
67 wp_send_json_error(__('Insufficient permissions.', 'bit-form'), 403);
68 }
69 }
70
71 /**
72 * Ajax: respond success if Bit CRM exists
73 *
74 * @return void
75 */
76 public static function bitcrmAuthorize()
77 {
78 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['_ajax_nonce'])), 'bitforms_save')) {
79 self::verifyAdminPermission();
80 if (self::checkedExistsBitCRM()) {
81 wp_send_json_success(true);
82 } else {
83 wp_send_json_error(
84 __(
85 'Please! Install & activate Bit CRM',
86 'bit-form'
87 ),
88 400
89 );
90 }
91 } else {
92 wp_send_json_error(
93 __(
94 'Token expired',
95 'bit-form'
96 ),
97 401
98 );
99 }
100 }
101
102 /**
103 * Ajax: respond with the lead fields (system + custom) of Bit CRM
104 *
105 * @return void
106 */
107 public static function bitcrmFields()
108 {
109 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['_ajax_nonce'])), 'bitforms_save')) {
110 self::verifyAdminPermission();
111 if (!self::checkedExistsBitCRM()) {
112 wp_send_json_error(
113 __(
114 'Bit CRM plugin not found',
115 'bit-form'
116 ),
117 400
118 );
119 }
120 $response['bitcrmFields'] = self::getLeadFields();
121 wp_send_json_success($response, 200);
122 } else {
123 wp_send_json_error(
124 __(
125 'Token expired',
126 'bit-form'
127 ),
128 401
129 );
130 }
131 }
132
133 /**
134 * Ajax: respond with the lead tags of Bit CRM
135 *
136 * @return void
137 */
138 public static function bitcrmTags()
139 {
140 if (isset($_REQUEST['_ajax_nonce']) && wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['_ajax_nonce'])), 'bitforms_save')) {
141 self::verifyAdminPermission();
142 if (!self::checkedExistsBitCRM()) {
143 wp_send_json_error(
144 __(
145 'Bit CRM plugin not found',
146 'bit-form'
147 ),
148 400
149 );
150 }
151 $response['bitcrmTags'] = self::getLeadTags();
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 /**
165 * Fetch normalized lead field list from Bit CRM
166 *
167 * @return array [{key, label, required, isCustom, fieldId, fieldType}]
168 */
169 public static function getLeadFields()
170 {
171 // Bit CRM asks integrators to use the raw service classes (their CrmApi facade
172 // is reserved for a future public API), so we call LeadService directly.
173 $fields = (new \BitApps\Crm\Services\LeadService())->fields();
174 $fieldOptions = [];
175 foreach ($fields as $field) {
176 $field = (array) $field;
177 // section rows are UI group headers in CRM, not mappable fields
178 if (isset($field['type']) && 'section' === $field['type']) {
179 continue;
180 }
181 // Group fields (billing/shipping address) are not columns themselves; their
182 // mappable columns are the leaf sub-fields (billing_city, shipping_zip, ...).
183 if (!empty($field['group_fields']) && is_array($field['group_fields'])) {
184 foreach ($field['group_fields'] as $leaf) {
185 $option = self::normalizeLeadField((array) $leaf);
186 if ($option) {
187 $fieldOptions[] = $option;
188 }
189 }
190 continue;
191 }
192 $option = self::normalizeLeadField($field);
193 if ($option) {
194 $fieldOptions[] = $option;
195 }
196 }
197 return $fieldOptions;
198 }
199
200 /**
201 * Normalize one Bit CRM lead field (or address leaf) into a mappable option.
202 *
203 * @param array $field
204 *
205 * @return object|null null when the field has no key
206 */
207 private static function normalizeLeadField($field)
208 {
209 if (empty($field['field_key'])) {
210 return null;
211 }
212 $required = !empty($field['required']) || !empty($field['is_always_required']);
213 // Bit CRM defaults currency, but the form should not force it as a required mapping.
214 if ('currency' === $field['field_key']) {
215 $required = false;
216 }
217 return (object) [
218 'key' => $field['field_key'],
219 'label' => isset($field['label']) ? $field['label'] : $field['field_key'],
220 'required' => $required,
221 'isCustom' => !empty($field['is_custom']),
222 'fieldId' => isset($field['id']) ? $field['id'] : null,
223 'fieldType' => isset($field['type']) ? $field['type'] : 'text',
224 ];
225 }
226
227 /**
228 * Fetch lead tags from Bit CRM
229 *
230 * @return array [{id, title}]
231 */
232 public static function getLeadTags()
233 {
234 // Use the raw TagService (per Bit CRM's guidance). tagsByModule returns
235 // ['success' => bool, 'data' => <Tag collection>] where each row is a Model object.
236 $result = (new \BitApps\Crm\Services\TagService())->tagsByModule(['module' => \BitApps\Crm\Model\Lead::MODULE_NAME]);
237 $tags = (isset($result['success']) && $result['success'] && isset($result['data'])) ? $result['data'] : [];
238
239 $bitcrmTags = [];
240 foreach ($tags as $tag) {
241 // Tag rows are WPDatabase Model objects (data in a protected `attributes`
242 // bag reachable via magic __get); a plain (array) cast mangles the keys.
243 if (is_array($tag)) {
244 $id = isset($tag['id']) ? $tag['id'] : null;
245 $title = isset($tag['title']) ? $tag['title'] : null;
246 } else {
247 $id = $tag->id;
248 $title = $tag->title;
249 }
250 if (is_null($id)) {
251 continue;
252 }
253 $bitcrmTags[] = (object) [
254 'id' => $id,
255 'title' => $title,
256 ];
257 }
258 return $bitcrmTags;
259 }
260
261 public function execute(IntegrationHandler $integrationHandler, $integrationData, $fieldValues, $entryID, $logID)
262 {
263 $integrationDetails = is_string($integrationData->integration_details) ? json_decode($integrationData->integration_details) : $integrationData->integration_details;
264
265 if (!self::checkedExistsBitCRM()) {
266 $error = ['success' => false, 'messages' => 'Bit CRM plugin is not active'];
267 (new UtilApiResponse())->apiResponse(
268 $logID,
269 $this->_integrationID,
270 ['type' => 'record', 'type_name' => 'Lead-create'],
271 'error',
272 $error,
273 ['formId' => $this->_formID, 'entryId' => $entryID, 'fieldValues' => $fieldValues]
274 );
275 return new WP_Error('PLUGIN_NOT_FOUND', __('Bit CRM plugin is not active', 'bit-form'));
276 }
277
278 $fieldMap = isset($integrationDetails->field_map) ? $integrationDetails->field_map : [];
279 if (empty($fieldMap)) {
280 return new WP_Error('REQ_FIELD_EMPTY', __('Field map is required for Bit CRM api', 'bit-form'));
281 }
282
283 $recordApiHelper = new RecordApiHelper($this->_integrationID, $logID, $entryID);
284
285 return $recordApiHelper->executeRecordApi(
286 $fieldValues,
287 $integrationDetails,
288 $this->_formID
289 );
290 }
291 }
292