-
Notifications
You must be signed in to change notification settings - Fork 1
feat(integrations): add MainWP action integration #172
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9f5da0d
b0d0061
acc8380
491e1bf
adcf9f6
9c0517f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| <?php | ||
|
|
||
| namespace BitApps\Integrations\Actions\MainWP; | ||
|
|
||
| if (!defined('ABSPATH')) { | ||
| exit; | ||
| } | ||
|
|
||
| class MainWPController | ||
| { | ||
| public static function isExists(): void | ||
| { | ||
| if (!class_exists('\MainWP\Dashboard\MainWP_DB')) { | ||
| wp_send_json_error( | ||
| __('MainWP Dashboard is not activated or not installed', 'bit-integrations'), | ||
| 400 | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| public static function mainWPAuthorize(): void | ||
| { | ||
| self::isExists(); | ||
| wp_send_json_success(true); | ||
| } | ||
|
|
||
| public static function refreshSites(): void | ||
| { | ||
| self::isExists(); | ||
|
|
||
| $websites = \MainWP\Dashboard\MainWP_DB::instance()->get_sites(); | ||
| $sites = []; | ||
|
|
||
| if (!empty($websites)) { | ||
| foreach ($websites as $website) { | ||
| $website = (array) $website; | ||
| if (empty($website['id'])) { | ||
| continue; | ||
| } | ||
| $sites[] = [ | ||
| 'value' => (string) $website['id'], | ||
| 'label' => ($website['name'] ?? 'Site') . ' (' . ($website['url'] ?? '') . ')', | ||
| ]; | ||
| } | ||
| } | ||
|
|
||
| wp_send_json_success(['sites' => $sites], 200); | ||
| } | ||
|
|
||
| public function execute($integrationData, $fieldValues) | ||
| { | ||
| $integrationDetails = $integrationData->flow_details; | ||
| $integId = $integrationData->id; | ||
| $fieldMap = $integrationDetails->field_map; | ||
|
|
||
| $RecordApiHelper = new RecordApiHelper($integrationDetails, $integId); | ||
|
|
||
| return $RecordApiHelper->execute($fieldValues, $fieldMap); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,151 @@ | ||
| <?php | ||
|
|
||
| namespace BitApps\Integrations\Actions\MainWP; | ||
|
|
||
| use BitApps\Integrations\Config; | ||
| use BitApps\Integrations\Core\Util\Common; | ||
| use BitApps\Integrations\Core\Util\Hooks; | ||
| use BitApps\Integrations\Log\LogHandler; | ||
|
|
||
| if (!defined('ABSPATH')) { | ||
| exit; | ||
| } | ||
|
|
||
| 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('\MainWP\Dashboard\MainWP_DB')) { | ||
| return [ | ||
| 'success' => false, | ||
| 'message' => __('MainWP Dashboard is not installed or activated', 'bit-integrations'), | ||
| ]; | ||
| } | ||
|
Comment on lines
+28
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To ensure defensive programming and prevent potential warnings or fatal errors in PHP 8.0+, we should verify that if (!class_exists('\\MainWP\\Dashboard\\MainWP_DB')) {
return [
'success' => false,
'message' => __('MainWP Dashboard is not installed or activated', 'bit-integrations'),
];
}
if (empty($this->_integrationDetails)) {
return [
'success' => false,
'message' => __('Integration details are missing', 'bit-integrations'),
];
}
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed β added a guard right after the if (empty($this->_integrationDetails)) {
return [
'success' => false,
'message' => __('Integration details are missing', 'bit-integrations'),
];
} |
||
|
|
||
| if (empty($this->_integrationDetails)) { | ||
| return [ | ||
| 'success' => false, | ||
| 'message' => __('Integration details are missing', 'bit-integrations'), | ||
| ]; | ||
| } | ||
|
|
||
| $fieldData = static::generateReqDataFromFieldMap($fieldMap, $fieldValues); | ||
| $mainAction = $this->_integrationDetails->mainAction ?? 'sync_site'; | ||
|
|
||
| if (!empty($this->_integrationDetails->selectedSite)) { | ||
| $fieldData['site_id'] = (int) $this->_integrationDetails->selectedSite; | ||
| } | ||
|
|
||
| if (in_array($mainAction, ['create_post', 'update_post'], true)) { | ||
| $utils = (array) ($this->_integrationDetails->utilities ?? []); | ||
| if (!empty($utils['post_type'])) { | ||
| $fieldData['post_type'] = sanitize_text_field($utils['post_type']); | ||
| } | ||
| if (!empty($utils['post_status'])) { | ||
| $fieldData['post_status'] = sanitize_text_field($utils['post_status']); | ||
| } | ||
| } | ||
|
|
||
| $defaultResponse = [ | ||
| 'success' => false, | ||
| 'message' => wp_sprintf(__('%s plugin is not installed or activated', 'bit-integrations'), 'Bit Integrations Pro'), | ||
| ]; | ||
|
|
||
| switch ($mainAction) { | ||
| case 'sync_site': | ||
| $response = Hooks::apply(Config::withPrefix('main_wp_sync_site'), $defaultResponse, $fieldData); | ||
| $actionType = 'sync_site'; | ||
|
|
||
| break; | ||
|
|
||
| case 'sync_all_sites': | ||
| $response = Hooks::apply(Config::withPrefix('main_wp_sync_all_sites'), $defaultResponse); | ||
| $actionType = 'sync_all_sites'; | ||
|
|
||
| break; | ||
|
|
||
| case 'create_post': | ||
| $response = Hooks::apply(Config::withPrefix('main_wp_create_post'), $defaultResponse, $fieldData); | ||
| $actionType = 'create_post'; | ||
|
|
||
| break; | ||
|
|
||
| case 'update_post': | ||
| $response = Hooks::apply(Config::withPrefix('main_wp_update_post'), $defaultResponse, $fieldData); | ||
| $actionType = 'update_post'; | ||
|
|
||
| break; | ||
|
|
||
| case 'delete_post': | ||
| $response = Hooks::apply(Config::withPrefix('main_wp_delete_post'), $defaultResponse, $fieldData); | ||
| $actionType = 'delete_post'; | ||
|
|
||
| break; | ||
|
|
||
| case 'activate_plugin': | ||
| $response = Hooks::apply(Config::withPrefix('main_wp_activate_plugin'), $defaultResponse, $fieldData); | ||
| $actionType = 'activate_plugin'; | ||
|
|
||
| break; | ||
|
|
||
| case 'deactivate_plugin': | ||
| $response = Hooks::apply(Config::withPrefix('main_wp_deactivate_plugin'), $defaultResponse, $fieldData); | ||
| $actionType = 'deactivate_plugin'; | ||
|
|
||
| break; | ||
|
|
||
| case 'create_user': | ||
| $response = Hooks::apply(Config::withPrefix('main_wp_create_user'), $defaultResponse, $fieldData); | ||
| $actionType = 'create_user'; | ||
|
|
||
| break; | ||
|
|
||
| default: | ||
| $response = ['success' => false, 'message' => __('Invalid action', 'bit-integrations')]; | ||
| $actionType = 'unknown'; | ||
|
|
||
| break; | ||
| } | ||
|
|
||
| if (is_wp_error($response)) { | ||
| $response = [ | ||
| 'success' => false, | ||
| 'message' => $response->get_error_message(), | ||
| ]; | ||
| } | ||
|
|
||
| $responseType = isset($response['success']) && $response['success'] ? 'success' : 'error'; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the response from if (is_wp_error($response)) {
$response = [
'success' => false,
'message' => $response->get_error_message(),
];
}
$responseType = isset($response['success']) && $response['success'] ? 'success' : 'error';References
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed β added an if (is_wp_error($response)) {
$response = ['success' => false, 'message' => $response->get_error_message()];
}
$responseType = isset($response['success']) && $response['success'] ? 'success' : 'error'; |
||
| LogHandler::save($this->_integrationID, ['type' => 'MainWP', 'type_name' => $actionType], $responseType, $response); | ||
|
|
||
| return $response; | ||
| } | ||
|
|
||
| private static function generateReqDataFromFieldMap($fieldMap, $fieldValues): array | ||
| { | ||
| $data = []; | ||
| foreach ($fieldMap as $item) { | ||
| $triggerValue = $item->formField; | ||
| $actionValue = $item->mainWPField; | ||
|
|
||
| if (empty($actionValue) || (empty($triggerValue) && $triggerValue !== 'custom')) { | ||
| continue; | ||
| } | ||
|
|
||
| $data[$actionValue] = $triggerValue === 'custom' && isset($item->customValue) | ||
| ? Common::replaceFieldWithValue($item->customValue, $fieldValues) | ||
| : $fieldValues[$triggerValue] ?? ''; | ||
| } | ||
|
|
||
| return $data; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| <?php | ||
|
|
||
| if (!defined('ABSPATH')) { | ||
| exit; | ||
| } | ||
|
|
||
| use BitApps\Integrations\Actions\MainWP\MainWPController; | ||
| use BitApps\Integrations\Core\Util\Route; | ||
|
|
||
| Route::post('main_wp_authorize', [MainWPController::class, 'mainWPAuthorize']); | ||
| Route::post('refresh_main_wp_sites', [MainWPController::class, 'refreshSites']); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| import { useState } from 'react' | ||
| import { useNavigate, useParams } from 'react-router' | ||
| 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 './MainWPCommonFunc' | ||
| import MainWPIntegLayout from './MainWPIntegLayout' | ||
|
|
||
| export default function EditMainWP({ allIntegURL }) { | ||
| const navigate = useNavigate() | ||
| const { id, formID } = useParams() | ||
|
|
||
| const [mainWPConf, setMainWPConf] = 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, mainWPConf, setMainWPConf)} | ||
| name="name" | ||
| value={mainWPConf.name} | ||
| type="text" | ||
| placeholder={__('Integration Name...', 'bit-integrations')} | ||
| /> | ||
| </div> | ||
| <br /> | ||
|
|
||
| <SetEditIntegComponents entity={flow.triggered_entity} setSnackbar={setSnackbar} /> | ||
|
|
||
| <MainWPIntegLayout | ||
| formID={formID} | ||
| formFields={formFields} | ||
| mainWPConf={mainWPConf} | ||
| setMainWPConf={setMainWPConf} | ||
| setSnackbar={setSnackbar} | ||
| isLoading={isLoading} | ||
| setIsLoading={setIsLoading} | ||
| /> | ||
|
|
||
| <IntegrationStepThree | ||
| edit | ||
| saveConfig={() => | ||
| saveActionConf({ | ||
| flow, | ||
| setFlow, | ||
| allIntegURL, | ||
| conf: mainWPConf, | ||
| navigate, | ||
| id, | ||
| edit: 1, | ||
| setIsLoading, | ||
| setSnackbar | ||
| }) | ||
| } | ||
| disabled={!checkMappedFields(mainWPConf)} | ||
| isLoading={isLoading} | ||
| dataConf={mainWPConf} | ||
| setDataConf={setMainWPConf} | ||
| formFields={formFields} | ||
| /> | ||
| <br /> | ||
| </div> | ||
| ) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
MainWP_DB::instance()->get_sites()method returns an array ofstdClassobjects. Accessing$websitedirectly as an array (e.g.,$website['id']) will throw a fatal error:Cannot use object of type stdClass as array. Casting$websiteto an array before processing prevents this fatal error and ensures compatibility.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed β
get_sites()returnsstdClassobjects, so the loop now casts each entry before key access: