Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e229a1a
feat: update ProFeatureSubtitle prop names and add send_confirmation_…
RishadAlam Apr 27, 2026
2858ee2
feat: enhance integration failure notification email template with im…
RishadAlam Apr 27, 2026
1fb057b
feat: add integration management features with tag support
RishadAlam Apr 28, 2026
bb69e9b
feat: enhance subscriber addition by including actions and improving …
RishadAlam Apr 28, 2026
adeb127
Merge branch 'main' into feat/mailpoet-utilities
RishadAlam Apr 28, 2026
2c7f9dc
Merge branch 'feat/mailpoet-utilities' into fix/plugin-review-team-is…
RishadAlam Apr 28, 2026
83aed08
feat: enhance order creation by adding line item subtotal and tax det…
RishadAlam Apr 28, 2026
ffe4580
feat: enhance insertRecord and addSubscriber methods to support optio…
RishadAlam Apr 28, 2026
4fa2084
feat: implement unassign subscriber from group functionality and enha…
RishadAlam Apr 29, 2026
4d43c7f
feat: refactor action selection to use MultiSelect component and upda…
RishadAlam Apr 29, 2026
5c56a74
feat: enhance existSubscriber method to return detailed response and …
RishadAlam Apr 29, 2026
22fbb60
fix: mailerLite blank page issue
RishadAlam Apr 29, 2026
68ef275
refactor: update documentation links in ActionHook, EssentialBlocksHe…
RishadAlam Apr 30, 2026
1d2a75e
fix: improve password generation and error handling in registration a…
RishadAlam May 2, 2026
3f142cb
fix: streamline SendFox integration components by removing unused imp…
RishadAlam May 2, 2026
110fe83
Merge branch 'main' into fix/plugin-review-team-issues
RishadAlam May 6, 2026
e866bd7
fix: update handling for CustomTrigger in saveIntegConfig and saveAct…
RishadAlam May 6, 2026
b651ab7
fix: update logo handling for Fluent CRM and add missing assets
RishadAlam May 6, 2026
f63f970
chore: update version to 2.8.3
RishadAlam May 6, 2026
a048dc3
fix: improve success response handling in MailPoet and standardize va…
RishadAlam May 6, 2026
9344eac
fix: add validation for empty group ID in RecordApiHelper and update …
RishadAlam May 6, 2026
09f131a
Merge branch 'main' into fix/plugin-review-team-issues
RishadAlam May 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 38 additions & 14 deletions backend/Actions/MailPoet/RecordApiHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ public function __construct($integId)
static::$mailPoet_api = \MailPoet\API\API::MP('v1');
}

