Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
82 changes: 82 additions & 0 deletions backend/Actions/UserRegistrationMembership/RecordApiHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

namespace BitApps\Integrations\Actions\UserRegistrationMembership;

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

/**
* Provide functionality for User Registration and Membership integration.
*/
class RecordApiHelper
{
private $_integrationID;

private $_integrationDetails;

public function __construct($integrationDetails, $integId)
{
$this->_integrationDetails = $integrationDetails;
$this->_integrationID = $integId;
}

public function execute($fieldValues, $fieldMap)
{
if (!class_exists('UserRegistration')) {
$response = [
'success' => false,
'message' => __('User Registration and Membership is not installed or activated', 'bit-integrations')
];

LogHandler::save($this->_integrationID, ['type' => 'User Registration', 'type_name' => 'check'], 'error', $response);

return $response;
}

$fieldData = $this->generateReqDataFromFieldMap($fieldMap, $fieldValues);
$mainAction = $this->_integrationDetails->mainAction ?? 'create_user';
$response = $this->processAction($mainAction, $fieldData);

$responseType = !empty($response['success']) ? 'success' : 'error';
LogHandler::save($this->_integrationID, ['type' => 'User Registration', 'type_name' => $mainAction], $responseType, $response);

return $response;
}

private function processAction($mainAction, $fieldData)
{
$defaultResponse = [
'success' => false,
'message' => wp_sprintf(__('%s plugin is not installed or activated', 'bit-integrations'), 'Bit Integrations Pro')
];

switch ($mainAction) {
case 'create_user':
return apply_filters(Config::withPrefix('user_registration_create_user'), $defaultResponse, $fieldData, $this->_integrationDetails);

default:
return [
'success' => false,
'message' => __('Invalid action', 'bit-integrations')
];
}
}

private function generateReqDataFromFieldMap($fieldMap, $fieldValues)
{
$dataFinal = [];

foreach ($fieldMap as $item) {
if (empty($item->userRegistrationField)) {
continue;
}

$dataFinal[$item->userRegistrationField] = $item->formField === 'custom' && isset($item->customValue)
? Common::replaceFieldWithValue($item->customValue, $fieldValues)
: ($fieldValues[$item->formField] ?? '');
}

return $dataFinal;
}
}
12 changes: 12 additions & 0 deletions backend/Actions/UserRegistrationMembership/Routes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

if (!defined('ABSPATH')) {
exit;
}

use BitApps\Integrations\Actions\UserRegistrationMembership\UserRegistrationMembershipController;
use BitApps\Integrations\Core\Util\Route;

Route::post('user_registration_authorize', [UserRegistrationMembershipController::class, 'userRegistrationAuthorize']);
Route::post('refresh_user_registration_forms', [UserRegistrationMembershipController::class, 'refreshForms']);
Route::post('refresh_user_registration_form_fields', [UserRegistrationMembershipController::class, 'refreshFormFields']);
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

namespace BitApps\Integrations\Actions\UserRegistrationMembership;

use WP_Error;

/**
* Provide functionality for User Registration and Membership integration.
*/
class UserRegistrationMembershipController
{
public static function userRegistrationAuthorize()
{
self::checkPluginExists();
wp_send_json_success(true);
}

public static function refreshForms()
{
self::checkPluginExists();

$allForms = get_posts([
'post_type' => 'user_registration',
'post_status' => 'publish',
'orderby' => 'ID',
'order' => 'DESC',
'no_found_rows' => true,
'nopaging' => true,
]);

$forms = array_map(
fn ($form) => (object) [
'value' => $form->ID,
'label' => $form->post_title,
],
$allForms
);

wp_send_json_success(['forms' => $forms], 200);
}

public static function refreshFormFields($request)
{
self::checkPluginExists();

$formId = absint($request->form_id ?? 0);

if (empty($formId)) {
wp_send_json_error(__('Form ID is required', 'bit-integrations'), 400);
}

$fields = self::getFormFields($formId);

wp_send_json_success(['fields' => array_values($fields)], 200);
}

public function execute($integrationData, $fieldValues)
{
$integrationDetails = $integrationData->flow_details;
$fieldMap = $integrationDetails->field_map ?? [];

if (empty($fieldMap)) {
return new WP_Error('field_map_empty', __('Field map is empty', 'bit-integrations'));
}

$recordApiHelper = new RecordApiHelper($integrationDetails, $integrationData->id);

return $recordApiHelper->execute($fieldValues, $fieldMap);
}

private static function getFormFields($formId)
{
if (!\function_exists('ur_get_form_fields')) {
return [];
}

$formFields = ur_get_form_fields($formId);

return array_map(
fn ($field) => (object) [
'label' => $field->general_setting->label ?? $field->field_key,
'value' => $field->field_key,
'required' => !empty($field->general_setting->required)
],
$formFields
);
}

private static function checkPluginExists()
{
if (!class_exists('UserRegistration')) {
wp_send_json_error(
__('User Registration and Membership is not activated or not installed', 'bit-integrations'),
400
);
}
}
}
1 change: 1 addition & 0 deletions backend/Core/Util/AllTriggersName.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ public static function allTriggersName()
'Tripetto' => ['name' => 'Tripetto', 'isPro' => true, 'is_active' => false],
'TutorLms' => ['name' => 'Tutor LMS', 'isPro' => true, 'is_active' => false],
'TeamsForWooCommerceMemberships' => ['name' => 'Teams For WooCommerce Memberships', 'isPro' => true, 'is_active' => false],
'UserRegistrationMembership' => ['name' => 'User Registration & Membership', 'isPro' => true, 'is_active' => false],
'UltimateMember' => ['name' => 'UltimateMember', 'isPro' => true, 'is_active' => false],
'UserFeedback' => ['name' => 'UserFeedback', 'isPro' => true, 'is_active' => false],
'Voxel' => ['name' => 'Voxel', 'isPro' => true, 'is_active' => false],
Expand Down
2 changes: 1 addition & 1 deletion backend/Core/Util/Common.php
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ private static function replaceFieldWithValueHelper($stringToReplaceField, $fiel
$fieldName = substr($field, 2, \strlen($field) - 3);
$smartTagValue = SmartTags::getSmartTagValue($fieldName, true);
if (isset($fieldValues[$fieldName]) && !self::isEmpty($fieldValues[$fieldName])) {
$stringToReplaceField = !\is_array($fieldValues[$fieldName]) ? str_replace($field, $fieldValues[$fieldName], $stringToReplaceField)
$stringToReplaceField = !\is_array($fieldValues[$fieldName]) && !\is_object($fieldValues[$fieldName]) ? str_replace($field, $fieldValues[$fieldName], $stringToReplaceField)
: str_replace(['"' . $field . '"', $field], wp_json_encode($fieldValues[$fieldName], JSON_UNESCAPED_UNICODE), $stringToReplaceField);
} elseif (!empty($smartTagValue)) {
$stringToReplaceField = str_replace($field, $smartTagValue, $stringToReplaceField);
Expand Down
5 changes: 5 additions & 0 deletions backend/Flow/Flow.php
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,11 @@ public static function execute($triggered_entity, $triggered_entity_id, $data, $

break;

case 'UserRegistration&Membership':
$integrationName = 'UserRegistrationMembership';

break;

default:
$integrationName = $integrationName;

Expand Down
4 changes: 4 additions & 0 deletions frontend/src/Utils/StaticData/tutorialLinks.js
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,10 @@ const tutorialLinks = {
seoPress: {
youTubeLink: '',
docLink: 'https://bit-integrations.com/wp-docs/actions/seopress-integrations-as-action/'
},
userRegistrationMembership: {
youTubeLink: '',
docLink: 'https://bit-integrations.com/wp-docs/actions/user-registration-and-membership-as-action/'
}
}
export default tutorialLinks
3 changes: 2 additions & 1 deletion frontend/src/Utils/StaticData/webhookIntegrations.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ export const customFormIntegrations = [
'TeamsForWooCommerceMemberships',
'WPCafe',
'SeoPress',
'ThriveLeads'
'ThriveLeads',
'UserRegistrationMembership'
]

export const actionHookIntegrations = ['ActionHook']
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/components/AllIntegrations/EditInteg.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ const EditTeamsForWooCommerceMemberships = lazy(() =>
import('./TeamsForWooCommerceMemberships/EditTeamsForWooCommerceMemberships')
)
const EditSeoPress = lazy(() => import('./SeoPress/EditSeoPress'))
const EditUserRegistrationMembership = lazy(
() => import('./UserRegistrationMembership/EditUserRegistrationMembership')
)

const loaderStyle = {
display: 'flex',
Expand Down Expand Up @@ -352,6 +355,8 @@ const IntegType = memo(({ allIntegURL, flow }) => {
return <EditSendy allIntegURL={allIntegURL} />
case 'Keap':
return <EditKeap allIntegURL={allIntegURL} />
case 'User Registration & Membership':
return <EditUserRegistrationMembership allIntegURL={allIntegURL} />
case 'Freshdesk':
return <EditFreshdesk allIntegURL={allIntegURL} />
case 'Zoom':
Expand Down
11 changes: 11 additions & 0 deletions frontend/src/components/AllIntegrations/IntegInfo.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ const TeamsForWooCommerceMembershipsAuthorization = lazy(
() => import('./TeamsForWooCommerceMemberships/TeamsForWooCommerceMembershipsAuthorization')
)
const SeoPressAuthorization = lazy(() => import('./SeoPress/SeoPressAuthorization'))
const UserRegistrationMembershipAuthorization = lazy(
() => import('./UserRegistrationMembership/UserRegistrationMembershipAuthorization')
)

export default function IntegInfo() {
const { id, type } = useParams()
Expand Down Expand Up @@ -278,6 +281,14 @@ export default function IntegInfo() {
isInfo
/>
)
case 'User Registration & Membership':
return (
<UserRegistrationMembershipAuthorization
userRegistrationConf={integrationConf}
step={1}
isInfo
/>
)
case 'Zoho Bigin':
return (
<ZohoBiginAuthorization
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/components/AllIntegrations/NewInteg.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ const TeamsForWooCommerceMemberships = lazy(() =>
import('./TeamsForWooCommerceMemberships/TeamsForWooCommerceMemberships')
)
const SeoPress = lazy(() => import('./SeoPress/SeoPress'))
const UserRegistrationMembership = lazy(
() => import('./UserRegistrationMembership/UserRegistrationMembership')
)

export default function NewInteg({ allIntegURL }) {
const { integUrlName } = useParams()
Expand Down Expand Up @@ -810,6 +813,15 @@ export default function NewInteg({ allIntegURL }) {
setFlow={setFlow}
/>
)
case 'User Registration & Membership':
return (
<UserRegistrationMembership
formFields={flow?.triggerData?.fields}
allIntegURL={allIntegURL}
flow={flow}
setFlow={setFlow}
/>
)
case 'Mailercloud':
return (
<Mailercloud
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ export default function SeoPress({ formFields, setFlow, flow, allIntegURL }) {
<br />
<button
onClick={() => nextPage(3)}
disabled={seoPressConf.field_map.length < 1}
className="btn f-right btcd-btn-lg purple sh-sm flx"
type="button"
disabled={!checkMappedFields(seoPressConf)}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { useState } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import { useRecoilState, useRecoilValue } from 'recoil'
import { $actionConf, $formFields, $newFlow } from '../../../GlobalStates'
import { __ } from '../../../Utils/i18nwrap'
import SnackMsg from '../../Utilities/SnackMsg'
import { saveActionConf } from '../IntegrationHelpers/IntegrationHelpers'
import IntegrationStepThree from '../IntegrationHelpers/IntegrationStepThree'
import SetEditIntegComponents from '../IntegrationHelpers/SetEditIntegComponents'
import { checkMappedFields, handleInput } from './UserRegistrationMembershipCommonFunc'
import UserRegistrationMembershipIntegLayout from './UserRegistrationMembershipIntegLayout'

export default function EditUserRegistrationMembership({ allIntegURL }) {
const navigate = useNavigate()
const { id } = useParams()

const [userRegistrationConf, setUserRegistrationConf] = useRecoilState($actionConf)
const [flow, setFlow] = useRecoilState($newFlow)
const formFields = useRecoilValue($formFields)
const [isLoading, setIsLoading] = useState(false)
const [snack, setSnackbar] = useState({ show: false })

return (
<div style={{ width: 900 }}>
<SnackMsg snack={snack} setSnackbar={setSnackbar} />

<div className="flx mt-3">
<b className="wdt-200 d-in-b">{__('Integration Name:', 'bit-integrations')}</b>
<input
className="btcd-paper-inp w-5"
onChange={e => handleInput(e, userRegistrationConf, setUserRegistrationConf)}
name="name"
value={userRegistrationConf.name}
type="text"
placeholder={__('Integration Name...', 'bit-integrations')}
/>
</div>
<br />

<SetEditIntegComponents entity={flow.triggered_entity} setSnackbar={setSnackbar} />

<UserRegistrationMembershipIntegLayout
formFields={formFields}
userRegistrationConf={userRegistrationConf}
setUserRegistrationConf={setUserRegistrationConf}
setIsLoading={setIsLoading}
isLoading={isLoading}
setSnackbar={setSnackbar}
/>

<IntegrationStepThree
edit
saveConfig={() =>
saveActionConf({
flow,
setFlow,
allIntegURL,
conf: userRegistrationConf,
navigate,
id,
edit: 1,
setIsLoading,
setSnackbar
})
}
disabled={!checkMappedFields(userRegistrationConf)}
isLoading={isLoading}
dataConf={userRegistrationConf}
setDataConf={setUserRegistrationConf}
formFields={formFields}
/>
<br />
</div>
)
}
Loading
Loading