RegistrationManager = new RegistrationManager(); } // function to sanitize json data public function jsonSanitize($data) { if (is_string($data)) { $data = json_decode($data, true); } if (is_array($data)) { foreach ($data as $key => $value) { if (is_array($value)) { $data[$key] = $this->jsonSanitize($value); } else { $data[$key] = sanitize_text_field($value); } } } else { $data = sanitize_text_field($data); } return wp_json_encode($data); } // Method to register the REST API route public function register_routes() { register_rest_route('advanced-block-controls/v1', '/settings', [ 'methods' => 'GET', 'callback' => [$this, 'get_all_settings'], 'permission_callback' => function () { return current_user_can('manage_options'); }, 'show_in_index' => false, ]); // New route for saving an option register_rest_route('advanced-block-controls/v1', '/save-option', array( 'methods' => 'POST', 'callback' => [$this, 'handle_save_option'], 'permission_callback' => [$this, 'save_option_permissions_check'], 'show_in_index' => false, )); // Update a single block and its controls register_rest_route('advanced-block-controls/v1', '/save-block', [ 'methods' => 'POST', 'callback' => [$this, 'handle_update_block_controls'], 'permission_callback' => function () { return current_user_can('manage_options'); }, 'show_in_index' => false, ]); } public function handle_update_block_controls($request) { global $wpdb; $params = $request->get_json_params(); $block_name = sanitize_text_field($params['block_name']); $block_target = $this->jsonSanitize($params['target']); $controls = $params['controls']; // Begin transaction $wpdb->query('START TRANSACTION'); $currentTime = gmdate("Y-m-d H:i:s"); try { // Check if block exists $existing_block = $wpdb->get_row($wpdb->prepare("SELECT id FROM {$wpdb->prefix}" . RegistrationManager::BLOCKS_TABLE_NAME . " WHERE block_name = %s", $block_name)); $block_id = $existing_block ? $existing_block->id : null; if ($existing_block) { // Update the existing block $wpdb->update("{$wpdb->prefix}" . RegistrationManager::BLOCKS_TABLE_NAME, ['target' => $block_target, 'date_edited' => $currentTime, 'is_default_settings' => false], ['id' => $block_id]); // Updating existing controls and inserting new ones foreach ($controls as $controlSlug => $controlData) { $controlId = sanitize_text_field($controlData['id']); $controlState = sanitize_text_field($controlData['state']); // We only need this here to check if the control is being trashed if ($controlState === 'trash') { // Delete the control $wpdb->delete("{$wpdb->prefix}" . RegistrationManager::CONTROLS_TABLE_NAME, ['id' => $controlId]); } else { $controlArray = [ 'title' => sanitize_text_field($controlData['title']), 'type' => sanitize_text_field($controlData['type']), 'state' => sanitize_text_field($controlData['state']), 'target' => $this->jsonSanitize($controlData['target']), 'blockId' => $block_id, 'order_num' => sanitize_text_field($controlData['order_num']), 'date_edited' => $currentTime ]; if ($controlId) { // Update existing control $wpdb->update("{$wpdb->prefix}" . RegistrationManager::CONTROLS_TABLE_NAME , $controlArray, ['id' => $controlId]); } else { // Insert new control $wpdb->insert("{$wpdb->prefix}" . RegistrationManager::CONTROLS_TABLE_NAME , $controlArray); } } } } else { // Insert new block $wpdb->insert("{$wpdb->prefix}" . RegistrationManager::BLOCKS_TABLE_NAME, ['block_name' => $block_name, 'target' => $block_target, 'date_edited' => $currentTime, 'is_default_settings' => false]); $block_id = $wpdb->insert_id; // Inserting the controls foreach ($controls as $controlSlug => $controlData) { $controlId = sanitize_text_field($controlData['id']); $controlState = sanitize_text_field($controlData['state']); // We only need this here to check if the control is being trashed if ($controlState === 'trash') { // Delete the control $wpdb->delete("{$wpdb->prefix}" . RegistrationManager::CONTROLS_TABLE_NAME, ['id' => $controlId]); } else { $default_clone = sanitize_text_field($controlData['default_clone']); $default_id = null; if($default_clone) { $default_id = $controlId; } $controlArray = [ 'title' => sanitize_text_field($controlData['title']), 'default_clone' => $default_clone, 'default_id' => $default_id, 'type' => sanitize_text_field($controlData['type']), 'state' => sanitize_text_field($controlData['state']), 'target' => $this->jsonSanitize($controlData['target']), 'blockId' => $block_id, 'order_num' => sanitize_text_field($controlData['order_num']), "date_edited" => $currentTime ]; // Insert all the controls $wpdb->insert("{$wpdb->prefix}" . RegistrationManager::CONTROLS_TABLE_NAME, $controlArray); } } } // Commit transaction $wpdb->query('COMMIT'); // Fetch updated controls $updatedControls = $this->get_controls_for_block($block_id); // Prepare response data $responseData = [ 'block_name' => $block_name, 'id' => $block_id, 'target' => $block_target, 'date_edited' => $currentTime, 'controls' => $updatedControls ]; return new \WP_REST_Response([ 'message' => 'Block and controls updated successfully', 'data' => $responseData ], 200); } catch (Exception $e) { // Rollback transaction in case of error $wpdb->query('ROLLBACK'); return new \WP_Error('db_error', $e->getMessage(), ['status' => 500]); } } private function get_controls_for_block($blockId) { global $wpdb; $sql = $wpdb->prepare( "SELECT id, title, type, state, target, order_num, date_edited, default_clone, default_id FROM {$wpdb->prefix}" . RegistrationManager::CONTROLS_TABLE_NAME . " WHERE blockId = %d AND state != %s ORDER BY order_num", $blockId, 'trash' ); $results = $wpdb->get_results($sql, ARRAY_A); $controls = []; foreach ($results as $row) { $controlSlug = $row['type'] . '_' . $row['id']; $controls[$controlSlug] = [ 'id' => $row['id'], 'default_clone' => $row['default_clone'], 'default_id' => $row['default_id'], 'title' => $row['title'], 'type' => $row['type'], 'state' => $row['state'], 'target' => $this->jsonSanitize($row['target']), 'order_num' => $row['order_num'], 'date_edited' => $row['date_edited'] ]; } return $controls; } // Callback method for the REST API route public function get_all_settings() { $options = $this->get_options(); $block_controls = $this->get_block_controls(); $deny_list = $this->get_deny_list(); $response = [ 'options' => $options, 'deny_list' => $deny_list, 'controls' => $block_controls, ]; return rest_ensure_response($response); } // Method to retrieve general settings from the options table private function get_options() { // Retrieve and decode the option $settings_option = get_option('abcon_settings'); $settings = json_decode($settings_option, true); return $settings; } // Metho to retieve denied blocks lisr private function get_deny_list() { // Retrieve and decode the option $deny_list_option = get_option('abcon_deny_list'); $deny_list = json_decode($deny_list_option, true); return $deny_list; } public function get_block_controls() { if($this->RegistrationManager->blocks_table_exists() && $this->RegistrationManager->controls_table_exists()) { global $wpdb; // SQL to retrieve blocks and their related controls, excluding controls with state 'trash' $sql = "SELECT b.id as block_id, b.block_name, b.target as block_target, b.is_default_settings, b.date_edited as block_edit_date, c.id as control_id, c.title, c.type, c.state, c.target as control_target, c.config, c.order_num, c.default_clone, c.default_id, c.date_edited as control_edit_date FROM {$wpdb->prefix}" . RegistrationManager::BLOCKS_TABLE_NAME . " b LEFT JOIN {$wpdb->prefix}" . RegistrationManager::CONTROLS_TABLE_NAME . " c ON b.id = c.blockId AND c.state != 'trash' ORDER BY b.id, c.order_num, c.id"; $results = $wpdb->get_results($sql, ARRAY_A); $blocks = array(); foreach ($results as $row) { // Initialize block if it hasn't been added to $blocks array if (!isset($blocks[$row['block_name']])) { $blocks[$row['block_name']] = array( 'id' => $row['block_id'], 'block_name' => $row['block_name'], 'target' => $this->jsonSanitize($row['block_target']), 'date_edited' => $row['block_edit_date'], 'is_default_settings' => $row['is_default_settings'], 'controls' => array() ); } // Add control to this block using type_controlId as the key if ($row['control_id']) { $controlSlug = $row['type'] . '_' . $row['control_id']; $blocks[$row['block_name']]['controls'][$controlSlug] = array( 'id' => $row['control_id'], 'default_clone' => $row['default_clone'], 'default_id' => $row['default_id'], 'title' => $row['title'], 'type' => $row['type'], 'state' => $row['state'], 'target' => $this->jsonSanitize($row['control_target']), 'order_num' => $row['order_num'], 'date_edited' => $row['block_edit_date'], 'config' => json_decode($row['config'], true) ); } } return $blocks; } return array(); } // Method to handle saving an option public function handle_save_option($request) { // Decode the JSON body from the request $params = json_decode($request->get_body(), true); // Extract the option name and value $option_name = array_key_first($params); $option_value = $params[$option_name]; if (empty($option_name)) { return new \WP_Error('missing_option_name', 'Option name is required', array('status' => 400)); } $result = update_option($option_name, $option_value); $response = get_option($option_name); if ($result) { return new \WP_REST_Response([ 'message' => 'Option Have been saved successfully', 'data' => [ 'option_name' => $option_name, 'option_value' => $response ] ], 200); } else { return new \WP_Error('db_error', 'Failed to save the option', array('status' => 500)); } } // Method for permission check public function save_option_permissions_check($request) { return current_user_can('manage_options'); } }