public function insertRecord($subscriber, $lists, $actions)
public function insertRecord($subscriber, $lists, $actions, $options = [])
{
try {
// try to find if user is already a subscriber
$existingSubscriber = static::$mailPoet_api->getSubscriber($subscriber['email']);

if (!$existingSubscriber) {
return static::addSubscriber($subscriber, $lists);
return static::addSubscriber($subscriber, $lists, $options);
}

if (!empty($actions->update)) {
Expand All @@ -54,19 +54,25 @@ public function insertRecord($subscriber, $lists, $actions)
// translators: %s: Plugin name
$errorMessages = wp_sprintf(__('%s is not active or not installed', 'bit-integrations'), 'Bit Integrations Pro');
} elseif (!$response['success']) {
$errorMessages = $response('message');
$errorMessages = $response['message'];
}

if (isset($errorMessages)) {
LogHandler::save($this->_integrationID, ['type' => 'record', 'type_name' => 'update'], 'error', $errorMessages);
return [
'success' => false,
'message' => $errorMessages,
];
}
}

return static::addSubscribeToLists($existingSubscriber['id'], $lists);
$newLists = static::getFilteredList($lists, $existingSubscriber['subscriptions']);
if (!empty($newLists)) {
return static::addSubscribeToLists($existingSubscriber['id'], $newLists, $options);
}
}
} catch (\MailPoet\API\MP\v1\APIException $e) {
if ($e->getCode() == 4) {
// Handle the case where the subscriber doesn't exist
return static::addSubscriber($subscriber, $lists);
return static::addSubscriber($subscriber, $lists, $options);
}

return [
Expand All @@ -91,7 +97,9 @@ public function execute($fieldValues, $fieldMap, $lists, $actions)
}

$fieldData = static::setFieldMap($fieldMap, $fieldValues);
$recordApiResponse = $this->insertRecord($fieldData, $lists, $actions);
$options = ['send_confirmation_email' => isset($actions->send_confirmation_email)];

$recordApiResponse = $this->insertRecord($fieldData, $lists, $actions, $options);

if ($recordApiResponse['success']) {
LogHandler::save($this->_integrationID, ['type' => 'record', 'type_name' => 'insert'], 'success', $recordApiResponse);
Expand Down Expand Up @@ -119,14 +127,18 @@ private static function setFieldMap($fieldMap, $fieldValues)
return $fieldData;
}

private static function addSubscriber($subscriber, $lists)
private static function addSubscriber($subscriber, $lists, $options = [])
{
try {
$subscriber = static::$mailPoet_api->addSubscriber($subscriber, $lists);
$subscriber = static::$mailPoet_api->addSubscriber($subscriber, $lists, $options);

if (isset($subscriber['id']) && !empty($lists)) {
return static::addSubscribeToLists($subscriber['id'], $lists, $options);
}

return [
'success' => true,
'id' => $subscriber['id'],
'success' => isset($subscriber['id']) ? true : false,
'data' => $subscriber,
];
Comment thread
RishadAlam marked this conversation as resolved.
} catch (\MailPoet\API\MP\v1\APIException $e) {
return [
Expand All @@ -137,10 +149,10 @@ private static function addSubscriber($subscriber, $lists)
}
}

private static function addSubscribeToLists($subscriber_id, $lists)
private static function addSubscribeToLists($subscriber_id, $lists, $options = [])
{
try {
$subscriber = static::$mailPoet_api->subscribeToLists($subscriber_id, $lists);
$subscriber = static::$mailPoet_api->subscribeToLists($subscriber_id, $lists, $options);

return [
'success' => true,
Expand All @@ -154,4 +166,16 @@ private static function addSubscribeToLists($subscriber_id, $lists)
];
}
}

private static function getFilteredList($listIds, $subscriptions)
{
$segmentIds = array_column($subscriptions, 'segment_id');

return array_filter(
$listIds,
function ($listId) use ($segmentIds) {
return !\in_array($listId, $segmentIds);
}
);
}
}
3 changes: 1 addition & 2 deletions backend/Actions/MailerLite/MailerLiteController.php
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@ public function execute($integrationData, $fieldValues)
$integId = $integrationData->id;
$auth_token = $integrationDetails->auth_token;
$version = $integrationDetails->version;
$groupIds = $integrationDetails->group_ids ?? '';
$fieldMap = $integrationDetails->field_map ?? '';
$type = $integrationDetails->mailer_lite_type ?? '';
$actions = $integrationDetails->actions ?? '';
Expand All @@ -208,7 +207,7 @@ public function execute($integrationData, $fieldValues)
}
$recordApiHelper = new RecordApiHelper($auth_token, $integrationDetails, $integId, $actions, $version);
$mailerliteApiResponse = $recordApiHelper->execute(
$groupIds,
$integrationDetails,
$type,
$fieldValues,
$fieldMap,
Expand Down
77 changes: 66 additions & 11 deletions backend/Actions/MailerLite/RecordApiHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

use BitApps\Integrations\Config;
use BitApps\Integrations\Core\Util\Common;
use BitApps\Integrations\Core\Util\HttpHelper;
use BitApps\Integrations\Core\Util\Hooks;
use BitApps\Integrations\Core\Util\HttpHelper;
use BitApps\Integrations\Log\LogHandler;

/**
Expand Down Expand Up @@ -65,7 +65,10 @@ public function existSubscriber($auth_token, $email)

$response = HttpHelper::get($apiEndpoints, null, $this->_defaultHeader);

return $response->data->id ?? false;
return [
'id' => $response->data->id ?? null,
'data' => $response->data ?? null
];
}

public function enableDoubleOptIn($auth_token)
Expand Down Expand Up @@ -104,10 +107,8 @@ public function addSubscriber($auth_token, $groupIds, $type, $finalData)

$requestParams = self::prepareRequestParams($finalData, $type, $this->_isMailerLiteV2);

$isExist = $this->existSubscriber($auth_token, $email);
$response = null;

if ($isExist && empty($this->_actions->update)) {
$existSubscriber = $this->existSubscriber($auth_token, $email);
if ($existSubscriber['id'] && empty($this->_actions->update)) {
return [
'success' => false,
'message' => __('Subscriber already exist', 'bit-integrations'),
Expand All @@ -121,7 +122,11 @@ public function addSubscriber($auth_token, $groupIds, $type, $finalData)
return self::sendToGroups($this, $splitGroupIds, $requestParams, $this->_isMailerLiteV2);
}

if ($isExist) {
if ($existSubscriber['id']) {
if (isset($existSubscriber['data']->status) && 'unsubscribed' === $existSubscriber['data']->status) {
$requestParams['resubscribe'] = true;
}

$response = HttpHelper::post($apiEndpoint, $requestParams, $this->_defaultHeader);
$response->update = true;

Expand Down Expand Up @@ -149,16 +154,18 @@ public function deleteSubscriber($auth_token, $finalData, $forget = false)
];
}

$subscriberId = $this->existSubscriber($auth_token, $finalData['email']);
$existSubscriber = $this->existSubscriber($auth_token, $finalData['email']);

if (empty($subscriberId)) {
if (empty($existSubscriber['id'])) {
return [
'success' => false,
'message' => __('Subscriber not exist', 'bit-integrations'),
'code' => 400
];
}

$subscriberId = $existSubscriber['id'];

$response = Hooks::apply(Config::withPrefix('mailerlite_delete_subscriber'), false, $subscriberId, $finalData, $this->_baseUrl, $this->_defaultHeader, $forget);

/**
Expand All @@ -170,6 +177,45 @@ public function deleteSubscriber($auth_token, $finalData, $forget = false)
return $response ? $response : (object) ['success' => false, 'message' => __('Bit Integrations Pro is required.', 'bit-integrations'), 'code' => 400];
}

public function unassignSubscriberFromGroup($auth_token, $groupId, $finalData)
{
if (!$this->_isMailerLiteV2) {
return [
'success' => false,
'message' => __('This action is not supported for Classic accounts.', 'bit-integrations'),
'code' => 400
];
}

if (empty($finalData['email'])) {
return [
'success' => false,
'message' => __('Required field Email is empty', 'bit-integrations'),
'code' => 400
];
}
if (empty($groupId)) {
return [
'success' => false,
'message' => __('Required field Group is empty', 'bit-integrations'),
'code' => 400
];
}

Comment thread
RishadAlam marked this conversation as resolved.
$existSubscriber = $this->existSubscriber($auth_token, $finalData['email']);
if (empty($existSubscriber['id'])) {
return [
'success' => false,
'message' => __('Subscriber not exist', 'bit-integrations'),
'code' => 400
];
}

$response = Hooks::apply(Config::withPrefix('mailerlite_unassign_subscriber_from_group'), false, $existSubscriber['id'], $groupId, $this->_baseUrl, $this->_defaultHeader);

return $response ? $response : (object) ['success' => false, 'message' => __('Bit Integrations Pro is required.', 'bit-integrations'), 'code' => 400];
}

public function generateReqDataFromFieldMap($data, $fieldMap)
{
$dataFinal = [];
Expand All @@ -188,7 +234,7 @@ public function generateReqDataFromFieldMap($data, $fieldMap)
}

public function execute(
$groupId,
$integrationDetails,
$type,
$fieldValues,
$fieldMap,
Expand All @@ -212,15 +258,24 @@ public function execute(

break;

case 'unassign_subscriber_from_group':
$groupId = $integrationDetails->selected_group_id ?? '';
$apiResponse = $this->unassignSubscriberFromGroup($auth_token, $groupId, $finalData);
$typeName = 'unassign-subscriber-from-group';
$res = ['success' => true, 'message' => __('Subscriber unassigned from group successfully', 'bit-integrations'), 'code' => 200];

break;

default:
$groupId = $integrationDetails->group_ids ?? '';
$apiResponse = $this->addSubscriber($auth_token, $groupId, $type, $finalData);
$typeName = 'add-subscriber';
$res = ['success' => true, 'message' => isset($apiResponse->update) ? __('Subscriber updated successfully', 'bit-integrations') : __('Subscriber created successfully', 'bit-integrations'), 'code' => 200];

break;
}

if (isset($apiResponse->data->id) || isset($apiResponse->id) || str_starts_with((string) HttpHelper::$responseCode, '20')) {
if (isset($apiResponse->data->id) || isset($apiResponse->id) || strpos((string) HttpHelper::$responseCode, '20') === 0) {
LogHandler::save($this->_integrationID, wp_json_encode(['type' => 'subscriber', 'type_name' => $typeName]), 'success', wp_json_encode($res));
} else {
LogHandler::save($this->_integrationID, wp_json_encode(['type' => 'subscriber', 'type_name' => $typeName]), 'error', wp_json_encode($apiResponse));
Expand Down
2 changes: 1 addition & 1 deletion backend/Actions/Registration/RegistrationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ private function userFieldMapping($user_map, $fieldValues, $flowDetails)
}

if (empty($fieldData['user_pass']) && $flowDetails->action_type !== 'updated_user') {
$fieldData['user_pass'] = random_int(100000, 999999);
$fieldData['user_pass'] = wp_generate_password(24);
}

return $fieldData;
Expand Down
31 changes: 10 additions & 21 deletions backend/Actions/SendFox/RecordApiHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,40 +132,29 @@ public function execute(
$access_token,
$integrationDetails
) {
$fieldData = [];
if ($integrationDetails->mainAction === '1') {
$type_name = 'Create List';
$finalData = $this->generateListReqDataFromFieldMap($fieldValues, $integrationDetails->field_map_list);
$apiResponseList = $this->createContactList($access_token, $finalData);

if (property_exists($apiResponseList, 'id')) {
LogHandler::save($this->_integrationID, wp_json_encode(['type' => 'record', 'type_name' => $type_name]), 'success', wp_json_encode($apiResponseList));
} else {
LogHandler::save($this->_integrationID, wp_json_encode(['type' => 'record', 'type_name' => $type_name]), 'error', wp_json_encode($apiResponseList));
}
$apiResponse = $this->createContactList($access_token, $finalData);
$type = 'List';
$event_name = 'Create List';
}
if ($integrationDetails->mainAction === '2') {
$type_name = 'Create Contact';
$finalData = $this->generateReqDataFromFieldMap($fieldValues, $fieldMap);
$apiResponse = $this->addContact($access_token, $listId, $finalData);
if (property_exists($apiResponse, 'errors')) {
LogHandler::save($this->_integrationID, wp_json_encode(['type' => 'contact', 'type_name' => $type_name]), 'error', wp_json_encode($apiResponse));
} else {
LogHandler::save($this->_integrationID, wp_json_encode(['type' => 'record', 'type_name' => $type_name]), 'success', wp_json_encode($apiResponse));
}
$type = 'Contact';
$event_name = 'Create Contact';
}

if ($integrationDetails->mainAction === '3') {
$type_name = 'Unsubscribe';
$finalData = $this->generateReqUnsubscribeDataFromFieldMap($fieldValues, $integrationDetails->field_map_unsubscribe);
$apiResponse = $this->unsubscribeContact($access_token, $finalData);
if (property_exists($apiResponse, 'id')) {
LogHandler::save($this->_integrationID, wp_json_encode(['type' => 'contact', 'type_name' => $type_name]), 'success', wp_json_encode($apiResponse));
} else {
LogHandler::save($this->_integrationID, wp_json_encode(['type' => 'record', 'type_name' => $type_name]), 'error', wp_json_encode($apiResponse));
}
$type = 'Contact';
$event_name = 'Unsubscribe Contact';
}

$response_type = HttpHelper::$responseCode >= 200 && HttpHelper::$responseCode < 300 ? 'success' : 'error';
LogHandler::save($this->_integrationID, wp_json_encode(['type' => $type, 'type_name' => $event_name]), $response_type, wp_json_encode($apiResponse));
Comment thread
RishadAlam marked this conversation as resolved.

return $apiResponse;
}
}
5 changes: 4 additions & 1 deletion backend/Actions/SureCart/SureCartController.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,12 @@ public function checkAuthorization($tokenRequestParams)
];

$request = wp_remote_post($this->api_url . 'webhook_endpoints', $headers);
if (is_wp_error($request)) {
wp_send_json_error($request->get_error_message(), 400);
}
$request_body = wp_remote_retrieve_body($request);
$request_data = json_decode($request_body);
if ($request_data->code !== 'unauthorized') {
if (!$request_data || $request_data->code !== 'unauthorized') {
wp_send_json_success($request_body, 200);
} else {
wp_send_json_error(
Expand Down
14 changes: 13 additions & 1 deletion backend/Actions/WooCommerce/RecordApiHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,19 @@ private function product_added_to_order($fieldDataLine, $module, $customer_id)

$order = wc_create_order(['customer_id' => $customer_id]);
$product = wc_get_product($product_id);
$order->add_product($product, (int) $lineItem->quantity);

$lineArgs = [];
if (isset($lineItem->subtotal) && $lineItem->subtotal !== '') {
$lineArgs['subtotal'] = (float) $lineItem->subtotal;
}
if (isset($lineItem->total) && $lineItem->total !== '') {
$lineArgs['total'] = (float) $lineItem->total;
}
if (isset($lineItem->line_subtotal_tax) && $lineItem->line_subtotal_tax !== '') {
$lineArgs['subtotal_tax'] = (float) $lineItem->line_subtotal_tax;
}

$order->add_product($product, (int) $lineItem->quantity, $lineArgs);

return $order;
}
Expand Down
2 changes: 1 addition & 1 deletion backend/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Config

public const VAR_PREFIX = 'bit_integrations_';

public const VERSION = '2.8.2';
public const VERSION = '2.8.3';

public const DB_VERSION = '1.1';

Expand Down
2 changes: 1 addition & 1 deletion backend/Triggers/Elementor/ElementorController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public static function info()
'title' => __('Elementor is the platform web creators choose to build professional WordPress websites, grow their skills, and build their business. Start for free today!', 'bit-integrations'),
'type' => 'custom_form_submission',
'is_active' => self::pluginActive(),
'documentation_url' => 'https://bitapps.pro/docs/bit-integrations/trigger/elementor-form-integrations',
'documentation_url' => 'https://bit-integrations.com/wp-docs/trigger/elementor-form-integrations/',
'tutorial_url' => 'https://youtube.com/playlist?list=PL7c6CDwwm-ALGg0fZNLDIHjh1QJPcDSXp&si=HIKa9m0-yjPSXP2p',
'tasks' => [
'action' => 'elementor/get',
Expand Down
Loading
Loading