name = esc_html__( 'Design', 'charitable' );
$this->slug = 'design';
$this->icon = 'panel_design.svg';
$this->order = 20;
$this->sidebar = true;
add_action( 'charitable_builder_fields', [ $this, 'fields' ] );
add_action( 'charitable_builder_fields_options', [ $this, 'fields_options' ] );
add_action( 'charitable_builder_preview', [ $this, 'preview' ] );
// Template for Campaign builder previews.
add_action( 'charitable_builder_print_footer_scripts', [ $this, 'design_preview_templates' ] );
}
/**
* Enqueue assets for the Design panel.
*
* @since 1.8.0
*/
public function enqueues() {
$min = charitable_get_min_suffix();
wp_enqueue_script(
'charitable-builder-drag-fields',
charitable()->get_path( 'directory', false ) . "assets/js/campaign-builder/drag-fields{$min}.js",
[ 'charitable-builder' ],
charitable()->get_version(),
true
);
}
/**
* Output the Field panel sidebar.
*
* @since 1.8.0
*/
public function panel_sidebar() {
// This should never be called unless we are on the campaign builder page.
if ( ! campaign_is_campaign_builder_admin_page() ) {
return;
}
?>
display_tour_divs();
if ( $display_tour_divs ) :
?>
campaign_data ); ?>
campaign_data ); ?>
campaign_data['template_id'] ) ? esc_attr( $this->campaign_data['template_id'] ) : charitable_campaign_builder_default_template();
$campaign_id = isset( $this->campaign_data['campaign_id'] ) ? esc_attr( $this->campaign_data['campaign_id'] ) : false;
$campaign_title = isset( $this->campaign_data['title'] ) ? esc_html( $this->campaign_data['title'] ) : esc_html( $this->campaign->post_title );
$builder_template = new Charitable_Campaign_Builder_Templates();
$template_data = $builder_template->get_template_data( $template_id );
/* get status */
$campaign = $campaign_id ? charitable_get_campaign( $campaign_id ) : false;
$status = $campaign ? $campaign->get_status() : false;
if ( 'finished' === $status && $campaign->has_goal() ) {
$status = $campaign->has_achieved_goal() ? 'successful' : 'unsuccessful';
}
$campaign_status = $campaign ? '' . $status . ' ' : false;
/* establish any classes to add to preview wrap upon load */
$preview_wrap_classes = array( 'charitable-preview-wrap' );
if ( ! empty( $this->campaign_data['layout']['advanced']['show_field_names'] ) && 'hide' === $this->campaign_data['layout']['advanced']['show_field_names'] ) {
$preview_wrap_classes[] = 'charitable-preview-hide-field-names';
}
if ( ! empty( $this->campaign_data['layout']['advanced']['preview_mode'] ) && 'minimum' === $this->campaign_data['layout']['advanced']['preview_mode'] ) {
$preview_wrap_classes[] = 'charitable-preview-minimum-preview';
}
$preview_wrap_classes = trim( implode( ' ', $preview_wrap_classes ) );
?>
campaign ); ?>
campaign_data, 'submit' ); // phpcs:ignore Charitable.PHP.ValidateHooks.InvalidHookName
?>
campaign_data ); ?>
[
'group_name' => esc_html__( 'Recommended', 'charitable' ),
'description' => false,
'fields' => [],
],
'standard' => [
'group_name' => esc_html__( 'Standard', 'charitable' ),
'description' => false,
'fields' => [],
],
'pro' => [
'group_name' => esc_html__( 'Pro', 'charitable' ),
'description' => false,
'fields' => [],
],
];
/**
* Allows developers to modify content of the the Add Field tab.
*
* With this filter developers can add their own fields or even fields groups.
*
* @since 1.8.0
*
* @param array $fields {
* Design data multidimensional array.
*
* @param array $recommended Recommended fields group.
* @param string $group_name Group name.
* @param array $fields Design array.
*
* @param array $standard Standard fields group.
* @param string $group_name Group name.
* @param array $fields Design array.
*
* @param array $pro Pro fields group.
* @param string $group_name Group name.
* @param array $fields Design array.
* }
*/
$fields = apply_filters( 'charitable_builder_design_buttons', $fields );
// If there is campaign data, make a list of fields already in use which might determine what CSS classes (etC) gets passed to the buttons on the left.
$fields_in_template = array();
if ( false !== $campaign_data ) {
if ( ! empty( $campaign_data['layout']['rows'] ) ) {
foreach ( $campaign_data['layout']['rows'] as $row ) {
if ( ! empty( $row['fields'] ) ) {
$fields_in_template = array_merge( $fields_in_template, $row['fields'] );
}
}
}
}
$donation_form_display = charitable_get_option( 'donation_form_display' );
// Output the buttons.
foreach ( $fields as $id => $group ) {
usort( $group['fields'], [ $this, 'field_order' ] );
echo '';
}
}
/**
* Determine if we need to disable an add field button in the builder (left).
*
* @since 1.8.0
*
* @param string $button_type The type of button to check.
* @param bool $fields_in_template Whether the fields are in the template.
* @param bool $campaign_data The campaign data.
* @param bool $donation_form_display Whether the donation form is displayed.
*/
public function maybe_disable_add_button( $button_type = '', $fields_in_template = false, $campaign_data = false, $donation_form_display = false ) {
if ( '' === trim( $button_type ) || false === $fields_in_template ) {
return false;
}
// If "modal" is set to true and the field is a form or donate amount, immedately reject because these elements shouldn't be available when the donation form is a modal.
if ( 'modal' === $donation_form_display ) {
if ( $button_type === 'donation-form' || $button_type === 'donate-amount' ) {
return '-modal';
}
} elseif ( 'same_page' === $donation_form_display ) {
if ( $button_type === 'donation-form' || $button_type === 'donate-amount' || $button_type === 'donate-button' ) {
return '-same_page';
}
}
// check the field deny list.
$deny_list = array(
'donation-form' => array(
'donate-button' => 0,
'donation-form' => 0,
'donate-amount' => 0,
),
'donate-button' => array(
'donation-form' => 0,
),
'donate-amount' => array(
'donation-form' => 0,
),
);
// for example: donate-amount should be enabled unless donation form is present.
foreach ( $deny_list as $field_exists => $fields_to_check ) {
foreach ( $fields_to_check as $field_to_check => $field_amount_limit ) {
// if the key of the sub array isn't 'donate-amount' skip this.
if ( $field_to_check !== $button_type ) {
continue;
}
// ok, we found 'donate-amount' but 'donation-form' doesn't exist, so skip this.
if ( ! in_array( $field_exists, $fields_in_template, true ) ) {
continue;
}
$vals = array_count_values( $fields_in_template );
// ok if donation form exists determine how many 'donate-amount' are allowed to exist before disabling the add field in the builder.
if ( isset( $vals[ $field_to_check ] ) && $field_amount_limit <= $vals[ $field_to_check ] ) {
return true;
}
}
}
return false;
}
/**
* Editor Field Options.
*
* @since 1.8.0
*/
public function fields_options() {
// Check to make sure the form actually has fields created already.
if ( empty( $this->campaign_data['design'] ) ) {
$this->general_design_options();
return;
}
$fields = $this->campaign_data['design'];
foreach ( $fields as $field ) {
$class = apply_filters( 'charitable_builder_field_option_class', '', $field );
printf( '', sanitize_html_class( $field['type'] ), charitable_sanitize_classes( $class ), (int) $field['id'], (int) $field['id'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
printf( ' ', (int) $field['id'], (int) $field['id'] );
printf( ' ', (int) $field['id'], esc_attr( $field['type'] ) );
do_action( "charitable_builder_design_options_{$field['type']}", $field );
echo '
';
}
}
/**
* Generate HTML for hidden inputs from given data.
*
* @since 1.8.0
*
* @param array $data Field array data.
* @param string $name Input name prefix.
*/
private function generate_hidden_inputs( $data = [], $name = '' ) {
if ( ! is_array( $data ) || empty( $data ) ) {
return;
}
foreach ( $data as $key => $value ) {
if ( $key === 'id' ) {
continue;
}
$key = ! empty( $data['id'] ) ? sprintf( '[%s][%s]', $data['id'], $key ) : sprintf( '[%s]', $key );
if ( ! empty( $name ) ) {
$key = trim( $name ) . $key;
}
if ( is_array( $value ) ) {
$this->generate_hidden_inputs( $value, $key );
} else {
printf( " ", esc_attr( $key ), esc_attr( $value ) );
}
}
}
/**
* No fields options markup.
*
* @since 1.6.0
*/
public function no_design_options() {
printf(
'%s
',
esc_html__( 'You don\'t have any fields yet.', 'charitable' )
);
}
/**
* No fields preview placeholder markup.
*
* @since 1.8.0
*/
public function no_design_preview() {
}
/**
* No fields options markup.
*
* @since 1.8.0
*/
public function general_design_options() {
// layout options
// -> general.
// -> advanced.
$tabs = isset( $this->campaign_data['tabs'] ) ? $this->campaign_data['tabs'] : false;
$max_tab_title_length = apply_filters( 'charitable_builder_design_tab_title_length', 20 );
?>
campaign_data['layout']['rows'] ) ) :
foreach ( $this->campaign_data['layout']['rows'] as $row_id => $row ) :
// header.
if ( isset( $row['fields'] ) ) {
$row_type = $row['type'];
if ( 'row' === $row_type || 'header' === $row_type ) {
foreach ( $row['fields'] as $field_id => $field_type ) {
$type = 'Charitable_Field_' . str_replace( ' ', '_', ( ucwords( str_replace( '-', ' ', $field_type ) ) ) );
if ( class_exists( $type ) ) :
$class = new $type();
if ( method_exists( $class, 'settings_display' ) ) {
echo $class->settings_display( $field_id, $this->campaign_data ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
endif;
}
} elseif ( 'tabs' === $row_type ) {
foreach ( $row['tabs'] as $tab_id => $tab ) {
foreach ( $tab as $field_id_key => $field_id ) {
$field_type = $this->campaign_data['layout']['rows'][ $row_id ]['fields'][ $field_id ];
$type = 'Charitable_Field_' . str_replace( ' ', '_', ( ucwords( str_replace( '-', ' ', $field_type ) ) ) );
if ( class_exists( $type ) ) :
$class = new $type();
if ( method_exists( $class, 'settings_display' ) ) {
echo $class->settings_display( $field_id, $this->campaign_data ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
endif;
}
}
}
}
endforeach;
endif;
?>
campaign_data['layout']['advanced']['enable_tabs'] ) && '' !== trim( $this->campaign_data['layout']['advanced']['enable_tabs'] ) ? $this->campaign_data['layout']['advanced']['enable_tabs'] : 'enabled'; ?>
/>
tabs.
if ( $tabs ) {
$counter = 0;
$number_of_tabs = count( $tabs );
$hide_tab_nav_disabled = $number_of_tabs > 1 ? 'disabled="disabled"' : false;
foreach ( $tabs as $tab_id => $tab_info ) :
$group_id = ( strtolower( $tab_id ) === 'campaign' ) ? 0 : $tab_id;
$group_name_var = ( $tab_id === 'campaign' ) ? $group_id : $group_id;
$group_title = isset( $tab_info['title'] ) && '' !== trim( $tab_info['title'] ) ? $tab_info['title'] : '[ New Tab ]';
$group_header = ( $tab_id === 'campaign' ) ? 'Campaign' : $group_title;
$group_desc = isset( $tab_info['desc'] ) && '' !== trim( $tab_info['desc'] ) ? $tab_info['desc'] : false;
$group_classes = isset( $tab_info['title'] ) && '' !== trim( $tab_info['title'] ) ? false : 'charitable-new-tab';
$data_group = ( $tab_id === 'campaign' ) ? 'general-layout-tab' : 'general-layout-tab';
$active = $counter === 0 ? 'active' : false;
$closed = $counter === 0 ? 'charitable-open' : 'charitable-closed';
$arrow_icon = ! $active ? 'fa fa-angle-down charitable-angle-right' : 'fa fa-angle-down charitable-angle-down';
$type = ( isset( $tab_info['type'] ) && '' !== trim( $tab_info['type'] ) ) ? $tab_info['type'] : 'html';
$row_class = 'html' !== $type ? 'hidden' : false;
$visible_nav = ! empty( $tab_info['visible_nav'] ) && 'invisible' === $tab_info['visible_nav'] ? 'checked="checked"' : '';
$visible_nav_checked = ! empty( $tab_info['visible_nav'] ) && 'invisible' === $tab_info['visible_nav'] ? 'checked="checked"' : '';
$visible_nav_checked = ( false !== $hide_tab_nav_disabled ) ? '' : $visible_nav_checked;
$disabled_css = ( false !== $hide_tab_nav_disabled ) ? 'charitable-disabled' : false;
?>
campaign_data['layout']['advanced']['tab_style'] ) && '' !== trim( $this->campaign_data['layout']['advanced']['tab_style'] ) ? $this->campaign_data['layout']['advanced']['tab_style'] : 'boxed';
$tab_size = isset( $this->campaign_data['layout']['advanced']['tab_size'] ) && '' !== trim( $this->campaign_data['layout']['advanced']['tab_size'] ) ? $this->campaign_data['layout']['advanced']['tab_size'] : 'medium';
$preview_mode = isset( $this->campaign_data['layout']['advanced']['preview_mode'] ) && '' !== trim( $this->campaign_data['layout']['advanced']['preview_mode'] ) ? $this->campaign_data['layout']['advanced']['preview_mode'] : 'normal';
$show_field_names_default = charitable_show_field_names_by_default() ? 'show' : 'hide';
$show_field_names = isset( $this->campaign_data['layout']['advanced']['show_field_names'] ) && '' !== trim( $this->campaign_data['layout']['advanced']['show_field_names'] ) ? $this->campaign_data['layout']['advanced']['show_field_names'] : $show_field_names_default;
// todo: filter these.
$theme_color_primary = isset( $this->campaign_data['layout']['advanced']['theme_color_primary'] ) && '' !== trim( $this->campaign_data['layout']['advanced']['theme_color_primary'] ) ? $this->campaign_data['layout']['advanced']['theme_color_primary'] : '';
$theme_color_secondary = isset( $this->campaign_data['layout']['advanced']['theme_color_secondary'] ) && '' !== trim( $this->campaign_data['layout']['advanced']['theme_color_secondary'] ) ? $this->campaign_data['layout']['advanced']['theme_color_secondary'] : '';
$theme_color_tertiary = isset( $this->campaign_data['layout']['advanced']['theme_color_tertiary'] ) && '' !== trim( $this->campaign_data['layout']['advanced']['theme_color_tertiary'] ) ? $this->campaign_data['layout']['advanced']['theme_color_tertiary'] : '';
$theme_color_button = isset( $this->campaign_data['layout']['advanced']['theme_color_button'] ) && '' !== trim( $this->campaign_data['layout']['advanced']['theme_color_button'] ) ? $this->campaign_data['layout']['advanced']['theme_color_button'] : '';
// tab enabled/disabled.
$enable_tabs_css = isset( $this->campaign_data['layout']['advanced']['enable_tabs'] ) && '' !== trim( $this->campaign_data['layout']['advanced']['enable_tabs'] ) ? 'disabled' : '';
?>