post_type, buildvex()->supported_post_types(), true ) && current_user_can( 'edit_post', $post->ID );
}
/**
* Hidden editor page (menu me nahi dikhta).
*/
public function register_editor_page() {
// "options.php" parent = hidden page jiska admin title phir bhi sahi set hota hai.
add_submenu_page( 'options.php', __( 'SoftPulse Builder Editor', 'softpulse-visual-page-builder' ), __( 'SoftPulse Builder Editor', 'softpulse-visual-page-builder' ), 'edit_posts', self::PAGE, array( $this, 'render_editor' ) );
}
/**
* Is editor screen?
*
* @return bool
*/
private function is_editor_screen() {
$screen = get_current_screen();
return $screen && false !== strpos( $screen->id, self::PAGE );
}
/**
* Full-screen body class.
*
* @param string $classes Classes.
* @return string
*/
public function body_class( $classes ) {
return $this->is_editor_screen() ? $classes . ' bvx-editor-fullscreen' : $classes;
}
/**
* Editor markup (JS UI banata hai).
*/
public function render_editor() {
$post_id = isset( $_GET['post'] ) ? absint( $_GET['post'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only, capability checked.
if ( ! $post_id || ! $this->supported( $post_id ) ) {
wp_die( esc_html__( 'You cannot edit this item with SoftPulse Builder.', 'softpulse-visual-page-builder' ) );
}
echo '
' . esc_html__( 'Loading editor…', 'softpulse-visual-page-builder' ) . '
';
echo '';
}
/**
* Editor data + assets.
*
* @param string $hook Hook.
*/
public function editor_data( $hook ) {
if ( false === strpos( $hook, self::PAGE ) ) {
return;
}
$post_id = isset( $_GET['post'] ) ? absint( $_GET['post'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( ! $post_id || ! $this->supported( $post_id ) ) {
return;
}
// WordPress emoji script editor ke icons (✨ 🖼 📱) ko bahar se images me badal deta hai — band.
remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
remove_action( 'admin_print_styles', 'print_emoji_styles' );
// Frontend styles bhi chahiye taake preview asal jaisa dikhe.
wp_enqueue_style( 'buildvex-frontend-preview', BUILDVEX_URL . 'public/css/frontend.css', array(), BUILDVEX_ASSET_VER );
wp_enqueue_style( 'buildvex-forms-preview', BUILDVEX_URL . 'public/css/forms.css', array(), BUILDVEX_ASSET_VER );
wp_enqueue_script( 'buildvex-frontend-preview', BUILDVEX_URL . 'public/js/frontend.js', array(), BUILDVEX_ASSET_VER, true );
$post = get_post( $post_id );
$renderer = buildvex()->get( 'renderer' );
$layout = $renderer->get_layout( $post_id );
$is_tpl = 'buildvex_template' === $post->post_type;
$ai = buildvex()->get( 'ai' );
$site = buildvex()->settings();
$data = array(
'layout' => $layout ? $layout : array( 'sections' => array() ),
'page' => array_merge(
$renderer->page_settings( $post_id ),
array( 'title' => $post->post_title )
),
'status' => $post->post_status,
'postType' => $post->post_type,
'postTypeLabel' => get_post_type_object( $post->post_type )->labels->singular_name,
'isTemplate' => $is_tpl,
'templateType' => $is_tpl ? get_post_meta( $post_id, '_buildvex_tpl_type', true ) : '',
'canPublish' => current_user_can( 'publish_post', $post_id ),
'previewUrl' => $is_tpl ? add_query_arg( 'buildvex_tpl_preview', $post_id, home_url( '/' ) ) : get_preview_post_link( $post_id ),
'viewUrl' => $is_tpl ? '' : get_permalink( $post_id ),
'exitUrl' => $is_tpl ? get_edit_post_link( $post_id, 'raw' ) : admin_url( 'edit.php?post_type=' . $post->post_type ),
'settingsUrl' => admin_url( 'admin.php?page=buildvex' ),
'dashboardUrl' => admin_url(),
'listUrl' => admin_url( 'edit.php?post_type=' . $post->post_type ),
'listLabel' => get_post_type_object( $post->post_type )->labels->name,
'wpEditUrl' => $is_tpl ? '' : get_edit_post_link( $post_id, 'raw' ),
'sectionControls' => Buildvex_Widgets_Manager::section_controls(),
'columnControls' => Buildvex_Widgets_Manager::column_controls(),
'aiReady' => $ai ? $ai->is_ready() : false,
'palette' => self::palette(),
'fonts' => Buildvex_Fonts::fonts(),
'googleFonts' => empty( buildvex()->settings()['disable_google_fonts'] ),
'categories' => Buildvex_Widgets_Manager::categories(),
'canManageStyles' => current_user_can( 'manage_options' ),
'siteStyles' => array(
'accent_color' => isset( $site['accent_color'] ) ? $site['accent_color'] : '',
'font_body' => isset( $site['font_body'] ) ? $site['font_body'] : '',
'font_heading' => isset( $site['font_heading'] ) ? $site['font_heading'] : '',
'disable_google_fonts' => empty( $site['disable_google_fonts'] ) ? 0 : 1,
),
);
/**
* Filters the data passed to the editor app.
*
* @param array $data Data.
* @param int $post_id Post ID.
*/
$data = apply_filters( 'buildvex_editor_data', $data, $post_id );
wp_add_inline_script( 'buildvex-editor', 'window.buildvexBuilderData = ' . wp_json_encode( $data ) . ';', 'before' );
}
/**
* Color swatches: accent + theme palette + kuch saaf default rang.
*
* @return string[]
*/
public static function palette() {
$colors = array();
$accent = buildvex()->settings()['accent_color'];
if ( $accent ) {
$colors[] = $accent;
}
$theme = array();
if ( function_exists( 'wp_get_global_settings' ) ) {
$p = wp_get_global_settings( array( 'color', 'palette', 'theme' ) );
$theme = is_array( $p ) ? $p : array();
}
if ( ! $theme ) {
$support = get_theme_support( 'editor-color-palette' );
$theme = is_array( $support ) && isset( $support[0] ) && is_array( $support[0] ) ? $support[0] : array();
}
foreach ( $theme as $c ) {
if ( ! empty( $c['color'] ) ) {
$colors[] = $c['color'];
}
}
$colors = array_merge( $colors, array( '#000000', '#ffffff', '#111827', '#374151', '#6b7280', '#e5e7eb', '#2563eb', '#4f46e5', '#16a34a', '#dc2626', '#f59e0b', '#d4a24c' ) );
$clean = array();
foreach ( $colors as $c ) {
$c = Buildvex_Controls::sanitize_color( $c );
if ( $c && ! in_array( $c, $clean, true ) ) {
$clean[] = $c;
}
}
return array_slice( $clean, 0, 18 );
}
/**
* Row action.
*
* @param array $actions Actions.
* @param WP_Post $post Post.
* @return array
*/
public function row_action( $actions, $post ) {
if ( $this->supported( $post ) && 'buildvex_template' !== $post->post_type ) {
$actions['buildvex_edit'] = sprintf( '✦ %s', esc_url( self::editor_url( $post->ID ) ), esc_html__( 'Edit with SoftPulse Builder', 'softpulse-visual-page-builder' ) );
}
return $actions;
}
/**
* "SoftPulse Builder" label in post list.
*
* @param array $states States.
* @param WP_Post $post Post.
* @return array
*/
public function post_state( $states, $post ) {
if ( buildvex()->is_built_with_builder( $post->ID ) && 'buildvex_template' !== $post->post_type ) {
$states['buildvex'] = 'SoftPulse Builder';
}
return $states;
}
/**
* Classic editor button.
*
* @param WP_Post $post Post.
*/
public function classic_button( $post ) {
if ( ! $this->supported( $post ) || 'buildvex_template' === $post->post_type ) {
return;
}
if ( 'auto-draft' === $post->post_status ) {
echo '' . esc_html__( 'Save a draft to edit this with SoftPulse Builder.', 'softpulse-visual-page-builder' ) . '
';
return;
}
printf(
'✦ %s
',
esc_url( self::editor_url( $post->ID ) ),
esc_html__( 'Edit with SoftPulse Builder', 'softpulse-visual-page-builder' )
);
}
/**
* Gutenberg button (Post status panel me).
*/
public function block_editor_button() {
$screen = get_current_screen();
if ( ! $screen || ! in_array( $screen->post_type, buildvex()->supported_post_types(), true ) ) {
return;
}
wp_enqueue_script(
'buildvex-block-editor',
BUILDVEX_URL . 'admin/js/block-editor.js',
array( 'wp-plugins', 'wp-element', 'wp-data', 'wp-editor' ),
BUILDVEX_ASSET_VER,
true
);
wp_localize_script(
'buildvex-block-editor',
'buildvexBlockEditor',
array(
'base' => admin_url( 'admin.php?page=' . self::PAGE . '&post=' ),
'label' => __( '✦ Edit with SoftPulse Builder', 'softpulse-visual-page-builder' ),
)
);
}
/**
* Admin bar link on frontend.
*
* @param WP_Admin_Bar $bar Bar.
*/
public function admin_bar( $bar ) {
if ( is_admin() || ! is_singular() ) {
return;
}
$id = get_queried_object_id();
if ( ! $this->supported( $id ) ) {
return;
}
$bar->add_node(
array(
'id' => 'bvx-edit',
'title' => '✦ ' . esc_html__( 'Edit with SoftPulse Builder', 'softpulse-visual-page-builder' ),
'href' => self::editor_url( $id ),
)
);
}
/**
* "✦ New with SoftPulse Builder" link on list screens.
*/
public function views_filters() {
foreach ( buildvex()->supported_post_types() as $pt ) {
if ( 'buildvex_template' === $pt ) {
continue;
}
add_filter(
'views_edit-' . $pt,
static function ( $views ) use ( $pt ) {
if ( current_user_can( get_post_type_object( $pt ) ? get_post_type_object( $pt )->cap->create_posts : 'edit_posts' ) ) {
$url = wp_nonce_url( admin_url( 'admin-post.php?action=buildvex_new&post_type=' . $pt ), 'buildvex_new' );
$views['buildvex_new'] = '✦ ' . esc_html__( 'New with SoftPulse Builder', 'softpulse-visual-page-builder' ) . '';
}
return $views;
}
);
}
}
/**
* Create a draft and open the editor.
*/
public function create_new() {
check_admin_referer( 'buildvex_new' );
$pt = isset( $_GET['post_type'] ) ? sanitize_key( wp_unslash( $_GET['post_type'] ) ) : 'page';
$obj = get_post_type_object( $pt );
if ( ! $obj || ! in_array( $pt, buildvex()->supported_post_types(), true ) || ! current_user_can( $obj->cap->create_posts ) ) {
wp_die( esc_html__( 'Sorry, you are not allowed to do that.', 'softpulse-visual-page-builder' ), 403 );
}
$id = wp_insert_post(
array(
'post_type' => $pt,
'post_status' => 'draft',
/* translators: %s: post type name. */
'post_title' => sprintf( __( 'New %s', 'softpulse-visual-page-builder' ), $obj->labels->singular_name ),
),
true
);
if ( is_wp_error( $id ) ) {
wp_die( esc_html( $id->get_error_message() ) );
}
update_post_meta( $id, BUILDVEX_META_KEY, wp_slash( wp_json_encode( array( 'sections' => array() ) ) ) );
wp_safe_redirect( self::editor_url( $id ) );
exit;
}
}