' . esc_html__( 'Edit Page Content', 'adventurebook' ) . ''; // Textfeld für den Titel $html .= ''; // Textfeld für den Inhalt $html .= ''; // Bildauswahl $html .= '
'; $html .= ''; $html .= ''; $html .= '
'; if ( $current_image_url ) { $html .= ''; } $html .= '
'; $html .= ' '; $html .= ''; $html .= '
'; // Text Input for resources $html .= '
'; $html .= ''; $resources = get_post_meta( $page_id, '_adventurebook_page_resources', true ); $html .= ''; $html .= '
'; // Buttons $html .= ''; $html .= ' '; break; case 'add_decision': // we need: // - a label for the decision // - the decision direction (none, north, south, etc. from the predefined list) // - a target page ID (list of all existing pages in the adventurebook to choose from) // - an optional backlink (if this is set, the target page will have a backlink to this page) // - a restriction type (none, item, stat, skill) // - a restriction value (item ID, stat name, skill name) $html .= '

' . esc_html__( 'Add Decision', 'adventurebook' ) . '

'; $html .= ''; $html .= ''; // target page, select from all pages in this adventurebook // add the option to select "New Page" which will create a new page and link to it, in this case the value is -1 $adventurebook_id = wp_get_post_parent_id( $page_id ); $pages = get_posts( array( 'post_type' => 'adventurebook_page', 'post_status' => 'publish', 'posts_per_page' => - 1, 'post_parent' => $adventurebook_id, 'orderby' => 'title', 'order' => 'ASC', ) ); $html .= ''; // new page title input field, hidden by default, only shown if "New Page" is selected $html .= ''; // backlink $html .= ''; // restriction type $html .= ''; // restriction value $html .= ''; $html .= ''; // show cancel button $html .= ' '; break; case 'add_item_spawn': $html .= '

' . esc_html__( 'Add Item Spawn', 'adventurebook' ) . '

'; // show all item definitions in a dropdown // get all item definitions $items = Item_Definition::get_all_item_definitions(); $html .= ''; $html .= ''; $html .= ''; $html .= ''; // show cancel button $html .= ' '; break; case 'add_enemy_spawn': $html .= '

' . esc_html__( 'Add Enemy Spawn', 'adventurebook' ) . '

'; // show all enemy definitions in a dropdown // get all enemy definitions $enemies = Enemy_Definition::get_all_enemy_definitions(); $html .= ''; $html .= ''; $html .= ''; // $html .= ''; // show cancel button $html .= ' '; break; default: wp_send_json_error( __( 'Invalid mode.', 'adventurebook' ) ); } wp_send_json_success( $html ); } add_action( 'wp_ajax_adventurebook_inline_edit_form', 'adventurebook_inline_edit_form_ajax' ); /** * AJAX handler to save inline edits (page content, decisions, item/enemy spawns) */ function adventurebook_saveInlineEdit_ajax() { global $adventurebook_decision_dirs, $adventurebook_restriction_types; check_ajax_referer( 'adventurebook_inline_edit_nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( __( 'You do not have permission to perform this action.', 'adventurebook' ) ); } global $wpdb; $mode = sanitize_text_field( wp_unslash( $_POST['mode'] ?? '' ) ); $page_id = intval( sanitize_text_field( wp_unslash( $_POST['page_id'] ?? 0 ) ) ); if ( ! $page_id ) { wp_send_json_error( __( 'Invalid page ID.', 'adventurebook' ) ); } switch ( $mode ) { // Edit existing page content case 'page': $new_content = wp_kses_post( wp_unslash( $_POST['content'] ?? '' ) ); $new_title = ab_get('title'); $new_image_id = intval( ab_get('image_id')); if ( ! $new_content ) { wp_send_json_error( __( 'Content is empty.', 'adventurebook' ) ); } wp_update_post( array( 'ID' => $page_id, 'post_title' => $new_title, 'post_content' => $new_content, ) ); // Seitenbild speichern oder löschen if ( $new_image_id > 0 ) { update_post_meta( $page_id, '_additional_image', $new_image_id ); } else { delete_post_meta( $page_id, '_additional_image' ); } // update resources $new_resources = sanitize_text_field( ab_get('resources') ); update_post_meta( $page_id, '_adventurebook_page_resources', $new_resources ); wp_send_json_success( __( 'Page content updated successfully.', 'adventurebook' ) ); break; // Add new decision // we need: // - a label for the decision // - the decision direction (none, north, south, etc. from the predefined list) // - a target page ID (list of all existing pages in the adventurebook to choose from) // - an optional backlink (if this is set, the target page will have a backlink to this page) // - a restriction type (none, item, stat, skill) // - a restriction value (item ID, stat name, skill name) // // see admin_page_decisions.php for reference // case 'decision': $option = array(); $option['label'] = sanitize_text_field( wp_unslash( $_POST['label'] ?? '' ) ); $option['decision_dir'] = strtolower( sanitize_text_field( wp_unslash( $_POST['decision_direction'] ?? 'none' ) ) ); $option['target'] = intval( sanitize_text_field( wp_unslash( $_POST['target'] ?? 0 ) ) ); $option['new_page_title'] = sanitize_text_field( wp_unslash( $_POST['new_page_title'] ?? '' ) ); $option['new_page_backlink'] = sanitize_text_field( wp_unslash( $_POST['backlink_label'] ?? '' ) ); $option['restriction_type'] = strtolower( sanitize_text_field( wp_unslash( $_POST['restriction_type'] ?? 'none' ) ) ); $option['restriction_value'] = sanitize_text_field( wp_unslash( $_POST['restriction_value'] ?? '' ) ); $valid_directions = $adventurebook_decision_dirs; $valid_restrictions = $adventurebook_restriction_types; // add the decision to the page meta data if ( ! in_array( $option['decision_dir'], $valid_directions, true ) ) { wp_send_json_error( __( 'Invalid direction.', 'adventurebook' ) ); } if ( ! in_array( $option['restriction_type'], $valid_restrictions, true ) ) { wp_send_json_error( __( 'Invalid restriction type.', 'adventurebook' ) ); } if ( $option['restriction_type'] !== 'none' && empty( $option['restriction_value'] ) ) { wp_send_json_error( __( 'Restriction value is required for the selected restriction type.', 'adventurebook' ) ); } // now save the decision if ( $option['target'] == - 1 ) { // create a new page // set the title to decision option ['new_page_title'] if it exists, otherwise to "New Page" $new_page_title = isset( $option['new_page_title'] ) && $option['new_page_title'] !== '' ? $option['new_page_title'] : __( 'New Page', 'adventurebook' ); $new_page = array( 'post_title' => $new_page_title, 'post_content' => '', 'post_status' => 'publish', 'post_type' => 'adventurebook_page', 'post_parent' => wp_get_post_parent_id( $page_id ), ); // we have a new target page, so set the target to the new page ID $option['target'] = wp_insert_post( $new_page ); } // make sure that the target page exists and is of the correct post type $target_page = get_post( $option['target'] ); if ( ! $target_page || $target_page->post_type != 'adventurebook_page' ) { // if the target page does not exist or is of the wrong post type, remove the decision option unset( $option ); wp_send_json_error( __( 'Target page does not exist.', 'adventurebook' ) ); } // add a new decision option to the page $decision_options = get_post_meta( $page_id, '_adventurebook_decision_options', true ); $decision_options = is_array( $decision_options ) ? $decision_options : array(); $decision_options[] = $option; update_post_meta( $page_id, '_adventurebook_decision_options', $decision_options ); // if a backlink was set, add a new decision option to the target page that links back to this page if ( isset( $option['new_page_backlink'] ) && $option['new_page_backlink'] !== '' ) { $backlink_option = array( 'label' => $option['new_page_backlink'], 'target' => $page_id, 'decision_dir' => adventurebook_get_reverse_dir( $option['decision_dir'] ), 'restriction_type' => $option['restriction_type'], 'restriction_value' => $option['restriction_value'], ); $target_decision_options = get_post_meta( $option['target'], '_adventurebook_decision_options', true ); $target_decision_options = is_array( $target_decision_options ) ? $target_decision_options : array(); // only add the backlink if it does not already exist $backlink_exists = false; foreach ( $target_decision_options as $existing_option ) { if ( $existing_option['target'] == $page_id ) { $backlink_exists = true; break; } } if ( ! $backlink_exists ) { $target_decision_options[] = $backlink_option; update_post_meta( $option['target'], '_adventurebook_decision_options', $target_decision_options ); } } wp_send_json_success( __( 'Decision added successfully.', 'adventurebook' ) ); break; // Add new item spawn case 'item_spawn': $item_id = intval( ab_get( 'item_id' ) ); $respawn_time = intval( ab_get( 'respawn_time' ) ); $data = ab_get( 'data' ); if ( $item_id <= 0 ) { wp_send_json_error( __( 'Invalid item ID.', 'adventurebook' ) ); } $item = Item_Definition::get_item_definition_by_id( $item_id ); Item_Spawn::create_item_spawn( $item->code, $page_id, $respawn_time, $data ); wp_send_json_success( __( 'Item spawn added successfully.', 'adventurebook' ) ); break; // Add new enemy spawn case 'enemy_spawn': $enemy_id = intval( ab_get( 'enemy_id' ) ); $respawn_time = intval( ab_get( 'respawn_time' ) ); $alternate_page_ids = ab_get( 'alternate_page_ids' ); if ( $enemy_id <= 0 ) { wp_send_json_error( __( 'Invalid enemy ID.', 'adventurebook' ) ); } $enemy = Enemy_Definition::get_enemy_definition_by_id( $enemy_id ); Enemy_Spawn::create_enemy_spawn_point_root( $enemy->code, $page_id, $respawn_time, $alternate_page_ids ); wp_send_json_success( __( 'Enemy spawn added successfully.', 'adventurebook' ) ); break; case 'delete_item_spawn': $spawn_id = $page_id; if ( $spawn_id <= 0 ) { wp_send_json_error( __( 'Invalid spawn ID.', 'adventurebook' ) ); } Item_Spawn::delete_item_spawn_point( $spawn_id ); wp_send_json_success( __( 'Item spawn deleted successfully.', 'adventurebook' ) ); break; case 'delete_enemy_spawn': $spawn_id = $page_id; if ( $spawn_id <= 0 ) { wp_send_json_error( __( 'Invalid spawn ID.', 'adventurebook' ) ); } Enemy_Spawn::delete_enemy_spawn_point( $spawn_id ); wp_send_json_success( __( 'Enemy spawn deleted successfully.', 'adventurebook' ) ); break; default: wp_send_json_error( __( 'Invalid mode.', 'adventurebook' ) ); } } add_action( 'wp_ajax_adventurebook_saveInlineEdit', 'adventurebook_saveInlineEdit_ajax' );